1 // SPDX-License-Identifier: GPL-2.0 2 /* Huawei HiNIC PCI Express Linux driver 3 * Copyright(c) 2017 Huawei Technologies Co., Ltd 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms and conditions of the GNU General Public License, 7 * version 2, as published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * for more details. 13 * 14 */ 15 16 #include <linux/kernel.h> 17 #include <linux/pci.h> 18 #include <linux/device.h> 19 #include <linux/module.h> 20 #include <linux/types.h> 21 #include <linux/errno.h> 22 #include <linux/interrupt.h> 23 #include <linux/etherdevice.h> 24 #include <linux/netdevice.h> 25 #include <linux/if_vlan.h> 26 #include <linux/ethtool.h> 27 #include <linux/vmalloc.h> 28 29 #include "hinic_hw_qp.h" 30 #include "hinic_hw_dev.h" 31 #include "hinic_port.h" 32 #include "hinic_tx.h" 33 #include "hinic_rx.h" 34 #include "hinic_dev.h" 35 36 #define SET_LINK_STR_MAX_LEN 128 37 38 #define GET_SUPPORTED_MODE 0 39 #define GET_ADVERTISED_MODE 1 40 41 #define ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE(ecmd, mode) \ 42 ((ecmd)->supported |= \ 43 (1UL << hw_to_ethtool_link_mode_table[mode].link_mode_bit)) 44 #define ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE(ecmd, mode) \ 45 ((ecmd)->advertising |= \ 46 (1UL << hw_to_ethtool_link_mode_table[mode].link_mode_bit)) 47 #define ETHTOOL_ADD_SUPPORTED_LINK_MODE(ecmd, mode) \ 48 ((ecmd)->supported |= SUPPORTED_##mode) 49 #define ETHTOOL_ADD_ADVERTISED_LINK_MODE(ecmd, mode) \ 50 ((ecmd)->advertising |= ADVERTISED_##mode) 51 52 struct hw2ethtool_link_mode { 53 enum ethtool_link_mode_bit_indices link_mode_bit; 54 u32 speed; 55 enum hinic_link_mode hw_link_mode; 56 }; 57 58 struct cmd_link_settings { 59 u64 supported; 60 u64 advertising; 61 62 u32 speed; 63 u8 duplex; 64 u8 port; 65 u8 autoneg; 66 }; 67 68 static u32 hw_to_ethtool_speed[LINK_SPEED_LEVELS] = { 69 SPEED_10, SPEED_100, 70 SPEED_1000, SPEED_10000, 71 SPEED_25000, SPEED_40000, 72 SPEED_100000 73 }; 74 75 static struct hw2ethtool_link_mode 76 hw_to_ethtool_link_mode_table[HINIC_LINK_MODE_NUMBERS] = { 77 { 78 .link_mode_bit = ETHTOOL_LINK_MODE_10000baseKR_Full_BIT, 79 .speed = SPEED_10000, 80 .hw_link_mode = HINIC_10GE_BASE_KR, 81 }, 82 { 83 .link_mode_bit = ETHTOOL_LINK_MODE_40000baseKR4_Full_BIT, 84 .speed = SPEED_40000, 85 .hw_link_mode = HINIC_40GE_BASE_KR4, 86 }, 87 { 88 .link_mode_bit = ETHTOOL_LINK_MODE_40000baseCR4_Full_BIT, 89 .speed = SPEED_40000, 90 .hw_link_mode = HINIC_40GE_BASE_CR4, 91 }, 92 { 93 .link_mode_bit = ETHTOOL_LINK_MODE_100000baseKR4_Full_BIT, 94 .speed = SPEED_100000, 95 .hw_link_mode = HINIC_100GE_BASE_KR4, 96 }, 97 { 98 .link_mode_bit = ETHTOOL_LINK_MODE_100000baseCR4_Full_BIT, 99 .speed = SPEED_100000, 100 .hw_link_mode = HINIC_100GE_BASE_CR4, 101 }, 102 { 103 .link_mode_bit = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, 104 .speed = SPEED_25000, 105 .hw_link_mode = HINIC_25GE_BASE_KR_S, 106 }, 107 { 108 .link_mode_bit = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, 109 .speed = SPEED_25000, 110 .hw_link_mode = HINIC_25GE_BASE_CR_S, 111 }, 112 { 113 .link_mode_bit = ETHTOOL_LINK_MODE_25000baseKR_Full_BIT, 114 .speed = SPEED_25000, 115 .hw_link_mode = HINIC_25GE_BASE_KR, 116 }, 117 { 118 .link_mode_bit = ETHTOOL_LINK_MODE_25000baseCR_Full_BIT, 119 .speed = SPEED_25000, 120 .hw_link_mode = HINIC_25GE_BASE_CR, 121 }, 122 { 123 .link_mode_bit = ETHTOOL_LINK_MODE_1000baseKX_Full_BIT, 124 .speed = SPEED_1000, 125 .hw_link_mode = HINIC_GE_BASE_KX, 126 }, 127 }; 128 129 static void set_link_speed(struct ethtool_link_ksettings *link_ksettings, 130 enum hinic_speed speed) 131 { 132 switch (speed) { 133 case HINIC_SPEED_10MB_LINK: 134 link_ksettings->base.speed = SPEED_10; 135 break; 136 137 case HINIC_SPEED_100MB_LINK: 138 link_ksettings->base.speed = SPEED_100; 139 break; 140 141 case HINIC_SPEED_1000MB_LINK: 142 link_ksettings->base.speed = SPEED_1000; 143 break; 144 145 case HINIC_SPEED_10GB_LINK: 146 link_ksettings->base.speed = SPEED_10000; 147 break; 148 149 case HINIC_SPEED_25GB_LINK: 150 link_ksettings->base.speed = SPEED_25000; 151 break; 152 153 case HINIC_SPEED_40GB_LINK: 154 link_ksettings->base.speed = SPEED_40000; 155 break; 156 157 case HINIC_SPEED_100GB_LINK: 158 link_ksettings->base.speed = SPEED_100000; 159 break; 160 161 default: 162 link_ksettings->base.speed = SPEED_UNKNOWN; 163 break; 164 } 165 } 166 167 static int hinic_get_link_mode_index(enum hinic_link_mode link_mode) 168 { 169 int i = 0; 170 171 for (i = 0; i < HINIC_LINK_MODE_NUMBERS; i++) { 172 if (link_mode == hw_to_ethtool_link_mode_table[i].hw_link_mode) 173 break; 174 } 175 176 return i; 177 } 178 179 static void hinic_add_ethtool_link_mode(struct cmd_link_settings *link_settings, 180 enum hinic_link_mode hw_link_mode, 181 u32 name) 182 { 183 enum hinic_link_mode link_mode; 184 int idx = 0; 185 186 for (link_mode = 0; link_mode < HINIC_LINK_MODE_NUMBERS; link_mode++) { 187 if (hw_link_mode & ((u32)1 << link_mode)) { 188 idx = hinic_get_link_mode_index(link_mode); 189 if (idx >= HINIC_LINK_MODE_NUMBERS) 190 continue; 191 192 if (name == GET_SUPPORTED_MODE) 193 ETHTOOL_ADD_SUPPORTED_SPEED_LINK_MODE 194 (link_settings, idx); 195 else 196 ETHTOOL_ADD_ADVERTISED_SPEED_LINK_MODE 197 (link_settings, idx); 198 } 199 } 200 } 201 202 static void hinic_link_port_type(struct cmd_link_settings *link_settings, 203 enum hinic_port_type port_type) 204 { 205 switch (port_type) { 206 case HINIC_PORT_ELEC: 207 case HINIC_PORT_TP: 208 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, TP); 209 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, TP); 210 link_settings->port = PORT_TP; 211 break; 212 213 case HINIC_PORT_AOC: 214 case HINIC_PORT_FIBRE: 215 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE); 216 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE); 217 link_settings->port = PORT_FIBRE; 218 break; 219 220 case HINIC_PORT_COPPER: 221 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, FIBRE); 222 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, FIBRE); 223 link_settings->port = PORT_DA; 224 break; 225 226 case HINIC_PORT_BACKPLANE: 227 ETHTOOL_ADD_SUPPORTED_LINK_MODE(link_settings, Backplane); 228 ETHTOOL_ADD_ADVERTISED_LINK_MODE(link_settings, Backplane); 229 link_settings->port = PORT_NONE; 230 break; 231 232 default: 233 link_settings->port = PORT_OTHER; 234 break; 235 } 236 } 237 238 static int hinic_get_link_ksettings(struct net_device *netdev, 239 struct ethtool_link_ksettings 240 *link_ksettings) 241 { 242 struct hinic_dev *nic_dev = netdev_priv(netdev); 243 struct hinic_link_mode_cmd link_mode = { 0 }; 244 struct hinic_pause_config pause_info = { 0 }; 245 struct cmd_link_settings settings = { 0 }; 246 enum hinic_port_link_state link_state; 247 struct hinic_port_cap port_cap; 248 int err; 249 250 ethtool_link_ksettings_zero_link_mode(link_ksettings, supported); 251 ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); 252 253 link_ksettings->base.speed = SPEED_UNKNOWN; 254 link_ksettings->base.autoneg = AUTONEG_DISABLE; 255 link_ksettings->base.duplex = DUPLEX_UNKNOWN; 256 257 err = hinic_port_get_cap(nic_dev, &port_cap); 258 if (err) 259 return err; 260 261 hinic_link_port_type(&settings, port_cap.port_type); 262 link_ksettings->base.port = settings.port; 263 264 err = hinic_port_link_state(nic_dev, &link_state); 265 if (err) 266 return err; 267 268 if (link_state == HINIC_LINK_STATE_UP) { 269 set_link_speed(link_ksettings, port_cap.speed); 270 link_ksettings->base.duplex = 271 (port_cap.duplex == HINIC_DUPLEX_FULL) ? 272 DUPLEX_FULL : DUPLEX_HALF; 273 } 274 275 if (!!(port_cap.autoneg_cap & HINIC_AUTONEG_SUPPORTED)) 276 ethtool_link_ksettings_add_link_mode(link_ksettings, 277 advertising, Autoneg); 278 279 if (port_cap.autoneg_state == HINIC_AUTONEG_ACTIVE) 280 link_ksettings->base.autoneg = AUTONEG_ENABLE; 281 282 err = hinic_get_link_mode(nic_dev->hwdev, &link_mode); 283 if (err || link_mode.supported == HINIC_SUPPORTED_UNKNOWN || 284 link_mode.advertised == HINIC_SUPPORTED_UNKNOWN) 285 return -EIO; 286 287 hinic_add_ethtool_link_mode(&settings, link_mode.supported, 288 GET_SUPPORTED_MODE); 289 hinic_add_ethtool_link_mode(&settings, link_mode.advertised, 290 GET_ADVERTISED_MODE); 291 292 if (!HINIC_IS_VF(nic_dev->hwdev->hwif)) { 293 err = hinic_get_hw_pause_info(nic_dev->hwdev, &pause_info); 294 if (err) 295 return err; 296 ETHTOOL_ADD_SUPPORTED_LINK_MODE(&settings, Pause); 297 if (pause_info.rx_pause && pause_info.tx_pause) { 298 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Pause); 299 } else if (pause_info.tx_pause) { 300 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Asym_Pause); 301 } else if (pause_info.rx_pause) { 302 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Pause); 303 ETHTOOL_ADD_ADVERTISED_LINK_MODE(&settings, Asym_Pause); 304 } 305 } 306 307 bitmap_copy(link_ksettings->link_modes.supported, 308 (unsigned long *)&settings.supported, 309 __ETHTOOL_LINK_MODE_MASK_NBITS); 310 bitmap_copy(link_ksettings->link_modes.advertising, 311 (unsigned long *)&settings.advertising, 312 __ETHTOOL_LINK_MODE_MASK_NBITS); 313 314 return 0; 315 } 316 317 static int hinic_ethtool_to_hw_speed_level(u32 speed) 318 { 319 int i; 320 321 for (i = 0; i < LINK_SPEED_LEVELS; i++) { 322 if (hw_to_ethtool_speed[i] == speed) 323 break; 324 } 325 326 return i; 327 } 328 329 static bool hinic_is_support_speed(enum hinic_link_mode supported_link, 330 u32 speed) 331 { 332 enum hinic_link_mode link_mode; 333 int idx; 334 335 for (link_mode = 0; link_mode < HINIC_LINK_MODE_NUMBERS; link_mode++) { 336 if (!(supported_link & ((u32)1 << link_mode))) 337 continue; 338 339 idx = hinic_get_link_mode_index(link_mode); 340 if (idx >= HINIC_LINK_MODE_NUMBERS) 341 continue; 342 343 if (hw_to_ethtool_link_mode_table[idx].speed == speed) 344 return true; 345 } 346 347 return false; 348 } 349 350 static bool hinic_is_speed_legal(struct hinic_dev *nic_dev, u32 speed) 351 { 352 struct hinic_link_mode_cmd link_mode = { 0 }; 353 struct net_device *netdev = nic_dev->netdev; 354 enum nic_speed_level speed_level = 0; 355 int err; 356 357 err = hinic_get_link_mode(nic_dev->hwdev, &link_mode); 358 if (err) 359 return false; 360 361 if (link_mode.supported == HINIC_SUPPORTED_UNKNOWN || 362 link_mode.advertised == HINIC_SUPPORTED_UNKNOWN) 363 return false; 364 365 speed_level = hinic_ethtool_to_hw_speed_level(speed); 366 if (speed_level >= LINK_SPEED_LEVELS || 367 !hinic_is_support_speed(link_mode.supported, speed)) { 368 netif_err(nic_dev, drv, netdev, 369 "Unsupported speed: %d\n", speed); 370 return false; 371 } 372 373 return true; 374 } 375 376 static int get_link_settings_type(struct hinic_dev *nic_dev, 377 u8 autoneg, u32 speed, u32 *set_settings) 378 { 379 struct hinic_port_cap port_cap = { 0 }; 380 int err; 381 382 err = hinic_port_get_cap(nic_dev, &port_cap); 383 if (err) 384 return err; 385 386 /* always set autonegotiation */ 387 if (port_cap.autoneg_cap) 388 *set_settings |= HILINK_LINK_SET_AUTONEG; 389 390 if (autoneg == AUTONEG_ENABLE) { 391 if (!port_cap.autoneg_cap) { 392 netif_err(nic_dev, drv, nic_dev->netdev, "Not support autoneg\n"); 393 return -EOPNOTSUPP; 394 } 395 } else if (speed != (u32)SPEED_UNKNOWN) { 396 /* set speed only when autoneg is disabled */ 397 if (!hinic_is_speed_legal(nic_dev, speed)) 398 return -EINVAL; 399 *set_settings |= HILINK_LINK_SET_SPEED; 400 } else { 401 netif_err(nic_dev, drv, nic_dev->netdev, "Need to set speed when autoneg is off\n"); 402 return -EOPNOTSUPP; 403 } 404 405 return 0; 406 } 407 408 static int set_link_settings_separate_cmd(struct hinic_dev *nic_dev, 409 u32 set_settings, u8 autoneg, 410 u32 speed) 411 { 412 enum nic_speed_level speed_level = 0; 413 int err = 0; 414 415 if (set_settings & HILINK_LINK_SET_AUTONEG) { 416 err = hinic_set_autoneg(nic_dev->hwdev, 417 (autoneg == AUTONEG_ENABLE)); 418 if (err) 419 netif_err(nic_dev, drv, nic_dev->netdev, "%s autoneg failed\n", 420 (autoneg == AUTONEG_ENABLE) ? 421 "Enable" : "Disable"); 422 else 423 netif_info(nic_dev, drv, nic_dev->netdev, "%s autoneg successfully\n", 424 (autoneg == AUTONEG_ENABLE) ? 425 "Enable" : "Disable"); 426 } 427 428 if (!err && (set_settings & HILINK_LINK_SET_SPEED)) { 429 speed_level = hinic_ethtool_to_hw_speed_level(speed); 430 err = hinic_set_speed(nic_dev->hwdev, speed_level); 431 if (err) 432 netif_err(nic_dev, drv, nic_dev->netdev, "Set speed %d failed\n", 433 speed); 434 else 435 netif_info(nic_dev, drv, nic_dev->netdev, "Set speed %d successfully\n", 436 speed); 437 } 438 439 return err; 440 } 441 442 static int hinic_set_settings_to_hw(struct hinic_dev *nic_dev, 443 u32 set_settings, u8 autoneg, u32 speed) 444 { 445 struct hinic_link_ksettings_info settings = {0}; 446 char set_link_str[SET_LINK_STR_MAX_LEN] = {0}; 447 struct net_device *netdev = nic_dev->netdev; 448 enum nic_speed_level speed_level = 0; 449 int err; 450 451 err = snprintf(set_link_str, SET_LINK_STR_MAX_LEN, "%s", 452 (set_settings & HILINK_LINK_SET_AUTONEG) ? 453 (autoneg ? "autong enable " : "autong disable ") : ""); 454 if (err < 0 || err >= SET_LINK_STR_MAX_LEN) { 455 netif_err(nic_dev, drv, netdev, "Failed to snprintf link state, function return(%d) and dest_len(%d)\n", 456 err, SET_LINK_STR_MAX_LEN); 457 return -EFAULT; 458 } 459 460 if (set_settings & HILINK_LINK_SET_SPEED) { 461 speed_level = hinic_ethtool_to_hw_speed_level(speed); 462 err = snprintf(set_link_str, SET_LINK_STR_MAX_LEN, 463 "%sspeed %d ", set_link_str, speed); 464 if (err <= 0 || err >= SET_LINK_STR_MAX_LEN) { 465 netif_err(nic_dev, drv, netdev, "Failed to snprintf link speed, function return(%d) and dest_len(%d)\n", 466 err, SET_LINK_STR_MAX_LEN); 467 return -EFAULT; 468 } 469 } 470 471 settings.func_id = HINIC_HWIF_FUNC_IDX(nic_dev->hwdev->hwif); 472 settings.valid_bitmap = set_settings; 473 settings.autoneg = autoneg; 474 settings.speed = speed_level; 475 476 err = hinic_set_link_settings(nic_dev->hwdev, &settings); 477 if (err != HINIC_MGMT_CMD_UNSUPPORTED) { 478 if (err) 479 netif_err(nic_dev, drv, netdev, "Set %s failed\n", 480 set_link_str); 481 else 482 netif_info(nic_dev, drv, netdev, "Set %s successfully\n", 483 set_link_str); 484 485 return err; 486 } 487 488 return set_link_settings_separate_cmd(nic_dev, set_settings, autoneg, 489 speed); 490 } 491 492 static int set_link_settings(struct net_device *netdev, u8 autoneg, u32 speed) 493 { 494 struct hinic_dev *nic_dev = netdev_priv(netdev); 495 u32 set_settings = 0; 496 int err; 497 498 err = get_link_settings_type(nic_dev, autoneg, speed, &set_settings); 499 if (err) 500 return err; 501 502 if (set_settings) 503 err = hinic_set_settings_to_hw(nic_dev, set_settings, 504 autoneg, speed); 505 else 506 netif_info(nic_dev, drv, netdev, "Nothing changed, exit without setting anything\n"); 507 508 return err; 509 } 510 511 static int hinic_set_link_ksettings(struct net_device *netdev, const struct 512 ethtool_link_ksettings *link_settings) 513 { 514 /* only support to set autoneg and speed */ 515 return set_link_settings(netdev, link_settings->base.autoneg, 516 link_settings->base.speed); 517 } 518 519 static void hinic_get_drvinfo(struct net_device *netdev, 520 struct ethtool_drvinfo *info) 521 { 522 struct hinic_dev *nic_dev = netdev_priv(netdev); 523 u8 mgmt_ver[HINIC_MGMT_VERSION_MAX_LEN] = {0}; 524 struct hinic_hwdev *hwdev = nic_dev->hwdev; 525 struct hinic_hwif *hwif = hwdev->hwif; 526 int err; 527 528 strlcpy(info->driver, HINIC_DRV_NAME, sizeof(info->driver)); 529 strlcpy(info->bus_info, pci_name(hwif->pdev), sizeof(info->bus_info)); 530 531 err = hinic_get_mgmt_version(nic_dev, mgmt_ver); 532 if (err) 533 return; 534 535 snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver); 536 } 537 538 static void hinic_get_ringparam(struct net_device *netdev, 539 struct ethtool_ringparam *ring) 540 { 541 struct hinic_dev *nic_dev = netdev_priv(netdev); 542 543 ring->rx_max_pending = HINIC_MAX_QUEUE_DEPTH; 544 ring->tx_max_pending = HINIC_MAX_QUEUE_DEPTH; 545 ring->rx_pending = nic_dev->rq_depth; 546 ring->tx_pending = nic_dev->sq_depth; 547 } 548 549 static int check_ringparam_valid(struct hinic_dev *nic_dev, 550 struct ethtool_ringparam *ring) 551 { 552 if (ring->rx_jumbo_pending || ring->rx_mini_pending) { 553 netif_err(nic_dev, drv, nic_dev->netdev, 554 "Unsupported rx_jumbo_pending/rx_mini_pending\n"); 555 return -EINVAL; 556 } 557 558 if (ring->tx_pending > HINIC_MAX_QUEUE_DEPTH || 559 ring->tx_pending < HINIC_MIN_QUEUE_DEPTH || 560 ring->rx_pending > HINIC_MAX_QUEUE_DEPTH || 561 ring->rx_pending < HINIC_MIN_QUEUE_DEPTH) { 562 netif_err(nic_dev, drv, nic_dev->netdev, 563 "Queue depth out of range [%d-%d]\n", 564 HINIC_MIN_QUEUE_DEPTH, HINIC_MAX_QUEUE_DEPTH); 565 return -EINVAL; 566 } 567 568 return 0; 569 } 570 571 static int hinic_set_ringparam(struct net_device *netdev, 572 struct ethtool_ringparam *ring) 573 { 574 struct hinic_dev *nic_dev = netdev_priv(netdev); 575 u16 new_sq_depth, new_rq_depth; 576 int err; 577 578 err = check_ringparam_valid(nic_dev, ring); 579 if (err) 580 return err; 581 582 new_sq_depth = (u16)(1U << (u16)ilog2(ring->tx_pending)); 583 new_rq_depth = (u16)(1U << (u16)ilog2(ring->rx_pending)); 584 585 if (new_sq_depth == nic_dev->sq_depth && 586 new_rq_depth == nic_dev->rq_depth) 587 return 0; 588 589 netif_info(nic_dev, drv, netdev, 590 "Change Tx/Rx ring depth from %d/%d to %d/%d\n", 591 nic_dev->sq_depth, nic_dev->rq_depth, 592 new_sq_depth, new_rq_depth); 593 594 nic_dev->sq_depth = new_sq_depth; 595 nic_dev->rq_depth = new_rq_depth; 596 597 if (netif_running(netdev)) { 598 netif_info(nic_dev, drv, netdev, "Restarting netdev\n"); 599 err = hinic_close(netdev); 600 if (err) { 601 netif_err(nic_dev, drv, netdev, 602 "Failed to close netdev\n"); 603 return -EFAULT; 604 } 605 606 err = hinic_open(netdev); 607 if (err) { 608 netif_err(nic_dev, drv, netdev, 609 "Failed to open netdev\n"); 610 return -EFAULT; 611 } 612 } 613 614 return 0; 615 } 616 static void hinic_get_channels(struct net_device *netdev, 617 struct ethtool_channels *channels) 618 { 619 struct hinic_dev *nic_dev = netdev_priv(netdev); 620 struct hinic_hwdev *hwdev = nic_dev->hwdev; 621 622 channels->max_rx = hwdev->nic_cap.max_qps; 623 channels->max_tx = hwdev->nic_cap.max_qps; 624 channels->max_other = 0; 625 channels->max_combined = 0; 626 channels->rx_count = hinic_hwdev_num_qps(hwdev); 627 channels->tx_count = hinic_hwdev_num_qps(hwdev); 628 channels->other_count = 0; 629 channels->combined_count = 0; 630 } 631 632 static int hinic_get_rss_hash_opts(struct hinic_dev *nic_dev, 633 struct ethtool_rxnfc *cmd) 634 { 635 struct hinic_rss_type rss_type = { 0 }; 636 int err; 637 638 cmd->data = 0; 639 640 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 641 return 0; 642 643 err = hinic_get_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 644 &rss_type); 645 if (err) 646 return err; 647 648 cmd->data = RXH_IP_SRC | RXH_IP_DST; 649 switch (cmd->flow_type) { 650 case TCP_V4_FLOW: 651 if (rss_type.tcp_ipv4) 652 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 653 break; 654 case TCP_V6_FLOW: 655 if (rss_type.tcp_ipv6) 656 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 657 break; 658 case UDP_V4_FLOW: 659 if (rss_type.udp_ipv4) 660 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 661 break; 662 case UDP_V6_FLOW: 663 if (rss_type.udp_ipv6) 664 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 665 break; 666 case IPV4_FLOW: 667 case IPV6_FLOW: 668 break; 669 default: 670 cmd->data = 0; 671 return -EINVAL; 672 } 673 674 return 0; 675 } 676 677 static int set_l4_rss_hash_ops(struct ethtool_rxnfc *cmd, 678 struct hinic_rss_type *rss_type) 679 { 680 u8 rss_l4_en = 0; 681 682 switch (cmd->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 683 case 0: 684 rss_l4_en = 0; 685 break; 686 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 687 rss_l4_en = 1; 688 break; 689 default: 690 return -EINVAL; 691 } 692 693 switch (cmd->flow_type) { 694 case TCP_V4_FLOW: 695 rss_type->tcp_ipv4 = rss_l4_en; 696 break; 697 case TCP_V6_FLOW: 698 rss_type->tcp_ipv6 = rss_l4_en; 699 break; 700 case UDP_V4_FLOW: 701 rss_type->udp_ipv4 = rss_l4_en; 702 break; 703 case UDP_V6_FLOW: 704 rss_type->udp_ipv6 = rss_l4_en; 705 break; 706 default: 707 return -EINVAL; 708 } 709 710 return 0; 711 } 712 713 static int hinic_set_rss_hash_opts(struct hinic_dev *nic_dev, 714 struct ethtool_rxnfc *cmd) 715 { 716 struct hinic_rss_type *rss_type = &nic_dev->rss_type; 717 int err; 718 719 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) { 720 cmd->data = 0; 721 return -EOPNOTSUPP; 722 } 723 724 /* RSS does not support anything other than hashing 725 * to queues on src and dst IPs and ports 726 */ 727 if (cmd->data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | 728 RXH_L4_B_2_3)) 729 return -EINVAL; 730 731 /* We need at least the IP SRC and DEST fields for hashing */ 732 if (!(cmd->data & RXH_IP_SRC) || !(cmd->data & RXH_IP_DST)) 733 return -EINVAL; 734 735 err = hinic_get_rss_type(nic_dev, 736 nic_dev->rss_tmpl_idx, rss_type); 737 if (err) 738 return -EFAULT; 739 740 switch (cmd->flow_type) { 741 case TCP_V4_FLOW: 742 case TCP_V6_FLOW: 743 case UDP_V4_FLOW: 744 case UDP_V6_FLOW: 745 err = set_l4_rss_hash_ops(cmd, rss_type); 746 if (err) 747 return err; 748 break; 749 case IPV4_FLOW: 750 rss_type->ipv4 = 1; 751 break; 752 case IPV6_FLOW: 753 rss_type->ipv6 = 1; 754 break; 755 default: 756 return -EINVAL; 757 } 758 759 err = hinic_set_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 760 *rss_type); 761 if (err) 762 return -EFAULT; 763 764 return 0; 765 } 766 767 static int __set_rss_rxfh(struct net_device *netdev, 768 const u32 *indir, const u8 *key) 769 { 770 struct hinic_dev *nic_dev = netdev_priv(netdev); 771 int err; 772 773 if (indir) { 774 if (!nic_dev->rss_indir_user) { 775 nic_dev->rss_indir_user = 776 kzalloc(sizeof(u32) * HINIC_RSS_INDIR_SIZE, 777 GFP_KERNEL); 778 if (!nic_dev->rss_indir_user) 779 return -ENOMEM; 780 } 781 782 memcpy(nic_dev->rss_indir_user, indir, 783 sizeof(u32) * HINIC_RSS_INDIR_SIZE); 784 785 err = hinic_rss_set_indir_tbl(nic_dev, 786 nic_dev->rss_tmpl_idx, indir); 787 if (err) 788 return -EFAULT; 789 } 790 791 if (key) { 792 if (!nic_dev->rss_hkey_user) { 793 nic_dev->rss_hkey_user = 794 kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL); 795 796 if (!nic_dev->rss_hkey_user) 797 return -ENOMEM; 798 } 799 800 memcpy(nic_dev->rss_hkey_user, key, HINIC_RSS_KEY_SIZE); 801 802 err = hinic_rss_set_template_tbl(nic_dev, 803 nic_dev->rss_tmpl_idx, key); 804 if (err) 805 return -EFAULT; 806 } 807 808 return 0; 809 } 810 811 static int hinic_get_rxnfc(struct net_device *netdev, 812 struct ethtool_rxnfc *cmd, u32 *rule_locs) 813 { 814 struct hinic_dev *nic_dev = netdev_priv(netdev); 815 int err = 0; 816 817 switch (cmd->cmd) { 818 case ETHTOOL_GRXRINGS: 819 cmd->data = nic_dev->num_qps; 820 break; 821 case ETHTOOL_GRXFH: 822 err = hinic_get_rss_hash_opts(nic_dev, cmd); 823 break; 824 default: 825 err = -EOPNOTSUPP; 826 break; 827 } 828 829 return err; 830 } 831 832 static int hinic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) 833 { 834 struct hinic_dev *nic_dev = netdev_priv(netdev); 835 int err = 0; 836 837 switch (cmd->cmd) { 838 case ETHTOOL_SRXFH: 839 err = hinic_set_rss_hash_opts(nic_dev, cmd); 840 break; 841 default: 842 err = -EOPNOTSUPP; 843 break; 844 } 845 846 return err; 847 } 848 849 static int hinic_get_rxfh(struct net_device *netdev, 850 u32 *indir, u8 *key, u8 *hfunc) 851 { 852 struct hinic_dev *nic_dev = netdev_priv(netdev); 853 u8 hash_engine_type = 0; 854 int err = 0; 855 856 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 857 return -EOPNOTSUPP; 858 859 if (hfunc) { 860 err = hinic_rss_get_hash_engine(nic_dev, 861 nic_dev->rss_tmpl_idx, 862 &hash_engine_type); 863 if (err) 864 return -EFAULT; 865 866 *hfunc = hash_engine_type ? ETH_RSS_HASH_TOP : ETH_RSS_HASH_XOR; 867 } 868 869 if (indir) { 870 err = hinic_rss_get_indir_tbl(nic_dev, 871 nic_dev->rss_tmpl_idx, indir); 872 if (err) 873 return -EFAULT; 874 } 875 876 if (key) 877 err = hinic_rss_get_template_tbl(nic_dev, 878 nic_dev->rss_tmpl_idx, key); 879 880 return err; 881 } 882 883 static int hinic_set_rxfh(struct net_device *netdev, const u32 *indir, 884 const u8 *key, const u8 hfunc) 885 { 886 struct hinic_dev *nic_dev = netdev_priv(netdev); 887 int err = 0; 888 889 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 890 return -EOPNOTSUPP; 891 892 if (hfunc != ETH_RSS_HASH_NO_CHANGE) { 893 if (hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR) 894 return -EOPNOTSUPP; 895 896 nic_dev->rss_hash_engine = (hfunc == ETH_RSS_HASH_XOR) ? 897 HINIC_RSS_HASH_ENGINE_TYPE_XOR : 898 HINIC_RSS_HASH_ENGINE_TYPE_TOEP; 899 err = hinic_rss_set_hash_engine 900 (nic_dev, nic_dev->rss_tmpl_idx, 901 nic_dev->rss_hash_engine); 902 if (err) 903 return -EFAULT; 904 } 905 906 err = __set_rss_rxfh(netdev, indir, key); 907 908 return err; 909 } 910 911 static u32 hinic_get_rxfh_key_size(struct net_device *netdev) 912 { 913 return HINIC_RSS_KEY_SIZE; 914 } 915 916 static u32 hinic_get_rxfh_indir_size(struct net_device *netdev) 917 { 918 return HINIC_RSS_INDIR_SIZE; 919 } 920 921 #define ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof(arr[0]))) 922 923 #define HINIC_FUNC_STAT(_stat_item) { \ 924 .name = #_stat_item, \ 925 .size = sizeof_field(struct hinic_vport_stats, _stat_item), \ 926 .offset = offsetof(struct hinic_vport_stats, _stat_item) \ 927 } 928 929 static struct hinic_stats hinic_function_stats[] = { 930 HINIC_FUNC_STAT(tx_unicast_pkts_vport), 931 HINIC_FUNC_STAT(tx_unicast_bytes_vport), 932 HINIC_FUNC_STAT(tx_multicast_pkts_vport), 933 HINIC_FUNC_STAT(tx_multicast_bytes_vport), 934 HINIC_FUNC_STAT(tx_broadcast_pkts_vport), 935 HINIC_FUNC_STAT(tx_broadcast_bytes_vport), 936 937 HINIC_FUNC_STAT(rx_unicast_pkts_vport), 938 HINIC_FUNC_STAT(rx_unicast_bytes_vport), 939 HINIC_FUNC_STAT(rx_multicast_pkts_vport), 940 HINIC_FUNC_STAT(rx_multicast_bytes_vport), 941 HINIC_FUNC_STAT(rx_broadcast_pkts_vport), 942 HINIC_FUNC_STAT(rx_broadcast_bytes_vport), 943 944 HINIC_FUNC_STAT(tx_discard_vport), 945 HINIC_FUNC_STAT(rx_discard_vport), 946 HINIC_FUNC_STAT(tx_err_vport), 947 HINIC_FUNC_STAT(rx_err_vport), 948 }; 949 950 #define HINIC_PORT_STAT(_stat_item) { \ 951 .name = #_stat_item, \ 952 .size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \ 953 .offset = offsetof(struct hinic_phy_port_stats, _stat_item) \ 954 } 955 956 static struct hinic_stats hinic_port_stats[] = { 957 HINIC_PORT_STAT(mac_rx_total_pkt_num), 958 HINIC_PORT_STAT(mac_rx_total_oct_num), 959 HINIC_PORT_STAT(mac_rx_bad_pkt_num), 960 HINIC_PORT_STAT(mac_rx_bad_oct_num), 961 HINIC_PORT_STAT(mac_rx_good_pkt_num), 962 HINIC_PORT_STAT(mac_rx_good_oct_num), 963 HINIC_PORT_STAT(mac_rx_uni_pkt_num), 964 HINIC_PORT_STAT(mac_rx_multi_pkt_num), 965 HINIC_PORT_STAT(mac_rx_broad_pkt_num), 966 HINIC_PORT_STAT(mac_tx_total_pkt_num), 967 HINIC_PORT_STAT(mac_tx_total_oct_num), 968 HINIC_PORT_STAT(mac_tx_bad_pkt_num), 969 HINIC_PORT_STAT(mac_tx_bad_oct_num), 970 HINIC_PORT_STAT(mac_tx_good_pkt_num), 971 HINIC_PORT_STAT(mac_tx_good_oct_num), 972 HINIC_PORT_STAT(mac_tx_uni_pkt_num), 973 HINIC_PORT_STAT(mac_tx_multi_pkt_num), 974 HINIC_PORT_STAT(mac_tx_broad_pkt_num), 975 HINIC_PORT_STAT(mac_rx_fragment_pkt_num), 976 HINIC_PORT_STAT(mac_rx_undersize_pkt_num), 977 HINIC_PORT_STAT(mac_rx_undermin_pkt_num), 978 HINIC_PORT_STAT(mac_rx_64_oct_pkt_num), 979 HINIC_PORT_STAT(mac_rx_65_127_oct_pkt_num), 980 HINIC_PORT_STAT(mac_rx_128_255_oct_pkt_num), 981 HINIC_PORT_STAT(mac_rx_256_511_oct_pkt_num), 982 HINIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num), 983 HINIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num), 984 HINIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num), 985 HINIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num), 986 HINIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num), 987 HINIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num), 988 HINIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num), 989 HINIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num), 990 HINIC_PORT_STAT(mac_rx_1519_max_good_pkt_num), 991 HINIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num), 992 HINIC_PORT_STAT(mac_rx_oversize_pkt_num), 993 HINIC_PORT_STAT(mac_rx_jabber_pkt_num), 994 HINIC_PORT_STAT(mac_rx_pause_num), 995 HINIC_PORT_STAT(mac_rx_pfc_pkt_num), 996 HINIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num), 997 HINIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num), 998 HINIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num), 999 HINIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num), 1000 HINIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num), 1001 HINIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num), 1002 HINIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num), 1003 HINIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num), 1004 HINIC_PORT_STAT(mac_rx_control_pkt_num), 1005 HINIC_PORT_STAT(mac_rx_sym_err_pkt_num), 1006 HINIC_PORT_STAT(mac_rx_fcs_err_pkt_num), 1007 HINIC_PORT_STAT(mac_rx_send_app_good_pkt_num), 1008 HINIC_PORT_STAT(mac_rx_send_app_bad_pkt_num), 1009 HINIC_PORT_STAT(mac_tx_fragment_pkt_num), 1010 HINIC_PORT_STAT(mac_tx_undersize_pkt_num), 1011 HINIC_PORT_STAT(mac_tx_undermin_pkt_num), 1012 HINIC_PORT_STAT(mac_tx_64_oct_pkt_num), 1013 HINIC_PORT_STAT(mac_tx_65_127_oct_pkt_num), 1014 HINIC_PORT_STAT(mac_tx_128_255_oct_pkt_num), 1015 HINIC_PORT_STAT(mac_tx_256_511_oct_pkt_num), 1016 HINIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num), 1017 HINIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num), 1018 HINIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num), 1019 HINIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num), 1020 HINIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num), 1021 HINIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num), 1022 HINIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num), 1023 HINIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num), 1024 HINIC_PORT_STAT(mac_tx_1519_max_good_pkt_num), 1025 HINIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num), 1026 HINIC_PORT_STAT(mac_tx_oversize_pkt_num), 1027 HINIC_PORT_STAT(mac_tx_jabber_pkt_num), 1028 HINIC_PORT_STAT(mac_tx_pause_num), 1029 HINIC_PORT_STAT(mac_tx_pfc_pkt_num), 1030 HINIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num), 1031 HINIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num), 1032 HINIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num), 1033 HINIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num), 1034 HINIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num), 1035 HINIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num), 1036 HINIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num), 1037 HINIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num), 1038 HINIC_PORT_STAT(mac_tx_control_pkt_num), 1039 HINIC_PORT_STAT(mac_tx_err_all_pkt_num), 1040 HINIC_PORT_STAT(mac_tx_from_app_good_pkt_num), 1041 HINIC_PORT_STAT(mac_tx_from_app_bad_pkt_num), 1042 }; 1043 1044 #define HINIC_TXQ_STAT(_stat_item) { \ 1045 .name = "txq%d_"#_stat_item, \ 1046 .size = sizeof_field(struct hinic_txq_stats, _stat_item), \ 1047 .offset = offsetof(struct hinic_txq_stats, _stat_item) \ 1048 } 1049 1050 static struct hinic_stats hinic_tx_queue_stats[] = { 1051 HINIC_TXQ_STAT(pkts), 1052 HINIC_TXQ_STAT(bytes), 1053 HINIC_TXQ_STAT(tx_busy), 1054 HINIC_TXQ_STAT(tx_wake), 1055 HINIC_TXQ_STAT(tx_dropped), 1056 HINIC_TXQ_STAT(big_frags_pkts), 1057 }; 1058 1059 #define HINIC_RXQ_STAT(_stat_item) { \ 1060 .name = "rxq%d_"#_stat_item, \ 1061 .size = sizeof_field(struct hinic_rxq_stats, _stat_item), \ 1062 .offset = offsetof(struct hinic_rxq_stats, _stat_item) \ 1063 } 1064 1065 static struct hinic_stats hinic_rx_queue_stats[] = { 1066 HINIC_RXQ_STAT(pkts), 1067 HINIC_RXQ_STAT(bytes), 1068 HINIC_RXQ_STAT(errors), 1069 HINIC_RXQ_STAT(csum_errors), 1070 HINIC_RXQ_STAT(other_errors), 1071 }; 1072 1073 static void get_drv_queue_stats(struct hinic_dev *nic_dev, u64 *data) 1074 { 1075 struct hinic_txq_stats txq_stats; 1076 struct hinic_rxq_stats rxq_stats; 1077 u16 i = 0, j = 0, qid = 0; 1078 char *p; 1079 1080 for (qid = 0; qid < nic_dev->num_qps; qid++) { 1081 if (!nic_dev->txqs) 1082 break; 1083 1084 hinic_txq_get_stats(&nic_dev->txqs[qid], &txq_stats); 1085 for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++, i++) { 1086 p = (char *)&txq_stats + 1087 hinic_tx_queue_stats[j].offset; 1088 data[i] = (hinic_tx_queue_stats[j].size == 1089 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1090 } 1091 } 1092 1093 for (qid = 0; qid < nic_dev->num_qps; qid++) { 1094 if (!nic_dev->rxqs) 1095 break; 1096 1097 hinic_rxq_get_stats(&nic_dev->rxqs[qid], &rxq_stats); 1098 for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++, i++) { 1099 p = (char *)&rxq_stats + 1100 hinic_rx_queue_stats[j].offset; 1101 data[i] = (hinic_rx_queue_stats[j].size == 1102 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1103 } 1104 } 1105 } 1106 1107 static void hinic_get_ethtool_stats(struct net_device *netdev, 1108 struct ethtool_stats *stats, u64 *data) 1109 { 1110 struct hinic_dev *nic_dev = netdev_priv(netdev); 1111 struct hinic_vport_stats vport_stats = {0}; 1112 struct hinic_phy_port_stats *port_stats; 1113 u16 i = 0, j = 0; 1114 char *p; 1115 int err; 1116 1117 err = hinic_get_vport_stats(nic_dev, &vport_stats); 1118 if (err) 1119 netif_err(nic_dev, drv, netdev, 1120 "Failed to get vport stats from firmware\n"); 1121 1122 for (j = 0; j < ARRAY_LEN(hinic_function_stats); j++, i++) { 1123 p = (char *)&vport_stats + hinic_function_stats[j].offset; 1124 data[i] = (hinic_function_stats[j].size == 1125 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1126 } 1127 1128 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); 1129 if (!port_stats) { 1130 memset(&data[i], 0, 1131 ARRAY_LEN(hinic_port_stats) * sizeof(*data)); 1132 i += ARRAY_LEN(hinic_port_stats); 1133 goto get_drv_stats; 1134 } 1135 1136 err = hinic_get_phy_port_stats(nic_dev, port_stats); 1137 if (err) 1138 netif_err(nic_dev, drv, netdev, 1139 "Failed to get port stats from firmware\n"); 1140 1141 for (j = 0; j < ARRAY_LEN(hinic_port_stats); j++, i++) { 1142 p = (char *)port_stats + hinic_port_stats[j].offset; 1143 data[i] = (hinic_port_stats[j].size == 1144 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1145 } 1146 1147 kfree(port_stats); 1148 1149 get_drv_stats: 1150 get_drv_queue_stats(nic_dev, data + i); 1151 } 1152 1153 static int hinic_get_sset_count(struct net_device *netdev, int sset) 1154 { 1155 struct hinic_dev *nic_dev = netdev_priv(netdev); 1156 int count, q_num; 1157 1158 switch (sset) { 1159 case ETH_SS_STATS: 1160 q_num = nic_dev->num_qps; 1161 count = ARRAY_LEN(hinic_function_stats) + 1162 (ARRAY_LEN(hinic_tx_queue_stats) + 1163 ARRAY_LEN(hinic_rx_queue_stats)) * q_num; 1164 1165 count += ARRAY_LEN(hinic_port_stats); 1166 1167 return count; 1168 default: 1169 return -EOPNOTSUPP; 1170 } 1171 } 1172 1173 static void hinic_get_strings(struct net_device *netdev, 1174 u32 stringset, u8 *data) 1175 { 1176 struct hinic_dev *nic_dev = netdev_priv(netdev); 1177 char *p = (char *)data; 1178 u16 i, j; 1179 1180 switch (stringset) { 1181 case ETH_SS_STATS: 1182 for (i = 0; i < ARRAY_LEN(hinic_function_stats); i++) { 1183 memcpy(p, hinic_function_stats[i].name, 1184 ETH_GSTRING_LEN); 1185 p += ETH_GSTRING_LEN; 1186 } 1187 1188 for (i = 0; i < ARRAY_LEN(hinic_port_stats); i++) { 1189 memcpy(p, hinic_port_stats[i].name, 1190 ETH_GSTRING_LEN); 1191 p += ETH_GSTRING_LEN; 1192 } 1193 1194 for (i = 0; i < nic_dev->num_qps; i++) { 1195 for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++) { 1196 sprintf(p, hinic_tx_queue_stats[j].name, i); 1197 p += ETH_GSTRING_LEN; 1198 } 1199 } 1200 1201 for (i = 0; i < nic_dev->num_qps; i++) { 1202 for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++) { 1203 sprintf(p, hinic_rx_queue_stats[j].name, i); 1204 p += ETH_GSTRING_LEN; 1205 } 1206 } 1207 1208 return; 1209 default: 1210 return; 1211 } 1212 } 1213 1214 static const struct ethtool_ops hinic_ethtool_ops = { 1215 .get_link_ksettings = hinic_get_link_ksettings, 1216 .set_link_ksettings = hinic_set_link_ksettings, 1217 .get_drvinfo = hinic_get_drvinfo, 1218 .get_link = ethtool_op_get_link, 1219 .get_ringparam = hinic_get_ringparam, 1220 .set_ringparam = hinic_set_ringparam, 1221 .get_channels = hinic_get_channels, 1222 .get_rxnfc = hinic_get_rxnfc, 1223 .set_rxnfc = hinic_set_rxnfc, 1224 .get_rxfh_key_size = hinic_get_rxfh_key_size, 1225 .get_rxfh_indir_size = hinic_get_rxfh_indir_size, 1226 .get_rxfh = hinic_get_rxfh, 1227 .set_rxfh = hinic_set_rxfh, 1228 .get_sset_count = hinic_get_sset_count, 1229 .get_ethtool_stats = hinic_get_ethtool_stats, 1230 .get_strings = hinic_get_strings, 1231 }; 1232 1233 void hinic_set_ethtool_ops(struct net_device *netdev) 1234 { 1235 netdev->ethtool_ops = &hinic_ethtool_ops; 1236 } 1237