You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
251 lines
7.9 KiB
251 lines
7.9 KiB
4 months ago
|
/*
|
||
|
* Copyright (c) Hisilicon Technologies Co., Ltd. 2019-2020. All rights reserved.
|
||
|
* Description: create the mac's address for android
|
||
|
* Author: bsp
|
||
|
* Create: 2019-12-15
|
||
|
*/
|
||
|
#ifdef SOCT_MINIBOOT_SUPPORT
|
||
|
#include "app.h"
|
||
|
#else
|
||
|
#include <common.h>
|
||
|
#include <asm/arch/platform.h>
|
||
|
#include <malloc.h>
|
||
|
#include <environment.h>
|
||
|
#include <asm/io.h>
|
||
|
#include <linux/string.h>
|
||
|
#include <linux/mtd/mtd.h>
|
||
|
#include "common_ext.h"
|
||
|
#include "pdm_ext.h"
|
||
|
|
||
|
#endif
|
||
|
|
||
|
#include "flash_ext.h"
|
||
|
#include "fixmac.h"
|
||
|
|
||
|
#define CFG_TIMERBASE23 REG_BASE_TIMER23
|
||
|
#define CFG_TIMER2_CTRL 0xC2
|
||
|
#define READ_TIMER2 (*(volatile unsigned long *)(CFG_TIMERBASE23 + REG_TIMER_VALUE))
|
||
|
|
||
|
#define FIXMAC_SUCCESS 0
|
||
|
#define FIXMAC_ERROR (-1)
|
||
|
#define MAC_LENTH 18
|
||
|
#define FASTBOOT_DEVICE_INFO_OFFSET 0
|
||
|
#define FASTBOOT_DEVICE_INFO_NAME "deviceinfo"
|
||
|
|
||
|
struct device_info {
|
||
|
char mac[MAC_LENTH];
|
||
|
};
|
||
|
|
||
|
static int check_mac_format(const char *mac, const int len)
|
||
|
{
|
||
|
int i;
|
||
|
if ((EXT_PDM_MAC_ADDR_LEN < MAC_LENTH) || (len < MAC_LENTH)) {
|
||
|
printf("strlen = %d, error!\n", EXT_PDM_MAC_ADDR_LEN);
|
||
|
return -1;
|
||
|
}
|
||
|
for (i = 0; i < MAC_LENTH - 1; ++i) {
|
||
|
if (i % 0x3 == 0x2) {
|
||
|
if (mac[i] != ':') {
|
||
|
return -1;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
static void mac_to_string(char *eth_str, const size_t eth_len, const unsigned char *mac, const int mac_len)
|
||
|
{
|
||
|
if (mac_len < 6) { // EtherAddr is 6 byte
|
||
|
printf("maclen = %d, error!\n", mac_len);
|
||
|
return;
|
||
|
}
|
||
|
if (sprintf_s(eth_str, eth_len, "%02X:%02X:%02X:%02X:%02X:%02X",
|
||
|
mac[0x0], mac[0x1], mac[0x2],
|
||
|
mac[0x3], mac[0x4], mac[0x5]) < 0) {
|
||
|
printf("sprintf_s ethStr failed!\n");
|
||
|
}
|
||
|
}
|
||
|
|
||
|
static void random_ether_addr(unsigned char *mac, const int len)
|
||
|
{
|
||
|
if (len < 6) { // EtherAddr is 6 byte
|
||
|
printf("maclen = %d, error!\n", len);
|
||
|
return;
|
||
|
}
|
||
|
#ifdef SOCT_MINIBOOT_SUPPORT
|
||
|
int loop = 6; // EtherAddr is 6 byte
|
||
|
uint8 *ptr = mac;
|
||
|
srand(get_timer_value());
|
||
|
while (loop-- > 0) {
|
||
|
*ptr++ = (uint8)(rand() % 0xFF);
|
||
|
}
|
||
|
mac[0] &= ~0x01;
|
||
|
#else
|
||
|
unsigned long eth_addr_low;
|
||
|
unsigned long eth_addr_high;
|
||
|
|
||
|
srand((unsigned int)(READ_TIMER2 & 0xFFFFFFFF));
|
||
|
|
||
|
/*
|
||
|
* setting the 2nd LSB in the most significant byte of
|
||
|
* the address makes it a locally administered ethernet
|
||
|
* address
|
||
|
*/
|
||
|
eth_addr_high = (unsigned long)(rand() & 0xfeff) | 0x0200;
|
||
|
eth_addr_low = (unsigned long)rand();
|
||
|
|
||
|
mac[0] = eth_addr_high >> 8; /* 8 : create first mac's address */
|
||
|
mac[1] = eth_addr_high & 0xff;
|
||
|
mac[2] = eth_addr_low >> 24; /* 24 : create third mac's address */
|
||
|
mac[3] = (eth_addr_low >> 16) & 0xff; /* 16 : create fourth mac's address, 3:fourth mac's address */
|
||
|
mac[4] = (eth_addr_low >> 8) & 0xff; /* 8 : create fifth mac's address, 4:fifth mac's address */
|
||
|
mac[5] = eth_addr_low & 0xff; /* 5:sixth mac's address */
|
||
|
|
||
|
mac[0] &= 0xfe; /* clear multicast bit */
|
||
|
mac[0] |= 0x02; /* set local assignment bit (IEEE802) */
|
||
|
#endif
|
||
|
}
|
||
|
int eth_addr_process(void)
|
||
|
{
|
||
|
td_s32 ret = -1;
|
||
|
td_u8 mac[6] = {0};
|
||
|
ext_pdm_config_info cfg_info = {0};
|
||
|
ext_pdm_config_info cfg_info_2 = {0};
|
||
|
|
||
|
#ifndef SOCT_MINIBOOT_SUPPORT
|
||
|
__raw_writel(0, CFG_TIMERBASE23 + REG_TIMER_CONTROL);
|
||
|
__raw_writel(~0, CFG_TIMERBASE23 + REG_TIMER_RELOAD);
|
||
|
__raw_writel(CFG_TIMER2_CTRL, CFG_TIMERBASE23 + REG_TIMER_CONTROL);
|
||
|
#endif
|
||
|
ret = ext_drv_pdm_get_cfg_info(&cfg_info);
|
||
|
printf("ext_drv_pdm_get_cfg_info x%x \n", ret);
|
||
|
cfg_info.mac_addr[MAC_LENTH - 1] = 0;
|
||
|
printf("[%s:%d]mac:%s\n", __func__, __LINE__, (char*)cfg_info.mac_addr);
|
||
|
if (ret == TD_SUCCESS) {
|
||
|
ret = check_mac_format((char*)cfg_info.mac_addr, sizeof(cfg_info.mac_addr));
|
||
|
if (ret == TD_SUCCESS) {
|
||
|
printf("[%s:%d]mac:%s\n", __func__, __LINE__, (char*)cfg_info.mac_addr);
|
||
|
env_set("ethaddr", (char *)cfg_info.mac_addr);
|
||
|
return ret;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
eth_env_get_enetaddr("ethaddr", mac);
|
||
|
if (env_get("ethaddr") == NULL) {
|
||
|
random_ether_addr(mac, sizeof(mac));
|
||
|
}
|
||
|
ret = memset_s(cfg_info.mac_addr, EXT_PDM_MAC_ADDR_LEN, 0, EXT_PDM_MAC_ADDR_LEN);
|
||
|
if (ret < 0) {
|
||
|
printf("memset_s cfg_info.mac_addr faild, error:x%x\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
mac_to_string((char*)cfg_info.mac_addr, sizeof(cfg_info.mac_addr), mac, sizeof(mac));
|
||
|
|
||
|
ret = ext_drv_pdm_update_cfg_info(&cfg_info);
|
||
|
if (ret != TD_SUCCESS) {
|
||
|
printf("ext_drv_pdm_update_cfg_info x%x error\n", ret);
|
||
|
return ret;
|
||
|
}
|
||
|
env_set("ethaddr", (char *)cfg_info.mac_addr);
|
||
|
|
||
|
ret = ext_drv_pdm_get_cfg_info(&cfg_info_2);
|
||
|
printf("ext_drv_pdm_get_cfg_info x%x \n", ret);
|
||
|
|
||
|
return ret;
|
||
|
}
|
||
|
|
||
|
static int eth_get_device_info(td_handle *flashhandle, unsigned char *tmp_buf,
|
||
|
td_u32 *tmp_buf_length, struct device_info *tmp_dev_info)
|
||
|
{
|
||
|
td_s32 ret;
|
||
|
ext_flash_internal_info flash_info;
|
||
|
*flashhandle = ext_flash_open_by_name(FASTBOOT_DEVICE_INFO_NAME);
|
||
|
if ((*flashhandle == 0) || (*flashhandle == TD_INVALID_HANDLE)) {
|
||
|
printf("EXT_Flash_Open partion %s error\n", FASTBOOT_DEVICE_INFO_NAME);
|
||
|
return FIXMAC_ERROR;
|
||
|
}
|
||
|
|
||
|
ret = ext_flash_get_info(*flashhandle, &flash_info);
|
||
|
|
||
|
*tmp_buf_length = flash_info.block_size;
|
||
|
|
||
|
tmp_buf = (unsigned char *)malloc(*tmp_buf_length * sizeof(char));
|
||
|
if (tmp_buf == NULL) {
|
||
|
printf("can not alloc mem for read buf!\n");
|
||
|
ext_flash_close(*flashhandle);
|
||
|
return FIXMAC_ERROR;
|
||
|
}
|
||
|
|
||
|
ret = ext_flash_read(*flashhandle, FASTBOOT_DEVICE_INFO_OFFSET, tmp_buf, *tmp_buf_length, UAPI_FLASH_RW_FLAG_RAW);
|
||
|
if (ret == TD_FAILURE) {
|
||
|
printf("ext_flash_read partion %s error\n", FASTBOOT_DEVICE_INFO_NAME);
|
||
|
goto ERROR;
|
||
|
}
|
||
|
|
||
|
tmp_dev_info = (struct device_info *)malloc(sizeof(struct device_info));
|
||
|
if (tmp_dev_info == NULL) {
|
||
|
printf("can not alloc mem for mac address!\n");
|
||
|
goto ERROR;
|
||
|
}
|
||
|
return FIXMAC_SUCCESS;
|
||
|
ERROR:
|
||
|
free(tmp_buf);
|
||
|
tmp_buf = NULL;
|
||
|
ext_flash_close(*flashhandle);
|
||
|
return FIXMAC_ERROR;
|
||
|
}
|
||
|
|
||
|
int set_default_eth_addr(void)
|
||
|
{
|
||
|
td_handle flashhandle;
|
||
|
unsigned char *tmp_buf = NULL;
|
||
|
td_u32 tmp_buf_length;
|
||
|
struct device_info *tmp_dev_info = NULL;
|
||
|
unsigned char mac[6];
|
||
|
td_s32 fix_mac_ret = FIXMAC_ERROR;
|
||
|
|
||
|
#ifndef SOCT_MINIBOOT_SUPPORT
|
||
|
__raw_writel(0, CFG_TIMERBASE23 + REG_TIMER_CONTROL);
|
||
|
__raw_writel(~0, CFG_TIMERBASE23 + REG_TIMER_RELOAD);
|
||
|
__raw_writel(CFG_TIMER2_CTRL, CFG_TIMERBASE23 + REG_TIMER_CONTROL);
|
||
|
#endif
|
||
|
if (eth_get_device_info(&flashhandle, tmp_buf, &tmp_buf_length, tmp_dev_info) != FIXMAC_SUCCESS) {
|
||
|
return FIXMAC_ERROR;
|
||
|
}
|
||
|
|
||
|
if (memcpy_s(tmp_dev_info, sizeof(struct device_info), tmp_buf, sizeof(struct device_info)) < 0) {
|
||
|
printf("memcpy_s tmp_dev_info faild!\n");
|
||
|
goto OUT;
|
||
|
}
|
||
|
if (check_mac_format(tmp_dev_info->mac, sizeof(tmp_dev_info->mac)) == 0) {
|
||
|
printf("mac:%s\n", tmp_dev_info->mac);
|
||
|
env_set("ethaddr", tmp_dev_info->mac);
|
||
|
fix_mac_ret = FIXMAC_SUCCESS;
|
||
|
goto OUT;
|
||
|
} else {
|
||
|
random_ether_addr(mac, sizeof(mac));
|
||
|
mac_to_string(tmp_dev_info->mac, sizeof(tmp_dev_info->mac), mac, sizeof(mac));
|
||
|
if (memcpy_s(tmp_buf, tmp_buf_length * sizeof(char), tmp_dev_info, sizeof(struct device_info)) < 0) {
|
||
|
printf("memcpy_s tmp_dev_info faild!\n");
|
||
|
goto OUT;
|
||
|
}
|
||
|
if (ext_flash_write(flashhandle, FASTBOOT_DEVICE_INFO_OFFSET, tmp_buf, tmp_buf_length,
|
||
|
UAPI_FLASH_RW_FLAG_ERASE_FIRST) == TD_FAILURE) {
|
||
|
printf("ext_flash_write partion %s error\n", FASTBOOT_DEVICE_INFO_NAME);
|
||
|
fix_mac_ret = FIXMAC_ERROR;
|
||
|
goto OUT;
|
||
|
}
|
||
|
printf("mac:%s\n", tmp_dev_info->mac);
|
||
|
env_set("ethaddr", tmp_dev_info->mac);
|
||
|
fix_mac_ret = FIXMAC_SUCCESS;
|
||
|
goto OUT;
|
||
|
}
|
||
|
OUT:
|
||
|
free(tmp_buf);
|
||
|
free(tmp_dev_info);
|
||
|
tmp_buf = NULL;
|
||
|
tmp_dev_info = NULL;
|
||
|
ext_flash_close(flashhandle);
|
||
|
return fix_mac_ret;
|
||
|
}
|