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 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 ******************************************************************************/
20 #define _RECV_OSDEP_C_
23 #include <osdep_service.h>
24 #include <drv_types.h>
27 #include <recv_osdep.h>
29 #include <osdep_intf.h>
36 //init os related resource in struct recv_priv
37 int rtw_os_recv_resource_init(struct recv_priv
*precvpriv
, _adapter
*padapter
)
44 //alloc os related resource in union recv_frame
45 int rtw_os_recv_resource_alloc(_adapter
*padapter
, union recv_frame
*precvframe
)
49 precvframe
->u
.hdr
.pkt_newalloc
= precvframe
->u
.hdr
.pkt
= NULL
;
55 //free os related resource in union recv_frame
56 void rtw_os_recv_resource_free(struct recv_priv
*precvpriv
)
62 //alloc os related resource in struct recv_buf
63 int rtw_os_recvbuf_resource_alloc(_adapter
*padapter
, struct recv_buf
*precvbuf
)
68 struct dvobj_priv
*pdvobjpriv
= adapter_to_dvobj(padapter
);
69 struct usb_device
*pusbd
= pdvobjpriv
->pusbdev
;
71 precvbuf
->irp_pending
= _FALSE
;
72 precvbuf
->purb
= usb_alloc_urb(0, GFP_KERNEL
);
73 if(precvbuf
->purb
== NULL
){
77 precvbuf
->pskb
= NULL
;
79 precvbuf
->reuse
= _FALSE
;
81 precvbuf
->pallocated_buf
= precvbuf
->pbuf
= NULL
;
83 precvbuf
->pdata
= precvbuf
->phead
= precvbuf
->ptail
= precvbuf
->pend
= NULL
;
85 precvbuf
->transfer_len
= 0;
89 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
90 precvbuf
->pallocated_buf
= rtw_usb_buffer_alloc(pusbd
, (size_t)precvbuf
->alloc_sz
, &precvbuf
->dma_transfer_addr
);
91 precvbuf
->pbuf
= precvbuf
->pallocated_buf
;
92 if(precvbuf
->pallocated_buf
== NULL
)
94 #endif //CONFIG_USE_USB_BUFFER_ALLOC_RX
96 #endif //CONFIG_USB_HCI
101 //free os related resource in struct recv_buf
102 int rtw_os_recvbuf_resource_free(_adapter
*padapter
, struct recv_buf
*precvbuf
)
106 #ifdef CONFIG_USB_HCI
108 #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
110 struct dvobj_priv
*pdvobjpriv
= adapter_to_dvobj(padapter
);
111 struct usb_device
*pusbd
= pdvobjpriv
->pusbdev
;
113 rtw_usb_buffer_free(pusbd
, (size_t)precvbuf
->alloc_sz
, precvbuf
->pallocated_buf
, precvbuf
->dma_transfer_addr
);
114 precvbuf
->pallocated_buf
= NULL
;
115 precvbuf
->dma_transfer_addr
= 0;
117 #endif //CONFIG_USE_USB_BUFFER_ALLOC_RX
121 //usb_kill_urb(precvbuf->purb);
122 usb_free_urb(precvbuf
->purb
);
125 #endif //CONFIG_USB_HCI
129 rtw_skb_free(precvbuf
->pskb
);
136 void rtw_handle_tkip_mic_err(_adapter
*padapter
,u8 bgroup
)
138 #ifdef CONFIG_IOCTL_CFG80211
139 enum nl80211_key_type key_type
= 0;
141 union iwreq_data wrqu
;
142 struct iw_michaelmicfailure ev
;
143 struct mlme_priv
* pmlmepriv
= &padapter
->mlmepriv
;
144 struct security_priv
*psecuritypriv
= &padapter
->securitypriv
;
147 if( psecuritypriv
->last_mic_err_time
== 0 )
149 psecuritypriv
->last_mic_err_time
= rtw_get_current_time();
153 cur_time
= rtw_get_current_time();
155 if( cur_time
- psecuritypriv
->last_mic_err_time
< 60*HZ
)
157 psecuritypriv
->btkip_countermeasure
= _TRUE
;
158 psecuritypriv
->last_mic_err_time
= 0;
159 psecuritypriv
->btkip_countermeasure_time
= cur_time
;
163 psecuritypriv
->last_mic_err_time
= rtw_get_current_time();
167 #ifdef CONFIG_IOCTL_CFG80211
170 key_type
|= NL80211_KEYTYPE_GROUP
;
174 key_type
|= NL80211_KEYTYPE_PAIRWISE
;
177 cfg80211_michael_mic_failure(padapter
->pnetdev
, (u8
*)&pmlmepriv
->assoc_bssid
[ 0 ], key_type
, -1,
181 _rtw_memset( &ev
, 0x00, sizeof( ev
) );
184 ev
.flags
|= IW_MICFAILURE_GROUP
;
188 ev
.flags
|= IW_MICFAILURE_PAIRWISE
;
191 ev
.src_addr
.sa_family
= ARPHRD_ETHER
;
192 _rtw_memcpy( ev
.src_addr
.sa_data
, &pmlmepriv
->assoc_bssid
[ 0 ], ETH_ALEN
);
194 _rtw_memset( &wrqu
, 0x00, sizeof( wrqu
) );
195 wrqu
.data
.length
= sizeof( ev
);
197 wireless_send_event( padapter
->pnetdev
, IWEVMICHAELMICFAILURE
, &wrqu
, (char*) &ev
);
200 void rtw_hostapd_mlme_rx(_adapter
*padapter
, union recv_frame
*precv_frame
)
202 #ifdef CONFIG_HOSTAPD_MLME
204 struct hostapd_priv
*phostapdpriv
= padapter
->phostapdpriv
;
205 struct net_device
*pmgnt_netdev
= phostapdpriv
->pmgnt_netdev
;
207 RT_TRACE(_module_recv_osdep_c_
, _drv_info_
, ("+rtw_hostapd_mlme_rx\n"));
209 skb
= precv_frame
->u
.hdr
.pkt
;
214 skb
->data
= precv_frame
->u
.hdr
.rx_data
;
215 skb
->tail
= precv_frame
->u
.hdr
.rx_tail
;
216 skb
->len
= precv_frame
->u
.hdr
.len
;
218 //pskb_copy = rtw_skb_copy(skb);
219 // if(skb == NULL) goto _exit;
221 skb
->dev
= pmgnt_netdev
;
222 skb
->ip_summed
= CHECKSUM_NONE
;
223 skb
->pkt_type
= PACKET_OTHERHOST
;
224 //skb->protocol = __constant_htons(0x0019); /*ETH_P_80211_RAW*/
225 skb
->protocol
= __constant_htons(0x0003); /*ETH_P_80211_RAW*/
227 //DBG_871X("(1)data=0x%x, head=0x%x, tail=0x%x, mac_header=0x%x, len=%d\n", skb->data, skb->head, skb->tail, skb->mac_header, skb->len);
229 //skb->mac.raw = skb->data;
230 skb_reset_mac_header(skb
);
233 _rtw_memset(skb
->cb
, 0, sizeof(skb
->cb
));
235 rtw_netif_rx(pmgnt_netdev
, skb
);
237 precv_frame
->u
.hdr
.pkt
= NULL
; // set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx()
241 int rtw_recv_indicatepkt(_adapter
*padapter
, union recv_frame
*precv_frame
)
243 struct recv_priv
*precvpriv
;
244 _queue
*pfree_recv_queue
;
246 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
247 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
248 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
252 void *br_port
= NULL
;
257 precvpriv
= &(padapter
->recvpriv
);
258 pfree_recv_queue
= &(precvpriv
->free_recv_queue
);
260 #ifdef CONFIG_DRVEXT_MODULE
261 if (drvext_rx_handler(padapter
, precv_frame
->u
.hdr
.rx_data
, precv_frame
->u
.hdr
.len
) == _SUCCESS
)
263 goto _recv_indicatepkt_drop
;
267 skb
= precv_frame
->u
.hdr
.pkt
;
270 RT_TRACE(_module_recv_osdep_c_
,_drv_err_
,("rtw_recv_indicatepkt():skb==NULL something wrong!!!!\n"));
271 goto _recv_indicatepkt_drop
;
274 RT_TRACE(_module_recv_osdep_c_
,_drv_info_
,("rtw_recv_indicatepkt():skb != NULL !!!\n"));
275 RT_TRACE(_module_recv_osdep_c_
,_drv_info_
,("rtw_recv_indicatepkt():precv_frame->u.hdr.rx_head=%p precv_frame->hdr.rx_data=%p\n", precv_frame
->u
.hdr
.rx_head
, precv_frame
->u
.hdr
.rx_data
));
276 RT_TRACE(_module_recv_osdep_c_
,_drv_info_
,("precv_frame->hdr.rx_tail=%p precv_frame->u.hdr.rx_end=%p precv_frame->hdr.len=%d \n", precv_frame
->u
.hdr
.rx_tail
, precv_frame
->u
.hdr
.rx_end
, precv_frame
->u
.hdr
.len
));
278 skb
->data
= precv_frame
->u
.hdr
.rx_data
;
280 skb_set_tail_pointer(skb
, precv_frame
->u
.hdr
.len
);
282 skb
->len
= precv_frame
->u
.hdr
.len
;
284 RT_TRACE(_module_recv_osdep_c_
,_drv_info_
,("\n skb->head=%p skb->data=%p skb->tail=%p skb->end=%p skb->len=%d\n", skb
->head
, skb
->data
, skb
->tail
, skb
->end
, skb
->len
));
286 if(check_fwstate(pmlmepriv
, WIFI_AP_STATE
) == _TRUE
)
289 struct sta_info
*psta
= NULL
;
290 struct sta_priv
*pstapriv
= &padapter
->stapriv
;
291 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
292 int bmcast
= IS_MCAST(pattrib
->dst
);
294 //DBG_871X("bmcast=%d\n", bmcast);
296 if(_rtw_memcmp(pattrib
->dst
, myid(&padapter
->eeprompriv
), ETH_ALEN
)==_FALSE
)
298 //DBG_871X("not ap psta=%p, addr=%pM\n", psta, pattrib->dst);
302 psta
= rtw_get_bcmc_stainfo(padapter
);
303 pskb2
= rtw_skb_clone(skb
);
305 psta
= rtw_get_stainfo(pstapriv
, pattrib
->dst
);
310 struct net_device
*pnetdev
= (struct net_device
*)padapter
->pnetdev
;
312 //DBG_871X("directly forwarding to the rtw_xmit_entry\n");
314 //skb->ip_summed = CHECKSUM_NONE;
316 #if (LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35))
317 skb_set_queue_mapping(skb
, rtw_recv_select_queue(skb
));
318 #endif //LINUX_VERSION_CODE>=KERNEL_VERSION(2,6,35)
320 _rtw_xmit_entry(skb
, pnetdev
);
325 goto _recv_indicatepkt_end
;
332 //DBG_871X("to APSelf\n");
339 #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
340 br_port
= padapter
->pnetdev
->br_port
;
341 #else // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
343 br_port
= rcu_dereference(padapter
->pnetdev
->rx_handler_data
);
345 #endif // (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
347 if( br_port
&& (check_fwstate(pmlmepriv
, WIFI_STATION_STATE
|WIFI_ADHOC_STATE
) == _TRUE
) )
349 int nat25_handle_frame(_adapter
*priv
, struct sk_buff
*skb
);
350 if (nat25_handle_frame(padapter
, skb
) == -1) {
351 //priv->ext_stats.rx_data_drops++;
352 //DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n");
355 // bypass this frame to upper layer!!
357 goto _recv_indicatepkt_drop
;
362 #endif // CONFIG_BR_EXT
365 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
366 if ( (pattrib
->tcpchk_valid
== 1) && (pattrib
->tcp_chkrpt
== 1) ) {
367 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
368 //DBG_871X("CHECKSUM_UNNECESSARY \n");
370 skb
->ip_summed
= CHECKSUM_NONE
;
371 //DBG_871X("CHECKSUM_NONE(%d, %d) \n", pattrib->tcpchk_valid, pattrib->tcp_chkrpt);
373 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
375 skb
->ip_summed
= CHECKSUM_NONE
;
379 skb
->dev
= padapter
->pnetdev
;
380 skb
->protocol
= eth_type_trans(skb
, padapter
->pnetdev
);
382 rtw_netif_rx(padapter
->pnetdev
, skb
);
384 _recv_indicatepkt_end
:
386 precv_frame
->u
.hdr
.pkt
= NULL
; // pointers to NULL before rtw_free_recvframe()
388 rtw_free_recvframe(precv_frame
, pfree_recv_queue
);
390 RT_TRACE(_module_recv_osdep_c_
,_drv_info_
,("\n rtw_recv_indicatepkt :after rtw_netif_rx!!!!\n"));
396 _recv_indicatepkt_drop
:
398 //enqueue back to free_recv_queue
400 rtw_free_recvframe(precv_frame
, pfree_recv_queue
);
408 void rtw_os_read_port(_adapter
*padapter
, struct recv_buf
*precvbuf
)
410 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
412 #ifdef CONFIG_USB_HCI
416 //free skb in recv_buf
417 rtw_skb_free(precvbuf
->pskb
);
419 precvbuf
->pskb
= NULL
;
420 precvbuf
->reuse
= _FALSE
;
422 if(precvbuf
->irp_pending
== _FALSE
)
424 rtw_read_port(padapter
, precvpriv
->ff_hwaddr
, 0, (unsigned char *)precvbuf
);
429 #ifdef CONFIG_SDIO_HCI
430 precvbuf
->pskb
= NULL
;
434 void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext
);
435 void _rtw_reordering_ctrl_timeout_handler (void *FunctionContext
)
437 struct recv_reorder_ctrl
*preorder_ctrl
= (struct recv_reorder_ctrl
*)FunctionContext
;
438 rtw_reordering_ctrl_timeout_handler(preorder_ctrl
);
441 void rtw_init_recv_timer(struct recv_reorder_ctrl
*preorder_ctrl
)
443 _adapter
*padapter
= preorder_ctrl
->padapter
;
445 _init_timer(&(preorder_ctrl
->reordering_ctrl_timer
), padapter
->pnetdev
, _rtw_reordering_ctrl_timeout_handler
, preorder_ctrl
);