Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 | // SPDX-License-Identifier: ISC /* * Copyright (C) 2016 Felix Fietkau <nbd@nbd.name> */ #include <linux/of.h> #include <linux/of_net.h> #include <linux/mtd/mtd.h> #include <linux/mtd/partitions.h> #include <linux/etherdevice.h> #include "mt76.h" static int mt76_get_of_eeprom(struct mt76_dev *dev, int len) { #if defined(CONFIG_OF) && defined(CONFIG_MTD) struct device_node *np = dev->dev->of_node; struct mtd_info *mtd; const __be32 *list; const char *part; phandle phandle; int offset = 0; int size; size_t retlen; int ret; if (!np) return -ENOENT; list = of_get_property(np, "mediatek,mtd-eeprom", &size); if (!list) return -ENOENT; phandle = be32_to_cpup(list++); if (!phandle) return -ENOENT; np = of_find_node_by_phandle(phandle); if (!np) return -EINVAL; part = of_get_property(np, "label", NULL); if (!part) part = np->name; mtd = get_mtd_device_nm(part); if (IS_ERR(mtd)) { ret = PTR_ERR(mtd); goto out_put_node; } if (size <= sizeof(*list)) { ret = -EINVAL; goto out_put_node; } offset = be32_to_cpup(list); ret = mtd_read(mtd, offset, len, &retlen, dev->eeprom.data); put_mtd_device(mtd); if (ret) goto out_put_node; if (retlen < len) { ret = -EINVAL; goto out_put_node; } out_put_node: of_node_put(np); return ret; #else return -ENOENT; #endif } void mt76_eeprom_override(struct mt76_dev *dev) { #ifdef CONFIG_OF struct device_node *np = dev->dev->of_node; const u8 *mac; if (!np) return; mac = of_get_mac_address(np); if (!IS_ERR(mac)) ether_addr_copy(dev->macaddr, mac); #endif if (!is_valid_ether_addr(dev->macaddr)) { eth_random_addr(dev->macaddr); dev_info(dev->dev, "Invalid MAC address, using random address %pM\n", dev->macaddr); } } EXPORT_SYMBOL_GPL(mt76_eeprom_override); int mt76_eeprom_init(struct mt76_dev *dev, int len) { dev->eeprom.size = len; dev->eeprom.data = devm_kzalloc(dev->dev, len, GFP_KERNEL); if (!dev->eeprom.data) return -ENOMEM; return !mt76_get_of_eeprom(dev, len); } EXPORT_SYMBOL_GPL(mt76_eeprom_init); |