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