78665eec3c1dc92fc149c5b9d606a3b909e16e24
[firefly-linux-kernel-4.4.55.git] / drivers / staging / rtl8723au / hal / rtl8723a_bt-coexist.c
1 /******************************************************************************
2  *
3  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it
6  * under the terms of version 2 of the GNU General Public License as
7  *published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12  * more details.
13  *
14  ******************************************************************************/
15 #include <drv_types.h>
16 #include <rtl8723a_hal.h>
17 #include <usb_ops_linux.h>
18
19 #define DIS_PS_RX_BCN
20
21 u32 BTCoexDbgLevel = _bt_dbg_off_;
22
23 #define RTPRINT(_Comp, _Level, Fmt)\
24 do {\
25         if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
26                 printk Fmt;\
27         }                                       \
28 } while (0)
29
30 #define RTPRINT_ADDR(dbgtype, dbgflag, printstr, _Ptr)\
31 if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
32         u32 __i;                                                \
33         u8 *ptr = (u8 *)_Ptr;   \
34         printk printstr;                                \
35         printk(" ");                                    \
36         for (__i = 0; __i < 6; __i++)           \
37                 printk("%02X%s", ptr[__i], (__i == 5)?"":"-");          \
38         printk("\n");                                                   \
39 }
40 #define RTPRINT_DATA(dbgtype, dbgflag, _TitleString, _HexData, _HexDataLen)\
41 if ((BTCoexDbgLevel == _bt_dbg_on_)) {\
42         u32 __i;                                                \
43         u8 *ptr = (u8 *)_HexData;                               \
44         printk(_TitleString);                                   \
45         for (__i = 0; __i < (u32)_HexDataLen; __i++) {          \
46                 printk("%02X%s", ptr[__i], (((__i + 1) % 4) == 0)?"  ":" ");\
47                 if (((__i + 1) % 16) == 0)                      \
48                         printk("\n");                           \
49         }                                                               \
50         printk("\n");                                                   \
51 }
52 /*  Added by Annie, 2005-11-22. */
53 #define MAX_STR_LEN     64
54 /*  I want to see ASCII 33 to 126 only. Otherwise, I print '?'. */
55 #define PRINTABLE(_ch)  (_ch >= ' ' && _ch <= '~')
56 #define RT_PRINT_STR(_Comp, _Level, _TitleString, _Ptr, _Len)           \
57         {                                                               \
58                 u32 __i;                                                \
59                 u8 buffer[MAX_STR_LEN];                                 \
60                 u32 length = (_Len < MAX_STR_LEN) ? _Len : (MAX_STR_LEN-1);\
61                 memset(buffer, 0, MAX_STR_LEN);                         \
62                 memcpy(buffer, (u8 *)_Ptr, length);                     \
63                 for (__i = 0; __i < length; __i++) {                    \
64                         if (!PRINTABLE(buffer[__i]))                    \
65                                 buffer[__i] = '?';                      \
66                 }                                                       \
67                 buffer[length] = '\0';                                  \
68                 printk(_TitleString);                                   \
69                 printk(": %d, <%s>\n", _Len, buffer);                   \
70         }
71
72 #define DCMD_Printf(...)
73 #define RT_ASSERT(...)
74
75 #define rsprintf snprintf
76
77 #define GetDefaultAdapter(padapter)     padapter
78
79 #define PlatformZeroMemory(ptr, sz)     memset(ptr, 0, sz)
80
81 #define PlatformProcessHCICommands(...)
82 #define PlatformTxBTQueuedPackets(...)
83 #define PlatformIndicateBTACLData(...)  (RT_STATUS_SUCCESS)
84 #define PlatformAcquireSpinLock(padapter, type)
85 #define PlatformReleaseSpinLock(padapter, type)
86
87 #define GET_UNDECORATED_AVERAGE_RSSI(padapter)  \
88                         (GET_HAL_DATA(padapter)->dmpriv.EntryMinUndecoratedSmoothedPWDB)
89 #define RT_RF_CHANGE_SOURCE u32
90
91 enum {
92         RT_JOIN_INFRA   = 1,
93         RT_JOIN_IBSS  = 2,
94         RT_START_IBSS = 3,
95         RT_NO_ACTION  = 4,
96 };
97
98 /*  power saving */
99
100 /*  ===== Below this line is sync from SD7 driver COMMOM/BT.c ===== */
101
102 static u8 BT_Operation(struct rtw_adapter *padapter)
103 {
104         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
105         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
106
107         if (pBtMgnt->BtOperationOn)
108                 return true;
109         else
110                 return false;
111 }
112
113 static u8 BT_IsLegalChannel(struct rtw_adapter *padapter, u8 channel)
114 {
115         struct rt_channel_info *pChanneList = NULL;
116         u8 channelLen, i;
117
118         pChanneList = padapter->mlmeextpriv.channel_set;
119         channelLen = padapter->mlmeextpriv.max_chan_nums;
120
121         for (i = 0; i < channelLen; i++) {
122                 RTPRINT(FIOCTL, IOCTL_STATE,
123                         ("Check if chnl(%d) in channel plan contains bt target chnl(%d) for BT connection\n",
124                          pChanneList[i].ChannelNum, channel));
125                 if ((channel == pChanneList[i].ChannelNum) ||
126                     (channel == pChanneList[i].ChannelNum + 2))
127                         return channel;
128         }
129         return 0;
130 }
131
132 void BT_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
133 {
134         BTDM_SignalCompensation(padapter, rssi_wifi, rssi_bt);
135 }
136
137 void rtl8723a_BT_wifiscan_notify(struct rtw_adapter *padapter, u8 scanType)
138 {
139         BTHCI_WifiScanNotify(padapter, scanType);
140         BTDM_CheckAntSelMode(padapter);
141         BTDM_WifiScanNotify(padapter, scanType);
142 }
143
144 void rtl8723a_BT_wifiassociate_notify(struct rtw_adapter *padapter, u8 action)
145 {
146         /*  action : */
147         /*  true = associate start */
148         /*  false = associate finished */
149         if (action)
150                 BTDM_CheckAntSelMode(padapter);
151
152         BTDM_WifiAssociateNotify(padapter, action);
153 }
154
155 void BT_HaltProcess(struct rtw_adapter *padapter)
156 {
157         BTDM_ForHalt(padapter);
158 }
159
160 /*  ===== End of sync from SD7 driver COMMOM/BT.c ===== */
161
162 #define i64fmt          "ll"
163 #define UINT64_C(v)  (v)
164
165 #define FillOctetString(_os, _octet, _len)              \
166         (_os).Octet = (u8 *)(_octet);                   \
167         (_os).Length = (_len);
168
169 static enum rt_status PlatformIndicateBTEvent(
170         struct rtw_adapter *padapter,
171         void                                            *pEvntData,
172         u32                                             dataLen
173         )
174 {
175         enum rt_status  rt_status = RT_STATUS_FAILURE;
176
177         RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, ("BT event start, %d bytes data to Transferred!!\n", dataLen));
178         RTPRINT_DATA(FIOCTL, IOCTL_BT_EVENT_DETAIL, "To transfer Hex Data :\n",
179                 pEvntData, dataLen);
180
181         BT_EventParse(padapter, pEvntData, dataLen);
182
183         printk(KERN_WARNING "%s: Linux has no way to report BT event!!\n", __func__);
184
185         RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL, ("BT event end, %s\n",
186                 (rt_status == RT_STATUS_SUCCESS) ? "SUCCESS" : "FAIL"));
187
188         return rt_status;
189 }
190
191 /*  ===== Below this line is sync from SD7 driver COMMOM/bt_hci.c ===== */
192
193 static u8 bthci_GetLocalChannel(struct rtw_adapter *padapter)
194 {
195         return padapter->mlmeextpriv.cur_channel;
196 }
197
198 static u8 bthci_GetCurrentEntryNum(struct rtw_adapter *padapter, u8 PhyHandle)
199 {
200         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
201         u8 i;
202
203         for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
204                 if ((pBTInfo->BtAsocEntry[i].bUsed) &&
205                     (pBTInfo->BtAsocEntry[i].PhyLinkCmdData.BtPhyLinkhandle == PhyHandle))
206                         return i;
207         }
208
209         return 0xFF;
210 }
211
212 static void bthci_DecideBTChannel(struct rtw_adapter *padapter, u8 EntryNum)
213 {
214 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
215         struct mlme_priv *pmlmepriv;
216         struct bt_30info *pBTInfo;
217         struct bt_mgnt *pBtMgnt;
218         struct bt_hci_info *pBtHciInfo;
219         struct chnl_txpower_triple *pTriple_subband = NULL;
220         struct common_triple *pTriple;
221         u8 i, j, localchnl, firstRemoteLegalChnlInTriplet = 0;
222         u8 regulatory_skipLen = 0;
223         u8 subbandTripletCnt = 0;
224
225         pmlmepriv = &padapter->mlmepriv;
226         pBTInfo = GET_BT_INFO(padapter);
227         pBtMgnt = &pBTInfo->BtMgnt;
228         pBtHciInfo = &pBTInfo->BtHciInfo;
229
230         pBtMgnt->CheckChnlIsSuit = true;
231         localchnl = bthci_GetLocalChannel(padapter);
232
233         pTriple = (struct common_triple *)
234                 &pBtHciInfo->BTPreChnllist[COUNTRY_STR_LEN];
235
236         /*  contains country string, len is 3 */
237         for (i = 0; i < (pBtHciInfo->BtPreChnlListLen-COUNTRY_STR_LEN); i += 3, pTriple++) {
238                 /*  */
239                 /*  check every triplet, an triplet may be */
240                 /*  regulatory extension identifier or sub-band triplet */
241                 /*  */
242                 if (pTriple->byte_1st == 0xc9) {
243                         /*  Regulatory Extension Identifier, skip it */
244                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
245                                 ("Find Regulatory ID, regulatory class = %d\n", pTriple->byte_2nd));
246                         regulatory_skipLen += 3;
247                         pTriple_subband = NULL;
248                         continue;
249                 } else {        /*  Sub-band triplet */
250                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Find Sub-band triplet \n"));
251                         subbandTripletCnt++;
252                         pTriple_subband = (struct chnl_txpower_triple *)pTriple;
253                         /*  if remote first legal channel not found, then find first remote channel */
254                         /*  and it's legal for our channel plan. */
255
256                         /*  search the sub-band triplet and find if remote channel is legal to our channel plan. */
257                         for (j = pTriple_subband->FirstChnl; j < (pTriple_subband->FirstChnl+pTriple_subband->NumChnls); j++) {
258                                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), (" Check if chnl(%d) is legal\n", j));
259                                 if (BT_IsLegalChannel(padapter, j)) {
260                                         /*  remote channel is legal for our channel plan. */
261                                         firstRemoteLegalChnlInTriplet = j;
262                                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
263                                                 ("Find first remote legal channel : %d\n",
264                                                 firstRemoteLegalChnlInTriplet));
265
266                                         /*  If we find a remote legal channel in the sub-band triplet */
267                                         /*  and only BT connection is established(local not connect to any AP or IBSS), */
268                                         /*  then we just switch channel to remote channel. */
269                                         if (!(check_fwstate(pmlmepriv, WIFI_ASOC_STATE|WIFI_ADHOC_STATE|WIFI_AP_STATE) ||
270                                             BTHCI_HsConnectionEstablished(padapter))) {
271                                                 pBtMgnt->BTChannel = firstRemoteLegalChnlInTriplet;
272                                                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Remote legal channel (%d) is selected, Local not connect to any!!\n", pBtMgnt->BTChannel));
273                                                 return;
274                                         } else {
275                                                 if ((localchnl >= firstRemoteLegalChnlInTriplet) &&
276                                                     (localchnl < (pTriple_subband->FirstChnl+pTriple_subband->NumChnls))) {
277                                                         pBtMgnt->BTChannel = localchnl;
278                                                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Local channel (%d) is selected, wifi or BT connection exists\n", pBtMgnt->BTChannel));
279                                                         return;
280                                                 }
281                                         }
282                                         break;
283                                 }
284                         }
285                 }
286         }
287
288         if (subbandTripletCnt) {
289                 /* if any preferred channel triplet exists */
290                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("There are %d sub band triplet exists, ", subbandTripletCnt));
291                 if (firstRemoteLegalChnlInTriplet == 0) {
292                         /* no legal channel is found, reject the connection. */
293                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("no legal channel is found!!\n"));
294                 } else {
295                         /*  Remote Legal channel is found but not match to local */
296                         /* wifi connection exists), so reject the connection. */
297                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
298                                 ("Remote Legal channel is found but not match to local(wifi connection exists)!!\n"));
299                 }
300                 pBtMgnt->CheckChnlIsSuit = false;
301         } else {
302                 /*  There are not any preferred channel triplet exists */
303                 /*  Use current legal channel as the bt channel. */
304                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("No sub band triplet exists!!\n"));
305         }
306         pBtMgnt->BTChannel = localchnl;
307         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Local channel (%d) is selected!!\n", pBtMgnt->BTChannel));
308 }
309
310 /* Success:return true */
311 /* Fail:return false */
312 static u8 bthci_GetAssocInfo(struct rtw_adapter *padapter, u8 EntryNum)
313 {
314         struct bt_30info *pBTInfo;
315         struct bt_hci_info *pBtHciInfo;
316         u8 tempBuf[256];
317         u8 i = 0;
318         u8 BaseMemoryShift = 0;
319         u16     TotalLen = 0;
320         struct amp_assoc_structure *pAmpAsoc;
321
322         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("GetAssocInfo start\n"));
323         pBTInfo = GET_BT_INFO(padapter);
324         pBtHciInfo = &pBTInfo->BtHciInfo;
325
326         if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar == 0) {
327                 if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen < (MAX_AMP_ASSOC_FRAG_LEN))
328                         TotalLen = pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen;
329                 else if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen == (MAX_AMP_ASSOC_FRAG_LEN))
330                         TotalLen = MAX_AMP_ASSOC_FRAG_LEN;
331         } else if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar > 0)
332                 TotalLen = pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar;
333
334         while ((pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar >= BaseMemoryShift) || TotalLen > BaseMemoryShift) {
335                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("GetAssocInfo, TotalLen =%d, BaseMemoryShift =%d\n", TotalLen, BaseMemoryShift));
336                 memcpy(tempBuf,
337                         (u8 *)pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment+BaseMemoryShift,
338                         TotalLen-BaseMemoryShift);
339                 RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, "GetAssocInfo :\n",
340                         tempBuf, TotalLen-BaseMemoryShift);
341
342                 pAmpAsoc = (struct amp_assoc_structure *)tempBuf;
343                 le16_to_cpus(&pAmpAsoc->Length);
344                 BaseMemoryShift += 3 + pAmpAsoc->Length;
345
346                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TypeID = 0x%x, ", pAmpAsoc->TypeID));
347                 RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, "Hex Data: \n", pAmpAsoc->Data, pAmpAsoc->Length);
348                 switch (pAmpAsoc->TypeID) {
349                 case AMP_MAC_ADDR:
350                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_MAC_ADDR\n"));
351                         if (pAmpAsoc->Length > 6)
352                                 return false;
353                         memcpy(pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr, pAmpAsoc->Data, 6);
354                         RTPRINT_ADDR(FIOCTL, IOCTL_BT_HCICMD, ("Remote Mac address \n"), pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr);
355                         break;
356                 case AMP_PREFERRED_CHANNEL_LIST:
357                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_PREFERRED_CHANNEL_LIST\n"));
358                         pBtHciInfo->BtPreChnlListLen = pAmpAsoc->Length;
359                         memcpy(pBtHciInfo->BTPreChnllist,
360                                 pAmpAsoc->Data,
361                                 pBtHciInfo->BtPreChnlListLen);
362                         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, "Preferred channel list : \n", pBtHciInfo->BTPreChnllist, pBtHciInfo->BtPreChnlListLen);
363                         bthci_DecideBTChannel(padapter, EntryNum);
364                         break;
365                 case AMP_CONNECTED_CHANNEL:
366                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_CONNECTED_CHANNEL\n"));
367                         pBtHciInfo->BTConnectChnlListLen = pAmpAsoc->Length;
368                         memcpy(pBtHciInfo->BTConnectChnllist,
369                                 pAmpAsoc->Data,
370                                 pBtHciInfo->BTConnectChnlListLen);
371                         break;
372                 case AMP_80211_PAL_CAP_LIST:
373                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> AMP_80211_PAL_CAP_LIST\n"));
374                         pBTInfo->BtAsocEntry[EntryNum].BTCapability = *(u32 *)(pAmpAsoc->Data);
375                         if (pBTInfo->BtAsocEntry[EntryNum].BTCapability & 0x00000001) {
376                                 /*  TODO: */
377
378                                 /* Signifies PAL capable of utilizing received activity reports. */
379                         }
380                         if (pBTInfo->BtAsocEntry[EntryNum].BTCapability & 0x00000002) {
381                                 /*  TODO: */
382                                 /* Signifies PAL is capable of utilizing scheduling information received in an activity reports. */
383                         }
384                         break;
385                 case AMP_80211_PAL_VISION:
386                         pBtHciInfo->BTPalVersion = *(u8 *)(pAmpAsoc->Data);
387                         pBtHciInfo->BTPalCompanyID = *(u16 *)(((u8 *)(pAmpAsoc->Data))+1);
388                         pBtHciInfo->BTPalsubversion = *(u16 *)(((u8 *)(pAmpAsoc->Data))+3);
389                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("==> AMP_80211_PAL_VISION PalVersion  0x%x, PalCompanyID  0x%x, Palsubversion 0x%x\n",
390                                 pBtHciInfo->BTPalVersion,
391                                 pBtHciInfo->BTPalCompanyID,
392                                 pBtHciInfo->BTPalsubversion));
393                         break;
394                 default:
395                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("==> Unsupport TypeID !!\n"));
396                         break;
397                 }
398                 i++;
399         }
400         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("GetAssocInfo end\n"));
401
402         return true;
403 }
404
405 static u8 bthci_AddEntry(struct rtw_adapter *padapter)
406 {
407         struct bt_30info *pBTInfo;
408         struct bt_mgnt *pBtMgnt;
409         u8 i;
410
411         pBTInfo = GET_BT_INFO(padapter);
412         pBtMgnt = &pBTInfo->BtMgnt;
413
414         for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
415                 if (pBTInfo->BtAsocEntry[i].bUsed == false) {
416                         pBTInfo->BtAsocEntry[i].bUsed = true;
417                         pBtMgnt->CurrentConnectEntryNum = i;
418                         break;
419                 }
420         }
421
422         if (i == MAX_BT_ASOC_ENTRY_NUM) {
423                 RTPRINT(FIOCTL, IOCTL_STATE, ("bthci_AddEntry(), Add entry fail!!\n"));
424                 return false;
425         }
426         return true;
427 }
428
429 static u8 bthci_DiscardTxPackets(struct rtw_adapter *padapter, u16 LLH)
430 {
431         return false;
432 }
433
434 static u8
435 bthci_CheckLogLinkBehavior(
436         struct rtw_adapter *padapter,
437         struct hci_flow_spec                    TxFlowSpec
438         )
439 {
440         u8 ID = TxFlowSpec.Identifier;
441         u8 ServiceType = TxFlowSpec.ServiceType;
442         u16     MaxSDUSize = TxFlowSpec.MaximumSDUSize;
443         u32     SDUInterArrivatime = TxFlowSpec.SDUInterArrivalTime;
444         u8 match = false;
445
446         switch (ID) {
447         case 1:
448                 if (ServiceType == BT_LL_BE) {
449                         match = true;
450                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  TX best effort flowspec\n"));
451                 } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 0xffff)) {
452                         match = true;
453                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  RX guaranteed latency flowspec\n"));
454                 } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 2500)) {
455                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  RX guaranteed Large latency flowspec\n"));
456                 }
457                 break;
458         case 2:
459                 if (ServiceType == BT_LL_BE) {
460                         match = true;
461                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  RX best effort flowspec\n"));
462
463                 }
464                 break;
465         case 3:
466                 if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 1492)) {
467                         match = true;
468                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  TX guaranteed latency flowspec\n"));
469                 } else if ((ServiceType == BT_LL_GU) && (MaxSDUSize == 2500)) {
470                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  TX guaranteed Large latency flowspec\n"));
471                 }
472                 break;
473         case 4:
474                 if (ServiceType == BT_LL_BE) {
475                         if ((SDUInterArrivatime == 0xffffffff) && (ServiceType == BT_LL_BE) && (MaxSDUSize == 1492)) {
476                                 match = true;
477                                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  TX/RX aggregated best effort flowspec\n"));
478                         }
479                 } else if (ServiceType == BT_LL_GU) {
480                         if (SDUInterArrivatime == 100) {
481                                 match = true;
482                                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  TX/RX guaranteed bandwidth flowspec\n"));
483                         }
484                 }
485                 break;
486         default:
487                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Logical Link Type =  Unknow Type !!!!!!!!\n"));
488                 break;
489         }
490
491         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO),
492                 ("ID = 0x%x, ServiceType = 0x%x, MaximumSDUSize = 0x%x, SDUInterArrivalTime = 0x%x, AccessLatency = 0x%x, FlushTimeout = 0x%x\n",
493                 TxFlowSpec.Identifier, TxFlowSpec.ServiceType, MaxSDUSize,
494                 SDUInterArrivatime, TxFlowSpec.AccessLatency, TxFlowSpec.FlushTimeout));
495         return match;
496 }
497
498 static u16 bthci_AssocMACAddr(struct rtw_adapter *padapter, void        *pbuf)
499 {
500         struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf;
501         pAssoStrc->TypeID = AMP_MAC_ADDR;
502         pAssoStrc->Length = 0x06;
503         memcpy(&pAssoStrc->Data[0], padapter->eeprompriv.mac_addr, 6);
504         RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO),
505                      ("AssocMACAddr : \n"), pAssoStrc, pAssoStrc->Length+3);
506
507         return pAssoStrc->Length + 3;
508 }
509
510 static u16
511 bthci_PALCapabilities(
512         struct rtw_adapter *padapter,
513         void    *pbuf
514         )
515 {
516         struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf;
517
518         pAssoStrc->TypeID = AMP_80211_PAL_CAP_LIST;
519         pAssoStrc->Length = 0x04;
520
521         pAssoStrc->Data[0] = 0x00;
522         pAssoStrc->Data[1] = 0x00;
523
524         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("PALCapabilities:\n"), pAssoStrc, pAssoStrc->Length+3);
525         RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("PALCapabilities \n"));
526
527         RTPRINT(FIOCTL, IOCTL_BT_LOGO, (" TypeID = 0x%x,\n Length = 0x%x,\n Content = 0x0000\n",
528                 pAssoStrc->TypeID,
529                 pAssoStrc->Length));
530
531         return pAssoStrc->Length + 3;
532 }
533
534 static u16 bthci_AssocPreferredChannelList(struct rtw_adapter *padapter,
535                                            void *pbuf, u8 EntryNum)
536 {
537         struct bt_30info *pBTInfo;
538         struct amp_assoc_structure *pAssoStrc;
539         struct amp_pref_chnl_regulatory *pReg;
540         struct chnl_txpower_triple *pTriple;
541         char ctrString[3] = {'X', 'X', 'X'};
542         u32 len = 0;
543         u8 preferredChnl;
544
545         pBTInfo = GET_BT_INFO(padapter);
546         pAssoStrc = (struct amp_assoc_structure *)pbuf;
547         pReg = (struct amp_pref_chnl_regulatory *)&pAssoStrc->Data[3];
548
549         preferredChnl = bthci_GetLocalChannel(padapter);
550         pAssoStrc->TypeID = AMP_PREFERRED_CHANNEL_LIST;
551
552         /*  locale unknown */
553         memcpy(&pAssoStrc->Data[0], &ctrString[0], 3);
554         pReg->reXId = 201;
555         pReg->regulatoryClass = 254;
556         pReg->coverageClass = 0;
557         len += 6;
558         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("PREFERRED_CHNL_LIST\n"));
559         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("XXX, 201, 254, 0\n"));
560         /*  at the following, chnl 1~11 should be contained */
561         pTriple = (struct chnl_txpower_triple *)&pAssoStrc->Data[len];
562
563         /*  (1) if any wifi or bt HS connection exists */
564         if ((pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_CREATOR) ||
565             (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE |
566                            WIFI_ADHOC_STATE | WIFI_ADHOC_MASTER_STATE |
567                            WIFI_AP_STATE)) ||
568             BTHCI_HsConnectionEstablished(padapter)) {
569                 pTriple->FirstChnl = preferredChnl;
570                 pTriple->NumChnls = 1;
571                 pTriple->MaxTxPowerInDbm = 20;
572                 len += 3;
573                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD | IOCTL_BT_LOGO), ("First Channel = %d, Channel Num = %d, MaxDbm = %d\n",
574                         pTriple->FirstChnl,
575                         pTriple->NumChnls,
576                         pTriple->MaxTxPowerInDbm));
577         }
578
579         pAssoStrc->Length = (u16)len;
580         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD, ("AssocPreferredChannelList : \n"), pAssoStrc, pAssoStrc->Length+3);
581
582         return pAssoStrc->Length + 3;
583 }
584
585 static u16 bthci_AssocPALVer(struct rtw_adapter *padapter, void *pbuf)
586 {
587         struct amp_assoc_structure *pAssoStrc = (struct amp_assoc_structure *)pbuf;
588         u8 *pu1Tmp;
589         u16     *pu2Tmp;
590
591         pAssoStrc->TypeID = AMP_80211_PAL_VISION;
592         pAssoStrc->Length = 0x5;
593         pu1Tmp = &pAssoStrc->Data[0];
594         *pu1Tmp = 0x1;  /*  PAL Version */
595         pu2Tmp = (u16 *)&pAssoStrc->Data[1];
596         *pu2Tmp = 0x5D; /*  SIG Company identifier of 802.11 PAL vendor */
597         pu2Tmp = (u16 *)&pAssoStrc->Data[3];
598         *pu2Tmp = 0x1;  /*  PAL Sub-version specifier */
599
600         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("AssocPALVer : \n"), pAssoStrc, pAssoStrc->Length+3);
601         RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("AssocPALVer \n"));
602
603         RTPRINT(FIOCTL, IOCTL_BT_LOGO, (" TypeID = 0x%x,\n Length = 0x%x,\n PAL Version = 0x01,\n PAL vendor = 0x01,\n PAL Sub-version specifier = 0x01\n",
604                 pAssoStrc->TypeID,
605                 pAssoStrc->Length));
606         return pAssoStrc->Length + 3;
607 }
608
609 static u8 bthci_CheckRfStateBeforeConnect(struct rtw_adapter *padapter)
610 {
611         struct bt_30info *pBTInfo;
612         enum rt_rf_power_state          RfState;
613
614         pBTInfo = GET_BT_INFO(padapter);
615
616         RfState = padapter->pwrctrlpriv.rf_pwrstate;
617
618         if (RfState != rf_on) {
619                 mod_timer(&pBTInfo->BTPsDisableTimer,
620                           jiffies + msecs_to_jiffies(50));
621                 return false;
622         }
623         return true;
624 }
625
626 static void bthci_ResponderStartToScan(struct rtw_adapter *padapter)
627 {
628 }
629
630 static u8 bthci_PhyLinkConnectionInProgress(struct rtw_adapter *padapter, u8 PhyLinkHandle)
631 {
632         struct bt_30info *pBTInfo;
633         struct bt_mgnt *pBtMgnt;
634
635         pBTInfo = GET_BT_INFO(padapter);
636         pBtMgnt = &pBTInfo->BtMgnt;
637
638         if (pBtMgnt->bPhyLinkInProgress &&
639                 (pBtMgnt->BtCurrentPhyLinkhandle == PhyLinkHandle))
640                 return true;
641         return false;
642 }
643
644 static void bthci_ResetFlowSpec(struct rtw_adapter *padapter, u8 EntryNum, u8 index)
645 {
646         struct bt_30info *pBTinfo;
647
648         pBTinfo = GET_BT_INFO(padapter);
649
650         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtLogLinkhandle = 0;
651         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtPhyLinkhandle = 0;
652         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].bLLCompleteEventIsSet = false;
653         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].bLLCancelCMDIsSetandComplete = false;
654         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].BtTxFlowSpecID = 0;
655         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].TxPacketCount = 0;
656
657         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.Identifier = 0x01;
658         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.ServiceType = SERVICE_BEST_EFFORT;
659         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.MaximumSDUSize = 0xffff;
660         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.SDUInterArrivalTime = 0xffffffff;
661         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.AccessLatency = 0xffffffff;
662         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Tx_Flow_Spec.FlushTimeout = 0xffffffff;
663
664         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.Identifier = 0x01;
665         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.ServiceType = SERVICE_BEST_EFFORT;
666         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.MaximumSDUSize = 0xffff;
667         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.SDUInterArrivalTime = 0xffffffff;
668         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.AccessLatency = 0xffffffff;
669         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[index].Rx_Flow_Spec.FlushTimeout = 0xffffffff;
670 }
671
672 static void bthci_ResetEntry(struct rtw_adapter *padapter, u8 EntryNum)
673 {
674         struct bt_30info *pBTinfo;
675         struct bt_mgnt *pBtMgnt;
676         u8 j;
677
678         pBTinfo = GET_BT_INFO(padapter);
679         pBtMgnt = &pBTinfo->BtMgnt;
680
681         pBTinfo->BtAsocEntry[EntryNum].bUsed = false;
682         pBTinfo->BtAsocEntry[EntryNum].BtCurrentState = HCI_STATE_DISCONNECTED;
683         pBTinfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED;
684
685         pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocRemLen = 0;
686         pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.BtPhyLinkhandle = 0;
687         if (pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment != NULL)
688                 memset(pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment, 0, TOTAL_ALLOCIATE_ASSOC_LEN);
689         pBTinfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar = 0;
690
691         pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType = 0;
692         pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle = 0;
693         memset(pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, 0,
694                pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen);
695         pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen = 0;
696
697         /* 0x640; 0.625ms*1600 = 1000ms, 0.625ms*16000 = 10000ms */
698         pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout = 0x3e80;
699
700         pBTinfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_NONE;
701
702         pBTinfo->BtAsocEntry[EntryNum].mAssoc = false;
703         pBTinfo->BtAsocEntry[EntryNum].b4waySuccess = false;
704
705         /*  Reset BT WPA */
706         pBTinfo->BtAsocEntry[EntryNum].KeyReplayCounter = 0;
707         pBTinfo->BtAsocEntry[EntryNum].BTWPAAuthState = STATE_WPA_AUTH_UNINITIALIZED;
708
709         pBTinfo->BtAsocEntry[EntryNum].bSendSupervisionPacket = false;
710         pBTinfo->BtAsocEntry[EntryNum].NoRxPktCnt = 0;
711         pBTinfo->BtAsocEntry[EntryNum].ShortRangeMode = 0;
712         pBTinfo->BtAsocEntry[EntryNum].rxSuvpPktCnt = 0;
713
714         for (j = 0; j < MAX_LOGICAL_LINK_NUM; j++)
715                 bthci_ResetFlowSpec(padapter, EntryNum, j);
716
717         pBtMgnt->BTAuthCount = 0;
718         pBtMgnt->BTAsocCount = 0;
719         pBtMgnt->BTCurrentConnectType = BT_DISCONNECT;
720         pBtMgnt->BTReceiveConnectPkt = BT_DISCONNECT;
721
722         HALBT_RemoveKey(padapter, EntryNum);
723 }
724
725 static void bthci_RemoveEntryByEntryNum(struct rtw_adapter *padapter, u8 EntryNum)
726 {
727         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
728         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
729
730         bthci_ResetEntry(padapter, EntryNum);
731
732         if (pBtMgnt->CurrentBTConnectionCnt > 0)
733                 pBtMgnt->CurrentBTConnectionCnt--;
734
735         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], CurrentBTConnectionCnt = %d!!\n",
736                 pBtMgnt->CurrentBTConnectionCnt));
737
738         if (pBtMgnt->CurrentBTConnectionCnt > 0) {
739                 pBtMgnt->BtOperationOn = true;
740         } else {
741                 pBtMgnt->BtOperationOn = false;
742                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], Bt Operation OFF!!\n"));
743         }
744
745         if (!pBtMgnt->BtOperationOn) {
746                 del_timer_sync(&pBTInfo->BTHCIDiscardAclDataTimer);
747                 del_timer_sync(&pBTInfo->BTBeaconTimer);
748                 pBtMgnt->bStartSendSupervisionPkt = false;
749         }
750 }
751
752 static u8
753 bthci_CommandCompleteHeader(
754         u8 *pbuf,
755         u16             OGF,
756         u16             OCF,
757         enum hci_status status
758         )
759 {
760         struct packet_irp_hcievent_data *PPacketIrpEvent = (struct packet_irp_hcievent_data *)pbuf;
761         u8 NumHCI_Comm = 0x1;
762
763         PPacketIrpEvent->EventCode = HCI_EVENT_COMMAND_COMPLETE;
764         PPacketIrpEvent->Data[0] = NumHCI_Comm; /* packet # */
765         PPacketIrpEvent->Data[1] = HCIOPCODELOW(OCF, OGF);
766         PPacketIrpEvent->Data[2] = HCIOPCODEHIGHT(OCF, OGF);
767
768         if (OGF == OGF_EXTENSION) {
769                 if (OCF == HCI_SET_RSSI_VALUE) {
770                         RTPRINT(FIOCTL, (IOCTL_BT_EVENT_PERIODICAL),
771                                 ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n",
772                                 NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF));
773                 } else {
774                         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_EXT),
775                                 ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n",
776                                 NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF));
777                 }
778         } else {
779                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO),
780                         ("[BT event], CommandComplete, Num_HCI_Comm = 0x%x, Opcode = 0x%02x%02x, status = 0x%x, OGF = 0x%x, OCF = 0x%x\n",
781                         NumHCI_Comm, (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), status, OGF, OCF));
782         }
783         return 3;
784 }
785
786 static u8 bthci_ExtensionEventHeaderRtk(u8 *pbuf, u8 extensionEvent)
787 {
788         struct packet_irp_hcievent_data *PPacketIrpEvent = (struct packet_irp_hcievent_data *)pbuf;
789         PPacketIrpEvent->EventCode = HCI_EVENT_EXTENSION_RTK;
790         PPacketIrpEvent->Data[0] = extensionEvent;      /* extension event code */
791
792         return 1;
793 }
794
795 static enum rt_status
796 bthci_IndicateEvent(
797         struct rtw_adapter *padapter,
798         void            *pEvntData,
799         u32             dataLen
800         )
801 {
802         enum rt_status  rt_status;
803
804         rt_status = PlatformIndicateBTEvent(padapter, pEvntData, dataLen);
805
806         return rt_status;
807 }
808
809 static void
810 bthci_EventWriteRemoteAmpAssoc(
811         struct rtw_adapter *padapter,
812         enum hci_status status,
813         u8 PLHandle
814         )
815 {
816         u8 localBuf[TmpLocalBufSize] = "";
817         u8 *pRetPar;
818         u8 len = 0;
819         struct packet_irp_hcievent_data *PPacketIrpEvent;
820
821         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
822         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
823
824         len += bthci_CommandCompleteHeader(&localBuf[0],
825                 OGF_STATUS_PARAMETERS,
826                 HCI_WRITE_REMOTE_AMP_ASSOC,
827                 status);
828         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("PhyLinkHandle = 0x%x, status = %d\n", PLHandle, status));
829         /*  Return parameters starts from here */
830         pRetPar = &PPacketIrpEvent->Data[len];
831         pRetPar[0] = status;            /* status */
832         pRetPar[1] = PLHandle;
833         len += 2;
834         PPacketIrpEvent->Length = len;
835
836         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
837 }
838
839 static void
840 bthci_EventEnhancedFlushComplete(
841         struct rtw_adapter *padapter,
842         u16                                     LLH
843         )
844 {
845         u8 localBuf[4] = "";
846         struct packet_irp_hcievent_data *PPacketIrpEvent;
847
848         RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("EventEnhancedFlushComplete, LLH = 0x%x\n", LLH));
849
850         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
851         PPacketIrpEvent->EventCode = HCI_EVENT_ENHANCED_FLUSH_COMPLETE;
852         PPacketIrpEvent->Length = 2;
853         /* Logical link handle */
854         PPacketIrpEvent->Data[0] = TWOBYTE_LOWBYTE(LLH);
855         PPacketIrpEvent->Data[1] = TWOBYTE_HIGHTBYTE(LLH);
856
857         bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
858 }
859
860 static void
861 bthci_EventShortRangeModeChangeComplete(
862         struct rtw_adapter *padapter,
863         enum hci_status                         HciStatus,
864         u8              ShortRangeState,
865         u8              EntryNum
866         )
867 {
868         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
869         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
870         u8 localBuf[5] = "";
871         struct packet_irp_hcievent_data *PPacketIrpEvent;
872
873         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE)) {
874                 RTPRINT(FIOCTL, IOCTL_BT_EVENT,
875                         ("[BT event], Short Range Mode Change Complete, Ignore to send this event due to event mask page 2\n"));
876                 return;
877         }
878         RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Short Range Mode Change Complete, Status = %d\n , PLH = 0x%x\n, Short_Range_Mode_State = 0x%x\n",
879                 HciStatus, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, ShortRangeState));
880
881         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
882         PPacketIrpEvent->EventCode = HCI_EVENT_SHORT_RANGE_MODE_CHANGE_COMPLETE;
883         PPacketIrpEvent->Length = 3;
884         PPacketIrpEvent->Data[0] = HciStatus;
885         PPacketIrpEvent->Data[1] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
886         PPacketIrpEvent->Data[2] = ShortRangeState;
887         bthci_IndicateEvent(padapter, PPacketIrpEvent, 5);
888 }
889
890 static void bthci_EventSendFlowSpecModifyComplete(struct rtw_adapter *padapter,
891                                                   enum hci_status HciStatus,
892                                                   u16 logicHandle)
893 {
894         u8 localBuf[5] = "";
895         struct packet_irp_hcievent_data *PPacketIrpEvent;
896         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
897         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
898
899         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE)) {
900                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO),
901                         ("[BT event], Flow Spec Modify Complete, Ignore to send this event due to event mask page 2\n"));
902                 return;
903         }
904         RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO),
905                 ("[BT event], Flow Spec Modify Complete, status = 0x%x, LLH = 0x%x\n", HciStatus, logicHandle));
906         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
907         PPacketIrpEvent->EventCode = HCI_EVENT_FLOW_SPEC_MODIFY_COMPLETE;
908         PPacketIrpEvent->Length = 3;
909
910         PPacketIrpEvent->Data[0] = HciStatus;
911         /* Logical link handle */
912         PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(logicHandle);
913         PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(logicHandle);
914
915         bthci_IndicateEvent(padapter, PPacketIrpEvent, 5);
916 }
917
918 static void
919 bthci_EventExtWifiScanNotify(
920         struct rtw_adapter *padapter,
921         u8                      scanType
922         )
923 {
924         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
925         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
926         u8 len = 0;
927         u8 localBuf[7] = "";
928         u8 *pRetPar;
929         u8 *pu1Temp;
930         struct packet_irp_hcievent_data *PPacketIrpEvent;
931
932         if (!pBtMgnt->BtOperationOn)
933                 return;
934
935         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
936
937         len += bthci_ExtensionEventHeaderRtk(&localBuf[0], HCI_EVENT_EXT_WIFI_SCAN_NOTIFY);
938
939         /*  Return parameters starts from here */
940         pRetPar = &PPacketIrpEvent->Data[len];
941         pu1Temp = (u8 *)&pRetPar[0];
942         *pu1Temp = scanType;
943         len += 1;
944
945         PPacketIrpEvent->Length = len;
946
947         if (bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2) == RT_STATUS_SUCCESS) {
948                 RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Wifi scan notify, scan type = %d\n",
949                         scanType));
950         }
951 }
952
953 static void
954 bthci_EventAMPReceiverReport(
955         struct rtw_adapter *padapter,
956         u8 Reason
957         )
958 {
959         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
960         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
961
962         if (pBtHciInfo->bTestNeedReport) {
963                 u8 localBuf[20] = "";
964                 u32     *pu4Temp;
965                 u16     *pu2Temp;
966                 struct packet_irp_hcievent_data *PPacketIrpEvent;
967
968                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), (" HCI_EVENT_AMP_RECEIVER_REPORT\n"));
969                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
970                 PPacketIrpEvent->EventCode = HCI_EVENT_AMP_RECEIVER_REPORT;
971                 PPacketIrpEvent->Length = 2;
972
973                 PPacketIrpEvent->Data[0] = pBtHciInfo->TestCtrType;
974
975                 PPacketIrpEvent->Data[1] = Reason;
976
977                 pu4Temp = (u32 *)&PPacketIrpEvent->Data[2];
978                 *pu4Temp = pBtHciInfo->TestEventType;
979
980                 pu2Temp = (u16 *)&PPacketIrpEvent->Data[6];
981                 *pu2Temp = pBtHciInfo->TestNumOfFrame;
982
983                 pu2Temp = (u16 *)&PPacketIrpEvent->Data[8];
984                 *pu2Temp = pBtHciInfo->TestNumOfErrFrame;
985
986                 pu4Temp = (u32 *)&PPacketIrpEvent->Data[10];
987                 *pu4Temp = pBtHciInfo->TestNumOfBits;
988
989                 pu4Temp = (u32 *)&PPacketIrpEvent->Data[14];
990                 *pu4Temp = pBtHciInfo->TestNumOfErrBits;
991
992                 bthci_IndicateEvent(padapter, PPacketIrpEvent, 20);
993
994                 /* Return to Idel state with RX and TX off. */
995
996         }
997
998         pBtHciInfo->TestNumOfFrame = 0x00;
999 }
1000
1001 static void
1002 bthci_EventChannelSelected(
1003         struct rtw_adapter *padapter,
1004         u8      EntryNum
1005         )
1006 {
1007         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1008         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1009         u8 localBuf[3] = "";
1010         struct packet_irp_hcievent_data *PPacketIrpEvent;
1011
1012         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_CHANNEL_SELECT)) {
1013                 RTPRINT(FIOCTL, IOCTL_BT_EVENT,
1014                         ("[BT event], Channel Selected, Ignore to send this event due to event mask page 2\n"));
1015                 return;
1016         }
1017
1018         RTPRINT(FIOCTL, IOCTL_BT_EVENT|IOCTL_STATE,
1019                 ("[BT event], Channel Selected, PhyLinkHandle %d\n",
1020                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle));
1021
1022         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1023         PPacketIrpEvent->EventCode = HCI_EVENT_CHANNEL_SELECT;
1024         PPacketIrpEvent->Length = 1;
1025         PPacketIrpEvent->Data[0] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
1026         bthci_IndicateEvent(padapter, PPacketIrpEvent, 3);
1027 }
1028
1029 static void
1030 bthci_EventDisconnectPhyLinkComplete(
1031         struct rtw_adapter *padapter,
1032         enum hci_status                         HciStatus,
1033         enum hci_status                         Reason,
1034         u8              EntryNum
1035         )
1036 {
1037         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1038         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1039         u8 localBuf[5] = "";
1040         struct packet_irp_hcievent_data *PPacketIrpEvent;
1041
1042         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE)) {
1043                 RTPRINT(FIOCTL, IOCTL_BT_EVENT,
1044                         ("[BT event], Disconnect Physical Link Complete, Ignore to send this event due to event mask page 2\n"));
1045                 return;
1046         }
1047         RTPRINT(FIOCTL, IOCTL_BT_EVENT,
1048                 ("[BT event], Disconnect Physical Link Complete, Status = 0x%x, PLH = 0x%x Reason = 0x%x\n",
1049                 HciStatus, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle, Reason));
1050         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1051         PPacketIrpEvent->EventCode = HCI_EVENT_DISCONNECT_PHY_LINK_COMPLETE;
1052         PPacketIrpEvent->Length = 3;
1053         PPacketIrpEvent->Data[0] = HciStatus;
1054         PPacketIrpEvent->Data[1] = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
1055         PPacketIrpEvent->Data[2] = Reason;
1056         bthci_IndicateEvent(padapter, PPacketIrpEvent, 5);
1057 }
1058
1059 static void
1060 bthci_EventPhysicalLinkComplete(
1061         struct rtw_adapter *padapter,
1062         enum hci_status                         HciStatus,
1063         u8              EntryNum,
1064         u8              PLHandle
1065         )
1066 {
1067         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1068         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
1069         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1070         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
1071         u8 localBuf[4] = "";
1072         struct packet_irp_hcievent_data *PPacketIrpEvent;
1073         u8 PL_handle;
1074
1075         pBtMgnt->bPhyLinkInProgress = false;
1076         pBtDbg->dbgHciInfo.hciCmdPhyLinkStatus = HciStatus;
1077         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_PHY_LINK_COMPLETE)) {
1078                 RTPRINT(FIOCTL, IOCTL_BT_EVENT,
1079                         ("[BT event], Physical Link Complete, Ignore to send this event due to event mask page 2\n"));
1080                 return;
1081         }
1082
1083         if (EntryNum == 0xff) {
1084                 /*  connection not started yet, just use the input physical link handle to response. */
1085                 PL_handle = PLHandle;
1086         } else {
1087                 /*  connection is under progress, use the phy link handle we recorded. */
1088                 PL_handle  = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
1089                 pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent = false;
1090         }
1091
1092         RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Physical Link Complete, Status = 0x%x PhyLinkHandle = 0x%x\n", HciStatus,
1093                 PL_handle));
1094
1095         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1096         PPacketIrpEvent->EventCode = HCI_EVENT_PHY_LINK_COMPLETE;
1097         PPacketIrpEvent->Length = 2;
1098
1099         PPacketIrpEvent->Data[0] = HciStatus;
1100         PPacketIrpEvent->Data[1] = PL_handle;
1101         bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
1102
1103 }
1104
1105 static void
1106 bthci_EventCommandStatus(
1107         struct rtw_adapter *padapter,
1108         u8              OGF,
1109         u16                                     OCF,
1110         enum hci_status                         HciStatus
1111         )
1112 {
1113
1114         u8 localBuf[6] = "";
1115         struct packet_irp_hcievent_data *PPacketIrpEvent;
1116         u8 Num_Hci_Comm = 0x1;
1117         RTPRINT(FIOCTL, IOCTL_BT_EVENT,
1118                 ("[BT event], CommandStatus, Opcode = 0x%02x%02x, OGF = 0x%x,  OCF = 0x%x, Status = 0x%x, Num_HCI_COMM = 0x%x\n",
1119                 (HCIOPCODEHIGHT(OCF, OGF)), (HCIOPCODELOW(OCF, OGF)), OGF, OCF, HciStatus, Num_Hci_Comm));
1120
1121         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1122         PPacketIrpEvent->EventCode = HCI_EVENT_COMMAND_STATUS;
1123         PPacketIrpEvent->Length = 4;
1124         PPacketIrpEvent->Data[0] = HciStatus;   /* current pending */
1125         PPacketIrpEvent->Data[1] = Num_Hci_Comm;        /* packet # */
1126         PPacketIrpEvent->Data[2] = HCIOPCODELOW(OCF, OGF);
1127         PPacketIrpEvent->Data[3] = HCIOPCODEHIGHT(OCF, OGF);
1128
1129         bthci_IndicateEvent(padapter, PPacketIrpEvent, 6);
1130
1131 }
1132
1133 static void
1134 bthci_EventLogicalLinkComplete(
1135         struct rtw_adapter *padapter,
1136         enum hci_status                         HciStatus,
1137         u8              PhyLinkHandle,
1138         u16                                     LogLinkHandle,
1139         u8              LogLinkIndex,
1140         u8              EntryNum
1141         )
1142 {
1143 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
1144         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1145         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1146         u8 localBuf[7] = "";
1147         struct packet_irp_hcievent_data *PPacketIrpEvent;
1148
1149         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_LOGICAL_LINK_COMPLETE)) {
1150                 RTPRINT(FIOCTL, IOCTL_BT_EVENT,
1151                         ("[BT event], Logical Link Complete, Ignore to send this event due to event mask page 2\n"));
1152                 return;
1153         }
1154         RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Logical Link Complete, PhyLinkHandle = 0x%x,  LogLinkHandle = 0x%x, Status = 0x%x\n",
1155                 PhyLinkHandle, LogLinkHandle, HciStatus));
1156
1157         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1158         PPacketIrpEvent->EventCode = HCI_EVENT_LOGICAL_LINK_COMPLETE;
1159         PPacketIrpEvent->Length = 5;
1160
1161         PPacketIrpEvent->Data[0] = HciStatus;/* status code */
1162         /* Logical link handle */
1163         PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(LogLinkHandle);
1164         PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(LogLinkHandle);
1165         /* Physical link handle */
1166         PPacketIrpEvent->Data[3] = TWOBYTE_LOWBYTE(PhyLinkHandle);
1167         /* corresponding Tx flow spec ID */
1168         if (HciStatus == HCI_STATUS_SUCCESS) {
1169                 PPacketIrpEvent->Data[4] =
1170                         pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData[LogLinkIndex].Tx_Flow_Spec.Identifier;
1171         } else {
1172                 PPacketIrpEvent->Data[4] = 0x0;
1173         }
1174
1175         bthci_IndicateEvent(padapter, PPacketIrpEvent, 7);
1176 }
1177
1178 static void
1179 bthci_EventDisconnectLogicalLinkComplete(
1180         struct rtw_adapter *padapter,
1181         enum hci_status                         HciStatus,
1182         u16                                     LogLinkHandle,
1183         enum hci_status                         Reason
1184         )
1185 {
1186         u8 localBuf[6] = "";
1187         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1188         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1189         struct packet_irp_hcievent_data *PPacketIrpEvent;
1190
1191         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE)) {
1192                 RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Disconnect Logical Link Complete, Ignore to send this event due to event mask page 2\n"));
1193                 return;
1194         }
1195         RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Disconnect Logical Link Complete, Status = 0x%x, LLH = 0x%x Reason = 0x%x\n", HciStatus, LogLinkHandle, Reason));
1196
1197         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1198         PPacketIrpEvent->EventCode = HCI_EVENT_DISCONNECT_LOGICAL_LINK_COMPLETE;
1199         PPacketIrpEvent->Length = 4;
1200
1201         PPacketIrpEvent->Data[0] = HciStatus;
1202         /* Logical link handle */
1203         PPacketIrpEvent->Data[1] = TWOBYTE_LOWBYTE(LogLinkHandle);
1204         PPacketIrpEvent->Data[2] = TWOBYTE_HIGHTBYTE(LogLinkHandle);
1205         /* Disconnect reason */
1206         PPacketIrpEvent->Data[3] = Reason;
1207
1208         bthci_IndicateEvent(padapter, PPacketIrpEvent, 6);
1209 }
1210
1211 static void
1212 bthci_EventFlushOccurred(
1213         struct rtw_adapter *padapter,
1214         u16                                     LogLinkHandle
1215         )
1216 {
1217         u8 localBuf[4] = "";
1218         struct packet_irp_hcievent_data *PPacketIrpEvent;
1219         RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("bthci_EventFlushOccurred(), LLH = 0x%x\n", LogLinkHandle));
1220
1221         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1222         PPacketIrpEvent->EventCode = HCI_EVENT_FLUSH_OCCRUED;
1223         PPacketIrpEvent->Length = 2;
1224         /* Logical link handle */
1225         PPacketIrpEvent->Data[0] = TWOBYTE_LOWBYTE(LogLinkHandle);
1226         PPacketIrpEvent->Data[1] = TWOBYTE_HIGHTBYTE(LogLinkHandle);
1227
1228         bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
1229 }
1230
1231 static enum hci_status
1232 bthci_BuildPhysicalLink(
1233         struct rtw_adapter *padapter,
1234         struct packet_irp_hcicmd_data *pHciCmd,
1235         u16     OCF
1236 )
1237 {
1238         enum hci_status         status = HCI_STATUS_SUCCESS;
1239         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1240         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
1241         u8 EntryNum, PLH;
1242
1243         /* Send HCI Command status event to AMP. */
1244         bthci_EventCommandStatus(padapter,
1245                         LINK_CONTROL_COMMANDS,
1246                         OCF,
1247                         HCI_STATUS_SUCCESS);
1248
1249         PLH = *((u8 *)pHciCmd->Data);
1250
1251         /*  Check if resource or bt connection is under progress, if yes, reject the link creation. */
1252         if (!bthci_AddEntry(padapter)) {
1253                 status = HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE;
1254                 bthci_EventPhysicalLinkComplete(padapter, status, INVALID_ENTRY_NUM, PLH);
1255                 return status;
1256         }
1257
1258         EntryNum = pBtMgnt->CurrentConnectEntryNum;
1259         pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle = PLH;
1260         pBtMgnt->BtCurrentPhyLinkhandle = PLH;
1261
1262         if (pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.AMPAssocfragment == NULL) {
1263                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Create/Accept PhysicalLink, AMP controller is busy\n"));
1264                 status = HCI_STATUS_CONTROLLER_BUSY;
1265                 bthci_EventPhysicalLinkComplete(padapter, status, INVALID_ENTRY_NUM, PLH);
1266                 return status;
1267         }
1268
1269         /*  Record Key and the info */
1270         pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen = (*((u8 *)pHciCmd->Data+1));
1271         pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType = (*((u8 *)pHciCmd->Data+2));
1272         memcpy(pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey,
1273                 (((u8 *)pHciCmd->Data+3)), pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen);
1274         memcpy(pBTInfo->BtAsocEntry[EntryNum].PMK, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey, PMK_LEN);
1275         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("BuildPhysicalLink, EntryNum = %d, PLH = 0x%x  KeyLen = 0x%x, KeyType = 0x%x\n",
1276                 EntryNum, pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle,
1277                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen,
1278                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyType));
1279         RTPRINT_DATA(FIOCTL, (IOCTL_BT_LOGO|IOCTL_BT_HCICMD), ("BtAMPKey\n"), pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKey,
1280                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtAMPKeyLen);
1281         RTPRINT_DATA(FIOCTL, (IOCTL_BT_LOGO|IOCTL_BT_HCICMD), ("PMK\n"), pBTInfo->BtAsocEntry[EntryNum].PMK,
1282                 PMK_LEN);
1283
1284         if (OCF == HCI_CREATE_PHYSICAL_LINK) {
1285                 /* These macros require braces */
1286                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_CREATE_PHY_LINK, EntryNum);
1287         } else if (OCF == HCI_ACCEPT_PHYSICAL_LINK) {
1288                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ACCEPT_PHY_LINK, EntryNum);
1289         }
1290
1291         return status;
1292 }
1293
1294 static void
1295 bthci_BuildLogicalLink(
1296         struct rtw_adapter *padapter,
1297         struct packet_irp_hcicmd_data *pHciCmd,
1298         u16 OCF
1299         )
1300 {
1301         enum hci_status status = HCI_STATUS_SUCCESS;
1302         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
1303         struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt;
1304         u8 PhyLinkHandle, EntryNum;
1305         static u16 AssignLogHandle = 1;
1306
1307         struct hci_flow_spec    TxFlowSpec;
1308         struct hci_flow_spec    RxFlowSpec;
1309         u32     MaxSDUSize, ArriveTime, Bandwidth;
1310
1311         PhyLinkHandle = *((u8 *)pHciCmd->Data);
1312
1313         EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
1314
1315         memcpy(&TxFlowSpec,
1316                 &pHciCmd->Data[1], sizeof(struct hci_flow_spec));
1317         memcpy(&RxFlowSpec,
1318                 &pHciCmd->Data[17], sizeof(struct hci_flow_spec));
1319
1320         MaxSDUSize = TxFlowSpec.MaximumSDUSize;
1321         ArriveTime = TxFlowSpec.SDUInterArrivalTime;
1322
1323         if (bthci_CheckLogLinkBehavior(padapter, TxFlowSpec) && bthci_CheckLogLinkBehavior(padapter, RxFlowSpec))
1324                 Bandwidth = BTTOTALBANDWIDTH;
1325         else if (MaxSDUSize == 0xffff && ArriveTime == 0xffffffff)
1326                 Bandwidth = BTTOTALBANDWIDTH;
1327         else
1328                 Bandwidth = MaxSDUSize*8*1000/(ArriveTime+244);
1329
1330         RTPRINT(FIOCTL, IOCTL_BT_HCICMD,
1331                 ("BuildLogicalLink, PhyLinkHandle = 0x%x, MaximumSDUSize = 0x%x, SDUInterArrivalTime = 0x%x, Bandwidth = 0x%x\n",
1332                 PhyLinkHandle, MaxSDUSize, ArriveTime, Bandwidth));
1333
1334         if (EntryNum == 0xff) {
1335                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Invalid Physical Link handle = 0x%x, status = HCI_STATUS_UNKNOW_CONNECT_ID, return\n", PhyLinkHandle));
1336                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
1337
1338                 /* When we receive Create/Accept logical link command, we should send command status event first. */
1339                 bthci_EventCommandStatus(padapter,
1340                         LINK_CONTROL_COMMANDS,
1341                         OCF,
1342                         status);
1343                 return;
1344         }
1345
1346         if (!pBtMgnt->bLogLinkInProgress) {
1347                 if (bthci_PhyLinkConnectionInProgress(padapter, PhyLinkHandle)) {
1348                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Physical link connection in progress, status = HCI_STATUS_CMD_DISALLOW, return\n"));
1349                         status = HCI_STATUS_CMD_DISALLOW;
1350
1351                         pBtMgnt->bPhyLinkInProgressStartLL = true;
1352                         /* When we receive Create/Accept logical link command, we should send command status event first. */
1353                         bthci_EventCommandStatus(padapter,
1354                                 LINK_CONTROL_COMMANDS,
1355                                 OCF,
1356                                 status);
1357
1358                         return;
1359                 }
1360
1361                 if (Bandwidth > BTTOTALBANDWIDTH) {
1362                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("status = HCI_STATUS_QOS_REJECT, Bandwidth = 0x%x, return\n", Bandwidth));
1363                         status = HCI_STATUS_QOS_REJECT;
1364
1365                         /* When we receive Create/Accept logical link command, we should send command status event first. */
1366                         bthci_EventCommandStatus(padapter,
1367                                 LINK_CONTROL_COMMANDS,
1368                                 OCF,
1369                                 status);
1370                 } else {
1371                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("status = HCI_STATUS_SUCCESS\n"));
1372                         status = HCI_STATUS_SUCCESS;
1373
1374                         /* When we receive Create/Accept logical link command, we should send command status event first. */
1375                         bthci_EventCommandStatus(padapter,
1376                                 LINK_CONTROL_COMMANDS,
1377                                 OCF,
1378                                 status);
1379
1380                 }
1381
1382                 if (pBTinfo->BtAsocEntry[EntryNum].BtCurrentState != HCI_STATE_CONNECTED) {
1383                         bthci_EventLogicalLinkComplete(padapter,
1384                                 HCI_STATUS_CMD_DISALLOW, 0, 0, 0, EntryNum);
1385                 } else {
1386                         u8 i, find = 0;
1387
1388                         pBtMgnt->bLogLinkInProgress = true;
1389
1390                         /*  find an unused logical link index and copy the data */
1391                         for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
1392                                 if (pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle == 0) {
1393                                         enum hci_status LogCompEventstatus = HCI_STATUS_SUCCESS;
1394
1395                                         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtPhyLinkhandle = *((u8 *)pHciCmd->Data);
1396                                         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle = AssignLogHandle;
1397                                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("BuildLogicalLink, EntryNum = %d, physical link handle = 0x%x, logical link handle = 0x%x\n",
1398                                                 EntryNum, pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle,
1399                                                                   pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle));
1400                                         memcpy(&pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].Tx_Flow_Spec,
1401                                                 &TxFlowSpec, sizeof(struct hci_flow_spec));
1402                                         memcpy(&pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].Rx_Flow_Spec,
1403                                                 &RxFlowSpec, sizeof(struct hci_flow_spec));
1404
1405                                         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCompleteEventIsSet = false;
1406
1407                                         if (pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCancelCMDIsSetandComplete)
1408                                                 LogCompEventstatus = HCI_STATUS_UNKNOW_CONNECT_ID;
1409                                         bthci_EventLogicalLinkComplete(padapter,
1410                                                 LogCompEventstatus,
1411                                                 pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtPhyLinkhandle,
1412                                                 pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].BtLogLinkhandle, i, EntryNum);
1413
1414                                         pBTinfo->BtAsocEntry[EntryNum].LogLinkCmdData[i].bLLCompleteEventIsSet = true;
1415
1416                                         find = 1;
1417                                         pBtMgnt->BtCurrentLogLinkhandle = AssignLogHandle;
1418                                         AssignLogHandle++;
1419                                         break;
1420                                 }
1421                         }
1422
1423                         if (!find) {
1424                                 bthci_EventLogicalLinkComplete(padapter,
1425                                         HCI_STATUS_CONNECT_RJT_LIMIT_RESOURCE, 0, 0, 0, EntryNum);
1426                         }
1427                         pBtMgnt->bLogLinkInProgress = false;
1428                 }
1429         } else {
1430                 bthci_EventLogicalLinkComplete(padapter,
1431                         HCI_STATUS_CONTROLLER_BUSY, 0, 0, 0, EntryNum);
1432         }
1433
1434 }
1435
1436 static void
1437 bthci_StartBeaconAndConnect(
1438         struct rtw_adapter *padapter,
1439         struct packet_irp_hcicmd_data *pHciCmd,
1440         u8 CurrentAssocNum
1441         )
1442 {
1443 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
1444         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1445         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
1446
1447         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("StartBeaconAndConnect, CurrentAssocNum =%d, AMPRole =%d\n",
1448                 CurrentAssocNum,
1449                 pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole));
1450
1451         if (!pBtMgnt->CheckChnlIsSuit) {
1452                 bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_CONNECT_REJ_NOT_SUIT_CHNL_FOUND, CurrentAssocNum, INVALID_PL_HANDLE);
1453                 bthci_RemoveEntryByEntryNum(padapter, CurrentAssocNum);
1454                 return;
1455         }
1456
1457         if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_CREATOR) {
1458                 rsprintf((char *)pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 32, "AMP-%02x-%02x-%02x-%02x-%02x-%02x",
1459                 padapter->eeprompriv.mac_addr[0],
1460                 padapter->eeprompriv.mac_addr[1],
1461                 padapter->eeprompriv.mac_addr[2],
1462                 padapter->eeprompriv.mac_addr[3],
1463                 padapter->eeprompriv.mac_addr[4],
1464                 padapter->eeprompriv.mac_addr[5]);
1465         } else if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_JOINER) {
1466                 rsprintf((char *)pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 32, "AMP-%02x-%02x-%02x-%02x-%02x-%02x",
1467                 pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[0],
1468                 pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[1],
1469                 pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[2],
1470                 pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[3],
1471                 pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[4],
1472                 pBTInfo->BtAsocEntry[CurrentAssocNum].BTRemoteMACAddr[5]);
1473         }
1474
1475         FillOctetString(pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsid, pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsidBuf, 21);
1476         pBTInfo->BtAsocEntry[CurrentAssocNum].BTSsid.Length = 21;
1477
1478         /* To avoid set the start ap or connect twice, or the original connection will be disconnected. */
1479         if (!pBtMgnt->bBTConnectInProgress) {
1480                 pBtMgnt->bBTConnectInProgress = true;
1481                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress ON!!\n"));
1482                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_STARTING, STATE_CMD_MAC_START_COMPLETE, CurrentAssocNum);
1483
1484                 /*  20100325 Joseph: Check RF ON/OFF. */
1485                 /*  If RF OFF, it reschedule connecting operation after 50ms. */
1486                 if (!bthci_CheckRfStateBeforeConnect(padapter))
1487                         return;
1488
1489                 if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_CREATOR) {
1490                         /* These macros need braces */
1491                         BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTING, STATE_CMD_MAC_CONNECT_COMPLETE, CurrentAssocNum);
1492                 } else if (pBTInfo->BtAsocEntry[CurrentAssocNum].AMPRole == AMP_BTAP_JOINER) {
1493                         bthci_ResponderStartToScan(padapter);
1494                 }
1495         }
1496         RT_PRINT_STR(_module_rtl871x_mlme_c_, _drv_notice_,
1497                      "StartBeaconAndConnect, SSID:\n",
1498                      pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].BTSsid.Octet,
1499                      pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].BTSsid.Length);
1500 }
1501
1502 static void bthci_ResetBtMgnt(struct bt_mgnt *pBtMgnt)
1503 {
1504         pBtMgnt->BtOperationOn = false;
1505         pBtMgnt->bBTConnectInProgress = false;
1506         pBtMgnt->bLogLinkInProgress = false;
1507         pBtMgnt->bPhyLinkInProgress = false;
1508         pBtMgnt->bPhyLinkInProgressStartLL = false;
1509         pBtMgnt->DisconnectEntryNum = 0xff;
1510         pBtMgnt->bStartSendSupervisionPkt = false;
1511         pBtMgnt->JoinerNeedSendAuth = false;
1512         pBtMgnt->CurrentBTConnectionCnt = 0;
1513         pBtMgnt->BTCurrentConnectType = BT_DISCONNECT;
1514         pBtMgnt->BTReceiveConnectPkt = BT_DISCONNECT;
1515         pBtMgnt->BTAuthCount = 0;
1516         pBtMgnt->btLogoTest = 0;
1517 }
1518
1519 static void bthci_ResetBtHciInfo(struct bt_hci_info *pBtHciInfo)
1520 {
1521         pBtHciInfo->BTEventMask = 0;
1522         pBtHciInfo->BTEventMaskPage2 = 0;
1523         pBtHciInfo->ConnAcceptTimeout =  10000;
1524         pBtHciInfo->PageTimeout  =  0x30;
1525         pBtHciInfo->LocationDomainAware = 0x0;
1526         pBtHciInfo->LocationDomain = 0x5858;
1527         pBtHciInfo->LocationDomainOptions = 0x58;
1528         pBtHciInfo->LocationOptions = 0x0;
1529         pBtHciInfo->FlowControlMode = 0x1;      /*  0:Packet based data flow control mode(BR/EDR), 1: Data block based data flow control mode(AMP). */
1530
1531         pBtHciInfo->enFlush_LLH = 0;
1532         pBtHciInfo->FLTO_LLH = 0;
1533
1534         /* Test command only */
1535         pBtHciInfo->bTestIsEnd = true;
1536         pBtHciInfo->bInTestMode = false;
1537         pBtHciInfo->bTestNeedReport = false;
1538         pBtHciInfo->TestScenario = 0xff;
1539         pBtHciInfo->TestReportInterval = 0x01;
1540         pBtHciInfo->TestCtrType = 0x5d;
1541         pBtHciInfo->TestEventType = 0x00;
1542         pBtHciInfo->TestNumOfFrame = 0;
1543         pBtHciInfo->TestNumOfErrFrame = 0;
1544         pBtHciInfo->TestNumOfBits = 0;
1545         pBtHciInfo->TestNumOfErrBits = 0;
1546 }
1547
1548 static void bthci_ResetBtSec(struct rtw_adapter *padapter, struct bt_security *pBtSec)
1549 {
1550 /*PMGNT_INFO    pMgntInfo = &padapter->MgntInfo; */
1551
1552         /*  Set BT used HW or SW encrypt !! */
1553         if (GET_HAL_DATA(padapter)->bBTMode)
1554                 pBtSec->bUsedHwEncrypt = true;
1555         else
1556                 pBtSec->bUsedHwEncrypt = false;
1557         RT_TRACE(_module_rtl871x_security_c_, _drv_info_, ("%s: bUsedHwEncrypt =%d\n", __func__, pBtSec->bUsedHwEncrypt));
1558
1559         pBtSec->RSNIE.Octet = pBtSec->RSNIEBuf;
1560 }
1561
1562 static void bthci_ResetBtExtInfo(struct bt_mgnt *pBtMgnt)
1563 {
1564         u8 i;
1565
1566         for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
1567                 pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = 0;
1568                 pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = 0;
1569                 pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = 0;
1570                 pBtMgnt->ExtConfig.linkInfo[i].BTProfile = BT_PROFILE_NONE;
1571                 pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = BT_SPEC_2_1_EDR;
1572                 pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI = 0;
1573                 pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = BT_PROFILE_NONE;
1574                 pBtMgnt->ExtConfig.linkInfo[i].linkRole = BT_LINK_MASTER;
1575         }
1576
1577         pBtMgnt->ExtConfig.CurrentConnectHandle = 0;
1578         pBtMgnt->ExtConfig.CurrentIncomingTrafficMode = 0;
1579         pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode = 0;
1580         pBtMgnt->ExtConfig.MIN_BT_RSSI = 0;
1581         pBtMgnt->ExtConfig.NumberOfHandle = 0;
1582         pBtMgnt->ExtConfig.NumberOfSCO = 0;
1583         pBtMgnt->ExtConfig.CurrentBTStatus = 0;
1584         pBtMgnt->ExtConfig.HCIExtensionVer = 0;
1585
1586         pBtMgnt->ExtConfig.bManualControl = false;
1587         pBtMgnt->ExtConfig.bBTBusy = false;
1588         pBtMgnt->ExtConfig.bBTA2DPBusy = false;
1589 }
1590
1591 static enum hci_status bthci_CmdReset(struct rtw_adapter *_padapter, u8 bNeedSendEvent)
1592 {
1593         enum hci_status status = HCI_STATUS_SUCCESS;
1594         struct rtw_adapter *padapter;
1595 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
1596         struct bt_30info *pBTInfo;
1597         struct bt_mgnt *pBtMgnt;
1598         struct bt_hci_info *pBtHciInfo;
1599         struct bt_security *pBtSec;
1600         struct bt_dgb *pBtDbg;
1601         u8 i;
1602
1603         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_CmdReset()\n"));
1604
1605         padapter = GetDefaultAdapter(_padapter);
1606         pBTInfo = GET_BT_INFO(padapter);
1607         pBtMgnt = &pBTInfo->BtMgnt;
1608         pBtHciInfo = &pBTInfo->BtHciInfo;
1609         pBtSec = &pBTInfo->BtSec;
1610         pBtDbg = &pBTInfo->BtDbg;
1611
1612         pBTInfo->padapter = padapter;
1613
1614         for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++)
1615                 bthci_ResetEntry(padapter, i);
1616
1617         bthci_ResetBtMgnt(pBtMgnt);
1618         bthci_ResetBtHciInfo(pBtHciInfo);
1619         bthci_ResetBtSec(padapter, pBtSec);
1620
1621         pBtMgnt->BTChannel = BT_Default_Chnl;
1622         pBtMgnt->CheckChnlIsSuit = true;
1623
1624         pBTInfo->BTBeaconTmrOn = false;
1625
1626         pBtMgnt->bCreateSpportQos = true;
1627
1628         del_timer_sync(&pBTInfo->BTHCIDiscardAclDataTimer);
1629         del_timer_sync(&pBTInfo->BTBeaconTimer);
1630
1631         HALBT_SetRtsCtsNoLenLimit(padapter);
1632         /*  */
1633         /*  Maybe we need to take care Group != AES case !! */
1634         /*  now we Pairwise and Group all used AES !! */
1635
1636         bthci_ResetBtExtInfo(pBtMgnt);
1637
1638         /* send command complete event here when all data are received. */
1639         if (bNeedSendEvent) {
1640                 u8 localBuf[6] = "";
1641                 u8 *pRetPar;
1642                 u8 len = 0;
1643                 struct packet_irp_hcievent_data *PPacketIrpEvent;
1644
1645                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1646
1647                 len += bthci_CommandCompleteHeader(&localBuf[0],
1648                         OGF_SET_EVENT_MASK_COMMAND,
1649                         HCI_RESET,
1650                         status);
1651
1652                 /*  Return parameters starts from here */
1653                 pRetPar = &PPacketIrpEvent->Data[len];
1654                 pRetPar[0] = status;            /* status */
1655                 len += 1;
1656                 PPacketIrpEvent->Length = len;
1657
1658                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1659         }
1660
1661         return status;
1662 }
1663
1664 static enum hci_status
1665 bthci_CmdWriteRemoteAMPAssoc(
1666         struct rtw_adapter *padapter,
1667         struct packet_irp_hcicmd_data *pHciCmd
1668         )
1669 {
1670         enum hci_status status = HCI_STATUS_SUCCESS;
1671         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1672         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
1673         u8 CurrentAssocNum;
1674         u8 PhyLinkHandle;
1675
1676         pBtDbg->dbgHciInfo.hciCmdCntWriteRemoteAmpAssoc++;
1677         PhyLinkHandle = *((u8 *)pHciCmd->Data);
1678         CurrentAssocNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
1679
1680         if (CurrentAssocNum == 0xff) {
1681                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, No such Handle in the Entry\n"));
1682                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
1683                 bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle);
1684                 return status;
1685         }
1686
1687         if (pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment == NULL) {
1688                 RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, AMP controller is busy\n"));
1689                 status = HCI_STATUS_CONTROLLER_BUSY;
1690                 bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle);
1691                 return status;
1692         }
1693
1694         pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.BtPhyLinkhandle = PhyLinkHandle;/* u8 *)pHciCmd->Data); */
1695         pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar = *((u16 *)((u8 *)pHciCmd->Data+1));
1696         pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen = *((u16 *)((u8 *)pHciCmd->Data+3));
1697
1698         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("WriteRemoteAMPAssoc, LenSoFar = 0x%x, AssocRemLen = 0x%x\n",
1699                 pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar,
1700                 pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen));
1701
1702         RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO),
1703                      ("WriteRemoteAMPAssoc fragment \n"),
1704                      pHciCmd->Data,
1705                      pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen+5);
1706         if ((pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen) > MAX_AMP_ASSOC_FRAG_LEN) {
1707                 memcpy(((u8 *)pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment+(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar*(sizeof(u8)))),
1708                         (u8 *)pHciCmd->Data+5,
1709                         MAX_AMP_ASSOC_FRAG_LEN);
1710         } else {
1711                 memcpy((u8 *)(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocfragment)+(pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.LenSoFar*(sizeof(u8))),
1712                         ((u8 *)pHciCmd->Data+5),
1713                         (pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen));
1714
1715                 RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), "WriteRemoteAMPAssoc :\n",
1716                         pHciCmd->Data+5, pBTInfo->BtAsocEntry[CurrentAssocNum].AmpAsocCmdData.AMPAssocRemLen);
1717
1718                 if (!bthci_GetAssocInfo(padapter, CurrentAssocNum))
1719                         status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
1720
1721                 bthci_EventWriteRemoteAmpAssoc(padapter, status, PhyLinkHandle);
1722
1723                 bthci_StartBeaconAndConnect(padapter, pHciCmd, CurrentAssocNum);
1724         }
1725
1726         return status;
1727 }
1728
1729 /* 7.3.13 */
1730 static enum hci_status bthci_CmdReadConnectionAcceptTimeout(struct rtw_adapter *padapter)
1731 {
1732         enum hci_status         status = HCI_STATUS_SUCCESS;
1733 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
1734         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1735         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1736         u8 localBuf[8] = "";
1737         u8 *pRetPar;
1738         u8 len = 0;
1739         struct packet_irp_hcievent_data *PPacketIrpEvent;
1740         u16 *pu2Temp;
1741
1742         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1743
1744         len += bthci_CommandCompleteHeader(&localBuf[0],
1745                 OGF_SET_EVENT_MASK_COMMAND,
1746                 HCI_READ_CONNECTION_ACCEPT_TIMEOUT,
1747                 status);
1748
1749         /*  Return parameters starts from here */
1750         pRetPar = &PPacketIrpEvent->Data[len];
1751         pRetPar[0] = status;            /* status */
1752         pu2Temp = (u16 *)&pRetPar[1];           /*  Conn_Accept_Timeout */
1753         *pu2Temp = pBtHciInfo->ConnAcceptTimeout;
1754         len += 3;
1755         PPacketIrpEvent->Length = len;
1756
1757         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1758
1759         return status;
1760 }
1761
1762 /* 7.3.14 */
1763 static enum hci_status
1764 bthci_CmdWriteConnectionAcceptTimeout(
1765         struct rtw_adapter *padapter,
1766         struct packet_irp_hcicmd_data *pHciCmd
1767         )
1768 {
1769         enum hci_status         status = HCI_STATUS_SUCCESS;
1770         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1771         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1772         u16     *pu2Temp;
1773         u8 localBuf[6] = "";
1774         u8 *pRetPar;
1775         u8 len = 0;
1776         struct packet_irp_hcievent_data *PPacketIrpEvent;
1777
1778         pu2Temp = (u16 *)&pHciCmd->Data[0];
1779         pBtHciInfo->ConnAcceptTimeout = *pu2Temp;
1780         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("ConnAcceptTimeout = 0x%x",
1781                 pBtHciInfo->ConnAcceptTimeout));
1782
1783         /* send command complete event here when all data are received. */
1784         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1785
1786         len += bthci_CommandCompleteHeader(&localBuf[0],
1787                 OGF_SET_EVENT_MASK_COMMAND,
1788                 HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT,
1789                 status);
1790
1791         /*  Return parameters starts from here */
1792         pRetPar = &PPacketIrpEvent->Data[len];
1793         pRetPar[0] = status;            /* status */
1794         len += 1;
1795         PPacketIrpEvent->Length = len;
1796
1797         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1798
1799         return status;
1800 }
1801
1802 static enum hci_status
1803 bthci_CmdReadPageTimeout(
1804         struct rtw_adapter *padapter,
1805         struct packet_irp_hcicmd_data *pHciCmd
1806         )
1807 {
1808         enum hci_status         status = HCI_STATUS_SUCCESS;
1809         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1810         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1811         u8 localBuf[8] = "";
1812         u8 *pRetPar;
1813         u8 len = 0;
1814         struct packet_irp_hcievent_data *PPacketIrpEvent;
1815         u16 *pu2Temp;
1816
1817         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1818
1819         len += bthci_CommandCompleteHeader(&localBuf[0],
1820                 OGF_SET_EVENT_MASK_COMMAND,
1821                 HCI_READ_PAGE_TIMEOUT,
1822                 status);
1823
1824         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Read PageTimeout = 0x%x\n", pBtHciInfo->PageTimeout));
1825         /*  Return parameters starts from here */
1826         pRetPar = &PPacketIrpEvent->Data[len];
1827         pRetPar[0] = status;            /* status */
1828         pu2Temp = (u16 *)&pRetPar[1];           /*  Page_Timeout */
1829         *pu2Temp = pBtHciInfo->PageTimeout;
1830         len += 3;
1831         PPacketIrpEvent->Length = len;
1832
1833         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1834
1835         return status;
1836 }
1837
1838 static enum hci_status
1839 bthci_CmdWritePageTimeout(
1840         struct rtw_adapter *padapter,
1841         struct packet_irp_hcicmd_data *pHciCmd
1842         )
1843 {
1844         enum hci_status         status = HCI_STATUS_SUCCESS;
1845         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
1846         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
1847         u16     *pu2Temp;
1848
1849         pu2Temp = (u16 *)&pHciCmd->Data[0];
1850         pBtHciInfo->PageTimeout = *pu2Temp;
1851         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Write PageTimeout = 0x%x\n",
1852                 pBtHciInfo->PageTimeout));
1853
1854         /* send command complete event here when all data are received. */
1855         {
1856                 u8 localBuf[6] = "";
1857                 u8 *pRetPar;
1858                 u8 len = 0;
1859                 struct packet_irp_hcievent_data *PPacketIrpEvent;
1860
1861                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1862
1863                 len += bthci_CommandCompleteHeader(&localBuf[0],
1864                         OGF_SET_EVENT_MASK_COMMAND,
1865                         HCI_WRITE_PAGE_TIMEOUT,
1866                         status);
1867
1868                 /*  Return parameters starts from here */
1869                 pRetPar = &PPacketIrpEvent->Data[len];
1870                 pRetPar[0] = status;            /* status */
1871                 len += 1;
1872                 PPacketIrpEvent->Length = len;
1873
1874                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1875         }
1876
1877         return status;
1878 }
1879
1880 static enum hci_status
1881 bthci_CmdReadLinkSupervisionTimeout(
1882         struct rtw_adapter *padapter,
1883         struct packet_irp_hcicmd_data *pHciCmd
1884         )
1885 {
1886         enum hci_status status = HCI_STATUS_SUCCESS;
1887         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
1888         u8 physicalLinkHandle, EntryNum;
1889
1890         physicalLinkHandle = *((u8 *)pHciCmd->Data);
1891
1892         EntryNum = bthci_GetCurrentEntryNum(padapter, physicalLinkHandle);
1893
1894         if (EntryNum == 0xff) {
1895                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLinkSupervisionTimeout, No such Handle in the Entry\n"));
1896                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
1897                 return status;
1898         }
1899
1900         if (pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle != physicalLinkHandle)
1901                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
1902
1903         {
1904                 u8 localBuf[10] = "";
1905                 u8 *pRetPar;
1906                 u8 len = 0;
1907                 struct packet_irp_hcievent_data *PPacketIrpEvent;
1908                 u16 *pu2Temp;
1909
1910                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1911
1912                 len += bthci_CommandCompleteHeader(&localBuf[0],
1913                         OGF_SET_EVENT_MASK_COMMAND,
1914                         HCI_READ_LINK_SUPERVISION_TIMEOUT,
1915                         status);
1916
1917                 /*  Return parameters starts from here */
1918                 pRetPar = &PPacketIrpEvent->Data[len];
1919                 pRetPar[0] = status;
1920                 pRetPar[1] = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
1921                 pRetPar[2] = 0;
1922                 pu2Temp = (u16 *)&pRetPar[3];           /*  Conn_Accept_Timeout */
1923                 *pu2Temp = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout;
1924                 len += 5;
1925                 PPacketIrpEvent->Length = len;
1926
1927                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1928         }
1929
1930         return status;
1931 }
1932
1933 static enum hci_status
1934 bthci_CmdWriteLinkSupervisionTimeout(
1935         struct rtw_adapter *padapter,
1936         struct packet_irp_hcicmd_data *pHciCmd
1937         )
1938 {
1939         enum hci_status status = HCI_STATUS_SUCCESS;
1940         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
1941         u8 physicalLinkHandle, EntryNum;
1942
1943         physicalLinkHandle = *((u8 *)pHciCmd->Data);
1944
1945         EntryNum = bthci_GetCurrentEntryNum(padapter, physicalLinkHandle);
1946
1947         if (EntryNum == 0xff) {
1948                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("WriteLinkSupervisionTimeout, No such Handle in the Entry\n"));
1949                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
1950         } else {
1951                 if (pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle != physicalLinkHandle) {
1952                         status = HCI_STATUS_UNKNOW_CONNECT_ID;
1953                 } else {
1954                         pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout = *((u16 *)(((u8 *)pHciCmd->Data)+2));
1955                         RTPRINT(FIOCTL, IOCTL_STATE, ("BT Write LinkSuperversionTimeout[%d] = 0x%x\n",
1956                                 EntryNum, pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.LinkSuperversionTimeout));
1957                 }
1958         }
1959
1960         {
1961                 u8 localBuf[8] = "";
1962                 u8 *pRetPar;
1963                 u8 len = 0;
1964                 struct packet_irp_hcievent_data *PPacketIrpEvent;
1965
1966                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
1967
1968                 len += bthci_CommandCompleteHeader(&localBuf[0],
1969                         OGF_SET_EVENT_MASK_COMMAND,
1970                         HCI_WRITE_LINK_SUPERVISION_TIMEOUT,
1971                         status);
1972
1973                 /*  Return parameters starts from here */
1974                 pRetPar = &PPacketIrpEvent->Data[len];
1975                 pRetPar[0] = status;
1976                 pRetPar[1] = pBTinfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;
1977                 pRetPar[2] = 0;
1978                 len += 3;
1979                 PPacketIrpEvent->Length = len;
1980
1981                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
1982         }
1983
1984         return status;
1985 }
1986
1987 static enum hci_status
1988 bthci_CmdEnhancedFlush(
1989         struct rtw_adapter *padapter,
1990         struct packet_irp_hcicmd_data *pHciCmd
1991         )
1992 {
1993         enum hci_status         status = HCI_STATUS_SUCCESS;
1994         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
1995         struct bt_hci_info *pBtHciInfo = &pBTinfo->BtHciInfo;
1996         u16             logicHandle;
1997         u8 Packet_Type;
1998
1999         logicHandle = *((u16 *)&pHciCmd->Data[0]);
2000         Packet_Type = pHciCmd->Data[2];
2001
2002         if (Packet_Type != 0)
2003                 status = HCI_STATUS_INVALID_HCI_CMD_PARA_VALUE;
2004         else
2005                 pBtHciInfo->enFlush_LLH = logicHandle;
2006
2007         if (bthci_DiscardTxPackets(padapter, pBtHciInfo->enFlush_LLH))
2008                 bthci_EventFlushOccurred(padapter, pBtHciInfo->enFlush_LLH);
2009
2010         /*  should send command status event */
2011         bthci_EventCommandStatus(padapter,
2012                         OGF_SET_EVENT_MASK_COMMAND,
2013                         HCI_ENHANCED_FLUSH,
2014                         status);
2015
2016         if (pBtHciInfo->enFlush_LLH) {
2017                 bthci_EventEnhancedFlushComplete(padapter, pBtHciInfo->enFlush_LLH);
2018                 pBtHciInfo->enFlush_LLH = 0;
2019         }
2020
2021         return status;
2022 }
2023
2024 static enum hci_status
2025 bthci_CmdReadLogicalLinkAcceptTimeout(
2026         struct rtw_adapter *padapter,
2027         struct packet_irp_hcicmd_data *pHciCmd
2028         )
2029 {
2030         enum hci_status         status = HCI_STATUS_SUCCESS;
2031 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
2032         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2033         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2034         u8 localBuf[8] = "";
2035         u8 *pRetPar;
2036         u8 len = 0;
2037         struct packet_irp_hcievent_data *PPacketIrpEvent;
2038         u16 *pu2Temp;
2039
2040         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2041
2042         len += bthci_CommandCompleteHeader(&localBuf[0],
2043                 OGF_SET_EVENT_MASK_COMMAND,
2044                 HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT,
2045                 status);
2046
2047         /*  Return parameters starts from here */
2048         pRetPar = &PPacketIrpEvent->Data[len];
2049         pRetPar[0] = status;
2050
2051         pu2Temp = (u16 *)&pRetPar[1];           /*  Conn_Accept_Timeout */
2052         *pu2Temp = pBtHciInfo->LogicalAcceptTimeout;
2053         len += 3;
2054         PPacketIrpEvent->Length = len;
2055
2056         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2057
2058         return status;
2059 }
2060
2061 static enum hci_status
2062 bthci_CmdWriteLogicalLinkAcceptTimeout(
2063         struct rtw_adapter *padapter,
2064         struct packet_irp_hcicmd_data *pHciCmd
2065         )
2066 {
2067         enum hci_status         status = HCI_STATUS_SUCCESS;
2068 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
2069         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2070         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2071         u8 localBuf[6] = "";
2072         u8 *pRetPar;
2073         u8 len = 0;
2074         struct packet_irp_hcievent_data *PPacketIrpEvent;
2075
2076         pBtHciInfo->LogicalAcceptTimeout = *((u16 *)pHciCmd->Data);
2077
2078         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2079
2080         len += bthci_CommandCompleteHeader(&localBuf[0],
2081                 OGF_SET_EVENT_MASK_COMMAND,
2082                 HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT,
2083                 status);
2084
2085         /*  Return parameters starts from here */
2086         pRetPar = &PPacketIrpEvent->Data[len];
2087         pRetPar[0] = status;
2088
2089         len += 1;
2090         PPacketIrpEvent->Length = len;
2091
2092         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2093         return status;
2094 }
2095
2096 static enum hci_status
2097 bthci_CmdSetEventMask(
2098         struct rtw_adapter *padapter,
2099         struct packet_irp_hcicmd_data *pHciCmd
2100         )
2101 {
2102         enum hci_status         status = HCI_STATUS_SUCCESS;
2103 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
2104         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2105         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2106         u8 *pu8Temp;
2107         u8 localBuf[6] = "";
2108         u8 *pRetPar;
2109         u8 len = 0;
2110         struct packet_irp_hcievent_data *PPacketIrpEvent;
2111
2112         pu8Temp = (u8 *)&pHciCmd->Data[0];
2113         pBtHciInfo->BTEventMask = *pu8Temp;
2114         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("BTEventMask = 0x%"i64fmt"x\n",
2115                 pBtHciInfo->BTEventMask));
2116
2117         /* send command complete event here when all data are received. */
2118         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2119
2120         len += bthci_CommandCompleteHeader(&localBuf[0],
2121                 OGF_SET_EVENT_MASK_COMMAND,
2122                 HCI_SET_EVENT_MASK,
2123                 status);
2124
2125         /*  Return parameters starts from here */
2126         pRetPar = &PPacketIrpEvent->Data[len];
2127         pRetPar[0] = status;            /* status */
2128         len += 1;
2129         PPacketIrpEvent->Length = len;
2130
2131         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2132
2133         return status;
2134 }
2135
2136 /*  7.3.69 */
2137 static enum hci_status
2138 bthci_CmdSetEventMaskPage2(
2139         struct rtw_adapter *padapter,
2140         struct packet_irp_hcicmd_data *pHciCmd
2141         )
2142 {
2143         enum hci_status         status = HCI_STATUS_SUCCESS;
2144         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2145         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2146         u8 *pu8Temp;
2147         u8 localBuf[6] = "";
2148         u8 *pRetPar;
2149         u8 len = 0;
2150         struct packet_irp_hcievent_data *PPacketIrpEvent;
2151
2152         pu8Temp = (u8 *)&pHciCmd->Data[0];
2153         pBtHciInfo->BTEventMaskPage2 = *pu8Temp;
2154         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("BTEventMaskPage2 = 0x%"i64fmt"x\n",
2155                 pBtHciInfo->BTEventMaskPage2));
2156
2157         /* send command complete event here when all data are received. */
2158         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2159
2160         len += bthci_CommandCompleteHeader(&localBuf[0],
2161                 OGF_SET_EVENT_MASK_COMMAND,
2162                 HCI_SET_EVENT_MASK_PAGE_2,
2163                 status);
2164
2165         /*  Return parameters starts from here */
2166         pRetPar = &PPacketIrpEvent->Data[len];
2167         pRetPar[0] = status;            /* status */
2168         len += 1;
2169         PPacketIrpEvent->Length = len;
2170
2171         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2172
2173         return status;
2174 }
2175
2176 static enum hci_status
2177 bthci_CmdReadLocationData(
2178         struct rtw_adapter *padapter,
2179         struct packet_irp_hcicmd_data *pHciCmd
2180         )
2181 {
2182         enum hci_status         status = HCI_STATUS_SUCCESS;
2183         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2184         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2185         u8 localBuf[12] = "";
2186         u8 *pRetPar;
2187         u8 len = 0;
2188         struct packet_irp_hcievent_data *PPacketIrpEvent;
2189         u16 *pu2Temp;
2190
2191         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2192
2193         len += bthci_CommandCompleteHeader(&localBuf[0],
2194                 OGF_SET_EVENT_MASK_COMMAND,
2195                 HCI_READ_LOCATION_DATA,
2196                 status);
2197         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainAware = 0x%x\n", pBtHciInfo->LocationDomainAware));
2198         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Domain = 0x%x\n", pBtHciInfo->LocationDomain));
2199         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainOptions = 0x%x\n", pBtHciInfo->LocationDomainOptions));
2200         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Options = 0x%x\n", pBtHciInfo->LocationOptions));
2201
2202         /*  Return parameters starts from here */
2203         pRetPar = &PPacketIrpEvent->Data[len];
2204         pRetPar[0] = status;
2205
2206         pRetPar[1] = pBtHciInfo->LocationDomainAware;   /* 0x0;  Location_Domain_Aware */
2207         pu2Temp = (u16 *)&pRetPar[2];                                   /*  Location_Domain */
2208         *pu2Temp = pBtHciInfo->LocationDomain;          /* 0x5858; */
2209         pRetPar[4] = pBtHciInfo->LocationDomainOptions; /* 0x58;        Location_Domain_Options */
2210         pRetPar[5] = pBtHciInfo->LocationOptions;               /* 0x0; Location_Options */
2211         len += 6;
2212         PPacketIrpEvent->Length = len;
2213
2214         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2215         return status;
2216 }
2217
2218 static enum hci_status
2219 bthci_CmdWriteLocationData(
2220         struct rtw_adapter *padapter,
2221         struct packet_irp_hcicmd_data *pHciCmd
2222         )
2223 {
2224         enum hci_status status = HCI_STATUS_SUCCESS;
2225         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2226         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2227         u16     *pu2Temp;
2228         u8 localBuf[6] = "";
2229         u8 *pRetPar;
2230         u8 len = 0;
2231         struct packet_irp_hcievent_data *PPacketIrpEvent;
2232
2233         pBtHciInfo->LocationDomainAware = pHciCmd->Data[0];
2234         pu2Temp = (u16 *)&pHciCmd->Data[1];
2235         pBtHciInfo->LocationDomain = *pu2Temp;
2236         pBtHciInfo->LocationDomainOptions = pHciCmd->Data[3];
2237         pBtHciInfo->LocationOptions = pHciCmd->Data[4];
2238         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainAware = 0x%x\n", pBtHciInfo->LocationDomainAware));
2239         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Domain = 0x%x\n", pBtHciInfo->LocationDomain));
2240         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DomainOptions = 0x%x\n", pBtHciInfo->LocationDomainOptions));
2241         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Options = 0x%x\n", pBtHciInfo->LocationOptions));
2242
2243         /* send command complete event here when all data are received. */
2244         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2245
2246         len += bthci_CommandCompleteHeader(&localBuf[0],
2247                 OGF_SET_EVENT_MASK_COMMAND,
2248                 HCI_WRITE_LOCATION_DATA,
2249                 status);
2250
2251         /*  Return parameters starts from here */
2252         pRetPar = &PPacketIrpEvent->Data[len];
2253         pRetPar[0] = status;            /* status */
2254         len += 1;
2255         PPacketIrpEvent->Length = len;
2256
2257         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2258
2259         return status;
2260 }
2261
2262 static enum hci_status
2263 bthci_CmdReadFlowControlMode(
2264         struct rtw_adapter *padapter,
2265         struct packet_irp_hcicmd_data *pHciCmd
2266         )
2267 {
2268         enum hci_status status = HCI_STATUS_SUCCESS;
2269         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2270         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2271         u8 localBuf[7] = "";
2272         u8 *pRetPar;
2273         u8 len = 0;
2274         struct packet_irp_hcievent_data *PPacketIrpEvent;
2275
2276         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2277
2278         len += bthci_CommandCompleteHeader(&localBuf[0],
2279                 OGF_SET_EVENT_MASK_COMMAND,
2280                 HCI_READ_FLOW_CONTROL_MODE,
2281                 status);
2282
2283         /*  Return parameters starts from here */
2284         pRetPar = &PPacketIrpEvent->Data[len];
2285         pRetPar[0] = status;
2286         pRetPar[1] = pBtHciInfo->FlowControlMode;       /*  Flow Control Mode */
2287         len += 2;
2288         PPacketIrpEvent->Length = len;
2289
2290         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2291         return status;
2292 }
2293
2294 static enum hci_status
2295 bthci_CmdWriteFlowControlMode(
2296         struct rtw_adapter *padapter,
2297         struct packet_irp_hcicmd_data *pHciCmd
2298         )
2299 {
2300         enum hci_status status = HCI_STATUS_SUCCESS;
2301         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2302         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2303         u8 localBuf[6] = "";
2304         u8 *pRetPar;
2305         u8 len = 0;
2306         struct packet_irp_hcievent_data *PPacketIrpEvent;
2307
2308         pBtHciInfo->FlowControlMode = pHciCmd->Data[0];
2309
2310         /* send command complete event here when all data are received. */
2311         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2312
2313         len += bthci_CommandCompleteHeader(&localBuf[0],
2314                 OGF_SET_EVENT_MASK_COMMAND,
2315                 HCI_WRITE_FLOW_CONTROL_MODE,
2316                 status);
2317
2318         /*  Return parameters starts from here */
2319         pRetPar = &PPacketIrpEvent->Data[len];
2320         pRetPar[0] = status;            /* status */
2321         len += 1;
2322         PPacketIrpEvent->Length = len;
2323
2324         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2325
2326         return status;
2327 }
2328
2329 static enum hci_status
2330 bthci_CmdReadBestEffortFlushTimeout(
2331         struct rtw_adapter *padapter,
2332         struct packet_irp_hcicmd_data *pHciCmd
2333         )
2334 {
2335         enum hci_status status = HCI_STATUS_SUCCESS;
2336         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
2337         u16 i, j, logicHandle;
2338         u32 BestEffortFlushTimeout = 0xffffffff;
2339         u8 find = 0;
2340
2341         logicHandle = *((u16 *)pHciCmd->Data);
2342         /*  find an matched logical link index and copy the data */
2343         for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
2344                 for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
2345                         if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
2346                                 BestEffortFlushTimeout = pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BestEffortFlushTimeout;
2347                                 find = 1;
2348                                 break;
2349                         }
2350                 }
2351         }
2352
2353         if (!find)
2354                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
2355
2356         {
2357                 u8 localBuf[10] = "";
2358                 u8 *pRetPar;
2359                 u8 len = 0;
2360                 struct packet_irp_hcievent_data *PPacketIrpEvent;
2361                 u32 *pu4Temp;
2362
2363                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2364
2365                 len += bthci_CommandCompleteHeader(&localBuf[0],
2366                         OGF_SET_EVENT_MASK_COMMAND,
2367                         HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT,
2368                         status);
2369
2370                 /*  Return parameters starts from here */
2371                 pRetPar = &PPacketIrpEvent->Data[len];
2372                 pRetPar[0] = status;
2373                 pu4Temp = (u32 *)&pRetPar[1];   /*  Best_Effort_Flush_Timeout */
2374                 *pu4Temp = BestEffortFlushTimeout;
2375                 len += 5;
2376                 PPacketIrpEvent->Length = len;
2377
2378                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2379         }
2380         return status;
2381 }
2382
2383 static enum hci_status
2384 bthci_CmdWriteBestEffortFlushTimeout(
2385         struct rtw_adapter *padapter,
2386         struct packet_irp_hcicmd_data *pHciCmd
2387         )
2388 {
2389         enum hci_status status = HCI_STATUS_SUCCESS;
2390         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
2391         u16 i, j, logicHandle;
2392         u32 BestEffortFlushTimeout = 0xffffffff;
2393         u8 find = 0;
2394
2395         logicHandle = *((u16 *)pHciCmd->Data);
2396         BestEffortFlushTimeout = *((u32 *)(pHciCmd->Data+1));
2397
2398         /*  find an matched logical link index and copy the data */
2399         for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
2400                 for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
2401                         if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
2402                                 pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BestEffortFlushTimeout = BestEffortFlushTimeout;
2403                                 find = 1;
2404                                 break;
2405                         }
2406                 }
2407         }
2408
2409         if (!find)
2410                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
2411
2412         {
2413                 u8 localBuf[6] = "";
2414                 u8 *pRetPar;
2415                 u8 len = 0;
2416                 struct packet_irp_hcievent_data *PPacketIrpEvent;
2417
2418                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2419
2420                 len += bthci_CommandCompleteHeader(&localBuf[0],
2421                         OGF_SET_EVENT_MASK_COMMAND,
2422                         HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT,
2423                         status);
2424
2425                 /*  Return parameters starts from here */
2426                 pRetPar = &PPacketIrpEvent->Data[len];
2427                 pRetPar[0] = status;
2428                 len += 1;
2429                 PPacketIrpEvent->Length = len;
2430
2431                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2432         }
2433         return status;
2434 }
2435
2436 static enum hci_status
2437 bthci_CmdShortRangeMode(
2438         struct rtw_adapter *padapter,
2439         struct packet_irp_hcicmd_data *pHciCmd
2440         )
2441 {
2442         enum hci_status status = HCI_STATUS_SUCCESS;
2443         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2444         u8 PhyLinkHandle, EntryNum, ShortRangeMode;
2445
2446         PhyLinkHandle = pHciCmd->Data[0];
2447         ShortRangeMode = pHciCmd->Data[1];
2448         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PLH = 0x%x, Short_Range_Mode = 0x%x\n", PhyLinkHandle, ShortRangeMode));
2449
2450         EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
2451         if (EntryNum != 0xff) {
2452                 pBTInfo->BtAsocEntry[EntryNum].ShortRangeMode = ShortRangeMode;
2453         } else {
2454                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("No such PLH(0x%x)\n", PhyLinkHandle));
2455                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
2456         }
2457
2458         bthci_EventCommandStatus(padapter,
2459                         OGF_SET_EVENT_MASK_COMMAND,
2460                         HCI_SHORT_RANGE_MODE,
2461                         status);
2462
2463         bthci_EventShortRangeModeChangeComplete(padapter, status, ShortRangeMode, EntryNum);
2464
2465         return status;
2466 }
2467
2468 static enum hci_status bthci_CmdReadLocalSupportedCommands(struct rtw_adapter *padapter)
2469 {
2470         enum hci_status status = HCI_STATUS_SUCCESS;
2471         u8 localBuf[TmpLocalBufSize] = "";
2472         u8 *pRetPar, *pSupportedCmds;
2473         u8 len = 0;
2474         struct packet_irp_hcievent_data *PPacketIrpEvent;
2475
2476         /*  send command complete event here when all data are received. */
2477         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2478         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2479
2480         len += bthci_CommandCompleteHeader(&localBuf[0],
2481                 OGF_INFORMATIONAL_PARAMETERS,
2482                 HCI_READ_LOCAL_SUPPORTED_COMMANDS,
2483                 status);
2484
2485         /*  Return parameters starts from here */
2486         pRetPar = &PPacketIrpEvent->Data[len];
2487         pRetPar[0] = status;            /* status */
2488         len += 1;
2489         pSupportedCmds = &pRetPar[1];
2490         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[5]= 0xc0\nBit [6]= Set Event Mask, [7]= Reset\n"));
2491         pSupportedCmds[5] = 0xc0;
2492         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[6]= 0x01\nBit [0]= Set Event Filter\n"));
2493         pSupportedCmds[6] = 0x01;
2494         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[7]= 0x0c\nBit [2]= Read Connection Accept Timeout, [3]= Write Connection Accept Timeout\n"));
2495         pSupportedCmds[7] = 0x0c;
2496         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[10]= 0x80\nBit [7]= Host Number Of Completed Packets\n"));
2497         pSupportedCmds[10] = 0x80;
2498         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[11]= 0x03\nBit [0]= Read Link Supervision Timeout, [1]= Write Link Supervision Timeout\n"));
2499         pSupportedCmds[11] = 0x03;
2500         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[14]= 0xa8\nBit [3]= Read Local Version Information, [5]= Read Local Supported Features, [7]= Read Buffer Size\n"));
2501         pSupportedCmds[14] = 0xa8;
2502         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[15]= 0x1c\nBit [2]= Read Failed Contact Count, [3]= Reset Failed Contact Count, [4]= Get Link Quality\n"));
2503         pSupportedCmds[15] = 0x1c;
2504         /* pSupportedCmds[16] = 0x04; */
2505         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[19]= 0x40\nBit [6]= Enhanced Flush\n"));
2506         pSupportedCmds[19] = 0x40;
2507         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[21]= 0xff\nBit [0]= Create Physical Link, [1]= Accept Physical Link, [2]= Disconnect Physical Link, [3]= Create Logical Link\n"));
2508         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("     [4]= Accept Logical Link, [5]= Disconnect Logical Link, [6]= Logical Link Cancel, [7]= Flow Spec Modify\n"));
2509         pSupportedCmds[21] = 0xff;
2510         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[22]= 0xff\nBit [0]= Read Logical Link Accept Timeout, [1]= Write Logical Link Accept Timeout, [2]= Set Event Mask Page 2, [3]= Read Location Data\n"));
2511         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("     [4]= Write Location Data, [5]= Read Local AMP Info, [6]= Read Local AMP_ASSOC, [7]= Write Remote AMP_ASSOC\n"));
2512         pSupportedCmds[22] = 0xff;
2513         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[23]= 0x07\nBit [0]= Read Flow Control Mode, [1]= Write Flow Control Mode, [2]= Read Data Block Size\n"));
2514         pSupportedCmds[23] = 0x07;
2515         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD|IOCTL_BT_LOGO), ("Octet[24]= 0x1c\nBit [2]= Read Best Effort Flush Timeout, [3]= Write Best Effort Flush Timeout, [4]= Short Range Mode\n"));
2516         pSupportedCmds[24] = 0x1c;
2517         len += 64;
2518         PPacketIrpEvent->Length = len;
2519
2520         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2521
2522         return status;
2523 }
2524
2525 static enum hci_status bthci_CmdReadLocalSupportedFeatures(struct rtw_adapter *padapter)
2526 {
2527         enum hci_status status = HCI_STATUS_SUCCESS;
2528         u8 localBuf[TmpLocalBufSize] = "";
2529         u8 *pRetPar;
2530         u8 len = 0;
2531         struct packet_irp_hcievent_data *PPacketIrpEvent;
2532
2533         /* send command complete event here when all data are received. */
2534         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2535         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2536
2537         len += bthci_CommandCompleteHeader(&localBuf[0],
2538                 OGF_INFORMATIONAL_PARAMETERS,
2539                 HCI_READ_LOCAL_SUPPORTED_FEATURES,
2540                 status);
2541
2542         /*  Return parameters starts from here */
2543         pRetPar = &PPacketIrpEvent->Data[len];
2544         pRetPar[0] = status;            /* status */
2545         len += 9;
2546         PPacketIrpEvent->Length = len;
2547
2548         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2549         return status;
2550 }
2551
2552 static enum hci_status bthci_CmdReadLocalAMPAssoc(struct rtw_adapter *padapter,
2553         struct packet_irp_hcicmd_data *pHciCmd)
2554 {
2555         enum hci_status status = HCI_STATUS_SUCCESS;
2556         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2557         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
2558         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
2559         u8 PhyLinkHandle, EntryNum;
2560
2561         pBtDbg->dbgHciInfo.hciCmdCntReadLocalAmpAssoc++;
2562         PhyLinkHandle = *((u8 *)pHciCmd->Data);
2563         EntryNum = bthci_GetCurrentEntryNum(padapter, PhyLinkHandle);
2564
2565         if ((EntryNum == 0xff) && PhyLinkHandle != 0) {
2566                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, EntryNum = %d  !!!!!, physical link handle = 0x%x\n",
2567                 EntryNum, PhyLinkHandle));
2568                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
2569         } else if (pBtMgnt->bPhyLinkInProgressStartLL) {
2570                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
2571                 pBtMgnt->bPhyLinkInProgressStartLL = false;
2572         } else {
2573                 pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.BtPhyLinkhandle = *((u8 *)pHciCmd->Data);
2574                 pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar = *((u16 *)((u8 *)pHciCmd->Data+1));
2575                 pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.MaxRemoteASSOCLen = *((u16 *)((u8 *)pHciCmd->Data+3));
2576                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("ReadLocalAMPAssoc, LenSoFar =%d, MaxRemoteASSOCLen =%d\n",
2577                         pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar,
2578                         pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.MaxRemoteASSOCLen));
2579         }
2580
2581         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, EntryNum = %d  !!!!!, physical link handle = 0x%x, LengthSoFar = %x  \n",
2582                 EntryNum, PhyLinkHandle, pBTInfo->BtAsocEntry[EntryNum].AmpAsocCmdData.LenSoFar));
2583
2584         /* send command complete event here when all data are received. */
2585         {
2586                 struct packet_irp_hcievent_data *PPacketIrpEvent;
2587
2588                 /* PVOID buffer = padapter->IrpHCILocalbuf.Ptr; */
2589                 u8 localBuf[TmpLocalBufSize] = "";
2590                 u16     *pRemainLen;
2591                 u32     totalLen = 0;
2592                 u16     typeLen = 0, remainLen = 0, ret_index = 0;
2593                 u8 *pRetPar;
2594
2595                 PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2596                 /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
2597                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2598
2599                 totalLen += bthci_CommandCompleteHeader(&localBuf[0],
2600                         OGF_STATUS_PARAMETERS,
2601                         HCI_READ_LOCAL_AMP_ASSOC,
2602                         status);
2603                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, Remaining_Len =%d  \n", remainLen));
2604                 /*  Return parameters starts from here */
2605                 pRetPar = &PPacketIrpEvent->Data[totalLen];
2606                 pRetPar[0] = status;            /* status */
2607                 pRetPar[1] = *((u8 *)pHciCmd->Data);
2608                 pRemainLen = (u16 *)&pRetPar[2];        /* AMP_ASSOC_Remaining_Length */
2609                 totalLen += 4;  /* 0]~[3] */
2610                 ret_index = 4;
2611
2612                 typeLen = bthci_AssocMACAddr(padapter, &pRetPar[ret_index]);
2613                 totalLen += typeLen;
2614                 remainLen += typeLen;
2615                 ret_index += typeLen;
2616                 typeLen = bthci_AssocPreferredChannelList(padapter, &pRetPar[ret_index], EntryNum);
2617                 totalLen += typeLen;
2618                 remainLen += typeLen;
2619                 ret_index += typeLen;
2620                 typeLen = bthci_PALCapabilities(padapter, &pRetPar[ret_index]);
2621                 totalLen += typeLen;
2622                 remainLen += typeLen;
2623                 ret_index += typeLen;
2624                 typeLen = bthci_AssocPALVer(padapter, &pRetPar[ret_index]);
2625                 totalLen += typeLen;
2626                 remainLen += typeLen;
2627                 PPacketIrpEvent->Length = (u8)totalLen;
2628                 *pRemainLen = remainLen;        /*  AMP_ASSOC_Remaining_Length */
2629                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("ReadLocalAMPAssoc, Remaining_Len =%d  \n", remainLen));
2630                 RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("AMP_ASSOC_fragment : \n"), PPacketIrpEvent->Data, totalLen);
2631
2632                 bthci_IndicateEvent(padapter, PPacketIrpEvent, totalLen+2);
2633         }
2634
2635         return status;
2636 }
2637
2638 static enum hci_status bthci_CmdReadFailedContactCounter(struct rtw_adapter *padapter,
2639                        struct packet_irp_hcicmd_data *pHciCmd)
2640 {
2641
2642         enum hci_status         status = HCI_STATUS_SUCCESS;
2643         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2644         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2645         u8 localBuf[TmpLocalBufSize] = "";
2646         u8 *pRetPar;
2647         u8 len = 0;
2648         struct packet_irp_hcievent_data *PPacketIrpEvent;
2649         u16 handle;
2650
2651         handle = *((u16 *)pHciCmd->Data);
2652         /* send command complete event here when all data are received. */
2653         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2654         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2655
2656         len += bthci_CommandCompleteHeader(&localBuf[0],
2657                 OGF_STATUS_PARAMETERS,
2658                 HCI_READ_FAILED_CONTACT_COUNTER,
2659                 status);
2660
2661         /*  Return parameters starts from here */
2662         pRetPar = &PPacketIrpEvent->Data[len];
2663         pRetPar[0] = status;            /* status */
2664         pRetPar[1] = TWOBYTE_LOWBYTE(handle);
2665         pRetPar[2] = TWOBYTE_HIGHTBYTE(handle);
2666         pRetPar[3] = TWOBYTE_LOWBYTE(pBtHciInfo->FailContactCount);
2667         pRetPar[4] = TWOBYTE_HIGHTBYTE(pBtHciInfo->FailContactCount);
2668         len += 5;
2669         PPacketIrpEvent->Length = len;
2670
2671         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2672
2673         return status;
2674 }
2675
2676 static enum hci_status
2677 bthci_CmdResetFailedContactCounter(
2678         struct rtw_adapter *padapter,
2679         struct packet_irp_hcicmd_data *pHciCmd
2680         )
2681 {
2682         enum hci_status         status = HCI_STATUS_SUCCESS;
2683 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
2684         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2685         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
2686         u16             handle;
2687         u8 localBuf[TmpLocalBufSize] = "";
2688         u8 *pRetPar;
2689         u8 len = 0;
2690         struct packet_irp_hcievent_data *PPacketIrpEvent;
2691
2692         handle = *((u16 *)pHciCmd->Data);
2693         pBtHciInfo->FailContactCount = 0;
2694
2695         /* send command complete event here when all data are received. */
2696         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2697         /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
2698         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2699
2700         len += bthci_CommandCompleteHeader(&localBuf[0],
2701                 OGF_STATUS_PARAMETERS,
2702                 HCI_RESET_FAILED_CONTACT_COUNTER,
2703                 status);
2704
2705         /*  Return parameters starts from here */
2706         pRetPar = &PPacketIrpEvent->Data[len];
2707         pRetPar[0] = status;            /* status */
2708         pRetPar[1] = TWOBYTE_LOWBYTE(handle);
2709         pRetPar[2] = TWOBYTE_HIGHTBYTE(handle);
2710         len += 3;
2711         PPacketIrpEvent->Length = len;
2712
2713         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2714         return status;
2715 }
2716
2717 /*  */
2718 /*  BT 3.0+HS [Vol 2] 7.4.1 */
2719 /*  */
2720 static enum hci_status
2721 bthci_CmdReadLocalVersionInformation(
2722         struct rtw_adapter *padapter
2723         )
2724 {
2725         enum hci_status status = HCI_STATUS_SUCCESS;
2726         /* send command complete event here when all data are received. */
2727         u8 localBuf[TmpLocalBufSize] = "";
2728         u8 *pRetPar;
2729         u8 len = 0;
2730         struct packet_irp_hcievent_data *PPacketIrpEvent;
2731         u16 *pu2Temp;
2732
2733         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2734         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2735
2736         len += bthci_CommandCompleteHeader(&localBuf[0],
2737                 OGF_INFORMATIONAL_PARAMETERS,
2738                 HCI_READ_LOCAL_VERSION_INFORMATION,
2739                 status);
2740
2741         /*  Return parameters starts from here */
2742         pRetPar = &PPacketIrpEvent->Data[len];
2743         pRetPar[0] = status;            /* status */
2744         pRetPar[1] = 0x05;                      /*  HCI_Version */
2745         pu2Temp = (u16 *)&pRetPar[2];           /*  HCI_Revision */
2746         *pu2Temp = 0x0001;
2747         pRetPar[4] = 0x05;                      /*  LMP/PAL_Version */
2748         pu2Temp = (u16 *)&pRetPar[5];           /*  Manufacturer_Name */
2749         *pu2Temp = 0x005d;
2750         pu2Temp = (u16 *)&pRetPar[7];           /*  LMP/PAL_Subversion */
2751         *pu2Temp = 0x0001;
2752         len += 9;
2753         PPacketIrpEvent->Length = len;
2754
2755         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LOCAL_VERSION_INFORMATION\n"));
2756         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("Status  %x\n", status));
2757         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI_Version = 0x05\n"));
2758         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI_Revision = 0x0001\n"));
2759         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LMP/PAL_Version = 0x05\n"));
2760         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("Manufacturer_Name = 0x0001\n"));
2761         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("LMP/PAL_Subversion = 0x0001\n"));
2762
2763         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2764
2765         return status;
2766 }
2767
2768 /* 7.4.7 */
2769 static enum hci_status bthci_CmdReadDataBlockSize(struct rtw_adapter *padapter)
2770 {
2771         enum hci_status                 status = HCI_STATUS_SUCCESS;
2772         u8 localBuf[TmpLocalBufSize] = "";
2773         u8 *pRetPar;
2774         u8 len = 0;
2775         struct packet_irp_hcievent_data *PPacketIrpEvent;
2776         u16 *pu2Temp;
2777
2778         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2779         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2780
2781         len += bthci_CommandCompleteHeader(&localBuf[0],
2782                 OGF_INFORMATIONAL_PARAMETERS,
2783                 HCI_READ_DATA_BLOCK_SIZE,
2784                 status);
2785
2786         /*  Return parameters starts from here */
2787         pRetPar = &PPacketIrpEvent->Data[len];
2788         pRetPar[0] = HCI_STATUS_SUCCESS;        /* status */
2789         pu2Temp = (u16 *)&pRetPar[1];           /*  Max_ACL_Data_Packet_Length */
2790         *pu2Temp = Max80211PALPDUSize;
2791
2792         pu2Temp = (u16 *)&pRetPar[3];           /*  Data_Block_Length */
2793         *pu2Temp = Max80211PALPDUSize;
2794         pu2Temp = (u16 *)&pRetPar[5];           /*  Total_Num_Data_Blocks */
2795         *pu2Temp = BTTotalDataBlockNum;
2796         len += 7;
2797         PPacketIrpEvent->Length = len;
2798
2799         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2800
2801         return status;
2802 }
2803
2804 /*  7.4.5 */
2805 static enum hci_status bthci_CmdReadBufferSize(struct rtw_adapter *padapter)
2806 {
2807         enum hci_status status = HCI_STATUS_SUCCESS;
2808         u8 localBuf[TmpLocalBufSize] = "";
2809         u8 *pRetPar;
2810         u8 len = 0;
2811         struct packet_irp_hcievent_data *PPacketIrpEvent;
2812         u16 *pu2Temp;
2813
2814         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2815         /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
2816         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2817
2818         len += bthci_CommandCompleteHeader(&localBuf[0],
2819                 OGF_INFORMATIONAL_PARAMETERS,
2820                 HCI_READ_BUFFER_SIZE,
2821                 status);
2822         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Synchronous_Data_Packet_Length = 0x%x\n", BTSynDataPacketLength));
2823         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Total_Num_ACL_Data_Packets = 0x%x\n", BTTotalDataBlockNum));
2824         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("Total_Num_Synchronous_Data_Packets = 0x%x\n", BTTotalDataBlockNum));
2825         /*  Return parameters starts from here */
2826         pRetPar = &PPacketIrpEvent->Data[len];
2827         pRetPar[0] = status;            /* status */
2828         pu2Temp = (u16 *)&pRetPar[1];           /*  HC_ACL_Data_Packet_Length */
2829         *pu2Temp = Max80211PALPDUSize;
2830
2831         pRetPar[3] = BTSynDataPacketLength;     /*  HC_Synchronous_Data_Packet_Length */
2832         pu2Temp = (u16 *)&pRetPar[4];           /*  HC_Total_Num_ACL_Data_Packets */
2833         *pu2Temp = BTTotalDataBlockNum;
2834         pu2Temp = (u16 *)&pRetPar[6];           /*  HC_Total_Num_Synchronous_Data_Packets */
2835         *pu2Temp = BTTotalDataBlockNum;
2836         len += 8;
2837         PPacketIrpEvent->Length = len;
2838
2839         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2840
2841         return status;
2842 }
2843
2844 static enum hci_status bthci_CmdReadLocalAMPInfo(struct rtw_adapter *padapter)
2845 {
2846         enum hci_status status = HCI_STATUS_SUCCESS;
2847         struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv;
2848         u8 localBuf[TmpLocalBufSize] = "";
2849         u8 *pRetPar;
2850         u8 len = 0;
2851         struct packet_irp_hcievent_data *PPacketIrpEvent;
2852         u16 *pu2Temp;
2853         u32 *pu4Temp;
2854         u32     TotalBandwidth = BTTOTALBANDWIDTH, MaxBandGUBandwidth = BTMAXBANDGUBANDWIDTH;
2855         u8 ControlType = 0x01, AmpStatus = 0x01;
2856         u32     MaxFlushTimeout = 10000, BestEffortFlushTimeout = 5000;
2857         u16 MaxPDUSize = Max80211PALPDUSize, PalCap = 0x1, AmpAssocLen = Max80211AMPASSOCLen, MinLatency = 20;
2858
2859         if ((ppwrctrl->rfoff_reason & RF_CHANGE_BY_HW) ||
2860             (ppwrctrl->rfoff_reason & RF_CHANGE_BY_SW)) {
2861                 AmpStatus = AMP_STATUS_NO_CAPACITY_FOR_BT;
2862         }
2863
2864         PlatformZeroMemory(&localBuf[0], TmpLocalBufSize);
2865         /* PPacketIrpEvent = (struct packet_irp_hcievent_data *)(buffer); */
2866         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2867
2868         len += bthci_CommandCompleteHeader(&localBuf[0],
2869                 OGF_STATUS_PARAMETERS,
2870                 HCI_READ_LOCAL_AMP_INFO,
2871                 status);
2872
2873         /*  Return parameters starts from here */
2874         pRetPar = &PPacketIrpEvent->Data[len];
2875         pRetPar[0] = status;                    /* status */
2876         pRetPar[1] = AmpStatus;                 /*  AMP_Status */
2877         pu4Temp = (u32 *)&pRetPar[2];           /*  Total_Bandwidth */
2878         *pu4Temp = TotalBandwidth;              /* 0x19bfcc00;0x7530; */
2879         pu4Temp = (u32 *)&pRetPar[6];           /*  Max_Guaranteed_Bandwidth */
2880         *pu4Temp = MaxBandGUBandwidth;          /* 0x19bfcc00;0x4e20; */
2881         pu4Temp = (u32 *)&pRetPar[10];          /*  Min_Latency */
2882         *pu4Temp = MinLatency;                  /* 150; */
2883         pu4Temp = (u32 *)&pRetPar[14];          /*  Max_PDU_Size */
2884         *pu4Temp = MaxPDUSize;
2885         pRetPar[18] = ControlType;              /*  Controller_Type */
2886         pu2Temp = (u16 *)&pRetPar[19];          /*  PAL_Capabilities */
2887         *pu2Temp = PalCap;
2888         pu2Temp = (u16 *)&pRetPar[21];          /*  AMP_ASSOC_Length */
2889         *pu2Temp = AmpAssocLen;
2890         pu4Temp = (u32 *)&pRetPar[23];          /*  Max_Flush_Timeout */
2891         *pu4Temp = MaxFlushTimeout;
2892         pu4Temp = (u32 *)&pRetPar[27];          /*  Best_Effort_Flush_Timeout */
2893         *pu4Temp = BestEffortFlushTimeout;
2894         len += 31;
2895         PPacketIrpEvent->Length = len;
2896         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("AmpStatus = 0x%x\n",
2897                 AmpStatus));
2898         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("TotalBandwidth = 0x%x, MaxBandGUBandwidth = 0x%x, MinLatency = 0x%x, \n MaxPDUSize = 0x%x, ControlType = 0x%x\n",
2899                 TotalBandwidth, MaxBandGUBandwidth, MinLatency, MaxPDUSize, ControlType));
2900         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PalCap = 0x%x, AmpAssocLen = 0x%x, MaxFlushTimeout = 0x%x, BestEffortFlushTimeout = 0x%x\n",
2901                 PalCap, AmpAssocLen, MaxFlushTimeout, BestEffortFlushTimeout));
2902         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2903         return status;
2904 }
2905
2906 static enum hci_status
2907 bthci_CmdCreatePhysicalLink(
2908         struct rtw_adapter *padapter,
2909         struct packet_irp_hcicmd_data *pHciCmd
2910         )
2911 {
2912         enum hci_status status;
2913         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2914         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
2915
2916         pBtDbg->dbgHciInfo.hciCmdCntCreatePhyLink++;
2917
2918         status = bthci_BuildPhysicalLink(padapter,
2919                 pHciCmd, HCI_CREATE_PHYSICAL_LINK);
2920
2921         return status;
2922 }
2923
2924 static enum hci_status
2925 bthci_CmdReadLinkQuality(
2926         struct rtw_adapter *padapter,
2927         struct packet_irp_hcicmd_data *pHciCmd
2928         )
2929 {
2930         enum hci_status                 status = HCI_STATUS_SUCCESS;
2931         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2932         u16                             PLH;
2933         u8      EntryNum, LinkQuality = 0x55;
2934
2935         PLH = *((u16 *)&pHciCmd->Data[0]);
2936         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("PLH = 0x%x\n", PLH));
2937
2938         EntryNum = bthci_GetCurrentEntryNum(padapter, (u8)PLH);
2939         if (EntryNum == 0xff) {
2940                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("No such PLH(0x%x)\n", PLH));
2941                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
2942         }
2943
2944         {
2945                 u8 localBuf[11] = "";
2946                 u8 *pRetPar;
2947                 u8 len = 0;
2948                 struct packet_irp_hcievent_data *PPacketIrpEvent;
2949
2950                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
2951
2952                 len += bthci_CommandCompleteHeader(&localBuf[0],
2953                         OGF_STATUS_PARAMETERS,
2954                         HCI_READ_LINK_QUALITY,
2955                         status);
2956
2957                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, (" PLH = 0x%x\n Link Quality = 0x%x\n", PLH, LinkQuality));
2958
2959                 /*  Return parameters starts from here */
2960                 pRetPar = &PPacketIrpEvent->Data[len];
2961                 pRetPar[0] = status;                    /* status */
2962                 *((u16 *)&pRetPar[1]) = pBTInfo->BtAsocEntry[EntryNum].PhyLinkCmdData.BtPhyLinkhandle;  /*  Handle */
2963                 pRetPar[3] = 0x55;      /* Link Quailty */
2964                 len += 4;
2965                 PPacketIrpEvent->Length = len;
2966
2967                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
2968         }
2969
2970         return status;
2971 }
2972
2973 static enum hci_status
2974 bthci_CmdCreateLogicalLink(
2975         struct rtw_adapter *padapter,
2976         struct packet_irp_hcicmd_data *pHciCmd
2977         )
2978 {
2979         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2980         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
2981
2982         pBtDbg->dbgHciInfo.hciCmdCntCreateLogLink++;
2983
2984         bthci_BuildLogicalLink(padapter, pHciCmd,
2985                 HCI_CREATE_LOGICAL_LINK);
2986
2987         return HCI_STATUS_SUCCESS;
2988 }
2989
2990 static enum hci_status
2991 bthci_CmdAcceptLogicalLink(
2992         struct rtw_adapter *padapter,
2993         struct packet_irp_hcicmd_data *pHciCmd
2994         )
2995 {
2996         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
2997         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
2998
2999         pBtDbg->dbgHciInfo.hciCmdCntAcceptLogLink++;
3000
3001         bthci_BuildLogicalLink(padapter, pHciCmd,
3002                 HCI_ACCEPT_LOGICAL_LINK);
3003
3004         return HCI_STATUS_SUCCESS;
3005 }
3006
3007 static enum hci_status
3008 bthci_CmdDisconnectLogicalLink(
3009         struct rtw_adapter *padapter,
3010         struct packet_irp_hcicmd_data *pHciCmd
3011         )
3012 {
3013         enum hci_status status = HCI_STATUS_SUCCESS;
3014 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
3015         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
3016         struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt;
3017         struct bt_dgb *pBtDbg = &pBTinfo->BtDbg;
3018         u16     logicHandle;
3019         u8 i, j, find = 0, LogLinkCount = 0;
3020
3021         pBtDbg->dbgHciInfo.hciCmdCntDisconnectLogLink++;
3022
3023         logicHandle = *((u16 *)pHciCmd->Data);
3024         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DisconnectLogicalLink, logicHandle = 0x%x\n", logicHandle));
3025
3026         /*  find an created logical link index and clear the data */
3027         for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
3028                 for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
3029                         if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
3030                                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("DisconnectLogicalLink, logicHandle is matched  0x%x\n", logicHandle));
3031                                 bthci_ResetFlowSpec(padapter, j, i);
3032                                 find = 1;
3033                                 pBtMgnt->DisconnectEntryNum = j;
3034                                 break;
3035                         }
3036                 }
3037         }
3038
3039         if (!find)
3040                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
3041
3042         /*  To check each */
3043         for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
3044                 if (pBTinfo->BtAsocEntry[pBtMgnt->DisconnectEntryNum].LogLinkCmdData[i].BtLogLinkhandle != 0)
3045                         LogLinkCount++;
3046         }
3047
3048         /* When we receive Create logical link command, we should send command status event first. */
3049         bthci_EventCommandStatus(padapter,
3050                         LINK_CONTROL_COMMANDS,
3051                         HCI_DISCONNECT_LOGICAL_LINK,
3052                         status);
3053         /*  */
3054         /* When we determines the logical link is established, we should send command complete event. */
3055         /*  */
3056         if (status == HCI_STATUS_SUCCESS) {
3057                 bthci_EventDisconnectLogicalLinkComplete(padapter, status,
3058                         logicHandle, HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST);
3059         }
3060
3061         if (LogLinkCount == 0)
3062                 mod_timer(&pBTinfo->BTDisconnectPhyLinkTimer,
3063                           jiffies + msecs_to_jiffies(100));
3064
3065         return status;
3066 }
3067
3068 static enum hci_status
3069 bthci_CmdLogicalLinkCancel(struct rtw_adapter *padapter,
3070                            struct packet_irp_hcicmd_data *pHciCmd)
3071 {
3072         enum hci_status status = HCI_STATUS_SUCCESS;
3073         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
3074         struct bt_mgnt *pBtMgnt = &pBTinfo->BtMgnt;
3075         u8 CurrentEntryNum, CurrentLogEntryNum;
3076
3077         u8 physicalLinkHandle, TxFlowSpecID, i;
3078         u16     CurrentLogicalHandle;
3079
3080         physicalLinkHandle = *((u8 *)pHciCmd->Data);
3081         TxFlowSpecID = *(((u8 *)pHciCmd->Data)+1);
3082
3083         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, physicalLinkHandle = 0x%x, TxFlowSpecID = 0x%x\n",
3084                 physicalLinkHandle, TxFlowSpecID));
3085
3086         CurrentEntryNum = pBtMgnt->CurrentConnectEntryNum;
3087         CurrentLogicalHandle = pBtMgnt->BtCurrentLogLinkhandle;
3088
3089         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("CurrentEntryNum = 0x%x, CurrentLogicalHandle = 0x%x\n",
3090                 CurrentEntryNum, CurrentLogicalHandle));
3091
3092         CurrentLogEntryNum = 0xff;
3093         for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
3094                 if ((CurrentLogicalHandle == pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[i].BtLogLinkhandle) &&
3095                         (physicalLinkHandle == pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[i].BtPhyLinkhandle)) {
3096                         CurrentLogEntryNum = i;
3097                         break;
3098                 }
3099         }
3100
3101         if (CurrentLogEntryNum == 0xff) {
3102                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, CurrentLogEntryNum == 0xff !!!!\n"));
3103                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
3104                 return status;
3105         } else {
3106                 if (pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].bLLCompleteEventIsSet) {
3107                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("LogicalLinkCancel, LLCompleteEventIsSet!!!!\n"));
3108                         status = HCI_STATUS_ACL_CONNECT_EXISTS;
3109                 }
3110         }
3111
3112         {
3113                 u8 localBuf[8] = "";
3114                 u8 *pRetPar;
3115                 u8 len = 0;
3116                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3117
3118                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3119
3120                 len += bthci_CommandCompleteHeader(&localBuf[0],
3121                         LINK_CONTROL_COMMANDS,
3122                         HCI_LOGICAL_LINK_CANCEL,
3123                         status);
3124
3125                 /*  Return parameters starts from here */
3126                 pRetPar = &PPacketIrpEvent->Data[len];
3127                 pRetPar[0] = status;            /* status */
3128                 pRetPar[1] = pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].BtPhyLinkhandle;
3129                 pRetPar[2] = pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].BtTxFlowSpecID;
3130                 len += 3;
3131                 PPacketIrpEvent->Length = len;
3132
3133                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3134         }
3135
3136         pBTinfo->BtAsocEntry[CurrentEntryNum].LogLinkCmdData[CurrentLogEntryNum].bLLCancelCMDIsSetandComplete = true;
3137
3138         return status;
3139 }
3140
3141 static enum hci_status
3142 bthci_CmdFlowSpecModify(struct rtw_adapter *padapter,
3143                         struct packet_irp_hcicmd_data *pHciCmd)
3144 {
3145         enum hci_status status = HCI_STATUS_SUCCESS;
3146 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
3147         struct bt_30info *pBTinfo = GET_BT_INFO(padapter);
3148         u8 i, j, find = 0;
3149         u16 logicHandle;
3150
3151         logicHandle = *((u16 *)pHciCmd->Data);
3152         /*  find an matched logical link index and copy the data */
3153         for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
3154                 for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
3155                         if (pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle == logicHandle) {
3156                                 memcpy(&pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Tx_Flow_Spec,
3157                                         &pHciCmd->Data[2], sizeof(struct hci_flow_spec));
3158                                 memcpy(&pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Rx_Flow_Spec,
3159                                         &pHciCmd->Data[18], sizeof(struct hci_flow_spec));
3160
3161                                 bthci_CheckLogLinkBehavior(padapter, pBTinfo->BtAsocEntry[j].LogLinkCmdData[i].Tx_Flow_Spec);
3162                                 find = 1;
3163                                 break;
3164                         }
3165                 }
3166         }
3167         RTPRINT(FIOCTL, IOCTL_BT_LOGO, ("FlowSpecModify, LLH = 0x%x, \n", logicHandle));
3168
3169         /* When we receive Flow Spec Modify command, we should send command status event first. */
3170         bthci_EventCommandStatus(padapter,
3171                 LINK_CONTROL_COMMANDS,
3172                 HCI_FLOW_SPEC_MODIFY,
3173                 HCI_STATUS_SUCCESS);
3174
3175         if (!find)
3176                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
3177
3178         bthci_EventSendFlowSpecModifyComplete(padapter, status, logicHandle);
3179
3180         return status;
3181 }
3182
3183 static enum hci_status
3184 bthci_CmdAcceptPhysicalLink(struct rtw_adapter *padapter,
3185                             struct packet_irp_hcicmd_data *pHciCmd)
3186 {
3187         enum hci_status status;
3188         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3189         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
3190
3191         pBtDbg->dbgHciInfo.hciCmdCntAcceptPhyLink++;
3192
3193         status = bthci_BuildPhysicalLink(padapter,
3194                 pHciCmd, HCI_ACCEPT_PHYSICAL_LINK);
3195
3196         return status;
3197 }
3198
3199 static enum hci_status
3200 bthci_CmdDisconnectPhysicalLink(struct rtw_adapter *padapter,
3201                                 struct packet_irp_hcicmd_data *pHciCmd)
3202 {
3203         enum hci_status status = HCI_STATUS_SUCCESS;
3204         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3205         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
3206         u8 PLH, CurrentEntryNum, PhysLinkDisconnectReason;
3207
3208         pBtDbg->dbgHciInfo.hciCmdCntDisconnectPhyLink++;
3209
3210         PLH = *((u8 *)pHciCmd->Data);
3211         PhysLinkDisconnectReason = (*((u8 *)pHciCmd->Data+1));
3212         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_PHYSICAL_LINK  PhyHandle = 0x%x, Reason = 0x%x\n",
3213                 PLH, PhysLinkDisconnectReason));
3214
3215         CurrentEntryNum = bthci_GetCurrentEntryNum(padapter, PLH);
3216
3217         if (CurrentEntryNum == 0xff) {
3218                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD,
3219                         ("DisconnectPhysicalLink, No such Handle in the Entry\n"));
3220                 status = HCI_STATUS_UNKNOW_CONNECT_ID;
3221         } else {
3222                 pBTInfo->BtAsocEntry[CurrentEntryNum].PhyLinkDisconnectReason =
3223                         (enum hci_status)PhysLinkDisconnectReason;
3224         }
3225         /* Send HCI Command status event to AMP. */
3226         bthci_EventCommandStatus(padapter, LINK_CONTROL_COMMANDS,
3227                                  HCI_DISCONNECT_PHYSICAL_LINK, status);
3228
3229         if (status != HCI_STATUS_SUCCESS)
3230                 return status;
3231
3232         /* The macros below require { and } in the if statement */
3233         if (pBTInfo->BtAsocEntry[CurrentEntryNum].BtCurrentState == HCI_STATE_DISCONNECTED) {
3234                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_DISCONNECT_PHY_LINK, CurrentEntryNum);
3235         } else {
3236                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_DISCONNECT_PHY_LINK, CurrentEntryNum);
3237         }
3238         return status;
3239 }
3240
3241 static enum hci_status
3242 bthci_CmdSetACLLinkDataFlowMode(struct rtw_adapter *padapter,
3243                                 struct packet_irp_hcicmd_data *pHciCmd)
3244 {
3245         enum hci_status status = HCI_STATUS_SUCCESS;
3246         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3247         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3248         u8 localBuf[8] = "";
3249         u8 *pRetPar;
3250         u8 len = 0;
3251         struct packet_irp_hcievent_data *PPacketIrpEvent;
3252         u16 *pu2Temp;
3253
3254         pBtMgnt->ExtConfig.CurrentConnectHandle = *((u16 *)pHciCmd->Data);
3255         pBtMgnt->ExtConfig.CurrentIncomingTrafficMode = *((u8 *)pHciCmd->Data)+2;
3256         pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode = *((u8 *)pHciCmd->Data)+3;
3257         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Connection Handle = 0x%x, Incoming Traffic mode = 0x%x, Outgoing Traffic mode = 0x%x",
3258                 pBtMgnt->ExtConfig.CurrentConnectHandle,
3259                 pBtMgnt->ExtConfig.CurrentIncomingTrafficMode,
3260                 pBtMgnt->ExtConfig.CurrentOutgoingTrafficMode));
3261
3262
3263         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3264
3265         len += bthci_CommandCompleteHeader(&localBuf[0],
3266                 OGF_EXTENSION,
3267                 HCI_SET_ACL_LINK_DATA_FLOW_MODE,
3268                 status);
3269
3270         /*  Return parameters starts from here */
3271         pRetPar = &PPacketIrpEvent->Data[len];
3272         pRetPar[0] = status;            /* status */
3273
3274         pu2Temp = (u16 *)&pRetPar[1];
3275         *pu2Temp = pBtMgnt->ExtConfig.CurrentConnectHandle;
3276         len += 3;
3277         PPacketIrpEvent->Length = len;
3278
3279         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3280         return status;
3281 }
3282
3283 static enum hci_status
3284 bthci_CmdSetACLLinkStatus(struct rtw_adapter *padapter,
3285                           struct packet_irp_hcicmd_data *pHciCmd)
3286 {
3287         enum hci_status status = HCI_STATUS_SUCCESS;
3288         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3289         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3290         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
3291         u8 i;
3292         u8 *pTriple;
3293
3294         pBtDbg->dbgHciInfo.hciCmdCntSetAclLinkStatus++;
3295         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "SetACLLinkStatus, Hex Data :\n",
3296                         &pHciCmd->Data[0], pHciCmd->Length);
3297
3298         /*  Only Core Stack v251 and later version support this command. */
3299         pBtMgnt->bSupportProfile = true;
3300
3301         pBtMgnt->ExtConfig.NumberOfHandle = *((u8 *)pHciCmd->Data);
3302         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfHandle = 0x%x\n", pBtMgnt->ExtConfig.NumberOfHandle));
3303
3304         pTriple = &pHciCmd->Data[1];
3305         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
3306                 pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]);
3307                 pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = pTriple[2];
3308                 pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = pTriple[3];
3309                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT,
3310                         ("Connection_Handle = 0x%x, Incoming Traffic mode = 0x%x, Outgoing Traffic Mode = 0x%x\n",
3311                         pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
3312                         pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode,
3313                         pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode));
3314                 pTriple += 4;
3315         }
3316
3317         {
3318                 u8 localBuf[6] = "";
3319                 u8 *pRetPar;
3320                 u8 len = 0;
3321                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3322
3323                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3324
3325                 len += bthci_CommandCompleteHeader(&localBuf[0],
3326                         OGF_EXTENSION,
3327                         HCI_SET_ACL_LINK_STATUS,
3328                         status);
3329
3330                 /*  Return parameters starts from here */
3331                 pRetPar = &PPacketIrpEvent->Data[len];
3332                 pRetPar[0] = status;            /* status */
3333
3334                 len += 1;
3335                 PPacketIrpEvent->Length = len;
3336
3337                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3338         }
3339
3340         return status;
3341 }
3342
3343 static enum hci_status
3344 bthci_CmdSetSCOLinkStatus(
3345         struct rtw_adapter *padapter,
3346         struct packet_irp_hcicmd_data *pHciCmd
3347         )
3348 {
3349         enum hci_status status = HCI_STATUS_SUCCESS;
3350         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3351         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3352         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
3353
3354         pBtDbg->dbgHciInfo.hciCmdCntSetScoLinkStatus++;
3355         pBtMgnt->ExtConfig.NumberOfSCO = *((u8 *)pHciCmd->Data);
3356         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfSCO = 0x%x\n",
3357                 pBtMgnt->ExtConfig.NumberOfSCO));
3358
3359         {
3360                 u8 localBuf[6] = "";
3361                 u8 *pRetPar;
3362                 u8 len = 0;
3363                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3364
3365                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3366
3367                 len += bthci_CommandCompleteHeader(&localBuf[0],
3368                         OGF_EXTENSION,
3369                         HCI_SET_SCO_LINK_STATUS,
3370                         status);
3371
3372                 /*  Return parameters starts from here */
3373                 pRetPar = &PPacketIrpEvent->Data[len];
3374                 pRetPar[0] = status;            /* status */
3375
3376                 len += 1;
3377                 PPacketIrpEvent->Length = len;
3378
3379                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3380         }
3381
3382         return status;
3383 }
3384
3385 static enum hci_status
3386 bthci_CmdSetRSSIValue(
3387         struct rtw_adapter *padapter,
3388         struct packet_irp_hcicmd_data *pHciCmd
3389         )
3390 {
3391         enum hci_status status = HCI_STATUS_SUCCESS;
3392         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3393         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3394         s8              min_bt_rssi = 0;
3395         u8 i;
3396         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
3397                 if (pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle == *((u16 *)&pHciCmd->Data[0])) {
3398                         pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI = (s8)(pHciCmd->Data[2]);
3399                         RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL,
3400                         ("Connection_Handle = 0x%x, RSSI = %d \n",
3401                         pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
3402                         pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI));
3403                 }
3404                 /*  get the minimum bt rssi value */
3405                 if (pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI <= min_bt_rssi)
3406                         min_bt_rssi = pBtMgnt->ExtConfig.linkInfo[i].BT_RSSI;
3407         }
3408
3409         pBtMgnt->ExtConfig.MIN_BT_RSSI = min_bt_rssi;
3410         RTPRINT(FBT, BT_TRACE, ("[bt rssi], the min rssi is %d\n", min_bt_rssi));
3411
3412         {
3413                 u8 localBuf[6] = "";
3414                 u8 *pRetPar;
3415                 u8 len = 0;
3416                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3417
3418                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3419
3420                 len += bthci_CommandCompleteHeader(&localBuf[0],
3421                         OGF_EXTENSION,
3422                         HCI_SET_RSSI_VALUE,
3423                         status);
3424
3425                 /*  Return parameters starts from here */
3426                 pRetPar = &PPacketIrpEvent->Data[len];
3427                 pRetPar[0] = status;            /* status */
3428
3429                 len += 1;
3430                 PPacketIrpEvent->Length = len;
3431
3432                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3433         }
3434
3435         return status;
3436 }
3437
3438 static enum hci_status
3439 bthci_CmdSetCurrentBluetoothStatus(
3440         struct rtw_adapter *padapter,
3441         struct packet_irp_hcicmd_data *pHciCmd
3442         )
3443 {
3444         enum hci_status status = HCI_STATUS_SUCCESS;
3445 /*PMGNT_INFO    pMgntInfo = &padapter->MgntInfo; */
3446         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3447         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3448
3449         pBtMgnt->ExtConfig.CurrentBTStatus = *((u8 *)&pHciCmd->Data[0]);
3450         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("SetCurrentBluetoothStatus, CurrentBTStatus = 0x%x\n",
3451                 pBtMgnt->ExtConfig.CurrentBTStatus));
3452
3453         {
3454                 u8 localBuf[6] = "";
3455                 u8 *pRetPar;
3456                 u8 len = 0;
3457                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3458
3459                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3460
3461                 len += bthci_CommandCompleteHeader(&localBuf[0],
3462                         OGF_EXTENSION,
3463                         HCI_SET_CURRENT_BLUETOOTH_STATUS,
3464                         status);
3465
3466                 /*  Return parameters starts from here */
3467                 pRetPar = &PPacketIrpEvent->Data[len];
3468                 pRetPar[0] = status;            /* status */
3469                 len += 1;
3470
3471                 PPacketIrpEvent->Length = len;
3472
3473                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3474         }
3475
3476         return status;
3477 }
3478
3479 static enum hci_status
3480 bthci_CmdExtensionVersionNotify(
3481         struct rtw_adapter *padapter,
3482         struct packet_irp_hcicmd_data *pHciCmd
3483         )
3484 {
3485         enum hci_status status = HCI_STATUS_SUCCESS;
3486         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3487         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3488         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
3489
3490         pBtDbg->dbgHciInfo.hciCmdCntExtensionVersionNotify++;
3491         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "ExtensionVersionNotify, Hex Data :\n",
3492                         &pHciCmd->Data[0], pHciCmd->Length);
3493
3494         pBtMgnt->ExtConfig.HCIExtensionVer = *((u16 *)&pHciCmd->Data[0]);
3495         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = 0x%x\n", pBtMgnt->ExtConfig.HCIExtensionVer));
3496
3497         {
3498                 u8 localBuf[6] = "";
3499                 u8 *pRetPar;
3500                 u8 len = 0;
3501                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3502
3503                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3504
3505                 len += bthci_CommandCompleteHeader(&localBuf[0],
3506                         OGF_EXTENSION,
3507                         HCI_EXTENSION_VERSION_NOTIFY,
3508                         status);
3509
3510                 /*  Return parameters starts from here */
3511                 pRetPar = &PPacketIrpEvent->Data[len];
3512                 pRetPar[0] = status;            /* status */
3513
3514                 len += 1;
3515                 PPacketIrpEvent->Length = len;
3516
3517                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3518         }
3519
3520         return status;
3521 }
3522
3523 static enum hci_status
3524 bthci_CmdLinkStatusNotify(
3525         struct rtw_adapter *padapter,
3526         struct packet_irp_hcicmd_data *pHciCmd
3527         )
3528 {
3529         enum hci_status status = HCI_STATUS_SUCCESS;
3530         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3531         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3532         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
3533         u8 i;
3534         u8 *pTriple;
3535
3536         pBtDbg->dbgHciInfo.hciCmdCntLinkStatusNotify++;
3537         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "LinkStatusNotify, Hex Data :\n",
3538                         &pHciCmd->Data[0], pHciCmd->Length);
3539
3540         /*  Current only RTL8723 support this command. */
3541         pBtMgnt->bSupportProfile = true;
3542
3543         pBtMgnt->ExtConfig.NumberOfHandle = *((u8 *)pHciCmd->Data);
3544         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("NumberOfHandle = 0x%x\n", pBtMgnt->ExtConfig.NumberOfHandle));
3545         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCIExtensionVer = %d\n", pBtMgnt->ExtConfig.HCIExtensionVer));
3546
3547         pTriple = &pHciCmd->Data[1];
3548         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
3549                 if (pBtMgnt->ExtConfig.HCIExtensionVer < 1) {
3550                         pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]);
3551                         pBtMgnt->ExtConfig.linkInfo[i].BTProfile = pTriple[2];
3552                         pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = pTriple[3];
3553                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT,
3554                                 ("Connection_Handle = 0x%x, BTProfile =%d, BTSpec =%d\n",
3555                                 pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
3556                                 pBtMgnt->ExtConfig.linkInfo[i].BTProfile,
3557                                 pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec));
3558                         pTriple += 4;
3559                 } else if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
3560                         pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle = *((u16 *)&pTriple[0]);
3561                         pBtMgnt->ExtConfig.linkInfo[i].BTProfile = pTriple[2];
3562                         pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec = pTriple[3];
3563                         pBtMgnt->ExtConfig.linkInfo[i].linkRole = pTriple[4];
3564                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT,
3565                                 ("Connection_Handle = 0x%x, BTProfile =%d, BTSpec =%d, LinkRole =%d\n",
3566                                 pBtMgnt->ExtConfig.linkInfo[i].ConnectHandle,
3567                                 pBtMgnt->ExtConfig.linkInfo[i].BTProfile,
3568                                 pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec,
3569                                 pBtMgnt->ExtConfig.linkInfo[i].linkRole));
3570                         pTriple += 5;
3571                 }
3572
3573         }
3574         BTHCI_UpdateBTProfileRTKToMoto(padapter);
3575         {
3576                 u8 localBuf[6] = "";
3577                 u8 *pRetPar;
3578                 u8 len = 0;
3579                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3580
3581                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3582
3583                 len += bthci_CommandCompleteHeader(&localBuf[0],
3584                         OGF_EXTENSION,
3585                         HCI_LINK_STATUS_NOTIFY,
3586                         status);
3587
3588                 /*  Return parameters starts from here */
3589                 pRetPar = &PPacketIrpEvent->Data[len];
3590                 pRetPar[0] = status;            /* status */
3591
3592                 len += 1;
3593                 PPacketIrpEvent->Length = len;
3594
3595                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3596         }
3597
3598         return status;
3599 }
3600
3601 static enum hci_status
3602 bthci_CmdBtOperationNotify(
3603         struct rtw_adapter *padapter,
3604         struct packet_irp_hcicmd_data *pHciCmd
3605         )
3606 {
3607         enum hci_status status = HCI_STATUS_SUCCESS;
3608         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3609         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3610
3611         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "Bt Operation notify, Hex Data :\n",
3612                         &pHciCmd->Data[0], pHciCmd->Length);
3613
3614         pBtMgnt->ExtConfig.btOperationCode = *((u8 *)pHciCmd->Data);
3615         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("btOperationCode = 0x%x\n", pBtMgnt->ExtConfig.btOperationCode));
3616         switch (pBtMgnt->ExtConfig.btOperationCode) {
3617         case HCI_BT_OP_NONE:
3618                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Operation None!!\n"));
3619                 break;
3620         case HCI_BT_OP_INQUIRY_START:
3621                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Inquire start!!\n"));
3622                 break;
3623         case HCI_BT_OP_INQUIRY_FINISH:
3624                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Inquire finished!!\n"));
3625                 break;
3626         case HCI_BT_OP_PAGING_START:
3627                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging is started!!\n"));
3628                 break;
3629         case HCI_BT_OP_PAGING_SUCCESS:
3630                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging complete successfully!!\n"));
3631                 break;
3632         case HCI_BT_OP_PAGING_UNSUCCESS:
3633                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Paging complete unsuccessfully!!\n"));
3634                 break;
3635         case HCI_BT_OP_PAIRING_START:
3636                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Pairing start!!\n"));
3637                 break;
3638         case HCI_BT_OP_PAIRING_FINISH:
3639                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Pairing finished!!\n"));
3640                 break;
3641         case HCI_BT_OP_BT_DEV_ENABLE:
3642                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : BT Device is enabled!!\n"));
3643                 break;
3644         case HCI_BT_OP_BT_DEV_DISABLE:
3645                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : BT Device is disabled!!\n"));
3646                 break;
3647         default:
3648                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[bt operation] : Unknown, error!!\n"));
3649                 break;
3650         }
3651         BTDM_AdjustForBtOperation(padapter);
3652         {
3653                 u8 localBuf[6] = "";
3654                 u8 *pRetPar;
3655                 u8 len = 0;
3656                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3657
3658                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3659
3660                 len += bthci_CommandCompleteHeader(&localBuf[0],
3661                         OGF_EXTENSION,
3662                         HCI_BT_OPERATION_NOTIFY,
3663                         status);
3664
3665                 /*  Return parameters starts from here */
3666                 pRetPar = &PPacketIrpEvent->Data[len];
3667                 pRetPar[0] = status;            /* status */
3668
3669                 len += 1;
3670                 PPacketIrpEvent->Length = len;
3671
3672                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3673         }
3674
3675         return status;
3676 }
3677
3678 static enum hci_status
3679 bthci_CmdEnableWifiScanNotify(struct rtw_adapter *padapter,
3680                               struct packet_irp_hcicmd_data *pHciCmd)
3681 {
3682         enum hci_status status = HCI_STATUS_SUCCESS;
3683         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3684         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
3685
3686         RTPRINT_DATA(FIOCTL, IOCTL_BT_HCICMD_EXT, "Enable Wifi scan notify, Hex Data :\n",
3687                         &pHciCmd->Data[0], pHciCmd->Length);
3688
3689         pBtMgnt->ExtConfig.bEnableWifiScanNotify = *((u8 *)pHciCmd->Data);
3690         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("bEnableWifiScanNotify = %d\n", pBtMgnt->ExtConfig.bEnableWifiScanNotify));
3691
3692         {
3693                 u8 localBuf[6] = "";
3694                 u8 *pRetPar;
3695                 u8 len = 0;
3696                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3697
3698                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3699
3700                 len += bthci_CommandCompleteHeader(&localBuf[0],
3701                         OGF_EXTENSION,
3702                         HCI_ENABLE_WIFI_SCAN_NOTIFY,
3703                         status);
3704
3705                 /*  Return parameters starts from here */
3706                 pRetPar = &PPacketIrpEvent->Data[len];
3707                 pRetPar[0] = status;            /* status */
3708
3709                 len += 1;
3710                 PPacketIrpEvent->Length = len;
3711
3712                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3713         }
3714
3715         return status;
3716 }
3717
3718 static enum hci_status
3719 bthci_CmdWIFICurrentChannel(struct rtw_adapter *padapter,
3720                             struct packet_irp_hcicmd_data *pHciCmd)
3721 {
3722         enum hci_status status = HCI_STATUS_SUCCESS;
3723         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
3724         u8 chnl = pmlmeext->cur_channel;
3725
3726         if (pmlmeext->cur_bwmode == HT_CHANNEL_WIDTH_40) {
3727                 if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
3728                         chnl += 2;
3729                 else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
3730                         chnl -= 2;
3731         }
3732
3733         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Current Channel  = 0x%x\n", chnl));
3734
3735         {
3736                 u8 localBuf[8] = "";
3737                 u8 *pRetPar;
3738                 u8 len = 0;
3739                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3740
3741                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3742
3743                 len += bthci_CommandCompleteHeader(&localBuf[0],
3744                         OGF_EXTENSION,
3745                         HCI_WIFI_CURRENT_CHANNEL,
3746                         status);
3747
3748                 /*  Return parameters starts from here */
3749                 pRetPar = &PPacketIrpEvent->Data[len];
3750                 pRetPar[0] = status;            /* status */
3751                 pRetPar[1] = chnl;                      /* current channel */
3752                 len += 2;
3753                 PPacketIrpEvent->Length = len;
3754
3755                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3756         }
3757
3758         return status;
3759 }
3760
3761 static enum hci_status
3762 bthci_CmdWIFICurrentBandwidth(struct rtw_adapter *padapter,
3763                               struct packet_irp_hcicmd_data *pHciCmd)
3764 {
3765         enum hci_status status = HCI_STATUS_SUCCESS;
3766         enum ht_channel_width bw;
3767         u8 CurrentBW = 0;
3768
3769         bw = padapter->mlmeextpriv.cur_bwmode;
3770
3771         if (bw == HT_CHANNEL_WIDTH_20)
3772                 CurrentBW = 0;
3773         else if (bw == HT_CHANNEL_WIDTH_40)
3774                 CurrentBW = 1;
3775
3776         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("Current BW = 0x%x\n",
3777                 CurrentBW));
3778
3779         {
3780                 u8 localBuf[8] = "";
3781                 u8 *pRetPar;
3782                 u8 len = 0;
3783                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3784
3785                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3786
3787                 len += bthci_CommandCompleteHeader(&localBuf[0],
3788                         OGF_EXTENSION,
3789                         HCI_WIFI_CURRENT_BANDWIDTH,
3790                         status);
3791
3792                 /*  Return parameters starts from here */
3793                 pRetPar = &PPacketIrpEvent->Data[len];
3794                 pRetPar[0] = status;            /* status */
3795                 pRetPar[1] = CurrentBW;         /* current BW */
3796                 len += 2;
3797                 PPacketIrpEvent->Length = len;
3798
3799                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3800         }
3801
3802         return status;
3803 }
3804
3805 static enum hci_status
3806 bthci_CmdWIFIConnectionStatus(
3807         struct rtw_adapter *padapter,
3808         struct packet_irp_hcicmd_data *pHciCmd
3809         )
3810 {
3811         enum hci_status status = HCI_STATUS_SUCCESS;
3812         u8 connectStatus = HCI_WIFI_NOT_CONNECTED;
3813
3814         if (check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE)) {
3815                 if (padapter->stapriv.asoc_sta_count >= 3)
3816                         connectStatus = HCI_WIFI_CONNECTED;
3817                 else
3818                         connectStatus = HCI_WIFI_NOT_CONNECTED;
3819         } else if (check_fwstate(&padapter->mlmepriv, WIFI_ADHOC_STATE|WIFI_ADHOC_MASTER_STATE|WIFI_ASOC_STATE)) {
3820                 connectStatus = HCI_WIFI_CONNECTED;
3821         } else if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING)) {
3822                 connectStatus = HCI_WIFI_CONNECT_IN_PROGRESS;
3823         } else {
3824                 connectStatus = HCI_WIFI_NOT_CONNECTED;
3825         }
3826
3827         {
3828                 u8 localBuf[8] = "";
3829                 u8 *pRetPar;
3830                 u8 len = 0;
3831                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3832
3833                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3834
3835                 len += bthci_CommandCompleteHeader(&localBuf[0],
3836                         OGF_EXTENSION,
3837                         HCI_WIFI_CONNECTION_STATUS,
3838                         status);
3839
3840                 /*  Return parameters starts from here */
3841                 pRetPar = &PPacketIrpEvent->Data[len];
3842                 pRetPar[0] = status;                    /* status */
3843                 pRetPar[1] = connectStatus;     /* connect status */
3844                 len += 2;
3845                 PPacketIrpEvent->Length = len;
3846
3847                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3848         }
3849
3850         return status;
3851 }
3852
3853 static enum hci_status
3854 bthci_CmdEnableDeviceUnderTestMode(
3855         struct rtw_adapter *padapter,
3856         struct packet_irp_hcicmd_data *pHciCmd
3857         )
3858 {
3859         enum hci_status status = HCI_STATUS_SUCCESS;
3860         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3861         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
3862
3863         pBtHciInfo->bInTestMode = true;
3864         pBtHciInfo->bTestIsEnd = false;
3865
3866         /* send command complete event here when all data are received. */
3867         {
3868                 u8 localBuf[6] = "";
3869                 u8 *pRetPar;
3870                 u8 len = 0;
3871                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3872
3873                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3874
3875                 len += bthci_CommandCompleteHeader(&localBuf[0],
3876                         OGF_TESTING_COMMANDS,
3877                         HCI_ENABLE_DEVICE_UNDER_TEST_MODE,
3878                         status);
3879
3880                 /*  Return parameters starts from here */
3881                 pRetPar = &PPacketIrpEvent->Data[len];
3882                 pRetPar[0] = status;            /* status */
3883                 len += 1;
3884                 PPacketIrpEvent->Length = len;
3885
3886                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
3887         }
3888
3889         return status;
3890 }
3891
3892 static enum hci_status
3893 bthci_CmdAMPTestEnd(struct rtw_adapter *padapter,
3894                     struct packet_irp_hcicmd_data *pHciCmd)
3895 {
3896         enum hci_status status = HCI_STATUS_SUCCESS;
3897         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3898         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
3899
3900         if (!pBtHciInfo->bInTestMode) {
3901                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n"));
3902                 status = HCI_STATUS_CMD_DISALLOW;
3903                 return status;
3904         }
3905
3906         pBtHciInfo->bTestIsEnd = true;
3907
3908         del_timer_sync(&pBTInfo->BTTestSendPacketTimer);
3909
3910         rtl8723a_check_bssid(padapter, true);
3911
3912         /* send command complete event here when all data are received. */
3913         {
3914                 u8 localBuf[4] = "";
3915                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3916
3917                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("AMP Test End Event \n"));
3918                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3919                 PPacketIrpEvent->EventCode = HCI_EVENT_AMP_TEST_END;
3920                 PPacketIrpEvent->Length = 2;
3921
3922                 PPacketIrpEvent->Data[0] = status;
3923                 PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario;
3924
3925                 bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
3926         }
3927
3928         bthci_EventAMPReceiverReport(padapter, 0x01);
3929
3930         return status;
3931 }
3932
3933 static enum hci_status
3934 bthci_CmdAMPTestCommand(struct rtw_adapter *padapter,
3935                         struct packet_irp_hcicmd_data *pHciCmd)
3936 {
3937         enum hci_status status = HCI_STATUS_SUCCESS;
3938         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
3939         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
3940
3941         if (!pBtHciInfo->bInTestMode) {
3942                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Not in Test mode, return status = HCI_STATUS_CMD_DISALLOW\n"));
3943                 status = HCI_STATUS_CMD_DISALLOW;
3944                 return status;
3945         }
3946
3947         pBtHciInfo->TestScenario = *((u8 *)pHciCmd->Data);
3948
3949         if (pBtHciInfo->TestScenario == 0x01)
3950                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n"));
3951         else if (pBtHciInfo->TestScenario == 0x02)
3952                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n"));
3953         else
3954                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("No Such Test !!!!!!!!!!!!!!!!!! \n"));
3955
3956         if (pBtHciInfo->bTestIsEnd) {
3957                 u8 localBuf[5] = "";
3958                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3959
3960                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("AMP Test End Event \n"));
3961                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3962                 PPacketIrpEvent->EventCode = HCI_EVENT_AMP_TEST_END;
3963                 PPacketIrpEvent->Length = 2;
3964
3965                 PPacketIrpEvent->Data[0] = status;
3966                 PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario ;
3967
3968                 bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
3969
3970                 /* Return to Idel state with RX and TX off. */
3971
3972                 return status;
3973         }
3974
3975         /*  should send command status event */
3976         bthci_EventCommandStatus(padapter,
3977                         OGF_TESTING_COMMANDS,
3978                         HCI_AMP_TEST_COMMAND,
3979                         status);
3980
3981         /* The HCI_AMP_Start Test Event shall be generated when the */
3982         /* HCI_AMP_Test_Command has completed and the first data is ready to be sent */
3983         /* or received. */
3984
3985         {
3986                 u8 localBuf[5] = "";
3987                 struct packet_irp_hcievent_data *PPacketIrpEvent;
3988
3989                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), (" HCI_AMP_Start Test Event \n"));
3990                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
3991                 PPacketIrpEvent->EventCode = HCI_EVENT_AMP_START_TEST;
3992                 PPacketIrpEvent->Length = 2;
3993
3994                 PPacketIrpEvent->Data[0] = status;
3995                 PPacketIrpEvent->Data[1] = pBtHciInfo->TestScenario ;
3996
3997                 bthci_IndicateEvent(padapter, PPacketIrpEvent, 4);
3998
3999                 /* Return to Idel state with RX and TX off. */
4000         }
4001
4002         if (pBtHciInfo->TestScenario == 0x01) {
4003                 /*
4004                         When in a transmitter test scenario and the frames/bursts count have been
4005                         transmitted the HCI_AMP_Test_End event shall be sent.
4006                 */
4007                 mod_timer(&pBTInfo->BTTestSendPacketTimer,
4008                           jiffies + msecs_to_jiffies(50));
4009                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("TX Single Test \n"));
4010         } else if (pBtHciInfo->TestScenario == 0x02) {
4011                 rtl8723a_check_bssid(padapter, false);
4012                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_BT_LOGO), ("Receive Frame Test \n"));
4013         }
4014
4015         return status;
4016 }
4017
4018 static enum hci_status
4019 bthci_CmdEnableAMPReceiverReports(struct rtw_adapter *padapter,
4020                                   struct packet_irp_hcicmd_data *pHciCmd)
4021 {
4022         enum hci_status status = HCI_STATUS_SUCCESS;
4023         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4024         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
4025
4026         if (!pBtHciInfo->bInTestMode) {
4027                 status = HCI_STATUS_CMD_DISALLOW;
4028                 /* send command complete event here when all data are received. */
4029                 {
4030                         u8 localBuf[6] = "";
4031                         u8 *pRetPar;
4032                         u8 len = 0;
4033                         struct packet_irp_hcievent_data *PPacketIrpEvent;
4034
4035                         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
4036
4037                         len += bthci_CommandCompleteHeader(&localBuf[0],
4038                                 OGF_TESTING_COMMANDS,
4039                                 HCI_ENABLE_AMP_RECEIVER_REPORTS,
4040                                 status);
4041
4042                         /*  Return parameters starts from here */
4043                         pRetPar = &PPacketIrpEvent->Data[len];
4044                         pRetPar[0] = status;            /* status */
4045                         len += 1;
4046                         PPacketIrpEvent->Length = len;
4047
4048                         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
4049                 }
4050                 return status;
4051         }
4052
4053         pBtHciInfo->bTestNeedReport = *((u8 *)pHciCmd->Data);
4054         pBtHciInfo->TestReportInterval = (*((u8 *)pHciCmd->Data+2));
4055
4056         bthci_EventAMPReceiverReport(padapter, 0x00);
4057
4058         /* send command complete event here when all data are received. */
4059         {
4060                 u8 localBuf[6] = "";
4061                 u8 *pRetPar;
4062                 u8 len = 0;
4063                 struct packet_irp_hcievent_data *PPacketIrpEvent;
4064
4065                 PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
4066
4067                 len += bthci_CommandCompleteHeader(&localBuf[0],
4068                         OGF_TESTING_COMMANDS,
4069                         HCI_ENABLE_AMP_RECEIVER_REPORTS,
4070                         status);
4071
4072                 /*  Return parameters starts from here */
4073                 pRetPar = &PPacketIrpEvent->Data[len];
4074                 pRetPar[0] = status;            /* status */
4075                 len += 1;
4076                 PPacketIrpEvent->Length = len;
4077
4078                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
4079         }
4080
4081         return status;
4082 }
4083
4084 static enum hci_status
4085 bthci_CmdHostBufferSize(struct rtw_adapter *padapter,
4086                         struct packet_irp_hcicmd_data *pHciCmd)
4087 {
4088         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4089         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4090         struct packet_irp_hcievent_data *PPacketIrpEvent;
4091         enum hci_status status = HCI_STATUS_SUCCESS;
4092         u8 localBuf[6] = "";
4093         u8 *pRetPar;
4094         u8 len = 0;
4095
4096         pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].ACLPacketsData.ACLDataPacketLen = *((u16 *)pHciCmd->Data);
4097         pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].SyncDataPacketLen = *((u8 *)(pHciCmd->Data+2));
4098         pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].TotalNumACLDataPackets = *((u16 *)(pHciCmd->Data+3));
4099         pBTInfo->BtAsocEntry[pBtMgnt->CurrentConnectEntryNum].TotalSyncNumDataPackets = *((u16 *)(pHciCmd->Data+5));
4100
4101         /* send command complete event here when all data are received. */
4102         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
4103
4104         len += bthci_CommandCompleteHeader(&localBuf[0],
4105                 OGF_SET_EVENT_MASK_COMMAND,
4106                 HCI_HOST_BUFFER_SIZE,
4107                 status);
4108
4109         /*  Return parameters starts from here */
4110         pRetPar = &PPacketIrpEvent->Data[len];
4111         pRetPar[0] = status;            /* status */
4112         len += 1;
4113         PPacketIrpEvent->Length = len;
4114
4115         bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
4116
4117         return status;
4118 }
4119
4120 static enum hci_status
4121 bthci_UnknownCMD(struct rtw_adapter *padapter, struct packet_irp_hcicmd_data *pHciCmd)
4122 {
4123         enum hci_status status = HCI_STATUS_UNKNOW_HCI_CMD;
4124         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4125         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
4126
4127         pBtDbg->dbgHciInfo.hciCmdCntUnknown++;
4128         bthci_EventCommandStatus(padapter,
4129                         (u8)pHciCmd->OGF,
4130                         pHciCmd->OCF,
4131                         status);
4132
4133         return status;
4134 }
4135
4136 static enum hci_status
4137 bthci_HandleOGFInformationalParameters(struct rtw_adapter *padapter,
4138                                        struct packet_irp_hcicmd_data *pHciCmd)
4139 {
4140         enum hci_status status = HCI_STATUS_SUCCESS;
4141
4142         switch (pHciCmd->OCF) {
4143         case HCI_READ_LOCAL_VERSION_INFORMATION:
4144                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_VERSION_INFORMATION\n"));
4145                 status = bthci_CmdReadLocalVersionInformation(padapter);
4146                 break;
4147         case HCI_READ_LOCAL_SUPPORTED_COMMANDS:
4148                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_SUPPORTED_COMMANDS\n"));
4149                 status = bthci_CmdReadLocalSupportedCommands(padapter);
4150                 break;
4151         case HCI_READ_LOCAL_SUPPORTED_FEATURES:
4152                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_SUPPORTED_FEATURES\n"));
4153                 status = bthci_CmdReadLocalSupportedFeatures(padapter);
4154                 break;
4155         case HCI_READ_BUFFER_SIZE:
4156                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_BUFFER_SIZE\n"));
4157                 status = bthci_CmdReadBufferSize(padapter);
4158                 break;
4159         case HCI_READ_DATA_BLOCK_SIZE:
4160                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_DATA_BLOCK_SIZE\n"));
4161                 status = bthci_CmdReadDataBlockSize(padapter);
4162                 break;
4163         default:
4164                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFInformationalParameters(), Unknown case = 0x%x\n", pHciCmd->OCF));
4165                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
4166                 status = bthci_UnknownCMD(padapter, pHciCmd);
4167                 break;
4168         }
4169         return status;
4170 }
4171
4172 static enum hci_status
4173 bthci_HandleOGFSetEventMaskCMD(struct rtw_adapter *padapter,
4174                                struct packet_irp_hcicmd_data *pHciCmd)
4175 {
4176         enum hci_status status = HCI_STATUS_SUCCESS;
4177
4178         switch (pHciCmd->OCF) {
4179         case HCI_SET_EVENT_MASK:
4180                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_MASK\n"));
4181                 status = bthci_CmdSetEventMask(padapter, pHciCmd);
4182                 break;
4183         case HCI_RESET:
4184                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_RESET\n"));
4185                 status = bthci_CmdReset(padapter, true);
4186                 break;
4187         case HCI_READ_CONNECTION_ACCEPT_TIMEOUT:
4188                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_CONNECTION_ACCEPT_TIMEOUT\n"));
4189                 status = bthci_CmdReadConnectionAcceptTimeout(padapter);
4190                 break;
4191         case HCI_SET_EVENT_FILTER:
4192                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_FILTER\n"));
4193                 break;
4194         case HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT:
4195                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_CONNECTION_ACCEPT_TIMEOUT\n"));
4196                 status = bthci_CmdWriteConnectionAcceptTimeout(padapter, pHciCmd);
4197                 break;
4198         case HCI_READ_PAGE_TIMEOUT:
4199                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_PAGE_TIMEOUT\n"));
4200                 status = bthci_CmdReadPageTimeout(padapter, pHciCmd);
4201                 break;
4202         case HCI_WRITE_PAGE_TIMEOUT:
4203                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_PAGE_TIMEOUT\n"));
4204                 status = bthci_CmdWritePageTimeout(padapter, pHciCmd);
4205                 break;
4206         case HCI_HOST_NUMBER_OF_COMPLETED_PACKETS:
4207                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_NUMBER_OF_COMPLETED_PACKETS\n"));
4208                 break;
4209         case HCI_READ_LINK_SUPERVISION_TIMEOUT:
4210                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_SUPERVISION_TIMEOUT\n"));
4211                 status = bthci_CmdReadLinkSupervisionTimeout(padapter, pHciCmd);
4212                 break;
4213         case HCI_WRITE_LINK_SUPERVISION_TIMEOUT:
4214                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LINK_SUPERVISION_TIMEOUT\n"));
4215                 status = bthci_CmdWriteLinkSupervisionTimeout(padapter, pHciCmd);
4216                 break;
4217         case HCI_ENHANCED_FLUSH:
4218                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENHANCED_FLUSH\n"));
4219                 status = bthci_CmdEnhancedFlush(padapter, pHciCmd);
4220                 break;
4221         case HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT:
4222                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOGICAL_LINK_ACCEPT_TIMEOUT\n"));
4223                 status = bthci_CmdReadLogicalLinkAcceptTimeout(padapter, pHciCmd);
4224                 break;
4225         case HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT:
4226                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LOGICAL_LINK_ACCEPT_TIMEOUT\n"));
4227                 status = bthci_CmdWriteLogicalLinkAcceptTimeout(padapter, pHciCmd);
4228                 break;
4229         case HCI_SET_EVENT_MASK_PAGE_2:
4230                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SET_EVENT_MASK_PAGE_2\n"));
4231                 status = bthci_CmdSetEventMaskPage2(padapter, pHciCmd);
4232                 break;
4233         case HCI_READ_LOCATION_DATA:
4234                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCATION_DATA\n"));
4235                 status = bthci_CmdReadLocationData(padapter, pHciCmd);
4236                 break;
4237         case HCI_WRITE_LOCATION_DATA:
4238                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_LOCATION_DATA\n"));
4239                 status = bthci_CmdWriteLocationData(padapter, pHciCmd);
4240                 break;
4241         case HCI_READ_FLOW_CONTROL_MODE:
4242                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_FLOW_CONTROL_MODE\n"));
4243                 status = bthci_CmdReadFlowControlMode(padapter, pHciCmd);
4244                 break;
4245         case HCI_WRITE_FLOW_CONTROL_MODE:
4246                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_FLOW_CONTROL_MODE\n"));
4247                 status = bthci_CmdWriteFlowControlMode(padapter, pHciCmd);
4248                 break;
4249         case HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT:
4250                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_BEST_EFFORT_FLUSH_TIMEOUT\n"));
4251                 status = bthci_CmdReadBestEffortFlushTimeout(padapter, pHciCmd);
4252                 break;
4253         case HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT:
4254                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_BEST_EFFORT_FLUSH_TIMEOUT\n"));
4255                 status = bthci_CmdWriteBestEffortFlushTimeout(padapter, pHciCmd);
4256                 break;
4257         case HCI_SHORT_RANGE_MODE:
4258                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_SHORT_RANGE_MODE\n"));
4259                 status = bthci_CmdShortRangeMode(padapter, pHciCmd);
4260                 break;
4261         case HCI_HOST_BUFFER_SIZE:
4262                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_HOST_BUFFER_SIZE\n"));
4263                 status = bthci_CmdHostBufferSize(padapter, pHciCmd);
4264                 break;
4265         default:
4266                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFSetEventMaskCMD(), Unknown case = 0x%x\n", pHciCmd->OCF));
4267                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
4268                 status = bthci_UnknownCMD(padapter, pHciCmd);
4269                 break;
4270         }
4271         return status;
4272 }
4273
4274 static enum hci_status
4275 bthci_HandleOGFStatusParameters(struct rtw_adapter *padapter,
4276                                 struct packet_irp_hcicmd_data *pHciCmd)
4277 {
4278         enum hci_status status = HCI_STATUS_SUCCESS;
4279
4280         switch (pHciCmd->OCF) {
4281         case HCI_READ_FAILED_CONTACT_COUNTER:
4282                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_FAILED_CONTACT_COUNTER\n"));
4283                 status = bthci_CmdReadFailedContactCounter(padapter, pHciCmd);
4284                 break;
4285         case HCI_RESET_FAILED_CONTACT_COUNTER:
4286                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_RESET_FAILED_CONTACT_COUNTER\n"));
4287                 status = bthci_CmdResetFailedContactCounter(padapter, pHciCmd);
4288                 break;
4289         case HCI_READ_LINK_QUALITY:
4290                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LINK_QUALITY\n"));
4291                 status = bthci_CmdReadLinkQuality(padapter, pHciCmd);
4292                 break;
4293         case HCI_READ_RSSI:
4294                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_RSSI\n"));
4295                 break;
4296         case HCI_READ_LOCAL_AMP_INFO:
4297                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_INFO\n"));
4298                 status = bthci_CmdReadLocalAMPInfo(padapter);
4299                 break;
4300         case HCI_READ_LOCAL_AMP_ASSOC:
4301                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_READ_LOCAL_AMP_ASSOC\n"));
4302                 status = bthci_CmdReadLocalAMPAssoc(padapter, pHciCmd);
4303                 break;
4304         case HCI_WRITE_REMOTE_AMP_ASSOC:
4305                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_WRITE_REMOTE_AMP_ASSOC\n"));
4306                 status = bthci_CmdWriteRemoteAMPAssoc(padapter, pHciCmd);
4307                 break;
4308         default:
4309                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFStatusParameters(), Unknown case = 0x%x\n", pHciCmd->OCF));
4310                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
4311                 status = bthci_UnknownCMD(padapter, pHciCmd);
4312                 break;
4313         }
4314         return status;
4315 }
4316
4317 static enum hci_status
4318 bthci_HandleOGFLinkControlCMD(struct rtw_adapter *padapter,
4319                               struct packet_irp_hcicmd_data *pHciCmd)
4320 {
4321         enum hci_status status = HCI_STATUS_SUCCESS;
4322
4323         switch (pHciCmd->OCF) {
4324         case HCI_CREATE_PHYSICAL_LINK:
4325                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_CREATE_PHYSICAL_LINK\n"));
4326                 status = bthci_CmdCreatePhysicalLink(padapter, pHciCmd);
4327                 break;
4328         case HCI_ACCEPT_PHYSICAL_LINK:
4329                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ACCEPT_PHYSICAL_LINK\n"));
4330                 status = bthci_CmdAcceptPhysicalLink(padapter, pHciCmd);
4331                 break;
4332         case HCI_DISCONNECT_PHYSICAL_LINK:
4333                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_PHYSICAL_LINK\n"));
4334                 status = bthci_CmdDisconnectPhysicalLink(padapter, pHciCmd);
4335                 break;
4336         case HCI_CREATE_LOGICAL_LINK:
4337                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_CREATE_LOGICAL_LINK\n"));
4338                 status = bthci_CmdCreateLogicalLink(padapter, pHciCmd);
4339                 break;
4340         case HCI_ACCEPT_LOGICAL_LINK:
4341                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ACCEPT_LOGICAL_LINK\n"));
4342                 status = bthci_CmdAcceptLogicalLink(padapter, pHciCmd);
4343                 break;
4344         case HCI_DISCONNECT_LOGICAL_LINK:
4345                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_DISCONNECT_LOGICAL_LINK\n"));
4346                 status = bthci_CmdDisconnectLogicalLink(padapter, pHciCmd);
4347                 break;
4348         case HCI_LOGICAL_LINK_CANCEL:
4349                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_LOGICAL_LINK_CANCEL\n"));
4350                 status = bthci_CmdLogicalLinkCancel(padapter, pHciCmd);
4351                 break;
4352         case HCI_FLOW_SPEC_MODIFY:
4353                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_FLOW_SPEC_MODIFY\n"));
4354                 status = bthci_CmdFlowSpecModify(padapter, pHciCmd);
4355                 break;
4356         default:
4357                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("bthci_HandleOGFLinkControlCMD(), Unknown case = 0x%x\n", pHciCmd->OCF));
4358                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
4359                 status = bthci_UnknownCMD(padapter, pHciCmd);
4360                 break;
4361         }
4362         return status;
4363 }
4364
4365 static enum hci_status
4366 bthci_HandleOGFTestingCMD(struct rtw_adapter *padapter,
4367                           struct packet_irp_hcicmd_data *pHciCmd)
4368 {
4369         enum hci_status status = HCI_STATUS_SUCCESS;
4370         switch (pHciCmd->OCF) {
4371         case HCI_ENABLE_DEVICE_UNDER_TEST_MODE:
4372                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENABLE_DEVICE_UNDER_TEST_MODE\n"));
4373                 bthci_CmdEnableDeviceUnderTestMode(padapter, pHciCmd);
4374                 break;
4375         case HCI_AMP_TEST_END:
4376                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_AMP_TEST_END\n"));
4377                 bthci_CmdAMPTestEnd(padapter, pHciCmd);
4378                 break;
4379         case HCI_AMP_TEST_COMMAND:
4380                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_AMP_TEST_COMMAND\n"));
4381                 bthci_CmdAMPTestCommand(padapter, pHciCmd);
4382                 break;
4383         case HCI_ENABLE_AMP_RECEIVER_REPORTS:
4384                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_ENABLE_AMP_RECEIVER_REPORTS\n"));
4385                 bthci_CmdEnableAMPReceiverReports(padapter, pHciCmd);
4386                 break;
4387         default:
4388                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
4389                 status = bthci_UnknownCMD(padapter, pHciCmd);
4390                 break;
4391         }
4392         return status;
4393 }
4394
4395 static enum hci_status
4396 bthci_HandleOGFExtension(struct rtw_adapter *padapter,
4397                          struct packet_irp_hcicmd_data *pHciCmd)
4398 {
4399         enum hci_status status = HCI_STATUS_SUCCESS;
4400         switch (pHciCmd->OCF) {
4401         case HCI_SET_ACL_LINK_DATA_FLOW_MODE:
4402                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_ACL_LINK_DATA_FLOW_MODE\n"));
4403                 status = bthci_CmdSetACLLinkDataFlowMode(padapter, pHciCmd);
4404                 break;
4405         case HCI_SET_ACL_LINK_STATUS:
4406                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_ACL_LINK_STATUS\n"));
4407                 status = bthci_CmdSetACLLinkStatus(padapter, pHciCmd);
4408                 break;
4409         case HCI_SET_SCO_LINK_STATUS:
4410                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_SCO_LINK_STATUS\n"));
4411                 status = bthci_CmdSetSCOLinkStatus(padapter, pHciCmd);
4412                 break;
4413         case HCI_SET_RSSI_VALUE:
4414                 RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, ("HCI_SET_RSSI_VALUE\n"));
4415                 status = bthci_CmdSetRSSIValue(padapter, pHciCmd);
4416                 break;
4417         case HCI_SET_CURRENT_BLUETOOTH_STATUS:
4418                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_SET_CURRENT_BLUETOOTH_STATUS\n"));
4419                 status = bthci_CmdSetCurrentBluetoothStatus(padapter, pHciCmd);
4420                 break;
4421         /* The following is for RTK8723 */
4422
4423         case HCI_EXTENSION_VERSION_NOTIFY:
4424                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_EXTENSION_VERSION_NOTIFY\n"));
4425                 status = bthci_CmdExtensionVersionNotify(padapter, pHciCmd);
4426                 break;
4427         case HCI_LINK_STATUS_NOTIFY:
4428                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_LINK_STATUS_NOTIFY\n"));
4429                 status = bthci_CmdLinkStatusNotify(padapter, pHciCmd);
4430                 break;
4431         case HCI_BT_OPERATION_NOTIFY:
4432                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_BT_OPERATION_NOTIFY\n"));
4433                 status = bthci_CmdBtOperationNotify(padapter, pHciCmd);
4434                 break;
4435         case HCI_ENABLE_WIFI_SCAN_NOTIFY:
4436                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_ENABLE_WIFI_SCAN_NOTIFY\n"));
4437                 status = bthci_CmdEnableWifiScanNotify(padapter, pHciCmd);
4438                 break;
4439
4440         /* The following is for IVT */
4441         case HCI_WIFI_CURRENT_CHANNEL:
4442                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CURRENT_CHANNEL\n"));
4443                 status = bthci_CmdWIFICurrentChannel(padapter, pHciCmd);
4444                 break;
4445         case HCI_WIFI_CURRENT_BANDWIDTH:
4446                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CURRENT_BANDWIDTH\n"));
4447                 status = bthci_CmdWIFICurrentBandwidth(padapter, pHciCmd);
4448                 break;
4449         case HCI_WIFI_CONNECTION_STATUS:
4450                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_WIFI_CONNECTION_STATUS\n"));
4451                 status = bthci_CmdWIFIConnectionStatus(padapter, pHciCmd);
4452                 break;
4453
4454         default:
4455                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("HCI_UNKNOWN_COMMAND\n"));
4456                 status = bthci_UnknownCMD(padapter, pHciCmd);
4457                 break;
4458         }
4459         return status;
4460 }
4461
4462 static void
4463 bthci_StateStarting(struct rtw_adapter *padapter,
4464                     enum hci_state_with_cmd StateCmd, u8 EntryNum)
4465 {
4466         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4467         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4468
4469         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Starting], "));
4470         switch (StateCmd) {
4471         case STATE_CMD_CONNECT_ACCEPT_TIMEOUT:
4472                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n"));
4473                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT;
4474                 pBtMgnt->bNeedNotifyAMPNoCap = true;
4475                 BTHCI_DisconnectPeer(padapter, EntryNum);
4476                 break;
4477         case STATE_CMD_DISCONNECT_PHY_LINK:
4478                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
4479
4480                 bthci_EventDisconnectPhyLinkComplete(padapter,
4481                 HCI_STATUS_SUCCESS,
4482                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
4483                 EntryNum);
4484
4485                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4486
4487                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID;
4488
4489                 BTHCI_DisconnectPeer(padapter, EntryNum);
4490                 break;
4491         case STATE_CMD_MAC_START_COMPLETE:
4492                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_START_COMPLETE\n"));
4493                 if (pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_CREATOR)
4494                         bthci_EventChannelSelected(padapter, EntryNum);
4495                 break;
4496         default:
4497                 RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
4498                 break;
4499         }
4500 }
4501
4502 static void
4503 bthci_StateConnecting(struct rtw_adapter *padapter,
4504                       enum hci_state_with_cmd StateCmd, u8 EntryNum)
4505 {
4506         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4507         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4508
4509         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Connecting], "));
4510         switch (StateCmd) {
4511         case STATE_CMD_CONNECT_ACCEPT_TIMEOUT:
4512                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n"));
4513                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT;
4514                 pBtMgnt->bNeedNotifyAMPNoCap = true;
4515                 BTHCI_DisconnectPeer(padapter, EntryNum);
4516                 break;
4517         case STATE_CMD_MAC_CONNECT_COMPLETE:
4518                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_COMPLETE\n"));
4519
4520                 if (pBTInfo->BtAsocEntry[EntryNum].AMPRole == AMP_BTAP_JOINER) {
4521                         RT_TRACE(_module_rtl871x_security_c_,
4522                                  _drv_info_, ("StateConnecting \n"));
4523                 }
4524                 break;
4525         case STATE_CMD_DISCONNECT_PHY_LINK:
4526                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
4527
4528                 bthci_EventDisconnectPhyLinkComplete(padapter,
4529                 HCI_STATUS_SUCCESS,
4530                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
4531                 EntryNum);
4532
4533                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID;
4534
4535                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4536
4537                 BTHCI_DisconnectPeer(padapter, EntryNum);
4538
4539                 break;
4540         case STATE_CMD_MAC_CONNECT_CANCEL_INDICATE:
4541                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_CANCEL_INDICATE\n"));
4542                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONTROLLER_BUSY;
4543                 /*  Because this state cmd is caused by the BTHCI_EventAMPStatusChange(), */
4544                 /*  we don't need to send event in the following BTHCI_DisconnectPeer() again. */
4545                 pBtMgnt->bNeedNotifyAMPNoCap = false;
4546                 BTHCI_DisconnectPeer(padapter, EntryNum);
4547                 break;
4548         default:
4549                 RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
4550                 break;
4551         }
4552 }
4553
4554 static void
4555 bthci_StateConnected(struct rtw_adapter *padapter,
4556                      enum hci_state_with_cmd StateCmd, u8 EntryNum)
4557 {
4558 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
4559         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4560         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4561         u8 i;
4562         u16 logicHandle = 0;
4563
4564         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Connected], "));
4565         switch (StateCmd) {
4566         case STATE_CMD_DISCONNECT_PHY_LINK:
4567                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
4568
4569                 /* When we are trying to disconnect the phy link, we should disconnect log link first, */
4570                 for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
4571                         if (pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle != 0) {
4572                                 logicHandle = pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle;
4573
4574                                 bthci_EventDisconnectLogicalLinkComplete(padapter, HCI_STATUS_SUCCESS,
4575                                         logicHandle, pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason);
4576
4577                                 pBTInfo->BtAsocEntry[EntryNum].LogLinkCmdData->BtLogLinkhandle = 0;
4578                         }
4579                 }
4580
4581                 bthci_EventDisconnectPhyLinkComplete(padapter,
4582                 HCI_STATUS_SUCCESS,
4583                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
4584                 EntryNum);
4585
4586                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4587
4588                 BTHCI_DisconnectPeer(padapter, EntryNum);
4589                 break;
4590
4591         case STATE_CMD_MAC_DISCONNECT_INDICATE:
4592                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_DISCONNECT_INDICATE\n"));
4593
4594                 bthci_EventDisconnectPhyLinkComplete(padapter,
4595                 HCI_STATUS_SUCCESS,
4596                 /*  TODO: Remote Host not local host */
4597                 HCI_STATUS_CONNECT_TERMINATE_LOCAL_HOST,
4598                 EntryNum);
4599                 BTHCI_DisconnectPeer(padapter, EntryNum);
4600
4601                 break;
4602         case STATE_CMD_ENTER_STATE:
4603                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ENTER_STATE\n"));
4604
4605                 if (pBtMgnt->bBTConnectInProgress) {
4606                         pBtMgnt->bBTConnectInProgress = false;
4607                         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
4608                 }
4609                 pBTInfo->BtAsocEntry[EntryNum].BtCurrentState = HCI_STATE_CONNECTED;
4610                 pBTInfo->BtAsocEntry[EntryNum].b4waySuccess = true;
4611                 pBtMgnt->bStartSendSupervisionPkt = true;
4612
4613                 /*  for rate adaptive */
4614
4615                 rtl8723a_update_ramask(padapter,
4616                                        MAX_FW_SUPPORT_MACID_NUM-1-EntryNum, 0);
4617
4618                 HalSetBrateCfg23a(padapter, padapter->mlmepriv.cur_network.network.SupportedRates);
4619                 BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT);
4620                 break;
4621         default:
4622                 RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
4623                 break;
4624         }
4625 }
4626
4627 static void
4628 bthci_StateAuth(struct rtw_adapter *padapter, enum hci_state_with_cmd StateCmd,
4629                 u8 EntryNum)
4630 {
4631         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4632         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4633
4634         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Authenticating], "));
4635         switch (StateCmd) {
4636         case STATE_CMD_CONNECT_ACCEPT_TIMEOUT:
4637                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CONNECT_ACCEPT_TIMEOUT\n"));
4638                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_CONNECT_ACCEPT_TIMEOUT;
4639                 pBtMgnt->bNeedNotifyAMPNoCap = true;
4640                 BTHCI_DisconnectPeer(padapter, EntryNum);
4641                 break;
4642         case STATE_CMD_DISCONNECT_PHY_LINK:
4643                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
4644                 bthci_EventDisconnectPhyLinkComplete(padapter,
4645                 HCI_STATUS_SUCCESS,
4646                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
4647                 EntryNum);
4648
4649                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_UNKNOW_CONNECT_ID;
4650
4651                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4652
4653                 BTHCI_DisconnectPeer(padapter, EntryNum);
4654                 break;
4655         case STATE_CMD_4WAY_FAILED:
4656                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_4WAY_FAILED\n"));
4657
4658                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus = HCI_STATUS_AUTH_FAIL;
4659                 pBtMgnt->bNeedNotifyAMPNoCap = true;
4660
4661                 BTHCI_DisconnectPeer(padapter, EntryNum);
4662
4663                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4664                 break;
4665         case STATE_CMD_4WAY_SUCCESSED:
4666                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_4WAY_SUCCESSED\n"));
4667
4668                 bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_SUCCESS, EntryNum, INVALID_PL_HANDLE);
4669
4670                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4671
4672                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTED, STATE_CMD_ENTER_STATE, EntryNum);
4673                 break;
4674         default:
4675                 RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
4676                 break;
4677         }
4678 }
4679
4680 static void
4681 bthci_StateDisconnecting(struct rtw_adapter *padapter,
4682                          enum hci_state_with_cmd StateCmd, u8 EntryNum)
4683 {
4684         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4685         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4686
4687         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Disconnecting], "));
4688         switch (StateCmd) {
4689         case STATE_CMD_MAC_CONNECT_CANCEL_INDICATE:
4690                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_MAC_CONNECT_CANCEL_INDICATE\n"));
4691                 if (pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent) {
4692                         bthci_EventPhysicalLinkComplete(padapter,
4693                                 pBTInfo->BtAsocEntry[EntryNum].PhysLinkCompleteStatus,
4694                                 EntryNum, INVALID_PL_HANDLE);
4695                 }
4696
4697                 if (pBtMgnt->bBTConnectInProgress) {
4698                         pBtMgnt->bBTConnectInProgress = false;
4699                         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
4700                 }
4701
4702                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ENTER_STATE, EntryNum);
4703                 break;
4704         case STATE_CMD_DISCONNECT_PHY_LINK:
4705                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
4706
4707                 bthci_EventDisconnectPhyLinkComplete(padapter,
4708                 HCI_STATUS_SUCCESS,
4709                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
4710                 EntryNum);
4711
4712                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4713
4714                 BTHCI_DisconnectPeer(padapter, EntryNum);
4715                 break;
4716         default:
4717                 RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
4718                 break;
4719         }
4720 }
4721
4722 static void
4723 bthci_StateDisconnected(struct rtw_adapter *padapter,
4724                         enum hci_state_with_cmd StateCmd, u8 EntryNum)
4725 {
4726 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
4727         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4728         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
4729         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4730
4731         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT state], [Disconnected], "));
4732         switch (StateCmd) {
4733         case STATE_CMD_CREATE_PHY_LINK:
4734         case STATE_CMD_ACCEPT_PHY_LINK:
4735                 if (StateCmd == STATE_CMD_CREATE_PHY_LINK)
4736                         RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_CREATE_PHY_LINK\n"));
4737                 else
4738                         RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ACCEPT_PHY_LINK\n"));
4739
4740                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT PS], Disable IPS and LPS\n"));
4741                 ips_leave23a(padapter);
4742                 LPS_Leave23a(padapter);
4743
4744                 pBtMgnt->bPhyLinkInProgress = true;
4745                 pBtMgnt->BTCurrentConnectType = BT_DISCONNECT;
4746                 pBtMgnt->CurrentBTConnectionCnt++;
4747                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], CurrentBTConnectionCnt = %d\n",
4748                         pBtMgnt->CurrentBTConnectionCnt));
4749                 pBtMgnt->BtOperationOn = true;
4750                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], Bt Operation ON!! CurrentConnectEntryNum = %d\n",
4751                         pBtMgnt->CurrentConnectEntryNum));
4752
4753                 if (pBtMgnt->bBTConnectInProgress) {
4754                         bthci_EventPhysicalLinkComplete(padapter, HCI_STATUS_CONTROLLER_BUSY, INVALID_ENTRY_NUM, pBtMgnt->BtCurrentPhyLinkhandle);
4755                         bthci_RemoveEntryByEntryNum(padapter, EntryNum);
4756                         return;
4757                 }
4758
4759                 if (StateCmd == STATE_CMD_CREATE_PHY_LINK)
4760                         pBTInfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_CREATOR;
4761                 else
4762                         pBTInfo->BtAsocEntry[EntryNum].AMPRole = AMP_BTAP_JOINER;
4763
4764                 /*  1. MAC not yet in selected channel */
4765                 while (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE|WIFI_SITE_MONITOR)) {
4766                         RTPRINT(FIOCTL, IOCTL_STATE, ("Scan/Roaming/Wifi Link is in Progress, wait 200 ms\n"));
4767                         mdelay(200);
4768                 }
4769                 /*  2. MAC already in selected channel */
4770                 RTPRINT(FIOCTL, IOCTL_STATE, ("Channel is Ready\n"));
4771                 mod_timer(&pBTInfo->BTHCIJoinTimeoutTimer,
4772                           jiffies + msecs_to_jiffies(pBtHciInfo->ConnAcceptTimeout));
4773
4774                 pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent = true;
4775                 break;
4776         case STATE_CMD_DISCONNECT_PHY_LINK:
4777                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_DISCONNECT_PHY_LINK\n"));
4778
4779                 del_timer_sync(&pBTInfo->BTHCIJoinTimeoutTimer);
4780
4781                 bthci_EventDisconnectPhyLinkComplete(padapter,
4782                 HCI_STATUS_SUCCESS,
4783                 pBTInfo->BtAsocEntry[EntryNum].PhyLinkDisconnectReason,
4784                 EntryNum);
4785
4786                 if (pBTInfo->BtAsocEntry[EntryNum].bNeedPhysLinkCompleteEvent) {
4787                         bthci_EventPhysicalLinkComplete(padapter,
4788                                 HCI_STATUS_UNKNOW_CONNECT_ID,
4789                                 EntryNum, INVALID_PL_HANDLE);
4790                 }
4791
4792                 if (pBtMgnt->bBTConnectInProgress) {
4793                         pBtMgnt->bBTConnectInProgress = false;
4794                         RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
4795                 }
4796                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTED, STATE_CMD_ENTER_STATE, EntryNum);
4797                 bthci_RemoveEntryByEntryNum(padapter, EntryNum);
4798                 break;
4799         case STATE_CMD_ENTER_STATE:
4800                 RTPRINT(FIOCTL, IOCTL_STATE, ("STATE_CMD_ENTER_STATE\n"));
4801                 break;
4802         default:
4803                 RTPRINT(FIOCTL, IOCTL_STATE, ("State command(%d) is Wrong !!!\n", StateCmd));
4804                 break;
4805         }
4806 }
4807
4808 void BTHCI_EventParse(struct rtw_adapter *padapter, void *pEvntData, u32 dataLen)
4809 {
4810 }
4811
4812 u8 BTHCI_HsConnectionEstablished(struct rtw_adapter *padapter)
4813 {
4814         u8 bBtConnectionExist = false;
4815         struct bt_30info *pBtinfo = GET_BT_INFO(padapter);
4816         u8 i;
4817
4818         for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
4819                 if (pBtinfo->BtAsocEntry[i].b4waySuccess) {
4820                         bBtConnectionExist = true;
4821                         break;
4822                 }
4823         }
4824
4825 /*RTPRINT(FIOCTL, IOCTL_STATE, (" BTHCI_HsConnectionEstablished(), connection exist = %d\n", bBtConnectionExist)); */
4826
4827         return bBtConnectionExist;
4828 }
4829
4830 static u8
4831 BTHCI_CheckProfileExist(struct rtw_adapter *padapter,
4832                         enum bt_traffic_mode_profile Profile)
4833 {
4834         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4835         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4836         u8 IsPRofile = false;
4837         u8 i = 0;
4838
4839         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
4840                 if (pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile == Profile) {
4841                         IsPRofile = true;
4842                         break;
4843                 }
4844         }
4845
4846         return IsPRofile;
4847 }
4848
4849 void BTHCI_UpdateBTProfileRTKToMoto(struct rtw_adapter *padapter)
4850 {
4851         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4852         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4853         u8 i = 0;
4854
4855         pBtMgnt->ExtConfig.NumberOfSCO = 0;
4856
4857         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
4858                 pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = BT_PROFILE_NONE;
4859
4860                 if (pBtMgnt->ExtConfig.linkInfo[i].BTProfile == BT_PROFILE_SCO)
4861                         pBtMgnt->ExtConfig.NumberOfSCO++;
4862
4863                 pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile = pBtMgnt->ExtConfig.linkInfo[i].BTProfile;
4864                 switch (pBtMgnt->ExtConfig.linkInfo[i].TrafficProfile) {
4865                 case BT_PROFILE_SCO:
4866                         break;
4867                 case BT_PROFILE_PAN:
4868                         pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_BE;
4869                         pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_BE;
4870                         break;
4871                 case BT_PROFILE_A2DP:
4872                         pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_GULB;
4873                         pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_GULB;
4874                         break;
4875                 case BT_PROFILE_HID:
4876                         pBtMgnt->ExtConfig.linkInfo[i].IncomingTrafficMode = BT_MOTOR_EXT_GUL;
4877                         pBtMgnt->ExtConfig.linkInfo[i].OutgoingTrafficMode = BT_MOTOR_EXT_BE;
4878                         break;
4879                 default:
4880                         break;
4881                 }
4882         }
4883
4884         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RTK, NumberOfHandle = %d, NumberOfSCO = %d\n",
4885                 pBtMgnt->ExtConfig.NumberOfHandle, pBtMgnt->ExtConfig.NumberOfSCO));
4886 }
4887
4888 void BTHCI_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
4889 {
4890         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4891         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4892
4893         if (pBtMgnt->ExtConfig.bEnableWifiScanNotify)
4894                 bthci_EventExtWifiScanNotify(padapter, scanType);
4895 }
4896
4897 void
4898 BTHCI_StateMachine(
4899         struct rtw_adapter *padapter,
4900         u8              StateToEnter,
4901         enum hci_state_with_cmd         StateCmd,
4902         u8              EntryNum
4903         )
4904 {
4905         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4906         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4907
4908         if (EntryNum == 0xff) {
4909                 RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, error EntryNum = 0x%x \n", EntryNum));
4910                 return;
4911         }
4912         RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, EntryNum = 0x%x, CurrentState = 0x%x, BtNextState = 0x%x,  StateCmd = 0x%x , StateToEnter = 0x%x\n",
4913                 EntryNum, pBTInfo->BtAsocEntry[EntryNum].BtCurrentState, pBTInfo->BtAsocEntry[EntryNum].BtNextState, StateCmd, StateToEnter));
4914
4915         if (pBTInfo->BtAsocEntry[EntryNum].BtNextState & StateToEnter) {
4916                 pBTInfo->BtAsocEntry[EntryNum].BtCurrentState = StateToEnter;
4917
4918                 switch (StateToEnter) {
4919                 case HCI_STATE_STARTING:
4920                         pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTING | HCI_STATE_CONNECTING;
4921                         bthci_StateStarting(padapter, StateCmd, EntryNum);
4922                         break;
4923                 case HCI_STATE_CONNECTING:
4924                         pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_CONNECTING | HCI_STATE_DISCONNECTING | HCI_STATE_AUTHENTICATING;
4925                         bthci_StateConnecting(padapter, StateCmd, EntryNum);
4926                         break;
4927                 case HCI_STATE_AUTHENTICATING:
4928                         pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTING | HCI_STATE_CONNECTED;
4929                         bthci_StateAuth(padapter, StateCmd, EntryNum);
4930                         break;
4931                 case HCI_STATE_CONNECTED:
4932                         pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_CONNECTED | HCI_STATE_DISCONNECTING;
4933                         bthci_StateConnected(padapter, StateCmd, EntryNum);
4934                         break;
4935                 case HCI_STATE_DISCONNECTING:
4936                         pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED | HCI_STATE_DISCONNECTING;
4937                         bthci_StateDisconnecting(padapter, StateCmd, EntryNum);
4938                         break;
4939                 case HCI_STATE_DISCONNECTED:
4940                         pBTInfo->BtAsocEntry[EntryNum].BtNextState = HCI_STATE_DISCONNECTED | HCI_STATE_STARTING | HCI_STATE_CONNECTING;
4941                         bthci_StateDisconnected(padapter, StateCmd, EntryNum);
4942                         break;
4943                 default:
4944                         RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, Unknown state to enter!!!\n"));
4945                         break;
4946                 }
4947         } else {
4948                 RTPRINT(FIOCTL, IOCTL_STATE, (" StateMachine, Wrong state to enter\n"));
4949         }
4950
4951         /*  20100325 Joseph: Disable/Enable IPS/LPS according to BT status. */
4952         if (!pBtMgnt->bBTConnectInProgress && !pBtMgnt->BtOperationOn) {
4953                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT PS], ips_enter23a()\n"));
4954                 ips_enter23a(padapter);
4955         }
4956 }
4957
4958 void BTHCI_DisconnectPeer(struct rtw_adapter *padapter, u8 EntryNum)
4959 {
4960         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4961         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
4962
4963         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, (" BTHCI_DisconnectPeer()\n"));
4964
4965         BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, EntryNum);
4966
4967         if (pBTInfo->BtAsocEntry[EntryNum].bUsed) {
4968 /*BTPKT_SendDeauthentication(padapter, pBTInfo->BtAsocEntry[EntryNum].BTRemoteMACAddr, unspec_reason); not porting yet */
4969         }
4970
4971         if (pBtMgnt->bBTConnectInProgress) {
4972                 pBtMgnt->bBTConnectInProgress = false;
4973                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT Flag], BT Connect in progress OFF!!\n"));
4974         }
4975
4976         bthci_RemoveEntryByEntryNum(padapter, EntryNum);
4977
4978         if (pBtMgnt->bNeedNotifyAMPNoCap) {
4979                 RTPRINT(FIOCTL, IOCTL_STATE, ("[BT AMPStatus], set to invalid in BTHCI_DisconnectPeer()\n"));
4980                 BTHCI_EventAMPStatusChange(padapter, AMP_STATUS_NO_CAPACITY_FOR_BT);
4981         }
4982 }
4983
4984 void BTHCI_EventNumOfCompletedDataBlocks(struct rtw_adapter *padapter)
4985 {
4986 /*PMGNT_INFO pMgntInfo = &padapter->MgntInfo; */
4987         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
4988         struct bt_hci_info *pBtHciInfo = &pBTInfo->BtHciInfo;
4989         u8 localBuf[TmpLocalBufSize] = "";
4990         u8 *pRetPar, *pTriple;
4991         u8 len = 0, i, j, handleNum = 0;
4992         struct packet_irp_hcievent_data *PPacketIrpEvent;
4993         u16 *pu2Temp, *pPackets, *pHandle, *pDblocks;
4994         u8 sent = 0;
4995
4996         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
4997
4998         if (!(pBtHciInfo->BTEventMaskPage2 & EMP2_HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS)) {
4999                 RTPRINT(FIOCTL, IOCTL_BT_EVENT, ("[BT event], Num Of Completed DataBlocks, Ignore to send NumOfCompletedDataBlocksEvent due to event mask page 2\n"));
5000                 return;
5001         }
5002
5003         /*  Return parameters starts from here */
5004         pRetPar = &PPacketIrpEvent->Data[0];
5005         pTriple = &pRetPar[3];
5006         for (j = 0; j < MAX_BT_ASOC_ENTRY_NUM; j++) {
5007
5008                 for (i = 0; i < MAX_LOGICAL_LINK_NUM; i++) {
5009                         if (pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle) {
5010                                 handleNum++;
5011                                 pHandle = (u16 *)&pTriple[0];   /*  Handle[i] */
5012                                 pPackets = (u16 *)&pTriple[2];  /*  Num_Of_Completed_Packets[i] */
5013                                 pDblocks = (u16 *)&pTriple[4];  /*  Num_Of_Completed_Blocks[i] */
5014                                 *pHandle = pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].BtLogLinkhandle;
5015                                 *pPackets = (u16)pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount;
5016                                 *pDblocks = (u16)pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount;
5017                                 if (pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount) {
5018                                         sent = 1;
5019                                         RTPRINT(FIOCTL, IOCTL_BT_EVENT_DETAIL,
5020                                                 ("[BT event], Num Of Completed DataBlocks, Handle = 0x%x, Num_Of_Completed_Packets = 0x%x, Num_Of_Completed_Blocks = 0x%x\n",
5021                                         *pHandle, *pPackets, *pDblocks));
5022                                 }
5023                                 pBTInfo->BtAsocEntry[j].LogLinkCmdData[i].TxPacketCount = 0;
5024                                 len += 6;
5025                                 pTriple += len;
5026                         }
5027                 }
5028         }
5029
5030         pRetPar[2] = handleNum;                         /*  Number_of_Handles */
5031         len += 1;
5032         pu2Temp = (u16 *)&pRetPar[0];
5033         *pu2Temp = BTTotalDataBlockNum;
5034         len += 2;
5035
5036         PPacketIrpEvent->EventCode = HCI_EVENT_NUM_OF_COMPLETE_DATA_BLOCKS;
5037         PPacketIrpEvent->Length = len;
5038         if (handleNum && sent)
5039                 bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2);
5040 }
5041
5042 void BTHCI_EventAMPStatusChange(struct rtw_adapter *padapter, u8 AMP_Status)
5043 {
5044         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
5045         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
5046         struct packet_irp_hcievent_data *PPacketIrpEvent;
5047         u8 len = 0;
5048         u8 localBuf[7] = "";
5049         u8 *pRetPar;
5050
5051         if (AMP_Status == AMP_STATUS_NO_CAPACITY_FOR_BT) {
5052                 pBtMgnt->BTNeedAMPStatusChg = true;
5053                 pBtMgnt->bNeedNotifyAMPNoCap = false;
5054
5055                 BTHCI_DisconnectAll(padapter);
5056         } else if (AMP_Status == AMP_STATUS_FULL_CAPACITY_FOR_BT) {
5057                 pBtMgnt->BTNeedAMPStatusChg = false;
5058         }
5059
5060         PPacketIrpEvent = (struct packet_irp_hcievent_data *)(&localBuf[0]);
5061         /*  Return parameters starts from here */
5062         pRetPar = &PPacketIrpEvent->Data[0];
5063
5064         pRetPar[0] = 0; /*  Status */
5065         len += 1;
5066         pRetPar[1] = AMP_Status;        /*  AMP_Status */
5067         len += 1;
5068
5069         PPacketIrpEvent->EventCode = HCI_EVENT_AMP_STATUS_CHANGE;
5070         PPacketIrpEvent->Length = len;
5071         if (bthci_IndicateEvent(padapter, PPacketIrpEvent, len+2) == RT_STATUS_SUCCESS)
5072                 RTPRINT(FIOCTL, (IOCTL_BT_EVENT|IOCTL_STATE), ("[BT event], AMP Status Change, AMP_Status = %d\n", AMP_Status));
5073 }
5074
5075 void BTHCI_DisconnectAll(struct rtw_adapter *padapter)
5076 {
5077         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
5078         u8 i;
5079
5080         RTPRINT(FIOCTL, IOCTL_STATE, (" DisconnectALL()\n"));
5081
5082         for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
5083                 if (pBTInfo->BtAsocEntry[i].b4waySuccess) {
5084                         BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTED, STATE_CMD_DISCONNECT_PHY_LINK, i);
5085                 } else if (pBTInfo->BtAsocEntry[i].bUsed) {
5086                         if (pBTInfo->BtAsocEntry[i].BtCurrentState == HCI_STATE_CONNECTING) {
5087                                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_CONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, i);
5088                         } else if (pBTInfo->BtAsocEntry[i].BtCurrentState == HCI_STATE_DISCONNECTING) {
5089                                 BTHCI_SM_WITH_INFO(padapter, HCI_STATE_DISCONNECTING, STATE_CMD_MAC_CONNECT_CANCEL_INDICATE, i);
5090                         }
5091                 }
5092         }
5093 }
5094
5095 enum hci_status
5096 BTHCI_HandleHCICMD(
5097         struct rtw_adapter *padapter,
5098         struct packet_irp_hcicmd_data *pHciCmd
5099         )
5100 {
5101         enum hci_status status = HCI_STATUS_SUCCESS;
5102         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
5103         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
5104
5105         RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("\n"));
5106         RTPRINT(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), ("HCI Command start, OGF = 0x%x, OCF = 0x%x, Length = 0x%x\n",
5107                 pHciCmd->OGF, pHciCmd->OCF, pHciCmd->Length));
5108         if (pHciCmd->Length) {
5109                 RTPRINT_DATA(FIOCTL, (IOCTL_BT_HCICMD_DETAIL|IOCTL_BT_LOGO), "HCI Command, Hex Data :\n",
5110                         &pHciCmd->Data[0], pHciCmd->Length);
5111         }
5112         if (pHciCmd->OGF == OGF_EXTENSION) {
5113                 if (pHciCmd->OCF == HCI_SET_RSSI_VALUE)
5114                         RTPRINT(FIOCTL, IOCTL_BT_EVENT_PERIODICAL, ("[BT cmd], "));
5115                 else
5116                         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_EXT, ("[BT cmd], "));
5117         } else {
5118                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("[BT cmd], "));
5119         }
5120
5121         pBtDbg->dbgHciInfo.hciCmdCnt++;
5122
5123         switch (pHciCmd->OGF) {
5124         case LINK_CONTROL_COMMANDS:
5125                 status = bthci_HandleOGFLinkControlCMD(padapter, pHciCmd);
5126                 break;
5127         case HOLD_MODE_COMMAND:
5128                 break;
5129         case OGF_SET_EVENT_MASK_COMMAND:
5130                 status = bthci_HandleOGFSetEventMaskCMD(padapter, pHciCmd);
5131                 break;
5132         case OGF_INFORMATIONAL_PARAMETERS:
5133                 status = bthci_HandleOGFInformationalParameters(padapter, pHciCmd);
5134                 break;
5135         case OGF_STATUS_PARAMETERS:
5136                 status = bthci_HandleOGFStatusParameters(padapter, pHciCmd);
5137                 break;
5138         case OGF_TESTING_COMMANDS:
5139                 status = bthci_HandleOGFTestingCMD(padapter, pHciCmd);
5140                 break;
5141         case OGF_EXTENSION:
5142                 status = bthci_HandleOGFExtension(padapter, pHciCmd);
5143                 break;
5144         default:
5145                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI Command(), Unknown OGF = 0x%x\n", pHciCmd->OGF));
5146                 RTPRINT(FIOCTL, IOCTL_BT_HCICMD, ("HCI_UNKNOWN_COMMAND\n"));
5147                 status = bthci_UnknownCMD(padapter, pHciCmd);
5148                 break;
5149         }
5150         RTPRINT(FIOCTL, IOCTL_BT_HCICMD_DETAIL, ("HCI Command execution end!!\n"));
5151
5152         return status;
5153 }
5154
5155 /*  ===== End of sync from SD7 driver COMMOM/bt_hci.c ===== */
5156
5157 static const char *const BtStateString[] = {
5158         "BT_DISABLED",
5159         "BT_NO_CONNECTION",
5160         "BT_CONNECT_IDLE",
5161         "BT_INQ_OR_PAG",
5162         "BT_ACL_ONLY_BUSY",
5163         "BT_SCO_ONLY_BUSY",
5164         "BT_ACL_SCO_BUSY",
5165         "BT_ACL_INQ_OR_PAG",
5166         "BT_STATE_NOT_DEFINED"
5167 };
5168
5169 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */
5170
5171 static void btdm_SetFwIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable)
5172 {
5173         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
5174         u8 H2C_Parameter[1] = {0};
5175
5176         if (bEnable) {
5177                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Ignore Wlan_Act !!\n"));
5178                 H2C_Parameter[0] |= BIT(0);             /*  function enable */
5179                 pHalData->bt_coexist.bFWCoexistAllOff = false;
5180         } else {
5181                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT don't ignore Wlan_Act !!\n"));
5182         }
5183
5184         RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW for BT Ignore Wlan_Act, write 0x25 = 0x%02x\n",
5185                 H2C_Parameter[0]));
5186
5187         FillH2CCmd(padapter, BT_IGNORE_WLAN_ACT_EID, 1, H2C_Parameter);
5188 }
5189
5190 static void btdm_NotifyFwScan(struct rtw_adapter *padapter, u8 scanType)
5191 {
5192         u8 H2C_Parameter[1] = {0};
5193
5194         if (scanType == true)
5195                 H2C_Parameter[0] = 0x1;
5196
5197         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Notify FW for wifi scan, write 0x3b = 0x%02x\n",
5198                 H2C_Parameter[0]));
5199
5200         FillH2CCmd(padapter, 0x3b, 1, H2C_Parameter);
5201 }
5202
5203 static void btdm_1AntSetPSMode(struct rtw_adapter *padapter,
5204                                u8 enable, u8 smartps, u8 mode)
5205 {
5206         struct pwrctrl_priv *pwrctrl;
5207
5208         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Current LPS(%s, %d), smartps =%d\n", enable == true?"ON":"OFF", mode, smartps));
5209
5210         pwrctrl = &padapter->pwrctrlpriv;
5211
5212         if (enable == true) {
5213                 rtw_set_ps_mode23a(padapter, PS_MODE_MIN, smartps, mode);
5214         } else {
5215                 rtw_set_ps_mode23a(padapter, PS_MODE_ACTIVE, 0, 0);
5216                 LPS_RF_ON_check23a(padapter, 100);
5217         }
5218 }
5219
5220 static void btdm_1AntTSFSwitch(struct rtw_adapter *padapter, u8 enable)
5221 {
5222         u8 oldVal, newVal;
5223
5224         oldVal = rtl8723au_read8(padapter, 0x550);
5225
5226         if (enable)
5227                 newVal = oldVal | EN_BCN_FUNCTION;
5228         else
5229                 newVal = oldVal & ~EN_BCN_FUNCTION;
5230
5231         if (oldVal != newVal)
5232                 rtl8723au_write8(padapter, 0x550, newVal);
5233 }
5234
5235 static u8 btdm_Is1AntPsTdmaStateChange(struct rtw_adapter *padapter)
5236 {
5237         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
5238         struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
5239
5240         if ((pBtdm8723->bPrePsTdmaOn != pBtdm8723->bCurPsTdmaOn) ||
5241                 (pBtdm8723->prePsTdma != pBtdm8723->curPsTdma))
5242                 return true;
5243         else
5244                 return false;
5245 }
5246
5247 /*  Before enter TDMA, make sure Power Saving is enable! */
5248 static void
5249 btdm_1AntPsTdma(
5250         struct rtw_adapter *padapter,
5251         u8 bTurnOn,
5252         u8 type
5253         )
5254 {
5255         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
5256         struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
5257
5258         pBtdm8723->bCurPsTdmaOn = bTurnOn;
5259         pBtdm8723->curPsTdma = type;
5260         if (bTurnOn) {
5261                 switch (type) {
5262                 case 1: /*  A2DP Level-1 or FTP/OPP */
5263                 default:
5264                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5265                                 /*  wide duration for WiFi */
5266                                 BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x0, 0x58);
5267                         }
5268                         break;
5269                 case 2: /*  A2DP Level-2 */
5270                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5271                                 /*  normal duration for WiFi */
5272                                 BTDM_SetFw3a(padapter, 0xd3, 0x12, 0x12, 0x0, 0x58);
5273                         }
5274                         break;
5275                 case 3: /*  BT FTP/OPP */
5276                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5277                                 /*  normal duration for WiFi */
5278                                 BTDM_SetFw3a(padapter, 0xd3, 0x30, 0x03, 0x10, 0x58);
5279
5280                         }
5281                         break;
5282                 case 4: /*  for wifi scan & BT is connected */
5283                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5284                                 /*  protect 3 beacons in 3-beacon period & no Tx pause at BT slot */
5285                                 BTDM_SetFw3a(padapter, 0x93, 0x15, 0x03, 0x14, 0x0);
5286                         }
5287                         break;
5288                 case 5: /*  for WiFi connected-busy & BT is Non-Connected-Idle */
5289                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5290                                 /*  SCO mode, Ant fixed at WiFi, WLAN_Act toggle */
5291                                 BTDM_SetFw3a(padapter, 0x61, 0x15, 0x03, 0x31, 0x00);
5292                         }
5293                         break;
5294                 case 9: /*  ACL high-retry type - 2 */
5295                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5296                                 /*  narrow duration for WiFi */
5297                                 BTDM_SetFw3a(padapter, 0xd3, 0xa, 0xa, 0x0, 0x58); /* narrow duration for WiFi */
5298                         }
5299                         break;
5300                 case 10: /*  for WiFi connect idle & BT ACL busy or WiFi Connected-Busy & BT is Inquiry */
5301                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5302                                 BTDM_SetFw3a(padapter, 0x13, 0xa, 0xa, 0x0, 0x40);
5303                         break;
5304                 case 11: /*  ACL high-retry type - 3 */
5305                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5306                                 /*  narrow duration for WiFi */
5307                                 BTDM_SetFw3a(padapter, 0xd3, 0x05, 0x05, 0x00, 0x58);
5308                         }
5309                         break;
5310                 case 12: /*  for WiFi Connected-Busy & BT is Connected-Idle */
5311                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5312                                 /*  Allow High-Pri BT */
5313                                 BTDM_SetFw3a(padapter, 0xeb, 0x0a, 0x03, 0x31, 0x18);
5314                         }
5315                         break;
5316                 case 20: /*  WiFi only busy , TDMA mode for power saving */
5317                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5318                                 BTDM_SetFw3a(padapter, 0x13, 0x25, 0x25, 0x00, 0x00);
5319                         break;
5320                 case 27: /*  WiFi DHCP/Site Survey & BT SCO busy */
5321                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5322                                 BTDM_SetFw3a(padapter, 0xa3, 0x25, 0x03, 0x31, 0x98);
5323                         break;
5324                 case 28: /*  WiFi DHCP/Site Survey & BT idle */
5325                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5326                                 BTDM_SetFw3a(padapter, 0x69, 0x25, 0x03, 0x31, 0x00);
5327                         break;
5328                 case 29: /*  WiFi DHCP/Site Survey & BT ACL busy */
5329                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5330                                 BTDM_SetFw3a(padapter, 0xeb, 0x1a, 0x1a, 0x01, 0x18);
5331                                 rtl8723au_write32(padapter, 0x6c0, 0x5afa5afa);
5332                                 rtl8723au_write32(padapter, 0x6c4, 0x5afa5afa);
5333                         }
5334                         break;
5335                 case 30: /*  WiFi idle & BT Inquiry */
5336                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5337                                 BTDM_SetFw3a(padapter, 0x93, 0x15, 0x03, 0x14, 0x00);
5338                         break;
5339                 case 31:  /*  BT HID */
5340                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5341                                 BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x00, 0x58);
5342                         break;
5343                 case 32:  /*  BT SCO & Inquiry */
5344                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5345                                 BTDM_SetFw3a(padapter, 0xab, 0x0a, 0x03, 0x11, 0x98);
5346                         break;
5347                 case 33:  /*  BT SCO & WiFi site survey */
5348                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5349                                 BTDM_SetFw3a(padapter, 0xa3, 0x25, 0x03, 0x30, 0x98);
5350                         break;
5351                 case 34:  /*  BT HID & WiFi site survey */
5352                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5353                                 BTDM_SetFw3a(padapter, 0xd3, 0x1a, 0x1a, 0x00, 0x18);
5354                         break;
5355                 case 35:  /*  BT HID & WiFi Connecting */
5356                         if (btdm_Is1AntPsTdmaStateChange(padapter))
5357                                 BTDM_SetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x00, 0x18);
5358                         break;
5359                 }
5360         } else {
5361                 /*  disable PS-TDMA */
5362                 switch (type) {
5363                 case 8:
5364                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5365                                 /*  Antenna control by PTA, 0x870 = 0x310 */
5366                                 BTDM_SetFw3a(padapter, 0x8, 0x0, 0x0, 0x0, 0x0);
5367                         }
5368                         break;
5369                 case 0:
5370                 default:
5371                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5372                                 /*  Antenna control by PTA, 0x870 = 0x310 */
5373                                 BTDM_SetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
5374                         }
5375                         /*  Switch Antenna to BT */
5376                         rtl8723au_write16(padapter, 0x860, 0x210);
5377                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 0x860 = 0x210, Switch Antenna to BT\n"));
5378                         break;
5379                 case 9:
5380                         if (btdm_Is1AntPsTdmaStateChange(padapter)) {
5381                                 /*  Antenna control by PTA, 0x870 = 0x310 */
5382                                 BTDM_SetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
5383                         }
5384                         /*  Switch Antenna to WiFi */
5385                         rtl8723au_write16(padapter, 0x860, 0x110);
5386                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 0x860 = 0x110, Switch Antenna to WiFi\n"));
5387                         break;
5388                 }
5389         }
5390
5391         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Current TDMA(%s, %d)\n",
5392                 pBtdm8723->bCurPsTdmaOn?"ON":"OFF", pBtdm8723->curPsTdma));
5393
5394         /*  update pre state */
5395         pBtdm8723->bPrePsTdmaOn = pBtdm8723->bCurPsTdmaOn;
5396         pBtdm8723->prePsTdma = pBtdm8723->curPsTdma;
5397 }
5398
5399 static void
5400 _btdm_1AntSetPSTDMA(struct rtw_adapter *padapter, u8 bPSEn, u8 smartps,
5401                     u8 psOption, u8 bTDMAOn, u8 tdmaType)
5402 {
5403         struct pwrctrl_priv *pwrctrl;
5404         struct hal_data_8723a *pHalData;
5405         struct btdm_8723a_1ant *pBtdm8723;
5406         u8 psMode;
5407         u8 bSwitchPS;
5408
5409         if (!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE) &&
5410             (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) {
5411                 btdm_1AntPsTdma(padapter, bTDMAOn, tdmaType);
5412                 return;
5413         }
5414         psOption &= ~BIT(0);
5415
5416         RTPRINT(FBT, BT_TRACE,
5417                 ("[BTCoex], Set LPS(%s, %d) TDMA(%s, %d)\n",
5418                 bPSEn == true?"ON":"OFF", psOption,
5419                 bTDMAOn == true?"ON":"OFF", tdmaType));
5420
5421         pwrctrl = &padapter->pwrctrlpriv;
5422         pHalData = GET_HAL_DATA(padapter);
5423         pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
5424
5425         if (bPSEn) {
5426                 if (pBtdm8723->bWiFiHalt) {
5427                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi in Halt!!\n"));
5428                         return;
5429                 }
5430
5431                 if (pwrctrl->bInSuspend) {
5432                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi in Suspend!!\n"));
5433                         return;
5434                 }
5435
5436                 if (padapter->bDriverStopped) {
5437                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi driver stopped!!\n"));
5438                         return;
5439                 }
5440
5441                 if (padapter->bSurpriseRemoved) {
5442                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Enable PS Fail, WiFi Surprise Removed!!\n"));
5443                         return;
5444                 }
5445
5446                 psMode = PS_MODE_MIN;
5447         } else {
5448                 psMode = PS_MODE_ACTIVE;
5449                 psOption = 0;
5450         }
5451
5452         if (psMode != pwrctrl->pwr_mode) {
5453                 bSwitchPS = true;
5454         } else if (psMode != PS_MODE_ACTIVE) {
5455                 if (psOption != pwrctrl->bcn_ant_mode)
5456                         bSwitchPS = true;
5457                 else if (smartps != pwrctrl->smart_ps)
5458                         bSwitchPS = true;
5459                 else
5460                         bSwitchPS = false;
5461         } else {
5462                 bSwitchPS = false;
5463         }
5464
5465         if (bSwitchPS) {
5466                 /*  disable TDMA */
5467                 if (pBtdm8723->bCurPsTdmaOn) {
5468                         if (!bTDMAOn) {
5469                                 btdm_1AntPsTdma(padapter, false, tdmaType);
5470                         } else {
5471                                 if (!rtl8723a_BT_enabled(padapter) ||
5472                                     (pHalData->bt_coexist.halCoex8723.c2hBtInfo == BT_INFO_STATE_NO_CONNECTION) ||
5473                                     (pHalData->bt_coexist.halCoex8723.c2hBtInfo == BT_INFO_STATE_CONNECT_IDLE) ||
5474                                     (tdmaType == 29))
5475                                         btdm_1AntPsTdma(padapter, false, 9);
5476                                 else
5477                                         btdm_1AntPsTdma(padapter, false, 0);
5478                         }
5479                 }
5480
5481                 /*  change Power Save State */
5482                 btdm_1AntSetPSMode(padapter, bPSEn, smartps, psOption);
5483         }
5484
5485         btdm_1AntPsTdma(padapter, bTDMAOn, tdmaType);
5486 }
5487
5488 static void
5489 btdm_1AntSetPSTDMA(struct rtw_adapter *padapter, u8 bPSEn,
5490                    u8 psOption, u8 bTDMAOn, u8 tdmaType)
5491 {
5492         _btdm_1AntSetPSTDMA(padapter, bPSEn, 0, psOption, bTDMAOn, tdmaType);
5493 }
5494
5495 static void btdm_1AntWifiParaAdjust(struct rtw_adapter *padapter, u8 bEnable)
5496 {
5497         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
5498         struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
5499
5500         if (bEnable) {
5501                 pBtdm8723->curWifiPara = 1;
5502                 if (pBtdm8723->preWifiPara != pBtdm8723->curWifiPara)
5503                         BTDM_SetSwPenaltyTxRateAdaptive(padapter, BT_TX_RATE_ADAPTIVE_LOW_PENALTY);
5504         } else {
5505                 pBtdm8723->curWifiPara = 2;
5506                 if (pBtdm8723->preWifiPara != pBtdm8723->curWifiPara)
5507                         BTDM_SetSwPenaltyTxRateAdaptive(padapter, BT_TX_RATE_ADAPTIVE_NORMAL);
5508         }
5509
5510 }
5511
5512 static void btdm_1AntPtaParaReload(struct rtw_adapter *padapter)
5513 {
5514         /*  PTA parameter */
5515         rtl8723au_write8(padapter, 0x6cc, 0x0);         /*  1-Ant coex */
5516         rtl8723au_write32(padapter, 0x6c8, 0xffff);     /*  wifi break table */
5517         rtl8723au_write32(padapter, 0x6c4, 0x55555555); /*  coex table */
5518
5519         /*  Antenna switch control parameter */
5520         rtl8723au_write32(padapter, 0x858, 0xaaaaaaaa);
5521         if (IS_8723A_A_CUT(GET_HAL_DATA(padapter)->VersionID)) {
5522                 /*  SPDT(connected with TRSW) control by hardware PTA */
5523                 rtl8723au_write32(padapter, 0x870, 0x0);
5524                 rtl8723au_write8(padapter, 0x40, 0x24);
5525         } else {
5526                 rtl8723au_write8(padapter, 0x40, 0x20);
5527                 /*  set antenna at bt side if ANTSW is software control */
5528                 rtl8723au_write16(padapter, 0x860, 0x210);
5529                 /*  SPDT(connected with TRSW) control by hardware PTA */
5530                 rtl8723au_write32(padapter, 0x870, 0x300);
5531                 /*  ANTSW keep by GNT_BT */
5532                 rtl8723au_write32(padapter, 0x874, 0x22804000);
5533         }
5534
5535         /*  coexistence parameters */
5536         rtl8723au_write8(padapter, 0x778, 0x1); /*  enable RTK mode PTA */
5537
5538         /*  BT don't ignore WLAN_Act */
5539         btdm_SetFwIgnoreWlanAct(padapter, false);
5540 }
5541
5542 /*
5543  * Return
5544  *1: upgrade (add WiFi duration time)
5545  *0: keep
5546  *-1: downgrade (add BT duration time)
5547  */
5548 static s8 btdm_1AntTdmaJudgement(struct rtw_adapter *padapter, u8 retry)
5549 {
5550         struct hal_data_8723a *pHalData;
5551         struct btdm_8723a_1ant *pBtdm8723;
5552         static s8 up, dn, m = 1, n = 3, WaitCount;
5553         s8 ret;
5554
5555         pHalData = GET_HAL_DATA(padapter);
5556         pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
5557         ret = 0;
5558
5559         if (pBtdm8723->psTdmaMonitorCnt == 0) {
5560                 up = 0;
5561                 dn = 0;
5562                 m = 1;
5563                 n = 3;
5564                 WaitCount = 0;
5565         } else {
5566                 WaitCount++;
5567         }
5568
5569         if (retry == 0) {
5570         /*  no retry in the last 2-second duration */
5571                 up++;
5572                 dn--;
5573                 if (dn < 0)
5574                         dn = 0;
5575                 if (up >= 3*m) {
5576                         /*  retry = 0 in consecutive 3m*(2s), add WiFi duration */
5577                         ret = 1;
5578
5579                         n = 3;
5580                         up = 0;
5581                         dn = 0;
5582                         WaitCount = 0;
5583                 }
5584         } else if (retry <= 3) {
5585                 /*  retry<= 3 in the last 2-second duration */
5586                 up--;
5587                 dn++;
5588                 if (up < 0)
5589                         up = 0;
5590
5591                 if (dn == 2) {
5592                         /*  retry<= 3 in consecutive 2*(2s), minus WiFi duration (add BT duration) */
5593                         ret = -1;
5594
5595                         /*  record how many time downgrad WiFi duration */
5596                         if (WaitCount <= 2)
5597                                 m++;
5598                         else
5599                                 m = 1;
5600                         /*  the max number of m is 20 */
5601                         /*  the longest time of upgrade WiFi duration is 20*3*2s = 120s */
5602                         if (m >= 20)
5603                                 m = 20;
5604                         up = 0;
5605                         dn = 0;
5606                         WaitCount = 0;
5607                 }
5608         } else {
5609                 /*  retry count > 3 */
5610                 /*  retry>3, minus WiFi duration (add BT duration) */
5611                 ret = -1;
5612
5613                 /*  record how many time downgrad WiFi duration */
5614                 if (WaitCount == 1)
5615                         m++;
5616                 else
5617                         m = 1;
5618                 if (m >= 20)
5619                         m = 20;
5620
5621                 up = 0;
5622                 dn = 0;
5623                 WaitCount = 0;
5624         }
5625         return ret;
5626 }
5627
5628 static void btdm_1AntTdmaDurationAdjustForACL(struct rtw_adapter *padapter)
5629 {
5630         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
5631         struct btdm_8723a_1ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
5632
5633         if (pBtdm8723->psTdmaGlobalCnt != pBtdm8723->psTdmaMonitorCnt) {
5634                 pBtdm8723->psTdmaMonitorCnt = 0;
5635                 pBtdm8723->psTdmaGlobalCnt = 0;
5636         }
5637         if (pBtdm8723->psTdmaMonitorCnt == 0) {
5638                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 2);
5639                 pBtdm8723->psTdmaDuAdjType = 2;
5640         } else {
5641                 /*  Now we only have 4 level Ps Tdma, */
5642                 /*  if that's not the following 4 level(will changed by wifi scan, dhcp...), */
5643                 /*  then we have to adjust it back to the previous record one. */
5644                 if ((pBtdm8723->curPsTdma != 1) &&
5645                     (pBtdm8723->curPsTdma != 2) &&
5646                     (pBtdm8723->curPsTdma != 9) &&
5647                     (pBtdm8723->curPsTdma != 11)) {
5648                         btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
5649                 } else {
5650                         s32 judge = 0;
5651
5652                         judge = btdm_1AntTdmaJudgement(padapter, pHalData->bt_coexist.halCoex8723.btRetryCnt);
5653                         if (judge == -1) {
5654                                 if (pBtdm8723->curPsTdma == 1) {
5655                                         /*  Decrease WiFi duration for high BT retry */
5656                                         if (pHalData->bt_coexist.halCoex8723.btInfoExt)
5657                                                 pBtdm8723->psTdmaDuAdjType = 9;
5658                                         else
5659                                                 pBtdm8723->psTdmaDuAdjType = 2;
5660                                         btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
5661                                 } else if (pBtdm8723->curPsTdma == 2) {
5662                                         btdm_1AntSetPSTDMA(padapter, true, 0, true, 9);
5663                                         pBtdm8723->psTdmaDuAdjType = 9;
5664                                 } else if (pBtdm8723->curPsTdma == 9) {
5665                                         btdm_1AntSetPSTDMA(padapter, true, 0, true, 11);
5666                                         pBtdm8723->psTdmaDuAdjType = 11;
5667                                 }
5668                         } else if (judge == 1) {
5669                                 if (pBtdm8723->curPsTdma == 11) {
5670                                         btdm_1AntSetPSTDMA(padapter, true, 0, true, 9);
5671                                         pBtdm8723->psTdmaDuAdjType = 9;
5672                                 } else if (pBtdm8723->curPsTdma == 9) {
5673                                         if (pHalData->bt_coexist.halCoex8723.btInfoExt)
5674                                                 pBtdm8723->psTdmaDuAdjType = 9;
5675                                         else
5676                                                 pBtdm8723->psTdmaDuAdjType = 2;
5677                                         btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
5678                                 } else if (pBtdm8723->curPsTdma == 2) {
5679                                         if (pHalData->bt_coexist.halCoex8723.btInfoExt)
5680                                                 pBtdm8723->psTdmaDuAdjType = 9;
5681                                         else
5682                                                 pBtdm8723->psTdmaDuAdjType = 1;
5683                                         btdm_1AntSetPSTDMA(padapter, true, 0, true, pBtdm8723->psTdmaDuAdjType);
5684                                 }
5685                         }
5686                 }
5687                 RTPRINT(FBT, BT_TRACE,
5688                         ("[BTCoex], ACL current TDMA(%s, %d)\n",
5689                         (pBtdm8723->bCurPsTdmaOn ? "ON" : "OFF"), pBtdm8723->curPsTdma));
5690         }
5691         pBtdm8723->psTdmaMonitorCnt++;
5692 }
5693
5694 static void btdm_1AntCoexProcessForWifiConnect(struct rtw_adapter *padapter)
5695 {
5696         struct mlme_priv *pmlmepriv;
5697         struct hal_data_8723a *pHalData;
5698         struct bt_coexist_8723a *pBtCoex;
5699         struct btdm_8723a_1ant *pBtdm8723;
5700         u8 BtState;
5701
5702         pmlmepriv = &padapter->mlmepriv;
5703         pHalData = GET_HAL_DATA(padapter);
5704         pBtCoex = &pHalData->bt_coexist.halCoex8723;
5705         pBtdm8723 = &pBtCoex->btdm1Ant;
5706         BtState = pBtCoex->c2hBtInfo;
5707
5708         RTPRINT(FBT, BT_TRACE, ("[BTCoex], WiFi is %s\n",
5709                                 BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
5710         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is %s\n",
5711                                 BtStateString[BtState]));
5712
5713         padapter->pwrctrlpriv.btcoex_rfon = false;
5714
5715         if (!BTDM_IsWifiBusy(padapter) &&
5716             !check_fwstate(&padapter->mlmepriv, WIFI_AP_STATE) &&
5717             (BtState == BT_INFO_STATE_NO_CONNECTION ||
5718              BtState == BT_INFO_STATE_CONNECT_IDLE)) {
5719                 switch (BtState) {
5720                 case BT_INFO_STATE_NO_CONNECTION:
5721                         _btdm_1AntSetPSTDMA(padapter, true, 2, 0x26, false, 9);
5722                         break;
5723                 case BT_INFO_STATE_CONNECT_IDLE:
5724                         _btdm_1AntSetPSTDMA(padapter, true, 2, 0x26, false, 0);
5725                         break;
5726                 }
5727         } else {
5728                 switch (BtState) {
5729                 case BT_INFO_STATE_NO_CONNECTION:
5730                 case BT_INFO_STATE_CONNECT_IDLE:
5731                         /*  WiFi is Busy */
5732                         btdm_1AntSetPSTDMA(padapter, false, 0, true, 5);
5733                         rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
5734                         rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
5735                         break;
5736                 case BT_INFO_STATE_ACL_INQ_OR_PAG:
5737                         RTPRINT(FBT, BT_TRACE,
5738                                 ("[BTCoex], BT PROFILE is "
5739                                  "BT_INFO_STATE_ACL_INQ_OR_PAG\n"));
5740                 case BT_INFO_STATE_INQ_OR_PAG:
5741                         padapter->pwrctrlpriv.btcoex_rfon = true;
5742                         btdm_1AntSetPSTDMA(padapter, true, 0, true, 30);
5743                         break;
5744                 case BT_INFO_STATE_SCO_ONLY_BUSY:
5745                 case BT_INFO_STATE_ACL_SCO_BUSY:
5746                         if (true == pBtCoex->bC2hBtInquiryPage)
5747                                 btdm_1AntSetPSTDMA(padapter, false, 0,
5748                                                    true, 32);
5749                         else {
5750 #ifdef BTCOEX_CMCC_TEST
5751                                 btdm_1AntSetPSTDMA(padapter, false, 0,
5752                                                    true, 23);
5753 #else /*  !BTCOEX_CMCC_TEST */
5754                                 btdm_1AntSetPSTDMA(padapter, false, 0,
5755                                                    false, 8);
5756                                 rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
5757                                 rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
5758 #endif /*  !BTCOEX_CMCC_TEST */
5759                         }
5760                         break;
5761                 case BT_INFO_STATE_ACL_ONLY_BUSY:
5762                         padapter->pwrctrlpriv.btcoex_rfon = true;
5763                         if (pBtCoex->c2hBtProfile == BT_INFO_HID) {
5764                                 RTPRINT(FBT, BT_TRACE,
5765                                         ("[BTCoex], BT PROFILE is HID\n"));
5766                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 31);
5767                         } else if (pBtCoex->c2hBtProfile == BT_INFO_FTP) {
5768                                 RTPRINT(FBT, BT_TRACE,
5769                                         ("[BTCoex], BT PROFILE is FTP/OPP\n"));
5770                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 3);
5771                         } else if (pBtCoex->c2hBtProfile == (BT_INFO_A2DP|BT_INFO_FTP)) {
5772                                 RTPRINT(FBT, BT_TRACE,
5773                                         ("[BTCoex], BT PROFILE is A2DP_FTP\n"));
5774                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 11);
5775                         } else {
5776                                 if (pBtCoex->c2hBtProfile == BT_INFO_A2DP)
5777                                         RTPRINT(FBT, BT_TRACE,
5778                                                 ("[BTCoex], BT PROFILE is "
5779                                                  "A2DP\n"));
5780                                 else
5781                                         RTPRINT(FBT, BT_TRACE,
5782                                                 ("[BTCoex], BT PROFILE is "
5783                                                  "UNKNOWN(0x%02X)! Use A2DP "
5784                                                  "Profile\n",
5785                                                  pBtCoex->c2hBtProfile));
5786                                 btdm_1AntTdmaDurationAdjustForACL(padapter);
5787                         }
5788                         break;
5789                 }
5790         }
5791
5792         pBtdm8723->psTdmaGlobalCnt++;
5793 }
5794
5795 static void
5796 btdm_1AntUpdateHalRAMask(struct rtw_adapter *padapter, u32 mac_id, u32 filter)
5797 {
5798         u8 init_rate = 0;
5799         u8 raid;
5800         u32 mask;
5801         u8 shortGIrate = false;
5802         int supportRateNum = 0;
5803         struct sta_info *psta;
5804         struct hal_data_8723a *pHalData;
5805         struct dm_priv *pdmpriv;
5806         struct mlme_ext_priv *pmlmeext;
5807         struct mlme_ext_info *pmlmeinfo;
5808         struct wlan_bssid_ex *cur_network;
5809
5810         RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d, filter = 0x%08x!!\n",
5811                                 __func__, mac_id, filter));
5812
5813         pHalData = GET_HAL_DATA(padapter);
5814         pdmpriv = &pHalData->dmpriv;
5815         pmlmeext = &padapter->mlmeextpriv;
5816         pmlmeinfo = &pmlmeext->mlmext_info;
5817         cur_network = &pmlmeinfo->network;
5818
5819         if (mac_id >= NUM_STA) { /* CAM_SIZE */
5820                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, MACID =%d illegal!!\n",
5821                                         __func__, mac_id));
5822                 return;
5823         }
5824
5825         psta = pmlmeinfo->FW_sta_info[mac_id].psta;
5826         if (!psta) {
5827                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], %s, Can't find station!!\n",
5828                                         __func__));
5829                 return;
5830         }
5831
5832         raid = psta->raid;
5833
5834         switch (mac_id) {
5835         case 0:/*  for infra mode */
5836                 supportRateNum =
5837                         rtw_get_rateset_len23a(cur_network->SupportedRates);
5838                 mask = update_supported_rate23a(cur_network->SupportedRates,
5839                                                 supportRateNum);
5840                 mask |= (pmlmeinfo->HT_enable) ?
5841                         update_MSC_rate23a(&pmlmeinfo->ht_cap):0;
5842                 if (support_short_GI23a(padapter, &pmlmeinfo->ht_cap))
5843                         shortGIrate = true;
5844                 break;
5845         case 1:/* for broadcast/multicast */
5846                 supportRateNum = rtw_get_rateset_len23a(
5847                         pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
5848                 mask = update_basic_rate23a(cur_network->SupportedRates,
5849                                             supportRateNum);
5850                 break;
5851         default: /* for each sta in IBSS */
5852                 supportRateNum = rtw_get_rateset_len23a(
5853                         pmlmeinfo->FW_sta_info[mac_id].SupportedRates);
5854                 mask = update_supported_rate23a(cur_network->SupportedRates,
5855                                                 supportRateNum);
5856                 break;
5857         }
5858         mask |= ((raid<<28)&0xf0000000);
5859         mask &= 0xffffffff;
5860         mask &= ~filter;
5861         init_rate = get_highest_rate_idx23a(mask)&0x3f;
5862
5863         if (pHalData->fw_ractrl) {
5864                 u8 arg = 0;
5865
5866                 arg = mac_id&0x1f;/* MACID */
5867                 arg |= BIT(7);
5868                 if (true == shortGIrate)
5869                         arg |= BIT(5);
5870
5871                 RTPRINT(FBT, BT_TRACE,
5872                         ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, "
5873                          "arg = 0x%02x\n", mask, arg));
5874
5875                 rtl8723a_set_raid_cmd(padapter, mask, arg);
5876         } else {
5877                 if (shortGIrate)
5878                         init_rate |= BIT(6);
5879
5880                 rtl8723au_write8(padapter, REG_INIDATA_RATE_SEL + mac_id,
5881                                  init_rate);
5882         }
5883
5884         psta->init_rate = init_rate;
5885         pdmpriv->INIDATA_RATE[mac_id] = init_rate;
5886 }
5887
5888 static void
5889 btdm_1AntUpdateHalRAMaskForSCO(struct rtw_adapter *padapter, u8 forceUpdate)
5890 {
5891         struct btdm_8723a_1ant *pBtdm8723;
5892         struct sta_priv *pstapriv;
5893         struct wlan_bssid_ex *cur_network;
5894         struct sta_info *psta;
5895         u32 macid;
5896         u32 filter = 0;
5897
5898         pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
5899
5900         if (pBtdm8723->bRAChanged == true && forceUpdate == false)
5901                 return;
5902
5903         pstapriv = &padapter->stapriv;
5904         cur_network = &padapter->mlmeextpriv.mlmext_info.network;
5905         psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5906         macid = psta->mac_id;
5907
5908         filter |= BIT(_1M_RATE_);
5909         filter |= BIT(_2M_RATE_);
5910         filter |= BIT(_5M_RATE_);
5911         filter |= BIT(_11M_RATE_);
5912         filter |= BIT(_6M_RATE_);
5913         filter |= BIT(_9M_RATE_);
5914
5915         btdm_1AntUpdateHalRAMask(padapter, macid, filter);
5916
5917         pBtdm8723->bRAChanged = true;
5918 }
5919
5920 static void btdm_1AntRecoverHalRAMask(struct rtw_adapter *padapter)
5921 {
5922         struct btdm_8723a_1ant *pBtdm8723;
5923         struct sta_priv *pstapriv;
5924         struct wlan_bssid_ex *cur_network;
5925         struct sta_info *psta;
5926
5927         pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
5928
5929         if (pBtdm8723->bRAChanged == false)
5930                 return;
5931
5932         pstapriv = &padapter->stapriv;
5933         cur_network = &padapter->mlmeextpriv.mlmext_info.network;
5934         psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5935
5936         Update_RA_Entry23a(padapter, psta);
5937
5938         pBtdm8723->bRAChanged = false;
5939 }
5940
5941 static void
5942 btdm_1AntBTStateChangeHandler(struct rtw_adapter *padapter,
5943                               enum bt_state_1ant oldState,
5944                               enum bt_state_1ant newState)
5945 {
5946         struct hal_data_8723a *phaldata;
5947         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT state change, %s => %s\n",
5948                                 BtStateString[oldState],
5949                                 BtStateString[newState]));
5950
5951         /*  BT default ignore wlan active, */
5952         /*  WiFi MUST disable this when BT is enable */
5953         if (newState > BT_INFO_STATE_DISABLED)
5954                 btdm_SetFwIgnoreWlanAct(padapter, false);
5955
5956         if ((check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) &&
5957             (BTDM_IsWifiConnectionExist(padapter))) {
5958                 if ((newState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
5959                     (newState == BT_INFO_STATE_ACL_SCO_BUSY)) {
5960                         btdm_1AntUpdateHalRAMaskForSCO(padapter, false);
5961                 } else {
5962                         /*  Recover original RA setting */
5963                         btdm_1AntRecoverHalRAMask(padapter);
5964                 }
5965         } else {
5966                 phaldata = GET_HAL_DATA(padapter);
5967                 phaldata->bt_coexist.halCoex8723.btdm1Ant.bRAChanged = false;
5968         }
5969
5970         if (oldState == newState)
5971                 return;
5972
5973         if (oldState == BT_INFO_STATE_ACL_ONLY_BUSY) {
5974                 struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
5975                 Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCnt = 0;
5976                 Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
5977         }
5978
5979         if ((oldState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
5980             (oldState == BT_INFO_STATE_ACL_SCO_BUSY)) {
5981                 struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
5982                 Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
5983         }
5984
5985         /*  Active 2Ant mechanism when BT Connected */
5986         if ((oldState == BT_INFO_STATE_DISABLED) ||
5987             (oldState == BT_INFO_STATE_NO_CONNECTION)) {
5988                 if ((newState != BT_INFO_STATE_DISABLED) &&
5989                     (newState != BT_INFO_STATE_NO_CONNECTION)) {
5990                         BTDM_SetSwRfRxLpfCorner(padapter,
5991                                                 BT_RF_RX_LPF_CORNER_SHRINK);
5992                         BTDM_AGCTable(padapter, BT_AGCTABLE_ON);
5993                         BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON);
5994                 }
5995         } else {
5996                 if ((newState == BT_INFO_STATE_DISABLED) ||
5997                     (newState == BT_INFO_STATE_NO_CONNECTION)) {
5998                         BTDM_SetSwRfRxLpfCorner(padapter,
5999                                                 BT_RF_RX_LPF_CORNER_RESUME);
6000                         BTDM_AGCTable(padapter, BT_AGCTABLE_OFF);
6001                         BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_OFF);
6002                 }
6003         }
6004 }
6005
6006 static void btdm_1AntBtCoexistHandler(struct rtw_adapter *padapter)
6007 {
6008         struct hal_data_8723a *pHalData;
6009         struct bt_coexist_8723a *pBtCoex8723;
6010         struct btdm_8723a_1ant *pBtdm8723;
6011
6012         pHalData = GET_HAL_DATA(padapter);
6013         pBtCoex8723 = &pHalData->bt_coexist.halCoex8723;
6014         pBtdm8723 = &pBtCoex8723->btdm1Ant;
6015         padapter->pwrctrlpriv.btcoex_rfon = false;
6016         if (!rtl8723a_BT_enabled(padapter)) {
6017                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is disabled\n"));
6018
6019                 if (BTDM_IsWifiConnectionExist(padapter)) {
6020                         RTPRINT(FBT, BT_TRACE,
6021                                 ("[BTCoex], wifi is connected\n"));
6022
6023                         if (BTDM_IsWifiBusy(padapter)) {
6024                                 RTPRINT(FBT, BT_TRACE,
6025                                         ("[BTCoex], Wifi is busy\n"));
6026                                 btdm_1AntSetPSTDMA(padapter, false, 0,
6027                                                    false, 9);
6028                         } else {
6029                                 RTPRINT(FBT, BT_TRACE,
6030                                         ("[BTCoex], Wifi is idle\n"));
6031                                 _btdm_1AntSetPSTDMA(padapter, true, 2, 1,
6032                                                     false, 9);
6033                         }
6034                 } else {
6035                         RTPRINT(FBT, BT_TRACE,
6036                                 ("[BTCoex], wifi is disconnected\n"));
6037
6038                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
6039                 }
6040         } else {
6041                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is enabled\n"));
6042
6043                 if (BTDM_IsWifiConnectionExist(padapter)) {
6044                         RTPRINT(FBT, BT_TRACE,
6045                                 ("[BTCoex], wifi is connected\n"));
6046
6047                         btdm_1AntWifiParaAdjust(padapter, true);
6048                         btdm_1AntCoexProcessForWifiConnect(padapter);
6049                 } else {
6050                         RTPRINT(FBT, BT_TRACE,
6051                                 ("[BTCoex], wifi is disconnected\n"));
6052
6053                         /*  Antenna switch at BT side(0x870 = 0x300,
6054                             0x860 = 0x210) after PSTDMA off */
6055                         btdm_1AntWifiParaAdjust(padapter, false);
6056                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 0);
6057                 }
6058         }
6059
6060         btdm_1AntBTStateChangeHandler(padapter, pBtCoex8723->prec2hBtInfo,
6061                                       pBtCoex8723->c2hBtInfo);
6062         pBtCoex8723->prec2hBtInfo = pBtCoex8723->c2hBtInfo;
6063 }
6064
6065 void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
6066                                  u8 *rssi_wifi, u8 *rssi_bt)
6067 {
6068         struct hal_data_8723a *pHalData;
6069         struct btdm_8723a_1ant *pBtdm8723;
6070         u8 RSSI_WiFi_Cmpnstn, RSSI_BT_Cmpnstn;
6071
6072         pHalData = GET_HAL_DATA(padapter);
6073         pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
6074         RSSI_WiFi_Cmpnstn = 0;
6075         RSSI_BT_Cmpnstn = 0;
6076
6077         switch (pBtdm8723->curPsTdma) {
6078         case 1: /*  WiFi 52ms */
6079                 RSSI_WiFi_Cmpnstn = 11; /*  22*0.48 */
6080                 break;
6081         case 2: /*  WiFi 36ms */
6082                 RSSI_WiFi_Cmpnstn = 14; /*  22*0.64 */
6083                 break;
6084         case 9: /*  WiFi 20ms */
6085                 RSSI_WiFi_Cmpnstn = 18; /*  22*0.80 */
6086                 break;
6087         case 11: /*  WiFi 10ms */
6088                 RSSI_WiFi_Cmpnstn = 20; /*  22*0.90 */
6089                 break;
6090         case 4: /*  WiFi 21ms */
6091                 RSSI_WiFi_Cmpnstn = 17; /*  22*0.79 */
6092                 break;
6093         case 16: /*  WiFi 24ms */
6094                 RSSI_WiFi_Cmpnstn = 18; /*  22*0.76 */
6095                 break;
6096         case 18: /*  WiFi 37ms */
6097                 RSSI_WiFi_Cmpnstn = 14; /*  22*0.64 */
6098                 break;
6099         case 23: /* Level-1, Antenna switch to BT at all time */
6100         case 24: /* Level-2, Antenna switch to BT at all time */
6101         case 25: /* Level-3a, Antenna switch to BT at all time */
6102         case 26: /* Level-3b, Antenna switch to BT at all time */
6103         case 27: /* Level-3b, Antenna switch to BT at all time */
6104         case 33: /* BT SCO & WiFi site survey */
6105                 RSSI_WiFi_Cmpnstn = 22;
6106                 break;
6107         default:
6108                 break;
6109         }
6110
6111         if (rssi_wifi && RSSI_WiFi_Cmpnstn) {
6112                 RTPRINT(FBT, BT_TRACE,
6113                         ("[BTCoex], 1AntSgnlCmpnstn, case %d, WiFiCmpnstn "
6114                          "=%d(%d => %d)\n", pBtdm8723->curPsTdma,
6115                          RSSI_WiFi_Cmpnstn, *rssi_wifi,
6116                          *rssi_wifi+RSSI_WiFi_Cmpnstn));
6117                 *rssi_wifi += RSSI_WiFi_Cmpnstn;
6118         }
6119
6120         if (rssi_bt && RSSI_BT_Cmpnstn) {
6121                 RTPRINT(FBT, BT_TRACE,
6122                         ("[BTCoex], 1AntSgnlCmpnstn, case %d, BTCmpnstn "
6123                          "=%d(%d => %d)\n", pBtdm8723->curPsTdma,
6124                          RSSI_BT_Cmpnstn, *rssi_bt, *rssi_bt+RSSI_BT_Cmpnstn));
6125                 *rssi_bt += RSSI_BT_Cmpnstn;
6126         }
6127 }
6128
6129 static void BTDM_1AntParaInit(struct rtw_adapter *padapter)
6130 {
6131         struct hal_data_8723a *pHalData;
6132         struct bt_coexist_8723a *pBtCoex;
6133         struct btdm_8723a_1ant *pBtdm8723;
6134
6135         pHalData = GET_HAL_DATA(padapter);
6136         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6137         pBtdm8723 = &pBtCoex->btdm1Ant;
6138
6139         /*  Enable counter statistics */
6140         rtl8723au_write8(padapter, 0x76e, 0x4);
6141         btdm_1AntPtaParaReload(padapter);
6142
6143         pBtdm8723->wifiRssiThresh = 48;
6144
6145         pBtdm8723->bWiFiHalt = false;
6146         pBtdm8723->bRAChanged = false;
6147
6148         if ((pBtCoex->c2hBtInfo != BT_INFO_STATE_DISABLED) &&
6149             (pBtCoex->c2hBtInfo != BT_INFO_STATE_NO_CONNECTION)) {
6150                 BTDM_SetSwRfRxLpfCorner(padapter, BT_RF_RX_LPF_CORNER_SHRINK);
6151                 BTDM_AGCTable(padapter, BT_AGCTABLE_ON);
6152                 BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON);
6153         }
6154 }
6155
6156 static void BTDM_1AntForHalt(struct rtw_adapter *padapter)
6157 {
6158         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for halt\n"));
6159
6160         GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
6161                 true;
6162
6163         btdm_1AntWifiParaAdjust(padapter, false);
6164
6165         /*  don't use btdm_1AntSetPSTDMA() here */
6166         /*  it will call rtw_set_ps_mode23a() and request pwrpriv->lock. */
6167         /*  This will lead to deadlock, if this function is called in IPS */
6168         /*  Lucas@20130205 */
6169         btdm_1AntPsTdma(padapter, false, 0);
6170
6171         btdm_SetFwIgnoreWlanAct(padapter, true);
6172 }
6173
6174 static void BTDM_1AntLpsLeave(struct rtw_adapter *padapter)
6175 {
6176         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for LPS Leave\n"));
6177
6178         /*  Prevent from entering LPS again */
6179         GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
6180                 true;
6181
6182         btdm_1AntSetPSTDMA(padapter, false, 0, false, 8);
6183 /*btdm_1AntPsTdma(padapter, false, 8); */
6184 }
6185
6186 static void BTDM_1AntWifiAssociateNotify(struct rtw_adapter *padapter, u8 type)
6187 {
6188         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6189
6190         RTPRINT(FBT, BT_TRACE,
6191                 ("\n[BTCoex], 1Ant for associate, type =%d\n", type));
6192
6193         if (type) {
6194                 rtl8723a_CheckAntenna_Selection(padapter);
6195                 if (!rtl8723a_BT_enabled(padapter))
6196                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
6197                 else {
6198                         struct bt_coexist_8723a *pBtCoex;
6199                         u8 BtState;
6200
6201                         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6202                         BtState = pBtCoex->c2hBtInfo;
6203
6204                         btdm_1AntTSFSwitch(padapter, true);
6205
6206                         if (BtState == BT_INFO_STATE_NO_CONNECTION ||
6207                             BtState == BT_INFO_STATE_CONNECT_IDLE) {
6208                                 btdm_1AntSetPSTDMA(padapter, false, 0,
6209                                                    true, 28);
6210                         } else if (BtState == BT_INFO_STATE_SCO_ONLY_BUSY ||
6211                                    BtState == BT_INFO_STATE_ACL_SCO_BUSY) {
6212                                 btdm_1AntSetPSTDMA(padapter, false, 0,
6213                                                    false, 8);
6214                                 rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
6215                                 rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
6216                         } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY ||
6217                                    BtState == BT_INFO_STATE_ACL_INQ_OR_PAG) {
6218                                 if (pBtCoex->c2hBtProfile == BT_INFO_HID)
6219                                         btdm_1AntSetPSTDMA(padapter, false, 0,
6220                                                            true, 35);
6221                                 else
6222                                         btdm_1AntSetPSTDMA(padapter, false, 0,
6223                                                            true, 29);
6224                         }
6225                 }
6226         } else {
6227                 if (!rtl8723a_BT_enabled(padapter)) {
6228                         if (!BTDM_IsWifiConnectionExist(padapter)) {
6229                                 btdm_1AntPsTdma(padapter, false, 0);
6230                                 btdm_1AntTSFSwitch(padapter, false);
6231                         }
6232                 }
6233
6234                 btdm_1AntBtCoexistHandler(padapter);
6235         }
6236 }
6237
6238 static void
6239 BTDM_1AntMediaStatusNotify(struct rtw_adapter *padapter,
6240                            enum rt_media_status mstatus)
6241 {
6242         struct bt_coexist_8723a *pBtCoex;
6243
6244         pBtCoex = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723;
6245
6246         RTPRINT(FBT, BT_TRACE,
6247                 ("\n\n[BTCoex]******************************\n"));
6248         RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatus, WiFi %s !!\n",
6249                         mstatus == RT_MEDIA_CONNECT?"CONNECT":"DISCONNECT"));
6250         RTPRINT(FBT, BT_TRACE, ("[BTCoex]******************************\n"));
6251
6252         if (RT_MEDIA_CONNECT == mstatus) {
6253                 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) {
6254                         if (pBtCoex->c2hBtInfo == BT_INFO_STATE_SCO_ONLY_BUSY ||
6255                             pBtCoex->c2hBtInfo == BT_INFO_STATE_ACL_SCO_BUSY)
6256                                 btdm_1AntUpdateHalRAMaskForSCO(padapter, true);
6257                 }
6258
6259                 padapter->pwrctrlpriv.DelayLPSLastTimeStamp = jiffies;
6260                 BTDM_1AntForDhcp(padapter);
6261         } else {
6262                 /* DBG_8723A("%s rtl8723a_DeinitAntenna_Selection\n",
6263                    __func__); */
6264                 rtl8723a_DeinitAntenna_Selection(padapter);
6265                 btdm_1AntBtCoexistHandler(padapter);
6266                 pBtCoex->btdm1Ant.bRAChanged = false;
6267         }
6268 }
6269
6270 void BTDM_1AntForDhcp(struct rtw_adapter *padapter)
6271 {
6272         struct hal_data_8723a *pHalData;
6273         u8 BtState;
6274         struct bt_coexist_8723a *pBtCoex;
6275         struct btdm_8723a_1ant *pBtdm8723;
6276
6277         pHalData = GET_HAL_DATA(padapter);
6278         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6279         BtState = pBtCoex->c2hBtInfo;
6280         pBtdm8723 = &pBtCoex->btdm1Ant;
6281
6282         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for DHCP\n"));
6283         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, WiFi is %s\n",
6284                                 BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
6285         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, %s\n",
6286                                 BtStateString[BtState]));
6287
6288         BTDM_1AntWifiAssociateNotify(padapter, true);
6289 }
6290
6291 static void BTDM_1AntWifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
6292 {
6293         struct hal_data_8723a *pHalData;
6294         u8 BtState;
6295         struct bt_coexist_8723a *pBtCoex;
6296         struct btdm_8723a_1ant *pBtdm8723;
6297
6298         pHalData = GET_HAL_DATA(padapter);
6299         BtState = pHalData->bt_coexist.halCoex8723.c2hBtInfo;
6300         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6301         pBtdm8723 = &pBtCoex->btdm1Ant;
6302
6303         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for wifi scan =%d!!\n",
6304                                 scanType));
6305         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, WiFi is %s\n",
6306                                 BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
6307         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, %s\n",
6308                                 BtStateString[BtState]));
6309
6310         if (scanType) {
6311                 rtl8723a_CheckAntenna_Selection(padapter);
6312                 if (!rtl8723a_BT_enabled(padapter)) {
6313                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
6314                 } else if (BTDM_IsWifiConnectionExist(padapter) == false) {
6315                         BTDM_1AntWifiAssociateNotify(padapter, true);
6316                 } else {
6317                         if ((BtState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
6318                             (BtState == BT_INFO_STATE_ACL_SCO_BUSY)) {
6319                                 if (pBtCoex->bC2hBtInquiryPage) {
6320                                         btdm_1AntSetPSTDMA(padapter, false, 0,
6321                                                            true, 32);
6322                                 } else {
6323                                         padapter->pwrctrlpriv.btcoex_rfon =
6324                                                 true;
6325                                         btdm_1AntSetPSTDMA(padapter, true, 0,
6326                                                            true, 33);
6327                                 }
6328                         } else if (true == pBtCoex->bC2hBtInquiryPage) {
6329                                 padapter->pwrctrlpriv.btcoex_rfon = true;
6330                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 30);
6331                         } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY) {
6332                                 padapter->pwrctrlpriv.btcoex_rfon = true;
6333                                 if (pBtCoex->c2hBtProfile == BT_INFO_HID)
6334                                         btdm_1AntSetPSTDMA(padapter, true, 0,
6335                                                            true, 34);
6336                                 else
6337                                         btdm_1AntSetPSTDMA(padapter, true, 0,
6338                                                            true, 4);
6339                         } else {
6340                                 padapter->pwrctrlpriv.btcoex_rfon = true;
6341                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 5);
6342                         }
6343                 }
6344
6345                 btdm_NotifyFwScan(padapter, 1);
6346         } else {
6347                 /*  WiFi_Finish_Scan */
6348                 btdm_NotifyFwScan(padapter, 0);
6349                 btdm_1AntBtCoexistHandler(padapter);
6350         }
6351 }
6352
6353 static void BTDM_1AntFwC2hBtInfo8723A(struct rtw_adapter *padapter)
6354 {
6355         struct hal_data_8723a *pHalData;
6356         struct bt_30info *pBTInfo;
6357         struct bt_mgnt *pBtMgnt;
6358         struct bt_coexist_8723a *pBtCoex;
6359         u8 u1tmp, btState;
6360
6361         pHalData = GET_HAL_DATA(padapter);
6362         pBTInfo = GET_BT_INFO(padapter);
6363         pBtMgnt = &pBTInfo->BtMgnt;
6364         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6365
6366         u1tmp = pBtCoex->c2hBtInfoOriginal;
6367         /*  sco BUSY bit is not used on voice over PCM platform */
6368         btState = u1tmp & 0xF;
6369         pBtCoex->c2hBtProfile = u1tmp & 0xE0;
6370
6371         /*  default set bt to idle state. */
6372         pBtMgnt->ExtConfig.bBTBusy = false;
6373         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
6374
6375         /*  check BIT2 first ==> check if bt is under inquiry or page scan */
6376         if (btState & BIT(2))
6377                 pBtCoex->bC2hBtInquiryPage = true;
6378         else
6379                 pBtCoex->bC2hBtInquiryPage = false;
6380         btState &= ~BIT(2);
6381
6382         if (!(btState & BIT(0)))
6383                 pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
6384         else {
6385                 if (btState == 0x1)
6386                         pBtCoex->c2hBtInfo = BT_INFO_STATE_CONNECT_IDLE;
6387                 else if (btState == 0x9) {
6388                         if (pBtCoex->bC2hBtInquiryPage == true)
6389                                 pBtCoex->c2hBtInfo =
6390                                         BT_INFO_STATE_ACL_INQ_OR_PAG;
6391                         else
6392                                 pBtCoex->c2hBtInfo =
6393                                         BT_INFO_STATE_ACL_ONLY_BUSY;
6394                         pBtMgnt->ExtConfig.bBTBusy = true;
6395                 } else if (btState == 0x3) {
6396                         pBtCoex->c2hBtInfo = BT_INFO_STATE_SCO_ONLY_BUSY;
6397                         pBtMgnt->ExtConfig.bBTBusy = true;
6398                 } else if (btState == 0xb) {
6399                         pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_SCO_BUSY;
6400                         pBtMgnt->ExtConfig.bBTBusy = true;
6401                 } else
6402                         pBtCoex->c2hBtInfo = BT_INFO_STATE_MAX;
6403                 if (pBtMgnt->ExtConfig.bBTBusy)
6404                         pHalData->bt_coexist.CurrentState &=
6405                                 ~BT_COEX_STATE_BT_IDLE;
6406         }
6407
6408         if (BT_INFO_STATE_NO_CONNECTION == pBtCoex->c2hBtInfo ||
6409             BT_INFO_STATE_CONNECT_IDLE == pBtCoex->c2hBtInfo) {
6410                 if (pBtCoex->bC2hBtInquiryPage)
6411                         pBtCoex->c2hBtInfo = BT_INFO_STATE_INQ_OR_PAG;
6412         }
6413
6414         RTPRINT(FBT, BT_TRACE, ("[BTC2H], %s(%d)\n",
6415                         BtStateString[pBtCoex->c2hBtInfo], pBtCoex->c2hBtInfo));
6416
6417         if (pBtCoex->c2hBtProfile != BT_INFO_HID)
6418                 pBtCoex->c2hBtProfile &= ~BT_INFO_HID;
6419 }
6420
6421 void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter)
6422 {
6423         struct mlme_priv *pmlmepriv;
6424         struct hal_data_8723a *pHalData;
6425         unsigned long delta_time;
6426
6427         pmlmepriv = &padapter->mlmepriv;
6428         pHalData = GET_HAL_DATA(padapter);
6429
6430         if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)) {
6431                 /*  already done in BTDM_1AntForScan() */
6432                 RTPRINT(FBT, BT_TRACE,
6433                         ("[BTCoex], wifi is under scan progress!!\n"));
6434                 return;
6435         }
6436
6437         if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) {
6438                 RTPRINT(FBT, BT_TRACE,
6439                         ("[BTCoex], wifi is under link progress!!\n"));
6440                 return;
6441         }
6442
6443         /*  under DHCP(Special packet) */
6444         delta_time = jiffies - padapter->pwrctrlpriv.DelayLPSLastTimeStamp;
6445         delta_time = jiffies_to_msecs(delta_time);
6446         if (delta_time < 500) {
6447                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under DHCP "
6448                                         "progress(%li ms)!!\n", delta_time));
6449                 return;
6450         }
6451
6452         BTDM_CheckWiFiState(padapter);
6453
6454         btdm_1AntBtCoexistHandler(padapter);
6455 }
6456
6457 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */
6458
6459 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */
6460
6461 /*  local function start with btdm_ */
6462 static u8 btdm_ActionAlgorithm(struct rtw_adapter *padapter)
6463 {
6464         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
6465         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
6466         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6467         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6468         u8 bScoExist = false, bBtLinkExist = false, bBtHsModeExist = false;
6469         u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED;
6470
6471         if (pBtMgnt->ExtConfig.NumberOfHandle)
6472                 bBtLinkExist = true;
6473         if (pBtMgnt->ExtConfig.NumberOfSCO)
6474                 bScoExist = true;
6475         if (BT_HsConnectionEstablished(padapter))
6476                 bBtHsModeExist = true;
6477
6478         /*  here we get BT status first */
6479         /*  1) initialize */
6480         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
6481
6482         if ((bScoExist) || (bBtHsModeExist) ||
6483             (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID))) {
6484                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO or HID or HS exists, set BT non-idle !!!\n"));
6485                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6486         } else {
6487                 /*  A2dp profile */
6488                 if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) &&
6489                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP))) {
6490                         if (BTDM_BtTxRxCounterL(padapter) < 100) {
6491                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx < 100, set BT connected-idle!!!\n"));
6492                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6493                         } else {
6494                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx >= 100, set BT non-idle!!!\n"));
6495                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6496                         }
6497                 }
6498                 /*  Pan profile */
6499                 if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) &&
6500                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) {
6501                         if (BTDM_BtTxRxCounterL(padapter) < 600) {
6502                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority tx+rx < 600, set BT connected-idle!!!\n"));
6503                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6504                         } else {
6505                                 if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) {
6506                                         if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx /
6507                                             pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) {
6508                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority rx/tx > 9, set BT connected-idle!!!\n"));
6509                                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6510                                         }
6511                                 }
6512                         }
6513                         if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) {
6514                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, set BT non-idle!!!\n"));
6515                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6516                         }
6517                 }
6518                 /*  Pan+A2dp profile */
6519                 if ((pBtMgnt->ExtConfig.NumberOfHandle == 2) &&
6520                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) &&
6521                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) {
6522                         if (BTDM_BtTxRxCounterL(padapter) < 600) {
6523                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority tx+rx < 600, set BT connected-idle!!!\n"));
6524                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6525                         } else {
6526                                 if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) {
6527                                         if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx /
6528                                             pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) {
6529                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority rx/tx > 9, set BT connected-idle!!!\n"));
6530                                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6531                                         }
6532                                 }
6533                         }
6534                         if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) {
6535                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, set BT non-idle!!!\n"));
6536                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6537                         }
6538                 }
6539         }
6540         if (BT_2ANT_BT_STATUS_IDLE != pBtdm8723->btStatus)
6541                 pBtMgnt->ExtConfig.bBTBusy = true;
6542         else
6543                 pBtMgnt->ExtConfig.bBTBusy = false;
6544
6545         if (!bBtLinkExist) {
6546                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], No profile exists!!!\n"));
6547                 return algorithm;
6548         }
6549
6550         if (pBtMgnt->ExtConfig.NumberOfHandle == 1) {
6551                 if (bScoExist) {
6552                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n"));
6553                         algorithm = BT_2ANT_COEX_ALGO_SCO;
6554                 } else {
6555                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) {
6556                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID only\n"));
6557                                 algorithm = BT_2ANT_COEX_ALGO_HID;
6558                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6559                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP only\n"));
6560                                 algorithm = BT_2ANT_COEX_ALGO_A2DP;
6561                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6562                                 if (bBtHsModeExist) {
6563                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(HS) only\n"));
6564                                         algorithm = BT_2ANT_COEX_ALGO_PANHS;
6565                                 } else {
6566                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR) only\n"));
6567                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR;
6568                                 }
6569                         } else {
6570                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d \n",
6571                                 pBtMgnt->ExtConfig.NumberOfHandle));
6572                         }
6573                 }
6574         } else if (pBtMgnt->ExtConfig.NumberOfHandle == 2) {
6575                 if (bScoExist) {
6576                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) {
6577                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n"));
6578                                 algorithm = BT_2ANT_COEX_ALGO_HID;
6579                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6580                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n"));
6581                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6582                                 if (bBtHsModeExist) {
6583                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
6584                                         algorithm = BT_2ANT_COEX_ALGO_SCO;
6585                                 } else {
6586                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
6587                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
6588                                 }
6589                         } else {
6590                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched ACL profile for NumberOfHandle =%d\n",
6591                                 pBtMgnt->ExtConfig.NumberOfHandle));
6592                         }
6593                 } else {
6594                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6595                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6596                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
6597                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
6598                 } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6599                            BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6600                                 if (bBtHsModeExist) {
6601                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
6602                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
6603                                 } else {
6604                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
6605                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
6606                                 }
6607                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6608                                    BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6609                                 if (bBtHsModeExist) {
6610                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
6611                                         algorithm = BT_2ANT_COEX_ALGO_A2DP;
6612                                 } else {
6613                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
6614                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
6615                                 }
6616                         } else {
6617                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
6618                                         pBtMgnt->ExtConfig.NumberOfHandle));
6619                         }
6620                 }
6621         } else if (pBtMgnt->ExtConfig.NumberOfHandle == 3) {
6622                 if (bScoExist) {
6623                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6624                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6625                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP\n"));
6626                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6627                                    BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6628                                 if (bBtHsModeExist) {
6629                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n"));
6630                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
6631                                 } else {
6632                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n"));
6633                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
6634                                 }
6635                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6636                                    BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6637                                 if (bBtHsModeExist) {
6638                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(HS)\n"));
6639                                         algorithm = BT_2ANT_COEX_ALGO_SCO;
6640                                 } else {
6641                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(EDR)\n"));
6642                                 }
6643                         } else {
6644                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n",
6645                                         pBtMgnt->ExtConfig.NumberOfHandle));
6646                         }
6647                 } else {
6648                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6649                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6650                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6651                                 if (bBtHsModeExist) {
6652                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
6653                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANHS;
6654                                 } else {
6655                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
6656                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
6657                                 }
6658                         } else {
6659                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
6660                                         pBtMgnt->ExtConfig.NumberOfHandle));
6661                         }
6662                 }
6663         } else if (pBtMgnt->ExtConfig.NumberOfHandle >= 3) {
6664                 if (bScoExist) {
6665                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6666                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6667                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6668                                 if (bBtHsModeExist)
6669                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"));
6670                                 else
6671                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(EDR)\n"));
6672                         } else {
6673                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n",
6674                                         pBtMgnt->ExtConfig.NumberOfHandle));
6675                         }
6676                 } else {
6677                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
6678                                 pBtMgnt->ExtConfig.NumberOfHandle));
6679                 }
6680         }
6681         return algorithm;
6682 }
6683
6684 static u8 btdm_NeedToDecBtPwr(struct rtw_adapter *padapter)
6685 {
6686         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6687         u8 bRet = false;
6688
6689         if (BT_Operation(padapter)) {
6690                 if (pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB > 47) {
6691                         RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for HS mode!!\n"));
6692                         bRet = true;
6693                 } else {
6694                         RTPRINT(FBT, BT_TRACE, ("NO Need to decrease bt power for HS mode!!\n"));
6695                 }
6696         } else {
6697                 if (BTDM_IsWifiConnectionExist(padapter)) {
6698                         RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for Wifi is connected!!\n"));
6699                         bRet = true;
6700                 }
6701         }
6702         return bRet;
6703 }
6704
6705 static void
6706 btdm_SetCoexTable(struct rtw_adapter *padapter, u32 val0x6c0,
6707                   u32 val0x6c8, u8 val0x6cc)
6708 {
6709         RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c0 = 0x%x\n", val0x6c0));
6710         rtl8723au_write32(padapter, 0x6c0, val0x6c0);
6711
6712         RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c8 = 0x%x\n", val0x6c8));
6713         rtl8723au_write32(padapter, 0x6c8, val0x6c8);
6714
6715         RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6cc = 0x%x\n", val0x6cc));
6716         rtl8723au_write8(padapter, 0x6cc, val0x6cc);
6717 }
6718
6719 static void
6720 btdm_SetSwFullTimeDacSwing(struct rtw_adapter *padapter, u8 bSwDacSwingOn,
6721                            u32 swDacSwingLvl)
6722 {
6723         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6724
6725         if (bSwDacSwingOn) {
6726                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing = 0x%x\n", swDacSwingLvl));
6727                 PHY_SetBBReg(padapter, 0x880, 0xff000000, swDacSwingLvl);
6728                 pHalData->bt_coexist.bSWCoexistAllOff = false;
6729         } else {
6730                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing Off!\n"));
6731                 PHY_SetBBReg(padapter, 0x880, 0xff000000, 0xc0);
6732         }
6733 }
6734
6735 static void
6736 btdm_SetFwDacSwingLevel(struct rtw_adapter *padapter, u8 dacSwingLvl)
6737 {
6738         u8 H2C_Parameter[1] = {0};
6739
6740         H2C_Parameter[0] = dacSwingLvl;
6741
6742         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Set Dac Swing Level = 0x%x\n", dacSwingLvl));
6743         RTPRINT(FBT, BT_TRACE, ("[BTCoex], write 0x29 = 0x%x\n", H2C_Parameter[0]));
6744
6745         FillH2CCmd(padapter, 0x29, 1, H2C_Parameter);
6746 }
6747
6748 static void btdm_2AntDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr)
6749 {
6750         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6751         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6752
6753         RTPRINT(FBT, BT_TRACE,
6754                 ("[BTCoex], Dec BT power = %s\n",
6755                 ((bDecBtPwr) ? "ON" : "OFF")));
6756         pBtdm8723->bCurDecBtPwr = bDecBtPwr;
6757
6758         if (pBtdm8723->bPreDecBtPwr == pBtdm8723->bCurDecBtPwr)
6759                 return;
6760
6761         BTDM_SetFwDecBtPwr(padapter, pBtdm8723->bCurDecBtPwr);
6762
6763         pBtdm8723->bPreDecBtPwr = pBtdm8723->bCurDecBtPwr;
6764 }
6765
6766 static void
6767 btdm_2AntFwDacSwingLvl(struct rtw_adapter *padapter, u8 fwDacSwingLvl)
6768 {
6769         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6770         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6771
6772         RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW Dac Swing level = %d\n",  fwDacSwingLvl));
6773         pBtdm8723->curFwDacSwingLvl = fwDacSwingLvl;
6774
6775         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preFwDacSwingLvl =%d, curFwDacSwingLvl =%d\n", */
6776         /*pBtdm8723->preFwDacSwingLvl, pBtdm8723->curFwDacSwingLvl)); */
6777
6778         if (pBtdm8723->preFwDacSwingLvl == pBtdm8723->curFwDacSwingLvl)
6779                 return;
6780
6781         btdm_SetFwDacSwingLevel(padapter, pBtdm8723->curFwDacSwingLvl);
6782
6783         pBtdm8723->preFwDacSwingLvl = pBtdm8723->curFwDacSwingLvl;
6784 }
6785
6786 static void
6787 btdm_2AntRfShrink(struct rtw_adapter *padapter, u8 bRxRfShrinkOn)
6788 {
6789         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6790         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6791
6792         RTPRINT(FBT, BT_TRACE,
6793                 ("[BTCoex], turn Rx RF Shrink = %s\n",
6794                 ((bRxRfShrinkOn) ? "ON" : "OFF")));
6795         pBtdm8723->bCurRfRxLpfShrink = bRxRfShrinkOn;
6796
6797         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreRfRxLpfShrink =%d, bCurRfRxLpfShrink =%d\n", */
6798         /*pBtdm8723->bPreRfRxLpfShrink, pBtdm8723->bCurRfRxLpfShrink)); */
6799
6800         if (pBtdm8723->bPreRfRxLpfShrink == pBtdm8723->bCurRfRxLpfShrink)
6801                 return;
6802
6803         BTDM_SetSwRfRxLpfCorner(padapter, (u8)pBtdm8723->bCurRfRxLpfShrink);
6804
6805         pBtdm8723->bPreRfRxLpfShrink = pBtdm8723->bCurRfRxLpfShrink;
6806 }
6807
6808 static void
6809 btdm_2AntLowPenaltyRa(struct rtw_adapter *padapter, u8 bLowPenaltyRa)
6810 {
6811         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6812         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6813
6814         RTPRINT(FBT, BT_TRACE,
6815                 ("[BTCoex], turn LowPenaltyRA = %s\n",
6816                 ((bLowPenaltyRa) ? "ON" : "OFF")));
6817         pBtdm8723->bCurLowPenaltyRa = bLowPenaltyRa;
6818
6819         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreLowPenaltyRa =%d, bCurLowPenaltyRa =%d\n", */
6820         /*pBtdm8723->bPreLowPenaltyRa, pBtdm8723->bCurLowPenaltyRa)); */
6821
6822         if (pBtdm8723->bPreLowPenaltyRa == pBtdm8723->bCurLowPenaltyRa)
6823                 return;
6824
6825         BTDM_SetSwPenaltyTxRateAdaptive(padapter, (u8)pBtdm8723->bCurLowPenaltyRa);
6826
6827         pBtdm8723->bPreLowPenaltyRa = pBtdm8723->bCurLowPenaltyRa;
6828 }
6829
6830 static void
6831 btdm_2AntDacSwing(struct rtw_adapter *padapter,
6832                   u8 bDacSwingOn, u32 dacSwingLvl)
6833 {
6834         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6835         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6836
6837         RTPRINT(FBT, BT_TRACE,
6838                 ("[BTCoex], turn DacSwing =%s, dacSwingLvl = 0x%x\n",
6839                 (bDacSwingOn ? "ON" : "OFF"), dacSwingLvl));
6840         pBtdm8723->bCurDacSwingOn = bDacSwingOn;
6841         pBtdm8723->curDacSwingLvl = dacSwingLvl;
6842
6843         if ((pBtdm8723->bPreDacSwingOn == pBtdm8723->bCurDacSwingOn) &&
6844             (pBtdm8723->preDacSwingLvl == pBtdm8723->curDacSwingLvl))
6845                 return;
6846
6847         mdelay(30);
6848         btdm_SetSwFullTimeDacSwing(padapter, bDacSwingOn, dacSwingLvl);
6849
6850         pBtdm8723->bPreDacSwingOn = pBtdm8723->bCurDacSwingOn;
6851         pBtdm8723->preDacSwingLvl = pBtdm8723->curDacSwingLvl;
6852 }
6853
6854 static void btdm_2AntAdcBackOff(struct rtw_adapter *padapter, u8 bAdcBackOff)
6855 {
6856         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6857         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6858
6859         RTPRINT(FBT, BT_TRACE,
6860                 ("[BTCoex], turn AdcBackOff = %s\n",
6861                 ((bAdcBackOff) ? "ON" : "OFF")));
6862         pBtdm8723->bCurAdcBackOff = bAdcBackOff;
6863
6864         if (pBtdm8723->bPreAdcBackOff == pBtdm8723->bCurAdcBackOff)
6865                 return;
6866
6867         BTDM_BBBackOffLevel(padapter, (u8)pBtdm8723->bCurAdcBackOff);
6868
6869         pBtdm8723->bPreAdcBackOff = pBtdm8723->bCurAdcBackOff;
6870 }
6871
6872 static void btdm_2AntAgcTable(struct rtw_adapter *padapter, u8 bAgcTableEn)
6873 {
6874         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6875         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6876
6877         RTPRINT(FBT, BT_TRACE,
6878                 ("[BTCoex], %s Agc Table\n", ((bAgcTableEn) ? "Enable" : "Disable")));
6879         pBtdm8723->bCurAgcTableEn = bAgcTableEn;
6880
6881         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreAgcTableEn =%d, bCurAgcTableEn =%d\n", */
6882         /*pBtdm8723->bPreAgcTableEn, pBtdm8723->bCurAgcTableEn)); */
6883
6884         if (pBtdm8723->bPreAgcTableEn == pBtdm8723->bCurAgcTableEn)
6885                 return;
6886
6887         BTDM_AGCTable(padapter, (u8)bAgcTableEn);
6888
6889         pBtdm8723->bPreAgcTableEn = pBtdm8723->bCurAgcTableEn;
6890 }
6891
6892 static void
6893 btdm_2AntCoexTable(struct rtw_adapter *padapter,
6894                    u32 val0x6c0, u32 val0x6c8, u8 val0x6cc)
6895 {
6896         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6897         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6898
6899         RTPRINT(FBT, BT_TRACE, ("[BTCoex], write Coex Table 0x6c0 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
6900                 val0x6c0, val0x6c8, val0x6cc));
6901         pBtdm8723->curVal0x6c0 = val0x6c0;
6902         pBtdm8723->curVal0x6c8 = val0x6c8;
6903         pBtdm8723->curVal0x6cc = val0x6cc;
6904
6905         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n", */
6906         /*pBtdm8723->preVal0x6c0, pBtdm8723->preVal0x6c8, pBtdm8723->preVal0x6cc)); */
6907         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n", */
6908         /*pBtdm8723->curVal0x6c0, pBtdm8723->curVal0x6c8, pBtdm8723->curVal0x6cc)); */
6909
6910         if ((pBtdm8723->preVal0x6c0 == pBtdm8723->curVal0x6c0) &&
6911             (pBtdm8723->preVal0x6c8 == pBtdm8723->curVal0x6c8) &&
6912             (pBtdm8723->preVal0x6cc == pBtdm8723->curVal0x6cc))
6913                 return;
6914
6915         btdm_SetCoexTable(padapter, val0x6c0, val0x6c8, val0x6cc);
6916
6917         pBtdm8723->preVal0x6c0 = pBtdm8723->curVal0x6c0;
6918         pBtdm8723->preVal0x6c8 = pBtdm8723->curVal0x6c8;
6919         pBtdm8723->preVal0x6cc = pBtdm8723->curVal0x6cc;
6920 }
6921
6922 static void btdm_2AntIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable)
6923 {
6924         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6925         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6926
6927         RTPRINT(FBT, BT_TRACE,
6928                 ("[BTCoex], turn Ignore WlanAct %s\n", (bEnable ? "ON" : "OFF")));
6929         pBtdm8723->bCurIgnoreWlanAct = bEnable;
6930
6931
6932         if (pBtdm8723->bPreIgnoreWlanAct == pBtdm8723->bCurIgnoreWlanAct)
6933                 return;
6934
6935         btdm_SetFwIgnoreWlanAct(padapter, bEnable);
6936         pBtdm8723->bPreIgnoreWlanAct = pBtdm8723->bCurIgnoreWlanAct;
6937 }
6938
6939 static void
6940 btdm_2AntSetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2,
6941                  u8 byte3, u8 byte4, u8 byte5)
6942 {
6943         u8 H2C_Parameter[5] = {0};
6944
6945         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6946
6947         /*  byte1[1:0] != 0 means enable pstdma */
6948         /*  for 2Ant bt coexist, if byte1 != 0 means enable pstdma */
6949         if (byte1)
6950                 pHalData->bt_coexist.bFWCoexistAllOff = false;
6951         H2C_Parameter[0] = byte1;
6952         H2C_Parameter[1] = byte2;
6953         H2C_Parameter[2] = byte3;
6954         H2C_Parameter[3] = byte4;
6955         H2C_Parameter[4] = byte5;
6956
6957         pHalData->bt_coexist.fw3aVal[0] = byte1;
6958         pHalData->bt_coexist.fw3aVal[1] = byte2;
6959         pHalData->bt_coexist.fw3aVal[2] = byte3;
6960         pHalData->bt_coexist.fw3aVal[3] = byte4;
6961         pHalData->bt_coexist.fw3aVal[4] = byte5;
6962
6963         RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%x%08x\n",
6964                 H2C_Parameter[0],
6965                 H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
6966
6967         FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter);
6968         }
6969
6970 static void btdm_2AntPsTdma(struct rtw_adapter *padapter, u8 bTurnOn, u8 type)
6971 {
6972         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6973         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6974         u32                     btTxRxCnt = 0;
6975         u8 bTurnOnByCnt = false;
6976         u8 psTdmaTypeByCnt = 0;
6977
6978         btTxRxCnt = BTDM_BtTxRxCounterH(padapter)+BTDM_BtTxRxCounterL(padapter);
6979         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT TxRx Counters = %d\n", btTxRxCnt));
6980         if (btTxRxCnt > 3000) {
6981                 bTurnOnByCnt = true;
6982                 psTdmaTypeByCnt = 8;
6983
6984                 RTPRINT(FBT, BT_TRACE,
6985                         ("[BTCoex], For BTTxRxCounters, turn %s PS TDMA, type =%d\n",
6986                         (bTurnOnByCnt ? "ON" : "OFF"), psTdmaTypeByCnt));
6987                 pBtdm8723->bCurPsTdmaOn = bTurnOnByCnt;
6988                 pBtdm8723->curPsTdma = psTdmaTypeByCnt;
6989         } else {
6990                 RTPRINT(FBT, BT_TRACE,
6991                         ("[BTCoex], turn %s PS TDMA, type =%d\n",
6992                         (bTurnOn ? "ON" : "OFF"), type));
6993                 pBtdm8723->bCurPsTdmaOn = bTurnOn;
6994                 pBtdm8723->curPsTdma = type;
6995         }
6996
6997         if ((pBtdm8723->bPrePsTdmaOn == pBtdm8723->bCurPsTdmaOn) &&
6998             (pBtdm8723->prePsTdma == pBtdm8723->curPsTdma))
6999                 return;
7000
7001         if (bTurnOn) {
7002                 switch (type) {
7003                 case 1:
7004                 default:
7005                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98);
7006                         break;
7007                 case 2:
7008                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98);
7009                         break;
7010                 case 3:
7011                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98);
7012                         break;
7013                 case 4:
7014                         btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0xa1, 0x80);
7015                         break;
7016                 case 5:
7017                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98);
7018                         break;
7019                 case 6:
7020                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98);
7021                         break;
7022                 case 7:
7023                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98);
7024                         break;
7025                 case 8:
7026                         btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0x20, 0x80);
7027                         break;
7028                 case 9:
7029                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98);
7030                         break;
7031                 case 10:
7032                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98);
7033                         break;
7034                 case 11:
7035                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98);
7036                         break;
7037                 case 12:
7038                         btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98);
7039                         break;
7040                 case 13:
7041                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98);
7042                         break;
7043                 case 14:
7044                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98);
7045                         break;
7046                 case 15:
7047                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98);
7048                         break;
7049                 case 16:
7050                         btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0x20, 0x98);
7051                         break;
7052                 case 17:
7053                         btdm_2AntSetFw3a(padapter, 0xa3, 0x2f, 0x2f, 0x20, 0x80);
7054                         break;
7055                 case 18:
7056                         btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98);
7057                         break;
7058                 case 19:
7059                         btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0xa1, 0x98);
7060                         break;
7061                 case 20:
7062                         btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0x20, 0x98);
7063                         break;
7064                 }
7065         } else {
7066                 /*  disable PS tdma */
7067                 switch (type) {
7068                 case 0:
7069                         btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
7070                         break;
7071                 case 1:
7072                         btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x0, 0x0);
7073                         break;
7074                 default:
7075                         btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
7076                         break;
7077                 }
7078         }
7079
7080         /*  update pre state */
7081         pBtdm8723->bPrePsTdmaOn =  pBtdm8723->bCurPsTdmaOn;
7082         pBtdm8723->prePsTdma = pBtdm8723->curPsTdma;
7083 }
7084
7085 static void btdm_2AntBtInquiryPage(struct rtw_adapter *padapter)
7086 {
7087         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7088         btdm_2AntIgnoreWlanAct(padapter, false);
7089         btdm_2AntPsTdma(padapter, true, 8);
7090 }
7091
7092 static u8 btdm_HoldForBtInqPage(struct rtw_adapter *padapter)
7093 {
7094         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7095         u32 curTime = jiffies;
7096
7097         if (pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) {
7098                 /*  bt inquiry or page is started. */
7099                 if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime == 0) {
7100                         pHalData->bt_coexist.halCoex8723.btInqPageStartTime = curTime;
7101                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page is started at time : 0x%lx \n",
7102                         pHalData->bt_coexist.halCoex8723.btInqPageStartTime));
7103                 }
7104         }
7105         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page started time : 0x%lx, curTime : 0x%x \n",
7106                 pHalData->bt_coexist.halCoex8723.btInqPageStartTime, curTime));
7107
7108         if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) {
7109                 if (((curTime - pHalData->bt_coexist.halCoex8723.btInqPageStartTime)/1000000) >= 10) {
7110                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page >= 10sec!!!"));
7111                         pHalData->bt_coexist.halCoex8723.btInqPageStartTime = 0;
7112                 }
7113         }
7114
7115         if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) {
7116                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7117                 btdm_2AntIgnoreWlanAct(padapter, false);
7118                 btdm_2AntPsTdma(padapter, true, 8);
7119                 return true;
7120         } else {
7121                 return false;
7122         }
7123 }
7124
7125 static u8 btdm_Is2Ant8723ACommonAction(struct rtw_adapter *padapter)
7126 {
7127         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7128         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
7129         u8 bCommon = false;
7130
7131         RTPRINT(FBT, BT_TRACE, ("%s :BTDM_IsWifiConnectionExist =%x check_fwstate =%x pmlmepriv->fw_state = 0x%x\n", __func__, BTDM_IsWifiConnectionExist(padapter), check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)), padapter->mlmepriv.fw_state));
7132
7133         if ((!BTDM_IsWifiConnectionExist(padapter)) &&
7134             (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
7135             (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) {
7136                 RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt idle!!\n"));
7137
7138                 btdm_2AntLowPenaltyRa(padapter, false);
7139                 btdm_2AntRfShrink(padapter, false);
7140                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7141
7142                 btdm_2AntIgnoreWlanAct(padapter, false);
7143                 btdm_2AntPsTdma(padapter, false, 0);
7144                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7145                 btdm_2AntDecBtPwr(padapter, false);
7146
7147                 btdm_2AntAgcTable(padapter, false);
7148                 btdm_2AntAdcBackOff(padapter, false);
7149                 btdm_2AntDacSwing(padapter, false, 0xc0);
7150
7151                 bCommon = true;
7152         } else if (((BTDM_IsWifiConnectionExist(padapter)) ||
7153                    (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) &&
7154                    (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) {
7155                 RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT idle!!\n"));
7156
7157                 btdm_2AntLowPenaltyRa(padapter, true);
7158                 btdm_2AntRfShrink(padapter, false);
7159                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7160
7161                 btdm_2AntIgnoreWlanAct(padapter, false);
7162                 btdm_2AntPsTdma(padapter, false, 0);
7163                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7164                 btdm_2AntDecBtPwr(padapter, true);
7165
7166                 btdm_2AntAgcTable(padapter, false);
7167                 btdm_2AntAdcBackOff(padapter, false);
7168                 btdm_2AntDacSwing(padapter, false, 0xc0);
7169
7170                 bCommon = true;
7171         } else if ((!BTDM_IsWifiConnectionExist(padapter)) &&
7172                    (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
7173                    (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) {
7174                 RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt connected idle!!\n"));
7175
7176                 btdm_2AntLowPenaltyRa(padapter, true);
7177                 btdm_2AntRfShrink(padapter, true);
7178                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7179
7180                 btdm_2AntIgnoreWlanAct(padapter, false);
7181                 btdm_2AntPsTdma(padapter, false, 0);
7182                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7183                 btdm_2AntDecBtPwr(padapter, false);
7184
7185                 btdm_2AntAgcTable(padapter, false);
7186                 btdm_2AntAdcBackOff(padapter, false);
7187                 btdm_2AntDacSwing(padapter, false, 0xc0);
7188
7189                 bCommon = true;
7190         } else if (((BTDM_IsWifiConnectionExist(padapter)) ||
7191                    (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) &&
7192                    (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) {
7193                 RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + Bt connected idle!!\n"));
7194
7195                 btdm_2AntLowPenaltyRa(padapter, true);
7196                 btdm_2AntRfShrink(padapter, true);
7197                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7198
7199                 btdm_2AntIgnoreWlanAct(padapter, false);
7200                 btdm_2AntPsTdma(padapter, false, 0);
7201                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7202                 btdm_2AntDecBtPwr(padapter, true);
7203
7204                 btdm_2AntAgcTable(padapter, false);
7205                 btdm_2AntAdcBackOff(padapter, false);
7206                 btdm_2AntDacSwing(padapter, false, 0xc0);
7207
7208                 bCommon = true;
7209         } else if ((!BTDM_IsWifiConnectionExist(padapter)) &&
7210                    (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
7211                    (BT_2ANT_BT_STATUS_NON_IDLE == pBtdm8723->btStatus)) {
7212                 RTPRINT(FBT, BT_TRACE, ("Wifi idle + BT non-idle!!\n"));
7213
7214                 btdm_2AntLowPenaltyRa(padapter, true);
7215                 btdm_2AntRfShrink(padapter, true);
7216                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7217
7218                 btdm_2AntIgnoreWlanAct(padapter, false);
7219                 btdm_2AntPsTdma(padapter, false, 0);
7220                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7221                 btdm_2AntDecBtPwr(padapter, false);
7222
7223                 btdm_2AntAgcTable(padapter, false);
7224                 btdm_2AntAdcBackOff(padapter, false);
7225                 btdm_2AntDacSwing(padapter, false, 0xc0);
7226
7227                 bCommon = true;
7228         } else {
7229                 RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT non-idle!!\n"));
7230                 btdm_2AntLowPenaltyRa(padapter, true);
7231                 btdm_2AntRfShrink(padapter, true);
7232                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7233                 btdm_2AntIgnoreWlanAct(padapter, false);
7234                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7235
7236                 bCommon = false;
7237         }
7238         return bCommon;
7239 }
7240
7241 static void
7242 btdm_2AntTdmaDurationAdjust(struct rtw_adapter *padapter, u8 bScoHid,
7243                             u8 bTxPause, u8 maxInterval)
7244 {
7245         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7246         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
7247         static s32              up, dn, m, n, WaitCount;
7248         s32                     result;   /* 0: no change, +1: increase WiFi duration, -1: decrease WiFi duration */
7249         u8 retryCount = 0;
7250
7251         RTPRINT(FBT, BT_TRACE, ("[BTCoex], TdmaDurationAdjust()\n"));
7252
7253         if (pBtdm8723->bResetTdmaAdjust) {
7254                 pBtdm8723->bResetTdmaAdjust = false;
7255                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
7256                 if (bScoHid) {
7257                         if (bTxPause) {
7258                                 if (maxInterval == 1) {
7259                                         btdm_2AntPsTdma(padapter, true, 15);
7260                                         pBtdm8723->psTdmaDuAdjType = 15;
7261                                 } else if (maxInterval == 2) {
7262                                         btdm_2AntPsTdma(padapter, true, 15);
7263                                         pBtdm8723->psTdmaDuAdjType = 15;
7264                                 } else if (maxInterval == 3) {
7265                                         btdm_2AntPsTdma(padapter, true, 15);
7266                                         pBtdm8723->psTdmaDuAdjType = 15;
7267                                 } else {
7268                                         btdm_2AntPsTdma(padapter, true, 15);
7269                                         pBtdm8723->psTdmaDuAdjType = 15;
7270                                 }
7271                         } else {
7272                                 if (maxInterval == 1) {
7273                                         btdm_2AntPsTdma(padapter, true, 11);
7274                                         pBtdm8723->psTdmaDuAdjType = 11;
7275                                 } else if (maxInterval == 2) {
7276                                         btdm_2AntPsTdma(padapter, true, 11);
7277                                         pBtdm8723->psTdmaDuAdjType = 11;
7278                                 } else if (maxInterval == 3) {
7279                                         btdm_2AntPsTdma(padapter, true, 11);
7280                                         pBtdm8723->psTdmaDuAdjType = 11;
7281                                 } else {
7282                                         btdm_2AntPsTdma(padapter, true, 11);
7283                                         pBtdm8723->psTdmaDuAdjType = 11;
7284                                 }
7285                         }
7286                 } else {
7287                         if (bTxPause) {
7288                                 if (maxInterval == 1) {
7289                                         btdm_2AntPsTdma(padapter, true, 7);
7290                                         pBtdm8723->psTdmaDuAdjType = 7;
7291                                 } else if (maxInterval == 2) {
7292                                         btdm_2AntPsTdma(padapter, true, 7);
7293                                         pBtdm8723->psTdmaDuAdjType = 7;
7294                                 } else if (maxInterval == 3) {
7295                                         btdm_2AntPsTdma(padapter, true, 7);
7296                                         pBtdm8723->psTdmaDuAdjType = 7;
7297                                 } else {
7298                                         btdm_2AntPsTdma(padapter, true, 7);
7299                                         pBtdm8723->psTdmaDuAdjType = 7;
7300                                 }
7301                         } else {
7302                                 if (maxInterval == 1) {
7303                                         btdm_2AntPsTdma(padapter, true, 3);
7304                                         pBtdm8723->psTdmaDuAdjType = 3;
7305                                 } else if (maxInterval == 2) {
7306                                         btdm_2AntPsTdma(padapter, true, 3);
7307                                         pBtdm8723->psTdmaDuAdjType = 3;
7308                                 } else if (maxInterval == 3) {
7309                                         btdm_2AntPsTdma(padapter, true, 3);
7310                                         pBtdm8723->psTdmaDuAdjType = 3;
7311                                 } else {
7312                                         btdm_2AntPsTdma(padapter, true, 3);
7313                                         pBtdm8723->psTdmaDuAdjType = 3;
7314                                 }
7315                         }
7316                 }
7317                 up = 0;
7318                 dn = 0;
7319                 m = 1;
7320                 n = 3;
7321                 result = 0;
7322                 WaitCount = 0;
7323         } else {
7324                 /* accquire the BT TRx retry count from BT_Info byte2 */
7325                 retryCount = pHalData->bt_coexist.halCoex8723.btRetryCnt;
7326                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], retryCount = %d\n", retryCount));
7327                 result = 0;
7328                 WaitCount++;
7329
7330                 if (retryCount == 0) {  /*  no retry in the last 2-second duration */
7331                         up++;
7332                         dn--;
7333
7334                         if (dn <= 0)
7335                                 dn = 0;
7336
7337                         if (up >= n) {  /*  if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration */
7338                                 WaitCount = 0;
7339                                 n = 3;
7340                                 up = 0;
7341                                 dn = 0;
7342                                 result = 1;
7343                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Increase wifi duration!!\n"));
7344                         }
7345                 } else if (retryCount <= 3) {   /*  <= 3 retry in the last 2-second duration */
7346                         up--;
7347                         dn++;
7348
7349                         if (up <= 0)
7350                                 up = 0;
7351
7352                         if (dn == 2) {  /*  if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration */
7353                                 if (WaitCount <= 2)
7354                                         m++; /*  ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ */
7355                                 else
7356                                         m = 1;
7357
7358                                 if (m >= 20) /* m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */
7359                                         m = 20;
7360
7361                                 n = 3*m;
7362                                 up = 0;
7363                                 dn = 0;
7364                                 WaitCount = 0;
7365                                 result = -1;
7366                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
7367                         }
7368                 } else {  /* retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration */
7369                         if (WaitCount == 1)
7370                                 m++; /*  ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ */
7371                         else
7372                                 m = 1;
7373
7374                         if (m >= 20) /* m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */
7375                                 m = 20;
7376                         n = 3*m;
7377                         up = 0;
7378                         dn = 0;
7379                         WaitCount = 0;
7380                         result = -1;
7381                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n"));
7382                 }
7383
7384                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval));
7385                 if (maxInterval == 1) {
7386                         if (bTxPause) {
7387                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
7388                                 if (pBtdm8723->curPsTdma == 1) {
7389                                         btdm_2AntPsTdma(padapter, true, 5);
7390                                         pBtdm8723->psTdmaDuAdjType = 5;
7391                                 } else if (pBtdm8723->curPsTdma == 2) {
7392                                         btdm_2AntPsTdma(padapter, true, 6);
7393                                         pBtdm8723->psTdmaDuAdjType = 6;
7394                                 } else if (pBtdm8723->curPsTdma == 3) {
7395                                         btdm_2AntPsTdma(padapter, true, 7);
7396                                         pBtdm8723->psTdmaDuAdjType = 7;
7397                                 } else if (pBtdm8723->curPsTdma == 4) {
7398                                         btdm_2AntPsTdma(padapter, true, 8);
7399                                         pBtdm8723->psTdmaDuAdjType = 8;
7400                                 }
7401                                 if (pBtdm8723->curPsTdma == 9) {
7402                                         btdm_2AntPsTdma(padapter, true, 13);
7403                                         pBtdm8723->psTdmaDuAdjType = 13;
7404                                 } else if (pBtdm8723->curPsTdma == 10) {
7405                                         btdm_2AntPsTdma(padapter, true, 14);
7406                                         pBtdm8723->psTdmaDuAdjType = 14;
7407                                 } else if (pBtdm8723->curPsTdma == 11) {
7408                                         btdm_2AntPsTdma(padapter, true, 15);
7409                                         pBtdm8723->psTdmaDuAdjType = 15;
7410                                 } else if (pBtdm8723->curPsTdma == 12) {
7411                                         btdm_2AntPsTdma(padapter, true, 16);
7412                                         pBtdm8723->psTdmaDuAdjType = 16;
7413                                 }
7414
7415                                 if (result == -1) {
7416                                         if (pBtdm8723->curPsTdma == 5) {
7417                                                 btdm_2AntPsTdma(padapter, true, 6);
7418                                                 pBtdm8723->psTdmaDuAdjType = 6;
7419                                         } else if (pBtdm8723->curPsTdma == 6) {
7420                                                 btdm_2AntPsTdma(padapter, true, 7);
7421                                                 pBtdm8723->psTdmaDuAdjType = 7;
7422                                         } else if (pBtdm8723->curPsTdma == 7) {
7423                                                 btdm_2AntPsTdma(padapter, true, 8);
7424                                                 pBtdm8723->psTdmaDuAdjType = 8;
7425                                         } else if (pBtdm8723->curPsTdma == 13) {
7426                                                 btdm_2AntPsTdma(padapter, true, 14);
7427                                                 pBtdm8723->psTdmaDuAdjType = 14;
7428                                         } else if (pBtdm8723->curPsTdma == 14) {
7429                                                 btdm_2AntPsTdma(padapter, true, 15);
7430                                                 pBtdm8723->psTdmaDuAdjType = 15;
7431                                         } else if (pBtdm8723->curPsTdma == 15) {
7432                                                 btdm_2AntPsTdma(padapter, true, 16);
7433                                                 pBtdm8723->psTdmaDuAdjType = 16;
7434                                         }
7435                                 } else if (result == 1) {
7436                                         if (pBtdm8723->curPsTdma == 8) {
7437                                                 btdm_2AntPsTdma(padapter, true, 7);
7438                                                 pBtdm8723->psTdmaDuAdjType = 7;
7439                                         } else if (pBtdm8723->curPsTdma == 7) {
7440                                                 btdm_2AntPsTdma(padapter, true, 6);
7441                                                 pBtdm8723->psTdmaDuAdjType = 6;
7442                                         } else if (pBtdm8723->curPsTdma == 6) {
7443                                                 btdm_2AntPsTdma(padapter, true, 5);
7444                                                 pBtdm8723->psTdmaDuAdjType = 5;
7445                                         } else if (pBtdm8723->curPsTdma == 16) {
7446                                                 btdm_2AntPsTdma(padapter, true, 15);
7447                                                 pBtdm8723->psTdmaDuAdjType = 15;
7448                                         } else if (pBtdm8723->curPsTdma == 15) {
7449                                                 btdm_2AntPsTdma(padapter, true, 14);
7450                                                 pBtdm8723->psTdmaDuAdjType = 14;
7451                                         } else if (pBtdm8723->curPsTdma == 14) {
7452                                                 btdm_2AntPsTdma(padapter, true, 13);
7453                                                 pBtdm8723->psTdmaDuAdjType = 13;
7454                                         }
7455                                 }
7456                         } else {
7457                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
7458                                 if (pBtdm8723->curPsTdma == 5) {
7459                                         btdm_2AntPsTdma(padapter, true, 1);
7460                                         pBtdm8723->psTdmaDuAdjType = 1;
7461                                 } else if (pBtdm8723->curPsTdma == 6) {
7462                                         btdm_2AntPsTdma(padapter, true, 2);
7463                                         pBtdm8723->psTdmaDuAdjType = 2;
7464                                 } else if (pBtdm8723->curPsTdma == 7) {
7465                                         btdm_2AntPsTdma(padapter, true, 3);
7466                                         pBtdm8723->psTdmaDuAdjType = 3;
7467                                 } else if (pBtdm8723->curPsTdma == 8) {
7468                                         btdm_2AntPsTdma(padapter, true, 4);
7469                                         pBtdm8723->psTdmaDuAdjType = 4;
7470                                 }
7471                                 if (pBtdm8723->curPsTdma == 13) {
7472                                         btdm_2AntPsTdma(padapter, true, 9);
7473                                         pBtdm8723->psTdmaDuAdjType = 9;
7474                                 } else if (pBtdm8723->curPsTdma == 14) {
7475                                         btdm_2AntPsTdma(padapter, true, 10);
7476                                         pBtdm8723->psTdmaDuAdjType = 10;
7477                                 } else if (pBtdm8723->curPsTdma == 15) {
7478                                         btdm_2AntPsTdma(padapter, true, 11);
7479                                         pBtdm8723->psTdmaDuAdjType = 11;
7480                                 } else if (pBtdm8723->curPsTdma == 16) {
7481                                         btdm_2AntPsTdma(padapter, true, 12);
7482                                         pBtdm8723->psTdmaDuAdjType = 12;
7483                                 }
7484
7485                                 if (result == -1) {
7486                                         if (pBtdm8723->curPsTdma == 1) {
7487                                                 btdm_2AntPsTdma(padapter, true, 2);
7488                                                 pBtdm8723->psTdmaDuAdjType = 2;
7489                                         } else if (pBtdm8723->curPsTdma == 2) {
7490                                                 btdm_2AntPsTdma(padapter, true, 3);
7491                                                 pBtdm8723->psTdmaDuAdjType = 3;
7492                                         } else if (pBtdm8723->curPsTdma == 3) {
7493                                                 btdm_2AntPsTdma(padapter, true, 4);
7494                                                 pBtdm8723->psTdmaDuAdjType = 4;
7495                                         } else if (pBtdm8723->curPsTdma == 9) {
7496                                                 btdm_2AntPsTdma(padapter, true, 10);
7497                                                 pBtdm8723->psTdmaDuAdjType = 10;
7498                                         } else if (pBtdm8723->curPsTdma == 10) {
7499                                                 btdm_2AntPsTdma(padapter, true, 11);
7500                                                 pBtdm8723->psTdmaDuAdjType = 11;
7501                                         } else if (pBtdm8723->curPsTdma == 11) {
7502                                                 btdm_2AntPsTdma(padapter, true, 12);
7503                                                 pBtdm8723->psTdmaDuAdjType = 12;
7504                                         }
7505                                 } else if (result == 1) {
7506                                         if (pBtdm8723->curPsTdma == 4) {
7507                                                 btdm_2AntPsTdma(padapter, true, 3);
7508                                                 pBtdm8723->psTdmaDuAdjType = 3;
7509                                         } else if (pBtdm8723->curPsTdma == 3) {
7510                                                 btdm_2AntPsTdma(padapter, true, 2);
7511                                                 pBtdm8723->psTdmaDuAdjType = 2;
7512                                         } else if (pBtdm8723->curPsTdma == 2) {
7513                                                 btdm_2AntPsTdma(padapter, true, 1);
7514                                                 pBtdm8723->psTdmaDuAdjType = 1;
7515                                         } else if (pBtdm8723->curPsTdma == 12) {
7516                                                 btdm_2AntPsTdma(padapter, true, 11);
7517                                                 pBtdm8723->psTdmaDuAdjType = 11;
7518                                         } else if (pBtdm8723->curPsTdma == 11) {
7519                                                 btdm_2AntPsTdma(padapter, true, 10);
7520                                                 pBtdm8723->psTdmaDuAdjType = 10;
7521                                         } else if (pBtdm8723->curPsTdma == 10) {
7522                                                 btdm_2AntPsTdma(padapter, true, 9);
7523                                                 pBtdm8723->psTdmaDuAdjType = 9;
7524                                         }
7525                                 }
7526                         }
7527                 } else if (maxInterval == 2) {
7528                         if (bTxPause) {
7529                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
7530                                 if (pBtdm8723->curPsTdma == 1) {
7531                                         btdm_2AntPsTdma(padapter, true, 6);
7532                                         pBtdm8723->psTdmaDuAdjType = 6;
7533                                 } else if (pBtdm8723->curPsTdma == 2) {
7534                                         btdm_2AntPsTdma(padapter, true, 6);
7535                                         pBtdm8723->psTdmaDuAdjType = 6;
7536                                 } else if (pBtdm8723->curPsTdma == 3) {
7537                                         btdm_2AntPsTdma(padapter, true, 7);
7538                                         pBtdm8723->psTdmaDuAdjType = 7;
7539                                 } else if (pBtdm8723->curPsTdma == 4) {
7540                                         btdm_2AntPsTdma(padapter, true, 8);
7541                                         pBtdm8723->psTdmaDuAdjType = 8;
7542                                 }
7543                                 if (pBtdm8723->curPsTdma == 9) {
7544                                         btdm_2AntPsTdma(padapter, true, 14);
7545                                         pBtdm8723->psTdmaDuAdjType = 14;
7546                                 } else if (pBtdm8723->curPsTdma == 10) {
7547                                         btdm_2AntPsTdma(padapter, true, 14);
7548                                         pBtdm8723->psTdmaDuAdjType = 14;
7549                                 } else if (pBtdm8723->curPsTdma == 11) {
7550                                         btdm_2AntPsTdma(padapter, true, 15);
7551                                         pBtdm8723->psTdmaDuAdjType = 15;
7552                                 } else if (pBtdm8723->curPsTdma == 12) {
7553                                         btdm_2AntPsTdma(padapter, true, 16);
7554                                         pBtdm8723->psTdmaDuAdjType = 16;
7555                                 }
7556                                 if (result == -1) {
7557                                         if (pBtdm8723->curPsTdma == 5) {
7558                                                 btdm_2AntPsTdma(padapter, true, 6);
7559                                                 pBtdm8723->psTdmaDuAdjType = 6;
7560                                         } else if (pBtdm8723->curPsTdma == 6) {
7561                                                 btdm_2AntPsTdma(padapter, true, 7);
7562                                                 pBtdm8723->psTdmaDuAdjType = 7;
7563                                         } else if (pBtdm8723->curPsTdma == 7) {
7564                                                 btdm_2AntPsTdma(padapter, true, 8);
7565                                                 pBtdm8723->psTdmaDuAdjType = 8;
7566                                         } else if (pBtdm8723->curPsTdma == 13) {
7567                                                 btdm_2AntPsTdma(padapter, true, 14);
7568                                                 pBtdm8723->psTdmaDuAdjType = 14;
7569                                         } else if (pBtdm8723->curPsTdma == 14) {
7570                                                 btdm_2AntPsTdma(padapter, true, 15);
7571                                                 pBtdm8723->psTdmaDuAdjType = 15;
7572                                         } else if (pBtdm8723->curPsTdma == 15) {
7573                                                 btdm_2AntPsTdma(padapter, true, 16);
7574                                                 pBtdm8723->psTdmaDuAdjType = 16;
7575                                         }
7576                                 } else if (result == 1) {
7577                                         if (pBtdm8723->curPsTdma == 8) {
7578                                                 btdm_2AntPsTdma(padapter, true, 7);
7579                                                 pBtdm8723->psTdmaDuAdjType = 7;
7580                                         } else if (pBtdm8723->curPsTdma == 7) {
7581                                                 btdm_2AntPsTdma(padapter, true, 6);
7582                                                 pBtdm8723->psTdmaDuAdjType = 6;
7583                                         } else if (pBtdm8723->curPsTdma == 6) {
7584                                                 btdm_2AntPsTdma(padapter, true, 6);
7585                                                 pBtdm8723->psTdmaDuAdjType = 6;
7586                                         } else if (pBtdm8723->curPsTdma == 16) {
7587                                                 btdm_2AntPsTdma(padapter, true, 15);
7588                                                 pBtdm8723->psTdmaDuAdjType = 15;
7589                                         } else if (pBtdm8723->curPsTdma == 15) {
7590                                                 btdm_2AntPsTdma(padapter, true, 14);
7591                                                 pBtdm8723->psTdmaDuAdjType = 14;
7592                                         } else if (pBtdm8723->curPsTdma == 14) {
7593                                                 btdm_2AntPsTdma(padapter, true, 14);
7594                                                 pBtdm8723->psTdmaDuAdjType = 14;
7595                                         }
7596                                 }
7597                         } else {
7598                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
7599                                 if (pBtdm8723->curPsTdma == 5) {
7600                                         btdm_2AntPsTdma(padapter, true, 2);
7601                                         pBtdm8723->psTdmaDuAdjType = 2;
7602                                 } else if (pBtdm8723->curPsTdma == 6) {
7603                                         btdm_2AntPsTdma(padapter, true, 2);
7604                                         pBtdm8723->psTdmaDuAdjType = 2;
7605                                 } else if (pBtdm8723->curPsTdma == 7) {
7606                                         btdm_2AntPsTdma(padapter, true, 3);
7607                                         pBtdm8723->psTdmaDuAdjType = 3;
7608                                 } else if (pBtdm8723->curPsTdma == 8) {
7609                                         btdm_2AntPsTdma(padapter, true, 4);
7610                                         pBtdm8723->psTdmaDuAdjType = 4;
7611                                 }
7612                                 if (pBtdm8723->curPsTdma == 13) {
7613                                         btdm_2AntPsTdma(padapter, true, 10);
7614                                         pBtdm8723->psTdmaDuAdjType = 10;
7615                                 } else if (pBtdm8723->curPsTdma == 14) {
7616                                         btdm_2AntPsTdma(padapter, true, 10);
7617                                         pBtdm8723->psTdmaDuAdjType = 10;
7618                                 } else if (pBtdm8723->curPsTdma == 15) {
7619                                         btdm_2AntPsTdma(padapter, true, 11);
7620                                         pBtdm8723->psTdmaDuAdjType = 11;
7621                                 } else if (pBtdm8723->curPsTdma == 16) {
7622                                         btdm_2AntPsTdma(padapter, true, 12);
7623                                         pBtdm8723->psTdmaDuAdjType = 12;
7624                                 }
7625                                 if (result == -1) {
7626                                         if (pBtdm8723->curPsTdma == 1) {
7627                                                 btdm_2AntPsTdma(padapter, true, 2);
7628                                                 pBtdm8723->psTdmaDuAdjType = 2;
7629                                         } else if (pBtdm8723->curPsTdma == 2) {
7630                                                 btdm_2AntPsTdma(padapter, true, 3);
7631                                                 pBtdm8723->psTdmaDuAdjType = 3;
7632                                         } else if (pBtdm8723->curPsTdma == 3) {
7633                                                 btdm_2AntPsTdma(padapter, true, 4);
7634                                                 pBtdm8723->psTdmaDuAdjType = 4;
7635                                         } else if (pBtdm8723->curPsTdma == 9) {
7636                                                 btdm_2AntPsTdma(padapter, true, 10);
7637                                                 pBtdm8723->psTdmaDuAdjType = 10;
7638                                         } else if (pBtdm8723->curPsTdma == 10) {
7639                                                 btdm_2AntPsTdma(padapter, true, 11);
7640                                                 pBtdm8723->psTdmaDuAdjType = 11;
7641                                         } else if (pBtdm8723->curPsTdma == 11) {
7642                                                 btdm_2AntPsTdma(padapter, true, 12);
7643                                                 pBtdm8723->psTdmaDuAdjType = 12;
7644                                         }
7645                                 } else if (result == 1) {
7646                                         if (pBtdm8723->curPsTdma == 4) {
7647                                                 btdm_2AntPsTdma(padapter, true, 3);
7648                                                 pBtdm8723->psTdmaDuAdjType = 3;
7649                                         } else if (pBtdm8723->curPsTdma == 3) {
7650                                                 btdm_2AntPsTdma(padapter, true, 2);
7651                                                 pBtdm8723->psTdmaDuAdjType = 2;
7652                                         } else if (pBtdm8723->curPsTdma == 2) {
7653                                                 btdm_2AntPsTdma(padapter, true, 2);
7654                                                 pBtdm8723->psTdmaDuAdjType = 2;
7655                                         } else if (pBtdm8723->curPsTdma == 12) {
7656                                                 btdm_2AntPsTdma(padapter, true, 11);
7657                                                 pBtdm8723->psTdmaDuAdjType = 11;
7658                                         } else if (pBtdm8723->curPsTdma == 11) {
7659                                                 btdm_2AntPsTdma(padapter, true, 10);
7660                                                 pBtdm8723->psTdmaDuAdjType = 10;
7661                                         } else if (pBtdm8723->curPsTdma == 10) {
7662                                                 btdm_2AntPsTdma(padapter, true, 10);
7663                                                 pBtdm8723->psTdmaDuAdjType = 10;
7664                                         }
7665                                 }
7666                         }
7667                 } else if (maxInterval == 3) {
7668                         if (bTxPause) {
7669                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
7670                                 if (pBtdm8723->curPsTdma == 1) {
7671                                         btdm_2AntPsTdma(padapter, true, 7);
7672                                         pBtdm8723->psTdmaDuAdjType = 7;
7673                                 } else if (pBtdm8723->curPsTdma == 2) {
7674                                         btdm_2AntPsTdma(padapter, true, 7);
7675                                         pBtdm8723->psTdmaDuAdjType = 7;
7676                                 } else if (pBtdm8723->curPsTdma == 3) {
7677                                         btdm_2AntPsTdma(padapter, true, 7);
7678                                         pBtdm8723->psTdmaDuAdjType = 7;
7679                                 } else if (pBtdm8723->curPsTdma == 4) {
7680                                         btdm_2AntPsTdma(padapter, true, 8);
7681                                         pBtdm8723->psTdmaDuAdjType = 8;
7682                                 }
7683                                 if (pBtdm8723->curPsTdma == 9) {
7684                                         btdm_2AntPsTdma(padapter, true, 15);
7685                                         pBtdm8723->psTdmaDuAdjType = 15;
7686                                 } else if (pBtdm8723->curPsTdma == 10) {
7687                                         btdm_2AntPsTdma(padapter, true, 15);
7688                                         pBtdm8723->psTdmaDuAdjType = 15;
7689                                 } else if (pBtdm8723->curPsTdma == 11) {
7690                                         btdm_2AntPsTdma(padapter, true, 15);
7691                                         pBtdm8723->psTdmaDuAdjType = 15;
7692                                 } else if (pBtdm8723->curPsTdma == 12) {
7693                                         btdm_2AntPsTdma(padapter, true, 16);
7694                                         pBtdm8723->psTdmaDuAdjType = 16;
7695                                 }
7696                                 if (result == -1) {
7697                                         if (pBtdm8723->curPsTdma == 5) {
7698                                                 btdm_2AntPsTdma(padapter, true, 7);
7699                                                 pBtdm8723->psTdmaDuAdjType = 7;
7700                                         } else if (pBtdm8723->curPsTdma == 6) {
7701                                                 btdm_2AntPsTdma(padapter, true, 7);
7702                                                 pBtdm8723->psTdmaDuAdjType = 7;
7703                                         } else if (pBtdm8723->curPsTdma == 7) {
7704                                                 btdm_2AntPsTdma(padapter, true, 8);
7705                                                 pBtdm8723->psTdmaDuAdjType = 8;
7706                                         } else if (pBtdm8723->curPsTdma == 13) {
7707                                                 btdm_2AntPsTdma(padapter, true, 15);
7708                                                 pBtdm8723->psTdmaDuAdjType = 15;
7709                                         } else if (pBtdm8723->curPsTdma == 14) {
7710                                                 btdm_2AntPsTdma(padapter, true, 15);
7711                                                 pBtdm8723->psTdmaDuAdjType = 15;
7712                                         } else if (pBtdm8723->curPsTdma == 15) {
7713                                                 btdm_2AntPsTdma(padapter, true, 16);
7714                                                 pBtdm8723->psTdmaDuAdjType = 16;
7715                                         }
7716                                 } else if (result == 1) {
7717                                         if (pBtdm8723->curPsTdma == 8) {
7718                                                 btdm_2AntPsTdma(padapter, true, 7);
7719                                                 pBtdm8723->psTdmaDuAdjType = 7;
7720                                         } else if (pBtdm8723->curPsTdma == 7) {
7721                                                 btdm_2AntPsTdma(padapter, true, 7);
7722                                                 pBtdm8723->psTdmaDuAdjType = 7;
7723                                         } else if (pBtdm8723->curPsTdma == 6) {
7724                                                 btdm_2AntPsTdma(padapter, true, 7);
7725                                                 pBtdm8723->psTdmaDuAdjType = 7;
7726                                         } else if (pBtdm8723->curPsTdma == 16) {
7727                                                 btdm_2AntPsTdma(padapter, true, 15);
7728                                                 pBtdm8723->psTdmaDuAdjType = 15;
7729                                         } else if (pBtdm8723->curPsTdma == 15) {
7730                                                 btdm_2AntPsTdma(padapter, true, 15);
7731                                                 pBtdm8723->psTdmaDuAdjType = 15;
7732                                         } else if (pBtdm8723->curPsTdma == 14) {
7733                                                 btdm_2AntPsTdma(padapter, true, 15);
7734                                                 pBtdm8723->psTdmaDuAdjType = 15;
7735                                         }
7736                                 }
7737                         } else {
7738                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
7739                                 if (pBtdm8723->curPsTdma == 5) {
7740                                         btdm_2AntPsTdma(padapter, true, 3);
7741                                         pBtdm8723->psTdmaDuAdjType = 3;
7742                                 } else if (pBtdm8723->curPsTdma == 6) {
7743                                         btdm_2AntPsTdma(padapter, true, 3);
7744                                         pBtdm8723->psTdmaDuAdjType = 3;
7745                                 } else if (pBtdm8723->curPsTdma == 7) {
7746                                         btdm_2AntPsTdma(padapter, true, 3);
7747                                         pBtdm8723->psTdmaDuAdjType = 3;
7748                                 } else if (pBtdm8723->curPsTdma == 8) {
7749                                         btdm_2AntPsTdma(padapter, true, 4);
7750                                         pBtdm8723->psTdmaDuAdjType = 4;
7751                                 }
7752                                 if (pBtdm8723->curPsTdma == 13) {
7753                                         btdm_2AntPsTdma(padapter, true, 11);
7754                                         pBtdm8723->psTdmaDuAdjType = 11;
7755                                 } else if (pBtdm8723->curPsTdma == 14) {
7756                                         btdm_2AntPsTdma(padapter, true, 11);
7757                                         pBtdm8723->psTdmaDuAdjType = 11;
7758                                 } else if (pBtdm8723->curPsTdma == 15) {
7759                                         btdm_2AntPsTdma(padapter, true, 11);
7760                                         pBtdm8723->psTdmaDuAdjType = 11;
7761                                 } else if (pBtdm8723->curPsTdma == 16) {
7762                                         btdm_2AntPsTdma(padapter, true, 12);
7763                                         pBtdm8723->psTdmaDuAdjType = 12;
7764                                 }
7765                                 if (result == -1) {
7766                                         if (pBtdm8723->curPsTdma == 1) {
7767                                                 btdm_2AntPsTdma(padapter, true, 3);
7768                                                 pBtdm8723->psTdmaDuAdjType = 3;
7769                                         } else if (pBtdm8723->curPsTdma == 2) {
7770                                                 btdm_2AntPsTdma(padapter, true, 3);
7771                                                 pBtdm8723->psTdmaDuAdjType = 3;
7772                                         } else if (pBtdm8723->curPsTdma == 3) {
7773                                                 btdm_2AntPsTdma(padapter, true, 4);
7774                                                 pBtdm8723->psTdmaDuAdjType = 4;
7775                                         } else if (pBtdm8723->curPsTdma == 9) {
7776                                                 btdm_2AntPsTdma(padapter, true, 11);
7777                                                 pBtdm8723->psTdmaDuAdjType = 11;
7778                                         } else if (pBtdm8723->curPsTdma == 10) {
7779                                                 btdm_2AntPsTdma(padapter, true, 11);
7780                                                 pBtdm8723->psTdmaDuAdjType = 11;
7781                                         } else if (pBtdm8723->curPsTdma == 11) {
7782                                                 btdm_2AntPsTdma(padapter, true, 12);
7783                                                 pBtdm8723->psTdmaDuAdjType = 12;
7784                                         }
7785                                 } else if (result == 1) {
7786                                         if (pBtdm8723->curPsTdma == 4) {
7787                                                 btdm_2AntPsTdma(padapter, true, 3);
7788                                                 pBtdm8723->psTdmaDuAdjType = 3;
7789                                         } else if (pBtdm8723->curPsTdma == 3) {
7790                                                 btdm_2AntPsTdma(padapter, true, 3);
7791                                                 pBtdm8723->psTdmaDuAdjType = 3;
7792                                         } else if (pBtdm8723->curPsTdma == 2) {
7793                                                 btdm_2AntPsTdma(padapter, true, 3);
7794                                                 pBtdm8723->psTdmaDuAdjType = 3;
7795                                         } else if (pBtdm8723->curPsTdma == 12) {
7796                                                 btdm_2AntPsTdma(padapter, true, 11);
7797                                                 pBtdm8723->psTdmaDuAdjType = 11;
7798                                         } else if (pBtdm8723->curPsTdma == 11) {
7799                                                 btdm_2AntPsTdma(padapter, true, 11);
7800                                                 pBtdm8723->psTdmaDuAdjType = 11;
7801                                         } else if (pBtdm8723->curPsTdma == 10) {
7802                                                 btdm_2AntPsTdma(padapter, true, 11);
7803                                                 pBtdm8723->psTdmaDuAdjType = 11;
7804                                         }
7805                                 }
7806                         }
7807                 }
7808         }
7809         RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type : recordPsTdma =%d\n", pBtdm8723->psTdmaDuAdjType));
7810         /*  if current PsTdma not match with the recorded one (when scan, dhcp...), */
7811         /*  then we have to adjust it back to the previous record one. */
7812         if (pBtdm8723->curPsTdma != pBtdm8723->psTdmaDuAdjType) {
7813                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma =%d, recordPsTdma =%d\n",
7814                         pBtdm8723->curPsTdma, pBtdm8723->psTdmaDuAdjType));
7815
7816                 if (!check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING))
7817                         btdm_2AntPsTdma(padapter, true, pBtdm8723->psTdmaDuAdjType);
7818                 else
7819                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"));
7820         }
7821 }
7822
7823 /*  default Action */
7824 /*  SCO only or SCO+PAN(HS) */
7825 static void btdm_2Ant8723ASCOAction(struct rtw_adapter *padapter)
7826 {
7827         u8 btRssiState, btRssiState1;
7828
7829         if (btdm_NeedToDecBtPwr(padapter))
7830                 btdm_2AntDecBtPwr(padapter, true);
7831         else
7832                 btdm_2AntDecBtPwr(padapter, false);
7833
7834         if (BTDM_IsHT40(padapter)) {
7835                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7836                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7837                 /*  fw mechanism */
7838                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7839                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7840                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7841                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7842                         btdm_2AntPsTdma(padapter, true, 11);
7843                 } else {
7844                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7845                         btdm_2AntPsTdma(padapter, true, 15);
7846                 }
7847
7848                 /*  sw mechanism */
7849                 btdm_2AntAgcTable(padapter, false);
7850                 btdm_2AntAdcBackOff(padapter, true);
7851                 btdm_2AntDacSwing(padapter, false, 0xc0);
7852         } else {
7853                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
7854                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7855                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
7856
7857                 /*  fw mechanism */
7858                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
7859                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
7860                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7861                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7862                         btdm_2AntPsTdma(padapter, true, 11);
7863                 } else {
7864                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7865                         btdm_2AntPsTdma(padapter, true, 15);
7866                 }
7867
7868                 /*  sw mechanism */
7869                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7870                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7871                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7872                         btdm_2AntAgcTable(padapter, true);
7873                         btdm_2AntAdcBackOff(padapter, true);
7874                         btdm_2AntDacSwing(padapter, false, 0xc0);
7875                 } else {
7876                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7877                         btdm_2AntAgcTable(padapter, false);
7878                         btdm_2AntAdcBackOff(padapter, false);
7879                         btdm_2AntDacSwing(padapter, false, 0xc0);
7880                 }
7881         }
7882 }
7883
7884 static void btdm_2Ant8723AHIDAction(struct rtw_adapter *padapter)
7885 {
7886         u8 btRssiState, btRssiState1;
7887
7888         if (btdm_NeedToDecBtPwr(padapter))
7889                 btdm_2AntDecBtPwr(padapter, true);
7890         else
7891                 btdm_2AntDecBtPwr(padapter, false);
7892
7893         if (BTDM_IsHT40(padapter)) {
7894                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7895                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7896                         /*  fw mechanism */
7897                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7898                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7899                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7900                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7901                         btdm_2AntPsTdma(padapter, true, 9);
7902                 } else {
7903                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7904                         btdm_2AntPsTdma(padapter, true, 13);
7905                 }
7906
7907                 /*  sw mechanism */
7908                 btdm_2AntAgcTable(padapter, false);
7909                 btdm_2AntAdcBackOff(padapter, false);
7910                 btdm_2AntDacSwing(padapter, false, 0xc0);
7911         } else {
7912                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
7913                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7914                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
7915
7916                 /*  fw mechanism */
7917                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
7918                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
7919                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7920                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7921                         btdm_2AntPsTdma(padapter, true, 9);
7922                 } else {
7923                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7924                         btdm_2AntPsTdma(padapter, true, 13);
7925                 }
7926
7927                 /*  sw mechanism */
7928                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7929                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7930                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7931                         btdm_2AntAgcTable(padapter, true);
7932                         btdm_2AntAdcBackOff(padapter, true);
7933                         btdm_2AntDacSwing(padapter, false, 0xc0);
7934                 } else {
7935                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7936                         btdm_2AntAgcTable(padapter, false);
7937                         btdm_2AntAdcBackOff(padapter, false);
7938                         btdm_2AntDacSwing(padapter, false, 0xc0);
7939                 }
7940         }
7941 }
7942
7943 /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
7944 static void btdm_2Ant8723AA2DPAction(struct rtw_adapter *padapter)
7945 {
7946         u8 btRssiState, btRssiState1;
7947         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7948         u8 btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
7949
7950         if (btdm_NeedToDecBtPwr(padapter))
7951                 btdm_2AntDecBtPwr(padapter, true);
7952         else
7953                 btdm_2AntDecBtPwr(padapter, false);
7954
7955         if (BTDM_IsHT40(padapter)) {
7956                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7957                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7958
7959                 /*  fw mechanism */
7960                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7961                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7962                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7963                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7964
7965                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7966                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7967                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 3);
7968                         } else {
7969                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
7970                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
7971                         }
7972                 } else {
7973                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7974                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7975                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7976                                 btdm_2AntTdmaDurationAdjust(padapter, false, true, 3);
7977                         } else {
7978                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
7979                         btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
7980                         }
7981                 }
7982
7983                 /*  sw mechanism */
7984                 btdm_2AntAgcTable(padapter, false);
7985                 btdm_2AntAdcBackOff(padapter, true);
7986                 btdm_2AntDacSwing(padapter, false, 0xc0);
7987         } else {
7988                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
7989                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7990                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
7991
7992                 /*  fw mechanism */
7993                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
7994                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
7995                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7996                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7997                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7998                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7999                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 3);
8000                         } else {
8001                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8002                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
8003                         }
8004                 } else {
8005                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8006                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8007                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8008                                 btdm_2AntTdmaDurationAdjust(padapter, false, true, 3);
8009                         } else {
8010                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8011                                 btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
8012                         }
8013                 }
8014
8015                 /*  sw mechanism */
8016                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8017                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8018                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8019                         btdm_2AntAgcTable(padapter, true);
8020                         btdm_2AntAdcBackOff(padapter, true);
8021                         btdm_2AntDacSwing(padapter, false, 0xc0);
8022                 } else {
8023                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8024                         btdm_2AntAgcTable(padapter, false);
8025                         btdm_2AntAdcBackOff(padapter, false);
8026                         btdm_2AntDacSwing(padapter, false, 0xc0);
8027                 }
8028         }
8029 }
8030
8031 static void btdm_2Ant8723APANEDRAction(struct rtw_adapter *padapter)
8032 {
8033         u8 btRssiState, btRssiState1;
8034
8035         if (btdm_NeedToDecBtPwr(padapter))
8036                 btdm_2AntDecBtPwr(padapter, true);
8037         else
8038                 btdm_2AntDecBtPwr(padapter, false);
8039
8040         if (BTDM_IsHT40(padapter)) {
8041                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8042                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8043
8044                 /*  fw mechanism */
8045                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8046                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8047                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8048                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8049                         btdm_2AntPsTdma(padapter, true, 2);
8050                 } else {
8051                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8052                         btdm_2AntPsTdma(padapter, true, 6);
8053                 }
8054
8055                 /*  sw mechanism */
8056                 btdm_2AntAgcTable(padapter, false);
8057                 btdm_2AntAdcBackOff(padapter, true);
8058                 btdm_2AntDacSwing(padapter, false, 0xc0);
8059         } else {
8060                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8061                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8062                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8063
8064                 /*  fw mechanism */
8065                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8066                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8067                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8068                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8069                         btdm_2AntPsTdma(padapter, true, 2);
8070                 } else {
8071                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8072                         btdm_2AntPsTdma(padapter, true, 6);
8073                 }
8074
8075                 /*  sw mechanism */
8076                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8077                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8078                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8079                         btdm_2AntAgcTable(padapter, true);
8080                         btdm_2AntAdcBackOff(padapter, true);
8081                         btdm_2AntDacSwing(padapter, false, 0xc0);
8082                 } else {
8083                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8084                         btdm_2AntAgcTable(padapter, false);
8085                         btdm_2AntAdcBackOff(padapter, false);
8086                         btdm_2AntDacSwing(padapter, false, 0xc0);
8087                 }
8088         }
8089 }
8090
8091 /* PAN(HS) only */
8092 static void btdm_2Ant8723APANHSAction(struct rtw_adapter *padapter)
8093 {
8094         u8 btRssiState;
8095
8096         if (BTDM_IsHT40(padapter)) {
8097                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8098                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
8099                 /*  fw mechanism */
8100                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8101                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8102                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8103                         btdm_2AntDecBtPwr(padapter, true);
8104                 } else {
8105                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8106                         btdm_2AntDecBtPwr(padapter, false);
8107                 }
8108                 btdm_2AntPsTdma(padapter, false, 0);
8109
8110                 /*  sw mechanism */
8111                 btdm_2AntAgcTable(padapter, false);
8112                 btdm_2AntAdcBackOff(padapter, true);
8113                 btdm_2AntDacSwing(padapter, false, 0xc0);
8114         } else {
8115                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8116                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
8117
8118                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8119                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8120                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high\n"));
8121                         /*  fw mechanism */
8122                         btdm_2AntDecBtPwr(padapter, true);
8123                         btdm_2AntPsTdma(padapter, false, 0);
8124
8125                         /*  sw mechanism */
8126                         btdm_2AntAgcTable(padapter, true);
8127                         btdm_2AntAdcBackOff(padapter, true);
8128                         btdm_2AntDacSwing(padapter, false, 0xc0);
8129                 } else {
8130                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low\n"));
8131                         /*  fw mechanism */
8132                         btdm_2AntDecBtPwr(padapter, false);
8133                         btdm_2AntPsTdma(padapter, false, 0);
8134
8135                         /*  sw mechanism */
8136                         btdm_2AntAgcTable(padapter, false);
8137                         btdm_2AntAdcBackOff(padapter, false);
8138                         btdm_2AntDacSwing(padapter, false, 0xc0);
8139                 }
8140         }
8141 }
8142
8143 /* PAN(EDR)+A2DP */
8144 static void btdm_2Ant8723APANEDRA2DPAction(struct rtw_adapter *padapter)
8145 {
8146         u8 btRssiState, btRssiState1, btInfoExt;
8147         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8148
8149         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8150
8151         if (btdm_NeedToDecBtPwr(padapter))
8152                 btdm_2AntDecBtPwr(padapter, true);
8153         else
8154                 btdm_2AntDecBtPwr(padapter, false);
8155
8156         if (BTDM_IsHT40(padapter)) {
8157                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8158                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8159
8160                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8161                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8162                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8163                         /*  fw mechanism */
8164                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8165
8166                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8167                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8168                                 btdm_2AntPsTdma(padapter, true, 4);
8169                         } else {
8170                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8171                                 btdm_2AntPsTdma(padapter, true, 2);
8172                         }
8173                 } else {
8174                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8175                         /*  fw mechanism */
8176                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8177                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8178                                 btdm_2AntPsTdma(padapter, true, 8);
8179                         } else {
8180                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8181                                 btdm_2AntPsTdma(padapter, true, 6);
8182                         }
8183                 }
8184
8185                 /*  sw mechanism */
8186                 btdm_2AntAgcTable(padapter, false);
8187                 btdm_2AntAdcBackOff(padapter, true);
8188                 btdm_2AntDacSwing(padapter, false, 0xc0);
8189         } else {
8190                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8191                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8192                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8193
8194                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8195                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8196                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8197                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8198                         /*  fw mechanism */
8199                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8200                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8201                                 btdm_2AntPsTdma(padapter, true, 4);
8202                         } else {
8203                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8204                                 btdm_2AntPsTdma(padapter, true, 2);
8205                         }
8206                 } else {
8207                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8208                         /*  fw mechanism */
8209                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8210                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8211                                 btdm_2AntPsTdma(padapter, true, 8);
8212                         } else {
8213                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8214                                 btdm_2AntPsTdma(padapter, true, 6);
8215                         }
8216                 }
8217
8218                 /*  sw mechanism */
8219                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8220                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8221                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8222                         btdm_2AntAgcTable(padapter, true);
8223                         btdm_2AntAdcBackOff(padapter, true);
8224                         btdm_2AntDacSwing(padapter, false, 0xc0);
8225                 } else {
8226                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8227                         btdm_2AntAgcTable(padapter, false);
8228                         btdm_2AntAdcBackOff(padapter, false);
8229                         btdm_2AntDacSwing(padapter, false, 0xc0);
8230                 }
8231         }
8232 }
8233
8234 static void btdm_2Ant8723APANEDRHIDAction(struct rtw_adapter *padapter)
8235 {
8236         u8 btRssiState, btRssiState1;
8237
8238         if (btdm_NeedToDecBtPwr(padapter))
8239                 btdm_2AntDecBtPwr(padapter, true);
8240         else
8241                 btdm_2AntDecBtPwr(padapter, false);
8242
8243         if (BTDM_IsHT40(padapter)) {
8244                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8245                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8246                 /*  fw mechanism */
8247                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8248                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8249                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8250                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8251                         btdm_2AntPsTdma(padapter, true, 10);
8252                 } else {
8253                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8254                         btdm_2AntPsTdma(padapter, true, 14);
8255                 }
8256
8257                 /*  sw mechanism */
8258                 btdm_2AntAgcTable(padapter, false);
8259                 btdm_2AntAdcBackOff(padapter, true);
8260                 btdm_2AntDacSwing(padapter, false, 0xc0);
8261         } else {
8262                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8263                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8264                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8265
8266                 /*  fw mechanism */
8267                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8268                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8269                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8270                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8271                         btdm_2AntPsTdma(padapter, true, 10);
8272                 } else {
8273                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8274                         btdm_2AntPsTdma(padapter, true, 14);
8275                 }
8276
8277                 /*  sw mechanism */
8278                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8279                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8280                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8281                         btdm_2AntAgcTable(padapter, true);
8282                         btdm_2AntAdcBackOff(padapter, true);
8283                         btdm_2AntDacSwing(padapter, false, 0xc0);
8284                 } else {
8285                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8286                         btdm_2AntAgcTable(padapter, false);
8287                         btdm_2AntAdcBackOff(padapter, false);
8288                         btdm_2AntDacSwing(padapter, false, 0xc0);
8289                 }
8290         }
8291 }
8292
8293 /*  HID+A2DP+PAN(EDR) */
8294 static void btdm_2Ant8723AHIDA2DPPANEDRAction(struct rtw_adapter *padapter)
8295 {
8296         u8 btRssiState, btRssiState1, btInfoExt;
8297         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8298
8299         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8300
8301         if (btdm_NeedToDecBtPwr(padapter))
8302                 btdm_2AntDecBtPwr(padapter, true);
8303         else
8304                 btdm_2AntDecBtPwr(padapter, false);
8305
8306         if (BTDM_IsHT40(padapter)) {
8307                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8308                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8309                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8310                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8311                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8312                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8313
8314                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8315                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8316                                 btdm_2AntPsTdma(padapter, true, 12);
8317                         } else {
8318                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8319                                 btdm_2AntPsTdma(padapter, true, 10);
8320                         }
8321                 } else {
8322                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8323                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8324                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8325                                 btdm_2AntPsTdma(padapter, true, 16);
8326                         } else {
8327                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8328                                 btdm_2AntPsTdma(padapter, true, 14);
8329                         }
8330                 }
8331
8332                 /*  sw mechanism */
8333                 btdm_2AntAgcTable(padapter, false);
8334                 btdm_2AntAdcBackOff(padapter, true);
8335                 btdm_2AntDacSwing(padapter, false, 0xc0);
8336         } else {
8337                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8338                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 37, 0);
8339                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0);
8340                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8341                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8342                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8343                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8344
8345                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8346                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8347                                 btdm_2AntPsTdma(padapter, true, 12);
8348                         } else {
8349                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8350                                 btdm_2AntPsTdma(padapter, true, 10);
8351                         }
8352                 } else {
8353                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8354                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8355                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8356                                 btdm_2AntPsTdma(padapter, true, 16);
8357                         } else {
8358                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8359                                 btdm_2AntPsTdma(padapter, true, 14);
8360                         }
8361                 }
8362
8363                 /*  sw mechanism */
8364                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8365                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8366                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8367                         btdm_2AntAgcTable(padapter, true);
8368                         btdm_2AntAdcBackOff(padapter, true);
8369                         btdm_2AntDacSwing(padapter, false, 0xc0);
8370                 } else {
8371                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8372                         btdm_2AntAgcTable(padapter, false);
8373                         btdm_2AntAdcBackOff(padapter, false);
8374                         btdm_2AntDacSwing(padapter, false, 0xc0);
8375                 }
8376         }
8377 }
8378
8379 static void btdm_2Ant8723AHIDA2DPAction(struct rtw_adapter *padapter)
8380 {
8381         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8382         u8 btRssiState, btRssiState1, btInfoExt;
8383
8384         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8385
8386         if (btdm_NeedToDecBtPwr(padapter))
8387                 btdm_2AntDecBtPwr(padapter, true);
8388         else
8389                 btdm_2AntDecBtPwr(padapter, false);
8390
8391         if (BTDM_IsHT40(padapter)) {
8392                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8393                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8394                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8395                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8396                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8397                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8398
8399                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8400                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8401                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 3);
8402                         } else {
8403                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8404                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 1);
8405                         }
8406                 } else {
8407                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8408                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8409                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8410                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 3);
8411                         } else {
8412                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8413                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 1);
8414                         }
8415                 }
8416                 /*  sw mechanism */
8417                 btdm_2AntAgcTable(padapter, false);
8418                 btdm_2AntAdcBackOff(padapter, true);
8419                 btdm_2AntDacSwing(padapter, false, 0xc0);
8420         } else {
8421                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8422                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8423                 btRssiState1 = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0);
8424
8425                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8426                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8427                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8428                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8429
8430                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8431                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8432                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 3);
8433                         } else {
8434                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8435                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 1);
8436                         }
8437                 } else {
8438                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8439                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8440                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8441                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 3);
8442                         } else {
8443                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8444                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 1);
8445                         }
8446                 }
8447                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8448                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8449                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8450                         /*  sw mechanism */
8451                         btdm_2AntAgcTable(padapter, true);
8452                         btdm_2AntAdcBackOff(padapter, true);
8453                         btdm_2AntDacSwing(padapter, false, 0xc0);
8454                 } else {
8455                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8456                         /*  sw mechanism */
8457                         btdm_2AntAgcTable(padapter, false);
8458                         btdm_2AntAdcBackOff(padapter, false);
8459                         btdm_2AntDacSwing(padapter, false, 0xc0);
8460                 }
8461         }
8462 }
8463
8464 static void btdm_2Ant8723AA2dp(struct rtw_adapter *padapter)
8465 {
8466         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8467         u8 btRssiState, btRssiState1, btInfoExt;
8468
8469         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8470
8471         if (btdm_NeedToDecBtPwr(padapter))
8472                 btdm_2AntDecBtPwr(padapter, true);
8473         else
8474                 btdm_2AntDecBtPwr(padapter, false);
8475         /*  coex table */
8476         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8477         btdm_2AntIgnoreWlanAct(padapter, false);
8478
8479         if (BTDM_IsHT40(padapter)) {
8480                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8481                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8482                 /*  fw mechanism */
8483                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8484                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8485                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8486                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8487                         btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
8488                 } else {
8489                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8490                         btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
8491                 }
8492
8493                 /*  sw mechanism */
8494                 btdm_2AntAgcTable(padapter, false);
8495                 btdm_2AntAdcBackOff(padapter, true);
8496                 btdm_2AntDacSwing(padapter, false, 0xc0);
8497         } else {
8498                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8499                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
8500                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8501
8502                 /*  fw mechanism */
8503                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8504                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8505                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8506                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8507                         btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
8508                 } else {
8509                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8510                         btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
8511                 }
8512
8513                 /*  sw mechanism */
8514                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8515                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8516                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8517                         btdm_2AntAgcTable(padapter, true);
8518                         btdm_2AntAdcBackOff(padapter, true);
8519                         btdm_2AntDacSwing(padapter, false, 0xc0);
8520                 } else {
8521                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8522                         btdm_2AntAgcTable(padapter, false);
8523                         btdm_2AntAdcBackOff(padapter, false);
8524                         btdm_2AntDacSwing(padapter, false, 0xc0);
8525                 }
8526         }
8527 }
8528
8529 /*  extern function start with BTDM_ */
8530 static void BTDM_2AntParaInit(struct rtw_adapter *padapter)
8531 {
8532
8533         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8534         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
8535
8536         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2Ant Parameter Init!!\n"));
8537
8538         /*  Enable counter statistics */
8539         rtl8723au_write8(padapter, 0x76e, 0x4);
8540         rtl8723au_write8(padapter, 0x778, 0x3);
8541         rtl8723au_write8(padapter, 0x40, 0x20);
8542
8543         /*  force to reset coex mechanism */
8544         pBtdm8723->preVal0x6c0 = 0x0;
8545         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8546
8547         pBtdm8723->bPrePsTdmaOn = true;
8548         btdm_2AntPsTdma(padapter, false, 0);
8549
8550         pBtdm8723->preFwDacSwingLvl = 0x10;
8551         btdm_2AntFwDacSwingLvl(padapter, 0x20);
8552
8553         pBtdm8723->bPreDecBtPwr = true;
8554         btdm_2AntDecBtPwr(padapter, false);
8555
8556         pBtdm8723->bPreAgcTableEn = true;
8557         btdm_2AntAgcTable(padapter, false);
8558
8559         pBtdm8723->bPreAdcBackOff = true;
8560         btdm_2AntAdcBackOff(padapter, false);
8561
8562         pBtdm8723->bPreLowPenaltyRa = true;
8563         btdm_2AntLowPenaltyRa(padapter, false);
8564
8565         pBtdm8723->bPreRfRxLpfShrink = true;
8566         btdm_2AntRfShrink(padapter, false);
8567
8568         pBtdm8723->bPreDacSwingOn = true;
8569         btdm_2AntDacSwing(padapter, false, 0xc0);
8570
8571         pBtdm8723->bPreIgnoreWlanAct = true;
8572         btdm_2AntIgnoreWlanAct(padapter, false);
8573 }
8574
8575 static void BTDM_2AntHwCoexAllOff8723A(struct rtw_adapter *padapter)
8576 {
8577         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8578 }
8579
8580 static void BTDM_2AntFwCoexAllOff8723A(struct rtw_adapter *padapter)
8581 {
8582         btdm_2AntIgnoreWlanAct(padapter, false);
8583         btdm_2AntPsTdma(padapter, false, 0);
8584         btdm_2AntFwDacSwingLvl(padapter, 0x20);
8585         btdm_2AntDecBtPwr(padapter, false);
8586 }
8587
8588 static void BTDM_2AntSwCoexAllOff8723A(struct rtw_adapter *padapter)
8589 {
8590         btdm_2AntAgcTable(padapter, false);
8591         btdm_2AntAdcBackOff(padapter, false);
8592         btdm_2AntLowPenaltyRa(padapter, false);
8593         btdm_2AntRfShrink(padapter, false);
8594         btdm_2AntDacSwing(padapter, false, 0xc0);
8595 }
8596
8597 static void BTDM_2AntFwC2hBtInfo8723A(struct rtw_adapter *padapter)
8598 {
8599         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
8600         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
8601         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8602         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
8603         u8 btInfo = 0;
8604         u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED;
8605         u8 bBtLinkExist = false, bBtHsModeExist = false;
8606
8607         btInfo = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal;
8608         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
8609
8610         /*  check BIT2 first ==> check if bt is under inquiry or page scan */
8611         if (btInfo & BIT(2)) {
8612                 if (!pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) {
8613                         pBtMgnt->ExtConfig.bHoldForBtOperation = true;
8614                         pBtMgnt->ExtConfig.bHoldPeriodCnt = 1;
8615                         btdm_2AntBtInquiryPage(padapter);
8616                 } else {
8617                         pBtMgnt->ExtConfig.bHoldPeriodCnt++;
8618                         btdm_HoldForBtInqPage(padapter);
8619                 }
8620                 pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = true;
8621
8622         } else {
8623                 pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = false;
8624                 pBtMgnt->ExtConfig.bHoldForBtOperation = false;
8625                 pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
8626
8627         }
8628         RTPRINT(FBT, BT_TRACE,
8629                 ("[BTC2H], pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage =%x pBtMgnt->ExtConfig.bHoldPeriodCnt =%x pBtMgnt->ExtConfig.bHoldForBtOperation =%x\n",
8630                 pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage,
8631                 pBtMgnt->ExtConfig.bHoldPeriodCnt,
8632                 pBtMgnt->ExtConfig.bHoldForBtOperation));
8633
8634         RTPRINT(FBT, BT_TRACE,
8635                 ("[BTC2H],   btInfo =%x   pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal =%x\n",
8636                 btInfo, pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal));
8637         if (btInfo&BT_INFO_ACL) {
8638                 RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = true   btInfo =%x\n", btInfo));
8639                 bBtLinkExist = true;
8640                 if (((btInfo&(BT_INFO_FTP|BT_INFO_A2DP|BT_INFO_HID|BT_INFO_SCO_BUSY)) != 0) ||
8641                     pHalData->bt_coexist.halCoex8723.btRetryCnt > 0) {
8642                         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
8643                 } else {
8644                         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
8645                 }
8646
8647                 if (btInfo&BT_INFO_SCO || btInfo&BT_INFO_SCO_BUSY) {
8648                         if (btInfo&BT_INFO_FTP || btInfo&BT_INFO_A2DP || btInfo&BT_INFO_HID) {
8649                                 switch (btInfo&0xe0) {
8650                                 case BT_INFO_HID:
8651                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n"));
8652                                         algorithm = BT_2ANT_COEX_ALGO_HID;
8653                                         break;
8654                                 case BT_INFO_A2DP:
8655                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n"));
8656                                         break;
8657                                 case BT_INFO_FTP:
8658                                         if (bBtHsModeExist) {
8659                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
8660                                                 algorithm = BT_2ANT_COEX_ALGO_SCO;
8661                                         } else {
8662                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
8663                                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8664                                         }
8665                                         break;
8666                                 case (BT_INFO_HID | BT_INFO_A2DP):
8667                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
8668                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8669                                         break;
8670                                 case (BT_INFO_HID | BT_INFO_FTP):
8671                                         if (bBtHsModeExist) {
8672                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
8673                                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8674                                         } else {
8675                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
8676                                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8677                                         }
8678                                         break;
8679                                 case (BT_INFO_A2DP | BT_INFO_FTP):
8680                                         if (bBtHsModeExist) {
8681                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
8682                                                 algorithm = BT_2ANT_COEX_ALGO_A2DP;
8683                                         } else {
8684                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
8685                                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
8686                                         }
8687                                         break;
8688                                 case (BT_INFO_HID | BT_INFO_A2DP | BT_INFO_FTP):
8689                                         if (bBtHsModeExist) {
8690                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
8691                                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8692                                         } else {
8693                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
8694                                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
8695                                         }
8696                                         break;
8697                                 }
8698                         } else {
8699                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n"));
8700                                 algorithm = BT_2ANT_COEX_ALGO_SCO;
8701                         }
8702                 } else {
8703                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], non SCO\n"));
8704                         switch (btInfo&0xe0) {
8705                         case BT_INFO_HID:
8706                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID\n"));
8707                                 algorithm = BT_2ANT_COEX_ALGO_HID;
8708                                 break;
8709                         case BT_INFO_A2DP:
8710                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex],  A2DP\n"));
8711                                 algorithm = BT_2ANT_COEX_ALGO_A2DP;
8712                                 break;
8713                         case BT_INFO_FTP:
8714                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR)\n"));
8715                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8716                                 break;
8717                         case (BT_INFO_HID | BT_INFO_A2DP):
8718                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
8719                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8720                                 break;
8721                         case (BT_INFO_HID|BT_INFO_FTP):
8722                                 if (bBtHsModeExist) {
8723                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
8724                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8725                                 } else {
8726                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
8727                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8728                                 }
8729                                 break;
8730                         case (BT_INFO_A2DP|BT_INFO_FTP):
8731                                 if (bBtHsModeExist) {
8732                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
8733                                         algorithm = BT_2ANT_COEX_ALGO_A2DP;
8734                                 } else {
8735                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
8736                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
8737                                 }
8738                                 break;
8739                         case (BT_INFO_HID|BT_INFO_A2DP|BT_INFO_FTP):
8740                                 if (bBtHsModeExist) {
8741                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
8742                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8743                                 } else {
8744                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
8745                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
8746                                 }
8747                                 break;
8748                         }
8749
8750                 }
8751         } else {
8752                 RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = false\n"));
8753                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
8754         }
8755
8756         pBtdm8723->curAlgorithm = algorithm;
8757         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm));
8758
8759 /* From */
8760         BTDM_CheckWiFiState(padapter);
8761         if (pBtMgnt->ExtConfig.bManualControl) {
8762                 RTPRINT(FBT, BT_TRACE, ("Action Manual control, won't execute bt coexist mechanism!!\n"));
8763                 return;
8764         }
8765 }
8766
8767 void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter)
8768 {
8769         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
8770         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
8771         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
8772         u8 btInfoOriginal = 0;
8773         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8774         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
8775
8776         if (BTDM_BtProfileSupport(padapter)) {
8777                 if (pBtMgnt->ExtConfig.bHoldForBtOperation) {
8778                         RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n"));
8779                         return;
8780                 }
8781                 if (pBtMgnt->ExtConfig.bHoldPeriodCnt) {
8782                         RTPRINT(FBT, BT_TRACE, ("Hold BT inquiry/page scan setting (cnt = %d)!!\n",
8783                                 pBtMgnt->ExtConfig.bHoldPeriodCnt));
8784                         if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) {
8785                                 pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
8786                                 /*  next time the coexist parameters should be reset again. */
8787                         } else {
8788                                 pBtMgnt->ExtConfig.bHoldPeriodCnt++;
8789                         }
8790                         return;
8791                 }
8792
8793                 if (pBtDbg->dbgCtrl)
8794                         RTPRINT(FBT, BT_TRACE, ("[Dbg control], "));
8795
8796                 pBtdm8723->curAlgorithm = btdm_ActionAlgorithm(padapter);
8797                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm));
8798
8799                 if (btdm_Is2Ant8723ACommonAction(padapter)) {
8800                         RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n"));
8801                         pBtdm8723->bResetTdmaAdjust = true;
8802                 } else {
8803                         if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) {
8804                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n",
8805                                 pBtdm8723->preAlgorithm, pBtdm8723->curAlgorithm));
8806                                 pBtdm8723->bResetTdmaAdjust = true;
8807                         }
8808                         switch (pBtdm8723->curAlgorithm) {
8809                         case BT_2ANT_COEX_ALGO_SCO:
8810                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n"));
8811                                 btdm_2Ant8723ASCOAction(padapter);
8812                                 break;
8813                         case BT_2ANT_COEX_ALGO_HID:
8814                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n"));
8815                                 btdm_2Ant8723AHIDAction(padapter);
8816                                 break;
8817                         case BT_2ANT_COEX_ALGO_A2DP:
8818                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n"));
8819                                 btdm_2Ant8723AA2DPAction(padapter);
8820                                 break;
8821                         case BT_2ANT_COEX_ALGO_PANEDR:
8822                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n"));
8823                                 btdm_2Ant8723APANEDRAction(padapter);
8824                                 break;
8825                         case BT_2ANT_COEX_ALGO_PANHS:
8826                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n"));
8827                                 btdm_2Ant8723APANHSAction(padapter);
8828                                 break;
8829                         case BT_2ANT_COEX_ALGO_PANEDR_A2DP:
8830                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n"));
8831                                 btdm_2Ant8723APANEDRA2DPAction(padapter);
8832                                 break;
8833                         case BT_2ANT_COEX_ALGO_PANEDR_HID:
8834                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
8835                                 btdm_2Ant8723APANEDRHIDAction(padapter);
8836                                 break;
8837                         case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
8838                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
8839                                 btdm_2Ant8723AHIDA2DPPANEDRAction(padapter);
8840                                 break;
8841                         case BT_2ANT_COEX_ALGO_HID_A2DP:
8842                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n"));
8843                                 btdm_2Ant8723AHIDA2DPAction(padapter);
8844                                 break;
8845                         default:
8846                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n"));
8847                                 btdm_2Ant8723AA2DPAction(padapter);
8848                                 break;
8849                         }
8850                         pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm;
8851                 }
8852         } else {
8853                 RTPRINT(FBT, BT_TRACE, ("[BTCoex] Get bt info by fw!!\n"));
8854                 /* msg shows c2h rsp for bt_info is received or not. */
8855                 if (pHalData->bt_coexist.halCoex8723.bC2hBtInfoReqSent)
8856                         RTPRINT(FBT, BT_TRACE, ("[BTCoex] c2h for btInfo not rcvd yet!!\n"));
8857
8858                 btInfoOriginal = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal;
8859
8860                 if (pBtMgnt->ExtConfig.bHoldForBtOperation) {
8861                         RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n"));
8862                         return;
8863                 }
8864                 if (pBtMgnt->ExtConfig.bHoldPeriodCnt) {
8865                         RTPRINT(FBT, BT_TRACE,
8866                                 ("Hold BT inquiry/page scan setting (cnt = %d)!!\n",
8867                                 pBtMgnt->ExtConfig.bHoldPeriodCnt));
8868                         if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) {
8869                                 pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
8870                                 /*  next time the coexist parameters should be reset again. */
8871                         } else {
8872                                  pBtMgnt->ExtConfig.bHoldPeriodCnt++;
8873                         }
8874                         return;
8875                 }
8876
8877                 if (pBtDbg->dbgCtrl)
8878                         RTPRINT(FBT, BT_TRACE, ("[Dbg control], "));
8879                 if (btdm_Is2Ant8723ACommonAction(padapter)) {
8880                         RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n"));
8881                         pBtdm8723->bResetTdmaAdjust = true;
8882                 } else {
8883                         if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) {
8884                                 RTPRINT(FBT, BT_TRACE,
8885                                         ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n",
8886                                         pBtdm8723->preAlgorithm,
8887                                         pBtdm8723->curAlgorithm));
8888                                 pBtdm8723->bResetTdmaAdjust = true;
8889                         }
8890                         switch (pBtdm8723->curAlgorithm) {
8891                         case BT_2ANT_COEX_ALGO_SCO:
8892                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n"));
8893                                 btdm_2Ant8723ASCOAction(padapter);
8894                                 break;
8895                         case BT_2ANT_COEX_ALGO_HID:
8896                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n"));
8897                                 btdm_2Ant8723AHIDAction(padapter);
8898                                 break;
8899                         case BT_2ANT_COEX_ALGO_A2DP:
8900                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n"));
8901                                 btdm_2Ant8723AA2dp(padapter);
8902                                 break;
8903                         case BT_2ANT_COEX_ALGO_PANEDR:
8904                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n"));
8905                                 btdm_2Ant8723APANEDRAction(padapter);
8906                                 break;
8907                         case BT_2ANT_COEX_ALGO_PANHS:
8908                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n"));
8909                                 btdm_2Ant8723APANHSAction(padapter);
8910                                 break;
8911                         case BT_2ANT_COEX_ALGO_PANEDR_A2DP:
8912                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n"));
8913                                 btdm_2Ant8723APANEDRA2DPAction(padapter);
8914                                 break;
8915                         case BT_2ANT_COEX_ALGO_PANEDR_HID:
8916                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
8917                                 btdm_2Ant8723APANEDRHIDAction(padapter);
8918                                 break;
8919                         case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
8920                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
8921                                 btdm_2Ant8723AHIDA2DPPANEDRAction(padapter);
8922                                 break;
8923                         case BT_2ANT_COEX_ALGO_HID_A2DP:
8924                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n"));
8925                                 btdm_2Ant8723AHIDA2DPAction(padapter);
8926                                 break;
8927                         default:
8928                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n"));
8929                                 btdm_2Ant8723AA2DPAction(padapter);
8930                                 break;
8931                         }
8932                         pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm;
8933                 }
8934         }
8935 }
8936
8937 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */
8938
8939 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */
8940
8941 static u8 btCoexDbgBuf[BT_TMP_BUF_SIZE];
8942
8943 static const char *const BtProfileString[] = {
8944         "NONE",
8945         "A2DP",
8946         "PAN",
8947         "HID",
8948         "SCO",
8949 };
8950
8951 static const char *const BtSpecString[] = {
8952         "1.0b",
8953         "1.1",
8954         "1.2",
8955         "2.0+EDR",
8956         "2.1+EDR",
8957         "3.0+HS",
8958         "4.0",
8959 };
8960
8961 static const char *const BtLinkRoleString[] = {
8962         "Master",
8963         "Slave",
8964 };
8965
8966 static u8 btdm_BtWifiAntNum(struct rtw_adapter *padapter)
8967 {
8968         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8969         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
8970
8971         if (Ant_x2 == pHalData->bt_coexist.BT_Ant_Num) {
8972                 if (Ant_x2 == pBtCoex->TotalAntNum)
8973                         return Ant_x2;
8974                 else
8975                         return Ant_x1;
8976         } else {
8977                 return Ant_x1;
8978         }
8979         return Ant_x2;
8980 }
8981
8982 static void btdm_BtHwCountersMonitor(struct rtw_adapter *padapter)
8983 {
8984         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8985         u32     regHPTxRx, regLPTxRx, u4Tmp;
8986         u32     regHPTx = 0, regHPRx = 0, regLPTx = 0, regLPRx = 0;
8987
8988         regHPTxRx = REG_HIGH_PRIORITY_TXRX;
8989         regLPTxRx = REG_LOW_PRIORITY_TXRX;
8990
8991         u4Tmp = rtl8723au_read32(padapter, regHPTxRx);
8992         regHPTx = u4Tmp & bMaskLWord;
8993         regHPRx = (u4Tmp & bMaskHWord)>>16;
8994
8995         u4Tmp = rtl8723au_read32(padapter, regLPTxRx);
8996         regLPTx = u4Tmp & bMaskLWord;
8997         regLPRx = (u4Tmp & bMaskHWord)>>16;
8998
8999         pHalData->bt_coexist.halCoex8723.highPriorityTx = regHPTx;
9000         pHalData->bt_coexist.halCoex8723.highPriorityRx = regHPRx;
9001         pHalData->bt_coexist.halCoex8723.lowPriorityTx = regLPTx;
9002         pHalData->bt_coexist.halCoex8723.lowPriorityRx = regLPRx;
9003
9004         RTPRINT(FBT, BT_TRACE, ("High Priority Tx/Rx = %d / %d\n", regHPTx, regHPRx));
9005         RTPRINT(FBT, BT_TRACE, ("Low Priority Tx/Rx = %d / %d\n", regLPTx, regLPRx));
9006
9007         /*  reset counter */
9008         rtl8723au_write8(padapter, 0x76e, 0xc);
9009 }
9010
9011 /*  This function check if 8723 bt is disabled */
9012 static void btdm_BtEnableDisableCheck8723A(struct rtw_adapter *padapter)
9013 {
9014         u8 btAlife = true;
9015         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9016
9017 #ifdef CHECK_BT_EXIST_FROM_REG
9018         u8 val8;
9019
9020         /*  ox68[28]= 1 => BT enable; otherwise disable */
9021         val8 = rtl8723au_read8(padapter, 0x6B);
9022         if (!(val8 & BIT(4)))
9023                 btAlife = false;
9024
9025         if (btAlife)
9026                 pHalData->bt_coexist.bCurBtDisabled = false;
9027         else
9028                 pHalData->bt_coexist.bCurBtDisabled = true;
9029 #else
9030         if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0 &&
9031             pHalData->bt_coexist.halCoex8723.highPriorityRx == 0 &&
9032             pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0 &&
9033             pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0)
9034                 btAlife = false;
9035         if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xeaea &&
9036             pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xeaea &&
9037             pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xeaea &&
9038             pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xeaea)
9039                 btAlife = false;
9040         if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xffff &&
9041             pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xffff &&
9042             pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xffff &&
9043             pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xffff)
9044                 btAlife = false;
9045         if (btAlife) {
9046                 pHalData->bt_coexist.btActiveZeroCnt = 0;
9047                 pHalData->bt_coexist.bCurBtDisabled = false;
9048                 RTPRINT(FBT, BT_TRACE, ("8723A BT is enabled !!\n"));
9049         } else {
9050                 pHalData->bt_coexist.btActiveZeroCnt++;
9051                 RTPRINT(FBT, BT_TRACE, ("8723A bt all counters = 0, %d times!!\n",
9052                                 pHalData->bt_coexist.btActiveZeroCnt));
9053                 if (pHalData->bt_coexist.btActiveZeroCnt >= 2) {
9054                         pHalData->bt_coexist.bCurBtDisabled = true;
9055                         RTPRINT(FBT, BT_TRACE, ("8723A BT is disabled !!\n"));
9056                 }
9057         }
9058 #endif
9059
9060         if (!pHalData->bt_coexist.bCurBtDisabled) {
9061                 if (BTDM_IsWifiConnectionExist(padapter))
9062                         BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT);
9063                 else
9064                         BTDM_SetFwChnlInfo(padapter, RT_MEDIA_DISCONNECT);
9065         }
9066
9067         if (pHalData->bt_coexist.bPreBtDisabled !=
9068             pHalData->bt_coexist.bCurBtDisabled) {
9069                 RTPRINT(FBT, BT_TRACE, ("8723A BT is from %s to %s!!\n",
9070                         (pHalData->bt_coexist.bPreBtDisabled ? "disabled":"enabled"),
9071                         (pHalData->bt_coexist.bCurBtDisabled ? "disabled":"enabled")));
9072                 pHalData->bt_coexist.bPreBtDisabled = pHalData->bt_coexist.bCurBtDisabled;
9073         }
9074 }
9075
9076 static void btdm_BTCoexist8723AHandler(struct rtw_adapter *padapter)
9077 {
9078         struct hal_data_8723a *pHalData;
9079
9080         pHalData = GET_HAL_DATA(padapter);
9081
9082         if (btdm_BtWifiAntNum(padapter) == Ant_x2) {
9083                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2 Ant mechanism\n"));
9084                 BTDM_2AntBtCoexist8723A(padapter);
9085         } else {
9086                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1 Ant mechanism\n"));
9087                 BTDM_1AntBtCoexist8723A(padapter);
9088         }
9089
9090         if (!BTDM_IsSameCoexistState(padapter)) {
9091                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x\n",
9092                         pHalData->bt_coexist.PreviousState,
9093                         pHalData->bt_coexist.CurrentState));
9094                 pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState;
9095
9096                 RTPRINT(FBT, BT_TRACE, ("["));
9097                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT30)
9098                         RTPRINT(FBT, BT_TRACE, ("BT 3.0, "));
9099                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT20)
9100                         RTPRINT(FBT, BT_TRACE, ("HT20, "));
9101                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT40)
9102                         RTPRINT(FBT, BT_TRACE, ("HT40, "));
9103                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_LEGACY)
9104                         RTPRINT(FBT, BT_TRACE, ("Legacy, "));
9105                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_LOW)
9106                         RTPRINT(FBT, BT_TRACE, ("Rssi_Low, "));
9107                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_MEDIUM)
9108                         RTPRINT(FBT, BT_TRACE, ("Rssi_Mid, "));
9109                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_HIGH)
9110                         RTPRINT(FBT, BT_TRACE, ("Rssi_High, "));
9111                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_IDLE)
9112                         RTPRINT(FBT, BT_TRACE, ("Wifi_Idle, "));
9113                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_UPLINK)
9114                         RTPRINT(FBT, BT_TRACE, ("Wifi_Uplink, "));
9115                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_DOWNLINK)
9116                         RTPRINT(FBT, BT_TRACE, ("Wifi_Downlink, "));
9117                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)
9118                         RTPRINT(FBT, BT_TRACE, ("BT_idle, "));
9119                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_HID)
9120                         RTPRINT(FBT, BT_TRACE, ("PRO_HID, "));
9121                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_A2DP)
9122                         RTPRINT(FBT, BT_TRACE, ("PRO_A2DP, "));
9123                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_PAN)
9124                         RTPRINT(FBT, BT_TRACE, ("PRO_PAN, "));
9125                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_SCO)
9126                         RTPRINT(FBT, BT_TRACE, ("PRO_SCO, "));
9127                 RTPRINT(FBT, BT_TRACE, ("]\n"));
9128         }
9129 }
9130
9131 /*  extern function start with BTDM_ */
9132 u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter)
9133 {
9134         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9135         u32     counters = 0;
9136
9137         counters = pHalData->bt_coexist.halCoex8723.highPriorityTx+
9138                 pHalData->bt_coexist.halCoex8723.highPriorityRx;
9139         return counters;
9140 }
9141
9142 u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter)
9143 {
9144         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9145         u32     counters = 0;
9146
9147         counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+
9148                 pHalData->bt_coexist.halCoex8723.lowPriorityRx ;
9149         return counters;
9150 }
9151
9152 void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter, enum rt_media_status mstatus)
9153 {
9154         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9155         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9156         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9157         u8 H2C_Parameter[3] = {0};
9158         u8 chnl;
9159
9160         /*  opMode */
9161         if (RT_MEDIA_CONNECT == mstatus)
9162                 H2C_Parameter[0] = 0x1; /*  0: disconnected, 1:connected */
9163
9164         if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
9165                 /*  channel */
9166                 chnl = pmlmeext->cur_channel;
9167                 if (BTDM_IsHT40(padapter)) {
9168                         if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
9169                                 chnl -= 2;
9170                         else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
9171                                 chnl += 2;
9172                 }
9173                 H2C_Parameter[1] = chnl;
9174         } else {        /*  check if HS link is exists */
9175                 /*  channel */
9176                 if (BT_Operation(padapter))
9177                         H2C_Parameter[1] = pBtMgnt->BTChannel;
9178                 else
9179                         H2C_Parameter[1] = pmlmeext->cur_channel;
9180         }
9181
9182         if (BTDM_IsHT40(padapter))
9183                 H2C_Parameter[2] = 0x30;
9184         else
9185                 H2C_Parameter[2] = 0x20;
9186
9187         FillH2CCmd(padapter, 0x19, 3, H2C_Parameter);
9188 }
9189
9190 u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter)
9191 {
9192         u8 bRet = false;
9193
9194         if (BTHCI_HsConnectionEstablished(padapter))
9195                 bRet = true;
9196
9197         if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == true)
9198                 bRet = true;
9199
9200         return bRet;
9201 }
9202
9203 void BTDM_SetFw3a(
9204         struct rtw_adapter *padapter,
9205         u8 byte1,
9206         u8 byte2,
9207         u8 byte3,
9208         u8 byte4,
9209         u8 byte5
9210         )
9211 {
9212         u8 H2C_Parameter[5] = {0};
9213
9214         if (rtl8723a_BT_using_antenna_1(padapter)) {
9215                 if ((!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) &&
9216                     (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) {
9217                         /*  for softap mode */
9218                         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9219                         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
9220                         u8 BtState = pBtCoex->c2hBtInfo;
9221
9222                         if ((BtState != BT_INFO_STATE_NO_CONNECTION) &&
9223                             (BtState != BT_INFO_STATE_CONNECT_IDLE)) {
9224                                 if (byte1 & BIT(4)) {
9225                                         byte1 &= ~BIT(4);
9226                                         byte1 |= BIT(5);
9227                                 }
9228
9229                                 byte5 |= BIT(5);
9230                                 if (byte5 & BIT(6))
9231                                         byte5 &= ~BIT(6);
9232                         }
9233                 }
9234         }
9235
9236         H2C_Parameter[0] = byte1;
9237         H2C_Parameter[1] = byte2;
9238         H2C_Parameter[2] = byte3;
9239         H2C_Parameter[3] = byte4;
9240         H2C_Parameter[4] = byte5;
9241
9242         RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%02x%08x\n",
9243                 H2C_Parameter[0],
9244                 H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
9245
9246         FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter);
9247 }
9248
9249 void BTDM_QueryBtInformation(struct rtw_adapter *padapter)
9250 {
9251         u8 H2C_Parameter[1] = {0};
9252         struct hal_data_8723a *pHalData;
9253         struct bt_coexist_8723a *pBtCoex;
9254
9255         pHalData = GET_HAL_DATA(padapter);
9256         pBtCoex = &pHalData->bt_coexist.halCoex8723;
9257
9258         if (!rtl8723a_BT_enabled(padapter)) {
9259                 pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
9260                 pBtCoex->bC2hBtInfoReqSent = false;
9261                 return;
9262         }
9263
9264         if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED)
9265                 pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
9266
9267         if (pBtCoex->bC2hBtInfoReqSent == true)
9268                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], didn't recv previous BtInfo report!\n"));
9269         else
9270                 pBtCoex->bC2hBtInfoReqSent = true;
9271
9272         H2C_Parameter[0] |= BIT(0);     /*  trigger */
9273
9274 /*RTPRINT(FBT, BT_TRACE, ("[BTCoex], Query Bt information, write 0x38 = 0x%x\n", */
9275 /*H2C_Parameter[0])); */
9276
9277         FillH2CCmd(padapter, 0x38, 1, H2C_Parameter);
9278 }
9279
9280 void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type)
9281 {
9282         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9283
9284         if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
9285                 /* Shrink RF Rx LPF corner */
9286                 RTPRINT(FBT, BT_TRACE, ("Shrink RF Rx LPF corner!!\n"));
9287                 PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, 0xf0ff7);
9288                 pHalData->bt_coexist.bSWCoexistAllOff = false;
9289         } else if (BT_RF_RX_LPF_CORNER_RESUME == type) {
9290                 /* Resume RF Rx LPF corner */
9291                 RTPRINT(FBT, BT_TRACE, ("Resume RF Rx LPF corner!!\n"));
9292                 PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, pHalData->bt_coexist.BtRfRegOrigin1E);
9293         }
9294 }
9295
9296 void
9297 BTDM_SetSwPenaltyTxRateAdaptive(
9298         struct rtw_adapter *padapter,
9299         u8 raType
9300         )
9301 {
9302         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9303         u8 tmpU1;
9304
9305         tmpU1 = rtl8723au_read8(padapter, 0x4fd);
9306         tmpU1 |= BIT(0);
9307         if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == raType) {
9308                 tmpU1 &= ~BIT(2);
9309                 pHalData->bt_coexist.bSWCoexistAllOff = false;
9310         } else if (BT_TX_RATE_ADAPTIVE_NORMAL == raType) {
9311                 tmpU1 |= BIT(2);
9312         }
9313
9314         rtl8723au_write8(padapter, 0x4fd, tmpU1);
9315 }
9316
9317 void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr)
9318 {
9319         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9320         u8 H2C_Parameter[1] = {0};
9321
9322         H2C_Parameter[0] = 0;
9323
9324         if (bDecBtPwr) {
9325                 H2C_Parameter[0] |= BIT(1);
9326                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9327         }
9328
9329         RTPRINT(FBT, BT_TRACE, ("[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n",
9330                 (bDecBtPwr ? "Yes!!" : "No!!"), H2C_Parameter[0]));
9331
9332         FillH2CCmd(padapter, 0x21, 1, H2C_Parameter);
9333 }
9334
9335 u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter)
9336 {
9337         u8 bRet = false;
9338         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9339         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9340         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9341
9342         if (pBtMgnt->bSupportProfile &&
9343             !pHalData->bt_coexist.halCoex8723.bForceFwBtInfo)
9344                 bRet = true;
9345
9346         return bRet;
9347 }
9348
9349 static void BTDM_AdjustForBtOperation8723A(struct rtw_adapter *padapter)
9350 {
9351         /* BTDM_2AntAdjustForBtOperation8723(padapter); */
9352 }
9353
9354 static void BTDM_FwC2hBtRssi8723A(struct rtw_adapter *padapter, u8 *tmpBuf)
9355 {
9356         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9357         u8 percent = 0, u1tmp = 0;
9358
9359         u1tmp = tmpBuf[0];
9360         percent = u1tmp*2+10;
9361
9362         pHalData->bt_coexist.halCoex8723.btRssi = percent;
9363 /*RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", percent)); */
9364 }
9365
9366 void
9367 rtl8723a_fw_c2h_BT_info(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length)
9368 {
9369         struct hal_data_8723a *pHalData;
9370         struct bt_30info *pBTInfo;
9371         struct bt_mgnt *pBtMgnt;
9372         struct bt_coexist_8723a *pBtCoex;
9373         u8 i;
9374
9375         pHalData = GET_HAL_DATA(padapter);
9376         pBTInfo = GET_BT_INFO(padapter);
9377         pBtMgnt = &pBTInfo->BtMgnt;
9378         pBtCoex = &pHalData->bt_coexist.halCoex8723;
9379
9380         pBtCoex->bC2hBtInfoReqSent = false;
9381
9382         RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT info[%d]=[", length));
9383
9384         pBtCoex->btRetryCnt = 0;
9385         for (i = 0; i < length; i++) {
9386                 switch (i) {
9387                 case 0:
9388                         pBtCoex->c2hBtInfoOriginal = tmpBuf[i];
9389                         break;
9390                 case 1:
9391                         pBtCoex->btRetryCnt = tmpBuf[i];
9392                         break;
9393                 case 2:
9394                         BTDM_FwC2hBtRssi8723A(padapter, &tmpBuf[i]);
9395                         break;
9396                 case 3:
9397                         pBtCoex->btInfoExt = tmpBuf[i]&BIT(0);
9398                         break;
9399                 }
9400
9401                 if (i == length-1)
9402                         RTPRINT(FBT, BT_TRACE, ("0x%02x]\n", tmpBuf[i]));
9403                 else
9404                         RTPRINT(FBT, BT_TRACE, ("0x%02x, ", tmpBuf[i]));
9405         }
9406         RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", pBtCoex->btRssi));
9407         if (pBtCoex->btInfoExt)
9408                 RTPRINT(FBT, BT_TRACE, ("[BTC2H], pBtCoex->btInfoExt =%x\n", pBtCoex->btInfoExt));
9409
9410         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9411                 BTDM_1AntFwC2hBtInfo8723A(padapter);
9412         else
9413                 BTDM_2AntFwC2hBtInfo8723A(padapter);
9414
9415         if (pBtMgnt->ExtConfig.bManualControl) {
9416                 RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__));
9417                 return;
9418         }
9419
9420         btdm_BTCoexist8723AHandler(padapter);
9421 }
9422
9423 static void BTDM_Display8723ABtCoexInfo(struct rtw_adapter *padapter)
9424 {
9425         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9426         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
9427         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9428         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9429         u8 u1Tmp, u1Tmp1, u1Tmp2, i, btInfoExt, psTdmaCase = 0;
9430         u32 u4Tmp[4];
9431         u8 antNum = Ant_x2;
9432
9433         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============");
9434         DCMD_Printf(btCoexDbgBuf);
9435
9436         if (!rtl8723a_BT_coexist(padapter)) {
9437                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
9438                 DCMD_Printf(btCoexDbgBuf);
9439                 return;
9440         }
9441
9442         antNum = btdm_BtWifiAntNum(padapter);
9443         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/%d ", "Ant mechanism PG/Now run :", \
9444                 ((pHalData->bt_coexist.BT_Ant_Num == Ant_x2) ? 2 : 1), ((antNum == Ant_x2) ? 2 : 1));
9445         DCMD_Printf(btCoexDbgBuf);
9446
9447         if (pBtMgnt->ExtConfig.bManualControl) {
9448                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!");
9449                 DCMD_Printf(btCoexDbgBuf);
9450         } else {
9451                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \
9452                         ((pBtMgnt->bSupportProfile) ? "Yes" : "No"), pBtMgnt->ExtConfig.HCIExtensionVer);
9453                 DCMD_Printf(btCoexDbgBuf);
9454         }
9455
9456         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = / %d", "Dot11 channel / BT channel", \
9457                 pBtMgnt->BTChannel);
9458                 DCMD_Printf(btCoexDbgBuf);
9459
9460         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %d / %d / %d", "Wifi/BT/HS rssi", \
9461                 BTDM_GetRxSS(padapter),
9462                 pHalData->bt_coexist.halCoex8723.btRssi,
9463                 pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB);
9464                         DCMD_Printf(btCoexDbgBuf);
9465
9466         if (!pBtMgnt->ExtConfig.bManualControl) {
9467                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %s / %s ", "WIfi status",
9468                         ((BTDM_Legacy(padapter)) ? "Legacy" : (((BTDM_IsHT40(padapter)) ? "HT40" : "HT20"))),
9469                         ((!BTDM_IsWifiBusy(padapter)) ? "idle" : ((BTDM_IsWifiUplink(padapter)) ? "uplink" : "downlink")));
9470                 DCMD_Printf(btCoexDbgBuf);
9471
9472                 if (pBtMgnt->bSupportProfile) {
9473                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
9474                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_SCO)) ? 1 : 0),
9475                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) ? 1 : 0),
9476                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) ? 1 : 0),
9477                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) ? 1 : 0));
9478                 DCMD_Printf(btCoexDbgBuf);
9479
9480                         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
9481                                 if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
9482                                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Bt link type/spec/role",
9483                                                 BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile],
9484                                                 BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec],
9485                                                 BtLinkRoleString[pBtMgnt->ExtConfig.linkInfo[i].linkRole]);
9486                                         DCMD_Printf(btCoexDbgBuf);
9487
9488                                         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
9489                                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "A2DP rate", \
9490                                                  (btInfoExt & BIT(0)) ?
9491                                                  "Basic rate" : "EDR rate");
9492                                         DCMD_Printf(btCoexDbgBuf);
9493                                 } else {
9494                                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "Bt link type/spec", \
9495                                                 BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile],
9496                                                 BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec]);
9497                                         DCMD_Printf(btCoexDbgBuf);
9498                                 }
9499                         }
9500                 }
9501         }
9502
9503         /*  Sw mechanism */
9504         if (!pBtMgnt->ExtConfig.bManualControl) {
9505                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw BT Coex mechanism]============");
9506                 DCMD_Printf(btCoexDbgBuf);
9507                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "AGC Table", \
9508                         pBtCoex->btdm2Ant.bCurAgcTableEn);
9509                 DCMD_Printf(btCoexDbgBuf);
9510                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "ADC Backoff", \
9511                         pBtCoex->btdm2Ant.bCurAdcBackOff);
9512                 DCMD_Printf(btCoexDbgBuf);
9513                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Low penalty RA", \
9514                         pBtCoex->btdm2Ant.bCurLowPenaltyRa);
9515                 DCMD_Printf(btCoexDbgBuf);
9516                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "RF Rx LPF Shrink", \
9517                         pBtCoex->btdm2Ant.bCurRfRxLpfShrink);
9518                 DCMD_Printf(btCoexDbgBuf);
9519         }
9520         u4Tmp[0] = PHY_QueryRFReg(padapter, PathA, 0x1e, 0xff0);
9521         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "RF-A, 0x1e[11:4]/original val", \
9522                 u4Tmp[0], pHalData->bt_coexist.BtRfRegOrigin1E);
9523         DCMD_Printf(btCoexDbgBuf);
9524
9525         /*  Fw mechanism */
9526         if (!pBtMgnt->ExtConfig.bManualControl) {
9527                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw BT Coex mechanism]============");
9528                 DCMD_Printf(btCoexDbgBuf);
9529         }
9530         if (!pBtMgnt->ExtConfig.bManualControl) {
9531                 if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9532                         psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm1Ant.curPsTdma;
9533                 else
9534                         psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm2Ant.curPsTdma;
9535                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA(0x3a)", \
9536                         pHalData->bt_coexist.fw3aVal[0], pHalData->bt_coexist.fw3aVal[1],
9537                         pHalData->bt_coexist.fw3aVal[2], pHalData->bt_coexist.fw3aVal[3],
9538                         pHalData->bt_coexist.fw3aVal[4], psTdmaCase);
9539                 DCMD_Printf(btCoexDbgBuf);
9540
9541                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Decrease Bt Power", \
9542                         pBtCoex->btdm2Ant.bCurDecBtPwr);
9543                 DCMD_Printf(btCoexDbgBuf);
9544         }
9545         u1Tmp = rtl8723au_read8(padapter, 0x778);
9546         u1Tmp1 = rtl8723au_read8(padapter, 0x783);
9547         u1Tmp2 = rtl8723au_read8(padapter, 0x796);
9548         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \
9549                 u1Tmp, u1Tmp1, u1Tmp2);
9550         DCMD_Printf(btCoexDbgBuf);
9551
9552         if (!pBtMgnt->ExtConfig.bManualControl) {
9553                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x / 0x%x", "Sw DacSwing Ctrl/Val", \
9554                         pBtCoex->btdm2Ant.bCurDacSwingOn, pBtCoex->btdm2Ant.curDacSwingLvl);
9555                 DCMD_Printf(btCoexDbgBuf);
9556         }
9557         u4Tmp[0] =  rtl8723au_read32(padapter, 0x880);
9558         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \
9559                 u4Tmp[0]);
9560         DCMD_Printf(btCoexDbgBuf);
9561
9562         /*  Hw mechanism */
9563         if (!pBtMgnt->ExtConfig.bManualControl) {
9564                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw BT Coex mechanism]============");
9565                 DCMD_Printf(btCoexDbgBuf);
9566         }
9567
9568         u1Tmp = rtl8723au_read8(padapter, 0x40);
9569         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \
9570                 u1Tmp);
9571         DCMD_Printf(btCoexDbgBuf);
9572
9573         u4Tmp[0] = rtl8723au_read32(padapter, 0x550);
9574         u1Tmp = rtl8723au_read8(padapter, 0x522);
9575         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x", "0x550(bcn contrl)/0x522", \
9576                 u4Tmp[0], u1Tmp);
9577         DCMD_Printf(btCoexDbgBuf);
9578
9579         u4Tmp[0] = rtl8723au_read32(padapter, 0x484);
9580         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \
9581                 u4Tmp[0]);
9582         DCMD_Printf(btCoexDbgBuf);
9583
9584         u4Tmp[0] = rtl8723au_read32(padapter, 0x50);
9585         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \
9586                 u4Tmp[0]);
9587         DCMD_Printf(btCoexDbgBuf);
9588
9589         u4Tmp[0] = rtl8723au_read32(padapter, 0xda0);
9590         u4Tmp[1] = rtl8723au_read32(padapter, 0xda4);
9591         u4Tmp[2] = rtl8723au_read32(padapter, 0xda8);
9592         u4Tmp[3] = rtl8723au_read32(padapter, 0xdac);
9593         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \
9594                 u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]);
9595         DCMD_Printf(btCoexDbgBuf);
9596
9597         u4Tmp[0] = rtl8723au_read32(padapter, 0x6c0);
9598         u4Tmp[1] = rtl8723au_read32(padapter, 0x6c4);
9599         u4Tmp[2] = rtl8723au_read32(padapter, 0x6c8);
9600         u1Tmp = rtl8723au_read8(padapter, 0x6cc);
9601         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \
9602                 u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp);
9603         DCMD_Printf(btCoexDbgBuf);
9604
9605         /* u4Tmp = rtl8723au_read32(padapter, 0x770); */
9606         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x770(Hi pri Rx[31:16]/Tx[15:0])", \
9607                 pHalData->bt_coexist.halCoex8723.highPriorityRx,
9608                 pHalData->bt_coexist.halCoex8723.highPriorityTx);
9609         DCMD_Printf(btCoexDbgBuf);
9610         /* u4Tmp = rtl8723au_read32(padapter, 0x774); */
9611         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x774(Lo pri Rx[31:16]/Tx[15:0])", \
9612                 pHalData->bt_coexist.halCoex8723.lowPriorityRx,
9613                 pHalData->bt_coexist.halCoex8723.lowPriorityTx);
9614         DCMD_Printf(btCoexDbgBuf);
9615
9616         /*  Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang */
9617         u1Tmp = rtl8723au_read8(padapter, 0x41b);
9618         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (hang chk == 0xf)", \
9619                 u1Tmp);
9620         DCMD_Printf(btCoexDbgBuf);
9621         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "lastHMEBoxNum", \
9622                 pHalData->LastHMEBoxNum);
9623         DCMD_Printf(btCoexDbgBuf);
9624 }
9625
9626 static void
9627 BTDM_8723ASignalCompensation(struct rtw_adapter *padapter,
9628                              u8 *rssi_wifi, u8 *rssi_bt)
9629 {
9630         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9631                 BTDM_1AntSignalCompensation(padapter, rssi_wifi, rssi_bt);
9632 }
9633
9634 static void BTDM_8723AInit(struct rtw_adapter *padapter)
9635 {
9636         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9637                 BTDM_2AntParaInit(padapter);
9638         else
9639                 BTDM_1AntParaInit(padapter);
9640 }
9641
9642 static void BTDM_HWCoexAllOff8723A(struct rtw_adapter *padapter)
9643 {
9644         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9645         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9646
9647         if (pBtMgnt->ExtConfig.bManualControl)
9648                 return;
9649
9650         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9651                 BTDM_2AntHwCoexAllOff8723A(padapter);
9652 }
9653
9654 static void BTDM_FWCoexAllOff8723A(struct rtw_adapter *padapter)
9655 {
9656         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9657         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9658
9659         if (pBtMgnt->ExtConfig.bManualControl)
9660                 return;
9661
9662         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9663                 BTDM_2AntFwCoexAllOff8723A(padapter);
9664 }
9665
9666 static void BTDM_SWCoexAllOff8723A(struct rtw_adapter *padapter)
9667 {
9668         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9669         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9670
9671         if (pBtMgnt->ExtConfig.bManualControl)
9672                 return;
9673
9674         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9675                 BTDM_2AntSwCoexAllOff8723A(padapter);
9676 }
9677
9678 static void
9679 BTDM_Set8723ABtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
9680 {
9681         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9682         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
9683
9684         if (antNum == 1)
9685                 pBtCoex->TotalAntNum = Ant_x1;
9686         else if (antNum == 2)
9687                 pBtCoex->TotalAntNum = Ant_x2;
9688 }
9689
9690 void rtl8723a_BT_lps_leave(struct rtw_adapter *padapter)
9691 {
9692         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9693         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9694
9695         if (pBtMgnt->ExtConfig.bManualControl)
9696                 return;
9697
9698         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9699                 BTDM_1AntLpsLeave(padapter);
9700 }
9701
9702 static void BTDM_ForHalt8723A(struct rtw_adapter *padapter)
9703 {
9704         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9705         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9706
9707         if (pBtMgnt->ExtConfig.bManualControl)
9708                 return;
9709
9710         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9711                 BTDM_1AntForHalt(padapter);
9712 }
9713
9714 static void BTDM_WifiScanNotify8723A(struct rtw_adapter *padapter, u8 scanType)
9715 {
9716         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9717         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9718
9719         if (pBtMgnt->ExtConfig.bManualControl)
9720                 return;
9721
9722         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9723                 BTDM_1AntWifiScanNotify(padapter, scanType);
9724 }
9725
9726 static void
9727 BTDM_WifiAssociateNotify8723A(struct rtw_adapter *padapter, u8 action)
9728 {
9729         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9730         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9731
9732         if (pBtMgnt->ExtConfig.bManualControl)
9733                 return;
9734
9735         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9736                 BTDM_1AntWifiAssociateNotify(padapter, action);
9737 }
9738
9739 static void
9740 BTDM_MediaStatusNotify8723A(struct rtw_adapter *padapter,
9741                             enum rt_media_status mstatus)
9742 {
9743         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9744         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9745
9746         RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatusNotify, %s\n",
9747                 mstatus?"connect":"disconnect"));
9748
9749         BTDM_SetFwChnlInfo(padapter, mstatus);
9750
9751         if (pBtMgnt->ExtConfig.bManualControl)
9752                 return;
9753
9754         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9755                 BTDM_1AntMediaStatusNotify(padapter, mstatus);
9756 }
9757
9758 static void BTDM_ForDhcp8723A(struct rtw_adapter *padapter)
9759 {
9760         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9761         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9762
9763         if (pBtMgnt->ExtConfig.bManualControl)
9764                 return;
9765
9766         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9767                 BTDM_1AntForDhcp(padapter);
9768 }
9769
9770 bool rtl8723a_BT_using_antenna_1(struct rtw_adapter *padapter)
9771 {
9772         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9773                 return true;
9774         else
9775                 return false;
9776 }
9777
9778 static void BTDM_BTCoexist8723A(struct rtw_adapter *padapter)
9779 {
9780         struct hal_data_8723a *pHalData;
9781         struct bt_30info *pBTInfo;
9782         struct bt_mgnt *pBtMgnt;
9783         struct bt_coexist_8723a *pBtCoex;
9784
9785         pHalData = GET_HAL_DATA(padapter);
9786         pBTInfo = GET_BT_INFO(padapter);
9787         pBtMgnt = &pBTInfo->BtMgnt;
9788         pBtCoex = &pHalData->bt_coexist.halCoex8723;
9789
9790         RTPRINT(FBT, BT_TRACE, ("[BTCoex], beacon RSSI = 0x%x(%d)\n",
9791                 pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB,
9792                 pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB));
9793
9794         btdm_BtHwCountersMonitor(padapter);
9795         btdm_BtEnableDisableCheck8723A(padapter);
9796
9797         if (pBtMgnt->ExtConfig.bManualControl) {
9798                 RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__));
9799                 return;
9800         }
9801
9802         if (pBtCoex->bC2hBtInfoReqSent) {
9803                 if (!rtl8723a_BT_enabled(padapter)) {
9804                         pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
9805                 } else {
9806                         if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED)
9807                                 pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
9808                 }
9809
9810                 btdm_BTCoexist8723AHandler(padapter);
9811         } else if (!rtl8723a_BT_enabled(padapter)) {
9812                 pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
9813                 btdm_BTCoexist8723AHandler(padapter);
9814         }
9815
9816         BTDM_QueryBtInformation(padapter);
9817 }
9818
9819 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */
9820
9821 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */
9822
9823 /*  local function start with btdm_ */
9824 /*  extern function start with BTDM_ */
9825
9826 static void BTDM_SetAntenna(struct rtw_adapter *padapter, u8 who)
9827 {
9828 }
9829
9830 void
9831 BTDM_SingleAnt(
9832         struct rtw_adapter *padapter,
9833         u8 bSingleAntOn,
9834         u8 bInterruptOn,
9835         u8 bMultiNAVOn
9836         )
9837 {
9838         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9839         u8 H2C_Parameter[3] = {0};
9840
9841         if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1)
9842                 return;
9843
9844         H2C_Parameter[2] = 0;
9845         H2C_Parameter[1] = 0;
9846         H2C_Parameter[0] = 0;
9847
9848         if (bInterruptOn) {
9849                 H2C_Parameter[2] |= 0x02;       /* BIT1 */
9850                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9851         }
9852         pHalData->bt_coexist.bInterruptOn = bInterruptOn;
9853
9854         if (bSingleAntOn) {
9855                 H2C_Parameter[2] |= 0x10;       /* BIT4 */
9856                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9857         }
9858         pHalData->bt_coexist.bSingleAntOn = bSingleAntOn;
9859
9860         if (bMultiNAVOn) {
9861                 H2C_Parameter[2] |= 0x20;       /* BIT5 */
9862                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9863         }
9864         pHalData->bt_coexist.bMultiNAVOn = bMultiNAVOn;
9865
9866         RTPRINT(FBT, BT_TRACE, ("[DM][BT], SingleAntenna =[%s:%s:%s], write 0xe = 0x%x\n",
9867                 bSingleAntOn?"ON":"OFF", bInterruptOn?"ON":"OFF", bMultiNAVOn?"ON":"OFF",
9868                 H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
9869 }
9870
9871 void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter)
9872 {
9873         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9874         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9875         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9876 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
9877         u8      stateChange = false;
9878         u32                     BT_Polling, Ratio_Act, Ratio_STA;
9879         u32                             BT_Active, BT_State;
9880         u32                             regBTActive = 0, regBTState = 0, regBTPolling = 0;
9881
9882         if (!rtl8723a_BT_coexist(padapter))
9883                 return;
9884         if (pBtMgnt->ExtConfig.bManualControl)
9885                 return;
9886         if (pHalData->bt_coexist.BT_CoexistType != BT_CSR_BC8)
9887                 return;
9888         if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1)
9889                 return;
9890
9891         /*  The following we only consider CSR BC8 and fw version should be >= 62 */
9892         RTPRINT(FBT, BT_TRACE, ("[DM][BT], FirmwareVersion = 0x%x(%d)\n",
9893         pHalData->FirmwareVersion, pHalData->FirmwareVersion));
9894         regBTActive = REG_BT_ACTIVE;
9895         regBTState = REG_BT_STATE;
9896         if (pHalData->FirmwareVersion >= FW_VER_BT_REG1)
9897                 regBTPolling = REG_BT_POLLING1;
9898         else
9899                 regBTPolling = REG_BT_POLLING;
9900
9901         BT_Active = rtl8723au_read32(padapter, regBTActive);
9902         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Active(0x%x) =%x\n", regBTActive, BT_Active));
9903         BT_Active = BT_Active & 0x00ffffff;
9904
9905         BT_State = rtl8723au_read32(padapter, regBTState);
9906         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_State(0x%x) =%x\n", regBTState, BT_State));
9907         BT_State = BT_State & 0x00ffffff;
9908
9909         BT_Polling = rtl8723au_read32(padapter, regBTPolling);
9910         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Polling(0x%x) =%x\n", regBTPolling, BT_Polling));
9911
9912         if (BT_Active == 0xffffffff && BT_State == 0xffffffff && BT_Polling == 0xffffffff)
9913                 return;
9914         if (BT_Polling == 0)
9915                 return;
9916
9917         Ratio_Act = BT_Active*1000/BT_Polling;
9918         Ratio_STA = BT_State*1000/BT_Polling;
9919
9920         pHalData->bt_coexist.Ratio_Tx = Ratio_Act;
9921         pHalData->bt_coexist.Ratio_PRI = Ratio_STA;
9922
9923         RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_Act =%d\n", Ratio_Act));
9924         RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_STA =%d\n", Ratio_STA));
9925
9926         if (Ratio_STA < 60 && Ratio_Act < 500) {        /*  BT PAN idle */
9927                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_IDLE;
9928                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK;
9929                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
9930         } else {
9931                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_IDLE;
9932
9933                 if (Ratio_STA) {
9934                         /*  Check if BT PAN (under BT 2.1) is uplink or downlink */
9935                         if ((Ratio_Act/Ratio_STA) < 2) {
9936                                 /*  BT PAN Uplink */
9937                                 pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = true;
9938                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_UPLINK;
9939                                 pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = false;
9940                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK;
9941                         } else {
9942                                 /*  BT PAN downlink */
9943                                 pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false;
9944                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
9945                                 pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true;
9946                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK;
9947                         }
9948                 } else {
9949                         /*  BT PAN downlink */
9950                         pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false;
9951                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
9952                         pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true;
9953                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK;
9954                 }
9955         }
9956
9957         /*  Check BT is idle or not */
9958         if (pBtMgnt->ExtConfig.NumberOfHandle == 0 &&
9959             pBtMgnt->ExtConfig.NumberOfSCO == 0) {
9960                 pBtMgnt->ExtConfig.bBTBusy = false;
9961                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
9962         } else {
9963                 if (Ratio_STA < 60) {
9964                         pBtMgnt->ExtConfig.bBTBusy = false;
9965                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
9966                 } else {
9967                         pBtMgnt->ExtConfig.bBTBusy = true;
9968                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_IDLE;
9969                 }
9970         }
9971
9972         if (pBtMgnt->ExtConfig.NumberOfHandle == 0 &&
9973             pBtMgnt->ExtConfig.NumberOfSCO == 0) {
9974                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW;
9975                 pBtMgnt->ExtConfig.MIN_BT_RSSI = 0;
9976                 BTDM_SetAntenna(padapter, BTDM_ANT_BT_IDLE);
9977         } else {
9978                 if (pBtMgnt->ExtConfig.MIN_BT_RSSI <= -5) {
9979                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_RSSI_LOW;
9980                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Low\n"));
9981                 } else {
9982                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW;
9983                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Normal\n"));
9984                 }
9985         }
9986
9987         if (pHalData->bt_coexist.bBTBusyTraffic != pBtMgnt->ExtConfig.bBTBusy) {
9988                 /*  BT idle or BT non-idle */
9989                 pHalData->bt_coexist.bBTBusyTraffic = pBtMgnt->ExtConfig.bBTBusy;
9990                 stateChange = true;
9991         }
9992
9993         if (stateChange) {
9994                 if (!pBtMgnt->ExtConfig.bBTBusy)
9995                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n"));
9996                 else
9997                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is non-idle\n"));
9998         }
9999         if (!pBtMgnt->ExtConfig.bBTBusy) {
10000                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n"));
10001                 if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING|WIFI_SITE_MONITOR) == true)
10002                         BTDM_SetAntenna(padapter, BTDM_ANT_WIFI);
10003         }
10004 }
10005
10006 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */
10007
10008 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */
10009
10010 /*  local function start with btdm_ */
10011
10012 /*  Note: */
10013 /*  In the following, FW should be done before SW mechanism. */
10014 /*  BTDM_Balance(), BTDM_DiminishWiFi(), BT_NAV() should be done */
10015 /*  before BTDM_AGCTable(), BTDM_BBBackOffLevel(), btdm_DacSwing(). */
10016
10017 /*  extern function start with BTDM_ */
10018
10019 void
10020 BTDM_DiminishWiFi(
10021         struct rtw_adapter *padapter,
10022         u8 bDACOn,
10023         u8 bInterruptOn,
10024         u8 DACSwingLevel,
10025         u8 bNAVOn
10026         )
10027 {
10028         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10029         u8 H2C_Parameter[3] = {0};
10030
10031         if (pHalData->bt_coexist.BT_Ant_Num != Ant_x2)
10032                 return;
10033
10034         if ((pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_RSSI_LOW) &&
10035             (DACSwingLevel == 0x20)) {
10036                 RTPRINT(FBT, BT_TRACE, ("[BT]DiminishWiFi 0x20 original, but set 0x18 for Low RSSI!\n"));
10037                 DACSwingLevel = 0x18;
10038         }
10039
10040         H2C_Parameter[2] = 0;
10041         H2C_Parameter[1] = DACSwingLevel;
10042         H2C_Parameter[0] = 0;
10043         if (bDACOn) {
10044                 H2C_Parameter[2] |= 0x01;       /* BIT0 */
10045                 if (bInterruptOn)
10046                         H2C_Parameter[2] |= 0x02;       /* BIT1 */
10047                 pHalData->bt_coexist.bFWCoexistAllOff = false;
10048         }
10049         if (bNAVOn) {
10050                 H2C_Parameter[2] |= 0x08;       /* BIT3 */
10051                 pHalData->bt_coexist.bFWCoexistAllOff = false;
10052         }
10053
10054         RTPRINT(FBT, BT_TRACE, ("[DM][BT], bDACOn = %s, bInterruptOn = %s, write 0xe = 0x%x\n",
10055                 bDACOn?"ON":"OFF", bInterruptOn?"ON":"OFF",
10056                 H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
10057         RTPRINT(FBT, BT_TRACE, ("[DM][BT], bNAVOn = %s\n",
10058                 bNAVOn?"ON":"OFF"));
10059 }
10060
10061 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */
10062
10063 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */
10064
10065 /*  local function */
10066 static void btdm_ResetFWCoexState(struct rtw_adapter *padapter)
10067 {
10068         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10069
10070         pHalData->bt_coexist.CurrentState = 0;
10071         pHalData->bt_coexist.PreviousState = 0;
10072 }
10073
10074 static void btdm_InitBtCoexistDM(struct rtw_adapter *padapter)
10075 {
10076         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10077
10078         /*  20100415 Joseph: Restore RF register 0x1E and 0x1F value for further usage. */
10079         pHalData->bt_coexist.BtRfRegOrigin1E = PHY_QueryRFReg(padapter, PathA, RF_RCK1, bRFRegOffsetMask);
10080         pHalData->bt_coexist.BtRfRegOrigin1F = PHY_QueryRFReg(padapter, PathA, RF_RCK2, 0xf0);
10081
10082         pHalData->bt_coexist.CurrentState = 0;
10083         pHalData->bt_coexist.PreviousState = 0;
10084
10085         BTDM_8723AInit(padapter);
10086         pHalData->bt_coexist.bInitlized = true;
10087 }
10088
10089 /*  */
10090 /*  extern function */
10091 /*  */
10092 void BTDM_CheckAntSelMode(struct rtw_adapter *padapter)
10093 {
10094 }
10095
10096 void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf)
10097 {
10098         BTDM_FwC2hBtRssi8723A(padapter, tmpBuf);
10099 }
10100
10101 void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter)
10102 {
10103         BTDM_Display8723ABtCoexInfo(padapter);
10104 }
10105
10106 void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject)
10107 {
10108 }
10109
10110 u8 BTDM_IsHT40(struct rtw_adapter *padapter)
10111 {
10112         u8 isht40 = true;
10113         enum ht_channel_width bw;
10114
10115         bw = padapter->mlmeextpriv.cur_bwmode;
10116
10117         if (bw == HT_CHANNEL_WIDTH_20)
10118                 isht40 = false;
10119         else if (bw == HT_CHANNEL_WIDTH_40)
10120                 isht40 = true;
10121
10122         return isht40;
10123 }
10124
10125 u8 BTDM_Legacy(struct rtw_adapter *padapter)
10126 {
10127         struct mlme_ext_priv *pmlmeext;
10128         u8 isLegacy = false;
10129
10130         pmlmeext = &padapter->mlmeextpriv;
10131         if ((pmlmeext->cur_wireless_mode == WIRELESS_11B) ||
10132                 (pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
10133                 (pmlmeext->cur_wireless_mode == WIRELESS_11BG))
10134                 isLegacy = true;
10135
10136         return isLegacy;
10137 }
10138
10139 void BTDM_CheckWiFiState(struct rtw_adapter *padapter)
10140 {
10141         struct hal_data_8723a *pHalData;
10142         struct mlme_priv *pmlmepriv;
10143         struct bt_30info *pBTInfo;
10144         struct bt_mgnt *pBtMgnt;
10145
10146         pHalData = GET_HAL_DATA(padapter);
10147         pmlmepriv = &padapter->mlmepriv;
10148         pBTInfo = GET_BT_INFO(padapter);
10149         pBtMgnt = &pBTInfo->BtMgnt;
10150
10151         if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
10152                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_IDLE;
10153
10154                 if (pmlmepriv->LinkDetectInfo.bTxBusyTraffic)
10155                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_UPLINK;
10156                 else
10157                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK;
10158
10159                 if (pmlmepriv->LinkDetectInfo.bRxBusyTraffic)
10160                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_DOWNLINK;
10161                 else
10162                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK;
10163         } else {
10164                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_IDLE;
10165                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK;
10166                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK;
10167         }
10168
10169         if (BTDM_Legacy(padapter)) {
10170                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_LEGACY;
10171                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20;
10172                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40;
10173         } else {
10174                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_LEGACY;
10175                 if (BTDM_IsHT40(padapter)) {
10176                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT40;
10177                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20;
10178                 } else {
10179                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT20;
10180                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40;
10181                 }
10182         }
10183
10184         if (pBtMgnt->BtOperationOn)
10185                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT30;
10186         else
10187                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT30;
10188 }
10189
10190 s32 BTDM_GetRxSS(struct rtw_adapter *padapter)
10191 {
10192 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
10193         struct mlme_priv *pmlmepriv;
10194         struct hal_data_8723a *pHalData;
10195         s32                     UndecoratedSmoothedPWDB = 0;
10196
10197         pmlmepriv = &padapter->mlmepriv;
10198         pHalData = GET_HAL_DATA(padapter);
10199
10200         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
10201                 UndecoratedSmoothedPWDB = GET_UNDECORATED_AVERAGE_RSSI(padapter);
10202         } else { /*  associated entry pwdb */
10203                 UndecoratedSmoothedPWDB = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB;
10204                 /* pHalData->BT_EntryMinUndecoratedSmoothedPWDB */
10205         }
10206         RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxSS() = %d\n", UndecoratedSmoothedPWDB));
10207         return UndecoratedSmoothedPWDB;
10208 }
10209
10210 static s32 BTDM_GetRxBeaconSS(struct rtw_adapter *padapter)
10211 {
10212 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
10213         struct mlme_priv *pmlmepriv;
10214         struct hal_data_8723a *pHalData;
10215         s32                     pwdbBeacon = 0;
10216
10217         pmlmepriv = &padapter->mlmepriv;
10218         pHalData = GET_HAL_DATA(padapter);
10219
10220         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
10221                 /* pwdbBeacon = pHalData->dmpriv.UndecoratedSmoothedBeacon; */
10222                 pwdbBeacon = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB;
10223         }
10224         RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxBeaconSS() = %d\n", pwdbBeacon));
10225         return pwdbBeacon;
10226 }
10227
10228 /*  Get beacon rssi state */
10229 u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum,
10230                               u8 RssiThresh, u8 RssiThresh1)
10231 {
10232         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10233         s32 pwdbBeacon = 0;
10234         u8 bcnRssiState = 0;
10235
10236         pwdbBeacon = BTDM_GetRxBeaconSS(padapter);
10237
10238         if (levelNum == 2) {
10239                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10240
10241                 if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) ||
10242                     (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) {
10243                         if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10244                                 bcnRssiState = BT_RSSI_STATE_HIGH;
10245                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10246                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10247                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n"));
10248                         } else {
10249                                 bcnRssiState = BT_RSSI_STATE_STAY_LOW;
10250                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n"));
10251                         }
10252                 } else {
10253                         if (pwdbBeacon < RssiThresh) {
10254                                 bcnRssiState = BT_RSSI_STATE_LOW;
10255                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10256                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10257                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n"));
10258                         } else {
10259                                 bcnRssiState = BT_RSSI_STATE_STAY_HIGH;
10260                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n"));
10261                         }
10262                 }
10263         } else if (levelNum == 3) {
10264                 if (RssiThresh > RssiThresh1) {
10265                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON thresh error!!\n"));
10266                         return pHalData->bt_coexist.preRssiStateBeacon;
10267                 }
10268
10269                 if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) ||
10270                     (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) {
10271                         if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10272                                 bcnRssiState = BT_RSSI_STATE_MEDIUM;
10273                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10274                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10275                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10276                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n"));
10277                         } else {
10278                                 bcnRssiState = BT_RSSI_STATE_STAY_LOW;
10279                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n"));
10280                         }
10281                 } else if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_MEDIUM) ||
10282                            (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_MEDIUM)) {
10283                         if (pwdbBeacon >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
10284                                 bcnRssiState = BT_RSSI_STATE_HIGH;
10285                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10286                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10287                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10288                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n"));
10289                         } else if (pwdbBeacon < RssiThresh) {
10290                                 bcnRssiState = BT_RSSI_STATE_LOW;
10291                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10292                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10293                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10294                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n"));
10295                         } else {
10296                                 bcnRssiState = BT_RSSI_STATE_STAY_MEDIUM;
10297                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Medium\n"));
10298                         }
10299                 } else {
10300                         if (pwdbBeacon < RssiThresh1) {
10301                                 bcnRssiState = BT_RSSI_STATE_MEDIUM;
10302                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10303                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10304                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10305                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n"));
10306                         } else {
10307                                 bcnRssiState = BT_RSSI_STATE_STAY_HIGH;
10308                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n"));
10309                         }
10310                 }
10311         }
10312
10313         pHalData->bt_coexist.preRssiStateBeacon = bcnRssiState;
10314
10315         return bcnRssiState;
10316 }
10317
10318 u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum,
10319                             u8 RssiThresh, u8 RssiThresh1)
10320 {
10321         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10322         s32 UndecoratedSmoothedPWDB = 0;
10323         u8 btRssiState = 0;
10324
10325         UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter);
10326
10327         if (levelNum == 2) {
10328                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10329
10330                 if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) ||
10331                     (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) {
10332                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10333                                 btRssiState = BT_RSSI_STATE_HIGH;
10334                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10335                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10336                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
10337                         } else {
10338                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10339                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
10340                         }
10341                 } else {
10342                         if (UndecoratedSmoothedPWDB < RssiThresh) {
10343                                 btRssiState = BT_RSSI_STATE_LOW;
10344                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
10345                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10346                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
10347                         } else {
10348                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10349                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
10350                         }
10351                 }
10352         } else if (levelNum == 3) {
10353                 if (RssiThresh > RssiThresh1) {
10354                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 thresh error!!\n"));
10355                         return pHalData->bt_coexist.preRssiState1;
10356                 }
10357
10358                 if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) ||
10359                     (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) {
10360                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10361                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10362                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10363                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10364                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10365                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
10366                         } else {
10367                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10368                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
10369                         }
10370                 } else if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_MEDIUM) ||
10371                            (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_MEDIUM)) {
10372                         if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
10373                                 btRssiState = BT_RSSI_STATE_HIGH;
10374                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10375                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10376                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10377                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
10378                         } else if (UndecoratedSmoothedPWDB < RssiThresh) {
10379                                 btRssiState = BT_RSSI_STATE_LOW;
10380                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
10381                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10382                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10383                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
10384                         } else {
10385                                 btRssiState = BT_RSSI_STATE_STAY_MEDIUM;
10386                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Medium\n"));
10387                         }
10388                 } else {
10389                         if (UndecoratedSmoothedPWDB < RssiThresh1) {
10390                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10391                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10392                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10393                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10394                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
10395                         } else {
10396                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10397                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
10398                         }
10399                 }
10400         }
10401
10402         pHalData->bt_coexist.preRssiState1 = btRssiState;
10403
10404         return btRssiState;
10405 }
10406
10407 u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum,
10408                            u8 RssiThresh, u8 RssiThresh1)
10409 {
10410         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10411         s32 UndecoratedSmoothedPWDB = 0;
10412         u8 btRssiState = 0;
10413
10414         UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter);
10415
10416         if (levelNum == 2) {
10417                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10418
10419                 if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) ||
10420                     (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) {
10421                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10422                                 btRssiState = BT_RSSI_STATE_HIGH;
10423                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH;
10424                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10425                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n"));
10426                         } else {
10427                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10428                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n"));
10429                         }
10430                 } else {
10431                         if (UndecoratedSmoothedPWDB < RssiThresh) {
10432                                 btRssiState = BT_RSSI_STATE_LOW;
10433                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW;
10434                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10435                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n"));
10436                         } else {
10437                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10438                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n"));
10439                         }
10440                 }
10441         } else if (levelNum == 3) {
10442                 if (RssiThresh > RssiThresh1) {
10443                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI thresh error!!\n"));
10444                         return pHalData->bt_coexist.preRssiState;
10445                 }
10446
10447                 if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) ||
10448                     (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) {
10449                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10450                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10451                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10452                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10453                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10454                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n"));
10455                         } else {
10456                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10457                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n"));
10458                         }
10459                 } else if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_MEDIUM) ||
10460                            (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_MEDIUM)) {
10461                         if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
10462                                 btRssiState = BT_RSSI_STATE_HIGH;
10463                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH;
10464                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10465                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10466                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n"));
10467                         } else if (UndecoratedSmoothedPWDB < RssiThresh) {
10468                                 btRssiState = BT_RSSI_STATE_LOW;
10469                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW;
10470                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10471                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10472                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n"));
10473                         } else {
10474                                 btRssiState = BT_RSSI_STATE_STAY_MEDIUM;
10475                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Medium\n"));
10476                         }
10477                 } else {
10478                         if (UndecoratedSmoothedPWDB < RssiThresh1) {
10479                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10480                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10481                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10482                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10483                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n"));
10484                         } else {
10485                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10486                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n"));
10487                         }
10488                 }
10489         }
10490
10491         pHalData->bt_coexist.preRssiState = btRssiState;
10492
10493         return btRssiState;
10494 }
10495
10496 bool rtl8723a_BT_disable_EDCA_turbo(struct rtw_adapter *padapter)
10497 {
10498         struct bt_mgnt *pBtMgnt;
10499         struct hal_data_8723a *pHalData;
10500         u8 bBtChangeEDCA = false;
10501         u32 EDCA_BT_BE = 0x5ea42b, cur_EDCA_reg;
10502         bool bRet = false;
10503
10504         pHalData = GET_HAL_DATA(padapter);
10505         pBtMgnt = &pHalData->BtInfo.BtMgnt;
10506
10507         if (!rtl8723a_BT_coexist(padapter)) {
10508                 bRet = false;
10509                 pHalData->bt_coexist.lastBtEdca = 0;
10510                 return bRet;
10511         }
10512         if (!((pBtMgnt->bSupportProfile) ||
10513             (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC8))) {
10514                 bRet = false;
10515                 pHalData->bt_coexist.lastBtEdca = 0;
10516                 return bRet;
10517         }
10518
10519         if (rtl8723a_BT_using_antenna_1(padapter)) {
10520                 bRet = false;
10521                 pHalData->bt_coexist.lastBtEdca = 0;
10522                 return bRet;
10523         }
10524
10525         if (pHalData->bt_coexist.exec_cnt < 3)
10526                 pHalData->bt_coexist.exec_cnt++;
10527         else
10528                 pHalData->bt_coexist.bEDCAInitialized = true;
10529
10530         /*  When BT is non idle */
10531         if (!(pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)) {
10532                 RTPRINT(FBT, BT_TRACE, ("BT state non idle, set bt EDCA\n"));
10533
10534                 /* aggr_num = 0x0909; */
10535                 if (pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA) {
10536                         bBtChangeEDCA = true;
10537                         pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA = false;
10538                         pHalData->dmpriv.prv_traffic_idx = 3;
10539                 }
10540                 cur_EDCA_reg = rtl8723au_read32(padapter, REG_EDCA_BE_PARAM);
10541
10542                 if (cur_EDCA_reg != EDCA_BT_BE)
10543                         bBtChangeEDCA = true;
10544                 if (bBtChangeEDCA || !pHalData->bt_coexist.bEDCAInitialized) {
10545                         rtl8723au_write32(padapter, REG_EDCA_BE_PARAM,
10546                                           EDCA_BT_BE);
10547                         pHalData->bt_coexist.lastBtEdca = EDCA_BT_BE;
10548                 }
10549                 bRet = true;
10550         } else {
10551                 RTPRINT(FBT, BT_TRACE, ("BT state idle, set original EDCA\n"));
10552                 pHalData->bt_coexist.lastBtEdca = 0;
10553                 bRet = false;
10554         }
10555         return bRet;
10556 }
10557
10558 void
10559 BTDM_Balance(
10560         struct rtw_adapter *padapter,
10561         u8 bBalanceOn,
10562         u8 ms0,
10563         u8 ms1
10564         )
10565 {
10566         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10567         u8 H2C_Parameter[3] = {0};
10568
10569         if (bBalanceOn) {
10570                 H2C_Parameter[2] = 1;
10571                 H2C_Parameter[1] = ms1;
10572                 H2C_Parameter[0] = ms0;
10573                 pHalData->bt_coexist.bFWCoexistAllOff = false;
10574         } else {
10575                 H2C_Parameter[2] = 0;
10576                 H2C_Parameter[1] = 0;
10577                 H2C_Parameter[0] = 0;
10578         }
10579         pHalData->bt_coexist.bBalanceOn = bBalanceOn;
10580
10581         RTPRINT(FBT, BT_TRACE, ("[DM][BT], Balance =[%s:%dms:%dms], write 0xc = 0x%x\n",
10582                 bBalanceOn?"ON":"OFF", ms0, ms1,
10583                 H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
10584
10585         FillH2CCmd(padapter, 0xc, 3, H2C_Parameter);
10586 }
10587
10588 void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type)
10589 {
10590         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10591         if (type == BT_AGCTABLE_OFF) {
10592                 RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable Off!\n"));
10593                 rtl8723au_write32(padapter, 0xc78, 0x641c0001);
10594                 rtl8723au_write32(padapter, 0xc78, 0x631d0001);
10595                 rtl8723au_write32(padapter, 0xc78, 0x621e0001);
10596                 rtl8723au_write32(padapter, 0xc78, 0x611f0001);
10597                 rtl8723au_write32(padapter, 0xc78, 0x60200001);
10598
10599                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x32000);
10600                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x71000);
10601                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xb0000);
10602                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xfc000);
10603                 PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x30355);
10604
10605                 pHalData->bt_coexist.b8723aAgcTableOn = false;
10606         } else if (type == BT_AGCTABLE_ON) {
10607                 RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable On!\n"));
10608                 rtl8723au_write32(padapter, 0xc78, 0x4e1c0001);
10609                 rtl8723au_write32(padapter, 0xc78, 0x4d1d0001);
10610                 rtl8723au_write32(padapter, 0xc78, 0x4c1e0001);
10611                 rtl8723au_write32(padapter, 0xc78, 0x4b1f0001);
10612                 rtl8723au_write32(padapter, 0xc78, 0x4a200001);
10613
10614                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xdc000);
10615                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x90000);
10616                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x51000);
10617                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x12000);
10618                 PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x00355);
10619
10620                 pHalData->bt_coexist.b8723aAgcTableOn = true;
10621
10622                 pHalData->bt_coexist.bSWCoexistAllOff = false;
10623         }
10624 }
10625
10626 void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type)
10627 {
10628         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10629
10630         if (type == BT_BB_BACKOFF_OFF) {
10631                 RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel Off!\n"));
10632                 rtl8723au_write32(padapter, 0xc04, 0x3a05611);
10633         } else if (type == BT_BB_BACKOFF_ON) {
10634                 RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel On!\n"));
10635                 rtl8723au_write32(padapter, 0xc04, 0x3a07611);
10636                 pHalData->bt_coexist.bSWCoexistAllOff = false;
10637         }
10638 }
10639
10640 void BTDM_FWCoexAllOff(struct rtw_adapter *padapter)
10641 {
10642         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);;
10643
10644         RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff()\n"));
10645         if (pHalData->bt_coexist.bFWCoexistAllOff)
10646                 return;
10647         RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff(), real Do\n"));
10648
10649         BTDM_FWCoexAllOff8723A(padapter);
10650
10651         pHalData->bt_coexist.bFWCoexistAllOff = true;
10652 }
10653
10654 void BTDM_SWCoexAllOff(struct rtw_adapter *padapter)
10655 {
10656         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);;
10657
10658         RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff()\n"));
10659         if (pHalData->bt_coexist.bSWCoexistAllOff)
10660                 return;
10661         RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff(), real Do\n"));
10662         BTDM_SWCoexAllOff8723A(padapter);
10663
10664         pHalData->bt_coexist.bSWCoexistAllOff = true;
10665 }
10666
10667 void BTDM_HWCoexAllOff(struct rtw_adapter *padapter)
10668 {
10669         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);;
10670
10671         RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff()\n"));
10672         if (pHalData->bt_coexist.bHWCoexistAllOff)
10673                 return;
10674         RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff(), real Do\n"));
10675
10676         BTDM_HWCoexAllOff8723A(padapter);
10677
10678         pHalData->bt_coexist.bHWCoexistAllOff = true;
10679 }
10680
10681 void BTDM_CoexAllOff(struct rtw_adapter *padapter)
10682 {
10683         BTDM_FWCoexAllOff(padapter);
10684         BTDM_SWCoexAllOff(padapter);
10685         BTDM_HWCoexAllOff(padapter);
10686 }
10687
10688 void rtl8723a_BT_disable_coexist(struct rtw_adapter *padapter)
10689 {
10690         struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv;
10691
10692         if (!rtl8723a_BT_coexist(padapter))
10693                 return;
10694
10695         /*  8723 1Ant doesn't need to turn off bt coexist mechanism. */
10696         if (rtl8723a_BT_using_antenna_1(padapter))
10697                 return;
10698
10699         /*  Before enter IPS, turn off FW BT Co-exist mechanism */
10700         if (ppwrctrl->reg_rfoff == rf_on) {
10701                 RTPRINT(FBT, BT_TRACE, ("[BT][DM], Before enter IPS, turn off all Coexist DM\n"));
10702                 btdm_ResetFWCoexState(padapter);
10703                 BTDM_CoexAllOff(padapter);
10704                 BTDM_SetAntenna(padapter, BTDM_ANT_BT);
10705         }
10706 }
10707
10708 void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
10709 {
10710         BTDM_8723ASignalCompensation(padapter, rssi_wifi, rssi_bt);
10711 }
10712
10713 void rtl8723a_BT_do_coexist(struct rtw_adapter *padapter)
10714 {
10715         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10716
10717         if (!rtl8723a_BT_coexist(padapter)) {
10718                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT not exists!!\n"));
10719                 return;
10720         }
10721
10722         if (!pHalData->bt_coexist.bInitlized) {
10723                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], btdm_InitBtCoexistDM()\n"));
10724                 btdm_InitBtCoexistDM(padapter);
10725         }
10726
10727         RTPRINT(FBT, BT_TRACE, ("\n\n[DM][BT], BTDM start!!\n"));
10728
10729         BTDM_PWDBMonitor(padapter);
10730
10731         RTPRINT(FBT, BT_TRACE, ("[DM][BT], HW type is 8723\n"));
10732         BTDM_BTCoexist8723A(padapter);
10733         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BTDM end!!\n\n"));
10734 }
10735
10736 void BTDM_UpdateCoexState(struct rtw_adapter *padapter)
10737 {
10738         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10739
10740         if (!BTDM_IsSameCoexistState(padapter)) {
10741                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x,  changeBits = 0x%"i64fmt"x\n",
10742                         pHalData->bt_coexist.PreviousState,
10743                         pHalData->bt_coexist.CurrentState,
10744                         (pHalData->bt_coexist.PreviousState^pHalData->bt_coexist.CurrentState)));
10745                 pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState;
10746         }
10747 }
10748
10749 u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter)
10750 {
10751         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10752
10753         if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState) {
10754                 return true;
10755         } else {
10756                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], Coexist state changed!!\n"));
10757                 return false;
10758         }
10759 }
10760
10761 void BTDM_PWDBMonitor(struct rtw_adapter *padapter)
10762 {
10763         struct bt_30info *pBTInfo = GET_BT_INFO(GetDefaultAdapter(padapter));
10764         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
10765         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10766         u8 H2C_Parameter[3] = {0};
10767         s32 tmpBTEntryMaxPWDB = 0, tmpBTEntryMinPWDB = 0xff;
10768         u8 i;
10769
10770         if (pBtMgnt->BtOperationOn) {
10771                 for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
10772                         if (pBTInfo->BtAsocEntry[i].bUsed) {
10773                                 if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB < tmpBTEntryMinPWDB)
10774                                         tmpBTEntryMinPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB;
10775                                 if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB > tmpBTEntryMaxPWDB)
10776                                         tmpBTEntryMaxPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB;
10777                                 /*  Report every BT connection (HS mode) RSSI to FW */
10778                                 H2C_Parameter[2] = (u8)(pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB & 0xFF);
10779                                 H2C_Parameter[0] = (MAX_FW_SUPPORT_MACID_NUM-1-i);
10780                                 RTPRINT(FDM, DM_BT30, ("RSSI report for BT[%d], H2C_Par = 0x%x\n", i, H2C_Parameter[0]));
10781                                 FillH2CCmd(padapter, RSSI_SETTING_EID, 3, H2C_Parameter);
10782                                 RTPRINT_ADDR(FDM, (DM_PWDB|DM_BT30), ("BT_Entry Mac :"),
10783                                              pBTInfo->BtAsocEntry[i].BTRemoteMACAddr)
10784                                 RTPRINT(FDM, (DM_PWDB|DM_BT30),
10785                                         ("BT rx pwdb[%d] = 0x%x(%d)\n", i,
10786                                         pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB,
10787                                         pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB));
10788                         }
10789                 }
10790                 if (tmpBTEntryMaxPWDB != 0) {   /*  If associated entry is found */
10791                         pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = tmpBTEntryMaxPWDB;
10792                         RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMaxPWDB = 0x%x(%d)\n",
10793                                 tmpBTEntryMaxPWDB, tmpBTEntryMaxPWDB));
10794                 } else {
10795                         pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = 0;
10796                 }
10797                 if (tmpBTEntryMinPWDB != 0xff) { /*  If associated entry is found */
10798                         pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = tmpBTEntryMinPWDB;
10799                         RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMinPWDB = 0x%x(%d)\n",
10800                                 tmpBTEntryMinPWDB, tmpBTEntryMinPWDB));
10801                 } else {
10802                         pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = 0;
10803                 }
10804         }
10805 }
10806
10807 u8 BTDM_IsBTBusy(struct rtw_adapter *padapter)
10808 {
10809         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
10810         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
10811
10812         if (pBtMgnt->ExtConfig.bBTBusy)
10813                 return true;
10814         else
10815                 return false;
10816 }
10817
10818 u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter)
10819 {
10820 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10821         struct mlme_priv *pmlmepriv = &GetDefaultAdapter(padapter)->mlmepriv;
10822         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
10823         struct bt_traffic *pBtTraffic = &pBTInfo->BtTraffic;
10824
10825         if (pmlmepriv->LinkDetectInfo.bBusyTraffic ||
10826                 pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic ||
10827                 pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic)
10828                 return true;
10829         else
10830                 return false;
10831 }
10832
10833 u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter)
10834 {
10835         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10836
10837         if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState)
10838                 return false;
10839         else
10840                 return true;
10841 }
10842
10843 u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter)
10844 {
10845 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10846         struct mlme_priv *pmlmepriv;
10847         struct bt_30info *pBTInfo;
10848         struct bt_traffic *pBtTraffic;
10849
10850         pmlmepriv = &padapter->mlmepriv;
10851         pBTInfo = GET_BT_INFO(padapter);
10852         pBtTraffic = &pBTInfo->BtTraffic;
10853
10854         if ((pmlmepriv->LinkDetectInfo.bTxBusyTraffic) ||
10855                 (pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic))
10856                 return true;
10857         else
10858                 return false;
10859 }
10860
10861 u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter)
10862 {
10863 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10864         struct mlme_priv *pmlmepriv;
10865         struct bt_30info *pBTInfo;
10866         struct bt_traffic *pBtTraffic;
10867
10868         pmlmepriv = &padapter->mlmepriv;
10869         pBTInfo = GET_BT_INFO(padapter);
10870         pBtTraffic = &pBTInfo->BtTraffic;
10871
10872         if ((pmlmepriv->LinkDetectInfo.bRxBusyTraffic) ||
10873                 (pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic))
10874                 return true;
10875         else
10876                 return false;
10877 }
10878
10879 u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter)
10880 {
10881 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10882         struct hal_data_8723a *pHalData;
10883         struct bt_mgnt *pBtMgnt;
10884
10885         pHalData = GET_HAL_DATA(padapter);
10886         pBtMgnt = &pHalData->BtInfo.BtMgnt;
10887
10888         if (pBtMgnt->BtOperationOn)
10889                 return true;
10890         else
10891                 return false;
10892 }
10893
10894 u8 BTDM_IsBTUplink(struct rtw_adapter *padapter)
10895 {
10896         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10897
10898         if (pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic)
10899                 return true;
10900         else
10901                 return false;
10902 }
10903
10904 u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter)
10905 {
10906         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10907
10908         if (pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic)
10909                 return true;
10910         else
10911                 return false;
10912 }
10913
10914 void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter)
10915 {
10916         RTPRINT(FBT, BT_TRACE, ("[BT][DM], BTDM_AdjustForBtOperation()\n"));
10917         BTDM_AdjustForBtOperation8723A(padapter);
10918 }
10919
10920 void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
10921 {
10922         BTDM_Set8723ABtCoexCurrAntNum(padapter, antNum);
10923 }
10924
10925 void BTDM_ForHalt(struct rtw_adapter *padapter)
10926 {
10927         if (!rtl8723a_BT_coexist(padapter))
10928                 return;
10929
10930         BTDM_ForHalt8723A(padapter);
10931         GET_HAL_DATA(padapter)->bt_coexist.bInitlized = false;
10932 }
10933
10934 void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
10935 {
10936         if (!rtl8723a_BT_coexist(padapter))
10937                 return;
10938
10939         BTDM_WifiScanNotify8723A(padapter, scanType);
10940 }
10941
10942 void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action)
10943 {
10944         if (!rtl8723a_BT_coexist(padapter))
10945                 return;
10946
10947         BTDM_WifiAssociateNotify8723A(padapter, action);
10948 }
10949
10950 void rtl8723a_BT_mediastatus_notify(struct rtw_adapter *padapter,
10951                                     enum rt_media_status mstatus)
10952 {
10953         if (!rtl8723a_BT_coexist(padapter))
10954                 return;
10955
10956         BTDM_MediaStatusNotify8723A(padapter, mstatus);
10957 }
10958
10959 void rtl8723a_BT_specialpacket_notify(struct rtw_adapter *padapter)
10960 {
10961         if (!rtl8723a_BT_coexist(padapter))
10962                 return;
10963
10964         BTDM_ForDhcp8723A(padapter);
10965 }
10966
10967 void BTDM_ResetActionProfileState(struct rtw_adapter *padapter)
10968 {
10969         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10970
10971         pHalData->bt_coexist.CurrentState &= ~\
10972                 (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP|
10973                 BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_SCO);
10974 }
10975
10976 u8 BTDM_IsActionSCO(struct rtw_adapter *padapter)
10977 {
10978         struct hal_data_8723a *pHalData;
10979         struct bt_30info *pBTInfo;
10980         struct bt_mgnt *pBtMgnt;
10981         struct bt_dgb *pBtDbg;
10982         u8 bRet;
10983
10984         pHalData = GET_HAL_DATA(padapter);
10985         pBTInfo = GET_BT_INFO(padapter);
10986         pBtMgnt = &pBTInfo->BtMgnt;
10987         pBtDbg = &pBTInfo->BtDbg;
10988         bRet = false;
10989
10990         if (pBtDbg->dbgCtrl) {
10991                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_SCO) {
10992                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO;
10993                         bRet = true;
10994                 }
10995         } else {
10996                 if (pBtMgnt->ExtConfig.NumberOfSCO > 0) {
10997                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO;
10998                         bRet = true;
10999                 }
11000         }
11001         return bRet;
11002 }
11003
11004 u8 BTDM_IsActionHID(struct rtw_adapter *padapter)
11005 {
11006         struct bt_30info *pBTInfo;
11007         struct hal_data_8723a *pHalData;
11008         struct bt_mgnt *pBtMgnt;
11009         struct bt_dgb *pBtDbg;
11010         u8 bRet;
11011
11012         pHalData = GET_HAL_DATA(padapter);
11013         pBTInfo = GET_BT_INFO(padapter);
11014         pBtMgnt = &pBTInfo->BtMgnt;
11015         pBtDbg = &pBTInfo->BtDbg;
11016         bRet = false;
11017
11018         if (pBtDbg->dbgCtrl) {
11019                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID) {
11020                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID;
11021                         bRet = true;
11022                 }
11023         } else {
11024                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
11025                     pBtMgnt->ExtConfig.NumberOfHandle == 1) {
11026                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID;
11027                         bRet = true;
11028                 }
11029         }
11030         return bRet;
11031 }
11032
11033 u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter)
11034 {
11035         struct hal_data_8723a *pHalData;
11036         struct bt_30info *pBTInfo;
11037         struct bt_mgnt *pBtMgnt;
11038         struct bt_dgb *pBtDbg;
11039         u8 bRet;
11040
11041         pHalData = GET_HAL_DATA(padapter);
11042         pBTInfo = GET_BT_INFO(padapter);
11043         pBtMgnt = &pBTInfo->BtMgnt;
11044         pBtDbg = &pBTInfo->BtDbg;
11045         bRet = false;
11046
11047         if (pBtDbg->dbgCtrl) {
11048                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_A2DP) {
11049                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP;
11050                         bRet = true;
11051                 }
11052         } else {
11053                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP) &&
11054                     pBtMgnt->ExtConfig.NumberOfHandle == 1) {
11055                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP;
11056                         bRet = true;
11057                 }
11058         }
11059         return bRet;
11060 }
11061
11062 u8 BTDM_IsActionPAN(struct rtw_adapter *padapter)
11063 {
11064         struct hal_data_8723a *pHalData;
11065         struct bt_30info *pBTInfo;
11066         struct bt_mgnt *pBtMgnt;
11067         struct bt_dgb *pBtDbg;
11068         u8 bRet;
11069
11070         pHalData = GET_HAL_DATA(padapter);
11071         pBTInfo = GET_BT_INFO(padapter);
11072         pBtMgnt = &pBTInfo->BtMgnt;
11073         pBtDbg = &pBTInfo->BtDbg;
11074         bRet = false;
11075
11076         if (pBtDbg->dbgCtrl) {
11077                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN) {
11078                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN;
11079                         bRet = true;
11080                 }
11081         } else {
11082                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
11083                     pBtMgnt->ExtConfig.NumberOfHandle == 1) {
11084                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN;
11085                         bRet = true;
11086                 }
11087         }
11088         return bRet;
11089 }
11090
11091 u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter)
11092 {
11093         struct hal_data_8723a *pHalData;
11094         struct bt_30info *pBTInfo;
11095         struct bt_mgnt *pBtMgnt;
11096         struct bt_dgb *pBtDbg;
11097         u8 bRet;
11098
11099         pHalData = GET_HAL_DATA(padapter);
11100         pBTInfo = GET_BT_INFO(padapter);
11101         pBtMgnt = &pBTInfo->BtMgnt;
11102         pBtDbg = &pBTInfo->BtDbg;
11103         bRet = false;
11104
11105         if (pBtDbg->dbgCtrl) {
11106                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_A2DP) {
11107                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP);
11108                         bRet = true;
11109                 }
11110         } else {
11111                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
11112                     BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
11113                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP);
11114                         bRet = true;
11115                 }
11116         }
11117         return bRet;
11118 }
11119
11120 u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter)
11121 {
11122         struct hal_data_8723a *pHalData;
11123         struct bt_30info *pBTInfo;
11124         struct bt_dgb *pBtDbg;
11125         u8 bRet;
11126
11127         pHalData = GET_HAL_DATA(padapter);
11128         pBTInfo = GET_BT_INFO(padapter);
11129         pBtDbg = &pBTInfo->BtDbg;
11130         bRet = false;
11131
11132         if (pBtDbg->dbgCtrl) {
11133                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_PAN) {
11134                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN);
11135                         bRet = true;
11136                 }
11137         } else {
11138                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
11139                     BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
11140                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN);
11141                         bRet = true;
11142                 }
11143         }
11144         return bRet;
11145 }
11146
11147 u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter)
11148 {
11149         struct hal_data_8723a *pHalData;
11150         struct bt_30info *pBTInfo;
11151         struct bt_dgb *pBtDbg;
11152         u8 bRet;
11153
11154         pHalData = GET_HAL_DATA(padapter);
11155         pBTInfo = GET_BT_INFO(padapter);
11156         pBtDbg = &pBTInfo->BtDbg;
11157         bRet = false;
11158
11159         if (pBtDbg->dbgCtrl) {
11160                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN_A2DP) {
11161                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP);
11162                         bRet = true;
11163                 }
11164         } else {
11165                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
11166                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP);
11167                         bRet = true;
11168                 }
11169         }
11170         return bRet;
11171 }
11172
11173 bool rtl8723a_BT_enabled(struct rtw_adapter *padapter)
11174 {
11175         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11176
11177         if (pHalData->bt_coexist.bCurBtDisabled)
11178                 return false;
11179         else
11180                 return true;
11181 }
11182
11183 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */
11184
11185 /*  ===== Below this line is sync from SD7 driver HAL/HalBT.c ===== */
11186
11187 /*  */
11188 /*local function */
11189 /*  */
11190
11191 static void halbt_InitHwConfig8723A(struct rtw_adapter *padapter)
11192 {
11193 }
11194
11195 /*  */
11196 /*extern function */
11197 /*  */
11198 u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter)
11199 {
11200         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11201
11202         return pHalData->bt_coexist.BT_Ant_Num;
11203 }
11204
11205 void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum)
11206 {
11207         struct bt_30info *pBTinfo;
11208         struct bt_asoc_entry *pBtAssocEntry;
11209         u16                             usConfig = 0;
11210
11211         pBTinfo = GET_BT_INFO(padapter);
11212         pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum];
11213
11214         pBtAssocEntry->HwCAMIndex = BT_HWCAM_STAR + EntryNum;
11215
11216         usConfig = CAM_VALID | (CAM_AES << 2);
11217         rtl8723a_cam_write(padapter, pBtAssocEntry->HwCAMIndex, usConfig,
11218                            pBtAssocEntry->BTRemoteMACAddr,
11219                            pBtAssocEntry->PTK + TKIP_ENC_KEY_POS);
11220 }
11221
11222 void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum)
11223 {
11224         struct bt_30info *pBTinfo;
11225         struct bt_asoc_entry *pBtAssocEntry;
11226
11227         pBTinfo = GET_BT_INFO(padapter);
11228         pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum];
11229
11230         if (pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex != 0) {
11231                 /*  ToDo : add New HALBT_RemoveKey function !! */
11232                 if (pBtAssocEntry->HwCAMIndex >= BT_HWCAM_STAR &&
11233                     pBtAssocEntry->HwCAMIndex < HALF_CAM_ENTRY)
11234                         rtl8723a_cam_empty_entry(padapter,
11235                                                  pBtAssocEntry->HwCAMIndex);
11236                 pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex = 0;
11237         }
11238 }
11239
11240 void rtl8723a_BT_init_hal_vars(struct rtw_adapter *padapter)
11241 {
11242         struct hal_data_8723a *pHalData;
11243
11244         pHalData = GET_HAL_DATA(padapter);
11245
11246         pHalData->bt_coexist.BluetoothCoexist = pHalData->EEPROMBluetoothCoexist;
11247         pHalData->bt_coexist.BT_Ant_Num = pHalData->EEPROMBluetoothAntNum;
11248         pHalData->bt_coexist.BT_CoexistType = pHalData->EEPROMBluetoothType;
11249         pHalData->bt_coexist.BT_Ant_isolation = pHalData->EEPROMBluetoothAntIsolation;
11250         pHalData->bt_coexist.bt_radiosharedtype = pHalData->EEPROMBluetoothRadioShared;
11251
11252         RT_TRACE(_module_hal_init_c_, _drv_info_,
11253                  ("BT Coexistance = 0x%x\n", rtl8723a_BT_coexist(padapter)));
11254
11255         if (rtl8723a_BT_coexist(padapter)) {
11256                 if (pHalData->bt_coexist.BT_Ant_Num == Ant_x2) {
11257                         BTDM_SetBtCoexCurrAntNum(padapter, 2);
11258                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("BlueTooth BT_Ant_Num = Antx2\n"));
11259                 } else if (pHalData->bt_coexist.BT_Ant_Num == Ant_x1) {
11260                         BTDM_SetBtCoexCurrAntNum(padapter, 1);
11261                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("BlueTooth BT_Ant_Num = Antx1\n"));
11262                 }
11263                 pHalData->bt_coexist.bBTBusyTraffic = false;
11264                 pHalData->bt_coexist.bBTTrafficModeSet = false;
11265                 pHalData->bt_coexist.bBTNonTrafficModeSet = false;
11266                 pHalData->bt_coexist.CurrentState = 0;
11267                 pHalData->bt_coexist.PreviousState = 0;
11268
11269                 RT_TRACE(_module_hal_init_c_, _drv_info_,
11270                          ("bt_radiosharedType = 0x%x\n",
11271                          pHalData->bt_coexist.bt_radiosharedtype));
11272         }
11273 }
11274
11275 bool rtl8723a_BT_coexist(struct rtw_adapter *padapter)
11276 {
11277         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11278
11279         if (pHalData->bt_coexist.BluetoothCoexist)
11280                 return true;
11281         else
11282                 return false;
11283 }
11284
11285 u8 HALBT_BTChipType(struct rtw_adapter *padapter)
11286 {
11287         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11288
11289         return pHalData->bt_coexist.BT_CoexistType;
11290 }
11291
11292 void rtl8723a_BT_init_hwconfig(struct rtw_adapter *padapter)
11293 {
11294         halbt_InitHwConfig8723A(padapter);
11295         rtl8723a_BT_do_coexist(padapter);
11296 }
11297
11298 void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter)
11299 {
11300 }
11301
11302 /*  ===== End of sync from SD7 driver HAL/HalBT.c ===== */
11303
11304 void rtl8723a_dual_antenna_detection(struct rtw_adapter *padapter)
11305 {
11306         struct hal_data_8723a *pHalData;
11307         struct dm_odm_t *pDM_Odm;
11308         struct sw_ant_sw *pDM_SWAT_Table;
11309         u8 i;
11310
11311         pHalData = GET_HAL_DATA(padapter);
11312         pDM_Odm = &pHalData->odmpriv;
11313         pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
11314
11315         /*  */
11316         /*  <Roger_Notes> RTL8723A Single and Dual antenna dynamic detection
11317             mechanism when RF power state is on. */
11318         /*  We should take power tracking, IQK, LCK, RCK RF read/write
11319             operation into consideration. */
11320         /*  2011.12.15. */
11321         /*  */
11322         if (!pHalData->bAntennaDetected) {
11323                 u8 btAntNum = BT_GetPGAntNum(padapter);
11324
11325                 /*  Set default antenna B status */
11326                 if (btAntNum == Ant_x2)
11327                         pDM_SWAT_Table->ANTB_ON = true;
11328                 else if (btAntNum == Ant_x1)
11329                         pDM_SWAT_Table->ANTB_ON = false;
11330                 else
11331                         pDM_SWAT_Table->ANTB_ON = true;
11332
11333                 if (pHalData->CustomerID != RT_CID_TOSHIBA) {
11334                         for (i = 0; i < MAX_ANTENNA_DETECTION_CNT; i++) {
11335                                 if (ODM_SingleDualAntennaDetection
11336                                     (&pHalData->odmpriv, ANTTESTALL) == true)
11337                                         break;
11338                         }
11339
11340                         /*  Set default antenna number for BT coexistence */
11341                         if (btAntNum == Ant_x2)
11342                                 BT_SetBtCoexCurrAntNum(padapter,
11343                                                        pDM_SWAT_Table->
11344                                                        ANTB_ON ? 2 : 1);
11345                 }
11346                 pHalData->bAntennaDetected = true;
11347         }
11348 }