net: wireless: rockchip_wlan: add rtl8723ds support
[firefly-linux-kernel-4.4.55.git] / drivers / net / wireless / rockchip_wlan / rtl8723ds / hal / phydm / phydm_adc_sampling.c
1 #include "mp_precomp.h"\r
2 #include "phydm_precomp.h"\r
3 \r
4 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)\r
5 #if ((RTL8197F_SUPPORT == 1)||(RTL8822B_SUPPORT == 1))\r
6 #include "rtl8197f/Hal8197FPhyReg.h"\r
7 #include "WlanHAL/HalMac88XX/halmac_reg2.h"\r
8 #else\r
9 #include "WlanHAL/HalHeader/HalComReg.h"\r
10 #endif\r
11 #endif\r
12 \r
13 #if (PHYDM_LA_MODE_SUPPORT == 1)\r
14 \r
15 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
16 BOOLEAN\r
17 ADCSmp_BufferAllocate(\r
18         IN      PADAPTER                        Adapter,\r
19         IN      PRT_ADCSMP                      AdcSmp\r
20         )\r
21 {\r
22         PRT_ADCSMP_STRING       ADCSmpBuf = &(AdcSmp->ADCSmpBuf);\r
23 \r
24         if (ADCSmpBuf->Length == 0) {\r
25                 if (PlatformAllocateMemoryWithZero(Adapter, (void **)&(ADCSmpBuf->Octet), ADCSmpBuf->buffer_size) == RT_STATUS_SUCCESS)\r
26                         ADCSmpBuf->Length = ADCSmpBuf->buffer_size;\r
27                 else\r
28                         return FALSE;\r
29         }\r
30 \r
31         return TRUE;\r
32 }\r
33 #endif\r
34 \r
35 VOID\r
36 ADCSmp_GetTxPktBuf(\r
37         IN              PVOID                   pDM_VOID,\r
38         IN      PRT_ADCSMP_STRING       ADCSmpBuf\r
39         )\r
40 {\r
41         PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
42         u4Byte                          i = 0, value32, DataL = 0, DataH = 0;\r
43         u4Byte                          Addr, Finish_Addr;\r
44         u4Byte                          End_Addr = (ADCSmpBuf->start_pos  + ADCSmpBuf->buffer_size)-1;  /*End_Addr = 0x3ffff;*/\r
45         BOOLEAN                         bRoundUp;\r
46         static u4Byte                   page = 0xFF;\r
47         u4Byte                          while_cnt = 0;\r
48 \r
49         ODM_Memory_Set(pDM_Odm, ADCSmpBuf->Octet, 0, ADCSmpBuf->Length);\r
50         ODM_Write1Byte(pDM_Odm, 0x0106, 0x69);\r
51 \r
52         DbgPrint("%s\n", __func__);\r
53 \r
54         value32 = ODM_Read4Byte(pDM_Odm, 0x7c0);\r
55         bRoundUp = (BOOLEAN)((value32 & BIT31) >> 31);\r
56         Finish_Addr = (value32 & 0x7FFF0000) >> 16;     /*Reg7C0[30:16]: finish addr (unit: 8byte)*/\r
57 \r
58         if (bRoundUp)\r
59                 Addr = (Finish_Addr+1)<<3;\r
60         else\r
61                 Addr = ADCSmpBuf->start_pos;\r
62                 \r
63         DbgPrint("bRoundUp = %d, Finish_Addr=0x%x, value32=0x%x\n", bRoundUp, Finish_Addr, value32);\r
64         DbgPrint("End_Addr = %x, ADCSmpBuf->start_pos = 0x%x, ADCSmpBuf->buffer_size = 0x%x\n", End_Addr, ADCSmpBuf->start_pos, ADCSmpBuf->buffer_size);\r
65 \r
66 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)\r
67         watchdog_stop(pDM_Odm->priv);\r
68 #endif\r
69 \r
70         if (pDM_Odm->SupportICType & ODM_RTL8197F) {\r
71                 for (Addr = 0x0, i = 0; Addr < End_Addr; Addr += 8, i += 2) {   /*64K byte*/\r
72                         if ((Addr&0xfff) == 0)\r
73                                 ODM_SetBBReg(pDM_Odm, 0x0140, bMaskLWord, 0x780+(Addr >> 12));\r
74                         DataL = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff), bMaskDWord);\r
75                         DataH = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff)+4, bMaskDWord);\r
76 \r
77                         DbgPrint("%08x%08x\n", DataH, DataL);           \r
78                 }\r
79         } else {\r
80                 while (Addr != (Finish_Addr<<3)) {\r
81                         if (page != (Addr >> 12)) {\r
82                                 /*Reg140=0x780+(Addr>>12), Addr=0x30~0x3F, total 16 pages*/\r
83                                 page = (Addr >> 12);\r
84                         }\r
85                         ODM_SetBBReg(pDM_Odm, 0x0140, bMaskLWord, 0x780+page);\r
86 \r
87                         /*pDataL = 0x8000+(Addr&0xfff);*/\r
88                         DataL = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff), bMaskDWord);\r
89                         DataH = ODM_GetBBReg(pDM_Odm, 0x8000+(Addr&0xfff)+4, bMaskDWord);\r
90 \r
91 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
92                         ADCSmpBuf->Octet[i] = DataH;\r
93                         ADCSmpBuf->Octet[i+1] = DataL;\r
94 #endif\r
95                         DbgPrint("%08x%08x\n", DataH, DataL);\r
96                         i = i + 2;\r
97                         \r
98                         if ((Addr+8) >= End_Addr)\r
99                                 Addr = ADCSmpBuf->start_pos;\r
100                         else\r
101                                 Addr = Addr + 8;\r
102 \r
103                         while_cnt = while_cnt + 1;\r
104                         if (while_cnt > ((ADCSmpBuf->buffer_size)>>3))\r
105                                 break;\r
106                 }\r
107         }\r
108         \r
109 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)\r
110         watchdog_resume(pDM_Odm->priv);\r
111 #endif\r
112 }       \r
113 \r
114 \r
115 VOID\r
116 ADCSmp_Start(\r
117         IN              PVOID                   pDM_VOID,\r
118         IN              PRT_ADCSMP              AdcSmp\r
119         )\r
120 {\r
121         PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
122         u1Byte                                  tmpU1b;\r
123         PRT_ADCSMP_STRING               Buffer = &(AdcSmp->ADCSmpBuf);\r
124         RT_ADCSMP_TRIG_SIG_SEL  TrigSigSel = AdcSmp->ADCSmpTrigSigSel;\r
125         u1Byte                                  backup_DMA, while_cnt = 0;\r
126 \r
127         DbgPrint("%s\n", __func__);\r
128 \r
129         if (pDM_Odm->SupportICType & ODM_RTL8197F)\r
130                 ODM_SetBBReg(pDM_Odm, 0x9a0, 0xf00, AdcSmp->ADCSmpDmaDataSigSel);       /*0x9A0[11:8]*/\r
131         else\r
132                 ODM_SetBBReg(pDM_Odm , ODM_ADC_TRIGGER_Jaguar2, 0xf00, AdcSmp->ADCSmpDmaDataSigSel);    /*0x95C[11:8]*/\r
133 \r
134         ODM_Write1Byte(pDM_Odm, 0x7c0+1, AdcSmp->ADCSmpTriggerTime);\r
135 \r
136 \r
137         if (pDM_Odm->SupportICType & ODM_RTL8197F)\r
138                 ODM_SetBBReg(pDM_Odm, 0xd00, BIT26, 0x1);\r
139         else {  /*for 8814A and 8822B?*/\r
140                 ODM_Write1Byte(pDM_Odm, 0x198c, 0x7);\r
141                 ODM_Write1Byte(pDM_Odm, 0x8b4, 0x80);\r
142         }\r
143         \r
144         if (AdcSmp->ADCSmpTrigSel == ADCSMP_MAC_TRIG) { /* trigger by MAC*/\r
145                 if (TrigSigSel == ADCSMP_TRIG_REG) {                    /* manual trigger 0x7C0[5] = 0 -> 1*/\r
146                         ODM_Write1Byte(pDM_Odm, 0x7c0, 0xCB);           /*0x7C0[7:0]=8'b1100_1011*/\r
147                         ODM_Write1Byte(pDM_Odm, 0x7c0, 0xEB);           /*0x7C0[7:0]=8'b1110_1011*/\r
148                 } else if (TrigSigSel == ADCSMP_TRIG_CCA)\r
149                         ODM_Write1Byte(pDM_Odm, 0x7c0, 0x8B);           /*0x7C0[7:0]=8'b1000_1011*/\r
150                 else if (TrigSigSel == ADCSMP_TRIG_CRCFAIL)\r
151                         ODM_Write1Byte(pDM_Odm, 0x7c0, 0x4B);           /*0x7C0[7:0]=8'b0100_1011*/\r
152                 else if (TrigSigSel == ADCSMP_TRIG_CRCOK)\r
153                         ODM_Write1Byte(pDM_Odm, 0x7c0, 0x0B);           /*0x7C0[7:0]=8'b0000_1011*/\r
154         } else {                                                                                                /*trigger by BB*/\r
155                 if (pDM_Odm->SupportICType & ODM_RTL8197F)\r
156                         ODM_SetBBReg(pDM_Odm, 0x9a0, 0x1f, TrigSigSel); /*0x9A0[4:0]*/\r
157                 else\r
158                         ODM_SetBBReg(pDM_Odm , ODM_ADC_TRIGGER_Jaguar2, 0x1f, TrigSigSel);      /*0x95C[4:0], 0x1F: trigger by CCA*/\r
159                 ODM_Write1Byte(pDM_Odm, 0x7c0, 0x03);   /*0x7C0[7:0]=8'b0000_0011*/\r
160         }\r
161         \r
162 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)\r
163         watchdog_stop(pDM_Odm->priv);\r
164 #endif\r
165 \r
166         /*Polling time always use 100ms, when it exceed 2s, break while loop*/\r
167         do {\r
168                 tmpU1b = ODM_Read1Byte(pDM_Odm, 0x7c0);\r
169 \r
170                 if (AdcSmp->ADCSmpState != ADCSMP_STATE_SET) {\r
171                         DbgPrint("ADCSmpState != ADCSMP_STATE_SET\n");\r
172                         break;\r
173                         \r
174                 } else if (tmpU1b & BIT1) {\r
175                         ODM_delay_ms(100);\r
176                         while_cnt = while_cnt + 1;\r
177                         continue;\r
178                 } else {\r
179                         DbgPrint("%s Query OK\n", __func__);\r
180                         if (pDM_Odm->SupportICType & ODM_RTL8197F)\r
181                                 ODM_SetBBReg(pDM_Odm, 0x7c0, BIT0, 0x0);\r
182                         break;\r
183                 }\r
184         } while (while_cnt < 20);\r
185         \r
186 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)\r
187         watchdog_resume(pDM_Odm->priv);\r
188 #if (RTL8197F_SUPPORT == 1)\r
189         if (pDM_Odm->SupportICType & ODM_RTL8197F) {\r
190                 /*Stop DMA*/\r
191                 backup_DMA = ODM_GetMACReg(pDM_Odm, 0x300, bMaskLWord);\r
192                 ODM_SetMACReg(pDM_Odm, 0x300, 0x7fff, backup_DMA|0x7fff);\r
193                 \r
194                 /*move LA mode content from IMEM to TxPktBuffer \r
195                         Src : OCPBASE_IMEM 0x00000000\r
196                         Dest : OCPBASE_TXBUF 0x18780000\r
197                         Len : 64K*/\r
198                 GET_HAL_INTERFACE(pDM_Odm->priv)->InitDDMAHandler(pDM_Odm->priv, OCPBASE_IMEM, OCPBASE_TXBUF, 0x10000);\r
199         }\r
200 #endif\r
201 #endif\r
202 \r
203         if (AdcSmp->ADCSmpState == ADCSMP_STATE_SET)\r
204                 ADCSmp_GetTxPktBuf(pDM_Odm, Buffer);\r
205 \r
206 #if (DM_ODM_SUPPORT_TYPE & ODM_AP)\r
207         if (pDM_Odm->SupportICType & ODM_RTL8197F) \r
208                 ODM_SetMACReg(pDM_Odm, 0x300, 0x7fff, backup_DMA);      /*Resume DMA*/\r
209 #endif\r
210 \r
211 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
212         if (AdcSmp->ADCSmpState == ADCSMP_STATE_SET)\r
213                 AdcSmp->ADCSmpState = ADCSMP_STATE_QUERY;\r
214 #endif\r
215 \r
216         DbgPrint("%s Status %d\n", __func__, AdcSmp->ADCSmpState);\r
217 }\r
218 \r
219 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
220 VOID\r
221 ADCSmpWorkItemCallback(\r
222         IN      PVOID   pContext\r
223         )\r
224 {\r
225         PADAPTER                        Adapter = (PADAPTER)pContext;\r
226         PHAL_DATA_TYPE          pHalData = GET_HAL_DATA(Adapter);\r
227         PDM_ODM_T               pDM_Odm = &pHalData->DM_OutSrc;\r
228         PRT_ADCSMP              AdcSmp = &(pDM_Odm->adcsmp);\r
229 \r
230         ADCSmp_Start(pDM_Odm, AdcSmp);\r
231         ADCSmp_Stop(pDM_Odm);\r
232 }\r
233 #endif\r
234 \r
235 VOID\r
236 ADCSmp_Set(\r
237         IN              PVOID                   pDM_VOID,\r
238         IN      RT_ADCSMP_TRIG_SEL              TrigSel,\r
239         IN      RT_ADCSMP_TRIG_SIG_SEL  TrigSigSel,\r
240         IN      u1Byte                                  DmaDataSigSel,\r
241         IN      u1Byte                                  TriggerTime,\r
242         IN      u2Byte                                  PollingTime\r
243         )\r
244 {\r
245         PDM_ODM_T                               pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
246         BOOLEAN                         retValue = TRUE;\r
247         PRT_ADCSMP                      AdcSmp = &(pDM_Odm->adcsmp);\r
248 \r
249         AdcSmp->ADCSmpTrigSel = TrigSel;\r
250         AdcSmp->ADCSmpTrigSigSel = TrigSigSel;\r
251         AdcSmp->ADCSmpDmaDataSigSel = DmaDataSigSel;\r
252         AdcSmp->ADCSmpTriggerTime = TriggerTime;\r
253         AdcSmp->ADCSmpPollingTime = PollingTime;\r
254 \r
255 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
256         if (AdcSmp->ADCSmpState != ADCSMP_STATE_IDLE)\r
257                 retValue = FALSE;\r
258         else if (AdcSmp->ADCSmpBuf.Length == 0)\r
259                 retValue = ADCSmp_BufferAllocate(pDM_Odm->Adapter, AdcSmp);\r
260 #endif\r
261 \r
262         if (retValue) {\r
263                 AdcSmp->ADCSmpState = ADCSMP_STATE_SET;\r
264                 \r
265 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
266                 ODM_ScheduleWorkItem(&(AdcSmp->ADCSmpWorkItem));\r
267 #else\r
268                 ADCSmp_Start(pDM_Odm, AdcSmp); \r
269 #endif\r
270         }       \r
271 \r
272         DbgPrint("ADCSmpState %d Return Status %d\n", AdcSmp->ADCSmpState, retValue);\r
273 }\r
274 \r
275 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
276 RT_STATUS\r
277 ADCSmp_Query(\r
278         IN      PVOID                           pDM_VOID,\r
279         IN      ULONG                           InformationBufferLength, \r
280         OUT     PVOID                           InformationBuffer, \r
281         OUT     PULONG                          BytesWritten\r
282         )\r
283 {\r
284         PDM_ODM_T                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
285         PRT_ADCSMP                      AdcSmp = &(pDM_Odm->adcsmp);\r
286         RT_STATUS                       retStatus = RT_STATUS_SUCCESS;\r
287         PRT_ADCSMP_STRING       ADCSmpBuf = &(AdcSmp->ADCSmpBuf);\r
288 \r
289         DbgPrint("%s ADCSmpState %d", __func__, AdcSmp->ADCSmpState);\r
290 \r
291         if (InformationBufferLength != ADCSmpBuf->buffer_size)  {\r
292                 *BytesWritten = 0;\r
293                 retStatus = RT_STATUS_RESOURCE;\r
294         } else if (ADCSmpBuf->Length != ADCSmpBuf->buffer_size) {\r
295                 *BytesWritten = 0;\r
296                 retStatus = RT_STATUS_RESOURCE;\r
297         } else if (AdcSmp->ADCSmpState != ADCSMP_STATE_QUERY) {\r
298                 *BytesWritten = 0;\r
299                 retStatus = RT_STATUS_PENDING;\r
300         } else {\r
301                 ODM_MoveMemory(pDM_Odm, InformationBuffer, ADCSmpBuf->Octet, ADCSmpBuf->buffer_size);\r
302                 *BytesWritten = ADCSmpBuf->buffer_size;\r
303 \r
304                 AdcSmp->ADCSmpState = ADCSMP_STATE_IDLE;\r
305         }\r
306 \r
307         DbgPrint("Return Status %d\n", retStatus);\r
308 \r
309         return retStatus;\r
310 }\r
311 #endif\r
312 \r
313 VOID\r
314 ADCSmp_Stop(\r
315         IN              PVOID                   pDM_VOID\r
316         )\r
317 {\r
318         PDM_ODM_T                       pDM_Odm = (PDM_ODM_T)pDM_VOID;  \r
319         PRT_ADCSMP                      AdcSmp = &(pDM_Odm->adcsmp);\r
320 \r
321         AdcSmp->ADCSmpState = ADCSMP_STATE_IDLE;\r
322 \r
323         DbgPrint("%s status %d\n", __func__, AdcSmp->ADCSmpState);\r
324 }\r
325 \r
326 VOID\r
327 ADCSmp_Init(\r
328         IN              PVOID                   pDM_VOID\r
329         )\r
330 {\r
331         PDM_ODM_T                       pDM_Odm = (PDM_ODM_T)pDM_VOID;  \r
332         PRT_ADCSMP                      AdcSmp = &(pDM_Odm->adcsmp);\r
333         PRT_ADCSMP_STRING       ADCSmpBuf = &(AdcSmp->ADCSmpBuf);\r
334 \r
335         AdcSmp->ADCSmpState = ADCSMP_STATE_IDLE;\r
336 \r
337         if (pDM_Odm->SupportICType & ODM_RTL8814A) {\r
338                 ADCSmpBuf->start_pos = 0x30000;\r
339                 ADCSmpBuf->buffer_size = 0x10000;       \r
340         } else if (pDM_Odm->SupportICType & ODM_RTL8822B) {\r
341                 ADCSmpBuf->start_pos = 0x20000;\r
342                 ADCSmpBuf->buffer_size = 0x20000;       \r
343         } else if (pDM_Odm->SupportICType & ODM_RTL8197F) {\r
344                 ADCSmpBuf->start_pos = 0x00000;\r
345                 ADCSmpBuf->buffer_size = 0x10000;       \r
346         } else if (pDM_Odm->SupportICType & ODM_RTL8821C) {\r
347                 ADCSmpBuf->start_pos = 0x8000;\r
348                 ADCSmpBuf->buffer_size = 0x8000;        \r
349         }\r
350         \r
351 }\r
352 \r
353 #if (DM_ODM_SUPPORT_TYPE & ODM_WIN)\r
354 VOID\r
355 ADCSmp_DeInit(\r
356         IN              PVOID                   pDM_VOID\r
357         )\r
358 {\r
359         PDM_ODM_T                       pDM_Odm = (PDM_ODM_T)pDM_VOID;\r
360         PRT_ADCSMP                      AdcSmp = &(pDM_Odm->adcsmp);\r
361         PRT_ADCSMP_STRING       ADCSmpBuf = &(AdcSmp->ADCSmpBuf);\r
362 \r
363         ADCSmp_Stop(pDM_Odm);\r
364 \r
365         if (ADCSmpBuf->Length != 0x0) {\r
366                 ODM_FreeMemory(pDM_Odm, ADCSmpBuf->Octet, ADCSmpBuf->Length);\r
367                 ADCSmpBuf->Length = 0x0;\r
368         }\r
369 }       \r
370 \r
371 #endif\r
372 \r
373 #endif\r
374 \r