rtl8812a_xmit.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  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 _RTL8812A_XMIT_C_
  21. //#include <drv_types.h>
  22. #include <rtl8812a_hal.h>
  23. void _dbg_dump_tx_info(_adapter *padapter,int frame_tag, u8 *ptxdesc)
  24. {
  25. u8 bDumpTxPkt;
  26. u8 bDumpTxDesc = _FALSE;
  27. rtw_hal_get_def_var(padapter, HAL_DEF_DBG_DUMP_TXPKT, &(bDumpTxPkt));
  28. if(bDumpTxPkt ==1){//dump txdesc for data frame
  29. DBG_871X("dump tx_desc for data frame\n");
  30. if((frame_tag&0x0f) == DATA_FRAMETAG){
  31. bDumpTxDesc = _TRUE;
  32. }
  33. }
  34. else if(bDumpTxPkt ==2){//dump txdesc for mgnt frame
  35. DBG_871X("dump tx_desc for mgnt frame\n");
  36. if((frame_tag&0x0f) == MGNT_FRAMETAG){
  37. bDumpTxDesc = _TRUE;
  38. }
  39. }
  40. else if(bDumpTxPkt ==3){//dump early info
  41. }
  42. if(bDumpTxDesc){
  43. // ptxdesc->txdw4 = cpu_to_le32(0x00001006);//RTS Rate=24M
  44. // ptxdesc->txdw6 = 0x6666f800;
  45. DBG_8192C("=====================================\n");
  46. DBG_8192C("Offset00(0x%08x)\n",*((u32 *)(ptxdesc)));
  47. DBG_8192C("Offset04(0x%08x)\n",*((u32 *)(ptxdesc+4)));
  48. DBG_8192C("Offset08(0x%08x)\n",*((u32 *)(ptxdesc+8)));
  49. DBG_8192C("Offset12(0x%08x)\n",*((u32 *)(ptxdesc+12)));
  50. DBG_8192C("Offset16(0x%08x)\n",*((u32 *)(ptxdesc+16)));
  51. DBG_8192C("Offset20(0x%08x)\n",*((u32 *)(ptxdesc+20)));
  52. DBG_8192C("Offset24(0x%08x)\n",*((u32 *)(ptxdesc+24)));
  53. DBG_8192C("Offset28(0x%08x)\n",*((u32 *)(ptxdesc+28)));
  54. DBG_8192C("Offset32(0x%08x)\n",*((u32 *)(ptxdesc+32)));
  55. DBG_8192C("Offset36(0x%08x)\n",*((u32 *)(ptxdesc+36)));
  56. DBG_8192C("=====================================\n");
  57. }
  58. }
  59. /*
  60. * Description:
  61. * Aggregation packets and send to hardware
  62. *
  63. * Return:
  64. * 0 Success
  65. * -1 Hardware resource(TX FIFO) not ready
  66. * -2 Software resource(xmitbuf) not ready
  67. */
  68. #ifdef CONFIG_TX_EARLY_MODE
  69. //#define DBG_EMINFO
  70. #if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
  71. #define EARLY_MODE_MAX_PKT_NUM 10
  72. #else
  73. #define EARLY_MODE_MAX_PKT_NUM 5
  74. #endif
  75. struct EMInfo{
  76. u8 EMPktNum;
  77. u16 EMPktLen[EARLY_MODE_MAX_PKT_NUM];
  78. };
  79. void
  80. InsertEMContent_8812(
  81. struct EMInfo *pEMInfo,
  82. IN pu1Byte VirtualAddress)
  83. {
  84. #if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
  85. u1Byte index=0;
  86. u4Byte dwtmp=0;
  87. #endif
  88. _rtw_memset(VirtualAddress, 0, EARLY_MODE_INFO_SIZE);
  89. if(pEMInfo->EMPktNum==0)
  90. return;
  91. #ifdef DBG_EMINFO
  92. {
  93. int i;
  94. DBG_8192C("\n%s ==> pEMInfo->EMPktNum =%d\n",__FUNCTION__,pEMInfo->EMPktNum);
  95. for(i=0;i< EARLY_MODE_MAX_PKT_NUM;i++){
  96. DBG_8192C("%s ==> pEMInfo->EMPktLen[%d] =%d\n",__FUNCTION__,i,pEMInfo->EMPktLen[i]);
  97. }
  98. }
  99. #endif
  100. #if RTL8188E_EARLY_MODE_PKT_NUM_10 == 1
  101. SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
  102. if(pEMInfo->EMPktNum == 1){
  103. dwtmp = pEMInfo->EMPktLen[0];
  104. }else{
  105. dwtmp = pEMInfo->EMPktLen[0];
  106. dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
  107. dwtmp += pEMInfo->EMPktLen[1];
  108. }
  109. SET_EARLYMODE_LEN0(VirtualAddress, dwtmp);
  110. if(pEMInfo->EMPktNum <= 3){
  111. dwtmp = pEMInfo->EMPktLen[2];
  112. }else{
  113. dwtmp = pEMInfo->EMPktLen[2];
  114. dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
  115. dwtmp += pEMInfo->EMPktLen[3];
  116. }
  117. SET_EARLYMODE_LEN1(VirtualAddress, dwtmp);
  118. if(pEMInfo->EMPktNum <= 5){
  119. dwtmp = pEMInfo->EMPktLen[4];
  120. }else{
  121. dwtmp = pEMInfo->EMPktLen[4];
  122. dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
  123. dwtmp += pEMInfo->EMPktLen[5];
  124. }
  125. SET_EARLYMODE_LEN2_1(VirtualAddress, dwtmp&0xF);
  126. SET_EARLYMODE_LEN2_2(VirtualAddress, dwtmp>>4);
  127. if(pEMInfo->EMPktNum <= 7){
  128. dwtmp = pEMInfo->EMPktLen[6];
  129. }else{
  130. dwtmp = pEMInfo->EMPktLen[6];
  131. dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
  132. dwtmp += pEMInfo->EMPktLen[7];
  133. }
  134. SET_EARLYMODE_LEN3(VirtualAddress, dwtmp);
  135. if(pEMInfo->EMPktNum <= 9){
  136. dwtmp = pEMInfo->EMPktLen[8];
  137. }else{
  138. dwtmp = pEMInfo->EMPktLen[8];
  139. dwtmp += ((dwtmp%4)?(4-dwtmp%4):0)+4;
  140. dwtmp += pEMInfo->EMPktLen[9];
  141. }
  142. SET_EARLYMODE_LEN4(VirtualAddress, dwtmp);
  143. #else
  144. SET_EARLYMODE_PKTNUM(VirtualAddress, pEMInfo->EMPktNum);
  145. SET_EARLYMODE_LEN0(VirtualAddress, pEMInfo->EMPktLen[0]);
  146. SET_EARLYMODE_LEN1(VirtualAddress, pEMInfo->EMPktLen[1]);
  147. SET_EARLYMODE_LEN2_1(VirtualAddress, pEMInfo->EMPktLen[2]&0xF);
  148. SET_EARLYMODE_LEN2_2(VirtualAddress, pEMInfo->EMPktLen[2]>>4);
  149. SET_EARLYMODE_LEN3(VirtualAddress, pEMInfo->EMPktLen[3]);
  150. SET_EARLYMODE_LEN4(VirtualAddress, pEMInfo->EMPktLen[4]);
  151. #endif
  152. //RT_PRINT_DATA(COMP_SEND, DBG_LOUD, "EMHdr:", VirtualAddress, 8);
  153. }
  154. void UpdateEarlyModeInfo8812(struct xmit_priv *pxmitpriv,struct xmit_buf *pxmitbuf )
  155. {
  156. //_adapter *padapter, struct xmit_frame *pxmitframe,struct tx_servq *ptxservq
  157. int index,j;
  158. u16 offset,pktlen;
  159. PTXDESC_8812 ptxdesc;
  160. u8 *pmem,*pEMInfo_mem;
  161. s8 node_num_0=0,node_num_1=0;
  162. struct EMInfo eminfo;
  163. struct agg_pkt_info *paggpkt;
  164. struct xmit_frame *pframe = (struct xmit_frame*)pxmitbuf->priv_data;
  165. pmem= pframe->buf_addr;
  166. #ifdef DBG_EMINFO
  167. DBG_8192C("\n%s ==> agg_num:%d\n",__FUNCTION__, pframe->agg_num);
  168. for(index=0;index<pframe->agg_num;index++){
  169. offset = pxmitpriv->agg_pkt[index].offset;
  170. pktlen = pxmitpriv->agg_pkt[index].pkt_len;
  171. DBG_8192C("%s ==> agg_pkt[%d].offset=%d\n",__FUNCTION__,index,offset);
  172. DBG_8192C("%s ==> agg_pkt[%d].pkt_len=%d\n",__FUNCTION__,index,pktlen);
  173. }
  174. #endif
  175. if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM)
  176. {
  177. node_num_0 = pframe->agg_num;
  178. node_num_1= EARLY_MODE_MAX_PKT_NUM-1;
  179. }
  180. for(index=0;index<pframe->agg_num;index++){
  181. offset = pxmitpriv->agg_pkt[index].offset;
  182. pktlen = pxmitpriv->agg_pkt[index].pkt_len;
  183. _rtw_memset(&eminfo,0,sizeof(struct EMInfo));
  184. if( pframe->agg_num > EARLY_MODE_MAX_PKT_NUM){
  185. if(node_num_0 > EARLY_MODE_MAX_PKT_NUM){
  186. eminfo.EMPktNum = EARLY_MODE_MAX_PKT_NUM;
  187. node_num_0--;
  188. }
  189. else{
  190. eminfo.EMPktNum = node_num_1;
  191. node_num_1--;
  192. }
  193. }
  194. else{
  195. eminfo.EMPktNum = pframe->agg_num-(index+1);
  196. }
  197. for(j=0;j< eminfo.EMPktNum ;j++){
  198. eminfo.EMPktLen[j] = pxmitpriv->agg_pkt[index+1+j].pkt_len+4;// 4 bytes CRC
  199. }
  200. if(pmem){
  201. if(index==0){
  202. ptxdesc = (PTXDESC_8812)(pmem);
  203. pEMInfo_mem = ((u8 *)ptxdesc)+TXDESC_SIZE;
  204. }
  205. else{
  206. pmem = pmem + pxmitpriv->agg_pkt[index-1].offset;
  207. ptxdesc = (PTXDESC_8812)(pmem);
  208. pEMInfo_mem = ((u8 *)ptxdesc)+TXDESC_SIZE;
  209. }
  210. #ifdef DBG_EMINFO
  211. DBG_8192C("%s ==> desc.pkt_len=%d\n",__FUNCTION__,ptxdesc->pktlen);
  212. #endif
  213. InsertEMContent_8812(&eminfo,pEMInfo_mem);
  214. }
  215. }
  216. _rtw_memset(pxmitpriv->agg_pkt,0,sizeof(struct agg_pkt_info)*MAX_AGG_PKT_NUM);
  217. }
  218. #endif
  219. void rtl8812a_cal_txdesc_chksum(u8 *ptxdesc)
  220. {
  221. u16 *usPtr;
  222. u32 count;
  223. u32 index;
  224. u16 checksum = 0;
  225. usPtr = (u16*)ptxdesc;
  226. // checksume is always calculated by first 32 bytes,
  227. // and it doesn't depend on TX DESC length.
  228. // Thomas,Lucas@SD4,20130515
  229. count = 16;
  230. // Clear first
  231. SET_TX_DESC_TX_DESC_CHECKSUM_8812(ptxdesc, 0);
  232. for(index = 0 ; index < count ; index++){
  233. checksum = checksum ^ le16_to_cpu(*(usPtr + index));
  234. }
  235. SET_TX_DESC_TX_DESC_CHECKSUM_8812(ptxdesc, checksum);
  236. }
  237. //
  238. // Description: In normal chip, we should send some packet to Hw which will be used by Fw
  239. // in FW LPS mode. The function is to fill the Tx descriptor of this packets, then
  240. // Fw can tell Hw to send these packet derectly.
  241. //
  242. void rtl8812a_fill_fake_txdesc(
  243. PADAPTER padapter,
  244. u8* pDesc,
  245. u32 BufferLen,
  246. u8 IsPsPoll,
  247. u8 IsBTQosNull)
  248. {
  249. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  250. // Clear all status
  251. _rtw_memset(pDesc, 0, TXDESC_SIZE);
  252. SET_TX_DESC_FIRST_SEG_8812(pDesc, 1);
  253. SET_TX_DESC_LAST_SEG_8812(pDesc, 1);
  254. SET_TX_DESC_OFFSET_8812(pDesc, TXDESC_SIZE);
  255. SET_TX_DESC_PKT_SIZE_8812(pDesc, BufferLen);
  256. SET_TX_DESC_QUEUE_SEL_8812(pDesc, QSLT_MGNT);
  257. if (pmlmeext->cur_wireless_mode & WIRELESS_11B) {
  258. SET_TX_DESC_RATE_ID_8812(pDesc, RATEID_IDX_B);
  259. } else {
  260. SET_TX_DESC_RATE_ID_8812(pDesc, RATEID_IDX_G);
  261. }
  262. //Set NAVUSEHDR to prevent Ps-poll AId filed to be changed to error vlaue by Hw.
  263. if (IsPsPoll)
  264. {
  265. SET_TX_DESC_NAV_USE_HDR_8812(pDesc, 1);
  266. }
  267. else
  268. {
  269. SET_TX_DESC_HWSEQ_EN_8812(pDesc, 1); // Hw set sequence number
  270. }
  271. if(IsBTQosNull)
  272. {
  273. SET_TX_DESC_BT_INT_8812(pDesc, 1);
  274. }
  275. SET_TX_DESC_USE_RATE_8812(pDesc, 1);
  276. SET_TX_DESC_OWN_8812(pDesc, 1);
  277. SET_TX_DESC_TX_RATE_8812(pDesc, MRateToHwRate(pmlmeext->tx_rate));
  278. #if defined(CONFIG_USB_HCI) || defined(CONFIG_SDIO_HCI)
  279. // USB interface drop packet if the checksum of descriptor isn't correct.
  280. // Using this checksum can let hardware recovery from packet bulk out error (e.g. Cancel URC, Bulk out error.).
  281. rtl8812a_cal_txdesc_chksum(pDesc);
  282. #endif
  283. }
  284. void rtl8812a_fill_txdesc_sectype(struct pkt_attrib *pattrib, u8 *ptxdesc)
  285. {
  286. if ((pattrib->encrypt > 0) && !pattrib->bswenc)
  287. {
  288. switch (pattrib->encrypt)
  289. {
  290. //SEC_TYPE : 0:NO_ENC,1:WEP40/TKIP,2:WAPI,3:AES
  291. case _WEP40_:
  292. case _WEP104_:
  293. case _TKIP_:
  294. case _TKIP_WTMIC_:
  295. SET_TX_DESC_SEC_TYPE_8812(ptxdesc, 0x1);
  296. break;
  297. #ifdef CONFIG_WAPI_SUPPORT
  298. case _SMS4_:
  299. SET_TX_DESC_SEC_TYPE_8812(ptxdesc, 0x2);
  300. break;
  301. #endif
  302. case _AES_:
  303. SET_TX_DESC_SEC_TYPE_8812(ptxdesc, 0x3);
  304. break;
  305. case _NO_PRIVACY_:
  306. default:
  307. SET_TX_DESC_SEC_TYPE_8812(ptxdesc, 0x0);
  308. break;
  309. }
  310. }
  311. }
  312. void rtl8812a_fill_txdesc_vcs(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
  313. {
  314. struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
  315. struct mlme_ext_info *pmlmeinfo = &(pmlmeext->mlmext_info);
  316. //DBG_8192C("vcs_mode=%d\n", pattrib->vcs_mode);
  317. if (pattrib->vcs_mode) {
  318. switch(pattrib->vcs_mode)
  319. {
  320. case RTS_CTS:
  321. SET_TX_DESC_RTS_ENABLE_8812(ptxdesc, 1);
  322. break;
  323. case CTS_TO_SELF:
  324. SET_TX_DESC_CTS2SELF_8812(ptxdesc, 1);
  325. break;
  326. case NONE_VCS:
  327. default:
  328. break;
  329. }
  330. if (pmlmeinfo->preamble_mode == PREAMBLE_SHORT)
  331. SET_TX_DESC_RTS_SHORT_8812(ptxdesc, 1);
  332. SET_TX_DESC_RTS_RATE_8812(ptxdesc, 0x8);//RTS Rate=24M
  333. SET_TX_DESC_RTS_RATE_FB_LIMIT_8812(ptxdesc, 0xf);
  334. //Enable HW RTS
  335. //SET_TX_DESC_HW_RTS_ENABLE_8812(ptxdesc, 1);
  336. }
  337. }
  338. void rtl8812a_fill_txdesc_phy(PADAPTER padapter, struct pkt_attrib *pattrib, u8 *ptxdesc)
  339. {
  340. //DBG_8192C("bwmode=%d, ch_off=%d\n", pattrib->bwmode, pattrib->ch_offset);
  341. if(pattrib->ht_en)
  342. {
  343. // Set Bandwidth and sub-channel settings.
  344. SET_TX_DESC_DATA_BW_8812(ptxdesc, BWMapping_8812(padapter,pattrib));
  345. //SET_TX_DESC_DATA_SC_8812(ptxdesc, SCMapping_8812(padapter,pattrib));
  346. }
  347. }
  348. u8
  349. BWMapping_8812(
  350. IN PADAPTER Adapter,
  351. IN struct pkt_attrib *pattrib
  352. )
  353. {
  354. u8 BWSettingOfDesc = 0;
  355. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
  356. //DBG_871X("BWMapping pHalData->CurrentChannelBW %d, pattrib->bwmode %d \n",pHalData->CurrentChannelBW,pattrib->bwmode);
  357. if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_80)
  358. {
  359. if(pattrib->bwmode == CHANNEL_WIDTH_80)
  360. BWSettingOfDesc= 2;
  361. else if(pattrib->bwmode == CHANNEL_WIDTH_40)
  362. BWSettingOfDesc = 1;
  363. else
  364. BWSettingOfDesc = 0;
  365. }
  366. else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
  367. {
  368. if((pattrib->bwmode == CHANNEL_WIDTH_40) || (pattrib->bwmode == CHANNEL_WIDTH_80))
  369. BWSettingOfDesc = 1;
  370. else
  371. BWSettingOfDesc = 0;
  372. }
  373. else
  374. BWSettingOfDesc = 0;
  375. return BWSettingOfDesc;
  376. }
  377. u8
  378. SCMapping_8812(
  379. IN PADAPTER Adapter,
  380. IN struct pkt_attrib *pattrib
  381. )
  382. {
  383. u8 SCSettingOfDesc = 0;
  384. PHAL_DATA_TYPE pHalData = GET_HAL_DATA(Adapter);
  385. //DBG_871X("SCMapping: pHalData->CurrentChannelBW %d, pHalData->nCur80MhzPrimeSC %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur80MhzPrimeSC,pHalData->nCur40MhzPrimeSC);
  386. if(pHalData->CurrentChannelBW == CHANNEL_WIDTH_80)
  387. {
  388. if(pattrib->bwmode == CHANNEL_WIDTH_80)
  389. {
  390. SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
  391. }
  392. else if(pattrib->bwmode == CHANNEL_WIDTH_40)
  393. {
  394. if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
  395. SCSettingOfDesc = VHT_DATA_SC_40_LOWER_OF_80MHZ;
  396. else if(pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
  397. SCSettingOfDesc = VHT_DATA_SC_40_UPPER_OF_80MHZ;
  398. else
  399. DBG_871X("SCMapping: Not Correct Primary40MHz Setting \n");
  400. }
  401. else
  402. {
  403. if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
  404. SCSettingOfDesc = VHT_DATA_SC_20_LOWEST_OF_80MHZ;
  405. else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER))
  406. SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
  407. else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
  408. SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
  409. else if((pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER) && (pHalData->nCur80MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER))
  410. SCSettingOfDesc = VHT_DATA_SC_20_UPPERST_OF_80MHZ;
  411. else
  412. DBG_871X("SCMapping: Not Correct Primary40MHz Setting \n");
  413. }
  414. }
  415. else if(pHalData->CurrentChannelBW== CHANNEL_WIDTH_40)
  416. {
  417. //DBG_871X("SCMapping: HT Case: pHalData->CurrentChannelBW %d, pHalData->nCur40MhzPrimeSC %d \n",pHalData->CurrentChannelBW,pHalData->nCur40MhzPrimeSC);
  418. if(pattrib->bwmode == CHANNEL_WIDTH_40)
  419. {
  420. SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
  421. }
  422. else if(pattrib->bwmode == CHANNEL_WIDTH_20)
  423. {
  424. if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_UPPER)
  425. {
  426. SCSettingOfDesc = VHT_DATA_SC_20_UPPER_OF_80MHZ;
  427. }
  428. else if(pHalData->nCur40MhzPrimeSC == HAL_PRIME_CHNL_OFFSET_LOWER)
  429. {
  430. SCSettingOfDesc = VHT_DATA_SC_20_LOWER_OF_80MHZ;
  431. }
  432. else
  433. {
  434. SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
  435. }
  436. }
  437. }
  438. else
  439. {
  440. SCSettingOfDesc = VHT_DATA_SC_DONOT_CARE;
  441. }
  442. return SCSettingOfDesc;
  443. }