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