rtl8821ce_xmit.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2016 - 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 _RTL8821CE_XMIT_C_
  16. #include <drv_types.h> /* PADAPTER, rtw_xmit.h and etc. */
  17. #include <hal_data.h> /* HAL_DATA_TYPE */
  18. #include "../halmac/halmac_api.h"
  19. #include "../rtl8821c.h"
  20. #include "rtl8821ce.h"
  21. /* Debug Buffer Descriptor Ring */
  22. /*#define BUF_DESC_DEBUG*/
  23. #ifdef BUF_DESC_DEBUG
  24. #define buf_desc_debug(...) RTW_INFO("BUF_DESC:" __VA_ARGS__)
  25. #else
  26. #define buf_desc_debug(...) do {} while (0)
  27. #endif
  28. static void rtl8821ce_xmit_tasklet(void *priv)
  29. {
  30. _irqL irqL;
  31. _adapter *padapter = (_adapter *)priv;
  32. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  33. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  34. /* try to deal with the pending packets */
  35. rtl8821ce_xmitframe_resume(padapter);
  36. }
  37. s32 rtl8821ce_init_xmit_priv(_adapter *padapter)
  38. {
  39. s32 ret = _SUCCESS;
  40. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  41. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  42. _rtw_spinlock_init(&pdvobjpriv->irq_th_lock);
  43. #ifdef PLATFORM_LINUX
  44. tasklet_init(&pxmitpriv->xmit_tasklet,
  45. (void(*)(unsigned long))rtl8821ce_xmit_tasklet,
  46. (unsigned long)padapter);
  47. #endif
  48. rtl8821c_init_xmit_priv(padapter);
  49. return ret;
  50. }
  51. void rtl8821ce_free_xmit_priv(_adapter *padapter)
  52. {
  53. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  54. _rtw_spinlock_free(&pdvobjpriv->irq_th_lock);
  55. }
  56. static s32 rtl8821ce_enqueue_xmitbuf(struct rtw_tx_ring *ring,
  57. struct xmit_buf *pxmitbuf)
  58. {
  59. _irqL irqL;
  60. _queue *ppending_queue = &ring->queue;
  61. if (pxmitbuf == NULL)
  62. return _FAIL;
  63. rtw_list_delete(&pxmitbuf->list);
  64. rtw_list_insert_tail(&(pxmitbuf->list), get_list_head(ppending_queue));
  65. ring->qlen++;
  66. return _SUCCESS;
  67. }
  68. struct xmit_buf *rtl8821ce_dequeue_xmitbuf(struct rtw_tx_ring *ring)
  69. {
  70. _irqL irqL;
  71. _list *plist, *phead;
  72. struct xmit_buf *pxmitbuf = NULL;
  73. _queue *ppending_queue = &ring->queue;
  74. if (_rtw_queue_empty(ppending_queue) == _TRUE)
  75. pxmitbuf = NULL;
  76. else {
  77. phead = get_list_head(ppending_queue);
  78. plist = get_next(phead);
  79. pxmitbuf = LIST_CONTAINOR(plist, struct xmit_buf, list);
  80. rtw_list_delete(&(pxmitbuf->list));
  81. ring->qlen--;
  82. }
  83. return pxmitbuf;
  84. }
  85. static u8 *get_txbd(_adapter *padapter, u8 q_idx)
  86. {
  87. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  88. struct rtw_tx_ring *ring;
  89. u8 *ptxbd = NULL;
  90. int idx = 0;
  91. ring = &pxmitpriv->tx_ring[q_idx];
  92. /* DO NOT use last entry. */
  93. /* (len -1) to avoid wrap around overlap problem in cycler queue. */
  94. if (ring->qlen == (ring->entries - 1)) {
  95. RTW_INFO("No more TX desc@%d, ring->idx = %d,idx = %d\n",
  96. q_idx, ring->idx, idx);
  97. return NULL;
  98. }
  99. if (q_idx == BCN_QUEUE_INX)
  100. idx = 0;
  101. else
  102. idx = (ring->idx + ring->qlen) % ring->entries;
  103. ptxbd = (u8 *)&ring->buf_desc[idx];
  104. return ptxbd;
  105. }
  106. /*
  107. * Get txbd reg addr according to q_sel
  108. */
  109. u16 get_txbd_rw_reg(u16 q_idx)
  110. {
  111. u16 txbd_reg_addr = REG_BEQ_TXBD_IDX;
  112. switch (q_idx) {
  113. case BK_QUEUE_INX:
  114. txbd_reg_addr = REG_BKQ_TXBD_IDX;
  115. break;
  116. case BE_QUEUE_INX:
  117. txbd_reg_addr = REG_BEQ_TXBD_IDX;
  118. break;
  119. case VI_QUEUE_INX:
  120. txbd_reg_addr = REG_VIQ_TXBD_IDX;
  121. break;
  122. case VO_QUEUE_INX:
  123. txbd_reg_addr = REG_VOQ_TXBD_IDX;
  124. break;
  125. case BCN_QUEUE_INX:
  126. txbd_reg_addr = REG_BEQ_TXBD_IDX; /* need check */
  127. break;
  128. case TXCMD_QUEUE_INX:
  129. txbd_reg_addr = REG_H2CQ_TXBD_IDX;
  130. break;
  131. case MGT_QUEUE_INX:
  132. txbd_reg_addr = REG_MGQ_TXBD_IDX;
  133. break;
  134. case HIGH_QUEUE_INX:
  135. txbd_reg_addr = REG_HI0Q_TXBD_IDX; /* need check */
  136. break;
  137. default:
  138. break;
  139. }
  140. return txbd_reg_addr;
  141. }
  142. struct xmit_frame *__rtw_alloc_cmdxmitframe_8821ce(struct xmit_priv *pxmitpriv,
  143. enum cmdbuf_type buf_type)
  144. {
  145. _adapter *padapter;
  146. u16 queue_idx = BCN_QUEUE_INX;
  147. u8 *ptxdesc = NULL;
  148. padapter = GET_PRIMARY_ADAPTER(pxmitpriv->adapter);
  149. ptxdesc = get_txbd(padapter, BCN_QUEUE_INX);
  150. /* set OWN bit in Beacon tx descriptor */
  151. #if 1 /* vincent TODO */
  152. if (ptxdesc != NULL)
  153. SET_TX_BD_OWN(ptxdesc, 0);
  154. else
  155. return NULL;
  156. #endif
  157. return __rtw_alloc_cmdxmitframe(pxmitpriv, CMDBUF_BEACON);
  158. }
  159. /*
  160. * Update Read/Write pointer
  161. * Read pointer is h/w descriptor index
  162. * Write pointer is host desciptor index:
  163. * For tx side, if own bit is set in packet index n,
  164. * host pointer (write pointer) point to index n + 1.)
  165. */
  166. void fill_txbd_own(_adapter *padapter, u8 *txbd, u16 queue_idx,
  167. struct rtw_tx_ring *ptxring)
  168. {
  169. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  170. struct rtw_tx_ring *ring;
  171. u16 host_wp = 0;
  172. if (queue_idx == BCN_QUEUE_INX) {
  173. SET_TX_BD_OWN(txbd, 1);
  174. /* kick start */
  175. rtw_write8(padapter, REG_RX_RXBD_NUM + 1,
  176. rtw_read8(padapter, REG_RX_RXBD_NUM + 1) | BIT(4));
  177. return;
  178. }
  179. /*
  180. * update h/w index
  181. * for tx side, if own bit is set in packet index n,
  182. * host pointer (write pointer) point to index n + 1.
  183. */
  184. /* for current tx packet, enqueue has been ring->qlen++ before.
  185. * so, host_wp = ring->idx + ring->qlen.
  186. */
  187. host_wp = (ptxring->idx + ptxring->qlen) % ptxring->entries;
  188. rtw_write16(padapter, get_txbd_rw_reg(queue_idx), host_wp);
  189. }
  190. static u16 ffaddr2dma(u32 addr)
  191. {
  192. u16 dma_ctrl;
  193. switch (addr) {
  194. case VO_QUEUE_INX:
  195. dma_ctrl = BIT3;
  196. break;
  197. case VI_QUEUE_INX:
  198. dma_ctrl = BIT2;
  199. break;
  200. case BE_QUEUE_INX:
  201. dma_ctrl = BIT1;
  202. break;
  203. case BK_QUEUE_INX:
  204. dma_ctrl = BIT0;
  205. break;
  206. case BCN_QUEUE_INX:
  207. dma_ctrl = BIT4;
  208. break;
  209. case MGT_QUEUE_INX:
  210. dma_ctrl = BIT6;
  211. break;
  212. case HIGH_QUEUE_INX:
  213. dma_ctrl = BIT7;
  214. break;
  215. default:
  216. dma_ctrl = 0;
  217. break;
  218. }
  219. return dma_ctrl;
  220. }
  221. /*
  222. * Fill tx buffer desciptor. Map each buffer address in tx buffer descriptor
  223. * segment. Designed for tx buffer descriptor architecture
  224. * Input *pmem: pointer to the Tx Buffer Descriptor
  225. */
  226. static void rtl8821ce_update_txbd(struct xmit_frame *pxmitframe,
  227. u8 *txbd, s32 sz)
  228. {
  229. _adapter *padapter = pxmitframe->padapter;
  230. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  231. dma_addr_t mapping;
  232. u32 i = 0;
  233. u16 seg_num =
  234. ((TX_BUFFER_SEG_NUM == 0) ? 2 : ((TX_BUFFER_SEG_NUM == 1) ? 4 : 8));
  235. u16 tx_page_size_reg = 1;
  236. u16 page_size_length = 0;
  237. /* map TX DESC buf_addr (including TX DESC + tx data) */
  238. mapping = pci_map_single(pdvobjpriv->ppcidev, pxmitframe->buf_addr,
  239. sz + TX_WIFI_INFO_SIZE, PCI_DMA_TODEVICE);
  240. /* Calculate page size.
  241. * Total buffer length including TX_WIFI_INFO and PacketLen
  242. */
  243. if (tx_page_size_reg > 0) {
  244. page_size_length = (sz + TX_WIFI_INFO_SIZE) /
  245. (tx_page_size_reg * 128);
  246. if (((sz + TX_WIFI_INFO_SIZE) % (tx_page_size_reg * 128)) > 0)
  247. page_size_length++;
  248. }
  249. /*
  250. * Reset all tx buffer desciprtor content
  251. * -- Reset first element
  252. */
  253. SET_TX_BD_TX_BUFF_SIZE0(txbd, 0);
  254. SET_TX_BD_PSB(txbd, 0);
  255. SET_TX_BD_OWN(txbd, 0);
  256. /* -- Reset second and other element */
  257. for (i = 1 ; i < seg_num ; i++) {
  258. SET_TXBUFFER_DESC_LEN_WITH_OFFSET(txbd, i, 0);
  259. SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(txbd, i, 0);
  260. SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(txbd, i, 0);
  261. }
  262. /*
  263. * Fill buffer length of the first buffer,
  264. * For 8821ce, it is required that TX_WIFI_INFO is put in first segment,
  265. * and the size of the first segment cannot be larger than
  266. * TX_WIFI_INFO_SIZE.
  267. */
  268. SET_TX_BD_TX_BUFF_SIZE0(txbd, TX_WIFI_INFO_SIZE);
  269. SET_TX_BD_PSB(txbd, page_size_length);
  270. /* starting addr of TXDESC */
  271. SET_TX_BD_PHYSICAL_ADDR0_LOW(txbd, mapping);
  272. #ifdef CONFIG_64BIT_DMA
  273. SET_TX_BD_PHYSICAL_ADDR0_HIGH(txbd, mapping >> 32);
  274. #endif
  275. /*
  276. * It is assumed that in linux implementation, packet is coalesced
  277. * in only one buffer. Extension mode is not supported here
  278. */
  279. SET_TXBUFFER_DESC_LEN_WITH_OFFSET(txbd, 1, sz);
  280. /* don't using extendsion mode. */
  281. SET_TXBUFFER_DESC_AMSDU_WITH_OFFSET(txbd, 1, 0);
  282. SET_TXBUFFER_DESC_ADD_LOW_WITH_OFFSET(txbd, 1,
  283. mapping + TX_WIFI_INFO_SIZE); /* pkt */
  284. #ifdef CONFIG_64BIT_DMA
  285. SET_TXBUFFER_DESC_ADD_HIGH_WITH_OFFSET(txbd, 1,
  286. (mapping + TX_WIFI_INFO_SIZE) >> 32); /* pkt */
  287. #endif
  288. /*buf_desc_debug("TX:%s, txbd = 0x%p\n", __FUNCTION__, txbd);*/
  289. buf_desc_debug("%s, txbd = 0x%08x\n", __func__, txbd);
  290. buf_desc_debug("TXBD:, 00h(0x%08x)\n", *((u32 *)(txbd)));
  291. buf_desc_debug("TXBD:, 04h(0x%08x)\n", *((u32 *)(txbd + 4)));
  292. buf_desc_debug("TXBD:, 08h(0x%08x)\n", *((u32 *)(txbd + 8)));
  293. buf_desc_debug("TXBD:, 12h(0x%08x)\n", *((u32 *)(txbd + 12)));
  294. }
  295. static s32 update_txdesc(struct xmit_frame *pxmitframe, s32 sz)
  296. {
  297. uint qsel;
  298. u8 data_rate, pwr_status;
  299. _adapter *padapter = pxmitframe->padapter;
  300. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  301. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  302. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  303. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  304. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  305. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  306. u8 *ptxdesc;
  307. sint bmcst = IS_MCAST(pattrib->ra);
  308. u16 SWDefineContent = 0x0;
  309. u8 DriverFixedRate = 0x0;
  310. u8 hw_port = rtw_hal_get_port(padapter);
  311. ptxdesc = pxmitframe->buf_addr;
  312. _rtw_memset(ptxdesc, 0, TXDESC_SIZE);
  313. /* offset 0 */
  314. /*SET_TX_DESC_FIRST_SEG_8812(ptxdesc, 1);*/
  315. SET_TX_DESC_LS_8821C(ptxdesc, 1);
  316. /*SET_TX_DESC_OWN_8812(ptxdesc, 1);*/
  317. SET_TX_DESC_TXPKTSIZE_8821C(ptxdesc, sz);
  318. /* TX_DESC is not included in the data,
  319. * driver needs to fill in the TX_DESC with qsel=h2c
  320. * Offset in TX_DESC should be set to 0.
  321. */
  322. #ifdef CONFIG_TX_EARLY_MODE
  323. SET_TX_DESC_PKT_OFFSET_8812(ptxdesc, 1);
  324. if (pattrib->qsel == HALMAC_TXDESC_QSEL_H2C_CMD)
  325. SET_TX_DESC_OFFSET_8821C(ptxdesc, 0);
  326. else
  327. SET_TX_DESC_OFFSET_8821C(ptxdesc,
  328. TXDESC_SIZE + EARLY_MODE_INFO_SIZE);
  329. #else
  330. if (pattrib->qsel == HALMAC_TXDESC_QSEL_H2C_CMD)
  331. SET_TX_DESC_OFFSET_8821C(ptxdesc, 0);
  332. else
  333. SET_TX_DESC_OFFSET_8821C(ptxdesc, TXDESC_SIZE);
  334. #endif
  335. if (bmcst)
  336. SET_TX_DESC_BMC_8821C(ptxdesc, 1);
  337. SET_TX_DESC_MACID_8821C(ptxdesc, pattrib->mac_id);
  338. SET_TX_DESC_RATE_ID_8821C(ptxdesc, pattrib->raid);
  339. SET_TX_DESC_QSEL_8821C(ptxdesc, pattrib->qsel);
  340. if (!pattrib->qos_en) {
  341. /* Hw set sequence number */
  342. SET_TX_DESC_DISQSELSEQ_8821C(ptxdesc, 1);
  343. SET_TX_DESC_EN_HWSEQ_8821C(ptxdesc, 1);
  344. SET_TX_DESC_HW_SSN_SEL_8821C(ptxdesc, pattrib->hw_ssn_sel);
  345. SET_TX_DESC_EN_HWEXSEQ_8821C(ptxdesc, 0);
  346. } else
  347. SET_TX_DESC_SW_SEQ_8821C(ptxdesc, pattrib->seqnum);
  348. if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
  349. rtl8821c_fill_txdesc_sectype(pattrib, ptxdesc);
  350. rtl8821c_fill_txdesc_vcs(padapter, pattrib, ptxdesc);
  351. #ifdef CONFIG_CONCURRENT_MODE
  352. if (bmcst)
  353. fill_txdesc_force_bmc_camid(pattrib, ptxdesc);
  354. #endif
  355. #ifdef CONFIG_SUPPORT_DYNAMIC_TXPWR
  356. rtw_phydm_set_dyntxpwr(padapter, ptxdesc, pattrib->mac_id);
  357. #endif
  358. if ((pattrib->ether_type != 0x888e) &&
  359. (pattrib->ether_type != 0x0806) &&
  360. (pattrib->ether_type != 0x88b4) &&
  361. (pattrib->dhcp_pkt != 1)
  362. #ifdef CONFIG_AUTO_AP_MODE
  363. && (pattrib->pctrl != _TRUE)
  364. #endif
  365. ) {
  366. /* Non EAP & ARP & DHCP type data packet */
  367. if (pattrib->ampdu_en == _TRUE) {
  368. /* 8821c does NOT support AGG broadcast pkt */
  369. if (!bmcst)
  370. SET_TX_DESC_AGG_EN_8821C(ptxdesc, 1);
  371. SET_TX_DESC_MAX_AGG_NUM_8821C(ptxdesc, 0x1f);
  372. /* Set A-MPDU aggregation. */
  373. SET_TX_DESC_AMPDU_DENSITY_8821C(ptxdesc,
  374. pattrib->ampdu_spacing);
  375. } else
  376. SET_TX_DESC_BK_8821C(ptxdesc, 1);
  377. rtl8821c_fill_txdesc_phy(padapter, pattrib, ptxdesc);
  378. /* DATA Rate FB LMT */
  379. /* compatibility for MCC consideration,
  380. * use pmlmeext->cur_channel
  381. */
  382. if (pmlmeext->cur_channel > 14)
  383. /* for 5G. OFMD 6M */
  384. SET_TX_DESC_DATA_RTY_LOWEST_RATE_8821C(
  385. ptxdesc, 4);
  386. else
  387. /* for 2.4G. CCK 1M */
  388. SET_TX_DESC_DATA_RTY_LOWEST_RATE_8821C(
  389. ptxdesc, 0);
  390. if (pHalData->fw_ractrl == _FALSE) {
  391. SET_TX_DESC_USE_RATE_8821C(ptxdesc, 1);
  392. DriverFixedRate = 0x01;
  393. if (pHalData->INIDATA_RATE[pattrib->mac_id] &
  394. BIT(7))
  395. SET_TX_DESC_DATA_SHORT_8821C(
  396. ptxdesc, 1);
  397. SET_TX_DESC_DATARATE_8821C(ptxdesc,
  398. pHalData->INIDATA_RATE[pattrib->mac_id]
  399. & 0x7F);
  400. }
  401. if (bmcst) {
  402. DriverFixedRate = 0x01;
  403. fill_txdesc_bmc_tx_rate(pattrib, ptxdesc);
  404. }
  405. if (padapter->fix_rate != 0xFF) {
  406. /* modify data rate by iwpriv */
  407. SET_TX_DESC_USE_RATE_8821C(ptxdesc, 1);
  408. DriverFixedRate = 0x01;
  409. if (padapter->fix_rate & BIT(7))
  410. SET_TX_DESC_DATA_SHORT_8821C(
  411. ptxdesc, 1);
  412. SET_TX_DESC_DATARATE_8821C(ptxdesc,
  413. (padapter->fix_rate & 0x7F));
  414. if (!padapter->data_fb)
  415. SET_TX_DESC_DISDATAFB_8821C(ptxdesc, 1);
  416. }
  417. if (pattrib->ldpc)
  418. SET_TX_DESC_DATA_LDPC_8821C(ptxdesc, 1);
  419. if (pattrib->stbc)
  420. SET_TX_DESC_DATA_STBC_8821C(ptxdesc, 1);
  421. #ifdef CONFIG_WMMPS_STA
  422. if (pattrib->trigger_frame)
  423. SET_TX_DESC_TRI_FRAME_8821C (ptxdesc, 1);
  424. #endif /* CONFIG_WMMPS_STA */
  425. } else {
  426. /*
  427. * EAP data packet and ARP packet and DHCP.
  428. * Use the 1M data rate to send the EAP/ARP packet.
  429. * This will maybe make the handshake smooth.
  430. */
  431. SET_TX_DESC_USE_RATE_8821C(ptxdesc, 1);
  432. DriverFixedRate = 0x01;
  433. SET_TX_DESC_BK_8821C(ptxdesc, 1);
  434. /* HW will ignore this setting if the transmission rate
  435. * is legacy OFDM.
  436. */
  437. if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
  438. SET_TX_DESC_DATA_SHORT_8821C(ptxdesc, 1);
  439. SET_TX_DESC_DATARATE_8821C(ptxdesc,
  440. MRateToHwRate(pmlmeext->tx_rate));
  441. }
  442. #ifdef CONFIG_TDLS
  443. #ifdef CONFIG_XMIT_ACK
  444. /* CCX-TXRPT ack for xmit mgmt frames. */
  445. if (pxmitframe->ack_report) {
  446. SET_TX_DESC_SPE_RPT_8821C(ptxdesc, 1);
  447. #ifdef DBG_CCX
  448. RTW_INFO("%s set tx report\n", __func__);
  449. #endif
  450. }
  451. #endif /* CONFIG_XMIT_ACK */
  452. #endif
  453. } else if ((pxmitframe->frame_tag & 0x0f) == MGNT_FRAMETAG) {
  454. SET_TX_DESC_MBSSID_8821C(ptxdesc, pattrib->mbssid & 0xF);
  455. SET_TX_DESC_USE_RATE_8821C(ptxdesc, 1);
  456. DriverFixedRate = 0x01;
  457. SET_TX_DESC_DATARATE_8821C(ptxdesc, MRateToHwRate(pattrib->rate));
  458. SET_TX_DESC_RTY_LMT_EN_8821C(ptxdesc, 1);
  459. if (pattrib->retry_ctrl == _TRUE)
  460. SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(ptxdesc, 6);
  461. else
  462. SET_TX_DESC_RTS_DATA_RTY_LMT_8821C(ptxdesc, 12);
  463. /*rtl8821c_fill_txdesc_mgnt_bf(pxmitframe, ptxdesc); Todo for 8821C*/
  464. #ifdef CONFIG_XMIT_ACK
  465. /* CCX-TXRPT ack for xmit mgmt frames. */
  466. if (pxmitframe->ack_report) {
  467. SET_TX_DESC_SPE_RPT_8821C(ptxdesc, 1);
  468. #ifdef DBG_CCX
  469. RTW_INFO("%s set tx report\n", __func__);
  470. #endif
  471. }
  472. #endif /* CONFIG_XMIT_ACK */
  473. } else if ((pxmitframe->frame_tag & 0x0f) == TXAGG_FRAMETAG)
  474. RTW_INFO("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
  475. #ifdef CONFIG_MP_INCLUDED
  476. else if (((pxmitframe->frame_tag & 0x0f) == MP_FRAMETAG) &&
  477. (padapter->registrypriv.mp_mode == 1))
  478. fill_txdesc_for_mp(padapter, ptxdesc);
  479. #endif
  480. else {
  481. RTW_INFO("pxmitframe->frame_tag = %d\n",
  482. pxmitframe->frame_tag);
  483. SET_TX_DESC_USE_RATE_8821C(ptxdesc, 1);
  484. DriverFixedRate = 0x01;
  485. SET_TX_DESC_DATARATE_8821C(ptxdesc,
  486. MRateToHwRate(pmlmeext->tx_rate));
  487. }
  488. #ifdef CONFIG_ANTENNA_DIVERSITY
  489. ODM_SetTxAntByTxInfo(&pHalData->odmpriv, ptxdesc,
  490. pxmitframe->attrib.mac_id);
  491. #endif
  492. /*rtl8821c_fill_txdesc_bf(pxmitframe, ptxdesc);Todo for 8821C*/
  493. /*SET_TX_DESC_TX_BUFFER_SIZE_8812(ptxdesc, sz);*/
  494. if (DriverFixedRate)
  495. SWDefineContent |= 0x01;
  496. SET_TX_DESC_SW_DEFINE_8821C(ptxdesc, SWDefineContent);
  497. SET_TX_DESC_PORT_ID_8821C(ptxdesc, hw_port);
  498. SET_TX_DESC_MULTIPLE_PORT_8821C(ptxdesc, hw_port);
  499. rtl8821c_cal_txdesc_chksum(padapter, ptxdesc);
  500. rtl8821c_dbg_dump_tx_desc(padapter, pxmitframe->frame_tag, ptxdesc);
  501. return 0;
  502. }
  503. s32 rtl8821ce_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
  504. {
  505. s32 ret = _SUCCESS;
  506. s32 inner_ret = _SUCCESS;
  507. _irqL irqL;
  508. int t, sz, w_sz, pull = 0;
  509. u32 ff_hwaddr;
  510. struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
  511. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  512. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  513. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  514. struct security_priv *psecuritypriv = &padapter->securitypriv;
  515. u8 *txbd;
  516. struct rtw_tx_ring *ptx_ring;
  517. #ifdef CONFIG_80211N_HT
  518. if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
  519. (pxmitframe->attrib.ether_type != 0x0806) &&
  520. (pxmitframe->attrib.ether_type != 0x888e) &&
  521. (pxmitframe->attrib.dhcp_pkt != 1))
  522. rtw_issue_addbareq_cmd(padapter, pxmitframe);
  523. #endif /* CONFIG_80211N_HT */
  524. for (t = 0; t < pattrib->nr_frags; t++) {
  525. if (inner_ret != _SUCCESS && ret == _SUCCESS)
  526. ret = _FAIL;
  527. if (t != (pattrib->nr_frags - 1)) {
  528. sz = pxmitpriv->frag_len - 4;
  529. if (!psecuritypriv->sw_encrypt)
  530. sz -= pattrib->icv_len;
  531. } else {
  532. /* no frag */
  533. sz = pattrib->last_txcmdsz;
  534. }
  535. ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
  536. _enter_critical(&pdvobjpriv->irq_th_lock, &irqL);
  537. txbd = get_txbd(GET_PRIMARY_ADAPTER(padapter), ff_hwaddr);
  538. ptx_ring = &(GET_PRIMARY_ADAPTER(padapter)->xmitpriv.tx_ring[ff_hwaddr]);
  539. #ifndef CONFIG_BCN_ICF
  540. if (ff_hwaddr == BCN_QUEUE_INX)
  541. padapter->xmitpriv.beaconDMAing = _TRUE;
  542. #endif
  543. if (txbd == NULL) {
  544. _exit_critical(&pdvobjpriv->irq_th_lock, &irqL);
  545. rtw_sctx_done_err(&pxmitbuf->sctx,
  546. RTW_SCTX_DONE_TX_DESC_NA);
  547. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  548. RTW_INFO("##### Tx desc unavailable !#####\n");
  549. break;
  550. }
  551. if (pattrib->qsel != HALMAC_TXDESC_QSEL_H2C_CMD)
  552. update_txdesc(pxmitframe, sz);
  553. /* rtl8821ce_update_txbd() must be called after update_txdesc()
  554. * It rely on rtl8821ce_update_txbd() to map it into non cache memory
  555. */
  556. rtl8821ce_update_txbd(pxmitframe, txbd, sz);
  557. if (pxmitbuf->buf_tag != XMITBUF_CMD)
  558. rtl8821ce_enqueue_xmitbuf(ptx_ring, pxmitbuf);
  559. pxmitbuf->len = sz + TX_WIFI_INFO_SIZE;
  560. w_sz = sz;
  561. /* Please comment here */
  562. wmb();
  563. fill_txbd_own(padapter, txbd, ff_hwaddr, ptx_ring);
  564. #ifdef DBG_TXBD_DESC_DUMP
  565. if (pxmitpriv->dump_txbd_desc)
  566. rtw_tx_desc_backup(padapter, pxmitframe, TX_WIFI_INFO_SIZE, ff_hwaddr);
  567. #endif
  568. _exit_critical(&pdvobjpriv->irq_th_lock, &irqL);
  569. inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz,
  570. (unsigned char *)pxmitbuf);
  571. rtw_count_tx_stats(padapter, pxmitframe, sz);
  572. }
  573. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  574. if (ret != _SUCCESS)
  575. rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
  576. return ret;
  577. }
  578. /*
  579. * Packet should not be dequeued if there is no available descriptor
  580. * return: _SUCCESS if there is available descriptor
  581. */
  582. static u8 check_tx_desc_resource(_adapter *padapter, int prio)
  583. {
  584. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  585. struct rtw_tx_ring *ring;
  586. ring = &pxmitpriv->tx_ring[prio];
  587. /*
  588. * for now we reserve two free descriptor as a safety boundary
  589. * between the tail and the head
  590. */
  591. if ((ring->entries - ring->qlen) >= 2)
  592. return _TRUE;
  593. else
  594. return _FALSE;
  595. }
  596. static u8 check_nic_enough_desc_all(_adapter *padapter)
  597. {
  598. u8 status = (check_tx_desc_resource(padapter, VI_QUEUE_INX) &&
  599. check_tx_desc_resource(padapter, VO_QUEUE_INX) &&
  600. check_tx_desc_resource(padapter, BE_QUEUE_INX) &&
  601. check_tx_desc_resource(padapter, BK_QUEUE_INX) &&
  602. check_tx_desc_resource(padapter, MGT_QUEUE_INX) &&
  603. check_tx_desc_resource(padapter, TXCMD_QUEUE_INX) &&
  604. check_tx_desc_resource(padapter, HIGH_QUEUE_INX));
  605. return status;
  606. }
  607. static u8 check_nic_enough_desc(_adapter *padapter, struct pkt_attrib *pattrib)
  608. {
  609. u32 prio;
  610. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  611. struct rtw_tx_ring *ring;
  612. switch (pattrib->qsel) {
  613. case 0:
  614. case 3:
  615. prio = BE_QUEUE_INX;
  616. break;
  617. case 1:
  618. case 2:
  619. prio = BK_QUEUE_INX;
  620. break;
  621. case 4:
  622. case 5:
  623. prio = VI_QUEUE_INX;
  624. break;
  625. case 6:
  626. case 7:
  627. prio = VO_QUEUE_INX;
  628. break;
  629. default:
  630. prio = BE_QUEUE_INX;
  631. break;
  632. }
  633. ring = &pxmitpriv->tx_ring[prio];
  634. /*
  635. * for now we reserve two free descriptor as a safety boundary
  636. * between the tail and the head
  637. */
  638. if ((ring->entries - ring->qlen) >= 2)
  639. return _TRUE;
  640. else
  641. return _FALSE;
  642. }
  643. #ifdef CONFIG_XMIT_THREAD_MODE
  644. /*
  645. * Description
  646. * Transmit xmitbuf to hardware tx fifo
  647. *
  648. * Return
  649. * _SUCCESS ok
  650. * _FAIL something error
  651. */
  652. s32 rtl8821ce_xmit_buf_handler(_adapter *padapter)
  653. {
  654. PHAL_DATA_TYPE phal;
  655. struct xmit_priv *pxmitpriv;
  656. struct xmit_buf *pxmitbuf;
  657. struct xmit_frame *pxmitframe;
  658. s32 ret;
  659. phal = GET_HAL_DATA(padapter);
  660. pxmitpriv = &padapter->xmitpriv;
  661. ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
  662. if (ret == _FAIL) {
  663. RTW_ERR("%s: down XmitBufSema fail!\n", __FUNCTION__);
  664. return _FAIL;
  665. }
  666. if (RTW_CANNOT_RUN(padapter)) {
  667. RTW_INFO("%s: bDriverStopped(%s) bSurpriseRemoved(%s)!\n"
  668. , __func__
  669. , rtw_is_drv_stopped(padapter)?"True":"False"
  670. , rtw_is_surprise_removed(padapter)?"True":"False");
  671. return _FAIL;
  672. }
  673. if (check_pending_xmitbuf(pxmitpriv) == _FALSE)
  674. return _SUCCESS;
  675. #ifdef CONFIG_LPS_LCLK
  676. ret = rtw_register_tx_alive(padapter);
  677. if (ret != _SUCCESS) {
  678. RTW_INFO("%s: wait to leave LPS_LCLK\n", __FUNCTION__);
  679. return _SUCCESS;
  680. }
  681. #endif
  682. do {
  683. pxmitbuf = select_and_dequeue_pending_xmitbuf(padapter);
  684. if (pxmitbuf == NULL)
  685. break;
  686. pxmitframe = (struct xmit_frame *)pxmitbuf->priv_data;
  687. if (check_nic_enough_desc(padapter, &pxmitframe->attrib) == _FALSE) {
  688. enqueue_pending_xmitbuf_to_head(pxmitpriv, pxmitbuf);
  689. break;
  690. }
  691. rtl8821ce_dump_xframe(padapter, pxmitframe);
  692. } while (1);
  693. return _SUCCESS;
  694. }
  695. #endif
  696. static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
  697. {
  698. #ifdef CONFIG_XMIT_THREAD_MODE
  699. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  700. #endif
  701. s32 res = _SUCCESS;
  702. res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
  703. if (res == _SUCCESS) {
  704. #ifdef CONFIG_XMIT_THREAD_MODE
  705. enqueue_pending_xmitbuf(pxmitpriv, pxmitframe->pxmitbuf);
  706. #else
  707. rtl8821ce_dump_xframe(padapter, pxmitframe);
  708. #endif
  709. }
  710. return res;
  711. }
  712. #ifdef CONFIG_TX_AMSDU
  713. static s32 xmitframe_amsdu_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
  714. {
  715. struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
  716. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  717. s32 res = _SUCCESS;
  718. res = rtw_xmitframe_coalesce_amsdu(padapter, pxmitframe, NULL);
  719. if (res == _SUCCESS) {
  720. #ifdef CONFIG_XMIT_THREAD_MODE
  721. enqueue_pending_xmitbuf(pxmitpriv, pxmitframe->pxmitbuf);
  722. #else
  723. res = rtl8821ce_dump_xframe(padapter, pxmitframe);
  724. #endif
  725. } else {
  726. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  727. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  728. }
  729. return res;
  730. }
  731. #endif
  732. void rtl8821ce_xmitframe_resume(_adapter *padapter)
  733. {
  734. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  735. struct xmit_frame *pxmitframe = NULL;
  736. struct xmit_buf *pxmitbuf = NULL;
  737. int res = _SUCCESS, xcnt = 0;
  738. #ifdef CONFIG_TX_AMSDU
  739. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  740. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  741. int tx_amsdu = padapter->tx_amsdu;
  742. int tx_amsdu_rate = padapter->tx_amsdu_rate;
  743. int current_tx_rate = pdvobjpriv->traffic_stat.cur_tx_tp;
  744. struct pkt_attrib *pattrib = NULL;
  745. struct xmit_frame *pxmitframe_next = NULL;
  746. struct xmit_buf *pxmitbuf_next = NULL;
  747. struct pkt_attrib *pattrib_next = NULL;
  748. int num_frame = 0;
  749. u8 amsdu_timeout = 0;
  750. #endif
  751. while (1) {
  752. if (RTW_CANNOT_RUN(padapter)) {
  753. RTW_INFO("%s => bDriverStopped or bSurpriseRemoved\n",
  754. __func__);
  755. break;
  756. }
  757. #ifndef CONFIG_XMIT_THREAD_MODE
  758. if (!check_nic_enough_desc_all(padapter))
  759. break;
  760. #endif
  761. pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
  762. if (!pxmitbuf)
  763. break;
  764. #ifdef CONFIG_TX_AMSDU
  765. if (tx_amsdu == 0)
  766. goto dump_pkt;
  767. if (!check_fwstate(pmlmepriv, WIFI_STATION_STATE))
  768. goto dump_pkt;
  769. pxmitframe = rtw_get_xframe(pxmitpriv, &num_frame);
  770. if (num_frame == 0 || pxmitframe == NULL || !check_amsdu(pxmitframe))
  771. goto dump_pkt;
  772. pattrib = &pxmitframe->attrib;
  773. if (tx_amsdu == 1) {
  774. pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits,
  775. pxmitpriv->hwxmit_entry);
  776. if (pxmitframe) {
  777. pxmitframe->pxmitbuf = pxmitbuf;
  778. pxmitframe->buf_addr = pxmitbuf->pbuf;
  779. pxmitbuf->priv_data = pxmitframe;
  780. xmitframe_amsdu_direct(padapter, pxmitframe);
  781. pxmitpriv->amsdu_debug_coalesce_one++;
  782. continue;
  783. } else {
  784. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  785. break;
  786. }
  787. } else if (tx_amsdu == 2 && ((tx_amsdu_rate == 0) || (current_tx_rate > tx_amsdu_rate))) {
  788. if (num_frame == 1) {
  789. amsdu_timeout = rtw_amsdu_get_timer_status(padapter, pattrib->priority);
  790. if (amsdu_timeout == RTW_AMSDU_TIMER_UNSET) {
  791. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  792. rtw_amsdu_set_timer_status(padapter,
  793. pattrib->priority, RTW_AMSDU_TIMER_SETTING);
  794. rtw_amsdu_set_timer(padapter, pattrib->priority);
  795. pxmitpriv->amsdu_debug_set_timer++;
  796. break;
  797. } else if (amsdu_timeout == RTW_AMSDU_TIMER_SETTING) {
  798. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  799. break;
  800. } else if (amsdu_timeout == RTW_AMSDU_TIMER_TIMEOUT) {
  801. rtw_amsdu_set_timer_status(padapter,
  802. pattrib->priority, RTW_AMSDU_TIMER_UNSET);
  803. pxmitpriv->amsdu_debug_timeout++;
  804. pxmitframe = rtw_dequeue_xframe(pxmitpriv,
  805. pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
  806. if (pxmitframe) {
  807. pxmitframe->pxmitbuf = pxmitbuf;
  808. pxmitframe->buf_addr = pxmitbuf->pbuf;
  809. pxmitbuf->priv_data = pxmitframe;
  810. xmitframe_amsdu_direct(padapter, pxmitframe);
  811. } else {
  812. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  813. }
  814. break;
  815. }
  816. } else/* num_frame > 1*/{
  817. pxmitframe = rtw_dequeue_xframe(pxmitpriv,
  818. pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
  819. if (!pxmitframe) {
  820. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  821. break;
  822. }
  823. pxmitframe->pxmitbuf = pxmitbuf;
  824. pxmitframe->buf_addr = pxmitbuf->pbuf;
  825. pxmitbuf->priv_data = pxmitframe;
  826. pxmitframe_next = rtw_get_xframe(pxmitpriv, &num_frame);
  827. if (num_frame == 0) {
  828. xmitframe_amsdu_direct(padapter, pxmitframe);
  829. pxmitpriv->amsdu_debug_coalesce_one++;
  830. break;
  831. }
  832. if (!check_amsdu(pxmitframe_next)) {
  833. xmitframe_amsdu_direct(padapter, pxmitframe);
  834. pxmitpriv->amsdu_debug_coalesce_one++;
  835. continue;
  836. } else {
  837. pxmitbuf_next = rtw_alloc_xmitbuf(pxmitpriv);
  838. if (!pxmitbuf_next) {
  839. xmitframe_amsdu_direct(padapter, pxmitframe);
  840. pxmitpriv->amsdu_debug_coalesce_one++;
  841. continue;
  842. }
  843. pxmitframe_next = rtw_dequeue_xframe(pxmitpriv,
  844. pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
  845. if (!pxmitframe_next) {
  846. rtw_free_xmitbuf(pxmitpriv, pxmitbuf_next);
  847. xmitframe_amsdu_direct(padapter, pxmitframe);
  848. pxmitpriv->amsdu_debug_coalesce_one++;
  849. continue;
  850. }
  851. pxmitframe_next->pxmitbuf = pxmitbuf_next;
  852. pxmitframe_next->buf_addr = pxmitbuf_next->pbuf;
  853. pxmitbuf_next->priv_data = pxmitframe_next;
  854. rtw_xmitframe_coalesce_amsdu(padapter,
  855. pxmitframe_next, pxmitframe);
  856. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  857. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  858. #ifdef CONFIG_XMIT_THREAD_MODE
  859. enqueue_pending_xmitbuf(pxmitpriv, pxmitframe_next->pxmitbuf);
  860. #else
  861. rtl8821ce_dump_xframe(padapter, pxmitframe_next);
  862. #endif
  863. pxmitpriv->amsdu_debug_coalesce_two++;
  864. continue;
  865. }
  866. }
  867. }
  868. dump_pkt:
  869. #endif /* CONFIG_TX_AMSDU */
  870. pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits,
  871. pxmitpriv->hwxmit_entry);
  872. if (pxmitframe) {
  873. pxmitframe->pxmitbuf = pxmitbuf;
  874. pxmitframe->buf_addr = pxmitbuf->pbuf;
  875. pxmitbuf->priv_data = pxmitframe;
  876. if ((pxmitframe->frame_tag & 0x0f) == DATA_FRAMETAG) {
  877. if (pxmitframe->attrib.priority <= 15) {
  878. /* TID0~15 */
  879. res = rtw_xmitframe_coalesce(padapter,
  880. pxmitframe->pkt, pxmitframe);
  881. }
  882. /* always return ndis_packet after
  883. * rtw_xmitframe_coalesce
  884. */
  885. rtw_os_xmit_complete(padapter, pxmitframe);
  886. }
  887. if (res == _SUCCESS) {
  888. #ifdef CONFIG_XMIT_THREAD_MODE
  889. enqueue_pending_xmitbuf(pxmitpriv, pxmitframe->pxmitbuf);
  890. #else
  891. rtl8821ce_dump_xframe(padapter, pxmitframe);
  892. #endif
  893. } else {
  894. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  895. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  896. }
  897. xcnt++;
  898. } else {
  899. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  900. break;
  901. }
  902. }
  903. }
  904. /*
  905. * Return
  906. * _TRUE dump packet directly
  907. * _FALSE enqueue packet
  908. */
  909. static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
  910. {
  911. _irqL irqL;
  912. s32 res;
  913. struct xmit_buf *pxmitbuf = NULL;
  914. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  915. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  916. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  917. #ifdef CONFIG_TX_AMSDU
  918. int tx_amsdu = padapter->tx_amsdu;
  919. u8 amsdu_timeout = 0;
  920. #endif
  921. _enter_critical_bh(&pxmitpriv->lock, &irqL);
  922. if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
  923. goto enqueue;
  924. #ifndef CONFIG_XMIT_THREAD_MODE
  925. if (check_nic_enough_desc(padapter, pattrib) == _FALSE)
  926. goto enqueue;
  927. if (rtw_xmit_ac_blocked(padapter) == _TRUE)
  928. goto enqueue;
  929. #endif
  930. if (DEV_STA_LG_NUM(padapter->dvobj))
  931. goto enqueue;
  932. #ifdef CONFIG_TX_AMSDU
  933. if (check_fwstate(pmlmepriv, WIFI_STATION_STATE) &&
  934. check_amsdu_tx_support(padapter)) {
  935. if (IS_AMSDU_AMPDU_VALID(pattrib))
  936. goto enqueue;
  937. }
  938. #endif
  939. pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
  940. if (pxmitbuf == NULL)
  941. goto enqueue;
  942. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  943. pxmitframe->pxmitbuf = pxmitbuf;
  944. pxmitframe->buf_addr = pxmitbuf->pbuf;
  945. pxmitbuf->priv_data = pxmitframe;
  946. if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
  947. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  948. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  949. }
  950. return _TRUE;
  951. enqueue:
  952. res = rtw_xmitframe_enqueue(padapter, pxmitframe);
  953. #ifdef CONFIG_TX_AMSDU
  954. if (res == _SUCCESS && tx_amsdu == 2) {
  955. amsdu_timeout = rtw_amsdu_get_timer_status(padapter, pattrib->priority);
  956. if (amsdu_timeout == RTW_AMSDU_TIMER_SETTING) {
  957. rtw_amsdu_cancel_timer(padapter, pattrib->priority);
  958. rtw_amsdu_set_timer_status(padapter, pattrib->priority,
  959. RTW_AMSDU_TIMER_UNSET);
  960. }
  961. }
  962. #endif
  963. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  964. if (res != _SUCCESS) {
  965. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  966. pxmitpriv->tx_drop++;
  967. return _TRUE;
  968. }
  969. #ifdef CONFIG_TX_AMSDU
  970. tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
  971. #endif
  972. return _FALSE;
  973. }
  974. s32 rtl8821ce_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
  975. {
  976. #ifdef CONFIG_XMIT_THREAD_MODE
  977. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  978. struct pkt_attrib *pattrib = &pmgntframe->attrib;
  979. s32 ret = _SUCCESS;
  980. /* For FW download rsvd page and H2C pkt */
  981. if ((pattrib->qsel == QSLT_CMD) || (pattrib->qsel == QSLT_BEACON))
  982. ret = rtl8821ce_dump_xframe(padapter, pmgntframe);
  983. else
  984. enqueue_pending_xmitbuf(pxmitpriv, pmgntframe->pxmitbuf);
  985. return ret;
  986. #else
  987. return rtl8821ce_dump_xframe(padapter, pmgntframe);
  988. #endif
  989. }
  990. /*
  991. * Return
  992. * _TRUE dump packet directly ok
  993. * _FALSE temporary can't transmit packets to hardware
  994. */
  995. s32 rtl8821ce_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
  996. {
  997. return pre_xmitframe(padapter, pxmitframe);
  998. }
  999. s32 rtl8821ce_hal_xmitframe_enqueue(_adapter *padapter,
  1000. struct xmit_frame *pxmitframe)
  1001. {
  1002. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  1003. s32 err;
  1004. err = rtw_xmitframe_enqueue(padapter, pxmitframe);
  1005. if (err != _SUCCESS) {
  1006. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  1007. pxmitpriv->tx_drop++;
  1008. } else {
  1009. #ifdef PLATFORM_LINUX
  1010. if (check_nic_enough_desc(padapter,
  1011. &pxmitframe->attrib) == _TRUE)
  1012. tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
  1013. #endif
  1014. }
  1015. return err;
  1016. }
  1017. int rtl8821ce_init_txbd_ring(_adapter *padapter, unsigned int q_idx,
  1018. unsigned int entries)
  1019. {
  1020. struct xmit_priv *t_priv = &padapter->xmitpriv;
  1021. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  1022. struct pci_dev *pdev = pdvobjpriv->ppcidev;
  1023. struct tx_buf_desc *txbd;
  1024. u8 *tx_desc;
  1025. dma_addr_t dma;
  1026. int i;
  1027. RTW_INFO("%s entries num:%d\n", __func__, entries);
  1028. txbd = pci_alloc_consistent(pdev, sizeof(*txbd) * entries, &dma);
  1029. if (!txbd || (unsigned long)txbd & 0xFF) {
  1030. RTW_INFO("Cannot allocate TXBD (q_idx = %d)\n", q_idx);
  1031. return _FAIL;
  1032. }
  1033. _rtw_memset(txbd, 0, sizeof(*txbd) * entries);
  1034. t_priv->tx_ring[q_idx].buf_desc = txbd;
  1035. t_priv->tx_ring[q_idx].dma = dma;
  1036. t_priv->tx_ring[q_idx].idx = 0;
  1037. t_priv->tx_ring[q_idx].entries = entries;
  1038. _rtw_init_queue(&t_priv->tx_ring[q_idx].queue);
  1039. t_priv->tx_ring[q_idx].qlen = 0;
  1040. RTW_INFO("%s queue:%d, ring_addr:%p\n", __func__, q_idx, txbd);
  1041. return _SUCCESS;
  1042. }
  1043. void rtl8821ce_free_txbd_ring(_adapter *padapter, unsigned int prio)
  1044. {
  1045. struct xmit_priv *t_priv = &padapter->xmitpriv;
  1046. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(padapter);
  1047. struct pci_dev *pdev = pdvobjpriv->ppcidev;
  1048. struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
  1049. u8 *txbd;
  1050. struct xmit_buf *pxmitbuf;
  1051. dma_addr_t mapping;
  1052. while (ring->qlen) {
  1053. txbd = (u8 *)(&ring->buf_desc[ring->idx]);
  1054. SET_TX_BD_OWN(txbd, 0);
  1055. if (prio != BCN_QUEUE_INX)
  1056. ring->idx = (ring->idx + 1) % ring->entries;
  1057. pxmitbuf = rtl8821ce_dequeue_xmitbuf(ring);
  1058. if (pxmitbuf) {
  1059. mapping = GET_TX_BD_PHYSICAL_ADDR0_LOW(txbd);
  1060. #ifdef CONFIG_64BIT_DMA
  1061. mapping |= (dma_addr_t)GET_TX_BD_PHYSICAL_ADDR0_HIGH(txbd) << 32;
  1062. #endif
  1063. pci_unmap_single(pdev,
  1064. mapping,
  1065. pxmitbuf->len, PCI_DMA_TODEVICE);
  1066. rtw_free_xmitbuf(t_priv, pxmitbuf);
  1067. } else {
  1068. RTW_INFO("%s qlen=%d!=0,but have xmitbuf in pendingQ\n",
  1069. __func__, ring->qlen);
  1070. break;
  1071. }
  1072. }
  1073. pci_free_consistent(pdev, sizeof(*ring->buf_desc) * ring->entries,
  1074. ring->buf_desc, ring->dma);
  1075. ring->buf_desc = NULL;
  1076. }
  1077. /*
  1078. * Draw a line to show queue status. For debug
  1079. * i: queue index / W:HW index / h:host index / .: enpty entry / *:ready to DMA
  1080. * Example: R- 3- 4- 8 ..iW***h..... (i=3,W=4,h=8,
  1081. * *** means 3 tx_desc is reaady to dma)
  1082. */
  1083. #ifdef BUF_DESC_DEBUG
  1084. static void _draw_queue(PADAPTER Adapter, int prio)
  1085. {
  1086. int i;
  1087. u8 line[TX_BD_NUM_8821CE + 1];
  1088. u16 hw, host;
  1089. u32 index, tmp_4bytes = 0;
  1090. struct xmit_priv *t_priv = &Adapter->xmitpriv;
  1091. struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
  1092. tmp_4bytes = rtw_read32(Adapter, get_txbd_rw_reg(prio));
  1093. hw = (u16)((tmp_4bytes >> 16) & 0x7ff);
  1094. host = (u16)(tmp_4bytes & 0x7ff);
  1095. index = ring->idx;
  1096. _rtw_memset(line, '.', TX_BD_NUM_8821CE);
  1097. /* ready to return to driver */
  1098. if (index <= hw) {
  1099. for (i = index; i < hw; i++)
  1100. line[i] = ':';
  1101. } else { /* wrap */
  1102. for (i = index; i < TX_BD_NUM_8821CE; i++)
  1103. line[i] = ':';
  1104. for (i = 0; i < hw; i++)
  1105. line[i] = ':';
  1106. }
  1107. /* ready to dma */
  1108. if (hw <= host) {
  1109. for (i = hw; i < host; i++)
  1110. line[i] = '*';
  1111. } else { /* wrap */
  1112. for (i = hw; i < TX_BD_NUM_8821CE; i++)
  1113. line[i] = '*';
  1114. for (i = 0; i < host; i++)
  1115. line[i] = '*';
  1116. }
  1117. line[index] = 'i'; /* software queue index */
  1118. line[host] = 'h'; /* host index */
  1119. line[hw] = 'W'; /* hardware index */
  1120. line[TX_BD_NUM_8821CE] = 0x0;
  1121. /* Q2:10-20-30: */
  1122. buf_desc_debug("Q%d:%02d-%02d-%02d %s\n", prio, index, hw, host, line);
  1123. }
  1124. #endif
  1125. /*
  1126. * Read pointer is h/w descriptor index
  1127. * Write pointer is host desciptor index: For tx side, if own bit is set in
  1128. * packet index n, host pointer (write pointer) point to index n + 1.
  1129. */
  1130. static u32 rtl8821ce_check_txdesc_closed(PADAPTER Adapter, u32 queue_idx,
  1131. struct rtw_tx_ring *ring)
  1132. {
  1133. /*
  1134. * hw_rp_cache is used to reduce REG access.
  1135. */
  1136. u32 tmp32;
  1137. /* bcn queue should not enter this function */
  1138. if (queue_idx == BCN_QUEUE_INX)
  1139. return _TRUE;
  1140. /* qlen == 0 --> don't need to process */
  1141. if (ring->qlen == 0)
  1142. return _FALSE;
  1143. /* sw_rp == hw_rp_cache --> sync hw_rp */
  1144. if (ring->idx == ring->hw_rp_cache) {
  1145. tmp32 = rtw_read32(Adapter, get_txbd_rw_reg(queue_idx));
  1146. ring->hw_rp_cache = (tmp32 >> 16) & 0x0FFF;
  1147. }
  1148. /* check if need to handle TXOK */
  1149. if (ring->idx == ring->hw_rp_cache)
  1150. return _FALSE;
  1151. return _TRUE;
  1152. }
  1153. #ifdef CONFIG_BCN_ICF
  1154. void rtl8821ce_tx_isr(PADAPTER Adapter, int prio)
  1155. {
  1156. struct xmit_priv *t_priv = &Adapter->xmitpriv;
  1157. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
  1158. struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
  1159. struct xmit_buf *pxmitbuf;
  1160. u8 *tx_desc;
  1161. u16 tmp_4bytes;
  1162. u16 desc_idx_hw = 0, desc_idx_host = 0;
  1163. dma_addr_t mapping;
  1164. #ifdef CONFIG_LPS_LCLK
  1165. int index;
  1166. s32 enter32k = _SUCCESS;
  1167. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);
  1168. #endif
  1169. while (ring->qlen) {
  1170. tx_desc = (u8 *)&ring->buf_desc[ring->idx];
  1171. /* beacon use cmd buf Never run into here */
  1172. if (!rtl8821ce_check_txdesc_closed(Adapter, prio, ring))
  1173. return;
  1174. buf_desc_debug("TX: %s, q_idx = %d, tx_bd = %04x, close [%04x] r_idx [%04x]\n",
  1175. __func__, prio, (u32)tx_desc, ring->idx,
  1176. (ring->idx + 1) % ring->entries);
  1177. ring->idx = (ring->idx + 1) % ring->entries;
  1178. pxmitbuf = rtl8821ce_dequeue_xmitbuf(ring);
  1179. if (pxmitbuf) {
  1180. mapping = GET_TX_BD_PHYSICAL_ADDR0_LOW(tx_desc);
  1181. #ifdef CONFIG_64BIT_DMA
  1182. mapping |= (dma_addr_t)GET_TX_BD_PHYSICAL_ADDR0_HIGH(tx_desc) << 32;
  1183. #endif
  1184. pci_unmap_single(pdvobjpriv->ppcidev,
  1185. mapping,
  1186. pxmitbuf->len, PCI_DMA_TODEVICE);
  1187. rtw_sctx_done(&pxmitbuf->sctx);
  1188. rtw_free_xmitbuf(&(pxmitbuf->padapter->xmitpriv),
  1189. pxmitbuf);
  1190. } else {
  1191. RTW_INFO("%s qlen=%d!=0,but have xmitbuf in pendingQ\n",
  1192. __func__, ring->qlen);
  1193. }
  1194. }
  1195. #ifdef CONFIG_LPS_LCLK
  1196. for (index = 0; index < HW_QUEUE_ENTRY; index++) {
  1197. if (index != BCN_QUEUE_INX) {
  1198. if (_rtw_queue_empty(&(Adapter->xmitpriv.tx_ring[index].queue)) == _FALSE) {
  1199. enter32k = _FAIL;
  1200. break;
  1201. }
  1202. }
  1203. }
  1204. if (enter32k)
  1205. _set_workitem(&(pwrpriv->dma_event));
  1206. #endif
  1207. if (check_tx_desc_resource(Adapter, prio)
  1208. && rtw_xmit_ac_blocked(Adapter) != _TRUE)
  1209. rtw_mi_xmit_tasklet_schedule(Adapter);
  1210. }
  1211. #else /* !CONFIG_BCN_ICF */
  1212. void rtl8821ce_tx_isr(PADAPTER Adapter, int prio)
  1213. {
  1214. struct xmit_priv *t_priv = &Adapter->xmitpriv;
  1215. struct dvobj_priv *pdvobjpriv = adapter_to_dvobj(Adapter);
  1216. struct rtw_tx_ring *ring = &t_priv->tx_ring[prio];
  1217. struct xmit_buf *pxmitbuf;
  1218. u8 *tx_desc;
  1219. u16 tmp_4bytes;
  1220. u16 desc_idx_hw = 0, desc_idx_host = 0;
  1221. #ifdef CONFIG_LPS_LCLK
  1222. int index;
  1223. s32 enter32k = _SUCCESS;
  1224. struct pwrctrl_priv *pwrpriv = adapter_to_pwrctl(Adapter);
  1225. #endif
  1226. while (ring->qlen) {
  1227. tx_desc = (u8 *)&ring->buf_desc[ring->idx];
  1228. /*
  1229. * beacon packet will only use the first descriptor defautly,
  1230. * check register to see whether h/w has consumed buffer
  1231. * descriptor
  1232. */
  1233. if (prio != BCN_QUEUE_INX) {
  1234. if (!rtl8821ce_check_txdesc_closed(Adapter,
  1235. prio, ring->idx))
  1236. return;
  1237. buf_desc_debug("TX: %s, queue_idx = %d, tx_desc = %04x, close desc [%04x] and update ring->idx to [%04x]\n",
  1238. __func__, prio, (u32)tx_desc, ring->idx,
  1239. (ring->idx + 1) % ring->entries);
  1240. ring->idx = (ring->idx + 1) % ring->entries;
  1241. }
  1242. #if 0 /* 8821c change 00[31] to DISQSELSEQ */
  1243. else if (prio == BCN_QUEUE_INX)
  1244. SET_TX_DESC_OWN_92E(tx_desc, 0);
  1245. #endif
  1246. pxmitbuf = rtl8821ce_dequeue_xmitbuf(ring);
  1247. if (pxmitbuf) {
  1248. dma_addr_t mapping;
  1249. mapping = GET_TX_BD_PHYSICAL_ADDR0_LOW(tx_desc);
  1250. #ifdef CONFIG_64BIT_DMA
  1251. mapping |= (dma_addr_t)GET_TX_BD_PHYSICAL_ADDR0_HIGH(tx_desc) << 32;
  1252. #endif
  1253. pci_unmap_single(pdvobjpriv->ppcidev,
  1254. mapping,
  1255. pxmitbuf->len, PCI_DMA_TODEVICE);
  1256. rtw_sctx_done(&pxmitbuf->sctx);
  1257. rtw_free_xmitbuf(&(pxmitbuf->padapter->xmitpriv),
  1258. pxmitbuf);
  1259. } else {
  1260. RTW_INFO("%s qlen=%d!=0,but have xmitbuf in pendingQ\n",
  1261. __func__, ring->qlen);
  1262. }
  1263. }
  1264. #ifdef CONFIG_LPS_LCLK
  1265. for (index = 0; index < HW_QUEUE_ENTRY; index++) {
  1266. if (index != BCN_QUEUE_INX) {
  1267. if (_rtw_queue_empty(&(Adapter->xmitpriv.tx_ring[index].queue)) == _FALSE) {
  1268. enter32k = _FAIL;
  1269. break;
  1270. }
  1271. }
  1272. }
  1273. if (enter32k)
  1274. _set_workitem(&(pwrpriv->dma_event));
  1275. #endif
  1276. if ((prio != BCN_QUEUE_INX) && check_tx_desc_resource(Adapter, prio)
  1277. && rtw_xmit_ac_blocked(Adapter) != _TRUE)
  1278. rtw_mi_xmit_tasklet_schedule(Adapter);
  1279. }
  1280. #endif /* CONFIG_BCN_ICF */
  1281. #ifdef CONFIG_HOSTAPD_MLME
  1282. static void rtl8812ae_hostap_mgnt_xmit_cb(struct urb *urb)
  1283. {
  1284. #ifdef PLATFORM_LINUX
  1285. struct sk_buff *skb = (struct sk_buff *)urb->context;
  1286. dev_kfree_skb_any(skb);
  1287. #endif
  1288. }
  1289. s32 rtl8821ce_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
  1290. {
  1291. #ifdef PLATFORM_LINUX
  1292. u16 fc;
  1293. int rc, len, pipe;
  1294. unsigned int bmcst, tid, qsel;
  1295. struct sk_buff *skb, *pxmit_skb;
  1296. struct urb *urb;
  1297. unsigned char *pxmitbuf;
  1298. struct tx_desc *ptxdesc;
  1299. struct rtw_ieee80211_hdr *tx_hdr;
  1300. struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
  1301. struct net_device *pnetdev = padapter->pnetdev;
  1302. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  1303. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  1304. skb = pkt;
  1305. len = skb->len;
  1306. tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
  1307. fc = le16_to_cpu(tx_hdr->frame_ctl);
  1308. bmcst = IS_MCAST(tx_hdr->addr1);
  1309. if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
  1310. goto _exit;
  1311. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 18))
  1312. /* http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html */
  1313. pxmit_skb = dev_alloc_skb(len + TXDESC_SIZE);
  1314. #else
  1315. pxmit_skb = netdev_alloc_skb(pnetdev, len + TXDESC_SIZE);
  1316. #endif
  1317. if (!pxmit_skb)
  1318. goto _exit;
  1319. pxmitbuf = pxmit_skb->data;
  1320. urb = usb_alloc_urb(0, GFP_ATOMIC);
  1321. if (!urb)
  1322. goto _exit;
  1323. /* ----- fill tx desc ----- */
  1324. ptxdesc = (struct tx_desc *)pxmitbuf;
  1325. _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
  1326. /* offset 0 */
  1327. ptxdesc->txdw0 |= cpu_to_le32(len & 0x0000ffff);
  1328. /* default = 32 bytes for TX Desc */
  1329. ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE + OFFSET_SZ) << OFFSET_SHT) &
  1330. 0x00ff0000);
  1331. ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
  1332. if (bmcst)
  1333. ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
  1334. /* offset 4 */
  1335. ptxdesc->txdw1 |= cpu_to_le32(0x00);/* MAC_ID */
  1336. ptxdesc->txdw1 |= cpu_to_le32((0x12 << QSEL_SHT) & 0x00001f00);
  1337. ptxdesc->txdw1 |= cpu_to_le32((0x06 << 16) & 0x000f0000);/* b mode */
  1338. /* offset 8 */
  1339. /* offset 12 */
  1340. ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl) << 16) &
  1341. 0xffff0000);
  1342. /* offset 16 */
  1343. ptxdesc->txdw4 |= cpu_to_le32(BIT(8));/* driver uses rate */
  1344. /* offset 20 */
  1345. rtl8188e_cal_txdesc_chksum(ptxdesc);
  1346. /* ----- end of fill tx desc ----- */
  1347. skb_put(pxmit_skb, len + TXDESC_SIZE);
  1348. pxmitbuf = pxmitbuf + TXDESC_SIZE;
  1349. _rtw_memcpy(pxmitbuf, skb->data, len);
  1350. /* ----- prepare urb for submit ----- */
  1351. /* translate DMA FIFO addr to pipehandle */
  1352. /*pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);*/
  1353. pipe = usb_sndbulkpipe(pdvobj->pusbdev,
  1354. pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX] & 0x0f);
  1355. usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe, pxmit_skb->data,
  1356. pxmit_skb->len, rtl8188ee_hostap_mgnt_xmit_cb, pxmit_skb);
  1357. urb->transfer_flags |= URB_ZERO_PACKET;
  1358. usb_anchor_urb(urb, &phostapdpriv->anchored);
  1359. rc = usb_submit_urb(urb, GFP_ATOMIC);
  1360. if (rc < 0) {
  1361. usb_unanchor_urb(urb);
  1362. kfree_skb(skb);
  1363. }
  1364. usb_free_urb(urb);
  1365. _exit:
  1366. dev_kfree_skb_any(skb);
  1367. #endif
  1368. return 0;
  1369. }
  1370. #endif