net: wireless: rockchip: add rtl8822be pcie wifi driver
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8822be / hal / phydm / txbf / haltxbf8814a.c
1 //============================================================\r
2 // Description:\r
3 //\r
4 // This file is for 8814A TXBF mechanism\r
5 //\r
6 //============================================================\r
7 \r
8 #include "mp_precomp.h"\r
9 #include "../phydm_precomp.h"\r
10 \r
11 #if (BEAMFORMING_SUPPORT == 1)\r
12 #if (RTL8814A_SUPPORT == 1)\r
13 \r
14 BOOLEAN\r
15 phydm_beamforming_set_iqgen_8814A(\r
16         IN PVOID                        pDM_VOID\r
17 )\r
18 {\r
19         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
20         u1Byte i = 0;\r
21         u2Byte counter = 0;\r
22         u4Byte rf_mode[4];\r
23 \r
24         for (i = ODM_RF_PATH_A ; i < MAX_RF_PATH ; i++) {\r
25                 ODM_SetRFReg(pDM_Odm, i, RF_WE_LUT, 0x80000, 0x1);      /*RF Mode table write enable*/\r
26         }\r
27         \r
28         while(1) {\r
29                 counter++;\r
30                 for (i= ODM_RF_PATH_A; i < MAX_RF_PATH; i++) {\r
31                         ODM_SetRFReg(pDM_Odm, i, RF_RCK_OS, 0xfffff, 0x18000);  /*Select Rx mode*/\r
32                 }\r
33 \r
34                 ODM_delay_us(2);\r
35                 \r
36                 for (i= ODM_RF_PATH_A; i < MAX_RF_PATH; i++) {\r
37                         rf_mode[i] = ODM_GetRFReg(pDM_Odm, i, RF_RCK_OS, 0xfffff);\r
38                 }\r
39                 \r
40                 if ((rf_mode[0] == 0x180000) && (rf_mode[1] == 0x180000) && (rf_mode[2] == 0x180000) && (rf_mode[3] == 0x180000))\r
41                         break;\r
42                 else if (counter == 100) {\r
43                         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_TRACE, ("iqgen setting fail:8814A \n"));\r
44                         return FALSE;\r
45                 }\r
46         }\r
47 \r
48         for (i= ODM_RF_PATH_A ; i < MAX_RF_PATH ; i++) {\r
49                 ODM_SetRFReg(pDM_Odm, i, RF_TXPA_G1, 0xfffff, 0xBE77F); /*Set Table data*/\r
50                 ODM_SetRFReg(pDM_Odm, i, RF_TXPA_G2, 0xfffff, 0x226BF); /*Enable TXIQGEN in Rx mode*/\r
51         }\r
52         ODM_SetRFReg(pDM_Odm, ODM_RF_PATH_A, RF_TXPA_G2, 0xfffff, 0xE26BF); /*Enable TXIQGEN in Rx mode*/\r
53 \r
54         for (i= ODM_RF_PATH_A; i < MAX_RF_PATH; i++) {\r
55                 ODM_SetRFReg(pDM_Odm, i, RF_WE_LUT, 0x80000, 0x0);      /*RF Mode table write disable*/\r
56         }\r
57 \r
58         return TRUE;\r
59         \r
60 }\r
61 \r
62 \r
63 \r
64 VOID\r
65 HalTxbf8814A_setNDPArate(\r
66         IN PVOID                        pDM_VOID,\r
67         IN u1Byte       BW,\r
68         IN u1Byte       Rate\r
69 )\r
70 {\r
71         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
72         \r
73         ODM_Write1Byte(pDM_Odm, REG_NDPA_OPT_CTRL_8814A, BW);\r
74         ODM_Write1Byte(pDM_Odm, REG_NDPA_RATE_8814A, (u1Byte) Rate);\r
75 \r
76 }\r
77 \r
78 #define PHYDM_MEMORY_MAP_BUF_READ       0x8000\r
79 #define PHYDM_CTRL_INFO_PAGE                    0x660\r
80 \r
81 VOID\r
82 phydm_DataRate_8814A(\r
83         IN      PDM_ODM_T                       pDM_Odm,\r
84         IN      u1Byte                          macId,  \r
85         OUT     pu4Byte                         data,\r
86         IN      u1Byte                          dataLen\r
87         )\r
88 {\r
89         u1Byte  i = 0;\r
90         u2Byte  XReadDataAddr = 0;\r
91 \r
92         ODM_Write2Byte(pDM_Odm, REG_PKTBUF_DBG_CTRL_8814A, PHYDM_CTRL_INFO_PAGE);\r
93         XReadDataAddr = PHYDM_MEMORY_MAP_BUF_READ + macId*32; /*Ctrl Info: 32Bytes for each macid(n)*/\r
94         \r
95         if ((XReadDataAddr < PHYDM_MEMORY_MAP_BUF_READ) || (XReadDataAddr > 0x8FFF)) {\r
96                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("XReadDataAddr(0x%x) is not correct!\n", XReadDataAddr));\r
97                 return; \r
98         }\r
99         \r
100         /* Read data */\r
101         for (i = 0; i < dataLen; i++)\r
102                 *(data+i) = ODM_Read2Byte(pDM_Odm, XReadDataAddr+i);    \r
103         \r
104 }\r
105 \r
106 VOID\r
107 HalTxbf8814A_GetTxRate(\r
108         IN PVOID                        pDM_VOID\r
109 )\r
110 {\r
111         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
112         PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
113         PRT_BEAMFORMEE_ENTRY    pEntry;\r
114         u4Byte  TxRptData = 0;\r
115         u1Byte  DataRate = 0xFF;\r
116 \r
117         pEntry = &(pBeamInfo->BeamformeeEntry[pBeamInfo->BeamformeeCurIdx]);\r
118         \r
119         phydm_DataRate_8814A(pDM_Odm, (u1Byte)pEntry->MacId, &TxRptData, 1);\r
120         DataRate = (u1Byte)TxRptData;\r
121         DataRate &= bMask7bits;   /*Bit7 indicates SGI*/\r
122 \r
123         pDM_Odm->TxBfDataRate = DataRate;\r
124 \r
125         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] pDM_Odm->TxBfDataRate = 0x%x\n", __func__, pDM_Odm->TxBfDataRate));\r
126 }\r
127 \r
128 VOID\r
129 HalTxbf8814A_ResetTxPath(\r
130         IN PVOID                        pDM_VOID,\r
131         IN      u1Byte                          idx\r
132 )\r
133 {\r
134         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
135 #if DEV_BUS_TYPE == RT_USB_INTERFACE\r
136         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;\r
137         RT_BEAMFORMEE_ENTRY     BeamformeeEntry;\r
138         u1Byte  Nr_index = 0, txSS = 0;\r
139 \r
140         if (idx < BEAMFORMEE_ENTRY_NUM)\r
141                 BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx];\r
142         else\r
143                 return;\r
144 \r
145         if ((pDM_Odm->LastUSBHub) != (*pDM_Odm->HubUsbMode)) {\r
146                 Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(pDM_Odm), BeamformeeEntry.CompSteeringNumofBFer);\r
147 \r
148                 if (*pDM_Odm->HubUsbMode == 2) {\r
149                         if (pDM_Odm->RFType == ODM_4T4R)\r
150                                 txSS = 0xf;\r
151                         else if (pDM_Odm->RFType == ODM_3T3R)\r
152                                 txSS = 0xe;\r
153                         else\r
154                                 txSS = 0x6;\r
155                 } else if (*pDM_Odm->HubUsbMode == 1)   /*USB 2.0 always 2Tx*/\r
156                         txSS = 0x6;\r
157                 else\r
158                         txSS = 0x6;\r
159 \r
160                 if (txSS == 0xf) {\r
161                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x93f);\r
162                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskDWord, 0x93f93f0);\r
163                 } else if (txSS == 0xe) {\r
164                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x93e);\r
165                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8814A, bMaskDWord, 0x93e93e0);\r
166                 } else if (txSS == 0x6) {\r
167                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x936);\r
168                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8814A, bMaskLWord, 0x9360);\r
169                 }\r
170 \r
171                 if (idx == 0) {\r
172                         switch (Nr_index) {\r
173                         case 0:\r
174                         break;\r
175 \r
176                         case 1:                 /*Nsts = 2      BC*/\r
177                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366);               /*tx2path, BC*/\r
178                         break;\r
179 \r
180                         case 2:                 /*Nsts = 3      BCD*/\r
181                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee);    /*tx3path, BCD*/\r
182                         break;\r
183 \r
184                         default:                        /*Nr>3, same as Case 3*/\r
185                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff);    /*tx4path, ABCD*/\r
186                         break;\r
187                         }\r
188                 } else  {\r
189                         switch (Nr_index) {\r
190                         case 0:\r
191                                 break;\r
192 \r
193                         case 1:                 /*Nsts = 2      BC*/\r
194                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366);               /*tx2path, BC*/\r
195                         break;\r
196 \r
197                         case 2:                 /*Nsts = 3      BCD*/\r
198                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee);    /*tx3path, BCD*/\r
199                         break;\r
200 \r
201                         default:                        /*Nr>3, same as Case 3*/\r
202                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff);    /*tx4path, ABCD*/\r
203                         break;\r
204                         }\r
205                 }\r
206 \r
207                 pDM_Odm->LastUSBHub = *pDM_Odm->HubUsbMode;\r
208         } else\r
209                 return;\r
210 #endif\r
211 }\r
212 \r
213 \r
214 u1Byte\r
215 halTxbf8814A_GetNtx(\r
216         IN PVOID                        pDM_VOID\r
217 )\r
218 {\r
219         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
220         u1Byte          Ntx = 0, txSS = 3;\r
221 \r
222 #if DEV_BUS_TYPE == RT_USB_INTERFACE\r
223         txSS = *pDM_Odm->HubUsbMode;\r
224 #endif\r
225         if (txSS == 3 || txSS == 2) {\r
226                 if (pDM_Odm->RFType == ODM_4T4R)\r
227                         Ntx = 3;\r
228                 else if (pDM_Odm->RFType == ODM_3T3R)\r
229                         Ntx = 2;\r
230                 else\r
231                         Ntx = 1;\r
232         } else if (txSS == 1)   /*USB 2.0 always 2Tx*/\r
233                 Ntx = 1;\r
234         else\r
235                 Ntx = 1;\r
236 \r
237         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Ntx = %d\n", __func__, Ntx));\r
238         return Ntx;\r
239 }\r
240 \r
241 u1Byte\r
242 halTxbf8814A_GetNrx(\r
243         IN PVOID                        pDM_VOID\r
244 )\r
245 {\r
246         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
247         u1Byte                  Nrx = 0;\r
248 \r
249         if (pDM_Odm->RFType == ODM_4T4R)\r
250                 Nrx = 3;\r
251         else if (pDM_Odm->RFType == ODM_3T3R)\r
252                 Nrx = 2;\r
253         else if (pDM_Odm->RFType == ODM_2T2R)\r
254                 Nrx = 1;\r
255         else if (pDM_Odm->RFType == ODM_2T3R)\r
256                 Nrx = 2;\r
257         else if (pDM_Odm->RFType == ODM_2T4R)\r
258                 Nrx = 3;\r
259         else if (pDM_Odm->RFType == ODM_1T1R)\r
260                 Nrx = 0;\r
261         else if (pDM_Odm->RFType == ODM_1T2R)\r
262                 Nrx = 1;\r
263         else\r
264                 Nrx = 0;\r
265 \r
266         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Nrx = %d\n", __func__, Nrx));\r
267         return Nrx;\r
268 }\r
269 \r
270 VOID\r
271 halTxbf8814A_RfMode(\r
272         IN PVOID                        pDM_VOID,\r
273         IN      PRT_BEAMFORMING_INFO    pBeamformingInfo,\r
274         IN      u1Byte                                  idx\r
275 )\r
276 {\r
277         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
278         u1Byte                          i, Nr_index = 0;\r
279         u1Byte                          txSS = 3;               /*default use 3 Tx*/\r
280         RT_BEAMFORMEE_ENTRY     BeamformeeEntry;\r
281 \r
282         if (idx < BEAMFORMEE_ENTRY_NUM)\r
283                 BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[idx];\r
284         else\r
285                 return;\r
286 \r
287         Nr_index = TxBF_Nr(halTxbf8814A_GetNtx(pDM_Odm), BeamformeeEntry.CompSteeringNumofBFer);\r
288 \r
289         if (pDM_Odm->RFType == ODM_1T1R)\r
290                 return;\r
291 \r
292         if (pBeamformingInfo->beamformee_su_cnt > 0) {\r
293 #if DEV_BUS_TYPE == RT_USB_INTERFACE\r
294                 pDM_Odm->LastUSBHub = *pDM_Odm->HubUsbMode;\r
295                 txSS = *pDM_Odm->HubUsbMode;\r
296 #endif\r
297                 if (txSS == 3 || txSS == 2) {\r
298                         if (pDM_Odm->RFType == ODM_4T4R)\r
299                                 txSS = 0xf;\r
300                         else if (pDM_Odm->RFType == ODM_3T3R)\r
301                                 txSS = 0xe;\r
302                         else\r
303                                 txSS = 0x6;\r
304                 } else if (txSS == 1)   /*USB 2.0 always 2Tx*/\r
305                         txSS = 0x6;\r
306                 else\r
307                         txSS = 0x6;\r
308 \r
309                 if (txSS == 0xf) {\r
310                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x93f);\r
311                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskDWord, 0x93f93f0);\r
312                 } else if (txSS == 0xe) {\r
313                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x93e);\r
314                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8814A, bMaskDWord, 0x93e93e0);\r
315                 } else if (txSS == 0x6) {\r
316                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x936);\r
317                         ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8814A, bMaskLWord, 0x9360);\r
318                 }\r
319 \r
320                 /*for 8814 19ac(idx 1), 19b4(idx 0), different Tx ant setting*/\r
321                 ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, BIT28 | BIT29, 0x2);                       /*enable BB TxBF ant mapping register*/\r
322                 \r
323                 if (idx == 0) {\r
324                         switch (Nr_index) {\r
325                         case 0:\r
326                         break;\r
327 \r
328                         case 1:                 /*Nsts = 2      BC*/\r
329                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366);               /*tx2path, BC*/\r
330                         break;\r
331 \r
332                         case 2:                 /*Nsts = 3      BCD*/\r
333                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee);    /*tx3path, BCD*/\r
334                         break;\r
335 \r
336                         default:                        /*Nr>3, same as Case 3*/\r
337                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF0_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff);    /*tx4path, ABCD*/\r
338                         \r
339                         break;\r
340                         }\r
341                 } else {\r
342                         switch (Nr_index) {\r
343                         case 0:\r
344                         break;\r
345 \r
346                         case 1:                 /*Nsts = 2      BC*/\r
347                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x9366);               /*tx2path, BC*/\r
348                         break;\r
349 \r
350                         case 2:                 /*Nsts = 3      BCD*/\r
351                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93e93ee);    /*tx3path, BCD*/\r
352                         break;\r
353 \r
354                         default:                        /*Nr>3, same as Case 3*/\r
355                         ODM_SetBBReg(pDM_Odm, REG_BB_TXBF_ANT_SET_BF1_8814A, bMaskByte3LowNibble | bMaskL3Bytes, 0x93f93ff);    /*tx4path, ABCD*/\r
356                         break;\r
357                         }\r
358                 }\r
359         }\r
360 \r
361         if ((pBeamformingInfo->beamformee_su_cnt == 0) && (pBeamformingInfo->beamformer_su_cnt == 0)) {\r
362                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_1_8814A, bMaskByte3 | bMaskByte2HighNibble, 0x932);    /*set TxPath selection for 8814a BFer bug refine*/\r
363                 ODM_SetBBReg(pDM_Odm, REG_BB_TX_PATH_SEL_2_8814A, bMaskDWord, 0x93e9360);\r
364         }\r
365 }\r
366 #if 0\r
367 VOID\r
368 halTxbf8814A_DownloadNDPA(\r
369         IN PVOID                        pDM_VOID,\r
370         IN      u1Byte                          Idx\r
371 )\r
372 {\r
373         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
374         u1Byte                  u1bTmp = 0, tmpReg422 = 0;\r
375         u1Byte                  BcnValidReg = 0, count = 0, DLBcnCount = 0;\r
376         u2Byte                  Head_Page = 0x7FE;\r
377         BOOLEAN                 bSendBeacon = FALSE;\r
378         u2Byte                  TxPageBndy = LAST_ENTRY_OF_TX_PKT_BUFFER_8814A; /*default reseved 1 page for the IC type which is undefined.*/\r
379         PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
380         PRT_BEAMFORMEE_ENTRY    pBeamEntry = pBeamInfo->BeamformeeEntry + Idx;\r
381         PADAPTER                Adapter = pDM_Odm->Adapter;\r
382 \r
383 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)\r
384         *pDM_Odm->pbFwDwRsvdPageInProgress = TRUE;\r
385 #endif\r
386         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));\r
387 \r
388         Adapter->HalFunc.GetHalDefVarHandler(Adapter, HAL_DEF_TX_PAGE_BOUNDARY, (pu2Byte)&TxPageBndy);\r
389 \r
390         /*Set REG_CR bit 8. DMA beacon by SW.*/\r
391         u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8814A + 1);\r
392         ODM_Write1Byte(pDM_Odm,  REG_CR_8814A + 1, (u1bTmp | BIT0));\r
393 \r
394 \r
395         /*Set FWHW_TXQ_CTRL 0x422[6]=0 to tell Hw the packet is not a real beacon frame.*/\r
396         tmpReg422 = ODM_Read1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8814A + 2);\r
397         ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8814A + 2,  tmpReg422 & (~BIT6));\r
398 \r
399         if (tmpReg422 & BIT6) {\r
400                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s: There is an Adapter is sending beacon.\n", __func__));\r
401                 bSendBeacon = TRUE;\r
402         }\r
403 \r
404         /*0x204[11:0]   Beacon Head for TXDMA*/\r
405         ODM_Write2Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A, Head_Page);\r
406 \r
407         do {\r
408                 /*Clear beacon valid check bit.*/\r
409                 BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 1);\r
410                 ODM_Write1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 1, (BcnValidReg | BIT7));\r
411 \r
412                 /*download NDPA rsvd page.*/\r
413                 if (pBeamEntry->BeamformEntryCap & BEAMFORMER_CAP_VHT_SU)\r
414                         Beamforming_SendVHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->AID, pBeamEntry->SoundBW, BEACON_QUEUE);\r
415                 else\r
416                         Beamforming_SendHTNDPAPacket(pDM_Odm, pBeamEntry->MacAddr, pBeamEntry->SoundBW, BEACON_QUEUE);\r
417 \r
418                 /*check rsvd page download OK.*/\r
419                 BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 1);\r
420                 count = 0;\r
421                 while (!(BcnValidReg & BIT7) && count < 20) {\r
422                         count++;\r
423                         ODM_delay_ms(10);\r
424                         BcnValidReg = ODM_Read1Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A + 2);\r
425                 }\r
426                 DLBcnCount++;\r
427         } while (!(BcnValidReg & BIT7) && DLBcnCount < 5);\r
428 \r
429         if (!(BcnValidReg & BIT7))\r
430                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("%s Download RSVD page failed!\n", __func__));\r
431 \r
432         /*0x204[11:0]   Beacon Head for TXDMA*/\r
433         ODM_Write2Byte(pDM_Odm, REG_FIFOPAGE_CTRL_2_8814A, TxPageBndy);\r
434 \r
435         /*To make sure that if there exists an adapter which would like to send beacon.*/\r
436         /*If exists, the origianl value of 0x422[6] will be 1, we should check this to*/\r
437         /*prevent from setting 0x422[6] to 0 after download reserved page, or it will cause */\r
438         /*the beacon cannot be sent by HW.*/\r
439         /*2010.06.23. Added by tynli.*/\r
440         if (bSendBeacon)\r
441                 ODM_Write1Byte(pDM_Odm, REG_FWHW_TXQ_CTRL_8814A + 2, tmpReg422);\r
442 \r
443         /*Do not enable HW DMA BCN or it will cause Pcie interface hang by timing issue. 2011.11.24. by tynli.*/\r
444         /*Clear CR[8] or beacon packet will not be send to TxBuf anymore.*/\r
445         u1bTmp = ODM_Read1Byte(pDM_Odm, REG_CR_8814A + 1);\r
446         ODM_Write1Byte(pDM_Odm, REG_CR_8814A + 1, (u1bTmp & (~BIT0)));\r
447 \r
448         pBeamEntry->BeamformEntryState = BEAMFORMING_ENTRY_STATE_PROGRESSED;\r
449 \r
450 #if (DM_ODM_SUPPORT_TYPE == ODM_WIN)\r
451         *pDM_Odm->pbFwDwRsvdPageInProgress = FALSE;\r
452 #endif\r
453 }\r
454 \r
455 VOID\r
456 halTxbf8814A_FwTxBFCmd(\r
457         IN PVOID                        pDM_VOID\r
458 )\r
459 {\r
460         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
461         u1Byte  Idx, Period = 0;\r
462         u1Byte  PageNum0 = 0xFF, PageNum1 = 0xFF;\r
463         u1Byte  u1TxBFParm[3] = {0};\r
464         PRT_BEAMFORMING_INFO pBeamInfo = &pDM_Odm->BeamformingInfo;\r
465 \r
466         for (Idx = 0; Idx < BEAMFORMEE_ENTRY_NUM; Idx++) {\r
467                 if (pBeamInfo->BeamformeeEntry[Idx].bUsed && pBeamInfo->BeamformeeEntry[Idx].BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) {\r
468                         if (pBeamInfo->BeamformeeEntry[Idx].bSound) {\r
469                                 PageNum0 = 0xFE;\r
470                                 PageNum1 = 0x07;\r
471                                 Period = (u1Byte)(pBeamInfo->BeamformeeEntry[Idx].SoundPeriod);\r
472                         } else if (PageNum0 == 0xFF) {\r
473                                 PageNum0 = 0xFF; /*stop sounding*/\r
474                                 PageNum1 = 0x0F;\r
475                         }\r
476                 }\r
477         }\r
478 \r
479         u1TxBFParm[0] = PageNum0;\r
480         u1TxBFParm[1] = PageNum1;\r
481         u1TxBFParm[2] = Period;\r
482         ODM_FillH2CCmd(pDM_Odm, PHYDM_H2C_TXBF, 3, u1TxBFParm);\r
483 \r
484         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, \r
485                 ("[%s] PageNum0 = %d, PageNum1 = %d Period = %d\n", __func__, PageNum0, PageNum1, Period));\r
486 }\r
487 #endif\r
488 VOID\r
489 HalTxbf8814A_Enter(\r
490         IN PVOID                        pDM_VOID,\r
491         IN u1Byte                               BFerBFeeIdx\r
492 )\r
493 {\r
494         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
495         u1Byte                                  i = 0;\r
496         u1Byte                                  BFerIdx = (BFerBFeeIdx & 0xF0) >> 4;\r
497         u1Byte                                  BFeeIdx = (BFerBFeeIdx & 0xF);\r
498         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;\r
499         RT_BEAMFORMEE_ENTRY     BeamformeeEntry;\r
500         RT_BEAMFORMER_ENTRY     BeamformerEntry;\r
501         u2Byte                                  STAid = 0, CSI_Param = 0;\r
502         u1Byte                                  Nc_index = 0, Nr_index = 0, grouping = 0, codebookinfo = 0, coefficientsize = 0;\r
503 \r
504         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] BFerIdx=%d, BFeeIdx=%d\n", __func__, BFerIdx, BFeeIdx));\r
505         ODM_SetMACReg(pDM_Odm, REG_SND_PTCL_CTRL_8814A, bMaskByte1 | bMaskByte2, 0x0202);\r
506 \r
507         if ((pBeamformingInfo->beamformer_su_cnt > 0) && (BFerIdx < BEAMFORMER_ENTRY_NUM)) {\r
508                 BeamformerEntry = pBeamformingInfo->BeamformerEntry[BFerIdx];\r
509                 /*Sounding protocol control*/\r
510                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A, 0xDB);\r
511 \r
512                 /*MAC address/Partial AID of Beamformer*/\r
513                 if (BFerIdx == 0) {\r
514                         for (i = 0; i < 6 ; i++)\r
515                                 ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER0_INFO_8814A + i), BeamformerEntry.MacAddr[i]);\r
516                 } else {\r
517                         for (i = 0; i < 6 ; i++)\r
518                                 ODM_Write1Byte(pDM_Odm, (REG_ASSOCIATED_BFMER1_INFO_8814A + i), BeamformerEntry.MacAddr[i]);\r
519                 }\r
520 \r
521                 /*CSI report parameters of Beamformer*/\r
522                 Nc_index = halTxbf8814A_GetNrx(pDM_Odm);        /*for 8814A Nrx = 3(4 Ant), min=0(1 Ant)*/\r
523                 Nr_index = BeamformerEntry.NumofSoundingDim;    /*0x718[7] = 1 use Nsts, 0x718[7] = 0 use reg setting. as Bfee, we use Nsts, so Nr_index don't care*/\r
524 \r
525                 grouping = 0;\r
526 \r
527                 /*for ac = 1, for n = 3*/\r
528                 if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_VHT_SU)\r
529                         codebookinfo = 1;\r
530                 else if (BeamformerEntry.BeamformEntryCap & BEAMFORMEE_CAP_HT_EXPLICIT)\r
531                         codebookinfo = 3;\r
532 \r
533                 coefficientsize = 3;\r
534 \r
535                 CSI_Param = (u2Byte)((coefficientsize << 10) | (codebookinfo << 8) | (grouping << 6) | (Nr_index << 3) | (Nc_index));\r
536 \r
537                 if (BFerIdx == 0)\r
538                         ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A, CSI_Param);\r
539                 else\r
540                         ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A + 2, CSI_Param);\r
541                 /*ndp_rx_standby_timer, 8814 need > 0x56, suggest from Dvaid*/\r
542                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A + 3, 0x40);\r
543 \r
544         }\r
545 \r
546         if ((pBeamformingInfo->beamformee_su_cnt > 0) && (BFeeIdx < BEAMFORMEE_ENTRY_NUM)) {\r
547                 BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[BFeeIdx];\r
548 \r
549                 halTxbf8814A_RfMode(pDM_Odm, pBeamformingInfo, BFeeIdx);\r
550 \r
551                 if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS))\r
552                         STAid = BeamformeeEntry.MacId;\r
553                 else\r
554                         STAid = BeamformeeEntry.P_AID;\r
555 \r
556                 /*P_AID of Beamformee & enable NDPA transmission & enable NDPA interrupt*/\r
557                 if (BFeeIdx == 0) {\r
558                         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, STAid);\r
559                         ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3) | BIT4 | BIT6 | BIT7);\r
560                 } else\r
561                         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 2, STAid | BIT14 | BIT15 | BIT12);\r
562 \r
563                 /*CSI report parameters of Beamformee*/\r
564                 if (BFeeIdx == 0) {\r
565                         /*Get BIT24 & BIT25*/\r
566                         u1Byte  tmp = ODM_Read1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 3) & 0x3;\r
567 \r
568                         ODM_Write1Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 3, tmp | 0x60);\r
569                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A, STAid | BIT9);\r
570                 } else\r
571                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2, STAid | 0xE200);    /*Set BIT25*/\r
572 \r
573                 phydm_Beamforming_Notify(pDM_Odm);\r
574         }\r
575 \r
576 }\r
577 \r
578 \r
579 VOID\r
580 HalTxbf8814A_Leave(\r
581         IN PVOID                        pDM_VOID,\r
582         IN u1Byte                               Idx\r
583 )\r
584 {\r
585         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
586         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;\r
587         RT_BEAMFORMER_ENTRY     BeamformerEntry;\r
588         RT_BEAMFORMEE_ENTRY     BeamformeeEntry;\r
589 \r
590         if (Idx < BEAMFORMER_ENTRY_NUM) {\r
591                 BeamformerEntry = pBeamformingInfo->BeamformerEntry[Idx];\r
592                 BeamformeeEntry = pBeamformingInfo->BeamformeeEntry[Idx];\r
593         } else\r
594                 return;\r
595 \r
596         /*Clear P_AID of Beamformee*/\r
597         /*Clear MAC address of Beamformer*/\r
598         /*Clear Associated Bfmee Sel*/\r
599 \r
600         if (BeamformerEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) {\r
601                 ODM_Write1Byte(pDM_Odm, REG_SND_PTCL_CTRL_8814A, 0xD8);\r
602                 if (Idx == 0) {\r
603                         ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8814A, 0);\r
604                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER0_INFO_8814A + 4, 0);\r
605                         ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A, 0);\r
606                 } else {\r
607                         ODM_Write4Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8814A, 0);\r
608                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMER1_INFO_8814A + 4, 0);\r
609                         ODM_Write2Byte(pDM_Odm, REG_CSI_RPT_PARAM_BW20_8814A + 2, 0);\r
610                 }\r
611         }\r
612 \r
613         if (BeamformeeEntry.BeamformEntryCap == BEAMFORMING_CAP_NONE) {\r
614                 halTxbf8814A_RfMode(pDM_Odm, pBeamformingInfo, Idx);\r
615                 if (Idx == 0) {\r
616                         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, 0x0);\r
617                         ODM_Write1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3, ODM_Read1Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 3) | BIT4 | BIT6 | BIT7);\r
618                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A, 0);\r
619                 } else {\r
620                         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A + 2, 0x0 | BIT14 | BIT15 | BIT12);\r
621 \r
622                         ODM_Write2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2, ODM_Read2Byte(pDM_Odm, REG_ASSOCIATED_BFMEE_SEL_8814A + 2) & 0x60);\r
623                 }\r
624         }\r
625 }\r
626 \r
627 VOID\r
628 HalTxbf8814A_Status(\r
629         IN PVOID                        pDM_VOID,\r
630         IN u1Byte                               Idx\r
631 )\r
632 {\r
633         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
634         u2Byte                                  BeamCtrlVal, tmpVal;\r
635         u4Byte                                  BeamCtrlReg;\r
636         PRT_BEAMFORMING_INFO    pBeamformingInfo = &pDM_Odm->BeamformingInfo;\r
637         RT_BEAMFORMEE_ENTRY     BeamformEntry;\r
638 \r
639         if (Idx < BEAMFORMEE_ENTRY_NUM)\r
640                 BeamformEntry = pBeamformingInfo->BeamformeeEntry[Idx];\r
641         else\r
642                 return;\r
643 \r
644         if (phydm_actingDetermine(pDM_Odm, PhyDM_ACTING_AS_IBSS))\r
645                 BeamCtrlVal = BeamformEntry.MacId;\r
646         else\r
647                 BeamCtrlVal = BeamformEntry.P_AID;\r
648 \r
649         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, BeamformEntry.BeamformEntryState = %d", __func__, BeamformEntry.BeamformEntryState));\r
650 \r
651         if (Idx == 0)\r
652                 BeamCtrlReg = REG_TXBF_CTRL_8814A;\r
653         else {\r
654                 BeamCtrlReg = REG_TXBF_CTRL_8814A + 2;\r
655                 BeamCtrlVal |= BIT12 | BIT14 | BIT15;\r
656         }\r
657 \r
658         if ((BeamformEntry.BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSED) && (pBeamformingInfo->applyVmatrix == TRUE)) {\r
659                 if (BeamformEntry.SoundBW == CHANNEL_WIDTH_20)\r
660                         BeamCtrlVal |= BIT9;\r
661                 else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_40)\r
662                         BeamCtrlVal |= (BIT9 | BIT10);\r
663                 else if (BeamformEntry.SoundBW == CHANNEL_WIDTH_80)\r
664                         BeamCtrlVal |= (BIT9 | BIT10 | BIT11);\r
665         } else {\r
666                 ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("@%s, Don't apply Vmatrix",  __func__));\r
667                 BeamCtrlVal &= ~(BIT9 | BIT10 | BIT11);\r
668         }\r
669 \r
670         ODM_Write2Byte(pDM_Odm, BeamCtrlReg, BeamCtrlVal);\r
671         /*disable NDP packet use beamforming */\r
672         tmpVal = ODM_Read2Byte(pDM_Odm, REG_TXBF_CTRL_8814A);\r
673         ODM_Write2Byte(pDM_Odm, REG_TXBF_CTRL_8814A, tmpVal | BIT15);\r
674 \r
675 }\r
676 \r
677 \r
678 \r
679 \r
680 \r
681 VOID\r
682 HalTxbf8814A_FwTxBF(\r
683         IN PVOID                        pDM_VOID,\r
684         IN      u1Byte                          Idx\r
685 )\r
686 {\r
687 #if 0\r
688         PDM_ODM_T       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
689         PRT_BEAMFORMING_INFO    pBeamInfo = &pDM_Odm->BeamformingInfo;\r
690         PRT_BEAMFORMEE_ENTRY    pBeamEntry = pBeamInfo->BeamformeeEntry + Idx;\r
691 \r
692         ODM_RT_TRACE(pDM_Odm, PHYDM_COMP_TXBF, ODM_DBG_LOUD, ("[%s] Start!\n", __func__));\r
693 \r
694         if (pBeamEntry->BeamformEntryState == BEAMFORMING_ENTRY_STATE_PROGRESSING)\r
695                 halTxbf8814A_DownloadNDPA(pDM_Odm, Idx);\r
696 \r
697         halTxbf8814A_FwTxBFCmd(pDM_Odm);\r
698 #endif\r
699 }\r
700 \r
701 #endif  /* (RTL8814A_SUPPORT == 1)*/\r
702 \r
703 #endif\r
704 \r