recv_linux.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2017 Realtek Corporation.
  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. *****************************************************************************/
  15. #define _RECV_OSDEP_C_
  16. #include <drv_types.h>
  17. int rtw_os_recvframe_duplicate_skb(_adapter *padapter, union recv_frame *pcloneframe, _pkt *pskb)
  18. {
  19. int res = _SUCCESS;
  20. _pkt *pkt_copy = NULL;
  21. if (pskb == NULL) {
  22. RTW_INFO("%s [WARN] skb == NULL, drop frag frame\n", __func__);
  23. return _FAIL;
  24. }
  25. #if 1
  26. pkt_copy = rtw_skb_copy(pskb);
  27. if (pkt_copy == NULL) {
  28. RTW_INFO("%s [WARN] rtw_skb_copy fail , drop frag frame\n", __func__);
  29. return _FAIL;
  30. }
  31. #else
  32. pkt_copy = rtw_skb_clone(pskb);
  33. if (pkt_copy == NULL) {
  34. RTW_INFO("%s [WARN] rtw_skb_clone fail , drop frag frame\n", __func__);
  35. return _FAIL;
  36. }
  37. #endif
  38. pkt_copy->dev = padapter->pnetdev;
  39. pcloneframe->u.hdr.pkt = pkt_copy;
  40. pcloneframe->u.hdr.rx_head = pkt_copy->head;
  41. pcloneframe->u.hdr.rx_data = pkt_copy->data;
  42. pcloneframe->u.hdr.rx_end = skb_end_pointer(pkt_copy);
  43. pcloneframe->u.hdr.rx_tail = skb_tail_pointer(pkt_copy);
  44. pcloneframe->u.hdr.len = pkt_copy->len;
  45. return res;
  46. }
  47. int rtw_os_alloc_recvframe(_adapter *padapter, union recv_frame *precvframe, u8 *pdata, _pkt *pskb)
  48. {
  49. int res = _SUCCESS;
  50. u8 shift_sz = 0;
  51. u32 skb_len, alloc_sz;
  52. _pkt *pkt_copy = NULL;
  53. struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
  54. if (pdata == NULL) {
  55. precvframe->u.hdr.pkt = NULL;
  56. res = _FAIL;
  57. return res;
  58. }
  59. /* Modified by Albert 20101213 */
  60. /* For 8 bytes IP header alignment. */
  61. shift_sz = pattrib->qos ? 6 : 0; /* Qos data, wireless lan header length is 26 */
  62. skb_len = pattrib->pkt_len;
  63. /* for first fragment packet, driver need allocate 1536+drvinfo_sz+RXDESC_SIZE to defrag packet. */
  64. /* modify alloc_sz for recvive crc error packet by thomas 2011-06-02 */
  65. if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
  66. /* alloc_sz = 1664; */ /* 1664 is 128 alignment. */
  67. alloc_sz = (skb_len <= 1650) ? 1664 : (skb_len + 14);
  68. } else {
  69. alloc_sz = skb_len;
  70. /* 6 is for IP header 8 bytes alignment in QoS packet case. */
  71. /* 8 is for skb->data 4 bytes alignment. */
  72. alloc_sz += 14;
  73. }
  74. pkt_copy = rtw_skb_alloc(alloc_sz);
  75. if (pkt_copy) {
  76. pkt_copy->dev = padapter->pnetdev;
  77. pkt_copy->len = skb_len;
  78. precvframe->u.hdr.pkt = pkt_copy;
  79. precvframe->u.hdr.rx_head = pkt_copy->head;
  80. precvframe->u.hdr.rx_end = pkt_copy->data + alloc_sz;
  81. skb_reserve(pkt_copy, 8 - ((SIZE_PTR)(pkt_copy->data) & 7)); /* force pkt_copy->data at 8-byte alignment address */
  82. skb_reserve(pkt_copy, shift_sz);/* force ip_hdr at 8-byte alignment address according to shift_sz. */
  83. _rtw_memcpy(pkt_copy->data, pdata, skb_len);
  84. precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pkt_copy->data;
  85. } else {
  86. #if 0
  87. {
  88. rtw_free_recvframe(precvframe_if2, &precvpriv->free_recv_queue);
  89. rtw_enqueue_recvbuf_to_head(precvbuf, &precvpriv->recv_buf_pending_queue);
  90. /* The case of can't allocate skb is serious and may never be recovered,
  91. once bDriverStopped is enable, this task should be stopped.*/
  92. if (!rtw_is_drv_stopped(secondary_padapter))
  93. #ifdef PLATFORM_LINUX
  94. tasklet_schedule(&precvpriv->recv_tasklet);
  95. #endif
  96. return ret;
  97. }
  98. #endif
  99. #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
  100. RTW_INFO("%s:can not allocate memory for skb copy\n", __func__);
  101. precvframe->u.hdr.pkt = NULL;
  102. /* rtw_free_recvframe(precvframe, pfree_recv_queue); */
  103. /*exit_rtw_os_recv_resource_alloc;*/
  104. res = _FAIL;
  105. #else
  106. if ((pattrib->mfrag == 1) && (pattrib->frag_num == 0)) {
  107. RTW_INFO("%s: alloc_skb fail , drop frag frame\n", __FUNCTION__);
  108. /* rtw_free_recvframe(precvframe, pfree_recv_queue); */
  109. res = _FAIL;
  110. goto exit_rtw_os_recv_resource_alloc;
  111. }
  112. if (pskb == NULL) {
  113. res = _FAIL;
  114. goto exit_rtw_os_recv_resource_alloc;
  115. }
  116. precvframe->u.hdr.pkt = rtw_skb_clone(pskb);
  117. if (precvframe->u.hdr.pkt) {
  118. precvframe->u.hdr.pkt->dev = padapter->pnetdev;
  119. precvframe->u.hdr.rx_head = precvframe->u.hdr.rx_data = precvframe->u.hdr.rx_tail = pdata;
  120. precvframe->u.hdr.rx_end = pdata + alloc_sz;
  121. } else {
  122. RTW_INFO("%s: rtw_skb_clone fail\n", __FUNCTION__);
  123. /* rtw_free_recvframe(precvframe, pfree_recv_queue); */
  124. /*exit_rtw_os_recv_resource_alloc;*/
  125. res = _FAIL;
  126. }
  127. #endif
  128. }
  129. exit_rtw_os_recv_resource_alloc:
  130. return res;
  131. }
  132. void rtw_os_free_recvframe(union recv_frame *precvframe)
  133. {
  134. if (precvframe->u.hdr.pkt) {
  135. rtw_os_pkt_free(precvframe->u.hdr.pkt);
  136. precvframe->u.hdr.pkt = NULL;
  137. }
  138. }
  139. /* init os related resource in struct recv_priv */
  140. int rtw_os_recv_resource_init(struct recv_priv *precvpriv, _adapter *padapter)
  141. {
  142. int res = _SUCCESS;
  143. #ifdef CONFIG_RTW_NAPI
  144. skb_queue_head_init(&precvpriv->rx_napi_skb_queue);
  145. #endif /* CONFIG_RTW_NAPI */
  146. return res;
  147. }
  148. /* alloc os related resource in union recv_frame */
  149. int rtw_os_recv_resource_alloc(_adapter *padapter, union recv_frame *precvframe)
  150. {
  151. int res = _SUCCESS;
  152. precvframe->u.hdr.pkt = NULL;
  153. return res;
  154. }
  155. /* free os related resource in union recv_frame */
  156. void rtw_os_recv_resource_free(struct recv_priv *precvpriv)
  157. {
  158. sint i;
  159. union recv_frame *precvframe;
  160. precvframe = (union recv_frame *) precvpriv->precv_frame_buf;
  161. #ifdef CONFIG_RTW_NAPI
  162. if (skb_queue_len(&precvpriv->rx_napi_skb_queue))
  163. RTW_WARN("rx_napi_skb_queue not empty\n");
  164. rtw_skb_queue_purge(&precvpriv->rx_napi_skb_queue);
  165. #endif /* CONFIG_RTW_NAPI */
  166. for (i = 0; i < NR_RECVFRAME; i++) {
  167. rtw_os_free_recvframe(precvframe);
  168. precvframe++;
  169. }
  170. }
  171. /* alloc os related resource in struct recv_buf */
  172. int rtw_os_recvbuf_resource_alloc(_adapter *padapter, struct recv_buf *precvbuf)
  173. {
  174. int res = _SUCCESS;
  175. #ifdef CONFIG_USB_HCI
  176. #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
  177. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  178. struct usb_device *pusbd = pdvobjpriv->pusbdev;
  179. #endif
  180. precvbuf->irp_pending = _FALSE;
  181. precvbuf->purb = usb_alloc_urb(0, GFP_KERNEL);
  182. if (precvbuf->purb == NULL)
  183. res = _FAIL;
  184. precvbuf->pskb = NULL;
  185. precvbuf->pallocated_buf = precvbuf->pbuf = NULL;
  186. precvbuf->pdata = precvbuf->phead = precvbuf->ptail = precvbuf->pend = NULL;
  187. precvbuf->transfer_len = 0;
  188. precvbuf->len = 0;
  189. #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
  190. precvbuf->pallocated_buf = rtw_usb_buffer_alloc(pusbd, (size_t)precvbuf->alloc_sz, &precvbuf->dma_transfer_addr);
  191. precvbuf->pbuf = precvbuf->pallocated_buf;
  192. if (precvbuf->pallocated_buf == NULL)
  193. return _FAIL;
  194. #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
  195. #endif /* CONFIG_USB_HCI */
  196. return res;
  197. }
  198. /* free os related resource in struct recv_buf */
  199. int rtw_os_recvbuf_resource_free(_adapter *padapter, struct recv_buf *precvbuf)
  200. {
  201. int ret = _SUCCESS;
  202. #ifdef CONFIG_USB_HCI
  203. #ifdef CONFIG_USE_USB_BUFFER_ALLOC_RX
  204. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  205. struct usb_device *pusbd = pdvobjpriv->pusbdev;
  206. rtw_usb_buffer_free(pusbd, (size_t)precvbuf->alloc_sz, precvbuf->pallocated_buf, precvbuf->dma_transfer_addr);
  207. precvbuf->pallocated_buf = NULL;
  208. precvbuf->dma_transfer_addr = 0;
  209. #endif /* CONFIG_USE_USB_BUFFER_ALLOC_RX */
  210. if (precvbuf->purb) {
  211. /* usb_kill_urb(precvbuf->purb); */
  212. usb_free_urb(precvbuf->purb);
  213. }
  214. #endif /* CONFIG_USB_HCI */
  215. if (precvbuf->pskb) {
  216. #ifdef CONFIG_PREALLOC_RX_SKB_BUFFER
  217. if (rtw_free_skb_premem(precvbuf->pskb) != 0)
  218. #endif
  219. rtw_skb_free(precvbuf->pskb);
  220. }
  221. return ret;
  222. }
  223. _pkt *rtw_os_alloc_msdu_pkt(union recv_frame *prframe, const u8 *da, const u8 *sa, u8 *msdu ,u16 msdu_len)
  224. {
  225. u16 eth_type;
  226. u8 *data_ptr;
  227. _pkt *sub_skb;
  228. struct rx_pkt_attrib *pattrib;
  229. pattrib = &prframe->u.hdr.attrib;
  230. #ifdef CONFIG_SKB_COPY
  231. sub_skb = rtw_skb_alloc(msdu_len + 14);
  232. if (sub_skb) {
  233. skb_reserve(sub_skb, 14);
  234. data_ptr = (u8 *)skb_put(sub_skb, msdu_len);
  235. _rtw_memcpy(data_ptr, msdu, msdu_len);
  236. } else
  237. #endif /* CONFIG_SKB_COPY */
  238. {
  239. sub_skb = rtw_skb_clone(prframe->u.hdr.pkt);
  240. if (sub_skb) {
  241. sub_skb->data = msdu;
  242. sub_skb->len = msdu_len;
  243. skb_set_tail_pointer(sub_skb, msdu_len);
  244. } else {
  245. RTW_INFO("%s(): rtw_skb_clone() Fail!!!\n", __FUNCTION__);
  246. return NULL;
  247. }
  248. }
  249. eth_type = RTW_GET_BE16(&sub_skb->data[6]);
  250. if (sub_skb->len >= 8
  251. && ((_rtw_memcmp(sub_skb->data, rtw_rfc1042_header, SNAP_SIZE)
  252. && eth_type != ETH_P_AARP && eth_type != ETH_P_IPX)
  253. || _rtw_memcmp(sub_skb->data, rtw_bridge_tunnel_header, SNAP_SIZE))
  254. ) {
  255. /* remove RFC1042 or Bridge-Tunnel encapsulation and replace EtherType */
  256. skb_pull(sub_skb, SNAP_SIZE);
  257. _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), sa, ETH_ALEN);
  258. _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), da, ETH_ALEN);
  259. } else {
  260. /* Leave Ethernet header part of hdr and full payload */
  261. u16 len;
  262. len = htons(sub_skb->len);
  263. _rtw_memcpy(skb_push(sub_skb, 2), &len, 2);
  264. _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), sa, ETH_ALEN);
  265. _rtw_memcpy(skb_push(sub_skb, ETH_ALEN), da, ETH_ALEN);
  266. }
  267. return sub_skb;
  268. }
  269. #ifdef CONFIG_RTW_NAPI
  270. static int napi_recv(_adapter *padapter, int budget)
  271. {
  272. _pkt *pskb;
  273. struct recv_priv *precvpriv = &padapter->recvpriv;
  274. int work_done = 0;
  275. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  276. u8 rx_ok;
  277. while ((work_done < budget) &&
  278. (!skb_queue_empty(&precvpriv->rx_napi_skb_queue))) {
  279. pskb = skb_dequeue(&precvpriv->rx_napi_skb_queue);
  280. if (!pskb)
  281. break;
  282. rx_ok = _FALSE;
  283. #if defined(CONFIG_RTW_GRO) && LINUX_VERSION_CODE < KERNEL_VERSION(5, 12, 0)
  284. if (pregistrypriv->en_gro) {
  285. if (rtw_napi_gro_receive(&padapter->napi, pskb) != GRO_DROP)
  286. rx_ok = _TRUE;
  287. goto next;
  288. }
  289. #endif /* CONFIG_RTW_GRO */
  290. if (rtw_netif_receive_skb(padapter->pnetdev, pskb) == NET_RX_SUCCESS)
  291. rx_ok = _TRUE;
  292. next:
  293. if (rx_ok == _TRUE) {
  294. work_done++;
  295. DBG_COUNTER(padapter->rx_logs.os_netif_ok);
  296. } else {
  297. DBG_COUNTER(padapter->rx_logs.os_netif_err);
  298. }
  299. }
  300. return work_done;
  301. }
  302. int rtw_recv_napi_poll(struct napi_struct *napi, int budget)
  303. {
  304. _adapter *padapter = container_of(napi, _adapter, napi);
  305. int work_done = 0;
  306. struct recv_priv *precvpriv = &padapter->recvpriv;
  307. work_done = napi_recv(padapter, budget);
  308. if (work_done < budget) {
  309. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 19, 0)) && defined(CONFIG_PCI_HCI)
  310. napi_complete_done(napi, work_done);
  311. #else
  312. napi_complete(napi);
  313. #endif
  314. if (!skb_queue_empty(&precvpriv->rx_napi_skb_queue))
  315. napi_schedule(napi);
  316. }
  317. return work_done;
  318. }
  319. #ifdef CONFIG_RTW_NAPI_DYNAMIC
  320. void dynamic_napi_th_chk (_adapter *adapter)
  321. {
  322. if (adapter->registrypriv.en_napi) {
  323. struct dvobj_priv *dvobj;
  324. struct registry_priv *registry;
  325. dvobj = adapter_to_dvobj(adapter);
  326. registry = &adapter->registrypriv;
  327. if (dvobj->traffic_stat.cur_rx_tp > registry->napi_threshold)
  328. dvobj->en_napi_dynamic = 1;
  329. else
  330. dvobj->en_napi_dynamic = 0;
  331. }
  332. }
  333. #endif /* CONFIG_RTW_NAPI_DYNAMIC */
  334. #endif /* CONFIG_RTW_NAPI */
  335. void rtw_os_recv_indicate_pkt(_adapter *padapter, _pkt *pkt, union recv_frame *rframe)
  336. {
  337. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  338. struct recv_priv *precvpriv = &(padapter->recvpriv);
  339. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  340. #ifdef CONFIG_BR_EXT
  341. void *br_port = NULL;
  342. #endif
  343. int ret;
  344. /* Indicat the packets to upper layer */
  345. if (pkt) {
  346. struct ethhdr *ehdr = (struct ethhdr *)pkt->data;
  347. DBG_COUNTER(padapter->rx_logs.os_indicate);
  348. if (MLME_IS_AP(padapter)) {
  349. _pkt *pskb2 = NULL;
  350. struct sta_info *psta = NULL;
  351. struct sta_priv *pstapriv = &padapter->stapriv;
  352. int bmcast = IS_MCAST(ehdr->h_dest);
  353. /* RTW_INFO("bmcast=%d\n", bmcast); */
  354. if (_rtw_memcmp(ehdr->h_dest, adapter_mac_addr(padapter), ETH_ALEN) == _FALSE) {
  355. /* RTW_INFO("not ap psta=%p, addr=%pM\n", psta, ehdr->h_dest); */
  356. if (bmcast) {
  357. psta = rtw_get_bcmc_stainfo(padapter);
  358. pskb2 = rtw_skb_clone(pkt);
  359. } else
  360. psta = rtw_get_stainfo(pstapriv, ehdr->h_dest);
  361. if (psta) {
  362. struct net_device *pnetdev = (struct net_device *)padapter->pnetdev;
  363. /* RTW_INFO("directly forwarding to the rtw_xmit_entry\n"); */
  364. /* skb->ip_summed = CHECKSUM_NONE; */
  365. pkt->dev = pnetdev;
  366. #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35))
  367. skb_set_queue_mapping(pkt, rtw_recv_select_queue(pkt));
  368. #endif /* LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 35) */
  369. _rtw_xmit_entry(pkt, pnetdev);
  370. if (bmcast && (pskb2 != NULL)) {
  371. pkt = pskb2;
  372. DBG_COUNTER(padapter->rx_logs.os_indicate_ap_mcast);
  373. } else {
  374. DBG_COUNTER(padapter->rx_logs.os_indicate_ap_forward);
  375. return;
  376. }
  377. }
  378. } else { /* to APself */
  379. /* RTW_INFO("to APSelf\n"); */
  380. DBG_COUNTER(padapter->rx_logs.os_indicate_ap_self);
  381. }
  382. }
  383. #ifdef CONFIG_BR_EXT
  384. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE | WIFI_ADHOC_STATE) == _TRUE) {
  385. /* Insert NAT2.5 RX here! */
  386. #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2, 6, 35))
  387. br_port = padapter->pnetdev->br_port;
  388. #else
  389. rcu_read_lock();
  390. br_port = rcu_dereference(padapter->pnetdev->rx_handler_data);
  391. rcu_read_unlock();
  392. #endif
  393. if (br_port) {
  394. int nat25_handle_frame(_adapter *priv, struct sk_buff *skb);
  395. if (nat25_handle_frame(padapter, pkt) == -1) {
  396. /* priv->ext_stats.rx_data_drops++; */
  397. /* DEBUG_ERR("RX DROP: nat25_handle_frame fail!\n"); */
  398. /* return FAIL; */
  399. #if 1
  400. /* bypass this frame to upper layer!! */
  401. #else
  402. rtw_skb_free(sub_skb);
  403. continue;
  404. #endif
  405. }
  406. }
  407. }
  408. #endif /* CONFIG_BR_EXT */
  409. /* After eth_type_trans process , pkt->data pointer will move from ethrnet header to ip header */
  410. pkt->protocol = eth_type_trans(pkt, padapter->pnetdev);
  411. pkt->dev = padapter->pnetdev;
  412. pkt->ip_summed = CHECKSUM_NONE; /* CONFIG_TCP_CSUM_OFFLOAD_RX */
  413. #ifdef CONFIG_RTW_NAPI
  414. #ifdef CONFIG_RTW_NAPI_DYNAMIC
  415. if (!skb_queue_empty(&precvpriv->rx_napi_skb_queue)
  416. && !adapter_to_dvobj(padapter)->en_napi_dynamic
  417. )
  418. napi_recv(padapter, RTL_NAPI_WEIGHT);
  419. #endif
  420. if (pregistrypriv->en_napi
  421. #ifdef CONFIG_RTW_NAPI_DYNAMIC
  422. && adapter_to_dvobj(padapter)->en_napi_dynamic
  423. #endif
  424. ) {
  425. skb_queue_tail(&precvpriv->rx_napi_skb_queue, pkt);
  426. #ifndef CONFIG_RTW_NAPI_V2
  427. napi_schedule(&padapter->napi);
  428. #endif
  429. return;
  430. }
  431. #endif /* CONFIG_RTW_NAPI */
  432. ret = rtw_netif_rx(padapter->pnetdev, pkt);
  433. if (ret == NET_RX_SUCCESS)
  434. DBG_COUNTER(padapter->rx_logs.os_netif_ok);
  435. else
  436. DBG_COUNTER(padapter->rx_logs.os_netif_err);
  437. }
  438. }
  439. void rtw_handle_tkip_mic_err(_adapter *padapter, struct sta_info *sta, u8 bgroup)
  440. {
  441. #ifdef CONFIG_IOCTL_CFG80211
  442. enum nl80211_key_type key_type = 0;
  443. #endif
  444. union iwreq_data wrqu;
  445. struct iw_michaelmicfailure ev;
  446. struct security_priv *psecuritypriv = &padapter->securitypriv;
  447. systime cur_time = 0;
  448. if (psecuritypriv->last_mic_err_time == 0)
  449. psecuritypriv->last_mic_err_time = rtw_get_current_time();
  450. else {
  451. cur_time = rtw_get_current_time();
  452. if (cur_time - psecuritypriv->last_mic_err_time < 60 * HZ) {
  453. psecuritypriv->btkip_countermeasure = _TRUE;
  454. psecuritypriv->last_mic_err_time = 0;
  455. psecuritypriv->btkip_countermeasure_time = cur_time;
  456. } else
  457. psecuritypriv->last_mic_err_time = rtw_get_current_time();
  458. }
  459. #ifdef CONFIG_IOCTL_CFG80211
  460. if (bgroup)
  461. key_type |= NL80211_KEYTYPE_GROUP;
  462. else
  463. key_type |= NL80211_KEYTYPE_PAIRWISE;
  464. cfg80211_michael_mic_failure(padapter->pnetdev, sta->cmn.mac_addr, key_type, -1, NULL, GFP_ATOMIC);
  465. #endif
  466. _rtw_memset(&ev, 0x00, sizeof(ev));
  467. if (bgroup)
  468. ev.flags |= IW_MICFAILURE_GROUP;
  469. else
  470. ev.flags |= IW_MICFAILURE_PAIRWISE;
  471. ev.src_addr.sa_family = ARPHRD_ETHER;
  472. _rtw_memcpy(ev.src_addr.sa_data, sta->cmn.mac_addr, ETH_ALEN);
  473. _rtw_memset(&wrqu, 0x00, sizeof(wrqu));
  474. wrqu.data.length = sizeof(ev);
  475. #ifndef CONFIG_IOCTL_CFG80211
  476. wireless_send_event(padapter->pnetdev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
  477. #endif
  478. }
  479. #ifdef CONFIG_HOSTAPD_MLME
  480. void rtw_hostapd_mlme_rx(_adapter *padapter, union recv_frame *precv_frame)
  481. {
  482. _pkt *skb;
  483. struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
  484. struct net_device *pmgnt_netdev = phostapdpriv->pmgnt_netdev;
  485. skb = precv_frame->u.hdr.pkt;
  486. if (skb == NULL)
  487. return;
  488. skb->data = precv_frame->u.hdr.rx_data;
  489. skb->tail = precv_frame->u.hdr.rx_tail;
  490. skb->len = precv_frame->u.hdr.len;
  491. /* pskb_copy = rtw_skb_copy(skb);
  492. * if(skb == NULL) goto _exit; */
  493. skb->dev = pmgnt_netdev;
  494. skb->ip_summed = CHECKSUM_NONE;
  495. skb->pkt_type = PACKET_OTHERHOST;
  496. /* skb->protocol = __constant_htons(0x0019); ETH_P_80211_RAW */
  497. skb->protocol = __constant_htons(0x0003); /*ETH_P_80211_RAW*/
  498. /* RTW_INFO("(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); */
  499. /* skb->mac.raw = skb->data; */
  500. skb_reset_mac_header(skb);
  501. /* skb_pull(skb, 24); */
  502. _rtw_memset(skb->cb, 0, sizeof(skb->cb));
  503. rtw_netif_rx(pmgnt_netdev, skb);
  504. precv_frame->u.hdr.pkt = NULL; /* set pointer to NULL before rtw_free_recvframe() if call rtw_netif_rx() */
  505. }
  506. #endif /* CONFIG_HOSTAPD_MLME */
  507. int rtw_recv_monitor(_adapter *padapter, union recv_frame *precv_frame)
  508. {
  509. int ret = _FAIL;
  510. struct recv_priv *precvpriv;
  511. _queue *pfree_recv_queue;
  512. _pkt *skb;
  513. struct rx_pkt_attrib *pattrib;
  514. if (NULL == precv_frame)
  515. goto _recv_drop;
  516. pattrib = &precv_frame->u.hdr.attrib;
  517. precvpriv = &(padapter->recvpriv);
  518. pfree_recv_queue = &(precvpriv->free_recv_queue);
  519. skb = precv_frame->u.hdr.pkt;
  520. if (skb == NULL) {
  521. RTW_INFO("%s :skb==NULL something wrong!!!!\n", __func__);
  522. goto _recv_drop;
  523. }
  524. skb->data = precv_frame->u.hdr.rx_data;
  525. skb_set_tail_pointer(skb, precv_frame->u.hdr.len);
  526. skb->len = precv_frame->u.hdr.len;
  527. skb->ip_summed = CHECKSUM_NONE;
  528. skb->pkt_type = PACKET_OTHERHOST;
  529. skb->protocol = htons(0x0019); /* ETH_P_80211_RAW */
  530. rtw_netif_rx(padapter->pnetdev, skb);
  531. /* pointers to NULL before rtw_free_recvframe() */
  532. precv_frame->u.hdr.pkt = NULL;
  533. ret = _SUCCESS;
  534. _recv_drop:
  535. /* enqueue back to free_recv_queue */
  536. if (precv_frame)
  537. rtw_free_recvframe(precv_frame, pfree_recv_queue);
  538. return ret;
  539. }
  540. inline void rtw_rframe_set_os_pkt(union recv_frame *rframe)
  541. {
  542. _pkt *skb = rframe->u.hdr.pkt;
  543. skb->data = rframe->u.hdr.rx_data;
  544. skb_set_tail_pointer(skb, rframe->u.hdr.len);
  545. skb->len = rframe->u.hdr.len;
  546. }
  547. int rtw_recv_indicatepkt(_adapter *padapter, union recv_frame *precv_frame)
  548. {
  549. struct recv_priv *precvpriv;
  550. _queue *pfree_recv_queue;
  551. precvpriv = &(padapter->recvpriv);
  552. pfree_recv_queue = &(precvpriv->free_recv_queue);
  553. if (precv_frame->u.hdr.pkt == NULL)
  554. goto _recv_indicatepkt_drop;
  555. rtw_os_recv_indicate_pkt(padapter, precv_frame->u.hdr.pkt, precv_frame);
  556. _recv_indicatepkt_end:
  557. precv_frame->u.hdr.pkt = NULL;
  558. rtw_free_recvframe(precv_frame, pfree_recv_queue);
  559. return _SUCCESS;
  560. _recv_indicatepkt_drop:
  561. rtw_free_recvframe(precv_frame, pfree_recv_queue);
  562. DBG_COUNTER(padapter->rx_logs.os_indicate_err);
  563. return _FAIL;
  564. }
  565. void rtw_os_read_port(_adapter *padapter, struct recv_buf *precvbuf)
  566. {
  567. struct recv_priv *precvpriv = &padapter->recvpriv;
  568. #ifdef CONFIG_USB_HCI
  569. precvbuf->ref_cnt--;
  570. /* free skb in recv_buf */
  571. rtw_skb_free(precvbuf->pskb);
  572. precvbuf->pskb = NULL;
  573. if (precvbuf->irp_pending == _FALSE)
  574. rtw_read_port(padapter, precvpriv->ff_hwaddr, 0, (unsigned char *)precvbuf);
  575. #endif
  576. #if defined(CONFIG_SDIO_HCI) || defined(CONFIG_GSPI_HCI)
  577. precvbuf->pskb = NULL;
  578. #endif
  579. }