From 96ee88b19bf9c4a56dc7a3cef2ae13ab7fbdec27 Mon Sep 17 00:00:00 2001 From: liaoxl Date: Fri, 19 Oct 2018 14:12:17 +0800 Subject: [PATCH] WLAN: Implement reading of MAC address from UTAG for sm6150 - Read MAC Address from UTAG - Generate new MAC address from serial number, if UTAG is not programmed with MAC addresses in Factory. Port changes from (CR) to new Helium platform(sm6150). Change-Id: If6d2e532907ff0cd267262710b3c694bf73c9129 Reviewed-on: https://gerrit.mot.com/1257719 SLTApproved: Slta Waiver SME-Granted: SME Approvals Granted Tested-by: Jira Key Reviewed-by: Bin Liu Submit-Approved: Jira Key --- Kbuild | 2 + core/hdd/inc/wlan_hdd_cfg.h | 5 + core/hdd/src/wlan_hdd_cfg.c | 230 +++++++++++++++++++++++++++++++++++ core/hdd/src/wlan_hdd_main.c | 8 ++ 4 files changed, 245 insertions(+) mode change 100644 => 100755 core/hdd/src/wlan_hdd_cfg.c diff --git a/Kbuild b/Kbuild index 09448442dee4..5194b2b6ae87 100644 --- a/Kbuild +++ b/Kbuild @@ -3422,6 +3422,8 @@ cppflags-$(CONFIG_WLAN_HANG_EVENT) += -DHIF_BUS_LOG_INFO cppflags-$(CONFIG_WLAN_HANG_EVENT) += -DDP_SUPPORT_RECOVERY_NOTIFY #endof dummy flags +cppflags-y += -DMOTO_UTAGS_MAC + ccflags-$(CONFIG_ENABLE_SIZE_OPTIMIZE) += -Os # DFS component diff --git a/core/hdd/inc/wlan_hdd_cfg.h b/core/hdd/inc/wlan_hdd_cfg.h index a81d4e66ceb7..e56281f917d1 100644 --- a/core/hdd/inc/wlan_hdd_cfg.h +++ b/core/hdd/inc/wlan_hdd_cfg.h @@ -280,6 +280,11 @@ struct hdd_config { eCsrRoamWmmUserModeType hdd_to_csr_wmm_mode(uint8_t mode); QDF_STATUS hdd_update_mac_config(struct hdd_context *hdd_ctx); +#ifdef MOTO_UTAGS_MAC +QDF_STATUS hdd_update_mac_serial(struct hdd_context *hdd_ctx); +QDF_STATUS hdd_generate_random_mac_from_serialno(char *serialNo, + int serialength, char *computedMac); +#endif QDF_STATUS hdd_set_sme_config(struct hdd_context *hdd_ctx); QDF_STATUS hdd_set_policy_mgr_user_cfg(struct hdd_context *hdd_ctx); QDF_STATUS hdd_set_sme_chan_list(struct hdd_context *hdd_ctx); diff --git a/core/hdd/src/wlan_hdd_cfg.c b/core/hdd/src/wlan_hdd_cfg.c old mode 100644 new mode 100755 index 9e8f348016ad..570ed019f625 --- a/core/hdd/src/wlan_hdd_cfg.c +++ b/core/hdd/src/wlan_hdd_cfg.c @@ -51,6 +51,151 @@ #include #include "wlan_hdd_object_manager.h" +#ifdef MOTO_UTAGS_MAC +#include +#include +#include +#include + +#define WIFI_MAC_BOOTARG "androidboot.wifimacaddr=" +#define DEVICE_SERIALNO_BOOTARG "androidboot.serialno=" +#define MACSTRLEN 12 +#define MACSTRCOLON 58 +#define MACADDRESSUSED 1 + +struct sdesc { + struct shash_desc shash; + char ctx[]; +}; + +QDF_STATUS hdd_update_mac_serial(struct hdd_context *hdd_ctx) +{ + QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; + + int len = 0; + int serialnoLen = 0; + + char *buffer = NULL; + char *bufferPtr = NULL; + char *computedMac = NULL; + const char *cmd_line = NULL; + + struct device_node *chosen_node = NULL; + computedMac = (char*)qdf_mem_malloc(QDF_MAC_ADDR_SIZE); + + chosen_node = of_find_node_by_name(NULL, "chosen"); + hdd_err("%s: get chosen node \n", __func__); + + if (!chosen_node) + { + hdd_err("%s: get chosen node read failed \n", __func__); + goto config_exit; + } else { + cmd_line = of_get_property(chosen_node, "bootargs", &len); + if (!cmd_line || len <= 0) { + hdd_err("%s: get the barcode bootargs failed \n", __func__); + qdf_status = QDF_STATUS_E_FAILURE; + goto config_exit; + } else { + buffer = strstr(cmd_line, DEVICE_SERIALNO_BOOTARG); + if (buffer == NULL) { + hdd_err("%s: " DEVICE_SERIALNO_BOOTARG" not present cmd line argc", + __func__); + qdf_status = QDF_STATUS_E_FAILURE; + goto config_exit; + } else { + buffer += strlen(DEVICE_SERIALNO_BOOTARG); + bufferPtr = buffer; + while (*bufferPtr != ' ') { + bufferPtr++; + serialnoLen = serialnoLen + 1; + } + } + } + } + /*Data have been read from boot serial no */ + /*Now generate random unique the 6 byte string */ + if (hdd_generate_random_mac_from_serialno(buffer, serialnoLen, + computedMac) != QDF_STATUS_SUCCESS) { + qdf_status = QDF_STATUS_E_FAILURE; + goto config_exit; + } + qdf_mem_copy(&hdd_ctx->config->intfMacAddr[0].bytes[0], + (uint8_t *)computedMac, QDF_MAC_ADDR_SIZE); + +config_exit: + qdf_mem_free(computedMac); + return qdf_status; +} + +QDF_STATUS hdd_generate_random_mac_from_serialno(char *serialNo, int serialnoLen, + char *macAddr) +{ + unsigned int size; + struct crypto_shash *md5; + struct sdesc *sdescmd5; + char *hashBuf = NULL; + + QDF_STATUS cryptoStatus = QDF_STATUS_SUCCESS; + hashBuf = (char*)qdf_mem_malloc(16); + + /*Motorola OUI*/ + macAddr[0] = 0xA4; + macAddr[1] = 0x07; + macAddr[2] = 0xd6; + + md5 = crypto_alloc_shash("md5", 0, 0); + if (IS_ERR(md5)) { + cryptoStatus = QDF_STATUS_E_FAILURE; + hdd_err("%s: Crypto md5 allocation error \n", __func__); + qdf_mem_free(hashBuf); + return QDF_STATUS_E_FAILURE; + } + + size = sizeof(struct shash_desc) + crypto_shash_descsize(md5); + + sdescmd5 = kmalloc(size, GFP_KERNEL); + if (!sdescmd5) { + cryptoStatus = QDF_STATUS_E_FAILURE; + hdd_err("%s: Memory allocation error \n", __func__); + goto crypto_hash_err; + } + + sdescmd5->shash.tfm = md5; + sdescmd5->shash.flags = 0x0; + + if (crypto_shash_init(&sdescmd5->shash)) { + cryptoStatus = QDF_STATUS_E_FAILURE; + goto crypto_hash_err; + } + + if (crypto_shash_update(&sdescmd5->shash, serialNo, serialnoLen)) { + cryptoStatus = QDF_STATUS_E_FAILURE; + goto crypto_hash_err; + } + + if (crypto_shash_final(&sdescmd5->shash, &hashBuf[0])) { + cryptoStatus = QDF_STATUS_E_FAILURE; + goto crypto_hash_err; + } + + macAddr[3] = hashBuf[0]; + macAddr[4] = hashBuf[1]; + macAddr[5] = hashBuf[2]; + + hdd_err("%02X:%02X:%02X:%02X:%02X:%02X is the new MAC generated from serial number \n", macAddr[0], + macAddr[1], macAddr[2], macAddr[3], + macAddr[4], macAddr[5]); + crypto_hash_err: + qdf_mem_free(hashBuf); + crypto_free_shash(md5); + kfree(sdescmd5); + + return cryptoStatus; +} +#endif + + /** * get_next_line() - find and locate the new line pointer * @str: pointer to string @@ -246,6 +391,7 @@ static void hdd_set_power_save_offload_config(struct hdd_context *hdd_ctx) * Return: QDF_STATUS_SUCCESS if the MAC address is found from cfg file * and overwritten, otherwise QDF_STATUS_E_INVAL */ +#ifndef MOTO_UTAGS_MAC QDF_STATUS hdd_update_mac_config(struct hdd_context *hdd_ctx) { int status, i = 0; @@ -363,6 +509,90 @@ config_exit: return qdf_status; } +#else +QDF_STATUS hdd_update_mac_config(struct hdd_context *hdd_ctx) +{ + int len = 0; + int iteration = 0; + + char *bufferPtr = NULL; + char buffer_temp[MACSTRLEN]; + const char *cmd_line = NULL; + struct device_node *chosen_node = NULL; + char *buffer = NULL; + + struct hdd_cfg_entry macTable[QDF_MAX_CONCURRENCY_PERSONA]; + tSirMacAddr customMacAddr; + + QDF_STATUS qdf_status = QDF_STATUS_SUCCESS; + + memset(macTable, 0, sizeof(macTable)); + + /*Implemenation of QCOM is to read the MAC address from the predefined*/ + /*location where WLAN MMAC File have the MAC Address */ + /* Read MACs from bootparams. */ + chosen_node = of_find_node_by_name(NULL, "chosen"); + hdd_err("%s: get chosen node \n", __func__); + if (!chosen_node) + { + hdd_err("%s: get chosen node read failed \n", __func__); + goto config_exit; + } else { + cmd_line = of_get_property(chosen_node, "bootargs", &len); + + if (!cmd_line || len <= 0) { + hdd_err("%s: get wlan MACs bootargs failed \n", __func__); + qdf_status = QDF_STATUS_E_FAILURE; + goto config_exit; + } else { + buffer = strstr(cmd_line, WIFI_MAC_BOOTARG); + if (buffer == NULL) { + hdd_err("%s: " WIFI_MAC_BOOTARG " bootarg cmd line is null", __func__); + qdf_status = QDF_STATUS_E_FAILURE; + goto config_exit; + } else { + buffer += strlen(WIFI_MAC_BOOTARG); + bufferPtr = buffer; + } + } + } + /* Mac address data format used by qcom: + * Intf0MacAddress=00AA00BB00CC + * Intf1MacAddress=00AA00BB00CD + * xxxxxxxxxxxxxxxxxxxxxxxxxxxx + * From bootarg we need to strip off : from macaddress + */ + for (iteration = 0; iteration < MACSTRLEN; iteration++) { + if (*bufferPtr != MACSTRCOLON) { + buffer_temp[iteration] = *bufferPtr; + } else { + iteration = iteration - 1; + } + bufferPtr++; + } + /* Mac address data format used by qcom: + * Intf0MacAddress used for 1 macaddress + * if gp2pdeviceAdmistered is set to 1 + * if s020deviceAdmisnited is set to 0 + * it will use Intf1MacAddress for P2P seprately + * Motorola decided to use gp2pdeviceAdmistered = 1 i.e use + * locally gerated bin MAC addr for P2P + */ + macTable[0].name = "Intf0MacAddress"; + macTable[0].value = &buffer_temp[0]; + update_mac_from_string(hdd_ctx, &macTable[0], MACADDRESSUSED); + qdf_mem_copy(&customMacAddr, + &hdd_ctx->config->intfMacAddr[0].bytes[0], + sizeof(tSirMacAddr)); + sme_set_custom_mac_addr(customMacAddr); + +config_exit: + + return qdf_status; +} + +#endif + #ifdef FEATURE_RUNTIME_PM /** * hdd_disable_runtime_pm() - Override to disable runtime_pm. diff --git a/core/hdd/src/wlan_hdd_main.c b/core/hdd/src/wlan_hdd_main.c index 6ff051ffb47d..1576d18dfaad 100644 --- a/core/hdd/src/wlan_hdd_main.c +++ b/core/hdd/src/wlan_hdd_main.c @@ -13857,6 +13857,14 @@ static int hdd_initialize_mac_address(struct hdd_context *hdd_ctx) return 0; } +#ifdef MOTO_UTAGS_MAC + hdd_warn("Can't update mac config via wlan_mac.bin, using MAC from serial number"); + + status = hdd_update_mac_serial(hdd_ctx); + if (QDF_IS_STATUS_SUCCESS(status)) + return; +#endif + hdd_info("using default MAC address"); /* Use fw provided MAC */