aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/iwlwifi/mvm/bt-coex.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
index 61159f8abe78..fa054b364e52 100644
--- a/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
+++ b/drivers/net/wireless/iwlwifi/mvm/bt-coex.c
@@ -242,12 +242,60 @@ int iwl_send_bt_init_conf(struct iwl_mvm *mvm)
242 sizeof(cmd), &cmd); 242 sizeof(cmd), &cmd);
243} 243}
244 244
245struct iwl_bt_notif_iterator_data {
246 struct iwl_mvm *mvm;
247 struct iwl_bt_coex_profile_notif *notif;
248};
249
250static void iwl_mvm_bt_notif_iterator(void *_data, u8 *mac,
251 struct ieee80211_vif *vif)
252{
253 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
254 struct iwl_bt_notif_iterator_data *data = _data;
255 struct ieee80211_chanctx_conf *chanctx_conf;
256 enum ieee80211_smps_mode smps_mode;
257 enum ieee80211_band band;
258
259 if (vif->type != NL80211_IFTYPE_STATION)
260 return;
261
262 rcu_read_lock();
263 chanctx_conf = rcu_dereference(vif->chanctx_conf);
264 if (chanctx_conf && chanctx_conf->def.chan)
265 band = chanctx_conf->def.chan->band;
266 else
267 band = -1;
268 rcu_read_unlock();
269
270 if (band != IEEE80211_BAND_2GHZ)
271 return;
272
273 smps_mode = IEEE80211_SMPS_AUTOMATIC;
274
275 if (data->notif->bt_status)
276 smps_mode = IEEE80211_SMPS_DYNAMIC;
277
278 if (data->notif->bt_traffic_load)
279 smps_mode = IEEE80211_SMPS_STATIC;
280
281 IWL_DEBUG_COEX(data->mvm,
282 "mac %d: bt_status %d traffic_load %d smps_req %d\n",
283 mvmvif->id, data->notif->bt_status,
284 data->notif->bt_traffic_load, smps_mode);
285
286 ieee80211_request_smps(vif, smps_mode);
287}
288
245int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, 289int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
246 struct iwl_rx_cmd_buffer *rxb, 290 struct iwl_rx_cmd_buffer *rxb,
247 struct iwl_device_cmd *dev_cmd) 291 struct iwl_device_cmd *dev_cmd)
248{ 292{
249 struct iwl_rx_packet *pkt = rxb_addr(rxb); 293 struct iwl_rx_packet *pkt = rxb_addr(rxb);
250 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data; 294 struct iwl_bt_coex_profile_notif *notif = (void *)pkt->data;
295 struct iwl_bt_notif_iterator_data data = {
296 .mvm = mvm,
297 .notif = notif,
298 };
251 struct iwl_bt_coex_cmd cmd = {}; 299 struct iwl_bt_coex_cmd cmd = {};
252 enum iwl_bt_kill_msk bt_kill_msk; 300 enum iwl_bt_kill_msk bt_kill_msk;
253 301
@@ -259,6 +307,10 @@ int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm,
259 notif->bt_agg_traffic_load); 307 notif->bt_agg_traffic_load);
260 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance); 308 IWL_DEBUG_COEX(mvm, "\tBT ci compliance %d\n", notif->bt_ci_compliance);
261 309
310 ieee80211_iterate_active_interfaces_atomic(
311 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
312 iwl_mvm_bt_notif_iterator, &data);
313
262 /* Low latency BT profile is active: give higher prio to BT */ 314 /* Low latency BT profile is active: give higher prio to BT */
263 if (BT_MBOX_MSG(notif, 3, SCO_STATE) || 315 if (BT_MBOX_MSG(notif, 3, SCO_STATE) ||
264 BT_MBOX_MSG(notif, 3, A2DP_STATE) || 316 BT_MBOX_MSG(notif, 3, A2DP_STATE) ||