/drivers/staging/rtl8712/rtl871x_xmit.c

https://bitbucket.org/wisechild/galaxy-nexus · C · 1051 lines · 883 code · 63 blank · 105 comment · 190 complexity · 8923f7aa2a43b2e4df037fa538649e15 MD5 · raw file

  1. /******************************************************************************
  2. * rtl871x_xmit.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_XMIT_C_
  29. #include "osdep_service.h"
  30. #include "drv_types.h"
  31. #include "rtl871x_byteorder.h"
  32. #include "wifi.h"
  33. #include "osdep_intf.h"
  34. #include "usb_ops.h"
  35. static const u8 P802_1H_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0xf8};
  36. static const u8 RFC1042_OUI[P80211_OUI_LEN] = {0x00, 0x00, 0x00};
  37. static void init_hwxmits(struct hw_xmit *phwxmit, sint entry);
  38. static void alloc_hwxmits(struct _adapter *padapter);
  39. static void free_hwxmits(struct _adapter *padapter);
  40. static void _init_txservq(struct tx_servq *ptxservq)
  41. {
  42. _init_listhead(&ptxservq->tx_pending);
  43. _init_queue(&ptxservq->sta_pending);
  44. ptxservq->qcnt = 0;
  45. }
  46. void _r8712_init_sta_xmit_priv(struct sta_xmit_priv *psta_xmitpriv)
  47. {
  48. memset((unsigned char *)psta_xmitpriv, 0,
  49. sizeof(struct sta_xmit_priv));
  50. spin_lock_init(&psta_xmitpriv->lock);
  51. _init_txservq(&psta_xmitpriv->be_q);
  52. _init_txservq(&psta_xmitpriv->bk_q);
  53. _init_txservq(&psta_xmitpriv->vi_q);
  54. _init_txservq(&psta_xmitpriv->vo_q);
  55. _init_listhead(&psta_xmitpriv->legacy_dz);
  56. _init_listhead(&psta_xmitpriv->apsd);
  57. }
  58. sint _r8712_init_xmit_priv(struct xmit_priv *pxmitpriv,
  59. struct _adapter *padapter)
  60. {
  61. sint i;
  62. struct xmit_buf *pxmitbuf;
  63. struct xmit_frame *pxframe;
  64. memset((unsigned char *)pxmitpriv, 0, sizeof(struct xmit_priv));
  65. spin_lock_init(&pxmitpriv->lock);
  66. sema_init(&pxmitpriv->xmit_sema, 0);
  67. sema_init(&pxmitpriv->terminate_xmitthread_sema, 0);
  68. /*
  69. Please insert all the queue initializaiton using _init_queue below
  70. */
  71. pxmitpriv->adapter = padapter;
  72. _init_queue(&pxmitpriv->be_pending);
  73. _init_queue(&pxmitpriv->bk_pending);
  74. _init_queue(&pxmitpriv->vi_pending);
  75. _init_queue(&pxmitpriv->vo_pending);
  76. _init_queue(&pxmitpriv->bm_pending);
  77. _init_queue(&pxmitpriv->legacy_dz_queue);
  78. _init_queue(&pxmitpriv->apsd_queue);
  79. _init_queue(&pxmitpriv->free_xmit_queue);
  80. /*
  81. Please allocate memory with the sz = (struct xmit_frame) * NR_XMITFRAME,
  82. and initialize free_xmit_frame below.
  83. Please also apply free_txobj to link_up all the xmit_frames...
  84. */
  85. pxmitpriv->pallocated_frame_buf = _malloc(NR_XMITFRAME *
  86. sizeof(struct xmit_frame) + 4);
  87. if (pxmitpriv->pallocated_frame_buf == NULL) {
  88. pxmitpriv->pxmit_frame_buf = NULL;
  89. return _FAIL;
  90. }
  91. pxmitpriv->pxmit_frame_buf = pxmitpriv->pallocated_frame_buf + 4 -
  92. ((addr_t) (pxmitpriv->pallocated_frame_buf) & 3);
  93. pxframe = (struct xmit_frame *) pxmitpriv->pxmit_frame_buf;
  94. for (i = 0; i < NR_XMITFRAME; i++) {
  95. _init_listhead(&(pxframe->list));
  96. pxframe->padapter = padapter;
  97. pxframe->frame_tag = DATA_FRAMETAG;
  98. pxframe->pkt = NULL;
  99. pxframe->buf_addr = NULL;
  100. pxframe->pxmitbuf = NULL;
  101. list_insert_tail(&(pxframe->list),
  102. &(pxmitpriv->free_xmit_queue.queue));
  103. pxframe++;
  104. }
  105. pxmitpriv->free_xmitframe_cnt = NR_XMITFRAME;
  106. /*
  107. init xmit hw_txqueue
  108. */
  109. _r8712_init_hw_txqueue(&pxmitpriv->be_txqueue, BE_QUEUE_INX);
  110. _r8712_init_hw_txqueue(&pxmitpriv->bk_txqueue, BK_QUEUE_INX);
  111. _r8712_init_hw_txqueue(&pxmitpriv->vi_txqueue, VI_QUEUE_INX);
  112. _r8712_init_hw_txqueue(&pxmitpriv->vo_txqueue, VO_QUEUE_INX);
  113. _r8712_init_hw_txqueue(&pxmitpriv->bmc_txqueue, BMC_QUEUE_INX);
  114. pxmitpriv->frag_len = MAX_FRAG_THRESHOLD;
  115. pxmitpriv->txirp_cnt = 1;
  116. sema_init(&(pxmitpriv->tx_retevt), 0);
  117. /*per AC pending irp*/
  118. pxmitpriv->beq_cnt = 0;
  119. pxmitpriv->bkq_cnt = 0;
  120. pxmitpriv->viq_cnt = 0;
  121. pxmitpriv->voq_cnt = 0;
  122. /*init xmit_buf*/
  123. _init_queue(&pxmitpriv->free_xmitbuf_queue);
  124. _init_queue(&pxmitpriv->pending_xmitbuf_queue);
  125. pxmitpriv->pallocated_xmitbuf = _malloc(NR_XMITBUFF *
  126. sizeof(struct xmit_buf) + 4);
  127. if (pxmitpriv->pallocated_xmitbuf == NULL)
  128. return _FAIL;
  129. pxmitpriv->pxmitbuf = pxmitpriv->pallocated_xmitbuf + 4 -
  130. ((addr_t)(pxmitpriv->pallocated_xmitbuf) & 3);
  131. pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
  132. for (i = 0; i < NR_XMITBUFF; i++) {
  133. _init_listhead(&pxmitbuf->list);
  134. pxmitbuf->pallocated_buf = _malloc(MAX_XMITBUF_SZ +
  135. XMITBUF_ALIGN_SZ);
  136. if (pxmitbuf->pallocated_buf == NULL)
  137. return _FAIL;
  138. pxmitbuf->pbuf = pxmitbuf->pallocated_buf + XMITBUF_ALIGN_SZ -
  139. ((addr_t) (pxmitbuf->pallocated_buf) &
  140. (XMITBUF_ALIGN_SZ - 1));
  141. r8712_xmit_resource_alloc(padapter, pxmitbuf);
  142. list_insert_tail(&pxmitbuf->list,
  143. &(pxmitpriv->free_xmitbuf_queue.queue));
  144. pxmitbuf++;
  145. }
  146. pxmitpriv->free_xmitbuf_cnt = NR_XMITBUFF;
  147. alloc_hwxmits(padapter);
  148. init_hwxmits(pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
  149. tasklet_init(&pxmitpriv->xmit_tasklet,
  150. (void(*)(addr_t))r8712_xmit_bh,
  151. (addr_t)padapter);
  152. return _SUCCESS;
  153. }
  154. void _free_xmit_priv(struct xmit_priv *pxmitpriv)
  155. {
  156. int i;
  157. struct _adapter *padapter = pxmitpriv->adapter;
  158. struct xmit_frame *pxmitframe = (struct xmit_frame *)
  159. pxmitpriv->pxmit_frame_buf;
  160. struct xmit_buf *pxmitbuf = (struct xmit_buf *)pxmitpriv->pxmitbuf;
  161. if (pxmitpriv->pxmit_frame_buf == NULL)
  162. return;
  163. for (i = 0; i < NR_XMITFRAME; i++) {
  164. r8712_xmit_complete(padapter, pxmitframe);
  165. pxmitframe++;
  166. }
  167. for (i = 0; i < NR_XMITBUFF; i++) {
  168. r8712_xmit_resource_free(padapter, pxmitbuf);
  169. kfree(pxmitbuf->pallocated_buf);
  170. pxmitbuf++;
  171. }
  172. kfree(pxmitpriv->pallocated_frame_buf);
  173. kfree(pxmitpriv->pallocated_xmitbuf);
  174. free_hwxmits(padapter);
  175. }
  176. sint r8712_update_attrib(struct _adapter *padapter, _pkt *pkt,
  177. struct pkt_attrib *pattrib)
  178. {
  179. uint i;
  180. struct pkt_file pktfile;
  181. struct sta_info *psta = NULL;
  182. struct ethhdr etherhdr;
  183. struct tx_cmd txdesc;
  184. sint bmcast;
  185. struct sta_priv *pstapriv = &padapter->stapriv;
  186. struct security_priv *psecuritypriv = &padapter->securitypriv;
  187. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  188. struct qos_priv *pqospriv = &pmlmepriv->qospriv;
  189. _r8712_open_pktfile(pkt, &pktfile);
  190. i = _r8712_pktfile_read(&pktfile, (unsigned char *)&etherhdr, ETH_HLEN);
  191. pattrib->ether_type = ntohs(etherhdr.h_proto);
  192. {
  193. u8 bool;
  194. /*If driver xmit ARP packet, driver can set ps mode to initial
  195. * setting. It stands for getting DHCP or fix IP.*/
  196. if (pattrib->ether_type == 0x0806) {
  197. if (padapter->pwrctrlpriv.pwr_mode !=
  198. padapter->registrypriv.power_mgnt) {
  199. _cancel_timer(&(pmlmepriv->dhcp_timer), &bool);
  200. r8712_set_ps_mode(padapter, padapter->registrypriv.
  201. power_mgnt, padapter->registrypriv.smart_ps);
  202. }
  203. }
  204. }
  205. memcpy(pattrib->dst, &etherhdr.h_dest, ETH_ALEN);
  206. memcpy(pattrib->src, &etherhdr.h_source, ETH_ALEN);
  207. pattrib->pctrl = 0;
  208. if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true) ||
  209. (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE) == true)) {
  210. memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
  211. memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
  212. } else if (check_fwstate(pmlmepriv, WIFI_STATION_STATE)) {
  213. memcpy(pattrib->ra, get_bssid(pmlmepriv), ETH_ALEN);
  214. memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
  215. } else if (check_fwstate(pmlmepriv, WIFI_AP_STATE)) {
  216. memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
  217. memcpy(pattrib->ta, get_bssid(pmlmepriv), ETH_ALEN);
  218. } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
  219. /*firstly, filter packet not belongs to mp*/
  220. if (pattrib->ether_type != 0x8712)
  221. return _FAIL;
  222. /* for mp storing the txcmd per packet,
  223. * according to the info of txcmd to update pattrib */
  224. /*get MP_TXDESC_SIZE bytes txcmd per packet*/
  225. i = _r8712_pktfile_read(&pktfile, (u8 *)&txdesc, TXDESC_SIZE);
  226. memcpy(pattrib->ra, pattrib->dst, ETH_ALEN);
  227. memcpy(pattrib->ta, pattrib->src, ETH_ALEN);
  228. pattrib->pctrl = 1;
  229. }
  230. /* r8712_xmitframe_coalesce() overwrite this!*/
  231. pattrib->pktlen = pktfile.pkt_len;
  232. if (ETH_P_IP == pattrib->ether_type) {
  233. /* The following is for DHCP and ARP packet, we use cck1M to
  234. * tx these packets and let LPS awake some time
  235. * to prevent DHCP protocol fail */
  236. u8 tmp[24];
  237. _r8712_pktfile_read(&pktfile, &tmp[0], 24);
  238. pattrib->dhcp_pkt = 0;
  239. if (pktfile.pkt_len > 282) {/*MINIMUM_DHCP_PACKET_SIZE)*/
  240. if (ETH_P_IP == pattrib->ether_type) {/* IP header*/
  241. if (((tmp[21] == 68) && (tmp[23] == 67)) ||
  242. ((tmp[21] == 67) && (tmp[23] == 68))) {
  243. /* 68 : UDP BOOTP client
  244. * 67 : UDP BOOTP server
  245. * Use low rate to send DHCP packet.*/
  246. pattrib->dhcp_pkt = 1;
  247. }
  248. }
  249. }
  250. }
  251. bmcast = IS_MCAST(pattrib->ra);
  252. /* get sta_info*/
  253. if (bmcast) {
  254. psta = r8712_get_bcmc_stainfo(padapter);
  255. pattrib->mac_id = 4;
  256. } else {
  257. if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
  258. psta = r8712_get_stainfo(pstapriv,
  259. get_bssid(pmlmepriv));
  260. pattrib->mac_id = 5;
  261. } else {
  262. psta = r8712_get_stainfo(pstapriv, pattrib->ra);
  263. if (psta == NULL) /* drop the pkt */
  264. return _FAIL;
  265. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  266. pattrib->mac_id = 5;
  267. else
  268. pattrib->mac_id = psta->mac_id;
  269. }
  270. }
  271. if (psta) {
  272. pattrib->psta = psta;
  273. } else {
  274. /* if we cannot get psta => drrp the pkt */
  275. return _FAIL;
  276. }
  277. pattrib->ack_policy = 0;
  278. /* get ether_hdr_len */
  279. pattrib->pkt_hdrlen = ETH_HLEN;
  280. if (pqospriv->qos_option)
  281. r8712_set_qos(&pktfile, pattrib);
  282. else {
  283. pattrib->hdrlen = WLAN_HDR_A3_LEN;
  284. pattrib->subtype = WIFI_DATA_TYPE;
  285. pattrib->priority = 0;
  286. }
  287. if (psta->ieee8021x_blocked == true) {
  288. pattrib->encrypt = 0;
  289. if ((pattrib->ether_type != 0x888e) &&
  290. (check_fwstate(pmlmepriv, WIFI_MP_STATE) == false))
  291. return _FAIL;
  292. } else
  293. GET_ENCRY_ALGO(psecuritypriv, psta, pattrib->encrypt, bmcast);
  294. switch (pattrib->encrypt) {
  295. case _WEP40_:
  296. case _WEP104_:
  297. pattrib->iv_len = 4;
  298. pattrib->icv_len = 4;
  299. break;
  300. case _TKIP_:
  301. pattrib->iv_len = 8;
  302. pattrib->icv_len = 4;
  303. if (padapter->securitypriv.busetkipkey == _FAIL)
  304. return _FAIL;
  305. break;
  306. case _AES_:
  307. pattrib->iv_len = 8;
  308. pattrib->icv_len = 8;
  309. break;
  310. default:
  311. pattrib->iv_len = 0;
  312. pattrib->icv_len = 0;
  313. break;
  314. }
  315. if (pattrib->encrypt &&
  316. ((padapter->securitypriv.sw_encrypt == true) ||
  317. (psecuritypriv->hw_decrypted == false)))
  318. pattrib->bswenc = true;
  319. else
  320. pattrib->bswenc = false;
  321. /* if in MP_STATE, update pkt_attrib from mp_txcmd, and overwrite
  322. * some settings above.*/
  323. if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
  324. pattrib->priority = (txdesc.txdw1 >> QSEL_SHT) & 0x1f;
  325. return _SUCCESS;
  326. }
  327. static sint xmitframe_addmic(struct _adapter *padapter,
  328. struct xmit_frame *pxmitframe)
  329. {
  330. u32 curfragnum, length, datalen;
  331. u8 *pframe, *payload, mic[8];
  332. struct mic_data micdata;
  333. struct sta_info *stainfo;
  334. struct qos_priv *pqospriv = &(padapter->mlmepriv.qospriv);
  335. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  336. struct security_priv *psecuritypriv = &padapter->securitypriv;
  337. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  338. u8 priority[4] = {0x0, 0x0, 0x0, 0x0};
  339. sint bmcst = IS_MCAST(pattrib->ra);
  340. if (pattrib->psta)
  341. stainfo = pattrib->psta;
  342. else
  343. stainfo = r8712_get_stainfo(&padapter->stapriv,
  344. &pattrib->ra[0]);
  345. if (pattrib->encrypt == _TKIP_) {
  346. /*encode mic code*/
  347. if (stainfo != NULL) {
  348. u8 null_key[16] = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  349. 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
  350. 0x0, 0x0};
  351. datalen = pattrib->pktlen - pattrib->hdrlen;
  352. pframe = pxmitframe->buf_addr + TXDESC_OFFSET;
  353. if (bmcst) {
  354. if (!memcmp(psecuritypriv->XGrptxmickey
  355. [psecuritypriv->XGrpKeyid].skey,
  356. null_key, 16))
  357. return _FAIL;
  358. /*start to calculate the mic code*/
  359. r8712_secmicsetkey(&micdata,
  360. psecuritypriv->
  361. XGrptxmickey[psecuritypriv->
  362. XGrpKeyid].skey);
  363. } else {
  364. if (!memcmp(&stainfo->tkiptxmickey.skey[0],
  365. null_key, 16))
  366. return _FAIL;
  367. /* start to calculate the mic code */
  368. r8712_secmicsetkey(&micdata,
  369. &stainfo->tkiptxmickey.skey[0]);
  370. }
  371. if (pframe[1] & 1) { /* ToDS==1 */
  372. r8712_secmicappend(&micdata,
  373. &pframe[16], 6); /*DA*/
  374. if (pframe[1]&2) /* From Ds==1 */
  375. r8712_secmicappend(&micdata,
  376. &pframe[24], 6);
  377. else
  378. r8712_secmicappend(&micdata,
  379. &pframe[10], 6);
  380. } else { /* ToDS==0 */
  381. r8712_secmicappend(&micdata,
  382. &pframe[4], 6); /* DA */
  383. if (pframe[1]&2) /* From Ds==1 */
  384. r8712_secmicappend(&micdata,
  385. &pframe[16], 6);
  386. else
  387. r8712_secmicappend(&micdata,
  388. &pframe[10], 6);
  389. }
  390. if (pqospriv->qos_option == 1)
  391. priority[0] = (u8)pxmitframe->
  392. attrib.priority;
  393. r8712_secmicappend(&micdata, &priority[0], 4);
  394. payload = pframe;
  395. for (curfragnum = 0; curfragnum < pattrib->nr_frags;
  396. curfragnum++) {
  397. payload = (u8 *)RND4((addr_t)(payload));
  398. payload = payload+pattrib->
  399. hdrlen+pattrib->iv_len;
  400. if ((curfragnum + 1) == pattrib->nr_frags) {
  401. length = pattrib->last_txcmdsz -
  402. pattrib->hdrlen -
  403. pattrib->iv_len -
  404. ((psecuritypriv->sw_encrypt)
  405. ? pattrib->icv_len : 0);
  406. r8712_secmicappend(&micdata, payload,
  407. length);
  408. payload = payload+length;
  409. } else{
  410. length = pxmitpriv->frag_len -
  411. pattrib->hdrlen-pattrib->iv_len -
  412. ((psecuritypriv->sw_encrypt) ?
  413. pattrib->icv_len : 0);
  414. r8712_secmicappend(&micdata, payload,
  415. length);
  416. payload = payload + length +
  417. pattrib->icv_len;
  418. }
  419. }
  420. r8712_secgetmic(&micdata, &(mic[0]));
  421. /* add mic code and add the mic code length in
  422. * last_txcmdsz */
  423. memcpy(payload, &(mic[0]), 8);
  424. pattrib->last_txcmdsz += 8;
  425. payload = payload-pattrib->last_txcmdsz + 8;
  426. }
  427. }
  428. return _SUCCESS;
  429. }
  430. static sint xmitframe_swencrypt(struct _adapter *padapter,
  431. struct xmit_frame *pxmitframe)
  432. {
  433. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  434. if (pattrib->bswenc) {
  435. switch (pattrib->encrypt) {
  436. case _WEP40_:
  437. case _WEP104_:
  438. r8712_wep_encrypt(padapter, (u8 *)pxmitframe);
  439. break;
  440. case _TKIP_:
  441. r8712_tkip_encrypt(padapter, (u8 *)pxmitframe);
  442. break;
  443. case _AES_:
  444. r8712_aes_encrypt(padapter, (u8 *)pxmitframe);
  445. break;
  446. default:
  447. break;
  448. }
  449. }
  450. return _SUCCESS;
  451. }
  452. static sint make_wlanhdr(struct _adapter *padapter , u8 *hdr,
  453. struct pkt_attrib *pattrib)
  454. {
  455. u16 *qc;
  456. struct ieee80211_hdr *pwlanhdr = (struct ieee80211_hdr *)hdr;
  457. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  458. struct qos_priv *pqospriv = &pmlmepriv->qospriv;
  459. u16 *fctrl = &pwlanhdr->frame_ctl;
  460. memset(hdr, 0, WLANHDR_OFFSET);
  461. SetFrameSubType(fctrl, pattrib->subtype);
  462. if (pattrib->subtype & WIFI_DATA_TYPE) {
  463. if ((check_fwstate(pmlmepriv, WIFI_STATION_STATE) == true)) {
  464. /* to_ds = 1, fr_ds = 0; */
  465. SetToDs(fctrl);
  466. memcpy(pwlanhdr->addr1, get_bssid(pmlmepriv),
  467. ETH_ALEN);
  468. memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
  469. memcpy(pwlanhdr->addr3, pattrib->dst, ETH_ALEN);
  470. } else if ((check_fwstate(pmlmepriv, WIFI_AP_STATE) == true)) {
  471. /* to_ds = 0, fr_ds = 1; */
  472. SetFrDs(fctrl);
  473. memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
  474. memcpy(pwlanhdr->addr2, get_bssid(pmlmepriv),
  475. ETH_ALEN);
  476. memcpy(pwlanhdr->addr3, pattrib->src, ETH_ALEN);
  477. } else if ((check_fwstate(pmlmepriv, WIFI_ADHOC_STATE) == true)
  478. || (check_fwstate(pmlmepriv, WIFI_ADHOC_MASTER_STATE)
  479. == true)) {
  480. memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
  481. memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
  482. memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
  483. ETH_ALEN);
  484. } else if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
  485. memcpy(pwlanhdr->addr1, pattrib->dst, ETH_ALEN);
  486. memcpy(pwlanhdr->addr2, pattrib->src, ETH_ALEN);
  487. memcpy(pwlanhdr->addr3, get_bssid(pmlmepriv),
  488. ETH_ALEN);
  489. } else
  490. return _FAIL;
  491. if (pattrib->encrypt)
  492. SetPrivacy(fctrl);
  493. if (pqospriv->qos_option) {
  494. qc = (unsigned short *)(hdr + pattrib->hdrlen - 2);
  495. if (pattrib->priority)
  496. SetPriority(qc, pattrib->priority);
  497. SetAckpolicy(qc, pattrib->ack_policy);
  498. }
  499. /* TODO: fill HT Control Field */
  500. /* Update Seq Num will be handled by f/w */
  501. {
  502. struct sta_info *psta;
  503. sint bmcst = IS_MCAST(pattrib->ra);
  504. if (pattrib->psta)
  505. psta = pattrib->psta;
  506. else {
  507. if (bmcst)
  508. psta = r8712_get_bcmc_stainfo(padapter);
  509. else
  510. psta =
  511. r8712_get_stainfo(&padapter->stapriv,
  512. pattrib->ra);
  513. }
  514. if (psta) {
  515. psta->sta_xmitpriv.txseq_tid
  516. [pattrib->priority]++;
  517. psta->sta_xmitpriv.txseq_tid[pattrib->priority]
  518. &= 0xFFF;
  519. pattrib->seqnum = psta->sta_xmitpriv.
  520. txseq_tid[pattrib->priority];
  521. SetSeqNum(hdr, pattrib->seqnum);
  522. }
  523. }
  524. }
  525. return _SUCCESS;
  526. }
  527. static sint r8712_put_snap(u8 *data, u16 h_proto)
  528. {
  529. struct ieee80211_snap_hdr *snap;
  530. const u8 *oui;
  531. snap = (struct ieee80211_snap_hdr *)data;
  532. snap->dsap = 0xaa;
  533. snap->ssap = 0xaa;
  534. snap->ctrl = 0x03;
  535. if (h_proto == 0x8137 || h_proto == 0x80f3)
  536. oui = P802_1H_OUI;
  537. else
  538. oui = RFC1042_OUI;
  539. snap->oui[0] = oui[0];
  540. snap->oui[1] = oui[1];
  541. snap->oui[2] = oui[2];
  542. *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
  543. return SNAP_SIZE + sizeof(u16);
  544. }
  545. /*
  546. * This sub-routine will perform all the following:
  547. * 1. remove 802.3 header.
  548. * 2. create wlan_header, based on the info in pxmitframe
  549. * 3. append sta's iv/ext-iv
  550. * 4. append LLC
  551. * 5. move frag chunk from pframe to pxmitframe->mem
  552. * 6. apply sw-encrypt, if necessary.
  553. */
  554. sint r8712_xmitframe_coalesce(struct _adapter *padapter, _pkt *pkt,
  555. struct xmit_frame *pxmitframe)
  556. {
  557. struct pkt_file pktfile;
  558. sint frg_len, mpdu_len, llc_sz;
  559. u32 mem_sz;
  560. u8 frg_inx;
  561. addr_t addr;
  562. u8 *pframe, *mem_start, *ptxdesc;
  563. struct sta_info *psta;
  564. struct security_priv *psecuritypriv = &padapter->securitypriv;
  565. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  566. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  567. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  568. u8 *pbuf_start;
  569. sint bmcst = IS_MCAST(pattrib->ra);
  570. if (pattrib->psta == NULL)
  571. return _FAIL;
  572. psta = pattrib->psta;
  573. if (pxmitframe->buf_addr == NULL)
  574. return _FAIL;
  575. pbuf_start = pxmitframe->buf_addr;
  576. ptxdesc = pbuf_start;
  577. mem_start = pbuf_start + TXDESC_OFFSET;
  578. if (make_wlanhdr(padapter, mem_start, pattrib) == _FAIL)
  579. return _FAIL;
  580. _r8712_open_pktfile(pkt, &pktfile);
  581. _r8712_pktfile_read(&pktfile, NULL, pattrib->pkt_hdrlen);
  582. if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true) {
  583. /* truncate TXDESC_SIZE bytes txcmd if at mp mode for 871x */
  584. if (pattrib->ether_type == 0x8712) {
  585. /* take care - update_txdesc overwrite this */
  586. _r8712_pktfile_read(&pktfile, ptxdesc, TXDESC_SIZE);
  587. }
  588. }
  589. pattrib->pktlen = pktfile.pkt_len;
  590. frg_inx = 0;
  591. frg_len = pxmitpriv->frag_len - 4;
  592. while (1) {
  593. llc_sz = 0;
  594. mpdu_len = frg_len;
  595. pframe = mem_start;
  596. SetMFrag(mem_start);
  597. pframe += pattrib->hdrlen;
  598. mpdu_len -= pattrib->hdrlen;
  599. /* adding icv, if necessary...*/
  600. if (pattrib->iv_len) {
  601. if (psta != NULL) {
  602. switch (pattrib->encrypt) {
  603. case _WEP40_:
  604. case _WEP104_:
  605. WEP_IV(pattrib->iv, psta->txpn,
  606. (u8)psecuritypriv->
  607. PrivacyKeyIndex);
  608. break;
  609. case _TKIP_:
  610. if (bmcst)
  611. TKIP_IV(pattrib->iv,
  612. psta->txpn,
  613. (u8)psecuritypriv->
  614. XGrpKeyid);
  615. else
  616. TKIP_IV(pattrib->iv, psta->txpn,
  617. 0);
  618. break;
  619. case _AES_:
  620. if (bmcst)
  621. AES_IV(pattrib->iv, psta->txpn,
  622. (u8)psecuritypriv->
  623. XGrpKeyid);
  624. else
  625. AES_IV(pattrib->iv, psta->txpn,
  626. 0);
  627. break;
  628. }
  629. }
  630. memcpy(pframe, pattrib->iv, pattrib->iv_len);
  631. pframe += pattrib->iv_len;
  632. mpdu_len -= pattrib->iv_len;
  633. }
  634. if (frg_inx == 0) {
  635. llc_sz = r8712_put_snap(pframe, pattrib->ether_type);
  636. pframe += llc_sz;
  637. mpdu_len -= llc_sz;
  638. }
  639. if ((pattrib->icv_len > 0) && (pattrib->bswenc))
  640. mpdu_len -= pattrib->icv_len;
  641. if (bmcst)
  642. mem_sz = _r8712_pktfile_read(&pktfile, pframe,
  643. pattrib->pktlen);
  644. else
  645. mem_sz = _r8712_pktfile_read(&pktfile, pframe,
  646. mpdu_len);
  647. pframe += mem_sz;
  648. if ((pattrib->icv_len > 0) && (pattrib->bswenc)) {
  649. memcpy(pframe, pattrib->icv, pattrib->icv_len);
  650. pframe += pattrib->icv_len;
  651. }
  652. frg_inx++;
  653. if (bmcst || (r8712_endofpktfile(&pktfile) == true)) {
  654. pattrib->nr_frags = frg_inx;
  655. pattrib->last_txcmdsz = pattrib->hdrlen +
  656. pattrib->iv_len +
  657. ((pattrib->nr_frags == 1) ?
  658. llc_sz : 0) +
  659. ((pattrib->bswenc) ?
  660. pattrib->icv_len : 0) + mem_sz;
  661. ClearMFrag(mem_start);
  662. break;
  663. }
  664. addr = (addr_t)(pframe);
  665. mem_start = (unsigned char *)RND4(addr) + TXDESC_OFFSET;
  666. memcpy(mem_start, pbuf_start + TXDESC_OFFSET, pattrib->hdrlen);
  667. }
  668. if (xmitframe_addmic(padapter, pxmitframe) == _FAIL)
  669. return _FAIL;
  670. xmitframe_swencrypt(padapter, pxmitframe);
  671. return _SUCCESS;
  672. }
  673. void r8712_update_protection(struct _adapter *padapter, u8 *ie, uint ie_len)
  674. {
  675. uint protection;
  676. u8 *perp;
  677. sint erp_len;
  678. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  679. struct registry_priv *pregistrypriv = &padapter->registrypriv;
  680. switch (pxmitpriv->vcs_setting) {
  681. case DISABLE_VCS:
  682. pxmitpriv->vcs = NONE_VCS;
  683. break;
  684. case ENABLE_VCS:
  685. break;
  686. case AUTO_VCS:
  687. default:
  688. perp = r8712_get_ie(ie, _ERPINFO_IE_, &erp_len, ie_len);
  689. if (perp == NULL)
  690. pxmitpriv->vcs = NONE_VCS;
  691. else {
  692. protection = (*(perp + 2)) & BIT(1);
  693. if (protection) {
  694. if (pregistrypriv->vcs_type == RTS_CTS)
  695. pxmitpriv->vcs = RTS_CTS;
  696. else
  697. pxmitpriv->vcs = CTS_TO_SELF;
  698. } else
  699. pxmitpriv->vcs = NONE_VCS;
  700. }
  701. break;
  702. }
  703. }
  704. struct xmit_buf *r8712_alloc_xmitbuf(struct xmit_priv *pxmitpriv)
  705. {
  706. unsigned long irqL;
  707. struct xmit_buf *pxmitbuf = NULL;
  708. struct list_head *plist, *phead;
  709. struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
  710. spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
  711. if (_queue_empty(pfree_xmitbuf_queue) == true)
  712. pxmitbuf = NULL;
  713. else {
  714. phead = get_list_head(pfree_xmitbuf_queue);
  715. plist = get_next(phead);
  716. pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
  717. list_delete(&(pxmitbuf->list));
  718. }
  719. if (pxmitbuf != NULL)
  720. pxmitpriv->free_xmitbuf_cnt--;
  721. spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
  722. return pxmitbuf;
  723. }
  724. int r8712_free_xmitbuf(struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
  725. {
  726. unsigned long irqL;
  727. struct __queue *pfree_xmitbuf_queue = &pxmitpriv->free_xmitbuf_queue;
  728. if (pxmitbuf == NULL)
  729. return _FAIL;
  730. spin_lock_irqsave(&pfree_xmitbuf_queue->lock, irqL);
  731. list_delete(&pxmitbuf->list);
  732. list_insert_tail(&(pxmitbuf->list), get_list_head(pfree_xmitbuf_queue));
  733. pxmitpriv->free_xmitbuf_cnt++;
  734. spin_unlock_irqrestore(&pfree_xmitbuf_queue->lock, irqL);
  735. return _SUCCESS;
  736. }
  737. /*
  738. Calling context:
  739. 1. OS_TXENTRY
  740. 2. RXENTRY (rx_thread or RX_ISR/RX_CallBack)
  741. If we turn on USE_RXTHREAD, then, no need for critical section.
  742. Otherwise, we must use _enter/_exit critical to protect free_xmit_queue...
  743. Must be very very cautious...
  744. */
  745. struct xmit_frame *r8712_alloc_xmitframe(struct xmit_priv *pxmitpriv)
  746. {
  747. /*
  748. Please remember to use all the osdep_service api,
  749. and lock/unlock or _enter/_exit critical to protect
  750. pfree_xmit_queue
  751. */
  752. unsigned long irqL;
  753. struct xmit_frame *pxframe = NULL;
  754. struct list_head *plist, *phead;
  755. struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
  756. spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
  757. if (_queue_empty(pfree_xmit_queue) == true)
  758. pxframe = NULL;
  759. else {
  760. phead = get_list_head(pfree_xmit_queue);
  761. plist = get_next(phead);
  762. pxframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
  763. list_delete(&(pxframe->list));
  764. }
  765. if (pxframe != NULL) {
  766. pxmitpriv->free_xmitframe_cnt--;
  767. pxframe->buf_addr = NULL;
  768. pxframe->pxmitbuf = NULL;
  769. pxframe->attrib.psta = NULL;
  770. pxframe->pkt = NULL;
  771. }
  772. spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
  773. return pxframe;
  774. }
  775. void r8712_free_xmitframe(struct xmit_priv *pxmitpriv,
  776. struct xmit_frame *pxmitframe)
  777. {
  778. unsigned long irqL;
  779. struct __queue *pfree_xmit_queue = &pxmitpriv->free_xmit_queue;
  780. struct _adapter *padapter = pxmitpriv->adapter;
  781. if (pxmitframe == NULL)
  782. return;
  783. if (pxmitframe->pkt)
  784. r8712_xmit_complete(padapter, pxmitframe);
  785. spin_lock_irqsave(&pfree_xmit_queue->lock, irqL);
  786. list_delete(&pxmitframe->list);
  787. list_insert_tail(&pxmitframe->list, get_list_head(pfree_xmit_queue));
  788. pxmitpriv->free_xmitframe_cnt++;
  789. spin_unlock_irqrestore(&pfree_xmit_queue->lock, irqL);
  790. if (netif_queue_stopped(padapter->pnetdev))
  791. netif_wake_queue(padapter->pnetdev);
  792. }
  793. void r8712_free_xmitframe_ex(struct xmit_priv *pxmitpriv,
  794. struct xmit_frame *pxmitframe)
  795. {
  796. if (pxmitframe == NULL)
  797. return;
  798. if (pxmitframe->frame_tag == DATA_FRAMETAG)
  799. r8712_free_xmitframe(pxmitpriv, pxmitframe);
  800. }
  801. void r8712_free_xmitframe_queue(struct xmit_priv *pxmitpriv,
  802. struct __queue *pframequeue)
  803. {
  804. unsigned long irqL;
  805. struct list_head *plist, *phead;
  806. struct xmit_frame *pxmitframe;
  807. spin_lock_irqsave(&(pframequeue->lock), irqL);
  808. phead = get_list_head(pframequeue);
  809. plist = get_next(phead);
  810. while (end_of_queue_search(phead, plist) == false) {
  811. pxmitframe = LIST_CONTAINOR(plist, struct xmit_frame, list);
  812. plist = get_next(plist);
  813. r8712_free_xmitframe(pxmitpriv, pxmitframe);
  814. }
  815. spin_unlock_irqrestore(&(pframequeue->lock), irqL);
  816. }
  817. static inline struct tx_servq *get_sta_pending(struct _adapter *padapter,
  818. struct __queue **ppstapending,
  819. struct sta_info *psta, sint up)
  820. {
  821. struct tx_servq *ptxservq;
  822. struct hw_xmit *phwxmits = padapter->xmitpriv.hwxmits;
  823. switch (up) {
  824. case 1:
  825. case 2:
  826. ptxservq = &(psta->sta_xmitpriv.bk_q);
  827. *ppstapending = &padapter->xmitpriv.bk_pending;
  828. (phwxmits+3)->accnt++;
  829. break;
  830. case 4:
  831. case 5:
  832. ptxservq = &(psta->sta_xmitpriv.vi_q);
  833. *ppstapending = &padapter->xmitpriv.vi_pending;
  834. (phwxmits+1)->accnt++;
  835. break;
  836. case 6:
  837. case 7:
  838. ptxservq = &(psta->sta_xmitpriv.vo_q);
  839. *ppstapending = &padapter->xmitpriv.vo_pending;
  840. (phwxmits+0)->accnt++;
  841. break;
  842. case 0:
  843. case 3:
  844. default:
  845. ptxservq = &(psta->sta_xmitpriv.be_q);
  846. *ppstapending = &padapter->xmitpriv.be_pending;
  847. (phwxmits + 2)->accnt++;
  848. break;
  849. }
  850. return ptxservq;
  851. }
  852. /*
  853. * Will enqueue pxmitframe to the proper queue, and indicate it
  854. * to xx_pending list.....
  855. */
  856. sint r8712_xmit_classifier(struct _adapter *padapter,
  857. struct xmit_frame *pxmitframe)
  858. {
  859. unsigned long irqL0;
  860. struct __queue *pstapending;
  861. struct sta_info *psta;
  862. struct tx_servq *ptxservq;
  863. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  864. struct sta_priv *pstapriv = &padapter->stapriv;
  865. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  866. sint bmcst = IS_MCAST(pattrib->ra);
  867. if (pattrib->psta)
  868. psta = pattrib->psta;
  869. else {
  870. if (bmcst)
  871. psta = r8712_get_bcmc_stainfo(padapter);
  872. else {
  873. if (check_fwstate(pmlmepriv, WIFI_MP_STATE) == true)
  874. psta = r8712_get_stainfo(pstapriv,
  875. get_bssid(pmlmepriv));
  876. else
  877. psta = r8712_get_stainfo(pstapriv, pattrib->ra);
  878. }
  879. }
  880. if (psta == NULL)
  881. return _FAIL;
  882. ptxservq = get_sta_pending(padapter, &pstapending,
  883. psta, pattrib->priority);
  884. spin_lock_irqsave(&pstapending->lock, irqL0);
  885. if (is_list_empty(&ptxservq->tx_pending))
  886. list_insert_tail(&ptxservq->tx_pending,
  887. get_list_head(pstapending));
  888. list_insert_tail(&pxmitframe->list,
  889. get_list_head(&ptxservq->sta_pending));
  890. ptxservq->qcnt++;
  891. spin_unlock_irqrestore(&pstapending->lock, irqL0);
  892. return _SUCCESS;
  893. }
  894. static void alloc_hwxmits(struct _adapter *padapter)
  895. {
  896. struct hw_xmit *hwxmits;
  897. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  898. pxmitpriv->hwxmit_entry = HWXMIT_ENTRY;
  899. pxmitpriv->hwxmits = (struct hw_xmit *)_malloc(sizeof(struct hw_xmit) *
  900. pxmitpriv->hwxmit_entry);
  901. if (pxmitpriv->hwxmits == NULL)
  902. return;
  903. hwxmits = pxmitpriv->hwxmits;
  904. if (pxmitpriv->hwxmit_entry == 5) {
  905. pxmitpriv->bmc_txqueue.head = 0;
  906. hwxmits[0] .phwtxqueue = &pxmitpriv->bmc_txqueue;
  907. hwxmits[0] .sta_queue = &pxmitpriv->bm_pending;
  908. pxmitpriv->vo_txqueue.head = 0;
  909. hwxmits[1] .phwtxqueue = &pxmitpriv->vo_txqueue;
  910. hwxmits[1] .sta_queue = &pxmitpriv->vo_pending;
  911. pxmitpriv->vi_txqueue.head = 0;
  912. hwxmits[2] .phwtxqueue = &pxmitpriv->vi_txqueue;
  913. hwxmits[2] .sta_queue = &pxmitpriv->vi_pending;
  914. pxmitpriv->bk_txqueue.head = 0;
  915. hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
  916. hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
  917. pxmitpriv->be_txqueue.head = 0;
  918. hwxmits[4] .phwtxqueue = &pxmitpriv->be_txqueue;
  919. hwxmits[4] .sta_queue = &pxmitpriv->be_pending;
  920. } else if (pxmitpriv->hwxmit_entry == 4) {
  921. pxmitpriv->vo_txqueue.head = 0;
  922. hwxmits[0] .phwtxqueue = &pxmitpriv->vo_txqueue;
  923. hwxmits[0] .sta_queue = &pxmitpriv->vo_pending;
  924. pxmitpriv->vi_txqueue.head = 0;
  925. hwxmits[1] .phwtxqueue = &pxmitpriv->vi_txqueue;
  926. hwxmits[1] .sta_queue = &pxmitpriv->vi_pending;
  927. pxmitpriv->be_txqueue.head = 0;
  928. hwxmits[2] .phwtxqueue = &pxmitpriv->be_txqueue;
  929. hwxmits[2] .sta_queue = &pxmitpriv->be_pending;
  930. pxmitpriv->bk_txqueue.head = 0;
  931. hwxmits[3] .phwtxqueue = &pxmitpriv->bk_txqueue;
  932. hwxmits[3] .sta_queue = &pxmitpriv->bk_pending;
  933. }
  934. }
  935. static void free_hwxmits(struct _adapter *padapter)
  936. {
  937. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  938. kfree(pxmitpriv->hwxmits);
  939. }
  940. static void init_hwxmits(struct hw_xmit *phwxmit, sint entry)
  941. {
  942. sint i;
  943. for (i = 0; i < entry; i++, phwxmit++) {
  944. spin_lock_init(&phwxmit->xmit_lock);
  945. _init_listhead(&phwxmit->pending);
  946. phwxmit->txcmdcnt = 0;
  947. phwxmit->accnt = 0;
  948. }
  949. }
  950. /*
  951. * tx_action == 0 == no frames to transmit
  952. * tx_action > 0 ==> we have frames to transmit
  953. * tx_action < 0 ==> we have frames to transmit, but TXFF is not even enough
  954. * to transmit 1 frame.
  955. */
  956. int r8712_pre_xmit(struct _adapter *padapter, struct xmit_frame *pxmitframe)
  957. {
  958. unsigned long irqL;
  959. int ret;
  960. struct xmit_buf *pxmitbuf = NULL;
  961. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  962. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  963. r8712_do_queue_select(padapter, pattrib);
  964. spin_lock_irqsave(&pxmitpriv->lock, irqL);
  965. if (r8712_txframes_sta_ac_pending(padapter, pattrib) > 0) {
  966. ret = false;
  967. r8712_xmit_enqueue(padapter, pxmitframe);
  968. spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
  969. return ret;
  970. }
  971. pxmitbuf = r8712_alloc_xmitbuf(pxmitpriv);
  972. if (pxmitbuf == NULL) { /*enqueue packet*/
  973. ret = false;
  974. r8712_xmit_enqueue(padapter, pxmitframe);
  975. spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
  976. } else { /*dump packet directly*/
  977. spin_unlock_irqrestore(&pxmitpriv->lock, irqL);
  978. ret = true;
  979. pxmitframe->pxmitbuf = pxmitbuf;
  980. pxmitframe->pxmit_urb[0] = pxmitbuf->pxmit_urb[0];
  981. pxmitframe->buf_addr = pxmitbuf->pbuf;
  982. r8712_xmit_direct(padapter, pxmitframe);
  983. }
  984. return ret;
  985. }