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

Commit 2d07d8e4 authored by Quan Nguyen's avatar Quan Nguyen Committed by David S. Miller
Browse files

drivers: net: xgene: Extend ethtool statistics



This patch adds extended ethtool statistics support.

Signed-off-by: default avatarQuan Nguyen <qnguyen@apm.com>
Signed-off-by: default avatarIyappan Subramanian <isubramanian@apm.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 6f22a7ad
Loading
Loading
Loading
Loading
+88 −1
Original line number Diff line number Diff line
@@ -23,9 +23,17 @@
struct xgene_gstrings_stats {
	char name[ETH_GSTRING_LEN];
	int offset;
	u32 addr;
	u32 mask;
};

#define XGENE_STAT(m) { #m, offsetof(struct rtnl_link_stats64, m) }
#define XGENE_EXTD_STAT(s, a, m)		\
		{			\
		.name = #s,		\
		.addr = a ## _ADDR,	\
		.mask = m		\
		}

static const struct xgene_gstrings_stats gstrings_stats[] = {
	XGENE_STAT(rx_packets),
@@ -40,7 +48,51 @@ static const struct xgene_gstrings_stats gstrings_stats[] = {
	XGENE_STAT(rx_fifo_errors)
};

static const struct xgene_gstrings_stats gstrings_extd_stats[] = {
	XGENE_EXTD_STAT(tx_rx_64b_frame_cntr, TR64, 31),
	XGENE_EXTD_STAT(tx_rx_127b_frame_cntr, TR127, 31),
	XGENE_EXTD_STAT(tx_rx_255b_frame_cntr, TR255, 31),
	XGENE_EXTD_STAT(tx_rx_511b_frame_cntr, TR511, 31),
	XGENE_EXTD_STAT(tx_rx_1023b_frame_cntr, TR1K, 31),
	XGENE_EXTD_STAT(tx_rx_1518b_frame_cntr, TRMAX, 31),
	XGENE_EXTD_STAT(tx_rx_1522b_frame_cntr, TRMGV, 31),
	XGENE_EXTD_STAT(rx_fcs_error_cntr, RFCS, 16),
	XGENE_EXTD_STAT(rx_multicast_pkt_cntr, RMCA, 31),
	XGENE_EXTD_STAT(rx_broadcast_pkt_cntr, RBCA, 31),
	XGENE_EXTD_STAT(rx_ctrl_frame_pkt_cntr, RXCF, 16),
	XGENE_EXTD_STAT(rx_pause_frame_pkt_cntr, RXPF, 16),
	XGENE_EXTD_STAT(rx_unk_opcode_cntr, RXUO, 16),
	XGENE_EXTD_STAT(rx_align_err_cntr, RALN, 16),
	XGENE_EXTD_STAT(rx_frame_len_err_cntr, RFLR, 16),
	XGENE_EXTD_STAT(rx_code_err_cntr, RCDE, 16),
	XGENE_EXTD_STAT(rx_carrier_sense_err_cntr, RCSE, 16),
	XGENE_EXTD_STAT(rx_undersize_pkt_cntr, RUND, 16),
	XGENE_EXTD_STAT(rx_oversize_pkt_cntr, ROVR, 16),
	XGENE_EXTD_STAT(rx_fragments_cntr, RFRG, 16),
	XGENE_EXTD_STAT(rx_jabber_cntr, RJBR, 16),
	XGENE_EXTD_STAT(rx_dropped_pkt_cntr, RDRP, 16),
	XGENE_EXTD_STAT(tx_multicast_pkt_cntr, TMCA, 31),
	XGENE_EXTD_STAT(tx_broadcast_pkt_cntr, TBCA, 31),
	XGENE_EXTD_STAT(tx_pause_ctrl_frame_cntr, TXPF, 16),
	XGENE_EXTD_STAT(tx_defer_pkt_cntr, TDFR, 31),
	XGENE_EXTD_STAT(tx_excv_defer_pkt_cntr, TEDF, 31),
	XGENE_EXTD_STAT(tx_single_col_pkt_cntr, TSCL, 31),
	XGENE_EXTD_STAT(tx_multi_col_pkt_cntr, TMCL, 31),
	XGENE_EXTD_STAT(tx_late_col_pkt_cntr, TLCL, 31),
	XGENE_EXTD_STAT(tx_excv_col_pkt_cntr, TXCL, 31),
	XGENE_EXTD_STAT(tx_total_col_cntr, TNCL, 31),
	XGENE_EXTD_STAT(tx_pause_frames_hnrd_cntr, TPFH, 16),
	XGENE_EXTD_STAT(tx_drop_frame_cntr, TDRP, 16),
	XGENE_EXTD_STAT(tx_jabber_frame_cntr, TJBR, 12),
	XGENE_EXTD_STAT(tx_fcs_error_cntr, TFCS, 12),
	XGENE_EXTD_STAT(tx_ctrl_frame_cntr, TXCF, 12),
	XGENE_EXTD_STAT(tx_oversize_frame_cntr, TOVR, 12),
	XGENE_EXTD_STAT(tx_undersize_frame_cntr, TUND, 12),
	XGENE_EXTD_STAT(tx_fragments_cntr, TFRG, 12)
};

#define XGENE_STATS_LEN		ARRAY_SIZE(gstrings_stats)
#define XGENE_EXTD_STATS_LEN	ARRAY_SIZE(gstrings_extd_stats)

static void xgene_get_drvinfo(struct net_device *ndev,
			      struct ethtool_drvinfo *info)
@@ -142,6 +194,11 @@ static void xgene_get_strings(struct net_device *ndev, u32 stringset, u8 *data)
		memcpy(p, gstrings_stats[i].name, ETH_GSTRING_LEN);
		p += ETH_GSTRING_LEN;
	}

	for (i = 0; i < XGENE_EXTD_STATS_LEN; i++) {
		memcpy(p, gstrings_extd_stats[i].name, ETH_GSTRING_LEN);
		p += ETH_GSTRING_LEN;
	}
}

static int xgene_get_sset_count(struct net_device *ndev, int sset)
@@ -149,19 +206,49 @@ static int xgene_get_sset_count(struct net_device *ndev, int sset)
	if (sset != ETH_SS_STATS)
		return -EINVAL;

	return XGENE_STATS_LEN;
	return XGENE_STATS_LEN + XGENE_EXTD_STATS_LEN;
}

static void xgene_get_extd_stats(struct xgene_enet_pdata *pdata)
{
	u32 tmp;
	int i;

	for (i = 0; i < XGENE_EXTD_STATS_LEN; i++) {
		tmp = xgene_enet_rd_stat(pdata, gstrings_extd_stats[i].addr);
		pdata->extd_stats[i] += tmp &
			GENMASK(gstrings_extd_stats[i].mask - 1, 0);
	}
}

int xgene_extd_stats_init(struct xgene_enet_pdata *pdata)
{
	pdata->extd_stats = devm_kmalloc_array(&pdata->pdev->dev,
			XGENE_EXTD_STATS_LEN, sizeof(u64), GFP_KERNEL);
	if (!pdata->extd_stats)
		return -ENOMEM;

	xgene_get_extd_stats(pdata);
	memset(pdata->extd_stats, 0, XGENE_EXTD_STATS_LEN * sizeof(u64));

	return 0;
}

static void xgene_get_ethtool_stats(struct net_device *ndev,
				    struct ethtool_stats *dummy,
				    u64 *data)
{
	struct xgene_enet_pdata *pdata = netdev_priv(ndev);
	struct rtnl_link_stats64 stats;
	int i;

	dev_get_stats(ndev, &stats);
	for (i = 0; i < XGENE_STATS_LEN; i++)
		data[i] = *(u64 *)((char *)&stats + gstrings_stats[i].offset);

	xgene_get_extd_stats(pdata);
	for (i = 0; i < XGENE_EXTD_STATS_LEN; i++)
		data[i + XGENE_STATS_LEN] = pdata->extd_stats[i];
}

static void xgene_get_pauseparam(struct net_device *ndev,
+29 −0
Original line number Diff line number Diff line
@@ -359,6 +359,35 @@ u32 xgene_enet_rd_mac(struct xgene_enet_pdata *pdata, u32 rd_addr)
	return rd_data;
}

u32 xgene_enet_rd_stat(struct xgene_enet_pdata *pdata, u32 rd_addr)
{
	void __iomem *addr, *rd, *cmd, *cmd_done;
	u32 done, rd_data;
	u8 wait = 10;

	addr = pdata->mcx_stats_addr + STAT_ADDR_REG_OFFSET;
	rd = pdata->mcx_stats_addr + STAT_READ_REG_OFFSET;
	cmd = pdata->mcx_stats_addr + STAT_COMMAND_REG_OFFSET;
	cmd_done = pdata->mcx_stats_addr + STAT_COMMAND_DONE_REG_OFFSET;

	spin_lock(&pdata->stats_lock);
	iowrite32(rd_addr, addr);
	iowrite32(XGENE_ENET_RD_CMD, cmd);

	while (!(done = ioread32(cmd_done)) && wait--)
		udelay(1);

	if (!done)
		netdev_err(pdata->ndev, "mac stats read failed, addr: %04x\n",
			   rd_addr);

	rd_data = ioread32(rd);
	iowrite32(0, cmd);
	spin_unlock(&pdata->stats_lock);

	return rd_data;
}

static void xgene_gmac_set_mac_addr(struct xgene_enet_pdata *pdata)
{
	u32 addr0, addr1;
+51 −0
Original line number Diff line number Diff line
@@ -115,6 +115,7 @@ enum xgene_enet_rm {
#define BLOCK_ETH_CLKRST_CSR_OFFSET	0xc000
#define BLOCK_ETH_DIAG_CSR_OFFSET	0xD000
#define BLOCK_ETH_MAC_OFFSET		0x0000
#define BLOCK_ETH_STATS_OFFSET		0x0000
#define BLOCK_ETH_MAC_CSR_OFFSET	0x2800

#define CLKEN_ADDR			0xc208
@@ -126,6 +127,12 @@ enum xgene_enet_rm {
#define MAC_READ_REG_OFFSET		0x0c
#define MAC_COMMAND_DONE_REG_OFFSET	0x10

#define STAT_ADDR_REG_OFFSET            0x14
#define STAT_COMMAND_REG_OFFSET         0x18
#define STAT_WRITE_REG_OFFSET           0x1c
#define STAT_READ_REG_OFFSET            0x20
#define STAT_COMMAND_DONE_REG_OFFSET    0x24

#define PCS_ADDR_REG_OFFSET		0x00
#define PCS_COMMAND_REG_OFFSET		0x04
#define PCS_WRITE_REG_OFFSET		0x08
@@ -218,6 +225,49 @@ enum xgene_enet_rm {
#define PAD_CRC				BIT(2)
#define LENGTH_CHK			BIT(4)

#define TR64_ADDR	0x20
#define TR127_ADDR	0x21
#define TR255_ADDR	0x22
#define TR511_ADDR	0x23
#define TR1K_ADDR	0x24
#define TRMAX_ADDR	0x25
#define TRMGV_ADDR	0x26

#define RFCS_ADDR	0x29
#define RMCA_ADDR	0x2a
#define RBCA_ADDR	0x2b
#define RXCF_ADDR	0x2c
#define RXPF_ADDR	0x2d
#define RXUO_ADDR	0x2e
#define RALN_ADDR	0x2f
#define RFLR_ADDR	0x30
#define RCDE_ADDR	0x31
#define RCSE_ADDR	0x32
#define RUND_ADDR	0x33
#define ROVR_ADDR	0x34
#define RFRG_ADDR	0x35
#define RJBR_ADDR	0x36
#define RDRP_ADDR	0x37

#define TMCA_ADDR	0x3a
#define TBCA_ADDR	0x3b
#define TXPF_ADDR	0x3c
#define TDFR_ADDR	0x3d
#define TEDF_ADDR	0x3e
#define TSCL_ADDR	0x3f
#define TMCL_ADDR	0x40
#define TLCL_ADDR	0x41
#define TXCL_ADDR	0x42
#define TNCL_ADDR	0x43
#define TPFH_ADDR	0x44
#define TDRP_ADDR	0x45
#define TJBR_ADDR	0x46
#define TFCS_ADDR	0x47
#define TXCF_ADDR	0x48
#define TOVR_ADDR	0x49
#define TUND_ADDR	0x4a
#define TFRG_ADDR	0x4b

#define TSO_IPPROTO_TCP			1

#define USERINFO_POS			0
@@ -383,6 +433,7 @@ void xgene_enet_phy_disconnect(struct xgene_enet_pdata *pdata);
u32 xgene_enet_rd_mac(struct xgene_enet_pdata *pdata, u32 rd_addr);
void xgene_enet_wr_mac(struct xgene_enet_pdata *pdata, u32 wr_addr,
		       u32 wr_data);
u32 xgene_enet_rd_stat(struct xgene_enet_pdata *pdata, u32 rd_addr);

extern const struct xgene_mac_ops xgene_gmac_ops;
extern const struct xgene_port_ops xgene_gport_ops;
+8 −0
Original line number Diff line number Diff line
@@ -1792,12 +1792,15 @@ static int xgene_enet_get_resources(struct xgene_enet_pdata *pdata)
	if (pdata->phy_mode == PHY_INTERFACE_MODE_RGMII ||
	    pdata->phy_mode == PHY_INTERFACE_MODE_SGMII) {
		pdata->mcx_mac_addr = pdata->base_addr + BLOCK_ETH_MAC_OFFSET;
		pdata->mcx_stats_addr =
			pdata->base_addr + BLOCK_ETH_STATS_OFFSET;
		offset = (pdata->enet_id == XGENE_ENET1) ?
			  BLOCK_ETH_MAC_CSR_OFFSET :
			  X2_BLOCK_ETH_MAC_CSR_OFFSET;
		pdata->mcx_mac_csr_addr = base_addr + offset;
	} else {
		pdata->mcx_mac_addr = base_addr + BLOCK_AXG_MAC_OFFSET;
		pdata->mcx_stats_addr = base_addr + BLOCK_AXG_STATS_OFFSET;
		pdata->mcx_mac_csr_addr = base_addr + BLOCK_AXG_MAC_CSR_OFFSET;
		pdata->pcs_addr = base_addr + BLOCK_PCS_OFFSET;
	}
@@ -2090,6 +2093,11 @@ static int xgene_enet_probe(struct platform_device *pdev)
			goto err1;
	}

	spin_lock_init(&pdata->stats_lock);
	ret = xgene_extd_stats_init(pdata);
	if (ret)
		goto err2;

	xgene_enet_napi_add(pdata);
	ret = register_netdev(ndev);
	if (ret) {
+4 −0
Original line number Diff line number Diff line
@@ -214,6 +214,7 @@ struct xgene_enet_pdata {
	void __iomem *eth_diag_csr_addr;
	void __iomem *mcx_mac_addr;
	void __iomem *mcx_mac_csr_addr;
	void __iomem *mcx_stats_addr;
	void __iomem *base_addr;
	void __iomem *pcs_addr;
	void __iomem *ring_csr_addr;
@@ -221,6 +222,8 @@ struct xgene_enet_pdata {
	int phy_mode;
	enum xgene_enet_rm rm;
	struct xgene_enet_cle cle;
	u64 *extd_stats;
	spinlock_t stats_lock; /* statistics lock */
	const struct xgene_mac_ops *mac_ops;
	spinlock_t mac_lock; /* mac lock */
	const struct xgene_port_ops *port_ops;
@@ -265,5 +268,6 @@ static inline u16 xgene_enet_dst_ring_num(struct xgene_enet_desc_ring *ring)
}

void xgene_enet_set_ethtool_ops(struct net_device *netdev);
int xgene_extd_stats_init(struct xgene_enet_pdata *pdata);

#endif /* __XGENE_ENET_MAIN_H__ */
Loading