mt76: mt7915: add support for flash mode
authorShayne Chen <shayne.chen@mediatek.com>
Mon, 14 Dec 2020 02:38:55 +0000 (10:38 +0800)
committerFelix Fietkau <nbd@nbd.name>
Tue, 26 Jan 2021 19:07:47 +0000 (20:07 +0100)
Add support for getting rf values from flash.
This is used for some test purposes and products.
If the mtd partition is configured in dts, driver will read from flash
to init eeprom command; if not, still init it with efuse's values.

An example:
&slot0 {
mt7915@0,0 {
reg = <0x0000 0 0 0 0>;
device_type = "pci";
mediatek,mtd-eeprom = <&factory 0x0000>;
};
};

Acked-by: Ryder Lee <ryder.lee@mediatek.com>
Signed-off-by: Shayne Chen <shayne.chen@mediatek.com>
Signed-off-by: Felix Fietkau <nbd@nbd.name>
drivers/net/wireless/mediatek/mt76/mt7915/eeprom.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.c
drivers/net/wireless/mediatek/mt76/mt7915/mcu.h
drivers/net/wireless/mediatek/mt76/mt7915/mt7915.h

index 7a2be3f..0a3ac07 100644 (file)
@@ -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;
 }
index a41d22c..11e2fcc 100644 (file)
@@ -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);
 }
index cd1a425..30ec2ef 100644 (file)
@@ -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;
index 5223869..b585ad1 100644 (file)
@@ -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