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