Merge branch 'smp-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_ethtool.c
index 16486dff14933807d47b2a99f970ffbe3996b3a2..917fade5f5d55aa1a89c5abaadf73d9e5f37d612 100644 (file)
  */
 
 #include "en.h"
+#include "en_accel/ipsec.h"
 
-static void mlx5e_get_drvinfo(struct net_device *dev,
-                             struct ethtool_drvinfo *drvinfo)
+void mlx5e_ethtool_get_drvinfo(struct mlx5e_priv *priv,
+                              struct ethtool_drvinfo *drvinfo)
 {
-       struct mlx5e_priv *priv = netdev_priv(dev);
        struct mlx5_core_dev *mdev = priv->mdev;
 
        strlcpy(drvinfo->driver, DRIVER_NAME, sizeof(drvinfo->driver));
-       strlcpy(drvinfo->version, DRIVER_VERSION " (" DRIVER_RELDATE ")",
+       strlcpy(drvinfo->version, DRIVER_VERSION,
                sizeof(drvinfo->version));
        snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
                 "%d.%d.%04d (%.16s)",
@@ -49,6 +49,14 @@ static void mlx5e_get_drvinfo(struct net_device *dev,
                sizeof(drvinfo->bus_info));
 }
 
+static void mlx5e_get_drvinfo(struct net_device *dev,
+                             struct ethtool_drvinfo *drvinfo)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+
+       mlx5e_ethtool_get_drvinfo(priv, drvinfo);
+}
+
 struct ptys2ethtool_config {
        __ETHTOOL_DECLARE_LINK_MODE_MASK(supported);
        __ETHTOOL_DECLARE_LINK_MODE_MASK(advertised);
@@ -135,6 +143,9 @@ static unsigned long mlx5e_query_pfc_combined(struct mlx5e_priv *priv)
        u8 pfc_en_rx;
        int err;
 
+       if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+               return 0;
+
        err = mlx5_query_port_pfc(mdev, &pfc_en_tx, &pfc_en_rx);
 
        return err ? 0 : pfc_en_tx | pfc_en_rx;
@@ -147,6 +158,9 @@ static bool mlx5e_query_global_pause_combined(struct mlx5e_priv *priv)
        u32 tx_pause;
        int err;
 
+       if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
+               return false;
+
        err = mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
 
        return err ? false : rx_pause | tx_pause;
@@ -160,9 +174,8 @@ static bool mlx5e_query_global_pause_combined(struct mlx5e_priv *priv)
        ((mlx5e_query_global_pause_combined(priv) + hweight8(mlx5e_query_pfc_combined(priv))) * \
          NUM_PPORT_PER_PRIO_PFC_COUNTERS)
 
-static int mlx5e_get_sset_count(struct net_device *dev, int sset)
+int mlx5e_ethtool_get_sset_count(struct mlx5e_priv *priv, int sset)
 {
-       struct mlx5e_priv *priv = netdev_priv(dev);
 
        switch (sset) {
        case ETH_SS_STATS:
@@ -174,7 +187,8 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
                       MLX5E_NUM_SQ_STATS(priv) +
                       MLX5E_NUM_PFC_COUNTERS(priv) +
                       ARRAY_SIZE(mlx5e_pme_status_desc) +
-                      ARRAY_SIZE(mlx5e_pme_error_desc);
+                      ARRAY_SIZE(mlx5e_pme_error_desc) +
+                      mlx5e_ipsec_get_count(priv);
 
        case ETH_SS_PRIV_FLAGS:
                return ARRAY_SIZE(mlx5e_priv_flags);
@@ -186,6 +200,13 @@ static int mlx5e_get_sset_count(struct net_device *dev, int sset)
        }
 }
 
+static int mlx5e_get_sset_count(struct net_device *dev, int sset)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+
+       return mlx5e_ethtool_get_sset_count(priv, sset);
+}
+
 static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
 {
        int i, j, tc, prio, idx = 0;
@@ -256,6 +277,9 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
        for (i = 0; i < ARRAY_SIZE(mlx5e_pme_error_desc); i++)
                strcpy(data + (idx++) * ETH_GSTRING_LEN, mlx5e_pme_error_desc[i].format);
 
+       /* IPSec counters */
+       idx += mlx5e_ipsec_get_strings(priv, data + idx * ETH_GSTRING_LEN);
+
        if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
                return;
 
@@ -273,10 +297,9 @@ static void mlx5e_fill_stats_strings(struct mlx5e_priv *priv, uint8_t *data)
                                        priv->channel_tc2txq[i][tc]);
 }
 
-static void mlx5e_get_strings(struct net_device *dev,
-                             uint32_t stringset, uint8_t *data)
+void mlx5e_ethtool_get_strings(struct mlx5e_priv *priv,
+                              uint32_t stringset, uint8_t *data)
 {
-       struct mlx5e_priv *priv = netdev_priv(dev);
        int i;
 
        switch (stringset) {
@@ -297,10 +320,17 @@ static void mlx5e_get_strings(struct net_device *dev,
        }
 }
 
-static void mlx5e_get_ethtool_stats(struct net_device *dev,
-                                   struct ethtool_stats *stats, u64 *data)
+static void mlx5e_get_strings(struct net_device *dev,
+                             uint32_t stringset, uint8_t *data)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
+
+       mlx5e_ethtool_get_strings(priv, stringset, data);
+}
+
+void mlx5e_ethtool_get_ethtool_stats(struct mlx5e_priv *priv,
+                                    struct ethtool_stats *stats, u64 *data)
+{
        struct mlx5e_channels *channels;
        struct mlx5_priv *mlx5_priv;
        int i, j, tc, prio, idx = 0;
@@ -311,7 +341,7 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
 
        mutex_lock(&priv->state_lock);
        if (test_bit(MLX5E_STATE_OPENED, &priv->state))
-               mlx5e_update_stats(priv);
+               mlx5e_update_stats(priv, true);
        channels = &priv->channels;
        mutex_unlock(&priv->state_lock);
 
@@ -378,6 +408,9 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
                data[idx++] = MLX5E_READ_CTR64_CPU(mlx5_priv->pme_stats.error_counters,
                                                   mlx5e_pme_error_desc, i);
 
+       /* IPSec counters */
+       idx += mlx5e_ipsec_get_stats(priv, data + idx);
+
        if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
                return;
 
@@ -395,6 +428,15 @@ static void mlx5e_get_ethtool_stats(struct net_device *dev,
                                                                   sq_stats_desc, j);
 }
 
+static void mlx5e_get_ethtool_stats(struct net_device *dev,
+                                   struct ethtool_stats *stats,
+                                   u64 *data)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+
+       mlx5e_ethtool_get_ethtool_stats(priv, stats, data);
+}
+
 static u32 mlx5e_rx_wqes_to_packets(struct mlx5e_priv *priv, int rq_wq_type,
                                    int num_wqe)
 {
@@ -439,10 +481,9 @@ static u32 mlx5e_packets_to_rx_wqes(struct mlx5e_priv *priv, int rq_wq_type,
        return 1 << (order_base_2(num_wqes));
 }
 
-static void mlx5e_get_ringparam(struct net_device *dev,
-                               struct ethtool_ringparam *param)
+void mlx5e_ethtool_get_ringparam(struct mlx5e_priv *priv,
+                                struct ethtool_ringparam *param)
 {
-       struct mlx5e_priv *priv = netdev_priv(dev);
        int rq_wq_type = priv->channels.params.rq_wq_type;
 
        param->rx_max_pending = mlx5e_rx_wqes_to_packets(priv, rq_wq_type,
@@ -453,10 +494,17 @@ static void mlx5e_get_ringparam(struct net_device *dev,
        param->tx_pending     = 1 << priv->channels.params.log_sq_size;
 }
 
-static int mlx5e_set_ringparam(struct net_device *dev,
-                              struct ethtool_ringparam *param)
+static void mlx5e_get_ringparam(struct net_device *dev,
+                               struct ethtool_ringparam *param)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
+
+       mlx5e_ethtool_get_ringparam(priv, param);
+}
+
+int mlx5e_ethtool_set_ringparam(struct mlx5e_priv *priv,
+                               struct ethtool_ringparam *param)
+{
        int rq_wq_type = priv->channels.params.rq_wq_type;
        struct mlx5e_channels new_channels = {};
        u32 rx_pending_wqes;
@@ -468,12 +516,12 @@ static int mlx5e_set_ringparam(struct net_device *dev,
        int err = 0;
 
        if (param->rx_jumbo_pending) {
-               netdev_info(dev, "%s: rx_jumbo_pending not supported\n",
+               netdev_info(priv->netdev, "%s: rx_jumbo_pending not supported\n",
                            __func__);
                return -EINVAL;
        }
        if (param->rx_mini_pending) {
-               netdev_info(dev, "%s: rx_mini_pending not supported\n",
+               netdev_info(priv->netdev, "%s: rx_mini_pending not supported\n",
                            __func__);
                return -EINVAL;
        }
@@ -486,13 +534,13 @@ static int mlx5e_set_ringparam(struct net_device *dev,
                                                   param->rx_pending);
 
        if (param->rx_pending < min_rq_size) {
-               netdev_info(dev, "%s: rx_pending (%d) < min (%d)\n",
+               netdev_info(priv->netdev, "%s: rx_pending (%d) < min (%d)\n",
                            __func__, param->rx_pending,
                            min_rq_size);
                return -EINVAL;
        }
        if (param->rx_pending > max_rq_size) {
-               netdev_info(dev, "%s: rx_pending (%d) > max (%d)\n",
+               netdev_info(priv->netdev, "%s: rx_pending (%d) > max (%d)\n",
                            __func__, param->rx_pending,
                            max_rq_size);
                return -EINVAL;
@@ -501,19 +549,19 @@ static int mlx5e_set_ringparam(struct net_device *dev,
        num_mtts = MLX5E_REQUIRED_MTTS(rx_pending_wqes);
        if (priv->channels.params.rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ &&
            !MLX5E_VALID_NUM_MTTS(num_mtts)) {
-               netdev_info(dev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n",
+               netdev_info(priv->netdev, "%s: rx_pending (%d) request can't be satisfied, try to reduce.\n",
                            __func__, param->rx_pending);
                return -EINVAL;
        }
 
        if (param->tx_pending < (1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE)) {
-               netdev_info(dev, "%s: tx_pending (%d) < min (%d)\n",
+               netdev_info(priv->netdev, "%s: tx_pending (%d) < min (%d)\n",
                            __func__, param->tx_pending,
                            1 << MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE);
                return -EINVAL;
        }
        if (param->tx_pending > (1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE)) {
-               netdev_info(dev, "%s: tx_pending (%d) > max (%d)\n",
+               netdev_info(priv->netdev, "%s: tx_pending (%d) > max (%d)\n",
                            __func__, param->tx_pending,
                            1 << MLX5E_PARAMS_MAXIMUM_LOG_SQ_SIZE);
                return -EINVAL;
@@ -549,26 +597,39 @@ unlock:
        return err;
 }
 
-static void mlx5e_get_channels(struct net_device *dev,
-                              struct ethtool_channels *ch)
+static int mlx5e_set_ringparam(struct net_device *dev,
+                              struct ethtool_ringparam *param)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
 
+       return mlx5e_ethtool_set_ringparam(priv, param);
+}
+
+void mlx5e_ethtool_get_channels(struct mlx5e_priv *priv,
+                               struct ethtool_channels *ch)
+{
        ch->max_combined   = priv->profile->max_nch(priv->mdev);
        ch->combined_count = priv->channels.params.num_channels;
 }
 
-static int mlx5e_set_channels(struct net_device *dev,
-                             struct ethtool_channels *ch)
+static void mlx5e_get_channels(struct net_device *dev,
+                              struct ethtool_channels *ch)
 {
        struct mlx5e_priv *priv = netdev_priv(dev);
+
+       mlx5e_ethtool_get_channels(priv, ch);
+}
+
+int mlx5e_ethtool_set_channels(struct mlx5e_priv *priv,
+                              struct ethtool_channels *ch)
+{
        unsigned int count = ch->combined_count;
        struct mlx5e_channels new_channels = {};
        bool arfs_enabled;
        int err = 0;
 
        if (!count) {
-               netdev_info(dev, "%s: combined_count=0 not supported\n",
+               netdev_info(priv->netdev, "%s: combined_count=0 not supported\n",
                            __func__);
                return -EINVAL;
        }
@@ -593,7 +654,7 @@ static int mlx5e_set_channels(struct net_device *dev,
        if (err)
                goto out;
 
-       arfs_enabled = dev->features & NETIF_F_NTUPLE;
+       arfs_enabled = priv->netdev->features & NETIF_F_NTUPLE;
        if (arfs_enabled)
                mlx5e_arfs_disable(priv);
 
@@ -603,7 +664,7 @@ static int mlx5e_set_channels(struct net_device *dev,
        if (arfs_enabled) {
                err = mlx5e_arfs_enable(priv);
                if (err)
-                       netdev_err(dev, "%s: mlx5e_arfs_enable failed: %d\n",
+                       netdev_err(priv->netdev, "%s: mlx5e_arfs_enable failed: %d\n",
                                   __func__, err);
        }
 
@@ -613,11 +674,17 @@ out:
        return err;
 }
 
-static int mlx5e_get_coalesce(struct net_device *netdev,
-                             struct ethtool_coalesce *coal)
+static int mlx5e_set_channels(struct net_device *dev,
+                             struct ethtool_channels *ch)
 {
-       struct mlx5e_priv *priv = netdev_priv(netdev);
+       struct mlx5e_priv *priv = netdev_priv(dev);
+
+       return mlx5e_ethtool_set_channels(priv, ch);
+}
 
+int mlx5e_ethtool_get_coalesce(struct mlx5e_priv *priv,
+                              struct ethtool_coalesce *coal)
+{
        if (!MLX5_CAP_GEN(priv->mdev, cq_moderation))
                return -EOPNOTSUPP;
 
@@ -630,6 +697,14 @@ static int mlx5e_get_coalesce(struct net_device *netdev,
        return 0;
 }
 
+static int mlx5e_get_coalesce(struct net_device *netdev,
+                             struct ethtool_coalesce *coal)
+{
+       struct mlx5e_priv *priv = netdev_priv(netdev);
+
+       return mlx5e_ethtool_get_coalesce(priv, coal);
+}
+
 static void
 mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesce *coal)
 {
@@ -653,10 +728,9 @@ mlx5e_set_priv_channels_coalesce(struct mlx5e_priv *priv, struct ethtool_coalesc
        }
 }
 
-static int mlx5e_set_coalesce(struct net_device *netdev,
-                             struct ethtool_coalesce *coal)
+int mlx5e_ethtool_set_coalesce(struct mlx5e_priv *priv,
+                              struct ethtool_coalesce *coal)
 {
-       struct mlx5e_priv *priv    = netdev_priv(netdev);
        struct mlx5_core_dev *mdev = priv->mdev;
        struct mlx5e_channels new_channels = {};
        int err = 0;
@@ -699,6 +773,14 @@ out:
        return err;
 }
 
+static int mlx5e_set_coalesce(struct net_device *netdev,
+                             struct ethtool_coalesce *coal)
+{
+       struct mlx5e_priv *priv    = netdev_priv(netdev);
+
+       return mlx5e_ethtool_set_coalesce(priv, coal);
+}
+
 static void ptys2ethtool_supported_link(unsigned long *supported_modes,
                                        u32 eth_proto_cap)
 {
@@ -723,24 +805,81 @@ static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
                          __ETHTOOL_LINK_MODE_MASK_NBITS);
 }
 
-static void ptys2ethtool_supported_port(struct ethtool_link_ksettings *link_ksettings,
-                                       u32 eth_proto_cap)
+static void ptys2ethtool_supported_advertised_port(struct ethtool_link_ksettings *link_ksettings,
+                                                  u32 eth_proto_cap,
+                                                  u8 connector_type)
 {
-       if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
-                          | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
-                          | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
-                          | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
-                          | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
-                          | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
-               ethtool_link_ksettings_add_link_mode(link_ksettings, supported, FIBRE);
+       if (!connector_type || connector_type >= MLX5E_CONNECTOR_TYPE_NUMBER) {
+               if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_10GBASE_CR)
+                                  | MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
+                                  | MLX5E_PROT_MASK(MLX5E_40GBASE_CR4)
+                                  | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
+                                  | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
+                                  | MLX5E_PROT_MASK(MLX5E_1000BASE_CX_SGMII))) {
+                       ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                            supported,
+                                                            FIBRE);
+                       ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                            advertising,
+                                                            FIBRE);
+               }
+
+               if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
+                                  | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
+                                  | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
+                                  | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
+                                  | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
+                       ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                            supported,
+                                                            Backplane);
+                       ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                            advertising,
+                                                            Backplane);
+               }
+               return;
        }
 
-       if (eth_proto_cap & (MLX5E_PROT_MASK(MLX5E_100GBASE_KR4)
-                          | MLX5E_PROT_MASK(MLX5E_40GBASE_KR4)
-                          | MLX5E_PROT_MASK(MLX5E_10GBASE_KR)
-                          | MLX5E_PROT_MASK(MLX5E_10GBASE_KX4)
-                          | MLX5E_PROT_MASK(MLX5E_1000BASE_KX))) {
-               ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Backplane);
+       switch (connector_type) {
+       case MLX5E_PORT_TP:
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    supported, TP);
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    advertising, TP);
+               break;
+       case MLX5E_PORT_AUI:
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    supported, AUI);
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    advertising, AUI);
+               break;
+       case MLX5E_PORT_BNC:
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    supported, BNC);
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    advertising, BNC);
+               break;
+       case MLX5E_PORT_MII:
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    supported, MII);
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    advertising, MII);
+               break;
+       case MLX5E_PORT_FIBRE:
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    supported, FIBRE);
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    advertising, FIBRE);
+               break;
+       case MLX5E_PORT_DA:
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    supported, Backplane);
+               ethtool_link_ksettings_add_link_mode(link_ksettings,
+                                                    advertising, Backplane);
+               break;
+       case MLX5E_PORT_NONE:
+       case MLX5E_PORT_OTHER:
+       default:
+               break;
        }
 }
 
@@ -791,7 +930,6 @@ static void get_supported(u32 eth_proto_cap,
 {
        unsigned long *supported = link_ksettings->link_modes.supported;
 
-       ptys2ethtool_supported_port(link_ksettings, eth_proto_cap);
        ptys2ethtool_supported_link(supported, eth_proto_cap);
        ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
 }
@@ -809,8 +947,23 @@ static void get_advertising(u32 eth_proto_cap, u8 tx_pause,
                ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Asym_Pause);
 }
 
-static u8 get_connector_port(u32 eth_proto)
+static int ptys2connector_type[MLX5E_CONNECTOR_TYPE_NUMBER] = {
+               [MLX5E_PORT_UNKNOWN]            = PORT_OTHER,
+               [MLX5E_PORT_NONE]               = PORT_NONE,
+               [MLX5E_PORT_TP]                 = PORT_TP,
+               [MLX5E_PORT_AUI]                = PORT_AUI,
+               [MLX5E_PORT_BNC]                = PORT_BNC,
+               [MLX5E_PORT_MII]                = PORT_MII,
+               [MLX5E_PORT_FIBRE]              = PORT_FIBRE,
+               [MLX5E_PORT_DA]                 = PORT_DA,
+               [MLX5E_PORT_OTHER]              = PORT_OTHER,
+       };
+
+static u8 get_connector_port(u32 eth_proto, u8 connector_type)
 {
+       if (connector_type && connector_type < MLX5E_CONNECTOR_TYPE_NUMBER)
+               return ptys2connector_type[connector_type];
+
        if (eth_proto & (MLX5E_PROT_MASK(MLX5E_10GBASE_SR)
                         | MLX5E_PROT_MASK(MLX5E_40GBASE_SR4)
                         | MLX5E_PROT_MASK(MLX5E_100GBASE_SR4)
@@ -856,6 +1009,7 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
        u32 eth_proto_oper;
        u8 an_disable_admin;
        u8 an_status;
+       u8 connector_type;
        int err;
 
        err = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
@@ -871,6 +1025,7 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
        eth_proto_lp     = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
        an_disable_admin = MLX5_GET(ptys_reg, out, an_disable_admin);
        an_status        = MLX5_GET(ptys_reg, out, an_status);
+       connector_type   = MLX5_GET(ptys_reg, out, connector_type);
 
        mlx5_query_port_pause(mdev, &rx_pause, &tx_pause);
 
@@ -883,7 +1038,10 @@ static int mlx5e_get_link_ksettings(struct net_device *netdev,
 
        eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
 
-       link_ksettings->base.port = get_connector_port(eth_proto_oper);
+       link_ksettings->base.port = get_connector_port(eth_proto_oper,
+                                                      connector_type);
+       ptys2ethtool_supported_advertised_port(link_ksettings, eth_proto_admin,
+                                              connector_type);
        get_lp_advertising(eth_proto_lp, link_ksettings);
 
        if (an_status == MLX5_AN_COMPLETE)
@@ -1048,7 +1206,7 @@ static int mlx5e_set_rxfh(struct net_device *dev, const u32 *indir,
            (hfunc != ETH_RSS_HASH_TOP))
                return -EINVAL;
 
-       in = mlx5_vzalloc(inlen);
+       in = kvzalloc(inlen, GFP_KERNEL);
        if (!in)
                return -ENOMEM;
 
@@ -1222,13 +1380,12 @@ static int mlx5e_set_pauseparam(struct net_device *netdev,
        return err;
 }
 
-static int mlx5e_get_ts_info(struct net_device *dev,
-                            struct ethtool_ts_info *info)
+int mlx5e_ethtool_get_ts_info(struct mlx5e_priv *priv,
+                             struct ethtool_ts_info *info)
 {
-       struct mlx5e_priv *priv = netdev_priv(dev);
        int ret;
 
-       ret = ethtool_op_get_ts_info(dev, info);
+       ret = ethtool_op_get_ts_info(priv->netdev, info);
        if (ret)
                return ret;
 
@@ -1251,6 +1408,14 @@ static int mlx5e_get_ts_info(struct net_device *dev,
        return 0;
 }
 
+static int mlx5e_get_ts_info(struct net_device *dev,
+                            struct ethtool_ts_info *info)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+
+       return mlx5e_ethtool_get_ts_info(priv, info);
+}
+
 static __u32 mlx5e_get_wol_supported(struct mlx5_core_dev *mdev)
 {
        __u32 ret = 0;
@@ -1638,6 +1803,40 @@ static int mlx5e_set_rxnfc(struct net_device *dev, struct ethtool_rxnfc *cmd)
        return err;
 }
 
+int mlx5e_ethtool_flash_device(struct mlx5e_priv *priv,
+                              struct ethtool_flash *flash)
+{
+       struct mlx5_core_dev *mdev = priv->mdev;
+       struct net_device *dev = priv->netdev;
+       const struct firmware *fw;
+       int err;
+
+       if (flash->region != ETHTOOL_FLASH_ALL_REGIONS)
+               return -EOPNOTSUPP;
+
+       err = request_firmware_direct(&fw, flash->data, &dev->dev);
+       if (err)
+               return err;
+
+       dev_hold(dev);
+       rtnl_unlock();
+
+       err = mlx5_firmware_flash(mdev, fw);
+       release_firmware(fw);
+
+       rtnl_lock();
+       dev_put(dev);
+       return err;
+}
+
+static int mlx5e_flash_device(struct net_device *dev,
+                             struct ethtool_flash *flash)
+{
+       struct mlx5e_priv *priv = netdev_priv(dev);
+
+       return mlx5e_ethtool_flash_device(priv, flash);
+}
+
 const struct ethtool_ops mlx5e_ethtool_ops = {
        .get_drvinfo       = mlx5e_get_drvinfo,
        .get_link          = ethtool_op_get_link,
@@ -1658,6 +1857,7 @@ const struct ethtool_ops mlx5e_ethtool_ops = {
        .set_rxfh          = mlx5e_set_rxfh,
        .get_rxnfc         = mlx5e_get_rxnfc,
        .set_rxnfc         = mlx5e_set_rxnfc,
+       .flash_device      = mlx5e_flash_device,
        .get_tunable       = mlx5e_get_tunable,
        .set_tunable       = mlx5e_set_tunable,
        .get_pauseparam    = mlx5e_get_pauseparam,