1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3 *
4 * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
5 *
6 ******************************************************************************/
7 #define _RECV_OSDEP_C_
8
9 #include <drv_types.h>
10 #include <rtw_debug.h>
11 #include <linux/jiffies.h>
12 #include <net/cfg80211.h>
13 #include <asm/unaligned.h>
14
rtw_os_free_recvframe(union recv_frame * precvframe)15 void rtw_os_free_recvframe(union recv_frame *precvframe)
16 {
17 if (precvframe->u.hdr.pkt) {
18 dev_kfree_skb_any(precvframe->u.hdr.pkt);/* free skb by driver */
19
20 precvframe->u.hdr.pkt = NULL;
21 }
22 }
23
24 /* alloc os related resource in union recv_frame */
rtw_os_recv_resource_alloc(struct adapter * padapter,union recv_frame * precvframe)25 void rtw_os_recv_resource_alloc(struct adapter *padapter, union recv_frame *precvframe)
26 {
27 precvframe->u.hdr.pkt_newalloc = precvframe->u.hdr.pkt = NULL;
28 }
29
30 /* free os related resource in union recv_frame */
rtw_os_recv_resource_free(struct recv_priv * precvpriv)31 void rtw_os_recv_resource_free(struct recv_priv *precvpriv)
32 {
33 sint i;
34 union recv_frame *precvframe;
35
36 precvframe = (union recv_frame*) precvpriv->precv_frame_buf;
37
38 for (i = 0; i < NR_RECVFRAME; i++) {
39 if (precvframe->u.hdr.pkt) {
40 /* free skb by driver */
41 dev_kfree_skb_any(precvframe->u.hdr.pkt);
42 precvframe->u.hdr.pkt = NULL;
43 }
44 precvframe++;
45 }
46 }
47
48 /* free os related resource in struct recv_buf */
rtw_os_recvbuf_resource_free(struct adapter * padapter,struct recv_buf * precvbuf)49 void rtw_os_recvbuf_resource_free(struct adapter *padapter, struct recv_buf *precvbuf)
50 {
51 if (precvbuf->pskb) {
52 dev_kfree_skb_any(precvbuf->pskb);
53 }
54 }
55
rtw_os_alloc_msdu_pkt(union recv_frame * prframe,u16 nSubframe_Length,u8 * pdata)56 _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, u16 nSubframe_Length, u8 *pdata)
57 {
58 u16 eth_type;
59 _pkt *sub_skb;
60 struct rx_pkt_attrib *pattrib;
61
62 pattrib = &prframe->u.hdr.attrib;
63
64 sub_skb = rtw_skb_alloc(nSubframe_Length + 12);
65 if (!sub_skb) {
66 DBG_871X("%s(): rtw_skb_alloc() Fail!!!\n", __func__);
67 return NULL;
68 }
69
70 skb_reserve(sub_skb, 12);
71 skb_put_data(sub_skb, (pdata + ETH_HLEN), nSubframe_Length);
72
73 eth_type = get_unaligned_be16(&sub_skb->data[6]);
74
75 if (sub_skb->len >= 8 &&
76 ((!memcmp(sub_skb->data, rfc1042_header, SNAP_SIZE) &&
77 eth_type != ETH_P_AARP && eth_type != ETH_P_IPX) ||
78 !memcmp(sub_skb->data, bridge_tunnel_header, SNAP_SIZE))) {
79 /*
80 * remove RFC1042 or Bridge-Tunnel encapsulation and replace
81 * EtherType
82 */
83 skb_pull(sub_skb, SNAP_SIZE);
84 memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
85 memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
86 } else {
87 __be16 len;
88 /* Leave Ethernet header part of hdr and full payload */
89 len = htons(sub_skb->len);
90 memcpy(skb_push(sub_skb, 2), &len, 2);
91 memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->src, ETH_ALEN);
92 memcpy(skb_push(sub_skb, ETH_ALEN), pattrib->dst, ETH_ALEN);
93 }
94
95 return sub_skb;
96 }
97
rtw_os_recv_indicate_pkt(struct adapter * padapter,_pkt * pkt,struct rx_pkt_attrib * pattrib)98 void rtw_os_recv_indicate_pkt(struct adapter *padapter, _pkt *pkt, struct rx_pkt_attrib *pattrib)
99 {
100 struct mlme_priv*pmlmepriv = &padapter->mlmepriv;
101 int ret;
102
103 /* Indicate the packets to upper layer */
104 if (pkt) {
105 if (check_fwstate(pmlmepriv, WIFI_AP_STATE) == true) {
106 _pkt *pskb2 = NULL;
107 struct sta_info *psta = NULL;
108 struct sta_priv *pstapriv = &padapter->stapriv;
109 int bmcast = IS_MCAST(pattrib->dst);
110
111 if (memcmp(pattrib->dst, myid(&padapter->eeprompriv), ETH_ALEN)) {
112 if (bmcast) {
113 psta = rtw_get_bcmc_stainfo(padapter);
114 pskb2 = skb_clone(pkt, GFP_ATOMIC);
115 } else {
116 psta = rtw_get_stainfo(pstapriv, pattrib->dst);
117 }
118
119 if (psta) {
120 struct net_device *pnetdev = (struct net_device*)padapter->pnetdev;
121 /* skb->ip_summed = CHECKSUM_NONE; */
122 pkt->dev = pnetdev;
123 skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt));
124
125 _rtw_xmit_entry(pkt, pnetdev);
126
127 if (bmcast && (pskb2 != NULL)) {
128 pkt = pskb2;
129 DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast);
130 } else {
131 DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward);
132 return;
133 }
134 }
135 } else {
136 /* to APself */
137 /* DBG_871X("to APSelf\n"); */
138 DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self);
139 }
140 }
141
142 pkt->protocol = eth_type_trans(pkt, padapter->pnetdev);
143 pkt->dev = padapter->pnetdev;
144
145 #ifdef CONFIG_TCP_CSUM_OFFLOAD_RX
146 if ((pattrib->tcpchk_valid == 1) && (pattrib->tcp_chkrpt == 1))
147 pkt->ip_summed = CHECKSUM_UNNECESSARY;
148 else
149 pkt->ip_summed = CHECKSUM_NONE;
150
151 #else /* !CONFIG_TCP_CSUM_OFFLOAD_RX */
152 pkt->ip_summed = CHECKSUM_NONE;
153 #endif /* CONFIG_TCP_CSUM_OFFLOAD_RX */
154
155 ret = rtw_netif_rx(padapter->pnetdev, pkt);
156 if (ret == NET_RX_SUCCESS)
157 DBG_COUNTER(padapter->rx_logs.os_netif_ok);
158 else
159 DBG_COUNTER(padapter->rx_logs.os_netif_err);
160 }
161 }
162
rtw_handle_tkip_mic_err(struct adapter * padapter,u8 bgroup)163 void rtw_handle_tkip_mic_err(struct adapter *padapter, u8 bgroup)
164 {
165 enum nl80211_key_type key_type = 0;
166 union iwreq_data wrqu;
167 struct iw_michaelmicfailure ev;
168 struct mlme_priv* pmlmepriv = &padapter->mlmepriv;
169 struct security_priv *psecuritypriv = &padapter->securitypriv;
170 unsigned long cur_time = 0;
171
172 if (psecuritypriv->last_mic_err_time == 0) {
173 psecuritypriv->last_mic_err_time = jiffies;
174 } else {
175 cur_time = jiffies;
176
177 if (cur_time - psecuritypriv->last_mic_err_time < 60*HZ) {
178 psecuritypriv->btkip_countermeasure = true;
179 psecuritypriv->last_mic_err_time = 0;
180 psecuritypriv->btkip_countermeasure_time = cur_time;
181 } else {
182 psecuritypriv->last_mic_err_time = jiffies;
183 }
184 }
185
186 if (bgroup) {
187 key_type |= NL80211_KEYTYPE_GROUP;
188 } else {
189 key_type |= NL80211_KEYTYPE_PAIRWISE;
190 }
191
192 cfg80211_michael_mic_failure(padapter->pnetdev, (u8 *)&pmlmepriv->assoc_bssid[0], key_type, -1,
193 NULL, GFP_ATOMIC);
194
195 memset(&ev, 0x00, sizeof(ev));
196 if (bgroup) {
197 ev.flags |= IW_MICFAILURE_GROUP;
198 } else {
199 ev.flags |= IW_MICFAILURE_PAIRWISE;
200 }
201
202 ev.src_addr.sa_family = ARPHRD_ETHER;
203 memcpy(ev.src_addr.sa_data, &pmlmepriv->assoc_bssid[0], ETH_ALEN);
204
205 memset(&wrqu, 0x00, sizeof(wrqu));
206 wrqu.data.length = sizeof(ev);
207 }
208
209 #ifdef CONFIG_AUTO_AP_MODE
rtw_os_ksocket_send(struct adapter * padapter,union recv_frame * precv_frame)210 static void rtw_os_ksocket_send(struct adapter *padapter, union recv_frame *precv_frame)
211 {
212 _pkt *skb = precv_frame->u.hdr.pkt;
213 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
214 struct sta_info *psta = precv_frame->u.hdr.psta;
215
216 DBG_871X("eth rx: got eth_type = 0x%x\n", pattrib->eth_type);
217
218 if (psta && psta->isrc && psta->pid > 0) {
219 u16 rx_pid;
220
221 rx_pid = *(u16*)(skb->data+ETH_HLEN);
222
223 DBG_871X("eth rx(pid = 0x%x): sta("MAC_FMT") pid = 0x%x\n",
224 rx_pid, MAC_ARG(psta->hwaddr), psta->pid);
225
226 if (rx_pid == psta->pid) {
227 int i;
228 u16 len = *(u16 *)(skb->data+ETH_HLEN+2);
229 DBG_871X("eth, RC: len = 0x%x\n", len);
230
231 for (i = 0; i < len; i++)
232 DBG_871X("0x%x\n", *(skb->data+ETH_HLEN+4+i));
233
234 DBG_871X("eth, RC-end\n");
235 }
236
237 }
238
239 }
240 #endif /* CONFIG_AUTO_AP_MODE */
241
rtw_recv_indicatepkt(struct adapter * padapter,union recv_frame * precv_frame)242 int rtw_recv_indicatepkt(struct adapter *padapter, union recv_frame *precv_frame)
243 {
244 struct recv_priv *precvpriv;
245 struct __queue *pfree_recv_queue;
246 _pkt *skb;
247 struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
248
249 DBG_COUNTER(padapter->rx_logs.os_indicate);
250
251 precvpriv = &(padapter->recvpriv);
252 pfree_recv_queue = &(precvpriv->free_recv_queue);
253
254 skb = precv_frame->u.hdr.pkt;
255 if (skb == NULL) {
256 RT_TRACE(_module_recv_osdep_c_, _drv_err_, ("rtw_recv_indicatepkt():skb == NULL something wrong!!!!\n"));
257 goto _recv_indicatepkt_drop;
258 }
259
260 RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("rtw_recv_indicatepkt():skb != NULL !!!\n"));
261 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));
262 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));
263
264 skb->data = precv_frame->u.hdr.rx_data;
265
266 skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
267
268 skb->len = precv_frame->u.hdr.len;
269
270 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_pointer(skb), skb_end_pointer(skb), skb->len));
271
272 #ifdef CONFIG_AUTO_AP_MODE
273 if (0x8899 == pattrib->eth_type) {
274 rtw_os_ksocket_send(padapter, precv_frame);
275
276 /* goto _recv_indicatepkt_drop; */
277 }
278 #endif /* CONFIG_AUTO_AP_MODE */
279
280 rtw_os_recv_indicate_pkt(padapter, skb, pattrib);
281
282 /* pointers to NULL before rtw_free_recvframe() */
283 precv_frame->u.hdr.pkt = NULL;
284
285 rtw_free_recvframe(precv_frame, pfree_recv_queue);
286
287 RT_TRACE(_module_recv_osdep_c_, _drv_info_, ("\n rtw_recv_indicatepkt :after rtw_os_recv_indicate_pkt!!!!\n"));
288
289 return _SUCCESS;
290
291 _recv_indicatepkt_drop:
292
293 /* enqueue back to free_recv_queue */
294 rtw_free_recvframe(precv_frame, pfree_recv_queue);
295
296 DBG_COUNTER(padapter->rx_logs.os_indicate_err);
297 return _FAIL;
298 }
299
rtw_init_recv_timer(struct recv_reorder_ctrl * preorder_ctrl)300 void rtw_init_recv_timer(struct recv_reorder_ctrl *preorder_ctrl)
301 {
302 timer_setup(&preorder_ctrl->reordering_ctrl_timer,
303 rtw_reordering_ctrl_timeout_handler, 0);
304
305 }
306