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