ixgbe: further flow director performance optimizations
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / drivers / net / ixgbe / ixgbe_ethtool.c
index f61a8ce908eda19330db2abd6b4863af746a98ac..76e40e2b37e5e54e50767bba9b09bf045197d6c8 100644 (file)
@@ -185,6 +185,16 @@ static int ixgbe_get_settings(struct net_device *netdev,
                                             ADVERTISED_FIBRE);
                        ecmd->port = PORT_FIBRE;
                        ecmd->autoneg = AUTONEG_DISABLE;
+               } else if ((hw->device_id == IXGBE_DEV_ID_82599_COMBO_BACKPLANE) ||
+                          (hw->device_id == IXGBE_DEV_ID_82599_KX4_MEZZ)) {
+                       ecmd->supported |= (SUPPORTED_1000baseT_Full |
+                                           SUPPORTED_Autoneg |
+                                           SUPPORTED_FIBRE);
+                       ecmd->advertising = (ADVERTISED_10000baseT_Full |
+                                            ADVERTISED_1000baseT_Full |
+                                            ADVERTISED_Autoneg |
+                                            ADVERTISED_FIBRE);
+                       ecmd->port = PORT_FIBRE;
                } else {
                        ecmd->supported |= (SUPPORTED_1000baseT_Full |
                                            SUPPORTED_FIBRE);
@@ -204,6 +214,7 @@ static int ixgbe_get_settings(struct net_device *netdev,
        /* Get PHY type */
        switch (adapter->hw.phy.type) {
        case ixgbe_phy_tn:
+       case ixgbe_phy_aq:
        case ixgbe_phy_cu_unknown:
                /* Copper 10G-BASET */
                ecmd->port = PORT_TP;
@@ -332,13 +343,6 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
        else
                pause->autoneg = 1;
 
-#ifdef CONFIG_DCB
-       if (hw->fc.current_mode == ixgbe_fc_pfc) {
-               pause->rx_pause = 0;
-               pause->tx_pause = 0;
-       }
-
-#endif
        if (hw->fc.current_mode == ixgbe_fc_rx_pause) {
                pause->rx_pause = 1;
        } else if (hw->fc.current_mode == ixgbe_fc_tx_pause) {
@@ -346,6 +350,11 @@ static void ixgbe_get_pauseparam(struct net_device *netdev,
        } else if (hw->fc.current_mode == ixgbe_fc_full) {
                pause->rx_pause = 1;
                pause->tx_pause = 1;
+#ifdef CONFIG_DCB
+       } else if (hw->fc.current_mode == ixgbe_fc_pfc) {
+               pause->rx_pause = 0;
+               pause->tx_pause = 0;
+#endif
        }
 }
 
@@ -363,7 +372,6 @@ static int ixgbe_set_pauseparam(struct net_device *netdev,
                return -EINVAL;
 
 #endif
-
        fc = hw->fc;
 
        if (pause->autoneg != AUTONEG_ENABLE)
@@ -423,15 +431,21 @@ static u32 ixgbe_get_tx_csum(struct net_device *netdev)
 static int ixgbe_set_tx_csum(struct net_device *netdev, u32 data)
 {
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
+       u32 feature_list;
 
-       if (data) {
-               netdev->features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
-               if (adapter->hw.mac.type == ixgbe_mac_82599EB)
-                       netdev->features |= NETIF_F_SCTP_CSUM;
-       } else {
-               netdev->features &= ~(NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM |
-                                     NETIF_F_SCTP_CSUM);
+       feature_list = (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM);
+       switch (adapter->hw.mac.type) {
+       case ixgbe_mac_82599EB:
+       case ixgbe_mac_X540:
+               feature_list |= NETIF_F_SCTP_CSUM;
+               break;
+       default:
+               break;
        }
+       if (data)
+               netdev->features |= feature_list;
+       else
+               netdev->features &= ~feature_list;
 
        return 0;
 }
@@ -619,6 +633,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
        regs_buff[827] = IXGBE_READ_REG(hw, IXGBE_WUPM);
        regs_buff[828] = IXGBE_READ_REG(hw, IXGBE_FHFT(0));
 
+       /* DCB */
        regs_buff[829] = IXGBE_READ_REG(hw, IXGBE_RMCS);
        regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_DPMCS);
        regs_buff[831] = IXGBE_READ_REG(hw, IXGBE_PDPMCS);
@@ -824,9 +839,10 @@ static void ixgbe_get_drvinfo(struct net_device *netdev,
        struct ixgbe_adapter *adapter = netdev_priv(netdev);
        char firmware_version[32];
 
-       strncpy(drvinfo->driver, ixgbe_driver_name, sizeof(drvinfo->driver));
+       strncpy(drvinfo->driver, ixgbe_driver_name,
+               sizeof(drvinfo->driver) - 1);
        strncpy(drvinfo->version, ixgbe_driver_version,
-               sizeof(drvinfo->version));
+               sizeof(drvinfo->version) - 1);
 
        snprintf(firmware_version, sizeof(firmware_version), "%d.%d-%d",
                 (adapter->eeprom_version & 0xF000) >> 12,
@@ -1142,7 +1158,7 @@ struct ixgbe_reg_test {
 #define TABLE64_TEST_HI        6
 
 /* default 82599 register test */
-static struct ixgbe_reg_test reg_test_82599[] = {
+static const struct ixgbe_reg_test reg_test_82599[] = {
        { IXGBE_FCRTL_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
        { IXGBE_FCRTH_82599(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
        { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
@@ -1166,7 +1182,7 @@ static struct ixgbe_reg_test reg_test_82599[] = {
 };
 
 /* default 82598 register test */
-static struct ixgbe_reg_test reg_test_82598[] = {
+static const struct ixgbe_reg_test reg_test_82598[] = {
        { IXGBE_FCRTL(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
        { IXGBE_FCRTH(0), 1, PATTERN_TEST, 0x8007FFF0, 0x8007FFF0 },
        { IXGBE_PFCTOP, 1, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
@@ -1193,18 +1209,22 @@ static struct ixgbe_reg_test reg_test_82598[] = {
        { 0, 0, 0, 0 }
 };
 
+static const u32 register_test_patterns[] = {
+       0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF
+};
+
 #define REG_PATTERN_TEST(R, M, W)                                             \
 {                                                                             \
        u32 pat, val, before;                                                 \
-       const u32 _test[] = {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF}; \
-       for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {                       \
+       for (pat = 0; pat < ARRAY_SIZE(register_test_patterns); pat++) {      \
                before = readl(adapter->hw.hw_addr + R);                      \
-               writel((_test[pat] & W), (adapter->hw.hw_addr + R));          \
+               writel((register_test_patterns[pat] & W),                     \
+                      (adapter->hw.hw_addr + R));                            \
                val = readl(adapter->hw.hw_addr + R);                         \
-               if (val != (_test[pat] & W & M)) {                            \
-                       e_err(drv, "pattern test reg %04X failed: got "   \
-                             "0x%08X expected 0x%08X\n",                     \
-                             R, val, (_test[pat] & W & M));                \
+               if (val != (register_test_patterns[pat] & W & M)) {           \
+                       e_err(drv, "pattern test reg %04X failed: got "       \
+                             "0x%08X expected 0x%08X\n",                     \
+                             R, val, (register_test_patterns[pat] & W & M)); \
                        *data = R;                                            \
                        writel(before, adapter->hw.hw_addr + R);              \
                        return 1;                                             \
@@ -1231,7 +1251,7 @@ static struct ixgbe_reg_test reg_test_82598[] = {
 
 static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
 {
-       struct ixgbe_reg_test *test;
+       const struct ixgbe_reg_test *test;
        u32 value, before, after;
        u32 i, toggle;
 
@@ -1241,6 +1261,7 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
                test = reg_test_82598;
                break;
        case ixgbe_mac_82599EB:
+       case ixgbe_mac_X540:
                toggle = 0x7FFFF30F;
                test = reg_test_82599;
                break;
@@ -1456,9 +1477,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
        reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXCTRL);
        reg_ctl &= ~IXGBE_RXCTRL_RXEN;
        IXGBE_WRITE_REG(hw, IXGBE_RXCTRL, reg_ctl);
-       reg_ctl = IXGBE_READ_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx));
-       reg_ctl &= ~IXGBE_RXDCTL_ENABLE;
-       IXGBE_WRITE_REG(hw, IXGBE_RXDCTL(rx_ring->reg_idx), reg_ctl);
+       ixgbe_disable_rx_queue(adapter, rx_ring);
 
        /* now Tx */
        reg_ctl = IXGBE_READ_REG(hw, IXGBE_TXDCTL(tx_ring->reg_idx));
@@ -1467,6 +1486,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
 
        switch (hw->mac.type) {
        case ixgbe_mac_82599EB:
+       case ixgbe_mac_X540:
                reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
                reg_ctl &= ~IXGBE_DMATXCTL_TE;
                IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
@@ -1503,6 +1523,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
 
        switch (adapter->hw.mac.type) {
        case ixgbe_mac_82599EB:
+       case ixgbe_mac_X540:
                reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
                reg_data |= IXGBE_DMATXCTL_TE;
                IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
@@ -1861,7 +1882,25 @@ static int ixgbe_wol_exclusion(struct ixgbe_adapter *adapter,
        struct ixgbe_hw *hw = &adapter->hw;
        int retval = 1;
 
+       /* WOL not supported except for the following */
        switch(hw->device_id) {
+       case IXGBE_DEV_ID_82599_SFP:
+               /* Only this subdevice supports WOL */
+               if (hw->subsystem_device_id != IXGBE_SUBDEV_ID_82599_SFP) {
+                       wol->supported = 0;
+                       break;
+               }
+               retval = 0;
+               break;
+       case IXGBE_DEV_ID_82599_COMBO_BACKPLANE:
+               /* All except this subdevice support WOL */
+               if (hw->subsystem_device_id ==
+                   IXGBE_SUBDEV_ID_82599_KX4_KR_MEZZ) {
+                       wol->supported = 0;
+                       break;
+               }
+               retval = 0;
+               break;
        case IXGBE_DEV_ID_82599_KX4:
                retval = 0;
                break;
@@ -2162,7 +2201,7 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
        need_reset = (data & ETH_FLAG_RXVLAN) !=
                     (netdev->features & NETIF_F_HW_VLAN_RX);
 
-       rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO |
+       rc = ethtool_op_set_flags(netdev, data, ETH_FLAG_LRO | ETH_FLAG_NTUPLE |
                                        ETH_FLAG_RXVLAN | ETH_FLAG_TXVLAN);
        if (rc)
                return rc;
@@ -2182,6 +2221,22 @@ static int ixgbe_set_flags(struct net_device *netdev, u32 data)
                        case ixgbe_mac_82599EB:
                                need_reset = true;
                                break;
+                       case ixgbe_mac_X540: {
+                               int i;
+                               for (i = 0; i < adapter->num_rx_queues; i++) {
+                                       struct ixgbe_ring *ring =
+                                                         adapter->rx_ring[i];
+                                       if (adapter->flags2 &
+                                           IXGBE_FLAG2_RSC_ENABLED) {
+                                               ixgbe_configure_rscctl(adapter,
+                                                                      ring);
+                                       } else {
+                                               ixgbe_clear_rscctl(adapter,
+                                                                  ring);
+                                       }
+                               }
+                       }
+                               break;
                        default:
                                break;
                        }
@@ -2223,7 +2278,7 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev,
 {
        struct ixgbe_adapter *adapter = netdev_priv(dev);
        struct ethtool_rx_ntuple_flow_spec fs = cmd->fs;
-       struct ixgbe_atr_input input_struct;
+       union ixgbe_atr_input input_struct;
        struct ixgbe_atr_input_masks input_masks;
        int target_queue;
 
@@ -2238,7 +2293,7 @@ static int ixgbe_set_rx_ntuple(struct net_device *dev,
            (fs.action < ETHTOOL_RXNTUPLE_ACTION_DROP))
                return -EINVAL;
 
-       memset(&input_struct, 0, sizeof(struct ixgbe_atr_input));
+       memset(&input_struct, 0, sizeof(union ixgbe_atr_input));
        memset(&input_masks, 0, sizeof(struct ixgbe_atr_input_masks));
 
        input_masks.src_ip_mask = fs.m_u.tcp_ip4_spec.ip4src;