diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c index 7a2be3f61398..0a3ac07bab4a 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c @@ -22,7 +22,10 @@ static int mt7915_eeprom_load(struct mt7915_dev *dev) if (ret < 0) return ret; - memset(dev->mt76.eeprom.data, -1, MT7915_EEPROM_SIZE); + if (ret) + dev->flash_mode = true; + else + memset(dev->mt76.eeprom.data, -1, MT7915_EEPROM_SIZE); return 0; } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c index a41d22cdf2b4..11e2fcc2f18d 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.c @@ -3237,17 +3237,57 @@ int mt7915_mcu_set_chan_info(struct mt7915_phy *phy, int cmd) return mt76_mcu_send_msg(&dev->mt76, cmd, &req, sizeof(req), true); } +static int mt7915_mcu_set_eeprom_flash(struct mt7915_dev *dev) +{ +#define TOTAL_PAGE_MASK GENMASK(7, 5) +#define PAGE_IDX_MASK GENMASK(4, 2) +#define PER_PAGE_SIZE 0x400 + struct mt7915_mcu_eeprom req = { .buffer_mode = EE_MODE_BUFFER }; + u8 total = MT7915_EEPROM_SIZE / PER_PAGE_SIZE; + u8 *eep = (u8 *)dev->mt76.eeprom.data; + int eep_len; + int i; + + for (i = 0; i <= total; i++, eep += eep_len) { + struct sk_buff *skb; + int ret; + + if (i == total) + eep_len = MT7915_EEPROM_SIZE % PER_PAGE_SIZE; + else + eep_len = PER_PAGE_SIZE; + + skb = mt76_mcu_msg_alloc(&dev->mt76, NULL, + sizeof(req) + eep_len); + if (!skb) + return -ENOMEM; + + req.format = FIELD_PREP(TOTAL_PAGE_MASK, total) | + FIELD_PREP(PAGE_IDX_MASK, i) | EE_FORMAT_WHOLE; + req.len = cpu_to_le16(eep_len); + + skb_put_data(skb, &req, sizeof(req)); + skb_put_data(skb, eep, eep_len); + + ret = mt76_mcu_skb_send_msg(&dev->mt76, skb, + MCU_EXT_CMD_EFUSE_BUFFER_MODE, true); + if (ret) + return ret; + } + + return 0; +} + int mt7915_mcu_set_eeprom(struct mt7915_dev *dev) { - struct req_hdr { - u8 buffer_mode; - u8 format; - __le16 len; - } __packed req = { + struct mt7915_mcu_eeprom req = { .buffer_mode = EE_MODE_EFUSE, .format = EE_FORMAT_WHOLE, }; + if (dev->flash_mode) + return mt7915_mcu_set_eeprom_flash(dev); + return mt76_mcu_send_msg(&dev->mt76, MCU_EXT_CMD_EFUSE_BUFFER_MODE, &req, sizeof(req), true); } diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h index cd1a4256c843..30ec2ef4cc74 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mcu.h @@ -118,6 +118,12 @@ struct mt7915_mcu_rdd_report { } hw_pulse[32]; } __packed; +struct mt7915_mcu_eeprom { + u8 buffer_mode; + u8 format; + __le16 len; +} __packed; + struct mt7915_mcu_eeprom_info { __le32 addr; __le32 valid; diff --git a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h index 52238694b7d9..b585ad1c78ab 100644 --- a/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h +++ b/drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h @@ -175,6 +175,7 @@ struct mt7915_dev { s8 **rate_power; /* TODO: use mt76_rate_power */ bool dbdc_support; + bool flash_mode; bool fw_debug; #ifdef CONFIG_NL80211_TESTMODE