Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ixgbe: add support for VF Transmit rate limit using iproute2

Implemented ixgbe_ndo_set_vf_bw function which is being used by iproute2
tool. In addition, updated ixgbe_ndo_get_vf_config function to show the
actual rate limit to the user.

The rate limitation can be configured only when the link is up and the
link speed is 10Gb.
The rate limit value can be 0 or ranged between 11 and actual link
speed measured in Mbps. A value of '0' disables the rate limit for
this specific VF.

iproute2 usage will be 'ip link set ethX vf Y rate Z'.
After the command is made, the rate will be changed instantly.
To view the current rate limit, use 'ip link show ethX'.

The rates will be zeroed only upon driver reload or a link speed change.

This feature is being supported by 82599 and X540 devices.

Signed-off-by: Lior Levy <lior.levy@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

authored by

Lior Levy and committed by
Jeff Kirsher
ff4ab206 1390a594

+93 -2
+2
drivers/net/ixgbe/ixgbe.h
··· 118 118 bool pf_set_mac; 119 119 u16 pf_vlan; /* When set, guest VLAN config not allowed. */ 120 120 u16 pf_qos; 121 + u16 tx_rate; 121 122 }; 122 123 123 124 /* wrapper around a pointer to a socket buffer, ··· 469 468 DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); 470 469 unsigned int num_vfs; 471 470 struct vf_data_storage *vfinfo; 471 + int vf_rate_link_speed; 472 472 }; 473 473 474 474 enum ixbge_state_t {
+1
drivers/net/ixgbe/ixgbe_main.c
··· 6217 6217 (flow_tx ? "TX" : "None")))); 6218 6218 6219 6219 netif_carrier_on(netdev); 6220 + ixgbe_check_vf_rate_limit(adapter); 6220 6221 } else { 6221 6222 /* Force detection of hung controller */ 6222 6223 for (i = 0; i < adapter->num_tx_queues; i++) {
+83 -2
drivers/net/ixgbe/ixgbe_sriov.c
··· 478 478 return err; 479 479 } 480 480 481 + static int ixgbe_link_mbps(int internal_link_speed) 482 + { 483 + switch (internal_link_speed) { 484 + case IXGBE_LINK_SPEED_100_FULL: 485 + return 100; 486 + case IXGBE_LINK_SPEED_1GB_FULL: 487 + return 1000; 488 + case IXGBE_LINK_SPEED_10GB_FULL: 489 + return 10000; 490 + default: 491 + return 0; 492 + } 493 + } 494 + 495 + static void ixgbe_set_vf_rate_limit(struct ixgbe_hw *hw, int vf, int tx_rate, 496 + int link_speed) 497 + { 498 + int rf_dec, rf_int; 499 + u32 bcnrc_val; 500 + 501 + if (tx_rate != 0) { 502 + /* Calculate the rate factor values to set */ 503 + rf_int = link_speed / tx_rate; 504 + rf_dec = (link_speed - (rf_int * tx_rate)); 505 + rf_dec = (rf_dec * (1<<IXGBE_RTTBCNRC_RF_INT_SHIFT)) / tx_rate; 506 + 507 + bcnrc_val = IXGBE_RTTBCNRC_RS_ENA; 508 + bcnrc_val |= ((rf_int<<IXGBE_RTTBCNRC_RF_INT_SHIFT) & 509 + IXGBE_RTTBCNRC_RF_INT_MASK); 510 + bcnrc_val |= (rf_dec & IXGBE_RTTBCNRC_RF_DEC_MASK); 511 + } else { 512 + bcnrc_val = 0; 513 + } 514 + 515 + IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, 2*vf); /* vf Y uses queue 2*Y */ 516 + IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val); 517 + } 518 + 519 + void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter) 520 + { 521 + int actual_link_speed, i; 522 + bool reset_rate = false; 523 + 524 + /* VF Tx rate limit was not set */ 525 + if (adapter->vf_rate_link_speed == 0) 526 + return; 527 + 528 + actual_link_speed = ixgbe_link_mbps(adapter->link_speed); 529 + if (actual_link_speed != adapter->vf_rate_link_speed) { 530 + reset_rate = true; 531 + adapter->vf_rate_link_speed = 0; 532 + dev_info(&adapter->pdev->dev, 533 + "Link speed has been changed. VF Transmit rate " 534 + "is disabled\n"); 535 + } 536 + 537 + for (i = 0; i < adapter->num_vfs; i++) { 538 + if (reset_rate) 539 + adapter->vfinfo[i].tx_rate = 0; 540 + 541 + ixgbe_set_vf_rate_limit(&adapter->hw, i, 542 + adapter->vfinfo[i].tx_rate, 543 + actual_link_speed); 544 + } 545 + } 546 + 481 547 int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) 482 548 { 483 - return -EOPNOTSUPP; 549 + struct ixgbe_adapter *adapter = netdev_priv(netdev); 550 + struct ixgbe_hw *hw = &adapter->hw; 551 + int actual_link_speed; 552 + 553 + actual_link_speed = ixgbe_link_mbps(adapter->link_speed); 554 + if ((vf >= adapter->num_vfs) || (!adapter->link_up) || 555 + (tx_rate > actual_link_speed) || (actual_link_speed != 10000) || 556 + ((tx_rate != 0) && (tx_rate <= 10))) 557 + /* rate limit cannot be set to 10Mb or less in 10Gb adapters */ 558 + return -EINVAL; 559 + 560 + adapter->vf_rate_link_speed = actual_link_speed; 561 + adapter->vfinfo[vf].tx_rate = (u16)tx_rate; 562 + ixgbe_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed); 563 + 564 + return 0; 484 565 } 485 566 486 567 int ixgbe_ndo_get_vf_config(struct net_device *netdev, ··· 572 491 return -EINVAL; 573 492 ivi->vf = vf; 574 493 memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); 575 - ivi->tx_rate = 0; 494 + ivi->tx_rate = adapter->vfinfo[vf].tx_rate; 576 495 ivi->vlan = adapter->vfinfo[vf].pf_vlan; 577 496 ivi->qos = adapter->vfinfo[vf].pf_qos; 578 497 return 0;
+1
drivers/net/ixgbe/ixgbe_sriov.h
··· 40 40 int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); 41 41 int ixgbe_ndo_get_vf_config(struct net_device *netdev, 42 42 int vf, struct ifla_vf_info *ivi); 43 + void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter); 43 44 44 45 #endif /* _IXGBE_SRIOV_H_ */ 45 46
+6
drivers/net/ixgbe/ixgbe_type.h
··· 533 533 #define IXGBE_RTTDTECC 0x04990 534 534 #define IXGBE_RTTDTECC_NO_BCN 0x00000100 535 535 #define IXGBE_RTTBCNRC 0x04984 536 + #define IXGBE_RTTBCNRC_RS_ENA 0x80000000 537 + #define IXGBE_RTTBCNRC_RF_DEC_MASK 0x00003FFF 538 + #define IXGBE_RTTBCNRC_RF_INT_SHIFT 14 539 + #define IXGBE_RTTBCNRC_RF_INT_MASK \ 540 + (IXGBE_RTTBCNRC_RF_DEC_MASK << IXGBE_RTTBCNRC_RF_INT_SHIFT) 541 + 536 542 537 543 /* FCoE registers */ 538 544 #define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */