[PATCH 1/3] Get mac address from HW platform

Eugene Krasnikov k.eugene.e at gmail.com
Thu Aug 8 06:48:05 EDT 2013


Let the platform driver read mac address.

Signed-off-by: Eugene Krasnikov <k.eugene.e at gmail.com>
---
 main.c             | 65 ++++++------------------------------------------------
 smd.c              |  8 +++----
 wcn36xx.h          |  4 ++--
 wcn36xx_msm/main.c | 38 +++++++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 64 deletions(-)

diff --git a/main.c b/main.c
index 34d2d49..d44d645 100644
--- a/main.c
+++ b/main.c
@@ -16,7 +16,6 @@
  */
 
 #include <linux/module.h>
-#include <linux/firmware.h>
 #include <linux/platform_device.h>
 #include "wcn36xx.h"
 
@@ -612,7 +611,7 @@ static void wcn36xx_bss_info_changed(struct ieee80211_hw *hw,
 			wcn->beacon_enable = true;
 			wcn->current_vif->bss_index = 0xff;
 			wcn36xx_smd_config_bss(wcn, vif, NULL,
-					       wcn->addresses[0].addr, false);
+					       wcn->addresses.addr, false);
 			skb = ieee80211_beacon_get_tim(hw, vif, &tim_off,
 						       &tim_len);
 			if (!skb) {
@@ -878,8 +877,8 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
 	wcn->hw->wiphy->wowlan = &wowlan_support;
 #endif
 
-	wcn->hw->wiphy->n_addresses = ARRAY_SIZE(wcn->addresses);
-	wcn->hw->wiphy->addresses = wcn->addresses;
+	wcn->hw->wiphy->n_addresses = 1;
+	wcn->hw->wiphy->addresses = &wcn->addresses;
 
 	wcn->hw->max_listen_interval = 200;
 
@@ -893,57 +892,6 @@ static int wcn36xx_init_ieee80211(struct wcn36xx *wcn)
 	return ret;
 }
 
-static int wcn36xx_read_mac_addresses(struct wcn36xx *wcn)
-{
-	const struct firmware *addr_file = NULL;
-	int status;
-	u8 tmp[18];
-	static const u8 qcom_oui[3] = {0x00, 0x0A, 0xF5};
-	static const char *files[1] = {MAC_ADDR_0};
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(wcn->addresses); i++) {
-		if (i > ARRAY_SIZE(files) - 1)
-			status = -1;
-		else
-			status = request_firmware(&addr_file, files[i],
-						  wcn->dev);
-
-		if (status) {
-			if (i == 0) {
-				/* Assign a random mac with Qualcomm oui */
-				wcn36xx_warn("Failed to read macaddress file %s, using a random address instead",
-					     files[i]);
-				memcpy(wcn->addresses[i].addr, qcom_oui, 3);
-				get_random_bytes(wcn->addresses[i].addr + 3, 3);
-			} else {
-				wcn36xx_warn("Failed to read macaddress file, using a random address instead");
-				/* Assign locally administered mac addresses to
-				 * all but the first mac */
-				memcpy(wcn->addresses[i].addr,
-				       wcn->addresses[0].addr, ETH_ALEN);
-				wcn->addresses[i].addr[0] |= BIT(1);
-				get_random_bytes(wcn->addresses[i].addr + 3, 3);
-			}
-
-		} else {
-			memset(tmp, 0, sizeof(tmp));
-			memcpy(tmp, addr_file->data, sizeof(tmp) - 1);
-			sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-			       &wcn->addresses[i].addr[0],
-			       &wcn->addresses[i].addr[1],
-			       &wcn->addresses[i].addr[2],
-			       &wcn->addresses[i].addr[3],
-			       &wcn->addresses[i].addr[4],
-			       &wcn->addresses[i].addr[5]);
-
-			release_firmware(addr_file);
-		}
-		wcn36xx_info("mac%d: %pM", i, wcn->addresses[i].addr);
-	}
-
-	return 0;
-}
 static int wcn36xx_platform_get_resources(struct wcn36xx *wcn,
 					  struct platform_device *pdev)
 {
@@ -1021,8 +969,10 @@ static int __devinit wcn36xx_probe(struct platform_device *pdev)
 
 	wcn->supported_rates.supported_mcs_set[0] = 0xFF;
 
-	wcn36xx_read_mac_addresses(wcn);
-	SET_IEEE80211_PERM_ADDR(wcn->hw, wcn->addresses[0].addr);
+	if (!wcn->ctrl_ops->get_hw_mac(wcn->addresses.addr)) {
+		wcn36xx_info("mac address: %pM", wcn->addresses.addr);
+		SET_IEEE80211_PERM_ADDR(wcn->hw, wcn->addresses.addr);
+	}
 
 	ret = wcn36xx_platform_get_resources(wcn, pdev);
 	if (ret)
@@ -1092,4 +1042,3 @@ module_exit(wcn36xx_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e at gmail.com");
 MODULE_FIRMWARE(WLAN_NV_FILE);
-MODULE_FIRMWARE(MAC_ADDR_0);
diff --git a/smd.c b/smd.c
index 87ec564..a2769c4 100644
--- a/smd.c
+++ b/smd.c
@@ -389,7 +389,7 @@ int wcn36xx_smd_switch_channel(struct wcn36xx *wcn, int ch)
 	msg_body.channel_number = (u8)ch;
 	msg_body.tx_mgmt_power = 0xbf;
 	msg_body.max_tx_power = 0xbf;
-	memcpy(msg_body.self_sta_mac_addr, wcn->addresses[0].addr, ETH_ALEN);
+	memcpy(msg_body.self_sta_mac_addr, wcn->addresses.addr, ETH_ALEN);
 
 	PREPARE_HAL_BUF(wcn->smd_buf, msg_body);
 
@@ -816,7 +816,7 @@ int wcn36xx_smd_config_bss(struct wcn36xx *wcn, struct ieee80211_vif *vif,
 
 	memcpy(&bss->bssid, bssid, ETH_ALEN);
 
-	memcpy(&bss->self_mac_addr, &wcn->addresses[0], ETH_ALEN);
+	memcpy(&bss->self_mac_addr, &wcn->addresses, ETH_ALEN);
 
 	if (vif->type == NL80211_IFTYPE_STATION) {
 		bss->bss_type = WCN36XX_HAL_INFRASTRUCTURE_MODE;
@@ -987,7 +987,7 @@ int wcn36xx_smd_send_beacon(struct wcn36xx *wcn, struct sk_buff *skb_beacon,
 			      msg_body.beacon_length);
 		return -ENOMEM;
 	}
-	memcpy(&msg_body.bssid, &wcn->addresses[0], ETH_ALEN);
+	memcpy(&msg_body.bssid, &wcn->addresses, ETH_ALEN);
 
 	/* TODO need to find out why this is needed? */
 	msg_body.tim_ie_offset = tim_off+4;
@@ -1016,7 +1016,7 @@ int wcn36xx_smd_update_proberesp_tmpl(struct wcn36xx *wcn, struct sk_buff *skb)
 	msg.probe_resp_template_len = skb->len;
 	memcpy(&msg.probe_resp_template, skb->data, skb->len);
 
-	memcpy(&msg.bssid, &wcn->addresses[0], ETH_ALEN);
+	memcpy(&msg.bssid, &wcn->addresses, ETH_ALEN);
 
 	PREPARE_HAL_BUF(wcn->smd_buf, msg);
 
diff --git a/wcn36xx.h b/wcn36xx.h
index 271020a..6ec2fee 100644
--- a/wcn36xx.h
+++ b/wcn36xx.h
@@ -33,7 +33,6 @@
 
 #define DRIVER_PREFIX "wcn36xx: "
 #define WLAN_NV_FILE               "wlan/prima/WCNSS_qcom_wlan_nv.bin"
-#define MAC_ADDR_0 "wlan/macaddr0"
 #define WCN36XX_AGGR_BUFFER_SIZE 64
 
 extern unsigned int debug_mask;
@@ -108,6 +107,7 @@ struct wcn36xx_platform_ctrl_ops {
 	int (*open)(void *drv_priv, void *rsp_cb);
 	void (*close)(void);
 	int (*tx)(char *buf, size_t len);
+	int (*get_hw_mac)(u8 *addr);
 };
 
 /**
@@ -159,7 +159,7 @@ struct wcn36xx_dxe_ch;
 struct wcn36xx {
 	struct ieee80211_hw	*hw;
 	struct device		*dev;
-	struct mac_address	addresses[2];
+	struct mac_address	addresses;
 	struct wcn36xx_hal_mac_ssid ssid;
 	u16			aid;
 	struct wcn36xx_vif	*current_vif;
diff --git a/wcn36xx_msm/main.c b/wcn36xx_msm/main.c
index db7605c..a15919f 100644
--- a/wcn36xx_msm/main.c
+++ b/wcn36xx_msm/main.c
@@ -15,6 +15,7 @@
  */
 
 #include <linux/completion.h>
+#include <linux/firmware.h>
 #include <linux/module.h>
 #include <linux/platform_device.h>
 #include <linux/wcnss_wlan.h>
@@ -22,6 +23,8 @@
 #include <mach/msm_smd.h>
 #include "../wcn36xx.h"
 
+#define MAC_ADDR_0 "wlan/macaddr0"
+
 struct wcn36xx_msm {
 	struct wcn36xx_platform_ctrl_ops ctrl_ops;
 	struct platform_device *core;
@@ -34,6 +37,39 @@ struct wcn36xx_msm {
 	smd_channel_t		*smd_ch;
 } wmsm;
 
+static int wcn36xx_msm_get_hw_mac(u8 *addr)
+{
+	const struct firmware *addr_file = NULL;
+	int status;
+	u8 tmp[18];
+	static const u8 qcom_oui[3] = {0x00, 0x0A, 0xF5};
+	static const char *files = {MAC_ADDR_0};
+
+	status = request_firmware(&addr_file, files, &wmsm.core->dev);
+
+	if (status) {
+		/* Assign a random mac with Qualcomm oui */
+		dev_err(&wmsm.core->dev, "Failed to read macaddress file %s, using a random address instead",
+			     files);
+		memcpy(addr, qcom_oui, 3);
+		get_random_bytes(addr + 3, 3);
+	} else {
+		memset(tmp, 0, sizeof(tmp));
+		memcpy(tmp, addr_file->data, sizeof(tmp) - 1);
+		sscanf(tmp, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
+		       &addr[0],
+		       &addr[1],
+		       &addr[2],
+		       &addr[3],
+		       &addr[4],
+		       &addr[5]);
+
+		release_firmware(addr_file);
+	}
+
+	return 0;
+}
+
 static int wcn36xx_msm_smd_send_and_wait(char *buf, size_t len)
 {
 	int avail;
@@ -185,6 +221,7 @@ static int __init wcn36xx_msm_init(void)
 	wmsm.ctrl_ops.open = wcn36xx_msm_smd_open;
 	wmsm.ctrl_ops.close = wcn36xx_msm_smd_close;
 	wmsm.ctrl_ops.tx = wcn36xx_msm_smd_send_and_wait;
+	wmsm.ctrl_ops.get_hw_mac = wcn36xx_msm_get_hw_mac;
 
 	wcnss_memory =
 		platform_get_resource_byname(wcnss_get_platform_device(),
@@ -240,3 +277,4 @@ module_init(wcn36xx_msm_init);
 module_exit(wcn36xx_msm_exit);
 MODULE_LICENSE("GPL");
 MODULE_AUTHOR("Eugene Krasnikov k.eugene.e at gmail.com");
+MODULE_FIRMWARE(MAC_ADDR_0);
-- 
1.8.2.2




More information about the wcn36xx mailing list