rtl8821ce_xmit.c 38 KB

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