Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions mt7615/eeprom.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,62 @@
*/

#include <linux/of.h>
#include <linux/mtd/mtd.h>
#include "mt7615.h"
#include "eeprom.h"

static int mt7615_check_eeprom(struct mt76_dev *dev);

static int mt7615_read_factory_partition(struct mt7615_dev *dev, u8 **buf,
size_t *len)
{
#ifdef CONFIG_MTD
struct mtd_info *mtd;
u8 *data;
size_t retlen;
int ret;

mtd = get_mtd_device_nm("factory");
if (IS_ERR(mtd))
mtd = get_mtd_device(NULL, 2);
if (IS_ERR(mtd))
return PTR_ERR(mtd);

if (mtd->size < 0x8000 + MT7663_EEPROM_SIZE) {
put_mtd_device(mtd);
return -EINVAL;
}

data = kmalloc(mtd->size, GFP_KERNEL);
if (!data) {
put_mtd_device(mtd);
return -ENOMEM;
}

ret = mtd_read(mtd, 0, mtd->size, &retlen, data);
put_mtd_device(mtd);

if (mtd_is_bitflip(ret))
ret = 0;
if (ret) {
kfree(data);
return ret;
}

if (retlen < mtd->size) {
kfree(data);
return -EINVAL;
}

*buf = data;
*len = mtd->size;

return 0;
#else
return -ENOENT;
#endif
}

static int mt7615_efuse_read(struct mt7615_dev *dev, u32 base,
u16 addr, u8 *data)
{
Expand Down Expand Up @@ -73,6 +126,7 @@ static int mt7615_efuse_init(struct mt7615_dev *dev, u32 base)

static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
{
u8 *factory = NULL;
int ret;

BUILD_BUG_ON(MT7615_EEPROM_FULL_SIZE < MT7663_EEPROM_SIZE);
Expand All @@ -81,6 +135,71 @@ static int mt7615_eeprom_load(struct mt7615_dev *dev, u32 addr)
if (ret < 0)
return ret;

if (dev->is_mt7663_pci && mt7615_check_eeprom(&dev->mt76)) {
static const u32 mt7663_offsets[] = { 0x8000 };
size_t factory_len = 0;
u8 data[16];
int i;

for (i = 0; i < ARRAY_SIZE(mt7663_offsets); i++) {
ret = mt76_get_of_data_from_mtd(&dev->mt76, data,
mt7663_offsets[i], sizeof(data));
if (ret == -ENOENT) {
if (!factory) {
ret = mt7615_read_factory_partition(dev, &factory,
&factory_len);
if (ret)
goto out;
}

if (factory_len < mt7663_offsets[i] + sizeof(data)) {
ret = -EINVAL;
goto out;
}

memcpy(data, factory + mt7663_offsets[i], sizeof(data));
ret = 0;
}
if (ret)
continue;

if (get_unaligned_le16(data) != 0x7663 ||
!is_valid_ether_addr(data + MT_EE_MAC_ADDR))
continue;

memset(dev->mt76.eeprom.data, 0, dev->mt76.eeprom.size);
ret = mt76_get_of_data_from_mtd(&dev->mt76,
dev->mt76.eeprom.data,
mt7663_offsets[i],
MT7663_EEPROM_SIZE);
if (ret == -ENOENT) {
if (!factory) {
ret = mt7615_read_factory_partition(dev, &factory,
&factory_len);
if (ret)
goto out;
}

if (factory_len < mt7663_offsets[i] + MT7663_EEPROM_SIZE) {
ret = -EINVAL;
goto out;
}

memcpy(dev->mt76.eeprom.data, factory + mt7663_offsets[i],
MT7663_EEPROM_SIZE);
ret = 0;
}
if (ret)
goto out;
break;
}
}

out:
kfree(factory);
if (ret)
return ret;

return mt7615_efuse_init(dev, addr);
}

Expand Down
5 changes: 0 additions & 5 deletions mt7615/mcu.c
Original file line number Diff line number Diff line change
Expand Up @@ -2074,11 +2074,6 @@ static void mt7615_mcu_set_txpower_sku(struct mt7615_phy *phy, u8 *sku)
&limits, tx_power);
mphy->txpower_cur = tx_power;

if (is_mt7663(mphy->dev)) {
memset(sku, tx_power, MT_SKU_4SS_DELTA + 1);
return;
}

for (i = 0; i < MT_SKU_1SS_DELTA; i++)
sku[i] = limits_array[sku_mapping[i]];

Expand Down
3 changes: 2 additions & 1 deletion mt7615/mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ static u32 mt7615_rmw(struct mt76_dev *mdev, u32 offset, u32 mask, u32 val)
}

int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
int irq, const u32 *map)
int irq, const u32 *map, bool is_mt7663_pci)
{
static const struct mt76_driver_ops drv_ops = {
/* txwi_size = txd size + txp size */
Expand Down Expand Up @@ -203,6 +203,7 @@ int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
tasklet_setup(&mdev->irq_tasklet, mt7615_irq_tasklet);

dev->reg_map = map;
dev->is_mt7663_pci = is_mt7663_pci;
dev->ops = ops;
mdev->rev = (mt76_rr(dev, MT_HW_CHIPID) << 16) |
(mt76_rr(dev, MT_HW_REV) & 0xff);
Expand Down
3 changes: 2 additions & 1 deletion mt7615/mt7615.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ struct mt7615_dev {
bool fw_debug;
bool flash_eeprom;
bool dbdc_support;
bool is_mt7663_pci;

u8 fw_ver;

Expand Down Expand Up @@ -368,7 +369,7 @@ static inline int mt7622_wmac_init(struct mt7615_dev *dev)

int mt7615_thermal_init(struct mt7615_dev *dev);
int mt7615_mmio_probe(struct device *pdev, void __iomem *mem_base,
int irq, const u32 *map);
int irq, const u32 *map, bool is_mt7663_pci);
u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);

u32 mt7615_reg_map(struct mt7615_dev *dev, u32 addr);
Expand Down
2 changes: 1 addition & 1 deletion mt7615/pci.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ static int mt7615_pci_probe(struct pci_dev *pdev,

map = id->device == 0x7663 ? mt7663e_reg_map : mt7615e_reg_map;
ret = mt7615_mmio_probe(&pdev->dev, pcim_iomap_table(pdev)[0],
pdev->irq, map);
pdev->irq, map, id->device == 0x7663);
if (ret)
goto error;

Expand Down
3 changes: 2 additions & 1 deletion mt7615/soc.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ static int mt7622_wmac_probe(struct platform_device *pdev)
if (IS_ERR(mem_base))
return PTR_ERR(mem_base);

return mt7615_mmio_probe(&pdev->dev, mem_base, irq, mt7615e_reg_map);
return mt7615_mmio_probe(&pdev->dev, mem_base, irq, mt7615e_reg_map,
false);
}

#if LINUX_VERSION_CODE < KERNEL_VERSION(6,11,0)
Expand Down