summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEmmanuel Grumbach <emmanuel.grumbach@intel.com>2013-01-17 12:20:29 (GMT)
committerJohannes Berg <johannes.berg@intel.com>2013-03-06 15:47:59 (GMT)
commitf421f9c3b2dc77e2be1b9400a4420b6d2cdfb847 (patch)
tree433b69e75b6ff514a9e700d0adbf388cc9675a32
parent931d416049cdb6e8382792231317f76be0d922ce (diff)
downloadlinux-f421f9c3b2dc77e2be1b9400a4420b6d2cdfb847.tar.xz
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 d37865a..61159f8 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -64,6 +64,7 @@
#include "fw-api-bt-coex.h"
#include "iwl-modparams.h"
#include "mvm.h"
+#include "iwl-debug.h"
#define EVENT_PRIO_ANT(_evt, _prio, _shrd_ant) \
[(_evt)] = (((_prio) << BT_COEX_PRIO_TBL_PRIO_POS) | \
@@ -240,3 +241,52 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
return iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC,
sizeof(cmd), &cmd);
}
+
+int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *dev_cmd)
+{
+ struct iwl_rx_packet *pkt = rxb_addr(rxb);
+ struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
+ struct iwl_bt_coex_cmd cmd = {};
+ enum iwl_bt_kill_msk bt_kill_msk;
+
+ IWL_DEBUG_COEX(mvm, "BT Coex Notification received\n");
+ IWL_DEBUG_COEX(mvm, "\tBT %salive\n", notif->bt_status ? "" : "not ");
+ IWL_DEBUG_COEX(mvm, "\tBT open conn %d\n", notif->bt_open_conn);
+ IWL_DEBUG_COEX(mvm, "\tBT traffic load %d\n", notif->bt_traffic_load);
+ IWL_DEBUG_COEX(mvm, "\tBT agg traffic load %d\n",
+ notif->bt_agg_traffic_load);
+ IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
+
+ /* Low latency BT profile is active: give higher prio to BT */
+ if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
+ BT_MBOX_MSG(notif, 3, A2DP_STATE) ||
+ BT_MBOX_MSG(notif, 3, SNIFF_STATE))
+ bt_kill_msk = BT_KILL_MSK_SCO_HID_A2DP;
+ else
+ bt_kill_msk = BT_KILL_MSK_DEFAULT;
+
+ /* Don't send HCMD if there is no update */
+ if (bt_kill_msk == mvm->bt_kill_msk)
+ return 0;
+
+ IWL_DEBUG_COEX(mvm,
+ "Udpate kill_msk: %d\n\t SCO %sactive A2DP %sactive SNIFF %sactive\n",
+ bt_kill_msk,
+ BT_MBOX_MSG(notif, 3, SCO_STATE) ? "" : "in",
+ BT_MBOX_MSG(notif, 3, A2DP_STATE) ? "" : "in",
+ BT_MBOX_MSG(notif, 3, SNIFF_STATE) ? "" : "in");
+
+ mvm->bt_kill_msk = bt_kill_msk;
+ cmd.kill_ack_msk = cpu_to_le32(iwl_bt_ack_kill_msk[bt_kill_msk]);
+ cmd.kill_cts_msk = cpu_to_le32(iwl_bt_cts_kill_msk[bt_kill_msk]);
+
+ cmd.valid_bit_msk = cpu_to_le16(BT_VALID_KILL_ACK | BT_VALID_KILL_CTS);
+
+ if (iwl_mvm_send_cmd_pdu(mvm, BT_CONFIG, CMD_SYNC, sizeof(cmd), &cmd))
+ IWL_ERR(mvm, "Failed to sent BT Coex CMD\n");
+
+ /* This handler is ASYNC */
+ return 0;
+}
diff --git a/drivers/net/wireless/iwlwifi/mvm/mvm.h b/drivers/net/wireless/iwlwifi/mvm/mvm.h
index b7f27d5..a1f1a86 100644
--- a/drivers/net/wireless/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/iwlwifi/mvm/mvm.h
@@ -334,6 +334,9 @@ struct iwl_mvm {
#ifdef CONFIG_PM_SLEEP
int gtk_ivlen, gtk_icvlen, ptk_ivlen, ptk_icvlen;
#endif
+
+ /* BT-Coex */
+ u8 bt_kill_msk;
};
/* Extract MVM priv from op_mode and _hw */
@@ -507,5 +510,8 @@ void iwl_mvm_set_default_unicast_key(struct ieee80211_hw *hw,
/* BT Coex */
int iwl_send_bt_prio_tbl(struct iwl_mvm *mvm);
int iwl_send_bt_init_conf(struct iwl_mvm *mvm);
+int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
+ struct iwl_rx_cmd_buffer *rxb,
+ struct iwl_device_cmd *cmd);
#endif /* __IWL_MVM_H__ */
diff --git a/drivers/net/wireless/iwlwifi/mvm/ops.c b/drivers/net/wireless/iwlwifi/mvm/ops.c
index 2003daa..54595eb 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[] = {
RX_HANDLER(SCAN_REQUEST_CMD, iwl_mvm_rx_scan_response, false),
RX_HANDLER(SCAN_COMPLETE_NOTIFICATION, iwl_mvm_rx_scan_complete, false),
+ RX_HANDLER(BT_PROFILE_NOTIFICATION, iwl_mvm_rx_bt_coex_notif, true),
+
RX_HANDLER(RADIO_VERSION_NOTIFICATION, iwl_mvm_rx_radio_ver, false),
RX_HANDLER(CARD_STATE_NOTIFICATION, iwl_mvm_rx_card_state_notif, false),