1 /******************************************************************************
3 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 ******************************************************************************/
15 #define _RTL8192CU_RECV_C_
16 #include <osdep_service.h>
17 #include <drv_types.h>
18 #include <recv_osdep.h>
19 #include <mlme_osdep.h>
21 #include <linux/if_ether.h>
24 #include <rtl8723a_hal.h>
26 int rtl8723au_init_recv_priv(struct rtw_adapter
*padapter
)
28 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
29 int i
, size
, res
= _SUCCESS
;
30 struct recv_buf
*precvbuf
;
31 unsigned long tmpaddr
;
32 unsigned long alignment
;
35 tasklet_init(&precvpriv
->recv_tasklet
,
36 (void(*)(unsigned long))rtl8723au_recv_tasklet
,
37 (unsigned long)padapter
);
39 precvpriv
->int_in_urb
= usb_alloc_urb(0, GFP_KERNEL
);
40 if (!precvpriv
->int_in_urb
)
41 DBG_8723A("alloc_urb for interrupt in endpoint fail !!!!\n");
42 precvpriv
->int_in_buf
= kzalloc(USB_INTR_CONTENT_LENGTH
, GFP_KERNEL
);
43 if (!precvpriv
->int_in_buf
)
44 DBG_8723A("alloc_mem for interrupt in endpoint fail !!!!\n");
46 size
= NR_RECVBUFF
* sizeof(struct recv_buf
);
47 precvpriv
->precv_buf
= kzalloc(size
, GFP_KERNEL
);
48 if (!precvpriv
->precv_buf
) {
50 RT_TRACE(_module_rtl871x_recv_c_
, _drv_err_
,
51 "alloc recv_buf fail!\n");
55 precvbuf
= (struct recv_buf
*)precvpriv
->precv_buf
;
57 for (i
= 0; i
< NR_RECVBUFF
; i
++) {
58 INIT_LIST_HEAD(&precvbuf
->list
);
60 precvbuf
->purb
= usb_alloc_urb(0, GFP_KERNEL
);
64 precvbuf
->adapter
= padapter
;
69 skb_queue_head_init(&precvpriv
->rx_skb_queue
);
70 skb_queue_head_init(&precvpriv
->free_recv_skb_queue
);
72 for (i
= 0; i
< NR_PREALLOC_RECV_SKB
; i
++) {
73 size
= MAX_RECVBUF_SZ
+ RECVBUFF_ALIGN_SZ
;
74 pskb
= __netdev_alloc_skb(padapter
->pnetdev
, size
, GFP_KERNEL
);
77 pskb
->dev
= padapter
->pnetdev
;
79 tmpaddr
= (unsigned long)pskb
->data
;
80 alignment
= tmpaddr
& (RECVBUFF_ALIGN_SZ
-1);
81 skb_reserve(pskb
, (RECVBUFF_ALIGN_SZ
- alignment
));
83 skb_queue_tail(&precvpriv
->free_recv_skb_queue
, pskb
);
93 void rtl8723au_free_recv_priv(struct rtw_adapter
*padapter
)
96 struct recv_buf
*precvbuf
;
97 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
99 precvbuf
= (struct recv_buf
*)precvpriv
->precv_buf
;
101 for (i
= 0; i
< NR_RECVBUFF
; i
++) {
102 usb_free_urb(precvbuf
->purb
);
105 dev_kfree_skb_any(precvbuf
->pskb
);
110 kfree(precvpriv
->precv_buf
);
112 usb_free_urb(precvpriv
->int_in_urb
);
113 kfree(precvpriv
->int_in_buf
);
115 if (skb_queue_len(&precvpriv
->rx_skb_queue
))
116 DBG_8723A(KERN_WARNING
"rx_skb_queue not empty\n");
118 skb_queue_purge(&precvpriv
->rx_skb_queue
);
120 if (skb_queue_len(&precvpriv
->free_recv_skb_queue
)) {
121 DBG_8723A(KERN_WARNING
"free_recv_skb_queue not empty, %d\n",
122 skb_queue_len(&precvpriv
->free_recv_skb_queue
));
125 skb_queue_purge(&precvpriv
->free_recv_skb_queue
);
128 struct recv_stat_cpu
{
137 void update_recvframe_attrib(struct recv_frame
*precvframe
,
138 struct recv_stat
*prxstat
)
140 struct rx_pkt_attrib
*pattrib
;
141 struct recv_stat_cpu report
;
142 struct rxreport_8723a
*prxreport
;
144 report
.rxdw0
= le32_to_cpu(prxstat
->rxdw0
);
145 report
.rxdw1
= le32_to_cpu(prxstat
->rxdw1
);
146 report
.rxdw2
= le32_to_cpu(prxstat
->rxdw2
);
147 report
.rxdw3
= le32_to_cpu(prxstat
->rxdw3
);
148 report
.rxdw4
= le32_to_cpu(prxstat
->rxdw4
);
149 report
.rxdw5
= le32_to_cpu(prxstat
->rxdw5
);
151 prxreport
= (struct rxreport_8723a
*)&report
;
153 pattrib
= &precvframe
->attrib
;
154 memset(pattrib
, 0, sizeof(struct rx_pkt_attrib
));
156 /* update rx report to recv_frame attribute */
157 pattrib
->pkt_len
= (u16
)prxreport
->pktlen
;
158 pattrib
->drvinfo_sz
= (u8
)(prxreport
->drvinfosize
<< 3);
159 pattrib
->physt
= (u8
)prxreport
->physt
;
161 pattrib
->crc_err
= (u8
)prxreport
->crc32
;
162 pattrib
->icv_err
= (u8
)prxreport
->icverr
;
164 pattrib
->bdecrypted
= (u8
)(prxreport
->swdec
? 0 : 1);
165 pattrib
->encrypt
= (u8
)prxreport
->security
;
167 pattrib
->qos
= (u8
)prxreport
->qos
;
168 pattrib
->priority
= (u8
)prxreport
->tid
;
170 pattrib
->amsdu
= (u8
)prxreport
->amsdu
;
172 pattrib
->seq_num
= (u16
)prxreport
->seq
;
173 pattrib
->frag_num
= (u8
)prxreport
->frag
;
174 pattrib
->mfrag
= (u8
)prxreport
->mf
;
175 pattrib
->mdata
= (u8
)prxreport
->md
;
177 pattrib
->mcs_rate
= (u8
)prxreport
->rxmcs
;
178 pattrib
->rxht
= (u8
)prxreport
->rxht
;
181 void update_recvframe_phyinfo(struct recv_frame
*precvframe
,
182 struct phy_stat
*pphy_status
)
184 struct rtw_adapter
*padapter
= precvframe
->adapter
;
185 struct rx_pkt_attrib
*pattrib
= &precvframe
->attrib
;
186 struct hal_data_8723a
*pHalData
= GET_HAL_DATA(padapter
);
187 struct phy_info
*pPHYInfo
= &pattrib
->phy_info
;
188 struct odm_packet_info pkt_info
;
190 struct sta_priv
*pstapriv
;
191 struct sta_info
*psta
;
192 struct sk_buff
*skb
= precvframe
->pkt
;
193 struct ieee80211_hdr
*hdr
= (struct ieee80211_hdr
*) skb
->data
;
194 bool matchbssid
= false;
197 matchbssid
= !ieee80211_is_ctl(hdr
->frame_control
) &&
198 !pattrib
->icv_err
&& !pattrib
->crc_err
;
201 switch (hdr
->frame_control
&
202 cpu_to_le16(IEEE80211_FCTL_TODS
|
203 IEEE80211_FCTL_FROMDS
)) {
204 case cpu_to_le16(IEEE80211_FCTL_TODS
):
207 case cpu_to_le16(IEEE80211_FCTL_FROMDS
):
219 matchbssid
= ether_addr_equal(
220 get_bssid(&padapter
->mlmepriv
), bssid
);
223 pkt_info
.bPacketMatchBSSID
= matchbssid
;
225 da
= ieee80211_get_DA(hdr
);
226 pkt_info
.bPacketToSelf
= pkt_info
.bPacketMatchBSSID
&&
227 (!memcmp(da
, myid(&padapter
->eeprompriv
), ETH_ALEN
));
229 pkt_info
.bPacketBeacon
= pkt_info
.bPacketMatchBSSID
&&
230 ieee80211_is_beacon(hdr
->frame_control
);
232 pkt_info
.StationID
= 0xFF;
233 if (pkt_info
.bPacketBeacon
) {
234 if (check_fwstate(&padapter
->mlmepriv
, WIFI_STATION_STATE
) == true)
235 sa
= padapter
->mlmepriv
.cur_network
.network
.MacAddress
;
238 sa
= ieee80211_get_SA(hdr
);
241 pstapriv
= &padapter
->stapriv
;
242 psta
= rtw_get_stainfo23a(pstapriv
, sa
);
244 pkt_info
.StationID
= psta
->mac_id
;
245 /* printk("%s ==> StationID(%d)\n", __func__, pkt_info.StationID); */
247 pkt_info
.Rate
= pattrib
->mcs_rate
;
249 ODM_PhyStatusQuery23a(&pHalData
->odmpriv
, pPHYInfo
,
250 (u8
*)pphy_status
, &pkt_info
);
251 precvframe
->psta
= NULL
;
252 if (pkt_info
.bPacketMatchBSSID
&&
253 (check_fwstate(&padapter
->mlmepriv
, WIFI_AP_STATE
) == true)) {
255 precvframe
->psta
= psta
;
256 rtl8723a_process_phy_info(padapter
, precvframe
);
258 } else if (pkt_info
.bPacketToSelf
|| pkt_info
.bPacketBeacon
) {
259 if (check_fwstate(&padapter
->mlmepriv
,
260 WIFI_ADHOC_STATE
|WIFI_ADHOC_MASTER_STATE
) ==
263 precvframe
->psta
= psta
;
265 rtl8723a_process_phy_info(padapter
, precvframe
);
This page took 0.036888 seconds and 5 git commands to generate.