1 // SPDX-License-Identifier: (GPL-2.0+ OR BSD-3-Clause)
2 /* Copyright 2017-2019 NXP */
4 #include <linux/net_tstamp.h>
5 #include <linux/module.h>
8 static const u32 enetc_si_regs[] = {
9 ENETC_SIMR, ENETC_SIPMAR0, ENETC_SIPMAR1, ENETC_SICBDRMR,
10 ENETC_SICBDRSR, ENETC_SICBDRBAR0, ENETC_SICBDRBAR1, ENETC_SICBDRPIR,
11 ENETC_SICBDRCIR, ENETC_SICBDRLENR, ENETC_SICAPR0, ENETC_SICAPR1,
15 static const u32 enetc_txbdr_regs[] = {
16 ENETC_TBMR, ENETC_TBSR, ENETC_TBBAR0, ENETC_TBBAR1,
17 ENETC_TBPIR, ENETC_TBCIR, ENETC_TBLENR, ENETC_TBIER
20 static const u32 enetc_rxbdr_regs[] = {
21 ENETC_RBMR, ENETC_RBSR, ENETC_RBBSR, ENETC_RBCIR, ENETC_RBBAR0,
22 ENETC_RBBAR1, ENETC_RBPIR, ENETC_RBLENR, ENETC_RBICIR0, ENETC_RBIER
25 static const u32 enetc_port_regs[] = {
26 ENETC_PMR, ENETC_PSR, ENETC_PSIPMR, ENETC_PSIPMAR0(0),
27 ENETC_PSIPMAR1(0), ENETC_PTXMBAR, ENETC_PCAPR0, ENETC_PCAPR1,
28 ENETC_PSICFGR0(0), ENETC_PTCMSDUR(0), ENETC_PM0_CMD_CFG,
29 ENETC_PM0_MAXFRM, ENETC_PM0_IF_MODE
32 static int enetc_get_reglen(struct net_device *ndev)
34 struct enetc_ndev_priv *priv = netdev_priv(ndev);
35 struct enetc_hw *hw = &priv->si->hw;
38 len = ARRAY_SIZE(enetc_si_regs);
39 len += ARRAY_SIZE(enetc_txbdr_regs) * priv->num_tx_rings;
40 len += ARRAY_SIZE(enetc_rxbdr_regs) * priv->num_rx_rings;
43 len += ARRAY_SIZE(enetc_port_regs);
45 len *= sizeof(u32) * 2; /* store 2 entries per reg: addr and value */
50 static void enetc_get_regs(struct net_device *ndev, struct ethtool_regs *regs,
53 struct enetc_ndev_priv *priv = netdev_priv(ndev);
54 struct enetc_hw *hw = &priv->si->hw;
55 u32 *buf = (u32 *)regbuf;
59 for (i = 0; i < ARRAY_SIZE(enetc_si_regs); i++) {
60 *buf++ = enetc_si_regs[i];
61 *buf++ = enetc_rd(hw, enetc_si_regs[i]);
64 for (i = 0; i < priv->num_tx_rings; i++) {
65 for (j = 0; j < ARRAY_SIZE(enetc_txbdr_regs); j++) {
66 addr = ENETC_BDR(TX, i, enetc_txbdr_regs[j]);
69 *buf++ = enetc_rd(hw, addr);
73 for (i = 0; i < priv->num_rx_rings; i++) {
74 for (j = 0; j < ARRAY_SIZE(enetc_rxbdr_regs); j++) {
75 addr = ENETC_BDR(RX, i, enetc_rxbdr_regs[j]);
78 *buf++ = enetc_rd(hw, addr);
85 for (i = 0; i < ARRAY_SIZE(enetc_port_regs); i++) {
86 addr = ENETC_PORT_BASE + enetc_port_regs[i];
88 *buf++ = enetc_rd(hw, addr);
92 static void enetc_get_ringparam(struct net_device *ndev,
93 struct ethtool_ringparam *ring)
95 struct enetc_ndev_priv *priv = netdev_priv(ndev);
97 ring->rx_pending = priv->rx_bd_count;
98 ring->tx_pending = priv->tx_bd_count;
100 /* do some h/w sanity checks for BDR length */
101 if (netif_running(ndev)) {
102 struct enetc_hw *hw = &priv->si->hw;
103 u32 val = enetc_rxbdr_rd(hw, 0, ENETC_RBLENR);
105 if (val != priv->rx_bd_count)
106 netif_err(priv, hw, ndev, "RxBDR[RBLENR] = %d!\n", val);
108 val = enetc_txbdr_rd(hw, 0, ENETC_TBLENR);
110 if (val != priv->tx_bd_count)
111 netif_err(priv, hw, ndev, "TxBDR[TBLENR] = %d!\n", val);
115 static const struct ethtool_ops enetc_pf_ethtool_ops = {
116 .get_regs_len = enetc_get_reglen,
117 .get_regs = enetc_get_regs,
118 .get_ringparam = enetc_get_ringparam,
119 .get_link_ksettings = phy_ethtool_get_link_ksettings,
120 .set_link_ksettings = phy_ethtool_set_link_ksettings,
123 static const struct ethtool_ops enetc_vf_ethtool_ops = {
124 .get_regs_len = enetc_get_reglen,
125 .get_regs = enetc_get_regs,
126 .get_ringparam = enetc_get_ringparam,
129 void enetc_set_ethtool_ops(struct net_device *ndev)
131 struct enetc_ndev_priv *priv = netdev_priv(ndev);
133 if (enetc_si_is_pf(priv->si))
134 ndev->ethtool_ops = &enetc_pf_ethtool_ops;
136 ndev->ethtool_ops = &enetc_vf_ethtool_ops;