aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/bcmdhd/dhd_custom_sec.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/bcmdhd/dhd_custom_sec.c')
-rwxr-xr-xdrivers/net/wireless/bcmdhd/dhd_custom_sec.c1193
1 files changed, 1193 insertions, 0 deletions
diff --git a/drivers/net/wireless/bcmdhd/dhd_custom_sec.c b/drivers/net/wireless/bcmdhd/dhd_custom_sec.c
new file mode 100755
index 0000000..39f92ab
--- /dev/null
+++ b/drivers/net/wireless/bcmdhd/dhd_custom_sec.c
@@ -0,0 +1,1193 @@
+/*
+ * Customer HW 4 dependant file
+ *
+ * Copyright (C) 1999-2012, Broadcom Corporation
+ *
+ * Unless you and Broadcom execute a separate written software license
+ * agreement governing use of this software, this software is licensed to you
+ * under the terms of the GNU General Public License version 2 (the "GPL"),
+ * available at http://www.broadcom.com/licenses/GPLv2.php, with the
+ * following added to such license:
+ *
+ * As a special exception, the copyright holders of this software give you
+ * permission to link this software with independent modules, and to copy and
+ * distribute the resulting executable under terms of your choice, provided that
+ * you also meet, for each linked independent module, the terms and conditions of
+ * the license of that module. An independent module is a module which is not
+ * derived from this software. The special exception does not apply to any
+ * modifications of the software.
+ *
+ * Notwithstanding the above, under no circumstances may you combine this
+ * software in any way with any other Broadcom software provided under a license
+ * other than the GPL, without Broadcom's express prior written consent.
+ *
+ * $Id: dhd_custom_sec.c 334946 2012-05-24 20:38:00Z $
+ */
+#ifdef CUSTOMER_HW4
+#include <typedefs.h>
+#include <linuxver.h>
+#include <osl.h>
+
+#include <proto/ethernet.h>
+#include <dngl_stats.h>
+#include <bcmutils.h>
+#include <dhd.h>
+#include <dhd_dbg.h>
+
+#include <linux/fcntl.h>
+#include <linux/fs.h>
+
+struct dhd_info;
+extern int _dhd_set_mac_address(struct dhd_info *dhd,
+ int ifidx, struct ether_addr *addr);
+
+struct cntry_locales_custom {
+ char iso_abbrev[WLC_CNTRY_BUF_SZ]; /* ISO 3166-1 country abbreviation */
+ char custom_locale[WLC_CNTRY_BUF_SZ]; /* Custom firmware locale */
+ int32 custom_locale_rev; /* Custom local revisin default -1 */
+};
+
+/* Locale table for sec */
+const struct cntry_locales_custom translate_custom_table[] = {
+#ifdef BCM4334_CHIP
+ {"", "XZ", 11}, /* Universal if Country code is unknown or empty */
+#endif
+ {"AE", "AE", 1},
+ {"AR", "AR", 1},
+ {"AT", "AT", 1},
+ {"AU", "AU", 2},
+ {"BE", "BE", 1},
+ {"BG", "BG", 1},
+ {"BN", "BN", 1},
+ {"CA", "CA", 2},
+ {"CH", "CH", 1},
+ {"CN", "CN", 0},
+ {"CY", "CY", 1},
+ {"CZ", "CZ", 1},
+ {"DE", "DE", 3},
+ {"DK", "DK", 1},
+ {"EE", "EE", 1},
+ {"ES", "ES", 1},
+ {"FI", "FI", 1},
+ {"FR", "FR", 1},
+ {"GB", "GB", 1},
+ {"GR", "GR", 1},
+ {"HR", "HR", 1},
+ {"HU", "HU", 1},
+ {"IE", "IE", 1},
+ {"IS", "IS", 1},
+ {"IT", "IT", 1},
+ {"JP", "JP", 5},
+ {"KR", "KR", 24},
+ {"KW", "KW", 1},
+ {"LI", "LI", 1},
+ {"LT", "LT", 1},
+ {"LU", "LU", 1},
+ {"LV", "LV", 1},
+ {"MA", "MA", 1},
+ {"MT", "MT", 1},
+ {"MX", "MX", 1},
+ {"NL", "NL", 1},
+ {"NO", "NO", 1},
+ {"PL", "PL", 1},
+ {"PT", "PT", 1},
+ {"PY", "PY", 1},
+ {"RO", "RO", 1},
+ {"SE", "SE", 1},
+ {"SI", "SI", 1},
+ {"SK", "SK", 1},
+ {"TR", "TR", 7},
+ {"TW", "TW", 2},
+ {"IR", "XZ", 11}, /* Universal if Country code is IRAN, (ISLAMIC REPUBLIC OF) */
+ {"SD", "XZ", 11}, /* Universal if Country code is SUDAN */
+ {"SY", "XZ", 11}, /* Universal if Country code is SYRIAN ARAB REPUBLIC */
+ {"GL", "XZ", 11}, /* Universal if Country code is GREENLAND */
+ {"PS", "XZ", 11}, /* Universal if Country code is PALESTINIAN TERRITORY, OCCUPIED */
+ {"TL", "XZ", 11}, /* Universal if Country code is TIMOR-LESTE (EAST TIMOR) */
+ {"MH", "XZ", 11}, /* Universal if Country code is MARSHALL ISLANDS */
+ {"PK", "XZ", 11}, /* Universal if Country code is PAKISTAN */
+#ifdef BCM4334_CHIP
+ {"RU", "RU", 5},
+ {"SG", "SG", 4},
+ {"US", "US", 46}
+#endif
+#ifdef BCM4330_CHIP
+ {"RU", "RU", 1},
+ {"US", "US", 5}
+#endif
+};
+
+/* Customized Locale convertor
+* input : ISO 3166-1 country abbreviation
+* output: customized cspec
+*/
+void get_customized_country_code(char *country_iso_code, wl_country_t *cspec)
+{
+ int size, i;
+
+ size = ARRAYSIZE(translate_custom_table);
+
+ if (cspec == 0)
+ return;
+
+ if (size == 0)
+ return;
+
+ for (i = 0; i < size; i++) {
+ if (strcmp(country_iso_code, translate_custom_table[i].iso_abbrev) == 0) {
+ memcpy(cspec->ccode,
+ translate_custom_table[i].custom_locale, WLC_CNTRY_BUF_SZ);
+ cspec->rev = translate_custom_table[i].custom_locale_rev;
+ return;
+ }
+ }
+ return;
+}
+
+#ifdef SLP_PATH
+#define CIDINFO "/opt/etc/.cid.info"
+#define PSMINFO "/opt/etc/.psm.info"
+#define MACINFO "/opt/etc/.mac.info"
+#define MACINFO_EFS NULL
+#define REVINFO "/data/.rev"
+#else
+#define MACINFO "/data/.mac.info"
+#define MACINFO_EFS "/efs/wifi/.mac.info"
+#define NVMACINFO "/data/.nvmac.info"
+#define REVINFO "/data/.rev"
+#define CIDINFO "/data/.cid.info"
+#define PSMINFO "/data/.psm.info"
+#endif /* SLP_PATH */
+
+#ifdef READ_MACADDR
+int dhd_read_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
+{
+ struct file *fp = NULL;
+ char macbuffer[18] = {0};
+ mm_segment_t oldfs = {0};
+ char randommac[3] = {0};
+ char buf[18] = {0};
+ char *filepath_efs = MACINFO_EFS;
+#ifdef CONFIG_TARGET_LOCALE_VZW
+ char *nvfilepath = "/data/misc/wifi/.nvmac.info";
+#else
+ char *nvfilepath = NVMACINFO;
+#endif
+ int ret = 0;
+
+ fp = filp_open(filepath_efs, O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+start_readmac:
+ /* File Doesn't Exist. Create and write mac addr. */
+ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
+ if (IS_ERR(fp)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
+ return -1;
+ }
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ /* Generating the Random Bytes for 3 last octects of the MAC address */
+ get_random_bytes(randommac, 3);
+
+ sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ 0x00, 0x12, 0x34, randommac[0], randommac[1], randommac[2]);
+ DHD_ERROR(("[WIFI]The Random Generated MAC ID: %s\n", macbuffer));
+
+ if (fp->f_mode & FMODE_WRITE) {
+ ret = fp->f_op->write(fp, (const char *)macbuffer,
+ sizeof(macbuffer), &fp->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI]MAC address [%s] Failed to write into File: %s\n",
+ macbuffer, filepath_efs));
+ else
+ DHD_ERROR(("[WIFI]MAC address [%s] written into File: %s\n",
+ macbuffer, filepath_efs));
+ }
+ set_fs(oldfs);
+ /* Reading the MAC Address from .mac.info file
+ ( the existed file or just created file)
+ */
+ ret = kernel_read(fp, 0, buf, 18);
+ } else {
+ /* Reading the MAC Address from
+ .mac.info file( the existed file or just created file)
+ */
+ ret = kernel_read(fp, 0, buf, 18);
+/* to prevent abnormal string display when mac address is displayed on the screen. */
+ buf[17] = '\0';
+ DHD_ERROR(("Read MAC : [%s] [%d] \r\n",
+ buf, strncmp(buf, "00:00:00:00:00:00", 17)));
+ if (strncmp(buf, "00:00:00:00:00:00", 17) < 1) {
+ DHD_ERROR(("goto start_readmac \r\n"));
+ filp_close(fp, NULL);
+ goto start_readmac;
+ }
+ }
+
+ if (ret)
+ sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (unsigned int *)&(mac->octet[0]), (unsigned int *)&(mac->octet[1]),
+ (unsigned int *)&(mac->octet[2]), (unsigned int *)&(mac->octet[3]),
+ (unsigned int *)&(mac->octet[4]), (unsigned int *)&(mac->octet[5]));
+ else
+ DHD_ERROR(("dhd_bus_start: Reading from the '%s' returns 0 bytes\n", filepath_efs));
+
+ if (fp)
+ filp_close(fp, NULL);
+
+ /* Writing Newly generated MAC ID to the Dongle */
+ if (_dhd_set_mac_address(dhd, 0, mac) == 0)
+ DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
+ else
+ DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() failed\n"));
+
+ return 0;
+}
+#endif /* READ_MACADDR */
+
+#ifdef RDWR_MACADDR
+static int g_imac_flag;
+
+enum {
+ MACADDR_NONE = 0,
+ MACADDR_MOD,
+ MACADDR_MOD_RANDOM,
+ MACADDR_MOD_NONE,
+ MACADDR_COB,
+ MACADDR_COB_RANDOM
+};
+
+int dhd_write_rdwr_macaddr(struct ether_addr *mac)
+{
+ char *filepath_data = MACINFO;
+ char *filepath_efs = MACINFO_EFS;
+ struct file *fp_mac = NULL;
+ char buf[18] = {0};
+ mm_segment_t oldfs = {0};
+ int ret = -1;
+
+ if ((g_imac_flag != MACADDR_COB) && (g_imac_flag != MACADDR_MOD))
+ return 0;
+
+ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ mac->octet[0], mac->octet[1], mac->octet[2],
+ mac->octet[3], mac->octet[4], mac->octet[5]);
+
+ /* /data/.mac.info will be created */
+ fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);
+ if (IS_ERR(fp_mac)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data));
+ return -1;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp_mac->f_mode & FMODE_WRITE) {
+ ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
+ sizeof(buf), &fp_mac->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Mac address [%s] Failed"
+ " to write into File: %s\n", buf, filepath_data));
+ else
+ DHD_INFO(("[WIFI] Mac address [%s] written"
+ " into File: %s\n", buf, filepath_data));
+ }
+ set_fs(oldfs);
+ filp_close(fp_mac, NULL);
+ }
+ /* /efs/wifi/.mac.info will be created */
+ fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
+ if (IS_ERR(fp_mac)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
+ return -1;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp_mac->f_mode & FMODE_WRITE) {
+ ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
+ sizeof(buf), &fp_mac->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Mac address [%s] Failed"
+ " to write into File: %s\n", buf, filepath_efs));
+ else
+ DHD_INFO(("[WIFI] Mac address [%s] written"
+ " into File: %s\n", buf, filepath_efs));
+ }
+ set_fs(oldfs);
+ filp_close(fp_mac, NULL);
+ }
+
+ return 0;
+
+}
+
+int dhd_check_rdwr_macaddr(struct dhd_info *dhd, dhd_pub_t *dhdp,
+ struct ether_addr *mac)
+{
+ struct file *fp_mac = NULL;
+ struct file *fp_nvm = NULL;
+ char macbuffer[18] = {0};
+ char randommac[3] = {0};
+ char buf[18] = {0};
+ char *filepath_data = MACINFO;
+ char *filepath_efs = MACINFO_EFS;
+#ifdef CONFIG_TARGET_LOCALE_NA
+ char *nvfilepath = "/data/misc/wifi/.nvmac.info";
+#else
+ char *nvfilepath = NVMACINFO;
+#endif
+ char cur_mac[128] = {0};
+ char dummy_mac[ETHER_ADDR_LEN] = {0x00, 0x90, 0x4C, 0xC5, 0x12, 0x38};
+ char cur_macbuffer[18] = {0};
+ int ret = -1;
+
+ g_imac_flag = MACADDR_NONE;
+
+ fp_nvm = filp_open(nvfilepath, O_RDONLY, 0);
+ if (IS_ERR(fp_nvm)) { /* file does not exist */
+
+ /* Create the .nvmac.info */
+ fp_nvm = filp_open(nvfilepath, O_RDWR | O_CREAT, 0666);
+ if (!IS_ERR(fp_nvm))
+ filp_close(fp_nvm, NULL);
+
+ /* read MAC Address */
+ strcpy(cur_mac, "cur_etheraddr");
+ ret = dhd_wl_ioctl_cmd(dhdp, WLC_GET_VAR, cur_mac,
+ sizeof(cur_mac), 0, 0);
+ if (ret < 0) {
+ DHD_ERROR(("Current READ MAC error \r\n"));
+ memset(cur_mac, 0, ETHER_ADDR_LEN);
+ return -1;
+ } else {
+ DHD_ERROR(("MAC (OTP) : "
+ "[%02X:%02X:%02X:%02X:%02X:%02X] \r\n",
+ cur_mac[0], cur_mac[1], cur_mac[2], cur_mac[3],
+ cur_mac[4], cur_mac[5]));
+ }
+
+ sprintf(cur_macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ cur_mac[0], cur_mac[1], cur_mac[2],
+ cur_mac[3], cur_mac[4], cur_mac[5]);
+
+ fp_mac = filp_open(filepath_data, O_RDONLY, 0);
+ if (IS_ERR(fp_mac)) { /* file does not exist */
+ /* read mac is the dummy mac (00:90:4C:C5:12:38) */
+ if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
+ g_imac_flag = MACADDR_MOD_RANDOM;
+ else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
+ g_imac_flag = MACADDR_MOD_RANDOM;
+ else
+ g_imac_flag = MACADDR_MOD;
+ } else {
+ int is_zeromac;
+
+ ret = kernel_read(fp_mac, 0, buf, 18);
+ filp_close(fp_mac, NULL);
+ buf[17] = '\0';
+
+ is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
+ DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n",
+ buf, is_zeromac));
+
+ if (is_zeromac == 0) {
+ DHD_ERROR(("Zero MAC detected."
+ " Trying Random MAC.\n"));
+ g_imac_flag = MACADDR_MOD_RANDOM;
+ } else {
+ sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (unsigned int *)&(mac->octet[0]),
+ (unsigned int *)&(mac->octet[1]),
+ (unsigned int *)&(mac->octet[2]),
+ (unsigned int *)&(mac->octet[3]),
+ (unsigned int *)&(mac->octet[4]),
+ (unsigned int *)&(mac->octet[5]));
+ /* current MAC address is same as previous one */
+ if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
+ g_imac_flag = MACADDR_NONE;
+ } else { /* change MAC address */
+ if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
+ DHD_INFO(("%s: MACID is"
+ " overwritten\n", __FUNCTION__));
+ g_imac_flag = MACADDR_MOD;
+ } else {
+ DHD_ERROR(("%s: "
+ "_dhd_set_mac_address()"
+ " failed\n", __FUNCTION__));
+ g_imac_flag = MACADDR_NONE;
+ }
+ }
+ }
+ }
+ fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
+ if (IS_ERR(fp_mac)) { /* file does not exist */
+ /* read mac is the dummy mac (00:90:4C:C5:12:38) */
+ if (memcmp(cur_mac, dummy_mac, ETHER_ADDR_LEN) == 0)
+ g_imac_flag = MACADDR_MOD_RANDOM;
+ else if (strncmp(buf, "00:00:00:00:00:00", 17) == 0)
+ g_imac_flag = MACADDR_MOD_RANDOM;
+ else
+ g_imac_flag = MACADDR_MOD;
+ } else {
+ int is_zeromac;
+
+ ret = kernel_read(fp_mac, 0, buf, 18);
+ filp_close(fp_mac, NULL);
+ buf[17] = '\0';
+
+ is_zeromac = strncmp(buf, "00:00:00:00:00:00", 17);
+ DHD_ERROR(("MAC (FILE): [%s] [%d] \r\n",
+ buf, is_zeromac));
+
+ if (is_zeromac == 0) {
+ DHD_ERROR(("Zero MAC detected."
+ " Trying Random MAC.\n"));
+ g_imac_flag = MACADDR_MOD_RANDOM;
+ } else {
+ sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (unsigned int *)&(mac->octet[0]),
+ (unsigned int *)&(mac->octet[1]),
+ (unsigned int *)&(mac->octet[2]),
+ (unsigned int *)&(mac->octet[3]),
+ (unsigned int *)&(mac->octet[4]),
+ (unsigned int *)&(mac->octet[5]));
+ /* current MAC address is same as previous one */
+ if (memcmp(cur_mac, mac->octet, ETHER_ADDR_LEN) == 0) {
+ g_imac_flag = MACADDR_NONE;
+ } else { /* change MAC address */
+ if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
+ DHD_INFO(("%s: MACID is"
+ " overwritten\n", __FUNCTION__));
+ g_imac_flag = MACADDR_MOD;
+ } else {
+ DHD_ERROR(("%s: "
+ "_dhd_set_mac_address()"
+ " failed\n", __FUNCTION__));
+ g_imac_flag = MACADDR_NONE;
+ }
+ }
+ }
+ }
+ } else {
+ /* COB type. only COB. */
+ /* Reading the MAC Address from .nvmac.info file
+ * (the existed file or just created file)
+ */
+ ret = kernel_read(fp_nvm, 0, buf, 18);
+
+ /* to prevent abnormal string display when mac address
+ * is displayed on the screen.
+ */
+ buf[17] = '\0';
+ DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf,
+ strncmp(buf, "00:00:00:00:00:00", 17)));
+ if ((buf[0] == '\0') ||
+ (strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
+ g_imac_flag = MACADDR_COB_RANDOM;
+ } else {
+ sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (unsigned int *)&(mac->octet[0]),
+ (unsigned int *)&(mac->octet[1]),
+ (unsigned int *)&(mac->octet[2]),
+ (unsigned int *)&(mac->octet[3]),
+ (unsigned int *)&(mac->octet[4]),
+ (unsigned int *)&(mac->octet[5]));
+ /* Writing Newly generated MAC ID to the Dongle */
+ if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
+ DHD_INFO(("%s: MACID is overwritten\n",
+ __FUNCTION__));
+ g_imac_flag = MACADDR_COB;
+ } else {
+ DHD_ERROR(("%s: _dhd_set_mac_address()"
+ " failed\n", __FUNCTION__));
+ }
+ }
+ filp_close(fp_nvm, NULL);
+ }
+
+ if ((g_imac_flag == MACADDR_COB_RANDOM) ||
+ (g_imac_flag == MACADDR_MOD_RANDOM)) {
+ get_random_bytes(randommac, 3);
+ sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ 0x60, 0xd0, 0xa9, randommac[0], randommac[1],
+ randommac[2]);
+ DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n",
+ macbuffer));
+ sscanf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (unsigned int *)&(mac->octet[0]),
+ (unsigned int *)&(mac->octet[1]),
+ (unsigned int *)&(mac->octet[2]),
+ (unsigned int *)&(mac->octet[3]),
+ (unsigned int *)&(mac->octet[4]),
+ (unsigned int *)&(mac->octet[5]));
+ if (_dhd_set_mac_address(dhd, 0, mac) == 0) {
+ DHD_INFO(("%s: MACID is overwritten\n", __FUNCTION__));
+ g_imac_flag = MACADDR_COB;
+ } else {
+ DHD_ERROR(("%s: _dhd_set_mac_address() failed\n",
+ __FUNCTION__));
+ }
+ }
+
+ return 0;
+}
+#endif /* RDWR_MACADDR */
+
+#ifdef RDWR_KORICS_MACADDR
+int dhd_write_rdwr_korics_macaddr(struct dhd_info *dhd, struct ether_addr *mac)
+{
+ struct file *fp = NULL;
+ char macbuffer[18] = {0};
+ mm_segment_t oldfs = {0};
+ char randommac[3] = {0};
+ char buf[18] = {0};
+ char *filepath_efs = MACINFO_EFS;
+ int is_zeromac = 0;
+ int ret = 0;
+ /* MAC address copied from efs/wifi.mac.info */
+ fp = filp_open(filepath_efs, O_RDONLY, 0);
+
+ if (IS_ERR(fp)) {
+ /* File Doesn't Exist. Create and write mac addr. */
+ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
+ if (IS_ERR(fp)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n",
+ filepath_efs));
+ return -1;
+ }
+
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ /* Generating the Random Bytes for
+ * 3 last octects of the MAC address
+ */
+ get_random_bytes(randommac, 3);
+
+ sprintf(macbuffer, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ 0x60, 0xd0, 0xa9, randommac[0],
+ randommac[1], randommac[2]);
+ DHD_ERROR(("[WIFI] The Random Generated MAC ID : %s\n",
+ macbuffer));
+
+ if (fp->f_mode & FMODE_WRITE) {
+ ret = fp->f_op->write(fp,
+ (const char *)macbuffer,
+ sizeof(macbuffer), &fp->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Mac address [%s]"
+ " Failed to write into File:"
+ " %s\n", macbuffer, filepath_efs));
+ else
+ DHD_ERROR(("[WIFI] Mac address [%s]"
+ " written into File: %s\n",
+ macbuffer, filepath_efs));
+ }
+ set_fs(oldfs);
+ } else {
+ /* Reading the MAC Address from .mac.info file
+ * (the existed file or just created file)
+ */
+ ret = kernel_read(fp, 0, buf, 18);
+ /* to prevent abnormal string display when mac address
+ * is displayed on the screen.
+ */
+ buf[17] = '\0';
+ /* Remove security log */
+ /* DHD_ERROR(("Read MAC : [%s] [%d] \r\n", buf,
+ * strncmp(buf, "00:00:00:00:00:00", 17)));
+ */
+ if ((buf[0] == '\0') ||
+ (strncmp(buf, "00:00:00:00:00:00", 17) == 0)) {
+ is_zeromac = 1;
+ }
+ }
+
+ if (ret)
+ sscanf(buf, "%02X:%02X:%02X:%02X:%02X:%02X",
+ (unsigned int *)&(mac->octet[0]),
+ (unsigned int *)&(mac->octet[1]),
+ (unsigned int *)&(mac->octet[2]),
+ (unsigned int *)&(mac->octet[3]),
+ (unsigned int *)&(mac->octet[4]),
+ (unsigned int *)&(mac->octet[5]));
+ else
+ DHD_INFO(("dhd_bus_start: Reading from the"
+ " '%s' returns 0 bytes\n", filepath_efs));
+
+ if (fp)
+ filp_close(fp, NULL);
+
+ if (!is_zeromac) {
+ /* Writing Newly generated MAC ID to the Dongle */
+ if (_dhd_set_mac_address(dhd, 0, mac) == 0)
+ DHD_INFO(("dhd_bus_start: MACID is overwritten\n"));
+ else
+ DHD_ERROR(("dhd_bus_start: _dhd_set_mac_address() "
+ "failed\n"));
+ } else {
+ DHD_ERROR(("dhd_bus_start:Is ZeroMAC BypassWrite.mac.info!\n"));
+ }
+
+ return 0;
+}
+#endif /* RDWR_KORICS_MACADDR */
+
+#ifdef USE_CID_CHECK
+static int dhd_write_cid_file(const char *filepath_efs, const char *buf, int buf_len)
+{
+ struct file *fp = NULL;
+ mm_segment_t oldfs = {0};
+ int ret = 0;
+
+ /* File is always created. */
+ fp = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
+ if (IS_ERR(fp)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
+ return -1;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp->f_mode & FMODE_WRITE) {
+ ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Failed to write CIS[%s]"
+ " into '%s'\n", buf, filepath_efs));
+ else
+ DHD_ERROR(("[WIFI] CID [%s] written into"
+ " '%s'\n", buf, filepath_efs));
+ }
+ set_fs(oldfs);
+ }
+ filp_close(fp, NULL);
+
+ return 0;
+}
+
+#ifdef DUMP_CIS
+static void dhd_dump_cis(const unsigned char *buf, int size)
+{
+ int i;
+ for (i = 0; i < size; i++) {
+ DHD_ERROR(("%02X ", buf[i]));
+ if ((i % 15) == 15) DHD_ERROR(("\n"));
+ }
+ DHD_ERROR(("\n"));
+}
+#endif /* DUMP_CIS */
+
+#ifdef BCM4334_CHIP
+#define CIS_CID_OFFSET 43
+#else
+#define CIS_CID_OFFSET 31
+#endif /* BCM4334_CHIP */
+
+int dhd_check_module_cid(dhd_pub_t *dhd)
+{
+ int ret = -1;
+#ifdef BCM4334_CHIP
+ unsigned char cis_buf[250] = {0};
+ const char *revfilepath = REVINFO;
+ int flag_b3 = 0;
+#else
+ unsigned char cis_buf[128] = {0};
+#endif
+ const char *cidfilepath = CIDINFO;
+
+ /* Try reading out from CIS */
+ cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
+
+ cish->source = 0;
+ cish->byteoff = 0;
+ cish->nbytes = sizeof(cis_buf);
+
+ strcpy(cis_buf, "cisdump");
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
+ sizeof(cis_buf), 0, 0);
+ if (ret < 0) {
+ DHD_TRACE(("%s: CIS reading failed, err=%d\n",
+ __FUNCTION__, ret));
+ return ret;
+ } else {
+#ifdef BCM4334_CHIP
+ unsigned char semco_id[4] = {0x00, 0x00, 0x33, 0x33};
+
+ /* for SHARP FEM(new) */
+ unsigned char semco_id_sh[4] = {0x00, 0x00, 0xFB, 0x50};
+ DHD_ERROR(("%s: CIS reading success, ret=%d\n",
+ __FUNCTION__, ret));
+#ifdef DUMP_CIS
+ dump_cis(cis_buf, 48);
+#endif
+ if (memcmp(&cis_buf[CIS_CID_OFFSET], semco_id, 4) == 0) {
+ DHD_ERROR(("CID MATCH FOUND : Semco, "
+ "0x%02X 0x%02X 0x%02X 0x%02X\n",
+ cis_buf[CIS_CID_OFFSET],
+ cis_buf[CIS_CID_OFFSET+1], cis_buf[CIS_CID_OFFSET+2],
+ cis_buf[CIS_CID_OFFSET+3]));
+ dhd_write_cid_file(cidfilepath, "semco", 5);
+ } else if (memcmp(&cis_buf[CIS_CID_OFFSET], semco_id_sh, 4) == 0) {
+ DHD_ERROR(("CIS MATCH FOUND : Semco_sh, "
+ "0x%02X 0x%02X 0x%02X 0x%02X\n",
+ cis_buf[CIS_CID_OFFSET],
+ cis_buf[CIS_CID_OFFSET+1], cis_buf[CIS_CID_OFFSET+2],
+ cis_buf[CIS_CID_OFFSET+3]));
+ dhd_write_cid_file(cidfilepath, "semcosh", 7);
+ } else {
+ DHD_ERROR(("CID MATCH FOUND : Murata, "
+ "0x%02X 0x%02X 0x%02X 0x%02X\n", cis_buf[CIS_CID_OFFSET],
+ cis_buf[CIS_CID_OFFSET+1], cis_buf[CIS_CID_OFFSET+2],
+ cis_buf[CIS_CID_OFFSET+3]));
+ dhd_write_cid_file(cidfilepath, "murata", 6);
+ }
+
+ /* Try reading out from OTP to distinguish B2 or B3 */
+ memset(cis_buf, 0, sizeof(cis_buf));
+ cish = (cis_rw_t *)&cis_buf[8];
+
+ cish->source = 0;
+ cish->byteoff = 0;
+ cish->nbytes = sizeof(cis_buf);
+
+ strcpy(cis_buf, "otpdump");
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
+ sizeof(cis_buf), 0, 0);
+ if (ret < 0) {
+ DHD_ERROR(("%s: OTP reading failed, err=%d\n",
+ __FUNCTION__, ret));
+ return ret;
+ }
+
+ /* otp 33th character is identifier for 4334B3 */
+ cis_buf[34] = '\0';
+ flag_b3 = bcm_atoi(&cis_buf[33]);
+ if (flag_b3 & 0x1) {
+ DHD_ERROR(("REV MATCH FOUND : 4334B3, %c\n", cis_buf[33]));
+ dhd_write_cid_file(revfilepath, "4334B3", 6);
+ }
+
+#else /* BCM4330_CHIP */
+ unsigned char murata_id[4] = {0x80, 0x06, 0x81, 0x00};
+ unsigned char semco_ve[4] = {0x80, 0x02, 0x81, 0x99};
+#ifdef DUMP_CIS
+ dhd_dump_cis(cis_buf, 48);
+#endif
+ if (memcmp(&cis_buf[CIS_CID_OFFSET], murata_id, 4) == 0) {
+ DHD_ERROR(("CID MATCH FOUND : Murata\n"));
+ dhd_write_cid_file(cidfilepath, "murata", 6);
+ } else if (memcmp(&cis_buf[CIS_CID_OFFSET], semco_ve, 4)
+ == 0) {
+ DHD_ERROR(("CID MATCH FOUND : Semco VE\n"));
+ dhd_write_cid_file(cidfilepath, "semcove", 7);
+ } else {
+ DHD_ERROR(("CID MISMATCH"
+ " 0x%02X 0x%02X 0x%02X 0x%02X\n",
+ cis_buf[CIS_CID_OFFSET],
+ cis_buf[CIS_CID_OFFSET + 1],
+ cis_buf[CIS_CID_OFFSET + 2],
+ cis_buf[CIS_CID_OFFSET + 3]));
+ dhd_write_cid_file(cidfilepath, "samsung", 7);
+ }
+#endif /* BCM4334_CHIP */
+ DHD_ERROR(("%s: CIS write success, err=%d\n",
+ __FUNCTION__, ret));
+ }
+
+ return ret;
+}
+#endif /* USE_CID_CHECK */
+
+#ifdef GET_MAC_FROM_OTP
+static int dhd_write_mac_file(const char *filepath, const char *buf, int buf_len)
+{
+ struct file *fp = NULL;
+ mm_segment_t oldfs = {0};
+ int ret = 0;
+
+ fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ /* File is always created. */
+ if (IS_ERR(fp)) {
+ DHD_ERROR(("[WIFI] File open error\n"));
+ return -1;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp->f_mode & FMODE_WRITE) {
+ ret = fp->f_op->write(fp, buf, buf_len, &fp->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Failed to write CIS. \n"));
+ else
+ DHD_ERROR(("[WIFI] MAC written. \n"));
+ }
+ set_fs(oldfs);
+ }
+ filp_close(fp, NULL);
+
+ return 0;
+}
+
+#define CIS_MAC_OFFSET 33
+
+int dhd_check_module_mac(dhd_pub_t *dhd)
+{
+ int ret = -1;
+ unsigned char cis_buf[250] = {0};
+ unsigned char mac_buf[20] = {0};
+ unsigned char otp_mac_buf[20] = {0};
+ const char *macfilepath = MACINFO_EFS;
+
+ /* Try reading out from CIS */
+ cis_rw_t *cish = (cis_rw_t *)&cis_buf[8];
+ struct file *fp_mac = NULL;
+
+ cish->source = 0;
+ cish->byteoff = 0;
+ cish->nbytes = sizeof(cis_buf);
+
+ strcpy(cis_buf, "cisdump");
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, cis_buf,
+ sizeof(cis_buf), 0, 0);
+ if (ret < 0) {
+ DHD_TRACE(("%s: CIS reading failed, err=%d\n", __func__,
+ ret));
+ return ret;
+ } else {
+ unsigned char mac_id[6] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+#ifdef DUMP_CIS
+ dump_cis(cis_buf, 48);
+#endif
+ mac_id[0] = cis_buf[CIS_MAC_OFFSET];
+ mac_id[1] = cis_buf[CIS_MAC_OFFSET + 1];
+ mac_id[2] = cis_buf[CIS_MAC_OFFSET + 2];
+ mac_id[3] = cis_buf[CIS_MAC_OFFSET + 3];
+ mac_id[4] = cis_buf[CIS_MAC_OFFSET + 4];
+ mac_id[5] = cis_buf[CIS_MAC_OFFSET + 5];
+
+ sprintf(otp_mac_buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ mac_id[0], mac_id[1], mac_id[2], mac_id[3], mac_id[4],
+ mac_id[5]);
+ DHD_ERROR(("[WIFI]mac_id is setted from OTP \n"));
+ }
+
+ fp_mac = filp_open(macfilepath, O_RDONLY, 0);
+ if (!IS_ERR(fp_mac)) {
+ DHD_ERROR(("[WIFI]Check Mac address in .mac.info \n"));
+ kernel_read(fp_mac, fp_mac->f_pos, mac_buf, sizeof(mac_buf));
+
+ if (strncmp(mac_buf, otp_mac_buf, 17) != 0) {
+ DHD_ERROR(("[WIFI]file MAC is wrong. Write OTP MAC in .mac.info \n"));
+ dhd_write_mac_file(macfilepath, otp_mac_buf, sizeof(otp_mac_buf));
+ }
+ }
+
+ return ret;
+}
+#endif /* GET_MAC_FROM_OTP */
+
+#ifdef WRITE_MACADDR
+int dhd_write_macaddr(struct ether_addr *mac)
+{
+ char *filepath_data = MACINFO;
+ char *filepath_efs = MACINFO_EFS;
+
+ struct file *fp_mac = NULL;
+ char buf[18] = {0};
+ mm_segment_t oldfs = {0};
+ int ret = -1;
+ int retry_count = 0;
+
+startwrite:
+
+ sprintf(buf, "%02X:%02X:%02X:%02X:%02X:%02X\n",
+ mac->octet[0], mac->octet[1], mac->octet[2],
+ mac->octet[3], mac->octet[4], mac->octet[5]);
+
+ /* File will be created /data/.mac.info. */
+ fp_mac = filp_open(filepath_data, O_RDWR | O_CREAT, 0666);
+
+ if (IS_ERR(fp_mac)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_data));
+ return -1;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp_mac->f_mode & FMODE_WRITE) {
+ ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
+ sizeof(buf), &fp_mac->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Mac address [%s] Failed to"
+ " write into File: %s\n", buf, filepath_data));
+ else
+ DHD_INFO(("[WIFI] Mac address [%s] written"
+ " into File: %s\n", buf, filepath_data));
+ }
+ set_fs(oldfs);
+ filp_close(fp_mac, NULL);
+ }
+ /* check .mac.info file is 0 byte */
+ fp_mac = filp_open(filepath_data, O_RDONLY, 0);
+ ret = kernel_read(fp_mac, 0, buf, 18);
+
+ if ((ret == 0) && (retry_count++ < 3)) {
+ filp_close(fp_mac, NULL);
+ goto startwrite;
+ }
+
+ filp_close(fp_mac, NULL);
+ /* end of /data/.mac.info */
+
+ if (filepath_efs == NULL) {
+ DHD_ERROR(("[WIFI]%s : no efs filepath", __func__));
+ return 0;
+ }
+
+ /* File will be created /efs/wifi/.mac.info. */
+ fp_mac = filp_open(filepath_efs, O_RDWR | O_CREAT, 0666);
+
+ if (IS_ERR(fp_mac)) {
+ DHD_ERROR(("[WIFI] %s: File open error\n", filepath_efs));
+ return -1;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp_mac->f_mode & FMODE_WRITE) {
+ ret = fp_mac->f_op->write(fp_mac, (const char *)buf,
+ sizeof(buf), &fp_mac->f_pos);
+ if (ret < 0)
+ DHD_ERROR(("[WIFI] Mac address [%s] Failed to"
+ " write into File: %s\n", buf, filepath_efs));
+ else
+ DHD_INFO(("[WIFI] Mac address [%s] written"
+ " into File: %s\n", buf, filepath_efs));
+ }
+ set_fs(oldfs);
+ filp_close(fp_mac, NULL);
+ }
+
+ /* check .mac.info file is 0 byte */
+ fp_mac = filp_open(filepath_efs, O_RDONLY, 0);
+ ret = kernel_read(fp_mac, 0, buf, 18);
+
+ if ((ret == 0) && (retry_count++ < 3)) {
+ filp_close(fp_mac, NULL);
+ goto startwrite;
+ }
+
+ filp_close(fp_mac, NULL);
+
+ return 0;
+}
+#endif /* WRITE_MACADDR */
+
+#ifdef CONFIG_CONTROL_PM
+extern bool g_pm_control;
+void sec_control_pm(dhd_pub_t *dhd, uint *power_mode)
+{
+ struct file *fp = NULL;
+ char *filepath = PSMINFO;
+ mm_segment_t oldfs = {0};
+ char power_val = 0;
+ char iovbuf[WL_EVENTING_MASK_LEN + 12];
+
+ g_pm_control = FALSE;
+
+ fp = filp_open(filepath, O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ /* Enable PowerSave Mode */
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
+ sizeof(uint), TRUE, 0);
+
+ fp = filp_open(filepath, O_RDWR | O_CREAT, 0666);
+ if (IS_ERR(fp) || (fp == NULL)) {
+ DHD_ERROR(("[%s, %d] /data/.psm.info open failed\n",
+ __FUNCTION__, __LINE__));
+ return;
+ } else {
+ oldfs = get_fs();
+ set_fs(get_ds());
+
+ if (fp->f_mode & FMODE_WRITE) {
+ power_val = '1';
+ fp->f_op->write(fp, (const char *)&power_val,
+ sizeof(char), &fp->f_pos);
+ }
+ set_fs(oldfs);
+ }
+ } else {
+ if (fp == NULL) {
+ DHD_ERROR(("[%s, %d] /data/.psm.info open failed\n",
+ __FUNCTION__, __LINE__));
+ return;
+ }
+ kernel_read(fp, fp->f_pos, &power_val, 1);
+ DHD_ERROR(("POWER_VAL = %c \r\n", power_val));
+
+ if (power_val == '0') {
+#ifdef ROAM_ENABLE
+ uint roamvar = 1;
+#endif
+ *power_mode = PM_OFF;
+ /* Disable PowerSave Mode */
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
+ sizeof(uint), TRUE, 0);
+ /* Turn off MPC in AP mode */
+ bcm_mkiovar("mpc", (char *)power_mode, 4,
+ iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ sizeof(iovbuf), TRUE, 0);
+ g_pm_control = TRUE;
+#ifdef ROAM_ENABLE
+ /* Roaming off of dongle */
+ bcm_mkiovar("roam_off", (char *)&roamvar, 4,
+ iovbuf, sizeof(iovbuf));
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf,
+ sizeof(iovbuf), TRUE, 0);
+#endif
+ } else {
+ dhd_wl_ioctl_cmd(dhd, WLC_SET_PM, (char *)power_mode,
+ sizeof(uint), TRUE, 0);
+ }
+ }
+
+ if (fp)
+ filp_close(fp, NULL);
+}
+#endif /* CONFIG_CONTROL_PM */
+#ifdef GLOBALCONFIG_WLAN_COUNTRY_CODE
+int dhd_customer_set_country(dhd_pub_t *dhd)
+{
+ struct file *fp = NULL;
+ char *filepath = "/data/.ccode.info";
+ char iovbuf[WL_EVENTING_MASK_LEN + 12] = {0};
+ char buffer[10] = {0};
+ int ret = 0;
+ wl_country_t cspec;
+ int buf_len = 0;
+ char country_code[WLC_CNTRY_BUF_SZ];
+ int country_rev;
+ int country_offset;
+ int country_code_size;
+ char country_rev_buf[WLC_CNTRY_BUF_SZ];
+ fp = filp_open(filepath, O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ DHD_ERROR(("%s: %s open failed\n", __FUNCTION__, filepath));
+ return -1;
+ } else {
+ if (kernel_read(fp, 0, buffer, sizeof(buffer))) {
+ memset(&cspec, 0, sizeof(cspec));
+ memset(country_code, 0, sizeof(country_code));
+ memset(country_rev_buf, 0, sizeof(country_rev_buf));
+ country_offset = strcspn(buffer, " ");
+ country_code_size = country_offset;
+ if (country_offset != 0) {
+ strncpy(country_code, buffer, country_offset);
+ strncpy(country_rev_buf, buffer+country_offset+1,
+ strlen(buffer) - country_code_size + 1);
+ country_rev = bcm_atoi(country_rev_buf);
+ buf_len = bcm_mkiovar("country", (char *)&cspec,
+ sizeof(cspec), iovbuf, sizeof(iovbuf));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_GET_VAR, iovbuf, buf_len, FALSE, 0);
+ memcpy((void *)&cspec, iovbuf, sizeof(cspec));
+ if (!ret) {
+ DHD_ERROR(("%s: get country ccode:%s"
+ " country_abrev:%s rev:%d \n",
+ __FUNCTION__, cspec.ccode,
+ cspec.country_abbrev, cspec.rev));
+ if ((strncmp(country_code, cspec.ccode,
+ WLC_CNTRY_BUF_SZ) != 0) ||
+ (cspec.rev != country_rev)) {
+ strncpy(cspec.country_abbrev,
+ country_code, country_code_size);
+ strncpy(cspec.ccode, country_code,
+ country_code_size);
+ cspec.rev = country_rev;
+ DHD_ERROR(("%s: set country ccode:%s"
+ "country_abrev:%s rev:%d\n",
+ __FUNCTION__, cspec.ccode,
+ cspec.country_abbrev, cspec.rev));
+ buf_len = bcm_mkiovar("country", (char *)&cspec,
+ sizeof(cspec), iovbuf, sizeof(iovbuf));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR,
+ iovbuf, buf_len, TRUE, 0);
+ }
+ }
+ } else {
+ DHD_ERROR(("%s: set country %s failed code \n",
+ __FUNCTION__, country_code));
+ ret = -1;
+ }
+ } else {
+ DHD_ERROR(("%s: Reading from the '%s' returns 0 bytes \n",
+ __FUNCTION__, filepath));
+ ret = -1;
+ }
+ }
+ if (fp)
+ filp_close(fp, NULL);
+
+ return ret;
+}
+#endif /* GLOBALCONFIG_WLAN_COUNTRY_CODE */
+
+#ifdef MIMO_ANT_SETTING
+int dhd_sel_ant_from_file(dhd_pub_t *dhd)
+{
+ struct file *fp = NULL;
+ int ret = -1;
+ uint32 ant_val = 0;
+ char *filepath = "/data/.ant.info";
+ char iovbuf[WLC_IOCTL_SMLEN];
+
+ /* Read antenna settings from the file */
+ fp = filp_open(filepath, O_RDONLY, 0);
+ if (IS_ERR(fp)) {
+ DHD_ERROR(("[WIFI] %s: File [%s] open error\n", __FUNCTION__, filepath));
+ return ret;
+ } else {
+ ret = kernel_read(fp, 0, (char *)&ant_val, 4);
+ if (ret < 0) {
+ DHD_ERROR(("[WIFI] %s: File read error, ret=%d\n", __FUNCTION__, ret));
+ filp_close(fp, NULL);
+ return ret;
+ }
+
+ ant_val = bcm_atoi((char *)&ant_val);
+
+ DHD_ERROR(("[WIFI] %s: ANT val = %d\n", __FUNCTION__, ant_val));
+ filp_close(fp, NULL);
+
+ /* Check value from the file */
+ if (ant_val < 1 || ant_val > 3) {
+ DHD_ERROR(("[WIFI] %s: Invalid value %d read from the file %s\n",
+ __FUNCTION__, ant_val, filepath));
+ return -1;
+ }
+ }
+
+ /* Select Antenna */
+ bcm_mkiovar("txchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ if (ret) {
+ DHD_ERROR(("[WIFI] %s: Fail to execute dhd_wl_ioctl_cmd(): txchain, ret=%d\n",
+ __FUNCTION__, ret));
+ return ret;
+ }
+
+ bcm_mkiovar("rxchain", (char *)&ant_val, 4, iovbuf, sizeof(iovbuf));
+ ret = dhd_wl_ioctl_cmd(dhd, WLC_SET_VAR, iovbuf, sizeof(iovbuf), TRUE, 0);
+ if (ret) {
+ DHD_ERROR(("[WIFI] %s: Fail to execute dhd_wl_ioctl_cmd(): rxchain, ret=%d\n",
+ __FUNCTION__, ret));
+ return ret;
+ }
+
+ return 0;
+}
+#endif /* MIMO_ANTENNA_SETTING */
+#endif /* CUSTOMER_HW4 */