ixgb_ethtool.c (19572B)
1// SPDX-License-Identifier: GPL-2.0 2/* Copyright(c) 1999 - 2008 Intel Corporation. */ 3 4/* ethtool support for ixgb */ 5 6#include "ixgb.h" 7 8#include <linux/uaccess.h> 9 10#define IXGB_ALL_RAR_ENTRIES 16 11 12enum {NETDEV_STATS, IXGB_STATS}; 13 14struct ixgb_stats { 15 char stat_string[ETH_GSTRING_LEN]; 16 int type; 17 int sizeof_stat; 18 int stat_offset; 19}; 20 21#define IXGB_STAT(m) IXGB_STATS, \ 22 sizeof_field(struct ixgb_adapter, m), \ 23 offsetof(struct ixgb_adapter, m) 24#define IXGB_NETDEV_STAT(m) NETDEV_STATS, \ 25 sizeof_field(struct net_device, m), \ 26 offsetof(struct net_device, m) 27 28static struct ixgb_stats ixgb_gstrings_stats[] = { 29 {"rx_packets", IXGB_NETDEV_STAT(stats.rx_packets)}, 30 {"tx_packets", IXGB_NETDEV_STAT(stats.tx_packets)}, 31 {"rx_bytes", IXGB_NETDEV_STAT(stats.rx_bytes)}, 32 {"tx_bytes", IXGB_NETDEV_STAT(stats.tx_bytes)}, 33 {"rx_errors", IXGB_NETDEV_STAT(stats.rx_errors)}, 34 {"tx_errors", IXGB_NETDEV_STAT(stats.tx_errors)}, 35 {"rx_dropped", IXGB_NETDEV_STAT(stats.rx_dropped)}, 36 {"tx_dropped", IXGB_NETDEV_STAT(stats.tx_dropped)}, 37 {"multicast", IXGB_NETDEV_STAT(stats.multicast)}, 38 {"collisions", IXGB_NETDEV_STAT(stats.collisions)}, 39 40/* { "rx_length_errors", IXGB_NETDEV_STAT(stats.rx_length_errors) }, */ 41 {"rx_over_errors", IXGB_NETDEV_STAT(stats.rx_over_errors)}, 42 {"rx_crc_errors", IXGB_NETDEV_STAT(stats.rx_crc_errors)}, 43 {"rx_frame_errors", IXGB_NETDEV_STAT(stats.rx_frame_errors)}, 44 {"rx_no_buffer_count", IXGB_STAT(stats.rnbc)}, 45 {"rx_fifo_errors", IXGB_NETDEV_STAT(stats.rx_fifo_errors)}, 46 {"rx_missed_errors", IXGB_NETDEV_STAT(stats.rx_missed_errors)}, 47 {"tx_aborted_errors", IXGB_NETDEV_STAT(stats.tx_aborted_errors)}, 48 {"tx_carrier_errors", IXGB_NETDEV_STAT(stats.tx_carrier_errors)}, 49 {"tx_fifo_errors", IXGB_NETDEV_STAT(stats.tx_fifo_errors)}, 50 {"tx_heartbeat_errors", IXGB_NETDEV_STAT(stats.tx_heartbeat_errors)}, 51 {"tx_window_errors", IXGB_NETDEV_STAT(stats.tx_window_errors)}, 52 {"tx_deferred_ok", IXGB_STAT(stats.dc)}, 53 {"tx_timeout_count", IXGB_STAT(tx_timeout_count) }, 54 {"tx_restart_queue", IXGB_STAT(restart_queue) }, 55 {"rx_long_length_errors", IXGB_STAT(stats.roc)}, 56 {"rx_short_length_errors", IXGB_STAT(stats.ruc)}, 57 {"tx_tcp_seg_good", IXGB_STAT(stats.tsctc)}, 58 {"tx_tcp_seg_failed", IXGB_STAT(stats.tsctfc)}, 59 {"rx_flow_control_xon", IXGB_STAT(stats.xonrxc)}, 60 {"rx_flow_control_xoff", IXGB_STAT(stats.xoffrxc)}, 61 {"tx_flow_control_xon", IXGB_STAT(stats.xontxc)}, 62 {"tx_flow_control_xoff", IXGB_STAT(stats.xofftxc)}, 63 {"rx_csum_offload_good", IXGB_STAT(hw_csum_rx_good)}, 64 {"rx_csum_offload_errors", IXGB_STAT(hw_csum_rx_error)}, 65 {"tx_csum_offload_good", IXGB_STAT(hw_csum_tx_good)}, 66 {"tx_csum_offload_errors", IXGB_STAT(hw_csum_tx_error)} 67}; 68 69#define IXGB_STATS_LEN ARRAY_SIZE(ixgb_gstrings_stats) 70 71static int 72ixgb_get_link_ksettings(struct net_device *netdev, 73 struct ethtool_link_ksettings *cmd) 74{ 75 struct ixgb_adapter *adapter = netdev_priv(netdev); 76 77 ethtool_link_ksettings_zero_link_mode(cmd, supported); 78 ethtool_link_ksettings_add_link_mode(cmd, supported, 10000baseT_Full); 79 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 80 81 ethtool_link_ksettings_zero_link_mode(cmd, advertising); 82 ethtool_link_ksettings_add_link_mode(cmd, advertising, 10000baseT_Full); 83 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); 84 85 cmd->base.port = PORT_FIBRE; 86 87 if (netif_carrier_ok(adapter->netdev)) { 88 cmd->base.speed = SPEED_10000; 89 cmd->base.duplex = DUPLEX_FULL; 90 } else { 91 cmd->base.speed = SPEED_UNKNOWN; 92 cmd->base.duplex = DUPLEX_UNKNOWN; 93 } 94 95 cmd->base.autoneg = AUTONEG_DISABLE; 96 return 0; 97} 98 99void ixgb_set_speed_duplex(struct net_device *netdev) 100{ 101 struct ixgb_adapter *adapter = netdev_priv(netdev); 102 /* be optimistic about our link, since we were up before */ 103 adapter->link_speed = 10000; 104 adapter->link_duplex = FULL_DUPLEX; 105 netif_carrier_on(netdev); 106 netif_wake_queue(netdev); 107} 108 109static int 110ixgb_set_link_ksettings(struct net_device *netdev, 111 const struct ethtool_link_ksettings *cmd) 112{ 113 struct ixgb_adapter *adapter = netdev_priv(netdev); 114 u32 speed = cmd->base.speed; 115 116 if (cmd->base.autoneg == AUTONEG_ENABLE || 117 (speed + cmd->base.duplex != SPEED_10000 + DUPLEX_FULL)) 118 return -EINVAL; 119 120 if (netif_running(adapter->netdev)) { 121 ixgb_down(adapter, true); 122 ixgb_reset(adapter); 123 ixgb_up(adapter); 124 ixgb_set_speed_duplex(netdev); 125 } else 126 ixgb_reset(adapter); 127 128 return 0; 129} 130 131static void 132ixgb_get_pauseparam(struct net_device *netdev, 133 struct ethtool_pauseparam *pause) 134{ 135 struct ixgb_adapter *adapter = netdev_priv(netdev); 136 struct ixgb_hw *hw = &adapter->hw; 137 138 pause->autoneg = AUTONEG_DISABLE; 139 140 if (hw->fc.type == ixgb_fc_rx_pause) 141 pause->rx_pause = 1; 142 else if (hw->fc.type == ixgb_fc_tx_pause) 143 pause->tx_pause = 1; 144 else if (hw->fc.type == ixgb_fc_full) { 145 pause->rx_pause = 1; 146 pause->tx_pause = 1; 147 } 148} 149 150static int 151ixgb_set_pauseparam(struct net_device *netdev, 152 struct ethtool_pauseparam *pause) 153{ 154 struct ixgb_adapter *adapter = netdev_priv(netdev); 155 struct ixgb_hw *hw = &adapter->hw; 156 157 if (pause->autoneg == AUTONEG_ENABLE) 158 return -EINVAL; 159 160 if (pause->rx_pause && pause->tx_pause) 161 hw->fc.type = ixgb_fc_full; 162 else if (pause->rx_pause && !pause->tx_pause) 163 hw->fc.type = ixgb_fc_rx_pause; 164 else if (!pause->rx_pause && pause->tx_pause) 165 hw->fc.type = ixgb_fc_tx_pause; 166 else if (!pause->rx_pause && !pause->tx_pause) 167 hw->fc.type = ixgb_fc_none; 168 169 if (netif_running(adapter->netdev)) { 170 ixgb_down(adapter, true); 171 ixgb_up(adapter); 172 ixgb_set_speed_duplex(netdev); 173 } else 174 ixgb_reset(adapter); 175 176 return 0; 177} 178 179static u32 180ixgb_get_msglevel(struct net_device *netdev) 181{ 182 struct ixgb_adapter *adapter = netdev_priv(netdev); 183 return adapter->msg_enable; 184} 185 186static void 187ixgb_set_msglevel(struct net_device *netdev, u32 data) 188{ 189 struct ixgb_adapter *adapter = netdev_priv(netdev); 190 adapter->msg_enable = data; 191} 192#define IXGB_GET_STAT(_A_, _R_) _A_->stats._R_ 193 194static int 195ixgb_get_regs_len(struct net_device *netdev) 196{ 197#define IXGB_REG_DUMP_LEN 136*sizeof(u32) 198 return IXGB_REG_DUMP_LEN; 199} 200 201static void 202ixgb_get_regs(struct net_device *netdev, 203 struct ethtool_regs *regs, void *p) 204{ 205 struct ixgb_adapter *adapter = netdev_priv(netdev); 206 struct ixgb_hw *hw = &adapter->hw; 207 u32 *reg = p; 208 u32 *reg_start = reg; 209 u8 i; 210 211 /* the 1 (one) below indicates an attempt at versioning, if the 212 * interface in ethtool or the driver changes, this 1 should be 213 * incremented */ 214 regs->version = (1<<24) | hw->revision_id << 16 | hw->device_id; 215 216 /* General Registers */ 217 *reg++ = IXGB_READ_REG(hw, CTRL0); /* 0 */ 218 *reg++ = IXGB_READ_REG(hw, CTRL1); /* 1 */ 219 *reg++ = IXGB_READ_REG(hw, STATUS); /* 2 */ 220 *reg++ = IXGB_READ_REG(hw, EECD); /* 3 */ 221 *reg++ = IXGB_READ_REG(hw, MFS); /* 4 */ 222 223 /* Interrupt */ 224 *reg++ = IXGB_READ_REG(hw, ICR); /* 5 */ 225 *reg++ = IXGB_READ_REG(hw, ICS); /* 6 */ 226 *reg++ = IXGB_READ_REG(hw, IMS); /* 7 */ 227 *reg++ = IXGB_READ_REG(hw, IMC); /* 8 */ 228 229 /* Receive */ 230 *reg++ = IXGB_READ_REG(hw, RCTL); /* 9 */ 231 *reg++ = IXGB_READ_REG(hw, FCRTL); /* 10 */ 232 *reg++ = IXGB_READ_REG(hw, FCRTH); /* 11 */ 233 *reg++ = IXGB_READ_REG(hw, RDBAL); /* 12 */ 234 *reg++ = IXGB_READ_REG(hw, RDBAH); /* 13 */ 235 *reg++ = IXGB_READ_REG(hw, RDLEN); /* 14 */ 236 *reg++ = IXGB_READ_REG(hw, RDH); /* 15 */ 237 *reg++ = IXGB_READ_REG(hw, RDT); /* 16 */ 238 *reg++ = IXGB_READ_REG(hw, RDTR); /* 17 */ 239 *reg++ = IXGB_READ_REG(hw, RXDCTL); /* 18 */ 240 *reg++ = IXGB_READ_REG(hw, RAIDC); /* 19 */ 241 *reg++ = IXGB_READ_REG(hw, RXCSUM); /* 20 */ 242 243 /* there are 16 RAR entries in hardware, we only use 3 */ 244 for (i = 0; i < IXGB_ALL_RAR_ENTRIES; i++) { 245 *reg++ = IXGB_READ_REG_ARRAY(hw, RAL, (i << 1)); /*21,...,51 */ 246 *reg++ = IXGB_READ_REG_ARRAY(hw, RAH, (i << 1)); /*22,...,52 */ 247 } 248 249 /* Transmit */ 250 *reg++ = IXGB_READ_REG(hw, TCTL); /* 53 */ 251 *reg++ = IXGB_READ_REG(hw, TDBAL); /* 54 */ 252 *reg++ = IXGB_READ_REG(hw, TDBAH); /* 55 */ 253 *reg++ = IXGB_READ_REG(hw, TDLEN); /* 56 */ 254 *reg++ = IXGB_READ_REG(hw, TDH); /* 57 */ 255 *reg++ = IXGB_READ_REG(hw, TDT); /* 58 */ 256 *reg++ = IXGB_READ_REG(hw, TIDV); /* 59 */ 257 *reg++ = IXGB_READ_REG(hw, TXDCTL); /* 60 */ 258 *reg++ = IXGB_READ_REG(hw, TSPMT); /* 61 */ 259 *reg++ = IXGB_READ_REG(hw, PAP); /* 62 */ 260 261 /* Physical */ 262 *reg++ = IXGB_READ_REG(hw, PCSC1); /* 63 */ 263 *reg++ = IXGB_READ_REG(hw, PCSC2); /* 64 */ 264 *reg++ = IXGB_READ_REG(hw, PCSS1); /* 65 */ 265 *reg++ = IXGB_READ_REG(hw, PCSS2); /* 66 */ 266 *reg++ = IXGB_READ_REG(hw, XPCSS); /* 67 */ 267 *reg++ = IXGB_READ_REG(hw, UCCR); /* 68 */ 268 *reg++ = IXGB_READ_REG(hw, XPCSTC); /* 69 */ 269 *reg++ = IXGB_READ_REG(hw, MACA); /* 70 */ 270 *reg++ = IXGB_READ_REG(hw, APAE); /* 71 */ 271 *reg++ = IXGB_READ_REG(hw, ARD); /* 72 */ 272 *reg++ = IXGB_READ_REG(hw, AIS); /* 73 */ 273 *reg++ = IXGB_READ_REG(hw, MSCA); /* 74 */ 274 *reg++ = IXGB_READ_REG(hw, MSRWD); /* 75 */ 275 276 /* Statistics */ 277 *reg++ = IXGB_GET_STAT(adapter, tprl); /* 76 */ 278 *reg++ = IXGB_GET_STAT(adapter, tprh); /* 77 */ 279 *reg++ = IXGB_GET_STAT(adapter, gprcl); /* 78 */ 280 *reg++ = IXGB_GET_STAT(adapter, gprch); /* 79 */ 281 *reg++ = IXGB_GET_STAT(adapter, bprcl); /* 80 */ 282 *reg++ = IXGB_GET_STAT(adapter, bprch); /* 81 */ 283 *reg++ = IXGB_GET_STAT(adapter, mprcl); /* 82 */ 284 *reg++ = IXGB_GET_STAT(adapter, mprch); /* 83 */ 285 *reg++ = IXGB_GET_STAT(adapter, uprcl); /* 84 */ 286 *reg++ = IXGB_GET_STAT(adapter, uprch); /* 85 */ 287 *reg++ = IXGB_GET_STAT(adapter, vprcl); /* 86 */ 288 *reg++ = IXGB_GET_STAT(adapter, vprch); /* 87 */ 289 *reg++ = IXGB_GET_STAT(adapter, jprcl); /* 88 */ 290 *reg++ = IXGB_GET_STAT(adapter, jprch); /* 89 */ 291 *reg++ = IXGB_GET_STAT(adapter, gorcl); /* 90 */ 292 *reg++ = IXGB_GET_STAT(adapter, gorch); /* 91 */ 293 *reg++ = IXGB_GET_STAT(adapter, torl); /* 92 */ 294 *reg++ = IXGB_GET_STAT(adapter, torh); /* 93 */ 295 *reg++ = IXGB_GET_STAT(adapter, rnbc); /* 94 */ 296 *reg++ = IXGB_GET_STAT(adapter, ruc); /* 95 */ 297 *reg++ = IXGB_GET_STAT(adapter, roc); /* 96 */ 298 *reg++ = IXGB_GET_STAT(adapter, rlec); /* 97 */ 299 *reg++ = IXGB_GET_STAT(adapter, crcerrs); /* 98 */ 300 *reg++ = IXGB_GET_STAT(adapter, icbc); /* 99 */ 301 *reg++ = IXGB_GET_STAT(adapter, ecbc); /* 100 */ 302 *reg++ = IXGB_GET_STAT(adapter, mpc); /* 101 */ 303 *reg++ = IXGB_GET_STAT(adapter, tptl); /* 102 */ 304 *reg++ = IXGB_GET_STAT(adapter, tpth); /* 103 */ 305 *reg++ = IXGB_GET_STAT(adapter, gptcl); /* 104 */ 306 *reg++ = IXGB_GET_STAT(adapter, gptch); /* 105 */ 307 *reg++ = IXGB_GET_STAT(adapter, bptcl); /* 106 */ 308 *reg++ = IXGB_GET_STAT(adapter, bptch); /* 107 */ 309 *reg++ = IXGB_GET_STAT(adapter, mptcl); /* 108 */ 310 *reg++ = IXGB_GET_STAT(adapter, mptch); /* 109 */ 311 *reg++ = IXGB_GET_STAT(adapter, uptcl); /* 110 */ 312 *reg++ = IXGB_GET_STAT(adapter, uptch); /* 111 */ 313 *reg++ = IXGB_GET_STAT(adapter, vptcl); /* 112 */ 314 *reg++ = IXGB_GET_STAT(adapter, vptch); /* 113 */ 315 *reg++ = IXGB_GET_STAT(adapter, jptcl); /* 114 */ 316 *reg++ = IXGB_GET_STAT(adapter, jptch); /* 115 */ 317 *reg++ = IXGB_GET_STAT(adapter, gotcl); /* 116 */ 318 *reg++ = IXGB_GET_STAT(adapter, gotch); /* 117 */ 319 *reg++ = IXGB_GET_STAT(adapter, totl); /* 118 */ 320 *reg++ = IXGB_GET_STAT(adapter, toth); /* 119 */ 321 *reg++ = IXGB_GET_STAT(adapter, dc); /* 120 */ 322 *reg++ = IXGB_GET_STAT(adapter, plt64c); /* 121 */ 323 *reg++ = IXGB_GET_STAT(adapter, tsctc); /* 122 */ 324 *reg++ = IXGB_GET_STAT(adapter, tsctfc); /* 123 */ 325 *reg++ = IXGB_GET_STAT(adapter, ibic); /* 124 */ 326 *reg++ = IXGB_GET_STAT(adapter, rfc); /* 125 */ 327 *reg++ = IXGB_GET_STAT(adapter, lfc); /* 126 */ 328 *reg++ = IXGB_GET_STAT(adapter, pfrc); /* 127 */ 329 *reg++ = IXGB_GET_STAT(adapter, pftc); /* 128 */ 330 *reg++ = IXGB_GET_STAT(adapter, mcfrc); /* 129 */ 331 *reg++ = IXGB_GET_STAT(adapter, mcftc); /* 130 */ 332 *reg++ = IXGB_GET_STAT(adapter, xonrxc); /* 131 */ 333 *reg++ = IXGB_GET_STAT(adapter, xontxc); /* 132 */ 334 *reg++ = IXGB_GET_STAT(adapter, xoffrxc); /* 133 */ 335 *reg++ = IXGB_GET_STAT(adapter, xofftxc); /* 134 */ 336 *reg++ = IXGB_GET_STAT(adapter, rjc); /* 135 */ 337 338 regs->len = (reg - reg_start) * sizeof(u32); 339} 340 341static int 342ixgb_get_eeprom_len(struct net_device *netdev) 343{ 344 /* return size in bytes */ 345 return IXGB_EEPROM_SIZE << 1; 346} 347 348static int 349ixgb_get_eeprom(struct net_device *netdev, 350 struct ethtool_eeprom *eeprom, u8 *bytes) 351{ 352 struct ixgb_adapter *adapter = netdev_priv(netdev); 353 struct ixgb_hw *hw = &adapter->hw; 354 __le16 *eeprom_buff; 355 int i, max_len, first_word, last_word; 356 int ret_val = 0; 357 358 if (eeprom->len == 0) { 359 ret_val = -EINVAL; 360 goto geeprom_error; 361 } 362 363 eeprom->magic = hw->vendor_id | (hw->device_id << 16); 364 365 max_len = ixgb_get_eeprom_len(netdev); 366 367 if (eeprom->offset > eeprom->offset + eeprom->len) { 368 ret_val = -EINVAL; 369 goto geeprom_error; 370 } 371 372 if ((eeprom->offset + eeprom->len) > max_len) 373 eeprom->len = (max_len - eeprom->offset); 374 375 first_word = eeprom->offset >> 1; 376 last_word = (eeprom->offset + eeprom->len - 1) >> 1; 377 378 eeprom_buff = kmalloc_array(last_word - first_word + 1, 379 sizeof(__le16), 380 GFP_KERNEL); 381 if (!eeprom_buff) 382 return -ENOMEM; 383 384 /* note the eeprom was good because the driver loaded */ 385 for (i = 0; i <= (last_word - first_word); i++) 386 eeprom_buff[i] = ixgb_get_eeprom_word(hw, (first_word + i)); 387 388 memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); 389 kfree(eeprom_buff); 390 391geeprom_error: 392 return ret_val; 393} 394 395static int 396ixgb_set_eeprom(struct net_device *netdev, 397 struct ethtool_eeprom *eeprom, u8 *bytes) 398{ 399 struct ixgb_adapter *adapter = netdev_priv(netdev); 400 struct ixgb_hw *hw = &adapter->hw; 401 u16 *eeprom_buff; 402 void *ptr; 403 int max_len, first_word, last_word; 404 u16 i; 405 406 if (eeprom->len == 0) 407 return -EINVAL; 408 409 if (eeprom->magic != (hw->vendor_id | (hw->device_id << 16))) 410 return -EFAULT; 411 412 max_len = ixgb_get_eeprom_len(netdev); 413 414 if (eeprom->offset > eeprom->offset + eeprom->len) 415 return -EINVAL; 416 417 if ((eeprom->offset + eeprom->len) > max_len) 418 eeprom->len = (max_len - eeprom->offset); 419 420 first_word = eeprom->offset >> 1; 421 last_word = (eeprom->offset + eeprom->len - 1) >> 1; 422 eeprom_buff = kmalloc(max_len, GFP_KERNEL); 423 if (!eeprom_buff) 424 return -ENOMEM; 425 426 ptr = (void *)eeprom_buff; 427 428 if (eeprom->offset & 1) { 429 /* need read/modify/write of first changed EEPROM word */ 430 /* only the second byte of the word is being modified */ 431 eeprom_buff[0] = ixgb_read_eeprom(hw, first_word); 432 ptr++; 433 } 434 if ((eeprom->offset + eeprom->len) & 1) { 435 /* need read/modify/write of last changed EEPROM word */ 436 /* only the first byte of the word is being modified */ 437 eeprom_buff[last_word - first_word] 438 = ixgb_read_eeprom(hw, last_word); 439 } 440 441 memcpy(ptr, bytes, eeprom->len); 442 for (i = 0; i <= (last_word - first_word); i++) 443 ixgb_write_eeprom(hw, first_word + i, eeprom_buff[i]); 444 445 /* Update the checksum over the first part of the EEPROM if needed */ 446 if (first_word <= EEPROM_CHECKSUM_REG) 447 ixgb_update_eeprom_checksum(hw); 448 449 kfree(eeprom_buff); 450 return 0; 451} 452 453static void 454ixgb_get_drvinfo(struct net_device *netdev, 455 struct ethtool_drvinfo *drvinfo) 456{ 457 struct ixgb_adapter *adapter = netdev_priv(netdev); 458 459 strlcpy(drvinfo->driver, ixgb_driver_name, 460 sizeof(drvinfo->driver)); 461 strlcpy(drvinfo->bus_info, pci_name(adapter->pdev), 462 sizeof(drvinfo->bus_info)); 463} 464 465static void 466ixgb_get_ringparam(struct net_device *netdev, 467 struct ethtool_ringparam *ring, 468 struct kernel_ethtool_ringparam *kernel_ring, 469 struct netlink_ext_ack *extack) 470{ 471 struct ixgb_adapter *adapter = netdev_priv(netdev); 472 struct ixgb_desc_ring *txdr = &adapter->tx_ring; 473 struct ixgb_desc_ring *rxdr = &adapter->rx_ring; 474 475 ring->rx_max_pending = MAX_RXD; 476 ring->tx_max_pending = MAX_TXD; 477 ring->rx_pending = rxdr->count; 478 ring->tx_pending = txdr->count; 479} 480 481static int 482ixgb_set_ringparam(struct net_device *netdev, 483 struct ethtool_ringparam *ring, 484 struct kernel_ethtool_ringparam *kernel_ring, 485 struct netlink_ext_ack *extack) 486{ 487 struct ixgb_adapter *adapter = netdev_priv(netdev); 488 struct ixgb_desc_ring *txdr = &adapter->tx_ring; 489 struct ixgb_desc_ring *rxdr = &adapter->rx_ring; 490 struct ixgb_desc_ring tx_old, tx_new, rx_old, rx_new; 491 int err; 492 493 tx_old = adapter->tx_ring; 494 rx_old = adapter->rx_ring; 495 496 if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) 497 return -EINVAL; 498 499 if (netif_running(adapter->netdev)) 500 ixgb_down(adapter, true); 501 502 rxdr->count = max(ring->rx_pending,(u32)MIN_RXD); 503 rxdr->count = min(rxdr->count,(u32)MAX_RXD); 504 rxdr->count = ALIGN(rxdr->count, IXGB_REQ_RX_DESCRIPTOR_MULTIPLE); 505 506 txdr->count = max(ring->tx_pending,(u32)MIN_TXD); 507 txdr->count = min(txdr->count,(u32)MAX_TXD); 508 txdr->count = ALIGN(txdr->count, IXGB_REQ_TX_DESCRIPTOR_MULTIPLE); 509 510 if (netif_running(adapter->netdev)) { 511 /* Try to get new resources before deleting old */ 512 if ((err = ixgb_setup_rx_resources(adapter))) 513 goto err_setup_rx; 514 if ((err = ixgb_setup_tx_resources(adapter))) 515 goto err_setup_tx; 516 517 /* save the new, restore the old in order to free it, 518 * then restore the new back again */ 519 520 rx_new = adapter->rx_ring; 521 tx_new = adapter->tx_ring; 522 adapter->rx_ring = rx_old; 523 adapter->tx_ring = tx_old; 524 ixgb_free_rx_resources(adapter); 525 ixgb_free_tx_resources(adapter); 526 adapter->rx_ring = rx_new; 527 adapter->tx_ring = tx_new; 528 if ((err = ixgb_up(adapter))) 529 return err; 530 ixgb_set_speed_duplex(netdev); 531 } 532 533 return 0; 534err_setup_tx: 535 ixgb_free_rx_resources(adapter); 536err_setup_rx: 537 adapter->rx_ring = rx_old; 538 adapter->tx_ring = tx_old; 539 ixgb_up(adapter); 540 return err; 541} 542 543static int 544ixgb_set_phys_id(struct net_device *netdev, enum ethtool_phys_id_state state) 545{ 546 struct ixgb_adapter *adapter = netdev_priv(netdev); 547 548 switch (state) { 549 case ETHTOOL_ID_ACTIVE: 550 return 2; 551 552 case ETHTOOL_ID_ON: 553 ixgb_led_on(&adapter->hw); 554 break; 555 556 case ETHTOOL_ID_OFF: 557 case ETHTOOL_ID_INACTIVE: 558 ixgb_led_off(&adapter->hw); 559 } 560 561 return 0; 562} 563 564static int 565ixgb_get_sset_count(struct net_device *netdev, int sset) 566{ 567 switch (sset) { 568 case ETH_SS_STATS: 569 return IXGB_STATS_LEN; 570 default: 571 return -EOPNOTSUPP; 572 } 573} 574 575static void 576ixgb_get_ethtool_stats(struct net_device *netdev, 577 struct ethtool_stats *stats, u64 *data) 578{ 579 struct ixgb_adapter *adapter = netdev_priv(netdev); 580 int i; 581 char *p = NULL; 582 583 ixgb_update_stats(adapter); 584 for (i = 0; i < IXGB_STATS_LEN; i++) { 585 switch (ixgb_gstrings_stats[i].type) { 586 case NETDEV_STATS: 587 p = (char *) netdev + 588 ixgb_gstrings_stats[i].stat_offset; 589 break; 590 case IXGB_STATS: 591 p = (char *) adapter + 592 ixgb_gstrings_stats[i].stat_offset; 593 break; 594 } 595 596 data[i] = (ixgb_gstrings_stats[i].sizeof_stat == 597 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 598 } 599} 600 601static void 602ixgb_get_strings(struct net_device *netdev, u32 stringset, u8 *data) 603{ 604 int i; 605 606 switch(stringset) { 607 case ETH_SS_STATS: 608 for (i = 0; i < IXGB_STATS_LEN; i++) { 609 memcpy(data + i * ETH_GSTRING_LEN, 610 ixgb_gstrings_stats[i].stat_string, 611 ETH_GSTRING_LEN); 612 } 613 break; 614 } 615} 616 617static const struct ethtool_ops ixgb_ethtool_ops = { 618 .get_drvinfo = ixgb_get_drvinfo, 619 .get_regs_len = ixgb_get_regs_len, 620 .get_regs = ixgb_get_regs, 621 .get_link = ethtool_op_get_link, 622 .get_eeprom_len = ixgb_get_eeprom_len, 623 .get_eeprom = ixgb_get_eeprom, 624 .set_eeprom = ixgb_set_eeprom, 625 .get_ringparam = ixgb_get_ringparam, 626 .set_ringparam = ixgb_set_ringparam, 627 .get_pauseparam = ixgb_get_pauseparam, 628 .set_pauseparam = ixgb_set_pauseparam, 629 .get_msglevel = ixgb_get_msglevel, 630 .set_msglevel = ixgb_set_msglevel, 631 .get_strings = ixgb_get_strings, 632 .set_phys_id = ixgb_set_phys_id, 633 .get_sset_count = ixgb_get_sset_count, 634 .get_ethtool_stats = ixgb_get_ethtool_stats, 635 .get_link_ksettings = ixgb_get_link_ksettings, 636 .set_link_ksettings = ixgb_set_link_ksettings, 637}; 638 639void ixgb_set_ethtool_ops(struct net_device *netdev) 640{ 641 netdev->ethtool_ops = &ixgb_ethtool_ops; 642}