1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
4  *
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.
8  *
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
12  * more details.
13  *
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
17  *
18  *
19  ******************************************************************************/
20 #define _RECV_OSDEP_C_
21 
22 #include <osdep_service.h>
23 #include <drv_types.h>
24 
25 #include <wifi.h>
26 #include <recv_osdep.h>
27 
28 #include <osdep_intf.h>
29 #include <usb_ops_linux.h>
30 
31 /* alloc os related resource in struct recv_frame */
rtw_os_recv_resource_alloc(struct adapter * padapter,struct recv_frame * precvframe)32 int rtw_os_recv_resource_alloc(struct adapter *padapter,
33 			       struct recv_frame *precvframe)
34 {
35 	precvframe->pkt_newalloc = NULL;
36 	precvframe->pkt = NULL;
37 	return _SUCCESS;
38 }
39 
40 /* alloc os related resource in struct recv_buf */
rtw_os_recvbuf_resource_alloc(struct adapter * padapter,struct recv_buf * precvbuf)41 int rtw_os_recvbuf_resource_alloc(struct adapter *padapter,
42 				  struct recv_buf *precvbuf)
43 {
44 	int res = _SUCCESS;
45 
46 	precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
47 	if (precvbuf->purb == NULL)
48 		res = _FAIL;
49 	precvbuf->pskb = NULL;
50 	precvbuf->reuse = false;
51 	return res;
52 }
53 
rtw_handle_tkip_mic_err(struct adapter * padapter,u8 bgroup)54 void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup)
55 {
56 	union iwreq_data wrqu;
57 	struct iw_michaelmicfailure    ev;
58 	struct mlme_priv *pmlmepriv  = &padapter->mlmepriv;
59 	struct security_priv	*psecuritypriv = &padapter->securitypriv;
60 	u32 cur_time = 0;
61 
62 	if (psecuritypriv->last_mic_err_time == 0) {
63 		psecuritypriv->last_mic_err_time = jiffies;
64 	} else {
65 		cur_time = jiffies;
66 
67 		if (cur_time - psecuritypriv->last_mic_err_time < 60*HZ) {
68 			psecuritypriv->btkip_countermeasure = true;
69 			psecuritypriv->last_mic_err_time = 0;
70 			psecuritypriv->btkip_countermeasure_time = cur_time;
71 		} else {
72 			psecuritypriv->last_mic_err_time = jiffies;
73 		}
74 	}
75 
76 	memset(&ev, 0x00, sizeof(ev));
77 	if (bgroup)
78 		ev.flags |= IW_MICFAILURE_GROUP;
79 	else
80 		ev.flags |= IW_MICFAILURE_PAIRWISE;
81 
82 	ev.src_addr.sa_family = ARPHRD_ETHER;
83 	memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
84 	memset(&wrqu, 0x00, sizeof(wrqu));
85 	wrqu.data.length = sizeof(ev);
86 	wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE,
87 			    &wrqu, (char *)&ev);
88 }
89 
rtw_recv_indicatepkt(struct adapter * padapter,struct recv_frame * precv_frame)90 int rtw_recv_indicatepkt(struct adapter *padapter,
91 			 struct recv_frame *precv_frame)
92 {
93 	struct recv_priv *precvpriv;
94 	struct __queue *pfree_recv_queue;
95 	struct sk_buff *skb;
96 	struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
97 
98 
99 	precvpriv = &(padapter->recvpriv);
100 	pfree_recv_queue = &(precvpriv->free_recv_queue);
101 
102 	skb = precv_frame->pkt;
103 	if (skb == NULL) {
104 		RT_TRACE(_module_recv_osdep_c_, _drv_err_,
105 			 ("rtw_recv_indicatepkt():skb == NULL something wrong!!!!\n"));
106 		goto _recv_indicatepkt_drop;
107 	}
108 
109 	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
110 		 ("rtw_recv_indicatepkt():skb != NULL !!!\n"));
111 	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
112 		 ("rtw_recv_indicatepkt():precv_frame->rx_head =%p  precv_frame->hdr.rx_data =%p\n",
113 		 precv_frame->rx_head, precv_frame->rx_data));
114 	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
115 		 ("precv_frame->hdr.rx_tail =%p precv_frame->rx_end =%p precv_frame->hdr.len =%d\n",
116 		 precv_frame->rx_tail, precv_frame->rx_end,
117 		 precv_frame->len));
118 
119 	skb->data = precv_frame->rx_data;
120 
121 	skb_set_tail_pointer(skb, precv_frame->len);
122 
123 	skb->len = precv_frame->len;
124 
125 	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
126 		 ("skb->head =%p skb->data =%p skb->tail =%p skb->end =%p skb->len =%d\n",
127 		 skb->head, skb->data, skb_tail_pointer(skb),
128 		 skb_end_pointer(skb), skb->len));
129 
130 	if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
131 		struct sk_buff *pskb2 = NULL;
132 		struct sta_info *psta = NULL;
133 		struct sta_priv *pstapriv = &padapter->stapriv;
134 		struct rx_pkt_attrib *pattrib = &precv_frame->attrib;
135 		int bmcast = IS_MCAST(pattrib->dst);
136 
137 		if (memcmp(pattrib->dst, myid(&padapter->eeprompriv),
138 			   ETH_ALEN)) {
139 			if (bmcast) {
140 				psta = rtw_get_bcmc_stainfo(padapter);
141 				pskb2 = skb_clone(skb, GFP_ATOMIC);
142 			} else {
143 				psta = rtw_get_stainfo(pstapriv, pattrib->dst);
144 			}
145 
146 			if (psta) {
147 				struct net_device *pnetdev;
148 
149 				pnetdev = (struct net_device *)padapter->pnetdev;
150 				skb->dev = pnetdev;
151 				skb_set_queue_mapping(skb, rtw_recv_select_queue(skb));
152 
153 				rtw_xmit_entry(skb, pnetdev);
154 
155 				if (bmcast)
156 					skb = pskb2;
157 				else
158 					goto _recv_indicatepkt_end;
159 			}
160 		}
161 	}
162 
163 	rcu_read_lock();
164 	rcu_dereference(padapter->pnetdev->rx_handler_data);
165 	rcu_read_unlock();
166 
167 	skb->ip_summed = CHECKSUM_NONE;
168 	skb->dev = padapter->pnetdev;
169 	skb->protocol = eth_type_trans(skb, padapter->pnetdev);
170 
171 	netif_rx(skb);
172 
173 _recv_indicatepkt_end:
174 
175 	/*  pointers to NULL before rtw_free_recvframe() */
176 	precv_frame->pkt = NULL;
177 
178 	rtw_free_recvframe(precv_frame, pfree_recv_queue);
179 
180 	RT_TRACE(_module_recv_osdep_c_, _drv_info_,
181 		 ("\n rtw_recv_indicatepkt :after netif_rx!!!!\n"));
182 
183 
184 	return _SUCCESS;
185 
186 _recv_indicatepkt_drop:
187 
188 	 /* enqueue back to free_recv_queue */
189 	rtw_free_recvframe(precv_frame, pfree_recv_queue);
190 
191 	 return _FAIL;
192 }
193 
rtw_init_recv_timer(struct recv_reorder_ctrl * preorder_ctrl)194 void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
195 {
196 
197 	setup_timer(&preorder_ctrl->reordering_ctrl_timer,
198 		    rtw_reordering_ctrl_timeout_handler,
199 		    (unsigned long)preorder_ctrl);
200 }
201