aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c')
-rw-r--r--drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c43
1 files changed, 36 insertions, 7 deletions
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
index 525b26e0f65e..3f37fb64e71c 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mac80211.c
@@ -1623,6 +1623,7 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
1623 struct iwl_mvm_mc_iter_data iter_data = { 1623 struct iwl_mvm_mc_iter_data iter_data = {
1624 .mvm = mvm, 1624 .mvm = mvm,
1625 }; 1625 };
1626 int ret;
1626 1627
1627 lockdep_assert_held(&mvm->mutex); 1628 lockdep_assert_held(&mvm->mutex);
1628 1629
@@ -1632,6 +1633,22 @@ static void iwl_mvm_recalc_multicast(struct iwl_mvm *mvm)
1632 ieee80211_iterate_active_interfaces_atomic( 1633 ieee80211_iterate_active_interfaces_atomic(
1633 mvm->hw, IEEE80211_IFACE_ITER_NORMAL, 1634 mvm->hw, IEEE80211_IFACE_ITER_NORMAL,
1634 iwl_mvm_mc_iface_iterator, &iter_data); 1635 iwl_mvm_mc_iface_iterator, &iter_data);
1636
1637 /*
1638 * Send a (synchronous) ech command so that we wait for the
1639 * multiple asynchronous MCAST_FILTER_CMD commands sent by
1640 * the interface iterator. Otherwise, we might get here over
1641 * and over again (by userspace just sending a lot of these)
1642 * and the CPU can send them faster than the firmware can
1643 * process them.
1644 * Note that the CPU is still faster - but with this we'll
1645 * actually send fewer commands overall because the CPU will
1646 * not schedule the work in mac80211 as frequently if it's
1647 * still running when rescheduled (possibly multiple times).
1648 */
1649 ret = iwl_mvm_send_cmd_pdu(mvm, ECHO_CMD, 0, 0, NULL);
1650 if (ret)
1651 IWL_ERR(mvm, "Failed to synchronize multicast groups update\n");
1635} 1652}
1636 1653
1637static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw, 1654static u64 iwl_mvm_prepare_multicast(struct ieee80211_hw *hw,
@@ -2880,7 +2897,7 @@ static int iwl_mvm_mac_sta_state(struct ieee80211_hw *hw,
2880 2897
2881 /* this would be a mac80211 bug ... but don't crash */ 2898 /* this would be a mac80211 bug ... but don't crash */
2882 if (WARN_ON_ONCE(!mvmvif->phy_ctxt)) 2899 if (WARN_ON_ONCE(!mvmvif->phy_ctxt))
2883 return -EINVAL; 2900 return test_bit(IWL_MVM_STATUS_HW_RESTART_REQUESTED, &mvm->status) ? 0 : -EINVAL;
2884 2901
2885 /* 2902 /*
2886 * If we are in a STA removal flow and in DQA mode: 2903 * If we are in a STA removal flow and in DQA mode:
@@ -3496,6 +3513,7 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
3496 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); 3513 struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif);
3497 struct cfg80211_chan_def chandef; 3514 struct cfg80211_chan_def chandef;
3498 struct iwl_mvm_phy_ctxt *phy_ctxt; 3515 struct iwl_mvm_phy_ctxt *phy_ctxt;
3516 bool band_change_removal;
3499 int ret, i; 3517 int ret, i;
3500 3518
3501 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value, 3519 IWL_DEBUG_MAC80211(mvm, "enter (%d, %d, %d)\n", channel->hw_value,
@@ -3565,19 +3583,30 @@ static int iwl_mvm_roc(struct ieee80211_hw *hw,
3565 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT); 3583 cfg80211_chandef_create(&chandef, channel, NL80211_CHAN_NO_HT);
3566 3584
3567 /* 3585 /*
3568 * Change the PHY context configuration as it is currently referenced 3586 * Check if the remain-on-channel is on a different band and that
3569 * only by the P2P Device MAC 3587 * requires context removal, see iwl_mvm_phy_ctxt_changed(). If
3588 * so, we'll need to release and then re-configure here, since we
3589 * must not remove a PHY context that's part of a binding.
3570 */ 3590 */
3571 if (mvmvif->phy_ctxt->ref == 1) { 3591 band_change_removal =
3592 fw_has_capa(&mvm->fw->ucode_capa,
3593 IWL_UCODE_TLV_CAPA_BINDING_CDB_SUPPORT) &&
3594 mvmvif->phy_ctxt->channel->band != chandef.chan->band;
3595
3596 if (mvmvif->phy_ctxt->ref == 1 && !band_change_removal) {
3597 /*
3598 * Change the PHY context configuration as it is currently
3599 * referenced only by the P2P Device MAC (and we can modify it)
3600 */
3572 ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt, 3601 ret = iwl_mvm_phy_ctxt_changed(mvm, mvmvif->phy_ctxt,
3573 &chandef, 1, 1); 3602 &chandef, 1, 1);
3574 if (ret) 3603 if (ret)
3575 goto out_unlock; 3604 goto out_unlock;
3576 } else { 3605 } else {
3577 /* 3606 /*
3578 * The PHY context is shared with other MACs. Need to remove the 3607 * The PHY context is shared with other MACs (or we're trying to
3579 * P2P Device from the binding, allocate an new PHY context and 3608 * switch bands), so remove the P2P Device from the binding,
3580 * create a new binding 3609 * allocate an new PHY context and create a new binding.
3581 */ 3610 */
3582 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm); 3611 phy_ctxt = iwl_mvm_get_free_phy_ctxt(mvm);
3583 if (!phy_ctxt) { 3612 if (!phy_ctxt) {