Commit 14b539a3 authored by Pavel Belous's avatar Pavel Belous Committed by David S. Miller
Browse files

net: atlantic: PTP statistics



This patch adds PTP rings statistics. Before that
these were missing from overall stats, hardening debugging
and analysis.

Signed-off-by: default avatarPavel Belous <pbelous@marvell.com>
Signed-off-by: default avatarMark Starovoytov <mstarovoitov@marvell.com>
Signed-off-by: default avatarIgor Russkikh <irusskikh@marvell.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent aa7e17a3
Loading
Loading
Loading
Loading
+37 −0
Original line number Diff line number Diff line
@@ -177,6 +177,11 @@ static u32 aq_ethtool_n_stats(struct net_device *ndev)
	u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
		      (rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;

#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
	n_stats += rx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_RX) +
		   tx_stat_cnt * aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
#endif

#if IS_ENABLED(CONFIG_MACSEC)
	if (nic->macsec_cfg) {
		n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
@@ -199,6 +204,9 @@ static void aq_ethtool_stats(struct net_device *ndev,

	memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
	data = aq_nic_get_stats(aq_nic, data);
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
	data = aq_ptp_get_stats(aq_nic, data);
#endif
#if IS_ENABLED(CONFIG_MACSEC)
	data = aq_macsec_get_stats(aq_nic, data);
#endif
@@ -275,6 +283,35 @@ static void aq_ethtool_get_strings(struct net_device *ndev,
				}
			}
		}
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
		if (nic->aq_ptp) {
			const int rx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_RX);
			const int tx_ring_cnt = aq_ptp_get_ring_cnt(nic, ATL_RING_TX);
			unsigned int ptp_ring_idx =
				aq_ptp_ring_idx(nic->aq_nic_cfg.tc_mode);

			snprintf(tc_string, 8, "PTP ");

			for (i = 0; i < max(rx_ring_cnt, tx_ring_cnt); i++) {
				for (si = 0; si < rx_stat_cnt; si++) {
					snprintf(p, ETH_GSTRING_LEN,
						 aq_ethtool_queue_rx_stat_names[si],
						 tc_string,
						 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
					p += ETH_GSTRING_LEN;
				}
				if (i >= tx_ring_cnt)
					continue;
				for (si = 0; si < tx_stat_cnt; si++) {
					snprintf(p, ETH_GSTRING_LEN,
						 aq_ethtool_queue_tx_stat_names[si],
						 tc_string,
						 i ? PTP_HWST_RING_IDX : ptp_ring_idx);
					p += ETH_GSTRING_LEN;
				}
			}
		}
#endif
#if IS_ENABLED(CONFIG_MACSEC)
		if (!nic->macsec_cfg)
			break;
+43 −17
Original line number Diff line number Diff line
@@ -81,6 +81,8 @@ struct aq_ptp_s {

	bool extts_pin_enabled;
	u64 last_sync1588_ts;

	bool a1_ptp;
};

struct ptp_tm_offset {
@@ -947,21 +949,6 @@ void aq_ptp_ring_deinit(struct aq_nic_s *aq_nic)
	aq_ring_rx_deinit(&aq_ptp->ptp_rx);
}

#define PTP_8TC_RING_IDX             8
#define PTP_4TC_RING_IDX            16
#define PTP_HWST_RING_IDX           31

/* Index must be 8 (8 TCs) or 16 (4 TCs).
 * It depends on Traffic Class mode.
 */
static unsigned int ptp_ring_idx(const enum aq_tc_mode tc_mode)
{
	if (tc_mode == AQ_TC_MODE_8TCS)
		return PTP_8TC_RING_IDX;

	return PTP_4TC_RING_IDX;
}

int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
{
	struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
@@ -973,7 +960,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
	if (!aq_ptp)
		return 0;

	tx_ring_idx = ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
	tx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);

	ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
				tx_ring_idx, &aq_nic->aq_nic_cfg);
@@ -982,7 +969,7 @@ int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
		goto err_exit;
	}

	rx_ring_idx = ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);
	rx_ring_idx = aq_ptp_ring_idx(aq_nic->aq_nic_cfg.tc_mode);

	ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
				rx_ring_idx, &aq_nic->aq_nic_cfg);
@@ -1174,11 +1161,17 @@ static void aq_ptp_poll_sync_work_cb(struct work_struct *w);

int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
{
	bool a1_ptp = ATL_HW_IS_CHIP_FEATURE(aq_nic->aq_hw, ATLANTIC);
	struct hw_atl_utils_mbox mbox;
	struct ptp_clock *clock;
	struct aq_ptp_s *aq_ptp;
	int err = 0;

	if (!a1_ptp) {
		aq_nic->aq_ptp = NULL;
		return 0;
	}

	if (!aq_nic->aq_hw_ops->hw_get_ptp_ts) {
		aq_nic->aq_ptp = NULL;
		return 0;
@@ -1205,6 +1198,7 @@ int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
	}

	aq_ptp->aq_nic = aq_nic;
	aq_ptp->a1_ptp = a1_ptp;

	spin_lock_init(&aq_ptp->ptp_lock);
	spin_lock_init(&aq_ptp->ptp_ring_lock);
@@ -1395,4 +1389,36 @@ static void aq_ptp_poll_sync_work_cb(struct work_struct *w)
		schedule_delayed_work(&aq_ptp->poll_sync, timeout);
	}
}

int aq_ptp_get_ring_cnt(struct aq_nic_s *aq_nic, const enum atl_ring_type ring_type)
{
	if (!aq_nic->aq_ptp)
		return 0;

	/* Additional RX ring is allocated for PTP HWTS on A1 */
	return (aq_nic->aq_ptp->a1_ptp && ring_type == ATL_RING_RX) ? 2 : 1;
}

u64 *aq_ptp_get_stats(struct aq_nic_s *aq_nic, u64 *data)
{
	struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
	unsigned int count = 0U;

	if (!aq_ptp)
		return data;

	count = aq_ring_fill_stats_data(&aq_ptp->ptp_rx, data);
	data += count;
	count = aq_ring_fill_stats_data(&aq_ptp->ptp_tx, data);
	data += count;

	if (aq_ptp->a1_ptp) {
		/* Only Receive ring for HWTS */
		count = aq_ring_fill_stats_data(&aq_ptp->hwts_rx, data);
		data += count;
	}

	return data;
}

#endif
+25 −2
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/* Aquantia Corporation Network Driver
 * Copyright (C) 2014-2019 Aquantia Corporation. All rights reserved
/* Atlantic Network Driver
 *
 * Copyright (C) 2014-2019 aQuantia Corporation
 * Copyright (C) 2019-2020 Marvell International Ltd.
 */

/* File aq_ptp.h: Declaration of PTP functions.
@@ -10,6 +12,23 @@

#include <linux/net_tstamp.h>

#include "aq_ring.h"

#define PTP_8TC_RING_IDX             8
#define PTP_4TC_RING_IDX            16
#define PTP_HWST_RING_IDX           31

/* Index must to be 8 (8 TCs) or 16 (4 TCs).
 * It depends from Traffic Class mode.
 */
static inline unsigned int aq_ptp_ring_idx(const enum aq_tc_mode tc_mode)
{
	if (tc_mode == AQ_TC_MODE_8TCS)
		return PTP_8TC_RING_IDX;

	return PTP_4TC_RING_IDX;
}

#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)

/* Common functions */
@@ -55,6 +74,10 @@ struct ptp_clock *aq_ptp_get_ptp_clock(struct aq_ptp_s *aq_ptp);

int aq_ptp_link_change(struct aq_nic_s *aq_nic);

/* PTP ring statistics */
int aq_ptp_get_ring_cnt(struct aq_nic_s *aq_nic, const enum atl_ring_type ring_type);
u64 *aq_ptp_get_stats(struct aq_nic_s *aq_nic, u64 *data);

#else

static inline int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)