Skip to content

Commit

Permalink
Merge pull request #21 from francois-berder-imgtec/task-15
Browse files Browse the repository at this point in the history
Set ethernet and wifi MAC address
  • Loading branch information
Ham22 authored Dec 3, 2016
2 parents 31a08e5 + 842f390 commit 455f049
Show file tree
Hide file tree
Showing 9 changed files with 253 additions and 11 deletions.
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 <francois.berder@imgtec.com>
*
* 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
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 <francois.berder@imgtec.com>
*
* 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 <francois.berder@imgtec.com>
*
* 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

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
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 <avinash.tahakik@imgtec.com>
*
* 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 <avinash.tahakik@imgtec.com>
*
* 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

0 comments on commit 455f049

Please sign in to comment.