[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