Commit cea19a6c authored by Carl Huang's avatar Carl Huang Committed by Kalle Valo

ath10k: add WMI_SERVICE_AVAILABLE_EVENT support

Add WMI_SERVICE_AVAILABLE_EVENT to extend WMI_SERVICE_READY_EVENT,
the 128bit service map in WMI_SERVICE_READY_EVENT is not enough
for firmware to notice new WLAN service to host driver. Hereby,
for thoese new WLAN service, firmware will notice host driver by
WMI_SERVICE_AVAILABLE_EVENT.
Signed-off-by: default avatarAlan Liu <alanliu@codeaurora.org>
Signed-off-by: default avatarCarl Huang <cjhuang@codeaurora.org>
Signed-off-by: default avatarKalle Valo <kvalo@codeaurora.org>
parent 9ff6fde8
......@@ -25,6 +25,7 @@ struct sk_buff;
struct wmi_ops {
void (*rx)(struct ath10k *ar, struct sk_buff *skb);
void (*map_svc)(const __le32 *in, unsigned long *out, size_t len);
void (*map_svc_ext)(const __le32 *in, unsigned long *out, size_t len);
int (*pull_scan)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_scan_ev_arg *arg);
......@@ -54,6 +55,9 @@ struct wmi_ops {
struct wmi_wow_ev_arg *arg);
int (*pull_echo_ev)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_echo_ev_arg *arg);
int (*pull_svc_avail)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_svc_avail_ev_arg *arg);
enum wmi_txbf_conf (*get_txbf_conf_scheme)(struct ath10k *ar);
struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt);
......@@ -229,6 +233,17 @@ ath10k_wmi_map_svc(struct ath10k *ar, const __le32 *in, unsigned long *out,
return 0;
}
static inline int
ath10k_wmi_map_svc_ext(struct ath10k *ar, const __le32 *in, unsigned long *out,
size_t len)
{
if (!ar->wmi.ops->map_svc_ext)
return -EOPNOTSUPP;
ar->wmi.ops->map_svc_ext(in, out, len);
return 0;
}
static inline int
ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb,
struct wmi_scan_ev_arg *arg)
......@@ -329,6 +344,15 @@ ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb,
return ar->wmi.ops->pull_rdy(ar, skb, arg);
}
static inline int
ath10k_wmi_pull_svc_avail(struct ath10k *ar, struct sk_buff *skb,
struct wmi_svc_avail_ev_arg *arg)
{
if (!ar->wmi.ops->pull_svc_avail)
return -EOPNOTSUPP;
return ar->wmi.ops->pull_svc_avail(ar, skb, arg);
}
static inline int
ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
struct ath10k_fw_stats *stats)
......
......@@ -594,6 +594,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_READY_EVENTID:
ath10k_wmi_event_ready(ar, skb);
break;
case WMI_TLV_SERVICE_AVAILABLE_EVENTID:
ath10k_wmi_event_service_available(ar, skb);
break;
case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
break;
......@@ -1117,6 +1120,39 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
return 0;
}
static int ath10k_wmi_tlv_svc_avail_parse(struct ath10k *ar, u16 tag, u16 len,
const void *ptr, void *data)
{
struct wmi_svc_avail_ev_arg *arg = data;
switch (tag) {
case WMI_TLV_TAG_STRUCT_SERVICE_AVAILABLE_EVENT:
arg->service_map_ext_len = *(__le32 *)ptr;
arg->service_map_ext = ptr + sizeof(__le32);
return 0;
default:
break;
}
return -EPROTO;
}
static int ath10k_wmi_tlv_op_pull_svc_avail(struct ath10k *ar,
struct sk_buff *skb,
struct wmi_svc_avail_ev_arg *arg)
{
int ret;
ret = ath10k_wmi_tlv_iter(ar, skb->data, skb->len,
ath10k_wmi_tlv_svc_avail_parse, arg);
if (ret) {
ath10k_warn(ar, "failed to parse svc_avail tlv: %d\n", ret);
return ret;
}
return 0;
}
static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
struct ath10k_fw_stats_vdev *dst)
{
......@@ -3740,6 +3776,7 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
static const struct wmi_ops wmi_tlv_ops = {
.rx = ath10k_wmi_tlv_op_rx,
.map_svc = wmi_tlv_svc_map,
.map_svc_ext = wmi_tlv_svc_map_ext,
.pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
.pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
......@@ -3751,6 +3788,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
.pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
.pull_rdy = ath10k_wmi_tlv_op_pull_rdy_ev,
.pull_svc_avail = ath10k_wmi_tlv_op_pull_svc_avail,
.pull_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
.pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev,
.pull_wow_event = ath10k_wmi_tlv_op_pull_wow_ev,
......
This diff is collapsed.
......@@ -5059,7 +5059,6 @@ static void ath10k_wmi_event_service_ready_work(struct work_struct *work)
return;
}
memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map));
ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map,
arg.service_map_len);
......@@ -5269,6 +5268,21 @@ int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
return 0;
}
void ath10k_wmi_event_service_available(struct ath10k *ar, struct sk_buff *skb)
{
int ret;
struct wmi_svc_avail_ev_arg arg = {};
ret = ath10k_wmi_pull_svc_avail(ar, skb, &arg);
if (ret) {
ath10k_warn(ar, "failed to parse servive available event: %d\n",
ret);
}
ath10k_wmi_map_svc_ext(ar, arg.service_map_ext, ar->wmi.svc_map,
__le32_to_cpu(arg.service_map_ext_len));
}
static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
{
const struct wmi_pdev_temperature_event *ev;
......@@ -5465,6 +5479,9 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb)
ath10k_wmi_event_ready(ar, skb);
ath10k_wmi_queue_set_coverage_class_work(ar);
break;
case WMI_SERVICE_AVAILABLE_EVENTID:
ath10k_wmi_event_service_available(ar, skb);
break;
default:
ath10k_warn(ar, "Unknown eventid: %d\n", id);
break;
......@@ -5880,6 +5897,8 @@ int ath10k_wmi_connect(struct ath10k *ar)
struct ath10k_htc_svc_conn_req conn_req;
struct ath10k_htc_svc_conn_resp conn_resp;
memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map));
memset(&conn_req, 0, sizeof(conn_req));
memset(&conn_resp, 0, sizeof(conn_resp));
......
......@@ -202,6 +202,7 @@ enum wmi_service {
WMI_SERVICE_HOST_DFS_CHECK_SUPPORT,
WMI_SERVICE_TPC_STATS_FINAL,
WMI_SERVICE_RESET_CHIP,
WMI_SERVICE_SPOOF_MAC_SUPPORT,
/* keep last */
WMI_SERVICE_MAX,
......@@ -1190,6 +1191,7 @@ enum wmi_cmd_id {
enum wmi_event_id {
WMI_SERVICE_READY_EVENTID = 0x1,
WMI_READY_EVENTID,
WMI_SERVICE_AVAILABLE_EVENTID,
/* Scan specific events */
WMI_SCAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SCAN),
......@@ -6639,6 +6641,11 @@ struct wmi_svc_rdy_ev_arg {
const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS];
};
struct wmi_svc_avail_ev_arg {
__le32 service_map_ext_len;
const __le32 *service_map_ext;
};
struct wmi_rdy_ev_arg {
__le32 sw_version;
__le32 abi_version;
......@@ -7059,6 +7066,7 @@ void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb);
void ath10k_wmi_event_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb);
void ath10k_wmi_event_service_ready(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb);
void ath10k_wmi_event_service_available(struct ath10k *ar, struct sk_buff *skb);
int ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, const void *phyerr_buf,
int left_len, struct wmi_phyerr_ev_arg *arg);
void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment