Skip to content

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

Merged
merged 4 commits into from
Dec 3, 2016
Merged
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
4 changes: 4 additions & 0 deletions board/imgtec/pistachio_bub/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ endif
ifdef CONFIG_CMD_PISTACHIO_SCRATCHPAD
obj-y += cmd_scratchpad.o
endif
ifdef CONFIG_WINBOND_OTP
obj-y += fdt.o
obj-y += otp.o
endif
90 changes: 90 additions & 0 deletions board/imgtec/pistachio_bub/fdt.c
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 */
Copy link
Contributor

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 ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

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
22 changes: 22 additions & 0 deletions board/imgtec/pistachio_bub/otp.c
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;
}
28 changes: 28 additions & 0 deletions board/imgtec/pistachio_bub/otp.h
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

Copy link
Member

Choose a reason for hiding this comment

The 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?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

done

int read_otp_version(loff_t offset);

#endif

#endif
43 changes: 33 additions & 10 deletions board/imgtec/pistachio_bub/pistachio.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
{
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The 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 ?

Copy link
Author

Choose a reason for hiding this comment

The 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
Expand Down
1 change: 1 addition & 0 deletions drivers/mtd/spi/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ endif
obj-$(CONFIG_SPI_FLASH) += sf_probe.o
#endif
obj-$(CONFIG_CMD_SF) += sf.o
obj-$(CONFIG_WINBOND_OTP) += winbond-otp.o
obj-$(CONFIG_SPI_FLASH) += sf_ops.o sf_params.o
obj-$(CONFIG_SPI_FLASH_DATAFLASH) += sf_dataflash.o
obj-$(CONFIG_SPI_FLASH_MTD) += sf_mtd.o
Expand Down
56 changes: 56 additions & 0 deletions drivers/mtd/spi/winbond-otp.c
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);
}
7 changes: 6 additions & 1 deletion include/configs/pistachio_bub.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,13 @@
#define PISTACHIO_BOARD_NAME CONFIG_SYS_CONFIG_NAME
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_DISPLAY_BOARDINFO

#define CONFIG_WINBOND_OTP
#define CONFIG_OF_LIBFDT

#ifdef CONFIG_WINBOND_OTP
#define CONFIG_OF_BOARD_SETUP
#endif

/*
* CPU Configuration
*/
Expand Down
13 changes: 13 additions & 0 deletions include/winbond-otp.h
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