summaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDeren Wu <deren.wu@mediatek.com>2022-06-08 20:53:26 +0800
committerFelix Fietkau <nbd@nbd.name>2022-07-11 13:40:01 +0200
commit9d958b60ebc2434f2b7eae83d77849e22d1059eb (patch)
treed6d74839a33426a2b3c7d0b1a719feed9e67ad88 /drivers
parentc149d3a9058616ff942a6e44b6e968e18a84dd5a (diff)
downloadlinux-9d958b60ebc2434f2b7eae83d77849e22d1059eb.tar.bz2
mt76: mt7921: fix command timeout in AP stop period
Due to AP stop improperly, mt7921 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 Fixes: 116c69603b01 ("mt76: mt7921: Add AP mode support") Signed-off-by: Sean Wang <sean.wang@mediatek.com> Signed-off-by: Deren Wu <deren.wu@mediatek.com> Signed-off-by: Felix Fietkau <nbd@nbd.name>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c2
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/main.c49
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mcu.c5
-rw-r--r--drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h2
4 files changed, 45 insertions, 13 deletions
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index a963e51b7271..8c9b0f0b5c39 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1404,6 +1404,8 @@ int mt76_connac_mcu_uni_add_bss(struct mt76_phy *phy,
else
conn_type = CONNECTION_INFRA_AP;
basic_req.basic.conn_type = cpu_to_le32(conn_type);
+ /* Fully active/deactivate BSS network in AP mode only */
+ basic_req.basic.active = enable;
break;
case NL80211_IFTYPE_STATION:
if (vif->p2p)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 5163704356d8..4be488da0117 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -653,15 +653,6 @@ static void mt7921_bss_info_changed(struct ieee80211_hw *hw,
}
}
- if (changed & BSS_CHANGED_BEACON_ENABLED && info->enable_beacon) {
- struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
-
- mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
- true);
- mt7921_mcu_sta_update(dev, NULL, vif, true,
- MT76_STA_INFO_STATE_NONE);
- }
-
if (changed & (BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED))
mt7921_mcu_uni_add_beacon_offload(dev, hw, vif,
@@ -1513,6 +1504,44 @@ mt7921_channel_switch_beacon(struct ieee80211_hw *hw,
mt7921_mutex_release(dev);
}
+static int
+mt7921_start_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ unsigned int link_id)
+{
+ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+ struct mt7921_phy *phy = mt7921_hw_phy(hw);
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ int err;
+
+ err = mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid,
+ true);
+ if (err)
+ return err;
+
+ err = mt7921_mcu_set_bss_pm(dev, vif, true);
+ if (err)
+ return err;
+
+ return mt7921_mcu_sta_update(dev, NULL, vif, true,
+ MT76_STA_INFO_STATE_NONE);
+}
+
+static void
+mt7921_stop_ap(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ unsigned int link_id)
+{
+ struct mt7921_vif *mvif = (struct mt7921_vif *)vif->drv_priv;
+ struct mt7921_phy *phy = mt7921_hw_phy(hw);
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+ int err;
+
+ err = mt7921_mcu_set_bss_pm(dev, vif, false);
+ if (err)
+ return;
+
+ mt76_connac_mcu_uni_add_bss(phy->mt76, vif, &mvif->sta.wcid, false);
+}
+
const struct ieee80211_ops mt7921_ops = {
.tx = mt7921_tx,
.start = mt7921_start,
@@ -1523,6 +1552,8 @@ const struct ieee80211_ops mt7921_ops = {
.conf_tx = mt7921_conf_tx,
.configure_filter = mt7921_configure_filter,
.bss_info_changed = mt7921_bss_info_changed,
+ .start_ap = mt7921_start_ap,
+ .stop_ap = mt7921_stop_ap,
.sta_state = mt7921_sta_state,
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
.set_key = mt7921_set_key,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index b8e5f550b4d4..bc434e60dfc6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -745,7 +745,7 @@ mt7921_mcu_uni_bss_bcnft(struct mt7921_dev *dev, struct ieee80211_vif *vif,
&bcnft_req, sizeof(bcnft_req), true);
}
-static int
+int
mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
bool enable)
{
@@ -774,9 +774,6 @@ mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
};
int err;
- if (vif->type != NL80211_IFTYPE_STATION)
- return 0;
-
err = mt76_mcu_send_msg(&dev->mt76, MCU_CE_CMD(SET_BSS_ABORT),
&req_hdr, sizeof(req_hdr), false);
if (err < 0 || !enable)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index 7da29fadc27f..f7609c8ac549 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -284,6 +284,8 @@ int mt7921_wpdma_reset(struct mt7921_dev *dev, bool force);
int mt7921_wpdma_reinit_cond(struct mt7921_dev *dev);
void mt7921_dma_cleanup(struct mt7921_dev *dev);
int mt7921_run_firmware(struct mt7921_dev *dev);
+int mt7921_mcu_set_bss_pm(struct mt7921_dev *dev, struct ieee80211_vif *vif,
+ bool enable);
int mt7921_mcu_sta_update(struct mt7921_dev *dev, struct ieee80211_sta *sta,
struct ieee80211_vif *vif, bool enable,
enum mt76_sta_info_state state);