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 ARRAY_SIZE(octep_gstrings_global_stats) 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 ARRAY_SIZE(octep_gstrings_tx_q_stats) 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 ARRAY_SIZE(octep_gstrings_rx_q_stats) 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 const char *str; 84 int i, j; 85 86 switch (stringset) { 87 case ETH_SS_STATS: 88 for (i = 0; i < OCTEP_GLOBAL_STATS_CNT; i++) 89 ethtool_puts(&data, octep_gstrings_global_stats[i]); 90 91 for (i = 0; i < num_queues; i++) 92 for (j = 0; j < OCTEP_TX_Q_STATS_CNT; j++) { 93 str = octep_gstrings_tx_q_stats[j]; 94 ethtool_sprintf(&data, str, i); 95 } 96 97 for (i = 0; i < num_queues; i++) 98 for (j = 0; j < OCTEP_RX_Q_STATS_CNT; j++) { 99 str = octep_gstrings_rx_q_stats[j]; 100 ethtool_sprintf(&data, str, i); 101 } 102 break; 103 default: 104 break; 105 } 106 } 107 108 static int octep_get_sset_count(struct net_device *netdev, int sset) 109 { 110 struct octep_device *oct = netdev_priv(netdev); 111 u16 num_queues = CFG_GET_PORTS_ACTIVE_IO_RINGS(oct->conf); 112 113 switch (sset) { 114 case ETH_SS_STATS: 115 return OCTEP_GLOBAL_STATS_CNT + (num_queues * 116 (OCTEP_TX_Q_STATS_CNT + OCTEP_RX_Q_STATS_CNT)); 117 break; 118 default: 119 return -EOPNOTSUPP; 120 } 121 } 122 123 static void 124 octep_get_ethtool_stats(struct net_device *netdev, 125 struct ethtool_stats *stats, u64 *data) 126 { 127 struct octep_device *oct = netdev_priv(netdev); 128 struct octep_iface_tx_stats *iface_tx_stats; 129 struct octep_iface_rx_stats *iface_rx_stats; 130 u64 rx_packets, rx_bytes; 131 u64 tx_packets, tx_bytes; 132 u64 rx_alloc_errors, tx_busy_errors; 133 int q, i; 134 135 rx_packets = 0; 136 rx_bytes = 0; 137 tx_packets = 0; 138 tx_bytes = 0; 139 rx_alloc_errors = 0; 140 tx_busy_errors = 0; 141 tx_packets = 0; 142 tx_bytes = 0; 143 rx_packets = 0; 144 rx_bytes = 0; 145 146 iface_tx_stats = &oct->iface_tx_stats; 147 iface_rx_stats = &oct->iface_rx_stats; 148 octep_ctrl_net_get_if_stats(oct, 149 OCTEP_CTRL_NET_INVALID_VFID, 150 iface_rx_stats, 151 iface_tx_stats); 152 153 for (q = 0; q < oct->num_oqs; q++) { 154 struct octep_iq *iq = oct->iq[q]; 155 struct octep_oq *oq = oct->oq[q]; 156 157 tx_packets += iq->stats.instr_completed; 158 tx_bytes += iq->stats.bytes_sent; 159 tx_busy_errors += iq->stats.tx_busy; 160 161 rx_packets += oq->stats.packets; 162 rx_bytes += oq->stats.bytes; 163 rx_alloc_errors += oq->stats.alloc_failures; 164 } 165 i = 0; 166 data[i++] = rx_packets; 167 data[i++] = tx_packets; 168 data[i++] = rx_bytes; 169 data[i++] = tx_bytes; 170 data[i++] = rx_alloc_errors; 171 data[i++] = tx_busy_errors; 172 data[i++] = iface_rx_stats->dropped_pkts_fifo_full + 173 iface_rx_stats->err_pkts; 174 data[i++] = iface_tx_stats->xscol + 175 iface_tx_stats->xsdef; 176 data[i++] = iface_tx_stats->pkts; 177 data[i++] = iface_tx_stats->octs; 178 data[i++] = iface_tx_stats->bcst; 179 data[i++] = iface_tx_stats->mcst; 180 data[i++] = iface_tx_stats->undflw; 181 data[i++] = iface_tx_stats->ctl; 182 data[i++] = iface_tx_stats->hist_lt64; 183 data[i++] = iface_tx_stats->hist_eq64; 184 data[i++] = iface_tx_stats->hist_65to127; 185 data[i++] = iface_tx_stats->hist_128to255; 186 data[i++] = iface_tx_stats->hist_256to511; 187 data[i++] = iface_tx_stats->hist_512to1023; 188 data[i++] = iface_tx_stats->hist_1024to1518; 189 data[i++] = iface_tx_stats->hist_gt1518; 190 data[i++] = iface_rx_stats->pkts; 191 data[i++] = iface_rx_stats->octets; 192 data[i++] = iface_rx_stats->mcast_pkts; 193 data[i++] = iface_rx_stats->bcast_pkts; 194 data[i++] = iface_rx_stats->pause_pkts; 195 data[i++] = iface_rx_stats->pause_octets; 196 data[i++] = iface_rx_stats->dropped_pkts_fifo_full; 197 data[i++] = iface_rx_stats->dropped_octets_fifo_full; 198 data[i++] = iface_rx_stats->err_pkts; 199 200 /* Per Tx Queue stats */ 201 for (q = 0; q < oct->num_iqs; q++) { 202 struct octep_iq *iq = oct->iq[q]; 203 204 data[i++] = iq->stats.instr_posted; 205 data[i++] = iq->stats.instr_completed; 206 data[i++] = iq->stats.bytes_sent; 207 data[i++] = iq->stats.tx_busy; 208 } 209 210 /* Per Rx Queue stats */ 211 for (q = 0; q < oct->num_oqs; q++) { 212 struct octep_oq *oq = oct->oq[q]; 213 214 data[i++] = oq->stats.packets; 215 data[i++] = oq->stats.bytes; 216 data[i++] = oq->stats.alloc_failures; 217 } 218 } 219 220 #define OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(octep_speeds, ksettings, name) \ 221 { \ 222 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_T)) \ 223 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseT_Full); \ 224 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_R)) \ 225 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseR_FEC); \ 226 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_CR)) \ 227 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseCR_Full); \ 228 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_KR)) \ 229 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseKR_Full); \ 230 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_LR)) \ 231 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseLR_Full); \ 232 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_10GBASE_SR)) \ 233 ethtool_link_ksettings_add_link_mode(ksettings, name, 10000baseSR_Full); \ 234 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_CR)) \ 235 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseCR_Full); \ 236 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_KR)) \ 237 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseKR_Full); \ 238 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_25GBASE_SR)) \ 239 ethtool_link_ksettings_add_link_mode(ksettings, name, 25000baseSR_Full); \ 240 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_CR4)) \ 241 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseCR4_Full); \ 242 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_KR4)) \ 243 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseKR4_Full); \ 244 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_LR4)) \ 245 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseLR4_Full); \ 246 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_40GBASE_SR4)) \ 247 ethtool_link_ksettings_add_link_mode(ksettings, name, 40000baseSR4_Full); \ 248 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR2)) \ 249 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR2_Full); \ 250 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR2)) \ 251 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR2_Full); \ 252 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR2)) \ 253 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR2_Full); \ 254 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_CR)) \ 255 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseCR_Full); \ 256 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_KR)) \ 257 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseKR_Full); \ 258 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_LR)) \ 259 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseLR_ER_FR_Full); \ 260 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_50GBASE_SR)) \ 261 ethtool_link_ksettings_add_link_mode(ksettings, name, 50000baseSR_Full); \ 262 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_CR4)) \ 263 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseCR4_Full); \ 264 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_KR4)) \ 265 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseKR4_Full); \ 266 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_LR4)) \ 267 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseLR4_ER4_Full); \ 268 if ((octep_speeds) & BIT(OCTEP_LINK_MODE_100GBASE_SR4)) \ 269 ethtool_link_ksettings_add_link_mode(ksettings, name, 100000baseSR4_Full); \ 270 } 271 272 static int octep_get_link_ksettings(struct net_device *netdev, 273 struct ethtool_link_ksettings *cmd) 274 { 275 struct octep_device *oct = netdev_priv(netdev); 276 struct octep_iface_link_info *link_info; 277 u32 advertised_modes, supported_modes; 278 279 ethtool_link_ksettings_zero_link_mode(cmd, supported); 280 ethtool_link_ksettings_zero_link_mode(cmd, advertising); 281 282 link_info = &oct->link_info; 283 octep_ctrl_net_get_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, link_info); 284 285 advertised_modes = oct->link_info.advertised_modes; 286 supported_modes = oct->link_info.supported_modes; 287 288 OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(supported_modes, cmd, supported); 289 OCTEP_SET_ETHTOOL_LINK_MODES_BITMAP(advertised_modes, cmd, advertising); 290 291 if (link_info->autoneg) { 292 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED) 293 ethtool_link_ksettings_add_link_mode(cmd, supported, Autoneg); 294 if (link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_ADVERTISED) { 295 ethtool_link_ksettings_add_link_mode(cmd, advertising, Autoneg); 296 cmd->base.autoneg = AUTONEG_ENABLE; 297 } else { 298 cmd->base.autoneg = AUTONEG_DISABLE; 299 } 300 } else { 301 cmd->base.autoneg = AUTONEG_DISABLE; 302 } 303 304 if (link_info->pause) { 305 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_SUPPORTED) 306 ethtool_link_ksettings_add_link_mode(cmd, supported, Pause); 307 if (link_info->pause & OCTEP_LINK_MODE_PAUSE_ADVERTISED) 308 ethtool_link_ksettings_add_link_mode(cmd, advertising, Pause); 309 } 310 311 cmd->base.port = PORT_FIBRE; 312 ethtool_link_ksettings_add_link_mode(cmd, supported, FIBRE); 313 ethtool_link_ksettings_add_link_mode(cmd, advertising, FIBRE); 314 315 if (netif_carrier_ok(netdev)) { 316 cmd->base.speed = link_info->speed; 317 cmd->base.duplex = DUPLEX_FULL; 318 } else { 319 cmd->base.speed = SPEED_UNKNOWN; 320 cmd->base.duplex = DUPLEX_UNKNOWN; 321 } 322 return 0; 323 } 324 325 static int octep_set_link_ksettings(struct net_device *netdev, 326 const struct ethtool_link_ksettings *cmd) 327 { 328 struct octep_device *oct = netdev_priv(netdev); 329 struct octep_iface_link_info link_info_new; 330 struct octep_iface_link_info *link_info; 331 u64 advertised = 0; 332 u8 autoneg = 0; 333 int err; 334 335 link_info = &oct->link_info; 336 memcpy(&link_info_new, link_info, sizeof(struct octep_iface_link_info)); 337 338 /* Only Full duplex is supported; 339 * Assume full duplex when duplex is unknown. 340 */ 341 if (cmd->base.duplex != DUPLEX_FULL && 342 cmd->base.duplex != DUPLEX_UNKNOWN) 343 return -EOPNOTSUPP; 344 345 if (cmd->base.autoneg == AUTONEG_ENABLE) { 346 if (!(link_info->autoneg & OCTEP_LINK_MODE_AUTONEG_SUPPORTED)) 347 return -EOPNOTSUPP; 348 autoneg = 1; 349 } 350 351 if (!bitmap_subset(cmd->link_modes.advertising, 352 cmd->link_modes.supported, 353 __ETHTOOL_LINK_MODE_MASK_NBITS)) 354 return -EINVAL; 355 356 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 357 10000baseT_Full)) 358 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_T); 359 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 360 10000baseR_FEC)) 361 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_R); 362 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 363 10000baseCR_Full)) 364 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_CR); 365 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 366 10000baseKR_Full)) 367 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_KR); 368 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 369 10000baseLR_Full)) 370 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_LR); 371 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 372 10000baseSR_Full)) 373 advertised |= BIT(OCTEP_LINK_MODE_10GBASE_SR); 374 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 375 25000baseCR_Full)) 376 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_CR); 377 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 378 25000baseKR_Full)) 379 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_KR); 380 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 381 25000baseSR_Full)) 382 advertised |= BIT(OCTEP_LINK_MODE_25GBASE_SR); 383 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 384 40000baseCR4_Full)) 385 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_CR4); 386 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 387 40000baseKR4_Full)) 388 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_KR4); 389 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 390 40000baseLR4_Full)) 391 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_LR4); 392 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 393 40000baseSR4_Full)) 394 advertised |= BIT(OCTEP_LINK_MODE_40GBASE_SR4); 395 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 396 50000baseCR2_Full)) 397 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR2); 398 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 399 50000baseKR2_Full)) 400 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR2); 401 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 402 50000baseSR2_Full)) 403 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR2); 404 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 405 50000baseCR_Full)) 406 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_CR); 407 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 408 50000baseKR_Full)) 409 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_KR); 410 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 411 50000baseLR_ER_FR_Full)) 412 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_LR); 413 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 414 50000baseSR_Full)) 415 advertised |= BIT(OCTEP_LINK_MODE_50GBASE_SR); 416 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 417 100000baseCR4_Full)) 418 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_CR4); 419 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 420 100000baseKR4_Full)) 421 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_KR4); 422 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 423 100000baseLR4_ER4_Full)) 424 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_LR4); 425 if (ethtool_link_ksettings_test_link_mode(cmd, advertising, 426 100000baseSR4_Full)) 427 advertised |= BIT(OCTEP_LINK_MODE_100GBASE_SR4); 428 429 if (advertised == link_info->advertised_modes && 430 cmd->base.speed == link_info->speed && 431 cmd->base.autoneg == link_info->autoneg) 432 return 0; 433 434 link_info_new.advertised_modes = advertised; 435 link_info_new.speed = cmd->base.speed; 436 link_info_new.autoneg = autoneg; 437 438 err = octep_ctrl_net_set_link_info(oct, OCTEP_CTRL_NET_INVALID_VFID, 439 &link_info_new, true); 440 if (err) 441 return err; 442 443 memcpy(link_info, &link_info_new, sizeof(struct octep_iface_link_info)); 444 return 0; 445 } 446 447 static const struct ethtool_ops octep_ethtool_ops = { 448 .get_drvinfo = octep_get_drvinfo, 449 .get_link = ethtool_op_get_link, 450 .get_strings = octep_get_strings, 451 .get_sset_count = octep_get_sset_count, 452 .get_ethtool_stats = octep_get_ethtool_stats, 453 .get_link_ksettings = octep_get_link_ksettings, 454 .set_link_ksettings = octep_set_link_ksettings, 455 }; 456 457 void octep_set_ethtool_ops(struct net_device *netdev) 458 { 459 netdev->ethtool_ops = &octep_ethtool_ops; 460 } 461