/* * 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 #include #include #include #include #include #include #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; }