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