ath10k: wmi: modify svc bitmap parsing for wcn3990
Due to the limitation of wmi tlv parsing logic, if there are two parameters in a wmi event with same tlv tag, we can get only the last value, as it overwrites the prev value of the same tlv tag. The service ready event in wcn3990 contains two parameters of the same tag UINT32, due to which the svc bitmap is overwritten with the DBS support parameter. Refactor the service ready event parsing to allow parsing two tlv of the same tag UINT32 for wcn3990. Signed-off-by: Rakesh Pillai <pillair@qti.qualcomm.com> Signed-off-by: Govind Singh <govinds@qti.qualcomm.com> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
This commit is contained in:
parent
6d1f37323f
commit
229329ff34
|
@ -3574,7 +3574,9 @@ ath10k_mac_tx_h_get_txpath(struct ath10k *ar,
|
||||||
return ATH10K_MAC_TX_HTT;
|
return ATH10K_MAC_TX_HTT;
|
||||||
case ATH10K_HW_TXRX_MGMT:
|
case ATH10K_HW_TXRX_MGMT:
|
||||||
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
|
if (test_bit(ATH10K_FW_FEATURE_HAS_WMI_MGMT_TX,
|
||||||
ar->running_fw->fw_file.fw_features))
|
ar->running_fw->fw_file.fw_features) ||
|
||||||
|
test_bit(WMI_SERVICE_MGMT_TX_WMI,
|
||||||
|
ar->wmi.svc_map))
|
||||||
return ATH10K_MAC_TX_WMI_MGMT;
|
return ATH10K_MAC_TX_WMI_MGMT;
|
||||||
else if (ar->htt.target_version_major >= 3)
|
else if (ar->htt.target_version_major >= 3)
|
||||||
return ATH10K_MAC_TX_HTT;
|
return ATH10K_MAC_TX_HTT;
|
||||||
|
|
|
@ -917,33 +917,69 @@ ath10k_wmi_tlv_parse_mem_reqs(struct ath10k *ar, u16 tag, u16 len,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
|
struct wmi_tlv_svc_rdy_parse {
|
||||||
struct sk_buff *skb,
|
|
||||||
struct wmi_svc_rdy_ev_arg *arg)
|
|
||||||
{
|
|
||||||
const void **tb;
|
|
||||||
const struct hal_reg_capabilities *reg;
|
const struct hal_reg_capabilities *reg;
|
||||||
const struct wmi_tlv_svc_rdy_ev *ev;
|
const struct wmi_tlv_svc_rdy_ev *ev;
|
||||||
const __le32 *svc_bmap;
|
const __le32 *svc_bmap;
|
||||||
const struct wlan_host_mem_req *mem_reqs;
|
const struct wlan_host_mem_req *mem_reqs;
|
||||||
|
bool svc_bmap_done;
|
||||||
|
bool dbs_hw_mode_done;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int ath10k_wmi_tlv_svc_rdy_parse(struct ath10k *ar, u16 tag, u16 len,
|
||||||
|
const void *ptr, void *data)
|
||||||
|
{
|
||||||
|
struct wmi_tlv_svc_rdy_parse *svc_rdy = data;
|
||||||
|
|
||||||
|
switch (tag) {
|
||||||
|
case WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT:
|
||||||
|
svc_rdy->ev = ptr;
|
||||||
|
break;
|
||||||
|
case WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES:
|
||||||
|
svc_rdy->reg = ptr;
|
||||||
|
break;
|
||||||
|
case WMI_TLV_TAG_ARRAY_STRUCT:
|
||||||
|
svc_rdy->mem_reqs = ptr;
|
||||||
|
break;
|
||||||
|
case WMI_TLV_TAG_ARRAY_UINT32:
|
||||||
|
if (!svc_rdy->svc_bmap_done) {
|
||||||
|
svc_rdy->svc_bmap_done = true;
|
||||||
|
svc_rdy->svc_bmap = ptr;
|
||||||
|
} else if (!svc_rdy->dbs_hw_mode_done) {
|
||||||
|
svc_rdy->dbs_hw_mode_done = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
|
||||||
|
struct sk_buff *skb,
|
||||||
|
struct wmi_svc_rdy_ev_arg *arg)
|
||||||
|
{
|
||||||
|
const struct hal_reg_capabilities *reg;
|
||||||
|
const struct wmi_tlv_svc_rdy_ev *ev;
|
||||||
|
const __le32 *svc_bmap;
|
||||||
|
const struct wlan_host_mem_req *mem_reqs;
|
||||||
|
struct wmi_tlv_svc_rdy_parse svc_rdy = { };
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
tb = ath10k_wmi_tlv_parse_alloc(ar, skb->data, skb->len, GFP_ATOMIC);
|
ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
|
||||||
if (IS_ERR(tb)) {
|
ath10k_wmi_tlv_svc_rdy_parse, &svc_rdy);
|
||||||
ret = PTR_ERR(tb);
|
if (ret) {
|
||||||
ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
|
ath10k_warn(ar, "failed to parse tlv: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ev = tb[WMI_TLV_TAG_STRUCT_SERVICE_READY_EVENT];
|
ev = svc_rdy.ev;
|
||||||
reg = tb[WMI_TLV_TAG_STRUCT_HAL_REG_CAPABILITIES];
|
reg = svc_rdy.reg;
|
||||||
svc_bmap = tb[WMI_TLV_TAG_ARRAY_UINT32];
|
svc_bmap = svc_rdy.svc_bmap;
|
||||||
mem_reqs = tb[WMI_TLV_TAG_ARRAY_STRUCT];
|
mem_reqs = svc_rdy.mem_reqs;
|
||||||
|
|
||||||
if (!ev || !reg || !svc_bmap || !mem_reqs) {
|
if (!ev || !reg || !svc_bmap || !mem_reqs)
|
||||||
kfree(tb);
|
|
||||||
return -EPROTO;
|
return -EPROTO;
|
||||||
}
|
|
||||||
|
|
||||||
/* This is an internal ABI compatibility check for WMI TLV so check it
|
/* This is an internal ABI compatibility check for WMI TLV so check it
|
||||||
* here instead of the generic WMI code.
|
* here instead of the generic WMI code.
|
||||||
|
@ -961,7 +997,6 @@ static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
|
||||||
__le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
|
__le32_to_cpu(ev->abi.abi_ver_ns1) != WMI_TLV_ABI_VER_NS1 ||
|
||||||
__le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
|
__le32_to_cpu(ev->abi.abi_ver_ns2) != WMI_TLV_ABI_VER_NS2 ||
|
||||||
__le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
|
__le32_to_cpu(ev->abi.abi_ver_ns3) != WMI_TLV_ABI_VER_NS3) {
|
||||||
kfree(tb);
|
|
||||||
return -ENOTSUPP;
|
return -ENOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -982,12 +1017,10 @@ static int ath10k_wmi_tlv_op_pull_svc_rdy_ev(struct ath10k *ar,
|
||||||
ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
|
ret = ath10k_wmi_tlv_iter(ar, mem_reqs, ath10k_wmi_tlv_len(mem_reqs),
|
||||||
ath10k_wmi_tlv_parse_mem_reqs, arg);
|
ath10k_wmi_tlv_parse_mem_reqs, arg);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
kfree(tb);
|
|
||||||
ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
|
ath10k_warn(ar, "failed to parse mem_reqs tlv: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
kfree(tb);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -965,6 +965,50 @@ enum wmi_tlv_service {
|
||||||
WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
|
WMI_TLV_SERVICE_STA_RX_IPA_OFFLOAD_SUPPORT,
|
||||||
WMI_TLV_SERVICE_MDNS_OFFLOAD,
|
WMI_TLV_SERVICE_MDNS_OFFLOAD,
|
||||||
WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
|
WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
|
||||||
|
WMI_TLV_SERVICE_DUAL_BAND_SIMULTANEOUS_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_OCB,
|
||||||
|
WMI_TLV_SERVICE_AP_ARPNS_OFFLOAD,
|
||||||
|
WMI_TLV_SERVICE_PER_BAND_CHAINMASK_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_PACKET_FILTER_OFFLOAD,
|
||||||
|
WMI_TLV_SERVICE_MGMT_TX_HTT,
|
||||||
|
WMI_TLV_SERVICE_MGMT_TX_WMI,
|
||||||
|
WMI_TLV_SERVICE_EXT_MSG,
|
||||||
|
WMI_TLV_SERVICE_MAWC,
|
||||||
|
WMI_TLV_SERVICE_PEER_ASSOC_CONF,
|
||||||
|
WMI_TLV_SERVICE_EGAP,
|
||||||
|
WMI_TLV_SERVICE_STA_PMF_OFFLOAD,
|
||||||
|
WMI_TLV_SERVICE_UNIFIED_WOW_CAPABILITY,
|
||||||
|
WMI_TLV_SERVICE_ENHANCED_PROXY_STA,
|
||||||
|
WMI_TLV_SERVICE_ATF,
|
||||||
|
WMI_TLV_SERVICE_COEX_GPIO,
|
||||||
|
WMI_TLV_SERVICE_AUX_SPECTRAL_INTF,
|
||||||
|
WMI_TLV_SERVICE_AUX_CHAN_LOAD_INTF,
|
||||||
|
WMI_TLV_SERVICE_BSS_CHANNEL_INFO_64,
|
||||||
|
WMI_TLV_SERVICE_ENTERPRISE_MESH,
|
||||||
|
WMI_TLV_SERVICE_RESTRT_CHNL_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_BPF_OFFLOAD,
|
||||||
|
WMI_TLV_SERVICE_SYNC_DELETE_CMDS,
|
||||||
|
WMI_TLV_SERVICE_SMART_ANTENNA_SW_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_SMART_ANTENNA_HW_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_RATECTRL_LIMIT_MAX_MIN_RATES,
|
||||||
|
WMI_TLV_SERVICE_NAN_DATA,
|
||||||
|
WMI_TLV_SERVICE_NAN_RTT,
|
||||||
|
WMI_TLV_SERVICE_11AX,
|
||||||
|
WMI_TLV_SERVICE_DEPRECATED_REPLACE,
|
||||||
|
WMI_TLV_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||||
|
WMI_TLV_SERVICE_ENHANCED_MCAST_FILTER,
|
||||||
|
WMI_TLV_SERVICE_PERIODIC_CHAN_STAT_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_MESH_11S,
|
||||||
|
WMI_TLV_SERVICE_HALF_RATE_QUARTER_RATE_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_VDEV_RX_FILTER,
|
||||||
|
WMI_TLV_SERVICE_P2P_LISTEN_OFFLOAD_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_MARK_FIRST_WAKEUP_PACKET,
|
||||||
|
WMI_TLV_SERVICE_MULTIPLE_MCAST_FILTER_SET,
|
||||||
|
WMI_TLV_SERVICE_HOST_MANAGED_RX_REORDER,
|
||||||
|
WMI_TLV_SERVICE_FLASH_RDWR_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_WLAN_STATS_REPORT,
|
||||||
|
WMI_TLV_SERVICE_TX_MSDU_ID_NEW_PARTITION_SUPPORT,
|
||||||
|
WMI_TLV_SERVICE_DFS_PHYERR_OFFLOAD,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
|
#define WMI_SERVICE_IS_ENABLED(wmi_svc_bmap, svc_id, len) \
|
||||||
|
@ -1121,6 +1165,8 @@ wmi_tlv_svc_map(const __le32 *in, unsigned long *out, size_t len)
|
||||||
WMI_SERVICE_MDNS_OFFLOAD, len);
|
WMI_SERVICE_MDNS_OFFLOAD, len);
|
||||||
SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
|
SVCMAP(WMI_TLV_SERVICE_SAP_AUTH_OFFLOAD,
|
||||||
WMI_SERVICE_SAP_AUTH_OFFLOAD, len);
|
WMI_SERVICE_SAP_AUTH_OFFLOAD, len);
|
||||||
|
SVCMAP(WMI_TLV_SERVICE_MGMT_TX_WMI,
|
||||||
|
WMI_SERVICE_MGMT_TX_WMI, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#undef SVCMAP
|
#undef SVCMAP
|
||||||
|
|
|
@ -195,6 +195,7 @@ enum wmi_service {
|
||||||
WMI_SERVICE_SMART_LOGGING_SUPPORT,
|
WMI_SERVICE_SMART_LOGGING_SUPPORT,
|
||||||
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
WMI_SERVICE_TDLS_CONN_TRACKER_IN_HOST_MODE,
|
||||||
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
WMI_SERVICE_TDLS_EXPLICIT_MODE_ONLY,
|
||||||
|
WMI_SERVICE_MGMT_TX_WMI,
|
||||||
|
|
||||||
/* keep last */
|
/* keep last */
|
||||||
WMI_SERVICE_MAX,
|
WMI_SERVICE_MAX,
|
||||||
|
|
Loading…
Reference in New Issue