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 <liubin7@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
liaoxl 2018-10-19 14:12:17 +08:00 • committed by panyq6
commit 96ee88b19b
4 changed files with 245 additions and 0 deletions

2
Kbuild
View file

@ -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

View file

@ -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);

230
core/hdd/src/wlan_hdd_cfg.c Normal file → Executable file
View file

@ -51,6 +51,151 @@
#include <wma_api.h>
#include "wlan_hdd_object_manager.h"
#ifdef MOTO_UTAGS_MAC
#include <linux/of.h>
#include <linux/of_address.h>
#include <crypto/md5.h>
#include <crypto/hash.h>
#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.

View file

@ -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 */