Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bc6f9ae6 authored by Manikanta Pubbisetty's avatar Manikanta Pubbisetty Committed by Kalle Valo
Browse files

ath10k: make fw stats prints specific to firmware version



The patch makes debug stats prints fw specific by adding a new member
in wmi_ops. That way it's easier to add fw_stats support to 10.4 firmware.

Signed-off-by: default avatarManikanta Pubbisetty <c_mpubbi@qti.qualcomm.com>
Signed-off-by: default avatarTamizh Chelvam <c_traja@qti.qualcomm.com>
Signed-off-by: default avatarKalle Valo <kvalo@qca.qualcomm.com>
parent 1aaf8efb
Loading
Loading
Loading
Loading
+8 −259
Original line number Diff line number Diff line
@@ -291,28 +291,6 @@ static void ath10k_debug_fw_stats_reset(struct ath10k *ar)
	spin_unlock_bh(&ar->data_lock);
}

static size_t ath10k_debug_fw_stats_num_peers(struct list_head *head)
{
	struct ath10k_fw_stats_peer *i;
	size_t num = 0;

	list_for_each_entry(i, head, list)
		++num;

	return num;
}

static size_t ath10k_debug_fw_stats_num_vdevs(struct list_head *head)
{
	struct ath10k_fw_stats_vdev *i;
	size_t num = 0;

	list_for_each_entry(i, head, list)
		++num;

	return num;
}

void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
{
	struct ath10k_fw_stats stats = {};
@@ -349,8 +327,8 @@ void ath10k_debug_fw_stats_process(struct ath10k *ar, struct sk_buff *skb)
		goto free;
	}

	num_peers = ath10k_debug_fw_stats_num_peers(&ar->debug.fw_stats.peers);
	num_vdevs = ath10k_debug_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
	num_peers = ath10k_wmi_fw_stats_num_peers(&ar->debug.fw_stats.peers);
	num_vdevs = ath10k_wmi_fw_stats_num_vdevs(&ar->debug.fw_stats.vdevs);
	is_start = (list_empty(&ar->debug.fw_stats.pdevs) &&
		    !list_empty(&stats.pdevs));
	is_end = (!list_empty(&ar->debug.fw_stats.pdevs) &&
@@ -435,240 +413,6 @@ static int ath10k_debug_fw_stats_request(struct ath10k *ar)
	return 0;
}

/* FIXME: How to calculate the buffer size sanely? */
#define ATH10K_FW_STATS_BUF_SIZE (1024*1024)

static void ath10k_fw_stats_fill(struct ath10k *ar,
				 struct ath10k_fw_stats *fw_stats,
				 char *buf)
{
	unsigned int len = 0;
	unsigned int buf_len = ATH10K_FW_STATS_BUF_SIZE;
	const struct ath10k_fw_stats_pdev *pdev;
	const struct ath10k_fw_stats_vdev *vdev;
	const struct ath10k_fw_stats_peer *peer;
	size_t num_peers;
	size_t num_vdevs;
	int i;

	spin_lock_bh(&ar->data_lock);

	pdev = list_first_entry_or_null(&fw_stats->pdevs,
					struct ath10k_fw_stats_pdev, list);
	if (!pdev) {
		ath10k_warn(ar, "failed to get pdev stats\n");
		goto unlock;
	}

	num_peers = ath10k_debug_fw_stats_num_peers(&fw_stats->peers);
	num_vdevs = ath10k_debug_fw_stats_num_vdevs(&fw_stats->vdevs);

	len += scnprintf(buf + len, buf_len - len, "\n");
	len += scnprintf(buf + len, buf_len - len, "%30s\n",
			 "ath10k PDEV stats");
	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
				 "=================");

	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Channel noise floor", pdev->ch_noise_floor);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "Channel TX power", pdev->chan_tx_power);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "TX frame count", pdev->tx_frame_count);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "RX frame count", pdev->rx_frame_count);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "RX clear count", pdev->rx_clear_count);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "Cycle count", pdev->cycle_count);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "PHY error count", pdev->phy_err_count);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "RTS bad count", pdev->rts_bad);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "RTS good count", pdev->rts_good);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "FCS bad count", pdev->fcs_bad);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "No beacon count", pdev->no_beacons);
	len += scnprintf(buf + len, buf_len - len, "%30s %10u\n",
			 "MIB int count", pdev->mib_int_count);

	len += scnprintf(buf + len, buf_len - len, "\n");
	len += scnprintf(buf + len, buf_len - len, "%30s\n",
			 "ath10k PDEV TX stats");
	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
				 "=================");

	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "HTT cookies queued", pdev->comp_queued);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "HTT cookies disp.", pdev->comp_delivered);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MSDU queued", pdev->msdu_enqued);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MPDU queued", pdev->mpdu_enqued);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MSDUs dropped", pdev->wmm_drop);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Local enqued", pdev->local_enqued);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Local freed", pdev->local_freed);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "HW queued", pdev->hw_queued);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "PPDUs reaped", pdev->hw_reaped);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Num underruns", pdev->underrun);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "PPDUs cleaned", pdev->tx_abort);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MPDUs requed", pdev->mpdus_requed);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Excessive retries", pdev->tx_ko);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "HW rate", pdev->data_rc);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Sched self tiggers", pdev->self_triggers);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Dropped due to SW retries",
			 pdev->sw_retry_failure);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Illegal rate phy errors",
			 pdev->illgl_rate_phy_err);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Pdev continous xretry", pdev->pdev_cont_xretry);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "TX timeout", pdev->pdev_tx_timeout);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "PDEV resets", pdev->pdev_resets);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "PHY underrun", pdev->phy_underrun);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MPDU is more than txop limit", pdev->txop_ovf);

	len += scnprintf(buf + len, buf_len - len, "\n");
	len += scnprintf(buf + len, buf_len - len, "%30s\n",
			 "ath10k PDEV RX stats");
	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
				 "=================");

	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Mid PPDU route change",
			 pdev->mid_ppdu_route_change);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Tot. number of statuses", pdev->status_rcvd);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Extra frags on rings 0", pdev->r0_frags);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Extra frags on rings 1", pdev->r1_frags);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Extra frags on rings 2", pdev->r2_frags);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Extra frags on rings 3", pdev->r3_frags);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MSDUs delivered to HTT", pdev->htt_msdus);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MPDUs delivered to HTT", pdev->htt_mpdus);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MSDUs delivered to stack", pdev->loc_msdus);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MPDUs delivered to stack", pdev->loc_mpdus);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "Oversized AMSUs", pdev->oversize_amsdu);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "PHY errors", pdev->phy_errs);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "PHY errors drops", pdev->phy_err_drop);
	len += scnprintf(buf + len, buf_len - len, "%30s %10d\n",
			 "MPDU errors (FCS, MIC, ENC)", pdev->mpdu_errs);

	len += scnprintf(buf + len, buf_len - len, "\n");
	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
			 "ath10k VDEV stats", num_vdevs);
	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
				 "=================");

	list_for_each_entry(vdev, &fw_stats->vdevs, list) {
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "vdev id", vdev->vdev_id);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "beacon snr", vdev->beacon_snr);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "data snr", vdev->data_snr);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "num rx frames", vdev->num_rx_frames);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "num rts fail", vdev->num_rts_fail);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "num rts success", vdev->num_rts_success);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "num rx err", vdev->num_rx_err);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "num rx discard", vdev->num_rx_discard);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "num tx not acked", vdev->num_tx_not_acked);

		for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames); i++)
			len += scnprintf(buf + len, buf_len - len,
					"%25s [%02d] %u\n",
					 "num tx frames", i,
					 vdev->num_tx_frames[i]);

		for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_retries); i++)
			len += scnprintf(buf + len, buf_len - len,
					"%25s [%02d] %u\n",
					 "num tx frames retries", i,
					 vdev->num_tx_frames_retries[i]);

		for (i = 0 ; i < ARRAY_SIZE(vdev->num_tx_frames_failures); i++)
			len += scnprintf(buf + len, buf_len - len,
					"%25s [%02d] %u\n",
					 "num tx frames failures", i,
					 vdev->num_tx_frames_failures[i]);

		for (i = 0 ; i < ARRAY_SIZE(vdev->tx_rate_history); i++)
			len += scnprintf(buf + len, buf_len - len,
					"%25s [%02d] 0x%08x\n",
					 "tx rate history", i,
					 vdev->tx_rate_history[i]);

		for (i = 0 ; i < ARRAY_SIZE(vdev->beacon_rssi_history); i++)
			len += scnprintf(buf + len, buf_len - len,
					"%25s [%02d] %u\n",
					 "beacon rssi history", i,
					 vdev->beacon_rssi_history[i]);

		len += scnprintf(buf + len, buf_len - len, "\n");
	}

	len += scnprintf(buf + len, buf_len - len, "\n");
	len += scnprintf(buf + len, buf_len - len, "%30s (%zu)\n",
			 "ath10k PEER stats", num_peers);
	len += scnprintf(buf + len, buf_len - len, "%30s\n\n",
				 "=================");

	list_for_each_entry(peer, &fw_stats->peers, list) {
		len += scnprintf(buf + len, buf_len - len, "%30s %pM\n",
				 "Peer MAC address", peer->peer_macaddr);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "Peer RSSI", peer->peer_rssi);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "Peer TX rate", peer->peer_tx_rate);
		len += scnprintf(buf + len, buf_len - len, "%30s %u\n",
				 "Peer RX rate", peer->peer_rx_rate);
		len += scnprintf(buf + len, buf_len - len, "\n");
	}

unlock:
	spin_unlock_bh(&ar->data_lock);

	if (len >= buf_len)
		buf[len - 1] = 0;
	else
		buf[len] = 0;
}

static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
{
	struct ath10k *ar = inode->i_private;
@@ -694,7 +438,12 @@ static int ath10k_fw_stats_open(struct inode *inode, struct file *file)
		goto err_free;
	}

	ath10k_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
	ret = ath10k_wmi_fw_stats_fill(ar, &ar->debug.fw_stats, buf);
	if (ret) {
		ath10k_warn(ar, "failed to fill fw stats: %d\n", ret);
		goto err_free;
	}

	file->private_data = buf;

	mutex_unlock(&ar->conf_mutex);
+3 −0
Original line number Diff line number Diff line
@@ -55,6 +55,9 @@ enum ath10k_dbg_aggr_mode {
	ATH10K_DBG_AGGR_MODE_MAX,
};

/* FIXME: How to calculate the buffer size sanely? */
#define ATH10K_FW_STATS_BUF_SIZE (1024*1024)

extern unsigned int ath10k_debug_mask;

__printf(2, 3) void ath10k_info(struct ath10k *ar, const char *fmt, ...);
+13 −0
Original line number Diff line number Diff line
@@ -179,6 +179,9 @@ struct wmi_ops {
	struct sk_buff *(*gen_adaptive_qcs)(struct ath10k *ar, bool enable);
	struct sk_buff *(*gen_pdev_get_tpc_config)(struct ath10k *ar,
						   u32 param);
	void (*fw_stats_fill)(struct ath10k *ar,
			      struct ath10k_fw_stats *fw_stats,
			      char *buf);
};

int ath10k_wmi_cmd_send(struct ath10k *ar, struct sk_buff *skb, u32 cmd_id);
@@ -1289,4 +1292,14 @@ ath10k_wmi_pdev_get_tpc_config(struct ath10k *ar, u32 param)
				   ar->wmi.cmd->pdev_get_tpc_config_cmdid);
}

static inline int
ath10k_wmi_fw_stats_fill(struct ath10k *ar, struct ath10k_fw_stats *fw_stats,
			 char *buf)
{
	if (!ar->wmi.ops->fw_stats_fill)
		return -EOPNOTSUPP;

	ar->wmi.ops->fw_stats_fill(ar, fw_stats, buf);
	return 0;
}
#endif
+1 −0
Original line number Diff line number Diff line
@@ -3468,6 +3468,7 @@ static const struct wmi_ops wmi_tlv_ops = {
	.gen_update_fw_tdls_state = ath10k_wmi_tlv_op_gen_update_fw_tdls_state,
	.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,
};

/************/
+379 −0

File changed.

Preview size limit exceeded, changes collapsed.

Loading