]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
ixgbe: add a callback to set the maximum transmit bitrate
authorRostislav Pehlivanov <atomnuker@gmail.com>
Wed, 27 Jan 2016 18:33:30 +0000 (18:33 +0000)
committerChuck Anderson <chuck.anderson@oracle.com>
Wed, 6 Jul 2016 23:41:07 +0000 (16:41 -0700)
Orabug: 23177316

This commit adds a callback which allows to adjust the maximum transmit
bitrate the card can output. This makes it possible to get a smooth
traffic instead of the default burst-y behaviour when trying to output
e.g. a video stream.

Much of the logic needed to get a correct bcnrc_val was taken from the
ixgbe_set_vf_rate_limit() function.

Signed-off-by: Rostislav Pehlivanov <atomnuker@gmail.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
(cherry picked from commit c04f90e592431489df114971ff025265d429e48f)
Signed-off-by: Brian Maly <brian.maly@oracle.com>
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h

index ad9f938e03813106cd3264f92ebcaebafc82fc97..8948031e54ecc5475db37e1790888f975b1412e3 100644 (file)
@@ -1084,6 +1084,36 @@ static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
        }
 }
 
+/**
+ * ixgbe_tx_maxrate - callback to set the maximum per-queue bitrate
+ **/
+static int ixgbe_tx_maxrate(struct net_device *netdev,
+                           int queue_index, u32 maxrate)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       struct ixgbe_hw *hw = &adapter->hw;
+       u32 bcnrc_val = ixgbe_link_mbps(adapter);
+
+       if (!maxrate)
+               return 0;
+
+       /* Calculate the rate factor values to set */
+       bcnrc_val <<= IXGBE_RTTBCNRC_RF_INT_SHIFT;
+       bcnrc_val /= maxrate;
+
+       /* clear everything but the rate factor */
+       bcnrc_val &= IXGBE_RTTBCNRC_RF_INT_MASK |
+       IXGBE_RTTBCNRC_RF_DEC_MASK;
+
+       /* enable the rate scheduler */
+       bcnrc_val |= IXGBE_RTTBCNRC_RS_ENA;
+
+       IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, queue_index);
+       IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val);
+
+       return 0;
+}
+
 /**
  * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
  * @q_vector: structure containing interrupt and ring information
@@ -8617,6 +8647,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
        .ndo_set_mac_address    = ixgbe_set_mac,
        .ndo_change_mtu         = ixgbe_change_mtu,
        .ndo_tx_timeout         = ixgbe_tx_timeout,
+       .ndo_set_tx_maxrate     = ixgbe_tx_maxrate,
        .ndo_vlan_rx_add_vid    = ixgbe_vlan_rx_add_vid,
        .ndo_vlan_rx_kill_vid   = ixgbe_vlan_rx_kill_vid,
        .ndo_do_ioctl           = ixgbe_ioctl,
index 957c4c56ea62c76a745f6adc0f698d6648f3164f..82561dd60634d01e0f5789fbdb69af82ebb67748 100644 (file)
@@ -1384,7 +1384,7 @@ out:
        return err;
 }
 
-static int ixgbe_link_mbps(struct ixgbe_adapter *adapter)
+int ixgbe_link_mbps(struct ixgbe_adapter *adapter)
 {
        switch (adapter->link_speed) {
        case IXGBE_LINK_SPEED_100_FULL:
index 2c197e6d1fe7c3cb66c1be785bba2a8084e806fa..3125a7eb091976f73e972f8d2fab36648fa80df4 100644 (file)
@@ -44,6 +44,7 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
 int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
 int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
                           u8 qos);
+int ixgbe_link_mbps(struct ixgbe_adapter *adapter);
 int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
                        int max_tx_rate);
 int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);