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

Commit be08d839 authored by Igor Russkikh's avatar Igor Russkikh Committed by David S. Miller
Browse files

net: aquantia: Extend stat counters to 64bit values



Device hardware provides only 32bit counters. Using these directly
causes byte counters to overflow soon. A separate nic level structure
with 64 bit counters is now used to collect incrementally all the stats
and report these counters to ethtool stats and ndev stats.

Signed-off-by: default avatarIgor Russkikh <igor.russkikh@aquantia.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 1e366161
Loading
Loading
Loading
Loading
+23 −2
Original line number Original line Diff line number Diff line
@@ -46,6 +46,28 @@ struct aq_hw_link_status_s {
	unsigned int mbps;
	unsigned int mbps;
};
};


struct aq_stats_s {
	u64 uprc;
	u64 mprc;
	u64 bprc;
	u64 erpt;
	u64 uptc;
	u64 mptc;
	u64 bptc;
	u64 erpr;
	u64 mbtc;
	u64 bbtc;
	u64 mbrc;
	u64 bbrc;
	u64 ubrc;
	u64 ubtc;
	u64 dpc;
	u64 dma_pkt_rc;
	u64 dma_pkt_tc;
	u64 dma_oct_rc;
	u64 dma_oct_tc;
};

#define AQ_HW_IRQ_INVALID 0U
#define AQ_HW_IRQ_INVALID 0U
#define AQ_HW_IRQ_LEGACY  1U
#define AQ_HW_IRQ_LEGACY  1U
#define AQ_HW_IRQ_MSI     2U
#define AQ_HW_IRQ_MSI     2U
@@ -166,8 +188,7 @@ struct aq_hw_ops {


	int (*hw_update_stats)(struct aq_hw_s *self);
	int (*hw_update_stats)(struct aq_hw_s *self);


	int (*hw_get_hw_stats)(struct aq_hw_s *self, u64 *data,
	struct aq_stats_s *(*hw_get_hw_stats)(struct aq_hw_s *self);
			       unsigned int *p_count);


	int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);
	int (*hw_get_fw_version)(struct aq_hw_s *self, u32 *fw_version);


+29 −6
Original line number Original line Diff line number Diff line
@@ -750,16 +750,40 @@ int aq_nic_get_regs_count(struct aq_nic_s *self)


void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
{
{
	struct aq_vec_s *aq_vec = NULL;
	unsigned int i = 0U;
	unsigned int i = 0U;
	unsigned int count = 0U;
	unsigned int count = 0U;
	int err = 0;
	struct aq_vec_s *aq_vec = NULL;
	struct aq_stats_s *stats = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw);


	err = self->aq_hw_ops.hw_get_hw_stats(self->aq_hw, data, &count);
	if (!stats)
	if (err < 0)
		goto err_exit;
		goto err_exit;


	data += count;
	data[i] = stats->uprc + stats->mprc + stats->bprc;
	data[++i] = stats->uprc;
	data[++i] = stats->mprc;
	data[++i] = stats->bprc;
	data[++i] = stats->erpt;
	data[++i] = stats->uptc + stats->mptc + stats->bptc;
	data[++i] = stats->uptc;
	data[++i] = stats->mptc;
	data[++i] = stats->bptc;
	data[++i] = stats->ubrc;
	data[++i] = stats->ubtc;
	data[++i] = stats->mbrc;
	data[++i] = stats->mbtc;
	data[++i] = stats->bbrc;
	data[++i] = stats->bbtc;
	data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
	data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
	data[++i] = stats->dma_pkt_rc;
	data[++i] = stats->dma_pkt_tc;
	data[++i] = stats->dma_oct_rc;
	data[++i] = stats->dma_oct_tc;
	data[++i] = stats->dpc;

	i++;

	data += i;
	count = 0U;
	count = 0U;


	for (i = 0U, aq_vec = self->aq_vec[0];
	for (i = 0U, aq_vec = self->aq_vec[0];
@@ -769,7 +793,6 @@ void aq_nic_get_stats(struct aq_nic_s *self, u64 *data)
	}
	}


err_exit:;
err_exit:;
	(void)err;
}
}


void aq_nic_get_link_ksettings(struct aq_nic_s *self,
void aq_nic_get_link_ksettings(struct aq_nic_s *self,
+25 −55
Original line number Original line Diff line number Diff line
@@ -503,14 +503,11 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self)
	struct hw_atl_s *hw_self = PHAL_ATLANTIC;
	struct hw_atl_s *hw_self = PHAL_ATLANTIC;
	struct hw_aq_atl_utils_mbox mbox;
	struct hw_aq_atl_utils_mbox mbox;


	if (!self->aq_link_status.mbps)
		return 0;

	hw_atl_utils_mpi_read_stats(self, &mbox);
	hw_atl_utils_mpi_read_stats(self, &mbox);


#define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
#define AQ_SDELTA(_N_) (hw_self->curr_stats._N_ += \
			mbox.stats._N_ - hw_self->last_stats._N_)
			mbox.stats._N_ - hw_self->last_stats._N_)

	if (self->aq_link_status.mbps) {
		AQ_SDELTA(uprc);
		AQ_SDELTA(uprc);
		AQ_SDELTA(mprc);
		AQ_SDELTA(mprc);
		AQ_SDELTA(bprc);
		AQ_SDELTA(bprc);
@@ -528,48 +525,21 @@ int hw_atl_utils_update_stats(struct aq_hw_s *self)
		AQ_SDELTA(bbrc);
		AQ_SDELTA(bbrc);
		AQ_SDELTA(bbtc);
		AQ_SDELTA(bbtc);
		AQ_SDELTA(dpc);
		AQ_SDELTA(dpc);

	}
#undef AQ_SDELTA
#undef AQ_SDELTA
	hw_self->curr_stats.dma_pkt_rc = stats_rx_dma_good_pkt_counterlsw_get(self);
	hw_self->curr_stats.dma_pkt_tc = stats_tx_dma_good_pkt_counterlsw_get(self);
	hw_self->curr_stats.dma_oct_rc = stats_rx_dma_good_octet_counterlsw_get(self);
	hw_self->curr_stats.dma_oct_tc = stats_tx_dma_good_octet_counterlsw_get(self);


	memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));
	memcpy(&hw_self->last_stats, &mbox.stats, sizeof(mbox.stats));


	return 0;
	return 0;
}
}


int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self)
			      u64 *data, unsigned int *p_count)
{
{
	struct hw_atl_s *hw_self = PHAL_ATLANTIC;
	return &PHAL_ATLANTIC->curr_stats;
	struct hw_atl_stats_s *stats = &hw_self->curr_stats;
	int i = 0;

	data[i] = stats->uprc + stats->mprc + stats->bprc;
	data[++i] = stats->uprc;
	data[++i] = stats->mprc;
	data[++i] = stats->bprc;
	data[++i] = stats->erpt;
	data[++i] = stats->uptc + stats->mptc + stats->bptc;
	data[++i] = stats->uptc;
	data[++i] = stats->mptc;
	data[++i] = stats->bptc;
	data[++i] = stats->ubrc;
	data[++i] = stats->ubtc;
	data[++i] = stats->mbrc;
	data[++i] = stats->mbtc;
	data[++i] = stats->bbrc;
	data[++i] = stats->bbtc;
	data[++i] = stats->ubrc + stats->mbrc + stats->bbrc;
	data[++i] = stats->ubtc + stats->mbtc + stats->bbtc;
	data[++i] = stats_rx_dma_good_pkt_counterlsw_get(self);
	data[++i] = stats_tx_dma_good_pkt_counterlsw_get(self);
	data[++i] = stats_rx_dma_good_octet_counterlsw_get(self);
	data[++i] = stats_tx_dma_good_octet_counterlsw_get(self);
	data[++i] = stats->dpc;

	if (p_count)
		*p_count = ++i;

	return 0;
}
}


static const u32 hw_atl_utils_hw_mac_regs[] = {
static const u32 hw_atl_utils_hw_mac_regs[] = {
+2 −4
Original line number Original line Diff line number Diff line
@@ -129,7 +129,7 @@ struct __packed hw_aq_atl_utils_mbox {
struct __packed hw_atl_s {
struct __packed hw_atl_s {
	struct aq_hw_s base;
	struct aq_hw_s base;
	struct hw_atl_stats_s last_stats;
	struct hw_atl_stats_s last_stats;
	struct hw_atl_stats_s curr_stats;
	struct aq_stats_s curr_stats;
	u64 speed;
	u64 speed;
	unsigned int chip_features;
	unsigned int chip_features;
	u32 fw_ver_actual;
	u32 fw_ver_actual;
@@ -207,8 +207,6 @@ int hw_atl_utils_get_fw_version(struct aq_hw_s *self, u32 *fw_version);


int hw_atl_utils_update_stats(struct aq_hw_s *self);
int hw_atl_utils_update_stats(struct aq_hw_s *self);


int hw_atl_utils_get_hw_stats(struct aq_hw_s *self,
struct aq_stats_s *hw_atl_utils_get_hw_stats(struct aq_hw_s *self);
			      u64 *data,
			      unsigned int *p_count);


#endif /* HW_ATL_UTILS_H */
#endif /* HW_ATL_UTILS_H */