OSDN Git Service

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