diff options
-rw-r--r-- | drivers/net/ixgbe/ixgbe.h | 2 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_main.c | 1 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_sriov.c | 85 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_sriov.h | 1 | ||||
-rw-r--r-- | drivers/net/ixgbe/ixgbe_type.h | 6 |
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 | ||
473 | enum ixbge_state_t { | 475 | enum 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 | ||
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 | int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate) | 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 | int ixgbe_ndo_get_vf_config(struct net_device *netdev, | 567 | int 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, | |||
40 | int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); | 40 | int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int tx_rate); |
41 | int ixgbe_ndo_get_vf_config(struct net_device *netdev, | 41 | int 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); |
43 | void 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 */ |