Deleted Added
full compact
ar9300_mci.c (250007) ar9300_mci.c (250008)
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 */