From: Sean Wang <[email protected]>
WiFi subsytem reset should control MT_WFSYS_SW_RST_B and then poll the
same register until the bit WFSYS_SW_INIT_DONE bit is set.
Fixes: 0c1ce9884607 ("mt76: mt7921: add wifi reset support")
Reviewed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7921/dma.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
index 71e664ee7652..bd9143dc865f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/dma.c
@@ -313,9 +313,9 @@ static int mt7921_dma_reset(struct mt7921_dev *dev, bool force)
int mt7921_wfsys_reset(struct mt7921_dev *dev)
{
- mt76_set(dev, 0x70002600, BIT(0));
- msleep(200);
- mt76_clear(dev, 0x70002600, BIT(0));
+ mt76_clear(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B);
+ msleep(50);
+ mt76_set(dev, MT_WFSYS_SW_RST_B, WFSYS_SW_RST_B);
if (!__mt76_poll_msec(&dev->mt76, MT_WFSYS_SW_RST_B,
WFSYS_SW_INIT_DONE, WFSYS_SW_INIT_DONE, 500))
--
2.25.1
From: Sean Wang <[email protected]>
Add addtional the deep sleep control to runtime-pm knob to
allow us to control driver switching between the full power
mode and the deep sleep mode the firmware is able to support.
Reviewed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
---
.../wireless/mediatek/mt76/mt7921/debugfs.c | 18 ++++++++++++++++++
1 file changed, 18 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
index 6ee423dd4027..b41d70be948b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/debugfs.c
@@ -247,6 +247,9 @@ mt7921_pm_set(void *data, u64 val)
ieee80211_iterate_active_interfaces(mphy->hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
mt7921_pm_interface_iter, mphy->priv);
+
+ mt76_connac_mcu_set_deep_sleep(&dev->mt76, !!pm->enable);
+
mt7921_mutex_release(dev);
return 0;
@@ -264,6 +267,20 @@ mt7921_pm_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(fops_pm, mt7921_pm_get, mt7921_pm_set, "%lld\n");
+static int
+mt7921_deep_sleep_set(void *data, u64 val)
+{
+ struct mt7921_dev *dev = data;
+
+ mt7921_mutex_acquire(dev);
+ mt76_connac_mcu_set_deep_sleep(&dev->mt76, !!val);
+ mt7921_mutex_release(dev);
+
+ return 0;
+}
+
+DEFINE_DEBUGFS_ATTRIBUTE(fops_ds, NULL, mt7921_deep_sleep_set, "%lld\n");
+
static int
mt7921_pm_stats(struct seq_file *s, void *data)
{
@@ -355,6 +372,7 @@ int mt7921_init_debugfs(struct mt7921_dev *dev)
debugfs_create_file("chip_reset", 0600, dir, dev, &fops_reset);
debugfs_create_devm_seqfile(dev->mt76.dev, "runtime_pm_stats", dir,
mt7921_pm_stats);
+ debugfs_create_file("deep-sleep", 0600, dir, dev, &fops_ds);
return 0;
}
--
2.25.1
From: Sean Wang <[email protected]>
Keep Rx path classifier the mt7921 firmware prefers to allow frames pass
through MCU.
Fixes: 5c14a5f944b9 ("mt76: mt7921: introduce mt7921e support")
Reviewed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7921/init.c | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index 1d4ba5d0166a..6947d98287c0 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -118,30 +118,12 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
static void
mt7921_mac_init_band(struct mt7921_dev *dev, u8 band)
{
- u32 mask, set;
-
mt76_rmw_field(dev, MT_TMAC_CTCR0(band),
MT_TMAC_CTCR0_INS_DDLMT_REFTIME, 0x3f);
mt76_set(dev, MT_TMAC_CTCR0(band),
MT_TMAC_CTCR0_INS_DDLMT_VHT_SMPDU_EN |
MT_TMAC_CTCR0_INS_DDLMT_EN);
- mask = MT_MDP_RCFR0_MCU_RX_MGMT |
- MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR |
- MT_MDP_RCFR0_MCU_RX_CTL_BAR;
- set = FIELD_PREP(MT_MDP_RCFR0_MCU_RX_MGMT, MT_MDP_TO_HIF) |
- FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_NON_BAR, MT_MDP_TO_HIF) |
- FIELD_PREP(MT_MDP_RCFR0_MCU_RX_CTL_BAR, MT_MDP_TO_HIF);
- mt76_rmw(dev, MT_MDP_BNRCFR0(band), mask, set);
-
- mask = MT_MDP_RCFR1_MCU_RX_BYPASS |
- MT_MDP_RCFR1_RX_DROPPED_UCAST |
- MT_MDP_RCFR1_RX_DROPPED_MCAST;
- set = FIELD_PREP(MT_MDP_RCFR1_MCU_RX_BYPASS, MT_MDP_TO_HIF) |
- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_UCAST, MT_MDP_TO_HIF) |
- FIELD_PREP(MT_MDP_RCFR1_RX_DROPPED_MCAST, MT_MDP_TO_HIF);
- mt76_rmw(dev, MT_MDP_BNRCFR1(band), mask, set);
-
mt76_set(dev, MT_WF_RMAC_MIB_TIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
mt76_set(dev, MT_WF_RMAC_MIB_AIRTIME0(band), MT_WF_RMAC_MIB_RXTIME_EN);
--
2.25.1
From: Sean Wang <[email protected]>
Hw beacon cmd to the mt7921 firmware doesn't only filter out the beacon,
but also performs its own connection monitoring, including periodic
keep-alives to the AP and probing the AP on beacon loss. Will indicate
the host with the event when the firmware detects the connection is lost.
Fixes: 1d8efc741df8 ("mt76: mt7921: introduce Runtime PM support")
Reviewed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Deren Wu <[email protected]>
Signed-off-by: YN Chen <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7921/init.c | 4 +++
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 32 +++++++++++++------
2 files changed, 27 insertions(+), 9 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index cd68721314fa..cbb1d432a591 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -73,6 +73,7 @@ static void
mt7921_init_wiphy(struct ieee80211_hw *hw)
{
struct mt7921_phy *phy = mt7921_hw_phy(hw);
+ struct mt7921_dev *dev = phy->dev;
struct wiphy *wiphy = hw->wiphy;
hw->queues = 4;
@@ -112,6 +113,9 @@ mt7921_init_wiphy(struct ieee80211_hw *hw)
ieee80211_hw_set(hw, SUPPORTS_PS);
ieee80211_hw_set(hw, SUPPORTS_DYNAMIC_PS);
+ if (dev->pm.enable)
+ ieee80211_hw_set(hw, CONNECTION_MONITOR);
+
hw->max_tx_fragments = 4;
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 67dc4b4cc094..7c68182cad55 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -450,22 +450,33 @@ mt7921_mcu_scan_event(struct mt7921_dev *dev, struct sk_buff *skb)
}
static void
-mt7921_mcu_beacon_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
+mt7921_mcu_connection_loss_iter(void *priv, u8 *mac,
+ struct ieee80211_vif *vif)
+{
+ struct mt76_vif *mvif = (struct mt76_vif *)vif->drv_priv;
+ struct mt76_connac_beacon_loss_event *event = priv;
+
+ if (mvif->idx != event->bss_idx)
+ return;
+
+ if (!(vif->driver_flags & IEEE80211_VIF_BEACON_FILTER))
+ return;
+
+ ieee80211_connection_loss(vif);
+}
+
+static void
+mt7921_mcu_connection_loss_event(struct mt7921_dev *dev, struct sk_buff *skb)
{
struct mt76_connac_beacon_loss_event *event;
- struct mt76_phy *mphy;
- u8 band_idx = 0; /* DBDC support */
+ struct mt76_phy *mphy = &dev->mt76.phy;
skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
event = (struct mt76_connac_beacon_loss_event *)skb->data;
- if (band_idx && dev->mt76.phy2)
- mphy = dev->mt76.phy2;
- else
- mphy = &dev->mt76.phy;
ieee80211_iterate_active_interfaces_atomic(mphy->hw,
IEEE80211_IFACE_ITER_RESUME_ALL,
- mt76_connac_mcu_beacon_loss_iter, event);
+ mt7921_mcu_connection_loss_iter, event);
}
static void
@@ -530,7 +541,7 @@ mt7921_mcu_rx_unsolicited_event(struct mt7921_dev *dev, struct sk_buff *skb)
switch (rxd->eid) {
case MCU_EVENT_BSS_BEACON_LOSS:
- mt7921_mcu_beacon_loss_event(dev, skb);
+ mt7921_mcu_connection_loss_event(dev, skb);
break;
case MCU_EVENT_SCHED_SCAN_DONE:
case MCU_EVENT_SCAN_DONE:
@@ -1368,6 +1379,7 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
{
struct mt7921_phy *phy = priv;
struct mt7921_dev *dev = phy->dev;
+ struct ieee80211_hw *hw = mt76_hw(dev);
int ret;
if (dev->pm.enable)
@@ -1380,9 +1392,11 @@ mt7921_pm_interface_iter(void *priv, u8 *mac, struct ieee80211_vif *vif)
if (dev->pm.enable) {
vif->driver_flags |= IEEE80211_VIF_BEACON_FILTER;
+ ieee80211_hw_set(hw, CONNECTION_MONITOR);
mt76_set(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
} else {
vif->driver_flags &= ~IEEE80211_VIF_BEACON_FILTER;
+ __clear_bit(IEEE80211_HW_CONNECTION_MONITOR, hw->flags);
mt76_clear(dev, MT_WF_RFCR(0), MT_WF_RFCR_DROP_OTHER_BEACON);
}
}
--
2.25.1
From: Sean Wang <[email protected]>
It is possible the RCPI from the certain antenna is an invalid value,
especially packets are receiving while the system is frequently entering
deep sleep mode, so consider calculating RSSI with the reasonable upper
bound to avoid report the wrong value to the mac80211 layer.
Fixes: 163f4d22c118 ("mt76: mt7921: add MAC support")
Reviewed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 44b8918db95b..89a09381cfe4 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -461,16 +461,19 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
status->chain_signal[1] = to_rssi(MT_PRXV_RCPI1, v1);
status->chain_signal[2] = to_rssi(MT_PRXV_RCPI2, v1);
status->chain_signal[3] = to_rssi(MT_PRXV_RCPI3, v1);
- status->signal = status->chain_signal[0];
-
- for (i = 1; i < hweight8(mphy->antenna_mask); i++) {
- if (!(status->chains & BIT(i)))
+ status->signal = -128;
+ for (i = 0; i < hweight8(mphy->antenna_mask); i++) {
+ if (!(status->chains & BIT(i)) ||
+ status->chain_signal[i] >= 0)
continue;
status->signal = max(status->signal,
status->chain_signal[i]);
}
+ if (status->signal == -128)
+ status->flag |= RX_FLAG_NO_SIGNAL_VAL;
+
stbc = FIELD_GET(MT_PRXV_STBC, v0);
gi = FIELD_GET(MT_PRXV_SGI, v0);
cck = false;
--
2.25.1
From: Sean Wang <[email protected]>
Enable the deep sleep mode with that firmware is able to trap into
the doze state at runtime to reduce the power consumption further.
The deep sleep mode is not allowed in the STA state transition with
the firmware to have the fast connection experience as we've done in
the full power mode
Reviewed-by: Lorenzo Bianconi <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
---
.../wireless/mediatek/mt76/mt76_connac_mcu.c | 20 +++++++++++++
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 3 ++
.../net/wireless/mediatek/mt76/mt7921/init.c | 6 +++-
.../net/wireless/mediatek/mt76/mt7921/main.c | 28 +++++++++++++++++--
4 files changed, 54 insertions(+), 3 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 7b8f8e6f431d..542d7d9f1f52 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1596,6 +1596,26 @@ int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable)
}
EXPORT_SYMBOL_GPL(mt76_connac_mcu_set_deep_sleep);
+int mt76_connac_sta_state_dp(struct mt76_dev *dev,
+ enum ieee80211_sta_state old_state,
+ enum ieee80211_sta_state new_state)
+{
+ if ((old_state == IEEE80211_STA_ASSOC &&
+ new_state == IEEE80211_STA_AUTHORIZED) ||
+ (old_state == IEEE80211_STA_NONE &&
+ new_state == IEEE80211_STA_NOTEXIST))
+ mt76_connac_mcu_set_deep_sleep(dev, true);
+
+ if ((old_state == IEEE80211_STA_NOTEXIST &&
+ new_state == IEEE80211_STA_NONE) ||
+ (old_state == IEEE80211_STA_AUTHORIZED &&
+ new_state == IEEE80211_STA_ASSOC))
+ mt76_connac_mcu_set_deep_sleep(dev, false);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(mt76_connac_sta_state_dp);
+
void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
struct mt76_connac_coredump *coredump)
{
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 01fc9f2c2f4a..3ed2fb5e1389 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -1032,6 +1032,9 @@ int mt76_connac_mcu_update_gtk_rekey(struct ieee80211_hw *hw,
int mt76_connac_mcu_set_hif_suspend(struct mt76_dev *dev, bool suspend);
void mt76_connac_mcu_set_suspend_iter(void *priv, u8 *mac,
struct ieee80211_vif *vif);
+int mt76_connac_sta_state_dp(struct mt76_dev *dev,
+ enum ieee80211_sta_state old_state,
+ enum ieee80211_sta_state new_state);
int mt76_connac_mcu_chip_config(struct mt76_dev *dev);
int mt76_connac_mcu_set_deep_sleep(struct mt76_dev *dev, bool enable);
void mt76_connac_mcu_coredump_event(struct mt76_dev *dev, struct sk_buff *skb,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/init.c b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
index 6947d98287c0..cd68721314fa 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/init.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/init.c
@@ -250,7 +250,11 @@ int mt7921_register_device(struct mt7921_dev *dev)
if (ret)
return ret;
- return mt7921_init_debugfs(dev);
+ ret = mt7921_init_debugfs(dev);
+ if (ret)
+ return ret;
+
+ return mt76_connac_mcu_set_deep_sleep(&dev->mt76, dev->pm.enable);
}
void mt7921_unregister_device(struct mt7921_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
index 39b3e769925e..5dbccbefe047 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
@@ -848,6 +848,31 @@ mt7921_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
IEEE80211_STA_NOTEXIST);
}
+static int mt7921_sta_state(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta,
+ enum ieee80211_sta_state old_state,
+ enum ieee80211_sta_state new_state)
+{
+ struct mt7921_dev *dev = mt7921_hw_dev(hw);
+
+ if (dev->pm.enable) {
+ mt7921_mutex_acquire(dev);
+ mt76_connac_sta_state_dp(&dev->mt76, old_state, new_state);
+ mt7921_mutex_release(dev);
+ }
+
+ if (old_state == IEEE80211_STA_AUTH &&
+ new_state == IEEE80211_STA_ASSOC) {
+ return mt7921_sta_add(hw, vif, sta);
+ } else if (old_state == IEEE80211_STA_ASSOC &&
+ new_state == IEEE80211_STA_AUTH) {
+ return mt7921_sta_remove(hw, vif, sta);
+ }
+
+ return 0;
+}
+
static int
mt7921_get_stats(struct ieee80211_hw *hw,
struct ieee80211_low_level_stats *stats)
@@ -1191,8 +1216,7 @@ const struct ieee80211_ops mt7921_ops = {
.conf_tx = mt7921_conf_tx,
.configure_filter = mt7921_configure_filter,
.bss_info_changed = mt7921_bss_info_changed,
- .sta_add = mt7921_sta_add,
- .sta_remove = mt7921_sta_remove,
+ .sta_state = mt7921_sta_state,
.sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
.set_key = mt7921_set_key,
.sta_set_decap_offload = mt7921_sta_set_decap_offload,
--
2.25.1
On 2021-05-10 17:14, [email protected] wrote:
> From: Sean Wang <[email protected]>
>
> Hw beacon cmd to the mt7921 firmware doesn't only filter out the beacon,
> but also performs its own connection monitoring, including periodic
> keep-alives to the AP and probing the AP on beacon loss. Will indicate
> the host with the event when the firmware detects the connection is lost.
>
> Fixes: 1d8efc741df8 ("mt76: mt7921: introduce Runtime PM support")
> Reviewed-by: Lorenzo Bianconi <[email protected]>
> Signed-off-by: Deren Wu <[email protected]>
> Signed-off-by: YN Chen <[email protected]>
> Signed-off-by: Sean Wang <[email protected]>
What happened to Patch 8?
I don't see it on the list or patchwork.
- Felix
From: Sean Wang <[email protected]>
>On 2021-05-10 17:14, [email protected] wrote:
>> From: Sean Wang <[email protected]>
>>
>> Hw beacon cmd to the mt7921 firmware doesn't only filter out the
>> beacon, but also performs its own connection monitoring, including
>> periodic keep-alives to the AP and probing the AP on beacon loss. Will
>> indicate the host with the event when the firmware detects the connection is lost.
>>
>> Fixes: 1d8efc741df8 ("mt76: mt7921: introduce Runtime PM support")
>> Reviewed-by: Lorenzo Bianconi <[email protected]>
>> Signed-off-by: Deren Wu <[email protected]>
>> Signed-off-by: YN Chen <[email protected]>
>> Signed-off-by: Sean Wang <[email protected]>
>What happened to Patch 8?
>I don't see it on the list or patchwork.
I've sent again the patch 8. Please help take a look.
>
>
>- Felix
Hi Sean,
On 2021-05-10 17:14, [email protected] wrote:
> From: Sean Wang <[email protected]>
>
> Enable the deep sleep mode with that firmware is able to trap into
> the doze state at runtime to reduce the power consumption further.
>
> The deep sleep mode is not allowed in the STA state transition with
> the firmware to have the fast connection experience as we've done in
> the full power mode
>
> Reviewed-by: Lorenzo Bianconi <[email protected]>
> Signed-off-by: Sean Wang <[email protected]>
> ---
> .../wireless/mediatek/mt76/mt76_connac_mcu.c | 20 +++++++++++++
> .../wireless/mediatek/mt76/mt76_connac_mcu.h | 3 ++
> .../net/wireless/mediatek/mt76/mt7921/init.c | 6 +++-
> .../net/wireless/mediatek/mt76/mt7921/main.c | 28 +++++++++++++++++--
> 4 files changed, 54 insertions(+), 3 deletions(-)
>
> void mt7921_unregister_device(struct mt7921_dev *dev)
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/main.c b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
> index 39b3e769925e..5dbccbefe047 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7921/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7921/main.c
> @@ -848,6 +848,31 @@ mt7921_sta_remove(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
> IEEE80211_STA_NOTEXIST);
> }
>
> +static int mt7921_sta_state(struct ieee80211_hw *hw,
> + struct ieee80211_vif *vif,
> + struct ieee80211_sta *sta,
> + enum ieee80211_sta_state old_state,
> + enum ieee80211_sta_state new_state)
> +{
> + struct mt7921_dev *dev = mt7921_hw_dev(hw);
> +
> + if (dev->pm.enable) {
> + mt7921_mutex_acquire(dev);
> + mt76_connac_sta_state_dp(&dev->mt76, old_state, new_state);
> + mt7921_mutex_release(dev);
> + }
> +
> + if (old_state == IEEE80211_STA_AUTH &&
> + new_state == IEEE80211_STA_ASSOC) {
> + return mt7921_sta_add(hw, vif, sta);
> + } else if (old_state == IEEE80211_STA_ASSOC &&
> + new_state == IEEE80211_STA_AUTH) {
> + return mt7921_sta_remove(hw, vif, sta);
> + }
> +
> + return 0;
> +}
> +
> static int
> mt7921_get_stats(struct ieee80211_hw *hw,
> struct ieee80211_low_level_stats *stats)
> @@ -1191,8 +1216,7 @@ const struct ieee80211_ops mt7921_ops = {
> .conf_tx = mt7921_conf_tx,
> .configure_filter = mt7921_configure_filter,
> .bss_info_changed = mt7921_bss_info_changed,
> - .sta_add = mt7921_sta_add,
> - .sta_remove = mt7921_sta_remove,
> + .sta_state = mt7921_sta_state,
> .sta_pre_rcu_remove = mt76_sta_pre_rcu_remove,
> .set_key = mt7921_set_key,
> .sta_set_decap_offload = mt7921_sta_set_decap_offload,
Unfortunately, we can't switch from sta_add/remove to .sta_state here.
When .sta_state is implemented, mac80211 assumes that the station entry
is usable after the NOTEXIST->NONE transition, while the driver state is
only created after the AUTH->ASSOC transition.
Can you please send a fix, or a replacement patch?
Thanks,
- Felix