[Refactor and sync kernel/wifi from Openwrt]
[Description]
Refactor and sync kernel/wifi from Openwrt
[Release-log]
N/A
diff --git a/recipes-kernel/linux-mt76/files/patches/0011-mt76-testmode-use-random-payload-for-tx-packets.patch b/recipes-kernel/linux-mt76/files/patches/0011-mt76-testmode-use-random-payload-for-tx-packets.patch
new file mode 100644
index 0000000..dc04e36
--- /dev/null
+++ b/recipes-kernel/linux-mt76/files/patches/0011-mt76-testmode-use-random-payload-for-tx-packets.patch
@@ -0,0 +1,56 @@
+From 5b712b2ec82bb9e88346b379b5c6645b1fa7d7fe Mon Sep 17 00:00:00 2001
+From: Shayne Chen <shayne.chen@mediatek.com>
+Date: Wed, 6 Jul 2022 21:52:45 +0800
+Subject: [PATCH] mt76: testmode: use random payload for tx packets
+
+Compared to fixed payload packets, random payload packets have better
+measured EVM under the same txpower. Our tests show EVM becomes at least
+3 dB better in test cases with high rate and long tx length, which also
+aligns the testing result of proprietary driver.
+
+Suggested-by: Jm Chen <jm.chen@mediatek.com>
+Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
+---
+ drivers/net/wireless/mediatek/mt76/testmode.c | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/testmode.c b/testmode.c
+index 4a24f6c9..31439b39 100644
+--- a/testmode.c
++++ b/testmode.c
+@@ -1,5 +1,7 @@
+ // SPDX-License-Identifier: ISC
+ /* Copyright (C) 2020 Felix Fietkau <nbd@nbd.name> */
++
++#include <linux/random.h>
+ #include "mt76.h"
+
+ const struct nla_policy mt76_tm_policy[NUM_MT76_TM_ATTRS] = {
+@@ -124,12 +126,14 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+ if (!head)
+ return -ENOMEM;
+
+- hdr = __skb_put_zero(head, head_len);
++ hdr = __skb_put_zero(head, sizeof(*hdr));
+ hdr->frame_control = cpu_to_le16(fc);
+ memcpy(hdr->addr1, td->addr[0], ETH_ALEN);
+ memcpy(hdr->addr2, td->addr[1], ETH_ALEN);
+ memcpy(hdr->addr3, td->addr[2], ETH_ALEN);
+ skb_set_queue_mapping(head, IEEE80211_AC_BE);
++ get_random_bytes(__skb_put(head, head_len - sizeof(*hdr)),
++ head_len - sizeof(*hdr));
+
+ info = IEEE80211_SKB_CB(head);
+ info->flags = IEEE80211_TX_CTL_INJECTED |
+@@ -157,7 +161,7 @@ int mt76_testmode_alloc_skb(struct mt76_phy *phy, u32 len)
+ return -ENOMEM;
+ }
+
+- __skb_put_zero(frag, frag_len);
++ get_random_bytes(__skb_put(frag, frag_len), frag_len);
+ head->len += frag->len;
+ head->data_len += frag->len;
+
+--
+2.25.1
+
diff --git a/recipes-kernel/linux-mt76/files/patches/1117-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl.patch b/recipes-kernel/linux-mt76/files/patches/1117-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl.patch
new file mode 100644
index 0000000..c25f9b2
--- /dev/null
+++ b/recipes-kernel/linux-mt76/files/patches/1117-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl.patch
@@ -0,0 +1,245 @@
+From c1e72950b8f7df7c36c64e27613637f88e3c1ba3 Mon Sep 17 00:00:00 2001
+From: Howard Hsu <howard-yh.hsu@mediatek.com>
+Date: Fri, 24 Jun 2022 11:15:45 +0800
+Subject: [PATCH 1117/1117] mt76: mt7915: add vendor subcmd EDCCA ctrl
+
+Change-Id: I92dabf8be9c5a7ecec78f35325bc5645af8d15ab
+---
+ mt76_connac_mcu.h | 1 +
+ mt7915/main.c | 3 +++
+ mt7915/mcu.c | 38 ++++++++++++++++++++++++++++
+ mt7915/mcu.h | 12 +++++++++
+ mt7915/mt7915.h | 2 ++
+ mt7915/vendor.c | 63 +++++++++++++++++++++++++++++++++++++++++++++++
+ mt7915/vendor.h | 19 ++++++++++++++
+ 7 files changed, 138 insertions(+)
+
+diff --git a/mt76_connac_mcu.h b/mt76_connac_mcu.h
+index a0e6fa6e..1747e06d 100644
+--- a/mt76_connac_mcu.h
++++ b/mt76_connac_mcu.h
+@@ -1147,6 +1147,7 @@ enum {
+ MCU_EXT_CMD_SMESH_CTRL = 0xae,
+ MCU_EXT_CMD_RX_STAT_USER_CTRL = 0xb3,
+ MCU_EXT_CMD_CERT_CFG = 0xb7,
++ MCU_EXT_CMD_EDCCA = 0xba,
+ MCU_EXT_CMD_CSI_CTRL = 0xc2,
+ };
+
+diff --git a/mt7915/main.c b/mt7915/main.c
+index 6c97ce78..1dc41ab6 100644
+--- a/mt7915/main.c
++++ b/mt7915/main.c
+@@ -456,6 +456,9 @@ static int mt7915_config(struct ieee80211_hw *hw, u32 changed)
+ mutex_unlock(&dev->mt76.mutex);
+ }
+ #endif
++ ret = mt7915_mcu_set_edcca(phy, EDCCA_CTRL_SET_EN, NULL, 0);
++ if (ret)
++ return ret;
+ ieee80211_stop_queues(hw);
+ ret = mt7915_set_channel(phy);
+ if (ret)
+diff --git a/mt7915/mcu.c b/mt7915/mcu.c
+index 46eef36a..205ecbab 100644
+--- a/mt7915/mcu.c
++++ b/mt7915/mcu.c
+@@ -4217,3 +4217,41 @@ int mt7915_mcu_rf_regval(struct mt7915_dev *dev, u32 regidx, u32 *val, bool set)
+
+ return 0;
+ }
++
++int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value,
++ s8 compensation)
++{
++ static const u8 ch_band[] = {
++ [NL80211_BAND_2GHZ] = 0,
++ [NL80211_BAND_5GHZ] = 1,
++ [NL80211_BAND_6GHZ] = 2,
++ };
++ struct mt7915_dev *dev = phy->dev;
++ struct cfg80211_chan_def *chandef = &phy->mt76->chandef;
++ struct {
++ u8 band_idx;
++ u8 cmd_idx;
++ u8 setting[3];
++ bool record_in_fw;
++ u8 region;
++ s8 thres_compensation;
++ } __packed req = {
++ .band_idx = phy->band_idx,
++ .cmd_idx = mode,
++ .record_in_fw = false,
++ .region = dev->mt76.region,
++ .thres_compensation = compensation,
++ };
++
++ if (ch_band[chandef->chan->band] != 2)
++ return 0;
++
++ if (mode == EDCCA_CTRL_SET_EN) {
++ if (!value)
++ req.setting[0] = EDCCA_MODE_AUTO;
++ else
++ req.setting[0] = value[0];
++ }
++
++ return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD(EDCCA), &req, sizeof(req), true);
++}
+diff --git a/mt7915/mcu.h b/mt7915/mcu.h
+index 873a8055..72c2cfc6 100644
+--- a/mt7915/mcu.h
++++ b/mt7915/mcu.h
+@@ -785,4 +785,16 @@ enum {
+ };
+ #endif
+
++enum {
++ EDCCA_CTRL_SET_EN = 0,
++ EDCCA_CTRL_SET_THERS,
++ EDCCA_CTRL_GET_EN,
++ EDCCA_CTRL_GET_THERS,
++ EDCCA_CTRL_NUM,
++};
++
++enum {
++ EDCCA_MODE_FORCE_DISABLE,
++ EDCCA_MODE_AUTO,
++};
+ #endif
+diff --git a/mt7915/mt7915.h b/mt7915/mt7915.h
+index 0b7f73b3..5c58a29c 100644
+--- a/mt7915/mt7915.h
++++ b/mt7915/mt7915.h
+@@ -718,6 +718,8 @@ void mt7915_vendor_amnt_fill_rx(struct mt7915_phy *phy, struct sk_buff *skb);
+ int mt7915_vendor_amnt_sta_remove(struct mt7915_phy *phy,
+ struct ieee80211_sta *sta);
+ #endif
++int mt7915_mcu_set_edcca(struct mt7915_phy *phy, int mode, u8 *value,
++ s8 compensation);
+
+ #ifdef MTK_DEBUG
+ int mt7915_mtk_init_debugfs(struct mt7915_phy *phy, struct dentry *dir);
+diff --git a/mt7915/vendor.c b/mt7915/vendor.c
+index 77d71e48..5a28a554 100644
+--- a/mt7915/vendor.c
++++ b/mt7915/vendor.c
+@@ -62,6 +62,17 @@ phy_capa_dump_policy[NUM_MTK_VENDOR_ATTRS_PHY_CAPA_DUMP] = {
+ [MTK_VENDOR_ATTR_PHY_CAPA_DUMP_MAX_SUPPORTED_STA] = { .type = NLA_U16 },
+ };
+
++static const struct nla_policy
++edcca_ctrl_policy[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL] = {
++ [MTK_VENDOR_ATTR_EDCCA_CTRL_MODE] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL] = { .type = NLA_U8 },
++ [MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE] = { .type = NLA_S8 },
++};
++
++
+ struct csi_null_tone {
+ u8 start;
+ u8 end;
+@@ -1015,6 +1026,47 @@ mt7915_vendor_phy_capa_ctrl_dump(struct wiphy *wiphy, struct wireless_dev *wdev,
+ return len;
+ }
+
++static int mt7915_vendor_edcca_ctrl(struct wiphy *wiphy,
++ struct wireless_dev *wdev,
++ const void *data,
++ int data_len)
++{
++ struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy);
++ struct mt7915_phy *phy = mt7915_hw_phy(hw);
++ struct nlattr *tb[NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL];
++ int err;
++ u8 edcca_mode;
++ s8 edcca_compensation;
++
++ err = nla_parse(tb, MTK_VENDOR_ATTR_EDCCA_CTRL_MAX, data, data_len,
++ edcca_ctrl_policy, NULL);
++ if (err)
++ return err;
++
++ if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE])
++ return -EINVAL;
++
++ edcca_mode = nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_MODE]);
++ if (edcca_mode == EDCCA_CTRL_SET_EN) {
++ u8 edcca_value[3] = {0};
++ if (!tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL] ||
++ !tb[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE]) {
++ return -EINVAL;
++ }
++ edcca_value[0] =
++ nla_get_u8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL]);
++ edcca_compensation =
++ nla_get_s8(tb[MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE]);
++
++ err = mt7915_mcu_set_edcca(phy, edcca_mode, edcca_value,
++ edcca_compensation);
++ if (err)
++ return err;
++ }
++ return 0;
++}
++
++
+ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+ {
+ .info = {
+@@ -1083,6 +1135,17 @@ static const struct wiphy_vendor_command mt7915_vendor_commands[] = {
+ .dumpit = mt7915_vendor_phy_capa_ctrl_dump,
+ .policy = phy_capa_ctrl_policy,
+ .maxattr = MTK_VENDOR_ATTR_PHY_CAPA_CTRL_MAX,
++ },
++ {
++ .info = {
++ .vendor_id = MTK_NL80211_VENDOR_ID,
++ .subcmd = MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL,
++ },
++ .flags = WIPHY_VENDOR_CMD_NEED_NETDEV |
++ WIPHY_VENDOR_CMD_NEED_RUNNING,
++ .doit = mt7915_vendor_edcca_ctrl,
++ .policy = edcca_ctrl_policy,
++ .maxattr = MTK_VENDOR_ATTR_EDCCA_CTRL_MAX,
+ }
+ };
+
+diff --git a/mt7915/vendor.h b/mt7915/vendor.h
+index 719b851f..83c41bc1 100644
+--- a/mt7915/vendor.h
++++ b/mt7915/vendor.h
+@@ -10,8 +10,27 @@ enum mtk_nl80211_vendor_subcmds {
+ MTK_NL80211_VENDOR_SUBCMD_WIRELESS_CTRL = 0xc4,
+ MTK_NL80211_VENDOR_SUBCMD_HEMU_CTRL = 0xc5,
+ MTK_NL80211_VENDOR_SUBCMD_PHY_CAPA_CTRL = 0xc6,
++ MTK_NL80211_VENDOR_SUBCMD_EDCCA_CTRL = 0xc7,
+ };
+
++
++enum mtk_vendor_attr_edcca_ctrl {
++ MTK_VENDOR_ATTR_EDCCA_THRESHOLD_INVALID = 0,
++
++ MTK_VENDOR_ATTR_EDCCA_CTRL_MODE,
++ MTK_VENDOR_ATTR_EDCCA_CTRL_PRI20_VAL,
++ MTK_VENDOR_ATTR_EDCCA_CTRL_SEC20_VAL,
++ MTK_VENDOR_ATTR_EDCCA_CTRL_SEC40_VAL,
++ MTK_VENDOR_ATTR_EDCCA_CTRL_SEC80_VAL,
++ MTK_VENDOR_ATTR_EDCCA_CTRL_COMPENSATE,
++
++ /* keep last */
++ NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL,
++ MTK_VENDOR_ATTR_EDCCA_CTRL_MAX =
++ NUM_MTK_VENDOR_ATTRS_EDCCA_CTRL - 1
++};
++
++
+ enum mtk_capi_control_changed {
+ CAPI_RFEATURE_CHANGED = BIT(16),
+ CAPI_WIRELESS_CHANGED = BIT(17),
+--
+2.18.0
+
diff --git a/recipes-kernel/linux-mt76/files/patches/3002-mt76-add-wed-rx-support.patch b/recipes-kernel/linux-mt76/files/patches/3002-mt76-add-wed-rx-support.patch
index 5c5a05d..7040ca6 100755
--- a/recipes-kernel/linux-mt76/files/patches/3002-mt76-add-wed-rx-support.patch
+++ b/recipes-kernel/linux-mt76/files/patches/3002-mt76-add-wed-rx-support.patch
@@ -5,10 +5,10 @@
Signed-off-by: Sujuan Chen <sujuan.chen@mediatek.com>
---
- dma.c | 219 +++++++++++++++++++++++++++++++++--------
+ dma.c | 248 +++++++++++++++++++++++++++++++++--------
dma.h | 10 ++
mac80211.c | 8 +-
- mt76.h | 24 ++++-
+ mt76.h | 24 +++-
mt7603/dma.c | 2 +-
mt7603/mt7603.h | 2 +-
mt7615/mac.c | 2 +-
@@ -17,7 +17,7 @@
mt76x02.h | 2 +-
mt76x02_txrx.c | 2 +-
mt7915/dma.c | 10 ++
- mt7915/mac.c | 89 ++++++++++++++++-
+ mt7915/mac.c | 101 ++++++++++++++++-
mt7915/mcu.c | 3 +
mt7915/mmio.c | 26 ++++-
mt7915/mt7915.h | 7 +-
@@ -25,13 +25,11 @@
mt7921/mac.c | 2 +-
mt7921/mt7921.h | 4 +-
mt7921/pci_mac.c | 4 +-
- tx.c | 34 +++++++
- 21 files changed, 410 insertions(+), 65 deletions(-)
- mode change 100755 => 100644 mt7915/mac.c
- mode change 100755 => 100644 mt7915/mmio.c
+ tx.c | 34 ++++++
+ 21 files changed, 448 insertions(+), 68 deletions(-)
diff --git a/dma.c b/dma.c
-index 03ee910..094aede 100644
+index 03ee910..e46dbed 100644
--- a/dma.c
+++ b/dma.c
@@ -98,6 +98,63 @@ mt76_put_txwi(struct mt76_dev *dev, struct mt76_txwi_cache *t)
@@ -98,7 +96,29 @@
static void
mt76_free_pending_txwi(struct mt76_dev *dev)
{
-@@ -141,12 +198,15 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -112,6 +169,21 @@ mt76_free_pending_txwi(struct mt76_dev *dev)
+ local_bh_enable();
+ }
+
++static void
++mt76_free_pending_rxwi(struct mt76_dev *dev)
++{
++ struct mt76_txwi_cache *r;
++
++ local_bh_disable();
++ while ((r = __mt76_get_rxwi(dev)) != NULL) {
++ if (r->buf)
++ skb_free_frag(r->buf);
++
++ kfree(r);
++ }
++ local_bh_enable();
++}
++
+ static void
+ mt76_dma_sync_idx(struct mt76_dev *dev, struct mt76_queue *q)
+ {
+@@ -141,12 +213,15 @@ mt76_dma_queue_reset(struct mt76_dev *dev, struct mt76_queue *q)
static int
mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
struct mt76_queue_buf *buf, int nbufs, u32 info,
@@ -115,7 +135,7 @@
if (txwi) {
q->entry[q->head].txwi = DMA_DUMMY_DATA;
-@@ -162,28 +222,42 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -162,28 +237,42 @@ mt76_dma_add_buf(struct mt76_dev *dev, struct mt76_queue *q,
desc = &q->desc[idx];
entry = &q->entry[idx];
@@ -178,7 +198,7 @@
WRITE_ONCE(desc->buf0, cpu_to_le32(buf0));
WRITE_ONCE(desc->buf1, cpu_to_le32(buf1));
WRITE_ONCE(desc->info, cpu_to_le32(info));
-@@ -272,33 +346,63 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
+@@ -272,33 +361,63 @@ mt76_dma_tx_cleanup(struct mt76_dev *dev, struct mt76_queue *q, bool flush)
static void *
mt76_dma_get_buf(struct mt76_dev *dev, struct mt76_queue *q, int idx,
@@ -248,7 +268,7 @@
{
int idx = q->tail;
-@@ -314,7 +418,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
+@@ -314,7 +433,7 @@ mt76_dma_dequeue(struct mt76_dev *dev, struct mt76_queue *q, bool flush,
q->tail = (q->tail + 1) % q->ndesc;
q->queued--;
@@ -257,7 +277,7 @@
}
static int
-@@ -336,7 +440,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -336,7 +455,7 @@ mt76_dma_tx_queue_skb_raw(struct mt76_dev *dev, struct mt76_queue *q,
buf.len = skb->len;
spin_lock_bh(&q->lock);
@@ -266,7 +286,7 @@
mt76_dma_kick_queue(dev, q);
spin_unlock_bh(&q->lock);
-@@ -413,7 +517,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -413,7 +532,7 @@ mt76_dma_tx_queue_skb(struct mt76_dev *dev, struct mt76_queue *q,
goto unmap;
return mt76_dma_add_buf(dev, q, tx_info.buf, tx_info.nbuf,
@@ -275,15 +295,16 @@
unmap:
for (n--; n > 0; n--)
-@@ -448,6 +552,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -448,6 +567,8 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
int frames = 0;
int len = SKB_WITH_OVERHEAD(q->buf_size);
int offset = q->buf_offset;
+ struct mtk_wed_device *wed = &dev->mmio.wed;
++ struct page_frag_cache *rx_page;
if (!q->ndesc)
return 0;
-@@ -456,10 +561,27 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -456,10 +577,29 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
while (q->queued < q->ndesc - 1) {
struct mt76_queue_buf qbuf;
@@ -291,7 +312,9 @@
+ bool skip_alloc = false;
+ struct mt76_txwi_cache *r = NULL;
+
++ rx_page = &q->rx_page;
+ if (mtk_wed_device_active(wed) && type == MT76_WED_Q_RX) {
++ rx_page = &wed->rx_page;
+ r = mt76_get_rxwi(dev);
+ if (!r)
+ return -ENOMEM;
@@ -307,14 +330,14 @@
- if (!buf)
- break;
+ if (!skip_alloc) {
-+ buf = page_frag_alloc(&q->rx_page, q->buf_size, GFP_ATOMIC);
++ buf = page_frag_alloc(rx_page, q->buf_size, GFP_ATOMIC);
+ if (!buf)
+ break;
+ }
addr = dma_map_single(dev->dma_dev, buf, len, DMA_FROM_DEVICE);
if (unlikely(dma_mapping_error(dev->dma_dev, addr))) {
-@@ -470,7 +592,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -470,7 +610,7 @@ mt76_dma_rx_fill(struct mt76_dev *dev, struct mt76_queue *q)
qbuf.addr = addr + offset;
qbuf.len = len - offset;
qbuf.skip_unmap = false;
@@ -323,7 +346,7 @@
frames++;
}
-@@ -516,6 +638,11 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -516,6 +656,11 @@ mt76_dma_wed_setup(struct mt76_dev *dev, struct mt76_queue *q)
if (!ret)
q->wed_regs = wed->txfree_ring.reg_base;
break;
@@ -335,7 +358,7 @@
default:
ret = -EINVAL;
}
-@@ -531,7 +658,8 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -531,7 +676,8 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
int idx, int n_desc, int bufsize,
u32 ring_base)
{
@@ -345,7 +368,7 @@
spin_lock_init(&q->lock);
spin_lock_init(&q->cleanup_lock);
-@@ -541,6 +669,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
+@@ -541,6 +687,11 @@ mt76_dma_alloc_queue(struct mt76_dev *dev, struct mt76_queue *q,
q->buf_size = bufsize;
q->hw_idx = idx;
@@ -357,7 +380,7 @@
size = q->ndesc * sizeof(struct mt76_desc);
q->desc = dmam_alloc_coherent(dev->dma_dev, size, &q->desc_dma, GFP_KERNEL);
if (!q->desc)
-@@ -573,7 +706,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
+@@ -573,7 +724,7 @@ mt76_dma_rx_cleanup(struct mt76_dev *dev, struct mt76_queue *q)
spin_lock_bh(&q->lock);
do {
@@ -366,7 +389,7 @@
if (!buf)
break;
-@@ -614,7 +747,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
+@@ -614,7 +765,7 @@ mt76_dma_rx_reset(struct mt76_dev *dev, enum mt76_rxq_id qid)
static void
mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
@@ -375,7 +398,7 @@
{
struct sk_buff *skb = q->rx_head;
struct skb_shared_info *shinfo = skb_shinfo(skb);
-@@ -634,7 +767,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
+@@ -634,7 +785,7 @@ mt76_add_fragment(struct mt76_dev *dev, struct mt76_queue *q, void *data,
q->rx_head = NULL;
if (nr_frags < ARRAY_SIZE(shinfo->frags))
@@ -384,7 +407,7 @@
else
dev_kfree_skb(skb);
}
-@@ -655,6 +788,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -655,6 +806,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
}
while (done < budget) {
@@ -392,7 +415,7 @@
u32 info;
if (check_ddone) {
-@@ -665,10 +799,13 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -665,10 +817,13 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
break;
}
@@ -407,7 +430,7 @@
if (q->rx_head)
data_len = q->buf_size;
else
-@@ -681,7 +818,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -681,7 +836,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
}
if (q->rx_head) {
@@ -416,7 +439,7 @@
continue;
}
-@@ -708,7 +845,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
+@@ -708,7 +863,7 @@ mt76_dma_rx_process(struct mt76_dev *dev, struct mt76_queue *q, int budget)
continue;
}
@@ -425,6 +448,36 @@
continue;
free_frag:
+@@ -785,8 +940,8 @@ EXPORT_SYMBOL_GPL(mt76_dma_attach);
+
+ void mt76_dma_cleanup(struct mt76_dev *dev)
+ {
+- int i;
+-
++ int i, type;
++
+ mt76_worker_disable(&dev->tx_worker);
+ netif_napi_del(&dev->tx_napi);
+
+@@ -801,12 +956,17 @@ void mt76_dma_cleanup(struct mt76_dev *dev)
+
+ mt76_for_each_q_rx(dev, i) {
+ netif_napi_del(&dev->napi[i]);
+- mt76_dma_rx_cleanup(dev, &dev->q_rx[i]);
++ type = FIELD_GET(MT_QFLAG_WED_TYPE, dev->q_rx[i].flags);
++ if (type != MT76_WED_Q_RX)
++ mt76_dma_rx_cleanup(dev, &dev->q_rx[i]);
+ }
+
+ mt76_free_pending_txwi(dev);
++ mt76_free_pending_rxwi(dev);
+
+ if (mtk_wed_device_active(&dev->mmio.wed))
+ mtk_wed_device_detach(&dev->mmio.wed);
++
++ mt76_free_pending_rxwi(dev);
+ }
+ EXPORT_SYMBOL_GPL(mt76_dma_cleanup);
diff --git a/dma.h b/dma.h
index fdf786f..90370d1 100644
--- a/dma.h
@@ -628,7 +681,7 @@
int mt7615_mac_sta_add(struct mt76_dev *mdev, struct ieee80211_vif *vif,
struct ieee80211_sta *sta);
diff --git a/mt76_connac_mcu.c b/mt76_connac_mcu.c
-index cd35068..f90a08f 100644
+index cd35068..2454846 100644
--- a/mt76_connac_mcu.c
+++ b/mt76_connac_mcu.c
@@ -1190,6 +1190,7 @@ int mt76_connac_mcu_sta_ba(struct mt76_dev *dev, struct mt76_vif *mvif,
@@ -737,9 +790,7 @@
MT_RXQ_ID(MT_RXQ_EXT),
MT7915_RX_RING_SIZE,
diff --git a/mt7915/mac.c b/mt7915/mac.c
-old mode 100755
-new mode 100644
-index bc8da4d..79b7d01
+index bc8da4d..dd87a40 100644
--- a/mt7915/mac.c
+++ b/mt7915/mac.c
@@ -217,7 +217,7 @@ static void mt7915_mac_sta_poll(struct mt7915_dev *dev)
@@ -751,23 +802,32 @@
{
struct mt76_rx_status *status = (struct mt76_rx_status *)skb->cb;
struct mt76_phy *mphy = &dev->mt76.phy;
+@@ -234,7 +234,7 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
+ bool unicast, insert_ccmp_hdr = false;
+ u8 remove_pad, amsdu_info;
+ u8 mode = 0, qos_ctl = 0;
+- struct mt7915_sta *msta;
++ struct mt7915_sta *msta = NULL;
+ bool hdr_trans;
+ u16 hdr_gap;
+ u16 seq_ctrl = 0;
@@ -494,6 +494,27 @@ mt7915_mac_fill_rx(struct mt7915_dev *dev, struct sk_buff *skb)
#endif
} else {
status->flag |= RX_FLAG_8023;
-+ if (msta || msta->vif) {
++ if (msta && msta->vif) {
+ struct mtk_wed_device *wed;
+ int type;
+
+ wed = &dev->mt76.mmio.wed;
+ type = FIELD_GET(MT_QFLAG_WED_TYPE, dev->mt76.q_rx[q].flags);
+ if ((mtk_wed_device_active(wed) && type == MT76_WED_Q_RX) &&
-+ (info & MT_DMA_INFO_PPE_VLD)){
++ (info & MT_DMA_INFO_PPE_VLD)) {
+ struct ieee80211_vif *vif;
+ u32 hash, reason;
+
+ vif = container_of((void *)msta->vif, struct ieee80211_vif,
-+ drv_priv);
++ drv_priv);
+
+ skb->dev = ieee80211_vif_to_netdev(vif);
+ reason = FIELD_GET(MT_DMA_PPE_CPU_REASON, info);
@@ -779,7 +839,7 @@
}
if (rxv && mode >= MT_PHY_TYPE_HE_SU && !(status->flag & RX_FLAG_8023))
-@@ -840,6 +861,68 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
+@@ -840,6 +861,80 @@ u32 mt7915_wed_init_buf(void *ptr, dma_addr_t phys, int token_id)
return MT_TXD_TXP_BUF_SIZE;
}
@@ -826,6 +886,7 @@
+{
+ struct mt76_txwi_cache *rxwi;
+ struct mt7915_dev *dev;
++ struct page *page;
+ int token;
+
+ dev = container_of(wed, struct mt7915_dev, mt76.mmio.wed);
@@ -835,6 +896,9 @@
+ if(!rxwi)
+ continue;
+
++ if(!rxwi->buf)
++ continue;
++
+ dma_unmap_single(dev->mt76.dma_dev, rxwi->dma_addr,
+ wed->wlan.rx_pkt_size, DMA_FROM_DEVICE);
+ skb_free_frag(rxwi->buf);
@@ -842,13 +906,21 @@
+
+ mt76_put_rxwi(&dev->mt76, rxwi);
+ }
++
++ if (wed->rx_page.va)
++ return;
++
++ page = virt_to_page(wed->rx_page.va);
++ __page_frag_cache_drain(page, wed->rx_page.pagecnt_bias);
++ memset(&wed->rx_page, 0, sizeof(wed->rx_page));
++
+ return;
+}
+
static void
mt7915_tx_check_aggr(struct ieee80211_sta *sta, __le32 *txwi)
{
-@@ -1120,7 +1203,7 @@ bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len)
+@@ -1120,7 +1215,7 @@ bool mt7915_rx_check(struct mt76_dev *mdev, void *data, int len)
}
void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
@@ -857,7 +929,7 @@
{
struct mt7915_dev *dev = container_of(mdev, struct mt7915_dev, mt76);
__le32 *rxd = (__le32 *)skb->data;
-@@ -1154,7 +1237,7 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
+@@ -1154,7 +1249,7 @@ void mt7915_queue_rx_skb(struct mt76_dev *mdev, enum mt76_rxq_id q,
dev_kfree_skb(skb);
break;
case PKT_TYPE_NORMAL:
@@ -867,7 +939,7 @@
return;
}
diff --git a/mt7915/mcu.c b/mt7915/mcu.c
-index 1468c3c..4f64df4 100644
+index 1468c3c..5eace9e 100644
--- a/mt7915/mcu.c
+++ b/mt7915/mcu.c
@@ -1704,6 +1704,7 @@ int mt7915_mcu_add_sta(struct mt7915_dev *dev, struct ieee80211_vif *vif,
@@ -888,9 +960,7 @@
MCU_EXT_CMD(STA_REC_UPDATE), true);
}
diff --git a/mt7915/mmio.c b/mt7915/mmio.c
-old mode 100755
-new mode 100644
-index b4a3120..08ff556
+index b4a3120..08ff556 100644
--- a/mt7915/mmio.c
+++ b/mt7915/mmio.c
@@ -28,6 +28,9 @@ static const u32 mt7915_reg[] = {
diff --git a/recipes-kernel/linux-mt76/files/patches/patches.inc b/recipes-kernel/linux-mt76/files/patches/patches.inc
index da26649..5297bc1 100644
--- a/recipes-kernel/linux-mt76/files/patches/patches.inc
+++ b/recipes-kernel/linux-mt76/files/patches/patches.inc
@@ -7,6 +7,7 @@
file://0005-mt76-mt7915-drop-undefined-action-frame.patch \
file://0008-mt76-common-RF-CR-idx-require-8-bits.patch \
file://0010-mt76-mt7915-4addr-null-frame-using-fixed-rate-to-suc.patch \
+ file://0011-mt76-testmode-use-random-payload-for-tx-packets.patch \
file://100-Revert-of-net-pass-the-dst-buffer-to-of_get_mac_addr.patch \
file://1001-mt76-mt7915-add-mtk-internal-debug-tools-for-mt76.patch \
file://1002-mt76-mt7915-csi-implement-csi-support.patch \
@@ -22,6 +23,7 @@
file://1114-mt76-airtime-fairness-feature-off-in-mac80211.patch \
file://1115-mt76-mt7915-add-mt7986-and-mt7916-pre-calibration.patch \
file://1116-mt76-mt7915-add-vendor-dump-phy-capa.patch \
+ file://1117-mt76-mt7915-add-vendor-subcmd-EDCCA-ctrl.patch \
file://3001-mt76-add-wed-tx-support.patch \
file://3002-mt76-add-wed-rx-support.patch \
file://3003-mt76-add-fill-receive-path-to-report-wed-idx.patch \