7f091da0
[firefly-linux-kernel-4.4.55.git] /
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, arg;
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         arg = mac_id&0x1f;/* MACID */
5864         arg |= BIT(7);
5865         if (true == shortGIrate)
5866                 arg |= BIT(5);
5867
5868         RTPRINT(FBT, BT_TRACE,
5869                 ("[BTCoex], Update FW RAID entry, MASK = 0x%08x, "
5870                  "arg = 0x%02x\n", mask, arg));
5871
5872         rtl8723a_set_raid_cmd(padapter, mask, arg);
5873
5874         psta->init_rate = init_rate;
5875         pdmpriv->INIDATA_RATE[mac_id] = init_rate;
5876 }
5877
5878 static void
5879 btdm_1AntUpdateHalRAMaskForSCO(struct rtw_adapter *padapter, u8 forceUpdate)
5880 {
5881         struct btdm_8723a_1ant *pBtdm8723;
5882         struct sta_priv *pstapriv;
5883         struct wlan_bssid_ex *cur_network;
5884         struct sta_info *psta;
5885         u32 macid;
5886         u32 filter = 0;
5887
5888         pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
5889
5890         if (pBtdm8723->bRAChanged == true && forceUpdate == false)
5891                 return;
5892
5893         pstapriv = &padapter->stapriv;
5894         cur_network = &padapter->mlmeextpriv.mlmext_info.network;
5895         psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5896         macid = psta->mac_id;
5897
5898         filter |= BIT(_1M_RATE_);
5899         filter |= BIT(_2M_RATE_);
5900         filter |= BIT(_5M_RATE_);
5901         filter |= BIT(_11M_RATE_);
5902         filter |= BIT(_6M_RATE_);
5903         filter |= BIT(_9M_RATE_);
5904
5905         btdm_1AntUpdateHalRAMask(padapter, macid, filter);
5906
5907         pBtdm8723->bRAChanged = true;
5908 }
5909
5910 static void btdm_1AntRecoverHalRAMask(struct rtw_adapter *padapter)
5911 {
5912         struct btdm_8723a_1ant *pBtdm8723;
5913         struct sta_priv *pstapriv;
5914         struct wlan_bssid_ex *cur_network;
5915         struct sta_info *psta;
5916
5917         pBtdm8723 = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant;
5918
5919         if (pBtdm8723->bRAChanged == false)
5920                 return;
5921
5922         pstapriv = &padapter->stapriv;
5923         cur_network = &padapter->mlmeextpriv.mlmext_info.network;
5924         psta = rtw_get_stainfo23a(pstapriv, cur_network->MacAddress);
5925
5926         Update_RA_Entry23a(padapter, psta);
5927
5928         pBtdm8723->bRAChanged = false;
5929 }
5930
5931 static void
5932 btdm_1AntBTStateChangeHandler(struct rtw_adapter *padapter,
5933                               enum bt_state_1ant oldState,
5934                               enum bt_state_1ant newState)
5935 {
5936         struct hal_data_8723a *phaldata;
5937         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT state change, %s => %s\n",
5938                                 BtStateString[oldState],
5939                                 BtStateString[newState]));
5940
5941         /*  BT default ignore wlan active, */
5942         /*  WiFi MUST disable this when BT is enable */
5943         if (newState > BT_INFO_STATE_DISABLED)
5944                 btdm_SetFwIgnoreWlanAct(padapter, false);
5945
5946         if ((check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) &&
5947             (BTDM_IsWifiConnectionExist(padapter))) {
5948                 if ((newState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
5949                     (newState == BT_INFO_STATE_ACL_SCO_BUSY)) {
5950                         btdm_1AntUpdateHalRAMaskForSCO(padapter, false);
5951                 } else {
5952                         /*  Recover original RA setting */
5953                         btdm_1AntRecoverHalRAMask(padapter);
5954                 }
5955         } else {
5956                 phaldata = GET_HAL_DATA(padapter);
5957                 phaldata->bt_coexist.halCoex8723.btdm1Ant.bRAChanged = false;
5958         }
5959
5960         if (oldState == newState)
5961                 return;
5962
5963         if (oldState == BT_INFO_STATE_ACL_ONLY_BUSY) {
5964                 struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
5965                 Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCnt = 0;
5966                 Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
5967         }
5968
5969         if ((oldState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
5970             (oldState == BT_INFO_STATE_ACL_SCO_BUSY)) {
5971                 struct hal_data_8723a *Hal = GET_HAL_DATA(padapter);
5972                 Hal->bt_coexist.halCoex8723.btdm1Ant.psTdmaMonitorCntForSCO = 0;
5973         }
5974
5975         /*  Active 2Ant mechanism when BT Connected */
5976         if ((oldState == BT_INFO_STATE_DISABLED) ||
5977             (oldState == BT_INFO_STATE_NO_CONNECTION)) {
5978                 if ((newState != BT_INFO_STATE_DISABLED) &&
5979                     (newState != BT_INFO_STATE_NO_CONNECTION)) {
5980                         BTDM_SetSwRfRxLpfCorner(padapter,
5981                                                 BT_RF_RX_LPF_CORNER_SHRINK);
5982                         BTDM_AGCTable(padapter, BT_AGCTABLE_ON);
5983                         BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON);
5984                 }
5985         } else {
5986                 if ((newState == BT_INFO_STATE_DISABLED) ||
5987                     (newState == BT_INFO_STATE_NO_CONNECTION)) {
5988                         BTDM_SetSwRfRxLpfCorner(padapter,
5989                                                 BT_RF_RX_LPF_CORNER_RESUME);
5990                         BTDM_AGCTable(padapter, BT_AGCTABLE_OFF);
5991                         BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_OFF);
5992                 }
5993         }
5994 }
5995
5996 static void btdm_1AntBtCoexistHandler(struct rtw_adapter *padapter)
5997 {
5998         struct hal_data_8723a *pHalData;
5999         struct bt_coexist_8723a *pBtCoex8723;
6000         struct btdm_8723a_1ant *pBtdm8723;
6001
6002         pHalData = GET_HAL_DATA(padapter);
6003         pBtCoex8723 = &pHalData->bt_coexist.halCoex8723;
6004         pBtdm8723 = &pBtCoex8723->btdm1Ant;
6005         padapter->pwrctrlpriv.btcoex_rfon = false;
6006         if (!rtl8723a_BT_enabled(padapter)) {
6007                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is disabled\n"));
6008
6009                 if (BTDM_IsWifiConnectionExist(padapter)) {
6010                         RTPRINT(FBT, BT_TRACE,
6011                                 ("[BTCoex], wifi is connected\n"));
6012
6013                         if (BTDM_IsWifiBusy(padapter)) {
6014                                 RTPRINT(FBT, BT_TRACE,
6015                                         ("[BTCoex], Wifi is busy\n"));
6016                                 btdm_1AntSetPSTDMA(padapter, false, 0,
6017                                                    false, 9);
6018                         } else {
6019                                 RTPRINT(FBT, BT_TRACE,
6020                                         ("[BTCoex], Wifi is idle\n"));
6021                                 _btdm_1AntSetPSTDMA(padapter, true, 2, 1,
6022                                                     false, 9);
6023                         }
6024                 } else {
6025                         RTPRINT(FBT, BT_TRACE,
6026                                 ("[BTCoex], wifi is disconnected\n"));
6027
6028                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
6029                 }
6030         } else {
6031                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT is enabled\n"));
6032
6033                 if (BTDM_IsWifiConnectionExist(padapter)) {
6034                         RTPRINT(FBT, BT_TRACE,
6035                                 ("[BTCoex], wifi is connected\n"));
6036
6037                         btdm_1AntWifiParaAdjust(padapter, true);
6038                         btdm_1AntCoexProcessForWifiConnect(padapter);
6039                 } else {
6040                         RTPRINT(FBT, BT_TRACE,
6041                                 ("[BTCoex], wifi is disconnected\n"));
6042
6043                         /*  Antenna switch at BT side(0x870 = 0x300,
6044                             0x860 = 0x210) after PSTDMA off */
6045                         btdm_1AntWifiParaAdjust(padapter, false);
6046                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 0);
6047                 }
6048         }
6049
6050         btdm_1AntBTStateChangeHandler(padapter, pBtCoex8723->prec2hBtInfo,
6051                                       pBtCoex8723->c2hBtInfo);
6052         pBtCoex8723->prec2hBtInfo = pBtCoex8723->c2hBtInfo;
6053 }
6054
6055 void BTDM_1AntSignalCompensation(struct rtw_adapter *padapter,
6056                                  u8 *rssi_wifi, u8 *rssi_bt)
6057 {
6058         struct hal_data_8723a *pHalData;
6059         struct btdm_8723a_1ant *pBtdm8723;
6060         u8 RSSI_WiFi_Cmpnstn, RSSI_BT_Cmpnstn;
6061
6062         pHalData = GET_HAL_DATA(padapter);
6063         pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm1Ant;
6064         RSSI_WiFi_Cmpnstn = 0;
6065         RSSI_BT_Cmpnstn = 0;
6066
6067         switch (pBtdm8723->curPsTdma) {
6068         case 1: /*  WiFi 52ms */
6069                 RSSI_WiFi_Cmpnstn = 11; /*  22*0.48 */
6070                 break;
6071         case 2: /*  WiFi 36ms */
6072                 RSSI_WiFi_Cmpnstn = 14; /*  22*0.64 */
6073                 break;
6074         case 9: /*  WiFi 20ms */
6075                 RSSI_WiFi_Cmpnstn = 18; /*  22*0.80 */
6076                 break;
6077         case 11: /*  WiFi 10ms */
6078                 RSSI_WiFi_Cmpnstn = 20; /*  22*0.90 */
6079                 break;
6080         case 4: /*  WiFi 21ms */
6081                 RSSI_WiFi_Cmpnstn = 17; /*  22*0.79 */
6082                 break;
6083         case 16: /*  WiFi 24ms */
6084                 RSSI_WiFi_Cmpnstn = 18; /*  22*0.76 */
6085                 break;
6086         case 18: /*  WiFi 37ms */
6087                 RSSI_WiFi_Cmpnstn = 14; /*  22*0.64 */
6088                 break;
6089         case 23: /* Level-1, Antenna switch to BT at all time */
6090         case 24: /* Level-2, Antenna switch to BT at all time */
6091         case 25: /* Level-3a, Antenna switch to BT at all time */
6092         case 26: /* Level-3b, Antenna switch to BT at all time */
6093         case 27: /* Level-3b, Antenna switch to BT at all time */
6094         case 33: /* BT SCO & WiFi site survey */
6095                 RSSI_WiFi_Cmpnstn = 22;
6096                 break;
6097         default:
6098                 break;
6099         }
6100
6101         if (rssi_wifi && RSSI_WiFi_Cmpnstn) {
6102                 RTPRINT(FBT, BT_TRACE,
6103                         ("[BTCoex], 1AntSgnlCmpnstn, case %d, WiFiCmpnstn "
6104                          "=%d(%d => %d)\n", pBtdm8723->curPsTdma,
6105                          RSSI_WiFi_Cmpnstn, *rssi_wifi,
6106                          *rssi_wifi+RSSI_WiFi_Cmpnstn));
6107                 *rssi_wifi += RSSI_WiFi_Cmpnstn;
6108         }
6109
6110         if (rssi_bt && RSSI_BT_Cmpnstn) {
6111                 RTPRINT(FBT, BT_TRACE,
6112                         ("[BTCoex], 1AntSgnlCmpnstn, case %d, BTCmpnstn "
6113                          "=%d(%d => %d)\n", pBtdm8723->curPsTdma,
6114                          RSSI_BT_Cmpnstn, *rssi_bt, *rssi_bt+RSSI_BT_Cmpnstn));
6115                 *rssi_bt += RSSI_BT_Cmpnstn;
6116         }
6117 }
6118
6119 static void BTDM_1AntParaInit(struct rtw_adapter *padapter)
6120 {
6121         struct hal_data_8723a *pHalData;
6122         struct bt_coexist_8723a *pBtCoex;
6123         struct btdm_8723a_1ant *pBtdm8723;
6124
6125         pHalData = GET_HAL_DATA(padapter);
6126         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6127         pBtdm8723 = &pBtCoex->btdm1Ant;
6128
6129         /*  Enable counter statistics */
6130         rtl8723au_write8(padapter, 0x76e, 0x4);
6131         btdm_1AntPtaParaReload(padapter);
6132
6133         pBtdm8723->wifiRssiThresh = 48;
6134
6135         pBtdm8723->bWiFiHalt = false;
6136         pBtdm8723->bRAChanged = false;
6137
6138         if ((pBtCoex->c2hBtInfo != BT_INFO_STATE_DISABLED) &&
6139             (pBtCoex->c2hBtInfo != BT_INFO_STATE_NO_CONNECTION)) {
6140                 BTDM_SetSwRfRxLpfCorner(padapter, BT_RF_RX_LPF_CORNER_SHRINK);
6141                 BTDM_AGCTable(padapter, BT_AGCTABLE_ON);
6142                 BTDM_BBBackOffLevel(padapter, BT_BB_BACKOFF_ON);
6143         }
6144 }
6145
6146 static void BTDM_1AntForHalt(struct rtw_adapter *padapter)
6147 {
6148         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for halt\n"));
6149
6150         GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
6151                 true;
6152
6153         btdm_1AntWifiParaAdjust(padapter, false);
6154
6155         /*  don't use btdm_1AntSetPSTDMA() here */
6156         /*  it will call rtw_set_ps_mode23a() and request pwrpriv->lock. */
6157         /*  This will lead to deadlock, if this function is called in IPS */
6158         /*  Lucas@20130205 */
6159         btdm_1AntPsTdma(padapter, false, 0);
6160
6161         btdm_SetFwIgnoreWlanAct(padapter, true);
6162 }
6163
6164 static void BTDM_1AntLpsLeave(struct rtw_adapter *padapter)
6165 {
6166         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for LPS Leave\n"));
6167
6168         /*  Prevent from entering LPS again */
6169         GET_HAL_DATA(padapter)->bt_coexist.halCoex8723.btdm1Ant.bWiFiHalt =
6170                 true;
6171
6172         btdm_1AntSetPSTDMA(padapter, false, 0, false, 8);
6173 /*btdm_1AntPsTdma(padapter, false, 8); */
6174 }
6175
6176 static void BTDM_1AntWifiAssociateNotify(struct rtw_adapter *padapter, u8 type)
6177 {
6178         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6179
6180         RTPRINT(FBT, BT_TRACE,
6181                 ("\n[BTCoex], 1Ant for associate, type =%d\n", type));
6182
6183         if (type) {
6184                 rtl8723a_CheckAntenna_Selection(padapter);
6185                 if (!rtl8723a_BT_enabled(padapter))
6186                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
6187                 else {
6188                         struct bt_coexist_8723a *pBtCoex;
6189                         u8 BtState;
6190
6191                         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6192                         BtState = pBtCoex->c2hBtInfo;
6193
6194                         btdm_1AntTSFSwitch(padapter, true);
6195
6196                         if (BtState == BT_INFO_STATE_NO_CONNECTION ||
6197                             BtState == BT_INFO_STATE_CONNECT_IDLE) {
6198                                 btdm_1AntSetPSTDMA(padapter, false, 0,
6199                                                    true, 28);
6200                         } else if (BtState == BT_INFO_STATE_SCO_ONLY_BUSY ||
6201                                    BtState == BT_INFO_STATE_ACL_SCO_BUSY) {
6202                                 btdm_1AntSetPSTDMA(padapter, false, 0,
6203                                                    false, 8);
6204                                 rtl8723au_write32(padapter, 0x6c0, 0x5a5a5a5a);
6205                                 rtl8723au_write32(padapter, 0x6c4, 0x5a5a5a5a);
6206                         } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY ||
6207                                    BtState == BT_INFO_STATE_ACL_INQ_OR_PAG) {
6208                                 if (pBtCoex->c2hBtProfile == BT_INFO_HID)
6209                                         btdm_1AntSetPSTDMA(padapter, false, 0,
6210                                                            true, 35);
6211                                 else
6212                                         btdm_1AntSetPSTDMA(padapter, false, 0,
6213                                                            true, 29);
6214                         }
6215                 }
6216         } else {
6217                 if (!rtl8723a_BT_enabled(padapter)) {
6218                         if (!BTDM_IsWifiConnectionExist(padapter)) {
6219                                 btdm_1AntPsTdma(padapter, false, 0);
6220                                 btdm_1AntTSFSwitch(padapter, false);
6221                         }
6222                 }
6223
6224                 btdm_1AntBtCoexistHandler(padapter);
6225         }
6226 }
6227
6228 static void
6229 BTDM_1AntMediaStatusNotify(struct rtw_adapter *padapter,
6230                            enum rt_media_status mstatus)
6231 {
6232         struct bt_coexist_8723a *pBtCoex;
6233
6234         pBtCoex = &GET_HAL_DATA(padapter)->bt_coexist.halCoex8723;
6235
6236         RTPRINT(FBT, BT_TRACE,
6237                 ("\n\n[BTCoex]******************************\n"));
6238         RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatus, WiFi %s !!\n",
6239                         mstatus == RT_MEDIA_CONNECT?"CONNECT":"DISCONNECT"));
6240         RTPRINT(FBT, BT_TRACE, ("[BTCoex]******************************\n"));
6241
6242         if (RT_MEDIA_CONNECT == mstatus) {
6243                 if (check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) {
6244                         if (pBtCoex->c2hBtInfo == BT_INFO_STATE_SCO_ONLY_BUSY ||
6245                             pBtCoex->c2hBtInfo == BT_INFO_STATE_ACL_SCO_BUSY)
6246                                 btdm_1AntUpdateHalRAMaskForSCO(padapter, true);
6247                 }
6248
6249                 padapter->pwrctrlpriv.DelayLPSLastTimeStamp = jiffies;
6250                 BTDM_1AntForDhcp(padapter);
6251         } else {
6252                 /* DBG_8723A("%s rtl8723a_DeinitAntenna_Selection\n",
6253                    __func__); */
6254                 rtl8723a_DeinitAntenna_Selection(padapter);
6255                 btdm_1AntBtCoexistHandler(padapter);
6256                 pBtCoex->btdm1Ant.bRAChanged = false;
6257         }
6258 }
6259
6260 void BTDM_1AntForDhcp(struct rtw_adapter *padapter)
6261 {
6262         struct hal_data_8723a *pHalData;
6263         u8 BtState;
6264         struct bt_coexist_8723a *pBtCoex;
6265         struct btdm_8723a_1ant *pBtdm8723;
6266
6267         pHalData = GET_HAL_DATA(padapter);
6268         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6269         BtState = pBtCoex->c2hBtInfo;
6270         pBtdm8723 = &pBtCoex->btdm1Ant;
6271
6272         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for DHCP\n"));
6273         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, WiFi is %s\n",
6274                                 BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
6275         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for DHCP, %s\n",
6276                                 BtStateString[BtState]));
6277
6278         BTDM_1AntWifiAssociateNotify(padapter, true);
6279 }
6280
6281 static void BTDM_1AntWifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
6282 {
6283         struct hal_data_8723a *pHalData;
6284         u8 BtState;
6285         struct bt_coexist_8723a *pBtCoex;
6286         struct btdm_8723a_1ant *pBtdm8723;
6287
6288         pHalData = GET_HAL_DATA(padapter);
6289         BtState = pHalData->bt_coexist.halCoex8723.c2hBtInfo;
6290         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6291         pBtdm8723 = &pBtCoex->btdm1Ant;
6292
6293         RTPRINT(FBT, BT_TRACE, ("\n[BTCoex], 1Ant for wifi scan =%d!!\n",
6294                                 scanType));
6295         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, WiFi is %s\n",
6296                                 BTDM_IsWifiBusy(padapter)?"Busy":"IDLE"));
6297         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1Ant for wifi scan, %s\n",
6298                                 BtStateString[BtState]));
6299
6300         if (scanType) {
6301                 rtl8723a_CheckAntenna_Selection(padapter);
6302                 if (!rtl8723a_BT_enabled(padapter)) {
6303                         btdm_1AntSetPSTDMA(padapter, false, 0, false, 9);
6304                 } else if (BTDM_IsWifiConnectionExist(padapter) == false) {
6305                         BTDM_1AntWifiAssociateNotify(padapter, true);
6306                 } else {
6307                         if ((BtState == BT_INFO_STATE_SCO_ONLY_BUSY) ||
6308                             (BtState == BT_INFO_STATE_ACL_SCO_BUSY)) {
6309                                 if (pBtCoex->bC2hBtInquiryPage) {
6310                                         btdm_1AntSetPSTDMA(padapter, false, 0,
6311                                                            true, 32);
6312                                 } else {
6313                                         padapter->pwrctrlpriv.btcoex_rfon =
6314                                                 true;
6315                                         btdm_1AntSetPSTDMA(padapter, true, 0,
6316                                                            true, 33);
6317                                 }
6318                         } else if (true == pBtCoex->bC2hBtInquiryPage) {
6319                                 padapter->pwrctrlpriv.btcoex_rfon = true;
6320                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 30);
6321                         } else if (BtState == BT_INFO_STATE_ACL_ONLY_BUSY) {
6322                                 padapter->pwrctrlpriv.btcoex_rfon = true;
6323                                 if (pBtCoex->c2hBtProfile == BT_INFO_HID)
6324                                         btdm_1AntSetPSTDMA(padapter, true, 0,
6325                                                            true, 34);
6326                                 else
6327                                         btdm_1AntSetPSTDMA(padapter, true, 0,
6328                                                            true, 4);
6329                         } else {
6330                                 padapter->pwrctrlpriv.btcoex_rfon = true;
6331                                 btdm_1AntSetPSTDMA(padapter, true, 0, true, 5);
6332                         }
6333                 }
6334
6335                 btdm_NotifyFwScan(padapter, 1);
6336         } else {
6337                 /*  WiFi_Finish_Scan */
6338                 btdm_NotifyFwScan(padapter, 0);
6339                 btdm_1AntBtCoexistHandler(padapter);
6340         }
6341 }
6342
6343 static void BTDM_1AntFwC2hBtInfo8723A(struct rtw_adapter *padapter)
6344 {
6345         struct hal_data_8723a *pHalData;
6346         struct bt_30info *pBTInfo;
6347         struct bt_mgnt *pBtMgnt;
6348         struct bt_coexist_8723a *pBtCoex;
6349         u8 u1tmp, btState;
6350
6351         pHalData = GET_HAL_DATA(padapter);
6352         pBTInfo = GET_BT_INFO(padapter);
6353         pBtMgnt = &pBTInfo->BtMgnt;
6354         pBtCoex = &pHalData->bt_coexist.halCoex8723;
6355
6356         u1tmp = pBtCoex->c2hBtInfoOriginal;
6357         /*  sco BUSY bit is not used on voice over PCM platform */
6358         btState = u1tmp & 0xF;
6359         pBtCoex->c2hBtProfile = u1tmp & 0xE0;
6360
6361         /*  default set bt to idle state. */
6362         pBtMgnt->ExtConfig.bBTBusy = false;
6363         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
6364
6365         /*  check BIT2 first ==> check if bt is under inquiry or page scan */
6366         if (btState & BIT(2))
6367                 pBtCoex->bC2hBtInquiryPage = true;
6368         else
6369                 pBtCoex->bC2hBtInquiryPage = false;
6370         btState &= ~BIT(2);
6371
6372         if (!(btState & BIT(0)))
6373                 pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
6374         else {
6375                 if (btState == 0x1)
6376                         pBtCoex->c2hBtInfo = BT_INFO_STATE_CONNECT_IDLE;
6377                 else if (btState == 0x9) {
6378                         if (pBtCoex->bC2hBtInquiryPage == true)
6379                                 pBtCoex->c2hBtInfo =
6380                                         BT_INFO_STATE_ACL_INQ_OR_PAG;
6381                         else
6382                                 pBtCoex->c2hBtInfo =
6383                                         BT_INFO_STATE_ACL_ONLY_BUSY;
6384                         pBtMgnt->ExtConfig.bBTBusy = true;
6385                 } else if (btState == 0x3) {
6386                         pBtCoex->c2hBtInfo = BT_INFO_STATE_SCO_ONLY_BUSY;
6387                         pBtMgnt->ExtConfig.bBTBusy = true;
6388                 } else if (btState == 0xb) {
6389                         pBtCoex->c2hBtInfo = BT_INFO_STATE_ACL_SCO_BUSY;
6390                         pBtMgnt->ExtConfig.bBTBusy = true;
6391                 } else
6392                         pBtCoex->c2hBtInfo = BT_INFO_STATE_MAX;
6393                 if (pBtMgnt->ExtConfig.bBTBusy)
6394                         pHalData->bt_coexist.CurrentState &=
6395                                 ~BT_COEX_STATE_BT_IDLE;
6396         }
6397
6398         if (BT_INFO_STATE_NO_CONNECTION == pBtCoex->c2hBtInfo ||
6399             BT_INFO_STATE_CONNECT_IDLE == pBtCoex->c2hBtInfo) {
6400                 if (pBtCoex->bC2hBtInquiryPage)
6401                         pBtCoex->c2hBtInfo = BT_INFO_STATE_INQ_OR_PAG;
6402         }
6403
6404         RTPRINT(FBT, BT_TRACE, ("[BTC2H], %s(%d)\n",
6405                         BtStateString[pBtCoex->c2hBtInfo], pBtCoex->c2hBtInfo));
6406
6407         if (pBtCoex->c2hBtProfile != BT_INFO_HID)
6408                 pBtCoex->c2hBtProfile &= ~BT_INFO_HID;
6409 }
6410
6411 void BTDM_1AntBtCoexist8723A(struct rtw_adapter *padapter)
6412 {
6413         struct mlme_priv *pmlmepriv;
6414         struct hal_data_8723a *pHalData;
6415         unsigned long delta_time;
6416
6417         pmlmepriv = &padapter->mlmepriv;
6418         pHalData = GET_HAL_DATA(padapter);
6419
6420         if (check_fwstate(pmlmepriv, WIFI_SITE_MONITOR)) {
6421                 /*  already done in BTDM_1AntForScan() */
6422                 RTPRINT(FBT, BT_TRACE,
6423                         ("[BTCoex], wifi is under scan progress!!\n"));
6424                 return;
6425         }
6426
6427         if (check_fwstate(pmlmepriv, WIFI_UNDER_LINKING)) {
6428                 RTPRINT(FBT, BT_TRACE,
6429                         ("[BTCoex], wifi is under link progress!!\n"));
6430                 return;
6431         }
6432
6433         /*  under DHCP(Special packet) */
6434         delta_time = jiffies - padapter->pwrctrlpriv.DelayLPSLastTimeStamp;
6435         delta_time = jiffies_to_msecs(delta_time);
6436         if (delta_time < 500) {
6437                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], wifi is under DHCP "
6438                                         "progress(%li ms)!!\n", delta_time));
6439                 return;
6440         }
6441
6442         BTDM_CheckWiFiState(padapter);
6443
6444         btdm_1AntBtCoexistHandler(padapter);
6445 }
6446
6447 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87231Ant.c ===== */
6448
6449 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */
6450
6451 /*  local function start with btdm_ */
6452 static u8 btdm_ActionAlgorithm(struct rtw_adapter *padapter)
6453 {
6454         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
6455         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
6456         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6457         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6458         u8 bScoExist = false, bBtLinkExist = false, bBtHsModeExist = false;
6459         u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED;
6460
6461         if (pBtMgnt->ExtConfig.NumberOfHandle)
6462                 bBtLinkExist = true;
6463         if (pBtMgnt->ExtConfig.NumberOfSCO)
6464                 bScoExist = true;
6465         if (BT_HsConnectionEstablished(padapter))
6466                 bBtHsModeExist = true;
6467
6468         /*  here we get BT status first */
6469         /*  1) initialize */
6470         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
6471
6472         if ((bScoExist) || (bBtHsModeExist) ||
6473             (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID))) {
6474                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO or HID or HS exists, set BT non-idle !!!\n"));
6475                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6476         } else {
6477                 /*  A2dp profile */
6478                 if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) &&
6479                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP))) {
6480                         if (BTDM_BtTxRxCounterL(padapter) < 100) {
6481                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx < 100, set BT connected-idle!!!\n"));
6482                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6483                         } else {
6484                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP, low priority tx+rx >= 100, set BT non-idle!!!\n"));
6485                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6486                         }
6487                 }
6488                 /*  Pan profile */
6489                 if ((pBtMgnt->ExtConfig.NumberOfHandle == 1) &&
6490                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) {
6491                         if (BTDM_BtTxRxCounterL(padapter) < 600) {
6492                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority tx+rx < 600, set BT connected-idle!!!\n"));
6493                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6494                         } else {
6495                                 if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) {
6496                                         if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx /
6497                                             pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) {
6498                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, low priority rx/tx > 9, set BT connected-idle!!!\n"));
6499                                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6500                                         }
6501                                 }
6502                         }
6503                         if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) {
6504                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN, set BT non-idle!!!\n"));
6505                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6506                         }
6507                 }
6508                 /*  Pan+A2dp profile */
6509                 if ((pBtMgnt->ExtConfig.NumberOfHandle == 2) &&
6510                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) &&
6511                     (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN))) {
6512                         if (BTDM_BtTxRxCounterL(padapter) < 600) {
6513                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority tx+rx < 600, set BT connected-idle!!!\n"));
6514                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6515                         } else {
6516                                 if (pHalData->bt_coexist.halCoex8723.lowPriorityTx) {
6517                                         if ((pHalData->bt_coexist.halCoex8723.lowPriorityRx /
6518                                             pHalData->bt_coexist.halCoex8723.lowPriorityTx) > 9) {
6519                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, low priority rx/tx > 9, set BT connected-idle!!!\n"));
6520                                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
6521                                         }
6522                                 }
6523                         }
6524                         if (BT_2ANT_BT_STATUS_CONNECTED_IDLE != pBtdm8723->btStatus) {
6525                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN+A2DP, set BT non-idle!!!\n"));
6526                                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
6527                         }
6528                 }
6529         }
6530         if (BT_2ANT_BT_STATUS_IDLE != pBtdm8723->btStatus)
6531                 pBtMgnt->ExtConfig.bBTBusy = true;
6532         else
6533                 pBtMgnt->ExtConfig.bBTBusy = false;
6534
6535         if (!bBtLinkExist) {
6536                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], No profile exists!!!\n"));
6537                 return algorithm;
6538         }
6539
6540         if (pBtMgnt->ExtConfig.NumberOfHandle == 1) {
6541                 if (bScoExist) {
6542                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n"));
6543                         algorithm = BT_2ANT_COEX_ALGO_SCO;
6544                 } else {
6545                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) {
6546                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID only\n"));
6547                                 algorithm = BT_2ANT_COEX_ALGO_HID;
6548                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6549                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP only\n"));
6550                                 algorithm = BT_2ANT_COEX_ALGO_A2DP;
6551                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6552                                 if (bBtHsModeExist) {
6553                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(HS) only\n"));
6554                                         algorithm = BT_2ANT_COEX_ALGO_PANHS;
6555                                 } else {
6556                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR) only\n"));
6557                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR;
6558                                 }
6559                         } else {
6560                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d \n",
6561                                 pBtMgnt->ExtConfig.NumberOfHandle));
6562                         }
6563                 }
6564         } else if (pBtMgnt->ExtConfig.NumberOfHandle == 2) {
6565                 if (bScoExist) {
6566                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) {
6567                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n"));
6568                                 algorithm = BT_2ANT_COEX_ALGO_HID;
6569                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6570                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n"));
6571                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6572                                 if (bBtHsModeExist) {
6573                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
6574                                         algorithm = BT_2ANT_COEX_ALGO_SCO;
6575                                 } else {
6576                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
6577                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
6578                                 }
6579                         } else {
6580                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched ACL profile for NumberOfHandle =%d\n",
6581                                 pBtMgnt->ExtConfig.NumberOfHandle));
6582                         }
6583                 } else {
6584                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6585                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6586                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
6587                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
6588                 } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6589                            BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6590                                 if (bBtHsModeExist) {
6591                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
6592                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
6593                                 } else {
6594                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
6595                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
6596                                 }
6597                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6598                                    BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6599                                 if (bBtHsModeExist) {
6600                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
6601                                         algorithm = BT_2ANT_COEX_ALGO_A2DP;
6602                                 } else {
6603                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
6604                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
6605                                 }
6606                         } else {
6607                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
6608                                         pBtMgnt->ExtConfig.NumberOfHandle));
6609                         }
6610                 }
6611         } else if (pBtMgnt->ExtConfig.NumberOfHandle == 3) {
6612                 if (bScoExist) {
6613                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6614                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6615                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP\n"));
6616                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6617                                    BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
6618                                 if (bBtHsModeExist) {
6619                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n"));
6620                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
6621                                 } else {
6622                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n"));
6623                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
6624                                 }
6625                         } else if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6626                                    BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6627                                 if (bBtHsModeExist) {
6628                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(HS)\n"));
6629                                         algorithm = BT_2ANT_COEX_ALGO_SCO;
6630                                 } else {
6631                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP + PAN(EDR)\n"));
6632                                 }
6633                         } else {
6634                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n",
6635                                         pBtMgnt->ExtConfig.NumberOfHandle));
6636                         }
6637                 } else {
6638                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6639                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6640                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6641                                 if (bBtHsModeExist) {
6642                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
6643                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANHS;
6644                                 } else {
6645                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
6646                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
6647                                 }
6648                         } else {
6649                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
6650                                         pBtMgnt->ExtConfig.NumberOfHandle));
6651                         }
6652                 }
6653         } else if (pBtMgnt->ExtConfig.NumberOfHandle >= 3) {
6654                 if (bScoExist) {
6655                         if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
6656                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
6657                             BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
6658                                 if (bBtHsModeExist)
6659                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"));
6660                                 else
6661                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(EDR)\n"));
6662                         } else {
6663                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO exists but why NO matched profile for NumberOfHandle =%d\n",
6664                                         pBtMgnt->ExtConfig.NumberOfHandle));
6665                         }
6666                 } else {
6667                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! NO matched profile for NumberOfHandle =%d\n",
6668                                 pBtMgnt->ExtConfig.NumberOfHandle));
6669                 }
6670         }
6671         return algorithm;
6672 }
6673
6674 static u8 btdm_NeedToDecBtPwr(struct rtw_adapter *padapter)
6675 {
6676         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6677         u8 bRet = false;
6678
6679         if (BT_Operation(padapter)) {
6680                 if (pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB > 47) {
6681                         RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for HS mode!!\n"));
6682                         bRet = true;
6683                 } else {
6684                         RTPRINT(FBT, BT_TRACE, ("NO Need to decrease bt power for HS mode!!\n"));
6685                 }
6686         } else {
6687                 if (BTDM_IsWifiConnectionExist(padapter)) {
6688                         RTPRINT(FBT, BT_TRACE, ("Need to decrease bt power for Wifi is connected!!\n"));
6689                         bRet = true;
6690                 }
6691         }
6692         return bRet;
6693 }
6694
6695 static void
6696 btdm_SetCoexTable(struct rtw_adapter *padapter, u32 val0x6c0,
6697                   u32 val0x6c8, u8 val0x6cc)
6698 {
6699         RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c0 = 0x%x\n", val0x6c0));
6700         rtl8723au_write32(padapter, 0x6c0, val0x6c0);
6701
6702         RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6c8 = 0x%x\n", val0x6c8));
6703         rtl8723au_write32(padapter, 0x6c8, val0x6c8);
6704
6705         RTPRINT(FBT, BT_TRACE, ("set coex table, set 0x6cc = 0x%x\n", val0x6cc));
6706         rtl8723au_write8(padapter, 0x6cc, val0x6cc);
6707 }
6708
6709 static void
6710 btdm_SetSwFullTimeDacSwing(struct rtw_adapter *padapter, u8 bSwDacSwingOn,
6711                            u32 swDacSwingLvl)
6712 {
6713         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6714
6715         if (bSwDacSwingOn) {
6716                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing = 0x%x\n", swDacSwingLvl));
6717                 PHY_SetBBReg(padapter, 0x880, 0xff000000, swDacSwingLvl);
6718                 pHalData->bt_coexist.bSWCoexistAllOff = false;
6719         } else {
6720                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SwDacSwing Off!\n"));
6721                 PHY_SetBBReg(padapter, 0x880, 0xff000000, 0xc0);
6722         }
6723 }
6724
6725 static void
6726 btdm_SetFwDacSwingLevel(struct rtw_adapter *padapter, u8 dacSwingLvl)
6727 {
6728         u8 H2C_Parameter[1] = {0};
6729
6730         H2C_Parameter[0] = dacSwingLvl;
6731
6732         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Set Dac Swing Level = 0x%x\n", dacSwingLvl));
6733         RTPRINT(FBT, BT_TRACE, ("[BTCoex], write 0x29 = 0x%x\n", H2C_Parameter[0]));
6734
6735         FillH2CCmd(padapter, 0x29, 1, H2C_Parameter);
6736 }
6737
6738 static void btdm_2AntDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr)
6739 {
6740         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6741         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6742
6743         RTPRINT(FBT, BT_TRACE,
6744                 ("[BTCoex], Dec BT power = %s\n",
6745                 ((bDecBtPwr) ? "ON" : "OFF")));
6746         pBtdm8723->bCurDecBtPwr = bDecBtPwr;
6747
6748         if (pBtdm8723->bPreDecBtPwr == pBtdm8723->bCurDecBtPwr)
6749                 return;
6750
6751         BTDM_SetFwDecBtPwr(padapter, pBtdm8723->bCurDecBtPwr);
6752
6753         pBtdm8723->bPreDecBtPwr = pBtdm8723->bCurDecBtPwr;
6754 }
6755
6756 static void
6757 btdm_2AntFwDacSwingLvl(struct rtw_adapter *padapter, u8 fwDacSwingLvl)
6758 {
6759         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6760         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6761
6762         RTPRINT(FBT, BT_TRACE, ("[BTCoex], set FW Dac Swing level = %d\n",  fwDacSwingLvl));
6763         pBtdm8723->curFwDacSwingLvl = fwDacSwingLvl;
6764
6765         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preFwDacSwingLvl =%d, curFwDacSwingLvl =%d\n", */
6766         /*pBtdm8723->preFwDacSwingLvl, pBtdm8723->curFwDacSwingLvl)); */
6767
6768         if (pBtdm8723->preFwDacSwingLvl == pBtdm8723->curFwDacSwingLvl)
6769                 return;
6770
6771         btdm_SetFwDacSwingLevel(padapter, pBtdm8723->curFwDacSwingLvl);
6772
6773         pBtdm8723->preFwDacSwingLvl = pBtdm8723->curFwDacSwingLvl;
6774 }
6775
6776 static void
6777 btdm_2AntRfShrink(struct rtw_adapter *padapter, u8 bRxRfShrinkOn)
6778 {
6779         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6780         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6781
6782         RTPRINT(FBT, BT_TRACE,
6783                 ("[BTCoex], turn Rx RF Shrink = %s\n",
6784                 ((bRxRfShrinkOn) ? "ON" : "OFF")));
6785         pBtdm8723->bCurRfRxLpfShrink = bRxRfShrinkOn;
6786
6787         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreRfRxLpfShrink =%d, bCurRfRxLpfShrink =%d\n", */
6788         /*pBtdm8723->bPreRfRxLpfShrink, pBtdm8723->bCurRfRxLpfShrink)); */
6789
6790         if (pBtdm8723->bPreRfRxLpfShrink == pBtdm8723->bCurRfRxLpfShrink)
6791                 return;
6792
6793         BTDM_SetSwRfRxLpfCorner(padapter, (u8)pBtdm8723->bCurRfRxLpfShrink);
6794
6795         pBtdm8723->bPreRfRxLpfShrink = pBtdm8723->bCurRfRxLpfShrink;
6796 }
6797
6798 static void
6799 btdm_2AntLowPenaltyRa(struct rtw_adapter *padapter, u8 bLowPenaltyRa)
6800 {
6801         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6802         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6803
6804         RTPRINT(FBT, BT_TRACE,
6805                 ("[BTCoex], turn LowPenaltyRA = %s\n",
6806                 ((bLowPenaltyRa) ? "ON" : "OFF")));
6807         pBtdm8723->bCurLowPenaltyRa = bLowPenaltyRa;
6808
6809         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreLowPenaltyRa =%d, bCurLowPenaltyRa =%d\n", */
6810         /*pBtdm8723->bPreLowPenaltyRa, pBtdm8723->bCurLowPenaltyRa)); */
6811
6812         if (pBtdm8723->bPreLowPenaltyRa == pBtdm8723->bCurLowPenaltyRa)
6813                 return;
6814
6815         BTDM_SetSwPenaltyTxRateAdaptive(padapter, (u8)pBtdm8723->bCurLowPenaltyRa);
6816
6817         pBtdm8723->bPreLowPenaltyRa = pBtdm8723->bCurLowPenaltyRa;
6818 }
6819
6820 static void
6821 btdm_2AntDacSwing(struct rtw_adapter *padapter,
6822                   u8 bDacSwingOn, u32 dacSwingLvl)
6823 {
6824         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6825         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6826
6827         RTPRINT(FBT, BT_TRACE,
6828                 ("[BTCoex], turn DacSwing =%s, dacSwingLvl = 0x%x\n",
6829                 (bDacSwingOn ? "ON" : "OFF"), dacSwingLvl));
6830         pBtdm8723->bCurDacSwingOn = bDacSwingOn;
6831         pBtdm8723->curDacSwingLvl = dacSwingLvl;
6832
6833         if ((pBtdm8723->bPreDacSwingOn == pBtdm8723->bCurDacSwingOn) &&
6834             (pBtdm8723->preDacSwingLvl == pBtdm8723->curDacSwingLvl))
6835                 return;
6836
6837         mdelay(30);
6838         btdm_SetSwFullTimeDacSwing(padapter, bDacSwingOn, dacSwingLvl);
6839
6840         pBtdm8723->bPreDacSwingOn = pBtdm8723->bCurDacSwingOn;
6841         pBtdm8723->preDacSwingLvl = pBtdm8723->curDacSwingLvl;
6842 }
6843
6844 static void btdm_2AntAdcBackOff(struct rtw_adapter *padapter, u8 bAdcBackOff)
6845 {
6846         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6847         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6848
6849         RTPRINT(FBT, BT_TRACE,
6850                 ("[BTCoex], turn AdcBackOff = %s\n",
6851                 ((bAdcBackOff) ? "ON" : "OFF")));
6852         pBtdm8723->bCurAdcBackOff = bAdcBackOff;
6853
6854         if (pBtdm8723->bPreAdcBackOff == pBtdm8723->bCurAdcBackOff)
6855                 return;
6856
6857         BTDM_BBBackOffLevel(padapter, (u8)pBtdm8723->bCurAdcBackOff);
6858
6859         pBtdm8723->bPreAdcBackOff = pBtdm8723->bCurAdcBackOff;
6860 }
6861
6862 static void btdm_2AntAgcTable(struct rtw_adapter *padapter, u8 bAgcTableEn)
6863 {
6864         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6865         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6866
6867         RTPRINT(FBT, BT_TRACE,
6868                 ("[BTCoex], %s Agc Table\n", ((bAgcTableEn) ? "Enable" : "Disable")));
6869         pBtdm8723->bCurAgcTableEn = bAgcTableEn;
6870
6871         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], bPreAgcTableEn =%d, bCurAgcTableEn =%d\n", */
6872         /*pBtdm8723->bPreAgcTableEn, pBtdm8723->bCurAgcTableEn)); */
6873
6874         if (pBtdm8723->bPreAgcTableEn == pBtdm8723->bCurAgcTableEn)
6875                 return;
6876
6877         BTDM_AGCTable(padapter, (u8)bAgcTableEn);
6878
6879         pBtdm8723->bPreAgcTableEn = pBtdm8723->bCurAgcTableEn;
6880 }
6881
6882 static void
6883 btdm_2AntCoexTable(struct rtw_adapter *padapter,
6884                    u32 val0x6c0, u32 val0x6c8, u8 val0x6cc)
6885 {
6886         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6887         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6888
6889         RTPRINT(FBT, BT_TRACE, ("[BTCoex], write Coex Table 0x6c0 = 0x%x, 0x6c8 = 0x%x, 0x6cc = 0x%x\n",
6890                 val0x6c0, val0x6c8, val0x6cc));
6891         pBtdm8723->curVal0x6c0 = val0x6c0;
6892         pBtdm8723->curVal0x6c8 = val0x6c8;
6893         pBtdm8723->curVal0x6cc = val0x6cc;
6894
6895         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], preVal0x6c0 = 0x%x, preVal0x6c8 = 0x%x, preVal0x6cc = 0x%x !!\n", */
6896         /*pBtdm8723->preVal0x6c0, pBtdm8723->preVal0x6c8, pBtdm8723->preVal0x6cc)); */
6897         /* RTPRINT(FBT, BT_TRACE, ("[BTCoex], curVal0x6c0 = 0x%x, curVal0x6c8 = 0x%x, curVal0x6cc = 0x%x !!\n", */
6898         /*pBtdm8723->curVal0x6c0, pBtdm8723->curVal0x6c8, pBtdm8723->curVal0x6cc)); */
6899
6900         if ((pBtdm8723->preVal0x6c0 == pBtdm8723->curVal0x6c0) &&
6901             (pBtdm8723->preVal0x6c8 == pBtdm8723->curVal0x6c8) &&
6902             (pBtdm8723->preVal0x6cc == pBtdm8723->curVal0x6cc))
6903                 return;
6904
6905         btdm_SetCoexTable(padapter, val0x6c0, val0x6c8, val0x6cc);
6906
6907         pBtdm8723->preVal0x6c0 = pBtdm8723->curVal0x6c0;
6908         pBtdm8723->preVal0x6c8 = pBtdm8723->curVal0x6c8;
6909         pBtdm8723->preVal0x6cc = pBtdm8723->curVal0x6cc;
6910 }
6911
6912 static void btdm_2AntIgnoreWlanAct(struct rtw_adapter *padapter, u8 bEnable)
6913 {
6914         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6915         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6916
6917         RTPRINT(FBT, BT_TRACE,
6918                 ("[BTCoex], turn Ignore WlanAct %s\n", (bEnable ? "ON" : "OFF")));
6919         pBtdm8723->bCurIgnoreWlanAct = bEnable;
6920
6921
6922         if (pBtdm8723->bPreIgnoreWlanAct == pBtdm8723->bCurIgnoreWlanAct)
6923                 return;
6924
6925         btdm_SetFwIgnoreWlanAct(padapter, bEnable);
6926         pBtdm8723->bPreIgnoreWlanAct = pBtdm8723->bCurIgnoreWlanAct;
6927 }
6928
6929 static void
6930 btdm_2AntSetFw3a(struct rtw_adapter *padapter, u8 byte1, u8 byte2,
6931                  u8 byte3, u8 byte4, u8 byte5)
6932 {
6933         u8 H2C_Parameter[5] = {0};
6934
6935         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6936
6937         /*  byte1[1:0] != 0 means enable pstdma */
6938         /*  for 2Ant bt coexist, if byte1 != 0 means enable pstdma */
6939         if (byte1)
6940                 pHalData->bt_coexist.bFWCoexistAllOff = false;
6941         H2C_Parameter[0] = byte1;
6942         H2C_Parameter[1] = byte2;
6943         H2C_Parameter[2] = byte3;
6944         H2C_Parameter[3] = byte4;
6945         H2C_Parameter[4] = byte5;
6946
6947         pHalData->bt_coexist.fw3aVal[0] = byte1;
6948         pHalData->bt_coexist.fw3aVal[1] = byte2;
6949         pHalData->bt_coexist.fw3aVal[2] = byte3;
6950         pHalData->bt_coexist.fw3aVal[3] = byte4;
6951         pHalData->bt_coexist.fw3aVal[4] = byte5;
6952
6953         RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%x%08x\n",
6954                 H2C_Parameter[0],
6955                 H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
6956
6957         FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter);
6958         }
6959
6960 static void btdm_2AntPsTdma(struct rtw_adapter *padapter, u8 bTurnOn, u8 type)
6961 {
6962         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
6963         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
6964         u32                     btTxRxCnt = 0;
6965         u8 bTurnOnByCnt = false;
6966         u8 psTdmaTypeByCnt = 0;
6967
6968         btTxRxCnt = BTDM_BtTxRxCounterH(padapter)+BTDM_BtTxRxCounterL(padapter);
6969         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT TxRx Counters = %d\n", btTxRxCnt));
6970         if (btTxRxCnt > 3000) {
6971                 bTurnOnByCnt = true;
6972                 psTdmaTypeByCnt = 8;
6973
6974                 RTPRINT(FBT, BT_TRACE,
6975                         ("[BTCoex], For BTTxRxCounters, turn %s PS TDMA, type =%d\n",
6976                         (bTurnOnByCnt ? "ON" : "OFF"), psTdmaTypeByCnt));
6977                 pBtdm8723->bCurPsTdmaOn = bTurnOnByCnt;
6978                 pBtdm8723->curPsTdma = psTdmaTypeByCnt;
6979         } else {
6980                 RTPRINT(FBT, BT_TRACE,
6981                         ("[BTCoex], turn %s PS TDMA, type =%d\n",
6982                         (bTurnOn ? "ON" : "OFF"), type));
6983                 pBtdm8723->bCurPsTdmaOn = bTurnOn;
6984                 pBtdm8723->curPsTdma = type;
6985         }
6986
6987         if ((pBtdm8723->bPrePsTdmaOn == pBtdm8723->bCurPsTdmaOn) &&
6988             (pBtdm8723->prePsTdma == pBtdm8723->curPsTdma))
6989                 return;
6990
6991         if (bTurnOn) {
6992                 switch (type) {
6993                 case 1:
6994                 default:
6995                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98);
6996                         break;
6997                 case 2:
6998                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98);
6999                         break;
7000                 case 3:
7001                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98);
7002                         break;
7003                 case 4:
7004                         btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0xa1, 0x80);
7005                         break;
7006                 case 5:
7007                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98);
7008                         break;
7009                 case 6:
7010                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98);
7011                         break;
7012                 case 7:
7013                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98);
7014                         break;
7015                 case 8:
7016                         btdm_2AntSetFw3a(padapter, 0xa3, 0x5, 0x5, 0x20, 0x80);
7017                         break;
7018                 case 9:
7019                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0xa1, 0x98);
7020                         break;
7021                 case 10:
7022                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0xa1, 0x98);
7023                         break;
7024                 case 11:
7025                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0xa1, 0x98);
7026                         break;
7027                 case 12:
7028                         btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98);
7029                         break;
7030                 case 13:
7031                         btdm_2AntSetFw3a(padapter, 0xe3, 0x1a, 0x1a, 0x20, 0x98);
7032                         break;
7033                 case 14:
7034                         btdm_2AntSetFw3a(padapter, 0xe3, 0x12, 0x12, 0x20, 0x98);
7035                         break;
7036                 case 15:
7037                         btdm_2AntSetFw3a(padapter, 0xe3, 0xa, 0xa, 0x20, 0x98);
7038                         break;
7039                 case 16:
7040                         btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0x20, 0x98);
7041                         break;
7042                 case 17:
7043                         btdm_2AntSetFw3a(padapter, 0xa3, 0x2f, 0x2f, 0x20, 0x80);
7044                         break;
7045                 case 18:
7046                         btdm_2AntSetFw3a(padapter, 0xe3, 0x5, 0x5, 0xa1, 0x98);
7047                         break;
7048                 case 19:
7049                         btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0xa1, 0x98);
7050                         break;
7051                 case 20:
7052                         btdm_2AntSetFw3a(padapter, 0xe3, 0x25, 0x25, 0x20, 0x98);
7053                         break;
7054                 }
7055         } else {
7056                 /*  disable PS tdma */
7057                 switch (type) {
7058                 case 0:
7059                         btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
7060                         break;
7061                 case 1:
7062                         btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x0, 0x0);
7063                         break;
7064                 default:
7065                         btdm_2AntSetFw3a(padapter, 0x0, 0x0, 0x0, 0x8, 0x0);
7066                         break;
7067                 }
7068         }
7069
7070         /*  update pre state */
7071         pBtdm8723->bPrePsTdmaOn =  pBtdm8723->bCurPsTdmaOn;
7072         pBtdm8723->prePsTdma = pBtdm8723->curPsTdma;
7073 }
7074
7075 static void btdm_2AntBtInquiryPage(struct rtw_adapter *padapter)
7076 {
7077         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7078         btdm_2AntIgnoreWlanAct(padapter, false);
7079         btdm_2AntPsTdma(padapter, true, 8);
7080 }
7081
7082 static u8 btdm_HoldForBtInqPage(struct rtw_adapter *padapter)
7083 {
7084         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7085         u32 curTime = jiffies;
7086
7087         if (pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) {
7088                 /*  bt inquiry or page is started. */
7089                 if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime == 0) {
7090                         pHalData->bt_coexist.halCoex8723.btInqPageStartTime = curTime;
7091                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page is started at time : 0x%lx \n",
7092                         pHalData->bt_coexist.halCoex8723.btInqPageStartTime));
7093                 }
7094         }
7095         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page started time : 0x%lx, curTime : 0x%x \n",
7096                 pHalData->bt_coexist.halCoex8723.btInqPageStartTime, curTime));
7097
7098         if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) {
7099                 if (((curTime - pHalData->bt_coexist.halCoex8723.btInqPageStartTime)/1000000) >= 10) {
7100                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], BT Inquiry/page >= 10sec!!!"));
7101                         pHalData->bt_coexist.halCoex8723.btInqPageStartTime = 0;
7102                 }
7103         }
7104
7105         if (pHalData->bt_coexist.halCoex8723.btInqPageStartTime) {
7106                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7107                 btdm_2AntIgnoreWlanAct(padapter, false);
7108                 btdm_2AntPsTdma(padapter, true, 8);
7109                 return true;
7110         } else {
7111                 return false;
7112         }
7113 }
7114
7115 static u8 btdm_Is2Ant8723ACommonAction(struct rtw_adapter *padapter)
7116 {
7117         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7118         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
7119         u8 bCommon = false;
7120
7121         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));
7122
7123         if ((!BTDM_IsWifiConnectionExist(padapter)) &&
7124             (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
7125             (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) {
7126                 RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt idle!!\n"));
7127
7128                 btdm_2AntLowPenaltyRa(padapter, false);
7129                 btdm_2AntRfShrink(padapter, false);
7130                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7131
7132                 btdm_2AntIgnoreWlanAct(padapter, false);
7133                 btdm_2AntPsTdma(padapter, false, 0);
7134                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7135                 btdm_2AntDecBtPwr(padapter, false);
7136
7137                 btdm_2AntAgcTable(padapter, false);
7138                 btdm_2AntAdcBackOff(padapter, false);
7139                 btdm_2AntDacSwing(padapter, false, 0xc0);
7140
7141                 bCommon = true;
7142         } else if (((BTDM_IsWifiConnectionExist(padapter)) ||
7143                    (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) &&
7144                    (BT_2ANT_BT_STATUS_IDLE == pBtdm8723->btStatus)) {
7145                 RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT idle!!\n"));
7146
7147                 btdm_2AntLowPenaltyRa(padapter, true);
7148                 btdm_2AntRfShrink(padapter, false);
7149                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7150
7151                 btdm_2AntIgnoreWlanAct(padapter, false);
7152                 btdm_2AntPsTdma(padapter, false, 0);
7153                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7154                 btdm_2AntDecBtPwr(padapter, true);
7155
7156                 btdm_2AntAgcTable(padapter, false);
7157                 btdm_2AntAdcBackOff(padapter, false);
7158                 btdm_2AntDacSwing(padapter, false, 0xc0);
7159
7160                 bCommon = true;
7161         } else if ((!BTDM_IsWifiConnectionExist(padapter)) &&
7162                    (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
7163                    (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) {
7164                 RTPRINT(FBT, BT_TRACE, ("Wifi idle + Bt connected idle!!\n"));
7165
7166                 btdm_2AntLowPenaltyRa(padapter, true);
7167                 btdm_2AntRfShrink(padapter, true);
7168                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7169
7170                 btdm_2AntIgnoreWlanAct(padapter, false);
7171                 btdm_2AntPsTdma(padapter, false, 0);
7172                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7173                 btdm_2AntDecBtPwr(padapter, false);
7174
7175                 btdm_2AntAgcTable(padapter, false);
7176                 btdm_2AntAdcBackOff(padapter, false);
7177                 btdm_2AntDacSwing(padapter, false, 0xc0);
7178
7179                 bCommon = true;
7180         } else if (((BTDM_IsWifiConnectionExist(padapter)) ||
7181                    (check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING)))) &&
7182                    (BT_2ANT_BT_STATUS_CONNECTED_IDLE == pBtdm8723->btStatus)) {
7183                 RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + Bt connected idle!!\n"));
7184
7185                 btdm_2AntLowPenaltyRa(padapter, true);
7186                 btdm_2AntRfShrink(padapter, true);
7187                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7188
7189                 btdm_2AntIgnoreWlanAct(padapter, false);
7190                 btdm_2AntPsTdma(padapter, false, 0);
7191                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7192                 btdm_2AntDecBtPwr(padapter, true);
7193
7194                 btdm_2AntAgcTable(padapter, false);
7195                 btdm_2AntAdcBackOff(padapter, false);
7196                 btdm_2AntDacSwing(padapter, false, 0xc0);
7197
7198                 bCommon = true;
7199         } else if ((!BTDM_IsWifiConnectionExist(padapter)) &&
7200                    (!check_fwstate(&padapter->mlmepriv, (_FW_UNDER_SURVEY|_FW_UNDER_LINKING))) &&
7201                    (BT_2ANT_BT_STATUS_NON_IDLE == pBtdm8723->btStatus)) {
7202                 RTPRINT(FBT, BT_TRACE, ("Wifi idle + BT non-idle!!\n"));
7203
7204                 btdm_2AntLowPenaltyRa(padapter, true);
7205                 btdm_2AntRfShrink(padapter, true);
7206                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7207
7208                 btdm_2AntIgnoreWlanAct(padapter, false);
7209                 btdm_2AntPsTdma(padapter, false, 0);
7210                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7211                 btdm_2AntDecBtPwr(padapter, false);
7212
7213                 btdm_2AntAgcTable(padapter, false);
7214                 btdm_2AntAdcBackOff(padapter, false);
7215                 btdm_2AntDacSwing(padapter, false, 0xc0);
7216
7217                 bCommon = true;
7218         } else {
7219                 RTPRINT(FBT, BT_TRACE, ("Wifi non-idle + BT non-idle!!\n"));
7220                 btdm_2AntLowPenaltyRa(padapter, true);
7221                 btdm_2AntRfShrink(padapter, true);
7222                 btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
7223                 btdm_2AntIgnoreWlanAct(padapter, false);
7224                 btdm_2AntFwDacSwingLvl(padapter, 0x20);
7225
7226                 bCommon = false;
7227         }
7228         return bCommon;
7229 }
7230
7231 static void
7232 btdm_2AntTdmaDurationAdjust(struct rtw_adapter *padapter, u8 bScoHid,
7233                             u8 bTxPause, u8 maxInterval)
7234 {
7235         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7236         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
7237         static s32              up, dn, m, n, WaitCount;
7238         s32                     result;   /* 0: no change, +1: increase WiFi duration, -1: decrease WiFi duration */
7239         u8 retryCount = 0;
7240
7241         RTPRINT(FBT, BT_TRACE, ("[BTCoex], TdmaDurationAdjust()\n"));
7242
7243         if (pBtdm8723->bResetTdmaAdjust) {
7244                 pBtdm8723->bResetTdmaAdjust = false;
7245                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
7246                 if (bScoHid) {
7247                         if (bTxPause) {
7248                                 btdm_2AntPsTdma(padapter, true, 15);
7249                                 pBtdm8723->psTdmaDuAdjType = 15;
7250                         } else {
7251                                 btdm_2AntPsTdma(padapter, true, 11);
7252                                 pBtdm8723->psTdmaDuAdjType = 11;
7253                         }
7254                 } else {
7255                         if (bTxPause) {
7256                                 btdm_2AntPsTdma(padapter, true, 7);
7257                                 pBtdm8723->psTdmaDuAdjType = 7;
7258                         } else {
7259                                 btdm_2AntPsTdma(padapter, true, 3);
7260                                 pBtdm8723->psTdmaDuAdjType = 3;
7261                         }
7262                 }
7263                 up = 0;
7264                 dn = 0;
7265                 m = 1;
7266                 n = 3;
7267                 result = 0;
7268                 WaitCount = 0;
7269         } else {
7270                 /* accquire the BT TRx retry count from BT_Info byte2 */
7271                 retryCount = pHalData->bt_coexist.halCoex8723.btRetryCnt;
7272                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], retryCount = %d\n", retryCount));
7273                 result = 0;
7274                 WaitCount++;
7275
7276                 if (retryCount == 0) {  /*  no retry in the last 2-second duration */
7277                         up++;
7278                         dn--;
7279
7280                         if (dn <= 0)
7281                                 dn = 0;
7282
7283                         if (up >= n) {  /*  if ³sÄò n ­Ó2¬í retry count¬°0, «h½Õ¼eWiFi duration */
7284                                 WaitCount = 0;
7285                                 n = 3;
7286                                 up = 0;
7287                                 dn = 0;
7288                                 result = 1;
7289                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Increase wifi duration!!\n"));
7290                         }
7291                 } else if (retryCount <= 3) {   /*  <= 3 retry in the last 2-second duration */
7292                         up--;
7293                         dn++;
7294
7295                         if (up <= 0)
7296                                 up = 0;
7297
7298                         if (dn == 2) {  /*  if ³sÄò 2 ­Ó2¬í retry count< 3, «h½Õ¯¶WiFi duration */
7299                                 if (WaitCount <= 2)
7300                                         m++; /*  ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ */
7301                                 else
7302                                         m = 1;
7303
7304                                 if (m >= 20) /* m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */
7305                                         m = 20;
7306
7307                                 n = 3*m;
7308                                 up = 0;
7309                                 dn = 0;
7310                                 WaitCount = 0;
7311                                 result = -1;
7312                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
7313                         }
7314                 } else {  /* retry count > 3, ¥u­n1¦¸ retry count > 3, «h½Õ¯¶WiFi duration */
7315                         if (WaitCount == 1)
7316                                 m++; /*  ÁקK¤@ª½¦b¨â­Ólevel¤¤¨Ó¦^ */
7317                         else
7318                                 m = 1;
7319
7320                         if (m >= 20) /* m ³Ì¤j­È = 20 ' ³Ì¤j120¬í recheck¬O§_½Õ¾ã WiFi duration. */
7321                                 m = 20;
7322                         n = 3*m;
7323                         up = 0;
7324                         dn = 0;
7325                         WaitCount = 0;
7326                         result = -1;
7327                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n"));
7328                 }
7329
7330                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], max Interval = %d\n", maxInterval));
7331                 if (maxInterval == 1) {
7332                         if (bTxPause) {
7333                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
7334                                 if (pBtdm8723->curPsTdma == 1) {
7335                                         btdm_2AntPsTdma(padapter, true, 5);
7336                                         pBtdm8723->psTdmaDuAdjType = 5;
7337                                 } else if (pBtdm8723->curPsTdma == 2) {
7338                                         btdm_2AntPsTdma(padapter, true, 6);
7339                                         pBtdm8723->psTdmaDuAdjType = 6;
7340                                 } else if (pBtdm8723->curPsTdma == 3) {
7341                                         btdm_2AntPsTdma(padapter, true, 7);
7342                                         pBtdm8723->psTdmaDuAdjType = 7;
7343                                 } else if (pBtdm8723->curPsTdma == 4) {
7344                                         btdm_2AntPsTdma(padapter, true, 8);
7345                                         pBtdm8723->psTdmaDuAdjType = 8;
7346                                 }
7347                                 if (pBtdm8723->curPsTdma == 9) {
7348                                         btdm_2AntPsTdma(padapter, true, 13);
7349                                         pBtdm8723->psTdmaDuAdjType = 13;
7350                                 } else if (pBtdm8723->curPsTdma == 10) {
7351                                         btdm_2AntPsTdma(padapter, true, 14);
7352                                         pBtdm8723->psTdmaDuAdjType = 14;
7353                                 } else if (pBtdm8723->curPsTdma == 11) {
7354                                         btdm_2AntPsTdma(padapter, true, 15);
7355                                         pBtdm8723->psTdmaDuAdjType = 15;
7356                                 } else if (pBtdm8723->curPsTdma == 12) {
7357                                         btdm_2AntPsTdma(padapter, true, 16);
7358                                         pBtdm8723->psTdmaDuAdjType = 16;
7359                                 }
7360
7361                                 if (result == -1) {
7362                                         if (pBtdm8723->curPsTdma == 5) {
7363                                                 btdm_2AntPsTdma(padapter, true, 6);
7364                                                 pBtdm8723->psTdmaDuAdjType = 6;
7365                                         } else if (pBtdm8723->curPsTdma == 6) {
7366                                                 btdm_2AntPsTdma(padapter, true, 7);
7367                                                 pBtdm8723->psTdmaDuAdjType = 7;
7368                                         } else if (pBtdm8723->curPsTdma == 7) {
7369                                                 btdm_2AntPsTdma(padapter, true, 8);
7370                                                 pBtdm8723->psTdmaDuAdjType = 8;
7371                                         } else if (pBtdm8723->curPsTdma == 13) {
7372                                                 btdm_2AntPsTdma(padapter, true, 14);
7373                                                 pBtdm8723->psTdmaDuAdjType = 14;
7374                                         } else if (pBtdm8723->curPsTdma == 14) {
7375                                                 btdm_2AntPsTdma(padapter, true, 15);
7376                                                 pBtdm8723->psTdmaDuAdjType = 15;
7377                                         } else if (pBtdm8723->curPsTdma == 15) {
7378                                                 btdm_2AntPsTdma(padapter, true, 16);
7379                                                 pBtdm8723->psTdmaDuAdjType = 16;
7380                                         }
7381                                 } else if (result == 1) {
7382                                         if (pBtdm8723->curPsTdma == 8) {
7383                                                 btdm_2AntPsTdma(padapter, true, 7);
7384                                                 pBtdm8723->psTdmaDuAdjType = 7;
7385                                         } else if (pBtdm8723->curPsTdma == 7) {
7386                                                 btdm_2AntPsTdma(padapter, true, 6);
7387                                                 pBtdm8723->psTdmaDuAdjType = 6;
7388                                         } else if (pBtdm8723->curPsTdma == 6) {
7389                                                 btdm_2AntPsTdma(padapter, true, 5);
7390                                                 pBtdm8723->psTdmaDuAdjType = 5;
7391                                         } else if (pBtdm8723->curPsTdma == 16) {
7392                                                 btdm_2AntPsTdma(padapter, true, 15);
7393                                                 pBtdm8723->psTdmaDuAdjType = 15;
7394                                         } else if (pBtdm8723->curPsTdma == 15) {
7395                                                 btdm_2AntPsTdma(padapter, true, 14);
7396                                                 pBtdm8723->psTdmaDuAdjType = 14;
7397                                         } else if (pBtdm8723->curPsTdma == 14) {
7398                                                 btdm_2AntPsTdma(padapter, true, 13);
7399                                                 pBtdm8723->psTdmaDuAdjType = 13;
7400                                         }
7401                                 }
7402                         } else {
7403                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
7404                                 if (pBtdm8723->curPsTdma == 5) {
7405                                         btdm_2AntPsTdma(padapter, true, 1);
7406                                         pBtdm8723->psTdmaDuAdjType = 1;
7407                                 } else if (pBtdm8723->curPsTdma == 6) {
7408                                         btdm_2AntPsTdma(padapter, true, 2);
7409                                         pBtdm8723->psTdmaDuAdjType = 2;
7410                                 } else if (pBtdm8723->curPsTdma == 7) {
7411                                         btdm_2AntPsTdma(padapter, true, 3);
7412                                         pBtdm8723->psTdmaDuAdjType = 3;
7413                                 } else if (pBtdm8723->curPsTdma == 8) {
7414                                         btdm_2AntPsTdma(padapter, true, 4);
7415                                         pBtdm8723->psTdmaDuAdjType = 4;
7416                                 }
7417                                 if (pBtdm8723->curPsTdma == 13) {
7418                                         btdm_2AntPsTdma(padapter, true, 9);
7419                                         pBtdm8723->psTdmaDuAdjType = 9;
7420                                 } else if (pBtdm8723->curPsTdma == 14) {
7421                                         btdm_2AntPsTdma(padapter, true, 10);
7422                                         pBtdm8723->psTdmaDuAdjType = 10;
7423                                 } else if (pBtdm8723->curPsTdma == 15) {
7424                                         btdm_2AntPsTdma(padapter, true, 11);
7425                                         pBtdm8723->psTdmaDuAdjType = 11;
7426                                 } else if (pBtdm8723->curPsTdma == 16) {
7427                                         btdm_2AntPsTdma(padapter, true, 12);
7428                                         pBtdm8723->psTdmaDuAdjType = 12;
7429                                 }
7430
7431                                 if (result == -1) {
7432                                         if (pBtdm8723->curPsTdma == 1) {
7433                                                 btdm_2AntPsTdma(padapter, true, 2);
7434                                                 pBtdm8723->psTdmaDuAdjType = 2;
7435                                         } else if (pBtdm8723->curPsTdma == 2) {
7436                                                 btdm_2AntPsTdma(padapter, true, 3);
7437                                                 pBtdm8723->psTdmaDuAdjType = 3;
7438                                         } else if (pBtdm8723->curPsTdma == 3) {
7439                                                 btdm_2AntPsTdma(padapter, true, 4);
7440                                                 pBtdm8723->psTdmaDuAdjType = 4;
7441                                         } else if (pBtdm8723->curPsTdma == 9) {
7442                                                 btdm_2AntPsTdma(padapter, true, 10);
7443                                                 pBtdm8723->psTdmaDuAdjType = 10;
7444                                         } else if (pBtdm8723->curPsTdma == 10) {
7445                                                 btdm_2AntPsTdma(padapter, true, 11);
7446                                                 pBtdm8723->psTdmaDuAdjType = 11;
7447                                         } else if (pBtdm8723->curPsTdma == 11) {
7448                                                 btdm_2AntPsTdma(padapter, true, 12);
7449                                                 pBtdm8723->psTdmaDuAdjType = 12;
7450                                         }
7451                                 } else if (result == 1) {
7452                                         if (pBtdm8723->curPsTdma == 4) {
7453                                                 btdm_2AntPsTdma(padapter, true, 3);
7454                                                 pBtdm8723->psTdmaDuAdjType = 3;
7455                                         } else if (pBtdm8723->curPsTdma == 3) {
7456                                                 btdm_2AntPsTdma(padapter, true, 2);
7457                                                 pBtdm8723->psTdmaDuAdjType = 2;
7458                                         } else if (pBtdm8723->curPsTdma == 2) {
7459                                                 btdm_2AntPsTdma(padapter, true, 1);
7460                                                 pBtdm8723->psTdmaDuAdjType = 1;
7461                                         } else if (pBtdm8723->curPsTdma == 12) {
7462                                                 btdm_2AntPsTdma(padapter, true, 11);
7463                                                 pBtdm8723->psTdmaDuAdjType = 11;
7464                                         } else if (pBtdm8723->curPsTdma == 11) {
7465                                                 btdm_2AntPsTdma(padapter, true, 10);
7466                                                 pBtdm8723->psTdmaDuAdjType = 10;
7467                                         } else if (pBtdm8723->curPsTdma == 10) {
7468                                                 btdm_2AntPsTdma(padapter, true, 9);
7469                                                 pBtdm8723->psTdmaDuAdjType = 9;
7470                                         }
7471                                 }
7472                         }
7473                 } else if (maxInterval == 2) {
7474                         if (bTxPause) {
7475                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
7476                                 if (pBtdm8723->curPsTdma == 1) {
7477                                         btdm_2AntPsTdma(padapter, true, 6);
7478                                         pBtdm8723->psTdmaDuAdjType = 6;
7479                                 } else if (pBtdm8723->curPsTdma == 2) {
7480                                         btdm_2AntPsTdma(padapter, true, 6);
7481                                         pBtdm8723->psTdmaDuAdjType = 6;
7482                                 } else if (pBtdm8723->curPsTdma == 3) {
7483                                         btdm_2AntPsTdma(padapter, true, 7);
7484                                         pBtdm8723->psTdmaDuAdjType = 7;
7485                                 } else if (pBtdm8723->curPsTdma == 4) {
7486                                         btdm_2AntPsTdma(padapter, true, 8);
7487                                         pBtdm8723->psTdmaDuAdjType = 8;
7488                                 }
7489                                 if (pBtdm8723->curPsTdma == 9) {
7490                                         btdm_2AntPsTdma(padapter, true, 14);
7491                                         pBtdm8723->psTdmaDuAdjType = 14;
7492                                 } else if (pBtdm8723->curPsTdma == 10) {
7493                                         btdm_2AntPsTdma(padapter, true, 14);
7494                                         pBtdm8723->psTdmaDuAdjType = 14;
7495                                 } else if (pBtdm8723->curPsTdma == 11) {
7496                                         btdm_2AntPsTdma(padapter, true, 15);
7497                                         pBtdm8723->psTdmaDuAdjType = 15;
7498                                 } else if (pBtdm8723->curPsTdma == 12) {
7499                                         btdm_2AntPsTdma(padapter, true, 16);
7500                                         pBtdm8723->psTdmaDuAdjType = 16;
7501                                 }
7502                                 if (result == -1) {
7503                                         if (pBtdm8723->curPsTdma == 5) {
7504                                                 btdm_2AntPsTdma(padapter, true, 6);
7505                                                 pBtdm8723->psTdmaDuAdjType = 6;
7506                                         } else if (pBtdm8723->curPsTdma == 6) {
7507                                                 btdm_2AntPsTdma(padapter, true, 7);
7508                                                 pBtdm8723->psTdmaDuAdjType = 7;
7509                                         } else if (pBtdm8723->curPsTdma == 7) {
7510                                                 btdm_2AntPsTdma(padapter, true, 8);
7511                                                 pBtdm8723->psTdmaDuAdjType = 8;
7512                                         } else if (pBtdm8723->curPsTdma == 13) {
7513                                                 btdm_2AntPsTdma(padapter, true, 14);
7514                                                 pBtdm8723->psTdmaDuAdjType = 14;
7515                                         } else if (pBtdm8723->curPsTdma == 14) {
7516                                                 btdm_2AntPsTdma(padapter, true, 15);
7517                                                 pBtdm8723->psTdmaDuAdjType = 15;
7518                                         } else if (pBtdm8723->curPsTdma == 15) {
7519                                                 btdm_2AntPsTdma(padapter, true, 16);
7520                                                 pBtdm8723->psTdmaDuAdjType = 16;
7521                                         }
7522                                 } else if (result == 1) {
7523                                         if (pBtdm8723->curPsTdma == 8) {
7524                                                 btdm_2AntPsTdma(padapter, true, 7);
7525                                                 pBtdm8723->psTdmaDuAdjType = 7;
7526                                         } else if (pBtdm8723->curPsTdma == 7) {
7527                                                 btdm_2AntPsTdma(padapter, true, 6);
7528                                                 pBtdm8723->psTdmaDuAdjType = 6;
7529                                         } else if (pBtdm8723->curPsTdma == 6) {
7530                                                 btdm_2AntPsTdma(padapter, true, 6);
7531                                                 pBtdm8723->psTdmaDuAdjType = 6;
7532                                         } else if (pBtdm8723->curPsTdma == 16) {
7533                                                 btdm_2AntPsTdma(padapter, true, 15);
7534                                                 pBtdm8723->psTdmaDuAdjType = 15;
7535                                         } else if (pBtdm8723->curPsTdma == 15) {
7536                                                 btdm_2AntPsTdma(padapter, true, 14);
7537                                                 pBtdm8723->psTdmaDuAdjType = 14;
7538                                         } else if (pBtdm8723->curPsTdma == 14) {
7539                                                 btdm_2AntPsTdma(padapter, true, 14);
7540                                                 pBtdm8723->psTdmaDuAdjType = 14;
7541                                         }
7542                                 }
7543                         } else {
7544                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
7545                                 if (pBtdm8723->curPsTdma == 5) {
7546                                         btdm_2AntPsTdma(padapter, true, 2);
7547                                         pBtdm8723->psTdmaDuAdjType = 2;
7548                                 } else if (pBtdm8723->curPsTdma == 6) {
7549                                         btdm_2AntPsTdma(padapter, true, 2);
7550                                         pBtdm8723->psTdmaDuAdjType = 2;
7551                                 } else if (pBtdm8723->curPsTdma == 7) {
7552                                         btdm_2AntPsTdma(padapter, true, 3);
7553                                         pBtdm8723->psTdmaDuAdjType = 3;
7554                                 } else if (pBtdm8723->curPsTdma == 8) {
7555                                         btdm_2AntPsTdma(padapter, true, 4);
7556                                         pBtdm8723->psTdmaDuAdjType = 4;
7557                                 }
7558                                 if (pBtdm8723->curPsTdma == 13) {
7559                                         btdm_2AntPsTdma(padapter, true, 10);
7560                                         pBtdm8723->psTdmaDuAdjType = 10;
7561                                 } else if (pBtdm8723->curPsTdma == 14) {
7562                                         btdm_2AntPsTdma(padapter, true, 10);
7563                                         pBtdm8723->psTdmaDuAdjType = 10;
7564                                 } else if (pBtdm8723->curPsTdma == 15) {
7565                                         btdm_2AntPsTdma(padapter, true, 11);
7566                                         pBtdm8723->psTdmaDuAdjType = 11;
7567                                 } else if (pBtdm8723->curPsTdma == 16) {
7568                                         btdm_2AntPsTdma(padapter, true, 12);
7569                                         pBtdm8723->psTdmaDuAdjType = 12;
7570                                 }
7571                                 if (result == -1) {
7572                                         if (pBtdm8723->curPsTdma == 1) {
7573                                                 btdm_2AntPsTdma(padapter, true, 2);
7574                                                 pBtdm8723->psTdmaDuAdjType = 2;
7575                                         } else if (pBtdm8723->curPsTdma == 2) {
7576                                                 btdm_2AntPsTdma(padapter, true, 3);
7577                                                 pBtdm8723->psTdmaDuAdjType = 3;
7578                                         } else if (pBtdm8723->curPsTdma == 3) {
7579                                                 btdm_2AntPsTdma(padapter, true, 4);
7580                                                 pBtdm8723->psTdmaDuAdjType = 4;
7581                                         } else if (pBtdm8723->curPsTdma == 9) {
7582                                                 btdm_2AntPsTdma(padapter, true, 10);
7583                                                 pBtdm8723->psTdmaDuAdjType = 10;
7584                                         } else if (pBtdm8723->curPsTdma == 10) {
7585                                                 btdm_2AntPsTdma(padapter, true, 11);
7586                                                 pBtdm8723->psTdmaDuAdjType = 11;
7587                                         } else if (pBtdm8723->curPsTdma == 11) {
7588                                                 btdm_2AntPsTdma(padapter, true, 12);
7589                                                 pBtdm8723->psTdmaDuAdjType = 12;
7590                                         }
7591                                 } else if (result == 1) {
7592                                         if (pBtdm8723->curPsTdma == 4) {
7593                                                 btdm_2AntPsTdma(padapter, true, 3);
7594                                                 pBtdm8723->psTdmaDuAdjType = 3;
7595                                         } else if (pBtdm8723->curPsTdma == 3) {
7596                                                 btdm_2AntPsTdma(padapter, true, 2);
7597                                                 pBtdm8723->psTdmaDuAdjType = 2;
7598                                         } else if (pBtdm8723->curPsTdma == 2) {
7599                                                 btdm_2AntPsTdma(padapter, true, 2);
7600                                                 pBtdm8723->psTdmaDuAdjType = 2;
7601                                         } else if (pBtdm8723->curPsTdma == 12) {
7602                                                 btdm_2AntPsTdma(padapter, true, 11);
7603                                                 pBtdm8723->psTdmaDuAdjType = 11;
7604                                         } else if (pBtdm8723->curPsTdma == 11) {
7605                                                 btdm_2AntPsTdma(padapter, true, 10);
7606                                                 pBtdm8723->psTdmaDuAdjType = 10;
7607                                         } else if (pBtdm8723->curPsTdma == 10) {
7608                                                 btdm_2AntPsTdma(padapter, true, 10);
7609                                                 pBtdm8723->psTdmaDuAdjType = 10;
7610                                         }
7611                                 }
7612                         }
7613                 } else if (maxInterval == 3) {
7614                         if (bTxPause) {
7615                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 1\n"));
7616                                 if (pBtdm8723->curPsTdma == 1) {
7617                                         btdm_2AntPsTdma(padapter, true, 7);
7618                                         pBtdm8723->psTdmaDuAdjType = 7;
7619                                 } else if (pBtdm8723->curPsTdma == 2) {
7620                                         btdm_2AntPsTdma(padapter, true, 7);
7621                                         pBtdm8723->psTdmaDuAdjType = 7;
7622                                 } else if (pBtdm8723->curPsTdma == 3) {
7623                                         btdm_2AntPsTdma(padapter, true, 7);
7624                                         pBtdm8723->psTdmaDuAdjType = 7;
7625                                 } else if (pBtdm8723->curPsTdma == 4) {
7626                                         btdm_2AntPsTdma(padapter, true, 8);
7627                                         pBtdm8723->psTdmaDuAdjType = 8;
7628                                 }
7629                                 if (pBtdm8723->curPsTdma == 9) {
7630                                         btdm_2AntPsTdma(padapter, true, 15);
7631                                         pBtdm8723->psTdmaDuAdjType = 15;
7632                                 } else if (pBtdm8723->curPsTdma == 10) {
7633                                         btdm_2AntPsTdma(padapter, true, 15);
7634                                         pBtdm8723->psTdmaDuAdjType = 15;
7635                                 } else if (pBtdm8723->curPsTdma == 11) {
7636                                         btdm_2AntPsTdma(padapter, true, 15);
7637                                         pBtdm8723->psTdmaDuAdjType = 15;
7638                                 } else if (pBtdm8723->curPsTdma == 12) {
7639                                         btdm_2AntPsTdma(padapter, true, 16);
7640                                         pBtdm8723->psTdmaDuAdjType = 16;
7641                                 }
7642                                 if (result == -1) {
7643                                         if (pBtdm8723->curPsTdma == 5) {
7644                                                 btdm_2AntPsTdma(padapter, true, 7);
7645                                                 pBtdm8723->psTdmaDuAdjType = 7;
7646                                         } else if (pBtdm8723->curPsTdma == 6) {
7647                                                 btdm_2AntPsTdma(padapter, true, 7);
7648                                                 pBtdm8723->psTdmaDuAdjType = 7;
7649                                         } else if (pBtdm8723->curPsTdma == 7) {
7650                                                 btdm_2AntPsTdma(padapter, true, 8);
7651                                                 pBtdm8723->psTdmaDuAdjType = 8;
7652                                         } else if (pBtdm8723->curPsTdma == 13) {
7653                                                 btdm_2AntPsTdma(padapter, true, 15);
7654                                                 pBtdm8723->psTdmaDuAdjType = 15;
7655                                         } else if (pBtdm8723->curPsTdma == 14) {
7656                                                 btdm_2AntPsTdma(padapter, true, 15);
7657                                                 pBtdm8723->psTdmaDuAdjType = 15;
7658                                         } else if (pBtdm8723->curPsTdma == 15) {
7659                                                 btdm_2AntPsTdma(padapter, true, 16);
7660                                                 pBtdm8723->psTdmaDuAdjType = 16;
7661                                         }
7662                                 } else if (result == 1) {
7663                                         if (pBtdm8723->curPsTdma == 8) {
7664                                                 btdm_2AntPsTdma(padapter, true, 7);
7665                                                 pBtdm8723->psTdmaDuAdjType = 7;
7666                                         } else if (pBtdm8723->curPsTdma == 7) {
7667                                                 btdm_2AntPsTdma(padapter, true, 7);
7668                                                 pBtdm8723->psTdmaDuAdjType = 7;
7669                                         } else if (pBtdm8723->curPsTdma == 6) {
7670                                                 btdm_2AntPsTdma(padapter, true, 7);
7671                                                 pBtdm8723->psTdmaDuAdjType = 7;
7672                                         } else if (pBtdm8723->curPsTdma == 16) {
7673                                                 btdm_2AntPsTdma(padapter, true, 15);
7674                                                 pBtdm8723->psTdmaDuAdjType = 15;
7675                                         } else if (pBtdm8723->curPsTdma == 15) {
7676                                                 btdm_2AntPsTdma(padapter, true, 15);
7677                                                 pBtdm8723->psTdmaDuAdjType = 15;
7678                                         } else if (pBtdm8723->curPsTdma == 14) {
7679                                                 btdm_2AntPsTdma(padapter, true, 15);
7680                                                 pBtdm8723->psTdmaDuAdjType = 15;
7681                                         }
7682                                 }
7683                         } else {
7684                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], TxPause = 0\n"));
7685                                 if (pBtdm8723->curPsTdma == 5) {
7686                                         btdm_2AntPsTdma(padapter, true, 3);
7687                                         pBtdm8723->psTdmaDuAdjType = 3;
7688                                 } else if (pBtdm8723->curPsTdma == 6) {
7689                                         btdm_2AntPsTdma(padapter, true, 3);
7690                                         pBtdm8723->psTdmaDuAdjType = 3;
7691                                 } else if (pBtdm8723->curPsTdma == 7) {
7692                                         btdm_2AntPsTdma(padapter, true, 3);
7693                                         pBtdm8723->psTdmaDuAdjType = 3;
7694                                 } else if (pBtdm8723->curPsTdma == 8) {
7695                                         btdm_2AntPsTdma(padapter, true, 4);
7696                                         pBtdm8723->psTdmaDuAdjType = 4;
7697                                 }
7698                                 if (pBtdm8723->curPsTdma == 13) {
7699                                         btdm_2AntPsTdma(padapter, true, 11);
7700                                         pBtdm8723->psTdmaDuAdjType = 11;
7701                                 } else if (pBtdm8723->curPsTdma == 14) {
7702                                         btdm_2AntPsTdma(padapter, true, 11);
7703                                         pBtdm8723->psTdmaDuAdjType = 11;
7704                                 } else if (pBtdm8723->curPsTdma == 15) {
7705                                         btdm_2AntPsTdma(padapter, true, 11);
7706                                         pBtdm8723->psTdmaDuAdjType = 11;
7707                                 } else if (pBtdm8723->curPsTdma == 16) {
7708                                         btdm_2AntPsTdma(padapter, true, 12);
7709                                         pBtdm8723->psTdmaDuAdjType = 12;
7710                                 }
7711                                 if (result == -1) {
7712                                         if (pBtdm8723->curPsTdma == 1) {
7713                                                 btdm_2AntPsTdma(padapter, true, 3);
7714                                                 pBtdm8723->psTdmaDuAdjType = 3;
7715                                         } else if (pBtdm8723->curPsTdma == 2) {
7716                                                 btdm_2AntPsTdma(padapter, true, 3);
7717                                                 pBtdm8723->psTdmaDuAdjType = 3;
7718                                         } else if (pBtdm8723->curPsTdma == 3) {
7719                                                 btdm_2AntPsTdma(padapter, true, 4);
7720                                                 pBtdm8723->psTdmaDuAdjType = 4;
7721                                         } else if (pBtdm8723->curPsTdma == 9) {
7722                                                 btdm_2AntPsTdma(padapter, true, 11);
7723                                                 pBtdm8723->psTdmaDuAdjType = 11;
7724                                         } else if (pBtdm8723->curPsTdma == 10) {
7725                                                 btdm_2AntPsTdma(padapter, true, 11);
7726                                                 pBtdm8723->psTdmaDuAdjType = 11;
7727                                         } else if (pBtdm8723->curPsTdma == 11) {
7728                                                 btdm_2AntPsTdma(padapter, true, 12);
7729                                                 pBtdm8723->psTdmaDuAdjType = 12;
7730                                         }
7731                                 } else if (result == 1) {
7732                                         if (pBtdm8723->curPsTdma == 4) {
7733                                                 btdm_2AntPsTdma(padapter, true, 3);
7734                                                 pBtdm8723->psTdmaDuAdjType = 3;
7735                                         } else if (pBtdm8723->curPsTdma == 3) {
7736                                                 btdm_2AntPsTdma(padapter, true, 3);
7737                                                 pBtdm8723->psTdmaDuAdjType = 3;
7738                                         } else if (pBtdm8723->curPsTdma == 2) {
7739                                                 btdm_2AntPsTdma(padapter, true, 3);
7740                                                 pBtdm8723->psTdmaDuAdjType = 3;
7741                                         } else if (pBtdm8723->curPsTdma == 12) {
7742                                                 btdm_2AntPsTdma(padapter, true, 11);
7743                                                 pBtdm8723->psTdmaDuAdjType = 11;
7744                                         } else if (pBtdm8723->curPsTdma == 11) {
7745                                                 btdm_2AntPsTdma(padapter, true, 11);
7746                                                 pBtdm8723->psTdmaDuAdjType = 11;
7747                                         } else if (pBtdm8723->curPsTdma == 10) {
7748                                                 btdm_2AntPsTdma(padapter, true, 11);
7749                                                 pBtdm8723->psTdmaDuAdjType = 11;
7750                                         }
7751                                 }
7752                         }
7753                 }
7754         }
7755         RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type : recordPsTdma =%d\n", pBtdm8723->psTdmaDuAdjType));
7756         /*  if current PsTdma not match with the recorded one (when scan, dhcp...), */
7757         /*  then we have to adjust it back to the previous record one. */
7758         if (pBtdm8723->curPsTdma != pBtdm8723->psTdmaDuAdjType) {
7759                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma =%d, recordPsTdma =%d\n",
7760                         pBtdm8723->curPsTdma, pBtdm8723->psTdmaDuAdjType));
7761
7762                 if (!check_fwstate(&padapter->mlmepriv, _FW_UNDER_SURVEY|_FW_UNDER_LINKING))
7763                         btdm_2AntPsTdma(padapter, true, pBtdm8723->psTdmaDuAdjType);
7764                 else
7765                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"));
7766         }
7767 }
7768
7769 /*  default Action */
7770 /*  SCO only or SCO+PAN(HS) */
7771 static void btdm_2Ant8723ASCOAction(struct rtw_adapter *padapter)
7772 {
7773         u8 btRssiState, btRssiState1;
7774
7775         if (btdm_NeedToDecBtPwr(padapter))
7776                 btdm_2AntDecBtPwr(padapter, true);
7777         else
7778                 btdm_2AntDecBtPwr(padapter, false);
7779
7780         if (BTDM_IsHT40(padapter)) {
7781                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7782                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7783                 /*  fw mechanism */
7784                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7785                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7786                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7787                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7788                         btdm_2AntPsTdma(padapter, true, 11);
7789                 } else {
7790                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7791                         btdm_2AntPsTdma(padapter, true, 15);
7792                 }
7793
7794                 /*  sw mechanism */
7795                 btdm_2AntAgcTable(padapter, false);
7796                 btdm_2AntAdcBackOff(padapter, true);
7797                 btdm_2AntDacSwing(padapter, false, 0xc0);
7798         } else {
7799                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
7800                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7801                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
7802
7803                 /*  fw mechanism */
7804                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
7805                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
7806                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7807                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7808                         btdm_2AntPsTdma(padapter, true, 11);
7809                 } else {
7810                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7811                         btdm_2AntPsTdma(padapter, true, 15);
7812                 }
7813
7814                 /*  sw mechanism */
7815                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7816                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7817                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7818                         btdm_2AntAgcTable(padapter, true);
7819                         btdm_2AntAdcBackOff(padapter, true);
7820                         btdm_2AntDacSwing(padapter, false, 0xc0);
7821                 } else {
7822                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7823                         btdm_2AntAgcTable(padapter, false);
7824                         btdm_2AntAdcBackOff(padapter, false);
7825                         btdm_2AntDacSwing(padapter, false, 0xc0);
7826                 }
7827         }
7828 }
7829
7830 static void btdm_2Ant8723AHIDAction(struct rtw_adapter *padapter)
7831 {
7832         u8 btRssiState, btRssiState1;
7833
7834         if (btdm_NeedToDecBtPwr(padapter))
7835                 btdm_2AntDecBtPwr(padapter, true);
7836         else
7837                 btdm_2AntDecBtPwr(padapter, false);
7838
7839         if (BTDM_IsHT40(padapter)) {
7840                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7841                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7842                         /*  fw mechanism */
7843                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7844                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7845                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7846                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7847                         btdm_2AntPsTdma(padapter, true, 9);
7848                 } else {
7849                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7850                         btdm_2AntPsTdma(padapter, true, 13);
7851                 }
7852
7853                 /*  sw mechanism */
7854                 btdm_2AntAgcTable(padapter, false);
7855                 btdm_2AntAdcBackOff(padapter, false);
7856                 btdm_2AntDacSwing(padapter, false, 0xc0);
7857         } else {
7858                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
7859                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7860                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
7861
7862                 /*  fw mechanism */
7863                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
7864                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
7865                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7866                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7867                         btdm_2AntPsTdma(padapter, true, 9);
7868                 } else {
7869                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7870                         btdm_2AntPsTdma(padapter, true, 13);
7871                 }
7872
7873                 /*  sw mechanism */
7874                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7875                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7876                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7877                         btdm_2AntAgcTable(padapter, true);
7878                         btdm_2AntAdcBackOff(padapter, true);
7879                         btdm_2AntDacSwing(padapter, false, 0xc0);
7880                 } else {
7881                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7882                         btdm_2AntAgcTable(padapter, false);
7883                         btdm_2AntAdcBackOff(padapter, false);
7884                         btdm_2AntDacSwing(padapter, false, 0xc0);
7885                 }
7886         }
7887 }
7888
7889 /* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
7890 static void btdm_2Ant8723AA2DPAction(struct rtw_adapter *padapter)
7891 {
7892         u8 btRssiState, btRssiState1;
7893         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
7894         u8 btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
7895
7896         if (btdm_NeedToDecBtPwr(padapter))
7897                 btdm_2AntDecBtPwr(padapter, true);
7898         else
7899                 btdm_2AntDecBtPwr(padapter, false);
7900
7901         if (BTDM_IsHT40(padapter)) {
7902                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7903                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7904
7905                 /*  fw mechanism */
7906                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7907                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7908                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7909                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7910
7911                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7912                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7913                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 3);
7914                         } else {
7915                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
7916                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
7917                         }
7918                 } else {
7919                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7920                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7921                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7922                                 btdm_2AntTdmaDurationAdjust(padapter, false, true, 3);
7923                         } else {
7924                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
7925                         btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
7926                         }
7927                 }
7928
7929                 /*  sw mechanism */
7930                 btdm_2AntAgcTable(padapter, false);
7931                 btdm_2AntAdcBackOff(padapter, true);
7932                 btdm_2AntDacSwing(padapter, false, 0xc0);
7933         } else {
7934                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
7935                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7936                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
7937
7938                 /*  fw mechanism */
7939                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
7940                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
7941                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
7942                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7943                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7944                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7945                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 3);
7946                         } else {
7947                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
7948                                 btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
7949                         }
7950                 } else {
7951                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
7952                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
7953                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
7954                                 btdm_2AntTdmaDurationAdjust(padapter, false, true, 3);
7955                         } else {
7956                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
7957                                 btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
7958                         }
7959                 }
7960
7961                 /*  sw mechanism */
7962                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7963                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7964                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7965                         btdm_2AntAgcTable(padapter, true);
7966                         btdm_2AntAdcBackOff(padapter, true);
7967                         btdm_2AntDacSwing(padapter, false, 0xc0);
7968                 } else {
7969                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7970                         btdm_2AntAgcTable(padapter, false);
7971                         btdm_2AntAdcBackOff(padapter, false);
7972                         btdm_2AntDacSwing(padapter, false, 0xc0);
7973                 }
7974         }
7975 }
7976
7977 static void btdm_2Ant8723APANEDRAction(struct rtw_adapter *padapter)
7978 {
7979         u8 btRssiState, btRssiState1;
7980
7981         if (btdm_NeedToDecBtPwr(padapter))
7982                 btdm_2AntDecBtPwr(padapter, true);
7983         else
7984                 btdm_2AntDecBtPwr(padapter, false);
7985
7986         if (BTDM_IsHT40(padapter)) {
7987                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
7988                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
7989
7990                 /*  fw mechanism */
7991                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
7992                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
7993                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
7994                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
7995                         btdm_2AntPsTdma(padapter, true, 2);
7996                 } else {
7997                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
7998                         btdm_2AntPsTdma(padapter, true, 6);
7999                 }
8000
8001                 /*  sw mechanism */
8002                 btdm_2AntAgcTable(padapter, false);
8003                 btdm_2AntAdcBackOff(padapter, true);
8004                 btdm_2AntDacSwing(padapter, false, 0xc0);
8005         } else {
8006                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8007                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8008                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8009
8010                 /*  fw mechanism */
8011                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8012                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8013                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8014                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8015                         btdm_2AntPsTdma(padapter, true, 2);
8016                 } else {
8017                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8018                         btdm_2AntPsTdma(padapter, true, 6);
8019                 }
8020
8021                 /*  sw mechanism */
8022                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8023                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8024                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8025                         btdm_2AntAgcTable(padapter, true);
8026                         btdm_2AntAdcBackOff(padapter, true);
8027                         btdm_2AntDacSwing(padapter, false, 0xc0);
8028                 } else {
8029                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8030                         btdm_2AntAgcTable(padapter, false);
8031                         btdm_2AntAdcBackOff(padapter, false);
8032                         btdm_2AntDacSwing(padapter, false, 0xc0);
8033                 }
8034         }
8035 }
8036
8037 /* PAN(HS) only */
8038 static void btdm_2Ant8723APANHSAction(struct rtw_adapter *padapter)
8039 {
8040         u8 btRssiState;
8041
8042         if (BTDM_IsHT40(padapter)) {
8043                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8044                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
8045                 /*  fw mechanism */
8046                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8047                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8048                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8049                         btdm_2AntDecBtPwr(padapter, true);
8050                 } else {
8051                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8052                         btdm_2AntDecBtPwr(padapter, false);
8053                 }
8054                 btdm_2AntPsTdma(padapter, false, 0);
8055
8056                 /*  sw mechanism */
8057                 btdm_2AntAgcTable(padapter, false);
8058                 btdm_2AntAdcBackOff(padapter, true);
8059                 btdm_2AntDacSwing(padapter, false, 0xc0);
8060         } else {
8061                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8062                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
8063
8064                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8065                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8066                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high\n"));
8067                         /*  fw mechanism */
8068                         btdm_2AntDecBtPwr(padapter, true);
8069                         btdm_2AntPsTdma(padapter, false, 0);
8070
8071                         /*  sw mechanism */
8072                         btdm_2AntAgcTable(padapter, true);
8073                         btdm_2AntAdcBackOff(padapter, true);
8074                         btdm_2AntDacSwing(padapter, false, 0xc0);
8075                 } else {
8076                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low\n"));
8077                         /*  fw mechanism */
8078                         btdm_2AntDecBtPwr(padapter, false);
8079                         btdm_2AntPsTdma(padapter, false, 0);
8080
8081                         /*  sw mechanism */
8082                         btdm_2AntAgcTable(padapter, false);
8083                         btdm_2AntAdcBackOff(padapter, false);
8084                         btdm_2AntDacSwing(padapter, false, 0xc0);
8085                 }
8086         }
8087 }
8088
8089 /* PAN(EDR)+A2DP */
8090 static void btdm_2Ant8723APANEDRA2DPAction(struct rtw_adapter *padapter)
8091 {
8092         u8 btRssiState, btRssiState1, btInfoExt;
8093         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8094
8095         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8096
8097         if (btdm_NeedToDecBtPwr(padapter))
8098                 btdm_2AntDecBtPwr(padapter, true);
8099         else
8100                 btdm_2AntDecBtPwr(padapter, false);
8101
8102         if (BTDM_IsHT40(padapter)) {
8103                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8104                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8105
8106                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8107                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8108                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8109                         /*  fw mechanism */
8110                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8111
8112                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8113                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8114                                 btdm_2AntPsTdma(padapter, true, 4);
8115                         } else {
8116                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8117                                 btdm_2AntPsTdma(padapter, true, 2);
8118                         }
8119                 } else {
8120                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8121                         /*  fw mechanism */
8122                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8123                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8124                                 btdm_2AntPsTdma(padapter, true, 8);
8125                         } else {
8126                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8127                                 btdm_2AntPsTdma(padapter, true, 6);
8128                         }
8129                 }
8130
8131                 /*  sw mechanism */
8132                 btdm_2AntAgcTable(padapter, false);
8133                 btdm_2AntAdcBackOff(padapter, true);
8134                 btdm_2AntDacSwing(padapter, false, 0xc0);
8135         } else {
8136                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8137                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8138                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8139
8140                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8141                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8142                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8143                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8144                         /*  fw mechanism */
8145                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8146                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8147                                 btdm_2AntPsTdma(padapter, true, 4);
8148                         } else {
8149                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8150                                 btdm_2AntPsTdma(padapter, true, 2);
8151                         }
8152                 } else {
8153                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8154                         /*  fw mechanism */
8155                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8156                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8157                                 btdm_2AntPsTdma(padapter, true, 8);
8158                         } else {
8159                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8160                                 btdm_2AntPsTdma(padapter, true, 6);
8161                         }
8162                 }
8163
8164                 /*  sw mechanism */
8165                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8166                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8167                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8168                         btdm_2AntAgcTable(padapter, true);
8169                         btdm_2AntAdcBackOff(padapter, true);
8170                         btdm_2AntDacSwing(padapter, false, 0xc0);
8171                 } else {
8172                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8173                         btdm_2AntAgcTable(padapter, false);
8174                         btdm_2AntAdcBackOff(padapter, false);
8175                         btdm_2AntDacSwing(padapter, false, 0xc0);
8176                 }
8177         }
8178 }
8179
8180 static void btdm_2Ant8723APANEDRHIDAction(struct rtw_adapter *padapter)
8181 {
8182         u8 btRssiState, btRssiState1;
8183
8184         if (btdm_NeedToDecBtPwr(padapter))
8185                 btdm_2AntDecBtPwr(padapter, true);
8186         else
8187                 btdm_2AntDecBtPwr(padapter, false);
8188
8189         if (BTDM_IsHT40(padapter)) {
8190                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8191                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8192                 /*  fw mechanism */
8193                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8194                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8195                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8196                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8197                         btdm_2AntPsTdma(padapter, true, 10);
8198                 } else {
8199                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8200                         btdm_2AntPsTdma(padapter, true, 14);
8201                 }
8202
8203                 /*  sw mechanism */
8204                 btdm_2AntAgcTable(padapter, false);
8205                 btdm_2AntAdcBackOff(padapter, true);
8206                 btdm_2AntDacSwing(padapter, false, 0xc0);
8207         } else {
8208                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8209                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8210                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8211
8212                 /*  fw mechanism */
8213                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8214                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8215                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8216                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8217                         btdm_2AntPsTdma(padapter, true, 10);
8218                 } else {
8219                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8220                         btdm_2AntPsTdma(padapter, true, 14);
8221                 }
8222
8223                 /*  sw mechanism */
8224                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8225                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8226                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8227                         btdm_2AntAgcTable(padapter, true);
8228                         btdm_2AntAdcBackOff(padapter, true);
8229                         btdm_2AntDacSwing(padapter, false, 0xc0);
8230                 } else {
8231                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8232                         btdm_2AntAgcTable(padapter, false);
8233                         btdm_2AntAdcBackOff(padapter, false);
8234                         btdm_2AntDacSwing(padapter, false, 0xc0);
8235                 }
8236         }
8237 }
8238
8239 /*  HID+A2DP+PAN(EDR) */
8240 static void btdm_2Ant8723AHIDA2DPPANEDRAction(struct rtw_adapter *padapter)
8241 {
8242         u8 btRssiState, btRssiState1, btInfoExt;
8243         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8244
8245         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8246
8247         if (btdm_NeedToDecBtPwr(padapter))
8248                 btdm_2AntDecBtPwr(padapter, true);
8249         else
8250                 btdm_2AntDecBtPwr(padapter, false);
8251
8252         if (BTDM_IsHT40(padapter)) {
8253                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8254                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8255                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8256                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8257                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8258                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8259
8260                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8261                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8262                                 btdm_2AntPsTdma(padapter, true, 12);
8263                         } else {
8264                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8265                                 btdm_2AntPsTdma(padapter, true, 10);
8266                         }
8267                 } else {
8268                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8269                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8270                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8271                                 btdm_2AntPsTdma(padapter, true, 16);
8272                         } else {
8273                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8274                                 btdm_2AntPsTdma(padapter, true, 14);
8275                         }
8276                 }
8277
8278                 /*  sw mechanism */
8279                 btdm_2AntAgcTable(padapter, false);
8280                 btdm_2AntAdcBackOff(padapter, true);
8281                 btdm_2AntDacSwing(padapter, false, 0xc0);
8282         } else {
8283                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8284                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 37, 0);
8285                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0);
8286                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8287                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8288                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8289                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8290
8291                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8292                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8293                                 btdm_2AntPsTdma(padapter, true, 12);
8294                         } else {
8295                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8296                                 btdm_2AntPsTdma(padapter, true, 10);
8297                         }
8298                 } else {
8299                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8300                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8301                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8302                                 btdm_2AntPsTdma(padapter, true, 16);
8303                         } else {
8304                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8305                                 btdm_2AntPsTdma(padapter, true, 14);
8306                         }
8307                 }
8308
8309                 /*  sw mechanism */
8310                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8311                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8312                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8313                         btdm_2AntAgcTable(padapter, true);
8314                         btdm_2AntAdcBackOff(padapter, true);
8315                         btdm_2AntDacSwing(padapter, false, 0xc0);
8316                 } else {
8317                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8318                         btdm_2AntAgcTable(padapter, false);
8319                         btdm_2AntAdcBackOff(padapter, false);
8320                         btdm_2AntDacSwing(padapter, false, 0xc0);
8321                 }
8322         }
8323 }
8324
8325 static void btdm_2Ant8723AHIDA2DPAction(struct rtw_adapter *padapter)
8326 {
8327         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8328         u8 btRssiState, btRssiState1, btInfoExt;
8329
8330         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8331
8332         if (btdm_NeedToDecBtPwr(padapter))
8333                 btdm_2AntDecBtPwr(padapter, true);
8334         else
8335                 btdm_2AntDecBtPwr(padapter, false);
8336
8337         if (BTDM_IsHT40(padapter)) {
8338                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8339                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 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_2AntTdmaDurationAdjust(padapter, true, false, 3);
8348                         } else {
8349                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8350                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 1);
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_2AntTdmaDurationAdjust(padapter, true, true, 3);
8357                         } else {
8358                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8359                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 1);
8360                         }
8361                 }
8362                 /*  sw mechanism */
8363                 btdm_2AntAgcTable(padapter, false);
8364                 btdm_2AntAdcBackOff(padapter, true);
8365                 btdm_2AntDacSwing(padapter, false, 0xc0);
8366         } else {
8367                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8368                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8369                 btRssiState1 = BTDM_CheckCoexRSSIState(padapter, 2, 27, 0);
8370
8371                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8372                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8373                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8374                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8375
8376                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8377                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8378                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 3);
8379                         } else {
8380                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8381                                 btdm_2AntTdmaDurationAdjust(padapter, true, false, 1);
8382                         }
8383                 } else {
8384                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8385                         if (btInfoExt&BIT(0)) { /* a2dp rate, 1:basic /0:edr */
8386                                 RTPRINT(FBT, BT_TRACE, ("a2dp basic rate \n"));
8387                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 3);
8388                         } else {
8389                                 RTPRINT(FBT, BT_TRACE, ("a2dp edr rate \n"));
8390                                 btdm_2AntTdmaDurationAdjust(padapter, true, true, 1);
8391                         }
8392                 }
8393                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8394                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8395                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8396                         /*  sw mechanism */
8397                         btdm_2AntAgcTable(padapter, true);
8398                         btdm_2AntAdcBackOff(padapter, true);
8399                         btdm_2AntDacSwing(padapter, false, 0xc0);
8400                 } else {
8401                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8402                         /*  sw mechanism */
8403                         btdm_2AntAgcTable(padapter, false);
8404                         btdm_2AntAdcBackOff(padapter, false);
8405                         btdm_2AntDacSwing(padapter, false, 0xc0);
8406                 }
8407         }
8408 }
8409
8410 static void btdm_2Ant8723AA2dp(struct rtw_adapter *padapter)
8411 {
8412         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8413         u8 btRssiState, btRssiState1, btInfoExt;
8414
8415         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
8416
8417         if (btdm_NeedToDecBtPwr(padapter))
8418                 btdm_2AntDecBtPwr(padapter, true);
8419         else
8420                 btdm_2AntDecBtPwr(padapter, false);
8421         /*  coex table */
8422         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8423         btdm_2AntIgnoreWlanAct(padapter, false);
8424
8425         if (BTDM_IsHT40(padapter)) {
8426                 RTPRINT(FBT, BT_TRACE, ("HT40\n"));
8427                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 37, 0);
8428                 /*  fw mechanism */
8429                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8430                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8431                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8432                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8433                         btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
8434                 } else {
8435                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8436                         btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
8437                 }
8438
8439                 /*  sw mechanism */
8440                 btdm_2AntAgcTable(padapter, false);
8441                 btdm_2AntAdcBackOff(padapter, true);
8442                 btdm_2AntDacSwing(padapter, false, 0xc0);
8443         } else {
8444                 RTPRINT(FBT, BT_TRACE, ("HT20 or Legacy\n"));
8445                 btRssiState = BTDM_CheckCoexRSSIState(padapter, 2, 47, 0);
8446                 btRssiState1 = BTDM_CheckCoexRSSIState1(padapter, 2, 27, 0);
8447
8448                 /*  fw mechanism */
8449                 if ((btRssiState1 == BT_RSSI_STATE_HIGH) ||
8450                     (btRssiState1 == BT_RSSI_STATE_STAY_HIGH)) {
8451                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 high \n"));
8452                         PlatformEFIOWrite1Byte(padapter, 0x883, 0x40);
8453                         btdm_2AntTdmaDurationAdjust(padapter, false, false, 1);
8454                 } else {
8455                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi-1 low \n"));
8456                         btdm_2AntTdmaDurationAdjust(padapter, false, true, 1);
8457                 }
8458
8459                 /*  sw mechanism */
8460                 if ((btRssiState == BT_RSSI_STATE_HIGH) ||
8461                     (btRssiState == BT_RSSI_STATE_STAY_HIGH)) {
8462                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi high \n"));
8463                         btdm_2AntAgcTable(padapter, true);
8464                         btdm_2AntAdcBackOff(padapter, true);
8465                         btdm_2AntDacSwing(padapter, false, 0xc0);
8466                 } else {
8467                         RTPRINT(FBT, BT_TRACE, ("Wifi rssi low \n"));
8468                         btdm_2AntAgcTable(padapter, false);
8469                         btdm_2AntAdcBackOff(padapter, false);
8470                         btdm_2AntDacSwing(padapter, false, 0xc0);
8471                 }
8472         }
8473 }
8474
8475 /*  extern function start with BTDM_ */
8476 static void BTDM_2AntParaInit(struct rtw_adapter *padapter)
8477 {
8478
8479         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8480         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
8481
8482         RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2Ant Parameter Init!!\n"));
8483
8484         /*  Enable counter statistics */
8485         rtl8723au_write8(padapter, 0x76e, 0x4);
8486         rtl8723au_write8(padapter, 0x778, 0x3);
8487         rtl8723au_write8(padapter, 0x40, 0x20);
8488
8489         /*  force to reset coex mechanism */
8490         pBtdm8723->preVal0x6c0 = 0x0;
8491         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8492
8493         pBtdm8723->bPrePsTdmaOn = true;
8494         btdm_2AntPsTdma(padapter, false, 0);
8495
8496         pBtdm8723->preFwDacSwingLvl = 0x10;
8497         btdm_2AntFwDacSwingLvl(padapter, 0x20);
8498
8499         pBtdm8723->bPreDecBtPwr = true;
8500         btdm_2AntDecBtPwr(padapter, false);
8501
8502         pBtdm8723->bPreAgcTableEn = true;
8503         btdm_2AntAgcTable(padapter, false);
8504
8505         pBtdm8723->bPreAdcBackOff = true;
8506         btdm_2AntAdcBackOff(padapter, false);
8507
8508         pBtdm8723->bPreLowPenaltyRa = true;
8509         btdm_2AntLowPenaltyRa(padapter, false);
8510
8511         pBtdm8723->bPreRfRxLpfShrink = true;
8512         btdm_2AntRfShrink(padapter, false);
8513
8514         pBtdm8723->bPreDacSwingOn = true;
8515         btdm_2AntDacSwing(padapter, false, 0xc0);
8516
8517         pBtdm8723->bPreIgnoreWlanAct = true;
8518         btdm_2AntIgnoreWlanAct(padapter, false);
8519 }
8520
8521 static void BTDM_2AntHwCoexAllOff8723A(struct rtw_adapter *padapter)
8522 {
8523         btdm_2AntCoexTable(padapter, 0x55555555, 0xffff, 0x3);
8524 }
8525
8526 static void BTDM_2AntFwCoexAllOff8723A(struct rtw_adapter *padapter)
8527 {
8528         btdm_2AntIgnoreWlanAct(padapter, false);
8529         btdm_2AntPsTdma(padapter, false, 0);
8530         btdm_2AntFwDacSwingLvl(padapter, 0x20);
8531         btdm_2AntDecBtPwr(padapter, false);
8532 }
8533
8534 static void BTDM_2AntSwCoexAllOff8723A(struct rtw_adapter *padapter)
8535 {
8536         btdm_2AntAgcTable(padapter, false);
8537         btdm_2AntAdcBackOff(padapter, false);
8538         btdm_2AntLowPenaltyRa(padapter, false);
8539         btdm_2AntRfShrink(padapter, false);
8540         btdm_2AntDacSwing(padapter, false, 0xc0);
8541 }
8542
8543 static void BTDM_2AntFwC2hBtInfo8723A(struct rtw_adapter *padapter)
8544 {
8545         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
8546         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
8547         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8548         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
8549         u8 btInfo = 0;
8550         u8 algorithm = BT_2ANT_COEX_ALGO_UNDEFINED;
8551         u8 bBtLinkExist = false, bBtHsModeExist = false;
8552
8553         btInfo = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal;
8554         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
8555
8556         /*  check BIT2 first ==> check if bt is under inquiry or page scan */
8557         if (btInfo & BIT(2)) {
8558                 if (!pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage) {
8559                         pBtMgnt->ExtConfig.bHoldForBtOperation = true;
8560                         pBtMgnt->ExtConfig.bHoldPeriodCnt = 1;
8561                         btdm_2AntBtInquiryPage(padapter);
8562                 } else {
8563                         pBtMgnt->ExtConfig.bHoldPeriodCnt++;
8564                         btdm_HoldForBtInqPage(padapter);
8565                 }
8566                 pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = true;
8567
8568         } else {
8569                 pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage = false;
8570                 pBtMgnt->ExtConfig.bHoldForBtOperation = false;
8571                 pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
8572
8573         }
8574         RTPRINT(FBT, BT_TRACE,
8575                 ("[BTC2H], pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage =%x pBtMgnt->ExtConfig.bHoldPeriodCnt =%x pBtMgnt->ExtConfig.bHoldForBtOperation =%x\n",
8576                 pHalData->bt_coexist.halCoex8723.bC2hBtInquiryPage,
8577                 pBtMgnt->ExtConfig.bHoldPeriodCnt,
8578                 pBtMgnt->ExtConfig.bHoldForBtOperation));
8579
8580         RTPRINT(FBT, BT_TRACE,
8581                 ("[BTC2H],   btInfo =%x   pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal =%x\n",
8582                 btInfo, pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal));
8583         if (btInfo&BT_INFO_ACL) {
8584                 RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = true   btInfo =%x\n", btInfo));
8585                 bBtLinkExist = true;
8586                 if (((btInfo&(BT_INFO_FTP|BT_INFO_A2DP|BT_INFO_HID|BT_INFO_SCO_BUSY)) != 0) ||
8587                     pHalData->bt_coexist.halCoex8723.btRetryCnt > 0) {
8588                         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_NON_IDLE;
8589                 } else {
8590                         pBtdm8723->btStatus = BT_2ANT_BT_STATUS_CONNECTED_IDLE;
8591                 }
8592
8593                 if (btInfo&BT_INFO_SCO || btInfo&BT_INFO_SCO_BUSY) {
8594                         if (btInfo&BT_INFO_FTP || btInfo&BT_INFO_A2DP || btInfo&BT_INFO_HID) {
8595                                 switch (btInfo&0xe0) {
8596                                 case BT_INFO_HID:
8597                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + HID\n"));
8598                                         algorithm = BT_2ANT_COEX_ALGO_HID;
8599                                         break;
8600                                 case BT_INFO_A2DP:
8601                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Error!!! SCO + A2DP\n"));
8602                                         break;
8603                                 case BT_INFO_FTP:
8604                                         if (bBtHsModeExist) {
8605                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
8606                                                 algorithm = BT_2ANT_COEX_ALGO_SCO;
8607                                         } else {
8608                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
8609                                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8610                                         }
8611                                         break;
8612                                 case (BT_INFO_HID | BT_INFO_A2DP):
8613                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
8614                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8615                                         break;
8616                                 case (BT_INFO_HID | BT_INFO_FTP):
8617                                         if (bBtHsModeExist) {
8618                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
8619                                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8620                                         } else {
8621                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
8622                                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8623                                         }
8624                                         break;
8625                                 case (BT_INFO_A2DP | BT_INFO_FTP):
8626                                         if (bBtHsModeExist) {
8627                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
8628                                                 algorithm = BT_2ANT_COEX_ALGO_A2DP;
8629                                         } else {
8630                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
8631                                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
8632                                         }
8633                                         break;
8634                                 case (BT_INFO_HID | BT_INFO_A2DP | BT_INFO_FTP):
8635                                         if (bBtHsModeExist) {
8636                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
8637                                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8638                                         } else {
8639                                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
8640                                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
8641                                         }
8642                                         break;
8643                                 }
8644                         } else {
8645                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], SCO only\n"));
8646                                 algorithm = BT_2ANT_COEX_ALGO_SCO;
8647                         }
8648                 } else {
8649                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], non SCO\n"));
8650                         switch (btInfo&0xe0) {
8651                         case BT_INFO_HID:
8652                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID\n"));
8653                                 algorithm = BT_2ANT_COEX_ALGO_HID;
8654                                 break;
8655                         case BT_INFO_A2DP:
8656                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex],  A2DP\n"));
8657                                 algorithm = BT_2ANT_COEX_ALGO_A2DP;
8658                                 break;
8659                         case BT_INFO_FTP:
8660                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], PAN(EDR)\n"));
8661                                 algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8662                                 break;
8663                         case (BT_INFO_HID | BT_INFO_A2DP):
8664                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP\n"));
8665                                 algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8666                                 break;
8667                         case (BT_INFO_HID|BT_INFO_FTP):
8668                                 if (bBtHsModeExist) {
8669                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
8670                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8671                                 } else {
8672                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
8673                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_HID;
8674                                 }
8675                                 break;
8676                         case (BT_INFO_A2DP|BT_INFO_FTP):
8677                                 if (bBtHsModeExist) {
8678                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
8679                                         algorithm = BT_2ANT_COEX_ALGO_A2DP;
8680                                 } else {
8681                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
8682                                         algorithm = BT_2ANT_COEX_ALGO_PANEDR_A2DP;
8683                                 }
8684                                 break;
8685                         case (BT_INFO_HID|BT_INFO_A2DP|BT_INFO_FTP):
8686                                 if (bBtHsModeExist) {
8687                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
8688                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP;
8689                                 } else {
8690                                         RTPRINT(FBT, BT_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
8691                                         algorithm = BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
8692                                 }
8693                                 break;
8694                         }
8695
8696                 }
8697         } else {
8698                 RTPRINT(FBT, BT_TRACE, ("[BTC2H], BTInfo: bConnect = false\n"));
8699                 pBtdm8723->btStatus = BT_2ANT_BT_STATUS_IDLE;
8700         }
8701
8702         pBtdm8723->curAlgorithm = algorithm;
8703         RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm));
8704
8705 /* From */
8706         BTDM_CheckWiFiState(padapter);
8707         if (pBtMgnt->ExtConfig.bManualControl) {
8708                 RTPRINT(FBT, BT_TRACE, ("Action Manual control, won't execute bt coexist mechanism!!\n"));
8709                 return;
8710         }
8711 }
8712
8713 void BTDM_2AntBtCoexist8723A(struct rtw_adapter *padapter)
8714 {
8715         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
8716         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
8717         struct bt_dgb *pBtDbg = &pBTInfo->BtDbg;
8718         u8 btInfoOriginal = 0;
8719         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8720         struct btdm_8723a_2ant *pBtdm8723 = &pHalData->bt_coexist.halCoex8723.btdm2Ant;
8721
8722         if (BTDM_BtProfileSupport(padapter)) {
8723                 if (pBtMgnt->ExtConfig.bHoldForBtOperation) {
8724                         RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n"));
8725                         return;
8726                 }
8727                 if (pBtMgnt->ExtConfig.bHoldPeriodCnt) {
8728                         RTPRINT(FBT, BT_TRACE, ("Hold BT inquiry/page scan setting (cnt = %d)!!\n",
8729                                 pBtMgnt->ExtConfig.bHoldPeriodCnt));
8730                         if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) {
8731                                 pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
8732                                 /*  next time the coexist parameters should be reset again. */
8733                         } else {
8734                                 pBtMgnt->ExtConfig.bHoldPeriodCnt++;
8735                         }
8736                         return;
8737                 }
8738
8739                 if (pBtDbg->dbgCtrl)
8740                         RTPRINT(FBT, BT_TRACE, ("[Dbg control], "));
8741
8742                 pBtdm8723->curAlgorithm = btdm_ActionAlgorithm(padapter);
8743                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Algorithm = %d \n", pBtdm8723->curAlgorithm));
8744
8745                 if (btdm_Is2Ant8723ACommonAction(padapter)) {
8746                         RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n"));
8747                         pBtdm8723->bResetTdmaAdjust = true;
8748                 } else {
8749                         if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) {
8750                                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n",
8751                                 pBtdm8723->preAlgorithm, pBtdm8723->curAlgorithm));
8752                                 pBtdm8723->bResetTdmaAdjust = true;
8753                         }
8754                         switch (pBtdm8723->curAlgorithm) {
8755                         case BT_2ANT_COEX_ALGO_SCO:
8756                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n"));
8757                                 btdm_2Ant8723ASCOAction(padapter);
8758                                 break;
8759                         case BT_2ANT_COEX_ALGO_HID:
8760                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n"));
8761                                 btdm_2Ant8723AHIDAction(padapter);
8762                                 break;
8763                         case BT_2ANT_COEX_ALGO_A2DP:
8764                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n"));
8765                                 btdm_2Ant8723AA2DPAction(padapter);
8766                                 break;
8767                         case BT_2ANT_COEX_ALGO_PANEDR:
8768                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n"));
8769                                 btdm_2Ant8723APANEDRAction(padapter);
8770                                 break;
8771                         case BT_2ANT_COEX_ALGO_PANHS:
8772                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n"));
8773                                 btdm_2Ant8723APANHSAction(padapter);
8774                                 break;
8775                         case BT_2ANT_COEX_ALGO_PANEDR_A2DP:
8776                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n"));
8777                                 btdm_2Ant8723APANEDRA2DPAction(padapter);
8778                                 break;
8779                         case BT_2ANT_COEX_ALGO_PANEDR_HID:
8780                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
8781                                 btdm_2Ant8723APANEDRHIDAction(padapter);
8782                                 break;
8783                         case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
8784                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
8785                                 btdm_2Ant8723AHIDA2DPPANEDRAction(padapter);
8786                                 break;
8787                         case BT_2ANT_COEX_ALGO_HID_A2DP:
8788                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n"));
8789                                 btdm_2Ant8723AHIDA2DPAction(padapter);
8790                                 break;
8791                         default:
8792                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n"));
8793                                 btdm_2Ant8723AA2DPAction(padapter);
8794                                 break;
8795                         }
8796                         pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm;
8797                 }
8798         } else {
8799                 RTPRINT(FBT, BT_TRACE, ("[BTCoex] Get bt info by fw!!\n"));
8800                 /* msg shows c2h rsp for bt_info is received or not. */
8801                 if (pHalData->bt_coexist.halCoex8723.bC2hBtInfoReqSent)
8802                         RTPRINT(FBT, BT_TRACE, ("[BTCoex] c2h for btInfo not rcvd yet!!\n"));
8803
8804                 btInfoOriginal = pHalData->bt_coexist.halCoex8723.c2hBtInfoOriginal;
8805
8806                 if (pBtMgnt->ExtConfig.bHoldForBtOperation) {
8807                         RTPRINT(FBT, BT_TRACE, ("Action for BT Operation adjust!!\n"));
8808                         return;
8809                 }
8810                 if (pBtMgnt->ExtConfig.bHoldPeriodCnt) {
8811                         RTPRINT(FBT, BT_TRACE,
8812                                 ("Hold BT inquiry/page scan setting (cnt = %d)!!\n",
8813                                 pBtMgnt->ExtConfig.bHoldPeriodCnt));
8814                         if (pBtMgnt->ExtConfig.bHoldPeriodCnt >= 11) {
8815                                 pBtMgnt->ExtConfig.bHoldPeriodCnt = 0;
8816                                 /*  next time the coexist parameters should be reset again. */
8817                         } else {
8818                                  pBtMgnt->ExtConfig.bHoldPeriodCnt++;
8819                         }
8820                         return;
8821                 }
8822
8823                 if (pBtDbg->dbgCtrl)
8824                         RTPRINT(FBT, BT_TRACE, ("[Dbg control], "));
8825                 if (btdm_Is2Ant8723ACommonAction(padapter)) {
8826                         RTPRINT(FBT, BT_TRACE, ("Action 2-Ant common.\n"));
8827                         pBtdm8723->bResetTdmaAdjust = true;
8828                 } else {
8829                         if (pBtdm8723->curAlgorithm != pBtdm8723->preAlgorithm) {
8830                                 RTPRINT(FBT, BT_TRACE,
8831                                         ("[BTCoex], preAlgorithm =%d, curAlgorithm =%d\n",
8832                                         pBtdm8723->preAlgorithm,
8833                                         pBtdm8723->curAlgorithm));
8834                                 pBtdm8723->bResetTdmaAdjust = true;
8835                         }
8836                         switch (pBtdm8723->curAlgorithm) {
8837                         case BT_2ANT_COEX_ALGO_SCO:
8838                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = SCO.\n"));
8839                                 btdm_2Ant8723ASCOAction(padapter);
8840                                 break;
8841                         case BT_2ANT_COEX_ALGO_HID:
8842                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID.\n"));
8843                                 btdm_2Ant8723AHIDAction(padapter);
8844                                 break;
8845                         case BT_2ANT_COEX_ALGO_A2DP:
8846                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = A2DP.\n"));
8847                                 btdm_2Ant8723AA2dp(padapter);
8848                                 break;
8849                         case BT_2ANT_COEX_ALGO_PANEDR:
8850                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR).\n"));
8851                                 btdm_2Ant8723APANEDRAction(padapter);
8852                                 break;
8853                         case BT_2ANT_COEX_ALGO_PANHS:
8854                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HS mode.\n"));
8855                                 btdm_2Ant8723APANHSAction(padapter);
8856                                 break;
8857                         case BT_2ANT_COEX_ALGO_PANEDR_A2DP:
8858                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN+A2DP.\n"));
8859                                 btdm_2Ant8723APANEDRA2DPAction(padapter);
8860                                 break;
8861                         case BT_2ANT_COEX_ALGO_PANEDR_HID:
8862                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = PAN(EDR)+HID.\n"));
8863                                 btdm_2Ant8723APANEDRHIDAction(padapter);
8864                                 break;
8865                         case BT_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
8866                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP+PAN.\n"));
8867                                 btdm_2Ant8723AHIDA2DPPANEDRAction(padapter);
8868                                 break;
8869                         case BT_2ANT_COEX_ALGO_HID_A2DP:
8870                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = HID+A2DP.\n"));
8871                                 btdm_2Ant8723AHIDA2DPAction(padapter);
8872                                 break;
8873                         default:
8874                                 RTPRINT(FBT, BT_TRACE, ("Action 2-Ant, algorithm = 0.\n"));
8875                                 btdm_2Ant8723AA2DPAction(padapter);
8876                                 break;
8877                         }
8878                         pBtdm8723->preAlgorithm = pBtdm8723->curAlgorithm;
8879                 }
8880         }
8881 }
8882
8883 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc87232Ant.c ===== */
8884
8885 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */
8886
8887 static u8 btCoexDbgBuf[BT_TMP_BUF_SIZE];
8888
8889 static const char *const BtProfileString[] = {
8890         "NONE",
8891         "A2DP",
8892         "PAN",
8893         "HID",
8894         "SCO",
8895 };
8896
8897 static const char *const BtSpecString[] = {
8898         "1.0b",
8899         "1.1",
8900         "1.2",
8901         "2.0+EDR",
8902         "2.1+EDR",
8903         "3.0+HS",
8904         "4.0",
8905 };
8906
8907 static const char *const BtLinkRoleString[] = {
8908         "Master",
8909         "Slave",
8910 };
8911
8912 static u8 btdm_BtWifiAntNum(struct rtw_adapter *padapter)
8913 {
8914         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8915         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
8916
8917         if (Ant_x2 == pHalData->bt_coexist.BT_Ant_Num) {
8918                 if (Ant_x2 == pBtCoex->TotalAntNum)
8919                         return Ant_x2;
8920                 else
8921                         return Ant_x1;
8922         } else {
8923                 return Ant_x1;
8924         }
8925         return Ant_x2;
8926 }
8927
8928 static void btdm_BtHwCountersMonitor(struct rtw_adapter *padapter)
8929 {
8930         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8931         u32     regHPTxRx, regLPTxRx, u4Tmp;
8932         u32     regHPTx = 0, regHPRx = 0, regLPTx = 0, regLPRx = 0;
8933
8934         regHPTxRx = REG_HIGH_PRIORITY_TXRX;
8935         regLPTxRx = REG_LOW_PRIORITY_TXRX;
8936
8937         u4Tmp = rtl8723au_read32(padapter, regHPTxRx);
8938         regHPTx = u4Tmp & bMaskLWord;
8939         regHPRx = (u4Tmp & bMaskHWord)>>16;
8940
8941         u4Tmp = rtl8723au_read32(padapter, regLPTxRx);
8942         regLPTx = u4Tmp & bMaskLWord;
8943         regLPRx = (u4Tmp & bMaskHWord)>>16;
8944
8945         pHalData->bt_coexist.halCoex8723.highPriorityTx = regHPTx;
8946         pHalData->bt_coexist.halCoex8723.highPriorityRx = regHPRx;
8947         pHalData->bt_coexist.halCoex8723.lowPriorityTx = regLPTx;
8948         pHalData->bt_coexist.halCoex8723.lowPriorityRx = regLPRx;
8949
8950         RTPRINT(FBT, BT_TRACE, ("High Priority Tx/Rx = %d / %d\n", regHPTx, regHPRx));
8951         RTPRINT(FBT, BT_TRACE, ("Low Priority Tx/Rx = %d / %d\n", regLPTx, regLPRx));
8952
8953         /*  reset counter */
8954         rtl8723au_write8(padapter, 0x76e, 0xc);
8955 }
8956
8957 /*  This function check if 8723 bt is disabled */
8958 static void btdm_BtEnableDisableCheck8723A(struct rtw_adapter *padapter)
8959 {
8960         u8 btAlife = true;
8961         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
8962
8963 #ifdef CHECK_BT_EXIST_FROM_REG
8964         u8 val8;
8965
8966         /*  ox68[28]= 1 => BT enable; otherwise disable */
8967         val8 = rtl8723au_read8(padapter, 0x6B);
8968         if (!(val8 & BIT(4)))
8969                 btAlife = false;
8970
8971         if (btAlife)
8972                 pHalData->bt_coexist.bCurBtDisabled = false;
8973         else
8974                 pHalData->bt_coexist.bCurBtDisabled = true;
8975 #else
8976         if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0 &&
8977             pHalData->bt_coexist.halCoex8723.highPriorityRx == 0 &&
8978             pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0 &&
8979             pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0)
8980                 btAlife = false;
8981         if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xeaea &&
8982             pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xeaea &&
8983             pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xeaea &&
8984             pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xeaea)
8985                 btAlife = false;
8986         if (pHalData->bt_coexist.halCoex8723.highPriorityTx == 0xffff &&
8987             pHalData->bt_coexist.halCoex8723.highPriorityRx == 0xffff &&
8988             pHalData->bt_coexist.halCoex8723.lowPriorityTx == 0xffff &&
8989             pHalData->bt_coexist.halCoex8723.lowPriorityRx == 0xffff)
8990                 btAlife = false;
8991         if (btAlife) {
8992                 pHalData->bt_coexist.btActiveZeroCnt = 0;
8993                 pHalData->bt_coexist.bCurBtDisabled = false;
8994                 RTPRINT(FBT, BT_TRACE, ("8723A BT is enabled !!\n"));
8995         } else {
8996                 pHalData->bt_coexist.btActiveZeroCnt++;
8997                 RTPRINT(FBT, BT_TRACE, ("8723A bt all counters = 0, %d times!!\n",
8998                                 pHalData->bt_coexist.btActiveZeroCnt));
8999                 if (pHalData->bt_coexist.btActiveZeroCnt >= 2) {
9000                         pHalData->bt_coexist.bCurBtDisabled = true;
9001                         RTPRINT(FBT, BT_TRACE, ("8723A BT is disabled !!\n"));
9002                 }
9003         }
9004 #endif
9005
9006         if (!pHalData->bt_coexist.bCurBtDisabled) {
9007                 if (BTDM_IsWifiConnectionExist(padapter))
9008                         BTDM_SetFwChnlInfo(padapter, RT_MEDIA_CONNECT);
9009                 else
9010                         BTDM_SetFwChnlInfo(padapter, RT_MEDIA_DISCONNECT);
9011         }
9012
9013         if (pHalData->bt_coexist.bPreBtDisabled !=
9014             pHalData->bt_coexist.bCurBtDisabled) {
9015                 RTPRINT(FBT, BT_TRACE, ("8723A BT is from %s to %s!!\n",
9016                         (pHalData->bt_coexist.bPreBtDisabled ? "disabled":"enabled"),
9017                         (pHalData->bt_coexist.bCurBtDisabled ? "disabled":"enabled")));
9018                 pHalData->bt_coexist.bPreBtDisabled = pHalData->bt_coexist.bCurBtDisabled;
9019         }
9020 }
9021
9022 static void btdm_BTCoexist8723AHandler(struct rtw_adapter *padapter)
9023 {
9024         struct hal_data_8723a *pHalData;
9025
9026         pHalData = GET_HAL_DATA(padapter);
9027
9028         if (btdm_BtWifiAntNum(padapter) == Ant_x2) {
9029                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], 2 Ant mechanism\n"));
9030                 BTDM_2AntBtCoexist8723A(padapter);
9031         } else {
9032                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], 1 Ant mechanism\n"));
9033                 BTDM_1AntBtCoexist8723A(padapter);
9034         }
9035
9036         if (!BTDM_IsSameCoexistState(padapter)) {
9037                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x\n",
9038                         pHalData->bt_coexist.PreviousState,
9039                         pHalData->bt_coexist.CurrentState));
9040                 pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState;
9041
9042                 RTPRINT(FBT, BT_TRACE, ("["));
9043                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT30)
9044                         RTPRINT(FBT, BT_TRACE, ("BT 3.0, "));
9045                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT20)
9046                         RTPRINT(FBT, BT_TRACE, ("HT20, "));
9047                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_HT40)
9048                         RTPRINT(FBT, BT_TRACE, ("HT40, "));
9049                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_LEGACY)
9050                         RTPRINT(FBT, BT_TRACE, ("Legacy, "));
9051                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_LOW)
9052                         RTPRINT(FBT, BT_TRACE, ("Rssi_Low, "));
9053                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_MEDIUM)
9054                         RTPRINT(FBT, BT_TRACE, ("Rssi_Mid, "));
9055                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_RSSI_HIGH)
9056                         RTPRINT(FBT, BT_TRACE, ("Rssi_High, "));
9057                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_IDLE)
9058                         RTPRINT(FBT, BT_TRACE, ("Wifi_Idle, "));
9059                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_UPLINK)
9060                         RTPRINT(FBT, BT_TRACE, ("Wifi_Uplink, "));
9061                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_WIFI_DOWNLINK)
9062                         RTPRINT(FBT, BT_TRACE, ("Wifi_Downlink, "));
9063                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)
9064                         RTPRINT(FBT, BT_TRACE, ("BT_idle, "));
9065                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_HID)
9066                         RTPRINT(FBT, BT_TRACE, ("PRO_HID, "));
9067                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_A2DP)
9068                         RTPRINT(FBT, BT_TRACE, ("PRO_A2DP, "));
9069                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_PAN)
9070                         RTPRINT(FBT, BT_TRACE, ("PRO_PAN, "));
9071                 if (pHalData->bt_coexist.CurrentState & BT_COEX_STATE_PROFILE_SCO)
9072                         RTPRINT(FBT, BT_TRACE, ("PRO_SCO, "));
9073                 RTPRINT(FBT, BT_TRACE, ("]\n"));
9074         }
9075 }
9076
9077 /*  extern function start with BTDM_ */
9078 u32 BTDM_BtTxRxCounterH(struct rtw_adapter *padapter)
9079 {
9080         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9081         u32     counters = 0;
9082
9083         counters = pHalData->bt_coexist.halCoex8723.highPriorityTx+
9084                 pHalData->bt_coexist.halCoex8723.highPriorityRx;
9085         return counters;
9086 }
9087
9088 u32 BTDM_BtTxRxCounterL(struct rtw_adapter *padapter)
9089 {
9090         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9091         u32     counters = 0;
9092
9093         counters = pHalData->bt_coexist.halCoex8723.lowPriorityTx+
9094                 pHalData->bt_coexist.halCoex8723.lowPriorityRx;
9095         return counters;
9096 }
9097
9098 void BTDM_SetFwChnlInfo(struct rtw_adapter *padapter, enum rt_media_status mstatus)
9099 {
9100         struct mlme_ext_priv *pmlmeext = &padapter->mlmeextpriv;
9101         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9102         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9103         u8 H2C_Parameter[3] = {0};
9104         u8 chnl;
9105
9106         /*  opMode */
9107         if (RT_MEDIA_CONNECT == mstatus)
9108                 H2C_Parameter[0] = 0x1; /*  0: disconnected, 1:connected */
9109
9110         if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE)) {
9111                 /*  channel */
9112                 chnl = pmlmeext->cur_channel;
9113                 if (BTDM_IsHT40(padapter)) {
9114                         if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_UPPER)
9115                                 chnl -= 2;
9116                         else if (pmlmeext->cur_ch_offset == HAL_PRIME_CHNL_OFFSET_LOWER)
9117                                 chnl += 2;
9118                 }
9119                 H2C_Parameter[1] = chnl;
9120         } else {        /*  check if HS link is exists */
9121                 /*  channel */
9122                 if (BT_Operation(padapter))
9123                         H2C_Parameter[1] = pBtMgnt->BTChannel;
9124                 else
9125                         H2C_Parameter[1] = pmlmeext->cur_channel;
9126         }
9127
9128         if (BTDM_IsHT40(padapter))
9129                 H2C_Parameter[2] = 0x30;
9130         else
9131                 H2C_Parameter[2] = 0x20;
9132
9133         FillH2CCmd(padapter, 0x19, 3, H2C_Parameter);
9134 }
9135
9136 u8 BTDM_IsWifiConnectionExist(struct rtw_adapter *padapter)
9137 {
9138         u8 bRet = false;
9139
9140         if (BTHCI_HsConnectionEstablished(padapter))
9141                 bRet = true;
9142
9143         if (check_fwstate(&padapter->mlmepriv, WIFI_ASOC_STATE) == true)
9144                 bRet = true;
9145
9146         return bRet;
9147 }
9148
9149 void BTDM_SetFw3a(
9150         struct rtw_adapter *padapter,
9151         u8 byte1,
9152         u8 byte2,
9153         u8 byte3,
9154         u8 byte4,
9155         u8 byte5
9156         )
9157 {
9158         u8 H2C_Parameter[5] = {0};
9159
9160         if (rtl8723a_BT_using_antenna_1(padapter)) {
9161                 if ((!check_fwstate(&padapter->mlmepriv, WIFI_STATION_STATE)) &&
9162                     (get_fwstate(&padapter->mlmepriv) != WIFI_NULL_STATE)) {
9163                         /*  for softap mode */
9164                         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9165                         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
9166                         u8 BtState = pBtCoex->c2hBtInfo;
9167
9168                         if ((BtState != BT_INFO_STATE_NO_CONNECTION) &&
9169                             (BtState != BT_INFO_STATE_CONNECT_IDLE)) {
9170                                 if (byte1 & BIT(4)) {
9171                                         byte1 &= ~BIT(4);
9172                                         byte1 |= BIT(5);
9173                                 }
9174
9175                                 byte5 |= BIT(5);
9176                                 if (byte5 & BIT(6))
9177                                         byte5 &= ~BIT(6);
9178                         }
9179                 }
9180         }
9181
9182         H2C_Parameter[0] = byte1;
9183         H2C_Parameter[1] = byte2;
9184         H2C_Parameter[2] = byte3;
9185         H2C_Parameter[3] = byte4;
9186         H2C_Parameter[4] = byte5;
9187
9188         RTPRINT(FBT, BT_TRACE, ("[BTCoex], FW write 0x3a(5bytes) = 0x%02x%08x\n",
9189                 H2C_Parameter[0],
9190                 H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
9191
9192         FillH2CCmd(padapter, 0x3a, 5, H2C_Parameter);
9193 }
9194
9195 void BTDM_QueryBtInformation(struct rtw_adapter *padapter)
9196 {
9197         u8 H2C_Parameter[1] = {0};
9198         struct hal_data_8723a *pHalData;
9199         struct bt_coexist_8723a *pBtCoex;
9200
9201         pHalData = GET_HAL_DATA(padapter);
9202         pBtCoex = &pHalData->bt_coexist.halCoex8723;
9203
9204         if (!rtl8723a_BT_enabled(padapter)) {
9205                 pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
9206                 pBtCoex->bC2hBtInfoReqSent = false;
9207                 return;
9208         }
9209
9210         if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED)
9211                 pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
9212
9213         if (pBtCoex->bC2hBtInfoReqSent == true)
9214                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], didn't recv previous BtInfo report!\n"));
9215         else
9216                 pBtCoex->bC2hBtInfoReqSent = true;
9217
9218         H2C_Parameter[0] |= BIT(0);     /*  trigger */
9219
9220 /*RTPRINT(FBT, BT_TRACE, ("[BTCoex], Query Bt information, write 0x38 = 0x%x\n", */
9221 /*H2C_Parameter[0])); */
9222
9223         FillH2CCmd(padapter, 0x38, 1, H2C_Parameter);
9224 }
9225
9226 void BTDM_SetSwRfRxLpfCorner(struct rtw_adapter *padapter, u8 type)
9227 {
9228         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9229
9230         if (BT_RF_RX_LPF_CORNER_SHRINK == type) {
9231                 /* Shrink RF Rx LPF corner */
9232                 RTPRINT(FBT, BT_TRACE, ("Shrink RF Rx LPF corner!!\n"));
9233                 PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, 0xf0ff7);
9234                 pHalData->bt_coexist.bSWCoexistAllOff = false;
9235         } else if (BT_RF_RX_LPF_CORNER_RESUME == type) {
9236                 /* Resume RF Rx LPF corner */
9237                 RTPRINT(FBT, BT_TRACE, ("Resume RF Rx LPF corner!!\n"));
9238                 PHY_SetRFReg(padapter, PathA, 0x1e, bRFRegOffsetMask, pHalData->bt_coexist.BtRfRegOrigin1E);
9239         }
9240 }
9241
9242 void
9243 BTDM_SetSwPenaltyTxRateAdaptive(
9244         struct rtw_adapter *padapter,
9245         u8 raType
9246         )
9247 {
9248         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9249         u8 tmpU1;
9250
9251         tmpU1 = rtl8723au_read8(padapter, 0x4fd);
9252         tmpU1 |= BIT(0);
9253         if (BT_TX_RATE_ADAPTIVE_LOW_PENALTY == raType) {
9254                 tmpU1 &= ~BIT(2);
9255                 pHalData->bt_coexist.bSWCoexistAllOff = false;
9256         } else if (BT_TX_RATE_ADAPTIVE_NORMAL == raType) {
9257                 tmpU1 |= BIT(2);
9258         }
9259
9260         rtl8723au_write8(padapter, 0x4fd, tmpU1);
9261 }
9262
9263 void BTDM_SetFwDecBtPwr(struct rtw_adapter *padapter, u8 bDecBtPwr)
9264 {
9265         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9266         u8 H2C_Parameter[1] = {0};
9267
9268         H2C_Parameter[0] = 0;
9269
9270         if (bDecBtPwr) {
9271                 H2C_Parameter[0] |= BIT(1);
9272                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9273         }
9274
9275         RTPRINT(FBT, BT_TRACE, ("[BTCoex], decrease Bt Power : %s, write 0x21 = 0x%x\n",
9276                 (bDecBtPwr ? "Yes!!" : "No!!"), H2C_Parameter[0]));
9277
9278         FillH2CCmd(padapter, 0x21, 1, H2C_Parameter);
9279 }
9280
9281 u8 BTDM_BtProfileSupport(struct rtw_adapter *padapter)
9282 {
9283         u8 bRet = false;
9284         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9285         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9286         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9287
9288         if (pBtMgnt->bSupportProfile &&
9289             !pHalData->bt_coexist.halCoex8723.bForceFwBtInfo)
9290                 bRet = true;
9291
9292         return bRet;
9293 }
9294
9295 static void BTDM_AdjustForBtOperation8723A(struct rtw_adapter *padapter)
9296 {
9297         /* BTDM_2AntAdjustForBtOperation8723(padapter); */
9298 }
9299
9300 static void BTDM_FwC2hBtRssi8723A(struct rtw_adapter *padapter, u8 *tmpBuf)
9301 {
9302         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9303         u8 percent = 0, u1tmp = 0;
9304
9305         u1tmp = tmpBuf[0];
9306         percent = u1tmp*2+10;
9307
9308         pHalData->bt_coexist.halCoex8723.btRssi = percent;
9309 /*RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", percent)); */
9310 }
9311
9312 void
9313 rtl8723a_fw_c2h_BT_info(struct rtw_adapter *padapter, u8 *tmpBuf, u8 length)
9314 {
9315         struct hal_data_8723a *pHalData;
9316         struct bt_30info *pBTInfo;
9317         struct bt_mgnt *pBtMgnt;
9318         struct bt_coexist_8723a *pBtCoex;
9319         u8 i;
9320
9321         pHalData = GET_HAL_DATA(padapter);
9322         pBTInfo = GET_BT_INFO(padapter);
9323         pBtMgnt = &pBTInfo->BtMgnt;
9324         pBtCoex = &pHalData->bt_coexist.halCoex8723;
9325
9326         pBtCoex->bC2hBtInfoReqSent = false;
9327
9328         RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT info[%d]=[", length));
9329
9330         pBtCoex->btRetryCnt = 0;
9331         for (i = 0; i < length; i++) {
9332                 switch (i) {
9333                 case 0:
9334                         pBtCoex->c2hBtInfoOriginal = tmpBuf[i];
9335                         break;
9336                 case 1:
9337                         pBtCoex->btRetryCnt = tmpBuf[i];
9338                         break;
9339                 case 2:
9340                         BTDM_FwC2hBtRssi8723A(padapter, &tmpBuf[i]);
9341                         break;
9342                 case 3:
9343                         pBtCoex->btInfoExt = tmpBuf[i]&BIT(0);
9344                         break;
9345                 }
9346
9347                 if (i == length-1)
9348                         RTPRINT(FBT, BT_TRACE, ("0x%02x]\n", tmpBuf[i]));
9349                 else
9350                         RTPRINT(FBT, BT_TRACE, ("0x%02x, ", tmpBuf[i]));
9351         }
9352         RTPRINT(FBT, BT_TRACE, ("[BTC2H], BT RSSI =%d\n", pBtCoex->btRssi));
9353         if (pBtCoex->btInfoExt)
9354                 RTPRINT(FBT, BT_TRACE, ("[BTC2H], pBtCoex->btInfoExt =%x\n", pBtCoex->btInfoExt));
9355
9356         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9357                 BTDM_1AntFwC2hBtInfo8723A(padapter);
9358         else
9359                 BTDM_2AntFwC2hBtInfo8723A(padapter);
9360
9361         if (pBtMgnt->ExtConfig.bManualControl) {
9362                 RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__));
9363                 return;
9364         }
9365
9366         btdm_BTCoexist8723AHandler(padapter);
9367 }
9368
9369 static void BTDM_Display8723ABtCoexInfo(struct rtw_adapter *padapter)
9370 {
9371         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9372         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
9373         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9374         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9375         u8 u1Tmp, u1Tmp1, u1Tmp2, i, btInfoExt, psTdmaCase = 0;
9376         u32 u4Tmp[4];
9377         u8 antNum = Ant_x2;
9378
9379         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============");
9380         DCMD_Printf(btCoexDbgBuf);
9381
9382         if (!rtl8723a_BT_coexist(padapter)) {
9383                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
9384                 DCMD_Printf(btCoexDbgBuf);
9385                 return;
9386         }
9387
9388         antNum = btdm_BtWifiAntNum(padapter);
9389         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/%d ", "Ant mechanism PG/Now run :", \
9390                 ((pHalData->bt_coexist.BT_Ant_Num == Ant_x2) ? 2 : 1), ((antNum == Ant_x2) ? 2 : 1));
9391         DCMD_Printf(btCoexDbgBuf);
9392
9393         if (pBtMgnt->ExtConfig.bManualControl) {
9394                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!");
9395                 DCMD_Printf(btCoexDbgBuf);
9396         } else {
9397                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \
9398                         ((pBtMgnt->bSupportProfile) ? "Yes" : "No"), pBtMgnt->ExtConfig.HCIExtensionVer);
9399                 DCMD_Printf(btCoexDbgBuf);
9400         }
9401
9402         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = / %d", "Dot11 channel / BT channel", \
9403                 pBtMgnt->BTChannel);
9404                 DCMD_Printf(btCoexDbgBuf);
9405
9406         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %d / %d / %d", "Wifi/BT/HS rssi", \
9407                 BTDM_GetRxSS(padapter),
9408                 pHalData->bt_coexist.halCoex8723.btRssi,
9409                 pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB);
9410                         DCMD_Printf(btCoexDbgBuf);
9411
9412         if (!pBtMgnt->ExtConfig.bManualControl) {
9413                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\n %-35s = %s / %s ", "WIfi status",
9414                         ((BTDM_Legacy(padapter)) ? "Legacy" : (((BTDM_IsHT40(padapter)) ? "HT40" : "HT20"))),
9415                         ((!BTDM_IsWifiBusy(padapter)) ? "idle" : ((BTDM_IsWifiUplink(padapter)) ? "uplink" : "downlink")));
9416                 DCMD_Printf(btCoexDbgBuf);
9417
9418                 if (pBtMgnt->bSupportProfile) {
9419                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP",
9420                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_SCO)) ? 1 : 0),
9421                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID)) ? 1 : 0),
9422                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) ? 1 : 0),
9423                                 ((BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) ? 1 : 0));
9424                 DCMD_Printf(btCoexDbgBuf);
9425
9426                         for (i = 0; i < pBtMgnt->ExtConfig.NumberOfHandle; i++) {
9427                                 if (pBtMgnt->ExtConfig.HCIExtensionVer >= 1) {
9428                                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %s", "Bt link type/spec/role",
9429                                                 BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile],
9430                                                 BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec],
9431                                                 BtLinkRoleString[pBtMgnt->ExtConfig.linkInfo[i].linkRole]);
9432                                         DCMD_Printf(btCoexDbgBuf);
9433
9434                                         btInfoExt = pHalData->bt_coexist.halCoex8723.btInfoExt;
9435                                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "A2DP rate", \
9436                                                  (btInfoExt & BIT(0)) ?
9437                                                  "Basic rate" : "EDR rate");
9438                                         DCMD_Printf(btCoexDbgBuf);
9439                                 } else {
9440                                         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s", "Bt link type/spec", \
9441                                                 BtProfileString[pBtMgnt->ExtConfig.linkInfo[i].BTProfile],
9442                                                 BtSpecString[pBtMgnt->ExtConfig.linkInfo[i].BTCoreSpec]);
9443                                         DCMD_Printf(btCoexDbgBuf);
9444                                 }
9445                         }
9446                 }
9447         }
9448
9449         /*  Sw mechanism */
9450         if (!pBtMgnt->ExtConfig.bManualControl) {
9451                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw BT Coex mechanism]============");
9452                 DCMD_Printf(btCoexDbgBuf);
9453                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "AGC Table", \
9454                         pBtCoex->btdm2Ant.bCurAgcTableEn);
9455                 DCMD_Printf(btCoexDbgBuf);
9456                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "ADC Backoff", \
9457                         pBtCoex->btdm2Ant.bCurAdcBackOff);
9458                 DCMD_Printf(btCoexDbgBuf);
9459                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Low penalty RA", \
9460                         pBtCoex->btdm2Ant.bCurLowPenaltyRa);
9461                 DCMD_Printf(btCoexDbgBuf);
9462                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "RF Rx LPF Shrink", \
9463                         pBtCoex->btdm2Ant.bCurRfRxLpfShrink);
9464                 DCMD_Printf(btCoexDbgBuf);
9465         }
9466         u4Tmp[0] = PHY_QueryRFReg(padapter, PathA, 0x1e, 0xff0);
9467         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "RF-A, 0x1e[11:4]/original val", \
9468                 u4Tmp[0], pHalData->bt_coexist.BtRfRegOrigin1E);
9469         DCMD_Printf(btCoexDbgBuf);
9470
9471         /*  Fw mechanism */
9472         if (!pBtMgnt->ExtConfig.bManualControl) {
9473                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw BT Coex mechanism]============");
9474                 DCMD_Printf(btCoexDbgBuf);
9475         }
9476         if (!pBtMgnt->ExtConfig.bManualControl) {
9477                 if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9478                         psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm1Ant.curPsTdma;
9479                 else
9480                         psTdmaCase = pHalData->bt_coexist.halCoex8723.btdm2Ant.curPsTdma;
9481                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA(0x3a)", \
9482                         pHalData->bt_coexist.fw3aVal[0], pHalData->bt_coexist.fw3aVal[1],
9483                         pHalData->bt_coexist.fw3aVal[2], pHalData->bt_coexist.fw3aVal[3],
9484                         pHalData->bt_coexist.fw3aVal[4], psTdmaCase);
9485                 DCMD_Printf(btCoexDbgBuf);
9486
9487                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "Decrease Bt Power", \
9488                         pBtCoex->btdm2Ant.bCurDecBtPwr);
9489                 DCMD_Printf(btCoexDbgBuf);
9490         }
9491         u1Tmp = rtl8723au_read8(padapter, 0x778);
9492         u1Tmp1 = rtl8723au_read8(padapter, 0x783);
9493         u1Tmp2 = rtl8723au_read8(padapter, 0x796);
9494         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \
9495                 u1Tmp, u1Tmp1, u1Tmp2);
9496         DCMD_Printf(btCoexDbgBuf);
9497
9498         if (!pBtMgnt->ExtConfig.bManualControl) {
9499                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x / 0x%x", "Sw DacSwing Ctrl/Val", \
9500                         pBtCoex->btdm2Ant.bCurDacSwingOn, pBtCoex->btdm2Ant.curDacSwingLvl);
9501                 DCMD_Printf(btCoexDbgBuf);
9502         }
9503         u4Tmp[0] =  rtl8723au_read32(padapter, 0x880);
9504         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \
9505                 u4Tmp[0]);
9506         DCMD_Printf(btCoexDbgBuf);
9507
9508         /*  Hw mechanism */
9509         if (!pBtMgnt->ExtConfig.bManualControl) {
9510                 rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw BT Coex mechanism]============");
9511                 DCMD_Printf(btCoexDbgBuf);
9512         }
9513
9514         u1Tmp = rtl8723au_read8(padapter, 0x40);
9515         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \
9516                 u1Tmp);
9517         DCMD_Printf(btCoexDbgBuf);
9518
9519         u4Tmp[0] = rtl8723au_read32(padapter, 0x550);
9520         u1Tmp = rtl8723au_read8(padapter, 0x522);
9521         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x", "0x550(bcn contrl)/0x522", \
9522                 u4Tmp[0], u1Tmp);
9523         DCMD_Printf(btCoexDbgBuf);
9524
9525         u4Tmp[0] = rtl8723au_read32(padapter, 0x484);
9526         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \
9527                 u4Tmp[0]);
9528         DCMD_Printf(btCoexDbgBuf);
9529
9530         u4Tmp[0] = rtl8723au_read32(padapter, 0x50);
9531         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \
9532                 u4Tmp[0]);
9533         DCMD_Printf(btCoexDbgBuf);
9534
9535         u4Tmp[0] = rtl8723au_read32(padapter, 0xda0);
9536         u4Tmp[1] = rtl8723au_read32(padapter, 0xda4);
9537         u4Tmp[2] = rtl8723au_read32(padapter, 0xda8);
9538         u4Tmp[3] = rtl8723au_read32(padapter, 0xdac);
9539         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \
9540                 u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]);
9541         DCMD_Printf(btCoexDbgBuf);
9542
9543         u4Tmp[0] = rtl8723au_read32(padapter, 0x6c0);
9544         u4Tmp[1] = rtl8723au_read32(padapter, 0x6c4);
9545         u4Tmp[2] = rtl8723au_read32(padapter, 0x6c8);
9546         u1Tmp = rtl8723au_read8(padapter, 0x6cc);
9547         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \
9548                 u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp);
9549         DCMD_Printf(btCoexDbgBuf);
9550
9551         /* u4Tmp = rtl8723au_read32(padapter, 0x770); */
9552         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x770(Hi pri Rx[31:16]/Tx[15:0])", \
9553                 pHalData->bt_coexist.halCoex8723.highPriorityRx,
9554                 pHalData->bt_coexist.halCoex8723.highPriorityTx);
9555         DCMD_Printf(btCoexDbgBuf);
9556         /* u4Tmp = rtl8723au_read32(padapter, 0x774); */
9557         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d", "0x774(Lo pri Rx[31:16]/Tx[15:0])", \
9558                 pHalData->bt_coexist.halCoex8723.lowPriorityRx,
9559                 pHalData->bt_coexist.halCoex8723.lowPriorityTx);
9560         DCMD_Printf(btCoexDbgBuf);
9561
9562         /*  Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang */
9563         u1Tmp = rtl8723au_read8(padapter, 0x41b);
9564         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (hang chk == 0xf)", \
9565                 u1Tmp);
9566         DCMD_Printf(btCoexDbgBuf);
9567         rsprintf(btCoexDbgBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "lastHMEBoxNum", \
9568                 pHalData->LastHMEBoxNum);
9569         DCMD_Printf(btCoexDbgBuf);
9570 }
9571
9572 static void
9573 BTDM_8723ASignalCompensation(struct rtw_adapter *padapter,
9574                              u8 *rssi_wifi, u8 *rssi_bt)
9575 {
9576         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9577                 BTDM_1AntSignalCompensation(padapter, rssi_wifi, rssi_bt);
9578 }
9579
9580 static void BTDM_8723AInit(struct rtw_adapter *padapter)
9581 {
9582         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9583                 BTDM_2AntParaInit(padapter);
9584         else
9585                 BTDM_1AntParaInit(padapter);
9586 }
9587
9588 static void BTDM_HWCoexAllOff8723A(struct rtw_adapter *padapter)
9589 {
9590         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9591         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9592
9593         if (pBtMgnt->ExtConfig.bManualControl)
9594                 return;
9595
9596         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9597                 BTDM_2AntHwCoexAllOff8723A(padapter);
9598 }
9599
9600 static void BTDM_FWCoexAllOff8723A(struct rtw_adapter *padapter)
9601 {
9602         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9603         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9604
9605         if (pBtMgnt->ExtConfig.bManualControl)
9606                 return;
9607
9608         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9609                 BTDM_2AntFwCoexAllOff8723A(padapter);
9610 }
9611
9612 static void BTDM_SWCoexAllOff8723A(struct rtw_adapter *padapter)
9613 {
9614         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9615         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9616
9617         if (pBtMgnt->ExtConfig.bManualControl)
9618                 return;
9619
9620         if (btdm_BtWifiAntNum(padapter) == Ant_x2)
9621                 BTDM_2AntSwCoexAllOff8723A(padapter);
9622 }
9623
9624 static void
9625 BTDM_Set8723ABtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
9626 {
9627         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9628         struct bt_coexist_8723a *pBtCoex = &pHalData->bt_coexist.halCoex8723;
9629
9630         if (antNum == 1)
9631                 pBtCoex->TotalAntNum = Ant_x1;
9632         else if (antNum == 2)
9633                 pBtCoex->TotalAntNum = Ant_x2;
9634 }
9635
9636 void rtl8723a_BT_lps_leave(struct rtw_adapter *padapter)
9637 {
9638         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9639         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9640
9641         if (pBtMgnt->ExtConfig.bManualControl)
9642                 return;
9643
9644         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9645                 BTDM_1AntLpsLeave(padapter);
9646 }
9647
9648 static void BTDM_ForHalt8723A(struct rtw_adapter *padapter)
9649 {
9650         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9651         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9652
9653         if (pBtMgnt->ExtConfig.bManualControl)
9654                 return;
9655
9656         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9657                 BTDM_1AntForHalt(padapter);
9658 }
9659
9660 static void BTDM_WifiScanNotify8723A(struct rtw_adapter *padapter, u8 scanType)
9661 {
9662         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9663         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9664
9665         if (pBtMgnt->ExtConfig.bManualControl)
9666                 return;
9667
9668         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9669                 BTDM_1AntWifiScanNotify(padapter, scanType);
9670 }
9671
9672 static void
9673 BTDM_WifiAssociateNotify8723A(struct rtw_adapter *padapter, u8 action)
9674 {
9675         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9676         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9677
9678         if (pBtMgnt->ExtConfig.bManualControl)
9679                 return;
9680
9681         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9682                 BTDM_1AntWifiAssociateNotify(padapter, action);
9683 }
9684
9685 static void
9686 BTDM_MediaStatusNotify8723A(struct rtw_adapter *padapter,
9687                             enum rt_media_status mstatus)
9688 {
9689         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9690         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9691
9692         RTPRINT(FBT, BT_TRACE, ("[BTCoex], MediaStatusNotify, %s\n",
9693                 mstatus?"connect":"disconnect"));
9694
9695         BTDM_SetFwChnlInfo(padapter, mstatus);
9696
9697         if (pBtMgnt->ExtConfig.bManualControl)
9698                 return;
9699
9700         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9701                 BTDM_1AntMediaStatusNotify(padapter, mstatus);
9702 }
9703
9704 static void BTDM_ForDhcp8723A(struct rtw_adapter *padapter)
9705 {
9706         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9707         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9708
9709         if (pBtMgnt->ExtConfig.bManualControl)
9710                 return;
9711
9712         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9713                 BTDM_1AntForDhcp(padapter);
9714 }
9715
9716 bool rtl8723a_BT_using_antenna_1(struct rtw_adapter *padapter)
9717 {
9718         if (btdm_BtWifiAntNum(padapter) == Ant_x1)
9719                 return true;
9720         else
9721                 return false;
9722 }
9723
9724 static void BTDM_BTCoexist8723A(struct rtw_adapter *padapter)
9725 {
9726         struct hal_data_8723a *pHalData;
9727         struct bt_30info *pBTInfo;
9728         struct bt_mgnt *pBtMgnt;
9729         struct bt_coexist_8723a *pBtCoex;
9730
9731         pHalData = GET_HAL_DATA(padapter);
9732         pBTInfo = GET_BT_INFO(padapter);
9733         pBtMgnt = &pBTInfo->BtMgnt;
9734         pBtCoex = &pHalData->bt_coexist.halCoex8723;
9735
9736         RTPRINT(FBT, BT_TRACE, ("[BTCoex], beacon RSSI = 0x%x(%d)\n",
9737                 pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB,
9738                 pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB));
9739
9740         btdm_BtHwCountersMonitor(padapter);
9741         btdm_BtEnableDisableCheck8723A(padapter);
9742
9743         if (pBtMgnt->ExtConfig.bManualControl) {
9744                 RTPRINT(FBT, BT_TRACE, ("%s: Action Manual control!!\n", __func__));
9745                 return;
9746         }
9747
9748         if (pBtCoex->bC2hBtInfoReqSent) {
9749                 if (!rtl8723a_BT_enabled(padapter)) {
9750                         pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
9751                 } else {
9752                         if (pBtCoex->c2hBtInfo == BT_INFO_STATE_DISABLED)
9753                                 pBtCoex->c2hBtInfo = BT_INFO_STATE_NO_CONNECTION;
9754                 }
9755
9756                 btdm_BTCoexist8723AHandler(padapter);
9757         } else if (!rtl8723a_BT_enabled(padapter)) {
9758                 pBtCoex->c2hBtInfo = BT_INFO_STATE_DISABLED;
9759                 btdm_BTCoexist8723AHandler(padapter);
9760         }
9761
9762         BTDM_QueryBtInformation(padapter);
9763 }
9764
9765 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtc8723.c ===== */
9766
9767 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */
9768
9769 /*  local function start with btdm_ */
9770 /*  extern function start with BTDM_ */
9771
9772 static void BTDM_SetAntenna(struct rtw_adapter *padapter, u8 who)
9773 {
9774 }
9775
9776 void
9777 BTDM_SingleAnt(
9778         struct rtw_adapter *padapter,
9779         u8 bSingleAntOn,
9780         u8 bInterruptOn,
9781         u8 bMultiNAVOn
9782         )
9783 {
9784         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9785         u8 H2C_Parameter[3] = {0};
9786
9787         if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1)
9788                 return;
9789
9790         H2C_Parameter[2] = 0;
9791         H2C_Parameter[1] = 0;
9792         H2C_Parameter[0] = 0;
9793
9794         if (bInterruptOn) {
9795                 H2C_Parameter[2] |= 0x02;       /* BIT1 */
9796                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9797         }
9798         pHalData->bt_coexist.bInterruptOn = bInterruptOn;
9799
9800         if (bSingleAntOn) {
9801                 H2C_Parameter[2] |= 0x10;       /* BIT4 */
9802                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9803         }
9804         pHalData->bt_coexist.bSingleAntOn = bSingleAntOn;
9805
9806         if (bMultiNAVOn) {
9807                 H2C_Parameter[2] |= 0x20;       /* BIT5 */
9808                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9809         }
9810         pHalData->bt_coexist.bMultiNAVOn = bMultiNAVOn;
9811
9812         RTPRINT(FBT, BT_TRACE, ("[DM][BT], SingleAntenna =[%s:%s:%s], write 0xe = 0x%x\n",
9813                 bSingleAntOn?"ON":"OFF", bInterruptOn?"ON":"OFF", bMultiNAVOn?"ON":"OFF",
9814                 H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
9815 }
9816
9817 void BTDM_CheckBTIdleChange1Ant(struct rtw_adapter *padapter)
9818 {
9819         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
9820         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
9821         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9822 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
9823         u8      stateChange = false;
9824         u32                     BT_Polling, Ratio_Act, Ratio_STA;
9825         u32                             BT_Active, BT_State;
9826         u32                             regBTActive = 0, regBTState = 0, regBTPolling = 0;
9827
9828         if (!rtl8723a_BT_coexist(padapter))
9829                 return;
9830         if (pBtMgnt->ExtConfig.bManualControl)
9831                 return;
9832         if (pHalData->bt_coexist.BT_CoexistType != BT_CSR_BC8)
9833                 return;
9834         if (pHalData->bt_coexist.BT_Ant_Num != Ant_x1)
9835                 return;
9836
9837         /*  The following we only consider CSR BC8 and fw version should be >= 62 */
9838         RTPRINT(FBT, BT_TRACE, ("[DM][BT], FirmwareVersion = 0x%x(%d)\n",
9839         pHalData->FirmwareVersion, pHalData->FirmwareVersion));
9840         regBTActive = REG_BT_ACTIVE;
9841         regBTState = REG_BT_STATE;
9842         if (pHalData->FirmwareVersion >= FW_VER_BT_REG1)
9843                 regBTPolling = REG_BT_POLLING1;
9844         else
9845                 regBTPolling = REG_BT_POLLING;
9846
9847         BT_Active = rtl8723au_read32(padapter, regBTActive);
9848         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Active(0x%x) =%x\n", regBTActive, BT_Active));
9849         BT_Active = BT_Active & 0x00ffffff;
9850
9851         BT_State = rtl8723au_read32(padapter, regBTState);
9852         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_State(0x%x) =%x\n", regBTState, BT_State));
9853         BT_State = BT_State & 0x00ffffff;
9854
9855         BT_Polling = rtl8723au_read32(padapter, regBTPolling);
9856         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT_Polling(0x%x) =%x\n", regBTPolling, BT_Polling));
9857
9858         if (BT_Active == 0xffffffff && BT_State == 0xffffffff && BT_Polling == 0xffffffff)
9859                 return;
9860         if (BT_Polling == 0)
9861                 return;
9862
9863         Ratio_Act = BT_Active*1000/BT_Polling;
9864         Ratio_STA = BT_State*1000/BT_Polling;
9865
9866         pHalData->bt_coexist.Ratio_Tx = Ratio_Act;
9867         pHalData->bt_coexist.Ratio_PRI = Ratio_STA;
9868
9869         RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_Act =%d\n", Ratio_Act));
9870         RTPRINT(FBT, BT_TRACE, ("[DM][BT], Ratio_STA =%d\n", Ratio_STA));
9871
9872         if (Ratio_STA < 60 && Ratio_Act < 500) {        /*  BT PAN idle */
9873                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_IDLE;
9874                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK;
9875                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
9876         } else {
9877                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_IDLE;
9878
9879                 if (Ratio_STA) {
9880                         /*  Check if BT PAN (under BT 2.1) is uplink or downlink */
9881                         if ((Ratio_Act/Ratio_STA) < 2) {
9882                                 /*  BT PAN Uplink */
9883                                 pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = true;
9884                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_UPLINK;
9885                                 pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = false;
9886                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_DOWNLINK;
9887                         } else {
9888                                 /*  BT PAN downlink */
9889                                 pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false;
9890                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
9891                                 pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true;
9892                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK;
9893                         }
9894                 } else {
9895                         /*  BT PAN downlink */
9896                         pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic = false;
9897                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_PAN_UPLINK;
9898                         pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic = true;
9899                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_PAN_DOWNLINK;
9900                 }
9901         }
9902
9903         /*  Check BT is idle or not */
9904         if (pBtMgnt->ExtConfig.NumberOfHandle == 0 &&
9905             pBtMgnt->ExtConfig.NumberOfSCO == 0) {
9906                 pBtMgnt->ExtConfig.bBTBusy = false;
9907                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
9908         } else {
9909                 if (Ratio_STA < 60) {
9910                         pBtMgnt->ExtConfig.bBTBusy = false;
9911                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_IDLE;
9912                 } else {
9913                         pBtMgnt->ExtConfig.bBTBusy = true;
9914                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_IDLE;
9915                 }
9916         }
9917
9918         if (pBtMgnt->ExtConfig.NumberOfHandle == 0 &&
9919             pBtMgnt->ExtConfig.NumberOfSCO == 0) {
9920                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW;
9921                 pBtMgnt->ExtConfig.MIN_BT_RSSI = 0;
9922                 BTDM_SetAntenna(padapter, BTDM_ANT_BT_IDLE);
9923         } else {
9924                 if (pBtMgnt->ExtConfig.MIN_BT_RSSI <= -5) {
9925                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT_RSSI_LOW;
9926                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Low\n"));
9927                 } else {
9928                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT_RSSI_LOW;
9929                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], core stack notify bt rssi Normal\n"));
9930                 }
9931         }
9932
9933         if (pHalData->bt_coexist.bBTBusyTraffic != pBtMgnt->ExtConfig.bBTBusy) {
9934                 /*  BT idle or BT non-idle */
9935                 pHalData->bt_coexist.bBTBusyTraffic = pBtMgnt->ExtConfig.bBTBusy;
9936                 stateChange = true;
9937         }
9938
9939         if (stateChange) {
9940                 if (!pBtMgnt->ExtConfig.bBTBusy)
9941                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n"));
9942                 else
9943                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is non-idle\n"));
9944         }
9945         if (!pBtMgnt->ExtConfig.bBTBusy) {
9946                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT is idle or disable\n"));
9947                 if (check_fwstate(&padapter->mlmepriv, WIFI_UNDER_LINKING|WIFI_SITE_MONITOR) == true)
9948                         BTDM_SetAntenna(padapter, BTDM_ANT_WIFI);
9949         }
9950 }
9951
9952 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr1Ant.c ===== */
9953
9954 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */
9955
9956 /*  local function start with btdm_ */
9957
9958 /*  Note: */
9959 /*  In the following, FW should be done before SW mechanism. */
9960 /*  BTDM_Balance(), BTDM_DiminishWiFi(), BT_NAV() should be done */
9961 /*  before BTDM_AGCTable(), BTDM_BBBackOffLevel(), btdm_DacSwing(). */
9962
9963 /*  extern function start with BTDM_ */
9964
9965 void
9966 BTDM_DiminishWiFi(
9967         struct rtw_adapter *padapter,
9968         u8 bDACOn,
9969         u8 bInterruptOn,
9970         u8 DACSwingLevel,
9971         u8 bNAVOn
9972         )
9973 {
9974         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
9975         u8 H2C_Parameter[3] = {0};
9976
9977         if (pHalData->bt_coexist.BT_Ant_Num != Ant_x2)
9978                 return;
9979
9980         if ((pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_RSSI_LOW) &&
9981             (DACSwingLevel == 0x20)) {
9982                 RTPRINT(FBT, BT_TRACE, ("[BT]DiminishWiFi 0x20 original, but set 0x18 for Low RSSI!\n"));
9983                 DACSwingLevel = 0x18;
9984         }
9985
9986         H2C_Parameter[2] = 0;
9987         H2C_Parameter[1] = DACSwingLevel;
9988         H2C_Parameter[0] = 0;
9989         if (bDACOn) {
9990                 H2C_Parameter[2] |= 0x01;       /* BIT0 */
9991                 if (bInterruptOn)
9992                         H2C_Parameter[2] |= 0x02;       /* BIT1 */
9993                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9994         }
9995         if (bNAVOn) {
9996                 H2C_Parameter[2] |= 0x08;       /* BIT3 */
9997                 pHalData->bt_coexist.bFWCoexistAllOff = false;
9998         }
9999
10000         RTPRINT(FBT, BT_TRACE, ("[DM][BT], bDACOn = %s, bInterruptOn = %s, write 0xe = 0x%x\n",
10001                 bDACOn?"ON":"OFF", bInterruptOn?"ON":"OFF",
10002                 H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
10003         RTPRINT(FBT, BT_TRACE, ("[DM][BT], bNAVOn = %s\n",
10004                 bNAVOn?"ON":"OFF"));
10005 }
10006
10007 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtcCsr2Ant.c ===== */
10008
10009 /*  ===== Below this line is sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */
10010
10011 /*  local function */
10012 static void btdm_ResetFWCoexState(struct rtw_adapter *padapter)
10013 {
10014         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10015
10016         pHalData->bt_coexist.CurrentState = 0;
10017         pHalData->bt_coexist.PreviousState = 0;
10018 }
10019
10020 static void btdm_InitBtCoexistDM(struct rtw_adapter *padapter)
10021 {
10022         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10023
10024         /*  20100415 Joseph: Restore RF register 0x1E and 0x1F value for further usage. */
10025         pHalData->bt_coexist.BtRfRegOrigin1E = PHY_QueryRFReg(padapter, PathA, RF_RCK1, bRFRegOffsetMask);
10026         pHalData->bt_coexist.BtRfRegOrigin1F = PHY_QueryRFReg(padapter, PathA, RF_RCK2, 0xf0);
10027
10028         pHalData->bt_coexist.CurrentState = 0;
10029         pHalData->bt_coexist.PreviousState = 0;
10030
10031         BTDM_8723AInit(padapter);
10032         pHalData->bt_coexist.bInitlized = true;
10033 }
10034
10035 /*  */
10036 /*  extern function */
10037 /*  */
10038 void BTDM_CheckAntSelMode(struct rtw_adapter *padapter)
10039 {
10040 }
10041
10042 void BTDM_FwC2hBtRssi(struct rtw_adapter *padapter, u8 *tmpBuf)
10043 {
10044         BTDM_FwC2hBtRssi8723A(padapter, tmpBuf);
10045 }
10046
10047 void BTDM_DisplayBtCoexInfo(struct rtw_adapter *padapter)
10048 {
10049         BTDM_Display8723ABtCoexInfo(padapter);
10050 }
10051
10052 void BTDM_RejectAPAggregatedPacket(struct rtw_adapter *padapter, u8 bReject)
10053 {
10054 }
10055
10056 u8 BTDM_IsHT40(struct rtw_adapter *padapter)
10057 {
10058         u8 isht40 = true;
10059         enum ht_channel_width bw;
10060
10061         bw = padapter->mlmeextpriv.cur_bwmode;
10062
10063         if (bw == HT_CHANNEL_WIDTH_20)
10064                 isht40 = false;
10065         else if (bw == HT_CHANNEL_WIDTH_40)
10066                 isht40 = true;
10067
10068         return isht40;
10069 }
10070
10071 u8 BTDM_Legacy(struct rtw_adapter *padapter)
10072 {
10073         struct mlme_ext_priv *pmlmeext;
10074         u8 isLegacy = false;
10075
10076         pmlmeext = &padapter->mlmeextpriv;
10077         if ((pmlmeext->cur_wireless_mode == WIRELESS_11B) ||
10078                 (pmlmeext->cur_wireless_mode == WIRELESS_11G) ||
10079                 (pmlmeext->cur_wireless_mode == WIRELESS_11BG))
10080                 isLegacy = true;
10081
10082         return isLegacy;
10083 }
10084
10085 void BTDM_CheckWiFiState(struct rtw_adapter *padapter)
10086 {
10087         struct hal_data_8723a *pHalData;
10088         struct mlme_priv *pmlmepriv;
10089         struct bt_30info *pBTInfo;
10090         struct bt_mgnt *pBtMgnt;
10091
10092         pHalData = GET_HAL_DATA(padapter);
10093         pmlmepriv = &padapter->mlmepriv;
10094         pBTInfo = GET_BT_INFO(padapter);
10095         pBtMgnt = &pBTInfo->BtMgnt;
10096
10097         if (pmlmepriv->LinkDetectInfo.bBusyTraffic) {
10098                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_IDLE;
10099
10100                 if (pmlmepriv->LinkDetectInfo.bTxBusyTraffic)
10101                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_UPLINK;
10102                 else
10103                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK;
10104
10105                 if (pmlmepriv->LinkDetectInfo.bRxBusyTraffic)
10106                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_DOWNLINK;
10107                 else
10108                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK;
10109         } else {
10110                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_IDLE;
10111                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_UPLINK;
10112                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_DOWNLINK;
10113         }
10114
10115         if (BTDM_Legacy(padapter)) {
10116                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_LEGACY;
10117                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20;
10118                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40;
10119         } else {
10120                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_LEGACY;
10121                 if (BTDM_IsHT40(padapter)) {
10122                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT40;
10123                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT20;
10124                 } else {
10125                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_HT20;
10126                         pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_HT40;
10127                 }
10128         }
10129
10130         if (pBtMgnt->BtOperationOn)
10131                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_BT30;
10132         else
10133                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_BT30;
10134 }
10135
10136 s32 BTDM_GetRxSS(struct rtw_adapter *padapter)
10137 {
10138 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
10139         struct mlme_priv *pmlmepriv;
10140         struct hal_data_8723a *pHalData;
10141         s32                     UndecoratedSmoothedPWDB = 0;
10142
10143         pmlmepriv = &padapter->mlmepriv;
10144         pHalData = GET_HAL_DATA(padapter);
10145
10146         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
10147                 UndecoratedSmoothedPWDB = GET_UNDECORATED_AVERAGE_RSSI(padapter);
10148         } else { /*  associated entry pwdb */
10149                 UndecoratedSmoothedPWDB = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB;
10150                 /* pHalData->BT_EntryMinUndecoratedSmoothedPWDB */
10151         }
10152         RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxSS() = %d\n", UndecoratedSmoothedPWDB));
10153         return UndecoratedSmoothedPWDB;
10154 }
10155
10156 static s32 BTDM_GetRxBeaconSS(struct rtw_adapter *padapter)
10157 {
10158 /*PMGNT_INFO            pMgntInfo = &padapter->MgntInfo; */
10159         struct mlme_priv *pmlmepriv;
10160         struct hal_data_8723a *pHalData;
10161         s32                     pwdbBeacon = 0;
10162
10163         pmlmepriv = &padapter->mlmepriv;
10164         pHalData = GET_HAL_DATA(padapter);
10165
10166         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
10167                 /* pwdbBeacon = pHalData->dmpriv.UndecoratedSmoothedBeacon; */
10168                 pwdbBeacon = pHalData->dmpriv.EntryMinUndecoratedSmoothedPWDB;
10169         }
10170         RTPRINT(FBT, BT_TRACE, ("BTDM_GetRxBeaconSS() = %d\n", pwdbBeacon));
10171         return pwdbBeacon;
10172 }
10173
10174 /*  Get beacon rssi state */
10175 u8 BTDM_CheckCoexBcnRssiState(struct rtw_adapter *padapter, u8 levelNum,
10176                               u8 RssiThresh, u8 RssiThresh1)
10177 {
10178         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10179         s32 pwdbBeacon = 0;
10180         u8 bcnRssiState = 0;
10181
10182         pwdbBeacon = BTDM_GetRxBeaconSS(padapter);
10183
10184         if (levelNum == 2) {
10185                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10186
10187                 if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) ||
10188                     (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) {
10189                         if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10190                                 bcnRssiState = BT_RSSI_STATE_HIGH;
10191                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10192                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10193                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n"));
10194                         } else {
10195                                 bcnRssiState = BT_RSSI_STATE_STAY_LOW;
10196                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n"));
10197                         }
10198                 } else {
10199                         if (pwdbBeacon < RssiThresh) {
10200                                 bcnRssiState = BT_RSSI_STATE_LOW;
10201                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10202                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10203                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n"));
10204                         } else {
10205                                 bcnRssiState = BT_RSSI_STATE_STAY_HIGH;
10206                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n"));
10207                         }
10208                 }
10209         } else if (levelNum == 3) {
10210                 if (RssiThresh > RssiThresh1) {
10211                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON thresh error!!\n"));
10212                         return pHalData->bt_coexist.preRssiStateBeacon;
10213                 }
10214
10215                 if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_LOW) ||
10216                     (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_LOW)) {
10217                         if (pwdbBeacon >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10218                                 bcnRssiState = BT_RSSI_STATE_MEDIUM;
10219                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10220                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10221                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10222                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n"));
10223                         } else {
10224                                 bcnRssiState = BT_RSSI_STATE_STAY_LOW;
10225                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Low\n"));
10226                         }
10227                 } else if ((pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_MEDIUM) ||
10228                            (pHalData->bt_coexist.preRssiStateBeacon == BT_RSSI_STATE_STAY_MEDIUM)) {
10229                         if (pwdbBeacon >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
10230                                 bcnRssiState = BT_RSSI_STATE_HIGH;
10231                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10232                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10233                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10234                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to High\n"));
10235                         } else if (pwdbBeacon < RssiThresh) {
10236                                 bcnRssiState = BT_RSSI_STATE_LOW;
10237                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10238                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10239                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10240                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Low\n"));
10241                         } else {
10242                                 bcnRssiState = BT_RSSI_STATE_STAY_MEDIUM;
10243                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at Medium\n"));
10244                         }
10245                 } else {
10246                         if (pwdbBeacon < RssiThresh1) {
10247                                 bcnRssiState = BT_RSSI_STATE_MEDIUM;
10248                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_BEACON_MEDIUM;
10249                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_HIGH;
10250                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_BEACON_LOW;
10251                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state switch to Medium\n"));
10252                         } else {
10253                                 bcnRssiState = BT_RSSI_STATE_STAY_HIGH;
10254                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_BEACON state stay at High\n"));
10255                         }
10256                 }
10257         }
10258
10259         pHalData->bt_coexist.preRssiStateBeacon = bcnRssiState;
10260
10261         return bcnRssiState;
10262 }
10263
10264 u8 BTDM_CheckCoexRSSIState1(struct rtw_adapter *padapter, u8 levelNum,
10265                             u8 RssiThresh, u8 RssiThresh1)
10266 {
10267         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10268         s32 UndecoratedSmoothedPWDB = 0;
10269         u8 btRssiState = 0;
10270
10271         UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter);
10272
10273         if (levelNum == 2) {
10274                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10275
10276                 if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) ||
10277                     (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) {
10278                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10279                                 btRssiState = BT_RSSI_STATE_HIGH;
10280                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10281                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10282                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
10283                         } else {
10284                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10285                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
10286                         }
10287                 } else {
10288                         if (UndecoratedSmoothedPWDB < RssiThresh) {
10289                                 btRssiState = BT_RSSI_STATE_LOW;
10290                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
10291                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10292                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
10293                         } else {
10294                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10295                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
10296                         }
10297                 }
10298         } else if (levelNum == 3) {
10299                 if (RssiThresh > RssiThresh1) {
10300                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 thresh error!!\n"));
10301                         return pHalData->bt_coexist.preRssiState1;
10302                 }
10303
10304                 if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_LOW) ||
10305                     (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_LOW)) {
10306                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10307                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10308                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10309                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10310                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10311                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
10312                         } else {
10313                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10314                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Low\n"));
10315                         }
10316                 } else if ((pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_MEDIUM) ||
10317                            (pHalData->bt_coexist.preRssiState1 == BT_RSSI_STATE_STAY_MEDIUM)) {
10318                         if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
10319                                 btRssiState = BT_RSSI_STATE_HIGH;
10320                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10321                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10322                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10323                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to High\n"));
10324                         } else if (UndecoratedSmoothedPWDB < RssiThresh) {
10325                                 btRssiState = BT_RSSI_STATE_LOW;
10326                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_LOW;
10327                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10328                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10329                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Low\n"));
10330                         } else {
10331                                 btRssiState = BT_RSSI_STATE_STAY_MEDIUM;
10332                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at Medium\n"));
10333                         }
10334                 } else {
10335                         if (UndecoratedSmoothedPWDB < RssiThresh1) {
10336                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10337                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
10338                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
10339                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_1_LOW;
10340                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state switch to Medium\n"));
10341                         } else {
10342                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10343                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI_1 state stay at High\n"));
10344                         }
10345                 }
10346         }
10347
10348         pHalData->bt_coexist.preRssiState1 = btRssiState;
10349
10350         return btRssiState;
10351 }
10352
10353 u8 BTDM_CheckCoexRSSIState(struct rtw_adapter *padapter, u8 levelNum,
10354                            u8 RssiThresh, u8 RssiThresh1)
10355 {
10356         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10357         s32 UndecoratedSmoothedPWDB = 0;
10358         u8 btRssiState = 0;
10359
10360         UndecoratedSmoothedPWDB = BTDM_GetRxSS(padapter);
10361
10362         if (levelNum == 2) {
10363                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10364
10365                 if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) ||
10366                     (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) {
10367                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10368                                 btRssiState = BT_RSSI_STATE_HIGH;
10369                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH;
10370                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10371                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n"));
10372                         } else {
10373                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10374                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n"));
10375                         }
10376                 } else {
10377                         if (UndecoratedSmoothedPWDB < RssiThresh) {
10378                                 btRssiState = BT_RSSI_STATE_LOW;
10379                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW;
10380                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10381                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n"));
10382                         } else {
10383                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10384                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n"));
10385                         }
10386                 }
10387         } else if (levelNum == 3) {
10388                 if (RssiThresh > RssiThresh1) {
10389                         RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI thresh error!!\n"));
10390                         return pHalData->bt_coexist.preRssiState;
10391                 }
10392
10393                 if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_LOW) ||
10394                     (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_LOW)) {
10395                         if (UndecoratedSmoothedPWDB >= (RssiThresh+BT_FW_COEX_THRESH_TOL)) {
10396                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10397                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10398                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10399                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10400                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n"));
10401                         } else {
10402                                 btRssiState = BT_RSSI_STATE_STAY_LOW;
10403                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Low\n"));
10404                         }
10405                 } else if ((pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_MEDIUM) ||
10406                            (pHalData->bt_coexist.preRssiState == BT_RSSI_STATE_STAY_MEDIUM)) {
10407                         if (UndecoratedSmoothedPWDB >= (RssiThresh1+BT_FW_COEX_THRESH_TOL)) {
10408                                 btRssiState = BT_RSSI_STATE_HIGH;
10409                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_HIGH;
10410                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10411                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10412                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to High\n"));
10413                         } else if (UndecoratedSmoothedPWDB < RssiThresh) {
10414                                 btRssiState = BT_RSSI_STATE_LOW;
10415                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_LOW;
10416                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10417                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10418                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Low\n"));
10419                         } else {
10420                                 btRssiState = BT_RSSI_STATE_STAY_MEDIUM;
10421                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at Medium\n"));
10422                         }
10423                 } else {
10424                         if (UndecoratedSmoothedPWDB < RssiThresh1) {
10425                                 btRssiState = BT_RSSI_STATE_MEDIUM;
10426                                 pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
10427                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
10428                                 pHalData->bt_coexist.CurrentState &= ~BT_COEX_STATE_WIFI_RSSI_LOW;
10429                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state switch to Medium\n"));
10430                         } else {
10431                                 btRssiState = BT_RSSI_STATE_STAY_HIGH;
10432                                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], RSSI state stay at High\n"));
10433                         }
10434                 }
10435         }
10436
10437         pHalData->bt_coexist.preRssiState = btRssiState;
10438
10439         return btRssiState;
10440 }
10441
10442 bool rtl8723a_BT_disable_EDCA_turbo(struct rtw_adapter *padapter)
10443 {
10444         struct bt_mgnt *pBtMgnt;
10445         struct hal_data_8723a *pHalData;
10446         u8 bBtChangeEDCA = false;
10447         u32 EDCA_BT_BE = 0x5ea42b, cur_EDCA_reg;
10448         bool bRet = false;
10449
10450         pHalData = GET_HAL_DATA(padapter);
10451         pBtMgnt = &pHalData->BtInfo.BtMgnt;
10452
10453         if (!rtl8723a_BT_coexist(padapter)) {
10454                 bRet = false;
10455                 pHalData->bt_coexist.lastBtEdca = 0;
10456                 return bRet;
10457         }
10458         if (!((pBtMgnt->bSupportProfile) ||
10459             (pHalData->bt_coexist.BT_CoexistType == BT_CSR_BC8))) {
10460                 bRet = false;
10461                 pHalData->bt_coexist.lastBtEdca = 0;
10462                 return bRet;
10463         }
10464
10465         if (rtl8723a_BT_using_antenna_1(padapter)) {
10466                 bRet = false;
10467                 pHalData->bt_coexist.lastBtEdca = 0;
10468                 return bRet;
10469         }
10470
10471         if (pHalData->bt_coexist.exec_cnt < 3)
10472                 pHalData->bt_coexist.exec_cnt++;
10473         else
10474                 pHalData->bt_coexist.bEDCAInitialized = true;
10475
10476         /*  When BT is non idle */
10477         if (!(pHalData->bt_coexist.CurrentState & BT_COEX_STATE_BT_IDLE)) {
10478                 RTPRINT(FBT, BT_TRACE, ("BT state non idle, set bt EDCA\n"));
10479
10480                 /* aggr_num = 0x0909; */
10481                 if (pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA) {
10482                         bBtChangeEDCA = true;
10483                         pHalData->odmpriv.DM_EDCA_Table.bCurrentTurboEDCA = false;
10484                         pHalData->dmpriv.prv_traffic_idx = 3;
10485                 }
10486                 cur_EDCA_reg = rtl8723au_read32(padapter, REG_EDCA_BE_PARAM);
10487
10488                 if (cur_EDCA_reg != EDCA_BT_BE)
10489                         bBtChangeEDCA = true;
10490                 if (bBtChangeEDCA || !pHalData->bt_coexist.bEDCAInitialized) {
10491                         rtl8723au_write32(padapter, REG_EDCA_BE_PARAM,
10492                                           EDCA_BT_BE);
10493                         pHalData->bt_coexist.lastBtEdca = EDCA_BT_BE;
10494                 }
10495                 bRet = true;
10496         } else {
10497                 RTPRINT(FBT, BT_TRACE, ("BT state idle, set original EDCA\n"));
10498                 pHalData->bt_coexist.lastBtEdca = 0;
10499                 bRet = false;
10500         }
10501         return bRet;
10502 }
10503
10504 void
10505 BTDM_Balance(
10506         struct rtw_adapter *padapter,
10507         u8 bBalanceOn,
10508         u8 ms0,
10509         u8 ms1
10510         )
10511 {
10512         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10513         u8 H2C_Parameter[3] = {0};
10514
10515         if (bBalanceOn) {
10516                 H2C_Parameter[2] = 1;
10517                 H2C_Parameter[1] = ms1;
10518                 H2C_Parameter[0] = ms0;
10519                 pHalData->bt_coexist.bFWCoexistAllOff = false;
10520         } else {
10521                 H2C_Parameter[2] = 0;
10522                 H2C_Parameter[1] = 0;
10523                 H2C_Parameter[0] = 0;
10524         }
10525         pHalData->bt_coexist.bBalanceOn = bBalanceOn;
10526
10527         RTPRINT(FBT, BT_TRACE, ("[DM][BT], Balance =[%s:%dms:%dms], write 0xc = 0x%x\n",
10528                 bBalanceOn?"ON":"OFF", ms0, ms1,
10529                 H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
10530
10531         FillH2CCmd(padapter, 0xc, 3, H2C_Parameter);
10532 }
10533
10534 void BTDM_AGCTable(struct rtw_adapter *padapter, u8 type)
10535 {
10536         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10537         if (type == BT_AGCTABLE_OFF) {
10538                 RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable Off!\n"));
10539                 rtl8723au_write32(padapter, 0xc78, 0x641c0001);
10540                 rtl8723au_write32(padapter, 0xc78, 0x631d0001);
10541                 rtl8723au_write32(padapter, 0xc78, 0x621e0001);
10542                 rtl8723au_write32(padapter, 0xc78, 0x611f0001);
10543                 rtl8723au_write32(padapter, 0xc78, 0x60200001);
10544
10545                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x32000);
10546                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x71000);
10547                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xb0000);
10548                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xfc000);
10549                 PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x30355);
10550
10551                 pHalData->bt_coexist.b8723aAgcTableOn = false;
10552         } else if (type == BT_AGCTABLE_ON) {
10553                 RTPRINT(FBT, BT_TRACE, ("[BT]AGCTable On!\n"));
10554                 rtl8723au_write32(padapter, 0xc78, 0x4e1c0001);
10555                 rtl8723au_write32(padapter, 0xc78, 0x4d1d0001);
10556                 rtl8723au_write32(padapter, 0xc78, 0x4c1e0001);
10557                 rtl8723au_write32(padapter, 0xc78, 0x4b1f0001);
10558                 rtl8723au_write32(padapter, 0xc78, 0x4a200001);
10559
10560                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0xdc000);
10561                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x90000);
10562                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x51000);
10563                 PHY_SetRFReg(padapter, PathA, RF_RX_AGC_HP, bRFRegOffsetMask, 0x12000);
10564                 PHY_SetRFReg(padapter, PathA, RF_RX_G1, bRFRegOffsetMask, 0x00355);
10565
10566                 pHalData->bt_coexist.b8723aAgcTableOn = true;
10567
10568                 pHalData->bt_coexist.bSWCoexistAllOff = false;
10569         }
10570 }
10571
10572 void BTDM_BBBackOffLevel(struct rtw_adapter *padapter, u8 type)
10573 {
10574         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10575
10576         if (type == BT_BB_BACKOFF_OFF) {
10577                 RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel Off!\n"));
10578                 rtl8723au_write32(padapter, 0xc04, 0x3a05611);
10579         } else if (type == BT_BB_BACKOFF_ON) {
10580                 RTPRINT(FBT, BT_TRACE, ("[BT]BBBackOffLevel On!\n"));
10581                 rtl8723au_write32(padapter, 0xc04, 0x3a07611);
10582                 pHalData->bt_coexist.bSWCoexistAllOff = false;
10583         }
10584 }
10585
10586 void BTDM_FWCoexAllOff(struct rtw_adapter *padapter)
10587 {
10588         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10589
10590         RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff()\n"));
10591         if (pHalData->bt_coexist.bFWCoexistAllOff)
10592                 return;
10593         RTPRINT(FBT, BT_TRACE, ("BTDM_FWCoexAllOff(), real Do\n"));
10594
10595         BTDM_FWCoexAllOff8723A(padapter);
10596
10597         pHalData->bt_coexist.bFWCoexistAllOff = true;
10598 }
10599
10600 void BTDM_SWCoexAllOff(struct rtw_adapter *padapter)
10601 {
10602         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10603
10604         RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff()\n"));
10605         if (pHalData->bt_coexist.bSWCoexistAllOff)
10606                 return;
10607         RTPRINT(FBT, BT_TRACE, ("BTDM_SWCoexAllOff(), real Do\n"));
10608         BTDM_SWCoexAllOff8723A(padapter);
10609
10610         pHalData->bt_coexist.bSWCoexistAllOff = true;
10611 }
10612
10613 void BTDM_HWCoexAllOff(struct rtw_adapter *padapter)
10614 {
10615         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10616
10617         RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff()\n"));
10618         if (pHalData->bt_coexist.bHWCoexistAllOff)
10619                 return;
10620         RTPRINT(FBT, BT_TRACE, ("BTDM_HWCoexAllOff(), real Do\n"));
10621
10622         BTDM_HWCoexAllOff8723A(padapter);
10623
10624         pHalData->bt_coexist.bHWCoexistAllOff = true;
10625 }
10626
10627 void BTDM_CoexAllOff(struct rtw_adapter *padapter)
10628 {
10629         BTDM_FWCoexAllOff(padapter);
10630         BTDM_SWCoexAllOff(padapter);
10631         BTDM_HWCoexAllOff(padapter);
10632 }
10633
10634 void rtl8723a_BT_disable_coexist(struct rtw_adapter *padapter)
10635 {
10636         struct pwrctrl_priv *ppwrctrl = &padapter->pwrctrlpriv;
10637
10638         if (!rtl8723a_BT_coexist(padapter))
10639                 return;
10640
10641         /*  8723 1Ant doesn't need to turn off bt coexist mechanism. */
10642         if (rtl8723a_BT_using_antenna_1(padapter))
10643                 return;
10644
10645         /*  Before enter IPS, turn off FW BT Co-exist mechanism */
10646         if (ppwrctrl->reg_rfoff == rf_on) {
10647                 RTPRINT(FBT, BT_TRACE, ("[BT][DM], Before enter IPS, turn off all Coexist DM\n"));
10648                 btdm_ResetFWCoexState(padapter);
10649                 BTDM_CoexAllOff(padapter);
10650                 BTDM_SetAntenna(padapter, BTDM_ANT_BT);
10651         }
10652 }
10653
10654 void BTDM_SignalCompensation(struct rtw_adapter *padapter, u8 *rssi_wifi, u8 *rssi_bt)
10655 {
10656         BTDM_8723ASignalCompensation(padapter, rssi_wifi, rssi_bt);
10657 }
10658
10659 void rtl8723a_BT_do_coexist(struct rtw_adapter *padapter)
10660 {
10661         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10662
10663         if (!rtl8723a_BT_coexist(padapter)) {
10664                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], BT not exists!!\n"));
10665                 return;
10666         }
10667
10668         if (!pHalData->bt_coexist.bInitlized) {
10669                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], btdm_InitBtCoexistDM()\n"));
10670                 btdm_InitBtCoexistDM(padapter);
10671         }
10672
10673         RTPRINT(FBT, BT_TRACE, ("\n\n[DM][BT], BTDM start!!\n"));
10674
10675         BTDM_PWDBMonitor(padapter);
10676
10677         RTPRINT(FBT, BT_TRACE, ("[DM][BT], HW type is 8723\n"));
10678         BTDM_BTCoexist8723A(padapter);
10679         RTPRINT(FBT, BT_TRACE, ("[DM][BT], BTDM end!!\n\n"));
10680 }
10681
10682 void BTDM_UpdateCoexState(struct rtw_adapter *padapter)
10683 {
10684         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10685
10686         if (!BTDM_IsSameCoexistState(padapter)) {
10687                 RTPRINT(FBT, BT_TRACE, ("[BTCoex], Coexist State[bitMap] change from 0x%"i64fmt"x to 0x%"i64fmt"x,  changeBits = 0x%"i64fmt"x\n",
10688                         pHalData->bt_coexist.PreviousState,
10689                         pHalData->bt_coexist.CurrentState,
10690                         (pHalData->bt_coexist.PreviousState^pHalData->bt_coexist.CurrentState)));
10691                 pHalData->bt_coexist.PreviousState = pHalData->bt_coexist.CurrentState;
10692         }
10693 }
10694
10695 u8 BTDM_IsSameCoexistState(struct rtw_adapter *padapter)
10696 {
10697         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10698
10699         if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState) {
10700                 return true;
10701         } else {
10702                 RTPRINT(FBT, BT_TRACE, ("[DM][BT], Coexist state changed!!\n"));
10703                 return false;
10704         }
10705 }
10706
10707 void BTDM_PWDBMonitor(struct rtw_adapter *padapter)
10708 {
10709         struct bt_30info *pBTInfo = GET_BT_INFO(GetDefaultAdapter(padapter));
10710         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
10711         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10712         u8 H2C_Parameter[3] = {0};
10713         s32 tmpBTEntryMaxPWDB = 0, tmpBTEntryMinPWDB = 0xff;
10714         u8 i;
10715
10716         if (pBtMgnt->BtOperationOn) {
10717                 for (i = 0; i < MAX_BT_ASOC_ENTRY_NUM; i++) {
10718                         if (pBTInfo->BtAsocEntry[i].bUsed) {
10719                                 if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB < tmpBTEntryMinPWDB)
10720                                         tmpBTEntryMinPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB;
10721                                 if (pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB > tmpBTEntryMaxPWDB)
10722                                         tmpBTEntryMaxPWDB = pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB;
10723                                 /*  Report every BT connection (HS mode) RSSI to FW */
10724                                 H2C_Parameter[2] = (u8)(pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB & 0xFF);
10725                                 H2C_Parameter[0] = (MAX_FW_SUPPORT_MACID_NUM-1-i);
10726                                 RTPRINT(FDM, DM_BT30, ("RSSI report for BT[%d], H2C_Par = 0x%x\n", i, H2C_Parameter[0]));
10727                                 FillH2CCmd(padapter, RSSI_SETTING_EID, 3, H2C_Parameter);
10728                                 RTPRINT_ADDR(FDM, (DM_PWDB|DM_BT30), ("BT_Entry Mac :"),
10729                                              pBTInfo->BtAsocEntry[i].BTRemoteMACAddr)
10730                                 RTPRINT(FDM, (DM_PWDB|DM_BT30),
10731                                         ("BT rx pwdb[%d] = 0x%x(%d)\n", i,
10732                                         pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB,
10733                                         pBTInfo->BtAsocEntry[i].UndecoratedSmoothedPWDB));
10734                         }
10735                 }
10736                 if (tmpBTEntryMaxPWDB != 0) {   /*  If associated entry is found */
10737                         pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = tmpBTEntryMaxPWDB;
10738                         RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMaxPWDB = 0x%x(%d)\n",
10739                                 tmpBTEntryMaxPWDB, tmpBTEntryMaxPWDB));
10740                 } else {
10741                         pHalData->dmpriv.BT_EntryMaxUndecoratedSmoothedPWDB = 0;
10742                 }
10743                 if (tmpBTEntryMinPWDB != 0xff) { /*  If associated entry is found */
10744                         pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = tmpBTEntryMinPWDB;
10745                         RTPRINT(FDM, (DM_PWDB|DM_BT30), ("BT_EntryMinPWDB = 0x%x(%d)\n",
10746                                 tmpBTEntryMinPWDB, tmpBTEntryMinPWDB));
10747                 } else {
10748                         pHalData->dmpriv.BT_EntryMinUndecoratedSmoothedPWDB = 0;
10749                 }
10750         }
10751 }
10752
10753 u8 BTDM_IsBTBusy(struct rtw_adapter *padapter)
10754 {
10755         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
10756         struct bt_mgnt *pBtMgnt = &pBTInfo->BtMgnt;
10757
10758         if (pBtMgnt->ExtConfig.bBTBusy)
10759                 return true;
10760         else
10761                 return false;
10762 }
10763
10764 u8 BTDM_IsWifiBusy(struct rtw_adapter *padapter)
10765 {
10766 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10767         struct mlme_priv *pmlmepriv = &GetDefaultAdapter(padapter)->mlmepriv;
10768         struct bt_30info *pBTInfo = GET_BT_INFO(padapter);
10769         struct bt_traffic *pBtTraffic = &pBTInfo->BtTraffic;
10770
10771         if (pmlmepriv->LinkDetectInfo.bBusyTraffic ||
10772                 pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic ||
10773                 pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic)
10774                 return true;
10775         else
10776                 return false;
10777 }
10778
10779 u8 BTDM_IsCoexistStateChanged(struct rtw_adapter *padapter)
10780 {
10781         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10782
10783         if (pHalData->bt_coexist.PreviousState == pHalData->bt_coexist.CurrentState)
10784                 return false;
10785         else
10786                 return true;
10787 }
10788
10789 u8 BTDM_IsWifiUplink(struct rtw_adapter *padapter)
10790 {
10791 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10792         struct mlme_priv *pmlmepriv;
10793         struct bt_30info *pBTInfo;
10794         struct bt_traffic *pBtTraffic;
10795
10796         pmlmepriv = &padapter->mlmepriv;
10797         pBTInfo = GET_BT_INFO(padapter);
10798         pBtTraffic = &pBTInfo->BtTraffic;
10799
10800         if ((pmlmepriv->LinkDetectInfo.bTxBusyTraffic) ||
10801                 (pBtTraffic->Bt30TrafficStatistics.bTxBusyTraffic))
10802                 return true;
10803         else
10804                 return false;
10805 }
10806
10807 u8 BTDM_IsWifiDownlink(struct rtw_adapter *padapter)
10808 {
10809 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10810         struct mlme_priv *pmlmepriv;
10811         struct bt_30info *pBTInfo;
10812         struct bt_traffic *pBtTraffic;
10813
10814         pmlmepriv = &padapter->mlmepriv;
10815         pBTInfo = GET_BT_INFO(padapter);
10816         pBtTraffic = &pBTInfo->BtTraffic;
10817
10818         if ((pmlmepriv->LinkDetectInfo.bRxBusyTraffic) ||
10819                 (pBtTraffic->Bt30TrafficStatistics.bRxBusyTraffic))
10820                 return true;
10821         else
10822                 return false;
10823 }
10824
10825 u8 BTDM_IsBTHSMode(struct rtw_adapter *padapter)
10826 {
10827 /*PMGNT_INFO            pMgntInfo = &GetDefaultAdapter(padapter)->MgntInfo; */
10828         struct hal_data_8723a *pHalData;
10829         struct bt_mgnt *pBtMgnt;
10830
10831         pHalData = GET_HAL_DATA(padapter);
10832         pBtMgnt = &pHalData->BtInfo.BtMgnt;
10833
10834         if (pBtMgnt->BtOperationOn)
10835                 return true;
10836         else
10837                 return false;
10838 }
10839
10840 u8 BTDM_IsBTUplink(struct rtw_adapter *padapter)
10841 {
10842         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10843
10844         if (pHalData->bt_coexist.BT21TrafficStatistics.bTxBusyTraffic)
10845                 return true;
10846         else
10847                 return false;
10848 }
10849
10850 u8 BTDM_IsBTDownlink(struct rtw_adapter *padapter)
10851 {
10852         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10853
10854         if (pHalData->bt_coexist.BT21TrafficStatistics.bRxBusyTraffic)
10855                 return true;
10856         else
10857                 return false;
10858 }
10859
10860 void BTDM_AdjustForBtOperation(struct rtw_adapter *padapter)
10861 {
10862         RTPRINT(FBT, BT_TRACE, ("[BT][DM], BTDM_AdjustForBtOperation()\n"));
10863         BTDM_AdjustForBtOperation8723A(padapter);
10864 }
10865
10866 void BTDM_SetBtCoexCurrAntNum(struct rtw_adapter *padapter, u8 antNum)
10867 {
10868         BTDM_Set8723ABtCoexCurrAntNum(padapter, antNum);
10869 }
10870
10871 void BTDM_ForHalt(struct rtw_adapter *padapter)
10872 {
10873         if (!rtl8723a_BT_coexist(padapter))
10874                 return;
10875
10876         BTDM_ForHalt8723A(padapter);
10877         GET_HAL_DATA(padapter)->bt_coexist.bInitlized = false;
10878 }
10879
10880 void BTDM_WifiScanNotify(struct rtw_adapter *padapter, u8 scanType)
10881 {
10882         if (!rtl8723a_BT_coexist(padapter))
10883                 return;
10884
10885         BTDM_WifiScanNotify8723A(padapter, scanType);
10886 }
10887
10888 void BTDM_WifiAssociateNotify(struct rtw_adapter *padapter, u8 action)
10889 {
10890         if (!rtl8723a_BT_coexist(padapter))
10891                 return;
10892
10893         BTDM_WifiAssociateNotify8723A(padapter, action);
10894 }
10895
10896 void rtl8723a_BT_mediastatus_notify(struct rtw_adapter *padapter,
10897                                     enum rt_media_status mstatus)
10898 {
10899         if (!rtl8723a_BT_coexist(padapter))
10900                 return;
10901
10902         BTDM_MediaStatusNotify8723A(padapter, mstatus);
10903 }
10904
10905 void rtl8723a_BT_specialpacket_notify(struct rtw_adapter *padapter)
10906 {
10907         if (!rtl8723a_BT_coexist(padapter))
10908                 return;
10909
10910         BTDM_ForDhcp8723A(padapter);
10911 }
10912
10913 void BTDM_ResetActionProfileState(struct rtw_adapter *padapter)
10914 {
10915         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
10916
10917         pHalData->bt_coexist.CurrentState &= ~\
10918                 (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP|
10919                 BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_SCO);
10920 }
10921
10922 u8 BTDM_IsActionSCO(struct rtw_adapter *padapter)
10923 {
10924         struct hal_data_8723a *pHalData;
10925         struct bt_30info *pBTInfo;
10926         struct bt_mgnt *pBtMgnt;
10927         struct bt_dgb *pBtDbg;
10928         u8 bRet;
10929
10930         pHalData = GET_HAL_DATA(padapter);
10931         pBTInfo = GET_BT_INFO(padapter);
10932         pBtMgnt = &pBTInfo->BtMgnt;
10933         pBtDbg = &pBTInfo->BtDbg;
10934         bRet = false;
10935
10936         if (pBtDbg->dbgCtrl) {
10937                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_SCO) {
10938                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO;
10939                         bRet = true;
10940                 }
10941         } else {
10942                 if (pBtMgnt->ExtConfig.NumberOfSCO > 0) {
10943                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_SCO;
10944                         bRet = true;
10945                 }
10946         }
10947         return bRet;
10948 }
10949
10950 u8 BTDM_IsActionHID(struct rtw_adapter *padapter)
10951 {
10952         struct bt_30info *pBTInfo;
10953         struct hal_data_8723a *pHalData;
10954         struct bt_mgnt *pBtMgnt;
10955         struct bt_dgb *pBtDbg;
10956         u8 bRet;
10957
10958         pHalData = GET_HAL_DATA(padapter);
10959         pBTInfo = GET_BT_INFO(padapter);
10960         pBtMgnt = &pBTInfo->BtMgnt;
10961         pBtDbg = &pBTInfo->BtDbg;
10962         bRet = false;
10963
10964         if (pBtDbg->dbgCtrl) {
10965                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID) {
10966                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID;
10967                         bRet = true;
10968                 }
10969         } else {
10970                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
10971                     pBtMgnt->ExtConfig.NumberOfHandle == 1) {
10972                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_HID;
10973                         bRet = true;
10974                 }
10975         }
10976         return bRet;
10977 }
10978
10979 u8 BTDM_IsActionA2DP(struct rtw_adapter *padapter)
10980 {
10981         struct hal_data_8723a *pHalData;
10982         struct bt_30info *pBTInfo;
10983         struct bt_mgnt *pBtMgnt;
10984         struct bt_dgb *pBtDbg;
10985         u8 bRet;
10986
10987         pHalData = GET_HAL_DATA(padapter);
10988         pBTInfo = GET_BT_INFO(padapter);
10989         pBtMgnt = &pBTInfo->BtMgnt;
10990         pBtDbg = &pBTInfo->BtDbg;
10991         bRet = false;
10992
10993         if (pBtDbg->dbgCtrl) {
10994                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_A2DP) {
10995                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP;
10996                         bRet = true;
10997                 }
10998         } else {
10999                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP) &&
11000                     pBtMgnt->ExtConfig.NumberOfHandle == 1) {
11001                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_A2DP;
11002                         bRet = true;
11003                 }
11004         }
11005         return bRet;
11006 }
11007
11008 u8 BTDM_IsActionPAN(struct rtw_adapter *padapter)
11009 {
11010         struct hal_data_8723a *pHalData;
11011         struct bt_30info *pBTInfo;
11012         struct bt_mgnt *pBtMgnt;
11013         struct bt_dgb *pBtDbg;
11014         u8 bRet;
11015
11016         pHalData = GET_HAL_DATA(padapter);
11017         pBTInfo = GET_BT_INFO(padapter);
11018         pBtMgnt = &pBTInfo->BtMgnt;
11019         pBtDbg = &pBTInfo->BtDbg;
11020         bRet = false;
11021
11022         if (pBtDbg->dbgCtrl) {
11023                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN) {
11024                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN;
11025                         bRet = true;
11026                 }
11027         } else {
11028                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) &&
11029                     pBtMgnt->ExtConfig.NumberOfHandle == 1) {
11030                         pHalData->bt_coexist.CurrentState |= BT_COEX_STATE_PROFILE_PAN;
11031                         bRet = true;
11032                 }
11033         }
11034         return bRet;
11035 }
11036
11037 u8 BTDM_IsActionHIDA2DP(struct rtw_adapter *padapter)
11038 {
11039         struct hal_data_8723a *pHalData;
11040         struct bt_30info *pBTInfo;
11041         struct bt_mgnt *pBtMgnt;
11042         struct bt_dgb *pBtDbg;
11043         u8 bRet;
11044
11045         pHalData = GET_HAL_DATA(padapter);
11046         pBTInfo = GET_BT_INFO(padapter);
11047         pBtMgnt = &pBTInfo->BtMgnt;
11048         pBtDbg = &pBTInfo->BtDbg;
11049         bRet = false;
11050
11051         if (pBtDbg->dbgCtrl) {
11052                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_A2DP) {
11053                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP);
11054                         bRet = true;
11055                 }
11056         } else {
11057                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
11058                     BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
11059                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_A2DP);
11060                         bRet = true;
11061                 }
11062         }
11063         return bRet;
11064 }
11065
11066 u8 BTDM_IsActionHIDPAN(struct rtw_adapter *padapter)
11067 {
11068         struct hal_data_8723a *pHalData;
11069         struct bt_30info *pBTInfo;
11070         struct bt_dgb *pBtDbg;
11071         u8 bRet;
11072
11073         pHalData = GET_HAL_DATA(padapter);
11074         pBTInfo = GET_BT_INFO(padapter);
11075         pBtDbg = &pBTInfo->BtDbg;
11076         bRet = false;
11077
11078         if (pBtDbg->dbgCtrl) {
11079                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_HID_PAN) {
11080                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN);
11081                         bRet = true;
11082                 }
11083         } else {
11084                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_HID) &&
11085                     BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN)) {
11086                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_HID|BT_COEX_STATE_PROFILE_PAN);
11087                         bRet = true;
11088                 }
11089         }
11090         return bRet;
11091 }
11092
11093 u8 BTDM_IsActionPANA2DP(struct rtw_adapter *padapter)
11094 {
11095         struct hal_data_8723a *pHalData;
11096         struct bt_30info *pBTInfo;
11097         struct bt_dgb *pBtDbg;
11098         u8 bRet;
11099
11100         pHalData = GET_HAL_DATA(padapter);
11101         pBTInfo = GET_BT_INFO(padapter);
11102         pBtDbg = &pBTInfo->BtDbg;
11103         bRet = false;
11104
11105         if (pBtDbg->dbgCtrl) {
11106                 if (pBtDbg->dbgProfile == BT_DBG_PROFILE_PAN_A2DP) {
11107                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP);
11108                         bRet = true;
11109                 }
11110         } else {
11111                 if (BTHCI_CheckProfileExist(padapter, BT_PROFILE_PAN) && BTHCI_CheckProfileExist(padapter, BT_PROFILE_A2DP)) {
11112                         pHalData->bt_coexist.CurrentState |= (BT_COEX_STATE_PROFILE_PAN|BT_COEX_STATE_PROFILE_A2DP);
11113                         bRet = true;
11114                 }
11115         }
11116         return bRet;
11117 }
11118
11119 bool rtl8723a_BT_enabled(struct rtw_adapter *padapter)
11120 {
11121         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11122
11123         if (pHalData->bt_coexist.bCurBtDisabled)
11124                 return false;
11125         else
11126                 return true;
11127 }
11128
11129 /*  ===== End of sync from SD7 driver HAL/BTCoexist/HalBtCoexist.c ===== */
11130
11131 /*  ===== Below this line is sync from SD7 driver HAL/HalBT.c ===== */
11132
11133 /*  */
11134 /*local function */
11135 /*  */
11136
11137 static void halbt_InitHwConfig8723A(struct rtw_adapter *padapter)
11138 {
11139 }
11140
11141 /*  */
11142 /*extern function */
11143 /*  */
11144 u8 HALBT_GetPGAntNum(struct rtw_adapter *padapter)
11145 {
11146         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11147
11148         return pHalData->bt_coexist.BT_Ant_Num;
11149 }
11150
11151 void HALBT_SetKey(struct rtw_adapter *padapter, u8 EntryNum)
11152 {
11153         struct bt_30info *pBTinfo;
11154         struct bt_asoc_entry *pBtAssocEntry;
11155         u16                             usConfig = 0;
11156
11157         pBTinfo = GET_BT_INFO(padapter);
11158         pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum];
11159
11160         pBtAssocEntry->HwCAMIndex = BT_HWCAM_STAR + EntryNum;
11161
11162         usConfig = CAM_VALID | (CAM_AES << 2);
11163         rtl8723a_cam_write(padapter, pBtAssocEntry->HwCAMIndex, usConfig,
11164                            pBtAssocEntry->BTRemoteMACAddr,
11165                            pBtAssocEntry->PTK + TKIP_ENC_KEY_POS);
11166 }
11167
11168 void HALBT_RemoveKey(struct rtw_adapter *padapter, u8 EntryNum)
11169 {
11170         struct bt_30info *pBTinfo;
11171         struct bt_asoc_entry *pBtAssocEntry;
11172
11173         pBTinfo = GET_BT_INFO(padapter);
11174         pBtAssocEntry = &pBTinfo->BtAsocEntry[EntryNum];
11175
11176         if (pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex != 0) {
11177                 /*  ToDo : add New HALBT_RemoveKey function !! */
11178                 if (pBtAssocEntry->HwCAMIndex >= BT_HWCAM_STAR &&
11179                     pBtAssocEntry->HwCAMIndex < HALF_CAM_ENTRY)
11180                         rtl8723a_cam_empty_entry(padapter,
11181                                                  pBtAssocEntry->HwCAMIndex);
11182                 pBTinfo->BtAsocEntry[EntryNum].HwCAMIndex = 0;
11183         }
11184 }
11185
11186 void rtl8723a_BT_init_hal_vars(struct rtw_adapter *padapter)
11187 {
11188         struct hal_data_8723a *pHalData;
11189
11190         pHalData = GET_HAL_DATA(padapter);
11191
11192         pHalData->bt_coexist.BluetoothCoexist = pHalData->EEPROMBluetoothCoexist;
11193         pHalData->bt_coexist.BT_Ant_Num = pHalData->EEPROMBluetoothAntNum;
11194         pHalData->bt_coexist.BT_CoexistType = pHalData->EEPROMBluetoothType;
11195         pHalData->bt_coexist.BT_Ant_isolation = pHalData->EEPROMBluetoothAntIsolation;
11196         pHalData->bt_coexist.bt_radiosharedtype = pHalData->EEPROMBluetoothRadioShared;
11197
11198         RT_TRACE(_module_hal_init_c_, _drv_info_,
11199                  ("BT Coexistance = 0x%x\n", rtl8723a_BT_coexist(padapter)));
11200
11201         if (rtl8723a_BT_coexist(padapter)) {
11202                 if (pHalData->bt_coexist.BT_Ant_Num == Ant_x2) {
11203                         BTDM_SetBtCoexCurrAntNum(padapter, 2);
11204                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("BlueTooth BT_Ant_Num = Antx2\n"));
11205                 } else if (pHalData->bt_coexist.BT_Ant_Num == Ant_x1) {
11206                         BTDM_SetBtCoexCurrAntNum(padapter, 1);
11207                         RT_TRACE(_module_hal_init_c_, _drv_info_, ("BlueTooth BT_Ant_Num = Antx1\n"));
11208                 }
11209                 pHalData->bt_coexist.bBTBusyTraffic = false;
11210                 pHalData->bt_coexist.bBTTrafficModeSet = false;
11211                 pHalData->bt_coexist.bBTNonTrafficModeSet = false;
11212                 pHalData->bt_coexist.CurrentState = 0;
11213                 pHalData->bt_coexist.PreviousState = 0;
11214
11215                 RT_TRACE(_module_hal_init_c_, _drv_info_,
11216                          ("bt_radiosharedType = 0x%x\n",
11217                          pHalData->bt_coexist.bt_radiosharedtype));
11218         }
11219 }
11220
11221 bool rtl8723a_BT_coexist(struct rtw_adapter *padapter)
11222 {
11223         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11224
11225         if (pHalData->bt_coexist.BluetoothCoexist)
11226                 return true;
11227         else
11228                 return false;
11229 }
11230
11231 u8 HALBT_BTChipType(struct rtw_adapter *padapter)
11232 {
11233         struct hal_data_8723a *pHalData = GET_HAL_DATA(padapter);
11234
11235         return pHalData->bt_coexist.BT_CoexistType;
11236 }
11237
11238 void rtl8723a_BT_init_hwconfig(struct rtw_adapter *padapter)
11239 {
11240         halbt_InitHwConfig8723A(padapter);
11241         rtl8723a_BT_do_coexist(padapter);
11242 }
11243
11244 void HALBT_SetRtsCtsNoLenLimit(struct rtw_adapter *padapter)
11245 {
11246 }
11247
11248 /*  ===== End of sync from SD7 driver HAL/HalBT.c ===== */
11249
11250 void rtl8723a_dual_antenna_detection(struct rtw_adapter *padapter)
11251 {
11252         struct hal_data_8723a *pHalData;
11253         struct dm_odm_t *pDM_Odm;
11254         struct sw_ant_sw *pDM_SWAT_Table;
11255         u8 i;
11256
11257         pHalData = GET_HAL_DATA(padapter);
11258         pDM_Odm = &pHalData->odmpriv;
11259         pDM_SWAT_Table = &pDM_Odm->DM_SWAT_Table;
11260
11261         /*  */
11262         /*  <Roger_Notes> RTL8723A Single and Dual antenna dynamic detection
11263             mechanism when RF power state is on. */
11264         /*  We should take power tracking, IQK, LCK, RCK RF read/write
11265             operation into consideration. */
11266         /*  2011.12.15. */
11267         /*  */
11268         if (!pHalData->bAntennaDetected) {
11269                 u8 btAntNum = BT_GetPGAntNum(padapter);
11270
11271                 /*  Set default antenna B status */
11272                 if (btAntNum == Ant_x2)
11273                         pDM_SWAT_Table->ANTB_ON = true;
11274                 else if (btAntNum == Ant_x1)
11275                         pDM_SWAT_Table->ANTB_ON = false;
11276                 else
11277                         pDM_SWAT_Table->ANTB_ON = true;
11278
11279                 if (pHalData->CustomerID != RT_CID_TOSHIBA) {
11280                         for (i = 0; i < MAX_ANTENNA_DETECTION_CNT; i++) {
11281                                 if (ODM_SingleDualAntennaDetection
11282                                     (&pHalData->odmpriv, ANTTESTALL) == true)
11283                                         break;
11284                         }
11285
11286                         /*  Set default antenna number for BT coexistence */
11287                         if (btAntNum == Ant_x2)
11288                                 BT_SetBtCoexCurrAntNum(padapter,
11289                                                        pDM_SWAT_Table->
11290                                                        ANTB_ON ? 2 : 1);
11291                 }
11292                 pHalData->bAntennaDetected = true;
11293         }
11294 }