* [PATCH 2/8] wifi: mt76: mt7996: fix SER reset trigger on WED reset
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
2025-03-11 10:36 ` [PATCH 3/8] wifi: mt76: mt7996: remove unnecessary key->cipher check for BIP frames Felix Fietkau
` (5 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
From: Rex Lu <rex.lu@mediatek.com>
The firmware needs a specific trigger when WED is being reset due to an
ethernet reset condition. This helps prevent further L1 SER failure.
Signed-off-by: Rex Lu <rex.lu@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt7996/mcu.h | 3 ++-
drivers/net/wireless/mediatek/mt76/mt7996/mmio.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
index bd1ba00e1bc6..5fdc47dad28c 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mcu.h
@@ -896,7 +896,8 @@ enum {
UNI_CMD_SER_SET_RECOVER_L3_TX_DISABLE,
UNI_CMD_SER_SET_RECOVER_L3_BF,
UNI_CMD_SER_SET_RECOVER_L4_MDP,
- UNI_CMD_SER_SET_RECOVER_FULL,
+ UNI_CMD_SER_SET_RECOVER_FROM_ETH,
+ UNI_CMD_SER_SET_RECOVER_FULL = 8,
UNI_CMD_SER_SET_SYSTEM_ASSERT,
/* action */
UNI_CMD_SER_ENABLE = 1,
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
index 7a8ee6c75cf2..9d37f8238746 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mmio.c
@@ -281,7 +281,7 @@ static int mt7996_mmio_wed_reset(struct mtk_wed_device *wed)
if (test_and_set_bit(MT76_STATE_WED_RESET, &mphy->state))
return -EBUSY;
- ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_TRIGGER, UNI_CMD_SER_SET_RECOVER_L1,
+ ret = mt7996_mcu_set_ser(dev, UNI_CMD_SER_TRIGGER, UNI_CMD_SER_SET_RECOVER_FROM_ETH,
mphy->band_idx);
if (ret)
goto out;
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 3/8] wifi: mt76: mt7996: remove unnecessary key->cipher check for BIP frames
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
2025-03-11 10:36 ` [PATCH 2/8] wifi: mt76: mt7996: fix SER reset trigger on WED reset Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
2025-03-11 10:36 ` [PATCH 4/8] wifi: mt76: scan: set vif offchannel link for scanning/roc Felix Fietkau
` (4 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
From: Michael-CY Lee <michael-cy.lee@mediatek.com>
The cipher type check is redundant, and there is no need to dereference the
key struct here.
Signed-off-by: Michael-CY Lee <michael-cy.lee@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt7996/mac.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 33a8049d3356..162d1552602e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -773,8 +773,7 @@ mt7996_mac_write_txwi_80211(struct mt7996_dev *dev, __le32 *txwi,
info->flags & IEEE80211_TX_CTL_USE_MINRATE)
val |= MT_TXD1_FIXED_RATE;
- if (key && multicast && ieee80211_is_robust_mgmt_frame(skb) &&
- key->cipher == WLAN_CIPHER_SUITE_AES_CMAC) {
+ if (key && multicast && ieee80211_is_robust_mgmt_frame(skb)) {
val |= MT_TXD1_BIP;
txwi[3] &= ~cpu_to_le32(MT_TXD3_PROTECT_FRAME);
}
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 4/8] wifi: mt76: scan: set vif offchannel link for scanning/roc
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
2025-03-11 10:36 ` [PATCH 2/8] wifi: mt76: mt7996: fix SER reset trigger on WED reset Felix Fietkau
2025-03-11 10:36 ` [PATCH 3/8] wifi: mt76: mt7996: remove unnecessary key->cipher check for BIP frames Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
2025-03-11 10:36 ` [PATCH 5/8] wifi: mt76: mt7996: use the correct vif " Felix Fietkau
` (3 subsequent siblings)
6 siblings, 0 replies; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
The driver needs to know what vif link to use
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/channel.c | 3 +++
drivers/net/wireless/mediatek/mt76/mt76.h | 2 ++
2 files changed, 5 insertions(+)
diff --git a/drivers/net/wireless/mediatek/mt76/channel.c b/drivers/net/wireless/mediatek/mt76/channel.c
index 6a35c6ebd823..e7b839e74290 100644
--- a/drivers/net/wireless/mediatek/mt76/channel.c
+++ b/drivers/net/wireless/mediatek/mt76/channel.c
@@ -293,6 +293,7 @@ struct mt76_vif_link *mt76_get_vif_phy_link(struct mt76_phy *phy,
kfree(mlink);
return ERR_PTR(ret);
}
+ rcu_assign_pointer(mvif->offchannel_link, mlink);
return mlink;
}
@@ -301,10 +302,12 @@ void mt76_put_vif_phy_link(struct mt76_phy *phy, struct ieee80211_vif *vif,
struct mt76_vif_link *mlink)
{
struct mt76_dev *dev = phy->dev;
+ struct mt76_vif_data *mvif = mlink->mvif;
if (IS_ERR_OR_NULL(mlink) || !mlink->offchannel)
return;
+ rcu_assign_pointer(mvif->offchannel_link, NULL);
dev->drv->vif_link_remove(phy, vif, &vif->bss_conf, mlink);
kfree(mlink);
}
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index 7596191252dc..c16a6743ad64 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -351,6 +351,7 @@ struct mt76_wcid {
u8 hw_key_idx;
u8 hw_key_idx2;
+ u8 offchannel:1;
u8 sta:1;
u8 sta_disabled:1;
u8 amsdu:1;
@@ -787,6 +788,7 @@ struct mt76_vif_link {
struct mt76_vif_data {
struct mt76_vif_link __rcu *link[IEEE80211_MLD_MAX_NUM_LINKS];
+ struct mt76_vif_link __rcu *offchannel_link;
struct mt76_phy *roc_phy;
u16 valid_links;
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 5/8] wifi: mt76: mt7996: use the correct vif link for scanning/roc
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
` (2 preceding siblings ...)
2025-03-11 10:36 ` [PATCH 4/8] wifi: mt76: scan: set vif offchannel link for scanning/roc Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
2025-03-12 2:08 ` Ping-Ke Shih
2025-03-11 10:36 ` [PATCH 6/8] mt76: only mark tx-status-failed frames as ACKed on mt76x0/2 Felix Fietkau
` (2 subsequent siblings)
6 siblings, 1 reply; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
Use the newly added offchannel_link pointer in vif data
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
.../net/wireless/mediatek/mt76/mt7996/mac.c | 40 +++++++++++++------
.../net/wireless/mediatek/mt76/mt7996/main.c | 1 +
2 files changed, 28 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
index 162d1552602e..9dfc8106ebec 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/mac.c
@@ -831,7 +831,8 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
u8 band_idx = (info->hw_queue & MT_TX_HW_QUEUE_PHY) >> 2;
u8 p_fmt, q_idx, omac_idx = 0, wmm_idx = 0;
bool is_8023 = info->flags & IEEE80211_TX_CTL_HW_80211_ENCAP;
- struct mt76_vif_link *mvif;
+ struct mt76_vif_link *mlink = NULL;
+ struct mt7996_vif *mvif;
u16 tx_count = 15;
u32 val;
bool inband_disc = !!(changed & (BSS_CHANGED_UNSOL_BCAST_PROBE_RESP |
@@ -839,11 +840,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
bool beacon = !!(changed & (BSS_CHANGED_BEACON |
BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc);
- mvif = vif ? (struct mt76_vif_link *)vif->drv_priv : NULL;
- if (mvif) {
- omac_idx = mvif->omac_idx;
- wmm_idx = mvif->wmm_idx;
- band_idx = mvif->band_idx;
+ if (vif) {
+ mvif = (struct mt7996_vif *)vif->drv_priv;
+ if (wcid->offchannel)
+ mlink = rcu_dereference(mvif->mt76.offchannel_link);
+ if (!mlink)
+ mlink = &mvif->deflink.mt76;
+ }
+
+ if (mlink) {
+ omac_idx = mlink->omac_idx;
+ wmm_idx = mlink->wmm_idx;
+ band_idx = mlink->band_idx;
}
if (inband_disc) {
@@ -909,13 +917,13 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
is_multicast_ether_addr(hdr->addr1);
u8 idx = MT7996_BASIC_RATES_TBL;
- if (mvif) {
- if (mcast && mvif->mcast_rates_idx)
- idx = mvif->mcast_rates_idx;
- else if (beacon && mvif->beacon_rates_idx)
- idx = mvif->beacon_rates_idx;
+ if (mlink) {
+ if (mcast && mlink->mcast_rates_idx)
+ idx = mlink->mcast_rates_idx;
+ else if (beacon && mlink->beacon_rates_idx)
+ idx = mlink->beacon_rates_idx;
else
- idx = mvif->basic_rates_idx;
+ idx = mlink->basic_rates_idx;
}
val = FIELD_PREP(MT_TXD6_TX_RATE, idx) | MT_TXD6_FIXED_BW;
@@ -983,8 +991,14 @@ int mt7996_tx_prepare_skb(struct mt76_dev *mdev, void *txwi_ptr,
if (vif) {
struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt76_vif_link *mlink = NULL;
- txp->fw.bss_idx = mvif->deflink.mt76.idx;
+ if (wcid->offchannel)
+ mlink = rcu_dereference(mvif->mt76.offchannel_link);
+ if (!mlink)
+ mlink = &mvif->deflink.mt76;
+
+ txp->fw.bss_idx = mlink->idx;
}
txp->fw.token = cpu_to_le16(id);
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 69dd565d8319..886b6ef3462b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -249,6 +249,7 @@ int mt7996_vif_link_add(struct mt76_phy *mphy, struct ieee80211_vif *vif,
mlink->band_idx = band_idx;
mlink->wmm_idx = vif->type == NL80211_IFTYPE_AP ? 0 : 3;
mlink->wcid = &link->sta.wcid;
+ mlink->wcid->offchannel = mlink->offchannel;
ret = mt7996_mcu_add_dev_info(phy, vif, link_conf, mlink, true);
if (ret)
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* RE: [PATCH 5/8] wifi: mt76: mt7996: use the correct vif link for scanning/roc
2025-03-11 10:36 ` [PATCH 5/8] wifi: mt76: mt7996: use the correct vif " Felix Fietkau
@ 2025-03-12 2:08 ` Ping-Ke Shih
2025-03-12 9:06 ` Felix Fietkau
0 siblings, 1 reply; 13+ messages in thread
From: Ping-Ke Shih @ 2025-03-12 2:08 UTC (permalink / raw)
To: Felix Fietkau, linux-wireless@vger.kernel.org
> @@ -839,11 +840,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
> bool beacon = !!(changed & (BSS_CHANGED_BEACON |
> BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc);
>
> - mvif = vif ? (struct mt76_vif_link *)vif->drv_priv : NULL;
> - if (mvif) {
> - omac_idx = mvif->omac_idx;
> - wmm_idx = mvif->wmm_idx;
> - band_idx = mvif->band_idx;
> + if (vif) {
> + mvif = (struct mt7996_vif *)vif->drv_priv;
> + if (wcid->offchannel)
> + mlink = rcu_dereference(mvif->mt76.offchannel_link);
need a RCU read lock?
> + if (!mlink)
> + mlink = &mvif->deflink.mt76;
> + }
> +
> + if (mlink) {
> + omac_idx = mlink->omac_idx;
> + wmm_idx = mlink->wmm_idx;
> + band_idx = mlink->band_idx;
> }
>
> if (inband_disc) {
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 5/8] wifi: mt76: mt7996: use the correct vif link for scanning/roc
2025-03-12 2:08 ` Ping-Ke Shih
@ 2025-03-12 9:06 ` Felix Fietkau
0 siblings, 0 replies; 13+ messages in thread
From: Felix Fietkau @ 2025-03-12 9:06 UTC (permalink / raw)
To: Ping-Ke Shih, linux-wireless@vger.kernel.org
On 12.03.25 03:08, Ping-Ke Shih wrote:
>> @@ -839,11 +840,18 @@ void mt7996_mac_write_txwi(struct mt7996_dev *dev, __le32 *txwi,
>> bool beacon = !!(changed & (BSS_CHANGED_BEACON |
>> BSS_CHANGED_BEACON_ENABLED)) && (!inband_disc);
>>
>> - mvif = vif ? (struct mt76_vif_link *)vif->drv_priv : NULL;
>> - if (mvif) {
>> - omac_idx = mvif->omac_idx;
>> - wmm_idx = mvif->wmm_idx;
>> - band_idx = mvif->band_idx;
>> + if (vif) {
>> + mvif = (struct mt7996_vif *)vif->drv_priv;
>> + if (wcid->offchannel)
>> + mlink = rcu_dereference(mvif->mt76.offchannel_link);
>
> need a RCU read lock?
This path can only be reached from code that already holds the RCU lock.
- Felix
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 6/8] mt76: only mark tx-status-failed frames as ACKed on mt76x0/2
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
` (3 preceding siblings ...)
2025-03-11 10:36 ` [PATCH 5/8] wifi: mt76: mt7996: use the correct vif " Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
2025-03-11 10:47 ` Felix Fietkau
2025-03-11 10:36 ` [PATCH 7/8] wifi: mt76: mt7996: implement driver specific get_txpower function Felix Fietkau
2025-03-11 10:36 ` [PATCH 8/8] wifi: mt76: scan: fix setting tx_info fields Felix Fietkau
6 siblings, 1 reply; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
The interrupt status polling is unreliable, which can cause status events
to get lost. On all newer chips, txs-timeout is an indication that the
packet was either never sent, or never acked.
Fixes issues with inactivity polling.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/mt76.h | 1 +
drivers/net/wireless/mediatek/mt76/mt76x0/pci.c | 3 ++-
drivers/net/wireless/mediatek/mt76/mt76x0/usb.c | 3 ++-
drivers/net/wireless/mediatek/mt76/mt76x2/pci.c | 3 ++-
drivers/net/wireless/mediatek/mt76/mt76x2/usb.c | 3 ++-
drivers/net/wireless/mediatek/mt76/tx.c | 3 ++-
6 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt76.h b/drivers/net/wireless/mediatek/mt76/mt76.h
index c16a6743ad64..b461273c3306 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76.h
@@ -492,6 +492,7 @@ struct mt76_hw_cap {
#define MT_DRV_RX_DMA_HDR BIT(3)
#define MT_DRV_HW_MGMT_TXQ BIT(4)
#define MT_DRV_AMSDU_OFFLOAD BIT(5)
+#define MT_DRV_IGNORE_TXS_FAILED BIT(6)
struct mt76_driver_ops {
u32 drv_flags;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
index b456ccd00d58..11c16d1fc70f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/pci.c
@@ -156,7 +156,8 @@ mt76x0e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct mt76_driver_ops drv_ops = {
.txwi_size = sizeof(struct mt76x02_txwi),
.drv_flags = MT_DRV_TX_ALIGNED4_SKBS |
- MT_DRV_SW_RX_AIRTIME,
+ MT_DRV_SW_RX_AIRTIME |
+ MT_DRV_IGNORE_TXS_FAILED,
.survey_flags = SURVEY_INFO_TIME_TX,
.update_survey = mt76x02_update_channel,
.set_channel = mt76x0_set_channel,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
index b031c500b741..90e5666c0857 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x0/usb.c
@@ -214,7 +214,8 @@ static int mt76x0u_probe(struct usb_interface *usb_intf,
const struct usb_device_id *id)
{
static const struct mt76_driver_ops drv_ops = {
- .drv_flags = MT_DRV_SW_RX_AIRTIME,
+ .drv_flags = MT_DRV_SW_RX_AIRTIME |
+ MT_DRV_IGNORE_TXS_FAILED,
.survey_flags = SURVEY_INFO_TIME_TX,
.update_survey = mt76x02_update_channel,
.set_channel = mt76x0_set_channel,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
index 727bfdd00b40..2303019670e2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/pci.c
@@ -22,7 +22,8 @@ mt76x2e_probe(struct pci_dev *pdev, const struct pci_device_id *id)
static const struct mt76_driver_ops drv_ops = {
.txwi_size = sizeof(struct mt76x02_txwi),
.drv_flags = MT_DRV_TX_ALIGNED4_SKBS |
- MT_DRV_SW_RX_AIRTIME,
+ MT_DRV_SW_RX_AIRTIME |
+ MT_DRV_IGNORE_TXS_FAILED,
.survey_flags = SURVEY_INFO_TIME_TX,
.update_survey = mt76x02_update_channel,
.set_channel = mt76x2e_set_channel,
diff --git a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
index e832ad53e239..3747f9ed31e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76x2/usb.c
@@ -29,7 +29,8 @@ static int mt76x2u_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
static const struct mt76_driver_ops drv_ops = {
- .drv_flags = MT_DRV_SW_RX_AIRTIME,
+ .drv_flags = MT_DRV_SW_RX_AIRTIME |
+ MT_DRV_IGNORE_TXS_FAILED,
.survey_flags = SURVEY_INFO_TIME_TX,
.update_survey = mt76x02_update_channel,
.set_channel = mt76x2u_set_channel,
diff --git a/drivers/net/wireless/mediatek/mt76/tx.c b/drivers/net/wireless/mediatek/mt76/tx.c
index af0c50c983ec..513916469ca2 100644
--- a/drivers/net/wireless/mediatek/mt76/tx.c
+++ b/drivers/net/wireless/mediatek/mt76/tx.c
@@ -100,7 +100,8 @@ __mt76_tx_status_skb_done(struct mt76_dev *dev, struct sk_buff *skb, u8 flags,
return;
/* Tx status can be unreliable. if it fails, mark the frame as ACKed */
- if (flags & MT_TX_CB_TXS_FAILED) {
+ if (flags & MT_TX_CB_TXS_FAILED &&
+ (dev->drv->drv_flags & MT_DRV_IGNORE_TXS_FAILED)) {
info->status.rates[0].count = 0;
info->status.rates[0].idx = -1;
info->flags |= IEEE80211_TX_STAT_ACK;
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* [PATCH 7/8] wifi: mt76: mt7996: implement driver specific get_txpower function
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
` (4 preceding siblings ...)
2025-03-11 10:36 ` [PATCH 6/8] mt76: only mark tx-status-failed frames as ACKed on mt76x0/2 Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
2025-03-11 13:55 ` Lorenzo Bianconi
2025-03-11 10:36 ` [PATCH 8/8] wifi: mt76: scan: fix setting tx_info fields Felix Fietkau
6 siblings, 1 reply; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
Fixes reporting tx power for vifs that don't have a channel context
assigned. Report the tx power of a phy that is covered by the vif's
radio mask.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
.../net/wireless/mediatek/mt76/mt7996/main.c | 27 ++++++++++++++++++-
1 file changed, 26 insertions(+), 1 deletion(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
index 886b6ef3462b..89fc3f102555 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
@@ -602,6 +602,31 @@ static void mt7996_configure_filter(struct ieee80211_hw *hw,
mutex_unlock(&dev->mt76.mutex);
}
+static int
+mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
+{
+ struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
+ struct mt7996_phy *phy = mt7996_vif_link_phy(&mvif->deflink);
+ struct mt7996_dev *dev = mt7996_hw_dev(hw);
+ struct wireless_dev *wdev;
+ int n_chains, delta, i;
+
+ if (!phy) {
+ wdev = ieee80211_vif_to_wdev(vif);
+ for (i = 0; i < hw->wiphy->n_radio; i++)
+ if (wdev->radio_mask & BIT(i))
+ phy = dev->radio_phy[i];
+
+ if (!phy)
+ return -EINVAL;
+ }
+
+ n_chains = hweight16(phy->mt76->chainmask);
+ delta = mt76_tx_power_nss_delta(n_chains);
+ *dbm = DIV_ROUND_UP(phy->mt76->txpower_cur + delta, 2);
+
+ return 0;
+}
static u8
mt7996_get_rates_table(struct mt7996_phy *phy, struct ieee80211_bss_conf *conf,
bool beacon, bool mcast)
@@ -1651,7 +1676,7 @@ const struct ieee80211_ops mt7996_ops = {
.remain_on_channel = mt76_remain_on_channel,
.cancel_remain_on_channel = mt76_cancel_remain_on_channel,
.release_buffered_frames = mt76_release_buffered_frames,
- .get_txpower = mt76_get_txpower,
+ .get_txpower = mt7996_get_txpower,
.channel_switch_beacon = mt7996_channel_switch_beacon,
.get_stats = mt7996_get_stats,
.get_et_sset_count = mt7996_get_et_sset_count,
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread* Re: [PATCH 7/8] wifi: mt76: mt7996: implement driver specific get_txpower function
2025-03-11 10:36 ` [PATCH 7/8] wifi: mt76: mt7996: implement driver specific get_txpower function Felix Fietkau
@ 2025-03-11 13:55 ` Lorenzo Bianconi
2025-03-11 14:01 ` Felix Fietkau
0 siblings, 1 reply; 13+ messages in thread
From: Lorenzo Bianconi @ 2025-03-11 13:55 UTC (permalink / raw)
To: Felix Fietkau; +Cc: linux-wireless
[-- Attachment #1: Type: text/plain, Size: 2383 bytes --]
On Mar 11, Felix Fietkau wrote:
> Fixes reporting tx power for vifs that don't have a channel context
> assigned. Report the tx power of a phy that is covered by the vif's
> radio mask.
>
> Signed-off-by: Felix Fietkau <nbd@nbd.name>
> ---
> .../net/wireless/mediatek/mt76/mt7996/main.c | 27 ++++++++++++++++++-
> 1 file changed, 26 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
> index 886b6ef3462b..89fc3f102555 100644
> --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
> @@ -602,6 +602,31 @@ static void mt7996_configure_filter(struct ieee80211_hw *hw,
> mutex_unlock(&dev->mt76.mutex);
> }
>
> +static int
> +mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
I guess the signature here should be:
static int
mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
unsigned int link_id, int *dbm)
{
}
Regards,
Lorenzo
> +{
> + struct mt7996_vif *mvif = (struct mt7996_vif *)vif->drv_priv;
> + struct mt7996_phy *phy = mt7996_vif_link_phy(&mvif->deflink);
> + struct mt7996_dev *dev = mt7996_hw_dev(hw);
> + struct wireless_dev *wdev;
> + int n_chains, delta, i;
> +
> + if (!phy) {
> + wdev = ieee80211_vif_to_wdev(vif);
> + for (i = 0; i < hw->wiphy->n_radio; i++)
> + if (wdev->radio_mask & BIT(i))
> + phy = dev->radio_phy[i];
> +
> + if (!phy)
> + return -EINVAL;
> + }
> +
> + n_chains = hweight16(phy->mt76->chainmask);
> + delta = mt76_tx_power_nss_delta(n_chains);
> + *dbm = DIV_ROUND_UP(phy->mt76->txpower_cur + delta, 2);
> +
> + return 0;
> +}
> static u8
> mt7996_get_rates_table(struct mt7996_phy *phy, struct ieee80211_bss_conf *conf,
> bool beacon, bool mcast)
> @@ -1651,7 +1676,7 @@ const struct ieee80211_ops mt7996_ops = {
> .remain_on_channel = mt76_remain_on_channel,
> .cancel_remain_on_channel = mt76_cancel_remain_on_channel,
> .release_buffered_frames = mt76_release_buffered_frames,
> - .get_txpower = mt76_get_txpower,
> + .get_txpower = mt7996_get_txpower,
> .channel_switch_beacon = mt7996_channel_switch_beacon,
> .get_stats = mt7996_get_stats,
> .get_et_sset_count = mt7996_get_et_sset_count,
> --
> 2.47.1
>
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 13+ messages in thread* Re: [PATCH 7/8] wifi: mt76: mt7996: implement driver specific get_txpower function
2025-03-11 13:55 ` Lorenzo Bianconi
@ 2025-03-11 14:01 ` Felix Fietkau
0 siblings, 0 replies; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 14:01 UTC (permalink / raw)
To: Lorenzo Bianconi; +Cc: linux-wireless
On 11.03.25 14:55, Lorenzo Bianconi wrote:
> On Mar 11, Felix Fietkau wrote:
>> Fixes reporting tx power for vifs that don't have a channel context
>> assigned. Report the tx power of a phy that is covered by the vif's
>> radio mask.
>>
>> Signed-off-by: Felix Fietkau <nbd@nbd.name>
>> ---
>> .../net/wireless/mediatek/mt76/mt7996/main.c | 27 ++++++++++++++++++-
>> 1 file changed, 26 insertions(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/mediatek/mt76/mt7996/main.c b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
>> index 886b6ef3462b..89fc3f102555 100644
>> --- a/drivers/net/wireless/mediatek/mt76/mt7996/main.c
>> +++ b/drivers/net/wireless/mediatek/mt76/mt7996/main.c
>> @@ -602,6 +602,31 @@ static void mt7996_configure_filter(struct ieee80211_hw *hw,
>> mutex_unlock(&dev->mt76.mutex);
>> }
>>
>> +static int
>> +mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif, int *dbm)
>
> I guess the signature here should be:
>
> static int
> mt7996_get_txpower(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
> unsigned int link_id, int *dbm)
> {
> }
Will fix, thanks.
- Felix
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 8/8] wifi: mt76: scan: fix setting tx_info fields
2025-03-11 10:36 [PATCH 1/8] wifi: mt76: mt7996: revise TXS size Felix Fietkau
` (5 preceding siblings ...)
2025-03-11 10:36 ` [PATCH 7/8] wifi: mt76: mt7996: implement driver specific get_txpower function Felix Fietkau
@ 2025-03-11 10:36 ` Felix Fietkau
6 siblings, 0 replies; 13+ messages in thread
From: Felix Fietkau @ 2025-03-11 10:36 UTC (permalink / raw)
To: linux-wireless
ieee80211_tx_prepare_skb initializes the skb cb, so fields need to be set
afterwards.
Signed-off-by: Felix Fietkau <nbd@nbd.name>
---
drivers/net/wireless/mediatek/mt76/scan.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/scan.c b/drivers/net/wireless/mediatek/mt76/scan.c
index 1c4f9deaaada..9b20ccbeb8cf 100644
--- a/drivers/net/wireless/mediatek/mt76/scan.c
+++ b/drivers/net/wireless/mediatek/mt76/scan.c
@@ -52,11 +52,6 @@ mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)
ether_addr_copy(hdr->addr3, req->bssid);
}
- info = IEEE80211_SKB_CB(skb);
- if (req->no_cck)
- info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
- info->control.flags |= IEEE80211_TX_CTRL_DONT_USE_RATE_MASK;
-
if (req->ie_len)
skb_put_data(skb, req->ie, req->ie_len);
@@ -64,10 +59,20 @@ mt76_scan_send_probe(struct mt76_dev *dev, struct cfg80211_ssid *ssid)
skb_set_queue_mapping(skb, IEEE80211_AC_VO);
rcu_read_lock();
- if (ieee80211_tx_prepare_skb(phy->hw, vif, skb, band, NULL))
- mt76_tx(phy, NULL, mvif->wcid, skb);
- else
+
+ if (!ieee80211_tx_prepare_skb(phy->hw, vif, skb, band, NULL)) {
ieee80211_free_txskb(phy->hw, skb);
+ goto out;
+ }
+
+ info = IEEE80211_SKB_CB(skb);
+ if (req->no_cck)
+ info->flags |= IEEE80211_TX_CTL_NO_CCK_RATE;
+ info->control.flags |= IEEE80211_TX_CTRL_DONT_USE_RATE_MASK;
+
+ mt76_tx(phy, NULL, mvif->wcid, skb);
+
+out:
rcu_read_unlock();
}
--
2.47.1
^ permalink raw reply related [flat|nested] 13+ messages in thread