lkml.org 
[lkml]   [2018]   [Apr]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 4.9 302/310] net/mlx4_en: Fix mixed PFC and Global pause user control requests
    Date
    4.9-stable review patch.  If anyone has any objections, please let me know.

    ------------------

    From: Eran Ben Elisha <eranbe@mellanox.com>


    [ Upstream commit 6e8814ceb7e8f468659ef9253bd212c07ae19584 ]

    Global pause and PFC configuration should be mutually exclusive (i.e. only
    one of them at most can be set). However, once PFC was turned off,
    driver automatically turned Global pause on. This is a bug.

    Fix the driver behaviour to turn off PFC/Global once the user turned the
    other on.

    This also fixed a weird behaviour that at a current time, the profile
    had both PFC and global pause configuration turned on, which is
    Hardware-wise impossible and caused returning false positive indication
    to query tools.

    In addition, fix error code when setting global pause or PFC to change
    metadata only upon successful change.

    Also, removed useless debug print.

    Fixes: af7d51852631 ("net/mlx4_en: Add DCB PFC support through CEE netlink commands")
    Fixes: c27a02cd94d6 ("mlx4_en: Add driver for Mellanox ConnectX 10GbE NIC")
    Signed-off-by: Eran Ben Elisha <eranbe@mellanox.com>
    Signed-off-by: Tariq Toukan <tariqt@mellanox.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c | 72 +++++++++++++-----------
    drivers/net/ethernet/mellanox/mlx4/en_ethtool.c | 33 ++++++-----
    drivers/net/ethernet/mellanox/mlx4/en_main.c | 4 -
    3 files changed, 62 insertions(+), 47 deletions(-)

    --- a/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
    +++ b/drivers/net/ethernet/mellanox/mlx4/en_dcb_nl.c
    @@ -156,57 +156,63 @@ static int mlx4_en_dcbnl_getnumtcs(struc
    static u8 mlx4_en_dcbnl_set_all(struct net_device *netdev)
    {
    struct mlx4_en_priv *priv = netdev_priv(netdev);
    + struct mlx4_en_port_profile *prof = priv->prof;
    struct mlx4_en_dev *mdev = priv->mdev;
    + u8 tx_pause, tx_ppp, rx_pause, rx_ppp;

    if (!(priv->dcbx_cap & DCB_CAP_DCBX_VER_CEE))
    return 1;

    if (priv->cee_config.pfc_state) {
    int tc;
    + rx_ppp = prof->rx_ppp;
    + tx_ppp = prof->tx_ppp;

    - priv->prof->rx_pause = 0;
    - priv->prof->tx_pause = 0;
    for (tc = 0; tc < CEE_DCBX_MAX_PRIO; tc++) {
    u8 tc_mask = 1 << tc;

    switch (priv->cee_config.dcb_pfc[tc]) {
    case pfc_disabled:
    - priv->prof->tx_ppp &= ~tc_mask;
    - priv->prof->rx_ppp &= ~tc_mask;
    + tx_ppp &= ~tc_mask;
    + rx_ppp &= ~tc_mask;
    break;
    case pfc_enabled_full:
    - priv->prof->tx_ppp |= tc_mask;
    - priv->prof->rx_ppp |= tc_mask;
    + tx_ppp |= tc_mask;
    + rx_ppp |= tc_mask;
    break;
    case pfc_enabled_tx:
    - priv->prof->tx_ppp |= tc_mask;
    - priv->prof->rx_ppp &= ~tc_mask;
    + tx_ppp |= tc_mask;
    + rx_ppp &= ~tc_mask;
    break;
    case pfc_enabled_rx:
    - priv->prof->tx_ppp &= ~tc_mask;
    - priv->prof->rx_ppp |= tc_mask;
    + tx_ppp &= ~tc_mask;
    + rx_ppp |= tc_mask;
    break;
    default:
    break;
    }
    }
    - en_dbg(DRV, priv, "Set pfc on\n");
    + rx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->rx_pause;
    + tx_pause = !!(rx_ppp || tx_ppp) ? 0 : prof->tx_pause;
    } else {
    - priv->prof->rx_pause = 1;
    - priv->prof->tx_pause = 1;
    - en_dbg(DRV, priv, "Set pfc off\n");
    + rx_ppp = 0;
    + tx_ppp = 0;
    + rx_pause = prof->rx_pause;
    + tx_pause = prof->tx_pause;
    }

    if (mlx4_SET_PORT_general(mdev->dev, priv->port,
    priv->rx_skb_size + ETH_FCS_LEN,
    - priv->prof->tx_pause,
    - priv->prof->tx_ppp,
    - priv->prof->rx_pause,
    - priv->prof->rx_ppp)) {
    + tx_pause, tx_ppp, rx_pause, rx_ppp)) {
    en_err(priv, "Failed setting pause params\n");
    return 1;
    }

    + prof->tx_ppp = tx_ppp;
    + prof->rx_ppp = rx_ppp;
    + prof->tx_pause = tx_pause;
    + prof->rx_pause = rx_pause;
    +
    return 0;
    }

    @@ -408,6 +414,7 @@ static int mlx4_en_dcbnl_ieee_setpfc(str
    struct mlx4_en_priv *priv = netdev_priv(dev);
    struct mlx4_en_port_profile *prof = priv->prof;
    struct mlx4_en_dev *mdev = priv->mdev;
    + u32 tx_pause, tx_ppp, rx_pause, rx_ppp;
    int err;

    en_dbg(DRV, priv, "cap: 0x%x en: 0x%x mbc: 0x%x delay: %d\n",
    @@ -416,23 +423,26 @@ static int mlx4_en_dcbnl_ieee_setpfc(str
    pfc->mbc,
    pfc->delay);

    - prof->rx_pause = !pfc->pfc_en;
    - prof->tx_pause = !pfc->pfc_en;
    - prof->rx_ppp = pfc->pfc_en;
    - prof->tx_ppp = pfc->pfc_en;
    + rx_pause = prof->rx_pause && !pfc->pfc_en;
    + tx_pause = prof->tx_pause && !pfc->pfc_en;
    + rx_ppp = pfc->pfc_en;
    + tx_ppp = pfc->pfc_en;

    err = mlx4_SET_PORT_general(mdev->dev, priv->port,
    priv->rx_skb_size + ETH_FCS_LEN,
    - prof->tx_pause,
    - prof->tx_ppp,
    - prof->rx_pause,
    - prof->rx_ppp);
    - if (err)
    + tx_pause, tx_ppp, rx_pause, rx_ppp);
    + if (err) {
    en_err(priv, "Failed setting pause params\n");
    - else
    - mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
    - prof->rx_ppp, prof->rx_pause,
    - prof->tx_ppp, prof->tx_pause);
    + return err;
    + }
    +
    + mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
    + rx_ppp, rx_pause, tx_ppp, tx_pause);
    +
    + prof->tx_ppp = tx_ppp;
    + prof->rx_ppp = rx_ppp;
    + prof->rx_pause = rx_pause;
    + prof->tx_pause = tx_pause;

    return err;
    }
    --- a/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
    +++ b/drivers/net/ethernet/mellanox/mlx4/en_ethtool.c
    @@ -1003,27 +1003,32 @@ static int mlx4_en_set_pauseparam(struct
    {
    struct mlx4_en_priv *priv = netdev_priv(dev);
    struct mlx4_en_dev *mdev = priv->mdev;
    + u8 tx_pause, tx_ppp, rx_pause, rx_ppp;
    int err;

    if (pause->autoneg)
    return -EINVAL;

    - priv->prof->tx_pause = pause->tx_pause != 0;
    - priv->prof->rx_pause = pause->rx_pause != 0;
    + tx_pause = !!(pause->tx_pause);
    + rx_pause = !!(pause->rx_pause);
    + rx_ppp = priv->prof->rx_ppp && !(tx_pause || rx_pause);
    + tx_ppp = priv->prof->tx_ppp && !(tx_pause || rx_pause);
    +
    err = mlx4_SET_PORT_general(mdev->dev, priv->port,
    priv->rx_skb_size + ETH_FCS_LEN,
    - priv->prof->tx_pause,
    - priv->prof->tx_ppp,
    - priv->prof->rx_pause,
    - priv->prof->rx_ppp);
    - if (err)
    - en_err(priv, "Failed setting pause params\n");
    - else
    - mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
    - priv->prof->rx_ppp,
    - priv->prof->rx_pause,
    - priv->prof->tx_ppp,
    - priv->prof->tx_pause);
    + tx_pause, tx_ppp, rx_pause, rx_ppp);
    + if (err) {
    + en_err(priv, "Failed setting pause params, err = %d\n", err);
    + return err;
    + }
    +
    + mlx4_en_update_pfc_stats_bitmap(mdev->dev, &priv->stats_bitmap,
    + rx_ppp, rx_pause, tx_ppp, tx_pause);
    +
    + priv->prof->tx_pause = tx_pause;
    + priv->prof->rx_pause = rx_pause;
    + priv->prof->tx_ppp = tx_ppp;
    + priv->prof->rx_ppp = rx_ppp;

    return err;
    }
    --- a/drivers/net/ethernet/mellanox/mlx4/en_main.c
    +++ b/drivers/net/ethernet/mellanox/mlx4/en_main.c
    @@ -163,9 +163,9 @@ static int mlx4_en_get_profile(struct ml
    params->udp_rss = 0;
    }
    for (i = 1; i <= MLX4_MAX_PORTS; i++) {
    - params->prof[i].rx_pause = 1;
    + params->prof[i].rx_pause = !(pfcrx || pfctx);
    params->prof[i].rx_ppp = pfcrx;
    - params->prof[i].tx_pause = 1;
    + params->prof[i].tx_pause = !(pfcrx || pfctx);
    params->prof[i].tx_ppp = pfctx;
    params->prof[i].tx_ring_size = MLX4_EN_DEF_TX_RING_SIZE;
    params->prof[i].rx_ring_size = MLX4_EN_DEF_RX_RING_SIZE;

    \
     
     \ /
      Last update: 2018-04-11 21:12    [W:4.103 / U:0.032 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site