Commit 390d9b56 authored by Jakub Kicinski's avatar Jakub Kicinski

Merge tag 'mlx5-updates-2021-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-updates-2021-02-01

mlx5 netdev updates:

1) Trivial refactoring ahead of the upcoming uplink representor series.
2) Increased RSS table size to 256, for better results
3) Misc. Cleanup and very trivial improvements

* tag 'mlx5-updates-2021-02-01' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux:
  net/mlx5: DR, Avoid unnecessary csum recalculation on supporting devices
  net/mlx5e: CT: remove useless conversion to PTR_ERR then ERR_PTR
  net/mlx5e: accel, remove redundant space
  net/mlx5e: kTLS, Improve TLS RX workqueue scope
  net/mlx5e: remove h from printk format specifier
  net/mlx5e: Increase indirection RQ table size to 256
  net/mlx5e: Enable napi in channel's activation stage
  net/mlx5e: Move representor neigh init into profile enable
  net/mlx5e: Avoid false lock depenency warning on tc_ht
  net/mlx5e: Move set vxlan nic info to profile init
  net/mlx5e: Move netif_carrier_off() out of mlx5e_priv_init()
  net/mlx5e: Refactor mlx5e_netdev_init/cleanup to mlx5e_priv_init/cleanup
  net/mxl5e: Add change profile method
  net/mlx5e: Separate between netdev objects and mlx5e profiles initialization
====================

Link: https://lore.kernel.org/r/20210202065457.613312-1-saeed@kernel.orgSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a1a809c4 a283ea1b
...@@ -137,10 +137,10 @@ struct page_pool; ...@@ -137,10 +137,10 @@ struct page_pool;
#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES 0x80 #define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES 0x80
#define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW 0x2 #define MLX5E_PARAMS_DEFAULT_MIN_RX_WQES_MPW 0x2
#define MLX5E_LOG_INDIR_RQT_SIZE 0x7 #define MLX5E_LOG_INDIR_RQT_SIZE 0x8
#define MLX5E_INDIR_RQT_SIZE BIT(MLX5E_LOG_INDIR_RQT_SIZE) #define MLX5E_INDIR_RQT_SIZE BIT(MLX5E_LOG_INDIR_RQT_SIZE)
#define MLX5E_MIN_NUM_CHANNELS 0x1 #define MLX5E_MIN_NUM_CHANNELS 0x1
#define MLX5E_MAX_NUM_CHANNELS MLX5E_INDIR_RQT_SIZE #define MLX5E_MAX_NUM_CHANNELS (MLX5E_INDIR_RQT_SIZE / 2)
#define MLX5E_MAX_NUM_SQS (MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC) #define MLX5E_MAX_NUM_SQS (MLX5E_MAX_NUM_CHANNELS * MLX5E_MAX_NUM_TC)
#define MLX5E_TX_CQ_POLL_BUDGET 128 #define MLX5E_TX_CQ_POLL_BUDGET 128
#define MLX5E_TX_XSK_POLL_BUDGET 64 #define MLX5E_TX_XSK_POLL_BUDGET 64
...@@ -895,8 +895,7 @@ extern const struct mlx5e_rx_handlers mlx5e_rx_handlers_nic; ...@@ -895,8 +895,7 @@ extern const struct mlx5e_rx_handlers mlx5e_rx_handlers_nic;
struct mlx5e_profile { struct mlx5e_profile {
int (*init)(struct mlx5_core_dev *mdev, int (*init)(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev);
const struct mlx5e_profile *profile, void *ppriv);
void (*cleanup)(struct mlx5e_priv *priv); void (*cleanup)(struct mlx5e_priv *priv);
int (*init_rx)(struct mlx5e_priv *priv); int (*init_rx)(struct mlx5e_priv *priv);
void (*cleanup_rx)(struct mlx5e_priv *priv); void (*cleanup_rx)(struct mlx5e_priv *priv);
...@@ -1155,24 +1154,25 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv, ...@@ -1155,24 +1154,25 @@ int mlx5e_ethtool_set_pauseparam(struct mlx5e_priv *priv,
struct ethtool_pauseparam *pauseparam); struct ethtool_pauseparam *pauseparam);
/* mlx5e generic netdev management API */ /* mlx5e generic netdev management API */
int mlx5e_netdev_init(struct net_device *netdev, static inline unsigned int
struct mlx5e_priv *priv, mlx5e_calc_max_nch(struct mlx5e_priv *priv, const struct mlx5e_profile *profile)
struct mlx5_core_dev *mdev, {
const struct mlx5e_profile *profile, return priv->netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
void *ppriv); }
void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv);
struct net_device* int mlx5e_priv_init(struct mlx5e_priv *priv,
mlx5e_create_netdev(struct mlx5_core_dev *mdev, const struct mlx5e_profile *profile, struct net_device *netdev,
int nch, void *ppriv); struct mlx5_core_dev *mdev);
void mlx5e_priv_cleanup(struct mlx5e_priv *priv);
struct net_device *
mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs);
int mlx5e_attach_netdev(struct mlx5e_priv *priv); int mlx5e_attach_netdev(struct mlx5e_priv *priv);
void mlx5e_detach_netdev(struct mlx5e_priv *priv); void mlx5e_detach_netdev(struct mlx5e_priv *priv);
void mlx5e_destroy_netdev(struct mlx5e_priv *priv); void mlx5e_destroy_netdev(struct mlx5e_priv *priv);
int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
const struct mlx5e_profile *new_profile, void *new_ppriv);
void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv); void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv);
void mlx5e_build_nic_params(struct mlx5e_priv *priv, void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 mtu);
struct mlx5e_xsk *xsk,
struct mlx5e_rss_params *rss_params,
struct mlx5e_params *params,
u16 mtu);
void mlx5e_build_rq_params(struct mlx5_core_dev *mdev, void mlx5e_build_rq_params(struct mlx5_core_dev *mdev,
struct mlx5e_params *params); struct mlx5e_params *params);
void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params, void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
......
...@@ -179,7 +179,7 @@ int mlx5e_validate_params(struct mlx5e_priv *priv, struct mlx5e_params *params) ...@@ -179,7 +179,7 @@ int mlx5e_validate_params(struct mlx5e_priv *priv, struct mlx5e_params *params)
stop_room = mlx5e_calc_sq_stop_room(priv->mdev, params); stop_room = mlx5e_calc_sq_stop_room(priv->mdev, params);
if (stop_room >= sq_size) { if (stop_room >= sq_size) {
netdev_err(priv->netdev, "Stop room %hu is bigger than the SQ size %zu\n", netdev_err(priv->netdev, "Stop room %u is bigger than the SQ size %zu\n",
stop_room, sq_size); stop_room, sq_size);
return -EINVAL; return -EINVAL;
} }
......
...@@ -428,16 +428,13 @@ static int mlx5e_ptp_open_queues(struct mlx5e_port_ptp *c, ...@@ -428,16 +428,13 @@ static int mlx5e_ptp_open_queues(struct mlx5e_port_ptp *c,
if (err) if (err)
return err; return err;
napi_enable(&c->napi);
err = mlx5e_ptp_open_txqsqs(c, cparams); err = mlx5e_ptp_open_txqsqs(c, cparams);
if (err) if (err)
goto disable_napi; goto close_cqs;
return 0; return 0;
disable_napi: close_cqs:
napi_disable(&c->napi);
mlx5e_ptp_close_cqs(c); mlx5e_ptp_close_cqs(c);
return err; return err;
...@@ -446,7 +443,6 @@ static int mlx5e_ptp_open_queues(struct mlx5e_port_ptp *c, ...@@ -446,7 +443,6 @@ static int mlx5e_ptp_open_queues(struct mlx5e_port_ptp *c,
static void mlx5e_ptp_close_queues(struct mlx5e_port_ptp *c) static void mlx5e_ptp_close_queues(struct mlx5e_port_ptp *c)
{ {
mlx5e_ptp_close_txqsqs(c); mlx5e_ptp_close_txqsqs(c);
napi_disable(&c->napi);
mlx5e_ptp_close_cqs(c); mlx5e_ptp_close_cqs(c);
} }
...@@ -515,6 +511,8 @@ void mlx5e_ptp_activate_channel(struct mlx5e_port_ptp *c) ...@@ -515,6 +511,8 @@ void mlx5e_ptp_activate_channel(struct mlx5e_port_ptp *c)
{ {
int tc; int tc;
napi_enable(&c->napi);
for (tc = 0; tc < c->num_tc; tc++) for (tc = 0; tc < c->num_tc; tc++)
mlx5e_activate_txqsq(&c->ptpsq[tc].txqsq); mlx5e_activate_txqsq(&c->ptpsq[tc].txqsq);
} }
...@@ -525,4 +523,6 @@ void mlx5e_ptp_deactivate_channel(struct mlx5e_port_ptp *c) ...@@ -525,4 +523,6 @@ void mlx5e_ptp_deactivate_channel(struct mlx5e_port_ptp *c)
for (tc = 0; tc < c->num_tc; tc++) for (tc = 0; tc < c->num_tc; tc++)
mlx5e_deactivate_txqsq(&c->ptpsq[tc].txqsq); mlx5e_deactivate_txqsq(&c->ptpsq[tc].txqsq);
napi_disable(&c->napi);
} }
...@@ -279,7 +279,7 @@ int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv) ...@@ -279,7 +279,7 @@ int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv)
err = rhashtable_init(&neigh_update->neigh_ht, &mlx5e_neigh_ht_params); err = rhashtable_init(&neigh_update->neigh_ht, &mlx5e_neigh_ht_params);
if (err) if (err)
return err; goto out_err;
INIT_LIST_HEAD(&neigh_update->neigh_list); INIT_LIST_HEAD(&neigh_update->neigh_list);
mutex_init(&neigh_update->encap_lock); mutex_init(&neigh_update->encap_lock);
...@@ -287,14 +287,19 @@ int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv) ...@@ -287,14 +287,19 @@ int mlx5e_rep_neigh_init(struct mlx5e_rep_priv *rpriv)
mlx5e_rep_neigh_stats_work); mlx5e_rep_neigh_stats_work);
mlx5e_rep_neigh_update_init_interval(rpriv); mlx5e_rep_neigh_update_init_interval(rpriv);
rpriv->neigh_update.netevent_nb.notifier_call = mlx5e_rep_netevent_event; neigh_update->netevent_nb.notifier_call = mlx5e_rep_netevent_event;
err = register_netevent_notifier(&rpriv->neigh_update.netevent_nb); err = register_netevent_notifier(&neigh_update->netevent_nb);
if (err) if (err)
goto out_err; goto out_notifier;
return 0; return 0;
out_err: out_notifier:
neigh_update->netevent_nb.notifier_call = NULL;
rhashtable_destroy(&neigh_update->neigh_ht); rhashtable_destroy(&neigh_update->neigh_ht);
out_err:
netdev_warn(rpriv->netdev,
"Failed to initialize neighbours handling for vport %d\n",
rpriv->rep->vport);
return err; return err;
} }
...@@ -303,6 +308,9 @@ void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv) ...@@ -303,6 +308,9 @@ void mlx5e_rep_neigh_cleanup(struct mlx5e_rep_priv *rpriv)
struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update; struct mlx5e_neigh_update_table *neigh_update = &rpriv->neigh_update;
struct mlx5e_priv *priv = netdev_priv(rpriv->netdev); struct mlx5e_priv *priv = netdev_priv(rpriv->netdev);
if (!rpriv->neigh_update.netevent_nb.notifier_call)
return;
unregister_netevent_notifier(&neigh_update->netevent_nb); unregister_netevent_notifier(&neigh_update->netevent_nb);
flush_workqueue(priv->wq); /* flush neigh update works */ flush_workqueue(priv->wq); /* flush neigh update works */
......
...@@ -770,7 +770,6 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, ...@@ -770,7 +770,6 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv,
struct mlx5_ct_counter *shared_counter; struct mlx5_ct_counter *shared_counter;
struct mlx5_ct_entry *rev_entry; struct mlx5_ct_entry *rev_entry;
__be16 tmp_port; __be16 tmp_port;
int ret;
/* get the reversed tuple */ /* get the reversed tuple */
tmp_port = rev_tuple.port.src; tmp_port = rev_tuple.port.src;
...@@ -804,10 +803,8 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv, ...@@ -804,10 +803,8 @@ mlx5_tc_ct_shared_counter_get(struct mlx5_tc_ct_priv *ct_priv,
mutex_unlock(&ct_priv->shared_counter_lock); mutex_unlock(&ct_priv->shared_counter_lock);
shared_counter = mlx5_tc_ct_counter_create(ct_priv); shared_counter = mlx5_tc_ct_counter_create(ct_priv);
if (IS_ERR(shared_counter)) { if (IS_ERR(shared_counter))
ret = PTR_ERR(shared_counter); return shared_counter;
return ERR_PTR(ret);
}
shared_counter->is_shared = true; shared_counter->is_shared = true;
refcount_set(&shared_counter->refcount, 1); refcount_set(&shared_counter->refcount, 1);
......
...@@ -85,7 +85,7 @@ mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, u16 ih ...@@ -85,7 +85,7 @@ mlx5e_tx_tunnel_accel(struct sk_buff *skb, struct mlx5_wqe_eth_seg *eseg, u16 ih
} }
mlx5e_set_eseg_swp(skb, eseg, &swp_spec); mlx5e_set_eseg_swp(skb, eseg, &swp_spec);
if (skb_vlan_tag_present(skb) && ihs) if (skb_vlan_tag_present(skb) && ihs)
mlx5e_eseg_swp_offsets_add_vlan(eseg); mlx5e_eseg_swp_offsets_add_vlan(eseg);
} }
......
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
// Copyright (c) 2019 Mellanox Technologies. // Copyright (c) 2019 Mellanox Technologies.
#include "en.h" #include "en.h"
#include "en_accel/tls.h"
#include "en_accel/ktls.h" #include "en_accel/ktls.h"
#include "en_accel/ktls_utils.h" #include "en_accel/ktls_utils.h"
#include "en_accel/fs_tcp.h" #include "en_accel/fs_tcp.h"
...@@ -86,16 +87,33 @@ int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable) ...@@ -86,16 +87,33 @@ int mlx5e_ktls_set_feature_rx(struct net_device *netdev, bool enable)
int mlx5e_ktls_init_rx(struct mlx5e_priv *priv) int mlx5e_ktls_init_rx(struct mlx5e_priv *priv)
{ {
int err = 0; int err;
if (priv->netdev->features & NETIF_F_HW_TLS_RX) if (!mlx5_accel_is_ktls_rx(priv->mdev))
return 0;
priv->tls->rx_wq = create_singlethread_workqueue("mlx5e_tls_rx");
if (!priv->tls->rx_wq)
return -ENOMEM;
if (priv->netdev->features & NETIF_F_HW_TLS_RX) {
err = mlx5e_accel_fs_tcp_create(priv); err = mlx5e_accel_fs_tcp_create(priv);
if (err) {
destroy_workqueue(priv->tls->rx_wq);
return err;
}
}
return err; return 0;
} }
void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv) void mlx5e_ktls_cleanup_rx(struct mlx5e_priv *priv)
{ {
if (!mlx5_accel_is_ktls_rx(priv->mdev))
return;
if (priv->netdev->features & NETIF_F_HW_TLS_RX) if (priv->netdev->features & NETIF_F_HW_TLS_RX)
mlx5e_accel_fs_tcp_destroy(priv); mlx5e_accel_fs_tcp_destroy(priv);
destroy_workqueue(priv->tls->rx_wq);
} }
...@@ -231,12 +231,6 @@ int mlx5e_tls_init(struct mlx5e_priv *priv) ...@@ -231,12 +231,6 @@ int mlx5e_tls_init(struct mlx5e_priv *priv)
if (!tls) if (!tls)
return -ENOMEM; return -ENOMEM;
tls->rx_wq = create_singlethread_workqueue("mlx5e_tls_rx");
if (!tls->rx_wq) {
kfree(tls);
return -ENOMEM;
}
priv->tls = tls; priv->tls = tls;
return 0; return 0;
} }
...@@ -248,7 +242,6 @@ void mlx5e_tls_cleanup(struct mlx5e_priv *priv) ...@@ -248,7 +242,6 @@ void mlx5e_tls_cleanup(struct mlx5e_priv *priv)
if (!tls) if (!tls)
return; return;
destroy_workqueue(tls->rx_wq);
kfree(tls); kfree(tls);
priv->tls = NULL; priv->tls = NULL;
} }
...@@ -1892,13 +1892,11 @@ static int mlx5e_open_queues(struct mlx5e_channel *c, ...@@ -1892,13 +1892,11 @@ static int mlx5e_open_queues(struct mlx5e_channel *c,
if (err) if (err)
goto err_close_rx_cq; goto err_close_rx_cq;
napi_enable(&c->napi);
spin_lock_init(&c->async_icosq_lock); spin_lock_init(&c->async_icosq_lock);
err = mlx5e_open_icosq(c, params, &cparam->async_icosq, &c->async_icosq); err = mlx5e_open_icosq(c, params, &cparam->async_icosq, &c->async_icosq);
if (err) if (err)
goto err_disable_napi; goto err_close_xdpsq_cq;
err = mlx5e_open_icosq(c, params, &cparam->icosq, &c->icosq); err = mlx5e_open_icosq(c, params, &cparam->icosq, &c->icosq);
if (err) if (err)
...@@ -1941,9 +1939,7 @@ static int mlx5e_open_queues(struct mlx5e_channel *c, ...@@ -1941,9 +1939,7 @@ static int mlx5e_open_queues(struct mlx5e_channel *c,
err_close_async_icosq: err_close_async_icosq:
mlx5e_close_icosq(&c->async_icosq); mlx5e_close_icosq(&c->async_icosq);
err_disable_napi: err_close_xdpsq_cq:
napi_disable(&c->napi);
if (c->xdp) if (c->xdp)
mlx5e_close_cq(&c->rq_xdpsq.cq); mlx5e_close_cq(&c->rq_xdpsq.cq);
...@@ -1974,7 +1970,6 @@ static void mlx5e_close_queues(struct mlx5e_channel *c) ...@@ -1974,7 +1970,6 @@ static void mlx5e_close_queues(struct mlx5e_channel *c)
mlx5e_close_sqs(c); mlx5e_close_sqs(c);
mlx5e_close_icosq(&c->icosq); mlx5e_close_icosq(&c->icosq);
mlx5e_close_icosq(&c->async_icosq); mlx5e_close_icosq(&c->async_icosq);
napi_disable(&c->napi);
if (c->xdp) if (c->xdp)
mlx5e_close_cq(&c->rq_xdpsq.cq); mlx5e_close_cq(&c->rq_xdpsq.cq);
mlx5e_close_cq(&c->rq.cq); mlx5e_close_cq(&c->rq.cq);
...@@ -2059,6 +2054,8 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c) ...@@ -2059,6 +2054,8 @@ static void mlx5e_activate_channel(struct mlx5e_channel *c)
{ {
int tc; int tc;
napi_enable(&c->napi);
for (tc = 0; tc < c->num_tc; tc++) for (tc = 0; tc < c->num_tc; tc++)
mlx5e_activate_txqsq(&c->sq[tc]); mlx5e_activate_txqsq(&c->sq[tc]);
mlx5e_activate_icosq(&c->icosq); mlx5e_activate_icosq(&c->icosq);
...@@ -2081,8 +2078,9 @@ static void mlx5e_deactivate_channel(struct mlx5e_channel *c) ...@@ -2081,8 +2078,9 @@ static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
mlx5e_deactivate_icosq(&c->icosq); mlx5e_deactivate_icosq(&c->icosq);
for (tc = 0; tc < c->num_tc; tc++) for (tc = 0; tc < c->num_tc; tc++)
mlx5e_deactivate_txqsq(&c->sq[tc]); mlx5e_deactivate_txqsq(&c->sq[tc]);
mlx5e_qos_deactivate_queues(c); mlx5e_qos_deactivate_queues(c);
napi_disable(&c->napi);
} }
static void mlx5e_close_channel(struct mlx5e_channel *c) static void mlx5e_close_channel(struct mlx5e_channel *c)
...@@ -3888,7 +3886,7 @@ static int set_feature_lro(struct net_device *netdev, bool enable) ...@@ -3888,7 +3886,7 @@ static int set_feature_lro(struct net_device *netdev, bool enable)
mutex_lock(&priv->state_lock); mutex_lock(&priv->state_lock);
if (enable && priv->xsk.refcnt) { if (enable && priv->xsk.refcnt) {
netdev_warn(netdev, "LRO is incompatible with AF_XDP (%hu XSKs are active)\n", netdev_warn(netdev, "LRO is incompatible with AF_XDP (%u XSKs are active)\n",
priv->xsk.refcnt); priv->xsk.refcnt);
err = -EINVAL; err = -EINVAL;
goto out; goto out;
...@@ -4091,6 +4089,7 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev, ...@@ -4091,6 +4089,7 @@ static netdev_features_t mlx5e_fix_features(struct net_device *netdev,
if (!params->vlan_strip_disable) if (!params->vlan_strip_disable)
netdev_warn(netdev, "Dropping C-tag vlan stripping offload due to S-tag vlan\n"); netdev_warn(netdev, "Dropping C-tag vlan stripping offload due to S-tag vlan\n");
} }
if (!MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ)) { if (!MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
if (features & NETIF_F_LRO) { if (features & NETIF_F_LRO) {
netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n"); netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n");
...@@ -4138,7 +4137,7 @@ static bool mlx5e_xsk_validate_mtu(struct net_device *netdev, ...@@ -4138,7 +4137,7 @@ static bool mlx5e_xsk_validate_mtu(struct net_device *netdev,
max_mtu_page = mlx5e_xdp_max_mtu(new_params, &xsk); max_mtu_page = mlx5e_xdp_max_mtu(new_params, &xsk);
max_mtu = min(max_mtu_frame, max_mtu_page); max_mtu = min(max_mtu_frame, max_mtu_page);
netdev_err(netdev, "MTU %d is too big for an XSK running on channel %hu. Try MTU <= %d\n", netdev_err(netdev, "MTU %d is too big for an XSK running on channel %u. Try MTU <= %d\n",
new_params->sw_mtu, ix, max_mtu); new_params->sw_mtu, ix, max_mtu);
return false; return false;
} }
...@@ -4926,15 +4925,15 @@ void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params, ...@@ -4926,15 +4925,15 @@ void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
tirc_default_config[tt].rx_hash_fields; tirc_default_config[tt].rx_hash_fields;
} }
void mlx5e_build_nic_params(struct mlx5e_priv *priv, void mlx5e_build_nic_params(struct mlx5e_priv *priv, struct mlx5e_xsk *xsk, u16 mtu)
struct mlx5e_xsk *xsk,
struct mlx5e_rss_params *rss_params,
struct mlx5e_params *params,
u16 mtu)
{ {
struct mlx5e_rss_params *rss_params = &priv->rss_params;
struct mlx5e_params *params = &priv->channels.params;
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
u8 rx_cq_period_mode; u8 rx_cq_period_mode;
priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
params->sw_mtu = mtu; params->sw_mtu = mtu;
params->hard_mtu = MLX5E_ETH_HARD_MTU; params->hard_mtu = MLX5E_ETH_HARD_MTU;
params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2, params->num_channels = min_t(unsigned int, MLX5E_MAX_NUM_CHANNELS / 2,
...@@ -4992,6 +4991,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv, ...@@ -4992,6 +4991,11 @@ void mlx5e_build_nic_params(struct mlx5e_priv *priv,
/* AF_XDP */ /* AF_XDP */
params->xsk = xsk; params->xsk = xsk;
/* Do not update netdev->features directly in here
* on mlx5e_attach_netdev() we will call mlx5e_update_features()
* To update netdev->features please modify mlx5e_fix_features()
*/
} }
static void mlx5e_set_netdev_dev_addr(struct net_device *netdev) static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
...@@ -5093,8 +5097,6 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) ...@@ -5093,8 +5097,6 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX; netdev->hw_features |= NETIF_F_HW_VLAN_STAG_TX;
mlx5e_vxlan_set_netdev_info(priv);
if (mlx5e_tunnel_any_tx_proto_supported(mdev)) { if (mlx5e_tunnel_any_tx_proto_supported(mdev)) {
netdev->hw_enc_features |= NETIF_F_HW_CSUM; netdev->hw_enc_features |= NETIF_F_HW_CSUM;
netdev->hw_enc_features |= NETIF_F_TSO; netdev->hw_enc_features |= NETIF_F_TSO;
...@@ -5144,18 +5146,12 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev) ...@@ -5144,18 +5146,12 @@ static void mlx5e_build_nic_netdev(struct net_device *netdev)
netdev->hw_features |= NETIF_F_RXFCS; netdev->hw_features |= NETIF_F_RXFCS;
netdev->features = netdev->hw_features; netdev->features = netdev->hw_features;
if (!priv->channels.params.lro_en)
netdev->features &= ~NETIF_F_LRO;
/* Defaults */
if (fcs_enabled) if (fcs_enabled)
netdev->features &= ~NETIF_F_RXALL; netdev->features &= ~NETIF_F_RXALL;
netdev->features &= ~NETIF_F_LRO;
if (!priv->channels.params.scatter_fcs_en) netdev->features &= ~NETIF_F_RXFCS;
netdev->features &= ~NETIF_F_RXFCS;
/* prefere CQE compression over rxhash */
if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS))
netdev->features &= ~NETIF_F_RXHASH;
#define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f) #define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f)
if (FT_CAP(flow_modify_en) && if (FT_CAP(flow_modify_en) &&
...@@ -5221,33 +5217,28 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv) ...@@ -5221,33 +5217,28 @@ void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
} }
static int mlx5e_nic_init(struct mlx5_core_dev *mdev, static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev)
const struct mlx5e_profile *profile,
void *ppriv)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_rss_params *rss = &priv->rss_params;
int err; int err;
err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv); mlx5e_build_nic_params(priv, &priv->xsk, netdev->mtu);
if (err) mlx5e_vxlan_set_netdev_info(priv);
return err;
mlx5e_build_nic_params(priv, &priv->xsk, rss, &priv->channels.params,
netdev->mtu);
mlx5e_timestamp_init(priv); mlx5e_timestamp_init(priv);
err = mlx5e_ipsec_init(priv); err = mlx5e_ipsec_init(priv);
if (err) if (err)
mlx5_core_err(mdev, "IPSec initialization failed, %d\n", err); mlx5_core_err(mdev, "IPSec initialization failed, %d\n", err);
err = mlx5e_tls_init(priv); err = mlx5e_tls_init(priv);
if (err) if (err)
mlx5_core_err(mdev, "TLS initialization failed, %d\n", err); mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
mlx5e_build_nic_netdev(netdev);
err = mlx5e_devlink_port_register(priv); err = mlx5e_devlink_port_register(priv);
if (err) if (err)
mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err); mlx5_core_err(mdev, "mlx5e_devlink_port_register failed, %d\n", err);
mlx5e_health_create_reporters(priv); mlx5e_health_create_reporters(priv);
return 0; return 0;
...@@ -5259,7 +5250,6 @@ static void mlx5e_nic_cleanup(struct mlx5e_priv *priv) ...@@ -5259,7 +5250,6 @@ static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
mlx5e_devlink_port_unregister(priv); mlx5e_devlink_port_unregister(priv);
mlx5e_tls_cleanup(priv); mlx5e_tls_cleanup(priv);
mlx5e_ipsec_cleanup(priv); mlx5e_ipsec_cleanup(priv);
mlx5e_netdev_cleanup(priv->netdev, priv);
} }
static int mlx5e_init_nic_rx(struct mlx5e_priv *priv) static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
...@@ -5462,21 +5452,16 @@ static const struct mlx5e_profile mlx5e_nic_profile = { ...@@ -5462,21 +5452,16 @@ static const struct mlx5e_profile mlx5e_nic_profile = {
}; };
/* mlx5e generic netdev management API (move to en_common.c) */ /* mlx5e generic netdev management API (move to en_common.c) */
int mlx5e_priv_init(struct mlx5e_priv *priv,
/* mlx5e_netdev_init/cleanup must be called from profile->init/cleanup callbacks */ struct net_device *netdev,
int mlx5e_netdev_init(struct net_device *netdev, struct mlx5_core_dev *mdev)
struct mlx5e_priv *priv,
struct mlx5_core_dev *mdev,
const struct mlx5e_profile *profile,
void *ppriv)
{ {
memset(priv, 0, sizeof(*priv));
/* priv init */ /* priv init */
priv->mdev = mdev; priv->mdev = mdev;
priv->netdev = netdev; priv->netdev = netdev;
priv->profile = profile;
priv->ppriv = ppriv;
priv->msglevel = MLX5E_MSG_LEVEL; priv->msglevel = MLX5E_MSG_LEVEL;
priv->max_nch = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
priv->max_opened_tc = 1; priv->max_opened_tc = 1;
if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL)) if (!alloc_cpumask_var(&priv->scratchpad.cpumask, GFP_KERNEL))
...@@ -5493,9 +5478,6 @@ int mlx5e_netdev_init(struct net_device *netdev, ...@@ -5493,9 +5478,6 @@ int mlx5e_netdev_init(struct net_device *netdev,
if (!priv->wq) if (!priv->wq)
goto err_free_cpumask; goto err_free_cpumask;
/* netdev init */
netif_carrier_off(netdev);
return 0; return 0;
err_free_cpumask: err_free_cpumask:
...@@ -5504,7 +5486,7 @@ int mlx5e_netdev_init(struct net_device *netdev, ...@@ -5504,7 +5486,7 @@ int mlx5e_netdev_init(struct net_device *netdev,
return -ENOMEM; return -ENOMEM;
} }
void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv) void mlx5e_priv_cleanup(struct mlx5e_priv *priv)
{ {
int i; int i;
...@@ -5516,36 +5498,27 @@ void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv) ...@@ -5516,36 +5498,27 @@ void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv)
kvfree(priv->htb.qos_sq_stats); kvfree(priv->htb.qos_sq_stats);
} }
struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev, struct net_device *
const struct mlx5e_profile *profile, mlx5e_create_netdev(struct mlx5_core_dev *mdev, unsigned int txqs, unsigned int rxqs)
int nch,
void *ppriv)
{ {
struct net_device *netdev; struct net_device *netdev;
unsigned int ptp_txqs = 0;
int qos_sqs = 0;
int err; int err;
if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn)) netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv), txqs, rxqs);
ptp_txqs = profile->max_tc;
if (mlx5_qos_is_supported(mdev))
qos_sqs = mlx5e_qos_max_leaf_nodes(mdev);
netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
nch * profile->max_tc + ptp_txqs + qos_sqs,
nch * profile->rq_groups);
if (!netdev) { if (!netdev) {
mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n"); mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n");
return NULL; return NULL;
} }
err = profile->init(mdev, netdev, profile, ppriv); err = mlx5e_priv_init(netdev_priv(netdev), netdev, mdev);
if (err) { if (err) {
mlx5_core_err(mdev, "failed to init mlx5e profile %d\n", err); mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err);
goto err_free_netdev; goto err_free_netdev;
} }
netif_carrier_off(netdev);
dev_net_set(netdev, mlx5_core_net(mdev));
return netdev; return netdev;
err_free_netdev: err_free_netdev:
...@@ -5554,14 +5527,23 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev, ...@@ -5554,14 +5527,23 @@ struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
return NULL; return NULL;
} }
static void mlx5e_update_features(struct net_device *netdev)
{
if (netdev->reg_state != NETREG_REGISTERED)
return; /* features will be updated on netdev registration */
rtnl_lock();
netdev_update_features(netdev);
rtnl_unlock();
}
int mlx5e_attach_netdev(struct mlx5e_priv *priv) int mlx5e_attach_netdev(struct mlx5e_priv *priv)
{ {
const bool take_rtnl = priv->netdev->reg_state == NETREG_REGISTERED; const bool take_rtnl = priv->netdev->reg_state == NETREG_REGISTERED;
const struct mlx5e_profile *profile; const struct mlx5e_profile *profile = priv->profile;
int max_nch; int max_nch;
int err; int err;
profile = priv->profile;
clear_bit(MLX5E_STATE_DESTROYING, &priv->state); clear_bit(MLX5E_STATE_DESTROYING, &priv->state);
/* max number of channels may have changed */ /* max number of channels may have changed */
...@@ -5601,6 +5583,8 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv) ...@@ -5601,6 +5583,8 @@ int mlx5e_attach_netdev(struct mlx5e_priv *priv)
if (profile->enable) if (profile->enable)
profile->enable(priv); profile->enable(priv);
mlx5e_update_features(priv->netdev);
return 0; return 0;
err_cleanup_tx: err_cleanup_tx:
...@@ -5627,13 +5611,76 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv) ...@@ -5627,13 +5611,76 @@ void mlx5e_detach_netdev(struct mlx5e_priv *priv)
cancel_work_sync(&priv->update_stats_work); cancel_work_sync(&priv->update_stats_work);
} }
static int
mlx5e_netdev_attach_profile(struct mlx5e_priv *priv,
const struct mlx5e_profile *new_profile, void *new_ppriv)
{
struct net_device *netdev = priv->netdev;
struct mlx5_core_dev *mdev = priv->mdev;
int err;
err = mlx5e_priv_init(priv, netdev, mdev);
if (err) {
mlx5_core_err(mdev, "mlx5e_priv_init failed, err=%d\n", err);
return err;
}
netif_carrier_off(netdev);
priv->profile = new_profile;
priv->ppriv = new_ppriv;
err = new_profile->init(priv->mdev, priv->netdev);
if (err)
return err;
err = mlx5e_attach_netdev(priv);
if (err)
new_profile->cleanup(priv);
return err;
}
int mlx5e_netdev_change_profile(struct mlx5e_priv *priv,
const struct mlx5e_profile *new_profile, void *new_ppriv)
{
unsigned int new_max_nch = mlx5e_calc_max_nch(priv, new_profile);
const struct mlx5e_profile *orig_profile = priv->profile;
void *orig_ppriv = priv->ppriv;
int err, rollback_err;
/* sanity */
if (new_max_nch != priv->max_nch) {
netdev_warn(priv->netdev,
"%s: Replacing profile with different max channles\n",
__func__);
return -EINVAL;
}
/* cleanup old profile */
mlx5e_detach_netdev(priv);
priv->profile->cleanup(priv);
mlx5e_priv_cleanup(priv);
err = mlx5e_netdev_attach_profile(priv, new_profile, new_ppriv);
if (err) { /* roll back to original profile */
netdev_warn(priv->netdev, "%s: new profile init failed, %d\n",
__func__, err);
goto rollback;
}
return 0;
rollback:
rollback_err = mlx5e_netdev_attach_profile(priv, orig_profile, orig_ppriv);
if (rollback_err) {
netdev_err(priv->netdev,
"%s: failed to rollback to orig profile, %d\n",
__func__, rollback_err);
}
return err;
}
void mlx5e_destroy_netdev(struct mlx5e_priv *priv) void mlx5e_destroy_netdev(struct mlx5e_priv *priv)
{ {
const struct mlx5e_profile *profile = priv->profile;
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
if (profile->cleanup) mlx5e_priv_cleanup(priv);
profile->cleanup(priv);
free_netdev(netdev); free_netdev(netdev);
} }
...@@ -5679,28 +5726,48 @@ static int mlx5e_probe(struct auxiliary_device *adev, ...@@ -5679,28 +5726,48 @@ static int mlx5e_probe(struct auxiliary_device *adev,
const struct auxiliary_device_id *id) const struct auxiliary_device_id *id)
{ {
struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev); struct mlx5_adev *edev = container_of(adev, struct mlx5_adev, adev);
const struct mlx5e_profile *profile = &mlx5e_nic_profile;
struct mlx5_core_dev *mdev = edev->mdev; struct mlx5_core_dev *mdev = edev->mdev;
struct net_device *netdev; struct net_device *netdev;
pm_message_t state = {}; pm_message_t state = {};
void *priv; unsigned int txqs, rxqs, ptp_txqs = 0;
struct mlx5e_priv *priv;
int qos_sqs = 0;
int err; int err;
int nch; int nch;
if (MLX5_CAP_GEN(mdev, ts_cqe_to_dest_cqn))
ptp_txqs = profile->max_tc;
if (mlx5_qos_is_supported(mdev))
qos_sqs = mlx5e_qos_max_leaf_nodes(mdev);
nch = mlx5e_get_max_num_channels(mdev); nch = mlx5e_get_max_num_channels(mdev);
netdev = mlx5e_create_netdev(mdev, &mlx5e_nic_profile, nch, NULL); txqs = nch * profile->max_tc + ptp_txqs + qos_sqs;
rxqs = nch * profile->rq_groups;
netdev = mlx5e_create_netdev(mdev, txqs, rxqs);
if (!netdev) { if (!netdev) {
mlx5_core_err(mdev, "mlx5e_create_netdev failed\n"); mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
return -ENOMEM; return -ENOMEM;
} }
dev_net_set(netdev, mlx5_core_net(mdev)); mlx5e_build_nic_netdev(netdev);
priv = netdev_priv(netdev); priv = netdev_priv(netdev);
dev_set_drvdata(&adev->dev, priv); dev_set_drvdata(&adev->dev, priv);
priv->profile = profile;
priv->ppriv = NULL;
err = profile->init(mdev, netdev);
if (err) {
mlx5_core_err(mdev, "mlx5e_nic_profile init failed, %d\n", err);
goto err_destroy_netdev;
}
err = mlx5e_resume(adev); err = mlx5e_resume(adev);
if (err) { if (err) {
mlx5_core_err(mdev, "mlx5e_resume failed, %d\n", err); mlx5_core_err(mdev, "mlx5e_resume failed, %d\n", err);
goto err_destroy_netdev; goto err_profile_cleanup;
} }
err = register_netdev(netdev); err = register_netdev(netdev);
...@@ -5716,6 +5783,8 @@ static int mlx5e_probe(struct auxiliary_device *adev, ...@@ -5716,6 +5783,8 @@ static int mlx5e_probe(struct auxiliary_device *adev,
err_resume: err_resume:
mlx5e_suspend(adev, state); mlx5e_suspend(adev, state);
err_profile_cleanup:
profile->cleanup(priv);
err_destroy_netdev: err_destroy_netdev:
mlx5e_destroy_netdev(priv); mlx5e_destroy_netdev(priv);
return err; return err;
...@@ -5729,6 +5798,7 @@ static void mlx5e_remove(struct auxiliary_device *adev) ...@@ -5729,6 +5798,7 @@ static void mlx5e_remove(struct auxiliary_device *adev)
mlx5e_dcbnl_delete_app(priv); mlx5e_dcbnl_delete_app(priv);
unregister_netdev(priv->netdev); unregister_netdev(priv->netdev);
mlx5e_suspend(adev, state); mlx5e_suspend(adev, state);
priv->profile->cleanup(priv);
mlx5e_destroy_netdev(priv); mlx5e_destroy_netdev(priv);
} }
......
...@@ -684,7 +684,10 @@ static void mlx5e_build_rep_params(struct net_device *netdev) ...@@ -684,7 +684,10 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
MLX5_CQ_PERIOD_MODE_START_FROM_CQE : MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
MLX5_CQ_PERIOD_MODE_START_FROM_EQE; MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
priv->max_nch = mlx5e_calc_max_nch(priv, priv->profile);
params = &priv->channels.params; params = &priv->channels.params;
params->num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
params->hard_mtu = MLX5E_ETH_HARD_MTU; params->hard_mtu = MLX5E_ETH_HARD_MTU;
params->sw_mtu = netdev->mtu; params->sw_mtu = netdev->mtu;
...@@ -710,20 +713,16 @@ static void mlx5e_build_rep_params(struct net_device *netdev) ...@@ -710,20 +713,16 @@ static void mlx5e_build_rep_params(struct net_device *netdev)
mlx5e_build_rss_params(&priv->rss_params, params->num_channels); mlx5e_build_rss_params(&priv->rss_params, params->num_channels);
} }
static void mlx5e_build_rep_netdev(struct net_device *netdev) static void mlx5e_build_rep_netdev(struct net_device *netdev,
struct mlx5_core_dev *mdev,
struct mlx5_eswitch_rep *rep)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev);
struct mlx5e_rep_priv *rpriv = priv->ppriv;
struct mlx5_eswitch_rep *rep = rpriv->rep;
struct mlx5_core_dev *mdev = priv->mdev;
SET_NETDEV_DEV(netdev, mdev->device); SET_NETDEV_DEV(netdev, mdev->device);
if (rep->vport == MLX5_VPORT_UPLINK) { if (rep->vport == MLX5_VPORT_UPLINK) {
netdev->netdev_ops = &mlx5e_netdev_ops_uplink_rep; netdev->netdev_ops = &mlx5e_netdev_ops_uplink_rep;
/* we want a persistent mac for the uplink rep */ /* we want a persistent mac for the uplink rep */
mlx5_query_mac_address(mdev, netdev->dev_addr); mlx5_query_mac_address(mdev, netdev->dev_addr);
netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops; netdev->ethtool_ops = &mlx5e_uplink_rep_ethtool_ops;
mlx5e_vxlan_set_netdev_info(priv);
mlx5e_dcbnl_build_rep_netdev(netdev); mlx5e_dcbnl_build_rep_netdev(netdev);
} else { } else {
netdev->netdev_ops = &mlx5e_netdev_ops_rep; netdev->netdev_ops = &mlx5e_netdev_ops_rep;
...@@ -755,30 +754,27 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev) ...@@ -755,30 +754,27 @@ static void mlx5e_build_rep_netdev(struct net_device *netdev)
} }
static int mlx5e_init_rep(struct mlx5_core_dev *mdev, static int mlx5e_init_rep(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev)
const struct mlx5e_profile *profile,
void *ppriv)
{ {
struct mlx5e_priv *priv = netdev_priv(netdev); struct mlx5e_priv *priv = netdev_priv(netdev);
int err;
err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
if (err)
return err;
priv->channels.params.num_channels = MLX5E_REP_PARAMS_DEF_NUM_CHANNELS;
mlx5e_build_rep_params(netdev); mlx5e_build_rep_params(netdev);
mlx5e_build_rep_netdev(netdev);
mlx5e_timestamp_init(priv); mlx5e_timestamp_init(priv);
return 0; return 0;
} }
static int mlx5e_init_ul_rep(struct mlx5_core_dev *mdev,
struct net_device *netdev)
{
struct mlx5e_priv *priv = netdev_priv(netdev);
mlx5e_vxlan_set_netdev_info(priv);
return mlx5e_init_rep(mdev, netdev);
}
static void mlx5e_cleanup_rep(struct mlx5e_priv *priv) static void mlx5e_cleanup_rep(struct mlx5e_priv *priv)
{ {
mlx5e_netdev_cleanup(priv->netdev, priv);
} }
static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv) static int mlx5e_create_rep_ttc_table(struct mlx5e_priv *priv)
...@@ -1055,7 +1051,17 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv) ...@@ -1055,7 +1051,17 @@ static void mlx5e_cleanup_rep_tx(struct mlx5e_priv *priv)
static void mlx5e_rep_enable(struct mlx5e_priv *priv) static void mlx5e_rep_enable(struct mlx5e_priv *priv)
{ {
struct mlx5e_rep_priv *rpriv = priv->ppriv;
mlx5e_set_netdev_mtu_boundaries(priv); mlx5e_set_netdev_mtu_boundaries(priv);
mlx5e_rep_neigh_init(rpriv);
}
static void mlx5e_rep_disable(struct mlx5e_priv *priv)
{
struct mlx5e_rep_priv *rpriv = priv->ppriv;
mlx5e_rep_neigh_cleanup(rpriv);
} }
static int mlx5e_update_rep_rx(struct mlx5e_priv *priv) static int mlx5e_update_rep_rx(struct mlx5e_priv *priv)
...@@ -1090,6 +1096,7 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event ...@@ -1090,6 +1096,7 @@ static int uplink_rep_async_event(struct notifier_block *nb, unsigned long event
static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
{ {
struct mlx5e_rep_priv *rpriv = priv->ppriv;
struct net_device *netdev = priv->netdev; struct net_device *netdev = priv->netdev;
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
u16 max_mtu; u16 max_mtu;
...@@ -1108,12 +1115,15 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv) ...@@ -1108,12 +1115,15 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
mlx5_notifier_register(mdev, &priv->events_nb); mlx5_notifier_register(mdev, &priv->events_nb);
mlx5e_dcbnl_initialize(priv); mlx5e_dcbnl_initialize(priv);
mlx5e_dcbnl_init_app(priv); mlx5e_dcbnl_init_app(priv);
mlx5e_rep_neigh_init(rpriv);
} }
static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv) static void mlx5e_uplink_rep_disable(struct mlx5e_priv *priv)
{ {
struct mlx5e_rep_priv *rpriv = priv->ppriv;
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
mlx5e_rep_neigh_cleanup(rpriv);
mlx5e_dcbnl_delete_app(priv); mlx5e_dcbnl_delete_app(priv);
mlx5_notifier_unregister(mdev, &priv->events_nb); mlx5_notifier_unregister(mdev, &priv->events_nb);
mlx5e_rep_tc_disable(priv); mlx5e_rep_tc_disable(priv);
...@@ -1165,6 +1175,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = { ...@@ -1165,6 +1175,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = {
.init_tx = mlx5e_init_rep_tx, .init_tx = mlx5e_init_rep_tx,
.cleanup_tx = mlx5e_cleanup_rep_tx, .cleanup_tx = mlx5e_cleanup_rep_tx,
.enable = mlx5e_rep_enable, .enable = mlx5e_rep_enable,
.disable = mlx5e_rep_disable,
.update_rx = mlx5e_update_rep_rx, .update_rx = mlx5e_update_rep_rx,
.update_stats = mlx5e_stats_update_ndo_stats, .update_stats = mlx5e_stats_update_ndo_stats,
.rx_handlers = &mlx5e_rx_handlers_rep, .rx_handlers = &mlx5e_rx_handlers_rep,
...@@ -1175,7 +1186,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = { ...@@ -1175,7 +1186,7 @@ static const struct mlx5e_profile mlx5e_rep_profile = {
}; };
static const struct mlx5e_profile mlx5e_uplink_rep_profile = { static const struct mlx5e_profile mlx5e_uplink_rep_profile = {
.init = mlx5e_init_rep, .init = mlx5e_init_ul_rep,
.cleanup = mlx5e_cleanup_rep, .cleanup = mlx5e_cleanup_rep,
.init_rx = mlx5e_init_ul_rep_rx, .init_rx = mlx5e_init_ul_rep_rx,
.cleanup_rx = mlx5e_cleanup_ul_rep_rx, .cleanup_rx = mlx5e_cleanup_ul_rep_rx,
...@@ -1201,6 +1212,8 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1201,6 +1212,8 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
struct mlx5e_rep_priv *rpriv; struct mlx5e_rep_priv *rpriv;
struct devlink_port *dl_port; struct devlink_port *dl_port;
struct net_device *netdev; struct net_device *netdev;
struct mlx5e_priv *priv;
unsigned int txqs, rxqs;
int nch, err; int nch, err;
rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL); rpriv = kzalloc(sizeof(*rpriv), GFP_KERNEL);
...@@ -1210,10 +1223,13 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1210,10 +1223,13 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
/* rpriv->rep to be looked up when profile->init() is called */ /* rpriv->rep to be looked up when profile->init() is called */
rpriv->rep = rep; rpriv->rep = rep;
nch = mlx5e_get_max_num_channels(dev);
profile = (rep->vport == MLX5_VPORT_UPLINK) ? profile = (rep->vport == MLX5_VPORT_UPLINK) ?
&mlx5e_uplink_rep_profile : &mlx5e_rep_profile; &mlx5e_uplink_rep_profile : &mlx5e_rep_profile;
netdev = mlx5e_create_netdev(dev, profile, nch, rpriv);
nch = mlx5e_get_max_num_channels(dev);
txqs = nch * profile->max_tc;
rxqs = nch * profile->rq_groups;
netdev = mlx5e_create_netdev(dev, txqs, rxqs);
if (!netdev) { if (!netdev) {
mlx5_core_warn(dev, mlx5_core_warn(dev,
"Failed to create representor netdev for vport %d\n", "Failed to create representor netdev for vport %d\n",
...@@ -1222,7 +1238,8 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1222,7 +1238,8 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
return -EINVAL; return -EINVAL;
} }
dev_net_set(netdev, mlx5_core_net(dev)); mlx5e_build_rep_netdev(netdev, dev, rep);
rpriv->netdev = netdev; rpriv->netdev = netdev;
rep->rep_data[REP_ETH].priv = rpriv; rep->rep_data[REP_ETH].priv = rpriv;
INIT_LIST_HEAD(&rpriv->vport_sqs_list); INIT_LIST_HEAD(&rpriv->vport_sqs_list);
...@@ -1233,20 +1250,21 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1233,20 +1250,21 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
goto err_destroy_netdev; goto err_destroy_netdev;
} }
err = mlx5e_attach_netdev(netdev_priv(netdev)); priv = netdev_priv(netdev);
priv->profile = profile;
priv->ppriv = rpriv;
err = profile->init(dev, netdev);
if (err) { if (err) {
netdev_warn(netdev, netdev_warn(netdev, "rep profile init failed, %d\n", err);
"Failed to attach representor netdev for vport %d\n",
rep->vport);
goto err_destroy_mdev_resources; goto err_destroy_mdev_resources;
} }
err = mlx5e_rep_neigh_init(rpriv); err = mlx5e_attach_netdev(netdev_priv(netdev));
if (err) { if (err) {
netdev_warn(netdev, netdev_warn(netdev,
"Failed to initialized neighbours handling for vport %d\n", "Failed to attach representor netdev for vport %d\n",
rep->vport); rep->vport);
goto err_detach_netdev; goto err_cleanup_profile;
} }
err = register_netdev(netdev); err = register_netdev(netdev);
...@@ -1254,7 +1272,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1254,7 +1272,7 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
netdev_warn(netdev, netdev_warn(netdev,
"Failed to register representor netdev for vport %d\n", "Failed to register representor netdev for vport %d\n",
rep->vport); rep->vport);
goto err_neigh_cleanup; goto err_detach_netdev;
} }
dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport); dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch, rpriv->rep->vport);
...@@ -1262,12 +1280,12 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep) ...@@ -1262,12 +1280,12 @@ mlx5e_vport_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
devlink_port_type_eth_set(dl_port, netdev); devlink_port_type_eth_set(dl_port, netdev);
return 0; return 0;
err_neigh_cleanup:
mlx5e_rep_neigh_cleanup(rpriv);
err_detach_netdev: err_detach_netdev:
mlx5e_detach_netdev(netdev_priv(netdev)); mlx5e_detach_netdev(netdev_priv(netdev));
err_cleanup_profile:
priv->profile->cleanup(priv);
err_destroy_mdev_resources: err_destroy_mdev_resources:
if (rep->vport == MLX5_VPORT_UPLINK) if (rep->vport == MLX5_VPORT_UPLINK)
mlx5e_destroy_mdev_resources(dev); mlx5e_destroy_mdev_resources(dev);
...@@ -1292,8 +1310,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep) ...@@ -1292,8 +1310,8 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
if (dl_port) if (dl_port)
devlink_port_type_clear(dl_port); devlink_port_type_clear(dl_port);
unregister_netdev(netdev); unregister_netdev(netdev);
mlx5e_rep_neigh_cleanup(rpriv);
mlx5e_detach_netdev(priv); mlx5e_detach_netdev(priv);
priv->profile->cleanup(priv);
if (rep->vport == MLX5_VPORT_UPLINK) if (rep->vport == MLX5_VPORT_UPLINK)
mlx5e_destroy_mdev_resources(priv->mdev); mlx5e_destroy_mdev_resources(priv->mdev);
mlx5e_destroy_netdev(priv); mlx5e_destroy_netdev(priv);
......
...@@ -190,6 +190,14 @@ struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] = { ...@@ -190,6 +190,14 @@ struct mlx5e_tc_attr_to_reg_mapping mlx5e_tc_attr_to_reg_mappings[] = {
[NIC_ZONE_RESTORE_TO_REG] = nic_zone_restore_to_reg_ct, [NIC_ZONE_RESTORE_TO_REG] = nic_zone_restore_to_reg_ct,
}; };
/* To avoid false lock dependency warning set the tc_ht lock
* class different than the lock class of the ht being used when deleting
* last flow from a group and then deleting a group, we get into del_sw_flow_group()
* which call rhashtable_destroy on fg->ftes_hash which will take ht->mutex but
* it's different than the ht->mutex here.
*/
static struct lock_class_key tc_ht_lock_key;
static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow); static void mlx5e_put_flow_tunnel_id(struct mlx5e_tc_flow *flow);
void void
...@@ -5215,6 +5223,8 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv) ...@@ -5215,6 +5223,8 @@ int mlx5e_tc_nic_init(struct mlx5e_priv *priv)
if (err) if (err)
return err; return err;
lockdep_set_class(&tc->ht.mutex, &tc_ht_lock_key);
if (MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ignore_flow_level)) { if (MLX5_CAP_FLOWTABLE_NIC_RX(priv->mdev, ignore_flow_level)) {
attr.flags = MLX5_CHAINS_AND_PRIOS_SUPPORTED | attr.flags = MLX5_CHAINS_AND_PRIOS_SUPPORTED |
MLX5_CHAINS_IGNORE_FLOW_LEVEL_SUPPORTED; MLX5_CHAINS_IGNORE_FLOW_LEVEL_SUPPORTED;
...@@ -5333,6 +5343,8 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht) ...@@ -5333,6 +5343,8 @@ int mlx5e_tc_esw_init(struct rhashtable *tc_ht)
if (err) if (err)
goto err_ht_init; goto err_ht_init;
lockdep_set_class(&tc_ht->mutex, &tc_ht_lock_key);
return err; return err;
err_ht_init: err_ht_init:
......
...@@ -72,23 +72,15 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev, ...@@ -72,23 +72,15 @@ static void mlx5i_build_nic_params(struct mlx5_core_dev *mdev,
} }
/* Called directly after IPoIB netdevice was created to initialize SW structs */ /* Called directly after IPoIB netdevice was created to initialize SW structs */
int mlx5i_init(struct mlx5_core_dev *mdev, int mlx5i_init(struct mlx5_core_dev *mdev, struct net_device *netdev)
struct net_device *netdev,
const struct mlx5e_profile *profile,
void *ppriv)
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
int err;
err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
if (err)
return err;
netif_carrier_off(netdev);
mlx5e_set_netdev_mtu_boundaries(priv); mlx5e_set_netdev_mtu_boundaries(priv);
netdev->mtu = netdev->max_mtu; netdev->mtu = netdev->max_mtu;
mlx5e_build_nic_params(priv, NULL, &priv->rss_params, &priv->channels.params, mlx5e_build_nic_params(priv, NULL, netdev->mtu);
netdev->mtu);
mlx5i_build_nic_params(mdev, &priv->channels.params); mlx5i_build_nic_params(mdev, &priv->channels.params);
mlx5e_timestamp_init(priv); mlx5e_timestamp_init(priv);
...@@ -112,7 +104,7 @@ int mlx5i_init(struct mlx5_core_dev *mdev, ...@@ -112,7 +104,7 @@ int mlx5i_init(struct mlx5_core_dev *mdev,
/* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */ /* Called directly before IPoIB netdevice is destroyed to cleanup SW structs */
void mlx5i_cleanup(struct mlx5e_priv *priv) void mlx5i_cleanup(struct mlx5e_priv *priv)
{ {
mlx5e_netdev_cleanup(priv->netdev, priv); mlx5e_priv_cleanup(priv);
} }
static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv) static void mlx5i_grp_sw_update_stats(struct mlx5e_priv *priv)
...@@ -753,7 +745,14 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num, ...@@ -753,7 +745,14 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num,
goto destroy_ht; goto destroy_ht;
} }
prof->init(mdev, netdev, prof, ipriv); err = mlx5e_priv_init(epriv, netdev, mdev);
if (err)
goto destroy_mdev_resources;
epriv->profile = prof;
epriv->ppriv = ipriv;
prof->init(mdev, netdev);
err = mlx5e_attach_netdev(epriv); err = mlx5e_attach_netdev(epriv);
if (err) if (err)
...@@ -777,6 +776,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num, ...@@ -777,6 +776,7 @@ static int mlx5_rdma_setup_rn(struct ib_device *ibdev, u8 port_num,
prof->cleanup(epriv); prof->cleanup(epriv);
if (ipriv->sub_interface) if (ipriv->sub_interface)
return err; return err;
destroy_mdev_resources:
mlx5e_destroy_mdev_resources(mdev); mlx5e_destroy_mdev_resources(mdev);
destroy_ht: destroy_ht:
mlx5i_pkey_qpn_ht_cleanup(netdev); mlx5i_pkey_qpn_ht_cleanup(netdev);
......
...@@ -87,10 +87,7 @@ void mlx5i_dev_cleanup(struct net_device *dev); ...@@ -87,10 +87,7 @@ void mlx5i_dev_cleanup(struct net_device *dev);
int mlx5i_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); int mlx5i_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
/* Parent profile functions */ /* Parent profile functions */
int mlx5i_init(struct mlx5_core_dev *mdev, int mlx5i_init(struct mlx5_core_dev *mdev, struct net_device *netdev);
struct net_device *netdev,
const struct mlx5e_profile *profile,
void *ppriv);
void mlx5i_cleanup(struct mlx5e_priv *priv); void mlx5i_cleanup(struct mlx5e_priv *priv);
int mlx5i_update_nic_rx(struct mlx5e_priv *priv); int mlx5i_update_nic_rx(struct mlx5e_priv *priv);
......
...@@ -276,14 +276,12 @@ static int mlx5i_pkey_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -276,14 +276,12 @@ static int mlx5i_pkey_change_mtu(struct net_device *netdev, int new_mtu)
/* Called directly after IPoIB netdevice was created to initialize SW structs */ /* Called directly after IPoIB netdevice was created to initialize SW structs */
static int mlx5i_pkey_init(struct mlx5_core_dev *mdev, static int mlx5i_pkey_init(struct mlx5_core_dev *mdev,
struct net_device *netdev, struct net_device *netdev)
const struct mlx5e_profile *profile,
void *ppriv)
{ {
struct mlx5e_priv *priv = mlx5i_epriv(netdev); struct mlx5e_priv *priv = mlx5i_epriv(netdev);
int err; int err;
err = mlx5i_init(mdev, netdev, profile, ppriv); err = mlx5i_init(mdev, netdev);
if (err) if (err)
return err; return err;
......
...@@ -447,7 +447,8 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher, ...@@ -447,7 +447,8 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,
case DR_ACTION_TYP_MODIFY_HDR: case DR_ACTION_TYP_MODIFY_HDR:
attr.modify_index = action->rewrite.index; attr.modify_index = action->rewrite.index;
attr.modify_actions = action->rewrite.num_of_actions; attr.modify_actions = action->rewrite.num_of_actions;
recalc_cs_required = action->rewrite.modify_ttl; recalc_cs_required = action->rewrite.modify_ttl &&
!mlx5dr_ste_supp_ttl_cs_recalc(&dmn->info.caps);
break; break;
case DR_ACTION_TYP_L2_TO_TNL_L2: case DR_ACTION_TYP_L2_TO_TNL_L2:
case DR_ACTION_TYP_L2_TO_TNL_L3: case DR_ACTION_TYP_L2_TO_TNL_L3:
...@@ -501,9 +502,9 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher, ...@@ -501,9 +502,9 @@ int mlx5dr_actions_build_ste_arr(struct mlx5dr_matcher *matcher,
*new_hw_ste_arr_sz = nic_matcher->num_of_builders; *new_hw_ste_arr_sz = nic_matcher->num_of_builders;
last_ste = ste_arr + DR_STE_SIZE * (nic_matcher->num_of_builders - 1); last_ste = ste_arr + DR_STE_SIZE * (nic_matcher->num_of_builders - 1);
/* Due to a HW bug, modifying TTL on RX flows will cause an incorrect /* Due to a HW bug in some devices, modifying TTL on RX flows will
* checksum calculation. In this case we will use a FW table to * cause an incorrect checksum calculation. In this case we will
* recalculate. * use a FW table to recalculate.
*/ */
if (dmn->type == MLX5DR_DOMAIN_TYPE_FDB && if (dmn->type == MLX5DR_DOMAIN_TYPE_FDB &&
rx_rule && recalc_cs_required && dest_action) { rx_rule && recalc_cs_required && dest_action) {
......
...@@ -18,6 +18,11 @@ static u32 dr_ste_crc32_calc(const void *input_data, size_t length) ...@@ -18,6 +18,11 @@ static u32 dr_ste_crc32_calc(const void *input_data, size_t length)
return (__force u32)htonl(crc); return (__force u32)htonl(crc);
} }
bool mlx5dr_ste_supp_ttl_cs_recalc(struct mlx5dr_cmd_caps *caps)
{
return caps->sw_format_ver > MLX5_STEERING_FORMAT_CONNECTX_5;
}
u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl) u32 mlx5dr_ste_calc_hash_index(u8 *hw_ste_p, struct mlx5dr_ste_htbl *htbl)
{ {
struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p; struct dr_hw_ste_format *hw_ste = (struct dr_hw_ste_format *)hw_ste_p;
......
...@@ -1211,6 +1211,8 @@ int mlx5dr_cmd_set_fte(struct mlx5_core_dev *dev, ...@@ -1211,6 +1211,8 @@ int mlx5dr_cmd_set_fte(struct mlx5_core_dev *dev,
u32 group_id, u32 group_id,
struct mlx5dr_cmd_fte_info *fte); struct mlx5dr_cmd_fte_info *fte);
bool mlx5dr_ste_supp_ttl_cs_recalc(struct mlx5dr_cmd_caps *caps);
struct mlx5dr_fw_recalc_cs_ft { struct mlx5dr_fw_recalc_cs_ft {
u64 rx_icm_addr; u64 rx_icm_addr;
u32 table_id; u32 table_id;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment