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 static void set_link_speed(struct ethtool_link_ksettings *link_ksettings, 37 enum hinic_speed speed) 38 { 39 switch (speed) { 40 case HINIC_SPEED_10MB_LINK: 41 link_ksettings->base.speed = SPEED_10; 42 break; 43 44 case HINIC_SPEED_100MB_LINK: 45 link_ksettings->base.speed = SPEED_100; 46 break; 47 48 case HINIC_SPEED_1000MB_LINK: 49 link_ksettings->base.speed = SPEED_1000; 50 break; 51 52 case HINIC_SPEED_10GB_LINK: 53 link_ksettings->base.speed = SPEED_10000; 54 break; 55 56 case HINIC_SPEED_25GB_LINK: 57 link_ksettings->base.speed = SPEED_25000; 58 break; 59 60 case HINIC_SPEED_40GB_LINK: 61 link_ksettings->base.speed = SPEED_40000; 62 break; 63 64 case HINIC_SPEED_100GB_LINK: 65 link_ksettings->base.speed = SPEED_100000; 66 break; 67 68 default: 69 link_ksettings->base.speed = SPEED_UNKNOWN; 70 break; 71 } 72 } 73 74 static int hinic_get_link_ksettings(struct net_device *netdev, 75 struct ethtool_link_ksettings 76 *link_ksettings) 77 { 78 struct hinic_dev *nic_dev = netdev_priv(netdev); 79 enum hinic_port_link_state link_state; 80 struct hinic_port_cap port_cap; 81 int err; 82 83 ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); 84 ethtool_link_ksettings_add_link_mode(link_ksettings, supported, 85 Autoneg); 86 87 link_ksettings->base.speed = SPEED_UNKNOWN; 88 link_ksettings->base.autoneg = AUTONEG_DISABLE; 89 link_ksettings->base.duplex = DUPLEX_UNKNOWN; 90 91 err = hinic_port_get_cap(nic_dev, &port_cap); 92 if (err) 93 return err; 94 95 err = hinic_port_link_state(nic_dev, &link_state); 96 if (err) 97 return err; 98 99 if (link_state != HINIC_LINK_STATE_UP) 100 return err; 101 102 set_link_speed(link_ksettings, port_cap.speed); 103 104 if (!!(port_cap.autoneg_cap & HINIC_AUTONEG_SUPPORTED)) 105 ethtool_link_ksettings_add_link_mode(link_ksettings, 106 advertising, Autoneg); 107 108 if (port_cap.autoneg_state == HINIC_AUTONEG_ACTIVE) 109 link_ksettings->base.autoneg = AUTONEG_ENABLE; 110 111 link_ksettings->base.duplex = (port_cap.duplex == HINIC_DUPLEX_FULL) ? 112 DUPLEX_FULL : DUPLEX_HALF; 113 return 0; 114 } 115 116 static void hinic_get_drvinfo(struct net_device *netdev, 117 struct ethtool_drvinfo *info) 118 { 119 struct hinic_dev *nic_dev = netdev_priv(netdev); 120 u8 mgmt_ver[HINIC_MGMT_VERSION_MAX_LEN] = {0}; 121 struct hinic_hwdev *hwdev = nic_dev->hwdev; 122 struct hinic_hwif *hwif = hwdev->hwif; 123 int err; 124 125 strlcpy(info->driver, HINIC_DRV_NAME, sizeof(info->driver)); 126 strlcpy(info->bus_info, pci_name(hwif->pdev), sizeof(info->bus_info)); 127 128 err = hinic_get_mgmt_version(nic_dev, mgmt_ver); 129 if (err) 130 return; 131 132 snprintf(info->fw_version, sizeof(info->fw_version), "%s", mgmt_ver); 133 } 134 135 static void hinic_get_ringparam(struct net_device *netdev, 136 struct ethtool_ringparam *ring) 137 { 138 ring->rx_max_pending = HINIC_RQ_DEPTH; 139 ring->tx_max_pending = HINIC_SQ_DEPTH; 140 ring->rx_pending = HINIC_RQ_DEPTH; 141 ring->tx_pending = HINIC_SQ_DEPTH; 142 } 143 144 static void hinic_get_channels(struct net_device *netdev, 145 struct ethtool_channels *channels) 146 { 147 struct hinic_dev *nic_dev = netdev_priv(netdev); 148 struct hinic_hwdev *hwdev = nic_dev->hwdev; 149 150 channels->max_rx = hwdev->nic_cap.max_qps; 151 channels->max_tx = hwdev->nic_cap.max_qps; 152 channels->max_other = 0; 153 channels->max_combined = 0; 154 channels->rx_count = hinic_hwdev_num_qps(hwdev); 155 channels->tx_count = hinic_hwdev_num_qps(hwdev); 156 channels->other_count = 0; 157 channels->combined_count = 0; 158 } 159 160 static int hinic_get_rss_hash_opts(struct hinic_dev *nic_dev, 161 struct ethtool_rxnfc *cmd) 162 { 163 struct hinic_rss_type rss_type = { 0 }; 164 int err; 165 166 cmd->data = 0; 167 168 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 169 return 0; 170 171 err = hinic_get_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 172 &rss_type); 173 if (err) 174 return err; 175 176 cmd->data = RXH_IP_SRC | RXH_IP_DST; 177 switch (cmd->flow_type) { 178 case TCP_V4_FLOW: 179 if (rss_type.tcp_ipv4) 180 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 181 break; 182 case TCP_V6_FLOW: 183 if (rss_type.tcp_ipv6) 184 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 185 break; 186 case UDP_V4_FLOW: 187 if (rss_type.udp_ipv4) 188 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 189 break; 190 case UDP_V6_FLOW: 191 if (rss_type.udp_ipv6) 192 cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3; 193 break; 194 case IPV4_FLOW: 195 case IPV6_FLOW: 196 break; 197 default: 198 cmd->data = 0; 199 return -EINVAL; 200 } 201 202 return 0; 203 } 204 205 static int set_l4_rss_hash_ops(struct ethtool_rxnfc *cmd, 206 struct hinic_rss_type *rss_type) 207 { 208 u8 rss_l4_en = 0; 209 210 switch (cmd->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) { 211 case 0: 212 rss_l4_en = 0; 213 break; 214 case (RXH_L4_B_0_1 | RXH_L4_B_2_3): 215 rss_l4_en = 1; 216 break; 217 default: 218 return -EINVAL; 219 } 220 221 switch (cmd->flow_type) { 222 case TCP_V4_FLOW: 223 rss_type->tcp_ipv4 = rss_l4_en; 224 break; 225 case TCP_V6_FLOW: 226 rss_type->tcp_ipv6 = rss_l4_en; 227 break; 228 case UDP_V4_FLOW: 229 rss_type->udp_ipv4 = rss_l4_en; 230 break; 231 case UDP_V6_FLOW: 232 rss_type->udp_ipv6 = rss_l4_en; 233 break; 234 default: 235 return -EINVAL; 236 } 237 238 return 0; 239 } 240 241 static int hinic_set_rss_hash_opts(struct hinic_dev *nic_dev, 242 struct ethtool_rxnfc *cmd) 243 { 244 struct hinic_rss_type *rss_type = &nic_dev->rss_type; 245 int err; 246 247 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) { 248 cmd->data = 0; 249 return -EOPNOTSUPP; 250 } 251 252 /* RSS does not support anything other than hashing 253 * to queues on src and dst IPs and ports 254 */ 255 if (cmd->data & ~(RXH_IP_SRC | RXH_IP_DST | RXH_L4_B_0_1 | 256 RXH_L4_B_2_3)) 257 return -EINVAL; 258 259 /* We need at least the IP SRC and DEST fields for hashing */ 260 if (!(cmd->data & RXH_IP_SRC) || !(cmd->data & RXH_IP_DST)) 261 return -EINVAL; 262 263 err = hinic_get_rss_type(nic_dev, 264 nic_dev->rss_tmpl_idx, rss_type); 265 if (err) 266 return -EFAULT; 267 268 switch (cmd->flow_type) { 269 case TCP_V4_FLOW: 270 case TCP_V6_FLOW: 271 case UDP_V4_FLOW: 272 case UDP_V6_FLOW: 273 err = set_l4_rss_hash_ops(cmd, rss_type); 274 if (err) 275 return err; 276 break; 277 case IPV4_FLOW: 278 rss_type->ipv4 = 1; 279 break; 280 case IPV6_FLOW: 281 rss_type->ipv6 = 1; 282 break; 283 default: 284 return -EINVAL; 285 } 286 287 err = hinic_set_rss_type(nic_dev, nic_dev->rss_tmpl_idx, 288 *rss_type); 289 if (err) 290 return -EFAULT; 291 292 return 0; 293 } 294 295 static int __set_rss_rxfh(struct net_device *netdev, 296 const u32 *indir, const u8 *key) 297 { 298 struct hinic_dev *nic_dev = netdev_priv(netdev); 299 int err; 300 301 if (indir) { 302 if (!nic_dev->rss_indir_user) { 303 nic_dev->rss_indir_user = 304 kzalloc(sizeof(u32) * HINIC_RSS_INDIR_SIZE, 305 GFP_KERNEL); 306 if (!nic_dev->rss_indir_user) 307 return -ENOMEM; 308 } 309 310 memcpy(nic_dev->rss_indir_user, indir, 311 sizeof(u32) * HINIC_RSS_INDIR_SIZE); 312 313 err = hinic_rss_set_indir_tbl(nic_dev, 314 nic_dev->rss_tmpl_idx, indir); 315 if (err) 316 return -EFAULT; 317 } 318 319 if (key) { 320 if (!nic_dev->rss_hkey_user) { 321 nic_dev->rss_hkey_user = 322 kzalloc(HINIC_RSS_KEY_SIZE * 2, GFP_KERNEL); 323 324 if (!nic_dev->rss_hkey_user) 325 return -ENOMEM; 326 } 327 328 memcpy(nic_dev->rss_hkey_user, key, HINIC_RSS_KEY_SIZE); 329 330 err = hinic_rss_set_template_tbl(nic_dev, 331 nic_dev->rss_tmpl_idx, key); 332 if (err) 333 return -EFAULT; 334 } 335 336 return 0; 337 } 338 339 static int hinic_get_rxnfc(struct net_device *netdev, 340 struct ethtool_rxnfc *cmd, u32 *rule_locs) 341 { 342 struct hinic_dev *nic_dev = netdev_priv(netdev); 343 int err = 0; 344 345 switch (cmd->cmd) { 346 case ETHTOOL_GRXRINGS: 347 cmd->data = nic_dev->num_qps; 348 break; 349 case ETHTOOL_GRXFH: 350 err = hinic_get_rss_hash_opts(nic_dev, cmd); 351 break; 352 default: 353 err = -EOPNOTSUPP; 354 break; 355 } 356 357 return err; 358 } 359 360 static int hinic_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) 361 { 362 struct hinic_dev *nic_dev = netdev_priv(netdev); 363 int err = 0; 364 365 switch (cmd->cmd) { 366 case ETHTOOL_SRXFH: 367 err = hinic_set_rss_hash_opts(nic_dev, cmd); 368 break; 369 default: 370 err = -EOPNOTSUPP; 371 break; 372 } 373 374 return err; 375 } 376 377 static int hinic_get_rxfh(struct net_device *netdev, 378 u32 *indir, u8 *key, u8 *hfunc) 379 { 380 struct hinic_dev *nic_dev = netdev_priv(netdev); 381 u8 hash_engine_type = 0; 382 int err = 0; 383 384 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 385 return -EOPNOTSUPP; 386 387 if (hfunc) { 388 err = hinic_rss_get_hash_engine(nic_dev, 389 nic_dev->rss_tmpl_idx, 390 &hash_engine_type); 391 if (err) 392 return -EFAULT; 393 394 *hfunc = hash_engine_type ? ETH_RSS_HASH_TOP : ETH_RSS_HASH_XOR; 395 } 396 397 if (indir) { 398 err = hinic_rss_get_indir_tbl(nic_dev, 399 nic_dev->rss_tmpl_idx, indir); 400 if (err) 401 return -EFAULT; 402 } 403 404 if (key) 405 err = hinic_rss_get_template_tbl(nic_dev, 406 nic_dev->rss_tmpl_idx, key); 407 408 return err; 409 } 410 411 static int hinic_set_rxfh(struct net_device *netdev, const u32 *indir, 412 const u8 *key, const u8 hfunc) 413 { 414 struct hinic_dev *nic_dev = netdev_priv(netdev); 415 int err = 0; 416 417 if (!(nic_dev->flags & HINIC_RSS_ENABLE)) 418 return -EOPNOTSUPP; 419 420 if (hfunc != ETH_RSS_HASH_NO_CHANGE) { 421 if (hfunc != ETH_RSS_HASH_TOP && hfunc != ETH_RSS_HASH_XOR) 422 return -EOPNOTSUPP; 423 424 nic_dev->rss_hash_engine = (hfunc == ETH_RSS_HASH_XOR) ? 425 HINIC_RSS_HASH_ENGINE_TYPE_XOR : 426 HINIC_RSS_HASH_ENGINE_TYPE_TOEP; 427 err = hinic_rss_set_hash_engine 428 (nic_dev, nic_dev->rss_tmpl_idx, 429 nic_dev->rss_hash_engine); 430 if (err) 431 return -EFAULT; 432 } 433 434 err = __set_rss_rxfh(netdev, indir, key); 435 436 return err; 437 } 438 439 static u32 hinic_get_rxfh_key_size(struct net_device *netdev) 440 { 441 return HINIC_RSS_KEY_SIZE; 442 } 443 444 static u32 hinic_get_rxfh_indir_size(struct net_device *netdev) 445 { 446 return HINIC_RSS_INDIR_SIZE; 447 } 448 449 #define ARRAY_LEN(arr) ((int)((int)sizeof(arr) / (int)sizeof(arr[0]))) 450 451 #define HINIC_FUNC_STAT(_stat_item) { \ 452 .name = #_stat_item, \ 453 .size = sizeof_field(struct hinic_vport_stats, _stat_item), \ 454 .offset = offsetof(struct hinic_vport_stats, _stat_item) \ 455 } 456 457 static struct hinic_stats hinic_function_stats[] = { 458 HINIC_FUNC_STAT(tx_unicast_pkts_vport), 459 HINIC_FUNC_STAT(tx_unicast_bytes_vport), 460 HINIC_FUNC_STAT(tx_multicast_pkts_vport), 461 HINIC_FUNC_STAT(tx_multicast_bytes_vport), 462 HINIC_FUNC_STAT(tx_broadcast_pkts_vport), 463 HINIC_FUNC_STAT(tx_broadcast_bytes_vport), 464 465 HINIC_FUNC_STAT(rx_unicast_pkts_vport), 466 HINIC_FUNC_STAT(rx_unicast_bytes_vport), 467 HINIC_FUNC_STAT(rx_multicast_pkts_vport), 468 HINIC_FUNC_STAT(rx_multicast_bytes_vport), 469 HINIC_FUNC_STAT(rx_broadcast_pkts_vport), 470 HINIC_FUNC_STAT(rx_broadcast_bytes_vport), 471 472 HINIC_FUNC_STAT(tx_discard_vport), 473 HINIC_FUNC_STAT(rx_discard_vport), 474 HINIC_FUNC_STAT(tx_err_vport), 475 HINIC_FUNC_STAT(rx_err_vport), 476 }; 477 478 #define HINIC_PORT_STAT(_stat_item) { \ 479 .name = #_stat_item, \ 480 .size = sizeof_field(struct hinic_phy_port_stats, _stat_item), \ 481 .offset = offsetof(struct hinic_phy_port_stats, _stat_item) \ 482 } 483 484 static struct hinic_stats hinic_port_stats[] = { 485 HINIC_PORT_STAT(mac_rx_total_pkt_num), 486 HINIC_PORT_STAT(mac_rx_total_oct_num), 487 HINIC_PORT_STAT(mac_rx_bad_pkt_num), 488 HINIC_PORT_STAT(mac_rx_bad_oct_num), 489 HINIC_PORT_STAT(mac_rx_good_pkt_num), 490 HINIC_PORT_STAT(mac_rx_good_oct_num), 491 HINIC_PORT_STAT(mac_rx_uni_pkt_num), 492 HINIC_PORT_STAT(mac_rx_multi_pkt_num), 493 HINIC_PORT_STAT(mac_rx_broad_pkt_num), 494 HINIC_PORT_STAT(mac_tx_total_pkt_num), 495 HINIC_PORT_STAT(mac_tx_total_oct_num), 496 HINIC_PORT_STAT(mac_tx_bad_pkt_num), 497 HINIC_PORT_STAT(mac_tx_bad_oct_num), 498 HINIC_PORT_STAT(mac_tx_good_pkt_num), 499 HINIC_PORT_STAT(mac_tx_good_oct_num), 500 HINIC_PORT_STAT(mac_tx_uni_pkt_num), 501 HINIC_PORT_STAT(mac_tx_multi_pkt_num), 502 HINIC_PORT_STAT(mac_tx_broad_pkt_num), 503 HINIC_PORT_STAT(mac_rx_fragment_pkt_num), 504 HINIC_PORT_STAT(mac_rx_undersize_pkt_num), 505 HINIC_PORT_STAT(mac_rx_undermin_pkt_num), 506 HINIC_PORT_STAT(mac_rx_64_oct_pkt_num), 507 HINIC_PORT_STAT(mac_rx_65_127_oct_pkt_num), 508 HINIC_PORT_STAT(mac_rx_128_255_oct_pkt_num), 509 HINIC_PORT_STAT(mac_rx_256_511_oct_pkt_num), 510 HINIC_PORT_STAT(mac_rx_512_1023_oct_pkt_num), 511 HINIC_PORT_STAT(mac_rx_1024_1518_oct_pkt_num), 512 HINIC_PORT_STAT(mac_rx_1519_2047_oct_pkt_num), 513 HINIC_PORT_STAT(mac_rx_2048_4095_oct_pkt_num), 514 HINIC_PORT_STAT(mac_rx_4096_8191_oct_pkt_num), 515 HINIC_PORT_STAT(mac_rx_8192_9216_oct_pkt_num), 516 HINIC_PORT_STAT(mac_rx_9217_12287_oct_pkt_num), 517 HINIC_PORT_STAT(mac_rx_12288_16383_oct_pkt_num), 518 HINIC_PORT_STAT(mac_rx_1519_max_good_pkt_num), 519 HINIC_PORT_STAT(mac_rx_1519_max_bad_pkt_num), 520 HINIC_PORT_STAT(mac_rx_oversize_pkt_num), 521 HINIC_PORT_STAT(mac_rx_jabber_pkt_num), 522 HINIC_PORT_STAT(mac_rx_pause_num), 523 HINIC_PORT_STAT(mac_rx_pfc_pkt_num), 524 HINIC_PORT_STAT(mac_rx_pfc_pri0_pkt_num), 525 HINIC_PORT_STAT(mac_rx_pfc_pri1_pkt_num), 526 HINIC_PORT_STAT(mac_rx_pfc_pri2_pkt_num), 527 HINIC_PORT_STAT(mac_rx_pfc_pri3_pkt_num), 528 HINIC_PORT_STAT(mac_rx_pfc_pri4_pkt_num), 529 HINIC_PORT_STAT(mac_rx_pfc_pri5_pkt_num), 530 HINIC_PORT_STAT(mac_rx_pfc_pri6_pkt_num), 531 HINIC_PORT_STAT(mac_rx_pfc_pri7_pkt_num), 532 HINIC_PORT_STAT(mac_rx_control_pkt_num), 533 HINIC_PORT_STAT(mac_rx_sym_err_pkt_num), 534 HINIC_PORT_STAT(mac_rx_fcs_err_pkt_num), 535 HINIC_PORT_STAT(mac_rx_send_app_good_pkt_num), 536 HINIC_PORT_STAT(mac_rx_send_app_bad_pkt_num), 537 HINIC_PORT_STAT(mac_tx_fragment_pkt_num), 538 HINIC_PORT_STAT(mac_tx_undersize_pkt_num), 539 HINIC_PORT_STAT(mac_tx_undermin_pkt_num), 540 HINIC_PORT_STAT(mac_tx_64_oct_pkt_num), 541 HINIC_PORT_STAT(mac_tx_65_127_oct_pkt_num), 542 HINIC_PORT_STAT(mac_tx_128_255_oct_pkt_num), 543 HINIC_PORT_STAT(mac_tx_256_511_oct_pkt_num), 544 HINIC_PORT_STAT(mac_tx_512_1023_oct_pkt_num), 545 HINIC_PORT_STAT(mac_tx_1024_1518_oct_pkt_num), 546 HINIC_PORT_STAT(mac_tx_1519_2047_oct_pkt_num), 547 HINIC_PORT_STAT(mac_tx_2048_4095_oct_pkt_num), 548 HINIC_PORT_STAT(mac_tx_4096_8191_oct_pkt_num), 549 HINIC_PORT_STAT(mac_tx_8192_9216_oct_pkt_num), 550 HINIC_PORT_STAT(mac_tx_9217_12287_oct_pkt_num), 551 HINIC_PORT_STAT(mac_tx_12288_16383_oct_pkt_num), 552 HINIC_PORT_STAT(mac_tx_1519_max_good_pkt_num), 553 HINIC_PORT_STAT(mac_tx_1519_max_bad_pkt_num), 554 HINIC_PORT_STAT(mac_tx_oversize_pkt_num), 555 HINIC_PORT_STAT(mac_tx_jabber_pkt_num), 556 HINIC_PORT_STAT(mac_tx_pause_num), 557 HINIC_PORT_STAT(mac_tx_pfc_pkt_num), 558 HINIC_PORT_STAT(mac_tx_pfc_pri0_pkt_num), 559 HINIC_PORT_STAT(mac_tx_pfc_pri1_pkt_num), 560 HINIC_PORT_STAT(mac_tx_pfc_pri2_pkt_num), 561 HINIC_PORT_STAT(mac_tx_pfc_pri3_pkt_num), 562 HINIC_PORT_STAT(mac_tx_pfc_pri4_pkt_num), 563 HINIC_PORT_STAT(mac_tx_pfc_pri5_pkt_num), 564 HINIC_PORT_STAT(mac_tx_pfc_pri6_pkt_num), 565 HINIC_PORT_STAT(mac_tx_pfc_pri7_pkt_num), 566 HINIC_PORT_STAT(mac_tx_control_pkt_num), 567 HINIC_PORT_STAT(mac_tx_err_all_pkt_num), 568 HINIC_PORT_STAT(mac_tx_from_app_good_pkt_num), 569 HINIC_PORT_STAT(mac_tx_from_app_bad_pkt_num), 570 }; 571 572 #define HINIC_TXQ_STAT(_stat_item) { \ 573 .name = "txq%d_"#_stat_item, \ 574 .size = sizeof_field(struct hinic_txq_stats, _stat_item), \ 575 .offset = offsetof(struct hinic_txq_stats, _stat_item) \ 576 } 577 578 static struct hinic_stats hinic_tx_queue_stats[] = { 579 HINIC_TXQ_STAT(pkts), 580 HINIC_TXQ_STAT(bytes), 581 HINIC_TXQ_STAT(tx_busy), 582 HINIC_TXQ_STAT(tx_wake), 583 HINIC_TXQ_STAT(tx_dropped), 584 HINIC_TXQ_STAT(big_frags_pkts), 585 }; 586 587 #define HINIC_RXQ_STAT(_stat_item) { \ 588 .name = "rxq%d_"#_stat_item, \ 589 .size = sizeof_field(struct hinic_rxq_stats, _stat_item), \ 590 .offset = offsetof(struct hinic_rxq_stats, _stat_item) \ 591 } 592 593 static struct hinic_stats hinic_rx_queue_stats[] = { 594 HINIC_RXQ_STAT(pkts), 595 HINIC_RXQ_STAT(bytes), 596 HINIC_RXQ_STAT(errors), 597 HINIC_RXQ_STAT(csum_errors), 598 HINIC_RXQ_STAT(other_errors), 599 }; 600 601 static void get_drv_queue_stats(struct hinic_dev *nic_dev, u64 *data) 602 { 603 struct hinic_txq_stats txq_stats; 604 struct hinic_rxq_stats rxq_stats; 605 u16 i = 0, j = 0, qid = 0; 606 char *p; 607 608 for (qid = 0; qid < nic_dev->num_qps; qid++) { 609 if (!nic_dev->txqs) 610 break; 611 612 hinic_txq_get_stats(&nic_dev->txqs[qid], &txq_stats); 613 for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++, i++) { 614 p = (char *)&txq_stats + 615 hinic_tx_queue_stats[j].offset; 616 data[i] = (hinic_tx_queue_stats[j].size == 617 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 618 } 619 } 620 621 for (qid = 0; qid < nic_dev->num_qps; qid++) { 622 if (!nic_dev->rxqs) 623 break; 624 625 hinic_rxq_get_stats(&nic_dev->rxqs[qid], &rxq_stats); 626 for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++, i++) { 627 p = (char *)&rxq_stats + 628 hinic_rx_queue_stats[j].offset; 629 data[i] = (hinic_rx_queue_stats[j].size == 630 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 631 } 632 } 633 } 634 635 static void hinic_get_ethtool_stats(struct net_device *netdev, 636 struct ethtool_stats *stats, u64 *data) 637 { 638 struct hinic_dev *nic_dev = netdev_priv(netdev); 639 struct hinic_vport_stats vport_stats = {0}; 640 struct hinic_phy_port_stats *port_stats; 641 u16 i = 0, j = 0; 642 char *p; 643 int err; 644 645 err = hinic_get_vport_stats(nic_dev, &vport_stats); 646 if (err) 647 netif_err(nic_dev, drv, netdev, 648 "Failed to get vport stats from firmware\n"); 649 650 for (j = 0; j < ARRAY_LEN(hinic_function_stats); j++, i++) { 651 p = (char *)&vport_stats + hinic_function_stats[j].offset; 652 data[i] = (hinic_function_stats[j].size == 653 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 654 } 655 656 port_stats = kzalloc(sizeof(*port_stats), GFP_KERNEL); 657 if (!port_stats) { 658 memset(&data[i], 0, 659 ARRAY_LEN(hinic_port_stats) * sizeof(*data)); 660 i += ARRAY_LEN(hinic_port_stats); 661 goto get_drv_stats; 662 } 663 664 err = hinic_get_phy_port_stats(nic_dev, port_stats); 665 if (err) 666 netif_err(nic_dev, drv, netdev, 667 "Failed to get port stats from firmware\n"); 668 669 for (j = 0; j < ARRAY_LEN(hinic_port_stats); j++, i++) { 670 p = (char *)port_stats + hinic_port_stats[j].offset; 671 data[i] = (hinic_port_stats[j].size == 672 sizeof(u64)) ? *(u64 *)p : *(u32 *)p; 673 } 674 675 kfree(port_stats); 676 677 get_drv_stats: 678 get_drv_queue_stats(nic_dev, data + i); 679 } 680 681 static int hinic_get_sset_count(struct net_device *netdev, int sset) 682 { 683 struct hinic_dev *nic_dev = netdev_priv(netdev); 684 int count, q_num; 685 686 switch (sset) { 687 case ETH_SS_STATS: 688 q_num = nic_dev->num_qps; 689 count = ARRAY_LEN(hinic_function_stats) + 690 (ARRAY_LEN(hinic_tx_queue_stats) + 691 ARRAY_LEN(hinic_rx_queue_stats)) * q_num; 692 693 count += ARRAY_LEN(hinic_port_stats); 694 695 return count; 696 default: 697 return -EOPNOTSUPP; 698 } 699 } 700 701 static void hinic_get_strings(struct net_device *netdev, 702 u32 stringset, u8 *data) 703 { 704 struct hinic_dev *nic_dev = netdev_priv(netdev); 705 char *p = (char *)data; 706 u16 i, j; 707 708 switch (stringset) { 709 case ETH_SS_STATS: 710 for (i = 0; i < ARRAY_LEN(hinic_function_stats); i++) { 711 memcpy(p, hinic_function_stats[i].name, 712 ETH_GSTRING_LEN); 713 p += ETH_GSTRING_LEN; 714 } 715 716 for (i = 0; i < ARRAY_LEN(hinic_port_stats); i++) { 717 memcpy(p, hinic_port_stats[i].name, 718 ETH_GSTRING_LEN); 719 p += ETH_GSTRING_LEN; 720 } 721 722 for (i = 0; i < nic_dev->num_qps; i++) { 723 for (j = 0; j < ARRAY_LEN(hinic_tx_queue_stats); j++) { 724 sprintf(p, hinic_tx_queue_stats[j].name, i); 725 p += ETH_GSTRING_LEN; 726 } 727 } 728 729 for (i = 0; i < nic_dev->num_qps; i++) { 730 for (j = 0; j < ARRAY_LEN(hinic_rx_queue_stats); j++) { 731 sprintf(p, hinic_rx_queue_stats[j].name, i); 732 p += ETH_GSTRING_LEN; 733 } 734 } 735 736 return; 737 default: 738 return; 739 } 740 } 741 742 static const struct ethtool_ops hinic_ethtool_ops = { 743 .get_link_ksettings = hinic_get_link_ksettings, 744 .get_drvinfo = hinic_get_drvinfo, 745 .get_link = ethtool_op_get_link, 746 .get_ringparam = hinic_get_ringparam, 747 .get_channels = hinic_get_channels, 748 .get_rxnfc = hinic_get_rxnfc, 749 .set_rxnfc = hinic_set_rxnfc, 750 .get_rxfh_key_size = hinic_get_rxfh_key_size, 751 .get_rxfh_indir_size = hinic_get_rxfh_indir_size, 752 .get_rxfh = hinic_get_rxfh, 753 .set_rxfh = hinic_set_rxfh, 754 .get_sset_count = hinic_get_sset_count, 755 .get_ethtool_stats = hinic_get_ethtool_stats, 756 .get_strings = hinic_get_strings, 757 }; 758 759 void hinic_set_ethtool_ops(struct net_device *netdev) 760 { 761 netdev->ethtool_ops = &hinic_ethtool_ops; 762 } 763