LCOV - code coverage report
Current view: top level - drivers/net/wireless/ath/ath9k - ar9003_mci.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 15 790 1.9 %
Date: 2022-03-28 13:20:08 Functions: 1 42 2.4 %
Branches: 4 427 0.9 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * Copyright (c) 2008-2011 Atheros Communications Inc.
       3                 :            :  *
       4                 :            :  * Permission to use, copy, modify, and/or distribute this software for any
       5                 :            :  * purpose with or without fee is hereby granted, provided that the above
       6                 :            :  * copyright notice and this permission notice appear in all copies.
       7                 :            :  *
       8                 :            :  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
       9                 :            :  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
      10                 :            :  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
      11                 :            :  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
      12                 :            :  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
      13                 :            :  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
      14                 :            :  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
      15                 :            :  */
      16                 :            : 
      17                 :            : #include <linux/export.h>
      18                 :            : #include "hw.h"
      19                 :            : #include "hw-ops.h"
      20                 :            : #include "ar9003_phy.h"
      21                 :            : #include "ar9003_mci.h"
      22                 :            : #include "ar9003_aic.h"
      23                 :            : 
      24                 :          0 : static void ar9003_mci_reset_req_wakeup(struct ath_hw *ah)
      25                 :            : {
      26                 :          0 :         REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
      27                 :            :                       AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1);
      28                 :          0 :         udelay(1);
      29                 :          0 :         REG_RMW_FIELD(ah, AR_MCI_COMMAND2,
      30                 :            :                       AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0);
      31                 :          0 : }
      32                 :            : 
      33                 :          0 : static int ar9003_mci_wait_for_interrupt(struct ath_hw *ah, u32 address,
      34                 :            :                                         u32 bit_position, int time_out)
      35                 :            : {
      36                 :          0 :         struct ath_common *common = ath9k_hw_common(ah);
      37                 :            : 
      38         [ #  # ]:          0 :         while (time_out) {
      39         [ #  # ]:          0 :                 if (!(REG_READ(ah, address) & bit_position)) {
      40                 :          0 :                         udelay(10);
      41                 :          0 :                         time_out -= 10;
      42                 :            : 
      43         [ #  # ]:          0 :                         if (time_out < 0)
      44                 :            :                                 break;
      45                 :            :                         else
      46                 :          0 :                                 continue;
      47                 :            :                 }
      48                 :          0 :                 REG_WRITE(ah, address, bit_position);
      49                 :            : 
      50         [ #  # ]:          0 :                 if (address != AR_MCI_INTERRUPT_RX_MSG_RAW)
      51                 :            :                         break;
      52                 :            : 
      53         [ #  # ]:          0 :                 if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE)
      54                 :          0 :                         ar9003_mci_reset_req_wakeup(ah);
      55                 :            : 
      56         [ #  # ]:          0 :                 if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING |
      57                 :            :                                     AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING))
      58                 :          0 :                         REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
      59                 :            :                                   AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
      60                 :            : 
      61                 :          0 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG);
      62                 :          0 :                 break;
      63                 :            :         }
      64                 :            : 
      65         [ #  # ]:          0 :         if (time_out <= 0) {
      66         [ #  # ]:          0 :                 ath_dbg(common, MCI,
      67                 :            :                         "MCI Wait for Reg 0x%08x = 0x%08x timeout\n",
      68                 :            :                         address, bit_position);
      69         [ #  # ]:          0 :                 ath_dbg(common, MCI,
      70                 :            :                         "MCI INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n",
      71                 :            :                         REG_READ(ah, AR_MCI_INTERRUPT_RAW),
      72                 :            :                         REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
      73                 :            :                 time_out = 0;
      74                 :            :         }
      75                 :            : 
      76                 :          0 :         return time_out;
      77                 :            : }
      78                 :            : 
      79                 :          0 : static void ar9003_mci_remote_reset(struct ath_hw *ah, bool wait_done)
      80                 :            : {
      81                 :          0 :         u32 payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00};
      82                 :            : 
      83                 :          0 :         ar9003_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16,
      84                 :            :                                 wait_done, false);
      85                 :          0 :         udelay(5);
      86                 :          0 : }
      87                 :            : 
      88                 :          0 : static void ar9003_mci_send_lna_transfer(struct ath_hw *ah, bool wait_done)
      89                 :            : {
      90                 :          0 :         u32 payload = 0x00000000;
      91                 :            : 
      92                 :          0 :         ar9003_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1,
      93                 :            :                                 wait_done, false);
      94                 :          0 : }
      95                 :            : 
      96                 :          0 : static void ar9003_mci_send_req_wake(struct ath_hw *ah, bool wait_done)
      97                 :            : {
      98                 :          0 :         ar9003_mci_send_message(ah, MCI_REQ_WAKE, MCI_FLAG_DISABLE_TIMESTAMP,
      99                 :            :                                 NULL, 0, wait_done, false);
     100                 :          0 :         udelay(5);
     101                 :          0 : }
     102                 :            : 
     103                 :          0 : static void ar9003_mci_send_sys_waking(struct ath_hw *ah, bool wait_done)
     104                 :            : {
     105                 :          0 :         ar9003_mci_send_message(ah, MCI_SYS_WAKING, MCI_FLAG_DISABLE_TIMESTAMP,
     106                 :            :                                 NULL, 0, wait_done, false);
     107                 :            : }
     108                 :            : 
     109                 :          0 : static void ar9003_mci_send_lna_take(struct ath_hw *ah, bool wait_done)
     110                 :            : {
     111                 :          0 :         u32 payload = 0x70000000;
     112                 :            : 
     113                 :          0 :         ar9003_mci_send_message(ah, MCI_LNA_TAKE, 0, &payload, 1,
     114                 :            :                                 wait_done, false);
     115                 :            : }
     116                 :            : 
     117                 :          0 : static void ar9003_mci_send_sys_sleeping(struct ath_hw *ah, bool wait_done)
     118                 :            : {
     119                 :          0 :         ar9003_mci_send_message(ah, MCI_SYS_SLEEPING,
     120                 :            :                                 MCI_FLAG_DISABLE_TIMESTAMP,
     121                 :            :                                 NULL, 0, wait_done, false);
     122                 :            : }
     123                 :            : 
     124                 :          0 : static void ar9003_mci_send_coex_version_query(struct ath_hw *ah,
     125                 :            :                                                bool wait_done)
     126                 :            : {
     127                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     128                 :          0 :         u32 payload[4] = {0, 0, 0, 0};
     129                 :            : 
     130         [ #  # ]:          0 :         if (mci->bt_version_known ||
     131         [ #  # ]:          0 :             (mci->bt_state == MCI_BT_SLEEP))
     132                 :          0 :                 return;
     133                 :            : 
     134                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
     135                 :            :                                 MCI_GPM_COEX_VERSION_QUERY);
     136                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
     137                 :            : }
     138                 :            : 
     139                 :          0 : static void ar9003_mci_send_coex_version_response(struct ath_hw *ah,
     140                 :            :                                                   bool wait_done)
     141                 :            : {
     142                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     143                 :          0 :         u32 payload[4] = {0, 0, 0, 0};
     144                 :            : 
     145                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
     146                 :            :                                 MCI_GPM_COEX_VERSION_RESPONSE);
     147                 :          0 :         *(((u8 *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) =
     148                 :          0 :                 mci->wlan_ver_major;
     149                 :          0 :         *(((u8 *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) =
     150                 :          0 :                 mci->wlan_ver_minor;
     151                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
     152                 :          0 : }
     153                 :            : 
     154                 :          0 : static void ar9003_mci_send_coex_wlan_channels(struct ath_hw *ah,
     155                 :            :                                                bool wait_done)
     156                 :            : {
     157                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     158                 :          0 :         u32 *payload = &mci->wlan_channels[0];
     159                 :            : 
     160         [ #  # ]:          0 :         if (!mci->wlan_channels_update ||
     161         [ #  # ]:          0 :             (mci->bt_state == MCI_BT_SLEEP))
     162                 :            :                 return;
     163                 :            : 
     164                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
     165                 :            :                                 MCI_GPM_COEX_WLAN_CHANNELS);
     166                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
     167                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff);
     168                 :            : }
     169                 :            : 
     170                 :          0 : static void ar9003_mci_send_coex_bt_status_query(struct ath_hw *ah,
     171                 :            :                                                 bool wait_done, u8 query_type)
     172                 :            : {
     173                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     174                 :          0 :         u32 payload[4] = {0, 0, 0, 0};
     175                 :          0 :         bool query_btinfo;
     176                 :            : 
     177         [ #  # ]:          0 :         if (mci->bt_state == MCI_BT_SLEEP)
     178                 :          0 :                 return;
     179                 :            : 
     180                 :          0 :         query_btinfo = !!(query_type & (MCI_GPM_COEX_QUERY_BT_ALL_INFO |
     181                 :            :                                         MCI_GPM_COEX_QUERY_BT_TOPOLOGY));
     182                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
     183                 :            :                                 MCI_GPM_COEX_STATUS_QUERY);
     184                 :            : 
     185                 :          0 :         *(((u8 *)payload) + MCI_GPM_COEX_B_BT_BITMAP) = query_type;
     186                 :            : 
     187                 :            :         /*
     188                 :            :          * If bt_status_query message is  not sent successfully,
     189                 :            :          * then need_flush_btinfo should be set again.
     190                 :            :          */
     191         [ #  # ]:          0 :         if (!ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
     192                 :            :                                 wait_done, true)) {
     193         [ #  # ]:          0 :                 if (query_btinfo)
     194                 :          0 :                         mci->need_flush_btinfo = true;
     195                 :            :         }
     196                 :            : 
     197         [ #  # ]:          0 :         if (query_btinfo)
     198                 :          0 :                 mci->query_bt = false;
     199                 :            : }
     200                 :            : 
     201                 :          0 : static void ar9003_mci_send_coex_halt_bt_gpm(struct ath_hw *ah, bool halt,
     202                 :            :                                              bool wait_done)
     203                 :            : {
     204                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     205                 :          0 :         u32 payload[4] = {0, 0, 0, 0};
     206                 :            : 
     207                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(payload, MCI_GPM_COEX_AGENT,
     208                 :            :                                 MCI_GPM_COEX_HALT_BT_GPM);
     209                 :            : 
     210         [ #  # ]:          0 :         if (halt) {
     211                 :          0 :                 mci->query_bt = true;
     212                 :            :                 /* Send next unhalt no matter halt sent or not */
     213                 :          0 :                 mci->unhalt_bt_gpm = true;
     214                 :          0 :                 mci->need_flush_btinfo = true;
     215                 :          0 :                 *(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
     216                 :            :                         MCI_GPM_COEX_BT_GPM_HALT;
     217                 :            :         } else
     218                 :          0 :                 *(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) =
     219                 :            :                         MCI_GPM_COEX_BT_GPM_UNHALT;
     220                 :            : 
     221                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, true);
     222                 :          0 : }
     223                 :            : 
     224                 :          0 : static void ar9003_mci_prep_interface(struct ath_hw *ah)
     225                 :            : {
     226                 :          0 :         struct ath_common *common = ath9k_hw_common(ah);
     227                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     228                 :          0 :         u32 saved_mci_int_en;
     229                 :          0 :         u32 mci_timeout = 150;
     230                 :            : 
     231                 :          0 :         mci->bt_state = MCI_BT_SLEEP;
     232                 :          0 :         saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
     233                 :            : 
     234                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
     235                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     236                 :            :                   REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW));
     237                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
     238                 :            :                   REG_READ(ah, AR_MCI_INTERRUPT_RAW));
     239                 :            : 
     240                 :          0 :         ar9003_mci_remote_reset(ah, true);
     241                 :          0 :         ar9003_mci_send_req_wake(ah, true);
     242                 :            : 
     243         [ #  # ]:          0 :         if (!ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     244                 :            :                                   AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500))
     245                 :          0 :                 goto clear_redunt;
     246                 :            : 
     247                 :          0 :         mci->bt_state = MCI_BT_AWAKE;
     248                 :            : 
     249                 :            :         /*
     250                 :            :          * we don't need to send more remote_reset at this moment.
     251                 :            :          * If BT receive first remote_reset, then BT HW will
     252                 :            :          * be cleaned up and will be able to receive req_wake
     253                 :            :          * and BT HW will respond sys_waking.
     254                 :            :          * In this case, WLAN will receive BT's HW sys_waking.
     255                 :            :          * Otherwise, if BT SW missed initial remote_reset,
     256                 :            :          * that remote_reset will still clean up BT MCI RX,
     257                 :            :          * and the req_wake will wake BT up,
     258                 :            :          * and BT SW will respond this req_wake with a remote_reset and
     259                 :            :          * sys_waking. In this case, WLAN will receive BT's SW
     260                 :            :          * sys_waking. In either case, BT's RX is cleaned up. So we
     261                 :            :          * don't need to reply BT's remote_reset now, if any.
     262                 :            :          * Similarly, if in any case, WLAN can receive BT's sys_waking,
     263                 :            :          * that means WLAN's RX is also fine.
     264                 :            :          */
     265                 :          0 :         ar9003_mci_send_sys_waking(ah, true);
     266                 :          0 :         udelay(10);
     267                 :            : 
     268                 :            :         /*
     269                 :            :          * Set BT priority interrupt value to be 0xff to
     270                 :            :          * avoid having too many BT PRIORITY interrupts.
     271                 :            :          */
     272                 :          0 :         REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF);
     273                 :          0 :         REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF);
     274                 :          0 :         REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF);
     275                 :          0 :         REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF);
     276                 :          0 :         REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF);
     277                 :            : 
     278                 :            :         /*
     279                 :            :          * A contention reset will be received after send out
     280                 :            :          * sys_waking. Also BT priority interrupt bits will be set.
     281                 :            :          * Clear those bits before the next step.
     282                 :            :          */
     283                 :            : 
     284                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     285                 :            :                   AR_MCI_INTERRUPT_RX_MSG_CONT_RST);
     286                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI);
     287                 :            : 
     288   [ #  #  #  #  :          0 :         if (mci->is_2g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
                   #  # ]
     289                 :          0 :                 ar9003_mci_send_lna_transfer(ah, true);
     290                 :          0 :                 udelay(5);
     291                 :            :         }
     292                 :            : 
     293   [ #  #  #  #  :          0 :         if (mci->is_2g && !mci->update_2g5g && MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
             #  #  #  # ]
     294         [ #  # ]:          0 :                 if (ar9003_mci_wait_for_interrupt(ah,
     295                 :            :                                         AR_MCI_INTERRUPT_RX_MSG_RAW,
     296                 :            :                                         AR_MCI_INTERRUPT_RX_MSG_LNA_INFO,
     297                 :            :                                         mci_timeout))
     298         [ #  # ]:          0 :                         ath_dbg(common, MCI,
     299                 :            :                                 "MCI WLAN has control over the LNA & BT obeys it\n");
     300                 :            :                 else
     301         [ #  # ]:          0 :                         ath_dbg(common, MCI,
     302                 :            :                                 "MCI BT didn't respond to LNA_TRANS\n");
     303                 :            :         }
     304                 :            : 
     305                 :          0 : clear_redunt:
     306                 :            :         /* Clear the extra redundant SYS_WAKING from BT */
     307   [ #  #  #  # ]:          0 :         if ((mci->bt_state == MCI_BT_AWAKE) &&
     308                 :          0 :             (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     309                 :          0 :                             AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) &&
     310                 :          0 :             (REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     311         [ #  # ]:          0 :                             AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) {
     312                 :          0 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     313                 :            :                           AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING);
     314                 :          0 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
     315                 :            :                           AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE);
     316                 :            :         }
     317                 :            : 
     318                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
     319                 :          0 : }
     320                 :            : 
     321                 :          0 : void ar9003_mci_set_full_sleep(struct ath_hw *ah)
     322                 :            : {
     323                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     324                 :            : 
     325         [ #  # ]:          0 :         if (ar9003_mci_state(ah, MCI_STATE_ENABLE) &&
     326         [ #  # ]:          0 :             (mci->bt_state != MCI_BT_SLEEP) &&
     327         [ #  # ]:          0 :             !mci->halted_bt_gpm) {
     328                 :          0 :                 ar9003_mci_send_coex_halt_bt_gpm(ah, true, true);
     329                 :            :         }
     330                 :            : 
     331                 :          0 :         mci->ready = false;
     332                 :          0 : }
     333                 :            : 
     334                 :          0 : static void ar9003_mci_disable_interrupt(struct ath_hw *ah)
     335                 :            : {
     336                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
     337                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0);
     338                 :            : }
     339                 :            : 
     340                 :          0 : static void ar9003_mci_enable_interrupt(struct ath_hw *ah)
     341                 :            : {
     342                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT);
     343                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN,
     344                 :            :                   AR_MCI_INTERRUPT_RX_MSG_DEFAULT);
     345                 :          0 : }
     346                 :            : 
     347                 :          0 : static bool ar9003_mci_check_int(struct ath_hw *ah, u32 ints)
     348                 :            : {
     349                 :          0 :         u32 intr;
     350                 :            : 
     351                 :          0 :         intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
     352                 :          0 :         return ((intr & ints) == ints);
     353                 :            : }
     354                 :            : 
     355                 :          0 : void ar9003_mci_get_interrupt(struct ath_hw *ah, u32 *raw_intr,
     356                 :            :                               u32 *rx_msg_intr)
     357                 :            : {
     358                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     359                 :            : 
     360                 :          0 :         *raw_intr = mci->raw_intr;
     361                 :          0 :         *rx_msg_intr = mci->rx_msg_intr;
     362                 :            : 
     363                 :            :         /* Clean int bits after the values are read. */
     364                 :          0 :         mci->raw_intr = 0;
     365                 :          0 :         mci->rx_msg_intr = 0;
     366                 :          0 : }
     367                 :            : EXPORT_SYMBOL(ar9003_mci_get_interrupt);
     368                 :            : 
     369                 :          3 : void ar9003_mci_get_isr(struct ath_hw *ah, enum ath9k_int *masked)
     370                 :            : {
     371                 :          3 :         struct ath_common *common = ath9k_hw_common(ah);
     372                 :          3 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     373                 :          3 :         u32 raw_intr, rx_msg_intr;
     374                 :            : 
     375                 :          3 :         rx_msg_intr = REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW);
     376                 :          3 :         raw_intr = REG_READ(ah, AR_MCI_INTERRUPT_RAW);
     377                 :            : 
     378   [ +  -  -  + ]:          3 :         if ((raw_intr == 0xdeadbeef) || (rx_msg_intr == 0xdeadbeef)) {
     379         [ #  # ]:          0 :                 ath_dbg(common, MCI,
     380                 :            :                         "MCI gets 0xdeadbeef during int processing\n");
     381                 :            :         } else {
     382                 :          3 :                 mci->rx_msg_intr |= rx_msg_intr;
     383                 :          3 :                 mci->raw_intr |= raw_intr;
     384                 :          3 :                 *masked |= ATH9K_INT_MCI;
     385                 :            : 
     386         [ +  + ]:          3 :                 if (rx_msg_intr & AR_MCI_INTERRUPT_RX_MSG_CONT_INFO)
     387                 :          1 :                         mci->cont_status = REG_READ(ah, AR_MCI_CONT_STATUS);
     388                 :            : 
     389                 :          3 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, rx_msg_intr);
     390                 :          3 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, raw_intr);
     391                 :            :         }
     392                 :          3 : }
     393                 :            : 
     394                 :          0 : static void ar9003_mci_2g5g_changed(struct ath_hw *ah, bool is_2g)
     395                 :            : {
     396                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     397                 :            : 
     398                 :          0 :         if (!mci->update_2g5g &&
     399         [ #  # ]:          0 :             (mci->is_2g != is_2g))
     400                 :          0 :                 mci->update_2g5g = true;
     401                 :            : 
     402                 :          0 :         mci->is_2g = is_2g;
     403                 :            : }
     404                 :            : 
     405                 :          0 : static bool ar9003_mci_is_gpm_valid(struct ath_hw *ah, u32 msg_index)
     406                 :            : {
     407                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     408                 :          0 :         u32 *payload;
     409                 :          0 :         u32 recv_type, offset;
     410                 :            : 
     411                 :          0 :         if (msg_index == MCI_GPM_INVALID)
     412                 :            :                 return false;
     413                 :            : 
     414                 :          0 :         offset = msg_index << 4;
     415                 :            : 
     416                 :          0 :         payload = (u32 *)(mci->gpm_buf + offset);
     417                 :          0 :         recv_type = MCI_GPM_TYPE(payload);
     418                 :            : 
     419         [ #  # ]:          0 :         if (recv_type == MCI_GPM_RSVD_PATTERN)
     420                 :            :                 return false;
     421                 :            : 
     422                 :            :         return true;
     423                 :            : }
     424                 :            : 
     425                 :          0 : static void ar9003_mci_observation_set_up(struct ath_hw *ah)
     426                 :            : {
     427                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     428                 :            : 
     429         [ #  # ]:          0 :         if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MCI) {
     430                 :          0 :                 ath9k_hw_gpio_request_out(ah, 3, NULL,
     431                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA);
     432                 :          0 :                 ath9k_hw_gpio_request_out(ah, 2, NULL,
     433                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK);
     434                 :          0 :                 ath9k_hw_gpio_request_out(ah, 1, NULL,
     435                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
     436                 :          0 :                 ath9k_hw_gpio_request_out(ah, 0, NULL,
     437                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
     438         [ #  # ]:          0 :         } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_TXRX) {
     439                 :          0 :                 ath9k_hw_gpio_request_out(ah, 3, NULL,
     440                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_WL_IN_TX);
     441                 :          0 :                 ath9k_hw_gpio_request_out(ah, 2, NULL,
     442                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_WL_IN_RX);
     443                 :          0 :                 ath9k_hw_gpio_request_out(ah, 1, NULL,
     444                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
     445                 :          0 :                 ath9k_hw_gpio_request_out(ah, 0, NULL,
     446                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
     447                 :          0 :                 ath9k_hw_gpio_request_out(ah, 5, NULL,
     448                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_OUTPUT);
     449         [ #  # ]:          0 :         } else if (mci->config & ATH_MCI_CONFIG_MCI_OBS_BT) {
     450                 :          0 :                 ath9k_hw_gpio_request_out(ah, 3, NULL,
     451                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_BT_IN_TX);
     452                 :          0 :                 ath9k_hw_gpio_request_out(ah, 2, NULL,
     453                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_BT_IN_RX);
     454                 :          0 :                 ath9k_hw_gpio_request_out(ah, 1, NULL,
     455                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA);
     456                 :          0 :                 ath9k_hw_gpio_request_out(ah, 0, NULL,
     457                 :            :                                           AR_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK);
     458                 :            :         } else
     459                 :            :                 return;
     460                 :            : 
     461   [ #  #  #  # ]:          0 :         REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL, AR_GPIO_JTAG_DISABLE);
     462                 :            : 
     463                 :          0 :         REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1);
     464                 :          0 :         REG_RMW_FIELD(ah, AR_PHY_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0);
     465                 :          0 :         REG_SET_BIT(ah, AR_GLB_GPIO_CONTROL, ATH_MCI_CONFIG_MCI_OBS_GPIO);
     466                 :            : 
     467                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0);
     468                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1);
     469   [ #  #  #  # ]:          0 :         REG_WRITE(ah, AR_OBS, 0x4b);
     470                 :          0 :         REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03);
     471                 :          0 :         REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01);
     472                 :          0 :         REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02);
     473                 :          0 :         REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03);
     474         [ #  # ]:          0 :         REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS,
     475                 :            :                       AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07);
     476                 :            : }
     477                 :            : 
     478                 :          0 : static bool ar9003_mci_send_coex_bt_flags(struct ath_hw *ah, bool wait_done,
     479                 :            :                                           u8 opcode, u32 bt_flags)
     480                 :            : {
     481                 :          0 :         u32 pld[4] = {0, 0, 0, 0};
     482                 :            : 
     483                 :          0 :         MCI_GPM_SET_TYPE_OPCODE(pld, MCI_GPM_COEX_AGENT,
     484                 :            :                                 MCI_GPM_COEX_BT_UPDATE_FLAGS);
     485                 :            : 
     486                 :          0 :         *(((u8 *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP)  = opcode;
     487                 :          0 :         *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF;
     488                 :          0 :         *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) = (bt_flags >> 8) & 0xFF;
     489                 :          0 :         *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = (bt_flags >> 16) & 0xFF;
     490                 :          0 :         *(((u8 *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = (bt_flags >> 24) & 0xFF;
     491                 :            : 
     492                 :          0 :         return ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16,
     493                 :            :                                        wait_done, true);
     494                 :            : }
     495                 :            : 
     496                 :          0 : static void ar9003_mci_sync_bt_state(struct ath_hw *ah)
     497                 :            : {
     498                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     499                 :          0 :         u32 cur_bt_state;
     500                 :            : 
     501                 :          0 :         cur_bt_state = ar9003_mci_state(ah, MCI_STATE_REMOTE_SLEEP);
     502                 :            : 
     503         [ #  # ]:          0 :         if (mci->bt_state != cur_bt_state)
     504                 :          0 :                 mci->bt_state = cur_bt_state;
     505                 :            : 
     506         [ #  # ]:          0 :         if (mci->bt_state != MCI_BT_SLEEP) {
     507                 :            : 
     508                 :          0 :                 ar9003_mci_send_coex_version_query(ah, true);
     509                 :          0 :                 ar9003_mci_send_coex_wlan_channels(ah, true);
     510                 :            : 
     511         [ #  # ]:          0 :                 if (mci->unhalt_bt_gpm == true)
     512                 :          0 :                         ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
     513                 :            :         }
     514                 :          0 : }
     515                 :            : 
     516                 :          0 : void ar9003_mci_check_bt(struct ath_hw *ah)
     517                 :            : {
     518                 :          0 :         struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
     519                 :            : 
     520         [ #  # ]:          0 :         if (!mci_hw->ready)
     521                 :            :                 return;
     522                 :            : 
     523                 :            :         /*
     524                 :            :          * check BT state again to make
     525                 :            :          * sure it's not changed.
     526                 :            :          */
     527                 :          0 :         ar9003_mci_sync_bt_state(ah);
     528                 :          0 :         ar9003_mci_2g5g_switch(ah, true);
     529                 :            : 
     530         [ #  # ]:          0 :         if ((mci_hw->bt_state == MCI_BT_AWAKE) &&
     531         [ #  # ]:          0 :             (mci_hw->query_bt == true)) {
     532                 :          0 :                 mci_hw->need_flush_btinfo = true;
     533                 :            :         }
     534                 :            : }
     535                 :            : 
     536                 :          0 : static void ar9003_mci_process_gpm_extra(struct ath_hw *ah, u8 gpm_type,
     537                 :            :                                          u8 gpm_opcode, u32 *p_gpm)
     538                 :            : {
     539         [ #  # ]:          0 :         struct ath_common *common = ath9k_hw_common(ah);
     540                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     541                 :          0 :         u8 *p_data = (u8 *) p_gpm;
     542                 :            : 
     543         [ #  # ]:          0 :         if (gpm_type != MCI_GPM_COEX_AGENT)
     544                 :            :                 return;
     545                 :            : 
     546   [ #  #  #  #  :          0 :         switch (gpm_opcode) {
                   #  # ]
     547                 :          0 :         case MCI_GPM_COEX_VERSION_QUERY:
     548         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI Recv GPM COEX Version Query\n");
     549                 :          0 :                 ar9003_mci_send_coex_version_response(ah, true);
     550                 :          0 :                 break;
     551                 :          0 :         case MCI_GPM_COEX_VERSION_RESPONSE:
     552         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI Recv GPM COEX Version Response\n");
     553                 :          0 :                 mci->bt_ver_major =
     554                 :            :                         *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION);
     555                 :          0 :                 mci->bt_ver_minor =
     556                 :            :                         *(p_data + MCI_GPM_COEX_B_MINOR_VERSION);
     557                 :          0 :                 mci->bt_version_known = true;
     558         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI BT Coex version: %d.%d\n",
     559                 :            :                         mci->bt_ver_major, mci->bt_ver_minor);
     560                 :            :                 break;
     561                 :          0 :         case MCI_GPM_COEX_STATUS_QUERY:
     562         [ #  # ]:          0 :                 ath_dbg(common, MCI,
     563                 :            :                         "MCI Recv GPM COEX Status Query = 0x%02X\n",
     564                 :            :                         *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP));
     565                 :          0 :                 mci->wlan_channels_update = true;
     566                 :          0 :                 ar9003_mci_send_coex_wlan_channels(ah, true);
     567                 :          0 :                 break;
     568                 :          0 :         case MCI_GPM_COEX_BT_PROFILE_INFO:
     569                 :          0 :                 mci->query_bt = true;
     570         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI Recv GPM COEX BT_Profile_Info\n");
     571                 :            :                 break;
     572                 :          0 :         case MCI_GPM_COEX_BT_STATUS_UPDATE:
     573                 :          0 :                 mci->query_bt = true;
     574         [ #  # ]:          0 :                 ath_dbg(common, MCI,
     575                 :            :                         "MCI Recv GPM COEX BT_Status_Update SEQ=%d (drop&query)\n",
     576                 :            :                         *(p_gpm + 3));
     577                 :            :                 break;
     578                 :            :         default:
     579                 :            :                 break;
     580                 :            :         }
     581                 :            : }
     582                 :            : 
     583                 :          0 : static u32 ar9003_mci_wait_for_gpm(struct ath_hw *ah, u8 gpm_type,
     584                 :            :                                    u8 gpm_opcode, int time_out)
     585                 :            : {
     586                 :          0 :         struct ath_common *common = ath9k_hw_common(ah);
     587                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     588                 :          0 :         u32 *p_gpm = NULL, mismatch = 0, more_data;
     589                 :          0 :         u32 offset;
     590                 :          0 :         u8 recv_type = 0, recv_opcode = 0;
     591                 :          0 :         bool b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE);
     592                 :            : 
     593                 :          0 :         more_data = time_out ? MCI_GPM_NOMORE : MCI_GPM_MORE;
     594                 :            : 
     595         [ #  # ]:          0 :         while (time_out > 0) {
     596         [ #  # ]:          0 :                 if (p_gpm) {
     597                 :          0 :                         MCI_GPM_RECYCLE(p_gpm);
     598                 :          0 :                         p_gpm = NULL;
     599                 :            :                 }
     600                 :            : 
     601         [ #  # ]:          0 :                 if (more_data != MCI_GPM_MORE)
     602                 :          0 :                         time_out = ar9003_mci_wait_for_interrupt(ah,
     603                 :            :                                         AR_MCI_INTERRUPT_RX_MSG_RAW,
     604                 :            :                                         AR_MCI_INTERRUPT_RX_MSG_GPM,
     605                 :            :                                         time_out);
     606                 :            : 
     607         [ #  # ]:          0 :                 if (!time_out)
     608                 :            :                         break;
     609                 :            : 
     610                 :          0 :                 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
     611                 :            : 
     612         [ #  # ]:          0 :                 if (offset == MCI_GPM_INVALID)
     613                 :          0 :                         continue;
     614                 :            : 
     615                 :          0 :                 p_gpm = (u32 *) (mci->gpm_buf + offset);
     616                 :          0 :                 recv_type = MCI_GPM_TYPE(p_gpm);
     617                 :          0 :                 recv_opcode = MCI_GPM_OPCODE(p_gpm);
     618                 :            : 
     619         [ #  # ]:          0 :                 if (MCI_GPM_IS_CAL_TYPE(recv_type)) {
     620         [ #  # ]:          0 :                         if (recv_type == gpm_type) {
     621   [ #  #  #  # ]:          0 :                                 if ((gpm_type == MCI_GPM_BT_CAL_DONE) &&
     622                 :            :                                     !b_is_bt_cal_done) {
     623                 :          0 :                                         gpm_type = MCI_GPM_BT_CAL_GRANT;
     624                 :          0 :                                         continue;
     625                 :            :                                 }
     626                 :            :                                 break;
     627                 :            :                         }
     628   [ #  #  #  # ]:          0 :                 } else if ((recv_type == gpm_type) &&
     629                 :            :                            (recv_opcode == gpm_opcode))
     630                 :            :                         break;
     631                 :            : 
     632                 :            :                 /*
     633                 :            :                  * check if it's cal_grant
     634                 :            :                  *
     635                 :            :                  * When we're waiting for cal_grant in reset routine,
     636                 :            :                  * it's possible that BT sends out cal_request at the
     637                 :            :                  * same time. Since BT's calibration doesn't happen
     638                 :            :                  * that often, we'll let BT completes calibration then
     639                 :            :                  * we continue to wait for cal_grant from BT.
     640                 :            :                  * Orginal: Wait BT_CAL_GRANT.
     641                 :            :                  * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT->wait
     642                 :            :                  * BT_CAL_DONE -> Wait BT_CAL_GRANT.
     643                 :            :                  */
     644                 :            : 
     645   [ #  #  #  # ]:          0 :                 if ((gpm_type == MCI_GPM_BT_CAL_GRANT) &&
     646                 :            :                     (recv_type == MCI_GPM_BT_CAL_REQ)) {
     647                 :            : 
     648                 :          0 :                         u32 payload[4] = {0, 0, 0, 0};
     649                 :            : 
     650                 :          0 :                         gpm_type = MCI_GPM_BT_CAL_DONE;
     651                 :          0 :                         MCI_GPM_SET_CAL_TYPE(payload,
     652                 :            :                                              MCI_GPM_WLAN_CAL_GRANT);
     653                 :          0 :                         ar9003_mci_send_message(ah, MCI_GPM, 0, payload, 16,
     654                 :            :                                                 false, false);
     655                 :          0 :                         continue;
     656                 :            :                 } else {
     657         [ #  # ]:          0 :                         ath_dbg(common, MCI, "MCI GPM subtype not match 0x%x\n",
     658                 :            :                                 *(p_gpm + 1));
     659                 :          0 :                         mismatch++;
     660                 :          0 :                         ar9003_mci_process_gpm_extra(ah, recv_type,
     661                 :            :                                                      recv_opcode, p_gpm);
     662                 :            :                 }
     663                 :            :         }
     664                 :            : 
     665         [ #  # ]:          0 :         if (p_gpm) {
     666                 :          0 :                 MCI_GPM_RECYCLE(p_gpm);
     667                 :          0 :                 p_gpm = NULL;
     668                 :            :         }
     669                 :            : 
     670                 :          0 :         if (time_out <= 0)
     671                 :            :                 time_out = 0;
     672                 :            : 
     673                 :          0 :         while (more_data == MCI_GPM_MORE) {
     674                 :          0 :                 offset = ar9003_mci_get_next_gpm_offset(ah, &more_data);
     675         [ #  # ]:          0 :                 if (offset == MCI_GPM_INVALID)
     676                 :            :                         break;
     677                 :            : 
     678                 :          0 :                 p_gpm = (u32 *) (mci->gpm_buf + offset);
     679                 :          0 :                 recv_type = MCI_GPM_TYPE(p_gpm);
     680                 :          0 :                 recv_opcode = MCI_GPM_OPCODE(p_gpm);
     681                 :            : 
     682         [ #  # ]:          0 :                 if (!MCI_GPM_IS_CAL_TYPE(recv_type))
     683                 :          0 :                         ar9003_mci_process_gpm_extra(ah, recv_type,
     684                 :            :                                                      recv_opcode, p_gpm);
     685                 :            : 
     686         [ #  # ]:          0 :                 MCI_GPM_RECYCLE(p_gpm);
     687                 :            :         }
     688                 :            : 
     689                 :          0 :         return time_out;
     690                 :            : }
     691                 :            : 
     692                 :          0 : bool ar9003_mci_start_reset(struct ath_hw *ah, struct ath9k_channel *chan)
     693                 :            : {
     694         [ #  # ]:          0 :         struct ath_common *common = ath9k_hw_common(ah);
     695                 :          0 :         struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
     696                 :          0 :         u32 payload[4] = {0, 0, 0, 0};
     697                 :            : 
     698         [ #  # ]:          0 :         ar9003_mci_2g5g_changed(ah, IS_CHAN_2GHZ(chan));
     699                 :            : 
     700         [ #  # ]:          0 :         if (mci_hw->bt_state != MCI_BT_CAL_START)
     701                 :            :                 return false;
     702                 :            : 
     703                 :          0 :         mci_hw->bt_state = MCI_BT_CAL;
     704                 :            : 
     705                 :            :         /*
     706                 :            :          * MCI FIX: disable mci interrupt here. This is to avoid
     707                 :            :          * SW_MSG_DONE or RX_MSG bits to trigger MCI_INT and
     708                 :            :          * lead to mci_intr reentry.
     709                 :            :          */
     710                 :          0 :         ar9003_mci_disable_interrupt(ah);
     711                 :            : 
     712                 :          0 :         MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT);
     713                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, payload,
     714                 :            :                                 16, true, false);
     715                 :            : 
     716                 :            :         /* Wait BT calibration to be completed for 25ms */
     717                 :            : 
     718         [ #  # ]:          0 :         if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_DONE,
     719                 :            :                                     0, 25000))
     720         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI BT_CAL_DONE received\n");
     721                 :            :         else
     722         [ #  # ]:          0 :                 ath_dbg(common, MCI,
     723                 :            :                         "MCI BT_CAL_DONE not received\n");
     724                 :            : 
     725                 :          0 :         mci_hw->bt_state = MCI_BT_AWAKE;
     726                 :            :         /* MCI FIX: enable mci interrupt here */
     727                 :          0 :         ar9003_mci_enable_interrupt(ah);
     728                 :            : 
     729                 :          0 :         return true;
     730                 :            : }
     731                 :            : 
     732                 :          0 : int ar9003_mci_end_reset(struct ath_hw *ah, struct ath9k_channel *chan,
     733                 :            :                          struct ath9k_hw_cal_data *caldata)
     734                 :            : {
     735                 :          0 :         struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
     736                 :            : 
     737         [ #  # ]:          0 :         if (!mci_hw->ready)
     738                 :            :                 return 0;
     739                 :            : 
     740   [ #  #  #  # ]:          0 :         if (!IS_CHAN_2GHZ(chan) || (mci_hw->bt_state != MCI_BT_SLEEP))
     741                 :          0 :                 goto exit;
     742                 :            : 
     743   [ #  #  #  # ]:          0 :         if (!ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET) &&
     744                 :            :             !ar9003_mci_check_int(ah, AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE))
     745                 :          0 :                 goto exit;
     746                 :            : 
     747                 :            :         /*
     748                 :            :          * BT is sleeping. Check if BT wakes up during
     749                 :            :          * WLAN calibration. If BT wakes up during
     750                 :            :          * WLAN calibration, need to go through all
     751                 :            :          * message exchanges again and recal.
     752                 :            :          */
     753                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
     754                 :            :                   (AR_MCI_INTERRUPT_RX_MSG_REMOTE_RESET |
     755                 :            :                    AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE));
     756                 :            : 
     757                 :          0 :         ar9003_mci_remote_reset(ah, true);
     758                 :          0 :         ar9003_mci_send_sys_waking(ah, true);
     759                 :          0 :         udelay(1);
     760                 :            : 
     761         [ #  # ]:          0 :         if (IS_CHAN_2GHZ(chan))
     762                 :          0 :                 ar9003_mci_send_lna_transfer(ah, true);
     763                 :            : 
     764                 :          0 :         mci_hw->bt_state = MCI_BT_AWAKE;
     765                 :            : 
     766                 :          0 :         REG_CLR_BIT(ah, AR_PHY_TIMING4,
     767                 :            :                     1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT);
     768                 :            : 
     769         [ #  # ]:          0 :         if (caldata) {
     770                 :          0 :                 clear_bit(TXIQCAL_DONE, &caldata->cal_flags);
     771                 :          0 :                 clear_bit(TXCLCAL_DONE, &caldata->cal_flags);
     772                 :          0 :                 clear_bit(RTT_DONE, &caldata->cal_flags);
     773                 :            :         }
     774                 :            : 
     775         [ #  # ]:          0 :         if (!ath9k_hw_init_cal(ah, chan))
     776                 :            :                 return -EIO;
     777                 :            : 
     778                 :          0 :         REG_SET_BIT(ah, AR_PHY_TIMING4,
     779                 :            :                     1 << AR_PHY_TIMING_CONTROL4_DO_GAIN_DC_IQ_CAL_SHIFT);
     780                 :            : 
     781                 :          0 : exit:
     782                 :          0 :         ar9003_mci_enable_interrupt(ah);
     783                 :          0 :         return 0;
     784                 :            : }
     785                 :            : 
     786                 :          0 : static void ar9003_mci_mute_bt(struct ath_hw *ah)
     787                 :            : {
     788                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     789                 :            : 
     790                 :            :         /* disable all MCI messages */
     791                 :          0 :         REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xffff0000);
     792                 :          0 :         REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xffffffff);
     793                 :          0 :         REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xffffffff);
     794                 :          0 :         REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xffffffff);
     795                 :          0 :         REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xffffffff);
     796                 :          0 :         REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
     797                 :            : 
     798                 :            :         /* wait pending HW messages to flush out */
     799                 :          0 :         udelay(10);
     800                 :            : 
     801                 :            :         /*
     802                 :            :          * Send LNA_TAKE and SYS_SLEEPING when
     803                 :            :          * 1. reset not after resuming from full sleep
     804                 :            :          * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment
     805                 :            :          */
     806   [ #  #  #  # ]:          0 :         if (MCI_ANT_ARCH_PA_LNA_SHARED(mci)) {
     807                 :          0 :                 ar9003_mci_send_lna_take(ah, true);
     808                 :          0 :                 udelay(5);
     809                 :            :         }
     810                 :            : 
     811                 :          0 :         ar9003_mci_send_sys_sleeping(ah, true);
     812                 :          0 : }
     813                 :            : 
     814                 :          0 : static void ar9003_mci_osla_setup(struct ath_hw *ah, bool enable)
     815                 :            : {
     816                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     817                 :          0 :         u32 thresh;
     818                 :            : 
     819         [ #  # ]:          0 :         if (!enable) {
     820                 :          0 :                 REG_CLR_BIT(ah, AR_BTCOEX_CTRL,
     821                 :            :                             AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
     822                 :          0 :                 return;
     823                 :            :         }
     824                 :          0 :         REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1);
     825                 :          0 :         REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2,
     826                 :            :                       AR_MCI_SCHD_TABLE_2_MEM_BASED, 1);
     827                 :            : 
     828         [ #  # ]:          0 :         if (AR_SREV_9565(ah))
     829                 :          0 :                 REG_RMW_FIELD(ah, AR_MCI_MISC, AR_MCI_MISC_HW_FIX_EN, 1);
     830                 :            : 
     831         [ #  # ]:          0 :         if (!(mci->config & ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) {
     832                 :          0 :                 thresh = MS(mci->config, ATH_MCI_CONFIG_AGGR_THRESH);
     833                 :          0 :                 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
     834                 :            :                               AR_BTCOEX_CTRL_AGGR_THRESH, thresh);
     835                 :          0 :                 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
     836                 :            :                               AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1);
     837                 :            :         } else
     838                 :          0 :                 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
     839                 :            :                               AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0);
     840                 :            : 
     841                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
     842                 :            :                       AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1);
     843                 :            : }
     844                 :            : 
     845                 :          0 : static void ar9003_mci_stat_setup(struct ath_hw *ah)
     846                 :            : {
     847                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     848                 :            : 
     849         [ #  # ]:          0 :         if (!AR_SREV_9565(ah))
     850                 :            :                 return;
     851                 :            : 
     852         [ #  # ]:          0 :         if (mci->config & ATH_MCI_CONFIG_MCI_STAT_DBG) {
     853                 :          0 :                 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
     854                 :            :                               AR_MCI_DBG_CNT_CTRL_ENABLE, 1);
     855                 :          0 :                 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
     856                 :            :                               AR_MCI_DBG_CNT_CTRL_BT_LINKID,
     857                 :            :                               MCI_STAT_ALL_BT_LINKID);
     858                 :            :         } else {
     859                 :          0 :                 REG_RMW_FIELD(ah, AR_MCI_DBG_CNT_CTRL,
     860                 :            :                               AR_MCI_DBG_CNT_CTRL_ENABLE, 0);
     861                 :            :         }
     862                 :            : }
     863                 :            : 
     864                 :          0 : static void ar9003_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hw *ah)
     865                 :            : {
     866                 :          0 :         u32 regval;
     867                 :            : 
     868                 :          0 :         regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
     869                 :            :                  SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
     870                 :            :                  SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
     871                 :            :                  SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
     872                 :            :                  SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
     873                 :            :                  SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
     874                 :            :                  SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
     875                 :            :                  SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
     876                 :            :                  SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
     877                 :            : 
     878                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
     879                 :            :                       AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1);
     880                 :          0 :         REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
     881                 :          0 : }
     882                 :            : 
     883                 :          0 : static void ar9003_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hw *ah)
     884                 :            : {
     885                 :          0 :         u32 regval;
     886                 :            : 
     887                 :          0 :         regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
     888                 :            :                  SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
     889                 :            :                  SM(0, AR_BTCOEX_CTRL_PA_SHARED) |
     890                 :            :                  SM(0, AR_BTCOEX_CTRL_LNA_SHARED) |
     891                 :            :                  SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
     892                 :            :                  SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
     893                 :            :                  SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
     894                 :            :                  SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
     895                 :            :                  SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
     896                 :            : 
     897                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
     898                 :            :                       AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x0);
     899                 :          0 :         REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
     900                 :          0 : }
     901                 :            : 
     902                 :          0 : static void ar9003_mci_set_btcoex_ctrl_9462(struct ath_hw *ah)
     903                 :            : {
     904                 :          0 :         u32 regval;
     905                 :            : 
     906                 :          0 :         regval = SM(1, AR_BTCOEX_CTRL_AR9462_MODE) |
     907                 :            :                  SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) |
     908                 :            :                  SM(1, AR_BTCOEX_CTRL_PA_SHARED) |
     909                 :            :                  SM(1, AR_BTCOEX_CTRL_LNA_SHARED) |
     910                 :            :                  SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) |
     911                 :            :                  SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) |
     912                 :            :                  SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) |
     913                 :            :                  SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) |
     914                 :            :                  SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN);
     915                 :            : 
     916                 :          0 :         REG_WRITE(ah, AR_BTCOEX_CTRL, regval);
     917                 :          0 : }
     918                 :            : 
     919                 :          0 : int ar9003_mci_reset(struct ath_hw *ah, bool en_int, bool is_2g,
     920                 :            :                      bool is_full_sleep)
     921                 :            : {
     922         [ #  # ]:          0 :         struct ath_common *common = ath9k_hw_common(ah);
     923                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
     924                 :          0 :         u32 regval, i;
     925                 :            : 
     926         [ #  # ]:          0 :         ath_dbg(common, MCI, "MCI Reset (full_sleep = %d, is_2g = %d)\n",
     927                 :            :                 is_full_sleep, is_2g);
     928                 :            : 
     929         [ #  # ]:          0 :         if (REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) {
     930                 :          0 :                 ath_err(common, "BTCOEX control register is dead\n");
     931                 :          0 :                 return -EINVAL;
     932                 :            :         }
     933                 :            : 
     934                 :            :         /* Program MCI DMA related registers */
     935                 :          0 :         REG_WRITE(ah, AR_MCI_GPM_0, mci->gpm_addr);
     936                 :          0 :         REG_WRITE(ah, AR_MCI_GPM_1, mci->gpm_len);
     937                 :          0 :         REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, mci->sched_addr);
     938                 :            : 
     939                 :            :         /*
     940                 :            :         * To avoid MCI state machine be affected by incoming remote MCI msgs,
     941                 :            :         * MCI mode will be enabled later, right before reset the MCI TX and RX.
     942                 :            :         */
     943         [ #  # ]:          0 :         if (AR_SREV_9565(ah)) {
     944                 :          0 :                 u8 ant = MS(mci->config, ATH_MCI_CONFIG_ANT_ARCH);
     945                 :            : 
     946         [ #  # ]:          0 :                 if (ant == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED)
     947                 :          0 :                         ar9003_mci_set_btcoex_ctrl_9565_1ANT(ah);
     948                 :            :                 else
     949                 :          0 :                         ar9003_mci_set_btcoex_ctrl_9565_2ANT(ah);
     950                 :            :         } else {
     951                 :          0 :                 ar9003_mci_set_btcoex_ctrl_9462(ah);
     952                 :            :         }
     953                 :            : 
     954   [ #  #  #  # ]:          0 :         if (is_2g && !(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
     955                 :          0 :                 ar9003_mci_osla_setup(ah, true);
     956                 :            :         else
     957                 :          0 :                 ar9003_mci_osla_setup(ah, false);
     958                 :            : 
     959                 :          0 :         REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
     960                 :            :                     AR_BTCOEX_CTRL_SPDT_ENABLE);
     961                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3,
     962                 :            :                       AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20);
     963                 :            : 
     964                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0);
     965                 :          0 :         REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0);
     966                 :            : 
     967                 :            :         /* Set the time out to 3.125ms (5 BT slots) */
     968                 :          0 :         REG_RMW_FIELD(ah, AR_BTCOEX_WL_LNA, AR_BTCOEX_WL_LNA_TIMEOUT, 0x3D090);
     969                 :            : 
     970                 :            :         /* concurrent tx priority */
     971         [ #  # ]:          0 :         if (mci->config & ATH_MCI_CONFIG_CONCUR_TX) {
     972                 :          0 :                 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
     973                 :            :                               AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0);
     974                 :          0 :                 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2,
     975                 :            :                               AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f);
     976                 :          0 :                 REG_RMW_FIELD(ah, AR_BTCOEX_CTRL,
     977                 :            :                               AR_BTCOEX_CTRL_REDUCE_TXPWR, 0);
     978         [ #  # ]:          0 :                 for (i = 0; i < 8; i++)
     979                 :          0 :                         REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), 0x7f7f7f7f);
     980                 :            :         }
     981                 :            : 
     982                 :          0 :         regval = MS(mci->config, ATH_MCI_CONFIG_CLK_DIV);
     983                 :          0 :         REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval);
     984                 :          0 :         REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN);
     985                 :            : 
     986                 :            :         /* Resetting the Rx and Tx paths of MCI */
     987                 :          0 :         regval = REG_READ(ah, AR_MCI_COMMAND2);
     988                 :          0 :         regval |= SM(1, AR_MCI_COMMAND2_RESET_TX);
     989                 :          0 :         REG_WRITE(ah, AR_MCI_COMMAND2, regval);
     990                 :            : 
     991                 :          0 :         udelay(1);
     992                 :            : 
     993                 :          0 :         regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX);
     994                 :          0 :         REG_WRITE(ah, AR_MCI_COMMAND2, regval);
     995                 :            : 
     996         [ #  # ]:          0 :         if (is_full_sleep) {
     997                 :          0 :                 ar9003_mci_mute_bt(ah);
     998                 :          0 :                 udelay(100);
     999                 :            :         }
    1000                 :            : 
    1001                 :            :         /* Check pending GPM msg before MCI Reset Rx */
    1002                 :          0 :         ar9003_mci_check_gpm_offset(ah);
    1003                 :            : 
    1004                 :          0 :         regval |= SM(1, AR_MCI_COMMAND2_RESET_RX);
    1005                 :          0 :         REG_WRITE(ah, AR_MCI_COMMAND2, regval);
    1006                 :          0 :         udelay(1);
    1007                 :          0 :         regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX);
    1008                 :          0 :         REG_WRITE(ah, AR_MCI_COMMAND2, regval);
    1009                 :            : 
    1010                 :            :         /* Init GPM offset after MCI Reset Rx */
    1011                 :          0 :         ar9003_mci_state(ah, MCI_STATE_INIT_GPM_OFFSET);
    1012                 :            : 
    1013                 :          0 :         REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE,
    1014                 :            :                   (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) |
    1015                 :            :                    SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM)));
    1016                 :            : 
    1017   [ #  #  #  # ]:          0 :         if (MCI_ANT_ARCH_PA_LNA_SHARED(mci))
    1018                 :          0 :                 REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
    1019                 :            :                             AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
    1020                 :            :         else
    1021                 :          0 :                 REG_SET_BIT(ah, AR_MCI_TX_CTRL,
    1022                 :            :                             AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
    1023                 :            : 
    1024                 :          0 :         ar9003_mci_observation_set_up(ah);
    1025                 :            : 
    1026                 :          0 :         mci->ready = true;
    1027                 :          0 :         ar9003_mci_prep_interface(ah);
    1028                 :          0 :         ar9003_mci_stat_setup(ah);
    1029                 :            : 
    1030         [ #  # ]:          0 :         if (en_int)
    1031                 :          0 :                 ar9003_mci_enable_interrupt(ah);
    1032                 :            : 
    1033   [ #  #  #  # ]:          0 :         if (ath9k_hw_is_aic_enabled(ah))
    1034                 :          0 :                 ar9003_aic_start_normal(ah);
    1035                 :            : 
    1036                 :            :         return 0;
    1037                 :            : }
    1038                 :            : 
    1039                 :          0 : void ar9003_mci_stop_bt(struct ath_hw *ah, bool save_fullsleep)
    1040                 :            : {
    1041                 :          0 :         struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
    1042                 :            : 
    1043                 :          0 :         ar9003_mci_disable_interrupt(ah);
    1044                 :            : 
    1045   [ #  #  #  # ]:          0 :         if (mci_hw->ready && !save_fullsleep) {
    1046                 :          0 :                 ar9003_mci_mute_bt(ah);
    1047                 :          0 :                 udelay(20);
    1048                 :          0 :                 REG_WRITE(ah, AR_BTCOEX_CTRL, 0);
    1049                 :            :         }
    1050                 :            : 
    1051                 :          0 :         mci_hw->bt_state = MCI_BT_SLEEP;
    1052                 :          0 :         mci_hw->ready = false;
    1053                 :          0 : }
    1054                 :            : 
    1055                 :          0 : static void ar9003_mci_send_2g5g_status(struct ath_hw *ah, bool wait_done)
    1056                 :            : {
    1057                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1058                 :          0 :         u32 to_set, to_clear;
    1059                 :            : 
    1060   [ #  #  #  # ]:          0 :         if (!mci->update_2g5g || (mci->bt_state == MCI_BT_SLEEP))
    1061                 :            :                 return;
    1062                 :            : 
    1063         [ #  # ]:          0 :         if (mci->is_2g) {
    1064                 :            :                 to_clear = MCI_2G_FLAGS_CLEAR_MASK;
    1065                 :            :                 to_set = MCI_2G_FLAGS_SET_MASK;
    1066                 :            :         } else {
    1067                 :          0 :                 to_clear = MCI_5G_FLAGS_CLEAR_MASK;
    1068                 :          0 :                 to_set = MCI_5G_FLAGS_SET_MASK;
    1069                 :            :         }
    1070                 :            : 
    1071                 :          0 :         if (to_clear)
    1072                 :          0 :                 ar9003_mci_send_coex_bt_flags(ah, wait_done,
    1073                 :            :                                               MCI_GPM_COEX_BT_FLAGS_CLEAR,
    1074                 :            :                                               to_clear);
    1075         [ #  # ]:          0 :         if (to_set)
    1076                 :          0 :                 ar9003_mci_send_coex_bt_flags(ah, wait_done,
    1077                 :            :                                               MCI_GPM_COEX_BT_FLAGS_SET,
    1078                 :            :                                               to_set);
    1079                 :            : }
    1080                 :            : 
    1081                 :          0 : static void ar9003_mci_queue_unsent_gpm(struct ath_hw *ah, u8 header,
    1082                 :            :                                         u32 *payload, bool queue)
    1083                 :            : {
    1084                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1085                 :          0 :         u8 type, opcode;
    1086                 :            : 
    1087                 :            :         /* check if the message is to be queued */
    1088         [ #  # ]:          0 :         if (header != MCI_GPM)
    1089                 :            :                 return;
    1090                 :            : 
    1091                 :          0 :         type = MCI_GPM_TYPE(payload);
    1092                 :          0 :         opcode = MCI_GPM_OPCODE(payload);
    1093                 :            : 
    1094         [ #  # ]:          0 :         if (type != MCI_GPM_COEX_AGENT)
    1095                 :            :                 return;
    1096                 :            : 
    1097   [ #  #  #  # ]:          0 :         switch (opcode) {
    1098                 :          0 :         case MCI_GPM_COEX_BT_UPDATE_FLAGS:
    1099         [ #  # ]:          0 :                 if (*(((u8 *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) ==
    1100                 :            :                     MCI_GPM_COEX_BT_FLAGS_READ)
    1101                 :            :                         break;
    1102                 :            : 
    1103                 :          0 :                 mci->update_2g5g = queue;
    1104                 :            : 
    1105                 :          0 :                 break;
    1106                 :          0 :         case MCI_GPM_COEX_WLAN_CHANNELS:
    1107                 :          0 :                 mci->wlan_channels_update = queue;
    1108                 :          0 :                 break;
    1109                 :          0 :         case MCI_GPM_COEX_HALT_BT_GPM:
    1110         [ #  # ]:          0 :                 if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
    1111                 :            :                     MCI_GPM_COEX_BT_GPM_UNHALT) {
    1112                 :          0 :                         mci->unhalt_bt_gpm = queue;
    1113                 :            : 
    1114         [ #  # ]:          0 :                         if (!queue)
    1115                 :          0 :                                 mci->halted_bt_gpm = false;
    1116                 :            :                 }
    1117                 :            : 
    1118         [ #  # ]:          0 :                 if (*(((u8 *)payload) + MCI_GPM_COEX_B_HALT_STATE) ==
    1119                 :            :                                 MCI_GPM_COEX_BT_GPM_HALT) {
    1120                 :            : 
    1121                 :          0 :                         mci->halted_bt_gpm = !queue;
    1122                 :            :                 }
    1123                 :            : 
    1124                 :            :                 break;
    1125                 :            :         default:
    1126                 :            :                 break;
    1127                 :            :         }
    1128                 :          0 : }
    1129                 :            : 
    1130                 :          0 : void ar9003_mci_2g5g_switch(struct ath_hw *ah, bool force)
    1131                 :            : {
    1132                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1133                 :            : 
    1134   [ #  #  #  # ]:          0 :         if (!mci->update_2g5g && !force)
    1135                 :            :                 return;
    1136                 :            : 
    1137         [ #  # ]:          0 :         if (mci->is_2g) {
    1138                 :          0 :                 ar9003_mci_send_2g5g_status(ah, true);
    1139                 :          0 :                 ar9003_mci_send_lna_transfer(ah, true);
    1140                 :          0 :                 udelay(5);
    1141                 :            : 
    1142                 :          0 :                 REG_CLR_BIT(ah, AR_MCI_TX_CTRL,
    1143                 :            :                             AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
    1144                 :          0 :                 REG_CLR_BIT(ah, AR_PHY_GLB_CONTROL,
    1145                 :            :                             AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
    1146                 :            : 
    1147         [ #  # ]:          0 :                 if (!(mci->config & ATH_MCI_CONFIG_DISABLE_OSLA))
    1148                 :          0 :                         ar9003_mci_osla_setup(ah, true);
    1149                 :            : 
    1150         [ #  # ]:          0 :                 if (AR_SREV_9462(ah))
    1151                 :          0 :                         REG_WRITE(ah, AR_SELFGEN_MASK, 0x02);
    1152                 :            :         } else {
    1153                 :          0 :                 ar9003_mci_send_lna_take(ah, true);
    1154                 :          0 :                 udelay(5);
    1155                 :            : 
    1156                 :          0 :                 REG_SET_BIT(ah, AR_MCI_TX_CTRL,
    1157                 :            :                             AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE);
    1158                 :          0 :                 REG_SET_BIT(ah, AR_PHY_GLB_CONTROL,
    1159                 :            :                             AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
    1160                 :            : 
    1161                 :          0 :                 ar9003_mci_osla_setup(ah, false);
    1162                 :          0 :                 ar9003_mci_send_2g5g_status(ah, true);
    1163                 :            :         }
    1164                 :            : }
    1165                 :            : 
    1166                 :          0 : bool ar9003_mci_send_message(struct ath_hw *ah, u8 header, u32 flag,
    1167                 :            :                              u32 *payload, u8 len, bool wait_done,
    1168                 :            :                              bool check_bt)
    1169                 :            : {
    1170                 :          0 :         struct ath_common *common = ath9k_hw_common(ah);
    1171                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1172                 :          0 :         bool msg_sent = false;
    1173                 :          0 :         u32 regval;
    1174                 :          0 :         u32 saved_mci_int_en;
    1175                 :          0 :         int i;
    1176                 :            : 
    1177                 :          0 :         saved_mci_int_en = REG_READ(ah, AR_MCI_INTERRUPT_EN);
    1178                 :          0 :         regval = REG_READ(ah, AR_BTCOEX_CTRL);
    1179                 :            : 
    1180   [ #  #  #  # ]:          0 :         if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) {
    1181         [ #  # ]:          0 :                 ath_dbg(common, MCI,
    1182                 :            :                         "MCI Not sending 0x%x. MCI is not enabled. full_sleep = %d\n",
    1183                 :            :                         header, (ah->power_mode == ATH9K_PM_FULL_SLEEP) ? 1 : 0);
    1184                 :          0 :                 ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
    1185                 :          0 :                 return false;
    1186   [ #  #  #  # ]:          0 :         } else if (check_bt && (mci->bt_state == MCI_BT_SLEEP)) {
    1187         [ #  # ]:          0 :                 ath_dbg(common, MCI,
    1188                 :            :                         "MCI Don't send message 0x%x. BT is in sleep state\n",
    1189                 :            :                         header);
    1190                 :          0 :                 ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
    1191                 :          0 :                 return false;
    1192                 :            :         }
    1193                 :            : 
    1194         [ #  # ]:          0 :         if (wait_done)
    1195                 :          0 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0);
    1196                 :            : 
    1197                 :            :         /* Need to clear SW_MSG_DONE raw bit before wait */
    1198                 :            : 
    1199                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RAW,
    1200                 :            :                   (AR_MCI_INTERRUPT_SW_MSG_DONE |
    1201                 :            :                    AR_MCI_INTERRUPT_MSG_FAIL_MASK));
    1202                 :            : 
    1203         [ #  # ]:          0 :         if (payload) {
    1204         [ #  # ]:          0 :                 for (i = 0; (i * 4) < len; i++)
    1205                 :          0 :                         REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i * 4),
    1206                 :            :                                   *(payload + i));
    1207                 :            :         }
    1208                 :            : 
    1209                 :          0 :         REG_WRITE(ah, AR_MCI_COMMAND0,
    1210                 :            :                   (SM((flag & MCI_FLAG_DISABLE_TIMESTAMP),
    1211                 :            :                       AR_MCI_COMMAND0_DISABLE_TIMESTAMP) |
    1212                 :            :                    SM(len, AR_MCI_COMMAND0_LEN) |
    1213                 :            :                    SM(header, AR_MCI_COMMAND0_HEADER)));
    1214                 :            : 
    1215   [ #  #  #  # ]:          0 :         if (wait_done &&
    1216                 :          0 :             !(ar9003_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW,
    1217                 :            :                                             AR_MCI_INTERRUPT_SW_MSG_DONE, 500)))
    1218                 :          0 :                 ar9003_mci_queue_unsent_gpm(ah, header, payload, true);
    1219                 :            :         else {
    1220                 :          0 :                 ar9003_mci_queue_unsent_gpm(ah, header, payload, false);
    1221                 :          0 :                 msg_sent = true;
    1222                 :            :         }
    1223                 :            : 
    1224         [ #  # ]:          0 :         if (wait_done)
    1225                 :          0 :                 REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en);
    1226                 :            : 
    1227                 :            :         return msg_sent;
    1228                 :            : }
    1229                 :            : EXPORT_SYMBOL(ar9003_mci_send_message);
    1230                 :            : 
    1231                 :          0 : void ar9003_mci_init_cal_req(struct ath_hw *ah, bool *is_reusable)
    1232                 :            : {
    1233         [ #  # ]:          0 :         struct ath_common *common = ath9k_hw_common(ah);
    1234                 :          0 :         struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
    1235                 :          0 :         u32 pld[4] = {0, 0, 0, 0};
    1236                 :            : 
    1237         [ #  # ]:          0 :         if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
    1238         [ #  # ]:          0 :             (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
    1239                 :          0 :                 return;
    1240                 :            : 
    1241                 :          0 :         MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_REQ);
    1242                 :          0 :         pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_seq++;
    1243                 :            : 
    1244                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
    1245                 :            : 
    1246         [ #  # ]:          0 :         if (ar9003_mci_wait_for_gpm(ah, MCI_GPM_BT_CAL_GRANT, 0, 50000)) {
    1247         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI BT_CAL_GRANT received\n");
    1248                 :            :         } else {
    1249                 :          0 :                 *is_reusable = false;
    1250         [ #  # ]:          0 :                 ath_dbg(common, MCI, "MCI BT_CAL_GRANT not received\n");
    1251                 :            :         }
    1252                 :            : }
    1253                 :            : 
    1254                 :          0 : void ar9003_mci_init_cal_done(struct ath_hw *ah)
    1255                 :            : {
    1256                 :          0 :         struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
    1257                 :          0 :         u32 pld[4] = {0, 0, 0, 0};
    1258                 :            : 
    1259         [ #  # ]:          0 :         if ((mci_hw->bt_state != MCI_BT_AWAKE) ||
    1260         [ #  # ]:          0 :             (mci_hw->config & ATH_MCI_CONFIG_DISABLE_MCI_CAL))
    1261                 :          0 :                 return;
    1262                 :            : 
    1263                 :          0 :         MCI_GPM_SET_CAL_TYPE(pld, MCI_GPM_WLAN_CAL_DONE);
    1264                 :          0 :         pld[MCI_GPM_WLAN_CAL_W_SEQUENCE] = mci_hw->wlan_cal_done++;
    1265                 :          0 :         ar9003_mci_send_message(ah, MCI_GPM, 0, pld, 16, true, false);
    1266                 :            : }
    1267                 :            : 
    1268                 :          0 : int ar9003_mci_setup(struct ath_hw *ah, u32 gpm_addr, void *gpm_buf,
    1269                 :            :                      u16 len, u32 sched_addr)
    1270                 :            : {
    1271                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1272                 :            : 
    1273                 :          0 :         mci->gpm_addr = gpm_addr;
    1274                 :          0 :         mci->gpm_buf = gpm_buf;
    1275                 :          0 :         mci->gpm_len = len;
    1276                 :          0 :         mci->sched_addr = sched_addr;
    1277                 :            : 
    1278                 :          0 :         return ar9003_mci_reset(ah, true, true, true);
    1279                 :            : }
    1280                 :            : EXPORT_SYMBOL(ar9003_mci_setup);
    1281                 :            : 
    1282                 :          0 : void ar9003_mci_cleanup(struct ath_hw *ah)
    1283                 :            : {
    1284                 :            :         /* Turn off MCI and Jupiter mode. */
    1285                 :          0 :         REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00);
    1286                 :          0 :         ar9003_mci_disable_interrupt(ah);
    1287                 :          0 : }
    1288                 :            : EXPORT_SYMBOL(ar9003_mci_cleanup);
    1289                 :            : 
    1290                 :          0 : u32 ar9003_mci_state(struct ath_hw *ah, u32 state_type)
    1291                 :            : {
    1292                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1293                 :          0 :         u32 value = 0, tsf;
    1294                 :          0 :         u8 query_type;
    1295                 :            : 
    1296   [ #  #  #  #  :          0 :         switch (state_type) {
          #  #  #  #  #  
          #  #  #  #  #  
                #  #  # ]
    1297                 :          0 :         case MCI_STATE_ENABLE:
    1298         [ #  # ]:          0 :                 if (mci->ready) {
    1299                 :          0 :                         value = REG_READ(ah, AR_BTCOEX_CTRL);
    1300                 :            : 
    1301   [ #  #  #  # ]:          0 :                         if ((value == 0xdeadbeef) || (value == 0xffffffff))
    1302                 :          0 :                                 value = 0;
    1303                 :            :                 }
    1304                 :          0 :                 value &= AR_BTCOEX_CTRL_MCI_MODE_EN;
    1305                 :          0 :                 break;
    1306                 :          0 :         case MCI_STATE_INIT_GPM_OFFSET:
    1307                 :          0 :                 value = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
    1308                 :            : 
    1309         [ #  # ]:          0 :                 if (value < mci->gpm_len)
    1310                 :          0 :                         mci->gpm_idx = value;
    1311                 :            :                 else
    1312                 :          0 :                         mci->gpm_idx = 0;
    1313                 :            :                 break;
    1314                 :          0 :         case MCI_STATE_LAST_SCHD_MSG_OFFSET:
    1315                 :          0 :                 value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
    1316                 :            :                                     AR_MCI_RX_LAST_SCHD_MSG_INDEX);
    1317                 :            :                 /* Make it in bytes */
    1318                 :          0 :                 value <<= 4;
    1319                 :          0 :                 break;
    1320                 :          0 :         case MCI_STATE_REMOTE_SLEEP:
    1321                 :          0 :                 value = MS(REG_READ(ah, AR_MCI_RX_STATUS),
    1322                 :          0 :                            AR_MCI_RX_REMOTE_SLEEP) ?
    1323                 :          0 :                         MCI_BT_SLEEP : MCI_BT_AWAKE;
    1324                 :          0 :                 break;
    1325                 :          0 :         case MCI_STATE_SET_BT_AWAKE:
    1326                 :          0 :                 mci->bt_state = MCI_BT_AWAKE;
    1327                 :          0 :                 ar9003_mci_send_coex_version_query(ah, true);
    1328                 :          0 :                 ar9003_mci_send_coex_wlan_channels(ah, true);
    1329                 :            : 
    1330         [ #  # ]:          0 :                 if (mci->unhalt_bt_gpm)
    1331                 :          0 :                         ar9003_mci_send_coex_halt_bt_gpm(ah, false, true);
    1332                 :            : 
    1333                 :          0 :                 ar9003_mci_2g5g_switch(ah, false);
    1334                 :          0 :                 break;
    1335                 :          0 :         case MCI_STATE_RESET_REQ_WAKE:
    1336                 :          0 :                 ar9003_mci_reset_req_wakeup(ah);
    1337                 :          0 :                 mci->update_2g5g = true;
    1338                 :            : 
    1339         [ #  # ]:          0 :                 if (mci->config & ATH_MCI_CONFIG_MCI_OBS_MASK) {
    1340                 :            :                         /* Check if we still have control of the GPIOs */
    1341         [ #  # ]:          0 :                         if ((REG_READ(ah, AR_GLB_GPIO_CONTROL) &
    1342                 :            :                              ATH_MCI_CONFIG_MCI_OBS_GPIO) !=
    1343                 :            :                             ATH_MCI_CONFIG_MCI_OBS_GPIO) {
    1344                 :          0 :                                 ar9003_mci_observation_set_up(ah);
    1345                 :            :                         }
    1346                 :            :                 }
    1347                 :            :                 break;
    1348                 :          0 :         case MCI_STATE_SEND_WLAN_COEX_VERSION:
    1349                 :          0 :                 ar9003_mci_send_coex_version_response(ah, true);
    1350                 :          0 :                 break;
    1351                 :          0 :         case MCI_STATE_SEND_VERSION_QUERY:
    1352                 :          0 :                 ar9003_mci_send_coex_version_query(ah, true);
    1353                 :          0 :                 break;
    1354                 :          0 :         case MCI_STATE_SEND_STATUS_QUERY:
    1355                 :          0 :                 query_type = MCI_GPM_COEX_QUERY_BT_TOPOLOGY;
    1356                 :          0 :                 ar9003_mci_send_coex_bt_status_query(ah, true, query_type);
    1357                 :          0 :                 break;
    1358                 :          0 :         case MCI_STATE_RECOVER_RX:
    1359                 :          0 :                 tsf = ath9k_hw_gettsf32(ah);
    1360         [ #  # ]:          0 :                 if ((tsf - mci->last_recovery) <= MCI_RECOVERY_DUR_TSF) {
    1361         [ #  # ]:          0 :                         ath_dbg(ath9k_hw_common(ah), MCI,
    1362                 :            :                                 "(MCI) ignore Rx recovery\n");
    1363                 :            :                         break;
    1364                 :            :                 }
    1365         [ #  # ]:          0 :                 ath_dbg(ath9k_hw_common(ah), MCI, "(MCI) RECOVER RX\n");
    1366                 :          0 :                 mci->last_recovery = tsf;
    1367                 :          0 :                 ar9003_mci_prep_interface(ah);
    1368                 :          0 :                 mci->query_bt = true;
    1369                 :          0 :                 mci->need_flush_btinfo = true;
    1370                 :          0 :                 ar9003_mci_send_coex_wlan_channels(ah, true);
    1371                 :          0 :                 ar9003_mci_2g5g_switch(ah, false);
    1372                 :          0 :                 break;
    1373                 :          0 :         case MCI_STATE_NEED_FTP_STOMP:
    1374                 :          0 :                 value = !(mci->config & ATH_MCI_CONFIG_DISABLE_FTP_STOMP);
    1375                 :          0 :                 break;
    1376                 :          0 :         case MCI_STATE_NEED_FLUSH_BT_INFO:
    1377   [ #  #  #  # ]:          0 :                 value = (!mci->unhalt_bt_gpm && mci->need_flush_btinfo) ? 1 : 0;
    1378                 :          0 :                 mci->need_flush_btinfo = false;
    1379                 :          0 :                 break;
    1380                 :            :         case MCI_STATE_AIC_CAL:
    1381   [ #  #  #  # ]:          0 :                 if (ath9k_hw_is_aic_enabled(ah))
    1382                 :          0 :                         value = ar9003_aic_calibration(ah);
    1383                 :            :                 break;
    1384                 :            :         case MCI_STATE_AIC_START:
    1385   [ #  #  #  # ]:          0 :                 if (ath9k_hw_is_aic_enabled(ah))
    1386                 :          0 :                         ar9003_aic_start_normal(ah);
    1387                 :            :                 break;
    1388                 :            :         case MCI_STATE_AIC_CAL_RESET:
    1389   [ #  #  #  # ]:          0 :                 if (ath9k_hw_is_aic_enabled(ah))
    1390                 :          0 :                         value = ar9003_aic_cal_reset(ah);
    1391                 :            :                 break;
    1392                 :            :         case MCI_STATE_AIC_CAL_SINGLE:
    1393   [ #  #  #  # ]:          0 :                 if (ath9k_hw_is_aic_enabled(ah))
    1394                 :          0 :                         value = ar9003_aic_calibration_single(ah);
    1395                 :            :                 break;
    1396                 :            :         default:
    1397                 :            :                 break;
    1398                 :            :         }
    1399                 :            : 
    1400                 :          0 :         return value;
    1401                 :            : }
    1402                 :            : EXPORT_SYMBOL(ar9003_mci_state);
    1403                 :            : 
    1404                 :          0 : void ar9003_mci_bt_gain_ctrl(struct ath_hw *ah)
    1405                 :            : {
    1406         [ #  # ]:          0 :         struct ath_common *common = ath9k_hw_common(ah);
    1407                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1408                 :            : 
    1409         [ #  # ]:          0 :         ath_dbg(common, MCI, "Give LNA and SPDT control to BT\n");
    1410                 :            : 
    1411                 :          0 :         ar9003_mci_send_lna_take(ah, true);
    1412                 :          0 :         udelay(50);
    1413                 :            : 
    1414                 :          0 :         REG_SET_BIT(ah, AR_PHY_GLB_CONTROL, AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL);
    1415                 :          0 :         mci->is_2g = false;
    1416                 :          0 :         mci->update_2g5g = true;
    1417                 :          0 :         ar9003_mci_send_2g5g_status(ah, true);
    1418                 :            : 
    1419                 :            :         /* Force another 2g5g update at next scanning */
    1420                 :          0 :         mci->update_2g5g = true;
    1421                 :          0 : }
    1422                 :            : 
    1423                 :          0 : void ar9003_mci_set_power_awake(struct ath_hw *ah)
    1424                 :            : {
    1425                 :          0 :         u32 btcoex_ctrl2, diag_sw;
    1426                 :          0 :         int i;
    1427                 :          0 :         u8 lna_ctrl, bt_sleep;
    1428                 :            : 
    1429         [ #  # ]:          0 :         for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
    1430                 :          0 :                 btcoex_ctrl2 = REG_READ(ah, AR_BTCOEX_CTRL2);
    1431         [ #  # ]:          0 :                 if (btcoex_ctrl2 != 0xdeadbeef)
    1432                 :            :                         break;
    1433                 :          0 :                 udelay(AH_TIME_QUANTUM);
    1434                 :            :         }
    1435                 :          0 :         REG_WRITE(ah, AR_BTCOEX_CTRL2, (btcoex_ctrl2 | BIT(23)));
    1436                 :            : 
    1437         [ #  # ]:          0 :         for (i = 0; i < AH_WAIT_TIMEOUT; i++) {
    1438                 :          0 :                 diag_sw = REG_READ(ah, AR_DIAG_SW);
    1439         [ #  # ]:          0 :                 if (diag_sw != 0xdeadbeef)
    1440                 :            :                         break;
    1441                 :          0 :                 udelay(AH_TIME_QUANTUM);
    1442                 :            :         }
    1443                 :          0 :         REG_WRITE(ah, AR_DIAG_SW, (diag_sw | BIT(27) | BIT(19) | BIT(18)));
    1444                 :          0 :         lna_ctrl = REG_READ(ah, AR_OBS_BUS_CTRL) & 0x3;
    1445                 :          0 :         bt_sleep = MS(REG_READ(ah, AR_MCI_RX_STATUS), AR_MCI_RX_REMOTE_SLEEP);
    1446                 :            : 
    1447                 :          0 :         REG_WRITE(ah, AR_BTCOEX_CTRL2, btcoex_ctrl2);
    1448                 :          0 :         REG_WRITE(ah, AR_DIAG_SW, diag_sw);
    1449                 :            : 
    1450   [ #  #  #  # ]:          0 :         if (bt_sleep && (lna_ctrl == 2)) {
    1451                 :          0 :                 REG_SET_BIT(ah, AR_BTCOEX_RC, 0x1);
    1452                 :          0 :                 REG_CLR_BIT(ah, AR_BTCOEX_RC, 0x1);
    1453                 :          0 :                 udelay(50);
    1454                 :            :         }
    1455                 :          0 : }
    1456                 :            : 
    1457                 :          0 : void ar9003_mci_check_gpm_offset(struct ath_hw *ah)
    1458                 :            : {
    1459                 :          0 :         struct ath_common *common = ath9k_hw_common(ah);
    1460                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1461                 :          0 :         u32 offset;
    1462                 :            : 
    1463                 :            :         /*
    1464                 :            :          * This should only be called before "MAC Warm Reset" or "MCI Reset Rx".
    1465                 :            :          */
    1466                 :          0 :         offset = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
    1467         [ #  # ]:          0 :         if (mci->gpm_idx == offset)
    1468                 :            :                 return;
    1469         [ #  # ]:          0 :         ath_dbg(common, MCI, "GPM cached write pointer mismatch %d %d\n",
    1470                 :            :                 mci->gpm_idx, offset);
    1471                 :          0 :         mci->query_bt = true;
    1472                 :          0 :         mci->need_flush_btinfo = true;
    1473                 :          0 :         mci->gpm_idx = 0;
    1474                 :            : }
    1475                 :            : 
    1476                 :          0 : u32 ar9003_mci_get_next_gpm_offset(struct ath_hw *ah, u32 *more)
    1477                 :            : {
    1478                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1479                 :          0 :         u32 offset, more_gpm = 0, gpm_ptr;
    1480                 :            : 
    1481                 :            :         /*
    1482                 :            :          * This could be useful to avoid new GPM message interrupt which
    1483                 :            :          * may lead to spurious interrupt after power sleep, or multiple
    1484                 :            :          * entry of ath_mci_intr().
    1485                 :            :          * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can
    1486                 :            :          * alleviate this effect, but clearing GPM RX interrupt bit is
    1487                 :            :          * safe, because whether this is called from hw or driver code
    1488                 :            :          * there must be an interrupt bit set/triggered initially
    1489                 :            :          */
    1490                 :          0 :         REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW,
    1491                 :            :                         AR_MCI_INTERRUPT_RX_MSG_GPM);
    1492                 :            : 
    1493                 :          0 :         gpm_ptr = MS(REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR);
    1494                 :          0 :         offset = gpm_ptr;
    1495                 :            : 
    1496         [ #  # ]:          0 :         if (!offset)
    1497                 :          0 :                 offset = mci->gpm_len - 1;
    1498         [ #  # ]:          0 :         else if (offset >= mci->gpm_len) {
    1499         [ #  # ]:          0 :                 if (offset != 0xFFFF)
    1500                 :            :                         offset = 0;
    1501                 :            :         } else {
    1502                 :          0 :                 offset--;
    1503                 :            :         }
    1504                 :            : 
    1505   [ #  #  #  # ]:          0 :         if ((offset == 0xFFFF) || (gpm_ptr == mci->gpm_idx)) {
    1506                 :          0 :                 offset = MCI_GPM_INVALID;
    1507                 :          0 :                 more_gpm = MCI_GPM_NOMORE;
    1508                 :          0 :                 goto out;
    1509                 :            :         }
    1510                 :          0 :         for (;;) {
    1511                 :          0 :                 u32 temp_index;
    1512                 :            : 
    1513                 :            :                 /* skip reserved GPM if any */
    1514                 :            : 
    1515         [ #  # ]:          0 :                 if (offset != mci->gpm_idx)
    1516                 :            :                         more_gpm = MCI_GPM_MORE;
    1517                 :            :                 else
    1518                 :          0 :                         more_gpm = MCI_GPM_NOMORE;
    1519                 :            : 
    1520                 :          0 :                 temp_index = mci->gpm_idx;
    1521                 :            : 
    1522         [ #  # ]:          0 :                 if (temp_index >= mci->gpm_len)
    1523                 :          0 :                         temp_index = 0;
    1524                 :            : 
    1525                 :          0 :                 mci->gpm_idx++;
    1526                 :            : 
    1527         [ #  # ]:          0 :                 if (mci->gpm_idx >= mci->gpm_len)
    1528                 :          0 :                         mci->gpm_idx = 0;
    1529                 :            : 
    1530         [ #  # ]:          0 :                 if (ar9003_mci_is_gpm_valid(ah, temp_index)) {
    1531                 :            :                         offset = temp_index;
    1532                 :            :                         break;
    1533                 :            :                 }
    1534                 :            : 
    1535         [ #  # ]:          0 :                 if (more_gpm == MCI_GPM_NOMORE) {
    1536                 :            :                         offset = MCI_GPM_INVALID;
    1537                 :            :                         break;
    1538                 :            :                 }
    1539                 :            :         }
    1540                 :            : 
    1541         [ #  # ]:          0 :         if (offset != MCI_GPM_INVALID)
    1542                 :          0 :                 offset <<= 4;
    1543                 :          0 : out:
    1544         [ #  # ]:          0 :         if (more)
    1545                 :          0 :                 *more = more_gpm;
    1546                 :            : 
    1547                 :          0 :         return offset;
    1548                 :            : }
    1549                 :            : EXPORT_SYMBOL(ar9003_mci_get_next_gpm_offset);
    1550                 :            : 
    1551                 :          0 : void ar9003_mci_set_bt_version(struct ath_hw *ah, u8 major, u8 minor)
    1552                 :            : {
    1553                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1554                 :            : 
    1555                 :          0 :         mci->bt_ver_major = major;
    1556                 :          0 :         mci->bt_ver_minor = minor;
    1557                 :          0 :         mci->bt_version_known = true;
    1558         [ #  # ]:          0 :         ath_dbg(ath9k_hw_common(ah), MCI, "MCI BT version set: %d.%d\n",
    1559                 :            :                 mci->bt_ver_major, mci->bt_ver_minor);
    1560                 :          0 : }
    1561                 :            : EXPORT_SYMBOL(ar9003_mci_set_bt_version);
    1562                 :            : 
    1563                 :          0 : void ar9003_mci_send_wlan_channels(struct ath_hw *ah)
    1564                 :            : {
    1565                 :          0 :         struct ath9k_hw_mci *mci = &ah->btcoex_hw.mci;
    1566                 :            : 
    1567                 :          0 :         mci->wlan_channels_update = true;
    1568                 :          0 :         ar9003_mci_send_coex_wlan_channels(ah, true);
    1569                 :          0 : }
    1570                 :            : EXPORT_SYMBOL(ar9003_mci_send_wlan_channels);
    1571                 :            : 
    1572                 :          0 : u16 ar9003_mci_get_max_txpower(struct ath_hw *ah, u8 ctlmode)
    1573                 :            : {
    1574         [ #  # ]:          0 :         if (!ah->btcoex_hw.mci.concur_tx)
    1575                 :          0 :                 goto out;
    1576                 :            : 
    1577         [ #  # ]:          0 :         if (ctlmode == CTL_2GHT20)
    1578                 :            :                 return ATH_BTCOEX_HT20_MAX_TXPOWER;
    1579         [ #  # ]:          0 :         else if (ctlmode == CTL_2GHT40)
    1580                 :          0 :                 return ATH_BTCOEX_HT40_MAX_TXPOWER;
    1581                 :            : 
    1582                 :          0 : out:
    1583                 :            :         return -1;
    1584                 :            : }

Generated by: LCOV version 1.14