Skip to content

Commit

Permalink
Merge tag 'mlx5-fixes-2019-03-29' of git://git.kernel.org/pub/scm/lin…
Browse files Browse the repository at this point in the history
…ux/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: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Mar 29, 2019
2 parents ec915f4 + 7f1a546 commit 19c8474
Show file tree
Hide file tree
Showing 10 changed files with 154 additions and 81 deletions.
3 changes: 0 additions & 3 deletions drivers/net/ethernet/mellanox/mlx5/core/en/port.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,6 @@ int mlx5_port_query_eth_proto(struct mlx5_core_dev *dev, u8 port, bool ext,
if (!eproto)
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);
if (err)
return err;
Expand Down
39 changes: 22 additions & 17 deletions drivers/net/ethernet/mellanox/mlx5/core/en/port_buffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -122,18 +122,19 @@ static int port_set_buffer(struct mlx5e_priv *priv,
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)
{
u32 speed;
u32 xoff;
int err;

err = mlx5e_port_linkspeed(priv->mdev, &speed);
if (err) {
mlx5_core_warn(priv->mdev, "cannot get port speed\n");
return 0;
}
if (err)
speed = SPEED_40000;
speed = max_t(u32, speed, SPEED_40000);

xoff = (301 + 216 * priv->dcbx.cable_len / 100) * speed / 1000 + 272 * mtu / 100;

Expand All @@ -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,
u32 xoff, unsigned int mtu)
u32 xoff, unsigned int max_mtu)
{
int i;

Expand All @@ -154,19 +155,20 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
}

if (port_buffer->buffer[i].size <
(xoff + mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
(xoff + max_mtu + (1 << MLX5E_BUFFER_CELL_SHIFT)))
return -ENOMEM;

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;
}

/**
* update_buffer_lossy()
* mtu: device's MTU
* max_mtu: netdev's max_mtu
* pfc_en: <input> current pfc configuration
* buffer: <input> current prio to buffer mapping
* xoff: <input> xoff value
Expand All @@ -183,7 +185,7 @@ static int update_xoff_threshold(struct mlx5e_port_buffer *port_buffer,
* Return 0 if no error.
* 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,
struct mlx5e_port_buffer *port_buffer,
bool *change)
Expand Down Expand Up @@ -220,7 +222,7 @@ static int update_buffer_lossy(unsigned int mtu,
}

if (changed) {
err = update_xoff_threshold(port_buffer, xoff, mtu);
err = update_xoff_threshold(port_buffer, xoff, max_mtu);
if (err)
return err;

Expand All @@ -230,6 +232,7 @@ static int update_buffer_lossy(unsigned int mtu,
return 0;
}

#define MINIMUM_MAX_MTU 9216
int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
u32 change, unsigned int mtu,
struct ieee_pfc *pfc,
Expand All @@ -241,20 +244,22 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
bool update_prio2buffer = false;
u8 buffer[MLX5E_MAX_PRIORITY];
bool update_buffer = false;
unsigned int max_mtu;
u32 total_used = 0;
u8 curr_pfc_en;
int err;
int i;

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);
if (err)
return err;

if (change & MLX5E_PORT_BUFFER_CABLE_LEN) {
update_buffer = true;
err = update_xoff_threshold(&port_buffer, xoff, mtu);
err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
if (err)
return err;
}
Expand All @@ -264,7 +269,7 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
if (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);
if (err)
return err;
Expand All @@ -276,8 +281,8 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
if (err)
return err;

err = update_buffer_lossy(mtu, curr_pfc_en, prio2buffer, xoff,
&port_buffer, &update_buffer);
err = update_buffer_lossy(max_mtu, curr_pfc_en, prio2buffer,
xoff, &port_buffer, &update_buffer);
if (err)
return err;
}
Expand All @@ -301,15 +306,15 @@ int mlx5e_port_manual_buffer_config(struct mlx5e_priv *priv,
return -EINVAL;

update_buffer = true;
err = update_xoff_threshold(&port_buffer, xoff, mtu);
err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
if (err)
return err;
}

/* Need to update buffer configuration if xoff value is changed */
if (!update_buffer && xoff != priv->dcbx.xoff) {
update_buffer = true;
err = update_xoff_threshold(&port_buffer, xoff, mtu);
err = update_xoff_threshold(&port_buffer, xoff, max_mtu);
if (err)
return err;
}
Expand Down
13 changes: 11 additions & 2 deletions drivers/net/ethernet/mellanox/mlx5/core/en_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,16 +45,20 @@ int mlx5e_create_tir(struct mlx5_core_dev *mdev,
if (err)
return err;

mutex_lock(&mdev->mlx5e_res.td.list_lock);
list_add(&tir->list, &mdev->mlx5e_res.td.tirs_list);
mutex_unlock(&mdev->mlx5e_res.td.list_lock);

return 0;
}

void mlx5e_destroy_tir(struct mlx5_core_dev *mdev,
struct mlx5e_tir *tir)
{
mutex_lock(&mdev->mlx5e_res.td.list_lock);
mlx5_core_destroy_tir(mdev, tir->tirn);
list_del(&tir->list);
mutex_unlock(&mdev->mlx5e_res.td.list_lock);
}

static int mlx5e_create_mkey(struct mlx5_core_dev *mdev, u32 pdn,
Expand Down Expand Up @@ -114,6 +118,7 @@ int mlx5e_create_mdev_resources(struct mlx5_core_dev *mdev)
}

INIT_LIST_HEAD(&mdev->mlx5e_res.td.tirs_list);
mutex_init(&mdev->mlx5e_res.td.list_lock);

return 0;

Expand Down Expand Up @@ -141,22 +146,25 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
{
struct mlx5_core_dev *mdev = priv->mdev;
struct mlx5e_tir *tir;
int err = -ENOMEM;
int err = 0;
u32 tirn = 0;
int inlen;
void *in;

inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
in = kvzalloc(inlen, GFP_KERNEL);
if (!in)
if (!in) {
err = -ENOMEM;
goto out;
}

if (enable_uc_lb)
MLX5_SET(modify_tir_in, in, ctx.self_lb_block,
MLX5_TIRC_SELF_LB_BLOCK_BLOCK_UNICAST);

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) {
tirn = tir->tirn;
err = mlx5_core_modify_tir(mdev, tirn, in, inlen);
Expand All @@ -168,6 +176,7 @@ int mlx5e_refresh_tirs(struct mlx5e_priv *priv, bool enable_uc_lb)
kvfree(in);
if (err)
netdev_err(priv->netdev, "refresh tir(0x%x) failed, %d\n", tirn, err);
mutex_unlock(&mdev->mlx5e_res.td.list_lock);

return err;
}
Expand Down
52 changes: 34 additions & 18 deletions drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -603,16 +603,18 @@ static void ptys2ethtool_supported_link(struct mlx5_core_dev *mdev,
__ETHTOOL_LINK_MODE_MASK_NBITS);
}

static void ptys2ethtool_adver_link(struct mlx5_core_dev *mdev,
unsigned long *advertising_modes,
u32 eth_proto_cap)
static void ptys2ethtool_adver_link(unsigned long *advertising_modes,
u32 eth_proto_cap, bool ext)
{
unsigned long proto_cap = eth_proto_cap;
struct ptys2ethtool_config *table;
u32 max_size;
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)
bitmap_or(advertising_modes, advertising_modes,
table[proto].advertised,
Expand Down Expand Up @@ -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);
}

static void get_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_cap,
u8 tx_pause, u8 rx_pause,
struct ethtool_link_ksettings *link_ksettings)
static void get_advertising(u32 eth_proto_cap, u8 tx_pause, u8 rx_pause,
struct ethtool_link_ksettings *link_ksettings,
bool ext)
{
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)
ethtool_link_ksettings_add_link_mode(link_ksettings, advertising, Pause);
Expand Down Expand Up @@ -854,8 +856,9 @@ static void get_lp_advertising(struct mlx5_core_dev *mdev, u32 eth_proto_lp,
struct ethtool_link_ksettings *link_ksettings)
{
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,
Expand All @@ -872,6 +875,7 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
u8 an_disable_admin;
u8 an_status;
u8 connector_type;
bool admin_ext;
bool ext;
int err;

Expand All @@ -886,6 +890,19 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
eth_proto_capability);
eth_proto_admin = MLX5_GET_ETH_PROTO(ptys_reg, out, ext,
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);
eth_proto_lp = MLX5_GET(ptys_reg, out, eth_proto_lp_advertise);
Expand All @@ -899,7 +916,8 @@ int mlx5e_ethtool_get_link_ksettings(struct mlx5e_priv *priv,
ethtool_link_ksettings_zero_link_mode(link_ksettings, advertising);

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);

eth_proto_oper = eth_proto_oper ? eth_proto_oper : eth_proto_cap;
Expand Down Expand Up @@ -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)

ext_requested = (link_ksettings->link_modes.advertising[0] >
MLX5E_PTYS_EXT);
ext_requested = !!(link_ksettings->link_modes.advertising[0] >
MLX5E_PTYS_EXT ||
link_ksettings->link_modes.advertising[1]);
ext_supported = MLX5_CAP_PCAM_FEATURE(mdev, ptys_extended_ethernet);

/*when ptys_extended_ethernet is set legacy link modes are deprecated */
if (ext_requested != ext_supported)
return -EPROTONOSUPPORT;
ext_requested &= ext_supported;

speed = link_ksettings->base.speed;
ethtool2ptys_adver_func = ext_requested ?
mlx5e_ethtool2ptys_ext_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) {
netdev_err(priv->netdev, "%s: query port eth proto failed: %d\n",
__func__, err);
Expand Down Expand Up @@ -1037,7 +1053,7 @@ int mlx5e_ethtool_set_link_ksettings(struct mlx5e_priv *priv,
if (!an_changes && link_modes == eproto.admin)
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);

out:
Expand Down
Loading

0 comments on commit 19c8474

Please sign in to comment.