FILE
idpf_ethtool.c
File preview with syntax highlighting.
linux-6.19.14/drivers/net/ethernet/intel/idpf/idpf_ethtool.c
1// SPDX-License-Identifier: GPL-2.0-only 2/* Copyright (C) 2023 Intel Corporation */ 3 4#include "idpf.h" 5#include "idpf_ptp.h" 6#include "idpf_virtchnl.h" 7 8/** 9 * idpf_get_rx_ring_count - get RX ring count 10 * @netdev: network interface device structure 11 * 12 * Return: number of RX rings. 13 */ 14static u32 idpf_get_rx_ring_count(struct net_device *netdev) 15{ 16 struct idpf_vport *vport; 17 u32 num_rxq; 18 19 idpf_vport_ctrl_lock(netdev); 20 vport = idpf_netdev_to_vport(netdev); 21 num_rxq = vport->num_rxq; 22 idpf_vport_ctrl_unlock(netdev); 23 24 return num_rxq; 25} 26 27/** 28 * idpf_get_rxnfc - command to get RX flow classification rules 29 * @netdev: network interface device structure 30 * @cmd: ethtool rxnfc command 31 * @rule_locs: pointer to store rule locations 32 * 33 * Returns Success if the command is supported. 34 */ 35static int idpf_get_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd, 36 u32 *rule_locs) 37{ 38 struct idpf_netdev_priv *np = netdev_priv(netdev); 39 struct idpf_vport_user_config_data *user_config; 40 struct idpf_vport_config *vport_config; 41 struct idpf_fsteer_fltr *f; 42 struct idpf_vport *vport; 43 unsigned int cnt = 0; 44 int err = 0; 45 46 idpf_vport_ctrl_lock(netdev); 47 vport = idpf_netdev_to_vport(netdev); 48 vport_config = np->adapter->vport_config[np->vport_idx]; 49 user_config = &vport_config->user_config; 50 51 switch (cmd->cmd) { 52 case ETHTOOL_GRXCLSRLCNT: 53 cmd->rule_cnt = user_config->num_fsteer_fltrs; 54 cmd->data = idpf_fsteer_max_rules(vport); 55 break; 56 case ETHTOOL_GRXCLSRULE: 57 err = -ENOENT; 58 spin_lock_bh(&vport_config->flow_steer_list_lock); 59 list_for_each_entry(f, &user_config->flow_steer_list, list) 60 if (f->fs.location == cmd->fs.location) { 61 /* Avoid infoleak from padding: zero first, 62 * then assign fields 63 */ 64 memset(&cmd->fs, 0, sizeof(cmd->fs)); 65 cmd->fs = f->fs; 66 err = 0; 67 break; 68 } 69 spin_unlock_bh(&vport_config->flow_steer_list_lock); 70 break; 71 case ETHTOOL_GRXCLSRLALL: 72 cmd->data = idpf_fsteer_max_rules(vport); 73 spin_lock_bh(&vport_config->flow_steer_list_lock); 74 list_for_each_entry(f, &user_config->flow_steer_list, list) { 75 if (cnt == cmd->rule_cnt) { 76 err = -EMSGSIZE; 77 break; 78 } 79 rule_locs[cnt] = f->fs.location; 80 cnt++; 81 } 82 if (!err) 83 cmd->rule_cnt = user_config->num_fsteer_fltrs; 84 spin_unlock_bh(&vport_config->flow_steer_list_lock); 85 break; 86 default: 87 break; 88 } 89 90 idpf_vport_ctrl_unlock(netdev); 91 92 return err; 93} 94 95static void idpf_fsteer_fill_ipv4(struct virtchnl2_proto_hdrs *hdrs, 96 struct ethtool_rx_flow_spec *fsp) 97{ 98 struct iphdr *iph; 99 100 hdrs->proto_hdr[0].hdr_type = cpu_to_le32(VIRTCHNL2_PROTO_HDR_IPV4); 101 102 iph = (struct iphdr *)hdrs->proto_hdr[0].buffer_spec; 103 iph->saddr = fsp->h_u.tcp_ip4_spec.ip4src; 104 iph->daddr = fsp->h_u.tcp_ip4_spec.ip4dst; 105 106 iph = (struct iphdr *)hdrs->proto_hdr[0].buffer_mask; 107 iph->saddr = fsp->m_u.tcp_ip4_spec.ip4src; 108 iph->daddr = fsp->m_u.tcp_ip4_spec.ip4dst; 109} 110 111static void idpf_fsteer_fill_udp(struct virtchnl2_proto_hdrs *hdrs, 112 struct ethtool_rx_flow_spec *fsp, 113 bool v4) 114{ 115 struct udphdr *udph, *udpm; 116 117 hdrs->proto_hdr[1].hdr_type = cpu_to_le32(VIRTCHNL2_PROTO_HDR_UDP); 118 119 udph = (struct udphdr *)hdrs->proto_hdr[1].buffer_spec; 120 udpm = (struct udphdr *)hdrs->proto_hdr[1].buffer_mask; 121 122 if (v4) { 123 udph->source = fsp->h_u.udp_ip4_spec.psrc; 124 udph->dest = fsp->h_u.udp_ip4_spec.pdst; 125 udpm->source = fsp->m_u.udp_ip4_spec.psrc; 126 udpm->dest = fsp->m_u.udp_ip4_spec.pdst; 127 } else { 128 udph->source = fsp->h_u.udp_ip6_spec.psrc; 129 udph->dest = fsp->h_u.udp_ip6_spec.pdst; 130 udpm->source = fsp->m_u.udp_ip6_spec.psrc; 131 udpm->dest = fsp->m_u.udp_ip6_spec.pdst; 132 } 133} 134 135static void idpf_fsteer_fill_tcp(struct virtchnl2_proto_hdrs *hdrs, 136 struct ethtool_rx_flow_spec *fsp, 137 bool v4) 138{ 139 struct tcphdr *tcph, *tcpm; 140 141 hdrs->proto_hdr[1].hdr_type = cpu_to_le32(VIRTCHNL2_PROTO_HDR_TCP); 142 143 tcph = (struct tcphdr *)hdrs->proto_hdr[1].buffer_spec; 144 tcpm = (struct tcphdr *)hdrs->proto_hdr[1].buffer_mask; 145 146 if (v4) { 147 tcph->source = fsp->h_u.tcp_ip4_spec.psrc; 148 tcph->dest = fsp->h_u.tcp_ip4_spec.pdst; 149 tcpm->source = fsp->m_u.tcp_ip4_spec.psrc; 150 tcpm->dest = fsp->m_u.tcp_ip4_spec.pdst; 151 } else { 152 tcph->source = fsp->h_u.tcp_ip6_spec.psrc; 153 tcph->dest = fsp->h_u.tcp_ip6_spec.pdst; 154 tcpm->source = fsp->m_u.tcp_ip6_spec.psrc; 155 tcpm->dest = fsp->m_u.tcp_ip6_spec.pdst; 156 } 157} 158 159/** 160 * idpf_add_flow_steer - add a Flow Steering filter 161 * @netdev: network interface device structure 162 * @cmd: command to add Flow Steering filter 163 * 164 * Return: 0 on success and negative values for failure 165 */ 166static int idpf_add_flow_steer(struct net_device *netdev, 167 struct ethtool_rxnfc *cmd) 168{ 169 struct idpf_fsteer_fltr *fltr, *parent = NULL, *f; 170 struct idpf_netdev_priv *np = netdev_priv(netdev); 171 struct idpf_vport_user_config_data *user_config; 172 struct ethtool_rx_flow_spec *fsp = &cmd->fs; 173 struct virtchnl2_flow_rule_add_del *rule; 174 struct idpf_vport_config *vport_config; 175 struct virtchnl2_rule_action_set *acts; 176 struct virtchnl2_flow_rule_info *info; 177 struct virtchnl2_proto_hdrs *hdrs; 178 struct idpf_vport *vport; 179 u32 flow_type, q_index; 180 u16 num_rxq; 181 int err = 0; 182 183 vport = idpf_netdev_to_vport(netdev); 184 vport_config = vport->adapter->vport_config[np->vport_idx]; 185 user_config = &vport_config->user_config; 186 num_rxq = user_config->num_req_rx_qs; 187 188 flow_type = fsp->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT | FLOW_RSS); 189 if (flow_type != fsp->flow_type) 190 return -EINVAL; 191 192 if (!idpf_sideband_action_ena(vport, fsp) || 193 !idpf_sideband_flow_type_ena(vport, flow_type)) 194 return -EOPNOTSUPP; 195 196 if (user_config->num_fsteer_fltrs > idpf_fsteer_max_rules(vport)) 197 return -ENOSPC; 198 199 q_index = fsp->ring_cookie; 200 if (q_index >= num_rxq) 201 return -EINVAL; 202 203 rule = kzalloc(struct_size(rule, rule_info, 1), GFP_KERNEL); 204 if (!rule) 205 return -ENOMEM; 206 207 fltr = kzalloc(sizeof(*fltr), GFP_KERNEL); 208 if (!fltr) { 209 err = -ENOMEM; 210 goto out_free_rule; 211 } 212 213 /* detect duplicate entry and reject before adding rules */ 214 spin_lock_bh(&vport_config->flow_steer_list_lock); 215 list_for_each_entry(f, &user_config->flow_steer_list, list) { 216 if (f->fs.location == fsp->location) { 217 err = -EEXIST; 218 break; 219 } 220 221 if (f->fs.location > fsp->location) 222 break; 223 parent = f; 224 } 225 spin_unlock_bh(&vport_config->flow_steer_list_lock); 226 227 if (err) 228 goto out; 229 230 rule->vport_id = cpu_to_le32(vport->vport_id); 231 rule->count = cpu_to_le32(1); 232 info = &rule->rule_info[0]; 233 info->rule_id = cpu_to_le32(fsp->location); 234 235 hdrs = &info->rule_cfg.proto_hdrs; 236 hdrs->tunnel_level = 0; 237 hdrs->count = cpu_to_le32(2); 238 239 acts = &info->rule_cfg.action_set; 240 acts->count = cpu_to_le32(1); 241 acts->actions[0].action_type = cpu_to_le32(VIRTCHNL2_ACTION_QUEUE); 242 acts->actions[0].act_conf.q_id = cpu_to_le32(q_index); 243 244 switch (flow_type) { 245 case UDP_V4_FLOW: 246 idpf_fsteer_fill_ipv4(hdrs, fsp); 247 idpf_fsteer_fill_udp(hdrs, fsp, true); 248 break; 249 case TCP_V4_FLOW: 250 idpf_fsteer_fill_ipv4(hdrs, fsp); 251 idpf_fsteer_fill_tcp(hdrs, fsp, true); 252 break; 253 default: 254 err = -EINVAL; 255 goto out; 256 } 257 258 err = idpf_add_del_fsteer_filters(vport->adapter, rule, 259 VIRTCHNL2_OP_ADD_FLOW_RULE); 260 if (err) 261 goto out; 262 263 if (info->status != cpu_to_le32(VIRTCHNL2_FLOW_RULE_SUCCESS)) { 264 err = -EIO; 265 goto out; 266 } 267 268 /* Save a copy of the user's flow spec so ethtool can later retrieve it */ 269 fltr->fs = *fsp; 270 271 spin_lock_bh(&vport_config->flow_steer_list_lock); 272 parent ? list_add(&fltr->list, &parent->list) : 273 list_add(&fltr->list, &user_config->flow_steer_list); 274 275 user_config->num_fsteer_fltrs++; 276 spin_unlock_bh(&vport_config->flow_steer_list_lock); 277 goto out_free_rule; 278 279out: 280 kfree(fltr); 281out_free_rule: 282 kfree(rule); 283 return err; 284} 285 286/** 287 * idpf_del_flow_steer - delete a Flow Steering filter 288 * @netdev: network interface device structure 289 * @cmd: command to add Flow Steering filter 290 * 291 * Return: 0 on success and negative values for failure 292 */ 293static int idpf_del_flow_steer(struct net_device *netdev, 294 struct ethtool_rxnfc *cmd) 295{ 296 struct idpf_netdev_priv *np = netdev_priv(netdev); 297 struct idpf_vport_user_config_data *user_config; 298 struct ethtool_rx_flow_spec *fsp = &cmd->fs; 299 struct virtchnl2_flow_rule_add_del *rule; 300 struct idpf_vport_config *vport_config; 301 struct virtchnl2_flow_rule_info *info; 302 struct idpf_fsteer_fltr *f, *iter; 303 struct idpf_vport *vport; 304 int err; 305 306 vport = idpf_netdev_to_vport(netdev); 307 vport_config = vport->adapter->vport_config[np->vport_idx]; 308 user_config = &vport_config->user_config; 309 310 rule = kzalloc(struct_size(rule, rule_info, 1), GFP_KERNEL); 311 if (!rule) 312 return -ENOMEM; 313 314 rule->vport_id = cpu_to_le32(vport->vport_id); 315 rule->count = cpu_to_le32(1); 316 info = &rule->rule_info[0]; 317 info->rule_id = cpu_to_le32(fsp->location); 318 319 err = idpf_add_del_fsteer_filters(vport->adapter, rule, 320 VIRTCHNL2_OP_DEL_FLOW_RULE); 321 if (err) 322 goto out; 323 324 if (info->status != cpu_to_le32(VIRTCHNL2_FLOW_RULE_SUCCESS)) { 325 err = -EIO; 326 goto out; 327 } 328 329 spin_lock_bh(&vport_config->flow_steer_list_lock); 330 list_for_each_entry_safe(f, iter, 331 &user_config->flow_steer_list, list) { 332 if (f->fs.location == fsp->location) { 333 list_del(&f->list); 334 kfree(f); 335 user_config->num_fsteer_fltrs--; 336 goto out_unlock; 337 } 338 } 339 err = -ENOENT; 340 341out_unlock: 342 spin_unlock_bh(&vport_config->flow_steer_list_lock); 343out: 344 kfree(rule); 345 return err; 346} 347 348static int idpf_set_rxnfc(struct net_device *netdev, struct ethtool_rxnfc *cmd) 349{ 350 int ret = -EOPNOTSUPP; 351 352 idpf_vport_ctrl_lock(netdev); 353 switch (cmd->cmd) { 354 case ETHTOOL_SRXCLSRLINS: 355 ret = idpf_add_flow_steer(netdev, cmd); 356 break; 357 case ETHTOOL_SRXCLSRLDEL: 358 ret = idpf_del_flow_steer(netdev, cmd); 359 break; 360 default: 361 break; 362 } 363 364 idpf_vport_ctrl_unlock(netdev); 365 return ret; 366} 367 368/** 369 * idpf_get_rxfh_key_size - get the RSS hash key size 370 * @netdev: network interface device structure 371 * 372 * Returns the key size on success, error value on failure. 373 */ 374static u32 idpf_get_rxfh_key_size(struct net_device *netdev) 375{ 376 struct idpf_netdev_priv *np = netdev_priv(netdev); 377 struct idpf_vport_user_config_data *user_config; 378 379 if (!idpf_is_cap_ena_all(np->adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS)) 380 return 0; 381 382 user_config = &np->adapter->vport_config[np->vport_idx]->user_config; 383 384 return user_config->rss_data.rss_key_size; 385} 386 387/** 388 * idpf_get_rxfh_indir_size - get the rx flow hash indirection table size 389 * @netdev: network interface device structure 390 * 391 * Returns the table size on success, error value on failure. 392 */ 393static u32 idpf_get_rxfh_indir_size(struct net_device *netdev) 394{ 395 struct idpf_netdev_priv *np = netdev_priv(netdev); 396 struct idpf_vport_user_config_data *user_config; 397 398 if (!idpf_is_cap_ena_all(np->adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS)) 399 return 0; 400 401 user_config = &np->adapter->vport_config[np->vport_idx]->user_config; 402 403 return user_config->rss_data.rss_lut_size; 404} 405 406/** 407 * idpf_get_rxfh - get the rx flow hash indirection table 408 * @netdev: network interface device structure 409 * @rxfh: pointer to param struct (indir, key, hfunc) 410 * 411 * RSS LUT and Key information are read from driver's cached 412 * copy. When rxhash is off, rss lut will be displayed as zeros. 413 * 414 * Return: 0 on success, -errno otherwise. 415 */ 416static int idpf_get_rxfh(struct net_device *netdev, 417 struct ethtool_rxfh_param *rxfh) 418{ 419 struct idpf_netdev_priv *np = netdev_priv(netdev); 420 struct idpf_rss_data *rss_data; 421 struct idpf_adapter *adapter; 422 struct idpf_vport *vport; 423 bool rxhash_ena; 424 int err = 0; 425 u16 i; 426 427 idpf_vport_ctrl_lock(netdev); 428 vport = idpf_netdev_to_vport(netdev); 429 430 adapter = np->adapter; 431 432 if (!idpf_is_cap_ena_all(adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS)) { 433 err = -EOPNOTSUPP; 434 goto unlock_mutex; 435 } 436 437 rss_data = &adapter->vport_config[np->vport_idx]->user_config.rss_data; 438 439 rxhash_ena = idpf_is_feature_ena(vport, NETIF_F_RXHASH); 440 rxfh->hfunc = ETH_RSS_HASH_TOP; 441 442 if (rxfh->key) 443 memcpy(rxfh->key, rss_data->rss_key, rss_data->rss_key_size); 444 445 if (rxfh->indir) { 446 for (i = 0; i < rss_data->rss_lut_size; i++) 447 rxfh->indir[i] = rxhash_ena ? rss_data->rss_lut[i] : 0; 448 } 449 450unlock_mutex: 451 idpf_vport_ctrl_unlock(netdev); 452 453 return err; 454} 455 456/** 457 * idpf_set_rxfh - set the rx flow hash indirection table 458 * @netdev: network interface device structure 459 * @rxfh: pointer to param struct (indir, key, hfunc) 460 * @extack: extended ACK from the Netlink message 461 * 462 * Returns -EINVAL if the table specifies an invalid queue id, otherwise 463 * returns 0 after programming the table. 464 */ 465static int idpf_set_rxfh(struct net_device *netdev, 466 struct ethtool_rxfh_param *rxfh, 467 struct netlink_ext_ack *extack) 468{ 469 struct idpf_netdev_priv *np = netdev_priv(netdev); 470 struct idpf_rss_data *rss_data; 471 struct idpf_adapter *adapter; 472 struct idpf_vport *vport; 473 int err = 0; 474 u16 lut; 475 476 idpf_vport_ctrl_lock(netdev); 477 vport = idpf_netdev_to_vport(netdev); 478 479 adapter = vport->adapter; 480 481 if (!idpf_is_cap_ena_all(adapter, IDPF_RSS_CAPS, IDPF_CAP_RSS)) { 482 err = -EOPNOTSUPP; 483 goto unlock_mutex; 484 } 485 486 rss_data = &adapter->vport_config[vport->idx]->user_config.rss_data; 487 488 if (rxfh->hfunc != ETH_RSS_HASH_NO_CHANGE && 489 rxfh->hfunc != ETH_RSS_HASH_TOP) { 490 err = -EOPNOTSUPP; 491 goto unlock_mutex; 492 } 493 494 if (rxfh->key) 495 memcpy(rss_data->rss_key, rxfh->key, rss_data->rss_key_size); 496 497 if (rxfh->indir) { 498 for (lut = 0; lut < rss_data->rss_lut_size; lut++) 499 rss_data->rss_lut[lut] = rxfh->indir[lut]; 500 } 501 502 if (test_bit(IDPF_VPORT_UP, np->state)) 503 err = idpf_config_rss(vport); 504 505unlock_mutex: 506 idpf_vport_ctrl_unlock(netdev); 507 508 return err; 509} 510 511/** 512 * idpf_get_channels: get the number of channels supported by the device 513 * @netdev: network interface device structure 514 * @ch: channel information structure 515 * 516 * Report maximum of TX and RX. Report one extra channel to match our MailBox 517 * Queue. 518 */ 519static void idpf_get_channels(struct net_device *netdev, 520 struct ethtool_channels *ch) 521{ 522 struct idpf_netdev_priv *np = netdev_priv(netdev); 523 struct idpf_vport_config *vport_config; 524 u16 num_txq, num_rxq; 525 u16 combined; 526 527 vport_config = np->adapter->vport_config[np->vport_idx]; 528 529 num_txq = vport_config->user_config.num_req_tx_qs; 530 num_rxq = vport_config->user_config.num_req_rx_qs; 531 532 combined = min(num_txq, num_rxq); 533 534 /* Report maximum channels */ 535 ch->max_combined = min_t(u16, vport_config->max_q.max_txq, 536 vport_config->max_q.max_rxq); 537 ch->max_rx = vport_config->max_q.max_rxq; 538 ch->max_tx = vport_config->max_q.max_txq; 539 540 ch->max_other = IDPF_MAX_MBXQ; 541 ch->other_count = IDPF_MAX_MBXQ; 542 543 ch->combined_count = combined; 544 ch->rx_count = num_rxq - combined; 545 ch->tx_count = num_txq - combined; 546} 547 548/** 549 * idpf_set_channels: set the new channel count 550 * @netdev: network interface device structure 551 * @ch: channel information structure 552 * 553 * Negotiate a new number of channels with CP. Returns 0 on success, negative 554 * on failure. 555 */ 556static int idpf_set_channels(struct net_device *netdev, 557 struct ethtool_channels *ch) 558{ 559 struct idpf_vport_config *vport_config; 560 unsigned int num_req_tx_q; 561 unsigned int num_req_rx_q; 562 struct idpf_vport *vport; 563 u16 num_txq, num_rxq; 564 struct device *dev; 565 int err = 0; 566 u16 idx; 567 568 if (ch->rx_count && ch->tx_count) { 569 netdev_err(netdev, "Dedicated RX or TX channels cannot be used simultaneously\n"); 570 return -EINVAL; 571 } 572 573 idpf_vport_ctrl_lock(netdev); 574 vport = idpf_netdev_to_vport(netdev); 575 576 idx = vport->idx; 577 vport_config = vport->adapter->vport_config[idx]; 578 579 num_txq = vport_config->user_config.num_req_tx_qs; 580 num_rxq = vport_config->user_config.num_req_rx_qs; 581 582 num_req_tx_q = ch->combined_count + ch->tx_count; 583 num_req_rx_q = ch->combined_count + ch->rx_count; 584 585 dev = &vport->adapter->pdev->dev; 586 /* It's possible to specify number of queues that exceeds max. 587 * Stack checks max combined_count and max [tx|rx]_count but not the 588 * max combined_count + [tx|rx]_count. These checks should catch that. 589 */ 590 if (num_req_tx_q > vport_config->max_q.max_txq) { 591 dev_info(dev, "Maximum TX queues is %d\n", 592 vport_config->max_q.max_txq); 593 err = -EINVAL; 594 goto unlock_mutex; 595 } 596 if (num_req_rx_q > vport_config->max_q.max_rxq) { 597 dev_info(dev, "Maximum RX queues is %d\n", 598 vport_config->max_q.max_rxq); 599 err = -EINVAL; 600 goto unlock_mutex; 601 } 602 603 if (num_req_tx_q == num_txq && num_req_rx_q == num_rxq) 604 goto unlock_mutex; 605 606 vport_config->user_config.num_req_tx_qs = num_req_tx_q; 607 vport_config->user_config.num_req_rx_qs = num_req_rx_q; 608 609 err = idpf_initiate_soft_reset(vport, IDPF_SR_Q_CHANGE); 610 if (err) { 611 /* roll back queue change */ 612 vport_config->user_config.num_req_tx_qs = num_txq; 613 vport_config->user_config.num_req_rx_qs = num_rxq; 614 } 615 616unlock_mutex: 617 idpf_vport_ctrl_unlock(netdev); 618 619 return err; 620} 621 622/** 623 * idpf_get_ringparam - Get ring parameters 624 * @netdev: network interface device structure 625 * @ring: ethtool ringparam structure 626 * @kring: unused 627 * @ext_ack: unused 628 * 629 * Returns current ring parameters. TX and RX rings are reported separately, 630 * but the number of rings is not reported. 631 */ 632static void idpf_get_ringparam(struct net_device *netdev, 633 struct ethtool_ringparam *ring, 634 struct kernel_ethtool_ringparam *kring, 635 struct netlink_ext_ack *ext_ack) 636{ 637 struct idpf_vport *vport; 638 639 idpf_vport_ctrl_lock(netdev); 640 vport = idpf_netdev_to_vport(netdev); 641 642 ring->rx_max_pending = IDPF_MAX_RXQ_DESC; 643 ring->tx_max_pending = IDPF_MAX_TXQ_DESC; 644 ring->rx_pending = vport->rxq_desc_count; 645 ring->tx_pending = vport->txq_desc_count; 646 647 kring->tcp_data_split = idpf_vport_get_hsplit(vport); 648 649 idpf_vport_ctrl_unlock(netdev); 650} 651 652/** 653 * idpf_set_ringparam - Set ring parameters 654 * @netdev: network interface device structure 655 * @ring: ethtool ringparam structure 656 * @kring: unused 657 * @ext_ack: unused 658 * 659 * Sets ring parameters. TX and RX rings are controlled separately, but the 660 * number of rings is not specified, so all rings get the same settings. 661 */ 662static int idpf_set_ringparam(struct net_device *netdev, 663 struct ethtool_ringparam *ring, 664 struct kernel_ethtool_ringparam *kring, 665 struct netlink_ext_ack *ext_ack) 666{ 667 struct idpf_vport_user_config_data *config_data; 668 u32 new_rx_count, new_tx_count; 669 struct idpf_vport *vport; 670 int i, err = 0; 671 u16 idx; 672 673 idpf_vport_ctrl_lock(netdev); 674 vport = idpf_netdev_to_vport(netdev); 675 676 idx = vport->idx; 677 678 if (ring->tx_pending < IDPF_MIN_TXQ_DESC) { 679 netdev_err(netdev, "Descriptors requested (Tx: %u) is less than min supported (%u)\n", 680 ring->tx_pending, 681 IDPF_MIN_TXQ_DESC); 682 err = -EINVAL; 683 goto unlock_mutex; 684 } 685 686 if (ring->rx_pending < IDPF_MIN_RXQ_DESC) { 687 netdev_err(netdev, "Descriptors requested (Rx: %u) is less than min supported (%u)\n", 688 ring->rx_pending, 689 IDPF_MIN_RXQ_DESC); 690 err = -EINVAL; 691 goto unlock_mutex; 692 } 693 694 new_rx_count = ALIGN(ring->rx_pending, IDPF_REQ_RXQ_DESC_MULTIPLE); 695 if (new_rx_count != ring->rx_pending) 696 netdev_info(netdev, "Requested Rx descriptor count rounded up to %u\n", 697 new_rx_count); 698 699 new_tx_count = ALIGN(ring->tx_pending, IDPF_REQ_DESC_MULTIPLE); 700 if (new_tx_count != ring->tx_pending) 701 netdev_info(netdev, "Requested Tx descriptor count rounded up to %u\n", 702 new_tx_count); 703 704 if (new_tx_count == vport->txq_desc_count && 705 new_rx_count == vport->rxq_desc_count && 706 kring->tcp_data_split == idpf_vport_get_hsplit(vport)) 707 goto unlock_mutex; 708 709 if (!idpf_vport_set_hsplit(vport, kring->tcp_data_split)) { 710 NL_SET_ERR_MSG_MOD(ext_ack, 711 "setting TCP data split is not supported"); 712 err = -EOPNOTSUPP; 713 714 goto unlock_mutex; 715 } 716 717 config_data = &vport->adapter->vport_config[idx]->user_config; 718 config_data->num_req_txq_desc = new_tx_count; 719 config_data->num_req_rxq_desc = new_rx_count; 720 721 /* Since we adjusted the RX completion queue count, the RX buffer queue 722 * descriptor count needs to be adjusted as well 723 */ 724 for (i = 0; i < vport->num_bufqs_per_qgrp; i++) 725 vport->bufq_desc_count[i] = 726 IDPF_RX_BUFQ_DESC_COUNT(new_rx_count, 727 vport->num_bufqs_per_qgrp); 728 729 err = idpf_initiate_soft_reset(vport, IDPF_SR_Q_DESC_CHANGE); 730 731unlock_mutex: 732 idpf_vport_ctrl_unlock(netdev); 733 734 return err; 735} 736 737/** 738 * struct idpf_stats - definition for an ethtool statistic 739 * @stat_string: statistic name to display in ethtool -S output 740 * @sizeof_stat: the sizeof() the stat, must be no greater than sizeof(u64) 741 * @stat_offset: offsetof() the stat from a base pointer 742 * 743 * This structure defines a statistic to be added to the ethtool stats buffer. 744 * It defines a statistic as offset from a common base pointer. Stats should 745 * be defined in constant arrays using the IDPF_STAT macro, with every element 746 * of the array using the same _type for calculating the sizeof_stat and 747 * stat_offset. 748 * 749 * The @sizeof_stat is expected to be sizeof(u8), sizeof(u16), sizeof(u32) or 750 * sizeof(u64). Other sizes are not expected and will produce a WARN_ONCE from 751 * the idpf_add_ethtool_stat() helper function. 752 * 753 * The @stat_string is interpreted as a format string, allowing formatted 754 * values to be inserted while looping over multiple structures for a given 755 * statistics array. Thus, every statistic string in an array should have the 756 * same type and number of format specifiers, to be formatted by variadic 757 * arguments to the idpf_add_stat_string() helper function. 758 */ 759struct idpf_stats { 760 char stat_string[ETH_GSTRING_LEN]; 761 int sizeof_stat; 762 int stat_offset; 763}; 764 765/* Helper macro to define an idpf_stat structure with proper size and type. 766 * Use this when defining constant statistics arrays. Note that @_type expects 767 * only a type name and is used multiple times. 768 */ 769#define IDPF_STAT(_type, _name, _stat) { \ 770 .stat_string = _name, \ 771 .sizeof_stat = sizeof_field(_type, _stat), \ 772 .stat_offset = offsetof(_type, _stat) \ 773} 774 775/* Helper macros for defining some statistics related to queues */ 776#define IDPF_RX_QUEUE_STAT(_name, _stat) \ 777 IDPF_STAT(struct idpf_rx_queue, _name, _stat) 778#define IDPF_TX_QUEUE_STAT(_name, _stat) \ 779 IDPF_STAT(struct idpf_tx_queue, _name, _stat) 780 781/* Stats associated with a Tx queue */ 782static const struct idpf_stats idpf_gstrings_tx_queue_stats[] = { 783 IDPF_TX_QUEUE_STAT("pkts", q_stats.packets), 784 IDPF_TX_QUEUE_STAT("bytes", q_stats.bytes), 785 IDPF_TX_QUEUE_STAT("lso_pkts", q_stats.lso_pkts), 786}; 787 788/* Stats associated with an Rx queue */ 789static const struct idpf_stats idpf_gstrings_rx_queue_stats[] = { 790 IDPF_RX_QUEUE_STAT("pkts", q_stats.packets), 791 IDPF_RX_QUEUE_STAT("bytes", q_stats.bytes), 792 IDPF_RX_QUEUE_STAT("rx_gro_hw_pkts", q_stats.rsc_pkts), 793}; 794 795#define IDPF_TX_QUEUE_STATS_LEN ARRAY_SIZE(idpf_gstrings_tx_queue_stats) 796#define IDPF_RX_QUEUE_STATS_LEN ARRAY_SIZE(idpf_gstrings_rx_queue_stats) 797 798#define IDPF_PORT_STAT(_name, _stat) \ 799 IDPF_STAT(struct idpf_vport, _name, _stat) 800 801static const struct idpf_stats idpf_gstrings_port_stats[] = { 802 IDPF_PORT_STAT("rx-csum_errors", port_stats.rx_hw_csum_err), 803 IDPF_PORT_STAT("rx-hsplit", port_stats.rx_hsplit), 804 IDPF_PORT_STAT("rx-hsplit_hbo", port_stats.rx_hsplit_hbo), 805 IDPF_PORT_STAT("rx-bad_descs", port_stats.rx_bad_descs), 806 IDPF_PORT_STAT("tx-skb_drops", port_stats.tx_drops), 807 IDPF_PORT_STAT("tx-dma_map_errs", port_stats.tx_dma_map_errs), 808 IDPF_PORT_STAT("tx-linearized_pkts", port_stats.tx_linearize), 809 IDPF_PORT_STAT("tx-busy_events", port_stats.tx_busy), 810 IDPF_PORT_STAT("rx-unicast_pkts", port_stats.vport_stats.rx_unicast), 811 IDPF_PORT_STAT("rx-multicast_pkts", port_stats.vport_stats.rx_multicast), 812 IDPF_PORT_STAT("rx-broadcast_pkts", port_stats.vport_stats.rx_broadcast), 813 IDPF_PORT_STAT("rx-unknown_protocol", port_stats.vport_stats.rx_unknown_protocol), 814 IDPF_PORT_STAT("tx-unicast_pkts", port_stats.vport_stats.tx_unicast), 815 IDPF_PORT_STAT("tx-multicast_pkts", port_stats.vport_stats.tx_multicast), 816 IDPF_PORT_STAT("tx-broadcast_pkts", port_stats.vport_stats.tx_broadcast), 817}; 818 819#define IDPF_PORT_STATS_LEN ARRAY_SIZE(idpf_gstrings_port_stats) 820 821/** 822 * __idpf_add_qstat_strings - copy stat strings into ethtool buffer 823 * @p: ethtool supplied buffer 824 * @stats: stat definitions array 825 * @size: size of the stats array 826 * @type: stat type 827 * @idx: stat index 828 * 829 * Format and copy the strings described by stats into the buffer pointed at 830 * by p. 831 */ 832static void __idpf_add_qstat_strings(u8 **p, const struct idpf_stats *stats, 833 const unsigned int size, const char *type, 834 unsigned int idx) 835{ 836 unsigned int i; 837 838 for (i = 0; i < size; i++) 839 ethtool_sprintf(p, "%s_q-%u_%s", 840 type, idx, stats[i].stat_string); 841} 842 843/** 844 * idpf_add_qstat_strings - Copy queue stat strings into ethtool buffer 845 * @p: ethtool supplied buffer 846 * @stats: stat definitions array 847 * @type: stat type 848 * @idx: stat idx 849 * 850 * Format and copy the strings described by the const static stats value into 851 * the buffer pointed at by p. 852 * 853 * The parameter @stats is evaluated twice, so parameters with side effects 854 * should be avoided. Additionally, stats must be an array such that 855 * ARRAY_SIZE can be called on it. 856 */ 857#define idpf_add_qstat_strings(p, stats, type, idx) \ 858 __idpf_add_qstat_strings(p, stats, ARRAY_SIZE(stats), type, idx) 859 860/** 861 * idpf_add_stat_strings - Copy port stat strings into ethtool buffer 862 * @p: ethtool buffer 863 * @stats: struct to copy from 864 * @size: size of stats array to copy from 865 */ 866static void idpf_add_stat_strings(u8 **p, const struct idpf_stats *stats, 867 const unsigned int size) 868{ 869 unsigned int i; 870 871 for (i = 0; i < size; i++) 872 ethtool_puts(p, stats[i].stat_string); 873} 874 875/** 876 * idpf_get_stat_strings - Get stat strings 877 * @netdev: network interface device structure 878 * @data: buffer for string data 879 * 880 * Builds the statistics string table 881 */ 882static void idpf_get_stat_strings(struct net_device *netdev, u8 *data) 883{ 884 struct idpf_netdev_priv *np = netdev_priv(netdev); 885 struct idpf_vport_config *vport_config; 886 unsigned int i; 887 888 idpf_add_stat_strings(&data, idpf_gstrings_port_stats, 889 IDPF_PORT_STATS_LEN); 890 891 vport_config = np->adapter->vport_config[np->vport_idx]; 892 /* It's critical that we always report a constant number of strings and 893 * that the strings are reported in the same order regardless of how 894 * many queues are actually in use. 895 */ 896 for (i = 0; i < vport_config->max_q.max_txq; i++) 897 idpf_add_qstat_strings(&data, idpf_gstrings_tx_queue_stats, 898 "tx", i); 899 900 for (i = 0; i < vport_config->max_q.max_rxq; i++) 901 idpf_add_qstat_strings(&data, idpf_gstrings_rx_queue_stats, 902 "rx", i); 903} 904 905/** 906 * idpf_get_strings - Get string set 907 * @netdev: network interface device structure 908 * @sset: id of string set 909 * @data: buffer for string data 910 * 911 * Builds string tables for various string sets 912 */ 913static void idpf_get_strings(struct net_device *netdev, u32 sset, u8 *data) 914{ 915 switch (sset) { 916 case ETH_SS_STATS: 917 idpf_get_stat_strings(netdev, data); 918 break; 919 default: 920 break; 921 } 922} 923 924/** 925 * idpf_get_sset_count - Get length of string set 926 * @netdev: network interface device structure 927 * @sset: id of string set 928 * 929 * Reports size of various string tables. 930 */ 931static int idpf_get_sset_count(struct net_device *netdev, int sset) 932{ 933 struct idpf_netdev_priv *np = netdev_priv(netdev); 934 struct idpf_vport_config *vport_config; 935 u16 max_txq, max_rxq; 936 937 if (sset != ETH_SS_STATS) 938 return -EINVAL; 939 940 vport_config = np->adapter->vport_config[np->vport_idx]; 941 /* This size reported back here *must* be constant throughout the 942 * lifecycle of the netdevice, i.e. we must report the maximum length 943 * even for queues that don't technically exist. This is due to the 944 * fact that this userspace API uses three separate ioctl calls to get 945 * stats data but has no way to communicate back to userspace when that 946 * size has changed, which can typically happen as a result of changing 947 * number of queues. If the number/order of stats change in the middle 948 * of this call chain it will lead to userspace crashing/accessing bad 949 * data through buffer under/overflow. 950 */ 951 max_txq = vport_config->max_q.max_txq; 952 max_rxq = vport_config->max_q.max_rxq; 953 954 return IDPF_PORT_STATS_LEN + (IDPF_TX_QUEUE_STATS_LEN * max_txq) + 955 (IDPF_RX_QUEUE_STATS_LEN * max_rxq); 956} 957 958/** 959 * idpf_add_one_ethtool_stat - copy the stat into the supplied buffer 960 * @data: location to store the stat value 961 * @pstat: old stat pointer to copy from 962 * @stat: the stat definition 963 * 964 * Copies the stat data defined by the pointer and stat structure pair into 965 * the memory supplied as data. If the pointer is null, data will be zero'd. 966 */ 967static void idpf_add_one_ethtool_stat(u64 *data, const void *pstat, 968 const struct idpf_stats *stat) 969{ 970 char *p; 971 972 if (!pstat) { 973 /* Ensure that the ethtool data buffer is zero'd for any stats 974 * which don't have a valid pointer. 975 */ 976 *data = 0; 977 return; 978 } 979 980 p = (char *)pstat + stat->stat_offset; 981 switch (stat->sizeof_stat) { 982 case sizeof(u64): 983 *data = *((u64 *)p); 984 break; 985 case sizeof(u32): 986 *data = *((u32 *)p); 987 break; 988 case sizeof(u16): 989 *data = *((u16 *)p); 990 break; 991 case sizeof(u8): 992 *data = *((u8 *)p); 993 break; 994 default: 995 WARN_ONCE(1, "unexpected stat size for %s", 996 stat->stat_string); 997 *data = 0; 998 } 999} 1000 1001/** 1002 * idpf_add_queue_stats - copy queue statistics into supplied buffer 1003 * @data: ethtool stats buffer 1004 * @q: the queue to copy 1005 * @type: type of the queue 1006 * 1007 * Queue statistics must be copied while protected by u64_stats_fetch_begin, 1008 * so we can't directly use idpf_add_ethtool_stats. Assumes that queue stats 1009 * are defined in idpf_gstrings_queue_stats. If the queue pointer is null, 1010 * zero out the queue stat values and update the data pointer. Otherwise 1011 * safely copy the stats from the queue into the supplied buffer and update 1012 * the data pointer when finished. 1013 * 1014 * This function expects to be called while under rcu_read_lock(). 1015 */ 1016static void idpf_add_queue_stats(u64 **data, const void *q, 1017 enum virtchnl2_queue_type type) 1018{ 1019 const struct u64_stats_sync *stats_sync; 1020 const struct idpf_stats *stats; 1021 unsigned int start; 1022 unsigned int size; 1023 unsigned int i; 1024 1025 if (type == VIRTCHNL2_QUEUE_TYPE_RX) { 1026 size = IDPF_RX_QUEUE_STATS_LEN; 1027 stats = idpf_gstrings_rx_queue_stats; 1028 stats_sync = &((const struct idpf_rx_queue *)q)->stats_sync; 1029 } else { 1030 size = IDPF_TX_QUEUE_STATS_LEN; 1031 stats = idpf_gstrings_tx_queue_stats; 1032 stats_sync = &((const struct idpf_tx_queue *)q)->stats_sync; 1033 } 1034 1035 /* To avoid invalid statistics values, ensure that we keep retrying 1036 * the copy until we get a consistent value according to 1037 * u64_stats_fetch_retry. 1038 */ 1039 do { 1040 start = u64_stats_fetch_begin(stats_sync); 1041 for (i = 0; i < size; i++) 1042 idpf_add_one_ethtool_stat(&(*data)[i], q, &stats[i]); 1043 } while (u64_stats_fetch_retry(stats_sync, start)); 1044 1045 /* Once we successfully copy the stats in, update the data pointer */ 1046 *data += size; 1047} 1048 1049/** 1050 * idpf_add_empty_queue_stats - Add stats for a non-existent queue 1051 * @data: pointer to data buffer 1052 * @qtype: type of data queue 1053 * 1054 * We must report a constant length of stats back to userspace regardless of 1055 * how many queues are actually in use because stats collection happens over 1056 * three separate ioctls and there's no way to notify userspace the size 1057 * changed between those calls. This adds empty to data to the stats since we 1058 * don't have a real queue to refer to for this stats slot. 1059 */ 1060static void idpf_add_empty_queue_stats(u64 **data, u16 qtype) 1061{ 1062 unsigned int i; 1063 int stats_len; 1064 1065 if (qtype == VIRTCHNL2_QUEUE_TYPE_RX) 1066 stats_len = IDPF_RX_QUEUE_STATS_LEN; 1067 else 1068 stats_len = IDPF_TX_QUEUE_STATS_LEN; 1069 1070 for (i = 0; i < stats_len; i++) 1071 (*data)[i] = 0; 1072 *data += stats_len; 1073} 1074 1075/** 1076 * idpf_add_port_stats - Copy port stats into ethtool buffer 1077 * @vport: virtual port struct 1078 * @data: ethtool buffer to copy into 1079 */ 1080static void idpf_add_port_stats(struct idpf_vport *vport, u64 **data) 1081{ 1082 unsigned int size = IDPF_PORT_STATS_LEN; 1083 unsigned int start; 1084 unsigned int i; 1085 1086 do { 1087 start = u64_stats_fetch_begin(&vport->port_stats.stats_sync); 1088 for (i = 0; i < size; i++) 1089 idpf_add_one_ethtool_stat(&(*data)[i], vport, 1090 &idpf_gstrings_port_stats[i]); 1091 } while (u64_stats_fetch_retry(&vport->port_stats.stats_sync, start)); 1092 1093 *data += size; 1094} 1095 1096/** 1097 * idpf_collect_queue_stats - accumulate various per queue stats 1098 * into port level stats 1099 * @vport: pointer to vport struct 1100 **/ 1101static void idpf_collect_queue_stats(struct idpf_vport *vport) 1102{ 1103 struct idpf_port_stats *pstats = &vport->port_stats; 1104 int i, j; 1105 1106 /* zero out port stats since they're actually tracked in per 1107 * queue stats; this is only for reporting 1108 */ 1109 u64_stats_update_begin(&pstats->stats_sync); 1110 u64_stats_set(&pstats->rx_hw_csum_err, 0); 1111 u64_stats_set(&pstats->rx_hsplit, 0); 1112 u64_stats_set(&pstats->rx_hsplit_hbo, 0); 1113 u64_stats_set(&pstats->rx_bad_descs, 0); 1114 u64_stats_set(&pstats->tx_linearize, 0); 1115 u64_stats_set(&pstats->tx_busy, 0); 1116 u64_stats_set(&pstats->tx_drops, 0); 1117 u64_stats_set(&pstats->tx_dma_map_errs, 0); 1118 u64_stats_update_end(&pstats->stats_sync); 1119 1120 for (i = 0; i < vport->num_rxq_grp; i++) { 1121 struct idpf_rxq_group *rxq_grp = &vport->rxq_grps[i]; 1122 u16 num_rxq; 1123 1124 if (idpf_is_queue_model_split(vport->rxq_model)) 1125 num_rxq = rxq_grp->splitq.num_rxq_sets; 1126 else 1127 num_rxq = rxq_grp->singleq.num_rxq; 1128 1129 for (j = 0; j < num_rxq; j++) { 1130 u64 hw_csum_err, hsplit, hsplit_hbo, bad_descs; 1131 struct idpf_rx_queue_stats *stats; 1132 struct idpf_rx_queue *rxq; 1133 unsigned int start; 1134 1135 if (idpf_is_queue_model_split(vport->rxq_model)) 1136 rxq = &rxq_grp->splitq.rxq_sets[j]->rxq; 1137 else 1138 rxq = rxq_grp->singleq.rxqs[j]; 1139 1140 if (!rxq) 1141 continue; 1142 1143 do { 1144 start = u64_stats_fetch_begin(&rxq->stats_sync); 1145 1146 stats = &rxq->q_stats; 1147 hw_csum_err = u64_stats_read(&stats->hw_csum_err); 1148 hsplit = u64_stats_read(&stats->hsplit_pkts); 1149 hsplit_hbo = u64_stats_read(&stats->hsplit_buf_ovf); 1150 bad_descs = u64_stats_read(&stats->bad_descs); 1151 } while (u64_stats_fetch_retry(&rxq->stats_sync, start)); 1152 1153 u64_stats_update_begin(&pstats->stats_sync); 1154 u64_stats_add(&pstats->rx_hw_csum_err, hw_csum_err); 1155 u64_stats_add(&pstats->rx_hsplit, hsplit); 1156 u64_stats_add(&pstats->rx_hsplit_hbo, hsplit_hbo); 1157 u64_stats_add(&pstats->rx_bad_descs, bad_descs); 1158 u64_stats_update_end(&pstats->stats_sync); 1159 } 1160 } 1161 1162 for (i = 0; i < vport->num_txq_grp; i++) { 1163 struct idpf_txq_group *txq_grp = &vport->txq_grps[i]; 1164 1165 for (j = 0; j < txq_grp->num_txq; j++) { 1166 u64 linearize, qbusy, skb_drops, dma_map_errs; 1167 struct idpf_tx_queue *txq = txq_grp->txqs[j]; 1168 struct idpf_tx_queue_stats *stats; 1169 unsigned int start; 1170 1171 if (!txq) 1172 continue; 1173 1174 do { 1175 start = u64_stats_fetch_begin(&txq->stats_sync); 1176 1177 stats = &txq->q_stats; 1178 linearize = u64_stats_read(&stats->linearize); 1179 qbusy = u64_stats_read(&stats->q_busy); 1180 skb_drops = u64_stats_read(&stats->skb_drops); 1181 dma_map_errs = u64_stats_read(&stats->dma_map_errs); 1182 } while (u64_stats_fetch_retry(&txq->stats_sync, start)); 1183 1184 u64_stats_update_begin(&pstats->stats_sync); 1185 u64_stats_add(&pstats->tx_linearize, linearize); 1186 u64_stats_add(&pstats->tx_busy, qbusy); 1187 u64_stats_add(&pstats->tx_drops, skb_drops); 1188 u64_stats_add(&pstats->tx_dma_map_errs, dma_map_errs); 1189 u64_stats_update_end(&pstats->stats_sync); 1190 } 1191 } 1192} 1193 1194/** 1195 * idpf_get_ethtool_stats - report device statistics 1196 * @netdev: network interface device structure 1197 * @stats: ethtool statistics structure 1198 * @data: pointer to data buffer 1199 * 1200 * All statistics are added to the data buffer as an array of u64. 1201 */ 1202static void idpf_get_ethtool_stats(struct net_device *netdev, 1203 struct ethtool_stats __always_unused *stats, 1204 u64 *data) 1205{ 1206 struct idpf_netdev_priv *np = netdev_priv(netdev); 1207 struct idpf_vport_config *vport_config; 1208 struct idpf_vport *vport; 1209 unsigned int total = 0; 1210 unsigned int i, j; 1211 bool is_splitq; 1212 u16 qtype; 1213 1214 idpf_vport_ctrl_lock(netdev); 1215 vport = idpf_netdev_to_vport(netdev); 1216 1217 if (!test_bit(IDPF_VPORT_UP, np->state)) { 1218 idpf_vport_ctrl_unlock(netdev); 1219 1220 return; 1221 } 1222 1223 rcu_read_lock(); 1224 1225 idpf_collect_queue_stats(vport); 1226 idpf_add_port_stats(vport, &data); 1227 1228 for (i = 0; i < vport->num_txq_grp; i++) { 1229 struct idpf_txq_group *txq_grp = &vport->txq_grps[i]; 1230 1231 qtype = VIRTCHNL2_QUEUE_TYPE_TX; 1232 1233 for (j = 0; j < txq_grp->num_txq; j++, total++) { 1234 struct idpf_tx_queue *txq = txq_grp->txqs[j]; 1235 1236 if (!txq) 1237 idpf_add_empty_queue_stats(&data, qtype); 1238 else 1239 idpf_add_queue_stats(&data, txq, qtype); 1240 } 1241 } 1242 1243 vport_config = vport->adapter->vport_config[vport->idx]; 1244 /* It is critical we provide a constant number of stats back to 1245 * userspace regardless of how many queues are actually in use because 1246 * there is no way to inform userspace the size has changed between 1247 * ioctl calls. This will fill in any missing stats with zero. 1248 */ 1249 for (; total < vport_config->max_q.max_txq; total++) 1250 idpf_add_empty_queue_stats(&data, VIRTCHNL2_QUEUE_TYPE_TX); 1251 total = 0; 1252 1253 is_splitq = idpf_is_queue_model_split(vport->rxq_model); 1254 1255 for (i = 0; i < vport->num_rxq_grp; i++) { 1256 struct idpf_rxq_group *rxq_grp = &vport->rxq_grps[i]; 1257 u16 num_rxq; 1258 1259 qtype = VIRTCHNL2_QUEUE_TYPE_RX; 1260 1261 if (is_splitq) 1262 num_rxq = rxq_grp->splitq.num_rxq_sets; 1263 else 1264 num_rxq = rxq_grp->singleq.num_rxq; 1265 1266 for (j = 0; j < num_rxq; j++, total++) { 1267 struct idpf_rx_queue *rxq; 1268 1269 if (is_splitq) 1270 rxq = &rxq_grp->splitq.rxq_sets[j]->rxq; 1271 else 1272 rxq = rxq_grp->singleq.rxqs[j]; 1273 if (!rxq) 1274 idpf_add_empty_queue_stats(&data, qtype); 1275 else 1276 idpf_add_queue_stats(&data, rxq, qtype); 1277 } 1278 } 1279 1280 for (; total < vport_config->max_q.max_rxq; total++) 1281 idpf_add_empty_queue_stats(&data, VIRTCHNL2_QUEUE_TYPE_RX); 1282 1283 rcu_read_unlock(); 1284 1285 idpf_vport_ctrl_unlock(netdev); 1286} 1287 1288/** 1289 * idpf_find_rxq_vec - find rxq vector from q index 1290 * @vport: virtual port associated to queue 1291 * @q_num: q index used to find queue 1292 * 1293 * returns pointer to rx vector 1294 */ 1295struct idpf_q_vector *idpf_find_rxq_vec(const struct idpf_vport *vport, 1296 u32 q_num) 1297{ 1298 int q_grp, q_idx; 1299 1300 if (!idpf_is_queue_model_split(vport->rxq_model)) 1301 return vport->rxq_grps->singleq.rxqs[q_num]->q_vector; 1302 1303 q_grp = q_num / IDPF_DFLT_SPLITQ_RXQ_PER_GROUP; 1304 q_idx = q_num % IDPF_DFLT_SPLITQ_RXQ_PER_GROUP; 1305 1306 return vport->rxq_grps[q_grp].splitq.rxq_sets[q_idx]->rxq.q_vector; 1307} 1308 1309/** 1310 * idpf_find_txq_vec - find txq vector from q index 1311 * @vport: virtual port associated to queue 1312 * @q_num: q index used to find queue 1313 * 1314 * returns pointer to tx vector 1315 */ 1316struct idpf_q_vector *idpf_find_txq_vec(const struct idpf_vport *vport, 1317 u32 q_num) 1318{ 1319 int q_grp; 1320 1321 if (!idpf_is_queue_model_split(vport->txq_model)) 1322 return vport->txqs[q_num]->q_vector; 1323 1324 q_grp = q_num / IDPF_DFLT_SPLITQ_TXQ_PER_GROUP; 1325 1326 return vport->txq_grps[q_grp].complq->q_vector; 1327} 1328 1329/** 1330 * __idpf_get_q_coalesce - get ITR values for specific queue 1331 * @ec: ethtool structure to fill with driver's coalesce settings 1332 * @q_vector: queue vector corresponding to this queue 1333 * @type: queue type 1334 */ 1335static void __idpf_get_q_coalesce(struct ethtool_coalesce *ec, 1336 const struct idpf_q_vector *q_vector, 1337 enum virtchnl2_queue_type type) 1338{ 1339 if (type == VIRTCHNL2_QUEUE_TYPE_RX) { 1340 ec->use_adaptive_rx_coalesce = 1341 IDPF_ITR_IS_DYNAMIC(q_vector->rx_intr_mode); 1342 ec->rx_coalesce_usecs = q_vector->rx_itr_value; 1343 } else { 1344 ec->use_adaptive_tx_coalesce = 1345 IDPF_ITR_IS_DYNAMIC(q_vector->tx_intr_mode); 1346 ec->tx_coalesce_usecs = q_vector->tx_itr_value; 1347 } 1348} 1349 1350/** 1351 * idpf_get_q_coalesce - get ITR values for specific queue 1352 * @netdev: pointer to the netdev associated with this query 1353 * @ec: coalesce settings to program the device with 1354 * @q_num: update ITR/INTRL (coalesce) settings for this queue number/index 1355 * 1356 * Return 0 on success, and negative on failure 1357 */ 1358static int idpf_get_q_coalesce(struct net_device *netdev, 1359 struct ethtool_coalesce *ec, 1360 u32 q_num) 1361{ 1362 const struct idpf_netdev_priv *np = netdev_priv(netdev); 1363 const struct idpf_vport *vport; 1364 int err = 0; 1365 1366 idpf_vport_ctrl_lock(netdev); 1367 vport = idpf_netdev_to_vport(netdev); 1368 1369 if (!test_bit(IDPF_VPORT_UP, np->state)) 1370 goto unlock_mutex; 1371 1372 if (q_num >= vport->num_rxq && q_num >= vport->num_txq) { 1373 err = -EINVAL; 1374 goto unlock_mutex; 1375 } 1376 1377 if (q_num < vport->num_rxq) 1378 __idpf_get_q_coalesce(ec, idpf_find_rxq_vec(vport, q_num), 1379 VIRTCHNL2_QUEUE_TYPE_RX); 1380 1381 if (q_num < vport->num_txq) 1382 __idpf_get_q_coalesce(ec, idpf_find_txq_vec(vport, q_num), 1383 VIRTCHNL2_QUEUE_TYPE_TX); 1384 1385unlock_mutex: 1386 idpf_vport_ctrl_unlock(netdev); 1387 1388 return err; 1389} 1390 1391/** 1392 * idpf_get_coalesce - get ITR values as requested by user 1393 * @netdev: pointer to the netdev associated with this query 1394 * @ec: coalesce settings to be filled 1395 * @kec: unused 1396 * @extack: unused 1397 * 1398 * Return 0 on success, and negative on failure 1399 */ 1400static int idpf_get_coalesce(struct net_device *netdev, 1401 struct ethtool_coalesce *ec, 1402 struct kernel_ethtool_coalesce *kec, 1403 struct netlink_ext_ack *extack) 1404{ 1405 /* Return coalesce based on queue number zero */ 1406 return idpf_get_q_coalesce(netdev, ec, 0); 1407} 1408 1409/** 1410 * idpf_get_per_q_coalesce - get ITR values as requested by user 1411 * @netdev: pointer to the netdev associated with this query 1412 * @q_num: queue for which the itr values has to retrieved 1413 * @ec: coalesce settings to be filled 1414 * 1415 * Return 0 on success, and negative on failure 1416 */ 1417 1418static int idpf_get_per_q_coalesce(struct net_device *netdev, u32 q_num, 1419 struct ethtool_coalesce *ec) 1420{ 1421 return idpf_get_q_coalesce(netdev, ec, q_num); 1422} 1423 1424/** 1425 * __idpf_set_q_coalesce - set ITR values for specific queue 1426 * @ec: ethtool structure from user to update ITR settings 1427 * @q_coal: per queue coalesce settings 1428 * @qv: queue vector for which itr values has to be set 1429 * @is_rxq: is queue type rx 1430 * 1431 * Returns 0 on success, negative otherwise. 1432 */ 1433static int __idpf_set_q_coalesce(const struct ethtool_coalesce *ec, 1434 struct idpf_q_coalesce *q_coal, 1435 struct idpf_q_vector *qv, bool is_rxq) 1436{ 1437 u32 use_adaptive_coalesce, coalesce_usecs; 1438 bool is_dim_ena = false; 1439 u16 itr_val; 1440 1441 if (is_rxq) { 1442 is_dim_ena = IDPF_ITR_IS_DYNAMIC(qv->rx_intr_mode); 1443 use_adaptive_coalesce = ec->use_adaptive_rx_coalesce; 1444 coalesce_usecs = ec->rx_coalesce_usecs; 1445 itr_val = qv->rx_itr_value; 1446 } else { 1447 is_dim_ena = IDPF_ITR_IS_DYNAMIC(qv->tx_intr_mode); 1448 use_adaptive_coalesce = ec->use_adaptive_tx_coalesce; 1449 coalesce_usecs = ec->tx_coalesce_usecs; 1450 itr_val = qv->tx_itr_value; 1451 } 1452 if (coalesce_usecs != itr_val && use_adaptive_coalesce) { 1453 netdev_err(qv->vport->netdev, "Cannot set coalesce usecs if adaptive enabled\n"); 1454 1455 return -EINVAL; 1456 } 1457 1458 if (is_dim_ena && use_adaptive_coalesce) 1459 return 0; 1460 1461 if (coalesce_usecs > IDPF_ITR_MAX) { 1462 netdev_err(qv->vport->netdev, 1463 "Invalid value, %d-usecs range is 0-%d\n", 1464 coalesce_usecs, IDPF_ITR_MAX); 1465 1466 return -EINVAL; 1467 } 1468 1469 if (coalesce_usecs % 2) { 1470 coalesce_usecs--; 1471 netdev_info(qv->vport->netdev, 1472 "HW only supports even ITR values, ITR rounded to %d\n", 1473 coalesce_usecs); 1474 } 1475 1476 if (is_rxq) { 1477 qv->rx_itr_value = coalesce_usecs; 1478 q_coal->rx_coalesce_usecs = coalesce_usecs; 1479 if (use_adaptive_coalesce) { 1480 qv->rx_intr_mode = IDPF_ITR_DYNAMIC; 1481 q_coal->rx_intr_mode = IDPF_ITR_DYNAMIC; 1482 } else { 1483 qv->rx_intr_mode = !IDPF_ITR_DYNAMIC; 1484 q_coal->rx_intr_mode = !IDPF_ITR_DYNAMIC; 1485 idpf_vport_intr_write_itr(qv, coalesce_usecs, false); 1486 } 1487 } else { 1488 qv->tx_itr_value = coalesce_usecs; 1489 q_coal->tx_coalesce_usecs = coalesce_usecs; 1490 if (use_adaptive_coalesce) { 1491 qv->tx_intr_mode = IDPF_ITR_DYNAMIC; 1492 q_coal->tx_intr_mode = IDPF_ITR_DYNAMIC; 1493 } else { 1494 qv->tx_intr_mode = !IDPF_ITR_DYNAMIC; 1495 q_coal->tx_intr_mode = !IDPF_ITR_DYNAMIC; 1496 idpf_vport_intr_write_itr(qv, coalesce_usecs, true); 1497 } 1498 } 1499 1500 /* Update of static/dynamic itr will be taken care when interrupt is 1501 * fired 1502 */ 1503 return 0; 1504} 1505 1506/** 1507 * idpf_set_q_coalesce - set ITR values for specific queue 1508 * @vport: vport associated to the queue that need updating 1509 * @q_coal: per queue coalesce settings 1510 * @ec: coalesce settings to program the device with 1511 * @q_num: update ITR/INTRL (coalesce) settings for this queue number/index 1512 * @is_rxq: is queue type rx 1513 * 1514 * Return 0 on success, and negative on failure 1515 */ 1516static int idpf_set_q_coalesce(const struct idpf_vport *vport, 1517 struct idpf_q_coalesce *q_coal, 1518 const struct ethtool_coalesce *ec, 1519 int q_num, bool is_rxq) 1520{ 1521 struct idpf_q_vector *qv; 1522 1523 qv = is_rxq ? idpf_find_rxq_vec(vport, q_num) : 1524 idpf_find_txq_vec(vport, q_num); 1525 1526 if (qv && __idpf_set_q_coalesce(ec, q_coal, qv, is_rxq)) 1527 return -EINVAL; 1528 1529 return 0; 1530} 1531 1532/** 1533 * idpf_set_coalesce - set ITR values as requested by user 1534 * @netdev: pointer to the netdev associated with this query 1535 * @ec: coalesce settings to program the device with 1536 * @kec: unused 1537 * @extack: unused 1538 * 1539 * Return 0 on success, and negative on failure 1540 */ 1541static int idpf_set_coalesce(struct net_device *netdev, 1542 struct ethtool_coalesce *ec, 1543 struct kernel_ethtool_coalesce *kec, 1544 struct netlink_ext_ack *extack) 1545{ 1546 struct idpf_netdev_priv *np = netdev_priv(netdev); 1547 struct idpf_vport_user_config_data *user_config; 1548 struct idpf_q_coalesce *q_coal; 1549 struct idpf_vport *vport; 1550 int i, err = 0; 1551 1552 user_config = &np->adapter->vport_config[np->vport_idx]->user_config; 1553 1554 idpf_vport_ctrl_lock(netdev); 1555 vport = idpf_netdev_to_vport(netdev); 1556 1557 if (!test_bit(IDPF_VPORT_UP, np->state)) 1558 goto unlock_mutex; 1559 1560 for (i = 0; i < vport->num_txq; i++) { 1561 q_coal = &user_config->q_coalesce[i]; 1562 err = idpf_set_q_coalesce(vport, q_coal, ec, i, false); 1563 if (err) 1564 goto unlock_mutex; 1565 } 1566 1567 for (i = 0; i < vport->num_rxq; i++) { 1568 q_coal = &user_config->q_coalesce[i]; 1569 err = idpf_set_q_coalesce(vport, q_coal, ec, i, true); 1570 if (err) 1571 goto unlock_mutex; 1572 } 1573 1574unlock_mutex: 1575 idpf_vport_ctrl_unlock(netdev); 1576 1577 return err; 1578} 1579 1580/** 1581 * idpf_set_per_q_coalesce - set ITR values as requested by user 1582 * @netdev: pointer to the netdev associated with this query 1583 * @q_num: queue for which the itr values has to be set 1584 * @ec: coalesce settings to program the device with 1585 * 1586 * Return 0 on success, and negative on failure 1587 */ 1588static int idpf_set_per_q_coalesce(struct net_device *netdev, u32 q_num, 1589 struct ethtool_coalesce *ec) 1590{ 1591 struct idpf_netdev_priv *np = netdev_priv(netdev); 1592 struct idpf_vport_user_config_data *user_config; 1593 struct idpf_q_coalesce *q_coal; 1594 struct idpf_vport *vport; 1595 int err; 1596 1597 idpf_vport_ctrl_lock(netdev); 1598 vport = idpf_netdev_to_vport(netdev); 1599 user_config = &np->adapter->vport_config[np->vport_idx]->user_config; 1600 q_coal = &user_config->q_coalesce[q_num]; 1601 1602 err = idpf_set_q_coalesce(vport, q_coal, ec, q_num, false); 1603 if (err) { 1604 idpf_vport_ctrl_unlock(netdev); 1605 1606 return err; 1607 } 1608 1609 err = idpf_set_q_coalesce(vport, q_coal, ec, q_num, true); 1610 1611 idpf_vport_ctrl_unlock(netdev); 1612 1613 return err; 1614} 1615 1616/** 1617 * idpf_get_msglevel - Get debug message level 1618 * @netdev: network interface device structure 1619 * 1620 * Returns current debug message level. 1621 */ 1622static u32 idpf_get_msglevel(struct net_device *netdev) 1623{ 1624 struct idpf_adapter *adapter = idpf_netdev_to_adapter(netdev); 1625 1626 return adapter->msg_enable; 1627} 1628 1629/** 1630 * idpf_set_msglevel - Set debug message level 1631 * @netdev: network interface device structure 1632 * @data: message level 1633 * 1634 * Set current debug message level. Higher values cause the driver to 1635 * be noisier. 1636 */ 1637static void idpf_set_msglevel(struct net_device *netdev, u32 data) 1638{ 1639 struct idpf_adapter *adapter = idpf_netdev_to_adapter(netdev); 1640 1641 adapter->msg_enable = data; 1642} 1643 1644/** 1645 * idpf_get_link_ksettings - Get Link Speed and Duplex settings 1646 * @netdev: network interface device structure 1647 * @cmd: ethtool command 1648 * 1649 * Reports speed/duplex settings. 1650 **/ 1651static int idpf_get_link_ksettings(struct net_device *netdev, 1652 struct ethtool_link_ksettings *cmd) 1653{ 1654 struct idpf_netdev_priv *np = netdev_priv(netdev); 1655 1656 ethtool_link_ksettings_zero_link_mode(cmd, supported); 1657 cmd->base.autoneg = AUTONEG_DISABLE; 1658 cmd->base.port = PORT_NONE; 1659 if (netif_carrier_ok(netdev)) { 1660 cmd->base.duplex = DUPLEX_FULL; 1661 cmd->base.speed = np->link_speed_mbps; 1662 } else { 1663 cmd->base.duplex = DUPLEX_UNKNOWN; 1664 cmd->base.speed = SPEED_UNKNOWN; 1665 } 1666 1667 return 0; 1668} 1669 1670/** 1671 * idpf_get_timestamp_filters - Get the supported timestamping mode 1672 * @vport: Virtual port structure 1673 * @info: ethtool timestamping info structure 1674 * 1675 * Get the Tx/Rx timestamp filters. 1676 */ 1677static void idpf_get_timestamp_filters(const struct idpf_vport *vport, 1678 struct kernel_ethtool_ts_info *info) 1679{ 1680 info->so_timestamping = SOF_TIMESTAMPING_RX_HARDWARE | 1681 SOF_TIMESTAMPING_RAW_HARDWARE; 1682 1683 info->tx_types = BIT(HWTSTAMP_TX_OFF); 1684 info->rx_filters = BIT(HWTSTAMP_FILTER_NONE) | BIT(HWTSTAMP_FILTER_ALL); 1685 1686 if (!vport->tx_tstamp_caps || 1687 vport->adapter->ptp->tx_tstamp_access == IDPF_PTP_NONE) 1688 return; 1689 1690 info->so_timestamping |= SOF_TIMESTAMPING_TX_SOFTWARE | 1691 SOF_TIMESTAMPING_TX_HARDWARE; 1692 1693 info->tx_types |= BIT(HWTSTAMP_TX_ON); 1694} 1695 1696/** 1697 * idpf_get_ts_info - Get device PHC association 1698 * @netdev: network interface device structure 1699 * @info: ethtool timestamping info structure 1700 * 1701 * Return: 0 on success, -errno otherwise. 1702 */ 1703static int idpf_get_ts_info(struct net_device *netdev, 1704 struct kernel_ethtool_ts_info *info) 1705{ 1706 struct idpf_netdev_priv *np = netdev_priv(netdev); 1707 struct idpf_vport *vport; 1708 int err = 0; 1709 1710 if (!mutex_trylock(&np->adapter->vport_ctrl_lock)) 1711 return -EBUSY; 1712 1713 vport = idpf_netdev_to_vport(netdev); 1714 1715 if (!vport->adapter->ptp) { 1716 err = -EOPNOTSUPP; 1717 goto unlock; 1718 } 1719 1720 if (idpf_is_cap_ena(vport->adapter, IDPF_OTHER_CAPS, VIRTCHNL2_CAP_PTP) && 1721 vport->adapter->ptp->clock) { 1722 info->phc_index = ptp_clock_index(vport->adapter->ptp->clock); 1723 idpf_get_timestamp_filters(vport, info); 1724 } else { 1725 pci_dbg(vport->adapter->pdev, "PTP clock not detected\n"); 1726 err = ethtool_op_get_ts_info(netdev, info); 1727 } 1728 1729unlock: 1730 mutex_unlock(&np->adapter->vport_ctrl_lock); 1731 1732 return err; 1733} 1734 1735/** 1736 * idpf_get_ts_stats - Collect HW tstamping statistics 1737 * @netdev: network interface device structure 1738 * @ts_stats: HW timestamping stats structure 1739 * 1740 * Collect HW timestamping statistics including successfully timestamped 1741 * packets, discarded due to illegal values, flushed during releasing PTP and 1742 * skipped due to lack of the free index. 1743 */ 1744static void idpf_get_ts_stats(struct net_device *netdev, 1745 struct ethtool_ts_stats *ts_stats) 1746{ 1747 struct idpf_netdev_priv *np = netdev_priv(netdev); 1748 struct idpf_vport *vport; 1749 unsigned int start; 1750 1751 idpf_vport_ctrl_lock(netdev); 1752 vport = idpf_netdev_to_vport(netdev); 1753 do { 1754 start = u64_stats_fetch_begin(&vport->tstamp_stats.stats_sync); 1755 ts_stats->pkts = u64_stats_read(&vport->tstamp_stats.packets); 1756 ts_stats->lost = u64_stats_read(&vport->tstamp_stats.flushed); 1757 ts_stats->err = u64_stats_read(&vport->tstamp_stats.discarded); 1758 } while (u64_stats_fetch_retry(&vport->tstamp_stats.stats_sync, start)); 1759 1760 if (!test_bit(IDPF_VPORT_UP, np->state)) 1761 goto exit; 1762 1763 for (u16 i = 0; i < vport->num_txq_grp; i++) { 1764 struct idpf_txq_group *txq_grp = &vport->txq_grps[i]; 1765 1766 for (u16 j = 0; j < txq_grp->num_txq; j++) { 1767 struct idpf_tx_queue *txq = txq_grp->txqs[j]; 1768 struct idpf_tx_queue_stats *stats; 1769 u64 ts; 1770 1771 if (!txq) 1772 continue; 1773 1774 stats = &txq->q_stats; 1775 do { 1776 start = u64_stats_fetch_begin(&txq->stats_sync); 1777 1778 ts = u64_stats_read(&stats->tstamp_skipped); 1779 } while (u64_stats_fetch_retry(&txq->stats_sync, 1780 start)); 1781 1782 ts_stats->lost += ts; 1783 } 1784 } 1785 1786exit: 1787 idpf_vport_ctrl_unlock(netdev); 1788} 1789 1790static const struct ethtool_ops idpf_ethtool_ops = { 1791 .supported_coalesce_params = ETHTOOL_COALESCE_USECS | 1792 ETHTOOL_COALESCE_USE_ADAPTIVE, 1793 .supported_ring_params = ETHTOOL_RING_USE_TCP_DATA_SPLIT, 1794 .get_msglevel = idpf_get_msglevel, 1795 .set_msglevel = idpf_set_msglevel, 1796 .get_link = ethtool_op_get_link, 1797 .get_coalesce = idpf_get_coalesce, 1798 .set_coalesce = idpf_set_coalesce, 1799 .get_per_queue_coalesce = idpf_get_per_q_coalesce, 1800 .set_per_queue_coalesce = idpf_set_per_q_coalesce, 1801 .get_ethtool_stats = idpf_get_ethtool_stats, 1802 .get_strings = idpf_get_strings, 1803 .get_sset_count = idpf_get_sset_count, 1804 .get_channels = idpf_get_channels, 1805 .get_rxnfc = idpf_get_rxnfc, 1806 .set_rxnfc = idpf_set_rxnfc, 1807 .get_rx_ring_count = idpf_get_rx_ring_count, 1808 .get_rxfh_key_size = idpf_get_rxfh_key_size, 1809 .get_rxfh_indir_size = idpf_get_rxfh_indir_size, 1810 .get_rxfh = idpf_get_rxfh, 1811 .set_rxfh = idpf_set_rxfh, 1812 .set_channels = idpf_set_channels, 1813 .get_ringparam = idpf_get_ringparam, 1814 .set_ringparam = idpf_set_ringparam, 1815 .get_link_ksettings = idpf_get_link_ksettings, 1816 .get_ts_info = idpf_get_ts_info, 1817 .get_ts_stats = idpf_get_ts_stats, 1818}; 1819 1820/** 1821 * idpf_set_ethtool_ops - Initialize ethtool ops struct 1822 * @netdev: network interface device structure 1823 * 1824 * Sets ethtool ops struct in our netdev so that ethtool can call 1825 * our functions. 1826 */ 1827void idpf_set_ethtool_ops(struct net_device *netdev) 1828{ 1829 netdev->ethtool_ops = &idpf_ethtool_ops; 1830}
~/
Read-only file preview.