Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f421f9c3 authored by Emmanuel Grumbach's avatar Emmanuel Grumbach Committed by Johannes Berg
Browse files

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: default avatarEmmanuel Grumbach <emmanuel.grumbach@intel.com>
Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
parent 931d4160
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -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;
}
+6 −0
Original line number Diff line number Diff line
@@ -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__ */
+2 −0
Original line number Diff line number Diff line
@@ -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),