ath10k: Add support for BASE MAC ADDRESS CMD
Base address needs to be set for SAP interface in HL 1.0 firmware. If base mac address has not encoded in WLAN firmware board data file then auto generate base mac address using device serial number and user defined mac address. Change-Id: I66f72c3c14b620107b48664d753c9dcf7a9b418e Signed-off-by: Govind Singh <govinds@codeaurora.org> Signed-off-by: Sarada Prasanna Garnayak <sgarna@codeaurora.org>
This commit is contained in:
parent
01e31721d2
commit
6786441d1b
6 changed files with 98 additions and 1 deletions
|
@ -1528,6 +1528,7 @@ static void ath10k_core_restart(struct work_struct *work)
|
|||
struct ath10k *ar = container_of(work, struct ath10k, restart_work);
|
||||
|
||||
set_bit(ATH10K_FLAG_CRASH_FLUSH, &ar->dev_flags);
|
||||
ath10k_gen_set_base_mac_addr(ar, ar->base_mac_addr);
|
||||
|
||||
/* Place a barrier to make sure the compiler doesn't reorder
|
||||
* CRASH_FLUSH and calling other functions.
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <linux/pci.h>
|
||||
#include <linux/uuid.h>
|
||||
#include <linux/time.h>
|
||||
#include <soc/qcom/socinfo.h>
|
||||
|
||||
#include "htt.h"
|
||||
#include "htc.h"
|
||||
|
@ -708,6 +709,7 @@ struct ath10k {
|
|||
struct ieee80211_ops *ops;
|
||||
struct device *dev;
|
||||
u8 mac_addr[ETH_ALEN];
|
||||
u8 base_mac_addr[ETH_ALEN];
|
||||
|
||||
enum ath10k_hw_rev hw_rev;
|
||||
u16 dev_id;
|
||||
|
|
|
@ -188,6 +188,9 @@ struct wmi_ops {
|
|||
u8 enable,
|
||||
u32 detect_level,
|
||||
u32 detect_margin);
|
||||
struct sk_buff *(*gen_set_pdev_mac_addr)(struct ath10k *ar, u32 pdev_id,
|
||||
u8 *mac_addr);
|
||||
|
||||
struct sk_buff *(*ext_resource_config)(struct ath10k *ar,
|
||||
enum wmi_host_platform_type type,
|
||||
u32 fw_feature_bitmap);
|
||||
|
@ -1417,4 +1420,25 @@ ath10k_wmi_echo(struct ath10k *ar, u32 value)
|
|||
return ath10k_wmi_cmd_send(ar, skb, wmi->cmd->echo_cmdid);
|
||||
}
|
||||
|
||||
static inline int
|
||||
ath10k_gen_set_base_mac_addr(struct ath10k *ar, u8 *mac)
|
||||
{
|
||||
struct sk_buff *skb;
|
||||
int ret;
|
||||
|
||||
if (!ar->wmi.ops->gen_set_pdev_mac_addr)
|
||||
return -EOPNOTSUPP;
|
||||
|
||||
skb = ar->wmi.ops->gen_set_pdev_mac_addr(ar, 0, mac);
|
||||
if (IS_ERR(skb))
|
||||
return PTR_ERR(skb);
|
||||
|
||||
ret = ath10k_wmi_cmd_send(ar, skb,
|
||||
ar->wmi.cmd->pdev_set_base_macaddr_cmdid);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3173,6 +3173,33 @@ ath10k_wmi_tlv_op_gen_wow_del_pattern(struct ath10k *ar, u32 vdev_id,
|
|||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_tlv_op_gen_set_base_mac_addr(struct ath10k *ar, u32 pdev_id,
|
||||
u8 *mac_addr)
|
||||
{
|
||||
struct wmi_tlv_mac_addr_cmd *cmd;
|
||||
struct wmi_tlv *tlv;
|
||||
struct sk_buff *skb;
|
||||
size_t len;
|
||||
|
||||
len = sizeof(*tlv) + sizeof(*cmd);
|
||||
skb = ath10k_wmi_alloc_skb(ar, len);
|
||||
if (!skb)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
tlv = (struct wmi_tlv *)skb->data;
|
||||
tlv->tag = __cpu_to_le16(WMI_TLV_TAG_STRUCT_PDEV_SET_BASE_MACADDR_CMD);
|
||||
tlv->len = __cpu_to_le16(sizeof(*cmd));
|
||||
cmd = (void *)tlv->value;
|
||||
|
||||
cmd->pdev_id = __cpu_to_le32(pdev_id);
|
||||
ether_addr_copy(cmd->mac_addr.addr, mac_addr);
|
||||
|
||||
ath10k_dbg(ar, ATH10K_DBG_WMI, "wmi tlv set_base_mac addr pdev_id %d mac addr %pM\n",
|
||||
cmd->pdev_id, cmd->mac_addr.addr);
|
||||
return skb;
|
||||
}
|
||||
|
||||
static struct sk_buff *
|
||||
ath10k_wmi_tlv_op_gen_adaptive_qcs(struct ath10k *ar, bool enable)
|
||||
{
|
||||
|
@ -3719,6 +3746,7 @@ static const struct wmi_ops wmi_hl_1_0_ops = {
|
|||
.gen_tdls_peer_update = ath10k_wmi_tlv_op_gen_tdls_peer_update,
|
||||
.gen_adaptive_qcs = ath10k_wmi_tlv_op_gen_adaptive_qcs,
|
||||
.fw_stats_fill = ath10k_wmi_main_op_fw_stats_fill,
|
||||
.gen_set_pdev_mac_addr = ath10k_wmi_tlv_op_gen_set_base_mac_addr,
|
||||
};
|
||||
|
||||
void ath10k_wmi_hl_1_0_attach(struct ath10k *ar)
|
||||
|
|
|
@ -1849,4 +1849,9 @@ struct wmi_tlv_mgmt_tx_cmd {
|
|||
__le16 data_tag;
|
||||
u8 buf[0];
|
||||
} __packed;
|
||||
|
||||
struct wmi_tlv_mac_addr_cmd {
|
||||
__le32 pdev_id;
|
||||
struct wmi_mac_addr mac_addr;
|
||||
} __packed;
|
||||
#endif
|
||||
|
|
|
@ -4844,6 +4844,39 @@ static int ath10k_wmi_op_pull_echo_ev(struct ath10k *ar,
|
|||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ath10k_generate_mac_addr_auto(struct ath10k *ar, struct wmi_rdy_ev_arg *arg)
|
||||
{
|
||||
unsigned int soc_serial_num;
|
||||
u8 bdata_mac_addr[ETH_ALEN];
|
||||
u8 udef_mac_addr[] = {0x00, 0x0A, 0xF5, 0x00, 0x00, 0x00};
|
||||
|
||||
soc_serial_num = socinfo_get_serial_number();
|
||||
if (!soc_serial_num)
|
||||
return;
|
||||
|
||||
if (arg->mac_addr) {
|
||||
ether_addr_copy(ar->base_mac_addr, arg->mac_addr);
|
||||
ether_addr_copy(bdata_mac_addr, arg->mac_addr);
|
||||
soc_serial_num &= 0x00ffffff;
|
||||
bdata_mac_addr[3] = (soc_serial_num >> 16) & 0xff;
|
||||
bdata_mac_addr[4] = (soc_serial_num >> 8) & 0xff;
|
||||
bdata_mac_addr[5] = soc_serial_num & 0xff;
|
||||
ether_addr_copy(ar->mac_addr, bdata_mac_addr);
|
||||
} else {
|
||||
/* If mac address not encoded in wlan board data,
|
||||
* Auto-generate mac address using device serial
|
||||
* number and user defined mac address 'udef_mac_addr'.
|
||||
*/
|
||||
udef_mac_addr[3] = (soc_serial_num >> 16) & 0xff;
|
||||
udef_mac_addr[4] = (soc_serial_num >> 8) & 0xff;
|
||||
udef_mac_addr[5] = soc_serial_num & 0xff;
|
||||
ether_addr_copy(ar->base_mac_addr, udef_mac_addr);
|
||||
udef_mac_addr[2] = (soc_serial_num >> 24) & 0xff;
|
||||
ether_addr_copy(ar->mac_addr, udef_mac_addr);
|
||||
}
|
||||
}
|
||||
|
||||
int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
|
||||
{
|
||||
struct wmi_rdy_ev_arg arg = {};
|
||||
|
@ -4862,7 +4895,11 @@ int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
|
|||
arg.mac_addr,
|
||||
__le32_to_cpu(arg.status));
|
||||
|
||||
ether_addr_copy(ar->mac_addr, arg.mac_addr);
|
||||
if (QCA_REV_WCN3990(ar))
|
||||
ath10k_generate_mac_addr_auto(ar, &arg);
|
||||
else
|
||||
ether_addr_copy(ar->mac_addr, arg.mac_addr);
|
||||
|
||||
complete(&ar->wmi.unified_ready);
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue