diff options
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/bt-coex.c | 52 |
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 | ||
245 | struct iwl_bt_notif_iterator_data { | ||
246 | struct iwl_mvm *mvm; | ||
247 | struct iwl_bt_coex_profile_notif *notif; | ||
248 | }; | ||
249 | |||
250 | static 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 | |||
245 | int iwl_mvm_rx_bt_coex_notif(struct iwl_mvm *mvm, | 289 | int 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) || |