summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-12-03 02:17:52 -0800
committerGerrit - the friendly Code Review server <code-review@localhost>2016-12-03 02:17:52 -0800
commit25f0ed75e0973572ce99a73b5a6ed2093a9e9fc4 (patch)
treebfb22b8b7cc8380ec095855fddc18c0e9e8897a9
parentc8cee748e55f24fe90d1f8953d6647614fd70049 (diff)
parentd9a8fa86c0fcb9d2852f4ff581f3381d10ef450e (diff)
Merge "icnss: Add support of setting MAC address from platform driver"
-rw-r--r--drivers/soc/qcom/icnss.c83
-rw-r--r--include/soc/qcom/icnss.h3
2 files changed, 86 insertions, 0 deletions
diff --git a/drivers/soc/qcom/icnss.c b/drivers/soc/qcom/icnss.c
index 59d7f6423932..37204dcbc065 100644
--- a/drivers/soc/qcom/icnss.c
+++ b/drivers/soc/qcom/icnss.c
@@ -36,6 +36,7 @@
#include <linux/thread_info.h>
#include <linux/uaccess.h>
#include <linux/qpnp/qpnp-adc.h>
+#include <linux/etherdevice.h>
#include <soc/qcom/memory_dump.h>
#include <soc/qcom/icnss.h>
#include <soc/qcom/msm_qmi_interface.h>
@@ -409,6 +410,12 @@ struct icnss_stats {
uint32_t vbatt_req_err;
};
+#define MAX_NO_OF_MAC_ADDR 4
+struct icnss_wlan_mac_addr {
+ u8 mac_addr[MAX_NO_OF_MAC_ADDR][ETH_ALEN];
+ uint32_t no_of_mac_addr_set;
+};
+
static struct icnss_priv {
uint32_t magic;
struct platform_device *pdev;
@@ -466,6 +473,8 @@ static struct icnss_priv {
uint64_t vph_pwr;
atomic_t pm_count;
struct ramdump_device *msa0_dump_dev;
+ bool is_wlan_mac_set;
+ struct icnss_wlan_mac_addr wlan_mac_addr;
} *penv;
static void icnss_hw_write_reg(void *base, u32 offset, u32 val)
@@ -3548,6 +3557,80 @@ unsigned int icnss_socinfo_get_serial_number(struct device *dev)
}
EXPORT_SYMBOL(icnss_socinfo_get_serial_number);
+int icnss_set_wlan_mac_address(struct device *dev,
+ const u8 *in, uint32_t len)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+ uint32_t no_of_mac_addr;
+ struct icnss_wlan_mac_addr *addr = NULL;
+ int iter;
+ u8 *temp = NULL;
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ return -EINVAL;
+ }
+
+ if (priv->is_wlan_mac_set) {
+ icnss_pr_dbg("WLAN MAC address is already set\n");
+ return 0;
+ }
+
+ if (len == 0 || (len % ETH_ALEN) != 0) {
+ icnss_pr_err("Invalid length %d\n", len);
+ return -EINVAL;
+ }
+
+ no_of_mac_addr = len / ETH_ALEN;
+ if (no_of_mac_addr > MAX_NO_OF_MAC_ADDR) {
+ icnss_pr_err("Exceed maxinum supported MAC address %u %u\n",
+ MAX_NO_OF_MAC_ADDR, no_of_mac_addr);
+ return -EINVAL;
+ }
+
+ priv->is_wlan_mac_set = true;
+ addr = &priv->wlan_mac_addr;
+ addr->no_of_mac_addr_set = no_of_mac_addr;
+ temp = &addr->mac_addr[0][0];
+
+ for (iter = 0; iter < no_of_mac_addr;
+ ++iter, temp += ETH_ALEN, in += ETH_ALEN) {
+ ether_addr_copy(temp, in);
+ icnss_pr_dbg("MAC_ADDR:%02x:%02x:%02x:%02x:%02x:%02x\n",
+ temp[0], temp[1], temp[2],
+ temp[3], temp[4], temp[5]);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(icnss_set_wlan_mac_address);
+
+u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num)
+{
+ struct icnss_priv *priv = dev_get_drvdata(dev);
+ struct icnss_wlan_mac_addr *addr = NULL;
+
+ if (priv->magic != ICNSS_MAGIC) {
+ icnss_pr_err("Invalid drvdata: dev %p, data %p, magic 0x%x\n",
+ dev, priv, priv->magic);
+ goto out;
+ }
+
+ if (!priv->is_wlan_mac_set) {
+ icnss_pr_dbg("WLAN MAC address is not set\n");
+ goto out;
+ }
+
+ addr = &priv->wlan_mac_addr;
+ *num = addr->no_of_mac_addr_set;
+ return &addr->mac_addr[0][0];
+out:
+ *num = 0;
+ return NULL;
+}
+EXPORT_SYMBOL(icnss_get_wlan_mac_address);
+
static int icnss_smmu_init(struct icnss_priv *priv)
{
struct dma_iommu_mapping *mapping;
diff --git a/include/soc/qcom/icnss.h b/include/soc/qcom/icnss.h
index 7e2f32883aa4..29990f036552 100644
--- a/include/soc/qcom/icnss.h
+++ b/include/soc/qcom/icnss.h
@@ -124,5 +124,8 @@ extern int icnss_get_wlan_unsafe_channel(u16 *unsafe_ch_list, u16 *ch_count,
extern int icnss_wlan_set_dfs_nol(const void *info, u16 info_len);
extern int icnss_wlan_get_dfs_nol(void *info, u16 info_len);
extern bool icnss_is_qmi_disable(void);
+extern int icnss_set_wlan_mac_address(struct device *dev,
+ const u8 *in, uint32_t len);
+extern u8 *icnss_get_wlan_mac_address(struct device *dev, uint32_t *num);
#endif /* _ICNSS_WLAN_H_ */