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_combined = nic_dev->max_qps; 623 channels->combined_count = hinic_hwdev_num_qps(hwdev); 624 } 625 626 static int hinic_set_channels(struct net_device *netdev, 627 struct ethtool_channels *channels) 628 { 629 struct hinic_dev *nic_dev = netdev_priv(netdev); 630 unsigned int count = channels->combined_count; 631 int err; 632 633 netif_info(nic_dev, drv, netdev, "Set max combined queue number from %d to %d\n", 634 hinic_hwdev_num_qps(nic_dev->hwdev), count); 635 636 if (netif_running(netdev)) { 637 netif_info(nic_dev, drv, netdev, "Restarting netdev\n"); 638 hinic_close(netdev); 639 640 nic_dev->hwdev->nic_cap.num_qps = count; 641 642 err = hinic_open(netdev); 643 if (err) { 644 netif_err(nic_dev, drv, netdev, 645 "Failed to open netdev\n"); 646 return -EFAULT; 647 } 648 } else { 649 nic_dev->hwdev->nic_cap.num_qps = count; 650 } 651 652 return 0; 653 } 654 655 static int hinic_get_rss_hash_opts(struct hinic_dev *nic_dev, 656 struct ethtool_rxnfc *cmd) 657 { 658 struct hinic_rss_type rss_type = { 0 }; 659 int err; 660 661 cmd->data = 0; 662 663 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 664 return 0; 665 666 err = hinic_get_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 667 &rss_type); 668 if (err) 669 return err; 670 671 cmd->data = RXH_IP_SRC | RXH_IP_DST; 672 switch (cmd->flow_type) { 673 case TCP_V4_FLOW: 674 if (rss_type.tcp_ipv4) 675 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 676 break; 677 case TCP_V6_FLOW: 678 if (rss_type.tcp_ipv6) 679 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 680 break; 681 case UDP_V4_FLOW: 682 if (rss_type.udp_ipv4) 683 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 684 break; 685 case UDP_V6_FLOW: 686 if (rss_type.udp_ipv6) 687 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 688 break; 689 case IPV4_FLOW: 690 case IPV6_FLOW: 691 break; 692 default: 693 cmd->data = 0; 694 return -EINVAL; 695 } 696 697 return 0; 698 } 699 700 static int set_l4_rss_hash_ops(struct ethtool_rxnfc *cmd, 701 struct hinic_rss_type *rss_type) 702 { 703 u8 rss_l4_en = 0; 704 705 switch (cmd->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 706 case 0: 707 rss_l4_en = 0; 708 break; 709 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 710 rss_l4_en = 1; 711 break; 712 default: 713 return -EINVAL; 714 } 715 716 switch (cmd->flow_type) { 717 case TCP_V4_FLOW: 718 rss_type->tcp_ipv4 = rss_l4_en; 719 break; 720 case TCP_V6_FLOW: 721 rss_type->tcp_ipv6 = rss_l4_en; 722 break; 723 case UDP_V4_FLOW: 724 rss_type->udp_ipv4 = rss_l4_en; 725 break; 726 case UDP_V6_FLOW: 727 rss_type->udp_ipv6 = rss_l4_en; 728 break; 729 default: 730 return -EINVAL; 731 } 732 733 return 0; 734 } 735 736 static int hinic_set_rss_hash_opts(struct hinic_dev *nic_dev, 737 struct ethtool_rxnfc *cmd) 738 { 739 struct hinic_rss_type *rss_type = &nic_dev->rss_type; 740 int err; 741 742 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) { 743 cmd->data = 0; 744 return -EOPNOTSUPP; 745 } 746 747 /* RSS does not support anything other than hashing 748 * to queues on src and dst IPs and ports 749 */ 750 if (cmd->data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | 751 RXH_L4_B_2_3)) 752 return -EINVAL; 753 754 /* We need at least the IP SRC and DEST fields for hashing */ 755 if (!(cmd->data & RXH_IP_SRC) || !(cmd->data & RXH_IP_DST)) 756 return -EINVAL; 757 758 err = hinic_get_rss_type(nic_dev, 759 nic_dev->rss_tmpl_idx, rss_type); 760 if (err) 761 return -EFAULT; 762 763 switch (cmd->flow_type) { 764 case TCP_V4_FLOW: 765 case TCP_V6_FLOW: 766 case UDP_V4_FLOW: 767 case UDP_V6_FLOW: 768 err = set_l4_rss_hash_ops(cmd, rss_type); 769 if (err) 770 return err; 771 break; 772 case IPV4_FLOW: 773 rss_type->ipv4 = 1; 774 break; 775 case IPV6_FLOW: 776 rss_type->ipv6 = 1; 777 break; 778 default: 779 return -EINVAL; 780 } 781 782 err = hinic_set_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 783 *rss_type); 784 if (err) 785 return -EFAULT; 786 787 return 0; 788 } 789 790 static int __set_rss_rxfh(struct net_device *netdev, 791 const u32 *indir, const u8 *key) 792 { 793 struct hinic_dev *nic_dev = netdev_priv(netdev); 794 int err; 795 796 if (indir) { 797 if (!nic_dev->rss_indir_user) { 798 nic_dev->rss_indir_user = 799 kzalloc(sizeof(u32) * HINIC_RSS_INDIR_SIZE, 800 GFP_KERNEL); 801 if (!nic_dev->rss_indir_user) 802 return -ENOMEM; 803 } 804 805 memcpy(nic_dev->rss_indir_user, indir, 806 sizeof(u32) * HINIC_RSS_INDIR_SIZE); 807 808 err = hinic_rss_set_indir_tbl(nic_dev, 809 nic_dev->rss_tmpl_idx, indir); 810 if (err) 811 return -EFAULT; 812 } 813 814 if (key) { 815 if (!nic_dev->rss_hkey_user) { 816 nic_dev->rss_hkey_user = 817 kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL); 818 819 if (!nic_dev->rss_hkey_user) 820 return -ENOMEM; 821 } 822 823 memcpy(nic_dev->rss_hkey_user, key, HINIC_RSS_KEY_SIZE); 824 825 err = hinic_rss_set_template_tbl(nic_dev, 826 nic_dev->rss_tmpl_idx, key); 827 if (err) 828 return -EFAULT; 829 } 830 831 return 0; 832 } 833 834 static int hinic_get_rxnfc(struct net_device *netdev, 835 struct ethtool_rxnfc *cmd, u32 *rule_locs) 836 { 837 struct hinic_dev *nic_dev = netdev_priv(netdev); 838 int err = 0; 839 840 switch (cmd->cmd) { 841 case ETHTOOL_GRXRINGS: 842 cmd->data = nic_dev->num_qps; 843 break; 844 case ETHTOOL_GRXFH: 845 err = hinic_get_rss_hash_opts(nic_dev, cmd); 846 break; 847 default: 848 err = -EOPNOTSUPP; 849 break; 850 } 851 852 return err; 853 } 854 855 static int hinic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) 856 { 857 struct hinic_dev *nic_dev = netdev_priv(netdev); 858 int err = 0; 859 860 switch (cmd->cmd) { 861 case ETHTOOL_SRXFH: 862 err = hinic_set_rss_hash_opts(nic_dev, cmd); 863 break; 864 default: 865 err = -EOPNOTSUPP; 866 break; 867 } 868 869 return err; 870 } 871 872 static int hinic_get_rxfh(struct net_device *netdev, 873 u32 *indir, u8 *key, u8 *hfunc) 874 { 875 struct hinic_dev *nic_dev = netdev_priv(netdev); 876 u8 hash_engine_type = 0; 877 int err = 0; 878 879 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 880 return -EOPNOTSUPP; 881 882 if (hfunc) { 883 err = hinic_rss_get_hash_engine(nic_dev, 884 nic_dev->rss_tmpl_idx, 885 &hash_engine_type); 886 if (err) 887 return -EFAULT; 888 889 *hfunc = hash_engine_type ? ETH_RSS_HASH_TOP : ETH_RSS_HASH_XOR; 890 } 891 892 if (indir) { 893 err = hinic_rss_get_indir_tbl(nic_dev, 894 nic_dev->rss_tmpl_idx, indir); 895 if (err) 896 return -EFAULT; 897 } 898 899 if (key) 900 err = hinic_rss_get_template_tbl(nic_dev, 901 nic_dev->rss_tmpl_idx, key); 902 903 return err; 904 } 905 906 static int hinic_set_rxfh(struct net_device *netdev, const u32 *indir, 907 const u8 *key, const u8 hfunc) 908 { 909 struct hinic_dev *nic_dev = netdev_priv(netdev); 910 int err = 0; 911 912 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 913 return -EOPNOTSUPP; 914 915 if (hfunc != ETH_RSS_HASH_NO_CHANGE) { 916 if (hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR) 917 return -EOPNOTSUPP; 918 919 nic_dev->rss_hash_engine = (hfunc == ETH_RSS_HASH_XOR) ? 920 HINIC_RSS_HASH_ENGINE_TYPE_XOR : 921 HINIC_RSS_HASH_ENGINE_TYPE_TOEP; 922 err = hinic_rss_set_hash_engine 923 (nic_dev, nic_dev->rss_tmpl_idx, 924 nic_dev->rss_hash_engine); 925 if (err) 926 return -EFAULT; 927 } 928 929 err = __set_rss_rxfh(netdev, indir, key); 930 931 return err; 932 } 933 934 static u32 hinic_get_rxfh_key_size(struct net_device *netdev) 935 { 936 return HINIC_RSS_KEY_SIZE; 937 } 938 939 static u32 hinic_get_rxfh_indir_size(struct net_device *netdev) 940 { 941 return HINIC_RSS_INDIR_SIZE; 942 } 943 944 #define ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof(arr[0]))) 945 946 #define HINIC_FUNC_STAT(_stat_item) { \ 947 .name = #_stat_item, \ 948 .size = sizeof_field(struct hinic_vport_stats, _stat_item), \ 949 .offset = offsetof(struct hinic_vport_stats, _stat_item) \ 950 } 951 952 static struct hinic_stats hinic_function_stats[] = { 953 HINIC_FUNC_STAT(tx_unicast_pkts_vport), 954 HINIC_FUNC_STAT(tx_unicast_bytes_vport), 955 HINIC_FUNC_STAT(tx_multicast_pkts_vport), 956 HINIC_FUNC_STAT(tx_multicast_bytes_vport), 957 HINIC_FUNC_STAT(tx_broadcast_pkts_vport), 958 HINIC_FUNC_STAT(tx_broadcast_bytes_vport), 959 960 HINIC_FUNC_STAT(rx_unicast_pkts_vport), 961 HINIC_FUNC_STAT(rx_unicast_bytes_vport), 962 HINIC_FUNC_STAT(rx_multicast_pkts_vport), 963 HINIC_FUNC_STAT(rx_multicast_bytes_vport), 964 HINIC_FUNC_STAT(rx_broadcast_pkts_vport), 965 HINIC_FUNC_STAT(rx_broadcast_bytes_vport), 966 967 HINIC_FUNC_STAT(tx_discard_vport), 968 HINIC_FUNC_STAT(rx_discard_vport), 969 HINIC_FUNC_STAT(tx_err_vport), 970 HINIC_FUNC_STAT(rx_err_vport), 971 }; 972 973 #define HINIC_PORT_STAT(_stat_item) { \ 974 .name = #_stat_item, \ 975 .size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \ 976 .offset = offsetof(struct hinic_phy_port_stats, _stat_item) \ 977 } 978 979 static struct hinic_stats hinic_port_stats[] = { 980 HINIC_PORT_STAT(mac_rx_total_pkt_num), 981 HINIC_PORT_STAT(mac_rx_total_oct_num), 982 HINIC_PORT_STAT(mac_rx_bad_pkt_num), 983 HINIC_PORT_STAT(mac_rx_bad_oct_num), 984 HINIC_PORT_STAT(mac_rx_good_pkt_num), 985 HINIC_PORT_STAT(mac_rx_good_oct_num), 986 HINIC_PORT_STAT(mac_rx_uni_pkt_num), 987 HINIC_PORT_STAT(mac_rx_multi_pkt_num), 988 HINIC_PORT_STAT(mac_rx_broad_pkt_num), 989 HINIC_PORT_STAT(mac_tx_total_pkt_num), 990 HINIC_PORT_STAT(mac_tx_total_oct_num), 991 HINIC_PORT_STAT(mac_tx_bad_pkt_num), 992 HINIC_PORT_STAT(mac_tx_bad_oct_num), 993 HINIC_PORT_STAT(mac_tx_good_pkt_num), 994 HINIC_PORT_STAT(mac_tx_good_oct_num), 995 HINIC_PORT_STAT(mac_tx_uni_pkt_num), 996 HINIC_PORT_STAT(mac_tx_multi_pkt_num), 997 HINIC_PORT_STAT(mac_tx_broad_pkt_num), 998 HINIC_PORT_STAT(mac_rx_fragment_pkt_num), 999 HINIC_PORT_STAT(mac_rx_undersize_pkt_num), 1000 HINIC_PORT_STAT(mac_rx_undermin_pkt_num), 1001 HINIC_PORT_STAT(mac_rx_64_oct_pkt_num), 1002 HINIC_PORT_STAT(mac_rx_65_127_oct_pkt_num), 1003 HINIC_PORT_STAT(mac_rx_128_255_oct_pkt_num), 1004 HINIC_PORT_STAT(mac_rx_256_511_oct_pkt_num), 1005 HINIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num), 1006 HINIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num), 1007 HINIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num), 1008 HINIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num), 1009 HINIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num), 1010 HINIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num), 1011 HINIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num), 1012 HINIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num), 1013 HINIC_PORT_STAT(mac_rx_1519_max_good_pkt_num), 1014 HINIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num), 1015 HINIC_PORT_STAT(mac_rx_oversize_pkt_num), 1016 HINIC_PORT_STAT(mac_rx_jabber_pkt_num), 1017 HINIC_PORT_STAT(mac_rx_pause_num), 1018 HINIC_PORT_STAT(mac_rx_pfc_pkt_num), 1019 HINIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num), 1020 HINIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num), 1021 HINIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num), 1022 HINIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num), 1023 HINIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num), 1024 HINIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num), 1025 HINIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num), 1026 HINIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num), 1027 HINIC_PORT_STAT(mac_rx_control_pkt_num), 1028 HINIC_PORT_STAT(mac_rx_sym_err_pkt_num), 1029 HINIC_PORT_STAT(mac_rx_fcs_err_pkt_num), 1030 HINIC_PORT_STAT(mac_rx_send_app_good_pkt_num), 1031 HINIC_PORT_STAT(mac_rx_send_app_bad_pkt_num), 1032 HINIC_PORT_STAT(mac_tx_fragment_pkt_num), 1033 HINIC_PORT_STAT(mac_tx_undersize_pkt_num), 1034 HINIC_PORT_STAT(mac_tx_undermin_pkt_num), 1035 HINIC_PORT_STAT(mac_tx_64_oct_pkt_num), 1036 HINIC_PORT_STAT(mac_tx_65_127_oct_pkt_num), 1037 HINIC_PORT_STAT(mac_tx_128_255_oct_pkt_num), 1038 HINIC_PORT_STAT(mac_tx_256_511_oct_pkt_num), 1039 HINIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num), 1040 HINIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num), 1041 HINIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num), 1042 HINIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num), 1043 HINIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num), 1044 HINIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num), 1045 HINIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num), 1046 HINIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num), 1047 HINIC_PORT_STAT(mac_tx_1519_max_good_pkt_num), 1048 HINIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num), 1049 HINIC_PORT_STAT(mac_tx_oversize_pkt_num), 1050 HINIC_PORT_STAT(mac_tx_jabber_pkt_num), 1051 HINIC_PORT_STAT(mac_tx_pause_num), 1052 HINIC_PORT_STAT(mac_tx_pfc_pkt_num), 1053 HINIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num), 1054 HINIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num), 1055 HINIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num), 1056 HINIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num), 1057 HINIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num), 1058 HINIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num), 1059 HINIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num), 1060 HINIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num), 1061 HINIC_PORT_STAT(mac_tx_control_pkt_num), 1062 HINIC_PORT_STAT(mac_tx_err_all_pkt_num), 1063 HINIC_PORT_STAT(mac_tx_from_app_good_pkt_num), 1064 HINIC_PORT_STAT(mac_tx_from_app_bad_pkt_num), 1065 }; 1066 1067 #define HINIC_TXQ_STAT(_stat_item) { \ 1068 .name = "txq%d_"#_stat_item, \ 1069 .size = sizeof_field(struct hinic_txq_stats, _stat_item), \ 1070 .offset = offsetof(struct hinic_txq_stats, _stat_item) \ 1071 } 1072 1073 static struct hinic_stats hinic_tx_queue_stats[] = { 1074 HINIC_TXQ_STAT(pkts), 1075 HINIC_TXQ_STAT(bytes), 1076 HINIC_TXQ_STAT(tx_busy), 1077 HINIC_TXQ_STAT(tx_wake), 1078 HINIC_TXQ_STAT(tx_dropped), 1079 HINIC_TXQ_STAT(big_frags_pkts), 1080 }; 1081 1082 #define HINIC_RXQ_STAT(_stat_item) { \ 1083 .name = "rxq%d_"#_stat_item, \ 1084 .size = sizeof_field(struct hinic_rxq_stats, _stat_item), \ 1085 .offset = offsetof(struct hinic_rxq_stats, _stat_item) \ 1086 } 1087 1088 static struct hinic_stats hinic_rx_queue_stats[] = { 1089 HINIC_RXQ_STAT(pkts), 1090 HINIC_RXQ_STAT(bytes), 1091 HINIC_RXQ_STAT(errors), 1092 HINIC_RXQ_STAT(csum_errors), 1093 HINIC_RXQ_STAT(other_errors), 1094 }; 1095 1096 static void get_drv_queue_stats(struct hinic_dev *nic_dev, u64 *data) 1097 { 1098 struct hinic_txq_stats txq_stats; 1099 struct hinic_rxq_stats rxq_stats; 1100 u16 i = 0, j = 0, qid = 0; 1101 char *p; 1102 1103 for (qid = 0; qid < nic_dev->num_qps; qid++) { 1104 if (!nic_dev->txqs) 1105 break; 1106 1107 hinic_txq_get_stats(&nic_dev->txqs[qid], &txq_stats); 1108 for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++, i++) { 1109 p = (char *)&txq_stats + 1110 hinic_tx_queue_stats[j].offset; 1111 data[i] = (hinic_tx_queue_stats[j].size == 1112 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1113 } 1114 } 1115 1116 for (qid = 0; qid < nic_dev->num_qps; qid++) { 1117 if (!nic_dev->rxqs) 1118 break; 1119 1120 hinic_rxq_get_stats(&nic_dev->rxqs[qid], &rxq_stats); 1121 for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++, i++) { 1122 p = (char *)&rxq_stats + 1123 hinic_rx_queue_stats[j].offset; 1124 data[i] = (hinic_rx_queue_stats[j].size == 1125 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1126 } 1127 } 1128 } 1129 1130 static void hinic_get_ethtool_stats(struct net_device *netdev, 1131 struct ethtool_stats *stats, u64 *data) 1132 { 1133 struct hinic_dev *nic_dev = netdev_priv(netdev); 1134 struct hinic_vport_stats vport_stats = {0}; 1135 struct hinic_phy_port_stats *port_stats; 1136 u16 i = 0, j = 0; 1137 char *p; 1138 int err; 1139 1140 err = hinic_get_vport_stats(nic_dev, &vport_stats); 1141 if (err) 1142 netif_err(nic_dev, drv, netdev, 1143 "Failed to get vport stats from firmware\n"); 1144 1145 for (j = 0; j < ARRAY_LEN(hinic_function_stats); j++, i++) { 1146 p = (char *)&vport_stats + hinic_function_stats[j].offset; 1147 data[i] = (hinic_function_stats[j].size == 1148 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1149 } 1150 1151 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); 1152 if (!port_stats) { 1153 memset(&data[i], 0, 1154 ARRAY_LEN(hinic_port_stats) * sizeof(*data)); 1155 i += ARRAY_LEN(hinic_port_stats); 1156 goto get_drv_stats; 1157 } 1158 1159 err = hinic_get_phy_port_stats(nic_dev, port_stats); 1160 if (err) 1161 netif_err(nic_dev, drv, netdev, 1162 "Failed to get port stats from firmware\n"); 1163 1164 for (j = 0; j < ARRAY_LEN(hinic_port_stats); j++, i++) { 1165 p = (char *)port_stats + hinic_port_stats[j].offset; 1166 data[i] = (hinic_port_stats[j].size == 1167 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 1168 } 1169 1170 kfree(port_stats); 1171 1172 get_drv_stats: 1173 get_drv_queue_stats(nic_dev, data + i); 1174 } 1175 1176 static int hinic_get_sset_count(struct net_device *netdev, int sset) 1177 { 1178 struct hinic_dev *nic_dev = netdev_priv(netdev); 1179 int count, q_num; 1180 1181 switch (sset) { 1182 case ETH_SS_STATS: 1183 q_num = nic_dev->num_qps; 1184 count = ARRAY_LEN(hinic_function_stats) + 1185 (ARRAY_LEN(hinic_tx_queue_stats) + 1186 ARRAY_LEN(hinic_rx_queue_stats)) * q_num; 1187 1188 count += ARRAY_LEN(hinic_port_stats); 1189 1190 return count; 1191 default: 1192 return -EOPNOTSUPP; 1193 } 1194 } 1195 1196 static void hinic_get_strings(struct net_device *netdev, 1197 u32 stringset, u8 *data) 1198 { 1199 struct hinic_dev *nic_dev = netdev_priv(netdev); 1200 char *p = (char *)data; 1201 u16 i, j; 1202 1203 switch (stringset) { 1204 case ETH_SS_STATS: 1205 for (i = 0; i < ARRAY_LEN(hinic_function_stats); i++) { 1206 memcpy(p, hinic_function_stats[i].name, 1207 ETH_GSTRING_LEN); 1208 p += ETH_GSTRING_LEN; 1209 } 1210 1211 for (i = 0; i < ARRAY_LEN(hinic_port_stats); i++) { 1212 memcpy(p, hinic_port_stats[i].name, 1213 ETH_GSTRING_LEN); 1214 p += ETH_GSTRING_LEN; 1215 } 1216 1217 for (i = 0; i < nic_dev->num_qps; i++) { 1218 for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++) { 1219 sprintf(p, hinic_tx_queue_stats[j].name, i); 1220 p += ETH_GSTRING_LEN; 1221 } 1222 } 1223 1224 for (i = 0; i < nic_dev->num_qps; i++) { 1225 for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++) { 1226 sprintf(p, hinic_rx_queue_stats[j].name, i); 1227 p += ETH_GSTRING_LEN; 1228 } 1229 } 1230 1231 return; 1232 default: 1233 return; 1234 } 1235 } 1236 1237 static const struct ethtool_ops hinic_ethtool_ops = { 1238 .get_link_ksettings = hinic_get_link_ksettings, 1239 .set_link_ksettings = hinic_set_link_ksettings, 1240 .get_drvinfo = hinic_get_drvinfo, 1241 .get_link = ethtool_op_get_link, 1242 .get_ringparam = hinic_get_ringparam, 1243 .set_ringparam = hinic_set_ringparam, 1244 .get_channels = hinic_get_channels, 1245 .set_channels = hinic_set_channels, 1246 .get_rxnfc = hinic_get_rxnfc, 1247 .set_rxnfc = hinic_set_rxnfc, 1248 .get_rxfh_key_size = hinic_get_rxfh_key_size, 1249 .get_rxfh_indir_size = hinic_get_rxfh_indir_size, 1250 .get_rxfh = hinic_get_rxfh, 1251 .set_rxfh = hinic_set_rxfh, 1252 .get_sset_count = hinic_get_sset_count, 1253 .get_ethtool_stats = hinic_get_ethtool_stats, 1254 .get_strings = hinic_get_strings, 1255 }; 1256 1257 void hinic_set_ethtool_ops(struct net_device *netdev) 1258 { 1259 netdev->ethtool_ops = &hinic_ethtool_ops; 1260 } 1261