LCOV - code coverage report
Current view: top level - drivers/net/wireless/realtek/rtw88 - coex.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 0 1428 0.0 %
Date: 2022-03-28 16:04:14 Functions: 0 67 0.0 %
Branches: 0 701 0.0 %

           Branch data     Line data    Source code
       1                 :            : // SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause
       2                 :            : /* Copyright(c) 2018-2019  Realtek Corporation
       3                 :            :  */
       4                 :            : 
       5                 :            : #include "main.h"
       6                 :            : #include "coex.h"
       7                 :            : #include "fw.h"
       8                 :            : #include "ps.h"
       9                 :            : #include "debug.h"
      10                 :            : #include "reg.h"
      11                 :            : 
      12                 :          0 : static u8 rtw_coex_next_rssi_state(struct rtw_dev *rtwdev, u8 pre_state,
      13                 :            :                                    u8 rssi, u8 rssi_thresh)
      14                 :            : {
      15                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
      16                 :          0 :         u8 tol = chip->rssi_tolerance;
      17                 :          0 :         u8 next_state;
      18                 :            : 
      19   [ #  #  #  #  :          0 :         if (pre_state == COEX_RSSI_STATE_LOW ||
                   #  # ]
      20                 :            :             pre_state == COEX_RSSI_STATE_STAY_LOW) {
      21   [ #  #  #  #  :          0 :                 if (rssi >= (rssi_thresh + tol))
                   #  # ]
      22                 :            :                         next_state = COEX_RSSI_STATE_HIGH;
      23                 :            :                 else
      24                 :          0 :                         next_state = COEX_RSSI_STATE_STAY_LOW;
      25                 :            :         } else {
      26   [ #  #  #  #  :          0 :                 if (rssi < rssi_thresh)
                   #  # ]
      27                 :            :                         next_state = COEX_RSSI_STATE_LOW;
      28                 :            :                 else
      29                 :          0 :                         next_state = COEX_RSSI_STATE_STAY_HIGH;
      30                 :            :         }
      31                 :            : 
      32                 :          0 :         return next_state;
      33                 :            : }
      34                 :            : 
      35                 :          0 : static void rtw_coex_limited_tx(struct rtw_dev *rtwdev,
      36                 :            :                                 bool tx_limit_en, bool ampdu_limit_en)
      37                 :            : {
      38                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
      39                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
      40                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
      41                 :          0 :         bool wifi_under_b_mode = false;
      42                 :            : 
      43         [ #  # ]:          0 :         if (!chip->scbd_support)
      44                 :            :                 return;
      45                 :            : 
      46                 :            :         /* force max tx retry limit = 8 */
      47         [ #  # ]:          0 :         if (coex_stat->wl_tx_limit_en == tx_limit_en &&
      48         [ #  # ]:          0 :             coex_stat->wl_ampdu_limit_en == ampdu_limit_en)
      49                 :            :                 return;
      50                 :            : 
      51         [ #  # ]:          0 :         if (!coex_stat->wl_tx_limit_en) {
      52                 :          0 :                 coex_stat->darfrc = rtw_read32(rtwdev, REG_DARFRC);
      53                 :          0 :                 coex_stat->darfrch = rtw_read32(rtwdev, REG_DARFRCH);
      54                 :          0 :                 coex_stat->retry_limit = rtw_read16(rtwdev, REG_RETRY_LIMIT);
      55                 :            :         }
      56                 :            : 
      57         [ #  # ]:          0 :         if (!coex_stat->wl_ampdu_limit_en)
      58                 :          0 :                 coex_stat->ampdu_max_time =
      59                 :            :                                 rtw_read8(rtwdev, REG_AMPDU_MAX_TIME_V1);
      60                 :            : 
      61                 :          0 :         coex_stat->wl_tx_limit_en = tx_limit_en;
      62                 :          0 :         coex_stat->wl_ampdu_limit_en = ampdu_limit_en;
      63                 :            : 
      64         [ #  # ]:          0 :         if (tx_limit_en) {
      65                 :            :                 /* set BT polluted packet on for tx rate adaptive,
      66                 :            :                  * not including tx retry broken by PTA
      67                 :            :                  */
      68                 :          0 :                 rtw_write8_set(rtwdev, REG_TX_HANG_CTRL, BIT_EN_GNT_BT_AWAKE);
      69                 :            : 
      70                 :            :                 /* set queue life time to avoid can't reach tx retry limit
      71                 :            :                  * if tx is always broken by GNT_BT
      72                 :            :                  */
      73                 :          0 :                 rtw_write8_set(rtwdev, REG_LIFETIME_EN, 0xf);
      74                 :          0 :                 rtw_write16(rtwdev, REG_RETRY_LIMIT, 0x0808);
      75                 :            : 
      76                 :            :                 /* auto rate fallback step within 8 retries */
      77                 :          0 :                 if (wifi_under_b_mode) {
      78                 :            :                         rtw_write32(rtwdev, REG_DARFRC, 0x1000000);
      79                 :            :                         rtw_write32(rtwdev, REG_DARFRCH, 0x1010101);
      80                 :            :                 } else {
      81                 :          0 :                         rtw_write32(rtwdev, REG_DARFRC, 0x1000000);
      82                 :          0 :                         rtw_write32(rtwdev, REG_DARFRCH, 0x4030201);
      83                 :            :                 }
      84                 :            :         } else {
      85                 :          0 :                 rtw_write8_clr(rtwdev, REG_TX_HANG_CTRL, BIT_EN_GNT_BT_AWAKE);
      86                 :          0 :                 rtw_write8_clr(rtwdev, REG_LIFETIME_EN, 0xf);
      87                 :            : 
      88                 :          0 :                 rtw_write16(rtwdev, REG_RETRY_LIMIT, coex_stat->retry_limit);
      89                 :          0 :                 rtw_write32(rtwdev, REG_DARFRC, coex_stat->darfrc);
      90                 :          0 :                 rtw_write32(rtwdev, REG_DARFRCH, coex_stat->darfrch);
      91                 :            :         }
      92                 :            : 
      93         [ #  # ]:          0 :         if (ampdu_limit_en)
      94                 :          0 :                 rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1, 0x20);
      95                 :            :         else
      96                 :          0 :                 rtw_write8(rtwdev, REG_AMPDU_MAX_TIME_V1,
      97                 :          0 :                            coex_stat->ampdu_max_time);
      98                 :            : }
      99                 :            : 
     100                 :          0 : static void rtw_coex_limited_wl(struct rtw_dev *rtwdev)
     101                 :            : {
     102                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     103                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     104                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     105                 :          0 :         bool tx_limit = false;
     106                 :          0 :         bool tx_agg_ctrl = false;
     107                 :            : 
     108         [ #  # ]:          0 :         if (coex->under_5g ||
     109         [ #  # ]:          0 :             coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
     110                 :            :                 /* no need to limit tx */
     111                 :            :         } else {
     112                 :          0 :                 tx_limit = true;
     113         [ #  # ]:          0 :                 if (coex_stat->bt_hid_exist || coex_stat->bt_hfp_exist ||
     114         [ #  # ]:          0 :                     coex_stat->bt_hid_pair_num > 0)
     115                 :          0 :                         tx_agg_ctrl = true;
     116                 :            :         }
     117                 :            : 
     118                 :          0 :         rtw_coex_limited_tx(rtwdev, tx_limit, tx_agg_ctrl);
     119                 :          0 : }
     120                 :            : 
     121                 :          0 : static void rtw_coex_wl_ccklock_action(struct rtw_dev *rtwdev)
     122                 :            : {
     123                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     124                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     125                 :          0 :         u8 para[6] = {0};
     126                 :            : 
     127         [ #  # ]:          0 :         if (coex->stop_dm)
     128                 :          0 :                 return;
     129                 :            : 
     130                 :          0 :         para[0] = COEX_H2C69_WL_LEAKAP;
     131                 :            : 
     132   [ #  #  #  # ]:          0 :         if (coex_stat->tdma_timer_base == 3 && coex_stat->wl_slot_extend) {
     133                 :          0 :                 para[1] = PARA1_H2C69_DIS_5MS; /* disable 5ms extend */
     134                 :          0 :                 rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
     135                 :          0 :                 coex_stat->wl_slot_extend = false;
     136                 :          0 :                 coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0;
     137                 :          0 :                 return;
     138                 :            :         }
     139                 :            : 
     140   [ #  #  #  # ]:          0 :         if (coex_stat->wl_slot_extend && coex_stat->wl_force_lps_ctrl &&
     141         [ #  # ]:          0 :             !coex_stat->wl_cck_lock_ever) {
     142         [ #  # ]:          0 :                 if (coex_stat->wl_fw_dbg_info[7] <= 5)
     143                 :          0 :                         coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND]++;
     144                 :            :                 else
     145                 :          0 :                         coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0;
     146                 :            : 
     147         [ #  # ]:          0 :                 if (coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] == 7) {
     148                 :          0 :                         para[1] = 0x1; /* disable 5ms extend */
     149                 :          0 :                         rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
     150                 :          0 :                         coex_stat->wl_slot_extend = false;
     151                 :          0 :                         coex_stat->cnt_wl[COEX_CNT_WL_5MS_NOEXTEND] = 0;
     152                 :            :                 }
     153   [ #  #  #  # ]:          0 :         } else if (!coex_stat->wl_slot_extend && coex_stat->wl_cck_lock) {
     154                 :          0 :                 para[1] = 0x0; /* enable 5ms extend */
     155                 :          0 :                 rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
     156                 :          0 :                 coex_stat->wl_slot_extend = true;
     157                 :            :         }
     158                 :            : }
     159                 :            : 
     160                 :          0 : static void rtw_coex_wl_ccklock_detect(struct rtw_dev *rtwdev)
     161                 :            : {
     162                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     163                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     164                 :            : 
     165                 :            :         /* TODO: wait for rx_rate_change_notify implement */
     166                 :          0 :         coex_stat->wl_cck_lock = false;
     167                 :          0 :         coex_stat->wl_cck_lock_pre = false;
     168                 :          0 :         coex_stat->wl_cck_lock_ever = false;
     169                 :          0 : }
     170                 :            : 
     171                 :          0 : static void rtw_coex_wl_noisy_detect(struct rtw_dev *rtwdev)
     172                 :            : {
     173                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     174                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     175                 :          0 :         struct rtw_dm_info *dm_info = &rtwdev->dm_info;
     176                 :          0 :         u32 cnt_cck;
     177                 :            : 
     178                 :            :         /* wifi noisy environment identification */
     179                 :          0 :         cnt_cck = dm_info->cck_ok_cnt + dm_info->cck_err_cnt;
     180                 :            : 
     181         [ #  # ]:          0 :         if (!coex_stat->wl_gl_busy) {
     182         [ #  # ]:          0 :                 if (cnt_cck > 250) {
     183         [ #  # ]:          0 :                         if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] < 5)
     184                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY2]++;
     185                 :            : 
     186         [ #  # ]:          0 :                         if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] == 5) {
     187                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] = 0;
     188                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] = 0;
     189                 :            :                         }
     190         [ #  # ]:          0 :                 } else if (cnt_cck < 100) {
     191         [ #  # ]:          0 :                         if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] < 5)
     192                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY0]++;
     193                 :            : 
     194         [ #  # ]:          0 :                         if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] == 5) {
     195                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] = 0;
     196                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] = 0;
     197                 :            :                         }
     198                 :            :                 } else {
     199         [ #  # ]:          0 :                         if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] < 5)
     200                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY1]++;
     201                 :            : 
     202         [ #  # ]:          0 :                         if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] == 5) {
     203                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY0] = 0;
     204                 :          0 :                                 coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] = 0;
     205                 :            :                         }
     206                 :            :                 }
     207                 :            : 
     208         [ #  # ]:          0 :                 if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY2] == 5)
     209                 :          0 :                         coex_stat->wl_noisy_level = 2;
     210         [ #  # ]:          0 :                 else if (coex_stat->cnt_wl[COEX_CNT_WL_NOISY1] == 5)
     211                 :          0 :                         coex_stat->wl_noisy_level = 1;
     212                 :            :                 else
     213                 :          0 :                         coex_stat->wl_noisy_level = 0;
     214                 :            :         }
     215                 :          0 : }
     216                 :            : 
     217                 :          0 : static void rtw_coex_tdma_timer_base(struct rtw_dev *rtwdev, u8 type)
     218                 :            : {
     219                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     220                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     221                 :          0 :         u8 para[2] = {0};
     222                 :            : 
     223         [ #  # ]:          0 :         if (coex_stat->tdma_timer_base == type)
     224                 :          0 :                 return;
     225                 :            : 
     226                 :          0 :         coex_stat->tdma_timer_base = type;
     227                 :            : 
     228                 :          0 :         para[0] = COEX_H2C69_TDMA_SLOT;
     229                 :            : 
     230         [ #  # ]:          0 :         if (type == 3) /* 4-slot  */
     231                 :          0 :                 para[1] = PARA1_H2C69_TDMA_4SLOT; /* 4-slot */
     232                 :            :         else /* 2-slot  */
     233                 :          0 :                 para[1] = PARA1_H2C69_TDMA_2SLOT;
     234                 :            : 
     235                 :          0 :         rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
     236                 :            : 
     237                 :            :         /* no 5ms_wl_slot_extend for 4-slot mode  */
     238         [ #  # ]:          0 :         if (coex_stat->tdma_timer_base == 3)
     239                 :          0 :                 rtw_coex_wl_ccklock_action(rtwdev);
     240                 :            : }
     241                 :            : 
     242                 :          0 : static void rtw_coex_set_wl_pri_mask(struct rtw_dev *rtwdev, u8 bitmap,
     243                 :            :                                      u8 data)
     244                 :            : {
     245                 :          0 :         u32 addr;
     246                 :            : 
     247                 :          0 :         addr = REG_BT_COEX_TABLE_H + (bitmap / 8);
     248                 :          0 :         bitmap = bitmap % 8;
     249                 :            : 
     250                 :          0 :         rtw_write8_mask(rtwdev, addr, BIT(bitmap), data);
     251                 :            : }
     252                 :            : 
     253                 :          0 : void rtw_coex_write_scbd(struct rtw_dev *rtwdev, u16 bitpos, bool set)
     254                 :            : {
     255                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     256                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     257                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     258                 :          0 :         u16 val = 0x2;
     259                 :            : 
     260         [ #  # ]:          0 :         if (!chip->scbd_support)
     261                 :            :                 return;
     262                 :            : 
     263                 :          0 :         val |= coex_stat->score_board;
     264                 :            : 
     265                 :            :         /* for 8822b, scbd[10] is CQDDR on
     266                 :            :          * for 8822c, scbd[10] is no fix 2M
     267                 :            :          */
     268   [ #  #  #  # ]:          0 :         if (!chip->new_scbd10_def && (bitpos & COEX_SCBD_FIX2M)) {
     269         [ #  # ]:          0 :                 if (set)
     270                 :          0 :                         val &= ~COEX_SCBD_FIX2M;
     271                 :            :                 else
     272                 :          0 :                         val |= COEX_SCBD_FIX2M;
     273                 :            :         } else {
     274         [ #  # ]:          0 :                 if (set)
     275                 :          0 :                         val |= bitpos;
     276                 :            :                 else
     277                 :          0 :                         val &= ~bitpos;
     278                 :            :         }
     279                 :            : 
     280         [ #  # ]:          0 :         if (val != coex_stat->score_board) {
     281                 :          0 :                 coex_stat->score_board = val;
     282                 :          0 :                 val |= BIT_BT_INT_EN;
     283                 :          0 :                 rtw_write16(rtwdev, REG_WIFI_BT_INFO, val);
     284                 :            :         }
     285                 :            : }
     286                 :            : 
     287                 :          0 : static u16 rtw_coex_read_scbd(struct rtw_dev *rtwdev)
     288                 :            : {
     289                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     290                 :            : 
     291                 :          0 :         if (!chip->scbd_support)
     292                 :            :                 return 0;
     293                 :            : 
     294                 :          0 :         return (rtw_read16(rtwdev, REG_WIFI_BT_INFO)) & ~(BIT_BT_INT_EN);
     295                 :            : }
     296                 :            : 
     297                 :          0 : static void rtw_coex_check_rfk(struct rtw_dev *rtwdev)
     298                 :            : {
     299                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     300                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     301                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     302                 :          0 :         struct rtw_coex_rfe *coex_rfe = &coex->rfe;
     303                 :          0 :         u8 cnt = 0;
     304                 :          0 :         u32 wait_cnt;
     305                 :          0 :         bool btk, wlk;
     306                 :            : 
     307   [ #  #  #  # ]:          0 :         if (coex_rfe->wlg_at_btg && chip->scbd_support &&
     308         [ #  # ]:          0 :             coex_stat->bt_iqk_state != 0xff) {
     309                 :            :                 wait_cnt = COEX_RFK_TIMEOUT / COEX_MIN_DELAY;
     310                 :          0 :                 do {
     311                 :            :                         /* BT RFK */
     312         [ #  # ]:          0 :                         btk = !!(rtw_coex_read_scbd(rtwdev) & COEX_SCBD_BT_RFK);
     313                 :            : 
     314                 :            :                         /* WL RFK */
     315                 :          0 :                         wlk = !!(rtw_read8(rtwdev, REG_ARFR4) & BIT_WL_RFK);
     316                 :            : 
     317   [ #  #  #  # ]:          0 :                         if (!btk && !wlk)
     318                 :            :                                 break;
     319                 :            : 
     320         [ #  # ]:          0 :                         mdelay(COEX_MIN_DELAY);
     321         [ #  # ]:          0 :                 } while (++cnt < wait_cnt);
     322                 :            : 
     323         [ #  # ]:          0 :                 if (cnt >= wait_cnt)
     324                 :          0 :                         coex_stat->bt_iqk_state = 0xff;
     325                 :            :         }
     326                 :          0 : }
     327                 :            : 
     328                 :          0 : static void rtw_coex_query_bt_info(struct rtw_dev *rtwdev)
     329                 :            : {
     330                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     331                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     332                 :            : 
     333                 :          0 :         if (coex_stat->bt_disabled)
     334                 :            :                 return;
     335                 :            : 
     336                 :          0 :         rtw_fw_query_bt_info(rtwdev);
     337                 :            : }
     338                 :            : 
     339                 :          0 : static void rtw_coex_monitor_bt_enable(struct rtw_dev *rtwdev)
     340                 :            : {
     341                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     342                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     343                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     344                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     345                 :          0 :         bool bt_disabled = false;
     346                 :          0 :         u16 score_board;
     347                 :            : 
     348         [ #  # ]:          0 :         if (chip->scbd_support) {
     349                 :          0 :                 score_board = rtw_coex_read_scbd(rtwdev);
     350                 :          0 :                 bt_disabled = !(score_board & COEX_SCBD_ONOFF);
     351                 :            :         }
     352                 :            : 
     353         [ #  # ]:          0 :         if (coex_stat->bt_disabled != bt_disabled) {
     354                 :          0 :                 rtw_dbg(rtwdev, RTW_DBG_COEX, "coex: BT state changed (%d) -> (%d)\n",
     355                 :            :                         coex_stat->bt_disabled, bt_disabled);
     356                 :            : 
     357                 :          0 :                 coex_stat->bt_disabled = bt_disabled;
     358                 :          0 :                 coex_stat->bt_ble_scan_type = 0;
     359                 :          0 :                 coex_dm->cur_bt_lna_lvl = 0;
     360                 :            :         }
     361                 :            : 
     362         [ #  # ]:          0 :         if (!coex_stat->bt_disabled) {
     363                 :          0 :                 coex_stat->bt_reenable = true;
     364                 :          0 :                 ieee80211_queue_delayed_work(rtwdev->hw,
     365                 :            :                                              &coex->bt_reenable_work, 15 * HZ);
     366                 :            :         } else {
     367                 :          0 :                 coex_stat->bt_mailbox_reply = false;
     368                 :          0 :                 coex_stat->bt_reenable = false;
     369                 :            :         }
     370                 :          0 : }
     371                 :            : 
     372                 :          0 : static void rtw_coex_update_wl_link_info(struct rtw_dev *rtwdev, u8 reason)
     373                 :            : {
     374                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     375                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     376                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     377                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     378                 :          0 :         struct rtw_traffic_stats *stats = &rtwdev->stats;
     379                 :          0 :         bool is_5G = false;
     380                 :          0 :         bool scan = false, link = false;
     381                 :          0 :         int i;
     382                 :          0 :         u8 rssi_state;
     383                 :          0 :         u8 rssi_step;
     384                 :          0 :         u8 rssi;
     385                 :            : 
     386                 :          0 :         scan = test_bit(RTW_FLAG_SCANNING, rtwdev->flags);
     387                 :          0 :         coex_stat->wl_connected = !!rtwdev->sta_cnt;
     388                 :          0 :         coex_stat->wl_gl_busy = test_bit(RTW_FLAG_BUSY_TRAFFIC, rtwdev->flags);
     389                 :            : 
     390         [ #  # ]:          0 :         if (stats->tx_throughput > stats->rx_throughput)
     391                 :          0 :                 coex_stat->wl_tput_dir = COEX_WL_TPUT_TX;
     392                 :            :         else
     393                 :          0 :                 coex_stat->wl_tput_dir = COEX_WL_TPUT_RX;
     394                 :            : 
     395   [ #  #  #  #  :          0 :         if (scan || link || reason == COEX_RSN_2GCONSTART ||
                   #  # ]
     396         [ #  # ]:          0 :             reason == COEX_RSN_2GSCANSTART || reason == COEX_RSN_2GSWITCHBAND)
     397                 :          0 :                 coex_stat->wl_linkscan_proc = true;
     398                 :            :         else
     399                 :          0 :                 coex_stat->wl_linkscan_proc = false;
     400                 :            : 
     401                 :          0 :         rtw_coex_wl_noisy_detect(rtwdev);
     402                 :            : 
     403         [ #  # ]:          0 :         for (i = 0; i < 4; i++) {
     404                 :          0 :                 rssi_state = coex_dm->wl_rssi_state[i];
     405                 :          0 :                 rssi_step = chip->wl_rssi_step[i];
     406                 :          0 :                 rssi = rtwdev->dm_info.min_rssi;
     407         [ #  # ]:          0 :                 rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state,
     408                 :            :                                                       rssi, rssi_step);
     409                 :          0 :                 coex_dm->wl_rssi_state[i] = rssi_state;
     410                 :            :         }
     411                 :            : 
     412      [ #  #  # ]:          0 :         switch (reason) {
     413                 :            :         case COEX_RSN_5GSCANSTART:
     414                 :            :         case COEX_RSN_5GSWITCHBAND:
     415                 :            :         case COEX_RSN_5GCONSTART:
     416                 :            : 
     417                 :            :                 is_5G = true;
     418                 :            :                 break;
     419                 :          0 :         case COEX_RSN_2GSCANSTART:
     420                 :            :         case COEX_RSN_2GSWITCHBAND:
     421                 :            :         case COEX_RSN_2GCONSTART:
     422                 :            : 
     423                 :          0 :                 is_5G = false;
     424                 :          0 :                 break;
     425                 :          0 :         default:
     426         [ #  # ]:          0 :                 if (rtwdev->hal.current_band_type == RTW_BAND_5G)
     427                 :            :                         is_5G = true;
     428                 :            :                 else
     429                 :          0 :                         is_5G = false;
     430                 :            :                 break;
     431                 :            :         }
     432                 :            : 
     433                 :          0 :         coex->under_5g = is_5G;
     434                 :          0 : }
     435                 :            : 
     436                 :          0 : static inline u8 *get_payload_from_coex_resp(struct sk_buff *resp)
     437                 :            : {
     438                 :          0 :         struct rtw_c2h_cmd *c2h;
     439                 :          0 :         u32 pkt_offset;
     440                 :            : 
     441                 :          0 :         pkt_offset = *((u32 *)resp->cb);
     442                 :          0 :         c2h = (struct rtw_c2h_cmd *)(resp->data + pkt_offset);
     443                 :            : 
     444                 :          0 :         return c2h->payload;
     445                 :            : }
     446                 :            : 
     447                 :          0 : void rtw_coex_info_response(struct rtw_dev *rtwdev, struct sk_buff *skb)
     448                 :            : {
     449                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     450                 :          0 :         u8 *payload = get_payload_from_coex_resp(skb);
     451                 :            : 
     452         [ #  # ]:          0 :         if (payload[0] != COEX_RESP_ACK_BY_WL_FW)
     453                 :            :                 return;
     454                 :            : 
     455                 :          0 :         skb_queue_tail(&coex->queue, skb);
     456                 :          0 :         wake_up(&coex->wait);
     457                 :            : }
     458                 :            : 
     459                 :          0 : static struct sk_buff *rtw_coex_info_request(struct rtw_dev *rtwdev,
     460                 :            :                                              struct rtw_coex_info_req *req)
     461                 :            : {
     462                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     463                 :          0 :         struct sk_buff *skb_resp = NULL;
     464                 :            : 
     465                 :          0 :         mutex_lock(&coex->mutex);
     466                 :            : 
     467                 :          0 :         rtw_fw_query_bt_mp_info(rtwdev, req);
     468                 :            : 
     469   [ #  #  #  #  :          0 :         if (!wait_event_timeout(coex->wait, !skb_queue_empty(&coex->queue),
          #  #  #  #  #  
                #  #  # ]
     470                 :            :                                 COEX_REQUEST_TIMEOUT)) {
     471                 :          0 :                 rtw_err(rtwdev, "coex request time out\n");
     472                 :          0 :                 goto out;
     473                 :            :         }
     474                 :            : 
     475                 :          0 :         skb_resp = skb_dequeue(&coex->queue);
     476         [ #  # ]:          0 :         if (!skb_resp) {
     477                 :          0 :                 rtw_err(rtwdev, "failed to get coex info response\n");
     478                 :          0 :                 goto out;
     479                 :            :         }
     480                 :            : 
     481                 :          0 : out:
     482                 :          0 :         mutex_unlock(&coex->mutex);
     483                 :          0 :         return skb_resp;
     484                 :            : }
     485                 :            : 
     486                 :          0 : static bool rtw_coex_get_bt_scan_type(struct rtw_dev *rtwdev, u8 *scan_type)
     487                 :            : {
     488                 :          0 :         struct rtw_coex_info_req req = {0};
     489                 :          0 :         struct sk_buff *skb;
     490                 :          0 :         u8 *payload;
     491                 :          0 :         bool ret = false;
     492                 :            : 
     493                 :          0 :         req.op_code = BT_MP_INFO_OP_SCAN_TYPE;
     494                 :          0 :         skb = rtw_coex_info_request(rtwdev, &req);
     495         [ #  # ]:          0 :         if (!skb)
     496                 :          0 :                 goto out;
     497                 :            : 
     498                 :          0 :         payload = get_payload_from_coex_resp(skb);
     499                 :          0 :         *scan_type = GET_COEX_RESP_BT_SCAN_TYPE(payload);
     500                 :          0 :         dev_kfree_skb_any(skb);
     501                 :          0 :         ret = true;
     502                 :            : 
     503                 :          0 : out:
     504                 :          0 :         return ret;
     505                 :            : }
     506                 :            : 
     507                 :          0 : static bool rtw_coex_set_lna_constrain_level(struct rtw_dev *rtwdev,
     508                 :            :                                              u8 lna_constrain_level)
     509                 :            : {
     510                 :          0 :         struct rtw_coex_info_req req = {0};
     511                 :          0 :         struct sk_buff *skb;
     512                 :          0 :         bool ret = false;
     513                 :            : 
     514                 :          0 :         req.op_code = BT_MP_INFO_OP_LNA_CONSTRAINT;
     515                 :          0 :         req.para1 = lna_constrain_level;
     516                 :          0 :         skb = rtw_coex_info_request(rtwdev, &req);
     517         [ #  # ]:          0 :         if (!skb)
     518                 :          0 :                 goto out;
     519                 :            : 
     520                 :          0 :         dev_kfree_skb_any(skb);
     521                 :          0 :         ret = true;
     522                 :            : 
     523                 :          0 : out:
     524                 :          0 :         return ret;
     525                 :            : }
     526                 :            : 
     527                 :          0 : static void rtw_coex_update_bt_link_info(struct rtw_dev *rtwdev)
     528                 :            : {
     529                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     530                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     531                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     532                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     533                 :          0 :         u8 i;
     534                 :          0 :         u8 rssi_state;
     535                 :          0 :         u8 rssi_step;
     536                 :          0 :         u8 rssi;
     537                 :            : 
     538                 :            :         /* update wl/bt rssi by btinfo */
     539         [ #  # ]:          0 :         for (i = 0; i < COEX_RSSI_STEP; i++) {
     540                 :          0 :                 rssi_state = coex_dm->bt_rssi_state[i];
     541                 :          0 :                 rssi_step = chip->bt_rssi_step[i];
     542                 :          0 :                 rssi = coex_stat->bt_rssi;
     543         [ #  # ]:          0 :                 rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state,
     544                 :            :                                                       rssi, rssi_step);
     545                 :          0 :                 coex_dm->bt_rssi_state[i] = rssi_state;
     546                 :            :         }
     547                 :            : 
     548         [ #  # ]:          0 :         for (i = 0; i < COEX_RSSI_STEP; i++) {
     549                 :          0 :                 rssi_state = coex_dm->wl_rssi_state[i];
     550                 :          0 :                 rssi_step = chip->wl_rssi_step[i];
     551                 :          0 :                 rssi = rtwdev->dm_info.min_rssi;
     552         [ #  # ]:          0 :                 rssi_state = rtw_coex_next_rssi_state(rtwdev, rssi_state,
     553                 :            :                                                       rssi, rssi_step);
     554                 :          0 :                 coex_dm->wl_rssi_state[i] = rssi_state;
     555                 :            :         }
     556                 :            : 
     557         [ #  # ]:          0 :         if (coex_stat->bt_ble_scan_en &&
     558         [ #  # ]:          0 :             coex_stat->cnt_bt[COEX_CNT_BT_INFOUPDATE] % 3 == 0) {
     559                 :          0 :                 u8 scan_type;
     560                 :            : 
     561         [ #  # ]:          0 :                 if (rtw_coex_get_bt_scan_type(rtwdev, &scan_type)) {
     562                 :          0 :                         coex_stat->bt_ble_scan_type = scan_type;
     563         [ #  # ]:          0 :                         if ((coex_stat->bt_ble_scan_type & 0x1) == 0x1)
     564                 :          0 :                                 coex_stat->bt_init_scan = true;
     565                 :            :                         else
     566                 :          0 :                                 coex_stat->bt_init_scan = false;
     567                 :            :                 }
     568                 :            :         }
     569                 :            : 
     570                 :          0 :         coex_stat->bt_profile_num = 0;
     571                 :            : 
     572                 :            :         /* set link exist status */
     573         [ #  # ]:          0 :         if (!(coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION)) {
     574                 :          0 :                 coex_stat->bt_link_exist = false;
     575                 :          0 :                 coex_stat->bt_pan_exist = false;
     576                 :          0 :                 coex_stat->bt_a2dp_exist = false;
     577                 :          0 :                 coex_stat->bt_hid_exist = false;
     578                 :          0 :                 coex_stat->bt_hfp_exist = false;
     579                 :            :         } else {
     580                 :            :                 /* connection exists */
     581                 :          0 :                 coex_stat->bt_link_exist = true;
     582         [ #  # ]:          0 :                 if (coex_stat->bt_info_lb2 & COEX_INFO_FTP) {
     583                 :          0 :                         coex_stat->bt_pan_exist = true;
     584                 :          0 :                         coex_stat->bt_profile_num++;
     585                 :            :                 } else {
     586                 :          0 :                         coex_stat->bt_pan_exist = false;
     587                 :            :                 }
     588                 :            : 
     589         [ #  # ]:          0 :                 if (coex_stat->bt_info_lb2 & COEX_INFO_A2DP) {
     590                 :          0 :                         coex_stat->bt_a2dp_exist = true;
     591                 :          0 :                         coex_stat->bt_profile_num++;
     592                 :            :                 } else {
     593                 :          0 :                         coex_stat->bt_a2dp_exist = false;
     594                 :            :                 }
     595                 :            : 
     596         [ #  # ]:          0 :                 if (coex_stat->bt_info_lb2 & COEX_INFO_HID) {
     597                 :          0 :                         coex_stat->bt_hid_exist = true;
     598                 :          0 :                         coex_stat->bt_profile_num++;
     599                 :            :                 } else {
     600                 :          0 :                         coex_stat->bt_hid_exist = false;
     601                 :            :                 }
     602                 :            : 
     603         [ #  # ]:          0 :                 if (coex_stat->bt_info_lb2 & COEX_INFO_SCO_ESCO) {
     604                 :          0 :                         coex_stat->bt_hfp_exist = true;
     605                 :          0 :                         coex_stat->bt_profile_num++;
     606                 :            :                 } else {
     607                 :          0 :                         coex_stat->bt_hfp_exist = false;
     608                 :            :                 }
     609                 :            :         }
     610                 :            : 
     611         [ #  # ]:          0 :         if (coex_stat->bt_info_lb2 & COEX_INFO_INQ_PAGE) {
     612                 :          0 :                 coex_dm->bt_status = COEX_BTSTATUS_INQ_PAGE;
     613         [ #  # ]:          0 :         } else if (!(coex_stat->bt_info_lb2 & COEX_INFO_CONNECTION)) {
     614                 :          0 :                 coex_dm->bt_status = COEX_BTSTATUS_NCON_IDLE;
     615         [ #  # ]:          0 :         } else if (coex_stat->bt_info_lb2 == COEX_INFO_CONNECTION) {
     616                 :          0 :                 coex_dm->bt_status = COEX_BTSTATUS_CON_IDLE;
     617         [ #  # ]:          0 :         } else if ((coex_stat->bt_info_lb2 & COEX_INFO_SCO_ESCO) ||
     618                 :            :                    (coex_stat->bt_info_lb2 & COEX_INFO_SCO_BUSY)) {
     619         [ #  # ]:          0 :                 if (coex_stat->bt_info_lb2 & COEX_INFO_ACL_BUSY)
     620                 :          0 :                         coex_dm->bt_status = COEX_BTSTATUS_ACL_SCO_BUSY;
     621                 :            :                 else
     622                 :          0 :                         coex_dm->bt_status = COEX_BTSTATUS_SCO_BUSY;
     623         [ #  # ]:          0 :         } else if (coex_stat->bt_info_lb2 & COEX_INFO_ACL_BUSY) {
     624                 :          0 :                 coex_dm->bt_status = COEX_BTSTATUS_ACL_BUSY;
     625                 :            :         } else {
     626                 :          0 :                 coex_dm->bt_status = COEX_BTSTATUS_MAX;
     627                 :            :         }
     628                 :            : 
     629                 :          0 :         coex_stat->cnt_bt[COEX_CNT_BT_INFOUPDATE]++;
     630                 :            : 
     631                 :          0 :         rtw_dbg(rtwdev, RTW_DBG_COEX, "coex: bt status(%d)\n", coex_dm->bt_status);
     632                 :          0 : }
     633                 :            : 
     634                 :          0 : static void rtw_coex_update_wl_ch_info(struct rtw_dev *rtwdev, u8 type)
     635                 :            : {
     636                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     637                 :          0 :         struct rtw_coex_dm *coex_dm = &rtwdev->coex.dm;
     638                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
     639                 :          0 :         u8 link = 0;
     640                 :          0 :         u8 center_chan = 0;
     641                 :          0 :         u8 bw;
     642                 :          0 :         int i;
     643                 :            : 
     644                 :          0 :         bw = rtwdev->hal.current_band_width;
     645                 :            : 
     646         [ #  # ]:          0 :         if (type != COEX_MEDIA_DISCONNECT)
     647                 :          0 :                 center_chan = rtwdev->hal.current_channel;
     648                 :            : 
     649   [ #  #  #  #  :          0 :         if (center_chan == 0 || (efuse->share_ant && center_chan <= 14)) {
                   #  # ]
     650                 :            :                 link = 0;
     651         [ #  # ]:          0 :         } else if (center_chan <= 14) {
     652                 :          0 :                 link = 0x1;
     653                 :            : 
     654         [ #  # ]:          0 :                 if (bw == RTW_CHANNEL_WIDTH_40)
     655                 :          0 :                         bw = chip->bt_afh_span_bw40;
     656                 :            :                 else
     657                 :          0 :                         bw = chip->bt_afh_span_bw20;
     658         [ #  # ]:          0 :         } else if (chip->afh_5g_num > 1) {
     659         [ #  # ]:          0 :                 for (i = 0; i < chip->afh_5g_num; i++) {
     660         [ #  # ]:          0 :                         if (center_chan == chip->afh_5g[i].wl_5g_ch) {
     661                 :          0 :                                 link = 0x3;
     662                 :          0 :                                 center_chan = chip->afh_5g[i].bt_skip_ch;
     663                 :          0 :                                 bw = chip->afh_5g[i].bt_skip_span;
     664                 :          0 :                                 break;
     665                 :            :                         }
     666                 :            :                 }
     667                 :            :         }
     668                 :            : 
     669                 :          0 :         coex_dm->wl_ch_info[0] = link;
     670                 :          0 :         coex_dm->wl_ch_info[1] = center_chan;
     671                 :          0 :         coex_dm->wl_ch_info[2] = bw;
     672                 :            : 
     673                 :          0 :         rtw_fw_wl_ch_info(rtwdev, link, center_chan, bw);
     674                 :          0 : }
     675                 :            : 
     676                 :          0 : static void rtw_coex_set_bt_tx_power(struct rtw_dev *rtwdev, u8 bt_pwr_dec_lvl)
     677                 :            : {
     678                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     679                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     680                 :            : 
     681                 :          0 :         if (bt_pwr_dec_lvl == coex_dm->cur_bt_pwr_lvl)
     682                 :            :                 return;
     683                 :            : 
     684                 :          0 :         coex_dm->cur_bt_pwr_lvl = bt_pwr_dec_lvl;
     685                 :            : 
     686                 :          0 :         rtw_fw_force_bt_tx_power(rtwdev, bt_pwr_dec_lvl);
     687                 :            : }
     688                 :            : 
     689                 :          0 : static void rtw_coex_set_bt_rx_gain(struct rtw_dev *rtwdev, u8 bt_lna_lvl)
     690                 :            : {
     691                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     692                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     693                 :            : 
     694         [ #  # ]:          0 :         if (bt_lna_lvl == coex_dm->cur_bt_lna_lvl)
     695                 :            :                 return;
     696                 :            : 
     697                 :          0 :         coex_dm->cur_bt_lna_lvl = bt_lna_lvl;
     698                 :            : 
     699                 :            :         /* notify BT rx gain table changed */
     700         [ #  # ]:          0 :         if (bt_lna_lvl < 7) {
     701                 :          0 :                 rtw_coex_set_lna_constrain_level(rtwdev, bt_lna_lvl);
     702                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_RXGAIN, true);
     703                 :            :         } else {
     704                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_RXGAIN, false);
     705                 :            :         }
     706                 :            : }
     707                 :            : 
     708                 :          0 : static void rtw_coex_set_rf_para(struct rtw_dev *rtwdev,
     709                 :            :                                  struct coex_rf_para para)
     710                 :            : {
     711                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     712                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     713                 :          0 :         u8 offset = 0;
     714                 :            : 
     715   [ #  #  #  # ]:          0 :         if (coex->freerun && coex_stat->wl_noisy_level <= 1)
     716                 :          0 :                 offset = 3;
     717                 :            : 
     718                 :          0 :         rtw_coex_set_wl_tx_power(rtwdev, para.wl_pwr_dec_lvl);
     719         [ #  # ]:          0 :         rtw_coex_set_bt_tx_power(rtwdev, para.bt_pwr_dec_lvl + offset);
     720                 :          0 :         rtw_coex_set_wl_rx_gain(rtwdev, para.wl_low_gain_en);
     721                 :          0 :         rtw_coex_set_bt_rx_gain(rtwdev, para.bt_lna_lvl);
     722                 :          0 : }
     723                 :            : 
     724                 :          0 : u32 rtw_coex_read_indirect_reg(struct rtw_dev *rtwdev, u16 addr)
     725                 :            : {
     726                 :          0 :         u32 val;
     727                 :            : 
     728         [ #  # ]:          0 :         if (!ltecoex_read_reg(rtwdev, addr, &val)) {
     729                 :          0 :                 rtw_err(rtwdev, "failed to read indirect register\n");
     730                 :          0 :                 return 0;
     731                 :            :         }
     732                 :            : 
     733                 :          0 :         return val;
     734                 :            : }
     735                 :            : 
     736                 :          0 : void rtw_coex_write_indirect_reg(struct rtw_dev *rtwdev, u16 addr,
     737                 :            :                                  u32 mask, u32 val)
     738                 :            : {
     739                 :          0 :         u32 shift = __ffs(mask);
     740                 :          0 :         u32 tmp;
     741                 :            : 
     742                 :          0 :         tmp = rtw_coex_read_indirect_reg(rtwdev, addr);
     743                 :          0 :         tmp = (tmp & (~mask)) | ((val << shift) & mask);
     744                 :            : 
     745         [ #  # ]:          0 :         if (!ltecoex_reg_write(rtwdev, addr, tmp))
     746                 :          0 :                 rtw_err(rtwdev, "failed to write indirect register\n");
     747                 :          0 : }
     748                 :            : 
     749                 :          0 : static void rtw_coex_coex_ctrl_owner(struct rtw_dev *rtwdev, bool wifi_control)
     750                 :            : {
     751         [ #  # ]:          0 :         if (wifi_control)
     752                 :          0 :                 rtw_write32_set(rtwdev, REG_SYS_SDIO_CTRL, BIT_LTE_MUX_CTRL_PATH);
     753                 :            :         else
     754                 :          0 :                 rtw_write32_clr(rtwdev, REG_SYS_SDIO_CTRL, BIT_LTE_MUX_CTRL_PATH);
     755                 :          0 : }
     756                 :            : 
     757                 :          0 : static void rtw_coex_set_gnt_bt(struct rtw_dev *rtwdev, u8 state)
     758                 :            : {
     759                 :          0 :         rtw_coex_write_indirect_reg(rtwdev, 0x38, 0xc000, state);
     760                 :          0 :         rtw_coex_write_indirect_reg(rtwdev, 0x38, 0x0c00, state);
     761                 :          0 : }
     762                 :            : 
     763                 :          0 : static void rtw_coex_set_gnt_wl(struct rtw_dev *rtwdev, u8 state)
     764                 :            : {
     765                 :          0 :         rtw_coex_write_indirect_reg(rtwdev, 0x38, 0x3000, state);
     766                 :          0 :         rtw_coex_write_indirect_reg(rtwdev, 0x38, 0x0300, state);
     767                 :          0 : }
     768                 :            : 
     769                 :          0 : static void rtw_coex_set_table(struct rtw_dev *rtwdev, u32 table0, u32 table1)
     770                 :            : {
     771                 :            : #define DEF_BRK_TABLE_VAL       0xf0ffffff
     772                 :          0 :         rtw_write32(rtwdev, REG_BT_COEX_TABLE0, table0);
     773                 :          0 :         rtw_write32(rtwdev, REG_BT_COEX_TABLE1, table1);
     774                 :          0 :         rtw_write32(rtwdev, REG_BT_COEX_BRK_TABLE, DEF_BRK_TABLE_VAL);
     775                 :          0 : }
     776                 :            : 
     777                 :          0 : static void rtw_coex_table(struct rtw_dev *rtwdev, u8 type)
     778                 :            : {
     779                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     780                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     781                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     782                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
     783                 :            : 
     784                 :          0 :         coex_dm->cur_table = type;
     785                 :            : 
     786         [ #  # ]:          0 :         if (efuse->share_ant) {
     787         [ #  # ]:          0 :                 if (type < chip->table_sant_num)
     788                 :          0 :                         rtw_coex_set_table(rtwdev,
     789                 :            :                                            chip->table_sant[type].bt,
     790                 :          0 :                                            chip->table_sant[type].wl);
     791                 :            :         } else {
     792                 :          0 :                 type = type - 100;
     793         [ #  # ]:          0 :                 if (type < chip->table_nsant_num)
     794                 :          0 :                         rtw_coex_set_table(rtwdev,
     795                 :            :                                            chip->table_nsant[type].bt,
     796                 :          0 :                                            chip->table_nsant[type].wl);
     797                 :            :         }
     798                 :          0 : }
     799                 :            : 
     800                 :          0 : static void rtw_coex_ignore_wlan_act(struct rtw_dev *rtwdev, bool enable)
     801                 :            : {
     802                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     803                 :            : 
     804                 :          0 :         if (coex->stop_dm)
     805                 :            :                 return;
     806                 :            : 
     807                 :          0 :         rtw_fw_bt_ignore_wlan_action(rtwdev, enable);
     808                 :            : }
     809                 :            : 
     810                 :          0 : static void rtw_coex_power_save_state(struct rtw_dev *rtwdev, u8 ps_type,
     811                 :            :                                       u8 lps_val, u8 rpwm_val)
     812                 :            : {
     813                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     814                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     815                 :          0 :         u8 lps_mode = 0x0;
     816                 :            : 
     817                 :          0 :         lps_mode = rtwdev->lps_conf.mode;
     818                 :            : 
     819      [ #  #  # ]:          0 :         switch (ps_type) {
     820                 :          0 :         case COEX_PS_WIFI_NATIVE:
     821                 :            :                 /* recover to original 32k low power setting */
     822                 :          0 :                 coex_stat->wl_force_lps_ctrl = false;
     823                 :            : 
     824                 :          0 :                 rtw_leave_lps(rtwdev);
     825                 :          0 :                 break;
     826                 :          0 :         case COEX_PS_LPS_OFF:
     827                 :          0 :                 coex_stat->wl_force_lps_ctrl = true;
     828         [ #  # ]:          0 :                 if (lps_mode)
     829                 :          0 :                         rtw_fw_coex_tdma_type(rtwdev, 0x8, 0, 0, 0, 0);
     830                 :            : 
     831                 :          0 :                 rtw_leave_lps(rtwdev);
     832                 :          0 :                 break;
     833                 :            :         default:
     834                 :            :                 break;
     835                 :            :         }
     836                 :          0 : }
     837                 :            : 
     838                 :          0 : static void rtw_coex_set_tdma(struct rtw_dev *rtwdev, u8 byte1, u8 byte2,
     839                 :            :                               u8 byte3, u8 byte4, u8 byte5)
     840                 :            : {
     841                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     842                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     843                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     844                 :          0 :         u8 ps_type = COEX_PS_WIFI_NATIVE;
     845                 :          0 :         bool ap_enable = false;
     846                 :            : 
     847                 :          0 :         if (ap_enable && (byte1 & BIT(4) && !(byte1 & BIT(5)))) {
     848                 :            :                 byte1 &= ~BIT(4);
     849                 :            :                 byte1 |= BIT(5);
     850                 :            : 
     851                 :            :                 byte5 |= BIT(5);
     852                 :            :                 byte5 &= ~BIT(6);
     853                 :            : 
     854                 :            :                 ps_type = COEX_PS_WIFI_NATIVE;
     855                 :            :                 rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0);
     856         [ #  # ]:          0 :         } else if (byte1 & BIT(4) && !(byte1 & BIT(5))) {
     857         [ #  # ]:          0 :                 if (chip->pstdma_type == COEX_PSTDMA_FORCE_LPSOFF)
     858                 :            :                         ps_type = COEX_PS_LPS_OFF;
     859                 :            :                 else
     860                 :          0 :                         ps_type = COEX_PS_LPS_ON;
     861                 :          0 :                 rtw_coex_power_save_state(rtwdev, ps_type, 0x50, 0x4);
     862                 :            :         } else {
     863                 :          0 :                 ps_type = COEX_PS_WIFI_NATIVE;
     864                 :          0 :                 rtw_coex_power_save_state(rtwdev, ps_type, 0x0, 0x0);
     865                 :            :         }
     866                 :            : 
     867                 :          0 :         coex_dm->ps_tdma_para[0] = byte1;
     868                 :          0 :         coex_dm->ps_tdma_para[1] = byte2;
     869                 :          0 :         coex_dm->ps_tdma_para[2] = byte3;
     870                 :          0 :         coex_dm->ps_tdma_para[3] = byte4;
     871                 :          0 :         coex_dm->ps_tdma_para[4] = byte5;
     872                 :            : 
     873                 :          0 :         rtw_fw_coex_tdma_type(rtwdev, byte1, byte2, byte3, byte4, byte5);
     874                 :          0 : }
     875                 :            : 
     876                 :          0 : static void rtw_coex_tdma(struct rtw_dev *rtwdev, bool force, u32 tcase)
     877                 :            : {
     878                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     879                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     880                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
     881                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
     882                 :          0 :         u8 n, type;
     883                 :          0 :         bool turn_on;
     884                 :            : 
     885         [ #  # ]:          0 :         if (tcase & TDMA_4SLOT)/* 4-slot (50ms) mode */
     886                 :          0 :                 rtw_coex_tdma_timer_base(rtwdev, 3);
     887                 :            :         else
     888                 :          0 :                 rtw_coex_tdma_timer_base(rtwdev, 0);
     889                 :            : 
     890                 :          0 :         type = (u8)(tcase & 0xff);
     891                 :            : 
     892   [ #  #  #  # ]:          0 :         turn_on = (type == 0 || type == 100) ? false : true;
     893                 :            : 
     894         [ #  # ]:          0 :         if (!force) {
     895         [ #  # ]:          0 :                 if (turn_on == coex_dm->cur_ps_tdma_on &&
     896         [ #  # ]:          0 :                     type == coex_dm->cur_ps_tdma) {
     897                 :            :                         return;
     898                 :            :                 }
     899                 :            :         }
     900                 :            : 
     901         [ #  # ]:          0 :         if (turn_on) {
     902                 :            :                 /* enable TBTT interrupt */
     903                 :          0 :                 rtw_write8_set(rtwdev, REG_BCN_CTRL, BIT_EN_BCN_FUNCTION);
     904                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, true);
     905                 :            :         } else {
     906                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_TDMA, false);
     907                 :            :         }
     908                 :            : 
     909         [ #  # ]:          0 :         if (efuse->share_ant) {
     910         [ #  # ]:          0 :                 if (type < chip->tdma_sant_num)
     911                 :          0 :                         rtw_coex_set_tdma(rtwdev,
     912                 :          0 :                                           chip->tdma_sant[type].para[0],
     913                 :          0 :                                           chip->tdma_sant[type].para[1],
     914                 :          0 :                                           chip->tdma_sant[type].para[2],
     915                 :          0 :                                           chip->tdma_sant[type].para[3],
     916                 :          0 :                                           chip->tdma_sant[type].para[4]);
     917                 :            :         } else {
     918                 :          0 :                 n = type - 100;
     919         [ #  # ]:          0 :                 if (n < chip->tdma_nsant_num)
     920                 :          0 :                         rtw_coex_set_tdma(rtwdev,
     921                 :          0 :                                           chip->tdma_nsant[n].para[0],
     922                 :          0 :                                           chip->tdma_nsant[n].para[1],
     923                 :          0 :                                           chip->tdma_nsant[n].para[2],
     924                 :          0 :                                           chip->tdma_nsant[n].para[3],
     925                 :          0 :                                           chip->tdma_nsant[n].para[4]);
     926                 :            :         }
     927                 :            : 
     928                 :            :         /* update pre state */
     929                 :          0 :         coex_dm->cur_ps_tdma_on = turn_on;
     930                 :          0 :         coex_dm->cur_ps_tdma = type;
     931                 :            : 
     932                 :          0 :         rtw_dbg(rtwdev, RTW_DBG_COEX, "coex: coex tdma type (%d)\n", type);
     933                 :            : }
     934                 :            : 
     935                 :          0 : static void rtw_coex_set_ant_path(struct rtw_dev *rtwdev, bool force, u8 phase)
     936                 :            : {
     937                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
     938                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
     939                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
     940                 :          0 :         u8 ctrl_type = COEX_SWITCH_CTRL_MAX;
     941                 :          0 :         u8 pos_type = COEX_SWITCH_TO_MAX;
     942                 :            : 
     943   [ #  #  #  # ]:          0 :         if (!force && coex_dm->cur_ant_pos_type == phase)
     944                 :            :                 return;
     945                 :            : 
     946                 :          0 :         coex_dm->cur_ant_pos_type = phase;
     947                 :            : 
     948                 :            :         /* avoid switch coex_ctrl_owner during BT IQK */
     949                 :          0 :         rtw_coex_check_rfk(rtwdev);
     950                 :            : 
     951   [ #  #  #  #  :          0 :         switch (phase) {
             #  #  #  #  
                      # ]
     952                 :          0 :         case COEX_SET_ANT_POWERON:
     953                 :            :                 /* set path control owner to BT at power-on */
     954         [ #  # ]:          0 :                 if (coex_stat->bt_disabled)
     955                 :          0 :                         rtw_coex_coex_ctrl_owner(rtwdev, true);
     956                 :            :                 else
     957                 :          0 :                         rtw_coex_coex_ctrl_owner(rtwdev, false);
     958                 :            : 
     959                 :            :                 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
     960                 :            :                 pos_type = COEX_SWITCH_TO_BT;
     961                 :            :                 break;
     962                 :          0 :         case COEX_SET_ANT_INIT:
     963         [ #  # ]:          0 :                 if (coex_stat->bt_disabled) {
     964                 :            :                         /* set GNT_BT to SW low */
     965                 :          0 :                         rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW);
     966                 :            : 
     967                 :            :                         /* set GNT_WL to SW high */
     968                 :          0 :                         rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
     969                 :            :                 } else {
     970                 :            :                         /* set GNT_BT to SW high */
     971                 :          0 :                         rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_HIGH);
     972                 :            : 
     973                 :            :                         /* set GNT_WL to SW low */
     974                 :          0 :                         rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_LOW);
     975                 :            :                 }
     976                 :            : 
     977                 :            :                 /* set path control owner to wl at initial step */
     978                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, true);
     979                 :            : 
     980                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
     981                 :          0 :                 pos_type = COEX_SWITCH_TO_BT;
     982                 :          0 :                 break;
     983                 :          0 :         case COEX_SET_ANT_WONLY:
     984                 :            :                 /* set GNT_BT to SW Low */
     985                 :          0 :                 rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_LOW);
     986                 :            : 
     987                 :            :                 /* Set GNT_WL to SW high */
     988                 :          0 :                 rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
     989                 :            : 
     990                 :            :                 /* set path control owner to wl at initial step */
     991                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, true);
     992                 :            : 
     993                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
     994                 :          0 :                 pos_type = COEX_SWITCH_TO_WLG;
     995                 :          0 :                 break;
     996                 :          0 :         case COEX_SET_ANT_WOFF:
     997                 :            :                 /* set path control owner to BT */
     998                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, false);
     999                 :            : 
    1000                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_BT;
    1001                 :          0 :                 pos_type = COEX_SWITCH_TO_NOCARE;
    1002                 :          0 :                 break;
    1003                 :          0 :         case COEX_SET_ANT_2G:
    1004                 :            :                 /* set GNT_BT to PTA */
    1005                 :          0 :                 rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA);
    1006                 :            : 
    1007                 :            :                 /* set GNT_WL to PTA */
    1008                 :          0 :                 rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_HW_PTA);
    1009                 :            : 
    1010                 :            :                 /* set path control owner to wl at runtime step */
    1011                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, true);
    1012                 :            : 
    1013                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_PTA;
    1014                 :          0 :                 pos_type = COEX_SWITCH_TO_NOCARE;
    1015                 :          0 :                 break;
    1016                 :          0 :         case COEX_SET_ANT_5G:
    1017                 :            :                 /* set GNT_BT to PTA */
    1018                 :          0 :                 rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_HIGH);
    1019                 :            : 
    1020                 :            :                 /* set GNT_WL to SW high */
    1021                 :          0 :                 rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
    1022                 :            : 
    1023                 :            :                 /* set path control owner to wl at runtime step */
    1024                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, true);
    1025                 :            : 
    1026                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
    1027                 :          0 :                 pos_type = COEX_SWITCH_TO_WLA;
    1028                 :          0 :                 break;
    1029                 :          0 :         case COEX_SET_ANT_2G_FREERUN:
    1030                 :            :                 /* set GNT_BT to SW high */
    1031                 :          0 :                 rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_SW_HIGH);
    1032                 :            : 
    1033                 :            :                 /* Set GNT_WL to SW high */
    1034                 :          0 :                 rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_SW_HIGH);
    1035                 :            : 
    1036                 :            :                 /* set path control owner to wl at runtime step */
    1037                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, true);
    1038                 :            : 
    1039                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
    1040                 :          0 :                 pos_type = COEX_SWITCH_TO_WLG_BT;
    1041                 :          0 :                 break;
    1042                 :          0 :         case COEX_SET_ANT_2G_WLBT:
    1043                 :            :                 /* set GNT_BT to SW high */
    1044                 :          0 :                 rtw_coex_set_gnt_bt(rtwdev, COEX_GNT_SET_HW_PTA);
    1045                 :            : 
    1046                 :            :                 /* Set GNT_WL to SW high */
    1047                 :          0 :                 rtw_coex_set_gnt_wl(rtwdev, COEX_GNT_SET_HW_PTA);
    1048                 :            : 
    1049                 :            :                 /* set path control owner to wl at runtime step */
    1050                 :          0 :                 rtw_coex_coex_ctrl_owner(rtwdev, true);
    1051                 :            : 
    1052                 :          0 :                 ctrl_type = COEX_SWITCH_CTRL_BY_BBSW;
    1053                 :          0 :                 pos_type = COEX_SWITCH_TO_WLG_BT;
    1054                 :          0 :                 break;
    1055                 :            :         default:
    1056                 :          0 :                 WARN(1, "unknown phase when setting antenna path\n");
    1057                 :          0 :                 return;
    1058                 :            :         }
    1059                 :            : 
    1060                 :          0 :         if (ctrl_type < COEX_SWITCH_CTRL_MAX && pos_type < COEX_SWITCH_TO_MAX)
    1061         [ #  # ]:          0 :                 rtw_coex_set_ant_switch(rtwdev, ctrl_type, pos_type);
    1062                 :            : }
    1063                 :            : 
    1064                 :          0 : static u8 rtw_coex_algorithm(struct rtw_dev *rtwdev)
    1065                 :            : {
    1066                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1067                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1068                 :          0 :         u8 algorithm = COEX_ALGO_NOPROFILE;
    1069                 :          0 :         u8 profile_map = 0;
    1070                 :            : 
    1071         [ #  # ]:          0 :         if (coex_stat->bt_hfp_exist)
    1072                 :          0 :                 profile_map |= BPM_HFP;
    1073         [ #  # ]:          0 :         if (coex_stat->bt_hid_exist)
    1074                 :          0 :                 profile_map |= BPM_HID;
    1075         [ #  # ]:          0 :         if (coex_stat->bt_a2dp_exist)
    1076                 :          0 :                 profile_map |= BPM_A2DP;
    1077         [ #  # ]:          0 :         if (coex_stat->bt_pan_exist)
    1078                 :          0 :                 profile_map |= BPM_PAN;
    1079                 :            : 
    1080   [ #  #  #  #  :          0 :         switch (profile_map) {
             #  #  #  #  
                      # ]
    1081                 :            :         case BPM_HFP:
    1082                 :            :                 algorithm = COEX_ALGO_HFP;
    1083                 :            :                 break;
    1084                 :          0 :         case           BPM_HID:
    1085                 :            :         case BPM_HFP + BPM_HID:
    1086                 :          0 :                 algorithm = COEX_ALGO_HID;
    1087                 :          0 :                 break;
    1088                 :          0 :         case BPM_HFP           + BPM_A2DP:
    1089                 :            :         case           BPM_HID + BPM_A2DP:
    1090                 :            :         case BPM_HFP + BPM_HID + BPM_A2DP:
    1091                 :          0 :                 algorithm = COEX_ALGO_A2DP_HID;
    1092                 :          0 :                 break;
    1093                 :          0 :         case BPM_HFP                      + BPM_PAN:
    1094                 :            :         case           BPM_HID            + BPM_PAN:
    1095                 :            :         case BPM_HFP + BPM_HID            + BPM_PAN:
    1096                 :          0 :                 algorithm = COEX_ALGO_PAN_HID;
    1097                 :          0 :                 break;
    1098                 :          0 :         case BPM_HFP           + BPM_A2DP + BPM_PAN:
    1099                 :            :         case           BPM_HID + BPM_A2DP + BPM_PAN:
    1100                 :            :         case BPM_HFP + BPM_HID + BPM_A2DP + BPM_PAN:
    1101                 :          0 :                 algorithm = COEX_ALGO_A2DP_PAN_HID;
    1102                 :          0 :                 break;
    1103                 :          0 :         case                                BPM_PAN:
    1104                 :          0 :                 algorithm = COEX_ALGO_PAN;
    1105                 :          0 :                 break;
    1106                 :          0 :         case                     BPM_A2DP + BPM_PAN:
    1107                 :          0 :                 algorithm = COEX_ALGO_A2DP_PAN;
    1108                 :          0 :                 break;
    1109                 :          0 :         case                     BPM_A2DP:
    1110         [ #  # ]:          0 :                 if (coex_stat->bt_multi_link) {
    1111         [ #  # ]:          0 :                         if (coex_stat->bt_hid_pair_num > 0)
    1112                 :            :                                 algorithm = COEX_ALGO_A2DP_HID;
    1113                 :            :                         else
    1114                 :          0 :                                 algorithm = COEX_ALGO_A2DP_PAN;
    1115                 :            :                 } else {
    1116                 :            :                         algorithm = COEX_ALGO_A2DP;
    1117                 :            :                 }
    1118                 :            :                 break;
    1119                 :          0 :         default:
    1120                 :          0 :                 algorithm = COEX_ALGO_NOPROFILE;
    1121                 :          0 :                 break;
    1122                 :            :         }
    1123                 :            : 
    1124                 :          0 :         return algorithm;
    1125                 :            : }
    1126                 :            : 
    1127                 :          0 : static void rtw_coex_action_coex_all_off(struct rtw_dev *rtwdev)
    1128                 :            : {
    1129                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1130                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1131                 :          0 :         u8 table_case, tdma_case;
    1132                 :            : 
    1133         [ #  # ]:          0 :         if (efuse->share_ant) {
    1134                 :            :                 /* Shared-Ant */
    1135                 :            :                 table_case = 2;
    1136                 :            :                 tdma_case = 0;
    1137                 :            :         } else {
    1138                 :            :                 /* Non-Shared-Ant */
    1139                 :          0 :                 table_case = 100;
    1140                 :          0 :                 tdma_case = 100;
    1141                 :            :         }
    1142                 :            : 
    1143                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1144                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1145                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1146                 :          0 : }
    1147                 :            : 
    1148                 :          0 : static void rtw_coex_action_freerun(struct rtw_dev *rtwdev)
    1149                 :            : {
    1150                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1151                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1152                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1153                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1154                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1155                 :          0 :         u8 level = 0;
    1156                 :            : 
    1157         [ #  # ]:          0 :         if (efuse->share_ant)
    1158                 :            :                 return;
    1159                 :            : 
    1160                 :          0 :         coex->freerun = true;
    1161                 :            : 
    1162         [ #  # ]:          0 :         if (coex_stat->wl_connected)
    1163                 :          0 :                 rtw_coex_update_wl_ch_info(rtwdev, COEX_MEDIA_CONNECT);
    1164                 :            : 
    1165                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G_FREERUN);
    1166                 :            : 
    1167                 :          0 :         rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false);
    1168                 :            : 
    1169   [ #  #  #  # ]:          0 :         if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[0]))
    1170                 :            :                 level = 2;
    1171   [ #  #  #  # ]:          0 :         else if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
    1172                 :            :                 level = 3;
    1173   [ #  #  #  # ]:          0 :         else if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[2]))
    1174                 :            :                 level = 4;
    1175                 :            :         else
    1176                 :            :                 level = 5;
    1177                 :            : 
    1178         [ #  # ]:          0 :         if (level > chip->wl_rf_para_num - 1)
    1179                 :          0 :                 level = chip->wl_rf_para_num - 1;
    1180                 :            : 
    1181         [ #  # ]:          0 :         if (coex_stat->wl_tput_dir == COEX_WL_TPUT_TX)
    1182                 :          0 :                 rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_tx[level]);
    1183                 :            :         else
    1184                 :          0 :                 rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[level]);
    1185                 :            : 
    1186                 :          0 :         rtw_coex_table(rtwdev, 100);
    1187                 :          0 :         rtw_coex_tdma(rtwdev, false, 100);
    1188                 :            : }
    1189                 :            : 
    1190                 :          0 : static void rtw_coex_action_bt_whql_test(struct rtw_dev *rtwdev)
    1191                 :            : {
    1192                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1193                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1194                 :          0 :         u8 table_case, tdma_case;
    1195                 :            : 
    1196         [ #  # ]:          0 :         if (efuse->share_ant) {
    1197                 :            :                 /* Shared-Ant */
    1198                 :            :                 table_case = 2;
    1199                 :            :                 tdma_case = 0;
    1200                 :            :         } else {
    1201                 :            :                 /* Non-Shared-Ant */
    1202                 :          0 :                 table_case = 100;
    1203                 :          0 :                 tdma_case = 100;
    1204                 :            :         }
    1205                 :            : 
    1206                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1207                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1208                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1209                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1210                 :          0 : }
    1211                 :            : 
    1212                 :          0 : static void rtw_coex_action_bt_relink(struct rtw_dev *rtwdev)
    1213                 :            : {
    1214                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1215                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1216                 :          0 :         u8 table_case, tdma_case;
    1217                 :            : 
    1218         [ #  # ]:          0 :         if (efuse->share_ant) {
    1219                 :            :                 /* Shared-Ant */
    1220                 :            :                 table_case = 1;
    1221                 :            :                 tdma_case = 0;
    1222                 :            :         } else {
    1223                 :            :                 /* Non-Shared-Ant */
    1224                 :          0 :                 table_case = 100;
    1225                 :          0 :                 tdma_case = 100;
    1226                 :            :         }
    1227                 :            : 
    1228                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1229                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1230                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1231                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1232                 :          0 : }
    1233                 :            : 
    1234                 :          0 : static void rtw_coex_action_bt_idle(struct rtw_dev *rtwdev)
    1235                 :            : {
    1236                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1237                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1238                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1239                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1240                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1241                 :          0 :         struct rtw_coex_rfe *coex_rfe = &coex->rfe;
    1242                 :          0 :         u8 table_case = 0xff, tdma_case = 0xff;
    1243                 :            : 
    1244         [ #  # ]:          0 :         if (coex_rfe->ant_switch_with_bt &&
    1245         [ #  # ]:          0 :             coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
    1246         [ #  # ]:          0 :                 if (efuse->share_ant &&
    1247   [ #  #  #  # ]:          0 :                     COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1])) {
    1248                 :            :                         table_case = 0;
    1249                 :            :                         tdma_case = 0;
    1250         [ #  # ]:          0 :                 } else if (!efuse->share_ant) {
    1251                 :            :                         table_case = 100;
    1252                 :            :                         tdma_case = 100;
    1253                 :            :                 }
    1254                 :            :         }
    1255                 :            : 
    1256                 :            :         if (table_case != 0xff && tdma_case != 0xff) {
    1257                 :          0 :                 rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G_FREERUN);
    1258                 :          0 :                 rtw_coex_table(rtwdev, table_case);
    1259                 :          0 :                 rtw_coex_tdma(rtwdev, false, tdma_case);
    1260                 :          0 :                 return;
    1261                 :            :         }
    1262                 :            : 
    1263                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1264                 :            : 
    1265         [ #  # ]:          0 :         if (efuse->share_ant) {
    1266                 :            :                 /* Shared-Ant */
    1267         [ #  # ]:          0 :                 if (!coex_stat->wl_gl_busy) {
    1268                 :            :                         table_case = 10;
    1269                 :            :                         tdma_case = 3;
    1270         [ #  # ]:          0 :                 } else if (coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
    1271                 :            :                         table_case = 6;
    1272                 :            :                         tdma_case = 7;
    1273                 :            :                 } else {
    1274                 :          0 :                         table_case = 12;
    1275                 :          0 :                         tdma_case = 7;
    1276                 :            :                 }
    1277                 :            :         } else {
    1278                 :            :                 /* Non-Shared-Ant */
    1279         [ #  # ]:          0 :                 if (!coex_stat->wl_gl_busy) {
    1280                 :            :                         table_case = 112;
    1281                 :            :                         tdma_case = 104;
    1282         [ #  # ]:          0 :                 } else if ((coex_stat->bt_ble_scan_type & 0x2) &&
    1283         [ #  # ]:          0 :                             coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE) {
    1284                 :            :                         table_case = 114;
    1285                 :            :                         tdma_case = 103;
    1286                 :            :                 } else {
    1287                 :          0 :                         table_case = 112;
    1288                 :          0 :                         tdma_case = 103;
    1289                 :            :                 }
    1290                 :            :         }
    1291                 :            : 
    1292                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1293                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1294                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1295                 :            : }
    1296                 :            : 
    1297                 :          0 : static void rtw_coex_action_bt_inquiry(struct rtw_dev *rtwdev)
    1298                 :            : {
    1299                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1300                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1301                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1302                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1303                 :          0 :         bool wl_hi_pri = false;
    1304                 :          0 :         u8 table_case, tdma_case;
    1305                 :          0 :         u32 slot_type = 0;
    1306                 :            : 
    1307   [ #  #  #  # ]:          0 :         if (coex_stat->wl_linkscan_proc || coex_stat->wl_hi_pri_task1 ||
    1308                 :            :             coex_stat->wl_hi_pri_task2)
    1309                 :          0 :                 wl_hi_pri = true;
    1310                 :            : 
    1311         [ #  # ]:          0 :         if (efuse->share_ant) {
    1312                 :            :                 /* Shared-Ant */
    1313         [ #  # ]:          0 :                 if (wl_hi_pri) {
    1314                 :          0 :                         table_case = 15;
    1315         [ #  # ]:          0 :                         if (coex_stat->bt_a2dp_exist &&
    1316         [ #  # ]:          0 :                             !coex_stat->bt_pan_exist) {
    1317                 :            :                                 slot_type = TDMA_4SLOT;
    1318                 :            :                                 tdma_case = 11;
    1319         [ #  # ]:          0 :                         } else if (coex_stat->wl_hi_pri_task1) {
    1320                 :            :                                 tdma_case = 6;
    1321         [ #  # ]:          0 :                         } else if (!coex_stat->bt_page) {
    1322                 :            :                                 tdma_case = 8;
    1323                 :            :                         } else {
    1324                 :          0 :                                 tdma_case = 9;
    1325                 :            :                         }
    1326         [ #  # ]:          0 :                 } else if (coex_stat->wl_connected) {
    1327                 :            :                         table_case = 10;
    1328                 :            :                         tdma_case = 10;
    1329                 :            :                 } else {
    1330                 :          0 :                         table_case = 1;
    1331                 :          0 :                         tdma_case = 0;
    1332                 :            :                 }
    1333                 :            :         } else {
    1334                 :            :                 /* Non_Shared-Ant */
    1335         [ #  # ]:          0 :                 if (wl_hi_pri) {
    1336                 :          0 :                         table_case = 113;
    1337         [ #  # ]:          0 :                         if (coex_stat->bt_a2dp_exist &&
    1338         [ #  # ]:          0 :                             !coex_stat->bt_pan_exist)
    1339                 :            :                                 tdma_case = 111;
    1340         [ #  # ]:          0 :                         else if (coex_stat->wl_hi_pri_task1)
    1341                 :            :                                 tdma_case = 106;
    1342         [ #  # ]:          0 :                         else if (!coex_stat->bt_page)
    1343                 :            :                                 tdma_case = 108;
    1344                 :            :                         else
    1345                 :          0 :                                 tdma_case = 109;
    1346         [ #  # ]:          0 :                 } else if (coex_stat->wl_connected) {
    1347                 :            :                         table_case = 101;
    1348                 :            :                         tdma_case = 110;
    1349                 :            :                 } else {
    1350                 :          0 :                         table_case = 100;
    1351                 :          0 :                         tdma_case = 100;
    1352                 :            :                 }
    1353                 :            :         }
    1354                 :            : 
    1355                 :          0 :         rtw_dbg(rtwdev, RTW_DBG_COEX, "coex: wifi hi(%d), bt page(%d)\n",
    1356                 :            :                 wl_hi_pri, coex_stat->bt_page);
    1357                 :            : 
    1358                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1359                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1360                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1361                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
    1362                 :          0 : }
    1363                 :            : 
    1364                 :          0 : static void rtw_coex_action_bt_hfp(struct rtw_dev *rtwdev)
    1365                 :            : {
    1366                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1367                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1368                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1369                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1370                 :          0 :         u8 table_case, tdma_case;
    1371                 :            : 
    1372         [ #  # ]:          0 :         if (efuse->share_ant) {
    1373                 :            :                 /* Shared-Ant */
    1374         [ #  # ]:          0 :                 if (coex_stat->bt_multi_link) {
    1375                 :            :                         table_case = 10;
    1376                 :            :                         tdma_case = 17;
    1377                 :            :                 } else {
    1378                 :          0 :                         table_case = 10;
    1379                 :          0 :                         tdma_case = 5;
    1380                 :            :                 }
    1381                 :            :         } else {
    1382                 :            :                 /* Non-Shared-Ant */
    1383         [ #  # ]:          0 :                 if (coex_stat->bt_multi_link) {
    1384                 :            :                         table_case = 112;
    1385                 :            :                         tdma_case = 117;
    1386                 :            :                 } else {
    1387                 :          0 :                         table_case = 105;
    1388                 :          0 :                         tdma_case = 100;
    1389                 :            :                 }
    1390                 :            :         }
    1391                 :            : 
    1392                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1393                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1394                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1395                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1396                 :          0 : }
    1397                 :            : 
    1398                 :          0 : static void rtw_coex_action_bt_hid(struct rtw_dev *rtwdev)
    1399                 :            : {
    1400                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1401                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1402                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1403                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1404                 :          0 :         u8 table_case, tdma_case;
    1405                 :          0 :         u32 wl_bw;
    1406                 :            : 
    1407                 :          0 :         wl_bw = rtwdev->hal.current_band_width;
    1408                 :            : 
    1409         [ #  # ]:          0 :         if (efuse->share_ant) {
    1410                 :            :                 /* Shared-Ant */
    1411         [ #  # ]:          0 :                 if (coex_stat->bt_ble_exist) {
    1412                 :            :                         /* RCU */
    1413         [ #  # ]:          0 :                         if (!coex_stat->wl_gl_busy)
    1414                 :            :                                 table_case = 14;
    1415                 :            :                         else
    1416                 :          0 :                                 table_case = 15;
    1417                 :            : 
    1418   [ #  #  #  # ]:          0 :                         if (coex_stat->bt_a2dp_active || wl_bw == 0)
    1419                 :            :                                 tdma_case = 18;
    1420         [ #  # ]:          0 :                         else if (coex_stat->wl_gl_busy)
    1421                 :            :                                 tdma_case = 8;
    1422                 :            :                         else
    1423                 :          0 :                                 tdma_case = 4;
    1424                 :            :                 } else {
    1425   [ #  #  #  # ]:          0 :                         if (coex_stat->bt_a2dp_active || wl_bw == 0) {
    1426                 :            :                                 table_case = 8;
    1427                 :            :                                 tdma_case = 4;
    1428                 :            :                         } else {
    1429                 :            :                                 /* for 4/18 HID */
    1430         [ #  # ]:          0 :                                 if (coex_stat->bt_418_hid_exist &&
    1431         [ #  # ]:          0 :                                     coex_stat->wl_gl_busy)
    1432                 :            :                                         table_case = 12;
    1433                 :            :                                 else
    1434                 :          0 :                                         table_case = 10;
    1435                 :            :                                 tdma_case = 4;
    1436                 :            :                         }
    1437                 :            :                 }
    1438                 :            :         } else {
    1439                 :            :                 /* Non-Shared-Ant */
    1440         [ #  # ]:          0 :                 if (coex_stat->bt_a2dp_active) {
    1441                 :            :                         table_case = 113;
    1442                 :            :                         tdma_case = 118;
    1443         [ #  # ]:          0 :                 } else if (coex_stat->bt_ble_exist) {
    1444                 :            :                         /* BLE */
    1445                 :          0 :                         table_case = 113;
    1446                 :            : 
    1447         [ #  # ]:          0 :                         if (coex_stat->wl_gl_busy)
    1448                 :            :                                 tdma_case = 106;
    1449                 :            :                         else
    1450                 :          0 :                                 tdma_case = 104;
    1451                 :            :                 } else {
    1452                 :            :                         table_case = 113;
    1453                 :            :                         tdma_case = 104;
    1454                 :            :                 }
    1455                 :            :         }
    1456                 :            : 
    1457                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1458                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1459                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1460                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1461                 :          0 : }
    1462                 :            : 
    1463                 :          0 : static void rtw_coex_action_bt_a2dp(struct rtw_dev *rtwdev)
    1464                 :            : {
    1465                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1466                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1467                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1468                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1469                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1470                 :          0 :         u8 table_case, tdma_case;
    1471                 :          0 :         u32 slot_type = 0;
    1472                 :            : 
    1473         [ #  # ]:          0 :         if (efuse->share_ant) {
    1474                 :            :                 /* Shared-Ant */
    1475                 :          0 :                 slot_type = TDMA_4SLOT;
    1476                 :            : 
    1477   [ #  #  #  # ]:          0 :                 if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0)
    1478                 :            :                         table_case = 10;
    1479                 :            :                 else
    1480                 :          0 :                         table_case = 9;
    1481                 :            : 
    1482         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1483                 :            :                         tdma_case = 13;
    1484                 :            :                 else
    1485                 :          0 :                         tdma_case = 14;
    1486                 :            :         } else {
    1487                 :            :                 /* Non-Shared-Ant */
    1488                 :          0 :                 table_case = 112;
    1489                 :            : 
    1490   [ #  #  #  # ]:          0 :                 if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
    1491                 :            :                         tdma_case = 112;
    1492                 :            :                 else
    1493                 :            :                         tdma_case = 113;
    1494                 :            :         }
    1495                 :            : 
    1496                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1497                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1498                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1499                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
    1500                 :          0 : }
    1501                 :            : 
    1502                 :          0 : static void rtw_coex_action_bt_a2dpsink(struct rtw_dev *rtwdev)
    1503                 :            : {
    1504                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1505                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1506                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1507                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1508                 :          0 :         u8 table_case, tdma_case;
    1509                 :          0 :         bool ap_enable = false;
    1510                 :            : 
    1511         [ #  # ]:          0 :         if (efuse->share_ant) { /* Shared-Ant */
    1512                 :          0 :                 if (ap_enable) {
    1513                 :            :                         table_case = 2;
    1514                 :            :                         tdma_case = 0;
    1515         [ #  # ]:          0 :                 } else if (coex_stat->wl_gl_busy) {
    1516                 :            :                         table_case = 28;
    1517                 :            :                         tdma_case = 20;
    1518                 :            :                 } else {
    1519                 :          0 :                         table_case = 28;
    1520                 :          0 :                         tdma_case = 26;
    1521                 :            :                 }
    1522                 :            :         } else { /* Non-Shared-Ant */
    1523                 :            :                 if (ap_enable) {
    1524                 :            :                         table_case = 100;
    1525                 :            :                         tdma_case = 100;
    1526                 :            :                 } else {
    1527                 :            :                         table_case = 119;
    1528                 :            :                         tdma_case = 120;
    1529                 :            :                 }
    1530                 :            :         }
    1531                 :            : 
    1532                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1533                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1534                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1535                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1536                 :          0 : }
    1537                 :            : 
    1538                 :          0 : static void rtw_coex_action_bt_pan(struct rtw_dev *rtwdev)
    1539                 :            : {
    1540                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1541                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1542                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1543                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1544                 :          0 :         u8 table_case, tdma_case;
    1545                 :            : 
    1546         [ #  # ]:          0 :         if (efuse->share_ant) {
    1547                 :            :                 /* Shared-Ant */
    1548   [ #  #  #  # ]:          0 :                 if (coex_stat->wl_gl_busy && coex_stat->wl_noisy_level == 0)
    1549                 :            :                         table_case = 14;
    1550                 :            :                 else
    1551                 :          0 :                         table_case = 10;
    1552                 :            : 
    1553         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1554                 :            :                         tdma_case = 17;
    1555                 :            :                 else
    1556                 :          0 :                         tdma_case = 19;
    1557                 :            :         } else {
    1558                 :            :                 /* Non-Shared-Ant */
    1559                 :          0 :                 table_case = 112;
    1560                 :            : 
    1561         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1562                 :            :                         tdma_case = 117;
    1563                 :            :                 else
    1564                 :          0 :                         tdma_case = 119;
    1565                 :            :         }
    1566                 :            : 
    1567                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1568                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1569                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1570                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1571                 :          0 : }
    1572                 :            : 
    1573                 :          0 : static void rtw_coex_action_bt_a2dp_hid(struct rtw_dev *rtwdev)
    1574                 :            : {
    1575                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1576                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1577                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1578                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1579                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1580                 :          0 :         u8 table_case, tdma_case;
    1581                 :          0 :         u32 slot_type = 0;
    1582                 :            : 
    1583         [ #  # ]:          0 :         if (efuse->share_ant) {
    1584                 :            :                 /* Shared-Ant */
    1585                 :          0 :                 slot_type = TDMA_4SLOT;
    1586                 :            : 
    1587         [ #  # ]:          0 :                 if (coex_stat->bt_ble_exist)
    1588                 :            :                         table_case = 26;
    1589                 :            :                 else
    1590                 :          0 :                         table_case = 9;
    1591                 :            : 
    1592         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy) {
    1593                 :            :                         tdma_case = 13;
    1594                 :            :                 } else {
    1595                 :          0 :                         tdma_case = 14;
    1596                 :            :                 }
    1597                 :            :         } else {
    1598                 :            :                 /* Non-Shared-Ant */
    1599         [ #  # ]:          0 :                 if (coex_stat->bt_ble_exist)
    1600                 :            :                         table_case = 121;
    1601                 :            :                 else
    1602                 :          0 :                         table_case = 113;
    1603                 :            : 
    1604   [ #  #  #  # ]:          0 :                 if (COEX_RSSI_HIGH(coex_dm->wl_rssi_state[1]))
    1605                 :            :                         tdma_case = 112;
    1606                 :            :                 else
    1607                 :            :                         tdma_case = 113;
    1608                 :            :         }
    1609                 :            : 
    1610                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1611                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1612                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1613                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
    1614                 :          0 : }
    1615                 :            : 
    1616                 :          0 : static void rtw_coex_action_bt_a2dp_pan(struct rtw_dev *rtwdev)
    1617                 :            : {
    1618                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1619                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1620                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1621                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1622                 :          0 :         u8 table_case, tdma_case;
    1623                 :            : 
    1624         [ #  # ]:          0 :         if (efuse->share_ant) {
    1625                 :            :                 /* Shared-Ant */
    1626         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy &&
    1627         [ #  # ]:          0 :                     coex_stat->wl_noisy_level == 0)
    1628                 :            :                         table_case = 14;
    1629                 :            :                 else
    1630                 :          0 :                         table_case = 10;
    1631                 :            : 
    1632         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1633                 :            :                         tdma_case = 15;
    1634                 :            :                 else
    1635                 :          0 :                         tdma_case = 20;
    1636                 :            :         } else {
    1637                 :            :                 /* Non-Shared-Ant */
    1638                 :          0 :                 table_case = 112;
    1639                 :            : 
    1640         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1641                 :            :                         tdma_case = 115;
    1642                 :            :                 else
    1643                 :          0 :                         tdma_case = 120;
    1644                 :            :         }
    1645                 :            : 
    1646                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1647                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1648                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1649                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1650                 :          0 : }
    1651                 :            : 
    1652                 :          0 : static void rtw_coex_action_bt_pan_hid(struct rtw_dev *rtwdev)
    1653                 :            : {
    1654                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1655                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1656                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1657                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1658                 :          0 :         u8 table_case, tdma_case;
    1659                 :            : 
    1660         [ #  # ]:          0 :         if (efuse->share_ant) {
    1661                 :            :                 /* Shared-Ant */
    1662                 :          0 :                 table_case = 9;
    1663                 :            : 
    1664         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1665                 :            :                         tdma_case = 18;
    1666                 :            :                 else
    1667                 :          0 :                         tdma_case = 19;
    1668                 :            :         } else {
    1669                 :            :                 /* Non-Shared-Ant */
    1670                 :          0 :                 table_case = 113;
    1671                 :            : 
    1672         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1673                 :            :                         tdma_case = 117;
    1674                 :            :                 else
    1675                 :          0 :                         tdma_case = 119;
    1676                 :            :         }
    1677                 :            : 
    1678                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1679                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1680                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1681                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1682                 :          0 : }
    1683                 :            : 
    1684                 :          0 : static void rtw_coex_action_bt_a2dp_pan_hid(struct rtw_dev *rtwdev)
    1685                 :            : {
    1686                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1687                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1688                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1689                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1690                 :          0 :         u8 table_case, tdma_case;
    1691                 :            : 
    1692         [ #  # ]:          0 :         if (efuse->share_ant) {
    1693                 :            :                 /* Shared-Ant */
    1694                 :          0 :                 table_case = 10;
    1695                 :            : 
    1696         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1697                 :            :                         tdma_case = 15;
    1698                 :            :                 else
    1699                 :          0 :                         tdma_case = 20;
    1700                 :            :         } else {
    1701                 :            :                 /* Non-Shared-Ant */
    1702                 :          0 :                 table_case = 113;
    1703                 :            : 
    1704         [ #  # ]:          0 :                 if (coex_stat->wl_gl_busy)
    1705                 :            :                         tdma_case = 115;
    1706                 :            :                 else
    1707                 :          0 :                         tdma_case = 120;
    1708                 :            :         }
    1709                 :            : 
    1710                 :          0 :         rtw_coex_set_ant_path(rtwdev, false, COEX_SET_ANT_2G);
    1711                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1712                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1713                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1714                 :          0 : }
    1715                 :            : 
    1716                 :          0 : static void rtw_coex_action_wl_under5g(struct rtw_dev *rtwdev)
    1717                 :            : {
    1718                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1719                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1720                 :          0 :         u8 table_case, tdma_case;
    1721                 :            : 
    1722                 :          0 :         rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false);
    1723                 :            : 
    1724         [ #  # ]:          0 :         if (efuse->share_ant) {
    1725                 :            :                 /* Shared-Ant */
    1726                 :            :                 table_case = 0;
    1727                 :            :                 tdma_case = 0;
    1728                 :            :         } else {
    1729                 :            :                 /* Non-Shared-Ant */
    1730                 :          0 :                 table_case = 100;
    1731                 :          0 :                 tdma_case = 100;
    1732                 :            :         }
    1733                 :            : 
    1734                 :          0 :         rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
    1735                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1736                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1737                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1738                 :          0 : }
    1739                 :            : 
    1740                 :          0 : static void rtw_coex_action_wl_only(struct rtw_dev *rtwdev)
    1741                 :            : {
    1742                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1743                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1744                 :          0 :         u8 table_case, tdma_case;
    1745                 :            : 
    1746         [ #  # ]:          0 :         if (efuse->share_ant) {
    1747                 :            :                 /* Shared-Ant */
    1748                 :            :                 table_case = 2;
    1749                 :            :                 tdma_case = 0;
    1750                 :            :         } else {
    1751                 :            :                 /* Non-Shared-Ant */
    1752                 :          0 :                 table_case = 100;
    1753                 :          0 :                 tdma_case = 100;
    1754                 :            :         }
    1755                 :            : 
    1756                 :          0 :         rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    1757                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1758                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1759                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1760                 :          0 : }
    1761                 :            : 
    1762                 :          0 : static void rtw_coex_action_wl_native_lps(struct rtw_dev *rtwdev)
    1763                 :            : {
    1764                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1765                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1766                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1767                 :          0 :         u8 table_case, tdma_case;
    1768                 :            : 
    1769         [ #  # ]:          0 :         if (coex->under_5g)
    1770                 :            :                 return;
    1771                 :            : 
    1772         [ #  # ]:          0 :         if (efuse->share_ant) {
    1773                 :            :                 /* Shared-Ant */
    1774                 :            :                 table_case = 28;
    1775                 :            :                 tdma_case = 0;
    1776                 :            :         } else {
    1777                 :            :                 /* Non-Shared-Ant */
    1778                 :          0 :                 table_case = 100;
    1779                 :          0 :                 tdma_case = 100;
    1780                 :            :         }
    1781                 :            : 
    1782                 :          0 :         rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    1783                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1784                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1785                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1786                 :            : }
    1787                 :            : 
    1788                 :          0 : static void rtw_coex_action_wl_linkscan(struct rtw_dev *rtwdev)
    1789                 :            : {
    1790                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1791                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1792                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1793                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1794                 :          0 :         u8 table_case, tdma_case;
    1795                 :          0 :         u32 slot_type = 0;
    1796                 :            : 
    1797         [ #  # ]:          0 :         if (efuse->share_ant) {
    1798                 :            :                 /* Shared-Ant */
    1799         [ #  # ]:          0 :                 if (coex_stat->bt_a2dp_exist) {
    1800                 :            :                         slot_type = TDMA_4SLOT;
    1801                 :            :                         table_case = 9;
    1802                 :            :                         tdma_case = 11;
    1803                 :            :                 } else {
    1804                 :          0 :                         table_case = 9;
    1805                 :          0 :                         tdma_case = 7;
    1806                 :            :                 }
    1807                 :            :         } else {
    1808                 :            :                 /* Non-Shared-Ant */
    1809         [ #  # ]:          0 :                 if (coex_stat->bt_a2dp_exist) {
    1810                 :            :                         table_case = 112;
    1811                 :            :                         tdma_case = 111;
    1812                 :            :                 } else {
    1813                 :          0 :                         table_case = 112;
    1814                 :          0 :                         tdma_case = 107;
    1815                 :            :                 }
    1816                 :            :         }
    1817                 :            : 
    1818                 :          0 :         rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    1819                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1820                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1821                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case | slot_type);
    1822                 :          0 : }
    1823                 :            : 
    1824                 :          0 : static void rtw_coex_action_wl_not_connected(struct rtw_dev *rtwdev)
    1825                 :            : {
    1826                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1827                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    1828                 :          0 :         u8 table_case, tdma_case;
    1829                 :            : 
    1830         [ #  # ]:          0 :         if (efuse->share_ant) {
    1831                 :            :                 /* Shared-Ant */
    1832                 :            :                 table_case = 1;
    1833                 :            :                 tdma_case = 0;
    1834                 :            :         } else {
    1835                 :            :                 /* Non-Shared-Ant */
    1836                 :          0 :                 table_case = 100;
    1837                 :          0 :                 tdma_case = 100;
    1838                 :            :         }
    1839                 :            : 
    1840                 :          0 :         rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    1841                 :          0 :         rtw_coex_set_rf_para(rtwdev, chip->wl_rf_para_rx[0]);
    1842                 :          0 :         rtw_coex_table(rtwdev, table_case);
    1843                 :          0 :         rtw_coex_tdma(rtwdev, false, tdma_case);
    1844                 :          0 : }
    1845                 :            : 
    1846                 :          0 : static void rtw_coex_action_wl_connected(struct rtw_dev *rtwdev)
    1847                 :            : {
    1848                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1849                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1850                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1851                 :          0 :         struct rtw_efuse *efuse = &rtwdev->efuse;
    1852                 :          0 :         u8 algorithm;
    1853                 :            : 
    1854                 :            :         /* Non-Shared-Ant */
    1855   [ #  #  #  # ]:          0 :         if (!efuse->share_ant && coex_stat->wl_gl_busy &&
    1856   [ #  #  #  # ]:          0 :             COEX_RSSI_HIGH(coex_dm->wl_rssi_state[3]) &&
    1857   [ #  #  #  # ]:          0 :             COEX_RSSI_HIGH(coex_dm->bt_rssi_state[0])) {
    1858                 :          0 :                 rtw_coex_action_freerun(rtwdev);
    1859                 :          0 :                 return;
    1860                 :            :         }
    1861                 :            : 
    1862                 :          0 :         algorithm = rtw_coex_algorithm(rtwdev);
    1863                 :            : 
    1864   [ #  #  #  #  :          0 :         switch (algorithm) {
             #  #  #  #  
                      # ]
    1865                 :          0 :         case COEX_ALGO_HFP:
    1866                 :          0 :                 rtw_coex_action_bt_hfp(rtwdev);
    1867                 :          0 :                 break;
    1868                 :          0 :         case COEX_ALGO_HID:
    1869                 :          0 :                 rtw_coex_action_bt_hid(rtwdev);
    1870                 :          0 :                 break;
    1871                 :          0 :         case COEX_ALGO_A2DP:
    1872         [ #  # ]:          0 :                 if (coex_stat->bt_a2dp_sink)
    1873                 :          0 :                         rtw_coex_action_bt_a2dpsink(rtwdev);
    1874                 :            :                 else
    1875                 :          0 :                         rtw_coex_action_bt_a2dp(rtwdev);
    1876                 :            :                 break;
    1877                 :          0 :         case COEX_ALGO_PAN:
    1878                 :          0 :                 rtw_coex_action_bt_pan(rtwdev);
    1879                 :          0 :                 break;
    1880                 :          0 :         case COEX_ALGO_A2DP_HID:
    1881                 :          0 :                 rtw_coex_action_bt_a2dp_hid(rtwdev);
    1882                 :          0 :                 break;
    1883                 :          0 :         case COEX_ALGO_A2DP_PAN:
    1884                 :          0 :                 rtw_coex_action_bt_a2dp_pan(rtwdev);
    1885                 :          0 :                 break;
    1886                 :          0 :         case COEX_ALGO_PAN_HID:
    1887                 :          0 :                 rtw_coex_action_bt_pan_hid(rtwdev);
    1888                 :          0 :                 break;
    1889                 :          0 :         case COEX_ALGO_A2DP_PAN_HID:
    1890                 :          0 :                 rtw_coex_action_bt_a2dp_pan_hid(rtwdev);
    1891                 :          0 :                 break;
    1892                 :          0 :         default:
    1893                 :            :         case COEX_ALGO_NOPROFILE:
    1894                 :          0 :                 rtw_coex_action_bt_idle(rtwdev);
    1895                 :          0 :                 break;
    1896                 :            :         }
    1897                 :            : }
    1898                 :            : 
    1899                 :          0 : static void rtw_coex_run_coex(struct rtw_dev *rtwdev, u8 reason)
    1900                 :            : {
    1901                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1902                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1903                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1904                 :            : 
    1905                 :          0 :         lockdep_assert_held(&rtwdev->mutex);
    1906                 :            : 
    1907                 :          0 :         coex_dm->reason = reason;
    1908                 :            : 
    1909                 :            :         /* update wifi_link_info_ext variable */
    1910                 :          0 :         rtw_coex_update_wl_link_info(rtwdev, reason);
    1911                 :            : 
    1912                 :          0 :         rtw_coex_monitor_bt_enable(rtwdev);
    1913                 :            : 
    1914         [ #  # ]:          0 :         if (coex->stop_dm)
    1915                 :            :                 return;
    1916                 :            : 
    1917         [ #  # ]:          0 :         if (coex_stat->wl_under_ips)
    1918                 :            :                 return;
    1919                 :            : 
    1920   [ #  #  #  # ]:          0 :         if (coex->freeze && !coex_stat->bt_setup_link)
    1921                 :            :                 return;
    1922                 :            : 
    1923                 :          0 :         coex_stat->cnt_wl[COEX_CNT_WL_COEXRUN]++;
    1924                 :          0 :         coex->freerun = false;
    1925                 :            : 
    1926                 :            :         /* Pure-5G Coex Process */
    1927         [ #  # ]:          0 :         if (coex->under_5g) {
    1928                 :          0 :                 coex_stat->wl_coex_mode = COEX_WLINK_5G;
    1929                 :          0 :                 rtw_coex_action_wl_under5g(rtwdev);
    1930                 :          0 :                 goto exit;
    1931                 :            :         }
    1932                 :            : 
    1933                 :          0 :         coex_stat->wl_coex_mode = COEX_WLINK_2G1PORT;
    1934                 :          0 :         rtw_coex_write_scbd(rtwdev, COEX_SCBD_FIX2M, false);
    1935         [ #  # ]:          0 :         if (coex_stat->bt_disabled) {
    1936                 :          0 :                 rtw_coex_action_wl_only(rtwdev);
    1937                 :          0 :                 goto exit;
    1938                 :            :         }
    1939                 :            : 
    1940   [ #  #  #  # ]:          0 :         if (coex_stat->wl_under_lps && !coex_stat->wl_force_lps_ctrl) {
    1941                 :          0 :                 rtw_coex_action_wl_native_lps(rtwdev);
    1942                 :          0 :                 goto exit;
    1943                 :            :         }
    1944                 :            : 
    1945         [ #  # ]:          0 :         if (coex_stat->bt_whck_test) {
    1946                 :          0 :                 rtw_coex_action_bt_whql_test(rtwdev);
    1947                 :          0 :                 goto exit;
    1948                 :            :         }
    1949                 :            : 
    1950         [ #  # ]:          0 :         if (coex_stat->bt_setup_link) {
    1951                 :          0 :                 rtw_coex_action_bt_relink(rtwdev);
    1952                 :          0 :                 goto exit;
    1953                 :            :         }
    1954                 :            : 
    1955         [ #  # ]:          0 :         if (coex_stat->bt_inq_page) {
    1956                 :          0 :                 rtw_coex_action_bt_inquiry(rtwdev);
    1957                 :          0 :                 goto exit;
    1958                 :            :         }
    1959                 :            : 
    1960         [ #  # ]:          0 :         if ((coex_dm->bt_status == COEX_BTSTATUS_NCON_IDLE ||
    1961                 :          0 :              coex_dm->bt_status == COEX_BTSTATUS_CON_IDLE) &&
    1962         [ #  # ]:          0 :              coex_stat->wl_connected) {
    1963                 :          0 :                 rtw_coex_action_bt_idle(rtwdev);
    1964                 :          0 :                 goto exit;
    1965                 :            :         }
    1966                 :            : 
    1967         [ #  # ]:          0 :         if (coex_stat->wl_linkscan_proc) {
    1968                 :          0 :                 rtw_coex_action_wl_linkscan(rtwdev);
    1969                 :          0 :                 goto exit;
    1970                 :            :         }
    1971                 :            : 
    1972         [ #  # ]:          0 :         if (coex_stat->wl_connected)
    1973                 :          0 :                 rtw_coex_action_wl_connected(rtwdev);
    1974                 :            :         else
    1975                 :          0 :                 rtw_coex_action_wl_not_connected(rtwdev);
    1976                 :            : 
    1977                 :          0 : exit:
    1978                 :          0 :         rtw_coex_set_gnt_fix(rtwdev);
    1979                 :          0 :         rtw_coex_limited_wl(rtwdev);
    1980                 :            : }
    1981                 :            : 
    1982                 :          0 : static void rtw_coex_init_coex_var(struct rtw_dev *rtwdev)
    1983                 :            : {
    1984                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    1985                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    1986                 :          0 :         struct rtw_coex_dm *coex_dm = &coex->dm;
    1987                 :          0 :         u8 i;
    1988                 :            : 
    1989                 :          0 :         memset(coex_dm, 0, sizeof(*coex_dm));
    1990                 :          0 :         memset(coex_stat, 0, sizeof(*coex_stat));
    1991                 :            : 
    1992         [ #  # ]:          0 :         for (i = 0; i < COEX_CNT_WL_MAX; i++)
    1993                 :          0 :                 coex_stat->cnt_wl[i] = 0;
    1994                 :            : 
    1995         [ #  # ]:          0 :         for (i = 0; i < COEX_CNT_BT_MAX; i++)
    1996                 :          0 :                 coex_stat->cnt_bt[i] = 0;
    1997                 :            : 
    1998         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(coex_dm->bt_rssi_state); i++)
    1999                 :          0 :                 coex_dm->bt_rssi_state[i] = COEX_RSSI_STATE_LOW;
    2000                 :            : 
    2001         [ #  # ]:          0 :         for (i = 0; i < ARRAY_SIZE(coex_dm->wl_rssi_state); i++)
    2002                 :          0 :                 coex_dm->wl_rssi_state[i] = COEX_RSSI_STATE_LOW;
    2003                 :            : 
    2004                 :          0 :         coex_stat->wl_coex_mode = COEX_WLINK_MAX;
    2005                 :          0 : }
    2006                 :            : 
    2007                 :          0 : static void __rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
    2008                 :            : {
    2009                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2010                 :            : 
    2011                 :          0 :         rtw_coex_init_coex_var(rtwdev);
    2012                 :          0 :         rtw_coex_monitor_bt_enable(rtwdev);
    2013                 :          0 :         rtw_coex_set_rfe_type(rtwdev);
    2014                 :          0 :         rtw_coex_set_init(rtwdev);
    2015                 :            : 
    2016                 :            :         /* set Tx response = Hi-Pri (ex: Transmitting ACK,BA,CTS) */
    2017                 :          0 :         rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_RSP, 1);
    2018                 :            : 
    2019                 :            :         /* set Tx beacon = Hi-Pri */
    2020                 :          0 :         rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_BEACON, 1);
    2021                 :            : 
    2022                 :            :         /* set Tx beacon queue = Hi-Pri */
    2023                 :          0 :         rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_TX_BEACONQ, 1);
    2024                 :            : 
    2025                 :            :         /* antenna config */
    2026         [ #  # ]:          0 :         if (coex->wl_rf_off) {
    2027                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WOFF);
    2028                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ALL, false);
    2029                 :          0 :                 coex->stop_dm = true;
    2030         [ #  # ]:          0 :         } else if (wifi_only) {
    2031                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WONLY);
    2032                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_SCAN,
    2033                 :            :                                     true);
    2034                 :          0 :                 coex->stop_dm = true;
    2035                 :            :         } else {
    2036                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_INIT);
    2037                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_SCAN,
    2038                 :            :                                     true);
    2039                 :          0 :                 coex->stop_dm = false;
    2040                 :          0 :                 coex->freeze = true;
    2041                 :            :         }
    2042                 :            : 
    2043                 :            :         /* PTA parameter */
    2044                 :          0 :         rtw_coex_table(rtwdev, 0);
    2045                 :          0 :         rtw_coex_tdma(rtwdev, true, 0);
    2046         [ #  # ]:          0 :         rtw_coex_query_bt_info(rtwdev);
    2047                 :          0 : }
    2048                 :            : 
    2049                 :          0 : void rtw_coex_power_on_setting(struct rtw_dev *rtwdev)
    2050                 :            : {
    2051                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2052                 :            : 
    2053                 :          0 :         coex->stop_dm = true;
    2054                 :          0 :         coex->wl_rf_off = false;
    2055                 :            : 
    2056                 :            :         /* enable BB, we can write 0x948 */
    2057                 :          0 :         rtw_write8_set(rtwdev, REG_SYS_FUNC_EN, BIT(0) | BIT(1));
    2058                 :            : 
    2059                 :          0 :         rtw_coex_monitor_bt_enable(rtwdev);
    2060                 :          0 :         rtw_coex_set_rfe_type(rtwdev);
    2061                 :            : 
    2062                 :            :         /* set antenna path to BT */
    2063                 :          0 :         rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_POWERON);
    2064                 :            : 
    2065                 :            :         /* red x issue */
    2066                 :          0 :         rtw_write8(rtwdev, 0xff1a, 0x0);
    2067                 :          0 : }
    2068                 :            : 
    2069                 :          0 : void rtw_coex_init_hw_config(struct rtw_dev *rtwdev, bool wifi_only)
    2070                 :            : {
    2071                 :          0 :         __rtw_coex_init_hw_config(rtwdev, wifi_only);
    2072                 :          0 : }
    2073                 :            : 
    2074                 :          0 : void rtw_coex_ips_notify(struct rtw_dev *rtwdev, u8 type)
    2075                 :            : {
    2076                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2077                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2078                 :            : 
    2079         [ #  # ]:          0 :         if (coex->stop_dm)
    2080                 :            :                 return;
    2081                 :            : 
    2082         [ #  # ]:          0 :         if (type == COEX_IPS_ENTER) {
    2083                 :          0 :                 coex_stat->wl_under_ips = true;
    2084                 :            : 
    2085                 :            :                 /* for lps off */
    2086                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ALL, false);
    2087                 :            : 
    2088                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_WOFF);
    2089                 :          0 :                 rtw_coex_action_coex_all_off(rtwdev);
    2090         [ #  # ]:          0 :         } else if (type == COEX_IPS_LEAVE) {
    2091                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_ONOFF, true);
    2092                 :            : 
    2093                 :            :                 /* run init hw config (exclude wifi only) */
    2094                 :          0 :                 __rtw_coex_init_hw_config(rtwdev, false);
    2095                 :            :                 /* sw all off */
    2096                 :            : 
    2097                 :          0 :                 coex_stat->wl_under_ips = false;
    2098                 :            :         }
    2099                 :            : }
    2100                 :            : 
    2101                 :          0 : void rtw_coex_lps_notify(struct rtw_dev *rtwdev, u8 type)
    2102                 :            : {
    2103                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2104                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2105                 :            : 
    2106         [ #  # ]:          0 :         if (coex->stop_dm)
    2107                 :            :                 return;
    2108                 :            : 
    2109         [ #  # ]:          0 :         if (type == COEX_LPS_ENABLE) {
    2110                 :          0 :                 coex_stat->wl_under_lps = true;
    2111                 :            : 
    2112         [ #  # ]:          0 :                 if (coex_stat->wl_force_lps_ctrl) {
    2113                 :            :                         /* for ps-tdma */
    2114                 :          0 :                         rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
    2115                 :            :                 } else {
    2116                 :            :                         /* for native ps */
    2117                 :          0 :                         rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, false);
    2118                 :            : 
    2119                 :          0 :                         rtw_coex_run_coex(rtwdev, COEX_RSN_LPS);
    2120                 :            :                 }
    2121         [ #  # ]:          0 :         } else if (type == COEX_LPS_DISABLE) {
    2122                 :          0 :                 coex_stat->wl_under_lps = false;
    2123                 :            : 
    2124                 :            :                 /* for lps off */
    2125                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
    2126                 :            : 
    2127         [ #  # ]:          0 :                 if (!coex_stat->wl_force_lps_ctrl)
    2128         [ #  # ]:          0 :                         rtw_coex_query_bt_info(rtwdev);
    2129                 :            :         }
    2130                 :            : }
    2131                 :            : 
    2132                 :          0 : void rtw_coex_scan_notify(struct rtw_dev *rtwdev, u8 type)
    2133                 :            : {
    2134                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2135                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2136                 :            : 
    2137         [ #  # ]:          0 :         if (coex->stop_dm)
    2138                 :            :                 return;
    2139                 :            : 
    2140                 :          0 :         coex->freeze = false;
    2141                 :            : 
    2142         [ #  # ]:          0 :         if (type != COEX_SCAN_FINISH)
    2143                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_SCAN |
    2144                 :            :                                     COEX_SCBD_ONOFF, true);
    2145                 :            : 
    2146         [ #  # ]:          0 :         if (type == COEX_SCAN_START_5G) {
    2147                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
    2148                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_5GSCANSTART);
    2149         [ #  # ]:          0 :         } else if ((type == COEX_SCAN_START_2G) || (type == COEX_SCAN_START)) {
    2150                 :          0 :                 coex_stat->wl_hi_pri_task2 = true;
    2151                 :            : 
    2152                 :            :                 /* Force antenna setup for no scan result issue */
    2153                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    2154                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_2GSCANSTART);
    2155                 :            :         } else {
    2156                 :          0 :                 coex_stat->wl_hi_pri_task2 = false;
    2157                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_SCANFINISH);
    2158                 :            :         }
    2159                 :            : }
    2160                 :            : 
    2161                 :          0 : void rtw_coex_switchband_notify(struct rtw_dev *rtwdev, u8 type)
    2162                 :            : {
    2163                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2164                 :            : 
    2165         [ #  # ]:          0 :         if (coex->stop_dm)
    2166                 :            :                 return;
    2167                 :            : 
    2168         [ #  # ]:          0 :         if (type == COEX_SWITCH_TO_5G)
    2169                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_5GSWITCHBAND);
    2170         [ #  # ]:          0 :         else if (type == COEX_SWITCH_TO_24G_NOFORSCAN)
    2171                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_2GSWITCHBAND);
    2172                 :            :         else
    2173                 :          0 :                 rtw_coex_scan_notify(rtwdev, COEX_SCAN_START_2G);
    2174                 :            : }
    2175                 :            : 
    2176                 :          0 : void rtw_coex_connect_notify(struct rtw_dev *rtwdev, u8 type)
    2177                 :            : {
    2178                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2179                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2180                 :            : 
    2181         [ #  # ]:          0 :         if (coex->stop_dm)
    2182                 :            :                 return;
    2183                 :            : 
    2184                 :          0 :         rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE | COEX_SCBD_SCAN |
    2185                 :            :                             COEX_SCBD_ONOFF, true);
    2186                 :            : 
    2187         [ #  # ]:          0 :         if (type == COEX_ASSOCIATE_5G_START) {
    2188                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
    2189                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_5GCONSTART);
    2190         [ #  # ]:          0 :         } else if (type == COEX_ASSOCIATE_5G_FINISH) {
    2191                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
    2192                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_5GCONFINISH);
    2193         [ #  # ]:          0 :         } else if (type == COEX_ASSOCIATE_START) {
    2194                 :          0 :                 coex_stat->wl_hi_pri_task1 = true;
    2195                 :          0 :                 coex_stat->cnt_wl[COEX_CNT_WL_CONNPKT] = 2;
    2196                 :            : 
    2197                 :            :                 /* Force antenna setup for no scan result issue */
    2198                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    2199                 :            : 
    2200                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_2GCONSTART);
    2201                 :            : 
    2202                 :            :                 /* To keep TDMA case during connect process,
    2203                 :            :                  * to avoid changed by Btinfo and runcoexmechanism
    2204                 :            :                  */
    2205                 :          0 :                 coex->freeze = true;
    2206                 :          0 :                 ieee80211_queue_delayed_work(rtwdev->hw, &coex->defreeze_work,
    2207                 :            :                                              5 * HZ);
    2208                 :            :         } else {
    2209                 :          0 :                 coex_stat->wl_hi_pri_task1 = false;
    2210                 :          0 :                 coex->freeze = false;
    2211                 :            : 
    2212                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_2GCONFINISH);
    2213                 :            :         }
    2214                 :            : }
    2215                 :            : 
    2216                 :          0 : void rtw_coex_media_status_notify(struct rtw_dev *rtwdev, u8 type)
    2217                 :            : {
    2218                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2219                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2220                 :          0 :         u8 para[6] = {0};
    2221                 :            : 
    2222         [ #  # ]:          0 :         if (coex->stop_dm)
    2223                 :          0 :                 return;
    2224                 :            : 
    2225         [ #  # ]:          0 :         if (type == COEX_MEDIA_CONNECT_5G) {
    2226                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
    2227                 :            : 
    2228                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_5G);
    2229                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_5GMEDIA);
    2230         [ #  # ]:          0 :         } else if (type == COEX_MEDIA_CONNECT) {
    2231                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, true);
    2232                 :            : 
    2233                 :            :                 /* Force antenna setup for no scan result issue */
    2234                 :          0 :                 rtw_coex_set_ant_path(rtwdev, true, COEX_SET_ANT_2G);
    2235                 :            : 
    2236                 :            :                 /* Set CCK Rx high Pri */
    2237                 :          0 :                 rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, 1);
    2238                 :            : 
    2239                 :            :                 /* always enable 5ms extend if connect */
    2240                 :          0 :                 para[0] = COEX_H2C69_WL_LEAKAP;
    2241                 :          0 :                 para[1] = PARA1_H2C69_EN_5MS; /* enable 5ms extend */
    2242                 :          0 :                 rtw_fw_bt_wifi_control(rtwdev, para[0], &para[1]);
    2243                 :          0 :                 coex_stat->wl_slot_extend = true;
    2244                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_2GMEDIA);
    2245                 :            :         } else {
    2246                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_ACTIVE, false);
    2247                 :            : 
    2248                 :          0 :                 rtw_coex_set_wl_pri_mask(rtwdev, COEX_WLPRI_RX_CCK, 0);
    2249                 :            : 
    2250                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_MEDIADISCON);
    2251                 :            :         }
    2252                 :            : 
    2253                 :          0 :         rtw_coex_update_wl_ch_info(rtwdev, type);
    2254                 :            : }
    2255                 :            : 
    2256                 :          0 : void rtw_coex_bt_info_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
    2257                 :            : {
    2258                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2259                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2260                 :          0 :         struct rtw_chip_info *chip = rtwdev->chip;
    2261                 :          0 :         unsigned long bt_relink_time;
    2262                 :          0 :         u8 i, rsp_source = 0, type;
    2263                 :            : 
    2264                 :          0 :         rsp_source = buf[0] & 0xf;
    2265         [ #  # ]:          0 :         if (rsp_source >= COEX_BTINFO_SRC_MAX)
    2266                 :            :                 rsp_source = COEX_BTINFO_SRC_WL_FW;
    2267                 :            : 
    2268         [ #  # ]:          0 :         if (rsp_source == COEX_BTINFO_SRC_BT_IQK) {
    2269                 :          0 :                 coex_stat->bt_iqk_state = buf[1];
    2270         [ #  # ]:          0 :                 if (coex_stat->bt_iqk_state == 1)
    2271                 :          0 :                         coex_stat->cnt_bt[COEX_CNT_BT_IQK]++;
    2272         [ #  # ]:          0 :                 else if (coex_stat->bt_iqk_state == 2)
    2273                 :          0 :                         coex_stat->cnt_bt[COEX_CNT_BT_IQKFAIL]++;
    2274                 :            : 
    2275                 :          0 :                 return;
    2276                 :            :         }
    2277                 :            : 
    2278         [ #  # ]:          0 :         if (rsp_source == COEX_BTINFO_SRC_BT_SCBD) {
    2279                 :          0 :                 rtw_coex_monitor_bt_enable(rtwdev);
    2280         [ #  # ]:          0 :                 if (coex_stat->bt_disabled != coex_stat->bt_disabled_pre) {
    2281                 :          0 :                         coex_stat->bt_disabled_pre = coex_stat->bt_disabled;
    2282                 :          0 :                         rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO);
    2283                 :            :                 }
    2284                 :          0 :                 return;
    2285                 :            :         }
    2286                 :            : 
    2287         [ #  # ]:          0 :         if (rsp_source == COEX_BTINFO_SRC_BT_RSP ||
    2288                 :            :             rsp_source == COEX_BTINFO_SRC_BT_ACT) {
    2289         [ #  # ]:          0 :                 if (coex_stat->bt_disabled) {
    2290                 :          0 :                         coex_stat->bt_disabled = false;
    2291                 :          0 :                         coex_stat->bt_reenable = true;
    2292                 :          0 :                         ieee80211_queue_delayed_work(rtwdev->hw,
    2293                 :            :                                                      &coex->bt_reenable_work,
    2294                 :            :                                                      15 * HZ);
    2295                 :            :                 }
    2296                 :            :         }
    2297                 :            : 
    2298         [ #  # ]:          0 :         for (i = 0; i < length; i++) {
    2299         [ #  # ]:          0 :                 if (i < COEX_BTINFO_LENGTH_MAX)
    2300                 :          0 :                         coex_stat->bt_info_c2h[rsp_source][i] = buf[i];
    2301                 :            :                 else
    2302                 :            :                         break;
    2303                 :            :         }
    2304                 :            : 
    2305         [ #  # ]:          0 :         if (rsp_source == COEX_BTINFO_SRC_WL_FW) {
    2306                 :          0 :                 rtw_coex_update_bt_link_info(rtwdev);
    2307                 :          0 :                 rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO);
    2308                 :          0 :                 return;
    2309                 :            :         }
    2310                 :            : 
    2311                 :            :         /* get the same info from bt, skip it */
    2312         [ #  # ]:          0 :         if (coex_stat->bt_info_c2h[rsp_source][1] == coex_stat->bt_info_lb2 &&
    2313         [ #  # ]:          0 :             coex_stat->bt_info_c2h[rsp_source][2] == coex_stat->bt_info_lb3 &&
    2314         [ #  # ]:          0 :             coex_stat->bt_info_c2h[rsp_source][3] == coex_stat->bt_info_hb0 &&
    2315         [ #  # ]:          0 :             coex_stat->bt_info_c2h[rsp_source][4] == coex_stat->bt_info_hb1 &&
    2316         [ #  # ]:          0 :             coex_stat->bt_info_c2h[rsp_source][5] == coex_stat->bt_info_hb2 &&
    2317         [ #  # ]:          0 :             coex_stat->bt_info_c2h[rsp_source][6] == coex_stat->bt_info_hb3)
    2318                 :            :                 return;
    2319                 :            : 
    2320                 :          0 :         coex_stat->bt_info_lb2 = coex_stat->bt_info_c2h[rsp_source][1];
    2321                 :          0 :         coex_stat->bt_info_lb3 = coex_stat->bt_info_c2h[rsp_source][2];
    2322                 :          0 :         coex_stat->bt_info_hb0 = coex_stat->bt_info_c2h[rsp_source][3];
    2323                 :          0 :         coex_stat->bt_info_hb1 = coex_stat->bt_info_c2h[rsp_source][4];
    2324                 :          0 :         coex_stat->bt_info_hb2 = coex_stat->bt_info_c2h[rsp_source][5];
    2325                 :          0 :         coex_stat->bt_info_hb3 = coex_stat->bt_info_c2h[rsp_source][6];
    2326                 :            : 
    2327                 :            :         /* 0xff means BT is under WHCK test */
    2328                 :          0 :         coex_stat->bt_whck_test = (coex_stat->bt_info_lb2 == 0xff);
    2329                 :          0 :         coex_stat->bt_inq_page = ((coex_stat->bt_info_lb2 & BIT(2)) == BIT(2));
    2330                 :          0 :         coex_stat->bt_acl_busy = ((coex_stat->bt_info_lb2 & BIT(3)) == BIT(3));
    2331                 :          0 :         coex_stat->cnt_bt[COEX_CNT_BT_RETRY] = coex_stat->bt_info_lb3 & 0xf;
    2332         [ #  # ]:          0 :         if (coex_stat->cnt_bt[COEX_CNT_BT_RETRY] >= 1)
    2333                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_POPEVENT]++;
    2334                 :            : 
    2335                 :          0 :         coex_stat->bt_fix_2M = ((coex_stat->bt_info_lb3 & BIT(4)) == BIT(4));
    2336                 :          0 :         coex_stat->bt_inq = ((coex_stat->bt_info_lb3 & BIT(5)) == BIT(5));
    2337         [ #  # ]:          0 :         if (coex_stat->bt_inq)
    2338                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_INQ]++;
    2339                 :            : 
    2340                 :          0 :         coex_stat->bt_page = ((coex_stat->bt_info_lb3 & BIT(7)) == BIT(7));
    2341         [ #  # ]:          0 :         if (coex_stat->bt_page) {
    2342                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_PAGE]++;
    2343         [ #  # ]:          0 :                 if (coex_stat->wl_linkscan_proc ||
    2344                 :            :                     coex_stat->wl_hi_pri_task1 ||
    2345         [ #  # ]:          0 :                     coex_stat->wl_hi_pri_task2 || coex_stat->wl_gl_busy)
    2346                 :          0 :                         rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, true);
    2347                 :            :                 else
    2348                 :          0 :                         rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, false);
    2349                 :            :         } else {
    2350                 :          0 :                 rtw_coex_write_scbd(rtwdev, COEX_SCBD_SCAN, false);
    2351                 :            :         }
    2352                 :            : 
    2353                 :            :         /* unit: % (value-100 to translate to unit: dBm in coex info) */
    2354         [ #  # ]:          0 :         if (chip->bt_rssi_type == COEX_BTRSSI_RATIO) {
    2355                 :          0 :                 coex_stat->bt_rssi = coex_stat->bt_info_hb0 * 2 + 10;
    2356                 :            :         } else { /* original unit: dbm -> unit: % ->  value-100 in coex info */
    2357         [ #  # ]:          0 :                 if (coex_stat->bt_info_hb0 <= 127)
    2358                 :          0 :                         coex_stat->bt_rssi = 100;
    2359         [ #  # ]:          0 :                 else if (256 - coex_stat->bt_info_hb0 <= 100)
    2360                 :          0 :                         coex_stat->bt_rssi = 100 - (256 - coex_stat->bt_info_hb0);
    2361                 :            :                 else
    2362                 :          0 :                         coex_stat->bt_rssi = 0;
    2363                 :            :         }
    2364                 :            : 
    2365                 :          0 :         coex_stat->bt_ble_exist = ((coex_stat->bt_info_hb1 & BIT(0)) == BIT(0));
    2366         [ #  # ]:          0 :         if (coex_stat->bt_info_hb1 & BIT(1))
    2367                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_REINIT]++;
    2368                 :            : 
    2369         [ #  # ]:          0 :         if (coex_stat->bt_info_hb1 & BIT(2)) {
    2370                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_SETUPLINK]++;
    2371                 :          0 :                 coex_stat->bt_setup_link = true;
    2372         [ #  # ]:          0 :                 if (coex_stat->bt_reenable)
    2373                 :            :                         bt_relink_time = 6 * HZ;
    2374                 :            :                 else
    2375                 :          0 :                         bt_relink_time = 2 * HZ;
    2376                 :            : 
    2377                 :          0 :                 ieee80211_queue_delayed_work(rtwdev->hw,
    2378                 :            :                                              &coex->bt_relink_work,
    2379                 :            :                                              bt_relink_time);
    2380                 :            :         }
    2381                 :            : 
    2382         [ #  # ]:          0 :         if (coex_stat->bt_info_hb1 & BIT(3))
    2383                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_IGNWLANACT]++;
    2384                 :            : 
    2385                 :          0 :         coex_stat->bt_ble_voice = ((coex_stat->bt_info_hb1 & BIT(4)) == BIT(4));
    2386                 :          0 :         coex_stat->bt_ble_scan_en = ((coex_stat->bt_info_hb1 & BIT(5)) == BIT(5));
    2387         [ #  # ]:          0 :         if (coex_stat->bt_info_hb1 & BIT(6))
    2388                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_ROLESWITCH]++;
    2389                 :            : 
    2390                 :          0 :         coex_stat->bt_multi_link = ((coex_stat->bt_info_hb1 & BIT(7)) == BIT(7));
    2391                 :            :         /* resend wifi info to bt, it is reset and lost the info */
    2392         [ #  # ]:          0 :         if ((coex_stat->bt_info_hb1 & BIT(1))) {
    2393         [ #  # ]:          0 :                 if (coex_stat->wl_connected)
    2394                 :            :                         type = COEX_MEDIA_CONNECT;
    2395                 :            :                 else
    2396                 :          0 :                         type = COEX_MEDIA_DISCONNECT;
    2397                 :          0 :                 rtw_coex_update_wl_ch_info(rtwdev, type);
    2398                 :            :         }
    2399                 :            : 
    2400                 :            :         /* if ignore_wlan_act && not set_up_link */
    2401         [ #  # ]:          0 :         if ((coex_stat->bt_info_hb1 & BIT(3)) &&
    2402                 :            :             (!(coex_stat->bt_info_hb1 & BIT(2))))
    2403         [ #  # ]:          0 :                 rtw_coex_ignore_wlan_act(rtwdev, false);
    2404                 :            : 
    2405                 :          0 :         coex_stat->bt_opp_exist = ((coex_stat->bt_info_hb2 & BIT(0)) == BIT(0));
    2406         [ #  # ]:          0 :         if (coex_stat->bt_info_hb2 & BIT(1))
    2407                 :          0 :                 coex_stat->cnt_bt[COEX_CNT_BT_AFHUPDATE]++;
    2408                 :            : 
    2409                 :          0 :         coex_stat->bt_a2dp_active = (coex_stat->bt_info_hb2 & BIT(2)) == BIT(2);
    2410                 :          0 :         coex_stat->bt_slave = ((coex_stat->bt_info_hb2 & BIT(3)) == BIT(3));
    2411                 :          0 :         coex_stat->bt_hid_slot = (coex_stat->bt_info_hb2 & 0x30) >> 4;
    2412                 :          0 :         coex_stat->bt_hid_pair_num = (coex_stat->bt_info_hb2 & 0xc0) >> 6;
    2413   [ #  #  #  # ]:          0 :         if (coex_stat->bt_hid_pair_num > 0 && coex_stat->bt_hid_slot >= 2)
    2414                 :          0 :                 coex_stat->bt_418_hid_exist = true;
    2415         [ #  # ]:          0 :         else if (coex_stat->bt_hid_pair_num == 0)
    2416                 :          0 :                 coex_stat->bt_418_hid_exist = false;
    2417                 :            : 
    2418         [ #  # ]:          0 :         if ((coex_stat->bt_info_lb2 & 0x49) == 0x49)
    2419                 :          0 :                 coex_stat->bt_a2dp_bitpool = (coex_stat->bt_info_hb3 & 0x7f);
    2420                 :            :         else
    2421                 :          0 :                 coex_stat->bt_a2dp_bitpool = 0;
    2422                 :            : 
    2423                 :          0 :         coex_stat->bt_a2dp_sink = ((coex_stat->bt_info_hb3 & BIT(7)) == BIT(7));
    2424                 :            : 
    2425                 :          0 :         rtw_coex_update_bt_link_info(rtwdev);
    2426                 :          0 :         rtw_coex_run_coex(rtwdev, COEX_RSN_BTINFO);
    2427                 :            : }
    2428                 :            : 
    2429                 :          0 : void rtw_coex_wl_fwdbginfo_notify(struct rtw_dev *rtwdev, u8 *buf, u8 length)
    2430                 :            : {
    2431                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2432                 :          0 :         struct rtw_coex_stat *coex_stat = &coex->stat;
    2433                 :          0 :         u8 val;
    2434                 :          0 :         int i;
    2435                 :            : 
    2436   [ #  #  #  # ]:          0 :         if (WARN(length < 8, "invalid wl info c2h length\n"))
    2437                 :            :                 return;
    2438                 :            : 
    2439         [ #  # ]:          0 :         if (buf[0] != 0x08)
    2440                 :            :                 return;
    2441                 :            : 
    2442         [ #  # ]:          0 :         for (i = 1; i < 8; i++) {
    2443                 :          0 :                 val = coex_stat->wl_fw_dbg_info_pre[i];
    2444         [ #  # ]:          0 :                 if (buf[i] >= val)
    2445                 :          0 :                         coex_stat->wl_fw_dbg_info[i] = buf[i] - val;
    2446                 :            :                 else
    2447                 :          0 :                         coex_stat->wl_fw_dbg_info[i] = val - buf[i];
    2448                 :            : 
    2449                 :          0 :                 coex_stat->wl_fw_dbg_info_pre[i] = buf[i];
    2450                 :            :         }
    2451                 :            : 
    2452                 :          0 :         coex_stat->cnt_wl[COEX_CNT_WL_FW_NOTIFY]++;
    2453                 :          0 :         rtw_coex_wl_ccklock_action(rtwdev);
    2454                 :          0 :         rtw_coex_wl_ccklock_detect(rtwdev);
    2455                 :            : }
    2456                 :            : 
    2457                 :          0 : void rtw_coex_wl_status_change_notify(struct rtw_dev *rtwdev)
    2458                 :            : {
    2459                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2460                 :            : 
    2461         [ #  # ]:          0 :         if (coex->stop_dm)
    2462                 :            :                 return;
    2463                 :            : 
    2464                 :          0 :         rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
    2465                 :            : }
    2466                 :            : 
    2467                 :          0 : void rtw_coex_bt_relink_work(struct work_struct *work)
    2468                 :            : {
    2469                 :          0 :         struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
    2470                 :            :                                               coex.bt_relink_work.work);
    2471                 :          0 :         struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
    2472                 :            : 
    2473                 :          0 :         mutex_lock(&rtwdev->mutex);
    2474                 :          0 :         coex_stat->bt_setup_link = false;
    2475                 :          0 :         rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
    2476                 :          0 :         mutex_unlock(&rtwdev->mutex);
    2477                 :          0 : }
    2478                 :            : 
    2479                 :          0 : void rtw_coex_bt_reenable_work(struct work_struct *work)
    2480                 :            : {
    2481                 :          0 :         struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
    2482                 :            :                                               coex.bt_reenable_work.work);
    2483                 :          0 :         struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
    2484                 :            : 
    2485                 :          0 :         mutex_lock(&rtwdev->mutex);
    2486                 :          0 :         coex_stat->bt_reenable = false;
    2487                 :          0 :         mutex_unlock(&rtwdev->mutex);
    2488                 :          0 : }
    2489                 :            : 
    2490                 :          0 : void rtw_coex_defreeze_work(struct work_struct *work)
    2491                 :            : {
    2492                 :          0 :         struct rtw_dev *rtwdev = container_of(work, struct rtw_dev,
    2493                 :            :                                               coex.defreeze_work.work);
    2494                 :          0 :         struct rtw_coex *coex = &rtwdev->coex;
    2495                 :          0 :         struct rtw_coex_stat *coex_stat = &rtwdev->coex.stat;
    2496                 :            : 
    2497                 :          0 :         mutex_lock(&rtwdev->mutex);
    2498                 :          0 :         coex->freeze = false;
    2499                 :          0 :         coex_stat->wl_hi_pri_task1 = false;
    2500                 :          0 :         rtw_coex_run_coex(rtwdev, COEX_RSN_WLSTATUS);
    2501                 :          0 :         mutex_unlock(&rtwdev->mutex);
    2502                 :          0 : }

Generated by: LCOV version 1.14