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