2021-07-15 17:35:51

by Deren Wu

[permalink] [raw]
Subject: [PATCH] mt76: mt7921: Add mt7922 support

From: Deren Wu <[email protected]>

Add new chip mt7922 in mt7921 module with following items
1. new chip ID / fw bin name
2. is_mt7922()
check chip type for different fw files
3. mt7921_get_data_mode()
check security type of fw (backward compatible)

Co-developed-by: Jimmy Hu <[email protected]>
Signed-off-by: Jimmy Hu <[email protected]>
Signed-off-by: Deren Wu <[email protected]>
---
.../net/wireless/mediatek/mt76/mt76_connac.h | 7 +-
.../wireless/mediatek/mt76/mt7921/eeprom.c | 1 +
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 71 +++++++++++++++++--
.../wireless/mediatek/mt76/mt7921/mt7921.h | 3 +
.../net/wireless/mediatek/mt76/mt7921/pci.c | 3 +
5 files changed, 80 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt76_connac.h b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
index f49d97d0a1c5..e7f01c2978a2 100644
--- a/drivers/net/wireless/mediatek/mt76/mt76_connac.h
+++ b/drivers/net/wireless/mediatek/mt76/mt76_connac.h
@@ -85,9 +85,14 @@ struct mt76_connac_coredump {

extern const struct wiphy_wowlan_support mt76_connac_wowlan_support;

+static inline bool is_mt7922(struct mt76_dev *dev)
+{
+ return mt76_chip(dev) == 0x7922;
+}
+
static inline bool is_mt7921(struct mt76_dev *dev)
{
- return mt76_chip(dev) == 0x7961;
+ return mt76_chip(dev) == 0x7961 || is_mt7922(dev);
}

static inline bool is_mt7663(struct mt76_dev *dev)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c
index 691d14a1a7bf..4d0a4aeac6bf 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/eeprom.c
@@ -36,6 +36,7 @@ static int mt7921_check_eeprom(struct mt7921_dev *dev)
val = get_unaligned_le16(eeprom);

switch (val) {
+ case 0x7922:
case 0x7961:
return 0;
default:
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 35d57d94dadd..5672198a94e6 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -82,9 +82,17 @@ struct mt7921_fw_region {
#define FW_START_OVERRIDE BIT(0)
#define FW_START_WORKING_PDA_CR4 BIT(2)

+#define PATCH_SEC_NOT_SUPPORT GENMASK(31, 0)
#define PATCH_SEC_TYPE_MASK GENMASK(15, 0)
#define PATCH_SEC_TYPE_INFO 0x2

+#define PATCH_SEC_ENC_TYPE_MASK GENMASK(31, 24)
+#define PATCH_SEC_ENC_TYPE_PLAIN 0x00
+#define PATCH_SEC_ENC_TYPE_AES 0x01
+#define PATCH_SEC_ENC_TYPE_SCRAMBLE 0x02
+#define PATCH_SEC_ENC_SCRAMBLE_INFO_MASK GENMASK(15, 0)
+#define PATCH_SEC_ENC_AES_KEY_MASK GENMASK(7, 0)
+
#define to_wcid_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id)
#define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id)

@@ -738,6 +746,46 @@ static int mt7921_driver_own(struct mt7921_dev *dev)
return 0;
}

+static u32 mt7921_get_data_mode(struct mt7921_dev *dev, u32 info)
+{
+ u32 mode = DL_MODE_NEED_RSP;
+
+ if (info == PATCH_SEC_NOT_SUPPORT)
+ return mode;
+
+ switch (FIELD_GET(PATCH_SEC_ENC_TYPE_MASK, info)) {
+ case PATCH_SEC_ENC_TYPE_PLAIN:
+ break;
+ case PATCH_SEC_ENC_TYPE_AES:
+ mode |= DL_MODE_ENCRYPT;
+ mode |= FIELD_PREP(DL_MODE_KEY_IDX,
+ (info & PATCH_SEC_ENC_AES_KEY_MASK)) & DL_MODE_KEY_IDX;
+ mode |= DL_MODE_RESET_SEC_IV;
+ break;
+ case PATCH_SEC_ENC_TYPE_SCRAMBLE:
+ mode |= DL_MODE_ENCRYPT;
+ mode |= DL_CONFIG_ENCRY_MODE_SEL;
+ mode |= DL_MODE_RESET_SEC_IV;
+ break;
+ default:
+ dev_err(dev->mt76.dev, "Encryption type not support!\n");
+ }
+
+ return mode;
+}
+
+static char *mt7921_patch_name(struct mt7921_dev *dev)
+{
+ char *ret;
+
+ if (is_mt7922(&dev->mt76))
+ ret = MT7922_ROM_PATCH;
+ else
+ ret = MT7921_ROM_PATCH;
+
+ return ret;
+}
+
static int mt7921_load_patch(struct mt7921_dev *dev)
{
const struct mt7921_patch_hdr *hdr;
@@ -755,7 +803,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
return -EAGAIN;
}

- ret = request_firmware(&fw, MT7921_ROM_PATCH, dev->mt76.dev);
+ ret = request_firmware(&fw, mt7921_patch_name(dev), dev->mt76.dev);
if (ret)
goto out;

@@ -773,7 +821,8 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
struct mt7921_patch_sec *sec;
const u8 *dl;
- u32 len, addr;
+ u32 len, addr, mode;
+ u32 sec_info = 0;

sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) +
i * sizeof(*sec));
@@ -786,9 +835,11 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
addr = be32_to_cpu(sec->info.addr);
len = be32_to_cpu(sec->info.len);
dl = fw->data + be32_to_cpu(sec->offs);
+ sec_info = be32_to_cpu(sec->info.sec_key_idx);
+ mode = mt7921_get_data_mode(dev, sec_info);

ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
- DL_MODE_NEED_RSP);
+ mode);
if (ret) {
dev_err(dev->mt76.dev, "Download request failed\n");
goto out;
@@ -885,13 +936,25 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
return mt76_connac_mcu_start_firmware(&dev->mt76, override, option);
}

+static char *mt7921_ram_name(struct mt7921_dev *dev)
+{
+ char *ret;
+
+ if (is_mt7922(&dev->mt76))
+ ret = MT7922_FIRMWARE_WM;
+ else
+ ret = MT7921_FIRMWARE_WM;
+
+ return ret;
+}
+
static int mt7921_load_ram(struct mt7921_dev *dev)
{
const struct mt7921_fw_trailer *hdr;
const struct firmware *fw;
int ret;

- ret = request_firmware(&fw, MT7921_FIRMWARE_WM, dev->mt76.dev);
+ ret = request_firmware(&fw, mt7921_ram_name(dev), dev->mt76.dev);
if (ret)
return ret;

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
index 6e9e4dfb3928..51bcaa599268 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mt7921.h
@@ -33,6 +33,9 @@
#define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin"
#define MT7921_ROM_PATCH "mediatek/WIFI_MT7961_patch_mcu_1_2_hdr.bin"

+#define MT7922_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7922_1.bin"
+#define MT7922_ROM_PATCH "mediatek/WIFI_MT7922_patch_mcu_1_1_hdr.bin"
+
#define MT7921_EEPROM_SIZE 3584
#define MT7921_TOKEN_SIZE 8192

diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
index 33782e1ee312..97ca8290881f 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/pci.c
@@ -14,6 +14,7 @@

static const struct pci_device_id mt7921_pci_device_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) },
+ { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922) },
{ },
};

@@ -336,6 +337,8 @@ module_pci_driver(mt7921_pci_driver);
MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table);
MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
MODULE_FIRMWARE(MT7921_ROM_PATCH);
+MODULE_FIRMWARE(MT7922_FIRMWARE_WM);
+MODULE_FIRMWARE(MT7922_ROM_PATCH);
MODULE_AUTHOR("Sean Wang <[email protected]>");
MODULE_AUTHOR("Lorenzo Bianconi <[email protected]>");
MODULE_LICENSE("Dual BSD/GPL");
--
2.25.1