rtl8812au_xmit.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. /******************************************************************************
  2. *
  3. * Copyright(c) 2007 - 2011 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 _RTL8812AU_XMIT_C_
  21. //#include <drv_types.h>
  22. #include <rtl8812a_hal.h>
  23. s32 rtl8812au_init_xmit_priv(_adapter *padapter)
  24. {
  25. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  26. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  27. #ifdef PLATFORM_LINUX
  28. tasklet_init(&pxmitpriv->xmit_tasklet,
  29. (void(*)(unsigned long))rtl8812au_xmit_tasklet,
  30. (unsigned long)padapter);
  31. #endif
  32. #ifdef CONFIG_TX_EARLY_MODE
  33. pHalData->bEarlyModeEnable = padapter->registrypriv.early_mode;
  34. #endif
  35. return _SUCCESS;
  36. }
  37. void rtl8812au_free_xmit_priv(_adapter *padapter)
  38. {
  39. }
  40. static s32 update_txdesc(struct xmit_frame *pxmitframe, u8 *pmem, s32 sz ,u8 bagg_pkt)
  41. {
  42. int pull=0;
  43. uint qsel;
  44. u8 data_rate,pwr_status,offset;
  45. _adapter *padapter = pxmitframe->padapter;
  46. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  47. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  48. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  49. struct dm_priv *pdmpriv = &pHalData->dmpriv;
  50. u8 *ptxdesc = pmem;
  51. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  52. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  53. sint bmcst = IS_MCAST(pattrib->ra);
  54. #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
  55. if (padapter->registrypriv.mp_mode == 0)
  56. {
  57. if((!bagg_pkt) &&(rtw_usb_bulk_size_boundary(padapter,TXDESC_SIZE+sz)==_FALSE))
  58. {
  59. ptxdesc = (pmem+PACKET_OFFSET_SZ);
  60. //DBG_8192C("==> non-agg-pkt,shift pointer...\n");
  61. pull = 1;
  62. }
  63. }
  64. #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
  65. _rtw_memset(ptxdesc, 0, TXDESC_SIZE);
  66. //4 offset 0
  67. SET_TX_DESC_FIRST_SEG_8812(ptxdesc, 1);
  68. SET_TX_DESC_LAST_SEG_8812(ptxdesc, 1);
  69. SET_TX_DESC_OWN_8812(ptxdesc, 1);
  70. //DBG_8192C("%s==> pkt_len=%d,bagg_pkt=%02x\n",__FUNCTION__,sz,bagg_pkt);
  71. SET_TX_DESC_PKT_SIZE_8812(ptxdesc, sz);
  72. offset = TXDESC_SIZE + OFFSET_SZ;
  73. #ifdef CONFIG_TX_EARLY_MODE
  74. if(bagg_pkt){
  75. offset += EARLY_MODE_INFO_SIZE ;//0x28
  76. }
  77. #endif
  78. //DBG_8192C("%s==>offset(0x%02x) \n",__FUNCTION__,offset);
  79. SET_TX_DESC_OFFSET_8812(ptxdesc, offset);
  80. if (bmcst) {
  81. SET_TX_DESC_BMC_8812(ptxdesc, 1);
  82. }
  83. #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
  84. if (padapter->registrypriv.mp_mode == 0)
  85. {
  86. if(!bagg_pkt){
  87. if((pull) && (pxmitframe->pkt_offset>0)) {
  88. pxmitframe->pkt_offset = pxmitframe->pkt_offset -1;
  89. }
  90. }
  91. }
  92. #endif
  93. //DBG_8192C("%s, pkt_offset=0x%02x\n",__FUNCTION__,pxmitframe->pkt_offset);
  94. // pkt_offset, unit:8 bytes padding
  95. if (pxmitframe->pkt_offset > 0) {
  96. SET_TX_DESC_PKT_OFFSET_8812(ptxdesc, pxmitframe->pkt_offset);
  97. }
  98. SET_TX_DESC_MACID_8812(ptxdesc, pattrib->mac_id);
  99. SET_TX_DESC_RATE_ID_8812(ptxdesc, pattrib->raid);
  100. SET_TX_DESC_QUEUE_SEL_8812(ptxdesc, pattrib->qsel);
  101. //offset 12
  102. if (!pattrib->qos_en) {
  103. SET_TX_DESC_HWSEQ_EN_8812(ptxdesc, 1); // Hw set sequence number
  104. } else {
  105. SET_TX_DESC_SEQ_8812(ptxdesc, pattrib->seqnum);
  106. }
  107. if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
  108. {
  109. //DBG_8192C("pxmitframe->frame_tag == DATA_FRAMETAG\n");
  110. rtl8812a_fill_txdesc_sectype(pattrib, ptxdesc);
  111. //offset 20
  112. #ifdef CONFIG_USB_TX_AGGREGATION
  113. if (pxmitframe->agg_num > 1){
  114. //DBG_8192C("%s agg_num:%d\n",__FUNCTION__,pxmitframe->agg_num );
  115. SET_TX_DESC_USB_TXAGG_NUM_8812(ptxdesc, pxmitframe->agg_num);
  116. }
  117. #endif
  118. rtl8812a_fill_txdesc_vcs(padapter, pattrib, ptxdesc);
  119. if ((pattrib->ether_type != 0x888e) &&
  120. (pattrib->ether_type != 0x0806) &&
  121. (pattrib->ether_type != 0x88b4) &&
  122. (pattrib->dhcp_pkt != 1)
  123. #ifdef CONFIG_AUTO_AP_MODE
  124. && (pattrib->pctrl != _TRUE)
  125. #endif
  126. )
  127. {
  128. //Non EAP & ARP & DHCP type data packet
  129. if (pattrib->ampdu_en==_TRUE) {
  130. SET_TX_DESC_AGG_ENABLE_8812(ptxdesc, 1);
  131. SET_TX_DESC_MAX_AGG_NUM_8812(ptxdesc, 0x1f);
  132. // Set A-MPDU aggregation.
  133. SET_TX_DESC_AMPDU_DENSITY_8812(ptxdesc, pHalData->AMPDUDensity);
  134. } else {
  135. SET_TX_DESC_AGG_BREAK_8812(ptxdesc, 1);
  136. }
  137. rtl8812a_fill_txdesc_phy(padapter, pattrib, ptxdesc);
  138. //DATA Rate FB LMT
  139. SET_TX_DESC_DATA_RATE_FB_LIMIT_8812(ptxdesc, 0x1f);
  140. if (pHalData->fw_ractrl == _FALSE) {
  141. SET_TX_DESC_USE_RATE_8812(ptxdesc, 1);
  142. if(pdmpriv->INIDATA_RATE[pattrib->mac_id] & BIT(7))
  143. SET_TX_DESC_DATA_SHORT_8812(ptxdesc, 1);
  144. SET_TX_DESC_TX_RATE_8812(ptxdesc, (pdmpriv->INIDATA_RATE[pattrib->mac_id] & 0x7F));
  145. }
  146. if (padapter->fix_rate != 0xFF) { // modify data rate by iwpriv
  147. SET_TX_DESC_USE_RATE_8812(ptxdesc, 1);
  148. if(padapter->fix_rate & BIT(7))
  149. SET_TX_DESC_DATA_SHORT_8812(ptxdesc, 1);
  150. SET_TX_DESC_TX_RATE_8812(ptxdesc, (padapter->fix_rate & 0x7F));
  151. }
  152. if (pattrib->ldpc)
  153. SET_TX_DESC_DATA_LDPC_8812(ptxdesc, 1);
  154. if (pattrib->stbc)
  155. SET_TX_DESC_DATA_STBC_8812(ptxdesc, 1);
  156. }
  157. else
  158. {
  159. // EAP data packet and ARP packet and DHCP.
  160. // Use the 1M data rate to send the EAP/ARP packet.
  161. // This will maybe make the handshake smooth.
  162. SET_TX_DESC_USE_RATE_8812(ptxdesc, 1);
  163. SET_TX_DESC_AGG_BREAK_8812(ptxdesc, 1);
  164. // HW will ignore this setting if the transmission rate is legacy OFDM.
  165. if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT) {
  166. SET_TX_DESC_DATA_SHORT_8812(ptxdesc, 1);
  167. }
  168. SET_TX_DESC_TX_RATE_8812(ptxdesc, MRateToHwRate(pmlmeext->tx_rate));
  169. }
  170. }
  171. else if((pxmitframe->frame_tag&0x0f)== MGNT_FRAMETAG)
  172. {
  173. //DBG_8192C("pxmitframe->frame_tag == MGNT_FRAMETAG\n");
  174. if(IS_HARDWARE_TYPE_8821(padapter))
  175. SET_TX_DESC_MBSSID_8821(ptxdesc, pattrib->mbssid);
  176. //offset 20
  177. SET_TX_DESC_RETRY_LIMIT_ENABLE_8812(ptxdesc, 1);
  178. if (pattrib->retry_ctrl == _TRUE) {
  179. SET_TX_DESC_DATA_RETRY_LIMIT_8812(ptxdesc, 6);
  180. } else {
  181. SET_TX_DESC_DATA_RETRY_LIMIT_8812(ptxdesc, 12);
  182. }
  183. SET_TX_DESC_USE_RATE_8812(ptxdesc, 1);
  184. #ifdef CONFIG_INTEL_PROXIM
  185. if((padapter->proximity.proxim_on==_TRUE)&&(pattrib->intel_proxim==_TRUE)){
  186. DBG_871X("\n %s pattrib->rate=%d\n",__FUNCTION__,pattrib->rate);
  187. SET_TX_DESC_TX_RATE_8812(ptxdesc, pattrib->rate);
  188. }
  189. else
  190. #endif
  191. {
  192. SET_TX_DESC_TX_RATE_8812(ptxdesc, MRateToHwRate(pmlmeext->tx_rate));
  193. }
  194. }
  195. else if((pxmitframe->frame_tag&0x0f) == TXAGG_FRAMETAG)
  196. {
  197. DBG_8192C("pxmitframe->frame_tag == TXAGG_FRAMETAG\n");
  198. }
  199. #ifdef CONFIG_MP_INCLUDED
  200. else if(((pxmitframe->frame_tag&0x0f) == MP_FRAMETAG) &&
  201. (padapter->registrypriv.mp_mode == 1))
  202. {
  203. fill_txdesc_for_mp(padapter, (struct tx_desc *)ptxdesc);
  204. }
  205. #endif
  206. else
  207. {
  208. DBG_8192C("pxmitframe->frame_tag = %d\n", pxmitframe->frame_tag);
  209. SET_TX_DESC_USE_RATE_8812(ptxdesc, 1);
  210. SET_TX_DESC_TX_RATE_8812(ptxdesc, MRateToHwRate(pmlmeext->tx_rate));
  211. }
  212. rtl8812a_cal_txdesc_chksum(ptxdesc);
  213. _dbg_dump_tx_info(padapter,pxmitframe->frame_tag,ptxdesc);
  214. return pull;
  215. }
  216. #ifdef CONFIG_XMIT_THREAD_MODE
  217. /*
  218. * Description
  219. * Transmit xmitbuf to hardware tx fifo
  220. *
  221. * Return
  222. * _SUCCESS ok
  223. * _FAIL something error
  224. */
  225. s32 rtl8812au_xmit_buf_handler(PADAPTER padapter)
  226. {
  227. PHAL_DATA_TYPE phal;
  228. struct xmit_priv *pxmitpriv;
  229. struct xmit_buf *pxmitbuf;
  230. s32 ret;
  231. phal = GET_HAL_DATA(padapter);
  232. pxmitpriv = &padapter->xmitpriv;
  233. ret = _rtw_down_sema(&pxmitpriv->xmit_sema);
  234. if (_FAIL == ret) {
  235. RT_TRACE(_module_hal_xmit_c_, _drv_emerg_,
  236. ("%s: down SdioXmitBufSema fail!\n", __FUNCTION__));
  237. return _FAIL;
  238. }
  239. ret = (padapter->bDriverStopped == _TRUE) || (padapter->bSurpriseRemoved == _TRUE);
  240. if (ret) {
  241. RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
  242. ("%s: bDriverStopped(%d) bSurpriseRemoved(%d)!\n",
  243. __FUNCTION__, padapter->bDriverStopped, padapter->bSurpriseRemoved));
  244. return _FAIL;
  245. }
  246. if(check_pending_xmitbuf(pxmitpriv) == _FALSE)
  247. return _SUCCESS;
  248. #ifdef CONFIG_LPS_LCLK
  249. ret = rtw_register_tx_alive(padapter);
  250. if (ret != _SUCCESS) {
  251. RT_TRACE(_module_hal_xmit_c_, _drv_notice_,
  252. ("%s: wait to leave LPS_LCLK\n", __FUNCTION__));
  253. return _SUCCESS;
  254. }
  255. #endif
  256. do {
  257. pxmitbuf = dequeue_pending_xmitbuf(pxmitpriv);
  258. if (pxmitbuf == NULL) break;
  259. rtw_write_port(padapter, pxmitbuf->ff_hwaddr, pxmitbuf->len, (unsigned char*)pxmitbuf);
  260. } while (1);
  261. #ifdef CONFIG_LPS_LCLK
  262. rtw_unregister_tx_alive(padapter);
  263. #endif
  264. return _SUCCESS;
  265. }
  266. #endif
  267. //for non-agg data frame or management frame
  268. static s32 rtw_dump_xframe(_adapter *padapter, struct xmit_frame *pxmitframe)
  269. {
  270. s32 ret = _SUCCESS;
  271. s32 inner_ret = _SUCCESS;
  272. int t, sz, w_sz, pull=0;
  273. u8 *mem_addr;
  274. u32 ff_hwaddr;
  275. struct xmit_buf *pxmitbuf = pxmitframe->pxmitbuf;
  276. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  277. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  278. struct security_priv *psecuritypriv = &padapter->securitypriv;
  279. #ifdef CONFIG_80211N_HT
  280. if ((pxmitframe->frame_tag == DATA_FRAMETAG) &&
  281. (pxmitframe->attrib.ether_type != 0x0806) &&
  282. (pxmitframe->attrib.ether_type != 0x888e) &&
  283. (pxmitframe->attrib.ether_type != 0x88b4) &&
  284. (pxmitframe->attrib.dhcp_pkt != 1))
  285. {
  286. rtw_issue_addbareq_cmd(padapter, pxmitframe);
  287. }
  288. #endif //CONFIG_80211N_HT
  289. mem_addr = pxmitframe->buf_addr;
  290. RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_dump_xframe()\n"));
  291. for (t = 0; t < pattrib->nr_frags; t++)
  292. {
  293. if (inner_ret != _SUCCESS && ret == _SUCCESS)
  294. ret = _FAIL;
  295. if (t != (pattrib->nr_frags - 1))
  296. {
  297. RT_TRACE(_module_rtl871x_xmit_c_,_drv_err_,("pattrib->nr_frags=%d\n", pattrib->nr_frags));
  298. sz = pxmitpriv->frag_len;
  299. sz = sz - 4 - (psecuritypriv->sw_encrypt ? 0 : pattrib->icv_len);
  300. }
  301. else //no frag
  302. {
  303. sz = pattrib->last_txcmdsz;
  304. }
  305. pull = update_txdesc(pxmitframe, mem_addr, sz, _FALSE);
  306. if(pull)
  307. {
  308. mem_addr += PACKET_OFFSET_SZ; //pull txdesc head
  309. //pxmitbuf ->pbuf = mem_addr;
  310. pxmitframe->buf_addr = mem_addr;
  311. w_sz = sz + TXDESC_SIZE;
  312. }
  313. else
  314. {
  315. w_sz = sz + TXDESC_SIZE + PACKET_OFFSET_SZ;
  316. }
  317. ff_hwaddr = rtw_get_ff_hwaddr(pxmitframe);
  318. #ifdef CONFIG_XMIT_THREAD_MODE
  319. pxmitbuf->len = w_sz;
  320. pxmitbuf->ff_hwaddr = ff_hwaddr;
  321. enqueue_pending_xmitbuf(pxmitpriv, pxmitbuf);
  322. #else
  323. inner_ret = rtw_write_port(padapter, ff_hwaddr, w_sz, (unsigned char*)pxmitbuf);
  324. #endif
  325. rtw_count_tx_stats(padapter, pxmitframe, sz);
  326. RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("rtw_write_port, w_sz=%d\n", w_sz));
  327. //DBG_8192C("rtw_write_port, w_sz=%d, sz=%d, txdesc_sz=%d, tid=%d\n", w_sz, sz, w_sz-sz, pattrib->priority);
  328. mem_addr += w_sz;
  329. mem_addr = (u8 *)RND4(((SIZE_PTR)(mem_addr)));
  330. }
  331. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  332. if (ret != _SUCCESS)
  333. rtw_sctx_done_err(&pxmitbuf->sctx, RTW_SCTX_DONE_UNKNOWN);
  334. return ret;
  335. }
  336. #ifdef CONFIG_USB_TX_AGGREGATION
  337. static u32 xmitframe_need_length(struct xmit_frame *pxmitframe)
  338. {
  339. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  340. u32 len = 0;
  341. // no consider fragement
  342. len = pattrib->hdrlen + pattrib->iv_len +
  343. SNAP_SIZE + sizeof(u16) +
  344. pattrib->pktlen +
  345. ((pattrib->bswenc) ? pattrib->icv_len : 0);
  346. if(pattrib->encrypt ==_TKIP_)
  347. len += 8;
  348. return len;
  349. }
  350. #define IDEA_CONDITION 1 // check all packets before enqueue
  351. s32 rtl8812au_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
  352. {
  353. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  354. struct xmit_frame *pxmitframe = NULL;
  355. struct xmit_frame *pfirstframe = NULL;
  356. // aggregate variable
  357. struct hw_xmit *phwxmit;
  358. struct sta_info *psta = NULL;
  359. struct tx_servq *ptxservq = NULL;
  360. _irqL irqL;
  361. _list *xmitframe_plist = NULL, *xmitframe_phead = NULL;
  362. u32 pbuf; // next pkt address
  363. u32 pbuf_tail; // last pkt tail
  364. u32 len; // packet length, except TXDESC_SIZE and PKT_OFFSET
  365. u32 bulkSize = pHalData->UsbBulkOutSize;
  366. u8 descCount;
  367. u32 bulkPtr;
  368. // dump frame variable
  369. u32 ff_hwaddr;
  370. #ifndef IDEA_CONDITION
  371. int res = _SUCCESS;
  372. #endif
  373. RT_TRACE(_module_rtl8192c_xmit_c_, _drv_info_, ("+xmitframe_complete\n"));
  374. // check xmitbuffer is ok
  375. if (pxmitbuf == NULL) {
  376. pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
  377. if (pxmitbuf == NULL){
  378. //DBG_871X("%s #1, connot alloc xmitbuf!!!! \n",__FUNCTION__);
  379. return _FALSE;
  380. }
  381. }
  382. //DBG_8192C("%s ===================================== \n",__FUNCTION__);
  383. //3 1. pick up first frame
  384. do {
  385. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  386. pxmitframe = rtw_dequeue_xframe(pxmitpriv, pxmitpriv->hwxmits, pxmitpriv->hwxmit_entry);
  387. if (pxmitframe == NULL) {
  388. // no more xmit frame, release xmit buffer
  389. //DBG_8192C("no more xmit frame ,return\n");
  390. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  391. return _FALSE;
  392. }
  393. #ifndef IDEA_CONDITION
  394. if (pxmitframe->frame_tag != DATA_FRAMETAG) {
  395. RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
  396. ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
  397. pxmitframe->frame_tag, DATA_FRAMETAG));
  398. // rtw_free_xmitframe(pxmitpriv, pxmitframe);
  399. continue;
  400. }
  401. // TID 0~15
  402. if ((pxmitframe->attrib.priority < 0) ||
  403. (pxmitframe->attrib.priority > 15)) {
  404. RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
  405. ("xmitframe_complete: TID(%d) should be 0~15!\n",
  406. pxmitframe->attrib.priority));
  407. // rtw_free_xmitframe(pxmitpriv, pxmitframe);
  408. continue;
  409. }
  410. #endif
  411. //DBG_8192C("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority);
  412. pxmitframe->pxmitbuf = pxmitbuf;
  413. pxmitframe->buf_addr = pxmitbuf->pbuf;
  414. pxmitbuf->priv_data = pxmitframe;
  415. pxmitframe->agg_num = 1; // alloc xmitframe should assign to 1.
  416. #ifdef CONFIG_TX_EARLY_MODE
  417. pxmitframe->pkt_offset = 2; // first frame of aggregation, reserve one offset for EM info ,another for usb bulk-out block check
  418. #else
  419. pxmitframe->pkt_offset = 1; // first frame of aggregation, reserve offset
  420. #endif
  421. if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
  422. DBG_871X("%s coalesce 1st xmitframe failed \n",__FUNCTION__);
  423. continue;
  424. }
  425. // always return ndis_packet after rtw_xmitframe_coalesce
  426. rtw_os_xmit_complete(padapter, pxmitframe);
  427. break;
  428. } while (1);
  429. //3 2. aggregate same priority and same DA(AP or STA) frames
  430. pfirstframe = pxmitframe;
  431. len = xmitframe_need_length(pfirstframe) + TXDESC_SIZE+(pfirstframe->pkt_offset*PACKET_OFFSET_SZ);
  432. pbuf_tail = len;
  433. pbuf = _RND8(pbuf_tail);
  434. // check pkt amount in one bulk
  435. descCount = 0;
  436. bulkPtr = bulkSize;
  437. if (pbuf < bulkPtr)
  438. descCount++;
  439. else {
  440. descCount = 0;
  441. bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize; // round to next bulkSize
  442. }
  443. // dequeue same priority packet from station tx queue
  444. psta = pfirstframe->attrib.psta;
  445. switch (pfirstframe->attrib.priority) {
  446. case 1:
  447. case 2:
  448. ptxservq = &(psta->sta_xmitpriv.bk_q);
  449. phwxmit = pxmitpriv->hwxmits + 3;
  450. break;
  451. case 4:
  452. case 5:
  453. ptxservq = &(psta->sta_xmitpriv.vi_q);
  454. phwxmit = pxmitpriv->hwxmits + 1;
  455. break;
  456. case 6:
  457. case 7:
  458. ptxservq = &(psta->sta_xmitpriv.vo_q);
  459. phwxmit = pxmitpriv->hwxmits;
  460. break;
  461. case 0:
  462. case 3:
  463. default:
  464. ptxservq = &(psta->sta_xmitpriv.be_q);
  465. phwxmit = pxmitpriv->hwxmits + 2;
  466. break;
  467. }
  468. //DBG_8192C("==> pkt_no=%d,pkt_len=%d,len=%d,RND8_LEN=%d,pkt_offset=0x%02x\n",
  469. //pxmitframe->agg_num,pxmitframe->attrib.last_txcmdsz,len,pbuf,pxmitframe->pkt_offset );
  470. _enter_critical_bh(&pxmitpriv->lock, &irqL);
  471. xmitframe_phead = get_list_head(&ptxservq->sta_pending);
  472. xmitframe_plist = get_next(xmitframe_phead);
  473. while (rtw_end_of_queue_search(xmitframe_phead, xmitframe_plist) == _FALSE)
  474. {
  475. pxmitframe = LIST_CONTAINOR(xmitframe_plist, struct xmit_frame, list);
  476. xmitframe_plist = get_next(xmitframe_plist);
  477. pxmitframe->agg_num = 0; // not first frame of aggregation
  478. #ifdef CONFIG_TX_EARLY_MODE
  479. pxmitframe->pkt_offset = 1;// not first frame of aggregation,reserve offset for EM Info
  480. #else
  481. pxmitframe->pkt_offset = 0; // not first frame of aggregation, no need to reserve offset
  482. #endif
  483. len = xmitframe_need_length(pxmitframe) + TXDESC_SIZE +(pxmitframe->pkt_offset*PACKET_OFFSET_SZ);
  484. if (_RND8(pbuf + len) > MAX_XMITBUF_SZ)
  485. //if (_RND8(pbuf + len) > (MAX_XMITBUF_SZ/2))//to do : for TX TP finial tune , Georgia 2012-0323
  486. {
  487. //DBG_8192C("%s....len> MAX_XMITBUF_SZ\n",__FUNCTION__);
  488. pxmitframe->agg_num = 1;
  489. pxmitframe->pkt_offset = 1;
  490. break;
  491. }
  492. rtw_list_delete(&pxmitframe->list);
  493. ptxservq->qcnt--;
  494. phwxmit->accnt--;
  495. #ifndef IDEA_CONDITION
  496. // suppose only data frames would be in queue
  497. if (pxmitframe->frame_tag != DATA_FRAMETAG) {
  498. RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
  499. ("xmitframe_complete: frame tag(%d) is not DATA_FRAMETAG(%d)!\n",
  500. pxmitframe->frame_tag, DATA_FRAMETAG));
  501. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  502. continue;
  503. }
  504. // TID 0~15
  505. if ((pxmitframe->attrib.priority < 0) ||
  506. (pxmitframe->attrib.priority > 15)) {
  507. RT_TRACE(_module_rtl8192c_xmit_c_, _drv_err_,
  508. ("xmitframe_complete: TID(%d) should be 0~15!\n",
  509. pxmitframe->attrib.priority));
  510. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  511. continue;
  512. }
  513. #endif
  514. // pxmitframe->pxmitbuf = pxmitbuf;
  515. pxmitframe->buf_addr = pxmitbuf->pbuf + pbuf;
  516. if (rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe) == _FALSE) {
  517. DBG_871X("%s coalesce failed \n",__FUNCTION__);
  518. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  519. continue;
  520. }
  521. //DBG_8192C("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority);
  522. // always return ndis_packet after rtw_xmitframe_coalesce
  523. rtw_os_xmit_complete(padapter, pxmitframe);
  524. // (len - TXDESC_SIZE) == pxmitframe->attrib.last_txcmdsz
  525. update_txdesc(pxmitframe, pxmitframe->buf_addr, pxmitframe->attrib.last_txcmdsz,_TRUE);
  526. // don't need xmitframe any more
  527. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  528. // handle pointer and stop condition
  529. pbuf_tail = pbuf + len;
  530. pbuf = _RND8(pbuf_tail);
  531. pfirstframe->agg_num++;
  532. #ifdef CONFIG_TX_EARLY_MODE
  533. pxmitpriv->agg_pkt[pfirstframe->agg_num-1].offset = _RND8(len);
  534. pxmitpriv->agg_pkt[pfirstframe->agg_num-1].pkt_len = pxmitframe->attrib.last_txcmdsz;
  535. #endif
  536. if (MAX_TX_AGG_PACKET_NUMBER == pfirstframe->agg_num)
  537. break;
  538. if (pbuf < bulkPtr) {
  539. descCount++;
  540. if (descCount == pHalData->UsbTxAggDescNum)
  541. break;
  542. } else {
  543. descCount = 0;
  544. bulkPtr = ((pbuf / bulkSize) + 1) * bulkSize;
  545. }
  546. }//end while( aggregate same priority and same DA(AP or STA) frames)
  547. if (_rtw_queue_empty(&ptxservq->sta_pending) == _TRUE)
  548. rtw_list_delete(&ptxservq->tx_pending);
  549. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  550. #ifdef CONFIG_80211N_HT
  551. if ((pfirstframe->attrib.ether_type != 0x0806) &&
  552. (pfirstframe->attrib.ether_type != 0x888e) &&
  553. (pfirstframe->attrib.ether_type != 0x88b4) &&
  554. (pfirstframe->attrib.dhcp_pkt != 1))
  555. {
  556. rtw_issue_addbareq_cmd(padapter, pfirstframe);
  557. }
  558. #endif //CONFIG_80211N_HT
  559. #ifndef CONFIG_USE_USB_BUFFER_ALLOC_TX
  560. //3 3. update first frame txdesc
  561. if ((pbuf_tail % bulkSize) == 0) {
  562. // remove pkt_offset
  563. pbuf_tail -= PACKET_OFFSET_SZ;
  564. pfirstframe->buf_addr += PACKET_OFFSET_SZ;
  565. pfirstframe->pkt_offset--;
  566. //DBG_8192C("$$$$$ buf size equal to USB block size $$$$$$\n");
  567. }
  568. #endif // CONFIG_USE_USB_BUFFER_ALLOC_TX
  569. update_txdesc(pfirstframe, pfirstframe->buf_addr, pfirstframe->attrib.last_txcmdsz,_TRUE);
  570. #ifdef CONFIG_TX_EARLY_MODE
  571. //prepare EM info for first frame, agg_num value start from 1
  572. pxmitpriv->agg_pkt[0].offset = _RND8(pfirstframe->attrib.last_txcmdsz +TXDESC_SIZE +(pfirstframe->pkt_offset*PACKET_OFFSET_SZ));
  573. pxmitpriv->agg_pkt[0].pkt_len = pfirstframe->attrib.last_txcmdsz;//get from rtw_xmitframe_coalesce
  574. UpdateEarlyModeInfo8812(pxmitpriv,pxmitbuf );
  575. #endif
  576. //3 4. write xmit buffer to USB FIFO
  577. ff_hwaddr = rtw_get_ff_hwaddr(pfirstframe);
  578. //DBG_8192C("%s ===================================== write port,buf_size(%d) \n",__FUNCTION__,pbuf_tail);
  579. // xmit address == ((xmit_frame*)pxmitbuf->priv_data)->buf_addr
  580. rtw_write_port(padapter, ff_hwaddr, pbuf_tail, (u8*)pxmitbuf);
  581. //3 5. update statisitc
  582. pbuf_tail -= (pfirstframe->agg_num * TXDESC_SIZE);
  583. pbuf_tail -= (pfirstframe->pkt_offset * PACKET_OFFSET_SZ);
  584. rtw_count_tx_stats(padapter, pfirstframe, pbuf_tail);
  585. rtw_free_xmitframe(pxmitpriv, pfirstframe);
  586. return _TRUE;
  587. }
  588. #else
  589. s32 rtl8812au_xmitframe_complete(_adapter *padapter, struct xmit_priv *pxmitpriv, struct xmit_buf *pxmitbuf)
  590. {
  591. struct hw_xmit *phwxmits;
  592. sint hwentry;
  593. struct xmit_frame *pxmitframe=NULL;
  594. int res=_SUCCESS, xcnt = 0;
  595. phwxmits = pxmitpriv->hwxmits;
  596. hwentry = pxmitpriv->hwxmit_entry;
  597. RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete()\n"));
  598. if(pxmitbuf==NULL)
  599. {
  600. pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
  601. if(!pxmitbuf)
  602. {
  603. return _FALSE;
  604. }
  605. }
  606. do
  607. {
  608. pxmitframe = rtw_dequeue_xframe(pxmitpriv, phwxmits, hwentry);
  609. if(pxmitframe)
  610. {
  611. pxmitframe->pxmitbuf = pxmitbuf;
  612. pxmitframe->buf_addr = pxmitbuf->pbuf;
  613. pxmitbuf->priv_data = pxmitframe;
  614. if((pxmitframe->frame_tag&0x0f) == DATA_FRAMETAG)
  615. {
  616. if(pxmitframe->attrib.priority<=15)//TID0~15
  617. {
  618. res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
  619. }
  620. //DBG_8192C("==> pxmitframe->attrib.priority:%d\n",pxmitframe->attrib.priority);
  621. rtw_os_xmit_complete(padapter, pxmitframe);//always return ndis_packet after rtw_xmitframe_coalesce
  622. }
  623. RT_TRACE(_module_rtl871x_xmit_c_,_drv_info_,("xmitframe_complete(): rtw_dump_xframe\n"));
  624. if(res == _SUCCESS)
  625. {
  626. rtw_dump_xframe(padapter, pxmitframe);
  627. }
  628. else
  629. {
  630. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  631. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  632. }
  633. xcnt++;
  634. }
  635. else
  636. {
  637. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  638. return _FALSE;
  639. }
  640. break;
  641. }while(0/*xcnt < (NR_XMITFRAME >> 3)*/);
  642. return _TRUE;
  643. }
  644. #endif
  645. static s32 xmitframe_direct(_adapter *padapter, struct xmit_frame *pxmitframe)
  646. {
  647. s32 res = _SUCCESS;
  648. //DBG_8192C("==> %s \n",__FUNCTION__);
  649. res = rtw_xmitframe_coalesce(padapter, pxmitframe->pkt, pxmitframe);
  650. if (res == _SUCCESS) {
  651. rtw_dump_xframe(padapter, pxmitframe);
  652. }
  653. else{
  654. DBG_8192C("==> %s xmitframe_coalsece failed\n",__FUNCTION__);
  655. }
  656. return res;
  657. }
  658. /*
  659. * Return
  660. * _TRUE dump packet directly
  661. * _FALSE enqueue packet
  662. */
  663. static s32 pre_xmitframe(_adapter *padapter, struct xmit_frame *pxmitframe)
  664. {
  665. _irqL irqL;
  666. s32 res;
  667. struct xmit_buf *pxmitbuf = NULL;
  668. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  669. struct pkt_attrib *pattrib = &pxmitframe->attrib;
  670. struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  671. _enter_critical_bh(&pxmitpriv->lock, &irqL);
  672. //DBG_8192C("==> %s \n",__FUNCTION__);
  673. if (rtw_txframes_sta_ac_pending(padapter, pattrib) > 0)
  674. {
  675. //DBG_8192C("enqueue AC(%d)\n",pattrib->priority);
  676. goto enqueue;
  677. }
  678. if (check_fwstate(pmlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
  679. goto enqueue;
  680. #ifdef CONFIG_CONCURRENT_MODE
  681. if (check_buddy_fwstate(padapter, _FW_UNDER_SURVEY|_FW_UNDER_LINKING) == _TRUE)
  682. goto enqueue;
  683. #endif
  684. pxmitbuf = rtw_alloc_xmitbuf(pxmitpriv);
  685. if (pxmitbuf == NULL)
  686. goto enqueue;
  687. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  688. pxmitframe->pxmitbuf = pxmitbuf;
  689. pxmitframe->buf_addr = pxmitbuf->pbuf;
  690. pxmitbuf->priv_data = pxmitframe;
  691. if (xmitframe_direct(padapter, pxmitframe) != _SUCCESS) {
  692. rtw_free_xmitbuf(pxmitpriv, pxmitbuf);
  693. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  694. }
  695. return _TRUE;
  696. enqueue:
  697. res = rtw_xmitframe_enqueue(padapter, pxmitframe);
  698. _exit_critical_bh(&pxmitpriv->lock, &irqL);
  699. if (res != _SUCCESS) {
  700. RT_TRACE(_module_xmit_osdep_c_, _drv_err_, ("pre_xmitframe: enqueue xmitframe fail\n"));
  701. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  702. // Trick, make the statistics correct
  703. pxmitpriv->tx_pkts--;
  704. pxmitpriv->tx_drop++;
  705. return _TRUE;
  706. }
  707. return _FALSE;
  708. }
  709. s32 rtl8812au_mgnt_xmit(_adapter *padapter, struct xmit_frame *pmgntframe)
  710. {
  711. return rtw_dump_xframe(padapter, pmgntframe);
  712. }
  713. /*
  714. * Return
  715. * _TRUE dump packet directly ok
  716. * _FALSE temporary can't transmit packets to hardware
  717. */
  718. s32 rtl8812au_hal_xmit(_adapter *padapter, struct xmit_frame *pxmitframe)
  719. {
  720. return pre_xmitframe(padapter, pxmitframe);
  721. }
  722. s32 rtl8812au_hal_xmitframe_enqueue(_adapter *padapter, struct xmit_frame *pxmitframe)
  723. {
  724. struct xmit_priv *pxmitpriv = &padapter->xmitpriv;
  725. s32 err;
  726. if ((err=rtw_xmitframe_enqueue(padapter, pxmitframe)) != _SUCCESS)
  727. {
  728. rtw_free_xmitframe(pxmitpriv, pxmitframe);
  729. // Trick, make the statistics correct
  730. pxmitpriv->tx_pkts--;
  731. pxmitpriv->tx_drop++;
  732. }
  733. else
  734. {
  735. #ifdef PLATFORM_LINUX
  736. tasklet_hi_schedule(&pxmitpriv->xmit_tasklet);
  737. #endif
  738. }
  739. return err;
  740. }
  741. #ifdef CONFIG_HOSTAPD_MLME
  742. static void rtl8812au_hostap_mgnt_xmit_cb(struct urb *urb)
  743. {
  744. #ifdef PLATFORM_LINUX
  745. struct sk_buff *skb = (struct sk_buff *)urb->context;
  746. //DBG_8192C("%s\n", __FUNCTION__);
  747. dev_kfree_skb_any(skb);
  748. #endif
  749. }
  750. s32 rtl8812au_hostap_mgnt_xmit_entry(_adapter *padapter, _pkt *pkt)
  751. {
  752. #ifdef PLATFORM_LINUX
  753. u16 fc;
  754. int rc, len, pipe;
  755. unsigned int bmcst, tid, qsel;
  756. struct sk_buff *skb, *pxmit_skb;
  757. struct urb *urb;
  758. unsigned char *pxmitbuf;
  759. struct tx_desc *ptxdesc;
  760. struct rtw_ieee80211_hdr *tx_hdr;
  761. struct hostapd_priv *phostapdpriv = padapter->phostapdpriv;
  762. struct net_device *pnetdev = padapter->pnetdev;
  763. HAL_DATA_TYPE *pHalData = GET_HAL_DATA(padapter);
  764. struct dvobj_priv *pdvobj = adapter_to_dvobj(padapter);
  765. //DBG_8192C("%s\n", __FUNCTION__);
  766. skb = pkt;
  767. len = skb->len;
  768. tx_hdr = (struct rtw_ieee80211_hdr *)(skb->data);
  769. fc = le16_to_cpu(tx_hdr->frame_ctl);
  770. bmcst = IS_MCAST(tx_hdr->addr1);
  771. if ((fc & RTW_IEEE80211_FCTL_FTYPE) != RTW_IEEE80211_FTYPE_MGMT)
  772. goto _exit;
  773. #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18)) // http://www.mail-archive.com/netdev@vger.kernel.org/msg17214.html
  774. pxmit_skb = dev_alloc_skb(len + TXDESC_SIZE);
  775. #else
  776. pxmit_skb = netdev_alloc_skb(pnetdev, len + TXDESC_SIZE);
  777. #endif
  778. if(!pxmit_skb)
  779. goto _exit;
  780. pxmitbuf = pxmit_skb->data;
  781. urb = usb_alloc_urb(0, GFP_ATOMIC);
  782. if (!urb) {
  783. goto _exit;
  784. }
  785. // ----- fill tx desc -----
  786. ptxdesc = (struct tx_desc *)pxmitbuf;
  787. _rtw_memset(ptxdesc, 0, sizeof(*ptxdesc));
  788. //offset 0
  789. ptxdesc->txdw0 |= cpu_to_le32(len&0x0000ffff);
  790. ptxdesc->txdw0 |= cpu_to_le32(((TXDESC_SIZE+OFFSET_SZ)<<OFFSET_SHT)&0x00ff0000);//default = 32 bytes for TX Desc
  791. ptxdesc->txdw0 |= cpu_to_le32(OWN | FSG | LSG);
  792. if(bmcst)
  793. {
  794. ptxdesc->txdw0 |= cpu_to_le32(BIT(24));
  795. }
  796. //offset 4
  797. ptxdesc->txdw1 |= cpu_to_le32(0x00);//MAC_ID
  798. ptxdesc->txdw1 |= cpu_to_le32((0x12<<QSEL_SHT)&0x00001f00);
  799. ptxdesc->txdw1 |= cpu_to_le32((0x06<< 16) & 0x000f0000);//b mode
  800. //offset 8
  801. //offset 12
  802. ptxdesc->txdw3 |= cpu_to_le32((le16_to_cpu(tx_hdr->seq_ctl)<<16)&0xffff0000);
  803. //offset 16
  804. ptxdesc->txdw4 |= cpu_to_le32(BIT(8));//driver uses rate
  805. //offset 20
  806. //HW append seq
  807. ptxdesc->txdw4 |= cpu_to_le32(BIT(7)); // Hw set sequence number
  808. ptxdesc->txdw3 |= cpu_to_le32((8 <<28)); //set bit3 to 1. Suugested by TimChen. 2009.12.29.
  809. rtl8188eu_cal_txdesc_chksum(ptxdesc);
  810. // ----- end of fill tx desc -----
  811. //
  812. skb_put(pxmit_skb, len + TXDESC_SIZE);
  813. pxmitbuf = pxmitbuf + TXDESC_SIZE;
  814. _rtw_memcpy(pxmitbuf, skb->data, len);
  815. //DBG_8192C("mgnt_xmit, len=%x\n", pxmit_skb->len);
  816. // ----- prepare urb for submit -----
  817. //translate DMA FIFO addr to pipehandle
  818. //pipe = ffaddr2pipehdl(pdvobj, MGT_QUEUE_INX);
  819. pipe = usb_sndbulkpipe(pdvobj->pusbdev, pHalData->Queue2EPNum[(u8)MGT_QUEUE_INX]&0x0f);
  820. usb_fill_bulk_urb(urb, pdvobj->pusbdev, pipe,
  821. pxmit_skb->data, pxmit_skb->len, rtl8192cu_hostap_mgnt_xmit_cb, pxmit_skb);
  822. urb->transfer_flags |= URB_ZERO_PACKET;
  823. usb_anchor_urb(urb, &phostapdpriv->anchored);
  824. rc = usb_submit_urb(urb, GFP_ATOMIC);
  825. if (rc < 0) {
  826. usb_unanchor_urb(urb);
  827. kfree_skb(skb);
  828. }
  829. usb_free_urb(urb);
  830. _exit:
  831. dev_kfree_skb_any(skb);
  832. #endif
  833. return 0;
  834. }
  835. #endif