1 /* 2 * Copyright (c) 2013 Qualcomm Atheros, 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 WITH 9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 10 * AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, 11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR 13 * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 14 * PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 18 #include "opt_ah.h" 19 20 #include "ah.h" 21 #include "ah_internal.h" 22 23 #include "ar9300/ar9300.h" 24 #include "ar9300/ar9300reg.h" 25 #include "ar9300/ar9300phy.h" 26 27 #if ATH_SUPPORT_MCI 28 29 #define AH_MCI_REMOTE_RESET_INTERVAL_US 500 30 #define AH_MCI_DEBUG_PRINT_SCHED 0 31 32 static void ar9300_mci_print_msg(struct ath_hal *ah, HAL_BOOL send,u_int8_t hdr, 33 int len, u_int32_t *pl) 34 { 35 #if 0 36 char s[128]; 37 char *p = s; 38 int i; 39 u_int8_t *p_data = (u_int8_t *) pl; 40 41 if (send) { 42 p += snprintf(s, 60, 43 "(MCI) >>>>> Hdr: %02X, Len: %d, Payload:", hdr, len); 44 } 45 else { 46 p += snprintf(s, 60, 47 "(MCI) <<<<< Hdr: %02X, Len: %d, Payload:", hdr, len); 48 } 49 for ( i=0; i<len; i++) 50 { 51 p += snprintf(p, 60, " %02x", *(p_data + i)); 52 } 53 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s\n", s); 54 /* 55 for ( i=0; i<(len + 3)/4; i++) 56 { 57 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) 0x%08x\n", *(pl + i)); 58 } 59 */ 60 #endif 61 } 62 63 static 64 void ar9300_mci_osla_setup(struct ath_hal *ah, HAL_BOOL enable) 65 { 66 // struct ath_hal_9300 *ahp = AH9300(ah); 67 u_int32_t thresh; 68 69 if (enable) { 70 OS_REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_HW_BASED, 1); 71 OS_REG_RMW_FIELD(ah, AR_MCI_SCHD_TABLE_2, AR_MCI_SCHD_TABLE_2_MEM_BASED, 1); 72 73 if (!(ah->ah_config.ath_hal_mci_config & 74 ATH_MCI_CONFIG_DISABLE_AGGR_THRESH)) 75 { 76 77 if (AR_SREV_APHRODITE(ah)) 78 OS_REG_RMW_FIELD(ah, AR_MCI_MISC, AR_MCI_MISC_HW_FIX_EN, 1); 79 80 thresh = MS(ah->ah_config.ath_hal_mci_config, 81 ATH_MCI_CONFIG_AGGR_THRESH); 82 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, 83 AR_BTCOEX_CTRL_AGGR_THRESH, thresh); 84 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, 85 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 1); 86 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 87 "(MCI) SCHED aggr thresh: on, thresh=%d (%d.%d%%)\n", 88 thresh, (thresh + 1)*125/10, (thresh + 1)*125%10); 89 90 } 91 else { 92 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, 93 AR_BTCOEX_CTRL_TIME_TO_NEXT_BT_THRESH_EN, 0); 94 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED aggr thresh: off\n"); 95 } 96 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, 97 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN, 1); 98 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED one step look ahead: on\n"); 99 } 100 else { 101 OS_REG_CLR_BIT(ah, AR_BTCOEX_CTRL, 102 AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); 103 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED one step look ahead: off\n"); 104 } 105 } 106 107 static void ar9300_mci_reset_req_wakeup(struct ath_hal *ah) 108 { 109 /* to be tested in emulation */ 110 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 111 OS_REG_RMW_FIELD(ah, AR_MCI_COMMAND2, 112 AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 1); 113 OS_DELAY(1); 114 OS_REG_RMW_FIELD(ah, AR_MCI_COMMAND2, 115 AR_MCI_COMMAND2_RESET_REQ_WAKEUP, 0); 116 } 117 } 118 119 static int32_t ar9300_mci_wait_for_interrupt(struct ath_hal *ah, 120 u_int32_t address, 121 u_int32_t bit_position, 122 int32_t time_out) 123 { 124 int data; //, loop; 125 126 while (time_out) { 127 data = OS_REG_READ(ah, address); 128 129 if (data & bit_position) { 130 OS_REG_WRITE(ah, address, bit_position); 131 if (address == AR_MCI_INTERRUPT_RX_MSG_RAW) { 132 if (bit_position & AR_MCI_INTERRUPT_RX_MSG_REQ_WAKE) { 133 ar9300_mci_reset_req_wakeup(ah); 134 } 135 if (bit_position & (AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING | 136 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) 137 { 138 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, 139 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); 140 } 141 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_RX_MSG); 142 } 143 break; 144 } 145 146 OS_DELAY(10); 147 time_out -= 10; 148 if (time_out < 0) { 149 break; 150 } 151 } 152 153 if (time_out <= 0) { 154 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 155 "(MCI) %s: Wait for Reg0x%08x = 0x%08x timeout.\n", 156 __func__, address, bit_position); 157 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 158 "(MCI) INT_RAW = 0x%08x, RX_MSG_RAW = 0x%08x\n", 159 OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW), 160 OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW)); 161 time_out = 0; 162 } 163 return time_out; 164 } 165 166 void ar9300_mci_remote_reset(struct ath_hal *ah, HAL_BOOL wait_done) 167 { 168 u_int32_t payload[4] = { 0xffffffff, 0xffffffff, 0xffffffff, 0xffffff00}; 169 170 ar9300_mci_send_message(ah, MCI_REMOTE_RESET, 0, payload, 16, 171 wait_done, AH_FALSE); 172 173 OS_DELAY(5); 174 } 175 176 void ar9300_mci_send_lna_transfer(struct ath_hal *ah, HAL_BOOL wait_done) 177 { 178 u_int32_t payload = 0x00000000; 179 180 ar9300_mci_send_message(ah, MCI_LNA_TRANS, 0, &payload, 1, 181 wait_done, AH_FALSE); 182 } 183 184 static void ar9300_mci_send_req_wake(struct ath_hal *ah, HAL_BOOL wait_done) 185 { 186 ar9300_mci_send_message(ah, MCI_REQ_WAKE, 187 HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE); 188 189 OS_DELAY(5); 190 } 191 192 void ar9300_mci_send_sys_waking(struct ath_hal *ah, HAL_BOOL wait_done) 193 { 194 ar9300_mci_send_message(ah, MCI_SYS_WAKING, 195 HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE); 196 } 197 198 static void ar9300_mci_send_lna_take(struct ath_hal *ah, HAL_BOOL wait_done) 199 { 200 u_int32_t payload = 0x70000000; 201 202 /* LNA gain index is set to 7. */ 203 ar9300_mci_send_message(ah, MCI_LNA_TAKE, 204 HAL_MCI_FLAG_DISABLE_TIMESTAMP, &payload, 1, wait_done, AH_FALSE); 205 } 206 207 static void ar9300_mci_send_sys_sleeping(struct ath_hal *ah, HAL_BOOL wait_done) 208 { 209 ar9300_mci_send_message(ah, MCI_SYS_SLEEPING, 210 HAL_MCI_FLAG_DISABLE_TIMESTAMP, AH_NULL, 0, wait_done, AH_FALSE); 211 } 212 213 static void 214 ar9300_mci_send_coex_version_query(struct ath_hal *ah, HAL_BOOL wait_done) 215 { 216 struct ath_hal_9300 *ahp = AH9300(ah); 217 u_int32_t payload[4] = {0, 0, 0, 0}; 218 219 if ((ahp->ah_mci_coex_bt_version_known == AH_FALSE) && 220 (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) { 221 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send Coex version query.\n"); 222 MCI_GPM_SET_TYPE_OPCODE(payload, 223 MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_QUERY); 224 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE); 225 } 226 } 227 228 static void 229 ar9300_mci_send_coex_version_response(struct ath_hal *ah, HAL_BOOL wait_done) 230 { 231 struct ath_hal_9300 *ahp = AH9300(ah); 232 u_int32_t payload[4] = {0, 0, 0, 0}; 233 234 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send Coex version response.\n"); 235 MCI_GPM_SET_TYPE_OPCODE(payload, 236 MCI_GPM_COEX_AGENT, MCI_GPM_COEX_VERSION_RESPONSE); 237 *(((u_int8_t *)payload) + MCI_GPM_COEX_B_MAJOR_VERSION) = 238 ahp->ah_mci_coex_major_version_wlan; 239 *(((u_int8_t *)payload) + MCI_GPM_COEX_B_MINOR_VERSION) = 240 ahp->ah_mci_coex_minor_version_wlan; 241 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE); 242 } 243 244 static void 245 ar9300_mci_send_coex_wlan_channels(struct ath_hal *ah, HAL_BOOL wait_done) 246 { 247 struct ath_hal_9300 *ahp = AH9300(ah); 248 u_int32_t *payload = &ahp->ah_mci_coex_wlan_channels[0]; 249 250 if ((ahp->ah_mci_coex_wlan_channels_update == AH_TRUE) && 251 (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) 252 { 253 MCI_GPM_SET_TYPE_OPCODE(payload, 254 MCI_GPM_COEX_AGENT, MCI_GPM_COEX_WLAN_CHANNELS); 255 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE); 256 MCI_GPM_SET_TYPE_OPCODE(payload, 0xff, 0xff); 257 } 258 } 259 260 static void ar9300_mci_send_coex_bt_status_query(struct ath_hal *ah, 261 HAL_BOOL wait_done, u_int8_t query_type) 262 { 263 struct ath_hal_9300 *ahp = AH9300(ah); 264 u_int32_t pld[4] = {0, 0, 0, 0}; 265 HAL_BOOL query_btinfo = query_type & 266 (MCI_GPM_COEX_QUERY_BT_ALL_INFO | MCI_GPM_COEX_QUERY_BT_TOPOLOGY); 267 268 if (ahp->ah_mci_bt_state != MCI_BT_SLEEP) { 269 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 270 "(MCI) Send Coex BT Status Query 0x%02X\n", query_type); 271 MCI_GPM_SET_TYPE_OPCODE(pld, 272 MCI_GPM_COEX_AGENT, MCI_GPM_COEX_STATUS_QUERY); 273 *(((u_int8_t *)pld) + MCI_GPM_COEX_B_BT_BITMAP) = query_type; 274 /* 275 * If bt_status_query message is thought not sent successfully, 276 * then ah_mci_need_flush_btinfo should be set again. 277 */ 278 if (!ar9300_mci_send_message(ah, MCI_GPM, 0, pld, 16, wait_done, AH_TRUE)) 279 { 280 if (query_btinfo) { 281 ahp->ah_mci_need_flush_btinfo = AH_TRUE; 282 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 283 "(MCI) send bt_status_query fail, set flush flag again\n"); 284 } 285 } 286 if (query_btinfo) { 287 ahp->ah_mci_query_bt = AH_FALSE; 288 } 289 } 290 } 291 292 void ar9300_mci_send_coex_halt_bt_gpm(struct ath_hal *ah, 293 HAL_BOOL halt, HAL_BOOL wait_done) 294 { 295 struct ath_hal_9300 *ahp = AH9300(ah); 296 u_int32_t payload[4] = {0, 0, 0, 0}; 297 298 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 299 "(MCI) Send Coex %s BT GPM.\n", (halt == AH_TRUE)?"HALT":"UNHALT"); 300 301 MCI_GPM_SET_TYPE_OPCODE(payload, 302 MCI_GPM_COEX_AGENT, MCI_GPM_COEX_HALT_BT_GPM); 303 if (halt == AH_TRUE) { 304 ahp->ah_mci_query_bt = AH_TRUE; 305 /* Send next UNHALT no matter HALT sent or not */ 306 ahp->ah_mci_unhalt_bt_gpm = AH_TRUE; 307 ahp->ah_mci_need_flush_btinfo = AH_TRUE; 308 *(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) = 309 MCI_GPM_COEX_BT_GPM_HALT; 310 } 311 else { 312 *(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) = 313 MCI_GPM_COEX_BT_GPM_UNHALT; 314 } 315 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, wait_done, AH_TRUE); 316 } 317 318 static HAL_BOOL ar9300_mci_send_coex_bt_flags(struct ath_hal *ah, HAL_BOOL wait_done, 319 u_int8_t opcode, u_int32_t bt_flags) 320 { 321 // struct ath_hal_9300 *ahp = AH9300(ah); 322 u_int32_t pld[4] = {0, 0, 0, 0}; 323 324 MCI_GPM_SET_TYPE_OPCODE(pld, 325 MCI_GPM_COEX_AGENT, MCI_GPM_COEX_BT_UPDATE_FLAGS); 326 327 *(((u_int8_t *)pld) + MCI_GPM_COEX_B_BT_FLAGS_OP) = opcode; 328 *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 0) = bt_flags & 0xFF; 329 *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 1) = 330 (bt_flags >> 8) & 0xFF; 331 *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 2) = 332 (bt_flags >> 16) & 0xFF; 333 *(((u_int8_t *)pld) + MCI_GPM_COEX_W_BT_FLAGS + 3) = 334 (bt_flags >> 24) & 0xFF; 335 336 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 337 "(MCI) BT_MCI_FLAGS: Send Coex BT Update Flags %s 0x%08x\n", 338 (opcode == MCI_GPM_COEX_BT_FLAGS_READ)?"READ": 339 ((opcode == MCI_GPM_COEX_BT_FLAGS_SET)?"SET":"CLEAR"), 340 bt_flags); 341 342 return ar9300_mci_send_message(ah, MCI_GPM, 0, pld, 16, wait_done, AH_TRUE); 343 } 344 345 void ar9300_mci_2g5g_changed(struct ath_hal *ah, HAL_BOOL is_2g) 346 { 347 struct ath_hal_9300 *ahp = AH9300(ah); 348 349 if (ahp->ah_mci_coex_2g5g_update == AH_FALSE) { 350 if (ahp->ah_mci_coex_is_2g == is_2g) { 351 //HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: not changed\n"); 352 } else { 353 ahp->ah_mci_coex_2g5g_update = AH_TRUE; 354 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: changed\n"); 355 } 356 } else { 357 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT_MCI_FLAGS: force send\n"); 358 } 359 ahp->ah_mci_coex_is_2g = is_2g; 360 } 361 362 static void ar9300_mci_send_2g5g_status(struct ath_hal *ah, HAL_BOOL wait_done) 363 { 364 struct ath_hal_9300 *ahp = AH9300(ah); 365 u_int32_t new_flags, to_set, to_clear; 366 367 if ((AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) && 368 (ahp->ah_mci_coex_2g5g_update == AH_TRUE) && 369 (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) 370 { 371 if (ahp->ah_mci_coex_is_2g) { 372 new_flags = HAL_MCI_2G_FLAGS; 373 to_clear = HAL_MCI_2G_FLAGS_CLEAR_MASK; 374 to_set = HAL_MCI_2G_FLAGS_SET_MASK; 375 } else { 376 new_flags = HAL_MCI_5G_FLAGS; 377 to_clear = HAL_MCI_5G_FLAGS_CLEAR_MASK; 378 to_set = HAL_MCI_5G_FLAGS_SET_MASK; 379 } 380 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 381 "(MCI) BT_MCI_FLAGS: %s (0x%08x) clr=0x%08x, set=0x%08x\n", 382 ahp->ah_mci_coex_is_2g?"2G":"5G", new_flags, to_clear, to_set); 383 if (to_clear) { 384 ar9300_mci_send_coex_bt_flags(ah, wait_done, 385 MCI_GPM_COEX_BT_FLAGS_CLEAR, to_clear); 386 } 387 if (to_set) { 388 ar9300_mci_send_coex_bt_flags(ah, wait_done, 389 MCI_GPM_COEX_BT_FLAGS_SET, to_set); 390 } 391 } 392 if (AR_SREV_JUPITER_10(ah) && (ahp->ah_mci_bt_state != MCI_BT_SLEEP)) { 393 ahp->ah_mci_coex_2g5g_update = AH_FALSE; 394 } 395 } 396 397 void ar9300_mci_2g5g_switch(struct ath_hal *ah, HAL_BOOL wait_done) 398 { 399 struct ath_hal_9300 *ahp = AH9300(ah); 400 401 if (ahp->ah_mci_coex_2g5g_update) 402 { 403 if (ahp->ah_mci_coex_is_2g) { 404 ar9300_mci_send_2g5g_status(ah, AH_TRUE); 405 406 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA trans\n"); 407 ar9300_mci_send_lna_transfer(ah, AH_TRUE); 408 OS_DELAY(5); 409 410 OS_REG_CLR_BIT(ah, AR_MCI_TX_CTRL, 411 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 412 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 413 OS_REG_CLR_BIT(ah, AR_GLB_CONTROL, 414 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); 415 if (!(ah->ah_config.ath_hal_mci_config & 416 ATH_MCI_CONFIG_DISABLE_OSLA)) 417 { 418 ar9300_mci_osla_setup(ah, AH_TRUE); 419 } 420 } 421 } else { 422 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA take\n"); 423 ar9300_mci_send_lna_take(ah, AH_TRUE); 424 OS_DELAY(5); 425 426 OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL, 427 AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 428 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 429 OS_REG_SET_BIT(ah, AR_GLB_CONTROL, 430 AR_BTCOEX_CTRL_BT_OWN_SPDT_CTRL); 431 ar9300_mci_osla_setup(ah, AH_FALSE); 432 } 433 434 ar9300_mci_send_2g5g_status(ah, AH_TRUE); 435 } 436 } 437 438 /* 439 * Update self gen chain mask. Also set basic set for 440 * txbf. 441 */ 442 if (AR_SREV_JUPITER(ah)) { 443 if (ahp->ah_mci_coex_is_2g) { 444 ahp->ah_reduced_self_gen_mask = AH_TRUE; 445 OS_REG_WRITE(ah, AR_SELFGEN_MASK, 0x02); 446 ar9300_txbf_set_basic_set(ah); 447 } 448 else { 449 ahp->ah_reduced_self_gen_mask = AH_FALSE; 450 ar9300_txbf_set_basic_set(ah); 451 } 452 } 453 } 454 455 void ar9300_mci_mute_bt(struct ath_hal *ah) 456 { 457 458 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__); 459 460 /* disable all MCI messages */ 461 OS_REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 0xFFFF0000); 462 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, 0xFFFFFFFF); 463 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, 0xFFFFFFFF); 464 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, 0xFFFFFFFF); 465 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, 0xFFFFFFFF); 466 OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 467 /* wait pending HW messages to flush out */ 468 OS_DELAY(10); 469 470 /* 471 * Send LNA_TAKE and SYS_SLEEPING when 472 * 1. reset not after resuming from full sleep 473 * 2. before reset MCI RX, to quiet BT and avoid MCI RX misalignment 474 */ 475 if (MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config)) { 476 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send LNA take\n"); 477 ar9300_mci_send_lna_take(ah, AH_TRUE); 478 OS_DELAY(5); 479 } 480 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Send sys sleeping\n"); 481 ar9300_mci_send_sys_sleeping(ah, AH_TRUE); 482 } 483 484 static void ar9300_mci_observation_set_up(struct ath_hal *ah) 485 { 486 /* 487 * Set up the observation bus in order to monitor MCI bus 488 * through GPIOs (0, 1, 2, and 3). 489 */ 490 /* 491 OS_REG_WRITE(ah, AR_GPIO_INTR_POL, 0x00420000); 492 OS_REG_WRITE(ah, AR_GPIO_OE_OUT, 0x000000ff); // 4050 493 OS_REG_WRITE(ah, AR_GPIO_OUTPUT_MUX1, 0x000bdab4); // 4068 494 OS_REG_WRITE(ah, AR_OBS, 0x0000004b); // 4088 495 OS_REG_WRITE(ah, AR_DIAG_SW, 0x080c0000); 496 OS_REG_WRITE(ah, AR_MACMISC, 0x0001a000); 497 OS_REG_WRITE(ah, AR_PHY_TEST, 0x00080000); // a360 498 OS_REG_WRITE(ah, AR_PHY_TEST_CTL_STATUS, 0xe0000000); // a364 499 */ 500 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called; config=0x%08x\n", 501 __func__, ah->ah_config.ath_hal_mci_config); 502 503 if (ah->ah_config.ath_hal_mci_config & 504 ATH_MCI_CONFIG_MCI_OBS_MCI) 505 { 506 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: CONFIG_MCI_OBS_MCI\n", __func__); 507 ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_DATA); 508 ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_MCI_WLAN_CLK); 509 ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA); 510 ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK); 511 } 512 else if (ah->ah_config.ath_hal_mci_config & 513 ATH_MCI_CONFIG_MCI_OBS_TXRX) 514 { 515 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: CONFIG_MCI_OBS_TXRX\n", __func__); 516 ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_TX); 517 ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_WL_IN_RX); 518 ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX); 519 ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX); 520 ar9300_gpio_cfg_output(ah, 5, HAL_GPIO_OUTPUT_MUX_AS_OUTPUT); 521 } 522 else if (ah->ah_config.ath_hal_mci_config & 523 ATH_MCI_CONFIG_MCI_OBS_BT) 524 { 525 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: CONFIG_MCI_OBS_BT\n", __func__); 526 ar9300_gpio_cfg_output(ah, 3, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_TX); 527 ar9300_gpio_cfg_output(ah, 2, HAL_GPIO_OUTPUT_MUX_AS_BT_IN_RX); 528 ar9300_gpio_cfg_output(ah, 1, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_DATA); 529 ar9300_gpio_cfg_output(ah, 0, HAL_GPIO_OUTPUT_MUX_AS_MCI_BT_CLK); 530 } 531 else { 532 return; 533 } 534 535 OS_REG_SET_BIT(ah, 536 AR_HOSTIF_REG(ah, AR_GPIO_INPUT_EN_VAL), AR_GPIO_JTAG_DISABLE); 537 538 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 539 OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, AR_GLB_DS_JTAG_DISABLE, 1); 540 OS_REG_RMW_FIELD(ah, AR_GLB_CONTROL, AR_GLB_WLAN_UART_INTF_EN, 0); 541 OS_REG_WRITE(ah, AR_GLB_GPIO_CONTROL, 542 (OS_REG_READ(ah, AR_GLB_GPIO_CONTROL) | 543 ATH_MCI_CONFIG_MCI_OBS_GPIO)); 544 } 545 546 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_GPIO_OBS_SEL, 0); 547 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_MAC_BB_OBS_SEL, 1); 548 OS_REG_WRITE(ah, AR_HOSTIF_REG(ah, AR_OBS), 0x4b); 549 OS_REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL1, 0x03); 550 OS_REG_RMW_FIELD(ah, AR_DIAG_SW, AR_DIAG_OBS_PT_SEL2, 0x01); 551 OS_REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_LSB, 0x02); 552 OS_REG_RMW_FIELD(ah, AR_MACMISC, AR_MACMISC_MISC_OBS_BUS_MSB, 0x03); 553 //OS_REG_RMW_FIELD(ah, AR_PHY_TEST, AR_PHY_TEST_BBB_OBS_SEL, 0x01); 554 OS_REG_RMW_FIELD(ah, AR_PHY_TEST_CTL_STATUS, 555 AR_PHY_TEST_CTL_DEBUGPORT_SEL, 0x07); 556 } 557 558 static void ar9300_mci_process_gpm_extra(struct ath_hal *ah, 559 u_int8_t gpm_type, u_int8_t gpm_opcode, u_int32_t *p_gpm) 560 { 561 struct ath_hal_9300 *ahp = AH9300(ah); 562 u_int8_t *p_data = (u_int8_t *) p_gpm; 563 564 switch (gpm_type) 565 { 566 case MCI_GPM_COEX_AGENT: 567 switch (gpm_opcode) 568 { 569 case MCI_GPM_COEX_VERSION_QUERY: 570 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 571 "(MCI) Recv GPM COEX Version Query.\n"); 572 ar9300_mci_send_coex_version_response(ah, AH_TRUE); 573 break; 574 575 case MCI_GPM_COEX_VERSION_RESPONSE: 576 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 577 "(MCI) Recv GPM COEX Version Response.\n"); 578 ahp->ah_mci_coex_major_version_bt = 579 *(p_data + MCI_GPM_COEX_B_MAJOR_VERSION); 580 ahp->ah_mci_coex_minor_version_bt = 581 *(p_data + MCI_GPM_COEX_B_MINOR_VERSION); 582 ahp->ah_mci_coex_bt_version_known = AH_TRUE; 583 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 584 "(MCI) BT Coex version: %d.%d\n", 585 ahp->ah_mci_coex_major_version_bt, 586 ahp->ah_mci_coex_minor_version_bt); 587 break; 588 589 case MCI_GPM_COEX_STATUS_QUERY: 590 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 591 "(MCI) Recv GPM COEX Status Query = 0x%02X.\n", 592 *(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)); 593 //if ((*(p_data + MCI_GPM_COEX_B_WLAN_BITMAP)) & 594 // MCI_GPM_COEX_QUERY_WLAN_ALL_INFO) 595 { 596 ahp->ah_mci_coex_wlan_channels_update = AH_TRUE; 597 ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE); 598 } 599 break; 600 601 case MCI_GPM_COEX_BT_PROFILE_INFO: 602 ahp->ah_mci_query_bt = AH_TRUE; 603 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 604 "(MCI) Recv GPM COEX BT_Profile_Info (drop&query)\n"); 605 break; 606 607 case MCI_GPM_COEX_BT_STATUS_UPDATE: 608 ahp->ah_mci_query_bt = AH_TRUE; 609 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 610 "(MCI) Recv GPM COEX BT_Status_Update " 611 "SEQ=%d (drop&query)\n", 612 *(p_gpm + 3)); 613 break; 614 615 default: 616 break; 617 } 618 default: 619 break; 620 } 621 } 622 623 u_int32_t ar9300_mci_wait_for_gpm(struct ath_hal *ah, u_int8_t gpm_type, 624 u_int8_t gpm_opcode, int32_t time_out) 625 { 626 u_int32_t *p_gpm = NULL, mismatch = 0, more_data = HAL_MCI_GPM_NOMORE; 627 struct ath_hal_9300 *ahp = AH9300(ah); 628 HAL_BOOL b_is_bt_cal_done = (gpm_type == MCI_GPM_BT_CAL_DONE); 629 u_int32_t offset; 630 u_int8_t recv_type = 0, recv_opcode = 0; 631 632 if (time_out == 0) { 633 more_data = HAL_MCI_GPM_MORE; 634 } 635 636 while (time_out > 0) 637 { 638 if (p_gpm != NULL) { 639 MCI_GPM_RECYCLE(p_gpm); 640 p_gpm = NULL; 641 } 642 643 if (more_data != HAL_MCI_GPM_MORE) { 644 time_out = ar9300_mci_wait_for_interrupt(ah, 645 AR_MCI_INTERRUPT_RX_MSG_RAW, 646 AR_MCI_INTERRUPT_RX_MSG_GPM, 647 time_out); 648 } 649 650 if (time_out) { 651 offset = ar9300_mci_state(ah, 652 HAL_MCI_STATE_NEXT_GPM_OFFSET, &more_data); 653 654 if (offset == HAL_MCI_GPM_INVALID) { 655 continue; 656 } 657 p_gpm = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset); 658 ar9300_mci_print_msg(ah, AH_FALSE, MCI_GPM, 16, p_gpm); 659 660 recv_type = MCI_GPM_TYPE(p_gpm); 661 recv_opcode = MCI_GPM_OPCODE(p_gpm); 662 663 if (MCI_GPM_IS_CAL_TYPE(recv_type)) { 664 if (recv_type == gpm_type) { 665 if ((gpm_type == MCI_GPM_BT_CAL_DONE) && !b_is_bt_cal_done) 666 { 667 gpm_type = MCI_GPM_BT_CAL_GRANT; 668 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 669 "(MCI) Rcv BT_CAL_DONE. Now Wait BT_CAL_GRANT\n"); 670 continue; 671 } 672 if (gpm_type == MCI_GPM_BT_CAL_GRANT) { 673 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 674 "(MCI) BT_CAL_GRANT seq=%d, req_count=%d\n", 675 *(p_gpm + 2), *(p_gpm + 3)); 676 } 677 break; 678 } 679 } 680 else { 681 if ((recv_type == gpm_type) && (recv_opcode == gpm_opcode)) { 682 break; 683 } 684 } 685 686 /* not expected message */ 687 688 /* 689 * Check if it's cal_grant 690 * 691 * When we're waiting for cal_grant in reset routine, it's 692 * possible that BT sends out cal_request at the same time. 693 * Since BT's calibration doesn't happen that often, we'll 694 * let BT completes calibration then we continue to wait 695 * for cal_grant from BT. 696 * Orginal: Wait BT_CAL_GRANT. 697 * New: Receive BT_CAL_REQ -> send WLAN_CAL_GRANT -> wait 698 * BT_CAL_DONE -> Wait BT_CAL_GRANT. 699 */ 700 if ((gpm_type == MCI_GPM_BT_CAL_GRANT) && 701 (recv_type == MCI_GPM_BT_CAL_REQ)) 702 { 703 u_int32_t payload[4] = {0, 0, 0, 0}; 704 705 gpm_type = MCI_GPM_BT_CAL_DONE; 706 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 707 "(MCI) Rcv BT_CAL_REQ. Send WLAN_CAL_GRANT.\n"); 708 709 MCI_GPM_SET_CAL_TYPE(payload, MCI_GPM_WLAN_CAL_GRANT); 710 ar9300_mci_send_message(ah, MCI_GPM, 0, payload, 16, 711 AH_FALSE, AH_FALSE); 712 713 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 714 "(MCI) Now wait for BT_CAL_DONE.\n"); 715 continue; 716 } 717 else { 718 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 719 "(MCI) GPM subtype not match 0x%x\n", *(p_gpm + 1)); 720 mismatch++; 721 ar9300_mci_process_gpm_extra(ah, recv_type, recv_opcode, p_gpm); 722 } 723 } 724 } 725 if (p_gpm != NULL) { 726 MCI_GPM_RECYCLE(p_gpm); 727 p_gpm = NULL; 728 } 729 730 if (time_out <= 0) { 731 time_out = 0; 732 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 733 "(MCI) GPM receiving timeout, mismatch = %d\n", mismatch); 734 } else { 735 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 736 "(MCI) Receive GPM type=0x%x, code=0x%x\n", gpm_type, gpm_opcode); 737 } 738 739 while (more_data == HAL_MCI_GPM_MORE) { 740 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) discard remaining GPM\n"); 741 offset = ar9300_mci_state(ah, 742 HAL_MCI_STATE_NEXT_GPM_OFFSET, &more_data); 743 744 if (offset == HAL_MCI_GPM_INVALID) { 745 break; 746 } 747 p_gpm = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset); 748 ar9300_mci_print_msg(ah, AH_FALSE, MCI_GPM, 16, p_gpm); 749 recv_type = MCI_GPM_TYPE(p_gpm); 750 recv_opcode = MCI_GPM_OPCODE(p_gpm); 751 if (!MCI_GPM_IS_CAL_TYPE(recv_type)) { 752 ar9300_mci_process_gpm_extra(ah, recv_type, recv_opcode, p_gpm); 753 } 754 MCI_GPM_RECYCLE(p_gpm); 755 } 756 757 return time_out; 758 } 759 760 static void ar9300_mci_prep_interface(struct ath_hal *ah) 761 { 762 struct ath_hal_9300 *ahp = AH9300(ah); 763 u_int32_t saved_mci_int_en; 764 u_int32_t mci_timeout = 150; 765 766 ahp->ah_mci_bt_state = MCI_BT_SLEEP; 767 768 saved_mci_int_en = OS_REG_READ(ah, AR_MCI_INTERRUPT_EN); 769 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); 770 771 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 772 OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW)); 773 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, 774 OS_REG_READ(ah, AR_MCI_INTERRUPT_RAW)); 775 776 /* Remote Reset */ 777 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Reset sequence start\n", __func__); 778 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) send REMOTE_RESET\n"); 779 ar9300_mci_remote_reset(ah, AH_TRUE); 780 781 /* 782 * This delay is required for the reset delay worst case value 255 in 783 * MCI_COMMAND2 register 784 */ 785 if (AR_SREV_JUPITER_10(ah)) { 786 OS_DELAY(252); 787 } 788 789 /* Send REQ_WAKE to BT */ 790 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send REQ_WAKE to remote(BT)\n", 791 __func__); 792 793 ar9300_mci_send_req_wake(ah, AH_TRUE); 794 795 if (ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 796 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING, 500)) 797 { 798 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 799 "(MCI) %s: Saw SYS_WAKING from remote(BT)\n", __func__); 800 ahp->ah_mci_bt_state = MCI_BT_AWAKE; 801 802 if (AR_SREV_JUPITER_10(ah)) { 803 OS_DELAY(10); 804 } 805 /* 806 * We don't need to send more remote_reset at this moment. 807 * 808 * If BT receive first remote_reset, then BT HW will be cleaned up and 809 * will be able to receive req_wake and BT HW will respond sys_waking. 810 * In this case, WLAN will receive BT's HW sys_waking. 811 * 812 * Otherwise, if BT SW missed initial remote_reset, that remote_reset 813 * will still clean up BT MCI RX, and the req_wake will wake BT up, 814 * and BT SW will respond this req_wake with a remote_reset and 815 * sys_waking. In this case, WLAN will receive BT's SW sys_waking. 816 * 817 * In either case, BT's RX is cleaned up. So we don't need to reply 818 * BT's remote_reset now, if any. 819 * 820 * Similarly, if in any case, WLAN can receive BT's sys_waking, that 821 * means WLAN's RX is also fine. 822 */ 823 824 /* Send SYS_WAKING to BT */ 825 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 826 "(MCI) %s: Send SW SYS_WAKING to remot(BT)\n", __func__); 827 ar9300_mci_send_sys_waking(ah, AH_TRUE); 828 829 OS_DELAY(10); 830 831 /* 832 * Set BT priority interrupt value to be 0xff to 833 * avoid having too many BT PRIORITY interrupts. 834 */ 835 836 OS_REG_WRITE(ah, AR_MCI_BT_PRI0, 0xFFFFFFFF); 837 OS_REG_WRITE(ah, AR_MCI_BT_PRI1, 0xFFFFFFFF); 838 OS_REG_WRITE(ah, AR_MCI_BT_PRI2, 0xFFFFFFFF); 839 OS_REG_WRITE(ah, AR_MCI_BT_PRI3, 0xFFFFFFFF); 840 OS_REG_WRITE(ah, AR_MCI_BT_PRI, 0X000000FF); 841 842 /* 843 * A contention reset will be received after send out sys_waking. 844 * Also BT priority interrupt bits will be set. Clear those bits 845 * before the next step. 846 */ 847 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 848 AR_MCI_INTERRUPT_RX_MSG_CONT_RST); 849 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, AR_MCI_INTERRUPT_BT_PRI); 850 851 if (AR_SREV_JUPITER_10(ah) || 852 (ahp->ah_mci_coex_is_2g && 853 MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config))) { 854 /* Send LNA_TRANS */ 855 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: Send LNA_TRANS to BT\n", 856 __func__); 857 ar9300_mci_send_lna_transfer(ah, AH_TRUE); 858 859 OS_DELAY(5); 860 } 861 862 if (AR_SREV_JUPITER_10(ah) || 863 (ahp->ah_mci_coex_is_2g && !ahp->ah_mci_coex_2g5g_update && 864 MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config))) { 865 if (ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 866 AR_MCI_INTERRUPT_RX_MSG_LNA_INFO, mci_timeout)) { 867 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 868 "(MCI) %s: WLAN has control over the LNA & BT obeys it\n", 869 __func__); 870 } else { 871 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 872 "(MCI) %s: BT did not respond to LNA_TRANS!\n", __func__); 873 //ahp->ah_mci_bt_state = MCI_BT_SLEEP; 874 } 875 } 876 877 if (AR_SREV_JUPITER_10(ah)) { 878 /* Send another remote_reset to deassert BT clk_req. */ 879 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 880 "(MCI) %s: Another remote_reset to deassert clk_req.\n", 881 __func__); 882 ar9300_mci_remote_reset(ah, AH_TRUE); 883 OS_DELAY(252); 884 } 885 } 886 887 /* Clear the extra redundant SYS_WAKING from BT */ 888 if ((ahp->ah_mci_bt_state == MCI_BT_AWAKE) && 889 (OS_REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 890 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING)) && 891 (OS_REG_READ_FIELD(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 892 AR_MCI_INTERRUPT_RX_MSG_SYS_SLEEPING) == 0)) 893 { 894 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 895 AR_MCI_INTERRUPT_RX_MSG_SYS_WAKING); 896 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, 897 AR_MCI_INTERRUPT_REMOTE_SLEEP_UPDATE); 898 } 899 900 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en); 901 } 902 903 void ar9300_mci_setup(struct ath_hal *ah, u_int32_t gpm_addr, 904 void *gpm_buf, u_int16_t len, 905 u_int32_t sched_addr) 906 { 907 struct ath_hal_9300 *ahp = AH9300(ah); 908 void *sched_buf = (void *)((char *) gpm_buf + (sched_addr - gpm_addr)); 909 910 ahp->ah_mci_gpm_addr = gpm_addr; 911 ahp->ah_mci_gpm_buf = gpm_buf; 912 ahp->ah_mci_gpm_len = len; 913 ahp->ah_mci_sched_addr = sched_addr; 914 ahp->ah_mci_sched_buf = sched_buf; 915 916 ar9300_mci_reset(ah, AH_TRUE, AH_TRUE, AH_TRUE); 917 } 918 919 void ar9300_mci_disable_interrupt(struct ath_hal *ah) 920 { 921 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); 922 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 0); 923 } 924 925 void ar9300_mci_enable_interrupt(struct ath_hal *ah) 926 { 927 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, AR_MCI_INTERRUPT_DEFAULT); 928 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_EN, 929 AR_MCI_INTERRUPT_RX_MSG_DEFAULT); 930 } 931 932 static void ar9300_mci_set_btcoex_ctrl_9565_1ANT(struct ath_hal *ah) 933 { 934 uint32_t regval; 935 936 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__); 937 regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) | 938 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) | 939 SM(1, AR_BTCOEX_CTRL_PA_SHARED) | 940 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) | 941 SM(1, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 942 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) | 943 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) | 944 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | 945 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); 946 947 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, 948 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x1); 949 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval); 950 } 951 952 static void ar9300_mci_set_btcoex_ctrl_9565_2ANT(struct ath_hal *ah) 953 { 954 uint32_t regval; 955 956 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__); 957 regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) | 958 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) | 959 SM(0, AR_BTCOEX_CTRL_PA_SHARED) | 960 SM(0, AR_BTCOEX_CTRL_LNA_SHARED) | 961 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 962 SM(1, AR_BTCOEX_CTRL_RX_CHAIN_MASK) | 963 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) | 964 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | 965 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); 966 967 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, 968 AR_BTCOEX_CTRL2_TX_CHAIN_MASK, 0x0); 969 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval); 970 } 971 972 static void ar9300_mci_set_btcoex_ctrl_9462(struct ath_hal *ah) 973 { 974 uint32_t regval; 975 976 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: called\n", __func__); 977 regval = SM(1, AR_BTCOEX_CTRL_JUPITER_MODE) | 978 SM(1, AR_BTCOEX_CTRL_WBTIMER_EN) | 979 SM(1, AR_BTCOEX_CTRL_PA_SHARED) | 980 SM(1, AR_BTCOEX_CTRL_LNA_SHARED) | 981 SM(2, AR_BTCOEX_CTRL_NUM_ANTENNAS) | 982 SM(3, AR_BTCOEX_CTRL_RX_CHAIN_MASK) | 983 SM(0, AR_BTCOEX_CTRL_1_CHAIN_ACK) | 984 SM(0, AR_BTCOEX_CTRL_1_CHAIN_BCN) | 985 SM(0, AR_BTCOEX_CTRL_ONE_STEP_LOOK_AHEAD_EN); 986 987 if (AR_SREV_JUPITER_10(ah)) { 988 regval |= SM(1, AR_BTCOEX_CTRL_SPDT_ENABLE_10); 989 } 990 991 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, regval); 992 } 993 994 void ar9300_mci_reset(struct ath_hal *ah, HAL_BOOL en_int, HAL_BOOL is_2g, 995 HAL_BOOL is_full_sleep) 996 { 997 struct ath_hal_9300 *ahp = AH9300(ah); 998 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 999 u_int32_t regval; 1000 1001 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: full_sleep = %d, is_2g = %d\n", 1002 __func__, is_full_sleep, is_2g); 1003 1004 if (!ahp->ah_mci_gpm_addr && !ahp->ah_mci_sched_addr) { 1005 /* GPM buffer and scheduling message buffer are not allocated */ 1006 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1007 "(MCI) GPM and SCHEDULE buffers not allocated\n"); 1008 return; 1009 } 1010 1011 if (OS_REG_READ(ah, AR_BTCOEX_CTRL) == 0xdeadbeef) { 1012 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1013 "(MCI) %s: ### It's deadbeef, quit mcireset()\n", __func__); 1014 return; 1015 } 1016 1017 /* Program MCI DMA related registers */ 1018 OS_REG_WRITE(ah, AR_MCI_GPM_0, ahp->ah_mci_gpm_addr); 1019 OS_REG_WRITE(ah, AR_MCI_GPM_1, ahp->ah_mci_gpm_len); 1020 OS_REG_WRITE(ah, AR_MCI_SCHD_TABLE_0, ahp->ah_mci_sched_addr); 1021 1022 /* 1023 * To avoid MCI state machine be affected by incoming remote MCI messages, 1024 * MCI mode will be enabled later, right before reset the MCI TX and RX. 1025 */ 1026 if (AR_SREV_APHRODITE(ah)) { 1027 uint8_t ant = MS(ah->ah_config.ath_hal_mci_config, 1028 ATH_MCI_CONFIG_ANT_ARCH); 1029 if (ant == ATH_MCI_ANT_ARCH_1_ANT_PA_LNA_SHARED) 1030 ar9300_mci_set_btcoex_ctrl_9565_1ANT(ah); 1031 else 1032 ar9300_mci_set_btcoex_ctrl_9565_2ANT(ah); 1033 } else { 1034 ar9300_mci_set_btcoex_ctrl_9462(ah); 1035 } 1036 1037 1038 if (is_2g && (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) && 1039 !(ah->ah_config.ath_hal_mci_config & 1040 ATH_MCI_CONFIG_DISABLE_OSLA)) 1041 { 1042 ar9300_mci_osla_setup(ah, AH_TRUE); 1043 } 1044 else { 1045 ar9300_mci_osla_setup(ah, AH_FALSE); 1046 } 1047 1048 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 1049 OS_REG_SET_BIT(ah, AR_GLB_CONTROL, AR_BTCOEX_CTRL_SPDT_ENABLE); 1050 1051 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL3, 1052 AR_BTCOEX_CTRL3_CONT_INFO_TIMEOUT, 20); 1053 } 1054 1055 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, AR_BTCOEX_CTRL2_RX_DEWEIGHT, 0); 1056 1057 OS_REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); 1058 1059 /* Set the time out to 3.125ms (5 BT slots) */ 1060 OS_REG_RMW_FIELD(ah, AR_BTCOEX_WL_LNA, AR_BTCOEX_WL_LNA_TIMEOUT, 0x3D090); 1061 1062 if (ah->ah_config.ath_hal_mci_config & ATH_MCI_CONFIG_CONCUR_TX) { 1063 u_int8_t i; 1064 u_int32_t const *pmax_tx_pwr; 1065 1066 if ((ah->ah_config.ath_hal_mci_config & 1067 ATH_MCI_CONFIG_CONCUR_TX) == ATH_MCI_CONCUR_TX_SHARED_CHN) 1068 { 1069 ahp->ah_mci_concur_tx_en = (ahp->ah_bt_coex_flag & 1070 HAL_BT_COEX_FLAG_MCI_MAX_TX_PWR) ? AH_TRUE : AH_FALSE; 1071 1072 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) concur_tx_en = %d\n", 1073 ahp->ah_mci_concur_tx_en); 1074 /* 1075 * We're not relying on HW to reduce WLAN tx power. 1076 * Set the max tx power table to 0x7f for all. 1077 */ 1078 #if 0 1079 if (AH_PRIVATE(ah)->ah_curchan) { 1080 chan_flags = AH_PRIVATE(ah)->ah_curchan->channel_flags; 1081 } 1082 if (chan_flags == CHANNEL_G_HT20) { 1083 pmax_tx_pwr = &mci_concur_tx_max_pwr[2][0]; 1084 } 1085 else if (chan_flags == CHANNEL_G) { 1086 pmax_tx_pwr = &mci_concur_tx_max_pwr[1][0]; 1087 } 1088 else if ((chan_flags == CHANNEL_G_HT40PLUS) || 1089 (chan_flags == CHANNEL_G_HT40MINUS)) 1090 { 1091 pmax_tx_pwr = &mci_concur_tx_max_pwr[3][0]; 1092 } 1093 else { 1094 pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0]; 1095 } 1096 1097 if (ahp->ah_mci_concur_tx_en) { 1098 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1099 "(MCI) chan flags = 0x%x, max_tx_pwr = %d dBm\n", 1100 chan_flags, 1101 (MS(pmax_tx_pwr[2], 1102 ATH_MCI_CONCUR_TX_LOWEST_PWR_MASK) >> 1)); 1103 } 1104 #else 1105 pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0]; 1106 #endif 1107 } 1108 else if ((ah->ah_config.ath_hal_mci_config & 1109 ATH_MCI_CONFIG_CONCUR_TX) == ATH_MCI_CONCUR_TX_UNSHARED_CHN) 1110 { 1111 pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0]; 1112 ahp->ah_mci_concur_tx_en = AH_TRUE; 1113 } 1114 else { 1115 pmax_tx_pwr = &mci_concur_tx_max_pwr[0][0]; 1116 ahp->ah_mci_concur_tx_en = AH_TRUE; 1117 } 1118 1119 /* Default is using rate based TPC. */ 1120 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, 1121 AR_BTCOEX_CTRL2_DESC_BASED_TXPWR_ENABLE, 0); 1122 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL2, 1123 AR_BTCOEX_CTRL2_TXPWR_THRESH, 0x7f); 1124 OS_REG_RMW_FIELD(ah, AR_BTCOEX_CTRL, 1125 AR_BTCOEX_CTRL_REDUCE_TXPWR, 0); 1126 for (i = 0; i < 8; i++) { 1127 OS_REG_WRITE(ah, AR_BTCOEX_MAX_TXPWR(i), pmax_tx_pwr[i]); 1128 } 1129 } 1130 1131 regval = MS(ah->ah_config.ath_hal_mci_config, 1132 ATH_MCI_CONFIG_CLK_DIV); 1133 OS_REG_RMW_FIELD(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_CLK_DIV, regval); 1134 1135 OS_REG_SET_BIT(ah, AR_BTCOEX_CTRL, AR_BTCOEX_CTRL_MCI_MODE_EN); 1136 1137 /* Resetting the Rx and Tx paths of MCI */ 1138 regval = OS_REG_READ(ah, AR_MCI_COMMAND2); 1139 regval |= SM(1, AR_MCI_COMMAND2_RESET_TX); 1140 OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval); 1141 OS_DELAY(1); 1142 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_TX); 1143 OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval); 1144 1145 if (is_full_sleep) { 1146 ar9300_mci_mute_bt(ah); 1147 OS_DELAY(100); 1148 } 1149 1150 regval |= SM(1, AR_MCI_COMMAND2_RESET_RX); 1151 OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval); 1152 OS_DELAY(1); 1153 regval &= ~SM(1, AR_MCI_COMMAND2_RESET_RX); 1154 OS_REG_WRITE(ah, AR_MCI_COMMAND2, regval); 1155 1156 ar9300_mci_state(ah, HAL_MCI_STATE_INIT_GPM_OFFSET, NULL); 1157 OS_REG_WRITE(ah, AR_MCI_MSG_ATTRIBUTES_TABLE, 1158 (SM(0xe801, AR_MCI_MSG_ATTRIBUTES_TABLE_INVALID_HDR) | 1159 SM(0x0000, AR_MCI_MSG_ATTRIBUTES_TABLE_CHECKSUM))); 1160 if (MCI_ANT_ARCH_PA_LNA_SHARED(ah->ah_config.ath_hal_mci_config)) { 1161 OS_REG_CLR_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 1162 } else { 1163 OS_REG_SET_BIT(ah, AR_MCI_TX_CTRL, AR_MCI_TX_CTRL_DISABLE_LNA_UPDATE); 1164 } 1165 1166 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 1167 ar9300_mci_observation_set_up(ah); 1168 } 1169 1170 ahp->ah_mci_ready = AH_TRUE; 1171 ar9300_mci_prep_interface(ah); 1172 1173 if (en_int) { 1174 ar9300_mci_enable_interrupt(ah); 1175 } 1176 1177 #if ATH_SUPPORT_AIC 1178 if (ahp->ah_aic_enabled) { 1179 ar9300_aic_start_normal(ah); 1180 } 1181 #endif 1182 } 1183 1184 static void ar9300_mci_queue_unsent_gpm(struct ath_hal *ah, u_int8_t header, 1185 u_int32_t *payload, HAL_BOOL queue) 1186 { 1187 struct ath_hal_9300 *ahp = AH9300(ah); 1188 u_int8_t type, opcode; 1189 1190 if (queue == AH_TRUE) { 1191 if (payload != NULL) { 1192 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1193 "(MCI) ERROR: Send fail: %02x: %02x %02x %02x\n", 1194 header, 1195 *(((u_int8_t *)payload) + 4), 1196 *(((u_int8_t *)payload) + 5), 1197 *(((u_int8_t *)payload) + 6)); 1198 } else { 1199 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1200 "(MCI) ERROR: Send fail: %02x\n", header); 1201 } 1202 } 1203 /* check if the message is to be queued */ 1204 if (header == MCI_GPM) { 1205 type = MCI_GPM_TYPE(payload); 1206 opcode = MCI_GPM_OPCODE(payload); 1207 1208 if (type == MCI_GPM_COEX_AGENT) { 1209 switch (opcode) 1210 { 1211 case MCI_GPM_COEX_BT_UPDATE_FLAGS: 1212 if (AR_SREV_JUPITER_10(ah)) { 1213 break; 1214 } 1215 if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_BT_FLAGS_OP) == 1216 MCI_GPM_COEX_BT_FLAGS_READ) 1217 { 1218 break; 1219 } 1220 ahp->ah_mci_coex_2g5g_update = queue; 1221 if (queue == AH_TRUE) { 1222 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1223 "(MCI) BT_MCI_FLAGS: 2G5G status <queued> %s.\n", 1224 ahp->ah_mci_coex_is_2g?"2G":"5G"); 1225 } 1226 else { 1227 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1228 "(MCI) BT_MCI_FLAGS: 2G5G status <sent> %s.\n", 1229 ahp->ah_mci_coex_is_2g?"2G":"5G"); 1230 } 1231 break; 1232 1233 case MCI_GPM_COEX_WLAN_CHANNELS: 1234 ahp->ah_mci_coex_wlan_channels_update = queue; 1235 if (queue == AH_TRUE) { 1236 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1237 "(MCI) WLAN channel map <queued>.\n"); 1238 } 1239 else { 1240 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1241 "(MCI) WLAN channel map <sent>.\n"); 1242 } 1243 break; 1244 1245 case MCI_GPM_COEX_HALT_BT_GPM: 1246 if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) == 1247 MCI_GPM_COEX_BT_GPM_UNHALT) 1248 { 1249 ahp->ah_mci_unhalt_bt_gpm = queue; 1250 if (queue == AH_TRUE) { 1251 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1252 "(MCI) UNHALT BT GPM <queued>.\n"); 1253 } 1254 else { 1255 ahp->ah_mci_halted_bt_gpm = AH_FALSE; 1256 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1257 "(MCI) UNHALT BT GPM <sent>.\n"); 1258 } 1259 } 1260 if (*(((u_int8_t *)payload) + MCI_GPM_COEX_B_HALT_STATE) == 1261 MCI_GPM_COEX_BT_GPM_HALT) 1262 { 1263 ahp->ah_mci_halted_bt_gpm = !queue; 1264 if (queue == AH_TRUE) { 1265 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1266 "(MCI) HALT BT GPM <not sent>.\n"); 1267 } 1268 else { 1269 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1270 "(MCI) HALT BT GPM <sent>.\n"); 1271 } 1272 } 1273 break; 1274 1275 default: 1276 break; 1277 } 1278 } 1279 } 1280 } 1281 1282 HAL_BOOL ar9300_mci_send_message(struct ath_hal *ah, u_int8_t header, 1283 u_int32_t flag, u_int32_t *payload, 1284 u_int8_t len, HAL_BOOL wait_done, HAL_BOOL check_bt) 1285 { 1286 int i; 1287 struct ath_hal_9300 *ahp = AH9300(ah); 1288 HAL_BOOL msg_sent = AH_FALSE; 1289 u_int32_t regval; 1290 u_int32_t saved_mci_int_en = OS_REG_READ(ah, AR_MCI_INTERRUPT_EN); 1291 1292 regval = OS_REG_READ(ah, AR_BTCOEX_CTRL); 1293 if ((regval == 0xdeadbeef) || !(regval & AR_BTCOEX_CTRL_MCI_MODE_EN)) { 1294 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1295 "(MCI) %s: Not send 0x%x. MCI is not enabled. full_sleep = %d\n", 1296 __func__, header, ahp->ah_chip_full_sleep); 1297 ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE); 1298 return AH_FALSE; 1299 } 1300 else if (check_bt && (ahp->ah_mci_bt_state == MCI_BT_SLEEP)) { 1301 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1302 "(MCI) %s: Don't send message(0x%x). BT is in sleep state\n", 1303 __func__, header); 1304 ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE); 1305 return AH_FALSE; 1306 } 1307 1308 if (wait_done) { 1309 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, 0); 1310 } 1311 1312 /* Need to clear SW_MSG_DONE raw bit before wait */ 1313 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RAW, 1314 AR_MCI_INTERRUPT_SW_MSG_DONE | AR_MCI_INTERRUPT_MSG_FAIL_MASK); 1315 1316 if (payload != AH_NULL) { 1317 for (i = 0; (i*4) < len; i++) { 1318 OS_REG_WRITE(ah, (AR_MCI_TX_PAYLOAD0 + i*4), *(payload + i)); 1319 } 1320 } 1321 ar9300_mci_print_msg(ah, AH_TRUE, header, len, payload); 1322 1323 OS_REG_WRITE(ah, AR_MCI_COMMAND0, 1324 (SM((flag & HAL_MCI_FLAG_DISABLE_TIMESTAMP), 1325 AR_MCI_COMMAND0_DISABLE_TIMESTAMP) | 1326 SM(len, AR_MCI_COMMAND0_LEN) | 1327 SM(header, AR_MCI_COMMAND0_HEADER))); 1328 1329 if (wait_done && 1330 ar9300_mci_wait_for_interrupt(ah, AR_MCI_INTERRUPT_RAW, 1331 AR_MCI_INTERRUPT_SW_MSG_DONE, 500) == 0) 1332 { 1333 ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_TRUE); 1334 } 1335 else { 1336 ar9300_mci_queue_unsent_gpm(ah, header, payload, AH_FALSE); 1337 msg_sent = AH_TRUE; 1338 } 1339 1340 if (wait_done) { 1341 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_EN, saved_mci_int_en); 1342 } 1343 1344 return msg_sent; 1345 } 1346 1347 u_int32_t ar9300_mci_get_interrupt(struct ath_hal *ah, u_int32_t *mci_int, 1348 u_int32_t *mci_int_rx_msg) 1349 { 1350 struct ath_hal_9300 *ahp = AH9300(ah); 1351 1352 *mci_int = ahp->ah_mci_int_raw; 1353 *mci_int_rx_msg = ahp->ah_mci_int_rx_msg; 1354 1355 /* Clean int bits after the values are read. */ 1356 ahp->ah_mci_int_raw = 0; 1357 ahp->ah_mci_int_rx_msg = 0; 1358 1359 return 0; 1360 } 1361 1362 u_int32_t ar9300_mci_check_int(struct ath_hal *ah, u_int32_t ints) 1363 { 1364 u_int32_t reg; 1365 1366 reg = OS_REG_READ(ah, AR_MCI_INTERRUPT_RX_MSG_RAW); 1367 return ((reg & ints) == ints); 1368 } 1369 1370 void ar9300_mci_sync_bt_state(struct ath_hal *ah) 1371 { 1372 struct ath_hal_9300 *ahp = AH9300(ah); 1373 u_int32_t cur_bt_state; 1374 1375 cur_bt_state = ar9300_mci_state(ah, HAL_MCI_STATE_REMOTE_SLEEP, NULL); 1376 if (ahp->ah_mci_bt_state != cur_bt_state) { 1377 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1378 "(MCI) %s: BT state mismatches. old: %d, new: %d\n", 1379 __func__, ahp->ah_mci_bt_state, cur_bt_state); 1380 ahp->ah_mci_bt_state = cur_bt_state; 1381 } 1382 if (ahp->ah_mci_bt_state != MCI_BT_SLEEP) { 1383 #if MCI_QUERY_BT_VERSION_VERBOSE 1384 ar9300_mci_send_coex_version_query(ah, AH_TRUE); 1385 #endif 1386 ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE); 1387 if (ahp->ah_mci_unhalt_bt_gpm == AH_TRUE) { 1388 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: UNHALT BT GPM\n", __func__); 1389 ar9300_mci_send_coex_halt_bt_gpm(ah, AH_FALSE, AH_TRUE); 1390 } 1391 } 1392 } 1393 1394 static HAL_BOOL ar9300_mci_is_gpm_valid(struct ath_hal *ah, u_int32_t msg_index) 1395 { 1396 struct ath_hal_9300 *ahp = AH9300(ah); 1397 u_int32_t *payload; 1398 u_int32_t recv_type, offset = msg_index << 4; 1399 1400 if (msg_index == HAL_MCI_GPM_INVALID) { 1401 return AH_FALSE; 1402 } 1403 1404 payload = (u_int32_t *) (ahp->ah_mci_gpm_buf + offset); 1405 recv_type = MCI_GPM_TYPE(payload); 1406 1407 if (recv_type == MCI_GPM_RSVD_PATTERN) { 1408 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) Skip RSVD GPM\n"); 1409 return AH_FALSE; 1410 } 1411 1412 return AH_TRUE; 1413 } 1414 1415 u_int32_t 1416 ar9300_mci_state(struct ath_hal *ah, u_int32_t state_type, u_int32_t *p_data) 1417 { 1418 u_int32_t value = 0, more_gpm = 0, gpm_ptr; 1419 struct ath_hal_9300 *ahp = AH9300(ah); 1420 1421 switch (state_type) { 1422 case HAL_MCI_STATE_ENABLE: 1423 if (AH_PRIVATE(ah)->ah_caps.halMciSupport && ahp->ah_mci_ready) { 1424 value = OS_REG_READ(ah, AR_BTCOEX_CTRL); 1425 if ((value == 0xdeadbeef) || (value == 0xffffffff)) { 1426 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1427 "(MCI) BTCOEX_CTRL = 0xdeadbeef\n"); 1428 value = 0; 1429 } 1430 } 1431 value &= AR_BTCOEX_CTRL_MCI_MODE_EN; 1432 break; 1433 1434 case HAL_MCI_STATE_INIT_GPM_OFFSET: 1435 value = MS(OS_REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); 1436 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1437 "(MCI) %s: GPM initial WRITE_PTR=%d.\n", __func__, value); 1438 ahp->ah_mci_gpm_idx = value; 1439 break; 1440 1441 case HAL_MCI_STATE_NEXT_GPM_OFFSET: 1442 case HAL_MCI_STATE_LAST_GPM_OFFSET: 1443 /* 1444 * This could be useful to avoid new GPM message interrupt which 1445 * may lead to spurious interrupt after power sleep, or multiple 1446 * entry of ath_coex_mci_intr(). 1447 * Adding empty GPM check by returning HAL_MCI_GPM_INVALID can 1448 * alleviate this effect, but clearing GPM RX interrupt bit is 1449 * safe, because whether this is called from HAL or LMAC, there 1450 * must be an interrupt bit set/triggered initially. 1451 */ 1452 OS_REG_WRITE(ah, AR_MCI_INTERRUPT_RX_MSG_RAW, 1453 AR_MCI_INTERRUPT_RX_MSG_GPM); 1454 1455 gpm_ptr = MS(OS_REG_READ(ah, AR_MCI_GPM_1), AR_MCI_GPM_WRITE_PTR); 1456 value = gpm_ptr; 1457 1458 if (value == 0) { 1459 value = ahp->ah_mci_gpm_len - 1; 1460 } 1461 else if (value >= ahp->ah_mci_gpm_len) { 1462 if (value != 0xFFFF) { 1463 value = 0; 1464 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1465 "(MCI) %s: GPM offset out of range.\n", __func__); 1466 } 1467 } 1468 else { 1469 value--; 1470 } 1471 1472 if (value == 0xFFFF) { 1473 value = HAL_MCI_GPM_INVALID; 1474 more_gpm = HAL_MCI_GPM_NOMORE; 1475 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1476 "(MCI) %s: GPM ptr invalid " 1477 "@ptr=%d, @offset=%d, more=NOMORE.\n", 1478 __func__, gpm_ptr, value); 1479 } 1480 else if (state_type == HAL_MCI_STATE_NEXT_GPM_OFFSET) { 1481 if (gpm_ptr == ahp->ah_mci_gpm_idx) { 1482 value = HAL_MCI_GPM_INVALID; 1483 more_gpm = HAL_MCI_GPM_NOMORE; 1484 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1485 "(MCI) %s: GPM message not available " 1486 "@ptr=%d, @offset=%d, more=NOMORE.\n", 1487 __func__, gpm_ptr, value); 1488 } 1489 else { 1490 while (1) { 1491 u_int32_t temp_index; 1492 1493 /* skip reserved GPM if any */ 1494 if (value != ahp->ah_mci_gpm_idx) { 1495 more_gpm = HAL_MCI_GPM_MORE; 1496 } 1497 else { 1498 more_gpm = HAL_MCI_GPM_NOMORE; 1499 } 1500 temp_index = ahp->ah_mci_gpm_idx; 1501 ahp->ah_mci_gpm_idx++; 1502 if (ahp->ah_mci_gpm_idx >= ahp->ah_mci_gpm_len) { 1503 ahp->ah_mci_gpm_idx = 0; 1504 } 1505 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1506 "(MCI) %s: GPM message got " 1507 "@ptr=%d, @offset=%d, more=%s.\n", 1508 __func__, gpm_ptr, temp_index, 1509 (more_gpm == HAL_MCI_GPM_MORE)?"MORE":"NOMORE"); 1510 if (ar9300_mci_is_gpm_valid(ah, temp_index)) { 1511 value = temp_index; 1512 break; 1513 } 1514 if (more_gpm == HAL_MCI_GPM_NOMORE) { 1515 value = HAL_MCI_GPM_INVALID; 1516 break; 1517 } 1518 } 1519 } 1520 if (p_data != NULL) { 1521 *p_data = more_gpm; 1522 } 1523 } 1524 if (value != HAL_MCI_GPM_INVALID) { 1525 value <<= 4; 1526 } 1527 break; 1528 1529 case HAL_MCI_STATE_LAST_SCHD_MSG_OFFSET: 1530 value = MS(OS_REG_READ(ah, AR_MCI_RX_STATUS), 1531 AR_MCI_RX_LAST_SCHD_MSG_INDEX); 1532 1533 #if AH_MCI_DEBUG_PRINT_SCHED 1534 { 1535 u_int32_t index = value; 1536 u_int32_t prev_index, sched_idx; 1537 u_int32_t *pld; 1538 u_int8_t *pld8; 1539 u_int32_t wbtimer = OS_REG_READ(ah, AR_BTCOEX_WBTIMER); 1540 u_int32_t schd_ctl = OS_REG_READ(ah, AR_MCI_HW_SCHD_TBL_CTL); 1541 1542 if (index > 0) { 1543 prev_index = index - 1; 1544 } else { 1545 prev_index = index; 1546 } 1547 1548 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) SCHED\n"); 1549 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1550 "(MCI) SCHED SCHD_TBL_CTRL=0x%08x, WBTIMER=0x%08x (%d)\n", 1551 schd_ctl, wbtimer, wbtimer); 1552 for (sched_idx = prev_index; sched_idx <= index; sched_idx++) { 1553 pld = (u_int32_t *) (ahp->ah_mci_sched_buf + (sched_idx << 4)); 1554 pld8 = (u_int8_t *) pld; 1555 1556 ar9300_mci_print_msg(ah, AH_FALSE, MCI_SCHD_INFO, 16, pld); 1557 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1558 "(MCI) SCHED idx=%d, T1=0x%08x (%d), T2=0x%08x (%d)\n", 1559 sched_idx, 1560 pld[0], pld[0], pld[1], pld[1]); 1561 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1562 "(MCI) SCHED addr=%d %s pwr=%d prio=%d %s link=%d\n", 1563 pld8[11] >> 4, 1564 (pld8[11] & 0x08)?"TX":"RX", 1565 (int8_t) (((pld8[11] & 0x07) << 5) | (pld8[10] >> 3)), 1566 (((pld8[10] & 0x07) << 5) | (pld8[9] >> 3)), 1567 (pld8[9] & 0x04)?"LE":"BR/EDR", 1568 (((pld8[9] & 0x03) << 2) | (pld8[8] >> 6))); 1569 } 1570 } 1571 #endif /* AH_MCI_DEBUG_PRINT_SCHED */ 1572 1573 /* Make it in bytes */ 1574 value <<= 4; 1575 break; 1576 1577 case HAL_MCI_STATE_REMOTE_SLEEP: 1578 value = MS(OS_REG_READ(ah, AR_MCI_RX_STATUS), 1579 AR_MCI_RX_REMOTE_SLEEP) ? MCI_BT_SLEEP : MCI_BT_AWAKE; 1580 break; 1581 1582 case HAL_MCI_STATE_CONT_RSSI_POWER: 1583 value = MS(ahp->ah_mci_cont_status, 1584 AR_MCI_CONT_RSSI_POWER); 1585 break; 1586 1587 case HAL_MCI_STATE_CONT_PRIORITY: 1588 value = MS(ahp->ah_mci_cont_status, 1589 AR_MCI_CONT_RRIORITY); 1590 break; 1591 1592 case HAL_MCI_STATE_CONT_TXRX: 1593 value = MS(ahp->ah_mci_cont_status, 1594 AR_MCI_CONT_TXRX); 1595 break; 1596 1597 case HAL_MCI_STATE_BT: 1598 value = ahp->ah_mci_bt_state; 1599 break; 1600 1601 case HAL_MCI_STATE_SET_BT_SLEEP: 1602 ahp->ah_mci_bt_state = MCI_BT_SLEEP; 1603 break; 1604 1605 case HAL_MCI_STATE_SET_BT_AWAKE: 1606 ahp->ah_mci_bt_state = MCI_BT_AWAKE; 1607 ar9300_mci_send_coex_version_query(ah, AH_TRUE); 1608 ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE); 1609 if (ahp->ah_mci_unhalt_bt_gpm == AH_TRUE) { 1610 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1611 "(MCI) %s: UNHALT BT GPM\n", __func__); 1612 ar9300_mci_send_coex_halt_bt_gpm(ah, AH_FALSE, AH_TRUE); 1613 } 1614 ar9300_mci_2g5g_switch(ah, AH_TRUE); 1615 break; 1616 1617 case HAL_MCI_STATE_SET_BT_CAL_START: 1618 ahp->ah_mci_bt_state = MCI_BT_CAL_START; 1619 break; 1620 1621 case HAL_MCI_STATE_SET_BT_CAL: 1622 ahp->ah_mci_bt_state = MCI_BT_CAL; 1623 break; 1624 1625 case HAL_MCI_STATE_RESET_REQ_WAKE: 1626 ar9300_mci_reset_req_wakeup(ah); 1627 ahp->ah_mci_coex_2g5g_update = AH_TRUE; 1628 1629 if ((AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) && 1630 (ah->ah_config.ath_hal_mci_config & 1631 ATH_MCI_CONFIG_MCI_OBS_MASK)) 1632 { 1633 /* Check if we still have control of the GPIOs */ 1634 if ((OS_REG_READ(ah, AR_GLB_GPIO_CONTROL) & 1635 ATH_MCI_CONFIG_MCI_OBS_GPIO) != 1636 ATH_MCI_CONFIG_MCI_OBS_GPIO) 1637 { 1638 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1639 "(MCI) Reconfigure observation\n"); 1640 ar9300_mci_observation_set_up(ah); 1641 } 1642 } 1643 1644 break; 1645 1646 case HAL_MCI_STATE_SEND_WLAN_COEX_VERSION: 1647 ar9300_mci_send_coex_version_response(ah, AH_TRUE); 1648 break; 1649 1650 case HAL_MCI_STATE_SET_BT_COEX_VERSION: 1651 if (p_data == NULL) { 1652 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1653 "(MCI) Error: Set BT Coex version with NULL data !!!\n"); 1654 } 1655 else { 1656 ahp->ah_mci_coex_major_version_bt = (*p_data >> 8) & 0xff; 1657 ahp->ah_mci_coex_minor_version_bt = (*p_data) & 0xff; 1658 ahp->ah_mci_coex_bt_version_known = AH_TRUE; 1659 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) BT version set: %d.%d\n", 1660 ahp->ah_mci_coex_major_version_bt, 1661 ahp->ah_mci_coex_minor_version_bt); 1662 } 1663 break; 1664 1665 case HAL_MCI_STATE_SEND_WLAN_CHANNELS: 1666 if (p_data != NULL) 1667 { 1668 if (((ahp->ah_mci_coex_wlan_channels[1] & 0xffff0000) == 1669 (*(p_data + 1) & 0xffff0000)) && 1670 (ahp->ah_mci_coex_wlan_channels[2] == *(p_data + 2)) && 1671 (ahp->ah_mci_coex_wlan_channels[3] == *(p_data + 3))) 1672 { 1673 break; 1674 } 1675 ahp->ah_mci_coex_wlan_channels[0] = *p_data++; 1676 ahp->ah_mci_coex_wlan_channels[1] = *p_data++; 1677 ahp->ah_mci_coex_wlan_channels[2] = *p_data++; 1678 ahp->ah_mci_coex_wlan_channels[3] = *p_data++; 1679 } 1680 ahp->ah_mci_coex_wlan_channels_update = AH_TRUE; 1681 ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE); 1682 break; 1683 1684 case HAL_MCI_STATE_SEND_VERSION_QUERY: 1685 ar9300_mci_send_coex_version_query(ah, AH_TRUE); 1686 break; 1687 1688 case HAL_MCI_STATE_SEND_STATUS_QUERY: 1689 if (AR_SREV_JUPITER_10(ah)) { 1690 ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE, 1691 MCI_GPM_COEX_QUERY_BT_ALL_INFO); 1692 } else { 1693 ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE, 1694 MCI_GPM_COEX_QUERY_BT_TOPOLOGY); 1695 } 1696 break; 1697 1698 case HAL_MCI_STATE_NEED_FLUSH_BT_INFO: 1699 /* 1700 * ah_mci_unhalt_bt_gpm means whether it's needed to send 1701 * UNHALT message. It's set whenever there's a request to send HALT 1702 * message. ah_mci_halted_bt_gpm means whether HALT message is sent 1703 * out successfully. 1704 * 1705 * Checking (ah_mci_unhalt_bt_gpm == AH_FALSE) instead of checking 1706 * (ahp->ah_mci_halted_bt_gpm == AH_FALSE) will make sure currently is 1707 * in UNHALT-ed mode and BT can respond to status query. 1708 */ 1709 if ((ahp->ah_mci_unhalt_bt_gpm == AH_FALSE) && 1710 (ahp->ah_mci_need_flush_btinfo == AH_TRUE)) 1711 { 1712 value = 1; 1713 } 1714 else { 1715 value = 0; 1716 } 1717 if (p_data != NULL) { 1718 ahp->ah_mci_need_flush_btinfo = (*p_data != 0)? AH_TRUE : AH_FALSE; 1719 } 1720 break; 1721 1722 case HAL_MCI_STATE_SET_CONCUR_TX_PRI: 1723 if (p_data) { 1724 ahp->ah_mci_stomp_none_tx_pri = *p_data & 0xff; 1725 ahp->ah_mci_stomp_low_tx_pri = (*p_data >> 8) & 0xff; 1726 ahp->ah_mci_stomp_all_tx_pri = (*p_data >> 16) & 0xff; 1727 } 1728 break; 1729 1730 case HAL_MCI_STATE_RECOVER_RX: 1731 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) hal RECOVER_RX\n"); 1732 ar9300_mci_prep_interface(ah); 1733 ahp->ah_mci_query_bt = AH_TRUE; 1734 ahp->ah_mci_need_flush_btinfo = AH_TRUE; 1735 ar9300_mci_send_coex_wlan_channels(ah, AH_TRUE); 1736 ar9300_mci_2g5g_switch(ah, AH_TRUE); 1737 break; 1738 1739 case HAL_MCI_STATE_DEBUG: 1740 if (p_data != NULL) { 1741 if (*p_data == HAL_MCI_STATE_DEBUG_REQ_BT_DEBUG) { 1742 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) QUERY_BT_DEBUG\n"); 1743 ar9300_mci_send_coex_bt_status_query(ah, AH_TRUE, 1744 MCI_GPM_COEX_QUERY_BT_DEBUG); 1745 OS_DELAY(10); 1746 if (AR_SREV_JUPITER_20_OR_LATER(ah) || AR_SREV_APHRODITE(ah)) { 1747 ar9300_mci_send_coex_bt_flags(ah, AH_TRUE, 1748 MCI_GPM_COEX_BT_FLAGS_READ, 0); 1749 } 1750 } 1751 } 1752 break; 1753 1754 case HAL_MCI_STATE_NEED_FTP_STOMP: 1755 value = (ah->ah_config.ath_hal_mci_config & 1756 ATH_MCI_CONFIG_DISABLE_FTP_STOMP) ? 0 : 1; 1757 break; 1758 1759 case HAL_MCI_STATE_NEED_TUNING: 1760 value = (ah->ah_config.ath_hal_mci_config & 1761 ATH_MCI_CONFIG_DISABLE_TUNING) ? 0 : 1; 1762 break; 1763 1764 case HAL_MCI_STATE_SHARED_CHAIN_CONCUR_TX: 1765 value = ((ah->ah_config.ath_hal_mci_config & 1766 ATH_MCI_CONFIG_CONCUR_TX) == 1767 ATH_MCI_CONCUR_TX_SHARED_CHN)? 1 : 0; 1768 break; 1769 1770 default: 1771 break; 1772 } 1773 return value; 1774 } 1775 1776 void ar9300_mci_detach(struct ath_hal *ah) 1777 { 1778 /* Turn off MCI and Jupiter mode. */ 1779 OS_REG_WRITE(ah, AR_BTCOEX_CTRL, 0x00); 1780 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) ar9300_mci_detach\n"); 1781 ar9300_mci_disable_interrupt(ah); 1782 } 1783 1784 /* 1785 * Low priority BT: 0 - 59(0x3b) 1786 * High priority BT: 60 - 125(0x7d) 1787 * Critical BT: 126 - 255 1788 1789 BTCOEX_WL_WEIGHTS0_VALUE0 ; // wl_idle 1790 BTCOEX_WL_WEIGHTS0_VALUE1 ; // sw_ctrl[3] - all_stomp 1791 BTCOEX_WL_WEIGHTS0_VALUE2 ; // sw_ctrl[2] - all_not_stomp 1792 BTCOEX_WL_WEIGHTS0_VALUE3 ; // sw_ctrl[1] - pa_pre_distortion 1793 BTCOEX_WL_WEIGHTS1_VALUE0 ; // sw_ctrl[0] - general purpose 1794 BTCOEX_WL_WEIGHTS1_VALUE1 ; // tm_wl_wait_beacon 1795 BTCOEX_WL_WEIGHTS1_VALUE2 ; // ts_state_wait_ack_cts 1796 BTCOEX_WL_WEIGHTS1_VALUE3 ; // self_gen 1797 BTCOEX_WL_WEIGHTS2_VALUE0 ; // idle 1798 BTCOEX_WL_WEIGHTS2_VALUE1 ; // rx 1799 BTCOEX_WL_WEIGHTS2_VALUE2 ; // tx 1800 BTCOEX_WL_WEIGHTS2_VALUE3 ; // rx + tx 1801 BTCOEX_WL_WEIGHTS3_VALUE0 ; // tx 1802 BTCOEX_WL_WEIGHTS3_VALUE1 ; // rx 1803 BTCOEX_WL_WEIGHTS3_VALUE2 ; // tx 1804 BTCOEX_WL_WEIGHTS3_VALUE3 ; // rx + tx 1805 1806 Stomp all: 1807 ah_bt_coex_wlan_weight[0] = 0x00007d00 1808 ah_bt_coex_wlan_weight[1] = 0x7d7d7d00 1809 ah_bt_coex_wlan_weight[2] = 0x7d7d7d00 1810 ah_bt_coex_wlan_weight[3] = 0x7d7d7d7d 1811 Stomp low: 1812 ah_bt_coex_wlan_weight[0] = 0x00007d00 1813 ah_bt_coex_wlan_weight[1] = 0x7d3b3b00 1814 ah_bt_coex_wlan_weight[2] = 0x3b3b3b00 1815 ah_bt_coex_wlan_weight[3] = 0x3b3b3b3b 1816 Stomp none: 1817 ah_bt_coex_wlan_weight[0] = 0x00007d00 1818 ah_bt_coex_wlan_weight[1] = 0x7d000000 1819 ah_bt_coex_wlan_weight[2] = 0x00000000 1820 ah_bt_coex_wlan_weight[3] = 0x00000000 1821 */ 1822 1823 void ar9300_mci_bt_coex_set_weights(struct ath_hal *ah, u_int32_t stomp_type) 1824 { 1825 struct ath_hal_9300 *ahp = AH9300(ah); 1826 // struct ath_hal_private *ahpriv = AH_PRIVATE(ah); 1827 u_int32_t tx_priority = 0; 1828 1829 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "%s: stomp_type=%d\n", __func__, stomp_type); 1830 1831 switch (stomp_type) { 1832 case HAL_BT_COEX_STOMP_ALL: 1833 ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_ALL_WLAN_WGHT0; 1834 ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_ALL_WLAN_WGHT1; 1835 ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_ALL_WLAN_WGHT2; 1836 ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_ALL_WLAN_WGHT3; 1837 if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_all_tx_pri) { 1838 tx_priority = ahp->ah_mci_stomp_all_tx_pri; 1839 } 1840 break; 1841 case HAL_BT_COEX_STOMP_LOW: 1842 if (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_MCI_FTP_STOMP_RX) { 1843 ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT0; 1844 ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT1; 1845 ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT2; 1846 ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_FTP_WLAN_WGHT3; 1847 } 1848 else { 1849 ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_WLAN_WGHT0; 1850 ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_WLAN_WGHT1; 1851 ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_WLAN_WGHT2; 1852 ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_WLAN_WGHT3; 1853 } 1854 if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_low_tx_pri) { 1855 tx_priority = ahp->ah_mci_stomp_low_tx_pri; 1856 } 1857 if (ah->ah_config.ath_hal_mci_config & 1858 ATH_MCI_CONFIG_MCI_OBS_TXRX) 1859 { 1860 ar9300_gpio_set(ah, 5, 1); 1861 } 1862 break; 1863 case HAL_BT_COEX_STOMP_ALL_FORCE: 1864 ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT0; 1865 ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT1; 1866 ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT2; 1867 ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_ALL_FORCE_WLAN_WGHT3; 1868 break; 1869 case HAL_BT_COEX_STOMP_LOW_FORCE: 1870 ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT0; 1871 ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT1; 1872 ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT2; 1873 ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_LOW_FORCE_WLAN_WGHT3; 1874 if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_low_tx_pri) { 1875 tx_priority = ahp->ah_mci_stomp_low_tx_pri; 1876 } 1877 break; 1878 case HAL_BT_COEX_STOMP_NONE: 1879 case HAL_BT_COEX_NO_STOMP: 1880 ahp->ah_bt_coex_wlan_weight[0] = JUPITER_STOMP_NONE_WLAN_WGHT0; 1881 ahp->ah_bt_coex_wlan_weight[1] = JUPITER_STOMP_NONE_WLAN_WGHT1; 1882 ahp->ah_bt_coex_wlan_weight[2] = JUPITER_STOMP_NONE_WLAN_WGHT2; 1883 ahp->ah_bt_coex_wlan_weight[3] = JUPITER_STOMP_NONE_WLAN_WGHT3; 1884 if (ahp->ah_mci_concur_tx_en && ahp->ah_mci_stomp_none_tx_pri) { 1885 tx_priority = ahp->ah_mci_stomp_none_tx_pri; 1886 } 1887 if (ah->ah_config.ath_hal_mci_config & 1888 ATH_MCI_CONFIG_MCI_OBS_TXRX) 1889 { 1890 ar9300_gpio_set(ah, 5, 0); 1891 } 1892 break; 1893 case HAL_BT_COEX_STOMP_AUDIO: 1894 ahp->ah_bt_coex_wlan_weight[0] = 0xffffff01; 1895 ahp->ah_bt_coex_wlan_weight[1] = 0xffffffff; 1896 ahp->ah_bt_coex_wlan_weight[2] = 0xffffff01; 1897 ahp->ah_bt_coex_wlan_weight[3] = 0xffffffff; 1898 break; 1899 default: 1900 /* There is a forceWeight from registry */ 1901 ahp->ah_bt_coex_wlan_weight[0] = stomp_type; 1902 ahp->ah_bt_coex_wlan_weight[1] = stomp_type; 1903 break; 1904 } 1905 1906 if (ahp->ah_mci_concur_tx_en && tx_priority) { 1907 ahp->ah_bt_coex_wlan_weight[1] &= ~MCI_CONCUR_TX_WLAN_WGHT1_MASK; 1908 ahp->ah_bt_coex_wlan_weight[1] |= 1909 SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT1_MASK); 1910 ahp->ah_bt_coex_wlan_weight[2] &= ~MCI_CONCUR_TX_WLAN_WGHT2_MASK; 1911 ahp->ah_bt_coex_wlan_weight[2] |= 1912 SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT2_MASK); 1913 ahp->ah_bt_coex_wlan_weight[3] &= ~MCI_CONCUR_TX_WLAN_WGHT3_MASK; 1914 ahp->ah_bt_coex_wlan_weight[3] |= 1915 SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT3_MASK); 1916 ahp->ah_bt_coex_wlan_weight[3] &= ~MCI_CONCUR_TX_WLAN_WGHT3_MASK2; 1917 ahp->ah_bt_coex_wlan_weight[3] |= 1918 SM(tx_priority, MCI_CONCUR_TX_WLAN_WGHT3_MASK2); 1919 } 1920 // if (ah->ah_config.ath_hal_mci_config & 1921 // ATH_MCI_CONFIG_MCI_WEIGHT_DBG) 1922 // { 1923 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1924 "(MCI) Set weights: 0x%08x 0x%08x 0x%08x 0x%08x\n", 1925 ahp->ah_bt_coex_wlan_weight[0], 1926 ahp->ah_bt_coex_wlan_weight[1], 1927 ahp->ah_bt_coex_wlan_weight[2], 1928 ahp->ah_bt_coex_wlan_weight[3]); 1929 // } 1930 } 1931 1932 void ar9300_mci_bt_coex_disable(struct ath_hal *ah) 1933 { 1934 struct ath_hal_9300 *ahp = AH9300(ah); 1935 1936 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1937 "(MCI) %s: Set weight to stomp none.\n", __func__); 1938 1939 ar9300_mci_bt_coex_set_weights(ah, HAL_BT_COEX_STOMP_NONE); 1940 1941 /* 1942 * In Jupiter, when coex is disabled, we just set weight 1943 * table to be in favor of WLAN. 1944 */ 1945 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, ahp->ah_bt_coex_wlan_weight[0]); 1946 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, ahp->ah_bt_coex_wlan_weight[1]); 1947 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, ahp->ah_bt_coex_wlan_weight[2]); 1948 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, ahp->ah_bt_coex_wlan_weight[3]); 1949 1950 ahp->ah_bt_coex_enabled = AH_FALSE; 1951 } 1952 1953 int ar9300_mci_bt_coex_enable(struct ath_hal *ah) 1954 { 1955 struct ath_hal_9300 *ahp = AH9300(ah); 1956 1957 HALDEBUG(ah, HAL_DEBUG_BT_COEX, "(MCI) %s: called\n", __func__); 1958 1959 HALDEBUG(ah, HAL_DEBUG_BT_COEX, 1960 "(MCI) Write weights: 0x%08x 0x%08x 0x%08x 0x%08x\n", 1961 ahp->ah_bt_coex_wlan_weight[0], 1962 ahp->ah_bt_coex_wlan_weight[1], 1963 ahp->ah_bt_coex_wlan_weight[2], 1964 ahp->ah_bt_coex_wlan_weight[3]); 1965 1966 1967 /* Mainly change the WLAN weight table */ 1968 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS0, ahp->ah_bt_coex_wlan_weight[0]); 1969 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS1, ahp->ah_bt_coex_wlan_weight[1]); 1970 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS2, ahp->ah_bt_coex_wlan_weight[2]); 1971 OS_REG_WRITE(ah, AR_BTCOEX_WL_WEIGHTS3, ahp->ah_bt_coex_wlan_weight[3]); 1972 1973 /* Send ACK even when BT has higher priority. */ 1974 OS_REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); 1975 1976 if (ahp->ah_bt_coex_flag & HAL_BT_COEX_FLAG_LOW_ACK_PWR) { 1977 OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_LOW_ACK_POWER); 1978 } 1979 else { 1980 OS_REG_WRITE(ah, AR_TPC, HAL_BT_COEX_HIGH_ACK_POWER); 1981 } 1982 1983 ahp->ah_bt_coex_enabled = AH_TRUE; 1984 1985 return 0; 1986 } 1987 1988 #endif /* ATH_SUPPORT_MCI */ 1989