Commit 9311ccef authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5-fixes-2021-11-16' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
mlx5-fixes-2021-11-16

Please pull this mlx5 fixes series, or let me know in case of any problem.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 3751c3d3 c4c31767
...@@ -339,6 +339,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, ...@@ -339,6 +339,8 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
case MLX5_CMD_OP_PAGE_FAULT_RESUME: case MLX5_CMD_OP_PAGE_FAULT_RESUME:
case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS: case MLX5_CMD_OP_QUERY_ESW_FUNCTIONS:
case MLX5_CMD_OP_DEALLOC_SF: case MLX5_CMD_OP_DEALLOC_SF:
case MLX5_CMD_OP_DESTROY_UCTX:
case MLX5_CMD_OP_DESTROY_UMEM:
return MLX5_CMD_STAT_OK; return MLX5_CMD_STAT_OK;
case MLX5_CMD_OP_QUERY_HCA_CAP: case MLX5_CMD_OP_QUERY_HCA_CAP:
...@@ -464,9 +466,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op, ...@@ -464,9 +466,7 @@ static int mlx5_internal_err_ret_value(struct mlx5_core_dev *dev, u16 op,
case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT: case MLX5_CMD_OP_MODIFY_GENERAL_OBJECT:
case MLX5_CMD_OP_QUERY_GENERAL_OBJECT: case MLX5_CMD_OP_QUERY_GENERAL_OBJECT:
case MLX5_CMD_OP_CREATE_UCTX: case MLX5_CMD_OP_CREATE_UCTX:
case MLX5_CMD_OP_DESTROY_UCTX:
case MLX5_CMD_OP_CREATE_UMEM: case MLX5_CMD_OP_CREATE_UMEM:
case MLX5_CMD_OP_DESTROY_UMEM:
case MLX5_CMD_OP_ALLOC_MEMIC: case MLX5_CMD_OP_ALLOC_MEMIC:
case MLX5_CMD_OP_MODIFY_XRQ: case MLX5_CMD_OP_MODIFY_XRQ:
case MLX5_CMD_OP_RELEASE_XRQ_ERROR: case MLX5_CMD_OP_RELEASE_XRQ_ERROR:
......
...@@ -164,13 +164,14 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) ...@@ -164,13 +164,14 @@ int mlx5_core_destroy_cq(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
MLX5_SET(destroy_cq_in, in, cqn, cq->cqn); MLX5_SET(destroy_cq_in, in, cqn, cq->cqn);
MLX5_SET(destroy_cq_in, in, uid, cq->uid); MLX5_SET(destroy_cq_in, in, uid, cq->uid);
err = mlx5_cmd_exec_in(dev, destroy_cq, in); err = mlx5_cmd_exec_in(dev, destroy_cq, in);
if (err)
return err;
synchronize_irq(cq->irqn); synchronize_irq(cq->irqn);
mlx5_cq_put(cq); mlx5_cq_put(cq);
wait_for_completion(&cq->free); wait_for_completion(&cq->free);
return err; return 0;
} }
EXPORT_SYMBOL(mlx5_core_destroy_cq); EXPORT_SYMBOL(mlx5_core_destroy_cq);
......
...@@ -507,6 +507,8 @@ void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq) ...@@ -507,6 +507,8 @@ void mlx5_debug_cq_remove(struct mlx5_core_dev *dev, struct mlx5_core_cq *cq)
if (!mlx5_debugfs_root) if (!mlx5_debugfs_root)
return; return;
if (cq->dbg) if (cq->dbg) {
rem_res_tree(cq->dbg); rem_res_tree(cq->dbg);
cq->dbg = NULL;
}
} }
...@@ -1356,9 +1356,13 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv, ...@@ -1356,9 +1356,13 @@ mlx5_tc_ct_match_add(struct mlx5_tc_ct_priv *priv,
int int
mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
struct mlx5_flow_attr *attr, struct mlx5_flow_attr *attr,
struct mlx5e_tc_mod_hdr_acts *mod_acts,
const struct flow_action_entry *act, const struct flow_action_entry *act,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
bool clear_action = act->ct.action & TCA_CT_ACT_CLEAR;
int err;
if (!priv) { if (!priv) {
NL_SET_ERR_MSG_MOD(extack, NL_SET_ERR_MSG_MOD(extack,
"offload of ct action isn't available"); "offload of ct action isn't available");
...@@ -1369,6 +1373,17 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, ...@@ -1369,6 +1373,17 @@ mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
attr->ct_attr.ct_action = act->ct.action; attr->ct_attr.ct_action = act->ct.action;
attr->ct_attr.nf_ft = act->ct.flow_table; attr->ct_attr.nf_ft = act->ct.flow_table;
if (!clear_action)
goto out;
err = mlx5_tc_ct_entry_set_registers(priv, mod_acts, 0, 0, 0, 0);
if (err) {
NL_SET_ERR_MSG_MOD(extack, "Failed to set registers for ct clear");
return err;
}
attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
out:
return 0; return 0;
} }
...@@ -1898,23 +1913,16 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv, ...@@ -1898,23 +1913,16 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv,
memcpy(pre_ct_attr, attr, attr_sz); memcpy(pre_ct_attr, attr, attr_sz);
err = mlx5_tc_ct_entry_set_registers(ct_priv, mod_acts, 0, 0, 0, 0);
if (err) {
ct_dbg("Failed to set register for ct clear");
goto err_set_registers;
}
mod_hdr = mlx5_modify_header_alloc(priv->mdev, ct_priv->ns_type, mod_hdr = mlx5_modify_header_alloc(priv->mdev, ct_priv->ns_type,
mod_acts->num_actions, mod_acts->num_actions,
mod_acts->actions); mod_acts->actions);
if (IS_ERR(mod_hdr)) { if (IS_ERR(mod_hdr)) {
err = PTR_ERR(mod_hdr); err = PTR_ERR(mod_hdr);
ct_dbg("Failed to add create ct clear mod hdr"); ct_dbg("Failed to add create ct clear mod hdr");
goto err_set_registers; goto err_mod_hdr;
} }
pre_ct_attr->modify_hdr = mod_hdr; pre_ct_attr->modify_hdr = mod_hdr;
pre_ct_attr->action |= MLX5_FLOW_CONTEXT_ACTION_MOD_HDR;
rule = mlx5_tc_rule_insert(priv, orig_spec, pre_ct_attr); rule = mlx5_tc_rule_insert(priv, orig_spec, pre_ct_attr);
if (IS_ERR(rule)) { if (IS_ERR(rule)) {
...@@ -1930,7 +1938,7 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv, ...@@ -1930,7 +1938,7 @@ __mlx5_tc_ct_flow_offload_clear(struct mlx5_tc_ct_priv *ct_priv,
err_insert: err_insert:
mlx5_modify_header_dealloc(priv->mdev, mod_hdr); mlx5_modify_header_dealloc(priv->mdev, mod_hdr);
err_set_registers: err_mod_hdr:
netdev_warn(priv->netdev, netdev_warn(priv->netdev,
"Failed to offload ct clear flow, err %d\n", err); "Failed to offload ct clear flow, err %d\n", err);
kfree(pre_ct_attr); kfree(pre_ct_attr);
......
...@@ -110,6 +110,7 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec); ...@@ -110,6 +110,7 @@ int mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec);
int int
mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
struct mlx5_flow_attr *attr, struct mlx5_flow_attr *attr,
struct mlx5e_tc_mod_hdr_acts *mod_acts,
const struct flow_action_entry *act, const struct flow_action_entry *act,
struct netlink_ext_ack *extack); struct netlink_ext_ack *extack);
...@@ -172,6 +173,7 @@ mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec) ...@@ -172,6 +173,7 @@ mlx5_tc_ct_add_no_trk_match(struct mlx5_flow_spec *spec)
static inline int static inline int
mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv, mlx5_tc_ct_parse_action(struct mlx5_tc_ct_priv *priv,
struct mlx5_flow_attr *attr, struct mlx5_flow_attr *attr,
struct mlx5e_tc_mod_hdr_acts *mod_acts,
const struct flow_action_entry *act, const struct flow_action_entry *act,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
......
...@@ -102,6 +102,7 @@ struct mlx5e_tc_flow { ...@@ -102,6 +102,7 @@ struct mlx5e_tc_flow {
refcount_t refcnt; refcount_t refcnt;
struct rcu_head rcu_head; struct rcu_head rcu_head;
struct completion init_done; struct completion init_done;
struct completion del_hw_done;
int tunnel_id; /* the mapped tunnel id of this flow */ int tunnel_id; /* the mapped tunnel id of this flow */
struct mlx5_flow_attr *attr; struct mlx5_flow_attr *attr;
}; };
......
...@@ -245,8 +245,14 @@ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow, ...@@ -245,8 +245,14 @@ static void mlx5e_take_tmp_flow(struct mlx5e_tc_flow *flow,
struct list_head *flow_list, struct list_head *flow_list,
int index) int index)
{ {
if (IS_ERR(mlx5e_flow_get(flow))) if (IS_ERR(mlx5e_flow_get(flow))) {
/* Flow is being deleted concurrently. Wait for it to be
* unoffloaded from hardware, otherwise deleting encap will
* fail.
*/
wait_for_completion(&flow->del_hw_done);
return; return;
}
wait_for_completion(&flow->init_done); wait_for_completion(&flow->init_done);
flow->tmp_entry_index = index; flow->tmp_entry_index = index;
......
...@@ -55,6 +55,7 @@ struct mlx5e_ktls_offload_context_rx { ...@@ -55,6 +55,7 @@ struct mlx5e_ktls_offload_context_rx {
DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS); DECLARE_BITMAP(flags, MLX5E_NUM_PRIV_RX_FLAGS);
/* resync */ /* resync */
spinlock_t lock; /* protects resync fields */
struct mlx5e_ktls_rx_resync_ctx resync; struct mlx5e_ktls_rx_resync_ctx resync;
struct list_head list; struct list_head list;
}; };
...@@ -386,14 +387,18 @@ static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_r ...@@ -386,14 +387,18 @@ static void resync_handle_seq_match(struct mlx5e_ktls_offload_context_rx *priv_r
struct mlx5e_icosq *sq; struct mlx5e_icosq *sq;
bool trigger_poll; bool trigger_poll;
memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq));
sq = &c->async_icosq; sq = &c->async_icosq;
ktls_resync = sq->ktls_resync; ktls_resync = sq->ktls_resync;
trigger_poll = false;
spin_lock_bh(&ktls_resync->lock); spin_lock_bh(&ktls_resync->lock);
spin_lock_bh(&priv_rx->lock);
memcpy(info->rec_seq, &priv_rx->resync.sw_rcd_sn_be, sizeof(info->rec_seq));
if (list_empty(&priv_rx->list)) {
list_add_tail(&priv_rx->list, &ktls_resync->list); list_add_tail(&priv_rx->list, &ktls_resync->list);
trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state); trigger_poll = !test_and_set_bit(MLX5E_SQ_STATE_PENDING_TLS_RX_RESYNC, &sq->state);
}
spin_unlock_bh(&priv_rx->lock);
spin_unlock_bh(&ktls_resync->lock); spin_unlock_bh(&ktls_resync->lock);
if (!trigger_poll) if (!trigger_poll)
...@@ -617,6 +622,8 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk, ...@@ -617,6 +622,8 @@ int mlx5e_ktls_add_rx(struct net_device *netdev, struct sock *sk,
if (err) if (err)
goto err_create_key; goto err_create_key;
INIT_LIST_HEAD(&priv_rx->list);
spin_lock_init(&priv_rx->lock);
priv_rx->crypto_info = priv_rx->crypto_info =
*(struct tls12_crypto_info_aes_gcm_128 *)crypto_info; *(struct tls12_crypto_info_aes_gcm_128 *)crypto_info;
...@@ -730,10 +737,14 @@ bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget) ...@@ -730,10 +737,14 @@ bool mlx5e_ktls_rx_handle_resync_list(struct mlx5e_channel *c, int budget)
priv_rx = list_first_entry(&local_list, priv_rx = list_first_entry(&local_list,
struct mlx5e_ktls_offload_context_rx, struct mlx5e_ktls_offload_context_rx,
list); list);
spin_lock(&priv_rx->lock);
cseg = post_static_params(sq, priv_rx); cseg = post_static_params(sq, priv_rx);
if (IS_ERR(cseg)) if (IS_ERR(cseg)) {
spin_unlock(&priv_rx->lock);
break; break;
list_del(&priv_rx->list); }
list_del_init(&priv_rx->list);
spin_unlock(&priv_rx->lock);
db_cseg = cseg; db_cseg = cseg;
} }
if (db_cseg) if (db_cseg)
......
...@@ -1600,6 +1600,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv, ...@@ -1600,6 +1600,7 @@ static void mlx5e_tc_del_fdb_flow(struct mlx5e_priv *priv,
else else
mlx5e_tc_unoffload_fdb_rules(esw, flow, attr); mlx5e_tc_unoffload_fdb_rules(esw, flow, attr);
} }
complete_all(&flow->del_hw_done);
if (mlx5_flow_has_geneve_opt(flow)) if (mlx5_flow_has_geneve_opt(flow))
mlx5_geneve_tlv_option_del(priv->mdev->geneve); mlx5_geneve_tlv_option_del(priv->mdev->geneve);
...@@ -3607,7 +3608,9 @@ parse_tc_nic_actions(struct mlx5e_priv *priv, ...@@ -3607,7 +3608,9 @@ parse_tc_nic_actions(struct mlx5e_priv *priv,
attr->dest_chain = act->chain_index; attr->dest_chain = act->chain_index;
break; break;
case FLOW_ACTION_CT: case FLOW_ACTION_CT:
err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack); err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr,
&parse_attr->mod_hdr_acts,
act, extack);
if (err) if (err)
return err; return err;
...@@ -4276,7 +4279,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ...@@ -4276,7 +4279,9 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
NL_SET_ERR_MSG_MOD(extack, "Sample action with connection tracking is not supported"); NL_SET_ERR_MSG_MOD(extack, "Sample action with connection tracking is not supported");
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr, act, extack); err = mlx5_tc_ct_parse_action(get_ct_priv(priv), attr,
&parse_attr->mod_hdr_acts,
act, extack);
if (err) if (err)
return err; return err;
...@@ -4465,6 +4470,7 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size, ...@@ -4465,6 +4470,7 @@ mlx5e_alloc_flow(struct mlx5e_priv *priv, int attr_size,
INIT_LIST_HEAD(&flow->l3_to_l2_reformat); INIT_LIST_HEAD(&flow->l3_to_l2_reformat);
refcount_set(&flow->refcnt, 1); refcount_set(&flow->refcnt, 1);
init_completion(&flow->init_done); init_completion(&flow->init_done);
init_completion(&flow->del_hw_done);
*__flow = flow; *__flow = flow;
*__parse_attr = parse_attr; *__parse_attr = parse_attr;
......
...@@ -1305,12 +1305,17 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int mode, int num_vfs) ...@@ -1305,12 +1305,17 @@ int mlx5_eswitch_enable_locked(struct mlx5_eswitch *esw, int mode, int num_vfs)
*/ */
int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
{ {
bool toggle_lag;
int ret; int ret;
if (!mlx5_esw_allowed(esw)) if (!mlx5_esw_allowed(esw))
return 0; return 0;
toggle_lag = esw->mode == MLX5_ESWITCH_NONE;
if (toggle_lag)
mlx5_lag_disable_change(esw->dev); mlx5_lag_disable_change(esw->dev);
down_write(&esw->mode_lock); down_write(&esw->mode_lock);
if (esw->mode == MLX5_ESWITCH_NONE) { if (esw->mode == MLX5_ESWITCH_NONE) {
ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs); ret = mlx5_eswitch_enable_locked(esw, MLX5_ESWITCH_LEGACY, num_vfs);
...@@ -1324,7 +1329,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) ...@@ -1324,7 +1329,10 @@ int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs)
esw->esw_funcs.num_vfs = num_vfs; esw->esw_funcs.num_vfs = num_vfs;
} }
up_write(&esw->mode_lock); up_write(&esw->mode_lock);
if (toggle_lag)
mlx5_lag_enable_change(esw->dev); mlx5_lag_enable_change(esw->dev);
return ret; return ret;
} }
...@@ -1572,6 +1580,11 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev) ...@@ -1572,6 +1580,11 @@ int mlx5_eswitch_init(struct mlx5_core_dev *dev)
esw->enabled_vports = 0; esw->enabled_vports = 0;
esw->mode = MLX5_ESWITCH_NONE; esw->mode = MLX5_ESWITCH_NONE;
esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE; esw->offloads.inline_mode = MLX5_INLINE_MODE_NONE;
if (MLX5_CAP_ESW_FLOWTABLE_FDB(dev, reformat) &&
MLX5_CAP_ESW_FLOWTABLE_FDB(dev, decap))
esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
else
esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
dev->priv.eswitch = esw; dev->priv.eswitch = esw;
BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head); BLOCKING_INIT_NOTIFIER_HEAD(&esw->n_head);
...@@ -1934,7 +1947,7 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw, ...@@ -1934,7 +1947,7 @@ int mlx5_eswitch_get_vport_stats(struct mlx5_eswitch *esw,
return err; return err;
} }
u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev) u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev)
{ {
struct mlx5_eswitch *esw = dev->priv.eswitch; struct mlx5_eswitch *esw = dev->priv.eswitch;
...@@ -1948,7 +1961,7 @@ mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev) ...@@ -1948,7 +1961,7 @@ mlx5_eswitch_get_encap_mode(const struct mlx5_core_dev *dev)
struct mlx5_eswitch *esw; struct mlx5_eswitch *esw;
esw = dev->priv.eswitch; esw = dev->priv.eswitch;
return mlx5_esw_allowed(esw) ? esw->offloads.encap : return (mlx5_eswitch_mode(dev) == MLX5_ESWITCH_OFFLOADS) ? esw->offloads.encap :
DEVLINK_ESWITCH_ENCAP_MODE_NONE; DEVLINK_ESWITCH_ENCAP_MODE_NONE;
} }
EXPORT_SYMBOL(mlx5_eswitch_get_encap_mode); EXPORT_SYMBOL(mlx5_eswitch_get_encap_mode);
......
...@@ -3183,12 +3183,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw) ...@@ -3183,12 +3183,6 @@ int esw_offloads_enable(struct mlx5_eswitch *esw)
u64 mapping_id; u64 mapping_id;
int err; int err;
if (MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, reformat) &&
MLX5_CAP_ESW_FLOWTABLE_FDB(esw->dev, decap))
esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_BASIC;
else
esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
mutex_init(&esw->offloads.termtbl_mutex); mutex_init(&esw->offloads.termtbl_mutex);
mlx5_rdma_enable_roce(esw->dev); mlx5_rdma_enable_roce(esw->dev);
...@@ -3286,7 +3280,6 @@ void esw_offloads_disable(struct mlx5_eswitch *esw) ...@@ -3286,7 +3280,6 @@ void esw_offloads_disable(struct mlx5_eswitch *esw)
esw_offloads_metadata_uninit(esw); esw_offloads_metadata_uninit(esw);
mlx5_rdma_disable_roce(esw->dev); mlx5_rdma_disable_roce(esw->dev);
mutex_destroy(&esw->offloads.termtbl_mutex); mutex_destroy(&esw->offloads.termtbl_mutex);
esw->offloads.encap = DEVLINK_ESWITCH_ENCAP_MODE_NONE;
} }
static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode) static int esw_mode_from_devlink(u16 mode, u16 *mlx5_mode)
...@@ -3630,7 +3623,7 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink, ...@@ -3630,7 +3623,7 @@ int mlx5_devlink_eswitch_encap_mode_get(struct devlink *devlink,
*encap = esw->offloads.encap; *encap = esw->offloads.encap;
unlock: unlock:
up_write(&esw->mode_lock); up_write(&esw->mode_lock);
return 0; return err;
} }
static bool static bool
......
...@@ -40,7 +40,7 @@ ...@@ -40,7 +40,7 @@
#define MLX5_FC_STATS_PERIOD msecs_to_jiffies(1000) #define MLX5_FC_STATS_PERIOD msecs_to_jiffies(1000)
/* Max number of counters to query in bulk read is 32K */ /* Max number of counters to query in bulk read is 32K */
#define MLX5_SW_MAX_COUNTERS_BULK BIT(15) #define MLX5_SW_MAX_COUNTERS_BULK BIT(15)
#define MLX5_SF_NUM_COUNTERS_BULK 6 #define MLX5_SF_NUM_COUNTERS_BULK 8
#define MLX5_FC_POOL_MAX_THRESHOLD BIT(18) #define MLX5_FC_POOL_MAX_THRESHOLD BIT(18)
#define MLX5_FC_POOL_USED_BUFF_RATIO 10 #define MLX5_FC_POOL_USED_BUFF_RATIO 10
......
...@@ -615,6 +615,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, ...@@ -615,6 +615,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
bool is_bonded, is_in_lag, mode_supported; bool is_bonded, is_in_lag, mode_supported;
int bond_status = 0; int bond_status = 0;
int num_slaves = 0; int num_slaves = 0;
int changed = 0;
int idx; int idx;
if (!netif_is_lag_master(upper)) if (!netif_is_lag_master(upper))
...@@ -653,27 +654,27 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev, ...@@ -653,27 +654,27 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
*/ */
is_in_lag = num_slaves == MLX5_MAX_PORTS && bond_status == 0x3; is_in_lag = num_slaves == MLX5_MAX_PORTS && bond_status == 0x3;
if (!mlx5_lag_is_ready(ldev) && is_in_lag) {
NL_SET_ERR_MSG_MOD(info->info.extack,
"Can't activate LAG offload, PF is configured with more than 64 VFs");
return 0;
}
/* Lag mode must be activebackup or hash. */ /* Lag mode must be activebackup or hash. */
mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP || mode_supported = tracker->tx_type == NETDEV_LAG_TX_TYPE_ACTIVEBACKUP ||
tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH; tracker->tx_type == NETDEV_LAG_TX_TYPE_HASH;
if (is_in_lag && !mode_supported)
NL_SET_ERR_MSG_MOD(info->info.extack,
"Can't activate LAG offload, TX type isn't supported");
is_bonded = is_in_lag && mode_supported; is_bonded = is_in_lag && mode_supported;
if (tracker->is_bonded != is_bonded) { if (tracker->is_bonded != is_bonded) {
tracker->is_bonded = is_bonded; tracker->is_bonded = is_bonded;
return 1; changed = 1;
} }
return 0; if (!is_in_lag)
return changed;
if (!mlx5_lag_is_ready(ldev))
NL_SET_ERR_MSG_MOD(info->info.extack,
"Can't activate LAG offload, PF is configured with more than 64 VFs");
else if (!mode_supported)
NL_SET_ERR_MSG_MOD(info->info.extack,
"Can't activate LAG offload, TX type isn't supported");
return changed;
} }
static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev, static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
...@@ -716,9 +717,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this, ...@@ -716,9 +717,6 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
ldev = container_of(this, struct mlx5_lag, nb); ldev = container_of(this, struct mlx5_lag, nb);
if (!mlx5_lag_is_ready(ldev) && event == NETDEV_CHANGELOWERSTATE)
return NOTIFY_DONE;
tracker = ldev->tracker; tracker = ldev->tracker;
switch (event) { switch (event) {
......
...@@ -135,25 +135,14 @@ static void dr_domain_fill_uplink_caps(struct mlx5dr_domain *dmn, ...@@ -135,25 +135,14 @@ static void dr_domain_fill_uplink_caps(struct mlx5dr_domain *dmn,
static int dr_domain_query_vport(struct mlx5dr_domain *dmn, static int dr_domain_query_vport(struct mlx5dr_domain *dmn,
u16 vport_number, u16 vport_number,
bool other_vport,
struct mlx5dr_cmd_vport_cap *vport_caps) struct mlx5dr_cmd_vport_cap *vport_caps)
{ {
u16 cmd_vport = vport_number;
bool other_vport = true;
int ret; int ret;
if (vport_number == MLX5_VPORT_UPLINK) {
dr_domain_fill_uplink_caps(dmn, vport_caps);
return 0;
}
if (dmn->info.caps.is_ecpf && vport_number == MLX5_VPORT_ECPF) {
other_vport = false;
cmd_vport = 0;
}
ret = mlx5dr_cmd_query_esw_vport_context(dmn->mdev, ret = mlx5dr_cmd_query_esw_vport_context(dmn->mdev,
other_vport, other_vport,
cmd_vport, vport_number,
&vport_caps->icm_address_rx, &vport_caps->icm_address_rx,
&vport_caps->icm_address_tx); &vport_caps->icm_address_tx);
if (ret) if (ret)
...@@ -161,7 +150,7 @@ static int dr_domain_query_vport(struct mlx5dr_domain *dmn, ...@@ -161,7 +150,7 @@ static int dr_domain_query_vport(struct mlx5dr_domain *dmn,
ret = mlx5dr_cmd_query_gvmi(dmn->mdev, ret = mlx5dr_cmd_query_gvmi(dmn->mdev,
other_vport, other_vport,
cmd_vport, vport_number,
&vport_caps->vport_gvmi); &vport_caps->vport_gvmi);
if (ret) if (ret)
return ret; return ret;
...@@ -176,9 +165,15 @@ static int dr_domain_query_esw_mngr(struct mlx5dr_domain *dmn) ...@@ -176,9 +165,15 @@ static int dr_domain_query_esw_mngr(struct mlx5dr_domain *dmn)
{ {
return dr_domain_query_vport(dmn, return dr_domain_query_vport(dmn,
dmn->info.caps.is_ecpf ? MLX5_VPORT_ECPF : 0, dmn->info.caps.is_ecpf ? MLX5_VPORT_ECPF : 0,
false,
&dmn->info.caps.vports.esw_manager_caps); &dmn->info.caps.vports.esw_manager_caps);
} }
static void dr_domain_query_uplink(struct mlx5dr_domain *dmn)
{
dr_domain_fill_uplink_caps(dmn, &dmn->info.caps.vports.uplink_caps);
}
static struct mlx5dr_cmd_vport_cap * static struct mlx5dr_cmd_vport_cap *
dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
{ {
...@@ -190,7 +185,7 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) ...@@ -190,7 +185,7 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
if (!vport_caps) if (!vport_caps)
return NULL; return NULL;
ret = dr_domain_query_vport(dmn, vport, vport_caps); ret = dr_domain_query_vport(dmn, vport, true, vport_caps);
if (ret) { if (ret) {
kvfree(vport_caps); kvfree(vport_caps);
return NULL; return NULL;
...@@ -207,16 +202,26 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport) ...@@ -207,16 +202,26 @@ dr_domain_add_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
return vport_caps; return vport_caps;
} }
static bool dr_domain_is_esw_mgr_vport(struct mlx5dr_domain *dmn, u16 vport)
{
struct mlx5dr_cmd_caps *caps = &dmn->info.caps;
return (caps->is_ecpf && vport == MLX5_VPORT_ECPF) ||
(!caps->is_ecpf && vport == 0);
}
struct mlx5dr_cmd_vport_cap * struct mlx5dr_cmd_vport_cap *
mlx5dr_domain_get_vport_cap(struct mlx5dr_domain *dmn, u16 vport) mlx5dr_domain_get_vport_cap(struct mlx5dr_domain *dmn, u16 vport)
{ {
struct mlx5dr_cmd_caps *caps = &dmn->info.caps; struct mlx5dr_cmd_caps *caps = &dmn->info.caps;
struct mlx5dr_cmd_vport_cap *vport_caps; struct mlx5dr_cmd_vport_cap *vport_caps;
if ((caps->is_ecpf && vport == MLX5_VPORT_ECPF) || if (dr_domain_is_esw_mgr_vport(dmn, vport))
(!caps->is_ecpf && vport == 0))
return &caps->vports.esw_manager_caps; return &caps->vports.esw_manager_caps;
if (vport == MLX5_VPORT_UPLINK)
return &caps->vports.uplink_caps;
vport_load: vport_load:
vport_caps = xa_load(&caps->vports.vports_caps_xa, vport); vport_caps = xa_load(&caps->vports.vports_caps_xa, vport);
if (vport_caps) if (vport_caps)
...@@ -241,17 +246,6 @@ static void dr_domain_clear_vports(struct mlx5dr_domain *dmn) ...@@ -241,17 +246,6 @@ static void dr_domain_clear_vports(struct mlx5dr_domain *dmn)
} }
} }
static int dr_domain_query_uplink(struct mlx5dr_domain *dmn)
{
struct mlx5dr_cmd_vport_cap *vport_caps;
vport_caps = mlx5dr_domain_get_vport_cap(dmn, MLX5_VPORT_UPLINK);
if (!vport_caps)
return -EINVAL;
return 0;
}
static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev, static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev,
struct mlx5dr_domain *dmn) struct mlx5dr_domain *dmn)
{ {
...@@ -281,11 +275,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev, ...@@ -281,11 +275,7 @@ static int dr_domain_query_fdb_caps(struct mlx5_core_dev *mdev,
goto free_vports_caps_xa; goto free_vports_caps_xa;
} }
ret = dr_domain_query_uplink(dmn); dr_domain_query_uplink(dmn);
if (ret) {
mlx5dr_err(dmn, "Failed to query uplink vport caps (err: %d)", ret);
goto free_vports_caps_xa;
}
return 0; return 0;
......
...@@ -924,12 +924,13 @@ static int dr_matcher_init(struct mlx5dr_matcher *matcher, ...@@ -924,12 +924,13 @@ static int dr_matcher_init(struct mlx5dr_matcher *matcher,
/* Check that all mask data was consumed */ /* Check that all mask data was consumed */
for (i = 0; i < consumed_mask.match_sz; i++) { for (i = 0; i < consumed_mask.match_sz; i++) {
if (consumed_mask.match_buf[i]) { if (!((u8 *)consumed_mask.match_buf)[i])
continue;
mlx5dr_dbg(dmn, "Match param mask contains unsupported parameters\n"); mlx5dr_dbg(dmn, "Match param mask contains unsupported parameters\n");
ret = -EOPNOTSUPP; ret = -EOPNOTSUPP;
goto free_consumed_mask; goto free_consumed_mask;
} }
}
ret = 0; ret = 0;
free_consumed_mask: free_consumed_mask:
......
...@@ -764,6 +764,7 @@ struct mlx5dr_roce_cap { ...@@ -764,6 +764,7 @@ struct mlx5dr_roce_cap {
struct mlx5dr_vports { struct mlx5dr_vports {
struct mlx5dr_cmd_vport_cap esw_manager_caps; struct mlx5dr_cmd_vport_cap esw_manager_caps;
struct mlx5dr_cmd_vport_cap uplink_caps;
struct xarray vports_caps_xa; struct xarray vports_caps_xa;
}; };
......
...@@ -145,13 +145,13 @@ u32 mlx5_eswitch_get_vport_metadata_for_set(struct mlx5_eswitch *esw, ...@@ -145,13 +145,13 @@ u32 mlx5_eswitch_get_vport_metadata_for_set(struct mlx5_eswitch *esw,
GENMASK(31 - ESW_TUN_ID_BITS - ESW_RESERVED_BITS, \ GENMASK(31 - ESW_TUN_ID_BITS - ESW_RESERVED_BITS, \
ESW_TUN_OPTS_OFFSET + 1) ESW_TUN_OPTS_OFFSET + 1)
u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev); u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev);
u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev); u16 mlx5_eswitch_get_total_vports(const struct mlx5_core_dev *dev);
struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw); struct mlx5_core_dev *mlx5_eswitch_get_core_dev(struct mlx5_eswitch *esw);
#else /* CONFIG_MLX5_ESWITCH */ #else /* CONFIG_MLX5_ESWITCH */
static inline u8 mlx5_eswitch_mode(struct mlx5_core_dev *dev) static inline u8 mlx5_eswitch_mode(const struct mlx5_core_dev *dev)
{ {
return MLX5_ESWITCH_NONE; return MLX5_ESWITCH_NONE;
} }
......
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