mirror of
https://github.com/torvalds/linux.git
synced 2024-11-25 05:32:00 +00:00
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: Pavel Belous <pbelous@marvell.com> Signed-off-by: Mark Starovoytov <mstarovoitov@marvell.com> Signed-off-by: Igor Russkikh <irusskikh@marvell.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
aa7e17a3e3
commit
14b539a349
@ -177,6 +177,11 @@ static u32 aq_ethtool_n_stats(struct net_device *ndev)
|
|||||||
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
|
u32 n_stats = ARRAY_SIZE(aq_ethtool_stat_names) +
|
||||||
(rx_stat_cnt + tx_stat_cnt) * cfg->vecs * cfg->tcs;
|
(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 IS_ENABLED(CONFIG_MACSEC)
|
||||||
if (nic->macsec_cfg) {
|
if (nic->macsec_cfg) {
|
||||||
n_stats += ARRAY_SIZE(aq_macsec_stat_names) +
|
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));
|
memset(data, 0, aq_ethtool_n_stats(ndev) * sizeof(u64));
|
||||||
data = aq_nic_get_stats(aq_nic, data);
|
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)
|
#if IS_ENABLED(CONFIG_MACSEC)
|
||||||
data = aq_macsec_get_stats(aq_nic, data);
|
data = aq_macsec_get_stats(aq_nic, data);
|
||||||
#endif
|
#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 IS_ENABLED(CONFIG_MACSEC)
|
||||||
if (!nic->macsec_cfg)
|
if (!nic->macsec_cfg)
|
||||||
break;
|
break;
|
||||||
|
@ -81,6 +81,8 @@ struct aq_ptp_s {
|
|||||||
|
|
||||||
bool extts_pin_enabled;
|
bool extts_pin_enabled;
|
||||||
u64 last_sync1588_ts;
|
u64 last_sync1588_ts;
|
||||||
|
|
||||||
|
bool a1_ptp;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ptp_tm_offset {
|
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);
|
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)
|
int aq_ptp_ring_alloc(struct aq_nic_s *aq_nic)
|
||||||
{
|
{
|
||||||
struct aq_ptp_s *aq_ptp = aq_nic->aq_ptp;
|
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)
|
if (!aq_ptp)
|
||||||
return 0;
|
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,
|
ring = aq_ring_tx_alloc(&aq_ptp->ptp_tx, aq_nic,
|
||||||
tx_ring_idx, &aq_nic->aq_nic_cfg);
|
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;
|
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,
|
ring = aq_ring_rx_alloc(&aq_ptp->ptp_rx, aq_nic,
|
||||||
rx_ring_idx, &aq_nic->aq_nic_cfg);
|
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)
|
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 hw_atl_utils_mbox mbox;
|
||||||
struct ptp_clock *clock;
|
struct ptp_clock *clock;
|
||||||
struct aq_ptp_s *aq_ptp;
|
struct aq_ptp_s *aq_ptp;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
|
if (!a1_ptp) {
|
||||||
|
aq_nic->aq_ptp = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!aq_nic->aq_hw_ops->hw_get_ptp_ts) {
|
if (!aq_nic->aq_hw_ops->hw_get_ptp_ts) {
|
||||||
aq_nic->aq_ptp = NULL;
|
aq_nic->aq_ptp = NULL;
|
||||||
return 0;
|
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->aq_nic = aq_nic;
|
||||||
|
aq_ptp->a1_ptp = a1_ptp;
|
||||||
|
|
||||||
spin_lock_init(&aq_ptp->ptp_lock);
|
spin_lock_init(&aq_ptp->ptp_lock);
|
||||||
spin_lock_init(&aq_ptp->ptp_ring_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);
|
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
|
#endif
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||||
/* Aquantia Corporation Network Driver
|
/* Atlantic Network Driver
|
||||||
* Copyright (C) 2014-2019 Aquantia Corporation. All rights reserved
|
*
|
||||||
|
* Copyright (C) 2014-2019 aQuantia Corporation
|
||||||
|
* Copyright (C) 2019-2020 Marvell International Ltd.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* File aq_ptp.h: Declaration of PTP functions.
|
/* File aq_ptp.h: Declaration of PTP functions.
|
||||||
@ -10,6 +12,23 @@
|
|||||||
|
|
||||||
#include <linux/net_tstamp.h>
|
#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)
|
#if IS_REACHABLE(CONFIG_PTP_1588_CLOCK)
|
||||||
|
|
||||||
/* Common functions */
|
/* 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);
|
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
|
#else
|
||||||
|
|
||||||
static inline int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
|
static inline int aq_ptp_init(struct aq_nic_s *aq_nic, unsigned int idx_vec)
|
||||||
|
Loading…
Reference in New Issue
Block a user