diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-12-03 02:17:52 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-03 02:17:52 -0800 |
| commit | 25f0ed75e0973572ce99a73b5a6ed2093a9e9fc4 (patch) | |
| tree | bfb22b8b7cc8380ec095855fddc18c0e9e8897a9 | |
| parent | c8cee748e55f24fe90d1f8953d6647614fd70049 (diff) | |
| parent | d9a8fa86c0fcb9d2852f4ff581f3381d10ef450e (diff) | |
Merge "icnss: Add support of setting MAC address from platform driver"
| -rw-r--r-- | drivers/soc/qcom/icnss.c | 83 | ||||
| -rw-r--r-- | include/soc/qcom/icnss.h | 3 |
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_ */ |
