1 /* 2 * Copyright (c) 2009-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 <linux/types.h> 19 #include <linux/ath9k_platform.h> 20 #include "hw.h" 21 22 enum ath_bt_mode { 23 ATH_BT_COEX_MODE_LEGACY, /* legacy rx_clear mode */ 24 ATH_BT_COEX_MODE_UNSLOTTED, /* untimed/unslotted mode */ 25 ATH_BT_COEX_MODE_SLOTTED, /* slotted mode */ 26 ATH_BT_COEX_MODE_DISABLED, /* coexistence disabled */ 27 }; 28 29 struct ath_btcoex_config { 30 u8 bt_time_extend; 31 bool bt_txstate_extend; 32 bool bt_txframe_extend; 33 enum ath_bt_mode bt_mode; /* coexistence mode */ 34 bool bt_quiet_collision; 35 bool bt_rxclear_polarity; /* invert rx_clear as WLAN_ACTIVE*/ 36 u8 bt_priority_time; 37 u8 bt_first_slot_time; 38 bool bt_hold_rx_clear; 39 u8 wl_active_time; 40 u8 wl_qc_time; 41 }; 42 43 static const u32 ar9003_wlan_weights[ATH_BTCOEX_STOMP_MAX] 44 [AR9300_NUM_WLAN_WEIGHTS] = { 45 { 0xfffffff0, 0xfffffff0, 0xfffffff0, 0xfffffff0 }, /* STOMP_ALL */ 46 { 0x88888880, 0x88888880, 0x88888880, 0x88888880 }, /* STOMP_LOW */ 47 { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, /* STOMP_NONE */ 48 }; 49 50 static const u32 mci_wlan_weights[ATH_BTCOEX_STOMP_MAX] 51 [AR9300_NUM_WLAN_WEIGHTS] = { 52 { 0x01017d01, 0x41414101, 0x41414101, 0x41414141 }, /* STOMP_ALL */ 53 { 0x01017d01, 0x3b3b3b01, 0x3b3b3b01, 0x3b3b3b3b }, /* STOMP_LOW */ 54 { 0x01017d01, 0x01010101, 0x01010101, 0x01010101 }, /* STOMP_NONE */ 55 { 0x01017d01, 0x013b0101, 0x3b3b0101, 0x3b3b013b }, /* STOMP_LOW_FTP */ 56 { 0xffffff01, 0xffffffff, 0xffffff01, 0xffffffff }, /* STOMP_AUDIO */ 57 }; 58 59 void ath9k_hw_init_btcoex_hw(struct ath_hw *ah, int qnum) 60 { 61 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 62 const struct ath_btcoex_config ath_bt_config = { 63 .bt_time_extend = 0, 64 .bt_txstate_extend = true, 65 .bt_txframe_extend = true, 66 .bt_mode = ATH_BT_COEX_MODE_SLOTTED, 67 .bt_quiet_collision = true, 68 .bt_rxclear_polarity = true, 69 .bt_priority_time = 2, 70 .bt_first_slot_time = 5, 71 .bt_hold_rx_clear = true, 72 .wl_active_time = 0x20, 73 .wl_qc_time = 0x20, 74 }; 75 bool rxclear_polarity = ath_bt_config.bt_rxclear_polarity; 76 u8 time_extend = ath_bt_config.bt_time_extend; 77 u8 first_slot_time = ath_bt_config.bt_first_slot_time; 78 79 if (AR_SREV_9300_20_OR_LATER(ah)) 80 rxclear_polarity = !ath_bt_config.bt_rxclear_polarity; 81 82 if (AR_SREV_SOC(ah)) { 83 first_slot_time = 0x1d; 84 time_extend = 0xa; 85 86 btcoex_hw->bt_coex_mode3 = 87 SM(ath_bt_config.wl_active_time, AR_BT_WL_ACTIVE_TIME) | 88 SM(ath_bt_config.wl_qc_time, AR_BT_WL_QC_TIME); 89 90 btcoex_hw->bt_coex_mode2 = 91 AR_BT_PROTECT_BT_AFTER_WAKEUP | 92 AR_BT_PHY_ERR_BT_COLL_ENABLE; 93 } 94 95 btcoex_hw->bt_coex_mode = 96 (btcoex_hw->bt_coex_mode & AR_BT_QCU_THRESH) | 97 SM(time_extend, AR_BT_TIME_EXTEND) | 98 SM(ath_bt_config.bt_txstate_extend, AR_BT_TXSTATE_EXTEND) | 99 SM(ath_bt_config.bt_txframe_extend, AR_BT_TX_FRAME_EXTEND) | 100 SM(ath_bt_config.bt_mode, AR_BT_MODE) | 101 SM(ath_bt_config.bt_quiet_collision, AR_BT_QUIET) | 102 SM(rxclear_polarity, AR_BT_RX_CLEAR_POLARITY) | 103 SM(ath_bt_config.bt_priority_time, AR_BT_PRIORITY_TIME) | 104 SM(first_slot_time, AR_BT_FIRST_SLOT_TIME) | 105 SM(qnum, AR_BT_QCU_THRESH); 106 107 btcoex_hw->bt_coex_mode2 |= 108 SM(ath_bt_config.bt_hold_rx_clear, AR_BT_HOLD_RX_CLEAR) | 109 SM(ATH_BTCOEX_BMISS_THRESH, AR_BT_BCN_MISS_THRESH) | 110 AR_BT_DISABLE_BT_ANT; 111 } 112 EXPORT_SYMBOL(ath9k_hw_init_btcoex_hw); 113 114 static void ath9k_hw_btcoex_pin_init(struct ath_hw *ah, u8 wlanactive_gpio, 115 u8 btactive_gpio, u8 btpriority_gpio) 116 { 117 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 118 struct ath9k_platform_data *pdata = ah->dev->platform_data; 119 120 if (btcoex_hw->scheme != ATH_BTCOEX_CFG_2WIRE && 121 btcoex_hw->scheme != ATH_BTCOEX_CFG_3WIRE) 122 return; 123 124 /* bt priority GPIO will be ignored by 2 wire scheme */ 125 if (pdata && (pdata->bt_active_pin || pdata->bt_priority_pin || 126 pdata->wlan_active_pin)) { 127 btcoex_hw->btactive_gpio = pdata->bt_active_pin; 128 btcoex_hw->wlanactive_gpio = pdata->wlan_active_pin; 129 btcoex_hw->btpriority_gpio = pdata->bt_priority_pin; 130 } else { 131 btcoex_hw->btactive_gpio = btactive_gpio; 132 btcoex_hw->wlanactive_gpio = wlanactive_gpio; 133 btcoex_hw->btpriority_gpio = btpriority_gpio; 134 } 135 } 136 137 void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah) 138 { 139 struct ath_common *common = ath9k_hw_common(ah); 140 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 141 142 /* 143 * Check if BTCOEX is globally disabled. 144 */ 145 if (!common->btcoex_enabled) { 146 btcoex_hw->scheme = ATH_BTCOEX_CFG_NONE; 147 return; 148 } 149 150 if (ah->caps.hw_caps & ATH9K_HW_CAP_MCI) { 151 btcoex_hw->scheme = ATH_BTCOEX_CFG_MCI; 152 } else if (AR_SREV_9300_20_OR_LATER(ah)) { 153 btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; 154 155 ath9k_hw_btcoex_pin_init(ah, ATH_WLANACTIVE_GPIO_9300, 156 ATH_BTACTIVE_GPIO_9300, 157 ATH_BTPRIORITY_GPIO_9300); 158 } else if (AR_SREV_9280_20_OR_LATER(ah)) { 159 if (AR_SREV_9285(ah)) 160 btcoex_hw->scheme = ATH_BTCOEX_CFG_3WIRE; 161 else 162 btcoex_hw->scheme = ATH_BTCOEX_CFG_2WIRE; 163 164 ath9k_hw_btcoex_pin_init(ah, ATH_WLANACTIVE_GPIO_9280, 165 ATH_BTACTIVE_GPIO_9280, 166 ATH_BTPRIORITY_GPIO_9285); 167 } 168 } 169 EXPORT_SYMBOL(ath9k_hw_btcoex_init_scheme); 170 171 void ath9k_hw_btcoex_init_2wire(struct ath_hw *ah) 172 { 173 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 174 175 /* connect bt_active to baseband */ 176 REG_CLR_BIT(ah, AR_GPIO_INPUT_EN_VAL(ah), 177 (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_DEF | 178 AR_GPIO_INPUT_EN_VAL_BT_FREQUENCY_DEF)); 179 180 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL(ah), 181 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB); 182 183 /* Set input mux for bt_active to gpio pin */ 184 if (!AR_SREV_SOC(ah)) 185 REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1(ah), 186 AR_GPIO_INPUT_MUX1_BT_ACTIVE, 187 btcoex_hw->btactive_gpio); 188 189 /* Configure the desired gpio port for input */ 190 ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio, 191 "ath9k-btactive"); 192 } 193 EXPORT_SYMBOL(ath9k_hw_btcoex_init_2wire); 194 195 void ath9k_hw_btcoex_init_3wire(struct ath_hw *ah) 196 { 197 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 198 199 /* btcoex 3-wire */ 200 REG_SET_BIT(ah, AR_GPIO_INPUT_EN_VAL(ah), 201 (AR_GPIO_INPUT_EN_VAL_BT_PRIORITY_BB | 202 AR_GPIO_INPUT_EN_VAL_BT_ACTIVE_BB)); 203 204 /* Set input mux for bt_prority_async and 205 * bt_active_async to GPIO pins */ 206 if (!AR_SREV_SOC(ah)) { 207 REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1(ah), 208 AR_GPIO_INPUT_MUX1_BT_ACTIVE, 209 btcoex_hw->btactive_gpio); 210 REG_RMW_FIELD(ah, AR_GPIO_INPUT_MUX1(ah), 211 AR_GPIO_INPUT_MUX1_BT_PRIORITY, 212 btcoex_hw->btpriority_gpio); 213 } 214 215 /* Configure the desired GPIO ports for input */ 216 ath9k_hw_gpio_request_in(ah, btcoex_hw->btactive_gpio, 217 "ath9k-btactive"); 218 ath9k_hw_gpio_request_in(ah, btcoex_hw->btpriority_gpio, 219 "ath9k-btpriority"); 220 } 221 EXPORT_SYMBOL(ath9k_hw_btcoex_init_3wire); 222 223 void ath9k_hw_btcoex_deinit(struct ath_hw *ah) 224 { 225 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 226 227 ath9k_hw_gpio_free(ah, btcoex_hw->btactive_gpio); 228 ath9k_hw_gpio_free(ah, btcoex_hw->btpriority_gpio); 229 ath9k_hw_gpio_free(ah, btcoex_hw->wlanactive_gpio); 230 } 231 EXPORT_SYMBOL(ath9k_hw_btcoex_deinit); 232 233 void ath9k_hw_btcoex_init_mci(struct ath_hw *ah) 234 { 235 ah->btcoex_hw.mci.ready = false; 236 ah->btcoex_hw.mci.bt_state = 0; 237 ah->btcoex_hw.mci.bt_ver_major = 3; 238 ah->btcoex_hw.mci.bt_ver_minor = 0; 239 ah->btcoex_hw.mci.bt_version_known = false; 240 ah->btcoex_hw.mci.update_2g5g = true; 241 ah->btcoex_hw.mci.is_2g = true; 242 ah->btcoex_hw.mci.wlan_channels_update = false; 243 ah->btcoex_hw.mci.wlan_channels[0] = 0x00000000; 244 ah->btcoex_hw.mci.wlan_channels[1] = 0xffffffff; 245 ah->btcoex_hw.mci.wlan_channels[2] = 0xffffffff; 246 ah->btcoex_hw.mci.wlan_channels[3] = 0x7fffffff; 247 ah->btcoex_hw.mci.query_bt = true; 248 ah->btcoex_hw.mci.unhalt_bt_gpm = true; 249 ah->btcoex_hw.mci.halted_bt_gpm = false; 250 ah->btcoex_hw.mci.need_flush_btinfo = false; 251 ah->btcoex_hw.mci.wlan_cal_seq = 0; 252 ah->btcoex_hw.mci.wlan_cal_done = 0; 253 ah->btcoex_hw.mci.config = (AR_SREV_9462(ah)) ? 0x2201 : 0xa4c1; 254 } 255 EXPORT_SYMBOL(ath9k_hw_btcoex_init_mci); 256 257 static void ath9k_hw_btcoex_enable_2wire(struct ath_hw *ah) 258 { 259 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 260 261 /* Configure the desired GPIO port for TX_FRAME output */ 262 ath9k_hw_gpio_request_out(ah, btcoex_hw->wlanactive_gpio, 263 "ath9k-wlanactive", 264 AR_GPIO_OUTPUT_MUX_AS_TX_FRAME); 265 } 266 267 /* 268 * For AR9002, bt_weight/wlan_weight are used. 269 * For AR9003 and above, stomp_type is used. 270 */ 271 void ath9k_hw_btcoex_set_weight(struct ath_hw *ah, 272 u32 bt_weight, 273 u32 wlan_weight, 274 enum ath_stomp_type stomp_type) 275 { 276 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 277 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci; 278 u8 txprio_shift[] = { 24, 16, 16, 0 }; /* tx priority weight */ 279 bool concur_tx = (mci_hw->concur_tx && btcoex_hw->tx_prio[stomp_type]); 280 const u32 *weight = ar9003_wlan_weights[stomp_type]; 281 int i; 282 283 if (!AR_SREV_9300_20_OR_LATER(ah)) { 284 btcoex_hw->bt_coex_weights = 285 SM(bt_weight, AR_BTCOEX_BT_WGHT) | 286 SM(wlan_weight, AR_BTCOEX_WL_WGHT); 287 return; 288 } 289 290 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) { 291 enum ath_stomp_type stype = 292 ((stomp_type == ATH_BTCOEX_STOMP_LOW) && 293 btcoex_hw->mci.stomp_ftp) ? 294 ATH_BTCOEX_STOMP_LOW_FTP : stomp_type; 295 weight = mci_wlan_weights[stype]; 296 } 297 298 for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) { 299 btcoex_hw->bt_weight[i] = AR9300_BT_WGHT; 300 btcoex_hw->wlan_weight[i] = weight[i]; 301 if (concur_tx && i) { 302 btcoex_hw->wlan_weight[i] &= 303 ~(0xff << txprio_shift[i-1]); 304 btcoex_hw->wlan_weight[i] |= 305 (btcoex_hw->tx_prio[stomp_type] << 306 txprio_shift[i-1]); 307 } 308 } 309 310 /* Last WLAN weight has to be adjusted wrt tx priority */ 311 if (concur_tx) { 312 btcoex_hw->wlan_weight[i-1] &= ~(0xff << txprio_shift[i-1]); 313 btcoex_hw->wlan_weight[i-1] |= (btcoex_hw->tx_prio[stomp_type] 314 << txprio_shift[i-1]); 315 } 316 } 317 EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); 318 319 320 static void ath9k_hw_btcoex_enable_3wire(struct ath_hw *ah) 321 { 322 struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; 323 u32 val; 324 int i; 325 326 /* 327 * Program coex mode and weight registers to 328 * enable coex 3-wire 329 */ 330 if (AR_SREV_SOC(ah)) 331 REG_CLR_BIT(ah, AR_BT_COEX_MODE2, AR_BT_PHY_ERR_BT_COLL_ENABLE); 332 333 REG_WRITE(ah, AR_BT_COEX_MODE, btcoex->bt_coex_mode); 334 REG_WRITE(ah, AR_BT_COEX_MODE2, btcoex->bt_coex_mode2); 335 336 if (AR_SREV_SOC(ah)) 337 REG_WRITE(ah, AR_BT_COEX_MODE3, btcoex->bt_coex_mode3); 338 339 if (AR_SREV_9300_20_OR_LATER(ah)) { 340 REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, btcoex->wlan_weight[0]); 341 REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, btcoex->wlan_weight[1]); 342 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 343 REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS(i), 344 btcoex->bt_weight[i]); 345 } else 346 REG_WRITE(ah, AR_BT_COEX_WEIGHT, btcoex->bt_coex_weights); 347 348 if (AR_SREV_9271(ah)) { 349 val = REG_READ(ah, 0x50040); 350 val &= 0xFFFFFEFF; 351 REG_WRITE(ah, 0x50040, val); 352 } 353 354 REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); 355 REG_RMW_FIELD(ah, AR_PCU_MISC, AR_PCU_BT_ANT_PREVENT_RX, 0); 356 357 ath9k_hw_gpio_request_out(ah, btcoex->wlanactive_gpio, 358 "ath9k-wlanactive", 359 AR_GPIO_OUTPUT_MUX_AS_RX_CLEAR_EXTERNAL); 360 } 361 362 static void ath9k_hw_btcoex_enable_mci(struct ath_hw *ah) 363 { 364 struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; 365 int i; 366 367 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 368 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), 369 btcoex->wlan_weight[i]); 370 371 REG_RMW_FIELD(ah, AR_QUIET1, AR_QUIET1_QUIET_ACK_CTS_ENABLE, 1); 372 btcoex->enabled = true; 373 } 374 375 static void ath9k_hw_btcoex_disable_mci(struct ath_hw *ah) 376 { 377 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 378 int i; 379 380 ath9k_hw_btcoex_bt_stomp(ah, ATH_BTCOEX_STOMP_NONE); 381 382 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 383 REG_WRITE(ah, AR_MCI_COEX_WL_WEIGHTS(i), 384 btcoex_hw->wlan_weight[i]); 385 } 386 387 void ath9k_hw_btcoex_enable(struct ath_hw *ah) 388 { 389 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 390 391 switch (ath9k_hw_get_btcoex_scheme(ah)) { 392 case ATH_BTCOEX_CFG_NONE: 393 return; 394 case ATH_BTCOEX_CFG_2WIRE: 395 ath9k_hw_btcoex_enable_2wire(ah); 396 break; 397 case ATH_BTCOEX_CFG_3WIRE: 398 ath9k_hw_btcoex_enable_3wire(ah); 399 break; 400 case ATH_BTCOEX_CFG_MCI: 401 ath9k_hw_btcoex_enable_mci(ah); 402 break; 403 } 404 405 if (ath9k_hw_get_btcoex_scheme(ah) != ATH_BTCOEX_CFG_MCI && 406 !AR_SREV_SOC(ah)) { 407 REG_RMW(ah, AR_GPIO_PDPU(ah), 408 (0x2 << (btcoex_hw->btactive_gpio * 2)), 409 (0x3 << (btcoex_hw->btactive_gpio * 2))); 410 } 411 412 ah->btcoex_hw.enabled = true; 413 } 414 EXPORT_SYMBOL(ath9k_hw_btcoex_enable); 415 416 void ath9k_hw_btcoex_disable(struct ath_hw *ah) 417 { 418 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 419 int i; 420 421 btcoex_hw->enabled = false; 422 423 if (ath9k_hw_get_btcoex_scheme(ah) == ATH_BTCOEX_CFG_MCI) { 424 ath9k_hw_btcoex_disable_mci(ah); 425 return; 426 } 427 428 if (!AR_SREV_9300_20_OR_LATER(ah)) 429 ath9k_hw_set_gpio(ah, btcoex_hw->wlanactive_gpio, 0); 430 431 ath9k_hw_gpio_request_out(ah, btcoex_hw->wlanactive_gpio, 432 NULL, AR_GPIO_OUTPUT_MUX_AS_OUTPUT); 433 434 if (btcoex_hw->scheme == ATH_BTCOEX_CFG_3WIRE) { 435 REG_WRITE(ah, AR_BT_COEX_MODE, AR_BT_QUIET | AR_BT_MODE); 436 REG_WRITE(ah, AR_BT_COEX_MODE2, 0); 437 438 if (AR_SREV_9300_20_OR_LATER(ah)) { 439 REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS0, 0); 440 REG_WRITE(ah, AR_BT_COEX_WL_WEIGHTS1, 0); 441 for (i = 0; i < AR9300_NUM_BT_WEIGHTS; i++) 442 REG_WRITE(ah, AR_BT_COEX_BT_WEIGHTS(i), 0); 443 } else 444 REG_WRITE(ah, AR_BT_COEX_WEIGHT, 0); 445 446 } 447 } 448 EXPORT_SYMBOL(ath9k_hw_btcoex_disable); 449 450 /* 451 * Configures appropriate weight based on stomp type. 452 */ 453 void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, 454 enum ath_stomp_type stomp_type) 455 { 456 if (AR_SREV_9300_20_OR_LATER(ah)) { 457 ath9k_hw_btcoex_set_weight(ah, 0, 0, stomp_type); 458 return; 459 } 460 461 switch (stomp_type) { 462 case ATH_BTCOEX_STOMP_ALL: 463 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 464 AR_STOMP_ALL_WLAN_WGHT, 0); 465 break; 466 case ATH_BTCOEX_STOMP_LOW: 467 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 468 AR_STOMP_LOW_WLAN_WGHT, 0); 469 break; 470 case ATH_BTCOEX_STOMP_NONE: 471 ath9k_hw_btcoex_set_weight(ah, AR_BT_COEX_WGHT, 472 AR_STOMP_NONE_WLAN_WGHT, 0); 473 break; 474 default: 475 ath_dbg(ath9k_hw_common(ah), BTCOEX, "Invalid Stomptype\n"); 476 break; 477 } 478 } 479 EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); 480 481 void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio) 482 { 483 struct ath_btcoex_hw *btcoex = &ah->btcoex_hw; 484 int i; 485 486 for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++) 487 btcoex->tx_prio[i] = stomp_txprio[i]; 488 } 489 EXPORT_SYMBOL(ath9k_hw_btcoex_set_concur_txprio); 490