1 /******************************************************************************
4 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
5 * Linux device driver for RTL8192SU
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * You should have received a copy of the GNU General Public License along with
17 * this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
20 * Modifications for inclusion into the Linux staging tree are
21 * Copyright(c) 2010 Larry Finger. All rights reserved.
23 * Contact information:
24 * WLAN FAE <wlanfae@realtek.com>.
25 * Larry Finger <Larry.Finger@lwfinger.net>
27 ******************************************************************************/
29 #define _RECV_OSDEP_C_
31 #include "osdep_service.h"
32 #include "drv_types.h"
34 #include "recv_osdep.h"
35 #include "osdep_intf.h"
38 /*init os related resource in struct recv_priv*/
39 /*alloc os related resource in union recv_frame*/
40 int r8712_os_recv_resource_alloc(struct _adapter
*padapter
,
41 union recv_frame
*precvframe
)
43 precvframe
->u
.hdr
.pkt_newalloc
= precvframe
->u
.hdr
.pkt
= NULL
;
47 /*alloc os related resource in struct recv_buf*/
48 int r8712_os_recvbuf_resource_alloc(struct _adapter
*padapter
,
49 struct recv_buf
*precvbuf
)
53 precvbuf
->irp_pending
= false;
54 precvbuf
->purb
= _usb_alloc_urb(0, GFP_KERNEL
);
55 if (precvbuf
->purb
== NULL
)
57 precvbuf
->pskb
= NULL
;
58 precvbuf
->reuse
= false;
59 precvbuf
->pallocated_buf
= NULL
;
60 precvbuf
->pbuf
= NULL
;
61 precvbuf
->pdata
= NULL
;
62 precvbuf
->phead
= NULL
;
63 precvbuf
->ptail
= NULL
;
64 precvbuf
->pend
= NULL
;
65 precvbuf
->transfer_len
= 0;
70 /*free os related resource in struct recv_buf*/
71 int r8712_os_recvbuf_resource_free(struct _adapter
*padapter
,
72 struct recv_buf
*precvbuf
)
75 dev_kfree_skb_any(precvbuf
->pskb
);
77 usb_kill_urb(precvbuf
->purb
);
78 usb_free_urb(precvbuf
->purb
);
83 void r8712_handle_tkip_mic_err(struct _adapter
*padapter
, u8 bgroup
)
85 union iwreq_data wrqu
;
86 struct iw_michaelmicfailure ev
;
87 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
89 memset(&ev
, 0x00, sizeof(ev
));
91 ev
.flags
|= IW_MICFAILURE_GROUP
;
93 ev
.flags
|= IW_MICFAILURE_PAIRWISE
;
94 ev
.src_addr
.sa_family
= ARPHRD_ETHER
;
95 memcpy(ev
.src_addr
.sa_data
, &pmlmepriv
->assoc_bssid
[0], ETH_ALEN
);
96 memset(&wrqu
, 0x00, sizeof(wrqu
));
97 wrqu
.data
.length
= sizeof(ev
);
98 wireless_send_event(padapter
->pnetdev
, IWEVMICHAELMICFAILURE
, &wrqu
,
102 void r8712_recv_indicatepkt(struct _adapter
*padapter
,
103 union recv_frame
*precv_frame
)
105 struct recv_priv
*precvpriv
;
106 struct __queue
*pfree_recv_queue
;
108 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
110 precvpriv
= &(padapter
->recvpriv
);
111 pfree_recv_queue
= &(precvpriv
->free_recv_queue
);
112 skb
= precv_frame
->u
.hdr
.pkt
;
114 goto _recv_indicatepkt_drop
;
115 skb
->data
= precv_frame
->u
.hdr
.rx_data
;
116 #ifdef NET_SKBUFF_DATA_USES_OFFSET
117 skb
->tail
= (sk_buff_data_t
)(precv_frame
->u
.hdr
.rx_tail
-
118 precv_frame
->u
.hdr
.rx_head
);
120 skb
->tail
= (sk_buff_data_t
)precv_frame
->u
.hdr
.rx_tail
;
122 skb
->len
= precv_frame
->u
.hdr
.len
;
123 if ((pattrib
->tcpchk_valid
== 1) && (pattrib
->tcp_chkrpt
== 1))
124 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
126 skb
->ip_summed
= CHECKSUM_NONE
;
127 skb
->dev
= padapter
->pnetdev
;
128 skb
->protocol
= eth_type_trans(skb
, padapter
->pnetdev
);
130 precv_frame
->u
.hdr
.pkt
= NULL
; /* pointers to NULL before
131 * r8712_free_recvframe() */
132 r8712_free_recvframe(precv_frame
, pfree_recv_queue
);
134 _recv_indicatepkt_drop
:
135 /*enqueue back to free_recv_queue*/
137 r8712_free_recvframe(precv_frame
, pfree_recv_queue
);
138 precvpriv
->rx_drop
++;
141 void r8712_os_read_port(struct _adapter
*padapter
, struct recv_buf
*precvbuf
)
143 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
146 /*free skb in recv_buf*/
147 dev_kfree_skb_any(precvbuf
->pskb
);
148 precvbuf
->pskb
= NULL
;
149 precvbuf
->reuse
= false;
150 if (precvbuf
->irp_pending
== false)
151 r8712_read_port(padapter
, precvpriv
->ff_hwaddr
, 0,
152 (unsigned char *)precvbuf
);
155 static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext
)
157 struct recv_reorder_ctrl
*preorder_ctrl
=
158 (struct recv_reorder_ctrl
*)FunctionContext
;
160 r8712_reordering_ctrl_timeout_handler(preorder_ctrl
);
163 void r8712_init_recv_timer(struct recv_reorder_ctrl
*preorder_ctrl
)
165 struct _adapter
*padapter
= preorder_ctrl
->padapter
;
167 _init_timer(&(preorder_ctrl
->reordering_ctrl_timer
), padapter
->pnetdev
,
168 _r8712_reordering_ctrl_timeout_handler
, preorder_ctrl
);