|
@@ -1871,6 +1871,164 @@ static int ath10k_wmi_10x_op_pull_fw_stats(struct ath10k *ar,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static int ath10k_wmi_10_2_op_pull_fw_stats(struct ath10k *ar,
|
|
|
+ struct sk_buff *skb,
|
|
|
+ struct ath10k_fw_stats *stats)
|
|
|
+{
|
|
|
+ const struct wmi_10_2_stats_event *ev = (void *)skb->data;
|
|
|
+ u32 num_pdev_stats;
|
|
|
+ u32 num_pdev_ext_stats;
|
|
|
+ u32 num_vdev_stats;
|
|
|
+ u32 num_peer_stats;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (!skb_pull(skb, sizeof(*ev)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
|
|
|
+ num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
|
|
|
+ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
|
|
|
+ num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
|
|
|
+
|
|
|
+ for (i = 0; i < num_pdev_stats; i++) {
|
|
|
+ const struct wmi_10_2_pdev_stats *src;
|
|
|
+ struct ath10k_fw_stats_pdev *dst;
|
|
|
+
|
|
|
+ src = (void *)skb->data;
|
|
|
+ if (!skb_pull(skb, sizeof(*src)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
|
|
|
+ if (!dst)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
|
|
|
+ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
|
|
|
+ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
|
|
|
+ ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
|
|
|
+ /* FIXME: expose 10.2 specific values */
|
|
|
+
|
|
|
+ list_add_tail(&dst->list, &stats->pdevs);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < num_pdev_ext_stats; i++) {
|
|
|
+ const struct wmi_10_2_pdev_ext_stats *src;
|
|
|
+
|
|
|
+ src = (void *)skb->data;
|
|
|
+ if (!skb_pull(skb, sizeof(*src)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ /* FIXME: expose values to userspace
|
|
|
+ *
|
|
|
+ * Note: Even though this loop seems to do nothing it is
|
|
|
+ * required to parse following sub-structures properly.
|
|
|
+ */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* fw doesn't implement vdev stats */
|
|
|
+
|
|
|
+ for (i = 0; i < num_peer_stats; i++) {
|
|
|
+ const struct wmi_10_2_peer_stats *src;
|
|
|
+ struct ath10k_fw_stats_peer *dst;
|
|
|
+
|
|
|
+ src = (void *)skb->data;
|
|
|
+ if (!skb_pull(skb, sizeof(*src)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
|
|
|
+ if (!dst)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ath10k_wmi_pull_peer_stats(&src->old, dst);
|
|
|
+
|
|
|
+ dst->peer_rx_rate = __le32_to_cpu(src->peer_rx_rate);
|
|
|
+ /* FIXME: expose 10.2 specific values */
|
|
|
+
|
|
|
+ list_add_tail(&dst->list, &stats->peers);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int ath10k_wmi_10_2_4_op_pull_fw_stats(struct ath10k *ar,
|
|
|
+ struct sk_buff *skb,
|
|
|
+ struct ath10k_fw_stats *stats)
|
|
|
+{
|
|
|
+ const struct wmi_10_2_stats_event *ev = (void *)skb->data;
|
|
|
+ u32 num_pdev_stats;
|
|
|
+ u32 num_pdev_ext_stats;
|
|
|
+ u32 num_vdev_stats;
|
|
|
+ u32 num_peer_stats;
|
|
|
+ int i;
|
|
|
+
|
|
|
+ if (!skb_pull(skb, sizeof(*ev)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ num_pdev_stats = __le32_to_cpu(ev->num_pdev_stats);
|
|
|
+ num_pdev_ext_stats = __le32_to_cpu(ev->num_pdev_ext_stats);
|
|
|
+ num_vdev_stats = __le32_to_cpu(ev->num_vdev_stats);
|
|
|
+ num_peer_stats = __le32_to_cpu(ev->num_peer_stats);
|
|
|
+
|
|
|
+ for (i = 0; i < num_pdev_stats; i++) {
|
|
|
+ const struct wmi_10_2_pdev_stats *src;
|
|
|
+ struct ath10k_fw_stats_pdev *dst;
|
|
|
+
|
|
|
+ src = (void *)skb->data;
|
|
|
+ if (!skb_pull(skb, sizeof(*src)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
|
|
|
+ if (!dst)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ath10k_wmi_pull_pdev_stats_base(&src->base, dst);
|
|
|
+ ath10k_wmi_pull_pdev_stats_tx(&src->tx, dst);
|
|
|
+ ath10k_wmi_pull_pdev_stats_rx(&src->rx, dst);
|
|
|
+ ath10k_wmi_pull_pdev_stats_extra(&src->extra, dst);
|
|
|
+ /* FIXME: expose 10.2 specific values */
|
|
|
+
|
|
|
+ list_add_tail(&dst->list, &stats->pdevs);
|
|
|
+ }
|
|
|
+
|
|
|
+ for (i = 0; i < num_pdev_ext_stats; i++) {
|
|
|
+ const struct wmi_10_2_pdev_ext_stats *src;
|
|
|
+
|
|
|
+ src = (void *)skb->data;
|
|
|
+ if (!skb_pull(skb, sizeof(*src)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ /* FIXME: expose values to userspace
|
|
|
+ *
|
|
|
+ * Note: Even though this loop seems to do nothing it is
|
|
|
+ * required to parse following sub-structures properly.
|
|
|
+ */
|
|
|
+ }
|
|
|
+
|
|
|
+ /* fw doesn't implement vdev stats */
|
|
|
+
|
|
|
+ for (i = 0; i < num_peer_stats; i++) {
|
|
|
+ const struct wmi_10_2_4_peer_stats *src;
|
|
|
+ struct ath10k_fw_stats_peer *dst;
|
|
|
+
|
|
|
+ src = (void *)skb->data;
|
|
|
+ if (!skb_pull(skb, sizeof(*src)))
|
|
|
+ return -EPROTO;
|
|
|
+
|
|
|
+ dst = kzalloc(sizeof(*dst), GFP_ATOMIC);
|
|
|
+ if (!dst)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ ath10k_wmi_pull_peer_stats(&src->common.old, dst);
|
|
|
+
|
|
|
+ dst->peer_rx_rate = __le32_to_cpu(src->common.peer_rx_rate);
|
|
|
+ /* FIXME: expose 10.2 specific values */
|
|
|
+
|
|
|
+ list_add_tail(&dst->list, &stats->peers);
|
|
|
+ }
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
void ath10k_wmi_event_update_stats(struct ath10k *ar, struct sk_buff *skb)
|
|
|
{
|
|
|
ath10k_dbg(ar, ATH10K_DBG_WMI, "WMI_UPDATE_STATS_EVENTID\n");
|
|
@@ -5121,6 +5279,7 @@ static const struct wmi_ops wmi_10_1_ops = {
|
|
|
|
|
|
static const struct wmi_ops wmi_10_2_ops = {
|
|
|
.rx = ath10k_wmi_10_2_op_rx,
|
|
|
+ .pull_fw_stats = ath10k_wmi_10_2_op_pull_fw_stats,
|
|
|
.gen_init = ath10k_wmi_10_2_op_gen_init,
|
|
|
.gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
|
|
|
/* .gen_pdev_get_temperature not implemented */
|
|
@@ -5128,7 +5287,6 @@ static const struct wmi_ops wmi_10_2_ops = {
|
|
|
/* shared with 10.1 */
|
|
|
.map_svc = wmi_10x_svc_map,
|
|
|
.pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
|
|
|
- .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
|
|
|
.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
|
|
|
.gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
|
|
|
|
|
@@ -5180,6 +5338,7 @@ static const struct wmi_ops wmi_10_2_ops = {
|
|
|
|
|
|
static const struct wmi_ops wmi_10_2_4_ops = {
|
|
|
.rx = ath10k_wmi_10_2_op_rx,
|
|
|
+ .pull_fw_stats = ath10k_wmi_10_2_4_op_pull_fw_stats,
|
|
|
.gen_init = ath10k_wmi_10_2_op_gen_init,
|
|
|
.gen_peer_assoc = ath10k_wmi_10_2_op_gen_peer_assoc,
|
|
|
.gen_pdev_get_temperature = ath10k_wmi_10_2_op_gen_pdev_get_temperature,
|
|
@@ -5187,7 +5346,6 @@ static const struct wmi_ops wmi_10_2_4_ops = {
|
|
|
/* shared with 10.1 */
|
|
|
.map_svc = wmi_10x_svc_map,
|
|
|
.pull_svc_rdy = ath10k_wmi_10x_op_pull_svc_rdy_ev,
|
|
|
- .pull_fw_stats = ath10k_wmi_10x_op_pull_fw_stats,
|
|
|
.gen_pdev_set_rd = ath10k_wmi_10x_op_gen_pdev_set_rd,
|
|
|
.gen_start_scan = ath10k_wmi_10x_op_gen_start_scan,
|
|
|
|