Commit 19c84744 authored by David S. Miller's avatar David S. Miller

Merge tag 'mlx5-fixes-2019-03-29' of git://git.kernel.org/pub/scm/linux/kernel/git/saeed/linux

Saeed Mahameed says:

====================
Mellanox, mlx5 fixes 2019-03-29

This series introduces some fixes to mlx5 driver.

Please pull and let me know if there is any problem.

For -stable v4.11
('net/mlx5: Decrease default mr cache size')

For -stable v4.12
('net/mlx5e: Add a lock on tir list')

For -stable v4.13
('net/mlx5e: Fix error handling when refreshing TIRs')

For -stable v4.18
('net/mlx5e: Update xon formula')

For -stable v4.19
('net: mlx5: Add a missing check on idr_find, free buf')
('net/mlx5e: Update xoff formula')

net-next merge Note:
When merged with net-next the following simple conflict will appear,

drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c

++<<<<<<< HEAD (net)
 + *   max_mtu: netdev's max_mtu
++=======
+  *    @mtu: device's MTU
++>>>>>>> net-next

To resolve: just replace the line in net-next
*    @mtu: device's MTU
to
*    @max_mtu: netdev's max_mtu
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents ec915f47 7f1a546e
...@@ -96,9 +96,6 @@ int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext, ...@@ -96,9 +96,6 @@ int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
if (!eproto) if (!eproto)
return -EINVAL; return -EINVAL;
if (ext != MLX5_CAP_PCAM_FEATURE(dev, ptys_extended_ethernet))
return -EOPNOTSUPP;
err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port); err = mlx5_query_port_ptys(dev, out, sizeof(out), MLX5_PTYS_EN, port);
if (err) if (err)
return err; return err;
......
...@@ -122,7 +122,9 @@ static int port_set_buffer(struct mlx5e_priv *priv, ...@@ -122,7 +122,9 @@ static int port_set_buffer(struct mlx5e_priv *priv,
return err; return err;
} }
/* xoff = ((301+2.16 * len [m]) * speed [Gbps] + 2.72 MTU [B]) */ /* xoff = ((301+2.16 * len [m]) * speed [Gbps] + 2.72 MTU [B])
* minimum speed value is 40Gbps
*/
static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu) static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
{ {
u32 speed; u32 speed;
...@@ -130,10 +132,9 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu) ...@@ -130,10 +132,9 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
int err; int err;
err = mlx5e_port_linkspeed(priv->mdev, &speed); err = mlx5e_port_linkspeed(priv->mdev, &speed);
if (err) { if (err)
mlx5_core_warn(priv->mdev, "cannot get port speed\n"); speed = SPEED_40000;
return 0; speed = max_t(u32, speed, SPEED_40000);
}
xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100; xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100;
...@@ -142,7 +143,7 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu) ...@@ -142,7 +143,7 @@ static u32 calculate_xoff(struct mlx5e_priv *priv, unsigned int mtu)
} }
static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
u32 xoff, unsigned int mtu) u32 xoff, unsigned int max_mtu)
{ {
int i; int i;
...@@ -154,11 +155,12 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, ...@@ -154,11 +155,12 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
} }
if (port_buffer->buffer[i].size < if (port_buffer->buffer[i].size <
(xoff + mtu + (1 << MLX5E_BUFFER_CELL_SHIFT))) (xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
return -ENOMEM; return -ENOMEM;
port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff; port_buffer->buffer[i].xoff = port_buffer->buffer[i].size - xoff;
port_buffer->buffer[i].xon = port_buffer->buffer[i].xoff - mtu; port_buffer->buffer[i].xon =
port_buffer->buffer[i].xoff - max_mtu;
} }
return 0; return 0;
...@@ -166,7 +168,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, ...@@ -166,7 +168,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
/** /**
* update_buffer_lossy() * update_buffer_lossy()
* mtu: device's MTU * max_mtu: netdev's max_mtu
* pfc_en: <input> current pfc configuration * pfc_en: <input> current pfc configuration
* buffer: <input> current prio to buffer mapping * buffer: <input> current prio to buffer mapping
* xoff: <input> xoff value * xoff: <input> xoff value
...@@ -183,7 +185,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer, ...@@ -183,7 +185,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
* Return 0 if no error. * Return 0 if no error.
* Set change to true if buffer configuration is modified. * Set change to true if buffer configuration is modified.
*/ */
static int update_buffer_lossy(unsigned int mtu, static int update_buffer_lossy(unsigned int max_mtu,
u8 pfc_en, u8 *buffer, u32 xoff, u8 pfc_en, u8 *buffer, u32 xoff,
struct mlx5e_port_buffer *port_buffer, struct mlx5e_port_buffer *port_buffer,
bool *change) bool *change)
...@@ -220,7 +222,7 @@ static int update_buffer_lossy(unsigned int mtu, ...@@ -220,7 +222,7 @@ static int update_buffer_lossy(unsigned int mtu,
} }
if (changed) { if (changed) {
err = update_xoff_threshold(port_buffer, xoff, mtu); err = update_xoff_threshold(port_buffer, xoff, max_mtu);
if (err) if (err)
return err; return err;
...@@ -230,6 +232,7 @@ static int update_buffer_lossy(unsigned int mtu, ...@@ -230,6 +232,7 @@ static int update_buffer_lossy(unsigned int mtu,
return 0; return 0;
} }
#define MINIMUM_MAX_MTU 9216
int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
u32 change, unsigned int mtu, u32 change, unsigned int mtu,
struct ieee_pfc *pfc, struct ieee_pfc *pfc,
...@@ -241,12 +244,14 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, ...@@ -241,12 +244,14 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
bool update_prio2buffer = false; bool update_prio2buffer = false;
u8 buffer[MLX5E_MAX_PRIORITY]; u8 buffer[MLX5E_MAX_PRIORITY];
bool update_buffer = false; bool update_buffer = false;
unsigned int max_mtu;
u32 total_used = 0; u32 total_used = 0;
u8 curr_pfc_en; u8 curr_pfc_en;
int err; int err;
int i; int i;
mlx5e_dbg(HW, priv, "%s: change=%x\n", __func__, change); mlx5e_dbg(HW, priv, "%s: change=%x\n", __func__, change);
max_mtu = max_t(unsigned int, priv->netdev->max_mtu, MINIMUM_MAX_MTU);
err = mlx5e_port_query_buffer(priv, &port_buffer); err = mlx5e_port_query_buffer(priv, &port_buffer);
if (err) if (err)
...@@ -254,7 +259,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, ...@@ -254,7 +259,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
if (change & MLX5E_PORT_BUFFER_CABLE_LEN) { if (change & MLX5E_PORT_BUFFER_CABLE_LEN) {
update_buffer = true; update_buffer = true;
err = update_xoff_threshold(&port_buffer, xoff, mtu); err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
if (err) if (err)
return err; return err;
} }
...@@ -264,7 +269,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, ...@@ -264,7 +269,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
if (err) if (err)
return err; return err;
err = update_buffer_lossy(mtu, pfc->pfc_en, buffer, xoff, err = update_buffer_lossy(max_mtu, pfc->pfc_en, buffer, xoff,
&port_buffer, &update_buffer); &port_buffer, &update_buffer);
if (err) if (err)
return err; return err;
...@@ -276,8 +281,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, ...@@ -276,8 +281,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
if (err) if (err)
return err; return err;
err = update_buffer_lossy(mtu, curr_pfc_en, prio2buffer, xoff, err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer,
&port_buffer, &update_buffer); xoff, &port_buffer, &update_buffer);
if (err) if (err)
return err; return err;
} }
...@@ -301,7 +306,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, ...@@ -301,7 +306,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
return -EINVAL; return -EINVAL;
update_buffer = true; update_buffer = true;
err = update_xoff_threshold(&port_buffer, xoff, mtu); err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
if (err) if (err)
return err; return err;
} }
...@@ -309,7 +314,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv, ...@@ -309,7 +314,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
/* Need to update buffer configuration if xoff value is changed */ /* Need to update buffer configuration if xoff value is changed */
if (!update_buffer && xoff != priv->dcbx.xoff) { if (!update_buffer && xoff != priv->dcbx.xoff) {
update_buffer = true; update_buffer = true;
err = update_xoff_threshold(&port_buffer, xoff, mtu); err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
if (err) if (err)
return err; return err;
} }
......
...@@ -45,7 +45,9 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev, ...@@ -45,7 +45,9 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev,
if (err) if (err)
return err; return err;
mutex_lock(&mdev->mlx5e_res.td.list_lock);
list_add(&tir->list, &mdev->mlx5e_res.td.tirs_list); list_add(&tir->list, &mdev->mlx5e_res.td.tirs_list);
mutex_unlock(&mdev->mlx5e_res.td.list_lock);
return 0; return 0;
} }
...@@ -53,8 +55,10 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev, ...@@ -53,8 +55,10 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev,
void mlx5e_destroy_tir(struct mlx5_core_dev *mdev, void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
struct mlx5e_tir *tir) struct mlx5e_tir *tir)
{ {
mutex_lock(&mdev->mlx5e_res.td.list_lock);
mlx5_core_destroy_tir(mdev, tir->tirn); mlx5_core_destroy_tir(mdev, tir->tirn);
list_del(&tir->list); list_del(&tir->list);
mutex_unlock(&mdev->mlx5e_res.td.list_lock);
} }
static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn, static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
...@@ -114,6 +118,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev) ...@@ -114,6 +118,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev)
} }
INIT_LIST_HEAD(&mdev->mlx5e_res.td.tirs_list); INIT_LIST_HEAD(&mdev->mlx5e_res.td.tirs_list);
mutex_init(&mdev->mlx5e_res.td.list_lock);
return 0; return 0;
...@@ -141,15 +146,17 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) ...@@ -141,15 +146,17 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
{ {
struct mlx5_core_dev *mdev = priv->mdev; struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_tir *tir; struct mlx5e_tir *tir;
int err = -ENOMEM; int err = 0;
u32 tirn = 0; u32 tirn = 0;
int inlen; int inlen;
void *in; void *in;
inlen = MLX5_ST_SZ_BYTES(modify_tir_in); inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
in = kvzalloc(inlen, GFP_KERNEL); in = kvzalloc(inlen, GFP_KERNEL);
if (!in) if (!in) {
err = -ENOMEM;
goto out; goto out;
}
if (enable_uc_lb) if (enable_uc_lb)
MLX5_SET(modify_tir_in, in, ctx.self_lb_block, MLX5_SET(modify_tir_in, in, ctx.self_lb_block,
...@@ -157,6 +164,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) ...@@ -157,6 +164,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1); MLX5_SET(modify_tir_in, in, bitmask.self_lb_en, 1);
mutex_lock(&mdev->mlx5e_res.td.list_lock);
list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) { list_for_each_entry(tir, &mdev->mlx5e_res.td.tirs_list, list) {
tirn = tir->tirn; tirn = tir->tirn;
err = mlx5_core_modify_tir(mdev, tirn, in, inlen); err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
...@@ -168,6 +176,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb) ...@@ -168,6 +176,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
kvfree(in); kvfree(in);
if (err) if (err)
netdev_err(priv->netdev, "refresh tir(0x%x) failed, %d\n", tirn, err); netdev_err(priv->netdev, "refresh tir(0x%x) failed, %d\n", tirn, err);
mutex_unlock(&mdev->mlx5e_res.td.list_lock);
return err; return err;
} }
......
...@@ -603,16 +603,18 @@ static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev, ...@@ -603,16 +603,18 @@ static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
__ETHTOOL_LINK_MODE_MASK_NBITS); __ETHTOOL_LINK_MODE_MASK_NBITS);
} }
static void ptys2ethtool_adver_link(struct mlx5_core_dev *mdev, static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
unsigned long *advertising_modes, u32 eth_proto_cap, bool ext)
u32 eth_proto_cap)
{ {
unsigned long proto_cap = eth_proto_cap; unsigned long proto_cap = eth_proto_cap;
struct ptys2ethtool_config *table; struct ptys2ethtool_config *table;
u32 max_size; u32 max_size;
int proto; int proto;
mlx5e_ethtool_get_speed_arr(mdev, &table, &max_size); table = ext ? ptys2ext_ethtool_table : ptys2legacy_ethtool_table;
max_size = ext ? ARRAY_SIZE(ptys2ext_ethtool_table) :
ARRAY_SIZE(ptys2legacy_ethtool_table);
for_each_set_bit(proto, &proto_cap, max_size) for_each_set_bit(proto, &proto_cap, max_size)
bitmap_or(advertising_modes, advertising_modes, bitmap_or(advertising_modes, advertising_modes,
table[proto].advertised, table[proto].advertised,
...@@ -794,12 +796,12 @@ static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap, ...@@ -794,12 +796,12 @@ static void get_supported(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause); ethtool_link_ksettings_add_link_mode(link_ksettings, supported, Pause);
} }
static void get_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_cap, static void get_advertising(u32 eth_proto_cap, u8 tx_pause, u8 rx_pause,
u8 tx_pause, u8 rx_pause, struct ethtool_link_ksettings *link_ksettings,
struct ethtool_link_ksettings *link_ksettings) bool ext)
{ {
unsigned long *advertising = link_ksettings->link_modes.advertising; unsigned long *advertising = link_ksettings->link_modes.advertising;
ptys2ethtool_adver_link(mdev, advertising, eth_proto_cap); ptys2ethtool_adver_link(advertising, eth_proto_cap, ext);
if (rx_pause) if (rx_pause)
ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause); ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
...@@ -854,8 +856,9 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp, ...@@ -854,8 +856,9 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
struct ethtool_link_ksettings *link_ksettings) struct ethtool_link_ksettings *link_ksettings)
{ {
unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising; unsigned long *lp_advertising = link_ksettings->link_modes.lp_advertising;
bool ext = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
ptys2ethtool_adver_link(mdev, lp_advertising, eth_proto_lp); ptys2ethtool_adver_link(lp_advertising, eth_proto_lp, ext);
} }
int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
...@@ -872,6 +875,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, ...@@ -872,6 +875,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
u8 an_disable_admin; u8 an_disable_admin;
u8 an_status; u8 an_status;
u8 connector_type; u8 connector_type;
bool admin_ext;
bool ext; bool ext;
int err; int err;
...@@ -886,6 +890,19 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, ...@@ -886,6 +890,19 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
eth_proto_capability); eth_proto_capability);
eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
eth_proto_admin); eth_proto_admin);
/* Fields: eth_proto_admin and ext_eth_proto_admin are
* mutually exclusive. Hence try reading legacy advertising
* when extended advertising is zero.
* admin_ext indicates how eth_proto_admin should be
* interpreted
*/
admin_ext = ext;
if (ext && !eth_proto_admin) {
eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, false,
eth_proto_admin);
admin_ext = false;
}
eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext, eth_proto_oper = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
eth_proto_oper); eth_proto_oper);
eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise); eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
...@@ -899,7 +916,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv, ...@@ -899,7 +916,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising); ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);
get_supported(mdev, eth_proto_cap, link_ksettings); get_supported(mdev, eth_proto_cap, link_ksettings);
get_advertising(mdev, eth_proto_admin, tx_pause, rx_pause, link_ksettings); get_advertising(eth_proto_admin, tx_pause, rx_pause, link_ksettings,
admin_ext);
get_speed_duplex(priv->netdev, eth_proto_oper, link_ksettings); get_speed_duplex(priv->netdev, eth_proto_oper, link_ksettings);
eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap; eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
...@@ -997,19 +1015,17 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, ...@@ -997,19 +1015,17 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
#define MLX5E_PTYS_EXT ((1ULL << ETHTOOL_LINK_MODE_50000baseKR_Full_BIT) - 1) #define MLX5E_PTYS_EXT ((1ULL << ETHTOOL_LINK_MODE_50000baseKR_Full_BIT) - 1)
ext_requested = (link_ksettings->link_modes.advertising[0] > ext_requested = !!(link_ksettings->link_modes.advertising[0] >
MLX5E_PTYS_EXT); MLX5E_PTYS_EXT ||
link_ksettings->link_modes.advertising[1]);
ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet); ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);
ext_requested &= ext_supported;
/*when ptys_extended_ethernet is set legacy link modes are deprecated */
if (ext_requested != ext_supported)
return -EPROTONOSUPPORT;
speed = link_ksettings->base.speed; speed = link_ksettings->base.speed;
ethtool2ptys_adver_func = ext_requested ? ethtool2ptys_adver_func = ext_requested ?
mlx5e_ethtool2ptys_ext_adver_link : mlx5e_ethtool2ptys_ext_adver_link :
mlx5e_ethtool2ptys_adver_link; mlx5e_ethtool2ptys_adver_link;
err = mlx5_port_query_eth_proto(mdev, 1, ext_supported, &eproto); err = mlx5_port_query_eth_proto(mdev, 1, ext_requested, &eproto);
if (err) { if (err) {
netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n", netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
__func__, err); __func__, err);
...@@ -1037,7 +1053,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv, ...@@ -1037,7 +1053,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
if (!an_changes && link_modes == eproto.admin) if (!an_changes && link_modes == eproto.admin)
goto out; goto out;
mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext_supported); mlx5_port_set_eth_ptys(mdev, an_disable, link_modes, ext_requested);
mlx5_toggle_port_link(mdev); mlx5_toggle_port_link(mdev);
out: out:
......
...@@ -2158,6 +2158,52 @@ static bool csum_offload_supported(struct mlx5e_priv *priv, ...@@ -2158,6 +2158,52 @@ static bool csum_offload_supported(struct mlx5e_priv *priv,
return true; return true;
} }
struct ip_ttl_word {
__u8 ttl;
__u8 protocol;
__sum16 check;
};
struct ipv6_hoplimit_word {
__be16 payload_len;
__u8 nexthdr;
__u8 hop_limit;
};
static bool is_action_keys_supported(const struct flow_action_entry *act)
{
u32 mask, offset;
u8 htype;
htype = act->mangle.htype;
offset = act->mangle.offset;
mask = ~act->mangle.mask;
/* For IPv4 & IPv6 header check 4 byte word,
* to determine that modified fields
* are NOT ttl & hop_limit only.
*/
if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP4) {
struct ip_ttl_word *ttl_word =
(struct ip_ttl_word *)&mask;
if (offset != offsetof(struct iphdr, ttl) ||
ttl_word->protocol ||
ttl_word->check) {
return true;
}
} else if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) {
struct ipv6_hoplimit_word *hoplimit_word =
(struct ipv6_hoplimit_word *)&mask;
if (offset != offsetof(struct ipv6hdr, payload_len) ||
hoplimit_word->payload_len ||
hoplimit_word->nexthdr) {
return true;
}
}
return false;
}
static bool modify_header_match_supported(struct mlx5_flow_spec *spec, static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
struct flow_action *flow_action, struct flow_action *flow_action,
u32 actions, u32 actions,
...@@ -2165,9 +2211,9 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec, ...@@ -2165,9 +2211,9 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
{ {
const struct flow_action_entry *act; const struct flow_action_entry *act;
bool modify_ip_header; bool modify_ip_header;
u8 htype, ip_proto;
void *headers_v; void *headers_v;
u16 ethertype; u16 ethertype;
u8 ip_proto;
int i; int i;
if (actions & MLX5_FLOW_CONTEXT_ACTION_DECAP) if (actions & MLX5_FLOW_CONTEXT_ACTION_DECAP)
...@@ -2187,9 +2233,7 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec, ...@@ -2187,9 +2233,7 @@ static bool modify_header_match_supported(struct mlx5_flow_spec *spec,
act->id != FLOW_ACTION_ADD) act->id != FLOW_ACTION_ADD)
continue; continue;
htype = act->mangle.htype; if (is_action_keys_supported(act)) {
if (htype == FLOW_ACT_MANGLE_HDR_TYPE_IP4 ||
htype == FLOW_ACT_MANGLE_HDR_TYPE_IP6) {
modify_ip_header = true; modify_ip_header = true;
break; break;
} }
...@@ -2340,15 +2384,22 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv, ...@@ -2340,15 +2384,22 @@ static int parse_tc_nic_actions(struct mlx5e_priv *priv,
return 0; return 0;
} }
static inline int cmp_encap_info(struct ip_tunnel_key *a, struct encap_key {
struct ip_tunnel_key *b) struct ip_tunnel_key *ip_tun_key;
int tunnel_type;
};
static inline int cmp_encap_info(struct encap_key *a,
struct encap_key *b)
{ {
return memcmp(a, b, sizeof(*a)); return memcmp(a->ip_tun_key, b->ip_tun_key, sizeof(*a->ip_tun_key)) ||
a->tunnel_type != b->tunnel_type;
} }
static inline int hash_encap_info(struct ip_tunnel_key *key) static inline int hash_encap_info(struct encap_key *key)
{ {
return jhash(key, sizeof(*key), 0); return jhash(key->ip_tun_key, sizeof(*key->ip_tun_key),
key->tunnel_type);
} }
...@@ -2379,7 +2430,7 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -2379,7 +2430,7 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
struct mlx5_esw_flow_attr *attr = flow->esw_attr; struct mlx5_esw_flow_attr *attr = flow->esw_attr;
struct mlx5e_tc_flow_parse_attr *parse_attr; struct mlx5e_tc_flow_parse_attr *parse_attr;
struct ip_tunnel_info *tun_info; struct ip_tunnel_info *tun_info;
struct ip_tunnel_key *key; struct encap_key key, e_key;
struct mlx5e_encap_entry *e; struct mlx5e_encap_entry *e;
unsigned short family; unsigned short family;
uintptr_t hash_key; uintptr_t hash_key;
...@@ -2389,13 +2440,16 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv, ...@@ -2389,13 +2440,16 @@ static int mlx5e_attach_encap(struct mlx5e_priv *priv,
parse_attr = attr->parse_attr; parse_attr = attr->parse_attr;
tun_info = &parse_attr->tun_info[out_index]; tun_info = &parse_attr->tun_info[out_index];
family = ip_tunnel_info_af(tun_info); family = ip_tunnel_info_af(tun_info);
key = &tun_info->key; key.ip_tun_key = &tun_info->key;
key.tunnel_type = mlx5e_tc_tun_get_type(mirred_dev);
hash_key = hash_encap_info(key); hash_key = hash_encap_info(&key);
hash_for_each_possible_rcu(esw->offloads.encap_tbl, e, hash_for_each_possible_rcu(esw->offloads.encap_tbl, e,
encap_hlist, hash_key) { encap_hlist, hash_key) {
if (!cmp_encap_info(&e->tun_info.key, key)) { e_key.ip_tun_key = &e->tun_info.key;
e_key.tunnel_type = e->tunnel_type;
if (!cmp_encap_info(&e_key, &key)) {
found = true; found = true;
break; break;
} }
...@@ -2657,7 +2711,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv, ...@@ -2657,7 +2711,7 @@ static int parse_tc_fdb_actions(struct mlx5e_priv *priv,
if (hdrs[TCA_PEDIT_KEY_EX_CMD_SET].pedits || if (hdrs[TCA_PEDIT_KEY_EX_CMD_SET].pedits ||
hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].pedits) { hdrs[TCA_PEDIT_KEY_EX_CMD_ADD].pedits) {
err = alloc_tc_pedit_action(priv, MLX5_FLOW_NAMESPACE_KERNEL, err = alloc_tc_pedit_action(priv, MLX5_FLOW_NAMESPACE_FDB,
parse_attr, hdrs, extack); parse_attr, hdrs, extack);
if (err) if (err)
return err; return err;
......
...@@ -105,7 +105,6 @@ static int arm_vport_context_events_cmd(struct mlx5_core_dev *dev, u16 vport, ...@@ -105,7 +105,6 @@ static int arm_vport_context_events_cmd(struct mlx5_core_dev *dev, u16 vport,
opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT); opcode, MLX5_CMD_OP_MODIFY_NIC_VPORT_CONTEXT);
MLX5_SET(modify_nic_vport_context_in, in, field_select.change_event, 1); MLX5_SET(modify_nic_vport_context_in, in, field_select.change_event, 1);
MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport); MLX5_SET(modify_nic_vport_context_in, in, vport_number, vport);
if (vport)
MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1); MLX5_SET(modify_nic_vport_context_in, in, other_vport, 1);
nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in, nic_vport_ctx = MLX5_ADDR_OF(modify_nic_vport_context_in,
in, nic_vport_context); in, nic_vport_context);
...@@ -134,7 +133,6 @@ static int modify_esw_vport_context_cmd(struct mlx5_core_dev *dev, u16 vport, ...@@ -134,7 +133,6 @@ static int modify_esw_vport_context_cmd(struct mlx5_core_dev *dev, u16 vport,
MLX5_SET(modify_esw_vport_context_in, in, opcode, MLX5_SET(modify_esw_vport_context_in, in, opcode,
MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT); MLX5_CMD_OP_MODIFY_ESW_VPORT_CONTEXT);
MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport); MLX5_SET(modify_esw_vport_context_in, in, vport_number, vport);
if (vport)
MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1); MLX5_SET(modify_esw_vport_context_in, in, other_vport, 1);
return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out)); return mlx5_cmd_exec(dev, in, inlen, out, sizeof(out));
} }
...@@ -431,6 +429,8 @@ static int esw_create_legacy_table(struct mlx5_eswitch *esw) ...@@ -431,6 +429,8 @@ static int esw_create_legacy_table(struct mlx5_eswitch *esw)
{ {
int err; int err;
memset(&esw->fdb_table.legacy, 0, sizeof(struct legacy_fdb));
err = esw_create_legacy_vepa_table(esw); err = esw_create_legacy_vepa_table(esw);
if (err) if (err)
return err; return err;
...@@ -2157,6 +2157,7 @@ static int _mlx5_eswitch_set_vepa_locked(struct mlx5_eswitch *esw, ...@@ -2157,6 +2157,7 @@ static int _mlx5_eswitch_set_vepa_locked(struct mlx5_eswitch *esw,
/* Star rule to forward all traffic to uplink vport */ /* Star rule to forward all traffic to uplink vport */
memset(spec, 0, sizeof(*spec)); memset(spec, 0, sizeof(*spec));
memset(&dest, 0, sizeof(dest));
dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT; dest.type = MLX5_FLOW_DESTINATION_TYPE_VPORT;
dest.vport.num = MLX5_VPORT_UPLINK; dest.vport.num = MLX5_VPORT_UPLINK;
flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST; flow_act.action = MLX5_FLOW_CONTEXT_ACTION_FWD_DEST;
......
...@@ -1611,6 +1611,7 @@ static int esw_offloads_steering_init(struct mlx5_eswitch *esw, int nvports) ...@@ -1611,6 +1611,7 @@ static int esw_offloads_steering_init(struct mlx5_eswitch *esw, int nvports)
{ {
int err; int err;
memset(&esw->fdb_table.offloads, 0, sizeof(struct offloads_fdb));
mutex_init(&esw->fdb_table.offloads.fdb_prio_lock); mutex_init(&esw->fdb_table.offloads.fdb_prio_lock);
err = esw_create_offloads_fdb_tables(esw, nvports); err = esw_create_offloads_fdb_tables(esw, nvports);
......
...@@ -217,15 +217,21 @@ int mlx5_fpga_tls_resync_rx(struct mlx5_core_dev *mdev, u32 handle, u32 seq, ...@@ -217,15 +217,21 @@ int mlx5_fpga_tls_resync_rx(struct mlx5_core_dev *mdev, u32 handle, u32 seq,
void *cmd; void *cmd;
int ret; int ret;
rcu_read_lock();
flow = idr_find(&mdev->fpga->tls->rx_idr, ntohl(handle));
rcu_read_unlock();
if (!flow) {
WARN_ONCE(1, "Received NULL pointer for handle\n");
return -EINVAL;
}
buf = kzalloc(size, GFP_ATOMIC); buf = kzalloc(size, GFP_ATOMIC);
if (!buf) if (!buf)
return -ENOMEM; return -ENOMEM;
cmd = (buf + 1); cmd = (buf + 1);
rcu_read_lock();
flow = idr_find(&mdev->fpga->tls->rx_idr, ntohl(handle));
rcu_read_unlock();
mlx5_fpga_tls_flow_to_cmd(flow, cmd); mlx5_fpga_tls_flow_to_cmd(flow, cmd);
MLX5_SET(tls_cmd, cmd, swid, ntohl(handle)); MLX5_SET(tls_cmd, cmd, swid, ntohl(handle));
...@@ -238,6 +244,8 @@ int mlx5_fpga_tls_resync_rx(struct mlx5_core_dev *mdev, u32 handle, u32 seq, ...@@ -238,6 +244,8 @@ int mlx5_fpga_tls_resync_rx(struct mlx5_core_dev *mdev, u32 handle, u32 seq,
buf->complete = mlx_tls_kfree_complete; buf->complete = mlx_tls_kfree_complete;
ret = mlx5_fpga_sbu_conn_sendmsg(mdev->fpga->tls->conn, buf); ret = mlx5_fpga_sbu_conn_sendmsg(mdev->fpga->tls->conn, buf);
if (ret < 0)
kfree(buf);
return ret; return ret;
} }
......
...@@ -164,26 +164,6 @@ static struct mlx5_profile profile[] = { ...@@ -164,26 +164,6 @@ static struct mlx5_profile profile[] = {
.size = 8, .size = 8,
.limit = 4 .limit = 4
}, },
.mr_cache[16] = {
.size = 8,
.limit = 4
},
.mr_cache[17] = {
.size = 8,
.limit = 4
},
.mr_cache[18] = {
.size = 8,
.limit = 4
},
.mr_cache[19] = {
.size = 4,
.limit = 2
},
.mr_cache[20] = {
.size = 4,
.limit = 2
},
}, },
}; };
......
...@@ -594,6 +594,8 @@ enum mlx5_pagefault_type_flags { ...@@ -594,6 +594,8 @@ enum mlx5_pagefault_type_flags {
}; };
struct mlx5_td { struct mlx5_td {
/* protects tirs list changes while tirs refresh */
struct mutex list_lock;
struct list_head tirs_list; struct list_head tirs_list;
u32 tdn; u32 tdn;
}; };
......
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