0001
0002
0003
0004
0005 #include <linux/ethtool.h>
0006 #include <linux/phy.h>
0007
0008 #include "emac.h"
0009
0010 static const char * const emac_ethtool_stat_strings[] = {
0011 "rx_ok",
0012 "rx_bcast",
0013 "rx_mcast",
0014 "rx_pause",
0015 "rx_ctrl",
0016 "rx_fcs_err",
0017 "rx_len_err",
0018 "rx_byte_cnt",
0019 "rx_runt",
0020 "rx_frag",
0021 "rx_sz_64",
0022 "rx_sz_65_127",
0023 "rx_sz_128_255",
0024 "rx_sz_256_511",
0025 "rx_sz_512_1023",
0026 "rx_sz_1024_1518",
0027 "rx_sz_1519_max",
0028 "rx_sz_ov",
0029 "rx_rxf_ov",
0030 "rx_align_err",
0031 "rx_bcast_byte_cnt",
0032 "rx_mcast_byte_cnt",
0033 "rx_err_addr",
0034 "rx_crc_align",
0035 "rx_jabbers",
0036 "tx_ok",
0037 "tx_bcast",
0038 "tx_mcast",
0039 "tx_pause",
0040 "tx_exc_defer",
0041 "tx_ctrl",
0042 "tx_defer",
0043 "tx_byte_cnt",
0044 "tx_sz_64",
0045 "tx_sz_65_127",
0046 "tx_sz_128_255",
0047 "tx_sz_256_511",
0048 "tx_sz_512_1023",
0049 "tx_sz_1024_1518",
0050 "tx_sz_1519_max",
0051 "tx_1_col",
0052 "tx_2_col",
0053 "tx_late_col",
0054 "tx_abort_col",
0055 "tx_underrun",
0056 "tx_rd_eop",
0057 "tx_len_err",
0058 "tx_trunc",
0059 "tx_bcast_byte",
0060 "tx_mcast_byte",
0061 "tx_col",
0062 };
0063
0064 #define EMAC_STATS_LEN ARRAY_SIZE(emac_ethtool_stat_strings)
0065
0066 static u32 emac_get_msglevel(struct net_device *netdev)
0067 {
0068 struct emac_adapter *adpt = netdev_priv(netdev);
0069
0070 return adpt->msg_enable;
0071 }
0072
0073 static void emac_set_msglevel(struct net_device *netdev, u32 data)
0074 {
0075 struct emac_adapter *adpt = netdev_priv(netdev);
0076
0077 adpt->msg_enable = data;
0078 }
0079
0080 static int emac_get_sset_count(struct net_device *netdev, int sset)
0081 {
0082 switch (sset) {
0083 case ETH_SS_PRIV_FLAGS:
0084 return 1;
0085 case ETH_SS_STATS:
0086 return EMAC_STATS_LEN;
0087 default:
0088 return -EOPNOTSUPP;
0089 }
0090 }
0091
0092 static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data)
0093 {
0094 unsigned int i;
0095
0096 switch (stringset) {
0097 case ETH_SS_PRIV_FLAGS:
0098 strcpy(data, "single-pause-mode");
0099 break;
0100
0101 case ETH_SS_STATS:
0102 for (i = 0; i < EMAC_STATS_LEN; i++) {
0103 strscpy(data, emac_ethtool_stat_strings[i],
0104 ETH_GSTRING_LEN);
0105 data += ETH_GSTRING_LEN;
0106 }
0107 break;
0108 }
0109 }
0110
0111 static void emac_get_ethtool_stats(struct net_device *netdev,
0112 struct ethtool_stats *stats,
0113 u64 *data)
0114 {
0115 struct emac_adapter *adpt = netdev_priv(netdev);
0116
0117 spin_lock(&adpt->stats.lock);
0118
0119 emac_update_hw_stats(adpt);
0120 memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64));
0121
0122 spin_unlock(&adpt->stats.lock);
0123 }
0124
0125 static int emac_nway_reset(struct net_device *netdev)
0126 {
0127 struct phy_device *phydev = netdev->phydev;
0128
0129 if (!phydev)
0130 return -ENODEV;
0131
0132 return genphy_restart_aneg(phydev);
0133 }
0134
0135 static void emac_get_ringparam(struct net_device *netdev,
0136 struct ethtool_ringparam *ring,
0137 struct kernel_ethtool_ringparam *kernel_ring,
0138 struct netlink_ext_ack *extack)
0139 {
0140 struct emac_adapter *adpt = netdev_priv(netdev);
0141
0142 ring->rx_max_pending = EMAC_MAX_RX_DESCS;
0143 ring->tx_max_pending = EMAC_MAX_TX_DESCS;
0144 ring->rx_pending = adpt->rx_desc_cnt;
0145 ring->tx_pending = adpt->tx_desc_cnt;
0146 }
0147
0148 static int emac_set_ringparam(struct net_device *netdev,
0149 struct ethtool_ringparam *ring,
0150 struct kernel_ethtool_ringparam *kernel_ring,
0151 struct netlink_ext_ack *extack)
0152 {
0153 struct emac_adapter *adpt = netdev_priv(netdev);
0154
0155
0156
0157
0158 if (ring->rx_mini_pending || ring->rx_jumbo_pending)
0159 return -EINVAL;
0160
0161 adpt->tx_desc_cnt =
0162 clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS);
0163
0164 adpt->rx_desc_cnt =
0165 clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS);
0166
0167 if (netif_running(netdev))
0168 return emac_reinit_locked(adpt);
0169
0170 return 0;
0171 }
0172
0173 static void emac_get_pauseparam(struct net_device *netdev,
0174 struct ethtool_pauseparam *pause)
0175 {
0176 struct emac_adapter *adpt = netdev_priv(netdev);
0177
0178 pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE;
0179 pause->rx_pause = adpt->rx_flow_control ? 1 : 0;
0180 pause->tx_pause = adpt->tx_flow_control ? 1 : 0;
0181 }
0182
0183 static int emac_set_pauseparam(struct net_device *netdev,
0184 struct ethtool_pauseparam *pause)
0185 {
0186 struct emac_adapter *adpt = netdev_priv(netdev);
0187
0188 adpt->automatic = pause->autoneg == AUTONEG_ENABLE;
0189 adpt->rx_flow_control = pause->rx_pause != 0;
0190 adpt->tx_flow_control = pause->tx_pause != 0;
0191
0192 if (netif_running(netdev))
0193 return emac_reinit_locked(adpt);
0194
0195 return 0;
0196 }
0197
0198
0199 static const u16 emac_regs[] = {
0200 EMAC_DMA_MAS_CTRL,
0201 EMAC_MAC_CTRL,
0202 EMAC_TXQ_CTRL_0,
0203 EMAC_RXQ_CTRL_0,
0204 EMAC_DMA_CTRL,
0205 EMAC_INT_MASK,
0206 EMAC_AXI_MAST_CTRL,
0207 EMAC_CORE_HW_VERSION,
0208 EMAC_MISC_CTRL,
0209 };
0210
0211
0212 #define EMAC_REGS_VERSION 0
0213
0214 #define EMAC_MAX_REG_SIZE ARRAY_SIZE(emac_regs)
0215
0216 static void emac_get_regs(struct net_device *netdev,
0217 struct ethtool_regs *regs, void *buff)
0218 {
0219 struct emac_adapter *adpt = netdev_priv(netdev);
0220 u32 *val = buff;
0221 unsigned int i;
0222
0223 regs->version = EMAC_REGS_VERSION;
0224 regs->len = EMAC_MAX_REG_SIZE * sizeof(u32);
0225
0226 for (i = 0; i < EMAC_MAX_REG_SIZE; i++)
0227 val[i] = readl(adpt->base + emac_regs[i]);
0228 }
0229
0230 static int emac_get_regs_len(struct net_device *netdev)
0231 {
0232 return EMAC_MAX_REG_SIZE * sizeof(u32);
0233 }
0234
0235 #define EMAC_PRIV_ENABLE_SINGLE_PAUSE BIT(0)
0236
0237 static int emac_set_priv_flags(struct net_device *netdev, u32 flags)
0238 {
0239 struct emac_adapter *adpt = netdev_priv(netdev);
0240
0241 adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE);
0242
0243 if (netif_running(netdev))
0244 return emac_reinit_locked(adpt);
0245
0246 return 0;
0247 }
0248
0249 static u32 emac_get_priv_flags(struct net_device *netdev)
0250 {
0251 struct emac_adapter *adpt = netdev_priv(netdev);
0252
0253 return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0;
0254 }
0255
0256 static const struct ethtool_ops emac_ethtool_ops = {
0257 .get_link_ksettings = phy_ethtool_get_link_ksettings,
0258 .set_link_ksettings = phy_ethtool_set_link_ksettings,
0259
0260 .get_msglevel = emac_get_msglevel,
0261 .set_msglevel = emac_set_msglevel,
0262
0263 .get_sset_count = emac_get_sset_count,
0264 .get_strings = emac_get_strings,
0265 .get_ethtool_stats = emac_get_ethtool_stats,
0266
0267 .get_ringparam = emac_get_ringparam,
0268 .set_ringparam = emac_set_ringparam,
0269
0270 .get_pauseparam = emac_get_pauseparam,
0271 .set_pauseparam = emac_set_pauseparam,
0272
0273 .nway_reset = emac_nway_reset,
0274
0275 .get_link = ethtool_op_get_link,
0276
0277 .get_regs_len = emac_get_regs_len,
0278 .get_regs = emac_get_regs,
0279
0280 .set_priv_flags = emac_set_priv_flags,
0281 .get_priv_flags = emac_get_priv_flags,
0282 };
0283
0284 void emac_set_ethtool_ops(struct net_device *netdev)
0285 {
0286 netdev->ethtool_ops = &emac_ethtool_ops;
0287 }