2021-02-19 17:32:00

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 0/8] mt76: mt7921: multiple fixes

Align mt7921 driver to fw APIs available in linux-firmware.
Fix uninitialized pointer access.
Fix memory leak in mt7921_coredump_work
Fix suspend/resume sequence.

Changes since v1:
- drop unused variable reading rx stats
- fix suspend/resume sequence patch
- fix memory leak in mt7921_coredump_work patch

Sean Wang (8):
mt76: mt7921: fix suspend/resume sequence
mt76: mt7921: fix memory leak in mt7921_coredump_work
mt76: mt7921: switch to new api for hardware beacon filter
mt76: connac: fix up the setting for ht40 mode in
mt76_connac_mcu_uni_add_bss
mt76: mt7921: fixup rx bitrate statistics
mt76: mt7921: add flush operation
mt76: mt7921: fix uninitialized pointer access in mt7921_get_wtbl_info
mt76: connac: update sched_scan cmd usage

.../wireless/mediatek/mt76/mt7615/mt7615.h | 5 -
.../net/wireless/mediatek/mt76/mt76_connac.h | 5 +
.../wireless/mediatek/mt76/mt76_connac_mcu.c | 9 +-
.../wireless/mediatek/mt76/mt76_connac_mcu.h | 14 +-
.../net/wireless/mediatek/mt76/mt7921/mac.c | 161 +++++++++---------
.../net/wireless/mediatek/mt76/mt7921/mac.h | 10 +-
.../net/wireless/mediatek/mt76/mt7921/main.c | 59 +++++--
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 13 +-
.../net/wireless/mediatek/mt76/mt7921/pci.c | 14 +-
9 files changed, 172 insertions(+), 118 deletions(-)

--
2.29.2


2021-02-19 17:32:06

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 2/8] mt76: mt7921: fix memory leak in mt7921_coredump_work

From: Sean Wang <[email protected]>

Fix possible memory leak in mt7921_coredump_work.

Fixes: 1c099ab44727c ("mt76: mt7921: add MCU support")
Signed-off-by: Sean Wang <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7921/mac.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 9468c9c3b9cf..8befa8167cde 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -1503,8 +1503,10 @@ void mt7921_coredump_work(struct work_struct *work)
break;

skb_pull(skb, sizeof(struct mt7921_mcu_rxd));
- if (data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ)
- break;
+ if (data + skb->len - dump > MT76_CONNAC_COREDUMP_SZ) {
+ dev_kfree_skb(skb);
+ continue;
+ }

memcpy(data, skb->data, skb->len);
data += skb->len;
--
2.29.2

2021-02-19 17:32:23

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 5/8] mt76: mt7921: fixup rx bitrate statistics

From: Sean Wang <[email protected]>

Since the related rx bitrate fields have been moved to group3 in Rxv,
fix rx bitrate statistics in mt7921_mac_fill_rx routine.

Fixes: 163f4d22c118d ("mt76: mt7921: add MAC support")
Signed-off-by: Sean Wang <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
.../net/wireless/mediatek/mt76/mt7921/mac.c | 155 +++++++++---------
.../net/wireless/mediatek/mt76/mt7921/mac.h | 10 +-
2 files changed, 86 insertions(+), 79 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
index 8befa8167cde..76d5f194706f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.c
@@ -400,7 +400,9 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)

/* RXD Group 3 - P-RXV */
if (rxd1 & MT_RXD1_NORMAL_GROUP_3) {
- u32 v0, v1, v2;
+ u8 stbc, gi;
+ u32 v0, v1;
+ bool cck;

rxv = rxd;
rxd += 2;
@@ -409,7 +411,6 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)

v0 = le32_to_cpu(rxv[0]);
v1 = le32_to_cpu(rxv[1]);
- v2 = le32_to_cpu(rxv[2]);

if (v0 & MT_PRXV_HT_AD_CODE)
status->enc_flags |= RX_ENC_FLAG_LDPC;
@@ -429,87 +430,87 @@ int mt7921_mac_fill_rx(struct mt7921_dev *dev, struct sk_buff *skb)
status->chain_signal[i]);
}

- /* RXD Group 5 - C-RXV */
- if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
- u8 stbc = FIELD_GET(MT_CRXV_HT_STBC, v2);
- u8 gi = FIELD_GET(MT_CRXV_HT_SHORT_GI, v2);
- bool cck = false;
+ stbc = FIELD_GET(MT_PRXV_STBC, v0);
+ gi = FIELD_GET(MT_PRXV_SGI, v0);
+ cck = false;

- rxd += 18;
- if ((u8 *)rxd - skb->data >= skb->len)
- return -EINVAL;
+ idx = i = FIELD_GET(MT_PRXV_TX_RATE, v0);
+ mode = FIELD_GET(MT_PRXV_TX_MODE, v0);

- idx = i = FIELD_GET(MT_PRXV_TX_RATE, v0);
- mode = FIELD_GET(MT_CRXV_TX_MODE, v2);
-
- switch (mode) {
- case MT_PHY_TYPE_CCK:
- cck = true;
- fallthrough;
- case MT_PHY_TYPE_OFDM:
- i = mt76_get_rate(&dev->mt76, sband, i, cck);
- break;
- case MT_PHY_TYPE_HT_GF:
- case MT_PHY_TYPE_HT:
- status->encoding = RX_ENC_HT;
- if (i > 31)
- return -EINVAL;
- break;
- case MT_PHY_TYPE_VHT:
- status->nss =
- FIELD_GET(MT_PRXV_NSTS, v0) + 1;
- status->encoding = RX_ENC_VHT;
- if (i > 9)
- return -EINVAL;
- break;
- case MT_PHY_TYPE_HE_MU:
- status->flag |= RX_FLAG_RADIOTAP_HE_MU;
- fallthrough;
- case MT_PHY_TYPE_HE_SU:
- case MT_PHY_TYPE_HE_EXT_SU:
- case MT_PHY_TYPE_HE_TB:
- status->nss =
- FIELD_GET(MT_PRXV_NSTS, v0) + 1;
- status->encoding = RX_ENC_HE;
- status->flag |= RX_FLAG_RADIOTAP_HE;
- i &= GENMASK(3, 0);
-
- if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
- status->he_gi = gi;
-
- status->he_dcm = !!(idx & MT_PRXV_TX_DCM);
- break;
- default:
+ switch (mode) {
+ case MT_PHY_TYPE_CCK:
+ cck = true;
+ fallthrough;
+ case MT_PHY_TYPE_OFDM:
+ i = mt76_get_rate(&dev->mt76, sband, i, cck);
+ break;
+ case MT_PHY_TYPE_HT_GF:
+ case MT_PHY_TYPE_HT:
+ status->encoding = RX_ENC_HT;
+ if (i > 31)
return -EINVAL;
- }
- status->rate_idx = i;
-
- switch (FIELD_GET(MT_CRXV_FRAME_MODE, v2)) {
- case IEEE80211_STA_RX_BW_20:
- break;
- case IEEE80211_STA_RX_BW_40:
- if (mode & MT_PHY_TYPE_HE_EXT_SU &&
- (idx & MT_PRXV_TX_ER_SU_106T)) {
- status->bw = RATE_INFO_BW_HE_RU;
- status->he_ru =
- NL80211_RATE_INFO_HE_RU_ALLOC_106;
- } else {
- status->bw = RATE_INFO_BW_40;
- }
- break;
- case IEEE80211_STA_RX_BW_80:
- status->bw = RATE_INFO_BW_80;
- break;
- case IEEE80211_STA_RX_BW_160:
- status->bw = RATE_INFO_BW_160;
- break;
- default:
+ break;
+ case MT_PHY_TYPE_VHT:
+ status->nss =
+ FIELD_GET(MT_PRXV_NSTS, v0) + 1;
+ status->encoding = RX_ENC_VHT;
+ if (i > 9)
return -EINVAL;
+ break;
+ case MT_PHY_TYPE_HE_MU:
+ status->flag |= RX_FLAG_RADIOTAP_HE_MU;
+ fallthrough;
+ case MT_PHY_TYPE_HE_SU:
+ case MT_PHY_TYPE_HE_EXT_SU:
+ case MT_PHY_TYPE_HE_TB:
+ status->nss =
+ FIELD_GET(MT_PRXV_NSTS, v0) + 1;
+ status->encoding = RX_ENC_HE;
+ status->flag |= RX_FLAG_RADIOTAP_HE;
+ i &= GENMASK(3, 0);
+
+ if (gi <= NL80211_RATE_INFO_HE_GI_3_2)
+ status->he_gi = gi;
+
+ status->he_dcm = !!(idx & MT_PRXV_TX_DCM);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ status->rate_idx = i;
+
+ switch (FIELD_GET(MT_PRXV_FRAME_MODE, v0)) {
+ case IEEE80211_STA_RX_BW_20:
+ break;
+ case IEEE80211_STA_RX_BW_40:
+ if (mode & MT_PHY_TYPE_HE_EXT_SU &&
+ (idx & MT_PRXV_TX_ER_SU_106T)) {
+ status->bw = RATE_INFO_BW_HE_RU;
+ status->he_ru =
+ NL80211_RATE_INFO_HE_RU_ALLOC_106;
+ } else {
+ status->bw = RATE_INFO_BW_40;
}
+ break;
+ case IEEE80211_STA_RX_BW_80:
+ status->bw = RATE_INFO_BW_80;
+ break;
+ case IEEE80211_STA_RX_BW_160:
+ status->bw = RATE_INFO_BW_160;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc;
+ if (mode < MT_PHY_TYPE_HE_SU && gi)
+ status->enc_flags |= RX_ENC_FLAG_SHORT_GI;

- status->enc_flags |= RX_ENC_FLAG_STBC_MASK * stbc;
- if (mode < MT_PHY_TYPE_HE_SU && gi)
- status->enc_flags |= RX_ENC_FLAG_SHORT_GI;
+ if (rxd1 & MT_RXD1_NORMAL_GROUP_5) {
+ rxd += 18;
+ if ((u8 *)rxd - skb->data >= skb->len)
+ return -EINVAL;
}
}

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h
index a0c1fa0f20e4..109c8849d106 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mac.h
@@ -97,18 +97,24 @@ enum rx_pkt_type {
#define MT_RXD3_NORMAL_PF_MODE BIT(29)
#define MT_RXD3_NORMAL_PF_STS GENMASK(31, 30)

-/* P-RXV */
+/* P-RXV DW0 */
#define MT_PRXV_TX_RATE GENMASK(6, 0)
#define MT_PRXV_TX_DCM BIT(4)
#define MT_PRXV_TX_ER_SU_106T BIT(5)
#define MT_PRXV_NSTS GENMASK(9, 7)
#define MT_PRXV_HT_AD_CODE BIT(11)
+#define MT_PRXV_FRAME_MODE GENMASK(14, 12)
+#define MT_PRXV_SGI GENMASK(16, 15)
+#define MT_PRXV_STBC GENMASK(23, 22)
+#define MT_PRXV_TX_MODE GENMASK(27, 24)
#define MT_PRXV_HE_RU_ALLOC_L GENMASK(31, 28)
-#define MT_PRXV_HE_RU_ALLOC_H GENMASK(3, 0)
+
+/* P-RXV DW1 */
#define MT_PRXV_RCPI3 GENMASK(31, 24)
#define MT_PRXV_RCPI2 GENMASK(23, 16)
#define MT_PRXV_RCPI1 GENMASK(15, 8)
#define MT_PRXV_RCPI0 GENMASK(7, 0)
+#define MT_PRXV_HE_RU_ALLOC_H GENMASK(3, 0)

/* C-RXV */
#define MT_CRXV_HT_STBC GENMASK(1, 0)
--
2.29.2

2021-02-19 17:33:32

by Lorenzo Bianconi

[permalink] [raw]
Subject: [PATCH v2 8/8] mt76: connac: update sched_scan cmd usage

From: Sean Wang <[email protected]>

Update sched_scan command usage according to the current firmware
submitted into linux-firmware.git.

Fixes: 80fc1e37c0eb ("mt76: mt7921: rely on mt76_connac_mcu module for sched_scan and hw_scan")
Co-developed-by: Soul Huang <[email protected]>
Signed-off-by: Soul Huang <[email protected]>
Signed-off-by: Sean Wang <[email protected]>
Signed-off-by: Lorenzo Bianconi <[email protected]>
---
drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h | 5 -----
drivers/net/wireless/mediatek/mt76/mt76_connac.h | 5 +++++
.../net/wireless/mediatek/mt76/mt76_connac_mcu.c | 7 +++++--
.../net/wireless/mediatek/mt76/mt76_connac_mcu.h | 14 +++++++++++---
4 files changed, 21 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
index 491841bc6291..5ef19fbee6bd 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7615/mt7615.h
@@ -408,11 +408,6 @@ static inline bool is_mt7615(struct mt76_dev *dev)
return mt76_chip(dev) == 0x7615 || mt76_chip(dev) == 0x7611;
}

-static inline bool is_mt7663(struct mt76_dev *dev)
-{
- return mt76_chip(dev) == 0x7663;
-}
-
static inline bool is_mt7611(struct mt76_dev *dev)
{
return mt76_chip(dev) == 0x7611;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index 0d58606391b0..b811f3c410a1 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -73,6 +73,11 @@ static inline bool is_mt7921(struct mt76_dev *dev)
return mt76_chip(dev) == 0x7961;
}

+static inline bool is_mt7663(struct mt76_dev *dev)
+{
+ return mt76_chip(dev) == 0x7663;
+}
+
int mt76_connac_pm_wake(struct mt76_phy *phy, struct mt76_connac_pm *pm);
void mt76_connac_power_save_sched(struct mt76_phy *phy,
struct mt76_connac_pm *pm);
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
index 81515419b5b6..125e02b34a5f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.c
@@ -1438,10 +1438,13 @@ int mt76_connac_mcu_sched_scan_req(struct mt76_phy *phy,
req->version = 1;
req->seq_num = mvif->scan_seq_num | ext_phy << 7;

- if (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR) {
- get_random_mask_addr(req->random_mac, sreq->mac_addr,
+ if (is_mt7663(phy->dev) &&
+ (sreq->flags & NL80211_SCAN_FLAG_RANDOM_ADDR)) {
+ get_random_mask_addr(req->mt7663.random_mac, sreq->mac_addr,
sreq->mac_addr_mask);
req->scan_func = 1;
+ } else if (is_mt7921(phy->dev)) {
+ req->mt7921.bss_idx = mvif->idx;
}

req->ssids_num = sreq->n_ssids;
diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
index 9c26b90655a7..8478f019f5d3 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac_mcu.h
@@ -756,11 +756,19 @@ struct mt76_connac_sched_scan_req {
u8 channel_type;
u8 channels_num;
u8 intervals_num;
- u8 scan_func; /* BIT(0) eable random mac address */
+ u8 scan_func; /* MT7663: BIT(0) eable random mac address */
struct mt76_connac_mcu_scan_channel channels[64];
__le16 intervals[MT76_CONNAC_MAX_SCHED_SCAN_INTERVAL];
- u8 random_mac[ETH_ALEN]; /* valid when BIT(0) in scan_func is set */
- u8 pad2[58];
+ union {
+ struct {
+ u8 random_mac[ETH_ALEN];
+ u8 pad2[58];
+ } mt7663;
+ struct {
+ u8 bss_idx;
+ u8 pad2[63];
+ } mt7921;
+ };
} __packed;

struct mt76_connac_sched_scan_done {
--
2.29.2