aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/ethernet/mellanox/mlx5/core/en_main.c')
-rw-r--r--drivers/net/ethernet/mellanox/mlx5/core/en_main.c74
1 files changed, 67 insertions, 7 deletions
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
index 59874d666cff..1e52db32c73d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c
@@ -442,12 +442,12 @@ static void mlx5e_disable_rq(struct mlx5e_rq *rq)
static int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq)
{
+ unsigned long exp_time = jiffies + msecs_to_jiffies(20000);
struct mlx5e_channel *c = rq->channel;
struct mlx5e_priv *priv = c->priv;
struct mlx5_wq_ll *wq = &rq->wq;
- int i;
- for (i = 0; i < 1000; i++) {
+ while (time_before(jiffies, exp_time)) {
if (wq->cur_sz >= priv->params.min_rx_wqes)
return 0;
@@ -1332,6 +1332,42 @@ static int mlx5e_modify_tir_lro(struct mlx5e_priv *priv, int tt)
return err;
}
+static int mlx5e_refresh_tir_self_loopback_enable(struct mlx5_core_dev *mdev,
+ u32 tirn)
+{
+ void *in;
+ int inlen;
+ int err;
+
+ inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
+ in = mlx5_vzalloc(inlen);
+ if (!in)
+ return -ENOMEM;
+
+ MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
+
+ err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
+
+ kvfree(in);
+
+ return err;
+}
+
+static int mlx5e_refresh_tirs_self_loopback_enable(struct mlx5e_priv *priv)
+{
+ int err;
+ int i;
+
+ for (i = 0; i < MLX5E_NUM_TT; i++) {
+ err = mlx5e_refresh_tir_self_loopback_enable(priv->mdev,
+ priv->tirn[i]);
+ if (err)
+ return err;
+ }
+
+ return 0;
+}
+
static int mlx5e_set_dev_port_mtu(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
@@ -1367,13 +1403,20 @@ int mlx5e_open_locked(struct net_device *netdev)
err = mlx5e_set_dev_port_mtu(netdev);
if (err)
- return err;
+ goto err_clear_state_opened_flag;
err = mlx5e_open_channels(priv);
if (err) {
netdev_err(netdev, "%s: mlx5e_open_channels failed, %d\n",
__func__, err);
- return err;
+ goto err_clear_state_opened_flag;
+ }
+
+ err = mlx5e_refresh_tirs_self_loopback_enable(priv);
+ if (err) {
+ netdev_err(netdev, "%s: mlx5e_refresh_tirs_self_loopback_enable failed, %d\n",
+ __func__, err);
+ goto err_close_channels;
}
mlx5e_update_carrier(priv);
@@ -1382,6 +1425,12 @@ int mlx5e_open_locked(struct net_device *netdev)
schedule_delayed_work(&priv->update_stats_work, 0);
return 0;
+
+err_close_channels:
+ mlx5e_close_channels(priv);
+err_clear_state_opened_flag:
+ clear_bit(MLX5E_STATE_OPENED, &priv->state);
+ return err;
}
static int mlx5e_open(struct net_device *netdev)
@@ -1400,6 +1449,12 @@ int mlx5e_close_locked(struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
+ /* May already be CLOSED in case a previous configuration operation
+ * (e.g RX/TX queue size change) that involves close&open failed.
+ */
+ if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
+ return 0;
+
clear_bit(MLX5E_STATE_OPENED, &priv->state);
mlx5e_redirect_rqts(priv);
@@ -1833,7 +1888,7 @@ static int mlx5e_set_features(struct net_device *netdev,
mlx5e_disable_vlan_filter(priv);
}
- return 0;
+ return err;
}
static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
@@ -1846,6 +1901,8 @@ static int mlx5e_change_mtu(struct net_device *netdev, int new_mtu)
mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
+ max_mtu = MLX5E_HW2SW_MTU(max_mtu);
+
if (new_mtu > max_mtu) {
netdev_err(netdev,
"%s: Bad MTU (%d) > (%d) Max\n",
@@ -1899,6 +1956,9 @@ static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
"Not creating net device, some required device capabilities are missing\n");
return -ENOTSUPP;
}
+ if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable))
+ mlx5_core_warn(mdev, "Self loop back prevention is not supported\n");
+
return 0;
}
@@ -1994,6 +2054,7 @@ static void mlx5e_build_netdev(struct net_device *netdev)
netdev->vlan_features |= NETIF_F_LRO;
netdev->hw_features = netdev->vlan_features;
+ netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_TX;
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_RX;
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
@@ -2037,8 +2098,7 @@ static void *mlx5e_create_netdev(struct mlx5_core_dev *mdev)
{
struct net_device *netdev;
struct mlx5e_priv *priv;
- int nch = min_t(int, mdev->priv.eq_table.num_comp_vectors,
- MLX5E_MAX_NUM_CHANNELS);
+ int nch = mlx5e_get_max_num_channels(mdev);
int err;
if (mlx5e_check_required_hca_cap(mdev))