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