aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/igb
diff options
context:
space:
mode:
authorLior Levy <lior.levy@intel.com>2011-02-07 21:28:46 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-02-24 05:39:03 -0500
commit17dc566c5ee46e14021e6b8dd89098d3cb237208 (patch)
tree5d61a0b9fd3c2688aa0494126a6fd7d5dac95457 /drivers/net/igb
parent6799746ad63b3df7ddf47797bb06467db35c6f94 (diff)
igb: add support for VF Transmit rate limit using iproute2
Implemented igb_ndo_set_vf_bw function which is being used by iproute2 tool. In addition, updated igb_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. The rate limit value can be ranged between 0 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 only by 82576 device. Signed-off-by: Lior Levy <lior.levy@intel.com> Tested-by: Jeff Pieper <jeffrey.e.pieper@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Diffstat (limited to 'drivers/net/igb')
-rw-r--r--drivers/net/igb/e1000_defines.h7
-rw-r--r--drivers/net/igb/e1000_regs.h4
-rw-r--r--drivers/net/igb/igb.h2
-rw-r--r--drivers/net/igb/igb_main.c88
4 files changed, 99 insertions, 2 deletions
diff --git a/drivers/net/igb/e1000_defines.h b/drivers/net/igb/e1000_defines.h
index 6319ed902bc..ff46c91520a 100644
--- a/drivers/net/igb/e1000_defines.h
+++ b/drivers/net/igb/e1000_defines.h
@@ -770,4 +770,11 @@
770#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based 770#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based
771 on DMA coal */ 771 on DMA coal */
772 772
773/* Tx Rate-Scheduler Config fields */
774#define E1000_RTTBCNRC_RS_ENA 0x80000000
775#define E1000_RTTBCNRC_RF_DEC_MASK 0x00003FFF
776#define E1000_RTTBCNRC_RF_INT_SHIFT 14
777#define E1000_RTTBCNRC_RF_INT_MASK \
778 (E1000_RTTBCNRC_RF_DEC_MASK << E1000_RTTBCNRC_RF_INT_SHIFT)
779
773#endif 780#endif
diff --git a/drivers/net/igb/e1000_regs.h b/drivers/net/igb/e1000_regs.h
index 8ac83c5190d..3a6f8471aea 100644
--- a/drivers/net/igb/e1000_regs.h
+++ b/drivers/net/igb/e1000_regs.h
@@ -106,6 +106,10 @@
106 106
107#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40)) 107#define E1000_RQDPC(_n) (0x0C030 + ((_n) * 0x40))
108 108
109/* TX Rate Limit Registers */
110#define E1000_RTTDQSEL 0x3604 /* Tx Desc Plane Queue Select - WO */
111#define E1000_RTTBCNRC 0x36B0 /* Tx BCN Rate-Scheduler Config - WO */
112
109/* Split and Replication RX Control - RW */ 113/* Split and Replication RX Control - RW */
110#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */ 114#define E1000_RXPBS 0x02404 /* Rx Packet Buffer Size - RW */
111/* 115/*
diff --git a/drivers/net/igb/igb.h b/drivers/net/igb/igb.h
index 92a4ef09e55..bbc5ebfe254 100644
--- a/drivers/net/igb/igb.h
+++ b/drivers/net/igb/igb.h
@@ -77,6 +77,7 @@ struct vf_data_storage {
77 unsigned long last_nack; 77 unsigned long last_nack;
78 u16 pf_vlan; /* When set, guest VLAN config not allowed. */ 78 u16 pf_vlan; /* When set, guest VLAN config not allowed. */
79 u16 pf_qos; 79 u16 pf_qos;
80 u16 tx_rate;
80}; 81};
81 82
82#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */ 83#define IGB_VF_FLAG_CTS 0x00000001 /* VF is clear to send data */
@@ -323,6 +324,7 @@ struct igb_adapter {
323 u16 rx_ring_count; 324 u16 rx_ring_count;
324 unsigned int vfs_allocated_count; 325 unsigned int vfs_allocated_count;
325 struct vf_data_storage *vf_data; 326 struct vf_data_storage *vf_data;
327 int vf_rate_link_speed;
326 u32 rss_queues; 328 u32 rss_queues;
327 u32 wvbr; 329 u32 wvbr;
328}; 330};
diff --git a/drivers/net/igb/igb_main.c b/drivers/net/igb/igb_main.c
index cb6bf7b815a..88f8925b2d8 100644
--- a/drivers/net/igb/igb_main.c
+++ b/drivers/net/igb/igb_main.c
@@ -150,6 +150,7 @@ static int igb_ndo_set_vf_vlan(struct net_device *netdev,
150static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); 150static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
151static int igb_ndo_get_vf_config(struct net_device *netdev, int vf, 151static int igb_ndo_get_vf_config(struct net_device *netdev, int vf,
152 struct ifla_vf_info *ivi); 152 struct ifla_vf_info *ivi);
153static void igb_check_vf_rate_limit(struct igb_adapter *);
153 154
154#ifdef CONFIG_PM 155#ifdef CONFIG_PM
155static int igb_suspend(struct pci_dev *, pm_message_t); 156static int igb_suspend(struct pci_dev *, pm_message_t);
@@ -3511,6 +3512,7 @@ static void igb_watchdog_task(struct work_struct *work)
3511 netif_carrier_on(netdev); 3512 netif_carrier_on(netdev);
3512 3513
3513 igb_ping_all_vfs(adapter); 3514 igb_ping_all_vfs(adapter);
3515 igb_check_vf_rate_limit(adapter);
3514 3516
3515 /* link state has changed, schedule phy info update */ 3517 /* link state has changed, schedule phy info update */
3516 if (!test_bit(__IGB_DOWN, &adapter->state)) 3518 if (!test_bit(__IGB_DOWN, &adapter->state))
@@ -6599,9 +6601,91 @@ static int igb_ndo_set_vf_mac(struct net_device *netdev, int vf, u8 *mac)
6599 return igb_set_vf_mac(adapter, vf, mac); 6601 return igb_set_vf_mac(adapter, vf, mac);
6600} 6602}
6601 6603
6604static int igb_link_mbps(int internal_link_speed)
6605{
6606 switch (internal_link_speed) {
6607 case SPEED_100:
6608 return 100;
6609 case SPEED_1000:
6610 return 1000;
6611 default:
6612 return 0;
6613 }
6614}
6615
6616static void igb_set_vf_rate_limit(struct e1000_hw *hw, int vf, int tx_rate,
6617 int link_speed)
6618{
6619 int rf_dec, rf_int;
6620 u32 bcnrc_val;
6621
6622 if (tx_rate != 0) {
6623 /* Calculate the rate factor values to set */
6624 rf_int = link_speed / tx_rate;
6625 rf_dec = (link_speed - (rf_int * tx_rate));
6626 rf_dec = (rf_dec * (1<<E1000_RTTBCNRC_RF_INT_SHIFT)) / tx_rate;
6627
6628 bcnrc_val = E1000_RTTBCNRC_RS_ENA;
6629 bcnrc_val |= ((rf_int<<E1000_RTTBCNRC_RF_INT_SHIFT) &
6630 E1000_RTTBCNRC_RF_INT_MASK);
6631 bcnrc_val |= (rf_dec & E1000_RTTBCNRC_RF_DEC_MASK);
6632 } else {
6633 bcnrc_val = 0;
6634 }
6635
6636 wr32(E1000_RTTDQSEL, vf); /* vf X uses queue X */
6637 wr32(E1000_RTTBCNRC, bcnrc_val);
6638}
6639
6640static void igb_check_vf_rate_limit(struct igb_adapter *adapter)
6641{
6642 int actual_link_speed, i;
6643 bool reset_rate = false;
6644
6645 /* VF TX rate limit was not set or not supported */
6646 if ((adapter->vf_rate_link_speed == 0) ||
6647 (adapter->hw.mac.type != e1000_82576))
6648 return;
6649
6650 actual_link_speed = igb_link_mbps(adapter->link_speed);
6651 if (actual_link_speed != adapter->vf_rate_link_speed) {
6652 reset_rate = true;
6653 adapter->vf_rate_link_speed = 0;
6654 dev_info(&adapter->pdev->dev,
6655 "Link speed has been changed. VF Transmit "
6656 "rate is disabled\n");
6657 }
6658
6659 for (i = 0; i < adapter->vfs_allocated_count; i++) {
6660 if (reset_rate)
6661 adapter->vf_data[i].tx_rate = 0;
6662
6663 igb_set_vf_rate_limit(&adapter->hw, i,
6664 adapter->vf_data[i].tx_rate,
6665 actual_link_speed);
6666 }
6667}
6668
6602static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) 6669static int igb_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate)
6603{ 6670{
6604 return -EOPNOTSUPP; 6671 struct igb_adapter *adapter = netdev_priv(netdev);
6672 struct e1000_hw *hw = &adapter->hw;
6673 int actual_link_speed;
6674
6675 if (hw->mac.type != e1000_82576)
6676 return -EOPNOTSUPP;
6677
6678 actual_link_speed = igb_link_mbps(adapter->link_speed);
6679 if ((vf >= adapter->vfs_allocated_count) ||
6680 (!(rd32(E1000_STATUS) & E1000_STATUS_LU)) ||
6681 (tx_rate < 0) || (tx_rate > actual_link_speed))
6682 return -EINVAL;
6683
6684 adapter->vf_rate_link_speed = actual_link_speed;
6685 adapter->vf_data[vf].tx_rate = (u16)tx_rate;
6686 igb_set_vf_rate_limit(hw, vf, tx_rate, actual_link_speed);
6687
6688 return 0;
6605} 6689}
6606 6690
6607static int igb_ndo_get_vf_config(struct net_device *netdev, 6691static int igb_ndo_get_vf_config(struct net_device *netdev,
@@ -6612,7 +6696,7 @@ static int igb_ndo_get_vf_config(struct net_device *netdev,
6612 return -EINVAL; 6696 return -EINVAL;
6613 ivi->vf = vf; 6697 ivi->vf = vf;
6614 memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN); 6698 memcpy(&ivi->mac, adapter->vf_data[vf].vf_mac_addresses, ETH_ALEN);
6615 ivi->tx_rate = 0; 6699 ivi->tx_rate = adapter->vf_data[vf].tx_rate;
6616 ivi->vlan = adapter->vf_data[vf].pf_vlan; 6700 ivi->vlan = adapter->vf_data[vf].pf_vlan;
6617 ivi->qos = adapter->vf_data[vf].pf_qos; 6701 ivi->qos = adapter->vf_data[vf].pf_qos;
6618 return 0; 6702 return 0;