Commit 68808872 authored by Deren Wu's avatar Deren Wu Committed by Felix Fietkau

mt76: mt7921: Add mt7922 support

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: default avatarJimmy Hu <Jimmy.Hu@mediatek.com>
Signed-off-by: default avatarJimmy Hu <Jimmy.Hu@mediatek.com>
Signed-off-by: default avatarDeren Wu <deren.wu@mediatek.com>
Signed-off-by: default avatarFelix Fietkau <nbd@nbd.name>
parent b5cd1fd6
...@@ -85,9 +85,14 @@ struct mt76_connac_coredump { ...@@ -85,9 +85,14 @@ struct mt76_connac_coredump {
extern const struct wiphy_wowlan_support mt76_connac_wowlan_support; 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) 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) static inline bool is_mt7663(struct mt76_dev *dev)
......
...@@ -36,6 +36,7 @@ static int mt7921_check_eeprom(struct mt7921_dev *dev) ...@@ -36,6 +36,7 @@ static int mt7921_check_eeprom(struct mt7921_dev *dev)
val = get_unaligned_le16(eeprom); val = get_unaligned_le16(eeprom);
switch (val) { switch (val) {
case 0x7922:
case 0x7961: case 0x7961:
return 0; return 0;
default: default:
......
...@@ -82,9 +82,17 @@ struct mt7921_fw_region { ...@@ -82,9 +82,17 @@ struct mt7921_fw_region {
#define FW_START_OVERRIDE BIT(0) #define FW_START_OVERRIDE BIT(0)
#define FW_START_WORKING_PDA_CR4 BIT(2) #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_MASK GENMASK(15, 0)
#define PATCH_SEC_TYPE_INFO 0x2 #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_lo(id) FIELD_GET(GENMASK(7, 0), (u16)id)
#define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id) #define to_wcid_hi(id) FIELD_GET(GENMASK(9, 8), (u16)id)
...@@ -742,6 +750,46 @@ static int mt7921_driver_own(struct mt7921_dev *dev) ...@@ -742,6 +750,46 @@ static int mt7921_driver_own(struct mt7921_dev *dev)
return 0; 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) static int mt7921_load_patch(struct mt7921_dev *dev)
{ {
const struct mt7921_patch_hdr *hdr; const struct mt7921_patch_hdr *hdr;
...@@ -759,7 +807,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev) ...@@ -759,7 +807,7 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
return -EAGAIN; 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) if (ret)
goto out; goto out;
...@@ -777,7 +825,8 @@ static int mt7921_load_patch(struct mt7921_dev *dev) ...@@ -777,7 +825,8 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) { for (i = 0; i < be32_to_cpu(hdr->desc.n_region); i++) {
struct mt7921_patch_sec *sec; struct mt7921_patch_sec *sec;
const u8 *dl; const u8 *dl;
u32 len, addr; u32 len, addr, mode;
u32 sec_info = 0;
sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) + sec = (struct mt7921_patch_sec *)(fw->data + sizeof(*hdr) +
i * sizeof(*sec)); i * sizeof(*sec));
...@@ -790,9 +839,11 @@ static int mt7921_load_patch(struct mt7921_dev *dev) ...@@ -790,9 +839,11 @@ static int mt7921_load_patch(struct mt7921_dev *dev)
addr = be32_to_cpu(sec->info.addr); addr = be32_to_cpu(sec->info.addr);
len = be32_to_cpu(sec->info.len); len = be32_to_cpu(sec->info.len);
dl = fw->data + be32_to_cpu(sec->offs); 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, ret = mt76_connac_mcu_init_download(&dev->mt76, addr, len,
DL_MODE_NEED_RSP); mode);
if (ret) { if (ret) {
dev_err(dev->mt76.dev, "Download request failed\n"); dev_err(dev->mt76.dev, "Download request failed\n");
goto out; goto out;
...@@ -889,13 +940,25 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev, ...@@ -889,13 +940,25 @@ mt7921_mcu_send_ram_firmware(struct mt7921_dev *dev,
return mt76_connac_mcu_start_firmware(&dev->mt76, override, option); 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) static int mt7921_load_ram(struct mt7921_dev *dev)
{ {
const struct mt7921_fw_trailer *hdr; const struct mt7921_fw_trailer *hdr;
const struct firmware *fw; const struct firmware *fw;
int ret; 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) if (ret)
return ret; return ret;
......
...@@ -33,6 +33,9 @@ ...@@ -33,6 +33,9 @@
#define MT7921_FIRMWARE_WM "mediatek/WIFI_RAM_CODE_MT7961_1.bin" #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 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_EEPROM_SIZE 3584
#define MT7921_TOKEN_SIZE 8192 #define MT7921_TOKEN_SIZE 8192
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
static const struct pci_device_id mt7921_pci_device_table[] = { static const struct pci_device_id mt7921_pci_device_table[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) }, { PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7961) },
{ PCI_DEVICE(PCI_VENDOR_ID_MEDIATEK, 0x7922) },
{ }, { },
}; };
...@@ -336,6 +337,8 @@ module_pci_driver(mt7921_pci_driver); ...@@ -336,6 +337,8 @@ module_pci_driver(mt7921_pci_driver);
MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table); MODULE_DEVICE_TABLE(pci, mt7921_pci_device_table);
MODULE_FIRMWARE(MT7921_FIRMWARE_WM); MODULE_FIRMWARE(MT7921_FIRMWARE_WM);
MODULE_FIRMWARE(MT7921_ROM_PATCH); MODULE_FIRMWARE(MT7921_ROM_PATCH);
MODULE_FIRMWARE(MT7922_FIRMWARE_WM);
MODULE_FIRMWARE(MT7922_ROM_PATCH);
MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>"); MODULE_AUTHOR("Sean Wang <sean.wang@mediatek.com>");
MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>"); MODULE_AUTHOR("Lorenzo Bianconi <lorenzo@kernel.org>");
MODULE_LICENSE("Dual BSD/GPL"); MODULE_LICENSE("Dual BSD/GPL");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment