aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/net/wireless/ath/ath9k/ar9003_mci.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.c60
-rw-r--r--drivers/net/wireless/ath/ath9k/btcoex.h3
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.c60
-rw-r--r--drivers/net/wireless/ath/ath9k/mci.h3
5 files changed, 110 insertions, 17 deletions
diff --git a/drivers/net/wireless/ath/ath9k/ar9003_mci.h b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
index 2a2d0188961..29282348eb4 100644
--- a/drivers/net/wireless/ath/ath9k/ar9003_mci.h
+++ b/drivers/net/wireless/ath/ath9k/ar9003_mci.h
@@ -196,7 +196,6 @@ enum mci_state_type {
196 MCI_STATE_SEND_WLAN_COEX_VERSION, 196 MCI_STATE_SEND_WLAN_COEX_VERSION,
197 MCI_STATE_SEND_VERSION_QUERY, 197 MCI_STATE_SEND_VERSION_QUERY,
198 MCI_STATE_SEND_STATUS_QUERY, 198 MCI_STATE_SEND_STATUS_QUERY,
199 MCI_STATE_SET_CONCUR_TX_PRI,
200 MCI_STATE_RECOVER_RX, 199 MCI_STATE_RECOVER_RX,
201 MCI_STATE_NEED_FTP_STOMP, 200 MCI_STATE_NEED_FTP_STOMP,
202 MCI_STATE_DEBUG, 201 MCI_STATE_DEBUG,
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.c b/drivers/net/wireless/ath/ath9k/btcoex.c
index 419e9a3f2fe..05d9be5be52 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.c
+++ b/drivers/net/wireless/ath/ath9k/btcoex.c
@@ -218,27 +218,45 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
218 enum ath_stomp_type stomp_type) 218 enum ath_stomp_type stomp_type)
219{ 219{
220 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw; 220 struct ath_btcoex_hw *btcoex_hw = &ah->btcoex_hw;
221 struct ath9k_hw_mci *mci_hw = &ah->btcoex_hw.mci;
222 u8 txprio_shift[] = { 24, 16, 16, 0 }; /* tx priority weight */
223 bool concur_tx = (mci_hw->concur_tx && btcoex_hw->tx_prio[stomp_type]);
224 const u32 *weight = ar9003_wlan_weights[stomp_type];
225 int i;
221 226
222 if (AR_SREV_9300_20_OR_LATER(ah)) { 227 if (!AR_SREV_9300_20_OR_LATER(ah)) {
223 const u32 *weight = ar9003_wlan_weights[stomp_type];
224 int i;
225
226 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
227 if ((stomp_type == ATH_BTCOEX_STOMP_LOW) &&
228 btcoex_hw->mci.stomp_ftp)
229 stomp_type = ATH_BTCOEX_STOMP_LOW_FTP;
230 weight = mci_wlan_weights[stomp_type];
231 }
232
233 for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) {
234 btcoex_hw->bt_weight[i] = AR9300_BT_WGHT;
235 btcoex_hw->wlan_weight[i] = weight[i];
236 }
237 } else {
238 btcoex_hw->bt_coex_weights = 228 btcoex_hw->bt_coex_weights =
239 SM(bt_weight, AR_BTCOEX_BT_WGHT) | 229 SM(bt_weight, AR_BTCOEX_BT_WGHT) |
240 SM(wlan_weight, AR_BTCOEX_WL_WGHT); 230 SM(wlan_weight, AR_BTCOEX_WL_WGHT);
231 return;
232 }
233
234 if (AR_SREV_9462(ah) || AR_SREV_9565(ah)) {
235 enum ath_stomp_type stype =
236 ((stomp_type == ATH_BTCOEX_STOMP_LOW) &&
237 btcoex_hw->mci.stomp_ftp) ?
238 ATH_BTCOEX_STOMP_LOW_FTP : stomp_type;
239 weight = mci_wlan_weights[stype];
241 } 240 }
241
242 for (i = 0; i < AR9300_NUM_WLAN_WEIGHTS; i++) {
243 btcoex_hw->bt_weight[i] = AR9300_BT_WGHT;
244 btcoex_hw->wlan_weight[i] = weight[i];
245 if (concur_tx && i) {
246 btcoex_hw->wlan_weight[i] &=
247 ~(0xff << txprio_shift[i-1]);
248 btcoex_hw->wlan_weight[i] |=
249 (btcoex_hw->tx_prio[stomp_type] <<
250 txprio_shift[i-1]);
251 }
252 }
253 /* Last WLAN weight has to be adjusted wrt tx priority */
254 if (concur_tx) {
255 btcoex_hw->wlan_weight[i-1] &= ~(0xff << txprio_shift[i-1]);
256 btcoex_hw->wlan_weight[i-1] |= (btcoex_hw->tx_prio[stomp_type]
257 << txprio_shift[i-1]);
258 }
259
242} 260}
243EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight); 261EXPORT_SYMBOL(ath9k_hw_btcoex_set_weight);
244 262
@@ -385,3 +403,13 @@ void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
385 } 403 }
386} 404}
387EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp); 405EXPORT_SYMBOL(ath9k_hw_btcoex_bt_stomp);
406
407void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio)
408{
409 struct ath_btcoex_hw *btcoex = &ah->btcoex_hw;
410 int i;
411
412 for (i = 0; i < ATH_BTCOEX_STOMP_MAX; i++)
413 btcoex->tx_prio[i] = stomp_txprio[i];
414}
415EXPORT_SYMBOL(ath9k_hw_btcoex_set_concur_txprio);
diff --git a/drivers/net/wireless/ath/ath9k/btcoex.h b/drivers/net/wireless/ath/ath9k/btcoex.h
index 385197ad79b..a260fcb99d1 100644
--- a/drivers/net/wireless/ath/ath9k/btcoex.h
+++ b/drivers/net/wireless/ath/ath9k/btcoex.h
@@ -84,6 +84,7 @@ struct ath9k_hw_mci {
84 u8 bt_ver_minor; 84 u8 bt_ver_minor;
85 u8 bt_state; 85 u8 bt_state;
86 u8 stomp_ftp; 86 u8 stomp_ftp;
87 bool concur_tx;
87}; 88};
88 89
89struct ath_btcoex_hw { 90struct ath_btcoex_hw {
@@ -98,6 +99,7 @@ struct ath_btcoex_hw {
98 u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */ 99 u32 bt_coex_mode2; /* Register setting for AR_BT_COEX_MODE2 */
99 u32 bt_weight[AR9300_NUM_BT_WEIGHTS]; 100 u32 bt_weight[AR9300_NUM_BT_WEIGHTS];
100 u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS]; 101 u32 wlan_weight[AR9300_NUM_WLAN_WEIGHTS];
102 u8 tx_prio[ATH_BTCOEX_STOMP_MAX];
101}; 103};
102 104
103void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah); 105void ath9k_hw_btcoex_init_scheme(struct ath_hw *ah);
@@ -112,5 +114,6 @@ void ath9k_hw_btcoex_set_weight(struct ath_hw *ah,
112void ath9k_hw_btcoex_disable(struct ath_hw *ah); 114void ath9k_hw_btcoex_disable(struct ath_hw *ah);
113void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah, 115void ath9k_hw_btcoex_bt_stomp(struct ath_hw *ah,
114 enum ath_stomp_type stomp_type); 116 enum ath_stomp_type stomp_type);
117void ath9k_hw_btcoex_set_concur_txprio(struct ath_hw *ah, u8 *stomp_txprio);
115 118
116#endif 119#endif
diff --git a/drivers/net/wireless/ath/ath9k/mci.c b/drivers/net/wireless/ath/ath9k/mci.c
index 1733a5ac327..b37c8af6e02 100644
--- a/drivers/net/wireless/ath/ath9k/mci.c
+++ b/drivers/net/wireless/ath/ath9k/mci.c
@@ -43,6 +43,7 @@ static bool ath_mci_add_profile(struct ath_common *common,
43 struct ath_mci_profile_info *info) 43 struct ath_mci_profile_info *info)
44{ 44{
45 struct ath_mci_profile_info *entry; 45 struct ath_mci_profile_info *entry;
46 u8 voice_priority[] = { 110, 110, 110, 112, 110, 110, 114, 116, 118 };
46 47
47 if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) && 48 if ((mci->num_sco == ATH_MCI_MAX_SCO_PROFILE) &&
48 (info->type == MCI_GPM_COEX_PROFILE_VOICE)) 49 (info->type == MCI_GPM_COEX_PROFILE_VOICE))
@@ -59,6 +60,12 @@ static bool ath_mci_add_profile(struct ath_common *common,
59 memcpy(entry, info, 10); 60 memcpy(entry, info, 10);
60 INC_PROF(mci, info); 61 INC_PROF(mci, info);
61 list_add_tail(&entry->list, &mci->info); 62 list_add_tail(&entry->list, &mci->info);
63 if (info->type == MCI_GPM_COEX_PROFILE_VOICE) {
64 if (info->voice_type < sizeof(voice_priority))
65 mci->voice_priority = voice_priority[info->voice_type];
66 else
67 mci->voice_priority = 110;
68 }
62 69
63 return true; 70 return true;
64} 71}
@@ -250,6 +257,57 @@ static void ath9k_mci_work(struct work_struct *work)
250 ath_mci_update_scheme(sc); 257 ath_mci_update_scheme(sc);
251} 258}
252 259
260static void ath_mci_update_stomp_txprio(u8 cur_txprio, u8 *stomp_prio)
261{
262 if (cur_txprio < stomp_prio[ATH_BTCOEX_STOMP_NONE])
263 stomp_prio[ATH_BTCOEX_STOMP_NONE] = cur_txprio;
264
265 if (cur_txprio > stomp_prio[ATH_BTCOEX_STOMP_ALL])
266 stomp_prio[ATH_BTCOEX_STOMP_ALL] = cur_txprio;
267
268 if ((cur_txprio > ATH_MCI_HI_PRIO) &&
269 (cur_txprio < stomp_prio[ATH_BTCOEX_STOMP_LOW]))
270 stomp_prio[ATH_BTCOEX_STOMP_LOW] = cur_txprio;
271}
272
273static void ath_mci_set_concur_txprio(struct ath_softc *sc)
274{
275 struct ath_btcoex *btcoex = &sc->btcoex;
276 struct ath_mci_profile *mci = &btcoex->mci;
277 u8 stomp_txprio[] = { 0, 0, 0, 0 }; /* all, low, none, low_ftp */
278
279 if (mci->num_mgmt) {
280 stomp_txprio[ATH_BTCOEX_STOMP_ALL] = ATH_MCI_INQUIRY_PRIO;
281 if (!mci->num_pan && !mci->num_other_acl)
282 stomp_txprio[ATH_BTCOEX_STOMP_NONE] =
283 ATH_MCI_INQUIRY_PRIO;
284 } else {
285 u8 prof_prio[] = { 50, 90, 94, 52 };/* RFCOMM, A2DP, HID, PAN */
286
287 stomp_txprio[ATH_BTCOEX_STOMP_LOW] =
288 stomp_txprio[ATH_BTCOEX_STOMP_NONE] = 0xff;
289
290 if (mci->num_sco)
291 ath_mci_update_stomp_txprio(mci->voice_priority,
292 stomp_txprio);
293 if (mci->num_other_acl)
294 ath_mci_update_stomp_txprio(prof_prio[0], stomp_txprio);
295 if (mci->num_a2dp)
296 ath_mci_update_stomp_txprio(prof_prio[1], stomp_txprio);
297 if (mci->num_hid)
298 ath_mci_update_stomp_txprio(prof_prio[2], stomp_txprio);
299 if (mci->num_pan)
300 ath_mci_update_stomp_txprio(prof_prio[3], stomp_txprio);
301
302 if (stomp_txprio[ATH_BTCOEX_STOMP_NONE] == 0xff)
303 stomp_txprio[ATH_BTCOEX_STOMP_NONE] = 0;
304
305 if (stomp_txprio[ATH_BTCOEX_STOMP_LOW] == 0xff)
306 stomp_txprio[ATH_BTCOEX_STOMP_LOW] = 0;
307 }
308 ath9k_hw_btcoex_set_concur_txprio(sc->sc_ah, stomp_txprio);
309}
310
253static u8 ath_mci_process_profile(struct ath_softc *sc, 311static u8 ath_mci_process_profile(struct ath_softc *sc,
254 struct ath_mci_profile_info *info) 312 struct ath_mci_profile_info *info)
255{ 313{
@@ -281,6 +339,7 @@ static u8 ath_mci_process_profile(struct ath_softc *sc,
281 } else 339 } else
282 ath_mci_del_profile(common, mci, entry); 340 ath_mci_del_profile(common, mci, entry);
283 341
342 ath_mci_set_concur_txprio(sc);
284 return 1; 343 return 1;
285} 344}
286 345
@@ -314,6 +373,7 @@ static u8 ath_mci_process_status(struct ath_softc *sc,
314 mci->num_mgmt++; 373 mci->num_mgmt++;
315 } while (++i < ATH_MCI_MAX_PROFILE); 374 } while (++i < ATH_MCI_MAX_PROFILE);
316 375
376 ath_mci_set_concur_txprio(sc);
317 if (old_num_mgmt != mci->num_mgmt) 377 if (old_num_mgmt != mci->num_mgmt)
318 return 1; 378 return 1;
319 379
diff --git a/drivers/net/wireless/ath/ath9k/mci.h b/drivers/net/wireless/ath/ath9k/mci.h
index a3df314c1e7..e85a0e9506f 100644
--- a/drivers/net/wireless/ath/ath9k/mci.h
+++ b/drivers/net/wireless/ath/ath9k/mci.h
@@ -32,6 +32,8 @@
32#define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\ 32#define ATH_MCI_MAX_PROFILE (ATH_MCI_MAX_ACL_PROFILE +\
33 ATH_MCI_MAX_SCO_PROFILE) 33 ATH_MCI_MAX_SCO_PROFILE)
34 34
35#define ATH_MCI_INQUIRY_PRIO 62
36#define ATH_MCI_HI_PRIO 60
35#define ATH_MCI_NUM_BT_CHANNELS 79 37#define ATH_MCI_NUM_BT_CHANNELS 79
36 38
37#define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \ 39#define MCI_GPM_SET_CHANNEL_BIT(_p_gpm, _bt_chan) \
@@ -131,6 +133,7 @@ struct ath_mci_profile {
131 u8 num_pan; 133 u8 num_pan;
132 u8 num_other_acl; 134 u8 num_other_acl;
133 u8 num_bdr; 135 u8 num_bdr;
136 u8 voice_priority;
134}; 137};
135 138
136struct ath_mci_buf { 139struct ath_mci_buf {