These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / net / ethernet / intel / ixgbe / ixgbe_ethtool.c
index eafa9ec..d681273 100644 (file)
@@ -166,6 +166,8 @@ static int ixgbe_get_settings(struct net_device *netdev,
        /* set the supported link speeds */
        if (supported_link & IXGBE_LINK_SPEED_10GB_FULL)
                ecmd->supported |= SUPPORTED_10000baseT_Full;
+       if (supported_link & IXGBE_LINK_SPEED_2_5GB_FULL)
+               ecmd->supported |= SUPPORTED_2500baseX_Full;
        if (supported_link & IXGBE_LINK_SPEED_1GB_FULL)
                ecmd->supported |= SUPPORTED_1000baseT_Full;
        if (supported_link & IXGBE_LINK_SPEED_100_FULL)
@@ -177,6 +179,8 @@ static int ixgbe_get_settings(struct net_device *netdev,
                        ecmd->advertising |= ADVERTISED_100baseT_Full;
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
                        ecmd->advertising |= ADVERTISED_10000baseT_Full;
+               if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_2_5GB_FULL)
+                       ecmd->advertising |= ADVERTISED_2500baseX_Full;
                if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
                        ecmd->advertising |= ADVERTISED_1000baseT_Full;
        } else {
@@ -207,6 +211,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
        switch (adapter->hw.phy.type) {
        case ixgbe_phy_tn:
        case ixgbe_phy_aq:
+       case ixgbe_phy_x550em_ext_t:
        case ixgbe_phy_cu_unknown:
                ecmd->supported |= SUPPORTED_TP;
                ecmd->advertising |= ADVERTISED_TP;
@@ -285,6 +290,9 @@ static int ixgbe_get_settings(struct net_device *netdev,
                case IXGBE_LINK_SPEED_10GB_FULL:
                        ethtool_cmd_speed_set(ecmd, SPEED_10000);
                        break;
+               case IXGBE_LINK_SPEED_2_5GB_FULL:
+                       ethtool_cmd_speed_set(ecmd, SPEED_2500);
+                       break;
                case IXGBE_LINK_SPEED_1GB_FULL:
                        ethtool_cmd_speed_set(ecmd, SPEED_1000);
                        break;
@@ -470,16 +478,16 @@ static void ixgbe_get_regs(struct net_device *netdev,
        regs_buff[7] = IXGBE_READ_REG(hw, IXGBE_TCPTIMER);
 
        /* NVM Register */
-       regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_EEC);
+       regs_buff[8] = IXGBE_READ_REG(hw, IXGBE_EEC(hw));
        regs_buff[9] = IXGBE_READ_REG(hw, IXGBE_EERD);
-       regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_FLA);
+       regs_buff[10] = IXGBE_READ_REG(hw, IXGBE_FLA(hw));
        regs_buff[11] = IXGBE_READ_REG(hw, IXGBE_EEMNGCTL);
        regs_buff[12] = IXGBE_READ_REG(hw, IXGBE_EEMNGDATA);
        regs_buff[13] = IXGBE_READ_REG(hw, IXGBE_FLMNGCTL);
        regs_buff[14] = IXGBE_READ_REG(hw, IXGBE_FLMNGDATA);
        regs_buff[15] = IXGBE_READ_REG(hw, IXGBE_FLMNGCNT);
        regs_buff[16] = IXGBE_READ_REG(hw, IXGBE_FLOP);
-       regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC);
+       regs_buff[17] = IXGBE_READ_REG(hw, IXGBE_GRC(hw));
 
        /* Interrupt */
        /* don't read EICR because it can clear interrupt causes, instead
@@ -935,9 +943,6 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
 
        strlcpy(drvinfo->bus_info, pci_name(adapter->pdev),
                sizeof(drvinfo->bus_info));
-       drvinfo->n_stats = IXGBE_STATS_LEN;
-       drvinfo->testinfo_len = IXGBE_TEST_LEN;
-       drvinfo->regdump_len = ixgbe_get_regs_len(netdev);
 }
 
 static void ixgbe_get_ringparam(struct net_device *netdev,
@@ -2278,7 +2283,7 @@ static int ixgbe_set_coalesce(struct net_device *netdev,
                adapter->tx_itr_setting = ec->tx_coalesce_usecs;
 
        if (adapter->tx_itr_setting == 1)
-               tx_itr_param = IXGBE_10K_ITR;
+               tx_itr_param = IXGBE_12K_ITR;
        else
                tx_itr_param = adapter->tx_itr_setting;
 
@@ -2594,18 +2599,35 @@ static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
        struct ixgbe_hw *hw = &adapter->hw;
        struct ixgbe_fdir_filter *input;
        union ixgbe_atr_input mask;
+       u8 queue;
        int err;
 
        if (!(adapter->flags & IXGBE_FLAG_FDIR_PERFECT_CAPABLE))
                return -EOPNOTSUPP;
 
-       /*
-        * Don't allow programming if the action is a queue greater than
-        * the number of online Rx queues.
+       /* ring_cookie is a masked into a set of queues and ixgbe pools or
+        * we use the drop index.
         */
-       if ((fsp->ring_cookie != RX_CLS_FLOW_DISC) &&
-           (fsp->ring_cookie >= adapter->num_rx_queues))
-               return -EINVAL;
+       if (fsp->ring_cookie == RX_CLS_FLOW_DISC) {
+               queue = IXGBE_FDIR_DROP_QUEUE;
+       } else {
+               u32 ring = ethtool_get_flow_spec_ring(fsp->ring_cookie);
+               u8 vf = ethtool_get_flow_spec_ring_vf(fsp->ring_cookie);
+
+               if (!vf && (ring >= adapter->num_rx_queues))
+                       return -EINVAL;
+               else if (vf &&
+                        ((vf > adapter->num_vfs) ||
+                          ring >= adapter->num_rx_queues_per_pool))
+                       return -EINVAL;
+
+               /* Map the ring onto the absolute queue index */
+               if (!vf)
+                       queue = adapter->rx_ring[ring]->reg_idx;
+               else
+                       queue = ((vf - 1) *
+                               adapter->num_rx_queues_per_pool) + ring;
+       }
 
        /* Don't allow indexes to exist outside of available space */
        if (fsp->location >= ((1024 << adapter->fdir_pballoc) - 2)) {
@@ -2683,10 +2705,7 @@ static int ixgbe_add_ethtool_fdir_entry(struct ixgbe_adapter *adapter,
 
        /* program filters to filter memory */
        err = ixgbe_fdir_write_perfect_filter_82599(hw,
-                               &input->filter, input->sw_idx,
-                               (input->action == IXGBE_FDIR_DROP_QUEUE) ?
-                               IXGBE_FDIR_DROP_QUEUE :
-                               adapter->rx_ring[input->action]->reg_idx);
+                               &input->filter, input->sw_idx, queue);
        if (err)
                goto err_out_w_lock;
 
@@ -2853,6 +2872,14 @@ static int ixgbe_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
        return ret;
 }
 
+static int ixgbe_rss_indir_tbl_max(struct ixgbe_adapter *adapter)
+{
+       if (adapter->hw.mac.type < ixgbe_mac_X550)
+               return 16;
+       else
+               return 64;
+}
+
 static u32 ixgbe_get_rxfh_key_size(struct net_device *netdev)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
@@ -2892,6 +2919,44 @@ static int ixgbe_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
        return 0;
 }
 
+static int ixgbe_set_rxfh(struct net_device *netdev, const u32 *indir,
+                         const u8 *key, const u8 hfunc)
+{
+       struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       int i;
+       u32 reta_entries = ixgbe_rss_indir_tbl_entries(adapter);
+
+       if (hfunc)
+               return -EINVAL;
+
+       /* Fill out the redirection table */
+       if (indir) {
+               int max_queues = min_t(int, adapter->num_rx_queues,
+                                      ixgbe_rss_indir_tbl_max(adapter));
+
+               /*Allow at least 2 queues w/ SR-IOV.*/
+               if ((adapter->flags & IXGBE_FLAG_SRIOV_ENABLED) &&
+                   (max_queues < 2))
+                       max_queues = 2;
+
+               /* Verify user input. */
+               for (i = 0; i < reta_entries; i++)
+                       if (indir[i] >= max_queues)
+                               return -EINVAL;
+
+               for (i = 0; i < reta_entries; i++)
+                       adapter->rss_indir_tbl[i] = indir[i];
+       }
+
+       /* Fill out the rss hash key */
+       if (key)
+               memcpy(adapter->rss_key, key, ixgbe_get_rxfh_key_size(netdev));
+
+       ixgbe_store_reta(adapter);
+
+       return 0;
+}
+
 static int ixgbe_get_ts_info(struct net_device *dev,
                             struct ethtool_ts_info *info)
 {
@@ -2923,14 +2988,6 @@ static int ixgbe_get_ts_info(struct net_device *dev,
                        (1 << HWTSTAMP_FILTER_NONE) |
                        (1 << HWTSTAMP_FILTER_PTP_V1_L4_SYNC) |
                        (1 << HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_L2_EVENT) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_L4_EVENT) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_SYNC) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_L2_SYNC) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_L4_SYNC) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_DELAY_REQ) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ) |
-                       (1 << HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ) |
                        (1 << HWTSTAMP_FILTER_PTP_V2_EVENT);
                break;
        default:
@@ -3053,7 +3110,7 @@ static int ixgbe_get_module_info(struct net_device *dev,
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 status;
+       s32 status;
        u8 sff8472_rev, addr_mode;
        bool page_swap = false;
 
@@ -3061,14 +3118,14 @@ static int ixgbe_get_module_info(struct net_device *dev,
        status = hw->phy.ops.read_i2c_eeprom(hw,
                                             IXGBE_SFF_SFF_8472_COMP,
                                             &sff8472_rev);
-       if (status != 0)
+       if (status)
                return -EIO;
 
        /* addressing mode is not supported */
        status = hw->phy.ops.read_i2c_eeprom(hw,
                                             IXGBE_SFF_SFF_8472_SWAP,
                                             &addr_mode);
-       if (status != 0)
+       if (status)
                return -EIO;
 
        if (addr_mode & IXGBE_SFF_ADDRESSING_MODE) {
@@ -3095,7 +3152,7 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
        struct ixgbe_hw *hw = &adapter->hw;
-       u32 status = IXGBE_ERR_PHY_ADDR_INVALID;
+       s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
        u8 databyte = 0xFF;
        int i = 0;
 
@@ -3112,7 +3169,7 @@ static int ixgbe_get_module_eeprom(struct net_device *dev,
                else
                        status = hw->phy.ops.read_i2c_sff8472(hw, i, &databyte);
 
-               if (status != 0)
+               if (status)
                        return -EIO;
 
                data[i - ee->offset] = databyte;
@@ -3152,6 +3209,7 @@ static const struct ethtool_ops ixgbe_ethtool_ops = {
        .get_rxfh_indir_size    = ixgbe_rss_indir_size,
        .get_rxfh_key_size      = ixgbe_get_rxfh_key_size,
        .get_rxfh               = ixgbe_get_rxfh,
+       .set_rxfh               = ixgbe_set_rxfh,
        .get_channels           = ixgbe_get_channels,
        .set_channels           = ixgbe_set_channels,
        .get_ts_info            = ixgbe_get_ts_info,