net: wireless: rockchip_wlan: add rtl8723ds support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723ds / hal / phydm / txbf / haltxbf8822b.c
1 /*============================================================*/
2 /* Description:                                               */
3 /*                                                            */
4 /* This file is for 8814A TXBF mechanism                      */
5 /*                                                            */
6 /*============================================================*/
7
8 #include "mp_precomp.h"
9 #include "phydm_precomp.h"
10
11 #if (RTL8822B_SUPPORT == 1)
12 #if (BEAMFORMING_SUPPORT == 1)
13
14 u1Byte
15 halTxbf8822B_GetNtx(
16         IN PVOID                        pDM_VOID
17         )
18 {
19         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
20         u1Byte                  Ntx = 0;
21
22 #if DEV_BUS_TYPE == RT_USB_INTERFACE
23         if (pDM_Odm->SupportInterface == ODM_ITRF_USB) {
24                 if (*pDM_Odm->HubUsbMode == 2) {/*USB3.0*/
25                         if (pDM_Odm->RFType == ODM_4T4R)
26                                 Ntx = 3;
27                         else if (pDM_Odm->RFType == ODM_3T3R)
28                                 Ntx = 2;
29                         else
30                                 Ntx = 1;
31                 } else if (*pDM_Odm->HubUsbMode == 1)   /*USB 2.0 always 2Tx*/
32                         Ntx = 1;
33                 else
34                         Ntx = 1;
35         } else
36 #endif
37         {
38                 if (pDM_Odm->RFType == ODM_4T4R)
39                         Ntx = 3;
40                 else if (pDM_Odm->RFType == ODM_3T3R)
41                         Ntx = 2;
42                 else
43                         Ntx = 1;
44         }
45
46         return Ntx;
47
48 }
49
50 u1Byte
51 halTxbf8822B_GetNrx(
52         IN PVOID                        pDM_VOID
53         )
54 {
55         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
56         u1Byte                  Nrx = 0;
57
58         if (pDM_Odm->RFType == ODM_4T4R)
59                 Nrx = 3;
60         else if (pDM_Odm->RFType == ODM_3T3R)
61                 Nrx = 2;
62         else if (pDM_Odm->RFType == ODM_2T2R)
63                 Nrx = 1;
64         else if (pDM_Odm->RFType == ODM_2T3R)
65                 Nrx = 2;
66         else if (pDM_Odm->RFType == ODM_2T4R)
67                 Nrx = 3;
68         else if (pDM_Odm->RFType == ODM_1T1R)
69                 Nrx = 0;
70         else if (pDM_Odm->RFType == ODM_1T2R)
71                 Nrx = 1;
72         else
73                 Nrx = 0;
74
75         return Nrx;
76         
77 }
78
79 /***************SU & MU BFee Entry********************/
80 VOID
81 halTxbf8822B_RfMode(
82         IN PVOID                        pDM_VOID,
83         IN      PRT_BEAMFORMING_INFO    pBeamformingInfo,
84         IN      u1Byte                                  idx
85         )
86 {
87 #if 0
88         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
89         u1Byte                          i, Nr_index = 0;
90         BOOLEAN                         bSelfBeamformer = FALSE;
91         BOOLEAN                         bSelfBeamformee = FALSE;
92         RT_BEAMFORMEE_ENTRY     BeamformeeEntry;
93
94         if (idx < BEAMFORMEE_ENTRY_NUM)
95                 BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx];
96         else
97                 return;
98
99         if (pDM_Odm->RFType == ODM_1T1R)
100                 return;
101
102         for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
103                 ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)i, RF_WeLut_Jaguar, 0x80000, 0x1);
104                 /*RF Mode table write enable*/
105         }
106
107         if ((pBeamformingInfo->beamformee_su_cnt > 0) || (pBeamformingInfo->beamformee_mu_cnt > 0)) {
108                 for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
109                         ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)i, RF_ModeTableAddr, 0xfffff, 0x18000);
110                         /*Select RX mode*/
111                         ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)i, RF_ModeTableData0, 0xfffff, 0xBE77F);
112                         /*Set Table data*/
113                         ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)i, RF_ModeTableData1, 0xfffff, 0x226BF);
114                         /*Enable TXIQGEN in RX mode*/
115                 }
116                 ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_ModeTableData1, 0xfffff, 0xE26BF);
117                 /*Enable TXIQGEN in RX mode*/
118         }
119
120         for (i = ODM_RF_PATH_A; i < ODM_RF_PATH_B; i++) {
121                 ODM_SetRFReg(pDM_Odm, (ODM_RF_RADIO_PATH_E)i, RF_WeLut_Jaguar, 0x80000, 0x0);
122                 /*RF Mode table write disable*/
123         }
124
125         if (pBeamformingInfo->beamformee_su_cnt > 0) {
126
127                 /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/
128                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT28|BIT29, 0x2);                 /*enable BB TxBF ant mapping register*/
129                 
130                 if (idx == 0) {
131                         /*Nsts = 2      AB*/
132                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8822B, 0xffff, 0x0433);
133                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
134                         /*ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x430);*/
135
136                 } else {/*IDX =1*/
137                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
138                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
139                         /*ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2, bMaskLWord, 0x430;*/
140                 }
141         } else {
142                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x1); /*1SS by path-A*/
143                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8822B, bMaskLWord, 0x430); /*2SS by path-A,B*/
144         }
145         
146         if (pBeamformingInfo->beamformee_mu_cnt > 0) {
147                 /*MU STAs share the common setting*/
148                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT31, 1);
149                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
150                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
151         }
152 #endif
153 }
154 #if 0
155 VOID
156 halTxbf8822B_DownloadNDPA(
157         IN      PADAPTER                        Adapter,
158         IN      u1Byte                          Idx
159         )
160 {
161         u1Byte                  u1bTmp = 0, tmpReg422 = 0;
162         u1Byte                  BcnValidReg = 0, count = 0, DLBcnCount = 0;
163         u2Byte                  Head_Page = 0x7FE;
164         BOOLEAN                 bSendBeacon = FALSE;
165         HAL_DATA_TYPE   *pHalData = GET_HAL_DATA(Adapter);
166         u2Byte                  TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/
167         PRT_BEAMFORMING_INFO    pBeamInfo = GET_BEAMFORM_INFO(Adapter);
168         PRT_BEAMFORMEE_ENTRY    pBeamEntry = pBeamInfo->BeamformeeEntry+Idx;
169
170         pHalData->bFwDwRsvdPageInProgress = TRUE;
171         Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu2Byte)&TxPageBndy);
172         
173         /*Set REG_CR bit 8. DMA beacon by SW.*/
174         u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8814A+1);
175         PlatformEFIOWrite1Byte(Adapter,  REG_CR_8814A+1, (u1bTmp|BIT0));
176
177
178         /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/
179         tmpReg422 = PlatformEFIORead1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A+2);
180         PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A+2,  tmpReg422&(~BIT6));
181
182         if (tmpReg422 & BIT6) {
183                 RT_TRACE(COMP_INIT, DBG_LOUD, ("SetBeamformDownloadNDPA_8814A(): There is an Adapter is sending beacon.\n"));
184                 bSendBeacon = TRUE;
185         }
186
187         /*0x204[11:0]   Beacon Head for TXDMA*/
188         PlatformEFIOWrite2Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A, Head_Page);
189         
190         do {            
191                 /*Clear beacon valid check bit.*/
192                 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A+1);
193                 PlatformEFIOWrite1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A+1, (BcnValidReg|BIT7));
194                 
195                 /*download NDPA rsvd page.*/
196                 if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU)
197                         Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE);
198                 else 
199                         Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE);
200         
201                 /*check rsvd page download OK.*/
202                 BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A + 1);
203                 count = 0;
204                 while (!(BcnValidReg & BIT7) && count < 20) {
205                         count++;
206                         delay_us(10);
207                         BcnValidReg = PlatformEFIORead1Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A+2);
208                 }
209                 DLBcnCount++;
210         } while (!(BcnValidReg & BIT7) && DLBcnCount < 5);
211         
212         if (!(BcnValidReg & BIT0))
213                 RT_DISP(FBEAM, FBEAM_ERROR, ("%s Download RSVD page failed!\n", __func__));
214
215         /*0x204[11:0]   Beacon Head for TXDMA*/
216         PlatformEFIOWrite2Byte(Adapter, REG_FIFOPAGE_CTRL_2_8814A, TxPageBndy);
217
218         /*To make sure that if there exists an adapter which would like to send beacon.*/
219         /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/
220         /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */
221         /*the beacon cannot be sent by HW.*/
222         /*2010.06.23. Added by tynli.*/
223         if (bSendBeacon)
224                 PlatformEFIOWrite1Byte(Adapter, REG_FWHW_TXQ_CTRL_8814A+2, tmpReg422);
225
226         /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/
227         /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/
228         u1bTmp = PlatformEFIORead1Byte(Adapter, REG_CR_8814A+1);
229         PlatformEFIOWrite1Byte(Adapter, REG_CR_8814A+1, (u1bTmp&(~BIT0)));
230
231         pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED;
232
233         pHalData->bFwDwRsvdPageInProgress = FALSE;
234 }
235
236 VOID
237 halTxbf8822B_FwTxBFCmd(
238         IN      PADAPTER        Adapter
239         )
240 {
241         u1Byte  Idx, Period = 0;
242         u1Byte  PageNum0 = 0xFF, PageNum1 = 0xFF;
243         u1Byte  u1TxBFParm[3] = {0};
244
245         PMGNT_INFO                              pMgntInfo = &(Adapter->MgntInfo);
246         PRT_BEAMFORMING_INFO    pBeamInfo = GET_BEAMFORM_INFO(Adapter);
247
248         for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) {
249                 if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
250                         if (pBeamInfo->BeamformeeEntry[Idx].bSound) {
251                                 PageNum0 = 0xFE;
252                                 PageNum1 = 0x07;
253                                 Period = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod);
254                         } else if (PageNum0 == 0xFF) {
255                                 PageNum0 = 0xFF; /*stop sounding*/
256                                 PageNum1 = 0x0F;
257                         }
258                 }
259         }
260
261         u1TxBFParm[0] = PageNum0;
262         u1TxBFParm[1] = PageNum1;
263         u1TxBFParm[2] = Period;
264         FillH2CCmd(Adapter, PHYDM_H2C_TXBF, 3, u1TxBFParm);
265         
266         RT_DISP(FBEAM, FBEAM_FUN, ("@%s End, PageNum0 = 0x%x, PageNum1 = 0x%x Period = %d", __func__, PageNum0, PageNum1, Period));
267 }
268 #endif
269
270 VOID
271 HalTxbf8822B_Init(
272         IN PVOID                        pDM_VOID
273         )
274 {
275         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
276         u1Byte          u1bTmp;
277         PRT_BEAMFORMING_INFO            pBeamformingInfo = &pDM_Odm->BeamformingInfo;
278         PADAPTER                                Adapter = pDM_Odm->Adapter;
279
280         ODM_SetBBReg(pDM_Odm, 0x14c0 , BIT16, 1); /*Enable P1 aggr new packet according to P0 transfer time*/
281         ODM_SetBBReg(pDM_Odm, 0x14c0 , BIT15|BIT14|BIT13|BIT12, 10); /*MU Retry Limit*/
282         ODM_SetBBReg(pDM_Odm, 0x14c0 , BIT7, 0); /*Disable Tx MU-MIMO until sounding done*/     
283         ODM_SetBBReg(pDM_Odm, 0x14c0 , 0x3F, 0); /* Clear validity of MU STAs */
284         ODM_Write1Byte(pDM_Odm, 0x167c , 0x70); /*MU-MIMO Option as default value*/
285         ODM_Write2Byte(pDM_Odm, 0x1680 , 0); /*MU-MIMO Control as default value*/
286
287         /* Set MU NDPA rate & BW source */
288         /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
289         u1bTmp = ODM_Read1Byte(pDM_Odm, 0x42C);
290         ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B, (u1bTmp|BIT6));
291         /* 0x45F[7:0] = 0x10 (Rate=OFDM_6M, BW20) */
292         ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8822B, 0x10);
293
294         /*Temp Settings*/
295         ODM_SetBBReg(pDM_Odm, 0x6DC , 0x3F000000, 4); /*STA2's CSI rate is fixed at 6M*/
296         ODM_SetBBReg(pDM_Odm, 0x1C94 , bMaskDWord, 0xAFFFAFFF); /*Grouping bitmap parameters*/
297
298         /* Init HW variable */
299         pBeamformingInfo->RegMUTxCtrl = ODM_Read4Byte(pDM_Odm, 0x14c0);
300
301         if (pDM_Odm->RFType == ODM_2T2R) { /*2T2R*/
302                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: RFType is 2T2R\n", __func__));
303                 config_phydm_trx_mode_8822b(pDM_Odm, (ODM_RF_PATH_E)3, (ODM_RF_PATH_E)3, TRUE);/*Tx2path*/
304         }
305
306 #if (OMNIPEEK_SNIFFER_ENABLED == 1)
307         /* Config HW to receive packet on the user position from registry for sniffer mode. */
308         /* ODM_SetBBReg(pDM_Odm, 0xB00 , BIT9, 1);*/ /* For A-cut only. RegB00[9] = 1 (enable PMAC Rx) */
309         ODM_SetBBReg(pDM_Odm, 0xB54 , BIT30, 1); /* RegB54[30] = 1 (force user position) */
310         ODM_SetBBReg(pDM_Odm, 0xB54 , (BIT29|BIT28), Adapter->MgntInfo.SniffUserPosition); /* RegB54[29:28] = user position (0~3) */
311         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("Set Adapter->MgntInfo.SniffUserPosition=%#X\n", Adapter->MgntInfo.SniffUserPosition));
312 #endif
313 }
314
315 VOID
316 HalTxbf8822B_Enter(
317         IN PVOID                        pDM_VOID,
318         IN u1Byte                               BFerBFeeIdx
319         )
320 {
321         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
322         u1Byte                                  i = 0;
323         u1Byte                                  BFerIdx = (BFerBFeeIdx & 0xF0)>>4;
324         u1Byte                                  BFeeIdx = (BFerBFeeIdx & 0xF);
325         u2Byte                                  CSI_Param = 0;
326         PRT_BEAMFORMING_INFO            pBeamformingInfo = &pDM_Odm->BeamformingInfo;
327         PRT_BEAMFORMEE_ENTRY    pBeamformeeEntry;
328         PRT_BEAMFORMER_ENTRY    pBeamformerEntry;
329         u2Byte                                  value16, STAid = 0;
330         u1Byte                                  Nc_index = 0, Nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0;
331         u4Byte                                  gid_valid, user_position_l, user_position_h;
332         u4Byte                                  mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e};
333         u1Byte                                  u1bTmp;
334         u4Byte                                  u4bTmp;
335         
336         RT_DISP(FBEAM, FBEAM_FUN, ("%s: BFerBFeeIdx=%d, BFerIdx=%d, BFeeIdx=%d\n", __func__, BFerBFeeIdx, BFerIdx, BFeeIdx));
337
338         /*************SU BFer Entry Init*************/
339         if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) {
340                 pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[BFerIdx];
341                 pBeamformerEntry->is_mu_ap = FALSE;
342                 /*Sounding protocol control*/
343                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xDB); 
344         
345                 
346                 for (i = 0; i < MAX_BEAMFORMER_SU; i++) {
347                         if ((pBeamformingInfo->beamformer_su_reg_maping & BIT(i)) == 0) {
348                                 pBeamformingInfo->beamformer_su_reg_maping |= BIT(i);
349                                 pBeamformerEntry->su_reg_index = i;
350                                 break;
351                         }
352                 }
353                 
354                 /*MAC address/Partial AID of Beamformer*/
355                 if (pBeamformerEntry->su_reg_index == 0) {
356                         for (i = 0; i < 6 ; i++)
357                                 ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8822B+i), pBeamformerEntry->MacAddr[i]);
358                 } else {
359                         for (i = 0; i < 6 ; i++)
360                                 ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8822B+i), pBeamformerEntry->MacAddr[i]);
361                 }
362
363                 /*CSI report parameters of Beamformer*/
364                 Nc_index = halTxbf8822B_GetNrx(pDM_Odm);        /*for 8814A Nrx = 3(4 Ant), min=0(1 Ant)*/
365                 Nr_index = pBeamformerEntry->NumofSoundingDim;  /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/
366                 
367                 grouping = 0;
368
369                 /*for ac = 1, for n = 3*/
370                 if (pBeamformerEntry->BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU)
371                         codebookinfo = 1;       
372                 else if (pBeamformerEntry->BeamformEntryCap & BEAMFORMEE_CAP_HT_EXPLICIT)
373                         codebookinfo = 3;       
374
375                 coefficientsize = 3;
376
377                 CSI_Param = (u2Byte)((coefficientsize<<10)|(codebookinfo<<8)|(grouping<<6)|(Nr_index<<3)|(Nc_index));
378
379                 if (BFerIdx == 0)
380                         ODM_Write2Byte(pDM_Odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, CSI_Param);
381                 else
382                         ODM_Write2Byte(pDM_Odm, REG_TX_CSI_RPT_PARAM_BW20_8822B+2, CSI_Param);
383                 /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/
384                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B+3, 0x70);
385         
386         }
387
388         /*************SU BFee Entry Init*************/
389         if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) {
390                 pBeamformeeEntry = &pBeamformingInfo->BeamformeeEntry[BFeeIdx];
391                 pBeamformeeEntry->is_mu_sta = FALSE;
392                 halTxbf8822B_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx);
393                 
394                 if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS))
395                         STAid = pBeamformeeEntry->MacId;
396                 else 
397                         STAid = pBeamformeeEntry->P_AID;
398
399                 for (i = 0; i < MAX_BEAMFORMEE_SU; i++) {
400                         if ((pBeamformingInfo->beamformee_su_reg_maping & BIT(i)) == 0) {
401                                 pBeamformingInfo->beamformee_su_reg_maping |= BIT(i);
402                                 pBeamformeeEntry->su_reg_index = i;
403                                 break;
404                         }
405                 }
406                 
407                 /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/
408                 if (pBeamformeeEntry->su_reg_index == 0) {      
409                         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B, STAid);    
410                         ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3)|BIT4|BIT6|BIT7);
411                 } else {
412                         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B+2, STAid | BIT14 | BIT15 | BIT12);
413                 }       
414
415                 /*CSI report parameters of Beamformee*/
416                 if (pBeamformeeEntry->su_reg_index == 0) {
417                         /*Get BIT24 & BIT25*/
418                         u1Byte  tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+3) & 0x3;
419                         
420                         ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B + 3, tmp | 0x60);
421                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B, STAid | BIT9);
422                 } else          
423                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+2, STAid | 0xE200);      /*Set BIT25*/
424                         
425                         phydm_Beamforming_Notify(pDM_Odm);
426         }
427
428         /*************MU BFer Entry Init*************/
429         if ((pBeamformingInfo->beamformer_mu_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) {
430                 pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[BFerIdx];
431                 pBeamformingInfo->mu_ap_index = BFerIdx;
432                 pBeamformerEntry->is_mu_ap = TRUE;
433                 for (i = 0; i < 8; i++)
434                         pBeamformerEntry->gid_valid[i] = 0;
435                 for (i = 0; i < 16; i++)
436                         pBeamformerEntry->user_position[i] = 0;
437                 
438                 /*Sounding protocol control*/
439                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xDB); 
440
441                 /* MAC address */
442                 for (i = 0; i < 6 ; i++)
443                         ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8822B+i), pBeamformerEntry->MacAddr[i]);
444
445                 /* Set partial AID */
446                 ODM_Write2Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8822B+6), pBeamformerEntry->P_AID);
447
448                 /* Fill our AID to 0x1680[11:0] and [13:12] = 2b'00, BF report segment select to 3895 bytes*/
449                 u1bTmp = ODM_Read1Byte(pDM_Odm, 0x1680);
450                 u1bTmp = (pBeamformerEntry->AID)&0xFFF;
451                 ODM_Write1Byte(pDM_Odm, 0x1680, u1bTmp);
452
453                 /* Set 80us for leaving ndp_rx_standby_state */
454                 ODM_Write1Byte(pDM_Odm, 0x71B, 0x50);
455                 
456                 /* Set 0x6A0[14] = 1 to accept action_no_ack */
457                 u1bTmp = ODM_Read1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1);
458                 u1bTmp |= 0x40;
459                 ODM_Write1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1, u1bTmp);
460                 /* Set 0x6A2[5:4] = 1 to NDPA and BF report poll */
461                 u1bTmp = ODM_Read1Byte(pDM_Odm, REG_RXFLTMAP1_8822B);
462                 u1bTmp |= 0x30;
463                 ODM_Write1Byte(pDM_Odm, REG_RXFLTMAP1_8822B, u1bTmp);
464                 
465                 /*CSI report parameters of Beamformer*/
466                 Nc_index = halTxbf8822B_GetNrx(pDM_Odm);        /* Depend on RF type */
467                 Nr_index = 1;   /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/
468                 grouping = 0; /*no grouping*/
469                 codebookinfo = 1; /*7 bit for psi, 9 bit for phi*/
470                 coefficientsize = 0; /*This is nothing really matter*/ 
471                 CSI_Param = (u2Byte)((coefficientsize<<10)|(codebookinfo<<8)|(grouping<<6)|(Nr_index<<3)|(Nc_index));
472                 ODM_Write2Byte(pDM_Odm, 0x6F4, CSI_Param);
473
474                 /*for B-Cut*/
475                 ODM_SetBBReg(pDM_Odm, 0x6A0 , BIT20, 0);
476                 ODM_SetBBReg(pDM_Odm, 0x688 , BIT20, 0);
477
478         }
479         \r
480         /*************MU BFee Entry Init*************/
481         if ((pBeamformingInfo->beamformee_mu_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) {
482                 pBeamformeeEntry = &pBeamformingInfo->BeamformeeEntry[BFeeIdx];
483                 pBeamformeeEntry->is_mu_sta = TRUE;
484                 for (i = 0; i < MAX_BEAMFORMEE_MU; i++) {
485                         if ((pBeamformingInfo->beamformee_mu_reg_maping & BIT(i)) == 0) {
486                                 pBeamformingInfo->beamformee_mu_reg_maping |= BIT(i);
487                                 pBeamformeeEntry->mu_reg_index = i;
488                                 break;
489                         }
490                 }
491
492                 if (pBeamformeeEntry->mu_reg_index == 0xFF) {
493                         /* There is no valid bit in beamformee_mu_reg_maping */
494                         RT_DISP(FBEAM, FBEAM_FUN, ("%s: ERROR! There is no valid bit in beamformee_mu_reg_maping!\n", __func__));
495                         return;
496                 }
497                 
498                 /*User position table*/
499                 switch (pBeamformeeEntry->mu_reg_index) {
500                 case 0:
501                         gid_valid = 0x7fe;
502                         user_position_l = 0x111110;
503                         user_position_h = 0x0;
504                         break;
505                 case 1:
506                         gid_valid = 0x7f806;
507                         user_position_l = 0x11000004;
508                         user_position_h = 0x11;
509                         break;
510                 case 2:
511                         gid_valid = 0x1f81818;
512                         user_position_l = 0x400040;
513                         user_position_h = 0x11100;
514                         break;
515                 case 3:
516                         gid_valid = 0x1e186060;
517                         user_position_l = 0x4000400;
518                         user_position_h = 0x1100040;
519                         break;
520                 case 4:
521                         gid_valid = 0x66618180;
522                         user_position_l = 0x40004000;
523                         user_position_h = 0x10040400;
524                         break;
525                 case 5:
526                         gid_valid = 0x79860600;
527                         user_position_l = 0x40000;
528                         user_position_h = 0x4404004;
529                         break;
530                 }
531
532                 for (i = 0; i < 8; i++) {
533                         if (i < 4) {
534                                 pBeamformeeEntry->gid_valid[i] = (u1Byte)(gid_valid & 0xFF);
535                                 gid_valid = (gid_valid >> 8);
536                         } else
537                                 pBeamformeeEntry->gid_valid[i] = 0;
538                 }
539                 for (i = 0; i < 16; i++) {
540                         if (i < 4)
541                                 pBeamformeeEntry->user_position[i] = (u1Byte)((user_position_l >>(i*8)) & 0xFF);
542                         else if (i < 8)
543                                 pBeamformeeEntry->user_position[i] = (u1Byte)((user_position_h >>((i-4)*8)) & 0xFF);
544                         else
545                                 pBeamformeeEntry->user_position[i] = 0;
546                 }
547
548                 /*Sounding protocol control*/
549                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xDB); 
550
551                 /*select MU STA table*/
552                 pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10);
553                 pBeamformingInfo->RegMUTxCtrl |= (pBeamformeeEntry->mu_reg_index << 8)&(BIT8|BIT9|BIT10);
554                 ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl); 
555                 
556                 ODM_SetBBReg(pDM_Odm, 0x14c4 , bMaskDWord, 0); /*Reset gid_valid table*/
557                 ODM_SetBBReg(pDM_Odm, 0x14c8 , bMaskDWord, user_position_l);
558                 ODM_SetBBReg(pDM_Odm, 0x14cc , bMaskDWord, user_position_h);
559
560                 /*set validity of MU STAs*/             
561                 pBeamformingInfo->RegMUTxCtrl &= 0xFFFFFFC0;
562                 pBeamformingInfo->RegMUTxCtrl |= pBeamformingInfo->beamformee_mu_reg_maping&0x3F;
563                 ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
564
565                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, RegMUTxCtrl = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n", 
566                         __func__, pBeamformingInfo->RegMUTxCtrl, user_position_l, user_position_h));
567
568                 value16 = ODM_Read2Byte(pDM_Odm, mu_reg[pBeamformeeEntry->mu_reg_index]);
569                 value16 &= 0xFE00; /*Clear PAID*/
570                 value16 |= BIT9; /*Enable MU BFee*/
571                 value16 |= pBeamformeeEntry->P_AID;
572                 ODM_Write2Byte(pDM_Odm, mu_reg[pBeamformeeEntry->mu_reg_index] , value16);
573                 
574                 /* 0x42C[30] = 1 (0: from Tx desc, 1: from 0x45F) */
575                 u1bTmp = ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3);
576                 u1bTmp |= 0xD0; /* Set bit 28, 30, 31 to 3b'111*/
577                 ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3, u1bTmp);
578                 /* Set NDPA to 6M*/
579                 ODM_Write1Byte(pDM_Odm, REG_NDPA_RATE_8822B, 0x4); 
580
581                 u1bTmp = ODM_Read1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8822B);
582                 u1bTmp &= 0xFC; /* Clear bit 0, 1*/
583                 ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8822B, u1bTmp);
584
585                 u4bTmp = ODM_Read4Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B);
586                 u4bTmp = ((u4bTmp & 0xFF0000FF) | 0x020200); /* Set [23:8] to 0x0202*/
587                 ODM_Write4Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, u4bTmp);       
588
589                 /* Set 0x6A0[14] = 1 to accept action_no_ack */
590                 u1bTmp = ODM_Read1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1);
591                 u1bTmp |= 0x40;
592                 ODM_Write1Byte(pDM_Odm, REG_RXFLTMAP0_8822B+1, u1bTmp);
593                 /* End of MAC registers setting */
594                 
595                 halTxbf8822B_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx);
596 #if (SUPPORT_MU_BF == 1)
597                 /*Special for plugfest*/
598                 delay_ms(50); /* wait for 4-way handshake ending*/
599                 SendSWVHTGIDMgntFrame(pDM_Odm, pBeamformeeEntry->MacAddr, BFeeIdx);
600 #endif          
601
602                 phydm_Beamforming_Notify(pDM_Odm);
603 #if 1
604                 {
605                         u4Byte ctrl_info_offset, index;
606                         /*Set Ctrl Info*/
607                         ODM_Write2Byte(pDM_Odm, 0x140, 0x660);
608                         ctrl_info_offset = 0x8000 + 32 * pBeamformeeEntry->MacId;
609                         /*Reset Ctrl Info*/
610                         for (index = 0; index < 8; index++)
611                                 ODM_Write4Byte(pDM_Odm, ctrl_info_offset + index*4, 0);
612                         
613                         ODM_Write4Byte(pDM_Odm, ctrl_info_offset, (pBeamformeeEntry->mu_reg_index + 1) << 16);
614                         ODM_Write1Byte(pDM_Odm, 0x81, 0x80); /*RPTBUF ready*/
615
616                         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, MacId = %d, ctrl_info_offset = 0x%x, mu_reg_index = %x\n", 
617                         __func__, pBeamformeeEntry->MacId, ctrl_info_offset, pBeamformeeEntry->mu_reg_index));
618                 }
619 #endif
620         }
621
622 }
623
624
625 VOID
626 HalTxbf8822B_Leave(
627         IN PVOID                        pDM_VOID,
628         IN u1Byte                               Idx
629         )
630 {
631         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
632         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;
633         PRT_BEAMFORMER_ENTRY    pBeamformerEntry; 
634         PRT_BEAMFORMEE_ENTRY    pBeamformeeEntry;
635         u4Byte                                  mu_reg[6] = {0x1684, 0x1686, 0x1688, 0x168a, 0x168c, 0x168e};
636
637         if (Idx < BEAMFORMER_ENTRY_NUM) {
638                 pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[Idx];
639                 pBeamformeeEntry = &pBeamformingInfo->BeamformeeEntry[Idx];
640         } else
641                 return;
642
643         /*Clear P_AID of Beamformee*/
644         /*Clear MAC address of Beamformer*/
645         /*Clear Associated Bfmee Sel*/
646
647         if (pBeamformerEntry->BeamformEntryCap == BEAMFORMING_CAP_NONE) {
648                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8822B, 0xD8); 
649                 if (pBeamformerEntry->is_mu_ap == 0) { /*SU BFer */
650                         if (pBeamformerEntry->su_reg_index == 0) {      
651                                 ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8822B, 0);
652                                 ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8822B+4, 0);
653                                 ODM_Write2Byte(pDM_Odm, REG_TX_CSI_RPT_PARAM_BW20_8822B, 0);
654                         } else {
655                                 ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8822B, 0);
656                                 ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8822B+4, 0);
657                                 ODM_Write2Byte(pDM_Odm, REG_TX_CSI_RPT_PARAM_BW20_8822B+2, 0);
658                         }
659                         pBeamformingInfo->beamformer_su_reg_maping &= ~(BIT(pBeamformerEntry->su_reg_index));
660                         pBeamformerEntry->su_reg_index = 0xFF;
661                 } else { /*MU BFer */
662                         /*set validity of MU STA0 and MU STA1*/
663                         pBeamformingInfo->RegMUTxCtrl &= 0xFFFFFFC0;
664                         ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
665
666                         ODM_Memory_Set(pDM_Odm, pBeamformerEntry->gid_valid, 0, 8);
667                         ODM_Memory_Set(pDM_Odm, pBeamformerEntry->user_position, 0, 16);
668                         pBeamformerEntry->is_mu_ap = FALSE;
669                 }
670         }
671
672         if (pBeamformeeEntry->BeamformEntryCap == BEAMFORMING_CAP_NONE) {
673                 halTxbf8822B_RfMode(pDM_Odm, pBeamformingInfo, Idx);
674                 if (pBeamformeeEntry->is_mu_sta == 0) { /*SU BFee*/
675                         if (pBeamformeeEntry->su_reg_index == 0) {      
676                                 ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B, 0x0);      
677                                 ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8822B+3)|BIT4|BIT6|BIT7);
678                                 ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B, 0);
679                         } else {
680                                 ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B+2, 0x0 | BIT14 | BIT15 | BIT12);
681
682                                 ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+2, 
683                                 ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8822B+2) & 0x60);
684                         }
685                         pBeamformingInfo->beamformee_su_reg_maping &= ~(BIT(pBeamformeeEntry->su_reg_index));
686                         pBeamformeeEntry->su_reg_index = 0xFF;
687                 } else { /*MU BFee */
688                         /*Disable sending NDPA & BF-rpt-poll to this BFee*/
689                         ODM_Write2Byte(pDM_Odm, mu_reg[pBeamformeeEntry->mu_reg_index] , 0);
690                         /*set validity of MU STA*/
691                         pBeamformingInfo->RegMUTxCtrl &= ~(BIT(pBeamformeeEntry->mu_reg_index));
692                         ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
693
694                         
695                         pBeamformeeEntry->is_mu_sta = FALSE;
696                         pBeamformingInfo->beamformee_mu_reg_maping &= ~(BIT(pBeamformeeEntry->mu_reg_index));
697                         pBeamformeeEntry->mu_reg_index = 0xFF;
698                 }
699         }
700 }
701
702
703 /***********SU & MU BFee Entry Only when souding done****************/
704 VOID
705 HalTxbf8822B_Status(
706         IN PVOID                        pDM_VOID,
707         IN u1Byte                               Idx
708         )
709 {
710         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
711         u2Byte                                  BeamCtrlVal, tmpVal;
712         u4Byte                                  BeamCtrlReg;
713         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;
714         PRT_BEAMFORMEE_ENTRY    pBeamformEntry;
715         BOOLEAN is_mu_sounding = pBeamformingInfo->is_mu_sounding, is_bitmap_ready = FALSE;
716         u16 bitmap;
717         u8 idx, gid, i;
718         u8 id1, id0;
719         u32 gid_valid[6] = {0};
720         u32 user_position_lsb[6] = {0};
721         u32 user_position_msb[6] = {0};
722         u32 value32;
723         BOOLEAN is_sounding_success[6] = {FALSE};
724
725         if (Idx < BEAMFORMEE_ENTRY_NUM)
726                 pBeamformEntry = &pBeamformingInfo->BeamformeeEntry[Idx];
727         else
728                 return;
729         
730         /*SU sounding done */
731         if (is_mu_sounding == FALSE) {
732
733                 if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS))
734                         BeamCtrlVal = pBeamformEntry->MacId;
735                 else 
736                         BeamCtrlVal = pBeamformEntry->P_AID;
737
738                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BeamformEntry.BeamformEntryState = %d", __func__, pBeamformEntry->BeamformEntryState));
739
740                 if (pBeamformEntry->su_reg_index == 0) {
741                         BeamCtrlReg = REG_TXBF_CTRL_8822B;
742                 } else {
743                         BeamCtrlReg = REG_TXBF_CTRL_8822B+2;
744                         BeamCtrlVal |= BIT12|BIT14|BIT15;
745                 }
746
747                 if (pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
748                         if (pBeamformEntry->SoundBW == CHANNEL_WIDTH_20)
749                                 BeamCtrlVal |= BIT9;
750                         else if (pBeamformEntry->SoundBW == CHANNEL_WIDTH_40)
751                                 BeamCtrlVal |= (BIT9|BIT10);
752                         else if (pBeamformEntry->SoundBW == CHANNEL_WIDTH_80)
753                                 BeamCtrlVal |= (BIT9|BIT10|BIT11);              
754                 } else {
755                         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix",  __func__));
756                         BeamCtrlVal &= ~(BIT9|BIT10|BIT11);
757                 }
758
759                 ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal);
760                 /*disable NDP packet use beamforming */
761                 tmpVal = ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8822B);
762                 ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8822B, tmpVal|BIT15);
763         } else {
764                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, MU Sounding Done\n",  __func__));
765                 /*MU sounding done */
766                 if (1){//(pBeamformEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) {
767                         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BEAMFORMING_ENTRY_STATE_PROGRESSED\n",  __func__));
768
769                         value32 = ODM_GetBBReg(pDM_Odm, 0x1684, bMaskDWord);
770                         is_sounding_success[0] = (value32 & BIT10)?1:0;
771                         is_sounding_success[1] = (value32 & BIT26)?1:0;
772                         value32 = ODM_GetBBReg(pDM_Odm, 0x1688, bMaskDWord);
773                         is_sounding_success[2] = (value32 & BIT10)?1:0;
774                         is_sounding_success[3] = (value32 & BIT26)?1:0;
775                         value32 = ODM_GetBBReg(pDM_Odm, 0x168C, bMaskDWord);
776                         is_sounding_success[4] = (value32 & BIT10)?1:0;
777                         is_sounding_success[5] = (value32 & BIT26)?1:0;
778
779                         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, is_sounding_success STA1:%d,  STA2:%d, STA3:%d, STA4:%d, STA5:%d, STA6:%d\n", 
780                                 __func__, is_sounding_success[0], is_sounding_success[1] , is_sounding_success[2] , is_sounding_success[3] , is_sounding_success[4] , is_sounding_success[5] ));
781                         
782                         value32 = ODM_GetBBReg(pDM_Odm, 0xF4C, 0xFFFF0000);
783                         //ODM_SetBBReg(pDM_Odm, 0x19E0, bMaskHWord, 0xFFFF);/*Let MAC ignore bitmap*/
784                         
785                         is_bitmap_ready = (BOOLEAN)((value32 & BIT15) >> 15);
786                         bitmap = (u16)(value32 & 0x3FFF);
787                 
788                         for (idx = 0; idx < 15; idx++) {
789                                 if (idx < 5) {/*bit0~4*/
790                                         id0 = 0;
791                                         id1 = (u8)(idx + 1);
792                                 } else if (idx < 9) { /*bit5~8*/
793                                         id0 = 1;
794                                         id1 = (u8)(idx - 3);
795                                 } else if (idx < 12) { /*bit9~11*/
796                                         id0 = 2;
797                                         id1 = (u8)(idx - 6);
798                                 } else if (idx < 14) { /*bit12~13*/     
799                                         id0 = 3;
800                                         id1 = (u8)(idx - 8);
801                                 } else { /*bit14*/
802                                         id0 = 4;
803                                         id1 = (u8)(idx - 9);
804                                 }
805                                 if (bitmap & BIT(idx)) {
806                                         /*Pair 1*/
807                                         gid = (idx << 1) + 1;
808                                         gid_valid[id0] |= (BIT(gid));
809                                         gid_valid[id1] |= (BIT(gid));
810                                         /*Pair 2*/
811                                         gid += 1;
812                                         gid_valid[id0] |= (BIT(gid));
813                                         gid_valid[id1] |= (BIT(gid));
814                                 } else {
815                                         /*Pair 1*/
816                                         gid = (idx << 1) + 1;
817                                         gid_valid[id0] &= ~(BIT(gid));
818                                         gid_valid[id1] &= ~(BIT(gid));
819                                         /*Pair 2*/
820                                         gid += 1;
821                                         gid_valid[id0] &= ~(BIT(gid));
822                                         gid_valid[id1] &= ~(BIT(gid));
823                                 }
824                         }
825
826                         for (i = 0; i < BEAMFORMEE_ENTRY_NUM; i++) {
827                                 pBeamformEntry = &pBeamformingInfo->BeamformeeEntry[i];
828                                 if ((pBeamformEntry->is_mu_sta) && (pBeamformEntry->mu_reg_index < 6)) {
829                                         value32 = gid_valid[pBeamformEntry->mu_reg_index];
830                                         for (idx = 0; idx < 4; idx++) {
831                                                 pBeamformEntry->gid_valid[idx] = (u8)(value32 & 0xFF);
832                                                 value32 = (value32 >> 8);
833                                         }
834                                 }
835                         }
836
837                         for (idx = 0; idx < 6; idx++) {
838                                 pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10);
839                                 pBeamformingInfo->RegMUTxCtrl |= ((idx<<8)&(BIT8|BIT9|BIT10));
840                                 ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
841                                 ODM_SetMACReg(pDM_Odm, 0x14C4, bMaskDWord, gid_valid[idx]); /*set MU STA gid valid table*/
842                         }
843
844                         /*Enable TxMU PPDU*/
845                         if (pBeamformingInfo->dbg_disable_mu_tx == FALSE)
846                                 pBeamformingInfo->RegMUTxCtrl |= BIT7;
847                         else
848                                 pBeamformingInfo->RegMUTxCtrl &= ~BIT7;
849                         ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
850                 }
851         }
852 }
853
854 /*Only used for MU BFer Entry when get GID management frame (self is as MU STA)*/
855 VOID
856 HalTxbf8822B_ConfigGtab(
857         IN PVOID                        pDM_VOID
858         )
859 {
860         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
861         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;
862         PRT_BEAMFORMER_ENTRY    pBeamformerEntry = NULL;
863         u4Byte          gid_valid = 0, user_position_l = 0, user_position_h = 0, i;
864
865         if (pBeamformingInfo->mu_ap_index < BEAMFORMER_ENTRY_NUM)
866                 pBeamformerEntry = &pBeamformingInfo->BeamformerEntry[pBeamformingInfo->mu_ap_index];
867         else
868                 return;
869
870         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s==>\n", __func__));
871
872         /*For GID 0~31*/
873         for (i = 0; i < 4; i++)
874                 gid_valid |= (pBeamformerEntry->gid_valid[i] << (i<<3));
875         for (i = 0; i < 8; i++) {
876                 if (i < 4)
877                         user_position_l |= (pBeamformerEntry->user_position[i] << (i << 3));
878                 else
879                         user_position_h |= (pBeamformerEntry->user_position[i] << ((i - 4)<<3));
880         }
881         /*select MU STA0 table*/
882         pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10);
883         ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
884         ODM_SetBBReg(pDM_Odm, 0x14c4, bMaskDWord, gid_valid); 
885         ODM_SetBBReg(pDM_Odm, 0x14c8, bMaskDWord, user_position_l);
886         ODM_SetBBReg(pDM_Odm, 0x14cc, bMaskDWord, user_position_h);
887
888         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: STA0: gid_valid = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n",
889                 __func__, gid_valid, user_position_l, user_position_h));
890
891         gid_valid = 0;
892         user_position_l = 0;
893         user_position_h = 0;
894
895         /*For GID 32~64*/
896         for (i = 4; i < 8; i++)
897                 gid_valid |= (pBeamformerEntry->gid_valid[i] << ((i - 4)<<3));
898         for (i = 8; i < 16; i++) {
899                 if (i < 4)
900                         user_position_l |= (pBeamformerEntry->user_position[i] << ((i - 8) << 3));
901                 else
902                         user_position_h |= (pBeamformerEntry->user_position[i] << ((i - 12) << 3));
903         }
904         /*select MU STA1 table*/
905         pBeamformingInfo->RegMUTxCtrl &= ~(BIT8|BIT9|BIT10);
906         pBeamformingInfo->RegMUTxCtrl |= BIT8;
907         ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
908         ODM_SetBBReg(pDM_Odm, 0x14c4, bMaskDWord, gid_valid); 
909         ODM_SetBBReg(pDM_Odm, 0x14c8, bMaskDWord, user_position_l);
910         ODM_SetBBReg(pDM_Odm, 0x14cc, bMaskDWord, user_position_h);
911
912         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: STA1: gid_valid = 0x%x, user_position_l = 0x%x, user_position_h = 0x%x\n",
913                 __func__, gid_valid, user_position_l, user_position_h));
914
915         /* Set validity of MU STA0 and MU STA1*/
916         pBeamformingInfo->RegMUTxCtrl &= 0xFFFFFFC0;
917         pBeamformingInfo->RegMUTxCtrl |= 0x3; /* STA0, STA1*/
918         ODM_Write4Byte(pDM_Odm, 0x14c0, pBeamformingInfo->RegMUTxCtrl);
919         
920 }
921
922
923
924 #if 0
925 /*This function translate the bitmap to GTAB*/
926 VOID
927 haltxbf8822b_gtab_translation(
928         IN PDM_ODM_T                    pDM_Odm
929
930 {
931         u8 idx, gid;
932         u8 id1, id0;
933         u32 gid_valid[6] = {0};
934         u32 user_position_lsb[6] = {0};
935         u32 user_position_msb[6] = {0};
936         
937         for (idx = 0; idx < 15; idx++) {
938                 if (idx < 5) {/*bit0~4*/
939                         id0 = 0;
940                         id1 = (u8)(idx + 1);
941                 } else if (idx < 9) { /*bit5~8*/
942                         id0 = 1;
943                         id1 = (u8)(idx - 3);
944                 } else if (idx < 12) { /*bit9~11*/
945                         id0 = 2;
946                         id1 = (u8)(idx - 6);
947                 } else if (idx < 14) { /*bit12~13*/     
948                         id0 = 3;
949                         id1 = (u8)(idx - 8);
950                 } else { /*bit14*/
951                         id0 = 4;
952                         id1 = (u8)(idx - 9);
953                 }
954
955                 /*Pair 1*/
956                 gid = (idx << 1) + 1;
957                 gid_valid[id0] |= (1 << gid);
958                 gid_valid[id1] |= (1 << gid);
959                 if (gid < 16) {
960                         /*user_position_lsb[id0] |= (0 << (gid << 1));*/
961                         user_position_lsb[id1] |= (1 << (gid << 1));
962                 } else {
963                         /*user_position_msb[id0] |= (0 << ((gid - 16) << 1));*/
964                         user_position_msb[id1] |= (1 << ((gid - 16) << 1));
965                 }
966                 
967                 /*Pair 2*/
968                 gid += 1;
969                 gid_valid[id0] |= (1 << gid);
970                 gid_valid[id1] |= (1 << gid);
971                 if (gid < 16) {
972                         user_position_lsb[id0] |= (1 << (gid << 1));
973                         /*user_position_lsb[id1] |= (0 << (gid << 1));*/
974                 } else {
975                         user_position_msb[id0] |= (1 << ((gid - 16) << 1));
976                         /*user_position_msb[id1] |= (0 << ((gid - 16) << 1));*/
977                 }
978
979         }
980
981
982         for (idx = 0; idx < 6; idx++) {
983                 /*DbgPrint("gid_valid[%d] = 0x%x\n", idx, gid_valid[idx]);
984                 DbgPrint("user_position[%d] = 0x%x   %x\n", idx, user_position_msb[idx], user_position_lsb[idx]);*/
985         }
986 }
987 #endif
988
989 VOID
990 HalTxbf8822B_FwTxBF(
991         IN PVOID                        pDM_VOID,
992         IN      u1Byte                          Idx
993         )
994 {
995 #if 0
996         PRT_BEAMFORMING_INFO    pBeamInfo = GET_BEAMFORM_INFO(Adapter);
997         PRT_BEAMFORMEE_ENTRY    pBeamEntry = pBeamInfo->BeamformeeEntry+Idx;
998
999         if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING)
1000                 halTxbf8822B_DownloadNDPA(Adapter, Idx);
1001
1002         halTxbf8822B_FwTxBFCmd(Adapter);
1003 #endif
1004 }
1005
1006 #endif
1007
1008 #if (defined(CONFIG_BB_TXBF_API))
1009 /*this function is only used for BFer*/
1010 VOID
1011 phydm_8822btxbf_rfmode(
1012         IN PVOID                pDM_VOID,
1013         IN u1Byte       SUBFeeCnt,
1014         IN u1Byte       MUBFeeCnt
1015         )
1016 {
1017         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
1018         u1Byte          i, Nr_index = 0;
1019
1020         if (pDM_Odm->RFType == ODM_1T1R)
1021                 return;
1022
1023         if ((SUBFeeCnt > 0) || (MUBFeeCnt > 0)) {
1024                 for (i = ODM_RF_PATH_A; i <= ODM_RF_PATH_B; i++) {
1025                         ODM_SetRFReg(pDM_Odm, i, 0xEF, BIT19, 0x1); /*RF Mode table write enable*/
1026                         ODM_SetRFReg(pDM_Odm, i, 0x33, 0xF, 3); /*Select RX mode*/
1027                         ODM_SetRFReg(pDM_Odm, i, 0x3E, 0xfffff, 0x00036); /*Set Table data*/    
1028                         ODM_SetRFReg(pDM_Odm, i, 0x3F, 0xfffff, 0x5AFCE); /*Set Table data*/
1029                         ODM_SetRFReg(pDM_Odm, i, 0xEF, BIT19, 0x0); /*RF Mode table write disable*/
1030                 }
1031         }
1032
1033         if (SUBFeeCnt > 0 || MUBFeeCnt > 0) {
1034                 /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/
1035                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT28|BIT29, 0x2); /*enable BB TxBF ant mapping register*/
1036                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT31, 1);                 /*ignore user since 8822B only 2Tx*/
1037                 
1038                 /*Nsts = 2      AB*/
1039                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, 0xffff, 0x0433);
1040                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x043);
1041
1042         } else {
1043                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT28|BIT29, 0x0); /*enable BB TxBF ant mapping register*/
1044                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8822B, BIT31, 0);                 /*ignore user since 8822B only 2Tx*/
1045                 
1046                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8822B, 0xfff00000, 0x1); /*1SS by path-A*/
1047                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8822B, bMaskLWord, 0x430); /*2SS by path-A,B*/
1048         }
1049
1050 }
1051
1052
1053 /*this function is for BFer bug workaround*/
1054 VOID
1055 phydm_8822b_sutxbfer_workaroud(
1056         IN PVOID                pDM_VOID,
1057         IN BOOLEAN      EnableSUBfer,
1058         IN u1Byte       Nc,
1059         IN u1Byte       Nr,
1060         IN u1Byte       Ng,
1061         IN u1Byte       CB,
1062         IN u1Byte       BW,
1063         IN BOOLEAN      isVHT
1064         )
1065 {
1066         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;
1067
1068         if (EnableSUBfer) {
1069                 ODM_SetBBReg(pDM_Odm, 0x19f8, BIT22|BIT21|BIT20, 0x1);
1070                 ODM_SetBBReg(pDM_Odm, 0x19f8, BIT25|BIT24|BIT23, 0x0);
1071                 ODM_SetBBReg(pDM_Odm, 0x19f8, BIT16, 0x1);
1072
1073                 if (isVHT)
1074                         ODM_SetBBReg(pDM_Odm, 0x19f0, BIT5|BIT4|BIT3|BIT2|BIT1|BIT0, 0x1f);
1075                 else
1076                         ODM_SetBBReg(pDM_Odm, 0x19f0, BIT5|BIT4|BIT3|BIT2|BIT1|BIT0, 0x22);
1077                 
1078                 ODM_SetBBReg(pDM_Odm, 0x19f0, BIT7|BIT6, Nc);
1079                 ODM_SetBBReg(pDM_Odm, 0x19f0, BIT9|BIT8, Nr);
1080                 ODM_SetBBReg(pDM_Odm, 0x19f0, BIT11|BIT10, Ng);
1081                 ODM_SetBBReg(pDM_Odm, 0x19f0, BIT13|BIT12, CB);
1082
1083                 ODM_SetBBReg(pDM_Odm, 0xb58, BIT3|BIT2, BW);
1084                 ODM_SetBBReg(pDM_Odm, 0xb58, BIT7|BIT6|BIT5|BIT4, 0x0);
1085                 ODM_SetBBReg(pDM_Odm, 0xb58, BIT9|BIT8, BW);
1086                 ODM_SetBBReg(pDM_Odm, 0xb58, BIT13|BIT12|BIT11|BIT10, 0x0);
1087         } else
1088                 ODM_SetBBReg(pDM_Odm, 0x19f8, BIT16, 0x0);
1089
1090         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_TRACE, ("[%s] EnableSUBfer = %d, isVHT = %d\n", __func__, EnableSUBfer, isVHT));
1091         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_TRACE, ("[%s] Nc = %d, Nr = %d, Ng = %d, CB = %d, BW = %d\n", __func__, Nc, Nr, Ng, CB, BW));
1092         
1093
1094 }
1095 #endif
1096 #endif  /* (RTL8822B_SUPPORT == 1)*/
1097
1098