1
0
mirror of https://github.com/cjdelisle/openwrt.git synced 2025-06-18 16:39:47 +00:00
Files
openwrt/target/linux/qualcommbe/patches-6.6/103-33-net-ethernet-qualcomm-Add-PPE-port-MAC-MIB-statistic.patch
John Audia 11f1f67a3e qualcommb/ipq95xx: refresh patches ahead of 6.6.75
Refreshed patches for qualcommb/ipq95xx by running
make target/linux/refresh after creating a .config containing:
CONFIG_TARGET_qualcommbe=y
CONFIG_TARGET_qualcommbe_ipq95xx=y
CONFIG_TARGET_qualcommbe_ipq95xx_DEVICE_qcom_rdp433=y

Signed-off-by: John Audia <therealgraysky@proton.me>
Link: https://github.com/openwrt/openwrt/pull/17822
Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
2025-02-13 00:03:54 +01:00

674 lines
22 KiB
Diff

From 3e8cb061bff0bf74503cd2f206ed5c599a1e7ff7 Mon Sep 17 00:00:00 2001
From: Lei Wei <quic_leiwei@quicinc.com>
Date: Thu, 29 Feb 2024 20:16:14 +0800
Subject: [PATCH 33/50] net: ethernet: qualcomm: Add PPE port MAC MIB
statistics functions
Add PPE port MAC MIB statistics functions which are used by netdev
ops and ethtool. For GMAC, a polling task is scheduled to read the
MIB counters periodically to avoid 32bit register counter overflow.
Change-Id: Ic20e240061278f77d703f652e1f7d959db8fac37
Signed-off-by: Lei Wei <quic_leiwei@quicinc.com>
---
drivers/net/ethernet/qualcomm/ppe/ppe_port.c | 465 +++++++++++++++++++
drivers/net/ethernet/qualcomm/ppe/ppe_port.h | 13 +
drivers/net/ethernet/qualcomm/ppe/ppe_regs.h | 91 ++++
3 files changed, 569 insertions(+)
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.c
@@ -23,6 +23,122 @@
/* PPE BM port start for PPE MAC ports */
#define PPE_BM_PORT_MAC_START 7
+/* Poll interval time to poll GMAC MIBs for overflow protection,
+ * the time should ensure that the 32bit GMAC packet counter
+ * register would not overflow within this time at line rate
+ * speed for 64B packet size.
+ */
+#define PPE_GMIB_POLL_INTERVAL_MS 120000
+
+#define PPE_MAC_MIB_DESC(_s, _o, _n) \
+ { \
+ .size = (_s), \
+ .offset = (_o), \
+ .name = (_n), \
+ }
+
+/* PPE MAC MIB description */
+struct ppe_mac_mib_info {
+ u32 size;
+ u32 offset;
+ const char *name;
+};
+
+/* PPE GMAC MIB statistics type */
+enum ppe_gmib_stats_type {
+ gmib_rx_broadcast,
+ gmib_rx_pause,
+ gmib_rx_multicast,
+ gmib_rx_fcserr,
+ gmib_rx_alignerr,
+ gmib_rx_runt,
+ gmib_rx_frag,
+ gmib_rx_jumbofcserr,
+ gmib_rx_jumboalignerr,
+ gmib_rx_pkt64,
+ gmib_rx_pkt65to127,
+ gmib_rx_pkt128to255,
+ gmib_rx_pkt256to511,
+ gmib_rx_pkt512to1023,
+ gmib_rx_pkt1024to1518,
+ gmib_rx_pkt1519tomax,
+ gmib_rx_toolong,
+ gmib_rx_bytes_g,
+ gmib_rx_bytes_b,
+ gmib_rx_unicast,
+ gmib_tx_broadcast,
+ gmib_tx_pause,
+ gmib_tx_multicast,
+ gmib_tx_underrun,
+ gmib_tx_pkt64,
+ gmib_tx_pkt65to127,
+ gmib_tx_pkt128to255,
+ gmib_tx_pkt256to511,
+ gmib_tx_pkt512to1023,
+ gmib_tx_pkt1024to1518,
+ gmib_tx_pkt1519tomax,
+ gmib_tx_bytes,
+ gmib_tx_collisions,
+ gmib_tx_abortcol,
+ gmib_tx_multicol,
+ gmib_tx_singlecol,
+ gmib_tx_excdeffer,
+ gmib_tx_deffer,
+ gmib_tx_latecol,
+ gmib_tx_unicast,
+};
+
+/* PPE XGMAC MIB statistics type */
+enum ppe_xgmib_stats_type {
+ xgmib_tx_bytes,
+ xgmib_tx_frames,
+ xgmib_tx_broadcast_g,
+ xgmib_tx_multicast_g,
+ xgmib_tx_pkt64,
+ xgmib_tx_pkt65to127,
+ xgmib_tx_pkt128to255,
+ xgmib_tx_pkt256to511,
+ xgmib_tx_pkt512to1023,
+ xgmib_tx_pkt1024tomax,
+ xgmib_tx_unicast,
+ xgmib_tx_multicast,
+ xgmib_tx_broadcast,
+ xgmib_tx_underflow_err,
+ xgmib_tx_bytes_g,
+ xgmib_tx_frames_g,
+ xgmib_tx_pause,
+ xgmib_tx_vlan_g,
+ xgmib_tx_lpi_usec,
+ xgmib_tx_lpi_tran,
+ xgmib_rx_frames,
+ xgmib_rx_bytes,
+ xgmib_rx_bytes_g,
+ xgmib_rx_broadcast_g,
+ xgmib_rx_multicast_g,
+ xgmib_rx_crc_err,
+ xgmib_rx_runt_err,
+ xgmib_rx_jabber_err,
+ xgmib_rx_undersize_g,
+ xgmib_rx_oversize_g,
+ xgmib_rx_pkt64,
+ xgmib_rx_pkt65to127,
+ xgmib_rx_pkt128to255,
+ xgmib_rx_pkt256to511,
+ xgmib_rx_pkt512to1023,
+ xgmib_rx_pkt1024tomax,
+ xgmib_rx_unicast_g,
+ xgmib_rx_len_err,
+ xgmib_rx_outofrange_err,
+ xgmib_rx_pause,
+ xgmib_rx_fifo_overflow,
+ xgmib_rx_vlan,
+ xgmib_rx_wdog_err,
+ xgmib_rx_lpi_usec,
+ xgmib_rx_lpi_tran,
+ xgmib_rx_drop_frames,
+ xgmib_rx_drop_bytes,
+};
+
/* PPE port clock and reset name */
static const char * const ppe_port_clk_rst_name[] = {
[PPE_PORT_CLK_RST_MAC] = "port_mac",
@@ -30,6 +146,322 @@ static const char * const ppe_port_clk_r
[PPE_PORT_CLK_RST_TX] = "port_tx",
};
+/* PPE GMAC MIB statistics description information */
+static const struct ppe_mac_mib_info gmib_info[] = {
+ PPE_MAC_MIB_DESC(4, GMAC_RXBROAD_ADDR, "rx_broadcast"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPAUSE_ADDR, "rx_pause"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXMULTI_ADDR, "rx_multicast"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXFCSERR_ADDR, "rx_fcserr"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXALIGNERR_ADDR, "rx_alignerr"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXRUNT_ADDR, "rx_runt"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXFRAG_ADDR, "rx_frag"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOFCSERR_ADDR, "rx_jumbofcserr"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXJUMBOALIGNERR_ADDR, "rx_jumboalignerr"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT64_ADDR, "rx_pkt64"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT65TO127_ADDR, "rx_pkt65to127"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT128TO255_ADDR, "rx_pkt128to255"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT256TO511_ADDR, "rx_pkt256to511"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT512TO1023_ADDR, "rx_pkt512to1023"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT1024TO1518_ADDR, "rx_pkt1024to1518"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXPKT1519TOX_ADDR, "rx_pkt1519tomax"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXTOOLONG_ADDR, "rx_toolong"),
+ PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
+ PPE_MAC_MIB_DESC(8, GMAC_RXBYTE_B_ADDR, "rx_bytes_b"),
+ PPE_MAC_MIB_DESC(4, GMAC_RXUNI_ADDR, "rx_unicast"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXBROAD_ADDR, "tx_broadcast"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPAUSE_ADDR, "tx_pause"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXMULTI_ADDR, "tx_multicast"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXUNDERRUN_ADDR, "tx_underrun"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT64_ADDR, "tx_pkt64"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT65TO127_ADDR, "tx_pkt65to127"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT128TO255_ADDR, "tx_pkt128to255"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT256TO511_ADDR, "tx_pkt256to511"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT512TO1023_ADDR, "tx_pkt512to1023"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT1024TO1518_ADDR, "tx_pkt1024to1518"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXPKT1519TOX_ADDR, "tx_pkt1519tomax"),
+ PPE_MAC_MIB_DESC(8, GMAC_TXBYTE_ADDR, "tx_bytes"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXCOLLISIONS_ADDR, "tx_collisions"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXABORTCOL_ADDR, "tx_abortcol"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXMULTICOL_ADDR, "tx_multicol"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXSINGLECOL_ADDR, "tx_singlecol"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXEXCESSIVEDEFER_ADDR, "tx_excdeffer"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXDEFER_ADDR, "tx_deffer"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXLATECOL_ADDR, "tx_latecol"),
+ PPE_MAC_MIB_DESC(4, GMAC_TXUNI_ADDR, "tx_unicast"),
+};
+
+/* PPE XGMAC MIB statistics description information */
+static const struct ppe_mac_mib_info xgmib_info[] = {
+ PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_GB_ADDR, "tx_bytes"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_GB_ADDR, "tx_frames"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_G_ADDR, "tx_broadcast_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_G_ADDR, "tx_multicast_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT64_GB_ADDR, "tx_pkt64"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT65TO127_GB_ADDR, "tx_pkt65to127"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT128TO255_GB_ADDR, "tx_pkt128to255"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT256TO511_GB_ADDR, "tx_pkt256to511"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT512TO1023_GB_ADDR, "tx_pkt512to1023"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT1024TOMAX_GB_ADDR, "tx_pkt1024tomax"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXUNI_GB_ADDR, "tx_unicast"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXMULTI_GB_ADDR, "tx_multicast"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXBROAD_GB_ADDR, "tx_broadcast"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXUNDERFLOW_ERR_ADDR, "tx_underflow_err"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXBYTE_G_ADDR, "tx_bytes_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPKT_G_ADDR, "tx_frames_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXPAUSE_ADDR, "tx_pause"),
+ PPE_MAC_MIB_DESC(8, XGMAC_TXVLAN_G_ADDR, "tx_vlan_g"),
+ PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_USEC_ADDR, "tx_lpi_usec"),
+ PPE_MAC_MIB_DESC(4, XGMAC_TXLPI_TRAN_ADDR, "tx_lpi_tran"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT_GB_ADDR, "rx_frames"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_GB_ADDR, "rx_bytes"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXBYTE_G_ADDR, "rx_bytes_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXBROAD_G_ADDR, "rx_broadcast_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXMULTI_G_ADDR, "rx_multicast_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXCRC_ERR_ADDR, "rx_crc_err"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXRUNT_ERR_ADDR, "rx_runt_err"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXJABBER_ERR_ADDR, "rx_jabber_err"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXUNDERSIZE_G_ADDR, "rx_undersize_g"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXOVERSIZE_G_ADDR, "rx_oversize_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT64_GB_ADDR, "rx_pkt64"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT65TO127_GB_ADDR, "rx_pkt65to127"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT128TO255_GB_ADDR, "rx_pkt128to255"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT256TO511_GB_ADDR, "rx_pkt256to511"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT512TO1023_GB_ADDR, "rx_pkt512to1023"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPKT1024TOMAX_GB_ADDR, "rx_pkt1024tomax"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXUNI_G_ADDR, "rx_unicast_g"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXLEN_ERR_ADDR, "rx_len_err"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXOUTOFRANGE_ADDR, "rx_outofrange_err"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXPAUSE_ADDR, "rx_pause"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXFIFOOVERFLOW_ADDR, "rx_fifo_overflow"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXVLAN_GB_ADDR, "rx_vlan"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXWATCHDOG_ERR_ADDR, "rx_wdog_err"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_USEC_ADDR, "rx_lpi_usec"),
+ PPE_MAC_MIB_DESC(4, XGMAC_RXLPI_TRAN_ADDR, "rx_lpi_tran"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARD_GB_ADDR, "rx_drop_frames"),
+ PPE_MAC_MIB_DESC(8, XGMAC_RXDISCARDBYTE_GB_ADDR, "rx_drop_bytes"),
+};
+
+/* Get GMAC MIBs from registers and accumulate to PPE port GMIB stats array */
+static void ppe_port_gmib_update(struct ppe_port *ppe_port)
+{
+ struct ppe_device *ppe_dev = ppe_port->ppe_dev;
+ const struct ppe_mac_mib_info *mib;
+ int port = ppe_port->port_id;
+ u32 reg, val;
+ int i, ret;
+
+ for (i = 0; i < ARRAY_SIZE(gmib_info); i++) {
+ mib = &gmib_info[i];
+ reg = PPE_PORT_GMAC_ADDR(port) + mib->offset;
+
+ ret = regmap_read(ppe_dev->regmap, reg, &val);
+ if (ret) {
+ dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
+ continue;
+ }
+
+ ppe_port->gmib_stats[i] += val;
+ if (mib->size == 8) {
+ ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
+ if (ret) {
+ dev_warn(ppe_dev->dev, "%s: %d\n",
+ __func__, ret);
+ continue;
+ }
+
+ ppe_port->gmib_stats[i] += (u64)val << 32;
+ }
+ }
+}
+
+/* Polling task to read GMIB statistics to avoid GMIB 32bit register overflow */
+static void ppe_port_gmib_stats_poll(struct work_struct *work)
+{
+ struct ppe_port *ppe_port = container_of(work, struct ppe_port,
+ gmib_read.work);
+ spin_lock(&ppe_port->gmib_stats_lock);
+ ppe_port_gmib_update(ppe_port);
+ spin_unlock(&ppe_port->gmib_stats_lock);
+
+ schedule_delayed_work(&ppe_port->gmib_read,
+ msecs_to_jiffies(PPE_GMIB_POLL_INTERVAL_MS));
+}
+
+/* Get the XGMAC MIB counter based on the specific MIB stats type */
+static u64 ppe_port_xgmib_get(struct ppe_port *ppe_port,
+ enum ppe_xgmib_stats_type xgmib_type)
+{
+ struct ppe_device *ppe_dev = ppe_port->ppe_dev;
+ const struct ppe_mac_mib_info *mib;
+ int port = ppe_port->port_id;
+ u32 reg, val;
+ u64 data = 0;
+ int ret;
+
+ mib = &xgmib_info[xgmib_type];
+ reg = PPE_PORT_XGMAC_ADDR(port) + mib->offset;
+
+ ret = regmap_read(ppe_dev->regmap, reg, &val);
+ if (ret) {
+ dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
+ goto data_return;
+ }
+
+ data = val;
+ if (mib->size == 8) {
+ ret = regmap_read(ppe_dev->regmap, reg + 4, &val);
+ if (ret) {
+ dev_warn(ppe_dev->dev, "%s: %d\n", __func__, ret);
+ goto data_return;
+ }
+
+ data |= (u64)val << 32;
+ }
+
+data_return:
+ return data;
+}
+
+/**
+ * ppe_port_get_sset_count() - Get PPE port statistics string count
+ * @ppe_port: PPE port
+ * @sset: string set ID
+ *
+ * Description: Get the MAC statistics string count for the PPE port
+ * specified by @ppe_port.
+ *
+ * Return: The count of the statistics string.
+ */
+int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset)
+{
+ if (sset != ETH_SS_STATS)
+ return 0;
+
+ if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC)
+ return ARRAY_SIZE(gmib_info);
+ else
+ return ARRAY_SIZE(xgmib_info);
+}
+
+/**
+ * ppe_port_get_strings() - Get PPE port statistics strings
+ * @ppe_port: PPE port
+ * @stringset: string set ID
+ * @data: pointer to statistics strings
+ *
+ * Description: Get the MAC statistics stings for the PPE port
+ * specified by @ppe_port. The strings are stored in the buffer
+ * indicated by @data which used in the ethtool ops.
+ */
+void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data)
+{
+ int i;
+
+ if (stringset != ETH_SS_STATS)
+ return;
+
+ if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
+ for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
+ strscpy(data + i * ETH_GSTRING_LEN, gmib_info[i].name,
+ ETH_GSTRING_LEN);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
+ strscpy(data + i * ETH_GSTRING_LEN, xgmib_info[i].name,
+ ETH_GSTRING_LEN);
+ }
+}
+
+/**
+ * ppe_port_get_ethtool_stats() - Get PPE port ethtool statistics
+ * @ppe_port: PPE port
+ * @data: pointer to statistics data
+ *
+ * Description: Get the MAC statistics for the PPE port specified
+ * by @ppe_port. The statistics are stored in the buffer indicated
+ * by @data which used in the ethtool ops.
+ */
+void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data)
+{
+ int i;
+
+ if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
+ spin_lock(&ppe_port->gmib_stats_lock);
+
+ ppe_port_gmib_update(ppe_port);
+ for (i = 0; i < ARRAY_SIZE(gmib_info); i++)
+ data[i] = ppe_port->gmib_stats[i];
+
+ spin_unlock(&ppe_port->gmib_stats_lock);
+ } else {
+ for (i = 0; i < ARRAY_SIZE(xgmib_info); i++)
+ data[i] = ppe_port_xgmib_get(ppe_port, i);
+ }
+}
+
+/**
+ * ppe_port_get_stats64() - Get PPE port statistics
+ * @ppe_port: PPE port
+ * @s: statistics pointer
+ *
+ * Description: Get the MAC statistics for the PPE port specified
+ * by @ppe_port.
+ */
+void ppe_port_get_stats64(struct ppe_port *ppe_port,
+ struct rtnl_link_stats64 *s)
+{
+ if (ppe_port->mac_type == PPE_MAC_TYPE_GMAC) {
+ u64 *src = ppe_port->gmib_stats;
+
+ spin_lock(&ppe_port->gmib_stats_lock);
+
+ ppe_port_gmib_update(ppe_port);
+
+ s->rx_packets = src[gmib_rx_unicast] +
+ src[gmib_rx_broadcast] + src[gmib_rx_multicast];
+
+ s->tx_packets = src[gmib_tx_unicast] +
+ src[gmib_tx_broadcast] + src[gmib_tx_multicast];
+
+ s->rx_bytes = src[gmib_rx_bytes_g];
+ s->tx_bytes = src[gmib_tx_bytes];
+ s->multicast = src[gmib_rx_multicast];
+
+ s->rx_crc_errors = src[gmib_rx_fcserr] + src[gmib_rx_frag];
+ s->rx_frame_errors = src[gmib_rx_alignerr];
+ s->rx_errors = s->rx_crc_errors + s->rx_frame_errors;
+ s->rx_dropped = src[gmib_rx_toolong] + s->rx_errors;
+
+ s->tx_fifo_errors = src[gmib_tx_underrun];
+ s->tx_aborted_errors = src[gmib_tx_abortcol];
+ s->tx_errors = s->tx_fifo_errors + s->tx_aborted_errors;
+ s->collisions = src[gmib_tx_collisions];
+
+ spin_unlock(&ppe_port->gmib_stats_lock);
+ } else {
+ s->multicast = ppe_port_xgmib_get(ppe_port, xgmib_rx_multicast_g);
+
+ s->rx_packets = s->multicast;
+ s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_unicast_g);
+ s->rx_packets += ppe_port_xgmib_get(ppe_port, xgmib_rx_broadcast_g);
+
+ s->tx_packets = ppe_port_xgmib_get(ppe_port, xgmib_tx_frames);
+ s->rx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_rx_bytes);
+ s->tx_bytes = ppe_port_xgmib_get(ppe_port, xgmib_tx_bytes);
+
+ s->rx_crc_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_crc_err);
+ s->rx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_fifo_overflow);
+
+ s->rx_length_errors = ppe_port_xgmib_get(ppe_port, xgmib_rx_len_err);
+ s->rx_errors = s->rx_crc_errors +
+ s->rx_fifo_errors + s->rx_length_errors;
+ s->rx_dropped = s->rx_errors;
+
+ s->tx_fifo_errors = ppe_port_xgmib_get(ppe_port, xgmib_tx_underflow_err);
+ s->tx_errors = s->tx_packets -
+ ppe_port_xgmib_get(ppe_port, xgmib_tx_frames_g);
+ }
+}
+
/* PPE port and MAC reset */
static int ppe_port_mac_reset(struct ppe_port *ppe_port)
{
@@ -261,6 +693,9 @@ static void ppe_port_mac_link_up(struct
int ret, port = ppe_port->port_id;
u32 reg, val;
+ /* Start GMIB statistics polling */
+ schedule_delayed_work(&ppe_port->gmib_read, 0);
+
if (mac_type == PPE_MAC_TYPE_GMAC)
ret = ppe_port_gmac_link_up(ppe_port,
speed, duplex, tx_pause, rx_pause);
@@ -306,6 +741,9 @@ static void ppe_port_mac_link_down(struc
int ret, port = ppe_port->port_id;
u32 reg;
+ /* Stop GMIB statistics polling */
+ cancel_delayed_work_sync(&ppe_port->gmib_read);
+
/* Disable PPE port TX */
reg = PPE_PORT_BRIDGE_CTRL_ADDR + PPE_PORT_BRIDGE_CTRL_INC * port;
ret = regmap_update_bits(ppe_dev->regmap, reg,
@@ -627,6 +1065,27 @@ static int ppe_port_mac_hw_init(struct p
return ret;
}
+/* PPE port MAC MIB work task initialization */
+static int ppe_port_mac_mib_work_init(struct ppe_port *ppe_port)
+{
+ struct ppe_device *ppe_dev = ppe_port->ppe_dev;
+ u64 *gstats;
+
+ gstats = devm_kzalloc(ppe_dev->dev,
+ sizeof(*gstats) * ARRAY_SIZE(gmib_info),
+ GFP_KERNEL);
+ if (!gstats)
+ return -ENOMEM;
+
+ ppe_port->gmib_stats = gstats;
+
+ spin_lock_init(&ppe_port->gmib_stats_lock);
+ INIT_DELAYED_WORK(&ppe_port->gmib_read,
+ ppe_port_gmib_stats_poll);
+
+ return 0;
+}
+
/**
* ppe_port_mac_init() - Initialization of PPE ports for the PPE device
* @ppe_dev: PPE device
@@ -693,6 +1152,12 @@ int ppe_port_mac_init(struct ppe_device
goto err_port_node;
}
+ ret = ppe_port_mac_mib_work_init(&ppe_ports->port[i]);
+ if (ret) {
+ dev_err(ppe_dev->dev, "Failed to initialize MAC MIB work\n");
+ goto err_port_node;
+ }
+
i++;
}
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_port.h
@@ -8,6 +8,8 @@
#include <linux/phylink.h>
+struct rtnl_link_stats64;
+
/**
* enum ppe_port_clk_rst_type - PPE port clock and reset ID type
* @PPE_PORT_CLK_RST_MAC: The clock and reset ID for port MAC
@@ -44,6 +46,9 @@ enum ppe_mac_type {
* @port_id: Port ID
* @clks: Port clocks
* @rstcs: Port resets
+ * @gmib_read: Delay work task for GMAC MIB statistics polling function
+ * @gmib_stats: GMAC MIB statistics array
+ * @gmib_stats_lock: Lock to protect GMAC MIB statistics
*/
struct ppe_port {
struct phylink *phylink;
@@ -56,6 +61,9 @@ struct ppe_port {
int port_id;
struct clk *clks[PPE_PORT_CLK_RST_MAX];
struct reset_control *rstcs[PPE_PORT_CLK_RST_MAX];
+ struct delayed_work gmib_read;
+ u64 *gmib_stats;
+ spinlock_t gmib_stats_lock; /* Protects GMIB stats */
};
/**
@@ -73,4 +81,9 @@ void ppe_port_mac_deinit(struct ppe_devi
int ppe_port_phylink_setup(struct ppe_port *ppe_port,
struct net_device *netdev);
void ppe_port_phylink_destroy(struct ppe_port *ppe_port);
+int ppe_port_get_sset_count(struct ppe_port *ppe_port, int sset);
+void ppe_port_get_strings(struct ppe_port *ppe_port, u32 stringset, u8 *data);
+void ppe_port_get_ethtool_stats(struct ppe_port *ppe_port, u64 *data);
+void ppe_port_get_stats64(struct ppe_port *ppe_port,
+ struct rtnl_link_stats64 *s);
#endif
--- a/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
+++ b/drivers/net/ethernet/qualcomm/ppe/ppe_regs.h
@@ -606,6 +606,48 @@
#define GMAC_MIB_CTRL_MASK \
(GMAC_MIB_RD_CLR | GMAC_MIB_RST | GMAC_MIB_EN)
+/* GMAC MIB counter registers */
+#define GMAC_RXBROAD_ADDR 0x40
+#define GMAC_RXPAUSE_ADDR 0x44
+#define GMAC_RXMULTI_ADDR 0x48
+#define GMAC_RXFCSERR_ADDR 0x4C
+#define GMAC_RXALIGNERR_ADDR 0x50
+#define GMAC_RXRUNT_ADDR 0x54
+#define GMAC_RXFRAG_ADDR 0x58
+#define GMAC_RXJUMBOFCSERR_ADDR 0x5C
+#define GMAC_RXJUMBOALIGNERR_ADDR 0x60
+#define GMAC_RXPKT64_ADDR 0x64
+#define GMAC_RXPKT65TO127_ADDR 0x68
+#define GMAC_RXPKT128TO255_ADDR 0x6C
+#define GMAC_RXPKT256TO511_ADDR 0x70
+#define GMAC_RXPKT512TO1023_ADDR 0x74
+#define GMAC_RXPKT1024TO1518_ADDR 0x78
+#define GMAC_RXPKT1519TOX_ADDR 0x7C
+#define GMAC_RXTOOLONG_ADDR 0x80
+#define GMAC_RXBYTE_G_ADDR 0x84
+#define GMAC_RXBYTE_B_ADDR 0x8C
+#define GMAC_RXUNI_ADDR 0x94
+#define GMAC_TXBROAD_ADDR 0xA0
+#define GMAC_TXPAUSE_ADDR 0xA4
+#define GMAC_TXMULTI_ADDR 0xA8
+#define GMAC_TXUNDERRUN_ADDR 0xAC
+#define GMAC_TXPKT64_ADDR 0xB0
+#define GMAC_TXPKT65TO127_ADDR 0xB4
+#define GMAC_TXPKT128TO255_ADDR 0xB8
+#define GMAC_TXPKT256TO511_ADDR 0xBC
+#define GMAC_TXPKT512TO1023_ADDR 0xC0
+#define GMAC_TXPKT1024TO1518_ADDR 0xC4
+#define GMAC_TXPKT1519TOX_ADDR 0xC8
+#define GMAC_TXBYTE_ADDR 0xCC
+#define GMAC_TXCOLLISIONS_ADDR 0xD4
+#define GMAC_TXABORTCOL_ADDR 0xD8
+#define GMAC_TXMULTICOL_ADDR 0xDC
+#define GMAC_TXSINGLECOL_ADDR 0xE0
+#define GMAC_TXEXCESSIVEDEFER_ADDR 0xE4
+#define GMAC_TXDEFER_ADDR 0xE8
+#define GMAC_TXLATECOL_ADDR 0xEC
+#define GMAC_TXUNI_ADDR 0xF0
+
/* XGMAC TX configuration register */
#define XGMAC_TX_CONFIG_ADDR 0x0
#define XGMAC_SPEED_M GENMASK(31, 29)
@@ -668,4 +710,53 @@
#define XGMAC_MCF BIT(3)
#define XGMAC_CNTRST BIT(0)
+/* XGMAC MIB counter registers */
+#define XGMAC_TXBYTE_GB_ADDR 0x814
+#define XGMAC_TXPKT_GB_ADDR 0x81C
+#define XGMAC_TXBROAD_G_ADDR 0x824
+#define XGMAC_TXMULTI_G_ADDR 0x82C
+#define XGMAC_TXPKT64_GB_ADDR 0x834
+#define XGMAC_TXPKT65TO127_GB_ADDR 0x83C
+#define XGMAC_TXPKT128TO255_GB_ADDR 0x844
+#define XGMAC_TXPKT256TO511_GB_ADDR 0x84C
+#define XGMAC_TXPKT512TO1023_GB_ADDR 0x854
+#define XGMAC_TXPKT1024TOMAX_GB_ADDR 0x85C
+#define XGMAC_TXUNI_GB_ADDR 0x864
+#define XGMAC_TXMULTI_GB_ADDR 0x86C
+#define XGMAC_TXBROAD_GB_ADDR 0x874
+#define XGMAC_TXUNDERFLOW_ERR_ADDR 0x87C
+#define XGMAC_TXBYTE_G_ADDR 0x884
+#define XGMAC_TXPKT_G_ADDR 0x88C
+#define XGMAC_TXPAUSE_ADDR 0x894
+#define XGMAC_TXVLAN_G_ADDR 0x89C
+#define XGMAC_TXLPI_USEC_ADDR 0x8A4
+#define XGMAC_TXLPI_TRAN_ADDR 0x8A8
+#define XGMAC_RXPKT_GB_ADDR 0x900
+#define XGMAC_RXBYTE_GB_ADDR 0x908
+#define XGMAC_RXBYTE_G_ADDR 0x910
+#define XGMAC_RXBROAD_G_ADDR 0x918
+#define XGMAC_RXMULTI_G_ADDR 0x920
+#define XGMAC_RXCRC_ERR_ADDR 0x928
+#define XGMAC_RXRUNT_ERR_ADDR 0x930
+#define XGMAC_RXJABBER_ERR_ADDR 0x934
+#define XGMAC_RXUNDERSIZE_G_ADDR 0x938
+#define XGMAC_RXOVERSIZE_G_ADDR 0x93C
+#define XGMAC_RXPKT64_GB_ADDR 0x940
+#define XGMAC_RXPKT65TO127_GB_ADDR 0x948
+#define XGMAC_RXPKT128TO255_GB_ADDR 0x950
+#define XGMAC_RXPKT256TO511_GB_ADDR 0x958
+#define XGMAC_RXPKT512TO1023_GB_ADDR 0x960
+#define XGMAC_RXPKT1024TOMAX_GB_ADDR 0x968
+#define XGMAC_RXUNI_G_ADDR 0x970
+#define XGMAC_RXLEN_ERR_ADDR 0x978
+#define XGMAC_RXOUTOFRANGE_ADDR 0x980
+#define XGMAC_RXPAUSE_ADDR 0x988
+#define XGMAC_RXFIFOOVERFLOW_ADDR 0x990
+#define XGMAC_RXVLAN_GB_ADDR 0x998
+#define XGMAC_RXWATCHDOG_ERR_ADDR 0x9A0
+#define XGMAC_RXLPI_USEC_ADDR 0x9A4
+#define XGMAC_RXLPI_TRAN_ADDR 0x9A8
+#define XGMAC_RXDISCARD_GB_ADDR 0x9AC
+#define XGMAC_RXDISCARDBYTE_GB_ADDR 0x9B4
+
#endif