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; ...@@ -25,6 +25,7 @@ struct sk_buff;
struct wmi_ops { struct wmi_ops {
void (*rx)(struct ath10k *ar, struct sk_buff *skb); void (*rx)(struct ath10k *ar, struct sk_buff *skb);
void (*map_svc)(const __le32 *in, unsigned long *out, size_t len); 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, int (*pull_scan)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_scan_ev_arg *arg); struct wmi_scan_ev_arg *arg);
...@@ -54,6 +55,9 @@ struct wmi_ops { ...@@ -54,6 +55,9 @@ struct wmi_ops {
struct wmi_wow_ev_arg *arg); struct wmi_wow_ev_arg *arg);
int (*pull_echo_ev)(struct ath10k *ar, struct sk_buff *skb, int (*pull_echo_ev)(struct ath10k *ar, struct sk_buff *skb,
struct wmi_echo_ev_arg *arg); 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); enum wmi_txbf_conf (*get_txbf_conf_scheme)(struct ath10k *ar);
struct sk_buff *(*gen_pdev_suspend)(struct ath10k *ar, u32 suspend_opt); 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, ...@@ -229,6 +233,17 @@ ath10k_wmi_map_svc(struct ath10k *ar, const __le32 *in, unsigned long *out,
return 0; 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 static inline int
ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb, ath10k_wmi_pull_scan(struct ath10k *ar, struct sk_buff *skb,
struct wmi_scan_ev_arg *arg) struct wmi_scan_ev_arg *arg)
...@@ -329,6 +344,15 @@ ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb, ...@@ -329,6 +344,15 @@ ath10k_wmi_pull_rdy(struct ath10k *ar, struct sk_buff *skb,
return ar->wmi.ops->pull_rdy(ar, skb, arg); 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 static inline int
ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb, ath10k_wmi_pull_fw_stats(struct ath10k *ar, struct sk_buff *skb,
struct ath10k_fw_stats *stats) struct ath10k_fw_stats *stats)
......
...@@ -594,6 +594,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb) ...@@ -594,6 +594,9 @@ static void ath10k_wmi_tlv_op_rx(struct ath10k *ar, struct sk_buff *skb)
case WMI_TLV_READY_EVENTID: case WMI_TLV_READY_EVENTID:
ath10k_wmi_event_ready(ar, skb); ath10k_wmi_event_ready(ar, skb);
break; break;
case WMI_TLV_SERVICE_AVAILABLE_EVENTID:
ath10k_wmi_event_service_available(ar, skb);
break;
case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID: case WMI_TLV_OFFLOAD_BCN_TX_STATUS_EVENTID:
ath10k_wmi_tlv_event_bcn_tx_status(ar, skb); ath10k_wmi_tlv_event_bcn_tx_status(ar, skb);
break; break;
...@@ -1117,6 +1120,39 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar, ...@@ -1117,6 +1120,39 @@ static int ath10k_wmi_tlv_op_pull_rdy_ev(struct ath10k *ar,
return 0; 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, static void ath10k_wmi_tlv_pull_vdev_stats(const struct wmi_tlv_vdev_stats *src,
struct ath10k_fw_stats_vdev *dst) struct ath10k_fw_stats_vdev *dst)
{ {
...@@ -3740,6 +3776,7 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = { ...@@ -3740,6 +3776,7 @@ static struct wmi_vdev_param_map wmi_tlv_vdev_param_map = {
static const struct wmi_ops wmi_tlv_ops = { static const struct wmi_ops wmi_tlv_ops = {
.rx = ath10k_wmi_tlv_op_rx, .rx = ath10k_wmi_tlv_op_rx,
.map_svc = wmi_tlv_svc_map, .map_svc = wmi_tlv_svc_map,
.map_svc_ext = wmi_tlv_svc_map_ext,
.pull_scan = ath10k_wmi_tlv_op_pull_scan_ev, .pull_scan = ath10k_wmi_tlv_op_pull_scan_ev,
.pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev, .pull_mgmt_rx = ath10k_wmi_tlv_op_pull_mgmt_rx_ev,
...@@ -3751,6 +3788,7 @@ static const struct wmi_ops wmi_tlv_ops = { ...@@ -3751,6 +3788,7 @@ static const struct wmi_ops wmi_tlv_ops = {
.pull_phyerr = ath10k_wmi_op_pull_phyerr_ev, .pull_phyerr = ath10k_wmi_op_pull_phyerr_ev,
.pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev, .pull_svc_rdy = ath10k_wmi_tlv_op_pull_svc_rdy_ev,
.pull_rdy = ath10k_wmi_tlv_op_pull_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_fw_stats = ath10k_wmi_tlv_op_pull_fw_stats,
.pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev, .pull_roam_ev = ath10k_wmi_tlv_op_pull_roam_ev,
.pull_wow_event = ath10k_wmi_tlv_op_pull_wow_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) ...@@ -5059,7 +5059,6 @@ static void ath10k_wmi_event_service_ready_work(struct work_struct *work)
return; return;
} }
memset(&ar->wmi.svc_map, 0, sizeof(ar->wmi.svc_map));
ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map, ath10k_wmi_map_svc(ar, arg.service_map, ar->wmi.svc_map,
arg.service_map_len); arg.service_map_len);
...@@ -5269,6 +5268,21 @@ int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb) ...@@ -5269,6 +5268,21 @@ int ath10k_wmi_event_ready(struct ath10k *ar, struct sk_buff *skb)
return 0; 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) static int ath10k_wmi_event_temperature(struct ath10k *ar, struct sk_buff *skb)
{ {
const struct wmi_pdev_temperature_event *ev; const struct wmi_pdev_temperature_event *ev;
...@@ -5465,6 +5479,9 @@ static void ath10k_wmi_op_rx(struct ath10k *ar, struct sk_buff *skb) ...@@ -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_event_ready(ar, skb);
ath10k_wmi_queue_set_coverage_class_work(ar); ath10k_wmi_queue_set_coverage_class_work(ar);
break; break;
case WMI_SERVICE_AVAILABLE_EVENTID:
ath10k_wmi_event_service_available(ar, skb);
break;
default: default:
ath10k_warn(ar, "Unknown eventid: %d\n", id); ath10k_warn(ar, "Unknown eventid: %d\n", id);
break; break;
...@@ -5880,6 +5897,8 @@ int ath10k_wmi_connect(struct ath10k *ar) ...@@ -5880,6 +5897,8 @@ int ath10k_wmi_connect(struct ath10k *ar)
struct ath10k_htc_svc_conn_req conn_req; struct ath10k_htc_svc_conn_req conn_req;
struct ath10k_htc_svc_conn_resp conn_resp; 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_req, 0, sizeof(conn_req));
memset(&conn_resp, 0, sizeof(conn_resp)); memset(&conn_resp, 0, sizeof(conn_resp));
......
...@@ -202,6 +202,7 @@ enum wmi_service { ...@@ -202,6 +202,7 @@ enum wmi_service {
WMI_SERVICE_HOST_DFS_CHECK_SUPPORT, WMI_SERVICE_HOST_DFS_CHECK_SUPPORT,
WMI_SERVICE_TPC_STATS_FINAL, WMI_SERVICE_TPC_STATS_FINAL,
WMI_SERVICE_RESET_CHIP, WMI_SERVICE_RESET_CHIP,
WMI_SERVICE_SPOOF_MAC_SUPPORT,
/* keep last */ /* keep last */
WMI_SERVICE_MAX, WMI_SERVICE_MAX,
...@@ -1190,6 +1191,7 @@ enum wmi_cmd_id { ...@@ -1190,6 +1191,7 @@ enum wmi_cmd_id {
enum wmi_event_id { enum wmi_event_id {
WMI_SERVICE_READY_EVENTID = 0x1, WMI_SERVICE_READY_EVENTID = 0x1,
WMI_READY_EVENTID, WMI_READY_EVENTID,
WMI_SERVICE_AVAILABLE_EVENTID,
/* Scan specific events */ /* Scan specific events */
WMI_SCAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SCAN), WMI_SCAN_EVENTID = WMI_EVT_GRP_START_ID(WMI_GRP_SCAN),
...@@ -6639,6 +6641,11 @@ struct wmi_svc_rdy_ev_arg { ...@@ -6639,6 +6641,11 @@ struct wmi_svc_rdy_ev_arg {
const struct wlan_host_mem_req *mem_reqs[WMI_MAX_MEM_REQS]; 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 { struct wmi_rdy_ev_arg {
__le32 sw_version; __le32 sw_version;
__le32 abi_version; __le32 abi_version;
...@@ -7059,6 +7066,7 @@ void ath10k_wmi_event_vdev_standby_req(struct ath10k *ar, struct sk_buff *skb); ...@@ -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_vdev_resume_req(struct ath10k *ar, struct sk_buff *skb);
void ath10k_wmi_event_service_ready(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); 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 ath10k_wmi_op_pull_phyerr_ev(struct ath10k *ar, const void *phyerr_buf,
int left_len, struct wmi_phyerr_ev_arg *arg); int left_len, struct wmi_phyerr_ev_arg *arg);
void ath10k_wmi_main_op_fw_stats_fill(struct ath10k *ar, 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