rtl871x_recv.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687
  1. /******************************************************************************
  2. * rtl871x_recv.c
  3. *
  4. * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
  5. * Linux device driver for RTL8192SU
  6. *
  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.
  10. *
  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
  14. * more details.
  15. *
  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
  19. *
  20. * Modifications for inclusion into the Linux staging tree are
  21. * Copyright(c) 2010 Larry Finger. All rights reserved.
  22. *
  23. * Contact information:
  24. * WLAN FAE <wlanfae@realtek.com>
  25. * Larry Finger <Larry.Finger@lwfinger.net>
  26. *
  27. ******************************************************************************/
  28. #define _RTL871X_RECV_C_
  29. #include <linux/ip.h>
  30. #include <linux/slab.h>
  31. #include <linux/if_ether.h>
  32. #include <linux/kmemleak.h>
  33. #include <linux/etherdevice.h>
  34. #include "osdep_service.h"
  35. #include "drv_types.h"
  36. #include "recv_osdep.h"
  37. #include "mlme_osdep.h"
  38. #include "ethernet.h"
  39. #include "usb_ops.h"
  40. #include "wifi.h"
  41. static const u8 SNAP_ETH_TYPE_IPX[2] = {0x81, 0x37};
  42. /* Datagram Delivery Protocol */
  43. static const u8 SNAP_ETH_TYPE_APPLETALK_AARP[2] = {0x80, 0xf3};
  44. /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
  45. static const u8 bridge_tunnel_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8};
  46. /* Ethernet-II snap header (RFC1042 for most EtherTypes) */
  47. static const u8 rfc1042_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
  48. void _r8712_init_sta_recv_priv(struct sta_recv_priv *psta_recvpriv)
  49. {
  50. memset((u8 *)psta_recvpriv, 0, sizeof(struct sta_recv_priv));
  51. spin_lock_init(&psta_recvpriv->lock);
  52. _init_queue(&psta_recvpriv->defrag_q);
  53. }
  54. sint _r8712_init_recv_priv(struct recv_priv *precvpriv,
  55. struct _adapter *padapter)
  56. {
  57. sint i;
  58. union recv_frame *precvframe;
  59. memset((unsigned char *)precvpriv, 0, sizeof(struct recv_priv));
  60. spin_lock_init(&precvpriv->lock);
  61. _init_queue(&precvpriv->free_recv_queue);
  62. _init_queue(&precvpriv->recv_pending_queue);
  63. precvpriv->adapter = padapter;
  64. precvpriv->free_recvframe_cnt = NR_RECVFRAME;
  65. precvpriv->pallocated_frame_buf = kmalloc(NR_RECVFRAME *
  66. sizeof(union recv_frame) + RXFRAME_ALIGN_SZ,
  67. GFP_ATOMIC);
  68. if (precvpriv->pallocated_frame_buf == NULL)
  69. return _FAIL;
  70. kmemleak_not_leak(precvpriv->pallocated_frame_buf);
  71. memset(precvpriv->pallocated_frame_buf, 0, NR_RECVFRAME *
  72. sizeof(union recv_frame) + RXFRAME_ALIGN_SZ);
  73. precvpriv->precv_frame_buf = precvpriv->pallocated_frame_buf +
  74. RXFRAME_ALIGN_SZ -
  75. ((addr_t)(precvpriv->pallocated_frame_buf) &
  76. (RXFRAME_ALIGN_SZ - 1));
  77. precvframe = (union recv_frame *)precvpriv->precv_frame_buf;
  78. for (i = 0; i < NR_RECVFRAME; i++) {
  79. INIT_LIST_HEAD(&(precvframe->u.list));
  80. list_add_tail(&(precvframe->u.list),
  81. &(precvpriv->free_recv_queue.queue));
  82. r8712_os_recv_resource_alloc(padapter, precvframe);
  83. precvframe->u.hdr.adapter = padapter;
  84. precvframe++;
  85. }
  86. precvpriv->rx_pending_cnt = 1;
  87. return r8712_init_recv_priv(precvpriv, padapter);
  88. }
  89. void _r8712_free_recv_priv(struct recv_priv *precvpriv)
  90. {
  91. kfree(precvpriv->pallocated_frame_buf);
  92. r8712_free_recv_priv(precvpriv);
  93. }
  94. union recv_frame *r8712_alloc_recvframe(struct __queue *pfree_recv_queue)
  95. {
  96. unsigned long irqL;
  97. union recv_frame *precvframe;
  98. struct list_head *plist, *phead;
  99. struct _adapter *padapter;
  100. struct recv_priv *precvpriv;
  101. spin_lock_irqsave(&pfree_recv_queue->lock, irqL);
  102. if (list_empty(&pfree_recv_queue->queue)) {
  103. precvframe = NULL;
  104. } else {
  105. phead = &pfree_recv_queue->queue;
  106. plist = phead->next;
  107. precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
  108. list_del_init(&precvframe->u.hdr.list);
  109. padapter = precvframe->u.hdr.adapter;
  110. if (padapter != NULL) {
  111. precvpriv = &padapter->recvpriv;
  112. if (pfree_recv_queue == &precvpriv->free_recv_queue)
  113. precvpriv->free_recvframe_cnt--;
  114. }
  115. }
  116. spin_unlock_irqrestore(&pfree_recv_queue->lock, irqL);
  117. return precvframe;
  118. }
  119. /*
  120. caller : defrag; recvframe_chk_defrag in recv_thread (passive)
  121. pframequeue: defrag_queue : will be accessed in recv_thread (passive)
  122. using spin_lock to protect
  123. */
  124. void r8712_free_recvframe_queue(struct __queue *pframequeue,
  125. struct __queue *pfree_recv_queue)
  126. {
  127. union recv_frame *precvframe;
  128. struct list_head *plist, *phead;
  129. spin_lock(&pframequeue->lock);
  130. phead = &pframequeue->queue;
  131. plist = phead->next;
  132. while (!end_of_queue_search(phead, plist)) {
  133. precvframe = LIST_CONTAINOR(plist, union recv_frame, u);
  134. plist = plist->next;
  135. r8712_free_recvframe(precvframe, pfree_recv_queue);
  136. }
  137. spin_unlock(&pframequeue->lock);
  138. }
  139. sint r8712_recvframe_chkmic(struct _adapter *adapter,
  140. union recv_frame *precvframe)
  141. {
  142. sint i, res = _SUCCESS;
  143. u32 datalen;
  144. u8 miccode[8];
  145. u8 bmic_err = false;
  146. u8 *pframe, *payload, *pframemic;
  147. u8 *mickey, idx, *iv;
  148. struct sta_info *stainfo;
  149. struct rx_pkt_attrib *prxattrib = &precvframe->u.hdr.attrib;
  150. struct security_priv *psecuritypriv = &adapter->securitypriv;
  151. stainfo = r8712_get_stainfo(&adapter->stapriv, &prxattrib->ta[0]);
  152. if (prxattrib->encrypt == _TKIP_) {
  153. /* calculate mic code */
  154. if (stainfo != NULL) {
  155. if (IS_MCAST(prxattrib->ra)) {
  156. iv = precvframe->u.hdr.rx_data +
  157. prxattrib->hdrlen;
  158. idx = iv[3];
  159. mickey = &psecuritypriv->XGrprxmickey[(((idx >>
  160. 6) & 0x3)) - 1].skey[0];
  161. if (!psecuritypriv->binstallGrpkey)
  162. return _FAIL;
  163. } else {
  164. mickey = &stainfo->tkiprxmickey.skey[0];
  165. }
  166. /*icv_len included the mic code*/
  167. datalen = precvframe->u.hdr.len - prxattrib->hdrlen -
  168. prxattrib->iv_len - prxattrib->icv_len - 8;
  169. pframe = precvframe->u.hdr.rx_data;
  170. payload = pframe + prxattrib->hdrlen +
  171. prxattrib->iv_len;
  172. seccalctkipmic(mickey, pframe, payload, datalen,
  173. &miccode[0],
  174. (unsigned char)prxattrib->priority);
  175. pframemic = payload + datalen;
  176. bmic_err = false;
  177. for (i = 0; i < 8; i++) {
  178. if (miccode[i] != *(pframemic + i))
  179. bmic_err = true;
  180. }
  181. if (bmic_err) {
  182. if (prxattrib->bdecrypted)
  183. r8712_handle_tkip_mic_err(adapter,
  184. (u8)IS_MCAST(prxattrib->ra));
  185. res = _FAIL;
  186. } else {
  187. /* mic checked ok */
  188. if (!psecuritypriv->bcheck_grpkey &&
  189. IS_MCAST(prxattrib->ra))
  190. psecuritypriv->bcheck_grpkey = true;
  191. }
  192. recvframe_pull_tail(precvframe, 8);
  193. }
  194. }
  195. return res;
  196. }
  197. /* decrypt and set the ivlen,icvlen of the recv_frame */
  198. union recv_frame *r8712_decryptor(struct _adapter *padapter,
  199. union recv_frame *precv_frame)
  200. {
  201. struct rx_pkt_attrib *prxattrib = &precv_frame->u.hdr.attrib;
  202. struct security_priv *psecuritypriv = &padapter->securitypriv;
  203. union recv_frame *return_packet = precv_frame;
  204. if ((prxattrib->encrypt > 0) && ((prxattrib->bdecrypted == 0) ||
  205. psecuritypriv->sw_decrypt)) {
  206. psecuritypriv->hw_decrypted = false;
  207. switch (prxattrib->encrypt) {
  208. case _WEP40_:
  209. case _WEP104_:
  210. r8712_wep_decrypt(padapter, (u8 *)precv_frame);
  211. break;
  212. case _TKIP_:
  213. r8712_tkip_decrypt(padapter, (u8 *)precv_frame);
  214. break;
  215. case _AES_:
  216. r8712_aes_decrypt(padapter, (u8 *)precv_frame);
  217. break;
  218. default:
  219. break;
  220. }
  221. } else if (prxattrib->bdecrypted == 1) {
  222. psecuritypriv->hw_decrypted = true;
  223. }
  224. return return_packet;
  225. }
  226. /*###set the security information in the recv_frame */
  227. union recv_frame *r8712_portctrl(struct _adapter *adapter,
  228. union recv_frame *precv_frame)
  229. {
  230. u8 *psta_addr, *ptr;
  231. uint auth_alg;
  232. struct recv_frame_hdr *pfhdr;
  233. struct sta_info *psta;
  234. struct sta_priv *pstapriv;
  235. union recv_frame *prtnframe;
  236. u16 ether_type;
  237. pstapriv = &adapter->stapriv;
  238. ptr = get_recvframe_data(precv_frame);
  239. pfhdr = &precv_frame->u.hdr;
  240. psta_addr = pfhdr->attrib.ta;
  241. psta = r8712_get_stainfo(pstapriv, psta_addr);
  242. auth_alg = adapter->securitypriv.AuthAlgrthm;
  243. if (auth_alg == 2) {
  244. /* get ether_type */
  245. ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
  246. memcpy(&ether_type, ptr, 2);
  247. ether_type = ntohs((unsigned short)ether_type);
  248. if ((psta != NULL) && (psta->ieee8021x_blocked)) {
  249. /* blocked
  250. * only accept EAPOL frame */
  251. if (ether_type == 0x888e) {
  252. prtnframe = precv_frame;
  253. } else {
  254. /*free this frame*/
  255. r8712_free_recvframe(precv_frame,
  256. &adapter->recvpriv.free_recv_queue);
  257. prtnframe = NULL;
  258. }
  259. } else {
  260. /* allowed
  261. * check decryption status, and decrypt the
  262. * frame if needed */
  263. prtnframe = precv_frame;
  264. /* check is the EAPOL frame or not (Rekey) */
  265. if (ether_type == 0x888e) {
  266. /* check Rekey */
  267. prtnframe = precv_frame;
  268. }
  269. }
  270. } else {
  271. prtnframe = precv_frame;
  272. }
  273. return prtnframe;
  274. }
  275. static sint recv_decache(union recv_frame *precv_frame, u8 bretry,
  276. struct stainfo_rxcache *prxcache)
  277. {
  278. sint tid = precv_frame->u.hdr.attrib.priority;
  279. u16 seq_ctrl = ((precv_frame->u.hdr.attrib.seq_num & 0xffff) << 4) |
  280. (precv_frame->u.hdr.attrib.frag_num & 0xf);
  281. if (tid > 15)
  282. return _FAIL;
  283. if (seq_ctrl == prxcache->tid_rxseq[tid])
  284. return _FAIL;
  285. prxcache->tid_rxseq[tid] = seq_ctrl;
  286. return _SUCCESS;
  287. }
  288. static sint sta2sta_data_frame(struct _adapter *adapter,
  289. union recv_frame *precv_frame,
  290. struct sta_info **psta)
  291. {
  292. u8 *ptr = precv_frame->u.hdr.rx_data;
  293. sint ret = _SUCCESS;
  294. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  295. struct sta_priv *pstapriv = &adapter->stapriv;
  296. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  297. u8 *mybssid = get_bssid(pmlmepriv);
  298. u8 *myhwaddr = myid(&adapter->eeprompriv);
  299. u8 *sta_addr = NULL;
  300. sint bmcast = IS_MCAST(pattrib->dst);
  301. if (check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) ||
  302. check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)) {
  303. /* filter packets that SA is myself or multicast or broadcast */
  304. if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN))
  305. return _FAIL;
  306. if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast))
  307. return _FAIL;
  308. if (is_zero_ether_addr(pattrib->bssid) ||
  309. is_zero_ether_addr(mybssid) ||
  310. (memcmp(pattrib->bssid, mybssid, ETH_ALEN)))
  311. return _FAIL;
  312. sta_addr = pattrib->src;
  313. } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  314. /* For Station mode, sa and bssid should always be BSSID,
  315. * and DA is my mac-address */
  316. if (memcmp(pattrib->bssid, pattrib->src, ETH_ALEN))
  317. return _FAIL;
  318. sta_addr = pattrib->bssid;
  319. } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  320. if (bmcast) {
  321. /* For AP mode, if DA == MCAST, then BSSID should
  322. * be also MCAST */
  323. if (!IS_MCAST(pattrib->bssid))
  324. return _FAIL;
  325. } else { /* not mc-frame */
  326. /* For AP mode, if DA is non-MCAST, then it must be
  327. * BSSID, and bssid == BSSID */
  328. if (memcmp(pattrib->bssid, pattrib->dst, ETH_ALEN))
  329. return _FAIL;
  330. sta_addr = pattrib->src;
  331. }
  332. } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
  333. memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
  334. memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
  335. memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
  336. memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
  337. memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
  338. sta_addr = mybssid;
  339. } else {
  340. ret = _FAIL;
  341. }
  342. if (bmcast)
  343. *psta = r8712_get_bcmc_stainfo(adapter);
  344. else
  345. *psta = r8712_get_stainfo(pstapriv, sta_addr); /* get ap_info */
  346. if (*psta == NULL) {
  347. if (check_fwstate(pmlmepriv, WIFI_MP_STATE))
  348. adapter->mppriv.rx_pktloss++;
  349. return _FAIL;
  350. }
  351. return ret;
  352. }
  353. static sint ap2sta_data_frame(struct _adapter *adapter,
  354. union recv_frame *precv_frame,
  355. struct sta_info **psta)
  356. {
  357. u8 *ptr = precv_frame->u.hdr.rx_data;
  358. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  359. struct sta_priv *pstapriv = &adapter->stapriv;
  360. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  361. u8 *mybssid = get_bssid(pmlmepriv);
  362. u8 *myhwaddr = myid(&adapter->eeprompriv);
  363. sint bmcast = IS_MCAST(pattrib->dst);
  364. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
  365. check_fwstate(pmlmepriv, _FW_LINKED)) {
  366. /* if NULL-frame, drop packet */
  367. if ((GetFrameSubType(ptr)) == WIFI_DATA_NULL)
  368. return _FAIL;
  369. /* drop QoS-SubType Data, including QoS NULL,
  370. * excluding QoS-Data */
  371. if ((GetFrameSubType(ptr) & WIFI_QOS_DATA_TYPE) ==
  372. WIFI_QOS_DATA_TYPE) {
  373. if (GetFrameSubType(ptr) & (BIT(4) | BIT(5) | BIT(6)))
  374. return _FAIL;
  375. }
  376. /* filter packets that SA is myself or multicast or broadcast */
  377. if (!memcmp(myhwaddr, pattrib->src, ETH_ALEN))
  378. return _FAIL;
  379. /* da should be for me */
  380. if ((memcmp(myhwaddr, pattrib->dst, ETH_ALEN)) && (!bmcast))
  381. return _FAIL;
  382. /* check BSSID */
  383. if (is_zero_ether_addr(pattrib->bssid) ||
  384. is_zero_ether_addr(mybssid) ||
  385. (memcmp(pattrib->bssid, mybssid, ETH_ALEN)))
  386. return _FAIL;
  387. if (bmcast)
  388. *psta = r8712_get_bcmc_stainfo(adapter);
  389. else
  390. *psta = r8712_get_stainfo(pstapriv, pattrib->bssid);
  391. if (*psta == NULL)
  392. return _FAIL;
  393. } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) &&
  394. check_fwstate(pmlmepriv, _FW_LINKED)) {
  395. memcpy(pattrib->dst, GetAddr1Ptr(ptr), ETH_ALEN);
  396. memcpy(pattrib->src, GetAddr2Ptr(ptr), ETH_ALEN);
  397. memcpy(pattrib->bssid, GetAddr3Ptr(ptr), ETH_ALEN);
  398. memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
  399. memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
  400. memcpy(pattrib->bssid, mybssid, ETH_ALEN);
  401. *psta = r8712_get_stainfo(pstapriv, pattrib->bssid);
  402. if (*psta == NULL)
  403. return _FAIL;
  404. } else {
  405. return _FAIL;
  406. }
  407. return _SUCCESS;
  408. }
  409. static sint sta2ap_data_frame(struct _adapter *adapter,
  410. union recv_frame *precv_frame,
  411. struct sta_info **psta)
  412. {
  413. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  414. struct sta_priv *pstapriv = &adapter->stapriv;
  415. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  416. unsigned char *mybssid = get_bssid(pmlmepriv);
  417. if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  418. /* For AP mode, if DA is non-MCAST, then it must be BSSID,
  419. * and bssid == BSSID
  420. * For AP mode, RA=BSSID, TX=STA(SRC_ADDR), A3=DST_ADDR */
  421. if (memcmp(pattrib->bssid, mybssid, ETH_ALEN))
  422. return _FAIL;
  423. *psta = r8712_get_stainfo(pstapriv, pattrib->src);
  424. if (*psta == NULL)
  425. return _FAIL;
  426. }
  427. return _SUCCESS;
  428. }
  429. static sint validate_recv_ctrl_frame(struct _adapter *adapter,
  430. union recv_frame *precv_frame)
  431. {
  432. return _FAIL;
  433. }
  434. static sint validate_recv_mgnt_frame(struct _adapter *adapter,
  435. union recv_frame *precv_frame)
  436. {
  437. return _FAIL;
  438. }
  439. static sint validate_recv_data_frame(struct _adapter *adapter,
  440. union recv_frame *precv_frame)
  441. {
  442. int res;
  443. u8 bretry;
  444. u8 *psa, *pda, *pbssid;
  445. struct sta_info *psta = NULL;
  446. u8 *ptr = precv_frame->u.hdr.rx_data;
  447. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  448. struct security_priv *psecuritypriv = &adapter->securitypriv;
  449. bretry = GetRetry(ptr);
  450. pda = get_da(ptr);
  451. psa = get_sa(ptr);
  452. pbssid = get_hdr_bssid(ptr);
  453. if (pbssid == NULL)
  454. return _FAIL;
  455. memcpy(pattrib->dst, pda, ETH_ALEN);
  456. memcpy(pattrib->src, psa, ETH_ALEN);
  457. memcpy(pattrib->bssid, pbssid, ETH_ALEN);
  458. switch (pattrib->to_fr_ds) {
  459. case 0:
  460. memcpy(pattrib->ra, pda, ETH_ALEN);
  461. memcpy(pattrib->ta, psa, ETH_ALEN);
  462. res = sta2sta_data_frame(adapter, precv_frame, &psta);
  463. break;
  464. case 1:
  465. memcpy(pattrib->ra, pda, ETH_ALEN);
  466. memcpy(pattrib->ta, pbssid, ETH_ALEN);
  467. res = ap2sta_data_frame(adapter, precv_frame, &psta);
  468. break;
  469. case 2:
  470. memcpy(pattrib->ra, pbssid, ETH_ALEN);
  471. memcpy(pattrib->ta, psa, ETH_ALEN);
  472. res = sta2ap_data_frame(adapter, precv_frame, &psta);
  473. break;
  474. case 3:
  475. memcpy(pattrib->ra, GetAddr1Ptr(ptr), ETH_ALEN);
  476. memcpy(pattrib->ta, GetAddr2Ptr(ptr), ETH_ALEN);
  477. return _FAIL;
  478. default:
  479. return _FAIL;
  480. }
  481. if (res == _FAIL)
  482. return _FAIL;
  483. if (psta == NULL)
  484. return _FAIL;
  485. precv_frame->u.hdr.psta = psta;
  486. pattrib->amsdu = 0;
  487. /* parsing QC field */
  488. if (pattrib->qos == 1) {
  489. pattrib->priority = GetPriority((ptr + 24));
  490. pattrib->ack_policy = GetAckpolicy((ptr + 24));
  491. pattrib->amsdu = GetAMsdu((ptr + 24));
  492. pattrib->hdrlen = pattrib->to_fr_ds == 3 ? 32 : 26;
  493. } else {
  494. pattrib->priority = 0;
  495. pattrib->hdrlen = (pattrib->to_fr_ds == 3) ? 30 : 24;
  496. }
  497. if (pattrib->order)/*HT-CTRL 11n*/
  498. pattrib->hdrlen += 4;
  499. precv_frame->u.hdr.preorder_ctrl =
  500. &psta->recvreorder_ctrl[pattrib->priority];
  501. /* decache, drop duplicate recv packets */
  502. if (recv_decache(precv_frame, bretry, &psta->sta_recvpriv.rxcache) ==
  503. _FAIL)
  504. return _FAIL;
  505. if (pattrib->privacy) {
  506. GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt,
  507. IS_MCAST(pattrib->ra));
  508. SET_ICE_IV_LEN(pattrib->iv_len, pattrib->icv_len,
  509. pattrib->encrypt);
  510. } else {
  511. pattrib->encrypt = 0;
  512. pattrib->iv_len = pattrib->icv_len = 0;
  513. }
  514. return _SUCCESS;
  515. }
  516. sint r8712_validate_recv_frame(struct _adapter *adapter,
  517. union recv_frame *precv_frame)
  518. {
  519. /*shall check frame subtype, to / from ds, da, bssid */
  520. /*then call check if rx seq/frag. duplicated.*/
  521. u8 type;
  522. u8 subtype;
  523. sint retval = _SUCCESS;
  524. struct rx_pkt_attrib *pattrib = &precv_frame->u.hdr.attrib;
  525. u8 *ptr = precv_frame->u.hdr.rx_data;
  526. u8 ver = (unsigned char)(*ptr) & 0x3;
  527. /*add version chk*/
  528. if (ver != 0)
  529. return _FAIL;
  530. type = GetFrameType(ptr);
  531. subtype = GetFrameSubType(ptr); /*bit(7)~bit(2)*/
  532. pattrib->to_fr_ds = get_tofr_ds(ptr);
  533. pattrib->frag_num = GetFragNum(ptr);
  534. pattrib->seq_num = GetSequence(ptr);
  535. pattrib->pw_save = GetPwrMgt(ptr);
  536. pattrib->mfrag = GetMFrag(ptr);
  537. pattrib->mdata = GetMData(ptr);
  538. pattrib->privacy = GetPrivacy(ptr);
  539. pattrib->order = GetOrder(ptr);
  540. switch (type) {
  541. case WIFI_MGT_TYPE: /*mgnt*/
  542. retval = validate_recv_mgnt_frame(adapter, precv_frame);
  543. break;
  544. case WIFI_CTRL_TYPE:/*ctrl*/
  545. retval = validate_recv_ctrl_frame(adapter, precv_frame);
  546. break;
  547. case WIFI_DATA_TYPE: /*data*/
  548. pattrib->qos = (subtype & BIT(7)) ? 1 : 0;
  549. retval = validate_recv_data_frame(adapter, precv_frame);
  550. break;
  551. default:
  552. return _FAIL;
  553. }
  554. return retval;
  555. }
  556. sint r8712_wlanhdr_to_ethhdr(union recv_frame *precvframe)
  557. {
  558. /*remove the wlanhdr and add the eth_hdr*/
  559. sint rmv_len;
  560. u16 len;
  561. u8 bsnaphdr;
  562. u8 *psnap_type;
  563. struct ieee80211_snap_hdr *psnap;
  564. struct _adapter *adapter = precvframe->u.hdr.adapter;
  565. struct mlme_priv *pmlmepriv = &adapter->mlmepriv;
  566. u8 *ptr = get_recvframe_data(precvframe); /*point to frame_ctrl field*/
  567. struct rx_pkt_attrib *pattrib = &precvframe->u.hdr.attrib;
  568. if (pattrib->encrypt)
  569. recvframe_pull_tail(precvframe, pattrib->icv_len);
  570. psnap = (struct ieee80211_snap_hdr *)(ptr + pattrib->hdrlen +
  571. pattrib->iv_len);
  572. psnap_type = ptr + pattrib->hdrlen + pattrib->iv_len + SNAP_SIZE;
  573. /* convert hdr + possible LLC headers into Ethernet header */
  574. if ((!memcmp(psnap, (void *)rfc1042_header, SNAP_SIZE) &&
  575. (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_IPX, 2)) &&
  576. (memcmp(psnap_type, (void *)SNAP_ETH_TYPE_APPLETALK_AARP, 2))) ||
  577. !memcmp(psnap, (void *)bridge_tunnel_header, SNAP_SIZE)) {
  578. /* remove RFC1042 or Bridge-Tunnel encapsulation and
  579. * replace EtherType */
  580. bsnaphdr = true;
  581. } else {
  582. /* Leave Ethernet header part of hdr and full payload */
  583. bsnaphdr = false;
  584. }
  585. rmv_len = pattrib->hdrlen + pattrib->iv_len +
  586. (bsnaphdr ? SNAP_SIZE : 0);
  587. len = precvframe->u.hdr.len - rmv_len;
  588. if (check_fwstate(pmlmepriv, WIFI_MP_STATE)) {
  589. ptr += rmv_len;
  590. *ptr = 0x87;
  591. *(ptr + 1) = 0x12;
  592. /* append rx status for mp test packets */
  593. ptr = recvframe_pull(precvframe, (rmv_len -
  594. sizeof(struct ethhdr) + 2) - 24);
  595. if (!ptr)
  596. return _FAIL;
  597. memcpy(ptr, get_rxmem(precvframe), 24);
  598. ptr += 24;
  599. } else {
  600. ptr = recvframe_pull(precvframe, (rmv_len -
  601. sizeof(struct ethhdr) + (bsnaphdr ? 2 : 0)));
  602. if (!ptr)
  603. return _FAIL;
  604. }
  605. memcpy(ptr, pattrib->dst, ETH_ALEN);
  606. memcpy(ptr + ETH_ALEN, pattrib->src, ETH_ALEN);
  607. if (!bsnaphdr) {
  608. len = htons(len);
  609. memcpy(ptr + 12, &len, 2);
  610. }
  611. return _SUCCESS;
  612. }
  613. s32 r8712_recv_entry(union recv_frame *precvframe)
  614. {
  615. struct _adapter *padapter;
  616. struct recv_priv *precvpriv;
  617. s32 ret = _SUCCESS;
  618. padapter = precvframe->u.hdr.adapter;
  619. precvpriv = &(padapter->recvpriv);
  620. padapter->ledpriv.LedControlHandler(padapter, LED_CTL_RX);
  621. ret = recv_func(padapter, precvframe);
  622. if (ret == _FAIL)
  623. goto _recv_entry_drop;
  624. precvpriv->rx_pkts++;
  625. precvpriv->rx_bytes += (uint)(precvframe->u.hdr.rx_tail -
  626. precvframe->u.hdr.rx_data);
  627. return ret;
  628. _recv_entry_drop:
  629. precvpriv->rx_drop++;
  630. padapter->mppriv.rx_pktloss = precvpriv->rx_drop;
  631. return ret;
  632. }