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 <linux/usb.h>
33 #include "osdep_service.h"
34 #include "drv_types.h"
36 #include "recv_osdep.h"
37 #include "osdep_intf.h"
39 #include <linux/if_arp.h>
42 /*init os related resource in struct recv_priv*/
43 /*alloc os related resource in union recv_frame*/
44 int r8712_os_recv_resource_alloc(struct _adapter
*padapter
,
45 union recv_frame
*precvframe
)
47 precvframe
->u
.hdr
.pkt_newalloc
= precvframe
->u
.hdr
.pkt
= NULL
;
51 /*alloc os related resource in struct recv_buf*/
52 int r8712_os_recvbuf_resource_alloc(struct _adapter
*padapter
,
53 struct recv_buf
*precvbuf
)
57 precvbuf
->irp_pending
= false;
58 precvbuf
->purb
= usb_alloc_urb(0, GFP_KERNEL
);
59 if (precvbuf
->purb
== NULL
)
61 precvbuf
->pskb
= NULL
;
62 precvbuf
->reuse
= false;
63 precvbuf
->pallocated_buf
= NULL
;
64 precvbuf
->pbuf
= NULL
;
65 precvbuf
->pdata
= NULL
;
66 precvbuf
->phead
= NULL
;
67 precvbuf
->ptail
= NULL
;
68 precvbuf
->pend
= NULL
;
69 precvbuf
->transfer_len
= 0;
74 /*free os related resource in struct recv_buf*/
75 int r8712_os_recvbuf_resource_free(struct _adapter
*padapter
,
76 struct recv_buf
*precvbuf
)
79 dev_kfree_skb_any(precvbuf
->pskb
);
81 usb_kill_urb(precvbuf
->purb
);
82 usb_free_urb(precvbuf
->purb
);
87 void r8712_handle_tkip_mic_err(struct _adapter
*padapter
, u8 bgroup
)
89 union iwreq_data wrqu
;
90 struct iw_michaelmicfailure ev
;
91 struct mlme_priv
*pmlmepriv
= &padapter
->mlmepriv
;
93 memset(&ev
, 0x00, sizeof(ev
));
95 ev
.flags
|= IW_MICFAILURE_GROUP
;
97 ev
.flags
|= IW_MICFAILURE_PAIRWISE
;
98 ev
.src_addr
.sa_family
= ARPHRD_ETHER
;
99 memcpy(ev
.src_addr
.sa_data
, &pmlmepriv
->assoc_bssid
[0], ETH_ALEN
);
100 memset(&wrqu
, 0x00, sizeof(wrqu
));
101 wrqu
.data
.length
= sizeof(ev
);
102 wireless_send_event(padapter
->pnetdev
, IWEVMICHAELMICFAILURE
, &wrqu
,
106 void r8712_recv_indicatepkt(struct _adapter
*padapter
,
107 union recv_frame
*precv_frame
)
109 struct recv_priv
*precvpriv
;
110 struct __queue
*pfree_recv_queue
;
112 struct rx_pkt_attrib
*pattrib
= &precv_frame
->u
.hdr
.attrib
;
114 precvpriv
= &(padapter
->recvpriv
);
115 pfree_recv_queue
= &(precvpriv
->free_recv_queue
);
116 skb
= precv_frame
->u
.hdr
.pkt
;
118 goto _recv_indicatepkt_drop
;
119 skb
->data
= precv_frame
->u
.hdr
.rx_data
;
120 #ifdef NET_SKBUFF_DATA_USES_OFFSET
121 skb
->tail
= (sk_buff_data_t
)(precv_frame
->u
.hdr
.rx_tail
-
122 precv_frame
->u
.hdr
.rx_head
);
124 skb
->tail
= (sk_buff_data_t
)precv_frame
->u
.hdr
.rx_tail
;
126 skb
->len
= precv_frame
->u
.hdr
.len
;
127 if ((pattrib
->tcpchk_valid
== 1) && (pattrib
->tcp_chkrpt
== 1))
128 skb
->ip_summed
= CHECKSUM_UNNECESSARY
;
130 skb
->ip_summed
= CHECKSUM_NONE
;
131 skb
->dev
= padapter
->pnetdev
;
132 skb
->protocol
= eth_type_trans(skb
, padapter
->pnetdev
);
134 precv_frame
->u
.hdr
.pkt
= NULL
; /* pointers to NULL before
135 * r8712_free_recvframe() */
136 r8712_free_recvframe(precv_frame
, pfree_recv_queue
);
138 _recv_indicatepkt_drop
:
139 /*enqueue back to free_recv_queue*/
141 r8712_free_recvframe(precv_frame
, pfree_recv_queue
);
142 precvpriv
->rx_drop
++;
145 void r8712_os_read_port(struct _adapter
*padapter
, struct recv_buf
*precvbuf
)
147 struct recv_priv
*precvpriv
= &padapter
->recvpriv
;
150 /*free skb in recv_buf*/
151 dev_kfree_skb_any(precvbuf
->pskb
);
152 precvbuf
->pskb
= NULL
;
153 precvbuf
->reuse
= false;
154 if (precvbuf
->irp_pending
== false)
155 r8712_read_port(padapter
, precvpriv
->ff_hwaddr
, 0,
156 (unsigned char *)precvbuf
);
159 static void _r8712_reordering_ctrl_timeout_handler (void *FunctionContext
)
161 struct recv_reorder_ctrl
*preorder_ctrl
=
162 (struct recv_reorder_ctrl
*)FunctionContext
;
164 r8712_reordering_ctrl_timeout_handler(preorder_ctrl
);
167 void r8712_init_recv_timer(struct recv_reorder_ctrl
*preorder_ctrl
)
169 struct _adapter
*padapter
= preorder_ctrl
->padapter
;
171 _init_timer(&(preorder_ctrl
->reordering_ctrl_timer
), padapter
->pnetdev
,
172 _r8712_reordering_ctrl_timeout_handler
, preorder_ctrl
);