1 // SPDX-License-Identifier: GPL-2.0 2 /* Marvell Octeon EP (EndPoint) Ethernet Driver 3 * 4 * Copyright (C) 2020 Marvell. 5 * 6 */ 7 8 #include <linux/pci.h> 9 #include <linux/netdevice.h> 10 #include <linux/ethtool.h> 11 12 #include "octep_config.h" 13 #include "octep_main.h" 14 #include "octep_ctrl_net.h" 15 16 static const char octep_gstrings_global_stats[][ETH_GSTRING_LEN] = { 17 "rx_packets", 18 "tx_packets", 19 "rx_bytes", 20 "tx_bytes", 21 "rx_alloc_errors", 22 "tx_busy_errors", 23 "rx_dropped", 24 "tx_dropped", 25 "tx_hw_pkts", 26 "tx_hw_octs", 27 "tx_hw_bcast", 28 "tx_hw_mcast", 29 "tx_hw_underflow", 30 "tx_hw_control", 31 "tx_less_than_64", 32 "tx_equal_64", 33 "tx_equal_65_to_127", 34 "tx_equal_128_to_255", 35 "tx_equal_256_to_511", 36 "tx_equal_512_to_1023", 37 "tx_equal_1024_to_1518", 38 "tx_greater_than_1518", 39 "rx_hw_pkts", 40 "rx_hw_bytes", 41 "rx_hw_bcast", 42 "rx_hw_mcast", 43 "rx_pause_pkts", 44 "rx_pause_bytes", 45 "rx_dropped_pkts_fifo_full", 46 "rx_dropped_bytes_fifo_full", 47 "rx_err_pkts", 48 }; 49 50 #define OCTEP_GLOBAL_STATS_CNT (sizeof(octep_gstrings_global_stats) / ETH_GSTRING_LEN) 51 52 static const char octep_gstrings_tx_q_stats[][ETH_GSTRING_LEN] = { 53 "tx_packets_posted[Q-%u]", 54 "tx_packets_completed[Q-%u]", 55 "tx_bytes[Q-%u]", 56 "tx_busy[Q-%u]", 57 }; 58 59 #define OCTEP_TX_Q_STATS_CNT (sizeof(octep_gstrings_tx_q_stats) / ETH_GSTRING_LEN) 60 61 static const char octep_gstrings_rx_q_stats[][ETH_GSTRING_LEN] = { 62 "rx_packets[Q-%u]", 63 "rx_bytes[Q-%u]", 64 "rx_alloc_errors[Q-%u]", 65 }; 66 67 #define OCTEP_RX_Q_STATS_CNT (sizeof(octep_gstrings_rx_q_stats) / ETH_GSTRING_LEN) 68 69 static void octep_get_drvinfo(struct net_device *netdev, 70 struct ethtool_drvinfo *info) 71 { 72 struct octep_device *oct = netdev_priv(netdev); 73 74 strscpy(info->driver, OCTEP_DRV_NAME, sizeof(info->driver)); 75 strscpy(info->bus_info, pci_name(oct->pdev), sizeof(info->bus_info)); 76 } 77 78 static void octep_get_strings(struct net_device *netdev, 79 u32 stringset, u8 *data) 80 { 81 struct octep_device *oct = netdev_priv(netdev); 82 u16 num_queues = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); 83 char *strings = (char *)data; 84 int i, j; 85 86 switch (stringset) { 87 case ETH_SS_STATS: 88 for (i = 0; i < OCTEP_GLOBAL_STATS_CNT; i++) { 89 snprintf(strings, ETH_GSTRING_LEN, 90 octep_gstrings_global_stats[i]); 91 strings += ETH_GSTRING_LEN; 92 } 93 94 for (i = 0; i < num_queues; i++) { 95 for (j = 0; j < OCTEP_TX_Q_STATS_CNT; j++) { 96 snprintf(strings, ETH_GSTRING_LEN, 97 octep_gstrings_tx_q_stats[j], i); 98 strings += ETH_GSTRING_LEN; 99 } 100 } 101 102 for (i = 0; i < num_queues; i++) { 103 for (j = 0; j < OCTEP_RX_Q_STATS_CNT; j++) { 104 snprintf(strings, ETH_GSTRING_LEN, 105 octep_gstrings_rx_q_stats[j], i); 106 strings += ETH_GSTRING_LEN; 107 } 108 } 109 break; 110 default: 111 break; 112 } 113 } 114 115 static int octep_get_sset_count(struct net_device *netdev, int sset) 116 { 117 struct octep_device *oct = netdev_priv(netdev); 118 u16 num_queues = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); 119 120 switch (sset) { 121 case ETH_SS_STATS: 122 return OCTEP_GLOBAL_STATS_CNT + (num_queues * 123 (OCTEP_TX_Q_STATS_CNT + OCTEP_RX_Q_STATS_CNT)); 124 break; 125 default: 126 return -EOPNOTSUPP; 127 } 128 } 129 130 static void 131 octep_get_ethtool_stats(struct net_device *netdev, 132 struct ethtool_stats *stats, u64 *data) 133 { 134 struct octep_device *oct = netdev_priv(netdev); 135 struct octep_iface_tx_stats *iface_tx_stats; 136 struct octep_iface_rx_stats *iface_rx_stats; 137 u64 rx_packets, rx_bytes; 138 u64 tx_packets, tx_bytes; 139 u64 rx_alloc_errors, tx_busy_errors; 140 int q, i; 141 142 rx_packets = 0; 143 rx_bytes = 0; 144 tx_packets = 0; 145 tx_bytes = 0; 146 rx_alloc_errors = 0; 147 tx_busy_errors = 0; 148 tx_packets = 0; 149 tx_bytes = 0; 150 rx_packets = 0; 151 rx_bytes = 0; 152 153 iface_tx_stats = &oct->iface_tx_stats; 154 iface_rx_stats = &oct->iface_rx_stats; 155 octep_ctrl_net_get_if_stats(oct, 156 OCTEP_CTRL_NET_INVALID_VFID, 157 iface_rx_stats, 158 iface_tx_stats); 159 160 for (q = 0; q < oct->num_oqs; q++) { 161 struct octep_iq *iq = oct->iq[q]; 162 struct octep_oq *oq = oct->oq[q]; 163 164 tx_packets += iq->stats.instr_completed; 165 tx_bytes += iq->stats.bytes_sent; 166 tx_busy_errors += iq->stats.tx_busy; 167 168 rx_packets += oq->stats.packets; 169 rx_bytes += oq->stats.bytes; 170 rx_alloc_errors += oq->stats.alloc_failures; 171 } 172 i = 0; 173 data[i++] = rx_packets; 174 data[i++] = tx_packets; 175 data[i++] = rx_bytes; 176 data[i++] = tx_bytes; 177 data[i++] = rx_alloc_errors; 178 data[i++] = tx_busy_errors; 179 data[i++] = iface_rx_stats->dropped_pkts_fifo_full + 180 iface_rx_stats->err_pkts; 181 data[i++] = iface_tx_stats->xscol + 182 iface_tx_stats->xsdef; 183 data[i++] = iface_tx_stats->pkts; 184 data[i++] = iface_tx_stats->octs; 185 data[i++] = iface_tx_stats->bcst; 186 data[i++] = iface_tx_stats->mcst; 187 data[i++] = iface_tx_stats->undflw; 188 data[i++] = iface_tx_stats->ctl; 189 data[i++] = iface_tx_stats->hist_lt64; 190 data[i++] = iface_tx_stats->hist_eq64; 191 data[i++] = iface_tx_stats->hist_65to127; 192 data[i++] = iface_tx_stats->hist_128to255; 193 data[i++] = iface_tx_stats->hist_256to511; 194 data[i++] = iface_tx_stats->hist_512to1023; 195 data[i++] = iface_tx_stats->hist_1024to1518; 196 data[i++] = iface_tx_stats->hist_gt1518; 197 data[i++] = iface_rx_stats->pkts; 198 data[i++] = iface_rx_stats->octets; 199 data[i++] = iface_rx_stats->mcast_pkts; 200 data[i++] = iface_rx_stats->bcast_pkts; 201 data[i++] = iface_rx_stats->pause_pkts; 202 data[i++] = iface_rx_stats->pause_octets; 203 data[i++] = iface_rx_stats->dropped_pkts_fifo_full; 204 data[i++] = iface_rx_stats->dropped_octets_fifo_full; 205 data[i++] = iface_rx_stats->err_pkts; 206 207 /* Per Tx Queue stats */ 208 for (q = 0; q < oct->num_iqs; q++) { 209 struct octep_iq *iq = oct->iq[q]; 210 211 data[i++] = iq->stats.instr_posted; 212 data[i++] = iq->stats.instr_completed; 213 data[i++] = iq->stats.bytes_sent; 214 data[i++] = iq->stats.tx_busy; 215 } 216 217 /* Per Rx Queue stats */ 218 for (q = 0; q < oct->num_oqs; q++) { 219 struct octep_oq *oq = oct->oq[q]; 220 221 data[i++] = oq->stats.packets; 222 data[i++] = oq->stats.bytes; 223 data[i++] = oq->stats.alloc_failures; 224 } 225 } 226 227 #define OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(octep_speeds, ksettings, name) \ 228 { \ 229 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_T)) \ 230 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseT_Full); \ 231 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_R)) \ 232 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseR_FEC); \ 233 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_CR)) \ 234 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseCR_Full); \ 235 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_KR)) \ 236 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseKR_Full); \ 237 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_LR)) \ 238 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseLR_Full); \ 239 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_SR)) \ 240 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseSR_Full); \ 241 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_CR)) \ 242 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseCR_Full); \ 243 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_KR)) \ 244 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseKR_Full); \ 245 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_SR)) \ 246 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseSR_Full); \ 247 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_CR4)) \ 248 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseCR4_Full); \ 249 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_KR4)) \ 250 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseKR4_Full); \ 251 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_LR4)) \ 252 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseLR4_Full); \ 253 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_SR4)) \ 254 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseSR4_Full); \ 255 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR2)) \ 256 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR2_Full); \ 257 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR2)) \ 258 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR2_Full); \ 259 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR2)) \ 260 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR2_Full); \ 261 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR)) \ 262 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR_Full); \ 263 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR)) \ 264 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR_Full); \ 265 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_LR)) \ 266 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseLR_ER_FR_Full); \ 267 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR)) \ 268 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR_Full); \ 269 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_CR4)) \ 270 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseCR4_Full); \ 271 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_KR4)) \ 272 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseKR4_Full); \ 273 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_LR4)) \ 274 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseLR4_ER4_Full); \ 275 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_SR4)) \ 276 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseSR4_Full); \ 277 } 278 279 static int octep_get_link_ksettings(struct net_device *netdev, 280 struct ethtool_link_ksettings *cmd) 281 { 282 struct octep_device *oct = netdev_priv(netdev); 283 struct octep_iface_link_info *link_info; 284 u32 advertised_modes, supported_modes; 285 286 ethtool_link_ksettings_zero_link_mode(cmd, supported); 287 ethtool_link_ksettings_zero_link_mode(cmd, advertising); 288 289 link_info = &oct->link_info; 290 octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, link_info); 291 292 advertised_modes = oct->link_info.advertised_modes; 293 supported_modes = oct->link_info.supported_modes; 294 295 OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(supported_modes, cmd, supported); 296 OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(advertised_modes, cmd, advertising); 297 298 if (link_info->autoneg) { 299 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED) 300 ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); 301 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_ADVERTISED) { 302 ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); 303 cmd->base.autoneg = AUTONEG_ENABLE; 304 } else { 305 cmd->base.autoneg = AUTONEG_DISABLE; 306 } 307 } else { 308 cmd->base.autoneg = AUTONEG_DISABLE; 309 } 310 311 if (link_info->pause) { 312 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_SUPPORTED) 313 ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); 314 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_ADVERTISED) 315 ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); 316 } 317 318 cmd->base.port = PORT_FIBRE; 319 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 320 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); 321 322 if (netif_carrier_ok(netdev)) { 323 cmd->base.speed = link_info->speed; 324 cmd->base.duplex = DUPLEX_FULL; 325 } else { 326 cmd->base.speed = SPEED_UNKNOWN; 327 cmd->base.duplex = DUPLEX_UNKNOWN; 328 } 329 return 0; 330 } 331 332 static int octep_set_link_ksettings(struct net_device *netdev, 333 const struct ethtool_link_ksettings *cmd) 334 { 335 struct octep_device *oct = netdev_priv(netdev); 336 struct octep_iface_link_info link_info_new; 337 struct octep_iface_link_info *link_info; 338 u64 advertised = 0; 339 u8 autoneg = 0; 340 int err; 341 342 link_info = &oct->link_info; 343 memcpy(&link_info_new, link_info, sizeof(struct octep_iface_link_info)); 344 345 /* Only Full duplex is supported; 346 * Assume full duplex when duplex is unknown. 347 */ 348 if (cmd->base.duplex != DUPLEX_FULL && 349 cmd->base.duplex != DUPLEX_UNKNOWN) 350 return -EOPNOTSUPP; 351 352 if (cmd->base.autoneg == AUTONEG_ENABLE) { 353 if (!(link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED)) 354 return -EOPNOTSUPP; 355 autoneg = 1; 356 } 357 358 if (!bitmap_subset(cmd->link_modes.advertising, 359 cmd->link_modes.supported, 360 __ETHTOOL_LINK_MODE_MASK_NBITS)) 361 return -EINVAL; 362 363 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 364 10000baseT_Full)) 365 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_T); 366 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 367 10000baseR_FEC)) 368 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_R); 369 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 370 10000baseCR_Full)) 371 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_CR); 372 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 373 10000baseKR_Full)) 374 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_KR); 375 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 376 10000baseLR_Full)) 377 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_LR); 378 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 379 10000baseSR_Full)) 380 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_SR); 381 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 382 25000baseCR_Full)) 383 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_CR); 384 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 385 25000baseKR_Full)) 386 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_KR); 387 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 388 25000baseSR_Full)) 389 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_SR); 390 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 391 40000baseCR4_Full)) 392 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_CR4); 393 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 394 40000baseKR4_Full)) 395 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_KR4); 396 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 397 40000baseLR4_Full)) 398 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_LR4); 399 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 400 40000baseSR4_Full)) 401 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_SR4); 402 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 403 50000baseCR2_Full)) 404 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR2); 405 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 406 50000baseKR2_Full)) 407 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR2); 408 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 409 50000baseSR2_Full)) 410 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR2); 411 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 412 50000baseCR_Full)) 413 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR); 414 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 415 50000baseKR_Full)) 416 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR); 417 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 418 50000baseLR_ER_FR_Full)) 419 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_LR); 420 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 421 50000baseSR_Full)) 422 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR); 423 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 424 100000baseCR4_Full)) 425 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_CR4); 426 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 427 100000baseKR4_Full)) 428 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_KR4); 429 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 430 100000baseLR4_ER4_Full)) 431 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_LR4); 432 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 433 100000baseSR4_Full)) 434 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_SR4); 435 436 if (advertised == link_info->advertised_modes && 437 cmd->base.speed == link_info->speed && 438 cmd->base.autoneg == link_info->autoneg) 439 return 0; 440 441 link_info_new.advertised_modes = advertised; 442 link_info_new.speed = cmd->base.speed; 443 link_info_new.autoneg = autoneg; 444 445 err = octep_ctrl_net_set_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, 446 &link_info_new, true); 447 if (err) 448 return err; 449 450 memcpy(link_info, &link_info_new, sizeof(struct octep_iface_link_info)); 451 return 0; 452 } 453 454 static const struct ethtool_ops octep_ethtool_ops = { 455 .get_drvinfo = octep_get_drvinfo, 456 .get_link = ethtool_op_get_link, 457 .get_strings = octep_get_strings, 458 .get_sset_count = octep_get_sset_count, 459 .get_ethtool_stats = octep_get_ethtool_stats, 460 .get_link_ksettings = octep_get_link_ksettings, 461 .set_link_ksettings = octep_set_link_ksettings, 462 }; 463 464 void octep_set_ethtool_ops(struct net_device *netdev) 465 { 466 netdev->ethtool_ops = &octep_ethtool_ops; 467 } 468