net/mlx5e: Avoid reset netdev stats on configuration changes
[sfrench/cifs-2.6.git] / drivers / net / ethernet / mellanox / mlx5 / core / en_main.c
index a8b1e43384cadadf0ad2fc155ad73d4527475611..9b19863b059d2aeb20c4637bd246f70abfc25ed1 100644 (file)
@@ -423,6 +423,7 @@ static int mlx5e_alloc_rq(struct mlx5e_channel *c,
        rq->ix      = c->ix;
        rq->mdev    = mdev;
        rq->hw_mtu  = MLX5E_SW2HW_MTU(params, params->sw_mtu);
+       rq->stats   = &c->priv->channel_stats[c->ix].rq;
 
        rq->xdp_prog = params->xdp_prog ? bpf_prog_inc(params->xdp_prog) : NULL;
        if (IS_ERR(rq->xdp_prog)) {
@@ -646,8 +647,8 @@ static int mlx5e_create_rq(struct mlx5e_rq *rq,
                                                MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(wq, wq,  dbr_addr,           rq->wq_ctrl.db.dma);
 
-       mlx5_fill_page_array(&rq->wq_ctrl.buf,
-                            (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
+       mlx5_fill_page_frag_array(&rq->wq_ctrl.buf,
+                                 (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
 
        err = mlx5_core_create_rq(mdev, in, inlen, &rq->rqn);
 
@@ -1003,7 +1004,8 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
                             int txq_ix,
                             struct mlx5e_params *params,
                             struct mlx5e_sq_param *param,
-                            struct mlx5e_txqsq *sq)
+                            struct mlx5e_txqsq *sq,
+                            int tc)
 {
        void *sqc_wq               = MLX5_ADDR_OF(sqc, param->sqc, wq);
        struct mlx5_core_dev *mdev = c->mdev;
@@ -1018,6 +1020,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
        sq->txq_ix    = txq_ix;
        sq->uar_map   = mdev->mlx5e_res.bfreg.map;
        sq->min_inline_mode = params->tx_min_inline_mode;
+       sq->stats     = &c->priv->channel_stats[c->ix].sq[tc];
        INIT_WORK(&sq->recover.recover_work, mlx5e_sq_recover);
        if (MLX5_IPSEC_DEV(c->priv->mdev))
                set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
@@ -1096,7 +1099,8 @@ static int mlx5e_create_sq(struct mlx5_core_dev *mdev,
                                          MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(wq, wq, dbr_addr,      csp->wq_ctrl->db.dma);
 
-       mlx5_fill_page_array(&csp->wq_ctrl->buf, (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
+       mlx5_fill_page_frag_array(&csp->wq_ctrl->buf,
+                                 (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
 
        err = mlx5_core_create_sq(mdev, in, inlen, sqn);
 
@@ -1175,13 +1179,14 @@ static int mlx5e_open_txqsq(struct mlx5e_channel *c,
                            int txq_ix,
                            struct mlx5e_params *params,
                            struct mlx5e_sq_param *param,
-                           struct mlx5e_txqsq *sq)
+                           struct mlx5e_txqsq *sq,
+                           int tc)
 {
        struct mlx5e_create_sq_param csp = {};
        u32 tx_rate;
        int err;
 
-       err = mlx5e_alloc_txqsq(c, txq_ix, params, param, sq);
+       err = mlx5e_alloc_txqsq(c, txq_ix, params, param, sq, tc);
        if (err)
                return err;
 
@@ -1369,7 +1374,7 @@ static void mlx5e_sq_recover(struct work_struct *work)
                return;
 
        mlx5e_reset_txqsq_cc_pc(sq);
-       sq->stats.recover++;
+       sq->stats->recover++;
        recover->last_recover = jiffies;
        mlx5e_activate_txqsq(sq);
 }
@@ -1538,7 +1543,7 @@ static int mlx5e_alloc_cq(struct mlx5e_channel *c,
 
 static void mlx5e_free_cq(struct mlx5e_cq *cq)
 {
-       mlx5_cqwq_destroy(&cq->wq_ctrl);
+       mlx5_wq_destroy(&cq->wq_ctrl);
 }
 
 static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
@@ -1554,7 +1559,7 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
        int err;
 
        inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
-               sizeof(u64) * cq->wq_ctrl.frag_buf.npages;
+               sizeof(u64) * cq->wq_ctrl.buf.npages;
        in = kvzalloc(inlen, GFP_KERNEL);
        if (!in)
                return -ENOMEM;
@@ -1563,7 +1568,7 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
 
        memcpy(cqc, param->cqc, sizeof(param->cqc));
 
-       mlx5_fill_page_frag_array(&cq->wq_ctrl.frag_buf,
+       mlx5_fill_page_frag_array(&cq->wq_ctrl.buf,
                                  (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas));
 
        mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used);
@@ -1571,7 +1576,7 @@ static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
        MLX5_SET(cqc,   cqc, cq_period_mode, param->cq_period_mode);
        MLX5_SET(cqc,   cqc, c_eqn,         eqn);
        MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
-       MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.frag_buf.page_shift -
+       MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
                                            MLX5_ADAPTER_PAGE_SHIFT);
        MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);
 
@@ -1664,14 +1669,14 @@ static int mlx5e_open_sqs(struct mlx5e_channel *c,
                          struct mlx5e_params *params,
                          struct mlx5e_channel_param *cparam)
 {
-       int err;
-       int tc;
+       struct mlx5e_priv *priv = c->priv;
+       int err, tc, max_nch = priv->profile->max_nch(priv->mdev);
 
        for (tc = 0; tc < params->num_tc; tc++) {
-               int txq_ix = c->ix + tc * params->num_channels;
+               int txq_ix = c->ix + tc * max_nch;
 
                err = mlx5e_open_txqsq(c, c->priv->tisn[tc], txq_ix,
-                                      params, &cparam->sq, &c->sq[tc]);
+                                      params, &cparam->sq, &c->sq[tc], tc);
                if (err)
                        goto err_close_sqs;
        }
@@ -1801,6 +1806,7 @@ static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
        c->mkey_be  = cpu_to_be32(priv->mdev->mlx5e_res.mkey.key);
        c->num_tc   = params->num_tc;
        c->xdp      = !!params->xdp_prog;
+       c->stats    = &priv->channel_stats[ix].ch;
 
        mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq);
        c->irq_desc = irq_to_desc(irq);
@@ -2633,7 +2639,7 @@ static void mlx5e_build_channels_tx_maps(struct mlx5e_priv *priv)
        struct mlx5e_txqsq *sq;
        int i, tc;
 
-       for (i = 0; i < priv->channels.num; i++)
+       for (i = 0; i < priv->profile->max_nch(priv->mdev); i++)
                for (tc = 0; tc < priv->profile->max_tc; tc++)
                        priv->channel_tc2txq[i][tc] = i + tc * priv->channels.num;
 
@@ -2657,6 +2663,9 @@ void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
 
        mlx5e_build_channels_tx_maps(priv);
        mlx5e_activate_channels(&priv->channels);
+       write_lock(&priv->stats_lock);
+       priv->channels_active = true;
+       write_unlock(&priv->stats_lock);
        netif_tx_start_all_queues(priv->netdev);
 
        if (MLX5_VPORT_MANAGER(priv->mdev))
@@ -2678,6 +2687,9 @@ void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
         */
        netif_tx_stop_all_queues(priv->netdev);
        netif_tx_disable(priv->netdev);
+       write_lock(&priv->stats_lock);
+       priv->channels_active = false;
+       write_unlock(&priv->stats_lock);
        mlx5e_deactivate_channels(&priv->channels);
 }
 
@@ -3132,6 +3144,8 @@ static int mlx5e_setup_tc_mqprio(struct net_device *netdev,
        if (err)
                goto out;
 
+       priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
+                                   new_channels.params.num_tc);
        mlx5e_switch_priv_channels(priv, &new_channels, NULL);
 out:
        mutex_unlock(&priv->state_lock);
@@ -3222,6 +3236,7 @@ mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
                stats->tx_packets = PPORT_802_3_GET(pstats, a_frames_transmitted_ok);
                stats->tx_bytes   = PPORT_802_3_GET(pstats, a_octets_transmitted_ok);
        } else {
+               mlx5e_grp_sw_update_stats(priv);
                stats->rx_packets = sstats->rx_packets;
                stats->rx_bytes   = sstats->rx_bytes;
                stats->tx_packets = sstats->tx_packets;
@@ -3818,7 +3833,7 @@ static bool mlx5e_tx_timeout_eq_recover(struct net_device *dev,
                return false;
 
        netdev_err(dev, "Recover %d eqes on EQ 0x%x\n", eqe_count, eq->eqn);
-       sq->channel->stats.eq_rearm++;
+       sq->channel->stats->eq_rearm++;
        return true;
 }
 
@@ -4242,11 +4257,13 @@ static void mlx5e_build_nic_netdev_priv(struct mlx5_core_dev *mdev,
        priv->profile     = profile;
        priv->ppriv       = ppriv;
        priv->msglevel    = MLX5E_MSG_LEVEL;
+       priv->max_opened_tc = 1;
 
        mlx5e_build_nic_params(mdev, &priv->channels.params,
                               profile->max_nch(mdev), netdev->mtu);
 
        mutex_init(&priv->state_lock);
+       rwlock_init(&priv->stats_lock);
 
        INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
        INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);