Last active
April 2, 2019 12:59
-
-
Save zavorka/b1cd1b688648f259238ef2168c22782d to your computer and use it in GitHub Desktop.
burn_ethaddr_to_efuses
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
&emac { | |
nvmem-cells = <ðaddr>; | |
nvmem-cell-names = "mac-address"; | |
}; | |
&sid { | |
#address-cells = <1>; | |
#size-cells = <1>; | |
ethaddr: ethaddr@ec { | |
reg = <0xec 0x06>; | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// MAP OF WRITABLE REGIONS | |
// | |
// Obtained by sequentially writing 0xff into each byte except | |
// - CHIPID field (read-only), | |
// - THERMAL_SENSOR field (already contaminated) and | |
// - LCJS field (writable but the value is affecting behavior) | |
// | |
// I guess the remaining unchanged bits become writable under | |
// some yet-to-be-found condition. | |
// I didn't observe any undesirable effect after setting | |
// the eFuses, can't guarantee there aren't any though. | |
// (Tried out on hundreds of chips) | |
// | |
// 00000000 /* CHIPID */ | |
// 00000010 ff ff ff ff 00 00 00 00 ff ff ff ff ff ff ff ff | |
// 00000020 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 00000030 00 00 00 00 /* THERMAL_SENSOR */ ff ff ff ff | |
// 00000040 ff ff ff ff 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 00000050 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 00000070 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 00000080 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 000000a0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 000000b0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 000000c0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 000000d0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | |
// 000000e0 00 00 00 00 00 00 00 00 00 00 00 00 ff ff ff ff | |
// 000000f0 ff ff ff ff /* LCJS */ 00 00 00 00 00 00 00 00 | |
#include <cstdio> | |
#include <endian.h> | |
#include <cstring> | |
#include <cassert> | |
/* Forward declarations */ | |
typedef struct _feldev_handle feldev_handle; | |
uint32_t fel_readl(feldev_handle *dev, uint32_t addr); | |
void fel_writel(feldev_handle *dev, uint32_t addr, uint32_t val); | |
constexpr uint8_t SID_ETH_MAC_OFFSET 0xec; | |
constexpr uint32_t EFUSES_MAGIC = 0xac00u; | |
extern "C" uint32_t read_sid(feldev_handle *dev, uint8_t address) | |
{ | |
uint32_t prctl = (address << 16) | EFUSES_MAGIC | 0x02u; | |
fel_writel(dev, 0x01c14040, prctl); | |
uint32_t data = fel_readl(dev, 0x01c14060); | |
return be32toh(data); | |
} | |
extern "C" void write_sid(feldev_handle *dev, uint8_t address, uint32_t value) | |
{ | |
uint32_t prctl = (address << 16) | EFUSES_MAGIC | 0x01u; | |
fel_writel(dev, 0x01c14050, htobe32(value)); | |
fel_writel(dev, 0x01c14040, prctl); | |
} | |
extern "C" void write_eth_mac(feldev_handle* handle, uint8_t* mac) | |
{ | |
uint32_t tmp; | |
memcpy(&tmp, mac, 4); | |
write_sid(handle, SID_ETH_MAC_OFFSET, tmp); | |
memcpy(&tmp, mac + 4, 4); | |
write_sid(handle, SID_ETH_MAC_OFFSET + 4, tmp); | |
} | |
extern "C" void print_eth_mac(feldev_handle *dev) | |
{ | |
uint8_t ether_addr[8]; | |
uint32_t tmp = read_sid(dev, SID_ETH_MAC_OFFSET); | |
memcpy(ether_addr, &tmp, 4); | |
tmp = read_sid(dev, SID_ETH_MAC_OFFSET + 4); | |
memcpy(ether_addr + 4, &tmp, 4); | |
printf("eth mac is %02X:%02X:%02X:%02X:%02X:%02X\n", | |
ether_addr[0], ether_addr[1], ether_addr[2], | |
ether_addr[3], ether_addr[4], ether_addr[5] | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
967142cf31f8b20eeec2d5633eeb29ad9104c4ccommit 967142cf31f8b20eeec2d5633eeb29ad9104c4c3 | |
Author: Roman Beránek <roman.beranek@prusa3d.com> | |
Date: Fri Nov 16 02:19:25 2018 +0100 | |
net: stmmac: enable MAC address to be read from a nvmem cell as is described in Documentation/devicetree/bindings/net/ethernet.txt | |
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |
index 72da77b94ecd..8a7b804528ef 100644 | |
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c | |
@@ -25,6 +25,7 @@ | |
#include <linux/of_net.h> | |
#include <linux/of_device.h> | |
#include <linux/of_mdio.h> | |
+#include <linux/nvmem-consumer.h> | |
#include "stmmac.h" | |
#include "stmmac_platform.h" | |
@@ -375,6 +376,22 @@ static int stmmac_dt_phy(struct plat_stmmacenet_data *plat, | |
return 0; | |
} | |
+static void *stmmac_get_nvmem_address(struct device *dev) | |
+{ | |
+ struct nvmem_cell *cell; | |
+ size_t cell_size; | |
+ char *mac; | |
+ | |
+ cell = nvmem_cell_get(dev, "mac-address"); | |
+ if (IS_ERR(cell)) | |
+ return NULL; | |
+ | |
+ mac = nvmem_cell_read(cell, &cell_size); | |
+ nvmem_cell_put(cell); | |
+ | |
+ return mac; | |
+} | |
+ | |
/** | |
* stmmac_probe_config_dt - parse device-tree driver parameters | |
* @pdev: platform_device structure | |
@@ -389,13 +406,21 @@ stmmac_probe_config_dt(struct platform_device *pdev, const char **mac) | |
struct device_node *np = pdev->dev.of_node; | |
struct plat_stmmacenet_data *plat; | |
struct stmmac_dma_cfg *dma_cfg; | |
+ const u8 *mac_addr; | |
int rc; | |
plat = devm_kzalloc(&pdev->dev, sizeof(*plat), GFP_KERNEL); | |
if (!plat) | |
return ERR_PTR(-ENOMEM); | |
+ /* U-boot passes a MAC address it found/generated for the | |
+ interface as a "local-mac-address" attribute in the dt | |
+ node. Here it is received. | |
+ */ | |
*mac = of_get_mac_address(np); | |
+ mac_addr = stmmac_get_nvmem_address(&pdev->dev); | |
+ if (mac_addr && is_valid_ether_addr(mac_addr)) | |
+ *mac = mac_addr; | |
plat->interface = of_get_phy_mode(np); | |
/* Get max speed of operation from device tree */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment