diff options
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/mac80211.c | 26 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/sta.c | 61 | ||||
-rw-r--r-- | drivers/net/wireless/iwlwifi/mvm/sta.h | 15 |
3 files changed, 57 insertions, 45 deletions
diff --git a/drivers/net/wireless/iwlwifi/mvm/mac80211.c b/drivers/net/wireless/iwlwifi/mvm/mac80211.c index ac2b11a52b9f..78ed6bc326a0 100644 --- a/drivers/net/wireless/iwlwifi/mvm/mac80211.c +++ b/drivers/net/wireless/iwlwifi/mvm/mac80211.c | |||
@@ -971,19 +971,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
971 | */ | 971 | */ |
972 | if (vif->type == NL80211_IFTYPE_AP || | 972 | if (vif->type == NL80211_IFTYPE_AP || |
973 | vif->type == NL80211_IFTYPE_ADHOC) { | 973 | vif->type == NL80211_IFTYPE_ADHOC) { |
974 | u32 qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | 974 | ret = iwl_mvm_alloc_bcast_sta(mvm, vif); |
975 | |||
976 | /* | ||
977 | * The firmware defines the TFD queue mask to only be relevant | ||
978 | * for *unicast* queues, so the multicast (CAB) queue should | ||
979 | * be excluded. | ||
980 | */ | ||
981 | if (vif->type == NL80211_IFTYPE_AP) | ||
982 | qmask &= ~BIT(vif->cab_queue); | ||
983 | |||
984 | ret = iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, | ||
985 | qmask, | ||
986 | ieee80211_vif_type_p2p(vif)); | ||
987 | if (ret) { | 975 | if (ret) { |
988 | IWL_ERR(mvm, "Failed to allocate bcast sta\n"); | 976 | IWL_ERR(mvm, "Failed to allocate bcast sta\n"); |
989 | goto out_release; | 977 | goto out_release; |
@@ -1031,7 +1019,7 @@ static int iwl_mvm_mac_add_interface(struct ieee80211_hw *hw, | |||
1031 | if (ret) | 1019 | if (ret) |
1032 | goto out_unref_phy; | 1020 | goto out_unref_phy; |
1033 | 1021 | ||
1034 | ret = iwl_mvm_add_bcast_sta(mvm, vif, &mvmvif->bcast_sta); | 1022 | ret = iwl_mvm_add_bcast_sta(mvm, vif); |
1035 | if (ret) | 1023 | if (ret) |
1036 | goto out_unbind; | 1024 | goto out_unbind; |
1037 | 1025 | ||
@@ -1128,13 +1116,13 @@ static void iwl_mvm_mac_remove_interface(struct ieee80211_hw *hw, | |||
1128 | mvm->noa_duration = 0; | 1116 | mvm->noa_duration = 0; |
1129 | } | 1117 | } |
1130 | #endif | 1118 | #endif |
1131 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | 1119 | iwl_mvm_dealloc_bcast_sta(mvm, vif); |
1132 | goto out_release; | 1120 | goto out_release; |
1133 | } | 1121 | } |
1134 | 1122 | ||
1135 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { | 1123 | if (vif->type == NL80211_IFTYPE_P2P_DEVICE) { |
1136 | mvm->p2p_device_vif = NULL; | 1124 | mvm->p2p_device_vif = NULL; |
1137 | iwl_mvm_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1125 | iwl_mvm_rm_bcast_sta(mvm, vif); |
1138 | iwl_mvm_binding_remove_vif(mvm, vif); | 1126 | iwl_mvm_binding_remove_vif(mvm, vif); |
1139 | iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); | 1127 | iwl_mvm_phy_ctxt_unref(mvm, mvmvif->phy_ctxt); |
1140 | mvmvif->phy_ctxt = NULL; | 1128 | mvmvif->phy_ctxt = NULL; |
@@ -1633,7 +1621,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1633 | 1621 | ||
1634 | /* Send the bcast station. At this stage the TBTT and DTIM time events | 1622 | /* Send the bcast station. At this stage the TBTT and DTIM time events |
1635 | * are added and applied to the scheduler */ | 1623 | * are added and applied to the scheduler */ |
1636 | ret = iwl_mvm_send_bcast_sta(mvm, vif, &mvmvif->bcast_sta); | 1624 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
1637 | if (ret) | 1625 | if (ret) |
1638 | goto out_unbind; | 1626 | goto out_unbind; |
1639 | 1627 | ||
@@ -1665,7 +1653,7 @@ static int iwl_mvm_start_ap_ibss(struct ieee80211_hw *hw, | |||
1665 | out_quota_failed: | 1653 | out_quota_failed: |
1666 | iwl_mvm_power_update_mac(mvm); | 1654 | iwl_mvm_power_update_mac(mvm); |
1667 | mvmvif->ap_ibss_active = false; | 1655 | mvmvif->ap_ibss_active = false; |
1668 | iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1656 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
1669 | out_unbind: | 1657 | out_unbind: |
1670 | iwl_mvm_binding_remove_vif(mvm, vif); | 1658 | iwl_mvm_binding_remove_vif(mvm, vif); |
1671 | out_remove: | 1659 | out_remove: |
@@ -1710,7 +1698,7 @@ static void iwl_mvm_stop_ap_ibss(struct ieee80211_hw *hw, | |||
1710 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); | 1698 | iwl_mvm_mac_ctxt_changed(mvm, mvm->p2p_device_vif, false, NULL); |
1711 | 1699 | ||
1712 | iwl_mvm_update_quotas(mvm, NULL); | 1700 | iwl_mvm_update_quotas(mvm, NULL); |
1713 | iwl_mvm_send_rm_bcast_sta(mvm, &mvmvif->bcast_sta); | 1701 | iwl_mvm_send_rm_bcast_sta(mvm, vif); |
1714 | iwl_mvm_binding_remove_vif(mvm, vif); | 1702 | iwl_mvm_binding_remove_vif(mvm, vif); |
1715 | 1703 | ||
1716 | iwl_mvm_power_update_mac(mvm); | 1704 | iwl_mvm_power_update_mac(mvm); |
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.c b/drivers/net/wireless/iwlwifi/mvm/sta.c index ccfc256b710a..ef61979aa286 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.c +++ b/drivers/net/wireless/iwlwifi/mvm/sta.c | |||
@@ -558,10 +558,10 @@ int iwl_mvm_add_aux_sta(struct iwl_mvm *mvm) | |||
558 | * @vif: the interface to which the broadcast station is added | 558 | * @vif: the interface to which the broadcast station is added |
559 | * @bsta: the broadcast station to add. | 559 | * @bsta: the broadcast station to add. |
560 | */ | 560 | */ |
561 | int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 561 | int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
562 | struct iwl_mvm_int_sta *bsta) | ||
563 | { | 562 | { |
564 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 563 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
564 | struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta; | ||
565 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 565 | static const u8 _baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; |
566 | const u8 *baddr = _baddr; | 566 | const u8 *baddr = _baddr; |
567 | 567 | ||
@@ -579,19 +579,40 @@ int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | |||
579 | 579 | ||
580 | /* Send the FW a request to remove the station from it's internal data | 580 | /* Send the FW a request to remove the station from it's internal data |
581 | * structures, but DO NOT remove the entry from the local data structures. */ | 581 | * structures, but DO NOT remove the entry from the local data structures. */ |
582 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | 582 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
583 | struct iwl_mvm_int_sta *bsta) | ||
584 | { | 583 | { |
584 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
585 | int ret; | 585 | int ret; |
586 | 586 | ||
587 | lockdep_assert_held(&mvm->mutex); | 587 | lockdep_assert_held(&mvm->mutex); |
588 | 588 | ||
589 | ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); | 589 | ret = iwl_mvm_rm_sta_common(mvm, mvmvif->bcast_sta.sta_id); |
590 | if (ret) | 590 | if (ret) |
591 | IWL_WARN(mvm, "Failed sending remove station\n"); | 591 | IWL_WARN(mvm, "Failed sending remove station\n"); |
592 | return ret; | 592 | return ret; |
593 | } | 593 | } |
594 | 594 | ||
595 | int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
596 | { | ||
597 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
598 | u32 qmask; | ||
599 | |||
600 | lockdep_assert_held(&mvm->mutex); | ||
601 | |||
602 | qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | ||
603 | |||
604 | /* | ||
605 | * The firmware defines the TFD queue mask to only be relevant | ||
606 | * for *unicast* queues, so the multicast (CAB) queue shouldn't | ||
607 | * be included. | ||
608 | */ | ||
609 | if (vif->type == NL80211_IFTYPE_AP) | ||
610 | qmask &= ~BIT(vif->cab_queue); | ||
611 | |||
612 | return iwl_mvm_allocate_int_sta(mvm, &mvmvif->bcast_sta, qmask, | ||
613 | ieee80211_vif_type_p2p(vif)); | ||
614 | } | ||
615 | |||
595 | /* Allocate a new station entry for the broadcast station to the given vif, | 616 | /* Allocate a new station entry for the broadcast station to the given vif, |
596 | * and send it to the FW. | 617 | * and send it to the FW. |
597 | * Note that each P2P mac should have its own broadcast station. | 618 | * Note that each P2P mac should have its own broadcast station. |
@@ -599,45 +620,47 @@ int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | |||
599 | * @mvm: the mvm component | 620 | * @mvm: the mvm component |
600 | * @vif: the interface to which the broadcast station is added | 621 | * @vif: the interface to which the broadcast station is added |
601 | * @bsta: the broadcast station to add. */ | 622 | * @bsta: the broadcast station to add. */ |
602 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 623 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
603 | struct iwl_mvm_int_sta *bsta) | ||
604 | { | 624 | { |
605 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | 625 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); |
606 | static const u8 baddr[] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; | 626 | struct iwl_mvm_int_sta *bsta = &mvmvif->bcast_sta; |
607 | u32 qmask; | ||
608 | int ret; | 627 | int ret; |
609 | 628 | ||
610 | lockdep_assert_held(&mvm->mutex); | 629 | lockdep_assert_held(&mvm->mutex); |
611 | 630 | ||
612 | qmask = iwl_mvm_mac_get_queues_mask(mvm, vif); | 631 | ret = iwl_mvm_alloc_bcast_sta(mvm, vif); |
613 | ret = iwl_mvm_allocate_int_sta(mvm, bsta, qmask, | ||
614 | ieee80211_vif_type_p2p(vif)); | ||
615 | if (ret) | 632 | if (ret) |
616 | return ret; | 633 | return ret; |
617 | 634 | ||
618 | ret = iwl_mvm_add_int_sta_common(mvm, bsta, baddr, | 635 | ret = iwl_mvm_send_add_bcast_sta(mvm, vif); |
619 | mvmvif->id, mvmvif->color); | ||
620 | 636 | ||
621 | if (ret) | 637 | if (ret) |
622 | iwl_mvm_dealloc_int_sta(mvm, bsta); | 638 | iwl_mvm_dealloc_int_sta(mvm, bsta); |
639 | |||
623 | return ret; | 640 | return ret; |
624 | } | 641 | } |
625 | 642 | ||
643 | void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) | ||
644 | { | ||
645 | struct iwl_mvm_vif *mvmvif = iwl_mvm_vif_from_mac80211(vif); | ||
646 | |||
647 | iwl_mvm_dealloc_int_sta(mvm, &mvmvif->bcast_sta); | ||
648 | } | ||
649 | |||
626 | /* | 650 | /* |
627 | * Send the FW a request to remove the station from it's internal data | 651 | * Send the FW a request to remove the station from it's internal data |
628 | * structures, and in addition remove it from the local data structure. | 652 | * structures, and in addition remove it from the local data structure. |
629 | */ | 653 | */ |
630 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta) | 654 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif) |
631 | { | 655 | { |
632 | int ret; | 656 | int ret; |
633 | 657 | ||
634 | lockdep_assert_held(&mvm->mutex); | 658 | lockdep_assert_held(&mvm->mutex); |
635 | 659 | ||
636 | ret = iwl_mvm_rm_sta_common(mvm, bsta->sta_id); | 660 | ret = iwl_mvm_send_rm_bcast_sta(mvm, vif); |
637 | if (ret) | 661 | |
638 | return ret; | 662 | iwl_mvm_dealloc_bcast_sta(mvm, vif); |
639 | 663 | ||
640 | iwl_mvm_dealloc_int_sta(mvm, bsta); | ||
641 | return ret; | 664 | return ret; |
642 | } | 665 | } |
643 | 666 | ||
diff --git a/drivers/net/wireless/iwlwifi/mvm/sta.h b/drivers/net/wireless/iwlwifi/mvm/sta.h index ea4985eb8fa9..15984fef12b2 100644 --- a/drivers/net/wireless/iwlwifi/mvm/sta.h +++ b/drivers/net/wireless/iwlwifi/mvm/sta.h | |||
@@ -393,13 +393,14 @@ int iwl_mvm_allocate_int_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *sta, | |||
393 | u32 qmask, enum nl80211_iftype iftype); | 393 | u32 qmask, enum nl80211_iftype iftype); |
394 | void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, | 394 | void iwl_mvm_dealloc_int_sta(struct iwl_mvm *mvm, |
395 | struct iwl_mvm_int_sta *sta); | 395 | struct iwl_mvm_int_sta *sta); |
396 | int iwl_mvm_send_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 396 | |
397 | struct iwl_mvm_int_sta *bsta); | 397 | int iwl_mvm_alloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
398 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, | 398 | int iwl_mvm_send_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
399 | struct iwl_mvm_int_sta *bsta); | 399 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
400 | int iwl_mvm_add_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif, | 400 | int iwl_mvm_send_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
401 | struct iwl_mvm_int_sta *bsta); | 401 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
402 | int iwl_mvm_rm_bcast_sta(struct iwl_mvm *mvm, struct iwl_mvm_int_sta *bsta); | 402 | void iwl_mvm_dealloc_bcast_sta(struct iwl_mvm *mvm, struct ieee80211_vif *vif); |
403 | |||
403 | void iwl_mvm_sta_drained_wk(struct work_struct *wk); | 404 | void iwl_mvm_sta_drained_wk(struct work_struct *wk); |
404 | void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, | 405 | void iwl_mvm_sta_modify_ps_wake(struct iwl_mvm *mvm, |
405 | struct ieee80211_sta *sta); | 406 | struct ieee80211_sta *sta); |