mlx5-fixes-2020-07-28
-----BEGIN PGP SIGNATURE----- iQEzBAABCAAdFiEEGhZs6bAKwk/OTgTpSD+KveBX+j4FAl8ggswACgkQSD+KveBX +j7yOgf8DjzPtSpVfUA7Iq28WO6YxJy208oUdLjKNuRNr74vXulHegNlP6cFDHU3 QIddvTBNMTp2BpJpoFMbEod7sVTBq5KVQZvpIuFM2JU4h76vL4cYbWeBuT6rFIoJ m5vuuUyAB+16QbJzagY/rqfQMs0w7KnR+Zhv18JzwyHhBiRLaPzYdmSWM2kkF8HZ 3DrY8RWgkeaI9vTpE6Fau7BRNDUOMgjIahiUrojJuyPsYZpJf5g+KaMj4xvgcqMa vaPaw8iHN7+N3KIdcf6MJhfzx3SHP5YNieU/MfvE9sLvdPvfLETdpexYPB8b0/vs L9w2D8j0uZyXek30fIiIwHaibQGZPw== =W0Fn -----END PGP SIGNATURE----- Merge tag 'mlx5-fixes-2020-07-28' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux Saeed Mahameed says: ==================== mlx5 fixes-2020-07-28 This series introduces some fixes to mlx5 driver. v1->v2: - Drop the "Hold reference on mirred devices" patch, until Or's comments are addressed. - Imporve "Modify uplink state" patch commit message per Or's request. Please pull and let me know if there is any problem. For -Stable: For -stable v4.9 ('net/mlx5e: Fix error path of device attach') For -stable v4.15 ('net/mlx5: Verify Hardware supports requested ptp function on a given pin') For -stable v5.3 ('net/mlx5e: Modify uplink state on interface up/down') For -stable v5.4 ('net/mlx5e: Fix kernel crash when setting vf VLANID on a VF dev') ('net/mlx5: E-switch, Destroy TSAR when fail to enable the mode') For -stable v5.5 ('net/mlx5: E-switch, Destroy TSAR after reload interface') For -stable v5.7 ('net/mlx5: Fix a bug of using ptp channel index as pin index') ==================== Acked-by: Jakub Kicinski <kuba@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Коммит
b5cd55b334
|
@ -183,13 +183,16 @@ void mlx5e_rep_bond_unslave(struct mlx5_eswitch *esw,
|
|||
|
||||
static bool mlx5e_rep_is_lag_netdev(struct net_device *netdev)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
struct mlx5e_rep_priv *rpriv = priv->ppriv;
|
||||
struct mlx5e_rep_priv *rpriv;
|
||||
struct mlx5e_priv *priv;
|
||||
|
||||
/* A given netdev is not a representor or not a slave of LAG configuration */
|
||||
if (!mlx5e_eswitch_rep(netdev) || !bond_slave_get_rtnl(netdev))
|
||||
return false;
|
||||
|
||||
priv = netdev_priv(netdev);
|
||||
rpriv = priv->ppriv;
|
||||
|
||||
/* Egress acl forward to vport is supported only non-uplink representor */
|
||||
return rpriv->rep->vport != MLX5_VPORT_UPLINK;
|
||||
}
|
||||
|
|
|
@ -3069,6 +3069,25 @@ void mlx5e_timestamp_init(struct mlx5e_priv *priv)
|
|||
priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE;
|
||||
}
|
||||
|
||||
static void mlx5e_modify_admin_state(struct mlx5_core_dev *mdev,
|
||||
enum mlx5_port_status state)
|
||||
{
|
||||
struct mlx5_eswitch *esw = mdev->priv.eswitch;
|
||||
int vport_admin_state;
|
||||
|
||||
mlx5_set_port_admin_status(mdev, state);
|
||||
|
||||
if (!MLX5_ESWITCH_MANAGER(mdev) || mlx5_eswitch_mode(esw) == MLX5_ESWITCH_OFFLOADS)
|
||||
return;
|
||||
|
||||
if (state == MLX5_PORT_UP)
|
||||
vport_admin_state = MLX5_VPORT_ADMIN_STATE_AUTO;
|
||||
else
|
||||
vport_admin_state = MLX5_VPORT_ADMIN_STATE_DOWN;
|
||||
|
||||
mlx5_eswitch_set_vport_state(esw, MLX5_VPORT_UPLINK, vport_admin_state);
|
||||
}
|
||||
|
||||
int mlx5e_open_locked(struct net_device *netdev)
|
||||
{
|
||||
struct mlx5e_priv *priv = netdev_priv(netdev);
|
||||
|
@ -3101,7 +3120,7 @@ int mlx5e_open(struct net_device *netdev)
|
|||
mutex_lock(&priv->state_lock);
|
||||
err = mlx5e_open_locked(netdev);
|
||||
if (!err)
|
||||
mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
|
||||
mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_UP);
|
||||
mutex_unlock(&priv->state_lock);
|
||||
|
||||
return err;
|
||||
|
@ -3135,7 +3154,7 @@ int mlx5e_close(struct net_device *netdev)
|
|||
return -ENODEV;
|
||||
|
||||
mutex_lock(&priv->state_lock);
|
||||
mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN);
|
||||
mlx5e_modify_admin_state(priv->mdev, MLX5_PORT_DOWN);
|
||||
err = mlx5e_close_locked(netdev);
|
||||
mutex_unlock(&priv->state_lock);
|
||||
|
||||
|
@ -5182,7 +5201,7 @@ static void mlx5e_nic_enable(struct mlx5e_priv *priv)
|
|||
|
||||
/* Marking the link as currently not needed by the Driver */
|
||||
if (!netif_running(netdev))
|
||||
mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);
|
||||
mlx5e_modify_admin_state(mdev, MLX5_PORT_DOWN);
|
||||
|
||||
mlx5e_set_netdev_mtu_boundaries(priv);
|
||||
mlx5e_set_dev_port_mtu(priv);
|
||||
|
@ -5390,6 +5409,8 @@ err_cleanup_tx:
|
|||
profile->cleanup_tx(priv);
|
||||
|
||||
out:
|
||||
set_bit(MLX5E_STATE_DESTROYING, &priv->state);
|
||||
cancel_work_sync(&priv->update_stats_work);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
|
|
@ -936,6 +936,7 @@ err_close_drop_rq:
|
|||
|
||||
static void mlx5e_cleanup_rep_rx(struct mlx5e_priv *priv)
|
||||
{
|
||||
mlx5e_ethtool_cleanup_steering(priv);
|
||||
rep_vport_rx_rule_destroy(priv);
|
||||
mlx5e_destroy_rep_root_ft(priv);
|
||||
mlx5e_destroy_ttc_table(priv, &priv->fs.ttc);
|
||||
|
@ -1080,6 +1081,8 @@ static void mlx5e_uplink_rep_enable(struct mlx5e_priv *priv)
|
|||
|
||||
mlx5e_rep_tc_enable(priv);
|
||||
|
||||
mlx5_modify_vport_admin_state(mdev, MLX5_VPORT_STATE_OP_MOD_UPLINK,
|
||||
0, 0, MLX5_VPORT_ADMIN_STATE_AUTO);
|
||||
mlx5_lag_add(mdev, netdev);
|
||||
priv->events_nb.notifier_call = uplink_rep_async_event;
|
||||
mlx5_notifier_register(mdev, &priv->events_nb);
|
||||
|
|
|
@ -1608,7 +1608,7 @@ abort:
|
|||
mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
|
||||
mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_ETH);
|
||||
}
|
||||
|
||||
esw_destroy_tsar(esw);
|
||||
return err;
|
||||
}
|
||||
|
||||
|
@ -1653,8 +1653,6 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf)
|
|||
else if (esw->mode == MLX5_ESWITCH_OFFLOADS)
|
||||
esw_offloads_disable(esw);
|
||||
|
||||
esw_destroy_tsar(esw);
|
||||
|
||||
old_mode = esw->mode;
|
||||
esw->mode = MLX5_ESWITCH_NONE;
|
||||
|
||||
|
@ -1664,6 +1662,8 @@ void mlx5_eswitch_disable_locked(struct mlx5_eswitch *esw, bool clear_vf)
|
|||
mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_IB);
|
||||
mlx5_reload_interface(esw->dev, MLX5_INTERFACE_PROTOCOL_ETH);
|
||||
}
|
||||
esw_destroy_tsar(esw);
|
||||
|
||||
if (clear_vf)
|
||||
mlx5_eswitch_clear_vf_vports_info(esw);
|
||||
}
|
||||
|
@ -1826,6 +1826,8 @@ int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
|
|||
u16 vport, int link_state)
|
||||
{
|
||||
struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
|
||||
int opmod = MLX5_VPORT_STATE_OP_MOD_ESW_VPORT;
|
||||
int other_vport = 1;
|
||||
int err = 0;
|
||||
|
||||
if (!ESW_ALLOWED(esw))
|
||||
|
@ -1833,15 +1835,17 @@ int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw,
|
|||
if (IS_ERR(evport))
|
||||
return PTR_ERR(evport);
|
||||
|
||||
if (vport == MLX5_VPORT_UPLINK) {
|
||||
opmod = MLX5_VPORT_STATE_OP_MOD_UPLINK;
|
||||
other_vport = 0;
|
||||
vport = 0;
|
||||
}
|
||||
mutex_lock(&esw->state_lock);
|
||||
|
||||
err = mlx5_modify_vport_admin_state(esw->dev,
|
||||
MLX5_VPORT_STATE_OP_MOD_ESW_VPORT,
|
||||
vport, 1, link_state);
|
||||
err = mlx5_modify_vport_admin_state(esw->dev, opmod, vport, other_vport, link_state);
|
||||
if (err) {
|
||||
mlx5_core_warn(esw->dev,
|
||||
"Failed to set vport %d link state, err = %d",
|
||||
vport, err);
|
||||
mlx5_core_warn(esw->dev, "Failed to set vport %d link state, opmod = %d, err = %d",
|
||||
vport, opmod, err);
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
|
@ -1883,8 +1887,6 @@ int __mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
|
|||
struct mlx5_vport *evport = mlx5_eswitch_get_vport(esw, vport);
|
||||
int err = 0;
|
||||
|
||||
if (!ESW_ALLOWED(esw))
|
||||
return -EPERM;
|
||||
if (IS_ERR(evport))
|
||||
return PTR_ERR(evport);
|
||||
if (vlan > 4095 || qos > 7)
|
||||
|
@ -1912,6 +1914,9 @@ int mlx5_eswitch_set_vport_vlan(struct mlx5_eswitch *esw,
|
|||
u8 set_flags = 0;
|
||||
int err;
|
||||
|
||||
if (!ESW_ALLOWED(esw))
|
||||
return -EPERM;
|
||||
|
||||
if (vlan || qos)
|
||||
set_flags = SET_VLAN_STRIP | SET_VLAN_INSERT;
|
||||
|
||||
|
|
|
@ -680,6 +680,8 @@ static inline int mlx5_eswitch_enable(struct mlx5_eswitch *esw, int num_vfs) { r
|
|||
static inline void mlx5_eswitch_disable(struct mlx5_eswitch *esw, bool clear_vf) {}
|
||||
static inline bool mlx5_esw_lag_prereq(struct mlx5_core_dev *dev0, struct mlx5_core_dev *dev1) { return true; }
|
||||
static inline bool mlx5_eswitch_is_funcs_handler(struct mlx5_core_dev *dev) { return false; }
|
||||
static inline
|
||||
int mlx5_eswitch_set_vport_state(struct mlx5_eswitch *esw, u16 vport, int link_state) { return 0; }
|
||||
static inline const u32 *mlx5_esw_query_functions(struct mlx5_core_dev *dev)
|
||||
{
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
|
|
|
@ -797,7 +797,7 @@ static struct mlx5_flow_table *find_closest_ft_recursive(struct fs_node *root,
|
|||
return ft;
|
||||
}
|
||||
|
||||
/* If reverse if false then return the first flow table in next priority of
|
||||
/* If reverse is false then return the first flow table in next priority of
|
||||
* prio in the tree, else return the last flow table in the previous priority
|
||||
* of prio in the tree.
|
||||
*/
|
||||
|
@ -829,34 +829,16 @@ static struct mlx5_flow_table *find_prev_chained_ft(struct fs_prio *prio)
|
|||
return find_closest_ft(prio, true);
|
||||
}
|
||||
|
||||
static struct fs_prio *find_fwd_ns_prio(struct mlx5_flow_root_namespace *root,
|
||||
struct mlx5_flow_namespace *ns)
|
||||
{
|
||||
struct mlx5_flow_namespace *root_ns = &root->ns;
|
||||
struct fs_prio *iter_prio;
|
||||
struct fs_prio *prio;
|
||||
|
||||
fs_get_obj(prio, ns->node.parent);
|
||||
list_for_each_entry(iter_prio, &root_ns->node.children, node.list) {
|
||||
if (iter_prio == prio &&
|
||||
!list_is_last(&prio->node.children, &iter_prio->node.list))
|
||||
return list_next_entry(iter_prio, node.list);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static struct mlx5_flow_table *find_next_fwd_ft(struct mlx5_flow_table *ft,
|
||||
struct mlx5_flow_act *flow_act)
|
||||
{
|
||||
struct mlx5_flow_root_namespace *root = find_root(&ft->node);
|
||||
struct fs_prio *prio;
|
||||
bool next_ns;
|
||||
|
||||
if (flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS)
|
||||
prio = find_fwd_ns_prio(root, ft->ns);
|
||||
else
|
||||
fs_get_obj(prio, ft->node.parent);
|
||||
next_ns = flow_act->action & MLX5_FLOW_CONTEXT_ACTION_FWD_NEXT_NS;
|
||||
fs_get_obj(prio, next_ns ? ft->ns->node.parent : ft->node.parent);
|
||||
|
||||
return (prio) ? find_next_chained_ft(prio) : NULL;
|
||||
return find_next_chained_ft(prio);
|
||||
}
|
||||
|
||||
static int connect_fts_in_prio(struct mlx5_core_dev *dev,
|
||||
|
|
|
@ -273,17 +273,17 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp,
|
|||
if (rq->extts.index >= clock->ptp_info.n_pins)
|
||||
return -EINVAL;
|
||||
|
||||
pin = ptp_find_pin(clock->ptp, PTP_PF_EXTTS, rq->extts.index);
|
||||
if (pin < 0)
|
||||
return -EBUSY;
|
||||
|
||||
if (on) {
|
||||
pin = ptp_find_pin(clock->ptp, PTP_PF_EXTTS, rq->extts.index);
|
||||
if (pin < 0)
|
||||
return -EBUSY;
|
||||
pin_mode = MLX5_PIN_MODE_IN;
|
||||
pattern = !!(rq->extts.flags & PTP_FALLING_EDGE);
|
||||
field_select = MLX5_MTPPS_FS_PIN_MODE |
|
||||
MLX5_MTPPS_FS_PATTERN |
|
||||
MLX5_MTPPS_FS_ENABLE;
|
||||
} else {
|
||||
pin = rq->extts.index;
|
||||
field_select = MLX5_MTPPS_FS_ENABLE;
|
||||
}
|
||||
|
||||
|
@ -331,12 +331,12 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
|
|||
if (rq->perout.index >= clock->ptp_info.n_pins)
|
||||
return -EINVAL;
|
||||
|
||||
if (on) {
|
||||
pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT,
|
||||
rq->perout.index);
|
||||
if (pin < 0)
|
||||
return -EBUSY;
|
||||
pin = ptp_find_pin(clock->ptp, PTP_PF_PEROUT,
|
||||
rq->perout.index);
|
||||
if (pin < 0)
|
||||
return -EBUSY;
|
||||
|
||||
if (on) {
|
||||
pin_mode = MLX5_PIN_MODE_OUT;
|
||||
pattern = MLX5_OUT_PATTERN_PERIODIC;
|
||||
ts.tv_sec = rq->perout.period.sec;
|
||||
|
@ -362,7 +362,6 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp,
|
|||
MLX5_MTPPS_FS_ENABLE |
|
||||
MLX5_MTPPS_FS_TIME_STAMP;
|
||||
} else {
|
||||
pin = rq->perout.index;
|
||||
field_select = MLX5_MTPPS_FS_ENABLE;
|
||||
}
|
||||
|
||||
|
@ -409,10 +408,31 @@ static int mlx5_ptp_enable(struct ptp_clock_info *ptp,
|
|||
return 0;
|
||||
}
|
||||
|
||||
enum {
|
||||
MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_IN = BIT(0),
|
||||
MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_OUT = BIT(1),
|
||||
};
|
||||
|
||||
static int mlx5_ptp_verify(struct ptp_clock_info *ptp, unsigned int pin,
|
||||
enum ptp_pin_function func, unsigned int chan)
|
||||
{
|
||||
return (func == PTP_PF_PHYSYNC) ? -EOPNOTSUPP : 0;
|
||||
struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock,
|
||||
ptp_info);
|
||||
|
||||
switch (func) {
|
||||
case PTP_PF_NONE:
|
||||
return 0;
|
||||
case PTP_PF_EXTTS:
|
||||
return !(clock->pps_info.pin_caps[pin] &
|
||||
MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_IN);
|
||||
case PTP_PF_PEROUT:
|
||||
return !(clock->pps_info.pin_caps[pin] &
|
||||
MLX5_MTPPS_REG_CAP_PIN_X_MODE_SUPPORT_PPS_OUT);
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static const struct ptp_clock_info mlx5_ptp_clock_info = {
|
||||
|
@ -432,6 +452,38 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = {
|
|||
.verify = NULL,
|
||||
};
|
||||
|
||||
static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin,
|
||||
u32 *mtpps, u32 mtpps_size)
|
||||
{
|
||||
u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {};
|
||||
|
||||
MLX5_SET(mtpps_reg, in, pin, pin);
|
||||
|
||||
return mlx5_core_access_reg(mdev, in, sizeof(in), mtpps,
|
||||
mtpps_size, MLX5_REG_MTPPS, 0, 0);
|
||||
}
|
||||
|
||||
static int mlx5_get_pps_pin_mode(struct mlx5_clock *clock, u8 pin)
|
||||
{
|
||||
struct mlx5_core_dev *mdev = clock->mdev;
|
||||
u32 out[MLX5_ST_SZ_DW(mtpps_reg)] = {};
|
||||
u8 mode;
|
||||
int err;
|
||||
|
||||
err = mlx5_query_mtpps_pin_mode(mdev, pin, out, sizeof(out));
|
||||
if (err || !MLX5_GET(mtpps_reg, out, enable))
|
||||
return PTP_PF_NONE;
|
||||
|
||||
mode = MLX5_GET(mtpps_reg, out, pin_mode);
|
||||
|
||||
if (mode == MLX5_PIN_MODE_IN)
|
||||
return PTP_PF_EXTTS;
|
||||
else if (mode == MLX5_PIN_MODE_OUT)
|
||||
return PTP_PF_PEROUT;
|
||||
|
||||
return PTP_PF_NONE;
|
||||
}
|
||||
|
||||
static int mlx5_init_pin_config(struct mlx5_clock *clock)
|
||||
{
|
||||
int i;
|
||||
|
@ -451,8 +503,8 @@ static int mlx5_init_pin_config(struct mlx5_clock *clock)
|
|||
sizeof(clock->ptp_info.pin_config[i].name),
|
||||
"mlx5_pps%d", i);
|
||||
clock->ptp_info.pin_config[i].index = i;
|
||||
clock->ptp_info.pin_config[i].func = PTP_PF_NONE;
|
||||
clock->ptp_info.pin_config[i].chan = i;
|
||||
clock->ptp_info.pin_config[i].func = mlx5_get_pps_pin_mode(clock, i);
|
||||
clock->ptp_info.pin_config[i].chan = 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -4381,6 +4381,7 @@ struct mlx5_ifc_query_vport_state_out_bits {
|
|||
enum {
|
||||
MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT = 0x0,
|
||||
MLX5_VPORT_STATE_OP_MOD_ESW_VPORT = 0x1,
|
||||
MLX5_VPORT_STATE_OP_MOD_UPLINK = 0x2,
|
||||
};
|
||||
|
||||
struct mlx5_ifc_arm_monitor_counter_in_bits {
|
||||
|
|
Загрузка…
Ссылка в новой задаче