[rdkb][common][bsp][Refactor and sync wifi from openwrt]
[Description]
05a67730 [mac80211][mt76][wifi6][do not report ACK when TXS is lost]
0bae31b5 [Fix WiFi7 Release Build Fail]
7bf748ba [openwrt-24][Mac80211][Fix Mozart build fail]
b52c9c66 [mac80211][mt76][wifi6][delete twt flow before remove stations]
7c4179d9 [mac8021][core][wifi6][set IEEE80211_TX_CTL_USE_MINRATE when probing]
8d17b91d [MAC80211][WiFi6][TWT][refine twt mcu update flow]
6d5ab74e [MAC80211][WiFi6][mt76][fix mt76 Makefile patch failed]
c6eeb297 [MAC80211][WiFi7][Misc][Fix release build fail because of mt76 version upgradation]
4df78532 [MAC80211][WiFi6][mt76][Fix TX/RX hang and SER hw bit didn't detect issue]
[Release-log]
Change-Id: I78f985181c5b667036461de240eec86e3912f431
diff --git a/recipes-wifi/linux-mt76/files/patches-3.x/0189-mtk-mt76-mt7996-add-efuse-write-protection.patch b/recipes-wifi/linux-mt76/files/patches-3.x/0189-mtk-mt76-mt7996-add-efuse-write-protection.patch
new file mode 100644
index 0000000..2ee41ed
--- /dev/null
+++ b/recipes-wifi/linux-mt76/files/patches-3.x/0189-mtk-mt76-mt7996-add-efuse-write-protection.patch
@@ -0,0 +1,271 @@
+From 5bdd94800111ac1742558a5d6e8b9daae0c24e79 Mon Sep 17 00:00:00 2001
+From: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Date: Thu, 29 Aug 2024 09:47:44 +0800
+Subject: [PATCH 189/193] mtk: mt76: mt7996: add efuse write protection
+
+Add efuse write protection in case that the user overwritten
+the FT value stored in efuse.
+Reference change list (Logan):
+https://gerrit.mediatek.inc/c/neptune/wlan_driver/logan/+/9473737
+https://gerrit.mediatek.inc/c/neptune/wlan_driver/logan/+/9497426
+
+Signed-off-by: StanleyYP Wang <StanleyYP.Wang@mediatek.com>
+Change-Id: If50d6965da8d9488d44c9da77a4bfca9906da9bc
+---
+ mt7996/mcu.c | 11 +---
+ mt7996/mt7996.h | 23 ++++++++
+ mt7996/testmode.c | 135 ++++++++++++++++++++++++++++++++++++++++++----
+ mt7996/testmode.h | 6 +++
+ 4 files changed, 157 insertions(+), 18 deletions(-)
+
+diff --git a/mt7996/mcu.c b/mt7996/mcu.c
+index b584a0e..cd10ee9 100644
+--- a/mt7996/mcu.c
++++ b/mt7996/mcu.c
+@@ -5115,13 +5115,6 @@ static int mt7996_mcu_set_cal_free_data(struct mt7996_dev *dev)
+ #define MT_EE_CAL_FREE_MAX_SIZE 30
+ #define MT_EE_7977BN_OFFSET (0x1200 - 0x500)
+ #define MT_EE_END_OFFSET 0xffff
+- enum adie_type {
+- ADIE_7975,
+- ADIE_7976,
+- ADIE_7977,
+- ADIE_7978,
+- ADIE_7979,
+- };
+ static const u16 adie_offs_list[][MT_EE_CAL_FREE_MAX_SIZE] = {
+ [ADIE_7975] = {0x5cd, 0x5cf, 0x5d1, 0x5d3, 0x6c0, 0x6c1, 0x6c2, 0x6c3,
+ 0x7a1, 0x7a6, 0x7a8, 0x7aa, -1},
+@@ -5151,10 +5144,10 @@ static int mt7996_mcu_set_cal_free_data(struct mt7996_dev *dev)
+ 0x127a, 0x127b, 0x127c, 0x127e, 0x1280, -1},
+ };
+ static const u16 adie_base_7996[] = {
+- 0x400, 0x1e00, 0x1200
++ EFUSE_BASE_OFFS_ADIE0, EFUSE_BASE_OFFS_ADIE1, EFUSE_BASE_OFFS_ADIE2
+ };
+ static const u16 adie_base_7992[] = {
+- 0x400, 0x1200, 0x0
++ EFUSE_BASE_OFFS_ADIE0, EFUSE_BASE_OFFS_ADIE1_7992, 0x0
+ };
+ static const u16 *adie_offs[__MT_MAX_BAND];
+ static const u16 *eep_offs[__MT_MAX_BAND];
+diff --git a/mt7996/mt7996.h b/mt7996/mt7996.h
+index e65d2a6..ddc44de 100644
+--- a/mt7996/mt7996.h
++++ b/mt7996/mt7996.h
+@@ -180,6 +180,29 @@ enum mt7996_eeprom_mode {
+ EXT_EEPROM_MODE,
+ };
+
++enum mt7996_ddie_type {
++ DDIE_7996,
++ DDIE_7992,
++ DDIE_TYPE_NUM,
++};
++
++enum mt7996_adie_type {
++ ADIE_7975,
++ ADIE_7976,
++ ADIE_7977,
++ ADIE_7978,
++ ADIE_7979,
++ ADIE_TYPE_NUM,
++};
++
++enum mt7996_efuse_base_offs {
++ EFUSE_BASE_OFFS_DDIE = 0x0,
++ EFUSE_BASE_OFFS_ADIE0 = 0x400,
++ EFUSE_BASE_OFFS_ADIE2 = 0x1200,
++ EFUSE_BASE_OFFS_ADIE1_7992 = 0x1200,
++ EFUSE_BASE_OFFS_ADIE1 = 0x1e00,
++};
++
+ enum mt7996_coredump_state {
+ MT7996_COREDUMP_IDLE = 0,
+ MT7996_COREDUMP_MANUAL_WA,
+diff --git a/mt7996/testmode.c b/mt7996/testmode.c
+index b369263..6e1cfcf 100644
+--- a/mt7996/testmode.c
++++ b/mt7996/testmode.c
+@@ -2133,6 +2133,127 @@ mt7996_tm_dump_stats(struct mt76_phy *mphy, struct sk_buff *msg)
+ return 0;
+ }
+
++static bool
++mt7996_tm_efuse_update_is_valid(struct mt7996_dev *dev, u32 offset, u8 *write_buf)
++{
++#define PROT_OFFS_MAX_SIZE 8
++#define EFUSE_PROT_END_OFFSET 0xffff
++#define EFUSE_PROT_ALL_MASK GENMASK(15, 0)
++ static const struct efuse_region ddie_prot_offs[][PROT_OFFS_MAX_SIZE] = {
++ [DDIE_7996] = {{.start = 0x10, .end = 0x18f, .prot_mask = -1},
++ {.start = 0x1b0, .end = 0x2bf, .prot_mask = -1},
++ {.start = 0x2c0, .end = 0x2cf, .prot_mask = GENMASK(15, 6)},
++ {.start = 0x2d0, .end = 0x2ff, .prot_mask = -1},
++ {.start = 0x300, .end = 0x30f, .prot_mask = GENMASK(15, 1)},
++ {.start = 0x310, .end = 0x31f, .prot_mask = GENMASK(15, 1)},
++ {.start = 0x320, .end = 0x3ff, .prot_mask = -1},
++ {.start = -1}},
++ [DDIE_7992] = {{.start = 0x10, .end = 0x18f, .prot_mask = -1},
++ {.start = 0x1b0, .end = 0x3ff, .prot_mask = -1},
++ {.start = -1}},
++ };
++ static const struct efuse_region adie_prot_offs[][PROT_OFFS_MAX_SIZE] = {
++ [ADIE_7975] = {{.start = 0x5c0, .end = 0x62f, .prot_mask = -1},
++ {.start = 0x6c0, .end = 0x6ff, .prot_mask = -1},
++ {.start = 0x7a0, .end = 0x7af, .prot_mask = BIT(1) | BIT(9)},
++ {.start = 0x7b0, .end = 0x7bf, .prot_mask = -1},
++ {.start = -1}},
++ [ADIE_7976] = {{.start = 0x0, .end = 0x7f, .prot_mask = -1},
++ {.start = 0x790, .end = 0x79f,
++ .prot_mask = GENMASK(15, 10) | GENMASK(8, 0)},
++ {.start = 0x7a0, .end = 0x7af,
++ .prot_mask = BIT(6) | BIT(8) | BIT(10)},
++ {.start = 0x7b0, .end = 0x7bf, .prot_mask = -1},
++ {.start = -1}},
++ [ADIE_7977] = {{.start = 0x0, .end = 0x5f, .prot_mask = -1},
++ {.start = 0x60, .end = 0x6f, .prot_mask = GENMASK(14, 0)},
++ {.start = 0x70, .end = 0x7f,
++ .prot_mask = GENMASK(15, 14) | GENMASK(12, 0)},
++ {.start = 0x80, .end = 0x10f, .prot_mask = -1},
++ {.start = -1}},
++ };
++ static const struct efuse_region *prot_offs;
++ u8 read_buf[MT76_TM_EEPROM_BLOCK_SIZE], *eeprom = dev->mt76.eeprom.data;
++ int ret, i = 0;
++ u16 base;
++
++ if (!write_buf)
++ return false;
++
++ memset(read_buf, 0, MT76_TM_EEPROM_BLOCK_SIZE);
++ ret = mt7996_mcu_get_eeprom(dev, offset, read_buf,
++ MT76_TM_EEPROM_BLOCK_SIZE, EFUSE_MODE);
++ if (ret && ret != -EINVAL)
++ return false;
++
++ /* no change in this block, so skip it */
++ if (!memcmp(eeprom + offset, read_buf, MT76_TM_EEPROM_BLOCK_SIZE))
++ return false;
++
++ memcpy(write_buf, eeprom + offset, MT76_TM_EEPROM_BLOCK_SIZE);
++
++ switch (mt76_chip(&dev->mt76)) {
++ case 0x7990:
++ if (offset < EFUSE_BASE_OFFS_ADIE0) {
++ base = EFUSE_BASE_OFFS_DDIE;
++ prot_offs = ddie_prot_offs[DDIE_7996];
++ } else if (offset >= EFUSE_BASE_OFFS_ADIE0 &&
++ offset < EFUSE_BASE_OFFS_ADIE2) {
++ base = EFUSE_BASE_OFFS_ADIE0;
++ if (dev->chip_sku == MT7996_VAR_TYPE_233 ||
++ dev->fem_type == MT7996_FEM_EXT)
++ prot_offs = adie_prot_offs[ADIE_7976];
++ else
++ prot_offs = adie_prot_offs[ADIE_7975];
++ } else if (offset >= EFUSE_BASE_OFFS_ADIE2 &&
++ offset < EFUSE_BASE_OFFS_ADIE1) {
++ base = EFUSE_BASE_OFFS_ADIE2;
++ prot_offs = adie_prot_offs[ADIE_7977];
++ } else {
++ base = EFUSE_BASE_OFFS_ADIE1;
++ prot_offs = adie_prot_offs[ADIE_7977];
++ }
++ break;
++ case 0x7992:
++ /* block all the adie region in efuse for kite */
++ if (offset >= EFUSE_BASE_OFFS_ADIE0)
++ return false;
++ base = EFUSE_BASE_OFFS_DDIE;
++ prot_offs = ddie_prot_offs[DDIE_7992];
++ break;
++ default:
++ return false;
++ }
++
++ /* check efuse protection */
++ while (prot_offs[i].start != EFUSE_PROT_END_OFFSET) {
++ if (offset >= prot_offs[i].start + base &&
++ offset <= prot_offs[i].end + base) {
++ unsigned long prot_mask = prot_offs[i].prot_mask;
++ int j;
++
++ if (prot_mask == EFUSE_PROT_ALL_MASK)
++ return false;
++
++ for_each_set_bit(j, &prot_mask, MT76_TM_EEPROM_BLOCK_SIZE) {
++ if (write_buf[j] != read_buf[j]) {
++ write_buf[j] = read_buf[j];
++ dev_warn(dev->mt76.dev,
++ "offset %x is invalid to write\n",
++ offset + j);
++ }
++ }
++ break;
++ }
++ i++;
++ }
++
++ if (!memcmp(read_buf, write_buf, MT76_TM_EEPROM_BLOCK_SIZE))
++ return false;
++
++ return true;
++}
++
+ static int
+ mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev)
+ {
+@@ -2141,8 +2262,9 @@ mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev)
+ .len = cpu_to_le16(sizeof(req) - 4 +
+ MT76_TM_EEPROM_BLOCK_SIZE),
+ };
+- u8 read_buf[MT76_TM_EEPROM_BLOCK_SIZE], *eeprom = dev->mt76.eeprom.data;
+ int msg_len = sizeof(req) + MT76_TM_EEPROM_BLOCK_SIZE;
++ u8 *eeprom = dev->mt76.eeprom.data;
++ u8 write_buf[MT76_TM_EEPROM_BLOCK_SIZE];
+ int i, ret = -EINVAL;
+
+ /* prevent from damaging chip id in efuse */
+@@ -2152,13 +2274,8 @@ mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev)
+ for (i = 0; i < MT7996_EEPROM_SIZE; i += MT76_TM_EEPROM_BLOCK_SIZE) {
+ struct sk_buff *skb;
+
+- memset(read_buf, 0, MT76_TM_EEPROM_BLOCK_SIZE);
+- ret = mt7996_mcu_get_eeprom(dev, i, read_buf, sizeof(read_buf),
+- EFUSE_MODE);
+- if (ret && ret != -EINVAL)
+- return ret;
+-
+- if (!memcmp(eeprom + i, read_buf, MT76_TM_EEPROM_BLOCK_SIZE))
++ memset(write_buf, 0, MT76_TM_EEPROM_BLOCK_SIZE);
++ if (!mt7996_tm_efuse_update_is_valid(dev, i, write_buf))
+ continue;
+
+ skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, msg_len);
+@@ -2167,7 +2284,7 @@ mt7996_tm_write_back_to_efuse(struct mt7996_dev *dev)
+
+ req.addr = cpu_to_le32(i);
+ skb_put_data(skb, &req, sizeof(req));
+- skb_put_data(skb, eeprom + i, MT76_TM_EEPROM_BLOCK_SIZE);
++ skb_put_data(skb, write_buf, MT76_TM_EEPROM_BLOCK_SIZE);
+
+ ret = mt76_mcu_skb_send_msg(&dev->mt76, skb,
+ MCU_WM_UNI_CMD(EFUSE_CTRL), true);
+diff --git a/mt7996/testmode.h b/mt7996/testmode.h
+index 5c720da..154392d 100644
+--- a/mt7996/testmode.h
++++ b/mt7996/testmode.h
+@@ -363,4 +363,10 @@ struct mt7996_tm_rdd_ipi_ctrl {
+ __le32 tx_assert_time; /* unit: us */
+ } __packed;
+
++struct efuse_region {
++ u16 start;
++ u16 end;
++ u16 prot_mask;
++};
++
+ #endif
+--
+2.45.2
+