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