aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-01-17 07:20:29 -0500
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 10:47:59 -0500
commitf421f9c3b2dc77e2be1b9400a4420b6d2cdfb847 (patch)
tree433b69e75b6ff514a9e700d0adbf388cc9675a32
parent931d416049cdb6e8382792231317f76be0d922ce (diff)
iwlwifi: mvm: handle BT-coex notification
The BT-Coex notification is sent by the fw when there are updates wrt. BT activity. Driver action might be taken based on the info in this notification. For now, update the Ack/Cts_kill_msk if HID / SCO / A2DP profiles are active. Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com> Signed-off-by: Johannes Berg <johannes.berg@intel.com>
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c50
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/mvm.h6
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/ops.c2
3 files changed, 58 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index d37865af3254..61159f8abe78 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -64,6 +64,7 @@
64#include "fw-api-bt-coex.h" 64#include "fw-api-bt-coex.h"
65#include "iwl-modparams.h" 65#include "iwl-modparams.h"
66#include "mvm.h" 66#include "mvm.h"
67#include "iwl-debug.h"
67 68
68#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \ 69#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
69 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \ 70 [(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
@@ -240,3 +241,52 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
240 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, 241 return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
241 sizeof(cmd), &cmd); 242 sizeof(cmd), &cmd);
242} 243}
244
245int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
246 struct iwl_rx_cmd_buffer *rxb,
247 struct iwl_device_cmd *dev_cmd)
248{
249 struct iwl_rx_packet *pkt = rxb_addr(rxb);
250 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
251 struct iwl_bt_coex_cmd cmd = {};
252 enum iwl_bt_kill_msk bt_kill_msk;
253
254 IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
255 IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not ");
256 IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
257 IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load);
258 IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
259 notif->bt_agg_traffic_load);
260 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
261
262 /* Low latency BT profile is active: give higher prio to BT */
263 if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
264 BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
265 BT_MBOX_MSG(notif, 3, SNIFF_STATE))
266 bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
267 else
268 bt_kill_msk = BT_KILL_MSK_DEFAULT;
269
270 /* Don't send HCMD if there is no update */
271 if (bt_kill_msk == mvm->bt_kill_msk)
272 return 0;
273
274 IWL_DEBUG_COEX(mvm,
275 "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n",
276 bt_kill_msk,
277 BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
278 BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
279 BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
280
281 mvm->bt_kill_msk = bt_kill_msk;
282 cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
283 cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
284
285 cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);
286
287 if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd))
288 IWL_ERR(mvm, "Failed to sent BT Coex CMD\n");
289
290 /* This handler is ASYNC */
291 return 0;
292}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index b7f27d59fc24..a1f1a86643e5 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -334,6 +334,9 @@ struct iwl_mvm {
334#ifdef CONFIG_PM_SLEEP 334#ifdef CONFIG_PM_SLEEP
335 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen; 335 int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
336#endif 336#endif
337
338 /* BT-Coex */
339 u8 bt_kill_msk;
337}; 340};
338 341
339/* Extract MVM priv from op_mode and _hw */ 342/* Extract MVM priv from op_mode and _hw */
@@ -507,5 +510,8 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
507/* BT Coex */ 510/* BT Coex */
508int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm); 511int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
509int iwl_send_bt_init_conf(struct iwl_mvm *mvm); 512int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
513int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
514 struct iwl_rx_cmd_buffer *rxb,
515 struct iwl_device_cmd *cmd);
510 516
511#endif /* __IWL_MVM_H__ */ 517#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 2003daa0cf76..54595eb7b92a 100644
--- a/drivers/net/wireless/iwlwifi/mvm/ops.c
+++ b/drivers/net/wireless/iwlwifi/mvm/ops.c
@@ -230,6 +230,8 @@ static const struct iwl_rx_handlers iwl_mvm_rx_handlers[] = {
230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false), 230 RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false), 231 RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
232 232
233 RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
234
233 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false), 235 RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
234 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false), 236 RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),
235 237