-
Notifications
You must be signed in to change notification settings - Fork 12
Set ethernet and wifi MAC address #21
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
/* | ||
* Copyright (C) 2016 Imagination Technologies | ||
* Author: Francois Berder <[email protected]> | ||
* | ||
* SPDX-License-Identifier: GPL-2.0+ | ||
*/ | ||
|
||
#include <common.h> | ||
|
||
#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_OF_BOARD_SETUP) | ||
|
||
#include <winbond-otp.h> | ||
#include "otp.h" | ||
|
||
DECLARE_GLOBAL_DATA_PTR; | ||
|
||
static void fixup_wifi_mac(void *blob, int node) | ||
{ | ||
u_char wifi_sta_mac_addr[MAC_ADDR_LEN], wifi_ap_mac_addr[MAC_ADDR_LEN]; | ||
|
||
memset(wifi_sta_mac_addr, 0, sizeof(wifi_sta_mac_addr)); | ||
memset(wifi_ap_mac_addr, 0, sizeof(wifi_ap_mac_addr)); | ||
|
||
if (read_otp_version(VERSION_REG0_OFFSET) >= 1) { | ||
/* Read MAC addresses from OTP */ | ||
if (read_otp_data(WIFI_STA_MAC_ADDRESS_OFFSET, MAC_ADDR_LEN, | ||
(char *)wifi_sta_mac_addr) | ||
|| read_otp_data(WIFI_AP_MAC_ADDRESS_OFFSET, MAC_ADDR_LEN, | ||
(char *)wifi_ap_mac_addr)) { | ||
printf("WARNING: Could not read Wifi MAC addresses from OTP\n"); | ||
return; | ||
} | ||
} | ||
|
||
/* Set Wifi STA and AP MAC address in device tree */ | ||
if (is_valid_ethaddr(wifi_sta_mac_addr)) | ||
fdt_setprop(blob, node, "mac-address0", wifi_sta_mac_addr, | ||
MAC_ADDR_LEN); | ||
else | ||
printf("WARNING: Invalid Wifi sta MAC address.\n"); | ||
|
||
if (is_valid_ethaddr(wifi_ap_mac_addr)) | ||
fdt_setprop(blob, node, "mac-address1", wifi_ap_mac_addr, | ||
MAC_ADDR_LEN); | ||
else | ||
printf("WARNING: Invalid Wifi ap MAC address.\n"); | ||
} | ||
|
||
static void fixup_wifi_calibration(void *blob, int node) | ||
{ | ||
int len; | ||
char dcxo; | ||
char *rf_params_prop; | ||
int version_reg1 = read_otp_version(VERSION_REG1_OFFSET); | ||
|
||
if (version_reg1 >= 1) { | ||
/* Read calibration data from OTP */ | ||
if (read_otp_data(DCXO_OFFSET, sizeof(dcxo), &dcxo)) { | ||
printf("WARNING: Could not read dcxo from OTP\n"); | ||
return; | ||
} | ||
} | ||
|
||
/* Overwrite first byte of rf-params property with DXCO */ | ||
rf_params_prop = fdt_getprop_w(blob, node, "rf-params", &len); | ||
if (!rf_params_prop) { | ||
printf("WARNING: Could not find rf-params property.\n"); | ||
return; | ||
} | ||
|
||
if (version_reg1 >= 1) | ||
rf_params_prop[0] = dcxo; | ||
|
||
fdt_setprop(blob, node, "rf-params", rf_params_prop, len); | ||
} | ||
|
||
int ft_board_setup(void *blob, bd_t *bd) | ||
{ | ||
int node = fdt_path_offset(blob, "wifi0"); | ||
if (node < 0) { | ||
printf("WARNING: can't find wifi0 alias\n"); | ||
return -1; | ||
} | ||
|
||
fixup_wifi_mac(blob, node); | ||
fixup_wifi_calibration(blob, node); | ||
|
||
return 0; | ||
} | ||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
/* | ||
* Copyright (C) 2016 Imagination Technologies | ||
* Author: Francois Berder <[email protected]> | ||
* | ||
* SPDX-License-Identifier: GPL-2.0+ | ||
*/ | ||
|
||
#include <common.h> | ||
#include <winbond-otp.h> | ||
#include "otp.h" | ||
|
||
int read_otp_version(loff_t offset) | ||
{ | ||
u_char version; | ||
|
||
if (read_otp_data(offset, sizeof(version), (char *)&version)) { | ||
printf("WARNING: Could not read register version from OTP.\n"); | ||
return -1; | ||
} | ||
|
||
return version; | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
/* | ||
* Copyright (C) 2016 Imagination Technologies | ||
* Author: Francois Berder <[email protected]> | ||
* | ||
* SPDX-License-Identifier: GPL-2.0+ | ||
*/ | ||
|
||
#ifndef _OTP_H | ||
#define _OTP_H | ||
|
||
#define MAC_ADDR_LEN 6 | ||
|
||
#ifdef CONFIG_WINBOND_OTP | ||
|
||
#include <linux/types.h> | ||
|
||
#define VERSION_REG0_OFFSET 0x1002 | ||
#define VERSION_REG1_OFFSET 0x2002 | ||
#define WIFI_STA_MAC_ADDRESS_OFFSET 0x1003 | ||
#define WIFI_AP_MAC_ADDRESS_OFFSET 0x1009 | ||
#define ETH_MAC_ADDRESS_OFFSET 0x1015 | ||
#define DCXO_OFFSET 0x2003 | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Seeing as you've added this perhaps we could move all otp layout defines into here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. done |
||
int read_otp_version(loff_t offset); | ||
|
||
#endif | ||
|
||
#endif |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,11 +21,12 @@ | |
#include <asm-generic/sections.h> | ||
#include <watchdog.h> | ||
#include <tpm.h> | ||
|
||
#include <winbond-otp.h> | ||
#include "mfio.h" | ||
#include "otp.h" | ||
|
||
|
||
DECLARE_GLOBAL_DATA_PTR; | ||
const char *enet_dtb_macaddr = 0; | ||
|
||
int reloc_tlb_fixup(void) | ||
{ | ||
|
@@ -109,22 +110,44 @@ static const char *get_dtb_macaddr(u32 ifno) | |
if (mac && is_valid_ethaddr((u8 *)mac)) | ||
return mac; | ||
|
||
return NULL; | ||
return NULL; | ||
} | ||
#endif | ||
|
||
int board_eth_init(bd_t *bs) | ||
{ | ||
u_char mac_addr[MAC_ADDR_LEN]; | ||
|
||
mfio_setup_ethernet(); | ||
|
||
/* try to get a valid macaddr from dtb */ | ||
/* Order of precedence: | ||
* 1. Check for existing ethaddr environment variable | ||
* 2. Read from OTP | ||
* 3. Fallback on dtb | ||
*/ | ||
memset(mac_addr, 0, MAC_ADDR_LEN); | ||
eth_getenv_enetaddr("ethaddr", mac_addr); | ||
|
||
#ifdef CONFIG_WINBOND_OTP | ||
if (!is_valid_ethaddr(mac_addr)) { | ||
if (read_otp_version(VERSION_REG0_OFFSET) >= 1) { | ||
if (!read_otp_data(ETH_MAC_ADDRESS_OFFSET, MAC_ADDR_LEN, | ||
(char *)mac_addr) | ||
&& is_valid_ethaddr(mac_addr)) | ||
eth_setenv_enetaddr("ethaddr", (u8 *)mac_addr); | ||
else | ||
printf("Could not read MAC address from OTP\n"); | ||
} | ||
} | ||
#endif | ||
#ifdef CONFIG_OF_CONTROL | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enabling this config means, we wont be setting the mac address from OTP, is this what we want ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Enabling CONFIG_OF_CONTROL means that we will retrieve the MAC address from the DTB if we did not find a valid MAC in the OTP. |
||
enet_dtb_macaddr = get_dtb_macaddr(0); | ||
|
||
if (enet_dtb_macaddr) | ||
eth_setenv_enetaddr("ethaddr", (u8 *)enet_dtb_macaddr); | ||
else | ||
printf("No valid Mac-addr found from dtb\n"); | ||
if (!is_valid_ethaddr(mac_addr)) { | ||
const char *enet_dtb_macaddr = get_dtb_macaddr(0); | ||
if (enet_dtb_macaddr) | ||
eth_setenv_enetaddr("ethaddr", (u8 *)enet_dtb_macaddr); | ||
else | ||
printf("No valid Mac-addr found from dtb\n"); | ||
} | ||
#endif | ||
|
||
#ifndef CONFIG_DM_ETH | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
/* | ||
* Copyright (C) 2016 Imagination Technologies | ||
* Author: Avinash Tahakik <[email protected]> | ||
* | ||
* SPDX-License-Identifier: GPL-2.0+ | ||
*/ | ||
|
||
#include <common.h> | ||
#include <spi.h> | ||
#include <spi_flash.h> | ||
#include <winbond-otp.h> | ||
|
||
#include "sf_internal.h" | ||
|
||
/* SPI FLASH opcodes */ | ||
|
||
#define SPINOR_OP_RD_SECURITY_REG 0x48 /* Read security register */ | ||
#define SECURITY_REG_SIZE 256 /* bytes per security register */ | ||
|
||
#define REG1_START_ADDRESS 0X1000 | ||
#define REG2_START_ADDRESS 0X2000 | ||
#define REG3_START_ADDRESS 0X3000 | ||
|
||
#define REG1_END_ADDRESS 0X10FF | ||
#define REG2_END_ADDRESS 0X20FF | ||
#define REG3_END_ADDRESS 0X30FF | ||
|
||
static struct spi_flash *flash; | ||
|
||
static int check_addr_validity(loff_t from, size_t len) | ||
{ | ||
if ((REG1_START_ADDRESS <= from && from + len <= REG1_END_ADDRESS) | ||
|| (REG2_START_ADDRESS <= from && from + len <= REG2_END_ADDRESS) | ||
|| (REG3_START_ADDRESS <= from && from + len <= REG3_END_ADDRESS)) | ||
return 0; | ||
|
||
return -1; | ||
} | ||
|
||
int read_otp_data(loff_t from, size_t len, char *data) | ||
{ | ||
if (check_addr_validity(from, len)) | ||
return -1; | ||
|
||
if (!flash) | ||
flash = spi_flash_probe(1, 0, CONFIG_SF_DEFAULT_SPEED, | ||
CONFIG_SF_DEFAULT_MODE); | ||
|
||
if (!flash) { | ||
printf("Failed to initialize SPI flash at 1:0\n"); | ||
return -1; | ||
} | ||
|
||
flash->read_cmd = SPINOR_OP_RD_SECURITY_REG; | ||
return spi_flash_cmd_read_ops(flash, from, len, data); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
/* | ||
* Copyright (C) 2015 Imagination Technologies | ||
* Author: Avinash Tahakik <[email protected]> | ||
* | ||
* SPDX-License-Identifier: GPL-2.0+ | ||
*/ | ||
|
||
#ifndef WINBOND_OTP_H | ||
#define WINBOND_OTP_H | ||
|
||
int read_otp_data(loff_t from, size_t len, char *data); | ||
|
||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we check whether the addresses are valid before writing ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
done