wifi: mt76: mt7915: fix command timeout in AP stop period
authorRany Hany <rany_hany@riseup.net>
Sun, 28 May 2023 18:04:28 +0000 (21:04 +0300)
committerFelix Fietkau <nbd@nbd.name>
Tue, 25 Jul 2023 19:59:41 +0000 (21:59 +0200)
Due to AP stop improperly, mt7915 driver would face random command timeout
by chip fw problem. Migrate AP start/stop process to .start_ap/.stop_ap and
congiure BSS network settings in both hooks.

The new flow is shown below.
* AP start
    .start_ap()
      configure BSS network resource
      set BSS to connected state
    .bss_info_changed()
      enable fw beacon offload

* AP stop
    .bss_info_changed()
      disable fw beacon offload (skip this command)
    .stop_ap()
      set BSS to disconnected state (beacon offload disabled automatically)
      destroy BSS network resource

Based on "mt76: mt7921: fix command timeout in AP stop period"

Signed-off-by: Rany Hany <rany_hany@riseup.net>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7915/main.c

index 64c0273..679397d 100644 (file)
@@ -599,6 +599,7 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
 {
        struct mt7915_phy *phy = mt7915_hw_phy(hw);
        struct mt7915_dev *dev = mt7915_hw_dev(hw);
+       int set_bss_info = -1, set_sta = -1;
 
        mutex_lock(&dev->mt76.mutex);
 
@@ -607,15 +608,18 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
         * and then peer references bss_info_rfch to set bandwidth cap.
         */
        if (changed & BSS_CHANGED_BSSID &&
-           vif->type == NL80211_IFTYPE_STATION) {
-               bool join = !is_zero_ether_addr(info->bssid);
-
-               mt7915_mcu_add_bss_info(phy, vif, join);
-               mt7915_mcu_add_sta(dev, vif, NULL, join);
-       }
-
+           vif->type == NL80211_IFTYPE_STATION)
+               set_bss_info = set_sta = !is_zero_ether_addr(info->bssid);
        if (changed & BSS_CHANGED_ASSOC)
-               mt7915_mcu_add_bss_info(phy, vif, vif->cfg.assoc);
+               set_bss_info = vif->cfg.assoc;
+       if (changed & BSS_CHANGED_BEACON_ENABLED &&
+           vif->type != NL80211_IFTYPE_AP)
+               set_bss_info = set_sta = info->enable_beacon;
+
+       if (set_bss_info == 1)
+               mt7915_mcu_add_bss_info(phy, vif, true);
+       if (set_sta == 1)
+               mt7915_mcu_add_sta(dev, vif, NULL, true);
 
        if (changed & BSS_CHANGED_ERP_CTS_PROT)
                mt7915_mac_enable_rtscts(dev, vif, info->use_cts_prot);
@@ -629,11 +633,6 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
                }
        }
 
-       if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
-               mt7915_mcu_add_bss_info(phy, vif, true);
-               mt7915_mcu_add_sta(dev, vif, NULL, true);
-       }
-
        /* ensure that enable txcmd_mode after bss_info */
        if (changed & (BSS_CHANGED_QOS | BSS_CHANGED_BEACON_ENABLED))
                mt7915_mcu_set_tx(dev, vif);
@@ -650,6 +649,42 @@ static void mt7915_bss_info_changed(struct ieee80211_hw *hw,
                       BSS_CHANGED_FILS_DISCOVERY))
                mt7915_mcu_add_beacon(hw, vif, info->enable_beacon, changed);
 
+       if (set_bss_info == 0)
+               mt7915_mcu_add_bss_info(phy, vif, false);
+       if (set_sta == 0)
+               mt7915_mcu_add_sta(dev, vif, NULL, false);
+
+       mutex_unlock(&dev->mt76.mutex);
+}
+
+static int
+mt7915_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+               struct ieee80211_bss_conf *link_conf)
+{
+       struct mt7915_phy *phy = mt7915_hw_phy(hw);
+       struct mt7915_dev *dev = mt7915_hw_dev(hw);
+       int err;
+
+       mutex_lock(&dev->mt76.mutex);
+
+       err = mt7915_mcu_add_bss_info(phy, vif, true);
+       if (err)
+               goto out;
+       err = mt7915_mcu_add_sta(dev, vif, NULL, true);
+out:
+       mutex_unlock(&dev->mt76.mutex);
+
+       return err;
+}
+
+static void
+mt7915_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+              struct ieee80211_bss_conf *link_conf)
+{
+       struct mt7915_dev *dev = mt7915_hw_dev(hw);
+
+       mutex_lock(&dev->mt76.mutex);
+       mt7915_mcu_add_sta(dev, vif, NULL, false);
        mutex_unlock(&dev->mt76.mutex);
 }
 
@@ -1594,6 +1629,8 @@ const struct ieee80211_ops mt7915_ops = {
        .conf_tx = mt7915_conf_tx,
        .configure_filter = mt7915_configure_filter,
        .bss_info_changed = mt7915_bss_info_changed,
+       .start_ap = mt7915_start_ap,
+       .stop_ap = mt7915_stop_ap,
        .sta_add = mt7915_sta_add,
        .sta_remove = mt7915_sta_remove,
        .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,