aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLior Levy <lior.levy@intel.com>2011-03-10 21:03:07 -0500
committerJeff Kirsher <jeffrey.t.kirsher@intel.com>2011-03-12 07:15:08 -0500
commitff4ab2061199cdb938282d302d5044b1858e28c8 (patch)
treed0aaa0de221ca032c706e06379f89d0514571433
parent1390a59452a0895d3fea5b5504fa75ba36c13a74 (diff)
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>
-rw-r--r--drivers/net/ixgbe/ixgbe.h2
-rw-r--r--drivers/net/ixgbe/ixgbe_main.c1
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.c85
-rw-r--r--drivers/net/ixgbe/ixgbe_sriov.h1
-rw-r--r--drivers/net/ixgbe/ixgbe_type.h6
5 files changed, 93 insertions, 2 deletions
diff --git a/drivers/net/ixgbe/ixgbe.h b/drivers/net/ixgbe/ixgbe.h
index b7e62d568b85..8d468028bb55 100644
--- a/drivers/net/ixgbe/ixgbe.h
+++ b/drivers/net/ixgbe/ixgbe.h
@@ -118,6 +118,7 @@ struct vf_data_storage {
118 bool pf_set_mac; 118 bool pf_set_mac;
119 u16 pf_vlan; /* When set, guest VLAN config not allowed. */ 119 u16 pf_vlan; /* When set, guest VLAN config not allowed. */
120 u16 pf_qos; 120 u16 pf_qos;
121 u16 tx_rate;
121}; 122};
122 123
123/* wrapper around a pointer to a socket buffer, 124/* wrapper around a pointer to a socket buffer,
@@ -468,6 +469,7 @@ struct ixgbe_adapter {
468 DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS); 469 DECLARE_BITMAP(active_vfs, IXGBE_MAX_VF_FUNCTIONS);
469 unsigned int num_vfs; 470 unsigned int num_vfs;
470 struct vf_data_storage *vfinfo; 471 struct vf_data_storage *vfinfo;
472 int vf_rate_link_speed;
471}; 473};
472 474
473enum ixbge_state_t { 475enum ixbge_state_t {
diff --git a/drivers/net/ixgbe/ixgbe_main.c b/drivers/net/ixgbe/ixgbe_main.c
index 38f9758c4c44..f17e4a7ee731 100644
--- a/drivers/net/ixgbe/ixgbe_main.c
+++ b/drivers/net/ixgbe/ixgbe_main.c
@@ -6217,6 +6217,7 @@ static void ixgbe_watchdog_task(struct work_struct *work)
6217 (flow_tx ? "TX" : "None")))); 6217 (flow_tx ? "TX" : "None"))));
6218 6218
6219 netif_carrier_on(netdev); 6219 netif_carrier_on(netdev);
6220 ixgbe_check_vf_rate_limit(adapter);
6220 } else { 6221 } else {
6221 /* Force detection of hung controller */ 6222 /* Force detection of hung controller */
6222 for (i = 0; i < adapter->num_tx_queues; i++) { 6223 for (i = 0; i < adapter->num_tx_queues; i++) {
diff --git a/drivers/net/ixgbe/ixgbe_sriov.c b/drivers/net/ixgbe/ixgbe_sriov.c
index 58c9b45989ff..6e50d8328942 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ixgbe/ixgbe_sriov.c
@@ -478,9 +478,90 @@ out:
478 return err; 478 return err;
479} 479}
480 480
481static 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
495static 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
519void 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
481int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) 547int 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
486int ixgbe_ndo_get_vf_config(struct net_device *netdev, 567int ixgbe_ndo_get_vf_config(struct net_device *netdev,
@@ -491,7 +572,7 @@ int ixgbe_ndo_get_vf_config(struct net_device *netdev,
491 return -EINVAL; 572 return -EINVAL;
492 ivi->vf = vf; 573 ivi->vf = vf;
493 memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN); 574 memcpy(&ivi->mac, adapter->vfinfo[vf].vf_mac_addresses, ETH_ALEN);
494 ivi->tx_rate = 0; 575 ivi->tx_rate = adapter->vfinfo[vf].tx_rate;
495 ivi->vlan = adapter->vfinfo[vf].pf_vlan; 576 ivi->vlan = adapter->vfinfo[vf].pf_vlan;
496 ivi->qos = adapter->vfinfo[vf].pf_qos; 577 ivi->qos = adapter->vfinfo[vf].pf_qos;
497 return 0; 578 return 0;
diff --git a/drivers/net/ixgbe/ixgbe_sriov.h b/drivers/net/ixgbe/ixgbe_sriov.h
index e7dd029d576a..34175564bb78 100644
--- a/drivers/net/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ixgbe/ixgbe_sriov.h
@@ -40,6 +40,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
40int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); 40int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate);
41int ixgbe_ndo_get_vf_config(struct net_device *netdev, 41int ixgbe_ndo_get_vf_config(struct net_device *netdev,
42 int vf, struct ifla_vf_info *ivi); 42 int vf, struct ifla_vf_info *ivi);
43void ixgbe_check_vf_rate_limit(struct ixgbe_adapter *adapter);
43 44
44#endif /* _IXGBE_SRIOV_H_ */ 45#endif /* _IXGBE_SRIOV_H_ */
45 46
diff --git a/drivers/net/ixgbe/ixgbe_type.h b/drivers/net/ixgbe/ixgbe_type.h
index 63d862d3fd90..25c1fb7eda06 100644
--- a/drivers/net/ixgbe/ixgbe_type.h
+++ b/drivers/net/ixgbe/ixgbe_type.h
@@ -533,6 +533,12 @@
533#define IXGBE_RTTDTECC 0x04990 533#define IXGBE_RTTDTECC 0x04990
534#define IXGBE_RTTDTECC_NO_BCN 0x00000100 534#define IXGBE_RTTDTECC_NO_BCN 0x00000100
535#define IXGBE_RTTBCNRC 0x04984 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/* FCoE registers */ 543/* FCoE registers */
538#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */ 544#define IXGBE_FCPTRL 0x02410 /* FC User Desc. PTR Low */