1 // SPDX-License-Identifier: GPL-2.0-only 2 /* Copyright (c) 2016, The Linux Foundation. All rights reserved. 3 */ 4 5 #include <linux/ethtool.h> 6 #include <linux/phy.h> 7 8 #include "emac.h" 9 10 static const char * const emac_ethtool_stat_strings[] = { 11 "rx_ok", 12 "rx_bcast", 13 "rx_mcast", 14 "rx_pause", 15 "rx_ctrl", 16 "rx_fcs_err", 17 "rx_len_err", 18 "rx_byte_cnt", 19 "rx_runt", 20 "rx_frag", 21 "rx_sz_64", 22 "rx_sz_65_127", 23 "rx_sz_128_255", 24 "rx_sz_256_511", 25 "rx_sz_512_1023", 26 "rx_sz_1024_1518", 27 "rx_sz_1519_max", 28 "rx_sz_ov", 29 "rx_rxf_ov", 30 "rx_align_err", 31 "rx_bcast_byte_cnt", 32 "rx_mcast_byte_cnt", 33 "rx_err_addr", 34 "rx_crc_align", 35 "rx_jabbers", 36 "tx_ok", 37 "tx_bcast", 38 "tx_mcast", 39 "tx_pause", 40 "tx_exc_defer", 41 "tx_ctrl", 42 "tx_defer", 43 "tx_byte_cnt", 44 "tx_sz_64", 45 "tx_sz_65_127", 46 "tx_sz_128_255", 47 "tx_sz_256_511", 48 "tx_sz_512_1023", 49 "tx_sz_1024_1518", 50 "tx_sz_1519_max", 51 "tx_1_col", 52 "tx_2_col", 53 "tx_late_col", 54 "tx_abort_col", 55 "tx_underrun", 56 "tx_rd_eop", 57 "tx_len_err", 58 "tx_trunc", 59 "tx_bcast_byte", 60 "tx_mcast_byte", 61 "tx_col", 62 }; 63 64 #define EMAC_STATS_LEN ARRAY_SIZE(emac_ethtool_stat_strings) 65 66 static u32 emac_get_msglevel(struct net_device *netdev) 67 { 68 struct emac_adapter *adpt = netdev_priv(netdev); 69 70 return adpt->msg_enable; 71 } 72 73 static void emac_set_msglevel(struct net_device *netdev, u32 data) 74 { 75 struct emac_adapter *adpt = netdev_priv(netdev); 76 77 adpt->msg_enable = data; 78 } 79 80 static int emac_get_sset_count(struct net_device *netdev, int sset) 81 { 82 switch (sset) { 83 case ETH_SS_PRIV_FLAGS: 84 return 1; 85 case ETH_SS_STATS: 86 return EMAC_STATS_LEN; 87 default: 88 return -EOPNOTSUPP; 89 } 90 } 91 92 static void emac_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 93 { 94 unsigned int i; 95 96 switch (stringset) { 97 case ETH_SS_PRIV_FLAGS: 98 strcpy(data, "single-pause-mode"); 99 break; 100 101 case ETH_SS_STATS: 102 for (i = 0; i < EMAC_STATS_LEN; i++) { 103 strscpy(data, emac_ethtool_stat_strings[i], 104 ETH_GSTRING_LEN); 105 data += ETH_GSTRING_LEN; 106 } 107 break; 108 } 109 } 110 111 static void emac_get_ethtool_stats(struct net_device *netdev, 112 struct ethtool_stats *stats, 113 u64 *data) 114 { 115 struct emac_adapter *adpt = netdev_priv(netdev); 116 117 spin_lock(&adpt->stats.lock); 118 119 emac_update_hw_stats(adpt); 120 memcpy(data, &adpt->stats, EMAC_STATS_LEN * sizeof(u64)); 121 122 spin_unlock(&adpt->stats.lock); 123 } 124 125 static int emac_nway_reset(struct net_device *netdev) 126 { 127 struct phy_device *phydev = netdev->phydev; 128 129 if (!phydev) 130 return -ENODEV; 131 132 return genphy_restart_aneg(phydev); 133 } 134 135 static void emac_get_ringparam(struct net_device *netdev, 136 struct ethtool_ringparam *ring) 137 { 138 struct emac_adapter *adpt = netdev_priv(netdev); 139 140 ring->rx_max_pending = EMAC_MAX_RX_DESCS; 141 ring->tx_max_pending = EMAC_MAX_TX_DESCS; 142 ring->rx_pending = adpt->rx_desc_cnt; 143 ring->tx_pending = adpt->tx_desc_cnt; 144 } 145 146 static int emac_set_ringparam(struct net_device *netdev, 147 struct ethtool_ringparam *ring) 148 { 149 struct emac_adapter *adpt = netdev_priv(netdev); 150 151 /* We don't have separate queues/rings for small/large frames, so 152 * reject any attempt to specify those values separately. 153 */ 154 if (ring->rx_mini_pending || ring->rx_jumbo_pending) 155 return -EINVAL; 156 157 adpt->tx_desc_cnt = 158 clamp_val(ring->tx_pending, EMAC_MIN_TX_DESCS, EMAC_MAX_TX_DESCS); 159 160 adpt->rx_desc_cnt = 161 clamp_val(ring->rx_pending, EMAC_MIN_RX_DESCS, EMAC_MAX_RX_DESCS); 162 163 if (netif_running(netdev)) 164 return emac_reinit_locked(adpt); 165 166 return 0; 167 } 168 169 static void emac_get_pauseparam(struct net_device *netdev, 170 struct ethtool_pauseparam *pause) 171 { 172 struct emac_adapter *adpt = netdev_priv(netdev); 173 174 pause->autoneg = adpt->automatic ? AUTONEG_ENABLE : AUTONEG_DISABLE; 175 pause->rx_pause = adpt->rx_flow_control ? 1 : 0; 176 pause->tx_pause = adpt->tx_flow_control ? 1 : 0; 177 } 178 179 static int emac_set_pauseparam(struct net_device *netdev, 180 struct ethtool_pauseparam *pause) 181 { 182 struct emac_adapter *adpt = netdev_priv(netdev); 183 184 adpt->automatic = pause->autoneg == AUTONEG_ENABLE; 185 adpt->rx_flow_control = pause->rx_pause != 0; 186 adpt->tx_flow_control = pause->tx_pause != 0; 187 188 if (netif_running(netdev)) 189 return emac_reinit_locked(adpt); 190 191 return 0; 192 } 193 194 /* Selected registers that might want to track during runtime. */ 195 static const u16 emac_regs[] = { 196 EMAC_DMA_MAS_CTRL, 197 EMAC_MAC_CTRL, 198 EMAC_TXQ_CTRL_0, 199 EMAC_RXQ_CTRL_0, 200 EMAC_DMA_CTRL, 201 EMAC_INT_MASK, 202 EMAC_AXI_MAST_CTRL, 203 EMAC_CORE_HW_VERSION, 204 EMAC_MISC_CTRL, 205 }; 206 207 /* Every time emac_regs[] above is changed, increase this version number. */ 208 #define EMAC_REGS_VERSION 0 209 210 #define EMAC_MAX_REG_SIZE ARRAY_SIZE(emac_regs) 211 212 static void emac_get_regs(struct net_device *netdev, 213 struct ethtool_regs *regs, void *buff) 214 { 215 struct emac_adapter *adpt = netdev_priv(netdev); 216 u32 *val = buff; 217 unsigned int i; 218 219 regs->version = EMAC_REGS_VERSION; 220 regs->len = EMAC_MAX_REG_SIZE * sizeof(u32); 221 222 for (i = 0; i < EMAC_MAX_REG_SIZE; i++) 223 val[i] = readl(adpt->base + emac_regs[i]); 224 } 225 226 static int emac_get_regs_len(struct net_device *netdev) 227 { 228 return EMAC_MAX_REG_SIZE * sizeof(u32); 229 } 230 231 #define EMAC_PRIV_ENABLE_SINGLE_PAUSE BIT(0) 232 233 static int emac_set_priv_flags(struct net_device *netdev, u32 flags) 234 { 235 struct emac_adapter *adpt = netdev_priv(netdev); 236 237 adpt->single_pause_mode = !!(flags & EMAC_PRIV_ENABLE_SINGLE_PAUSE); 238 239 if (netif_running(netdev)) 240 return emac_reinit_locked(adpt); 241 242 return 0; 243 } 244 245 static u32 emac_get_priv_flags(struct net_device *netdev) 246 { 247 struct emac_adapter *adpt = netdev_priv(netdev); 248 249 return adpt->single_pause_mode ? EMAC_PRIV_ENABLE_SINGLE_PAUSE : 0; 250 } 251 252 static const struct ethtool_ops emac_ethtool_ops = { 253 .get_link_ksettings = phy_ethtool_get_link_ksettings, 254 .set_link_ksettings = phy_ethtool_set_link_ksettings, 255 256 .get_msglevel = emac_get_msglevel, 257 .set_msglevel = emac_set_msglevel, 258 259 .get_sset_count = emac_get_sset_count, 260 .get_strings = emac_get_strings, 261 .get_ethtool_stats = emac_get_ethtool_stats, 262 263 .get_ringparam = emac_get_ringparam, 264 .set_ringparam = emac_set_ringparam, 265 266 .get_pauseparam = emac_get_pauseparam, 267 .set_pauseparam = emac_set_pauseparam, 268 269 .nway_reset = emac_nway_reset, 270 271 .get_link = ethtool_op_get_link, 272 273 .get_regs_len = emac_get_regs_len, 274 .get_regs = emac_get_regs, 275 276 .set_priv_flags = emac_set_priv_flags, 277 .get_priv_flags = emac_get_priv_flags, 278 }; 279 280 void emac_set_ethtool_ops(struct net_device *netdev) 281 { 282 netdev->ethtool_ops = &emac_ethtool_ops; 283 } 284