en_main.c 137.4 KB
Newer Older
1
/*
2
 * Copyright (c) 2015-2016, Mellanox Technologies. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
 *
 * This software is available to you under a choice of one of two
 * licenses.  You may choose to be licensed under the terms of the GNU
 * General Public License (GPL) Version 2, available from the file
 * COPYING in the main directory of this source tree, or the
 * OpenIB.org BSD license below:
 *
 *     Redistribution and use in source and binary forms, with or
 *     without modification, are permitted provided that the following
 *     conditions are met:
 *
 *      - Redistributions of source code must retain the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer.
 *
 *      - Redistributions in binary form must reproduce the above
 *        copyright notice, this list of conditions and the following
 *        disclaimer in the documentation and/or other materials
 *        provided with the distribution.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */

33 34
#include <net/tc_act/tc_gact.h>
#include <net/pkt_cls.h>
35
#include <linux/mlx5/fs.h>
36
#include <net/vxlan.h>
37
#include <net/geneve.h>
38
#include <linux/bpf.h>
39
#include <linux/if_bridge.h>
40
#include <net/page_pool.h>
41
#include <net/xdp_sock.h>
42
#include "eswitch.h"
43
#include "en.h"
44
#include "en/txrx.h"
45
#include "en_tc.h"
46
#include "en_rep.h"
47
#include "en_accel/ipsec.h"
48
#include "en_accel/ipsec_rxtx.h"
49
#include "en_accel/en_accel.h"
50
#include "en_accel/tls.h"
51
#include "accel/ipsec.h"
52
#include "accel/tls.h"
53
#include "lib/vxlan.h"
54
#include "lib/clock.h"
55
#include "en/port.h"
56
#include "en/xdp.h"
57
#include "lib/eq.h"
58
#include "en/monitor_stats.h"
59
#include "en/health.h"
60
#include "en/params.h"
61 62 63 64
#include "en/xsk/umem.h"
#include "en/xsk/setup.h"
#include "en/xsk/rx.h"
#include "en/xsk/tx.h"
65
#include "en/hv_vhca_stats.h"
66
#include "lib/mlx5.h"
67

68

69
bool mlx5e_check_fragmented_striding_rq_cap(struct mlx5_core_dev *mdev)
70
{
71
	bool striding_rq_umr = MLX5_CAP_GEN(mdev, striding_rq) &&
72 73
		MLX5_CAP_GEN(mdev, umr_ptr_rlky) &&
		MLX5_CAP_ETH(mdev, reg_umr_sq);
74 75 76 77 78 79 80 81 82 83 84
	u16 max_wqe_sz_cap = MLX5_CAP_GEN(mdev, max_wqe_sz_sq);
	bool inline_umr = MLX5E_UMR_WQE_INLINE_SZ <= max_wqe_sz_cap;

	if (!striding_rq_umr)
		return false;
	if (!inline_umr) {
		mlx5_core_warn(mdev, "Cannot support Striding RQ: UMR WQE size (%d) exceeds maximum supported (%d).\n",
			       (int)MLX5E_UMR_WQE_INLINE_SZ, max_wqe_sz_cap);
		return false;
	}
	return true;
85 86
}

87
void mlx5e_init_rq_type_params(struct mlx5_core_dev *mdev,
88
			       struct mlx5e_params *params)
89
{
90 91 92
	params->log_rq_mtu_frames = is_kdump_kernel() ?
		MLX5E_PARAMS_MINIMUM_LOG_RQ_SIZE :
		MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
93

94 95
	mlx5_core_info(mdev, "MLX5E: StrdRq(%d) RqSz(%ld) StrdSz(%ld) RxCqeCmprss(%d)\n",
		       params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ,
96
		       params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ ?
97
		       BIT(mlx5e_mpwqe_get_log_rq_size(params, NULL)) :
98
		       BIT(params->log_rq_mtu_frames),
99
		       BIT(mlx5e_mpwqe_get_log_stride_size(mdev, params, NULL)),
100
		       MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS));
101 102
}

103 104 105
bool mlx5e_striding_rq_possible(struct mlx5_core_dev *mdev,
				struct mlx5e_params *params)
{
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
	if (!mlx5e_check_fragmented_striding_rq_cap(mdev))
		return false;

	if (MLX5_IPSEC_DEV(mdev))
		return false;

	if (params->xdp_prog) {
		/* XSK params are not considered here. If striding RQ is in use,
		 * and an XSK is being opened, mlx5e_rx_mpwqe_is_linear_skb will
		 * be called with the known XSK params.
		 */
		if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL))
			return false;
	}

	return true;
122
}
123

124
void mlx5e_set_rq_type(struct mlx5_core_dev *mdev, struct mlx5e_params *params)
125
{
126 127
	params->rq_wq_type = mlx5e_striding_rq_possible(mdev, params) &&
		MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ) ?
128
		MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ :
129
		MLX5_WQ_TYPE_CYCLIC;
130 131
}

132
void mlx5e_update_carrier(struct mlx5e_priv *priv)
133 134 135 136 137
{
	struct mlx5_core_dev *mdev = priv->mdev;
	u8 port_state;

	port_state = mlx5_query_vport_state(mdev,
138
					    MLX5_VPORT_STATE_OP_MOD_VNIC_VPORT,
139
					    0);
140

141 142
	if (port_state == VPORT_STATE_UP) {
		netdev_info(priv->netdev, "Link up\n");
143
		netif_carrier_on(priv->netdev);
144 145
	} else {
		netdev_info(priv->netdev, "Link down\n");
146
		netif_carrier_off(priv->netdev);
147
	}
148 149 150 151 152 153 154 155 156
}

static void mlx5e_update_carrier_work(struct work_struct *work)
{
	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
					       update_carrier_work);

	mutex_lock(&priv->state_lock);
	if (test_bit(MLX5E_STATE_OPENED, &priv->state))
157 158
		if (priv->profile->update_carrier)
			priv->profile->update_carrier(priv);
159 160 161
	mutex_unlock(&priv->state_lock);
}

162
void mlx5e_update_stats(struct mlx5e_priv *priv)
163
{
164
	int i;
165

166 167 168
	for (i = mlx5e_num_stats_grps - 1; i >= 0; i--)
		if (mlx5e_stats_grps[i].update_stats)
			mlx5e_stats_grps[i].update_stats(priv);
169 170
}

171
void mlx5e_update_ndo_stats(struct mlx5e_priv *priv)
172
{
173 174 175 176 177 178
	int i;

	for (i = mlx5e_num_stats_grps - 1; i >= 0; i--)
		if (mlx5e_stats_grps[i].update_stats_mask &
		    MLX5E_NDO_UPDATE_STATS)
			mlx5e_stats_grps[i].update_stats(priv);
179 180
}

181
static void mlx5e_update_stats_work(struct work_struct *work)
182
{
183
	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
184
					       update_stats_work);
185

186
	mutex_lock(&priv->state_lock);
187
	priv->profile->update_stats(priv);
188 189 190
	mutex_unlock(&priv->state_lock);
}

191 192 193 194 195 196 197 198 199 200 201
void mlx5e_queue_update_stats(struct mlx5e_priv *priv)
{
	if (!priv->profile->update_stats)
		return;

	if (unlikely(test_bit(MLX5E_STATE_DESTROYING, &priv->state)))
		return;

	queue_work(priv->wq, &priv->update_stats_work);
}

202
static int async_event(struct notifier_block *nb, unsigned long event, void *data)
203
{
204 205
	struct mlx5e_priv *priv = container_of(nb, struct mlx5e_priv, events_nb);
	struct mlx5_eqe   *eqe = data;
206

207 208
	if (event != MLX5_EVENT_TYPE_PORT_CHANGE)
		return NOTIFY_DONE;
209

210 211 212
	switch (eqe->sub_type) {
	case MLX5_PORT_CHANGE_SUBTYPE_DOWN:
	case MLX5_PORT_CHANGE_SUBTYPE_ACTIVE:
213
		queue_work(priv->wq, &priv->update_carrier_work);
214 215
		break;
	default:
216
		return NOTIFY_DONE;
217
	}
218 219

	return NOTIFY_OK;
220 221 222 223
}

static void mlx5e_enable_async_events(struct mlx5e_priv *priv)
{
224 225
	priv->events_nb.notifier_call = async_event;
	mlx5_notifier_register(priv->mdev, &priv->events_nb);
226 227 228 229
}

static void mlx5e_disable_async_events(struct mlx5e_priv *priv)
{
230
	mlx5_notifier_unregister(priv->mdev, &priv->events_nb);
231 232
}

S
Saeed Mahameed 已提交
233 234
static inline void mlx5e_build_umr_wqe(struct mlx5e_rq *rq,
				       struct mlx5e_icosq *sq,
235
				       struct mlx5e_umr_wqe *wqe)
236 237 238
{
	struct mlx5_wqe_ctrl_seg      *cseg = &wqe->ctrl;
	struct mlx5_wqe_umr_ctrl_seg *ucseg = &wqe->uctrl;
239
	u8 ds_cnt = DIV_ROUND_UP(MLX5E_UMR_WQE_INLINE_SZ, MLX5_SEND_WQE_DS);
240 241 242 243 244 245

	cseg->qpn_ds    = cpu_to_be32((sq->sqn << MLX5_WQE_CTRL_QPN_SHIFT) |
				      ds_cnt);
	cseg->fm_ce_se  = MLX5_WQE_CTRL_CQ_UPDATE;
	cseg->imm       = rq->mkey_be;

246
	ucseg->flags = MLX5_UMR_TRANSLATION_OFFSET_EN | MLX5_UMR_INLINE;
247
	ucseg->xlt_octowords =
248 249 250 251 252 253 254
		cpu_to_be16(MLX5_MTT_OCTW(MLX5_MPWRQ_PAGES_PER_WQE));
	ucseg->mkey_mask     = cpu_to_be64(MLX5_MKEY_MASK_FREE);
}

static int mlx5e_rq_alloc_mpwqe_info(struct mlx5e_rq *rq,
				     struct mlx5e_channel *c)
{
255
	int wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
256

257 258
	rq->mpwqe.info = kvzalloc_node(array_size(wq_sz,
						  sizeof(*rq->mpwqe.info)),
259
				       GFP_KERNEL, cpu_to_node(c->cpu));
260
	if (!rq->mpwqe.info)
261
		return -ENOMEM;
262

263
	mlx5e_build_umr_wqe(rq, &c->icosq, &rq->mpwqe.umr_wqe);
264 265 266 267

	return 0;
}

268
static int mlx5e_create_umr_mkey(struct mlx5_core_dev *mdev,
T
Tariq Toukan 已提交
269 270
				 u64 npages, u8 page_shift,
				 struct mlx5_core_mkey *umr_mkey)
271 272 273 274 275 276
{
	int inlen = MLX5_ST_SZ_BYTES(create_mkey_in);
	void *mkc;
	u32 *in;
	int err;

277
	in = kvzalloc(inlen, GFP_KERNEL);
278 279 280 281 282 283 284 285 286
	if (!in)
		return -ENOMEM;

	mkc = MLX5_ADDR_OF(create_mkey_in, in, memory_key_mkey_entry);

	MLX5_SET(mkc, mkc, free, 1);
	MLX5_SET(mkc, mkc, umr_en, 1);
	MLX5_SET(mkc, mkc, lw, 1);
	MLX5_SET(mkc, mkc, lr, 1);
287
	MLX5_SET(mkc, mkc, access_mode_1_0, MLX5_MKC_ACCESS_MODE_MTT);
288 289 290

	MLX5_SET(mkc, mkc, qpn, 0xffffff);
	MLX5_SET(mkc, mkc, pd, mdev->mlx5e_res.pdn);
T
Tariq Toukan 已提交
291
	MLX5_SET64(mkc, mkc, len, npages << page_shift);
292 293
	MLX5_SET(mkc, mkc, translations_octword_size,
		 MLX5_MTT_OCTW(npages));
T
Tariq Toukan 已提交
294
	MLX5_SET(mkc, mkc, log_page_size, page_shift);
295

T
Tariq Toukan 已提交
296
	err = mlx5_core_create_mkey(mdev, umr_mkey, in, inlen);
297 298 299 300 301

	kvfree(in);
	return err;
}

302
static int mlx5e_create_rq_umr_mkey(struct mlx5_core_dev *mdev, struct mlx5e_rq *rq)
T
Tariq Toukan 已提交
303
{
304
	u64 num_mtts = MLX5E_REQUIRED_MTTS(mlx5_wq_ll_get_size(&rq->mpwqe.wq));
T
Tariq Toukan 已提交
305

306
	return mlx5e_create_umr_mkey(mdev, num_mtts, PAGE_SHIFT, &rq->umr_mkey);
T
Tariq Toukan 已提交
307 308
}

309 310 311 312 313
static inline u64 mlx5e_get_mpwqe_offset(struct mlx5e_rq *rq, u16 wqe_ix)
{
	return (wqe_ix << MLX5E_LOG_ALIGNED_MPWQE_PPW) << PAGE_SHIFT;
}

314 315
static void mlx5e_init_frags_partition(struct mlx5e_rq *rq)
{
316 317
	struct mlx5e_wqe_frag_info next_frag = {};
	struct mlx5e_wqe_frag_info *prev = NULL;
318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351
	int i;

	next_frag.di = &rq->wqe.di[0];

	for (i = 0; i < mlx5_wq_cyc_get_size(&rq->wqe.wq); i++) {
		struct mlx5e_rq_frag_info *frag_info = &rq->wqe.info.arr[0];
		struct mlx5e_wqe_frag_info *frag =
			&rq->wqe.frags[i << rq->wqe.info.log_num_frags];
		int f;

		for (f = 0; f < rq->wqe.info.num_frags; f++, frag++) {
			if (next_frag.offset + frag_info[f].frag_stride > PAGE_SIZE) {
				next_frag.di++;
				next_frag.offset = 0;
				if (prev)
					prev->last_in_page = true;
			}
			*frag = next_frag;

			/* prepare next */
			next_frag.offset += frag_info[f].frag_stride;
			prev = frag;
		}
	}

	if (prev)
		prev->last_in_page = true;
}

static int mlx5e_init_di_list(struct mlx5e_rq *rq,
			      int wq_sz, int cpu)
{
	int len = wq_sz << rq->wqe.info.log_num_frags;

352
	rq->wqe.di = kvzalloc_node(array_size(len, sizeof(*rq->wqe.di)),
353 354 355 356 357 358 359 360 361 362 363 364 365 366
				   GFP_KERNEL, cpu_to_node(cpu));
	if (!rq->wqe.di)
		return -ENOMEM;

	mlx5e_init_frags_partition(rq);

	return 0;
}

static void mlx5e_free_di_list(struct mlx5e_rq *rq)
{
	kvfree(rq->wqe.di);
}

367 368 369 370 371 372 373
static void mlx5e_rq_err_cqe_work(struct work_struct *recover_work)
{
	struct mlx5e_rq *rq = container_of(recover_work, struct mlx5e_rq, recover_work);

	mlx5e_reporter_rq_cqe_err(rq);
}

374
static int mlx5e_alloc_rq(struct mlx5e_channel *c,
375
			  struct mlx5e_params *params,
376 377
			  struct mlx5e_xsk_param *xsk,
			  struct xdp_umem *umem,
378
			  struct mlx5e_rq_param *rqp,
379
			  struct mlx5e_rq *rq)
380
{
381
	struct page_pool_params pp_params = { 0 };
382
	struct mlx5_core_dev *mdev = c->mdev;
383
	void *rqc = rqp->rqc;
384
	void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
385 386
	u32 num_xsk_frames = 0;
	u32 rq_xdp_ix;
387
	u32 pool_size;
388 389 390 391
	int wq_sz;
	int err;
	int i;

392
	rqp->wq.db_numa_node = cpu_to_node(c->cpu);
393

394
	rq->wq_type = params->rq_wq_type;
395 396
	rq->pdev    = c->pdev;
	rq->netdev  = c->netdev;
397
	rq->tstamp  = c->tstamp;
398
	rq->clock   = &mdev->clock;
399 400
	rq->channel = c;
	rq->ix      = c->ix;
401
	rq->mdev    = mdev;
402
	rq->hw_mtu  = MLX5E_SW2HW_MTU(params, params->sw_mtu);
403
	rq->xdpsq   = &c->rq_xdpsq;
404 405 406 407 408 409
	rq->umem    = umem;

	if (rq->umem)
		rq->stats = &c->priv->channel_stats[c->ix].xskrq;
	else
		rq->stats = &c->priv->channel_stats[c->ix].rq;
410
	INIT_WORK(&rq->recover_work, mlx5e_rq_err_cqe_work);
411

412 413 414
	if (params->xdp_prog)
		bpf_prog_inc(params->xdp_prog);
	rq->xdp_prog = params->xdp_prog;
415

416 417 418 419
	rq_xdp_ix = rq->ix;
	if (xsk)
		rq_xdp_ix += params->num_channels * MLX5E_RQ_GROUP_XSK;
	err = xdp_rxq_info_reg(&rq->xdp_rxq, rq->netdev, rq_xdp_ix);
420
	if (err < 0)
421 422
		goto err_rq_wq_destroy;

423
	rq->buff.map_dir = rq->xdp_prog ? DMA_BIDIRECTIONAL : DMA_FROM_DEVICE;
424 425
	rq->buff.headroom = mlx5e_get_rq_headroom(mdev, params, xsk);
	rq->buff.umem_headroom = xsk ? xsk->headroom : 0;
426
	pool_size = 1 << params->log_rq_mtu_frames;
427

428
	switch (rq->wq_type) {
429
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
430 431 432 433 434 435 436 437
		err = mlx5_wq_ll_create(mdev, &rqp->wq, rqc_wq, &rq->mpwqe.wq,
					&rq->wq_ctrl);
		if (err)
			return err;

		rq->mpwqe.wq.db = &rq->mpwqe.wq.db[MLX5_RCV_DBR];

		wq_sz = mlx5_wq_ll_get_size(&rq->mpwqe.wq);
438

439 440 441 442 443 444
		if (xsk)
			num_xsk_frames = wq_sz <<
				mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk);

		pool_size = MLX5_MPWRQ_PAGES_PER_WQE <<
			mlx5e_mpwqe_get_log_rq_size(params, xsk);
445

446
		rq->post_wqes = mlx5e_post_rx_mpwqes;
447
		rq->dealloc_wqe = mlx5e_dealloc_rx_mpwqe;
448

449
		rq->handle_rx_cqe = c->priv->profile->rx_handlers.handle_rx_cqe_mpwqe;
450 451 452 453 454 455 456
#ifdef CONFIG_MLX5_EN_IPSEC
		if (MLX5_IPSEC_DEV(mdev)) {
			err = -EINVAL;
			netdev_err(c->netdev, "MPWQE RQ with IPSec offload not supported\n");
			goto err_rq_wq_destroy;
		}
#endif
457 458 459 460 461 462
		if (!rq->handle_rx_cqe) {
			err = -EINVAL;
			netdev_err(c->netdev, "RX handler of MPWQE RQ is not set, err %d\n", err);
			goto err_rq_wq_destroy;
		}

463 464 465 466 467 468 469 470 471
		rq->mpwqe.skb_from_cqe_mpwrq = xsk ?
			mlx5e_xsk_skb_from_cqe_mpwrq_linear :
			mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL) ?
				mlx5e_skb_from_cqe_mpwrq_linear :
				mlx5e_skb_from_cqe_mpwrq_nonlinear;

		rq->mpwqe.log_stride_sz = mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk);
		rq->mpwqe.num_strides =
			BIT(mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk));
472

473
		err = mlx5e_create_rq_umr_mkey(mdev, rq);
474 475
		if (err)
			goto err_rq_wq_destroy;
T
Tariq Toukan 已提交
476 477 478 479
		rq->mkey_be = cpu_to_be32(rq->umr_mkey.key);

		err = mlx5e_rq_alloc_mpwqe_info(rq, c);
		if (err)
480
			goto err_free;
481
		break;
482 483 484
	default: /* MLX5_WQ_TYPE_CYCLIC */
		err = mlx5_wq_cyc_create(mdev, &rqp->wq, rqc_wq, &rq->wqe.wq,
					 &rq->wq_ctrl);
485 486 487 488 489
		if (err)
			return err;

		rq->wqe.wq.db = &rq->wqe.wq.db[MLX5_RCV_DBR];

490
		wq_sz = mlx5_wq_cyc_get_size(&rq->wqe.wq);
491

492 493 494
		if (xsk)
			num_xsk_frames = wq_sz << rq->wqe.info.log_num_frags;

495 496
		rq->wqe.info = rqp->frags_info;
		rq->wqe.frags =
497 498
			kvzalloc_node(array_size(sizeof(*rq->wqe.frags),
					(wq_sz << rq->wqe.info.log_num_frags)),
499
				      GFP_KERNEL, cpu_to_node(c->cpu));
500 501
		if (!rq->wqe.frags) {
			err = -ENOMEM;
502
			goto err_free;
503
		}
504

505
		err = mlx5e_init_di_list(rq, wq_sz, c->cpu);
506 507
		if (err)
			goto err_free;
508

509
		rq->post_wqes = mlx5e_post_rx_wqes;
510
		rq->dealloc_wqe = mlx5e_dealloc_rx_wqe;
511

512 513 514 515 516 517
#ifdef CONFIG_MLX5_EN_IPSEC
		if (c->priv->ipsec)
			rq->handle_rx_cqe = mlx5e_ipsec_handle_rx_cqe;
		else
#endif
			rq->handle_rx_cqe = c->priv->profile->rx_handlers.handle_rx_cqe;
518 519 520
		if (!rq->handle_rx_cqe) {
			err = -EINVAL;
			netdev_err(c->netdev, "RX handler of RQ is not set, err %d\n", err);
521
			goto err_free;
522 523
		}

524 525 526 527 528
		rq->wqe.skb_from_cqe = xsk ?
			mlx5e_xsk_skb_from_cqe_linear :
			mlx5e_rx_is_linear_skb(params, NULL) ?
				mlx5e_skb_from_cqe_linear :
				mlx5e_skb_from_cqe_nonlinear;
529
		rq->mkey_be = c->mkey_be;
530
	}
531

532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565
	if (xsk) {
		err = mlx5e_xsk_resize_reuseq(umem, num_xsk_frames);
		if (unlikely(err)) {
			mlx5_core_err(mdev, "Unable to allocate the Reuse Ring for %u frames\n",
				      num_xsk_frames);
			goto err_free;
		}

		rq->zca.free = mlx5e_xsk_zca_free;
		err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
						 MEM_TYPE_ZERO_COPY,
						 &rq->zca);
	} else {
		/* Create a page_pool and register it with rxq */
		pp_params.order     = 0;
		pp_params.flags     = 0; /* No-internal DMA mapping in page_pool */
		pp_params.pool_size = pool_size;
		pp_params.nid       = cpu_to_node(c->cpu);
		pp_params.dev       = c->pdev;
		pp_params.dma_dir   = rq->buff.map_dir;

		/* page_pool can be used even when there is no rq->xdp_prog,
		 * given page_pool does not handle DMA mapping there is no
		 * required state to clear. And page_pool gracefully handle
		 * elevated refcnt.
		 */
		rq->page_pool = page_pool_create(&pp_params);
		if (IS_ERR(rq->page_pool)) {
			err = PTR_ERR(rq->page_pool);
			rq->page_pool = NULL;
			goto err_free;
		}
		err = xdp_rxq_info_reg_mem_model(&rq->xdp_rxq,
						 MEM_TYPE_PAGE_POOL, rq->page_pool);
566
	}
567
	if (err)
568
		goto err_free;
569

570
	for (i = 0; i < wq_sz; i++) {
571
		if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
572
			struct mlx5e_rx_wqe_ll *wqe =
573
				mlx5_wq_ll_get_wqe(&rq->mpwqe.wq, i);
574 575
			u32 byte_count =
				rq->mpwqe.num_strides << rq->mpwqe.log_stride_sz;
576
			u64 dma_offset = mlx5e_get_mpwqe_offset(rq, i);
577

578 579 580
			wqe->data[0].addr = cpu_to_be64(dma_offset + rq->buff.headroom);
			wqe->data[0].byte_count = cpu_to_be32(byte_count);
			wqe->data[0].lkey = rq->mkey_be;
581
		} else {
582 583
			struct mlx5e_rx_wqe_cyc *wqe =
				mlx5_wq_cyc_get_wqe(&rq->wqe.wq, i);
584 585 586 587 588 589 590 591 592 593 594 595 596 597 598
			int f;

			for (f = 0; f < rq->wqe.info.num_frags; f++) {
				u32 frag_size = rq->wqe.info.arr[f].frag_size |
					MLX5_HW_START_PADDING;

				wqe->data[f].byte_count = cpu_to_be32(frag_size);
				wqe->data[f].lkey = rq->mkey_be;
			}
			/* check if num_frags is not a pow of two */
			if (rq->wqe.info.num_frags < (1 << rq->wqe.info.log_num_frags)) {
				wqe->data[f].byte_count = 0;
				wqe->data[f].lkey = cpu_to_be32(MLX5_INVALID_LKEY);
				wqe->data[f].addr = 0;
			}
599
		}
600 601
	}

602 603 604 605
	INIT_WORK(&rq->dim.work, mlx5e_rx_dim_work);

	switch (params->rx_cq_moderation.cq_period_mode) {
	case MLX5_CQ_PERIOD_MODE_START_FROM_CQE:
606
		rq->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_CQE;
607 608 609
		break;
	case MLX5_CQ_PERIOD_MODE_START_FROM_EQE:
	default:
610
		rq->dim.mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
611 612
	}

613 614 615
	rq->page_cache.head = 0;
	rq->page_cache.tail = 0;

616 617
	return 0;

618 619 620
err_free:
	switch (rq->wq_type) {
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
621
		kvfree(rq->mpwqe.info);
622 623 624 625 626 627
		mlx5_core_destroy_mkey(mdev, &rq->umr_mkey);
		break;
	default: /* MLX5_WQ_TYPE_CYCLIC */
		kvfree(rq->wqe.frags);
		mlx5e_free_di_list(rq);
	}
T
Tariq Toukan 已提交
628

629
err_rq_wq_destroy:
630 631
	if (rq->xdp_prog)
		bpf_prog_put(rq->xdp_prog);
632
	xdp_rxq_info_unreg(&rq->xdp_rxq);
633
	page_pool_destroy(rq->page_pool);
634 635 636 637 638
	mlx5_wq_destroy(&rq->wq_ctrl);

	return err;
}

639
static void mlx5e_free_rq(struct mlx5e_rq *rq)
640
{
641 642
	int i;

643 644 645
	if (rq->xdp_prog)
		bpf_prog_put(rq->xdp_prog);

646 647
	switch (rq->wq_type) {
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
648
		kvfree(rq->mpwqe.info);
649
		mlx5_core_destroy_mkey(rq->mdev, &rq->umr_mkey);
650
		break;
651
	default: /* MLX5_WQ_TYPE_CYCLIC */
652 653
		kvfree(rq->wqe.frags);
		mlx5e_free_di_list(rq);
654 655
	}

656 657 658 659
	for (i = rq->page_cache.head; i != rq->page_cache.tail;
	     i = (i + 1) & (MLX5E_CACHE_SIZE - 1)) {
		struct mlx5e_dma_info *dma_info = &rq->page_cache.page_cache[i];

660 661 662 663 664
		/* With AF_XDP, page_cache is not used, so this loop is not
		 * entered, and it's safe to call mlx5e_page_release_dynamic
		 * directly.
		 */
		mlx5e_page_release_dynamic(rq, dma_info, false);
665
	}
666 667

	xdp_rxq_info_unreg(&rq->xdp_rxq);
668
	page_pool_destroy(rq->page_pool);
669 670 671
	mlx5_wq_destroy(&rq->wq_ctrl);
}

672 673
static int mlx5e_create_rq(struct mlx5e_rq *rq,
			   struct mlx5e_rq_param *param)
674
{
675
	struct mlx5_core_dev *mdev = rq->mdev;
676 677 678 679 680 681 682 683 684

	void *in;
	void *rqc;
	void *wq;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(create_rq_in) +
		sizeof(u64) * rq->wq_ctrl.buf.npages;
685
	in = kvzalloc(inlen, GFP_KERNEL);
686 687 688 689 690 691 692 693
	if (!in)
		return -ENOMEM;

	rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
	wq  = MLX5_ADDR_OF(rqc, rqc, wq);

	memcpy(rqc, param->rqc, sizeof(param->rqc));

694
	MLX5_SET(rqc,  rqc, cqn,		rq->cq.mcq.cqn);
695 696
	MLX5_SET(rqc,  rqc, state,		MLX5_RQC_STATE_RST);
	MLX5_SET(wq,   wq,  log_wq_pg_sz,	rq->wq_ctrl.buf.page_shift -
697
						MLX5_ADAPTER_PAGE_SHIFT);
698 699
	MLX5_SET64(wq, wq,  dbr_addr,		rq->wq_ctrl.db.dma);

700 701
	mlx5_fill_page_frag_array(&rq->wq_ctrl.buf,
				  (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
702

703
	err = mlx5_core_create_rq(mdev, in, inlen, &rq->rqn);
704 705 706 707 708 709

	kvfree(in);

	return err;
}

710
int mlx5e_modify_rq_state(struct mlx5e_rq *rq, int curr_state, int next_state)
711
{
712
	struct mlx5_core_dev *mdev = rq->mdev;
713 714 715 716 717 718 719

	void *in;
	void *rqc;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
720
	in = kvzalloc(inlen, GFP_KERNEL);
721 722 723 724 725 726 727 728
	if (!in)
		return -ENOMEM;

	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);

	MLX5_SET(modify_rq_in, in, rq_state, curr_state);
	MLX5_SET(rqc, rqc, state, next_state);

729
	err = mlx5_core_modify_rq(mdev, rq->rqn, in, inlen);
730 731 732 733 734 735

	kvfree(in);

	return err;
}

736 737 738 739 740 741 742 743 744 745 746 747
static int mlx5e_modify_rq_scatter_fcs(struct mlx5e_rq *rq, bool enable)
{
	struct mlx5e_channel *c = rq->channel;
	struct mlx5e_priv *priv = c->priv;
	struct mlx5_core_dev *mdev = priv->mdev;

	void *in;
	void *rqc;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
748
	in = kvzalloc(inlen, GFP_KERNEL);
749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766
	if (!in)
		return -ENOMEM;

	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);

	MLX5_SET(modify_rq_in, in, rq_state, MLX5_RQC_STATE_RDY);
	MLX5_SET64(modify_rq_in, in, modify_bitmask,
		   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_SCATTER_FCS);
	MLX5_SET(rqc, rqc, scatter_fcs, enable);
	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY);

	err = mlx5_core_modify_rq(mdev, rq->rqn, in, inlen);

	kvfree(in);

	return err;
}

767 768 769
static int mlx5e_modify_rq_vsd(struct mlx5e_rq *rq, bool vsd)
{
	struct mlx5e_channel *c = rq->channel;
770
	struct mlx5_core_dev *mdev = c->mdev;
771 772 773 774 775 776
	void *in;
	void *rqc;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
777
	in = kvzalloc(inlen, GFP_KERNEL);
778 779 780 781 782 783
	if (!in)
		return -ENOMEM;

	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);

	MLX5_SET(modify_rq_in, in, rq_state, MLX5_RQC_STATE_RDY);
784 785
	MLX5_SET64(modify_rq_in, in, modify_bitmask,
		   MLX5_MODIFY_RQ_IN_MODIFY_BITMASK_VSD);
786 787 788 789 790 791 792 793 794 795
	MLX5_SET(rqc, rqc, vsd, vsd);
	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RDY);

	err = mlx5_core_modify_rq(mdev, rq->rqn, in, inlen);

	kvfree(in);

	return err;
}

796
static void mlx5e_destroy_rq(struct mlx5e_rq *rq)
797
{
798
	mlx5_core_destroy_rq(rq->mdev, rq->rqn);
799 800
}

801
int mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq, int wait_time)
802
{
803
	unsigned long exp_time = jiffies + msecs_to_jiffies(wait_time);
804
	struct mlx5e_channel *c = rq->channel;
805

806
	u16 min_wqes = mlx5_min_rx_wqes(rq->wq_type, mlx5e_rqwq_get_size(rq));
807

808
	do {
809
		if (mlx5e_rqwq_get_cur_sz(rq) >= min_wqes)
810 811 812
			return 0;

		msleep(20);
813 814 815
	} while (time_before(jiffies, exp_time));

	netdev_warn(c->netdev, "Failed to get min RX wqes on Channel[%d] RQN[0x%x] wq cur_sz(%d) min_rx_wqes(%d)\n",
816
		    c->ix, rq->rqn, mlx5e_rqwq_get_cur_sz(rq), min_wqes);
817

818
	mlx5e_reporter_rx_timeout(rq);
819 820 821
	return -ETIMEDOUT;
}

822
void mlx5e_free_rx_descs(struct mlx5e_rq *rq)
823 824 825 826
{
	__be16 wqe_ix_be;
	u16 wqe_ix;

827 828
	if (rq->wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
		struct mlx5_wq_ll *wq = &rq->mpwqe.wq;
829 830
		u16 head = wq->head;
		int i;
831

832 833 834 835 836
		/* Outstanding UMR WQEs (in progress) start at wq->head */
		for (i = 0; i < rq->mpwqe.umr_in_progress; i++) {
			rq->dealloc_wqe(rq, head);
			head = mlx5_wq_ll_get_wqe_next_ix(wq, head);
		}
837 838

		while (!mlx5_wq_ll_is_empty(wq)) {
839
			struct mlx5e_rx_wqe_ll *wqe;
840 841 842 843 844 845 846 847 848

			wqe_ix_be = *wq->tail_next;
			wqe_ix    = be16_to_cpu(wqe_ix_be);
			wqe       = mlx5_wq_ll_get_wqe(wq, wqe_ix);
			rq->dealloc_wqe(rq, wqe_ix);
			mlx5_wq_ll_pop(wq, wqe_ix_be,
				       &wqe->next.next_wqe_index);
		}
	} else {
849
		struct mlx5_wq_cyc *wq = &rq->wqe.wq;
850

851 852
		while (!mlx5_wq_cyc_is_empty(wq)) {
			wqe_ix = mlx5_wq_cyc_get_tail(wq);
853
			rq->dealloc_wqe(rq, wqe_ix);
854
			mlx5_wq_cyc_pop(wq);
855
		}
856
	}
857

858 859
}

860 861 862
int mlx5e_open_rq(struct mlx5e_channel *c, struct mlx5e_params *params,
		  struct mlx5e_rq_param *param, struct mlx5e_xsk_param *xsk,
		  struct xdp_umem *umem, struct mlx5e_rq *rq)
863 864 865
{
	int err;

866
	err = mlx5e_alloc_rq(c, params, xsk, umem, param, rq);
867 868 869
	if (err)
		return err;

870
	err = mlx5e_create_rq(rq, param);
871
	if (err)
872
		goto err_free_rq;
873

874
	err = mlx5e_modify_rq_state(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
875
	if (err)
876
		goto err_destroy_rq;
877

878 879 880
	if (MLX5_CAP_ETH(c->mdev, cqe_checksum_full))
		__set_bit(MLX5E_RQ_STATE_CSUM_FULL, &c->rq.state);

881
	if (params->rx_dim_enabled)
882
		__set_bit(MLX5E_RQ_STATE_AM, &c->rq.state);
883

884 885 886 887 888
	/* We disable csum_complete when XDP is enabled since
	 * XDP programs might manipulate packets which will render
	 * skb->checksum incorrect.
	 */
	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE) || c->xdp)
889 890
		__set_bit(MLX5E_RQ_STATE_NO_CSUM_COMPLETE, &c->rq.state);

891 892 893 894
	return 0;

err_destroy_rq:
	mlx5e_destroy_rq(rq);
895 896
err_free_rq:
	mlx5e_free_rq(rq);
897 898 899 900

	return err;
}

901
void mlx5e_activate_rq(struct mlx5e_rq *rq)
902 903
{
	set_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
904
	mlx5e_trigger_irq(&rq->channel->icosq);
905 906
}

907
void mlx5e_deactivate_rq(struct mlx5e_rq *rq)
908
{
909
	clear_bit(MLX5E_RQ_STATE_ENABLED, &rq->state);
910
	napi_synchronize(&rq->channel->napi); /* prevent mlx5e_post_rx_wqes */
911
}
912

913
void mlx5e_close_rq(struct mlx5e_rq *rq)
914
{
915
	cancel_work_sync(&rq->dim.work);
916
	cancel_work_sync(&rq->channel->icosq.recover_work);
917
	cancel_work_sync(&rq->recover_work);
918
	mlx5e_destroy_rq(rq);
919 920
	mlx5e_free_rx_descs(rq);
	mlx5e_free_rq(rq);
921 922
}

S
Saeed Mahameed 已提交
923
static void mlx5e_free_xdpsq_db(struct mlx5e_xdpsq *sq)
924
{
925
	kvfree(sq->db.xdpi_fifo.xi);
926
	kvfree(sq->db.wqe_info);
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944
}

static int mlx5e_alloc_xdpsq_fifo(struct mlx5e_xdpsq *sq, int numa)
{
	struct mlx5e_xdp_info_fifo *xdpi_fifo = &sq->db.xdpi_fifo;
	int wq_sz        = mlx5_wq_cyc_get_size(&sq->wq);
	int dsegs_per_wq = wq_sz * MLX5_SEND_WQEBB_NUM_DS;

	xdpi_fifo->xi = kvzalloc_node(sizeof(*xdpi_fifo->xi) * dsegs_per_wq,
				      GFP_KERNEL, numa);
	if (!xdpi_fifo->xi)
		return -ENOMEM;

	xdpi_fifo->pc   = &sq->xdpi_fifo_pc;
	xdpi_fifo->cc   = &sq->xdpi_fifo_cc;
	xdpi_fifo->mask = dsegs_per_wq - 1;

	return 0;
945 946
}

S
Saeed Mahameed 已提交
947
static int mlx5e_alloc_xdpsq_db(struct mlx5e_xdpsq *sq, int numa)
948
{
949
	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
950
	int err;
951

952 953 954 955 956
	sq->db.wqe_info = kvzalloc_node(sizeof(*sq->db.wqe_info) * wq_sz,
					GFP_KERNEL, numa);
	if (!sq->db.wqe_info)
		return -ENOMEM;

957 958
	err = mlx5e_alloc_xdpsq_fifo(sq, numa);
	if (err) {
S
Saeed Mahameed 已提交
959
		mlx5e_free_xdpsq_db(sq);
960
		return err;
961 962 963 964 965
	}

	return 0;
}

S
Saeed Mahameed 已提交
966
static int mlx5e_alloc_xdpsq(struct mlx5e_channel *c,
967
			     struct mlx5e_params *params,
968
			     struct xdp_umem *umem,
S
Saeed Mahameed 已提交
969
			     struct mlx5e_sq_param *param,
970 971
			     struct mlx5e_xdpsq *sq,
			     bool is_redirect)
S
Saeed Mahameed 已提交
972 973
{
	void *sqc_wq               = MLX5_ADDR_OF(sqc, param->sqc, wq);
974
	struct mlx5_core_dev *mdev = c->mdev;
975
	struct mlx5_wq_cyc *wq = &sq->wq;
S
Saeed Mahameed 已提交
976 977 978 979 980 981
	int err;

	sq->pdev      = c->pdev;
	sq->mkey_be   = c->mkey_be;
	sq->channel   = c;
	sq->uar_map   = mdev->mlx5e_res.bfreg.map;
982
	sq->min_inline_mode = params->tx_min_inline_mode;
983
	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu);
984 985 986 987 988 989 990
	sq->umem      = umem;

	sq->stats = sq->umem ?
		&c->priv->channel_stats[c->ix].xsksq :
		is_redirect ?
			&c->priv->channel_stats[c->ix].xdpsq :
			&c->priv->channel_stats[c->ix].rq_xdpsq;
S
Saeed Mahameed 已提交
991

992
	param->wq.db_numa_node = cpu_to_node(c->cpu);
993
	err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, wq, &sq->wq_ctrl);
S
Saeed Mahameed 已提交
994 995
	if (err)
		return err;
996
	wq->db = &wq->db[MLX5_SND_DBR];
S
Saeed Mahameed 已提交
997

998
	err = mlx5e_alloc_xdpsq_db(sq, cpu_to_node(c->cpu));
S
Saeed Mahameed 已提交
999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016
	if (err)
		goto err_sq_wq_destroy;

	return 0;

err_sq_wq_destroy:
	mlx5_wq_destroy(&sq->wq_ctrl);

	return err;
}

static void mlx5e_free_xdpsq(struct mlx5e_xdpsq *sq)
{
	mlx5e_free_xdpsq_db(sq);
	mlx5_wq_destroy(&sq->wq_ctrl);
}

static void mlx5e_free_icosq_db(struct mlx5e_icosq *sq)
1017
{
1018
	kvfree(sq->db.ico_wqe);
1019 1020
}

S
Saeed Mahameed 已提交
1021
static int mlx5e_alloc_icosq_db(struct mlx5e_icosq *sq, int numa)
1022
{
1023
	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
1024

1025 1026
	sq->db.ico_wqe = kvzalloc_node(array_size(wq_sz,
						  sizeof(*sq->db.ico_wqe)),
1027
				       GFP_KERNEL, numa);
1028 1029 1030 1031 1032 1033
	if (!sq->db.ico_wqe)
		return -ENOMEM;

	return 0;
}

1034 1035 1036 1037 1038 1039 1040 1041
static void mlx5e_icosq_err_cqe_work(struct work_struct *recover_work)
{
	struct mlx5e_icosq *sq = container_of(recover_work, struct mlx5e_icosq,
					      recover_work);

	mlx5e_reporter_icosq_cqe_err(sq);
}

S
Saeed Mahameed 已提交
1042 1043 1044
static int mlx5e_alloc_icosq(struct mlx5e_channel *c,
			     struct mlx5e_sq_param *param,
			     struct mlx5e_icosq *sq)
1045
{
S
Saeed Mahameed 已提交
1046
	void *sqc_wq               = MLX5_ADDR_OF(sqc, param->sqc, wq);
1047
	struct mlx5_core_dev *mdev = c->mdev;
1048
	struct mlx5_wq_cyc *wq = &sq->wq;
S
Saeed Mahameed 已提交
1049
	int err;
1050

S
Saeed Mahameed 已提交
1051 1052
	sq->channel   = c;
	sq->uar_map   = mdev->mlx5e_res.bfreg.map;
1053

1054
	param->wq.db_numa_node = cpu_to_node(c->cpu);
1055
	err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, wq, &sq->wq_ctrl);
S
Saeed Mahameed 已提交
1056 1057
	if (err)
		return err;
1058
	wq->db = &wq->db[MLX5_SND_DBR];
1059

1060
	err = mlx5e_alloc_icosq_db(sq, cpu_to_node(c->cpu));
S
Saeed Mahameed 已提交
1061 1062 1063
	if (err)
		goto err_sq_wq_destroy;

1064 1065
	INIT_WORK(&sq->recover_work, mlx5e_icosq_err_cqe_work);

1066
	return 0;
S
Saeed Mahameed 已提交
1067 1068 1069 1070 1071

err_sq_wq_destroy:
	mlx5_wq_destroy(&sq->wq_ctrl);

	return err;
1072 1073
}

S
Saeed Mahameed 已提交
1074
static void mlx5e_free_icosq(struct mlx5e_icosq *sq)
1075
{
S
Saeed Mahameed 已提交
1076 1077
	mlx5e_free_icosq_db(sq);
	mlx5_wq_destroy(&sq->wq_ctrl);
1078 1079
}

S
Saeed Mahameed 已提交
1080
static void mlx5e_free_txqsq_db(struct mlx5e_txqsq *sq)
1081
{
1082 1083
	kvfree(sq->db.wqe_info);
	kvfree(sq->db.dma_fifo);
1084 1085
}

S
Saeed Mahameed 已提交
1086
static int mlx5e_alloc_txqsq_db(struct mlx5e_txqsq *sq, int numa)
1087
{
S
Saeed Mahameed 已提交
1088 1089 1090
	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
	int df_sz = wq_sz * MLX5_SEND_WQEBB_NUM_DS;

1091 1092
	sq->db.dma_fifo = kvzalloc_node(array_size(df_sz,
						   sizeof(*sq->db.dma_fifo)),
1093
					GFP_KERNEL, numa);
1094 1095
	sq->db.wqe_info = kvzalloc_node(array_size(wq_sz,
						   sizeof(*sq->db.wqe_info)),
1096
					GFP_KERNEL, numa);
S
Saeed Mahameed 已提交
1097
	if (!sq->db.dma_fifo || !sq->db.wqe_info) {
S
Saeed Mahameed 已提交
1098 1099
		mlx5e_free_txqsq_db(sq);
		return -ENOMEM;
1100
	}
S
Saeed Mahameed 已提交
1101 1102 1103 1104

	sq->dma_fifo_mask = df_sz - 1;

	return 0;
1105 1106
}

1107
static void mlx5e_tx_err_cqe_work(struct work_struct *recover_work);
S
Saeed Mahameed 已提交
1108
static int mlx5e_alloc_txqsq(struct mlx5e_channel *c,
1109
			     int txq_ix,
1110
			     struct mlx5e_params *params,
S
Saeed Mahameed 已提交
1111
			     struct mlx5e_sq_param *param,
1112 1113
			     struct mlx5e_txqsq *sq,
			     int tc)
1114
{
S
Saeed Mahameed 已提交
1115
	void *sqc_wq               = MLX5_ADDR_OF(sqc, param->sqc, wq);
1116
	struct mlx5_core_dev *mdev = c->mdev;
1117
	struct mlx5_wq_cyc *wq = &sq->wq;
1118 1119
	int err;

1120
	sq->pdev      = c->pdev;
1121
	sq->tstamp    = c->tstamp;
1122
	sq->clock     = &mdev->clock;
1123 1124
	sq->mkey_be   = c->mkey_be;
	sq->channel   = c;
1125
	sq->ch_ix     = c->ix;
1126
	sq->txq_ix    = txq_ix;
1127
	sq->uar_map   = mdev->mlx5e_res.bfreg.map;
1128
	sq->min_inline_mode = params->tx_min_inline_mode;
1129
	sq->hw_mtu    = MLX5E_SW2HW_MTU(params, params->sw_mtu);
1130
	sq->stats     = &c->priv->channel_stats[c->ix].sq[tc];
1131
	sq->stop_room = MLX5E_SQ_STOP_ROOM;
1132
	INIT_WORK(&sq->recover_work, mlx5e_tx_err_cqe_work);
1133 1134
	if (!MLX5_CAP_ETH(mdev, wqe_vlan_insert))
		set_bit(MLX5E_SQ_STATE_VLAN_NEED_L2_INLINE, &sq->state);
1135 1136
	if (MLX5_IPSEC_DEV(c->priv->mdev))
		set_bit(MLX5E_SQ_STATE_IPSEC, &sq->state);
1137
#ifdef CONFIG_MLX5_EN_TLS
1138
	if (mlx5_accel_is_tls_device(c->priv->mdev)) {
1139
		set_bit(MLX5E_SQ_STATE_TLS, &sq->state);
1140 1141 1142
		sq->stop_room += MLX5E_SQ_TLS_ROOM +
			mlx5e_ktls_dumps_num_wqebbs(sq, MAX_SKB_FRAGS,
						    TLS_MAX_PAYLOAD_SIZE);
1143
	}
1144
#endif
1145

1146
	param->wq.db_numa_node = cpu_to_node(c->cpu);
1147
	err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, wq, &sq->wq_ctrl);
1148
	if (err)
1149
		return err;
1150
	wq->db    = &wq->db[MLX5_SND_DBR];
1151

1152
	err = mlx5e_alloc_txqsq_db(sq, cpu_to_node(c->cpu));
D
Dan Carpenter 已提交
1153
	if (err)
1154 1155
		goto err_sq_wq_destroy;

1156 1157 1158
	INIT_WORK(&sq->dim.work, mlx5e_tx_dim_work);
	sq->dim.mode = params->tx_cq_moderation.cq_period_mode;

1159 1160 1161 1162 1163 1164 1165 1166
	return 0;

err_sq_wq_destroy:
	mlx5_wq_destroy(&sq->wq_ctrl);

	return err;
}

S
Saeed Mahameed 已提交
1167
static void mlx5e_free_txqsq(struct mlx5e_txqsq *sq)
1168
{
S
Saeed Mahameed 已提交
1169
	mlx5e_free_txqsq_db(sq);
1170 1171 1172
	mlx5_wq_destroy(&sq->wq_ctrl);
}

1173 1174 1175 1176 1177 1178 1179 1180
struct mlx5e_create_sq_param {
	struct mlx5_wq_ctrl        *wq_ctrl;
	u32                         cqn;
	u32                         tisn;
	u8                          tis_lst_sz;
	u8                          min_inline_mode;
};

1181
static int mlx5e_create_sq(struct mlx5_core_dev *mdev,
1182 1183 1184
			   struct mlx5e_sq_param *param,
			   struct mlx5e_create_sq_param *csp,
			   u32 *sqn)
1185 1186 1187 1188 1189 1190 1191 1192
{
	void *in;
	void *sqc;
	void *wq;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(create_sq_in) +
1193
		sizeof(u64) * csp->wq_ctrl->buf.npages;
1194
	in = kvzalloc(inlen, GFP_KERNEL);
1195 1196 1197 1198 1199 1200 1201
	if (!in)
		return -ENOMEM;

	sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
	wq = MLX5_ADDR_OF(sqc, sqc, wq);

	memcpy(sqc, param->sqc, sizeof(param->sqc));
1202 1203 1204
	MLX5_SET(sqc,  sqc, tis_lst_sz, csp->tis_lst_sz);
	MLX5_SET(sqc,  sqc, tis_num_0, csp->tisn);
	MLX5_SET(sqc,  sqc, cqn, csp->cqn);
1205 1206

	if (MLX5_CAP_ETH(mdev, wqe_inline_mode) == MLX5_CAP_INLINE_MODE_VPORT_CONTEXT)
1207
		MLX5_SET(sqc,  sqc, min_wqe_inline_mode, csp->min_inline_mode);
1208

1209
	MLX5_SET(sqc,  sqc, state, MLX5_SQC_STATE_RST);
1210
	MLX5_SET(sqc,  sqc, flush_in_error_en, 1);
1211 1212

	MLX5_SET(wq,   wq, wq_type,       MLX5_WQ_TYPE_CYCLIC);
1213
	MLX5_SET(wq,   wq, uar_page,      mdev->mlx5e_res.bfreg.index);
1214
	MLX5_SET(wq,   wq, log_wq_pg_sz,  csp->wq_ctrl->buf.page_shift -
1215
					  MLX5_ADAPTER_PAGE_SHIFT);
1216
	MLX5_SET64(wq, wq, dbr_addr,      csp->wq_ctrl->db.dma);
1217

1218 1219
	mlx5_fill_page_frag_array(&csp->wq_ctrl->buf,
				  (__be64 *)MLX5_ADDR_OF(wq, wq, pas));
1220

1221
	err = mlx5_core_create_sq(mdev, in, inlen, sqn);
1222 1223 1224 1225 1226 1227

	kvfree(in);

	return err;
}

1228 1229
int mlx5e_modify_sq(struct mlx5_core_dev *mdev, u32 sqn,
		    struct mlx5e_modify_sq_param *p)
1230 1231 1232 1233 1234 1235 1236
{
	void *in;
	void *sqc;
	int inlen;
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_sq_in);
1237
	in = kvzalloc(inlen, GFP_KERNEL);
1238 1239 1240 1241 1242
	if (!in)
		return -ENOMEM;

	sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);

1243 1244 1245
	MLX5_SET(modify_sq_in, in, sq_state, p->curr_state);
	MLX5_SET(sqc, sqc, state, p->next_state);
	if (p->rl_update && p->next_state == MLX5_SQC_STATE_RDY) {
1246
		MLX5_SET64(modify_sq_in, in, modify_bitmask, 1);
1247
		MLX5_SET(sqc,  sqc, packet_pacing_rate_limit_index, p->rl_index);
1248
	}
1249

1250
	err = mlx5_core_modify_sq(mdev, sqn, in, inlen);
1251 1252 1253 1254 1255 1256

	kvfree(in);

	return err;
}

1257
static void mlx5e_destroy_sq(struct mlx5_core_dev *mdev, u32 sqn)
1258
{
1259
	mlx5_core_destroy_sq(mdev, sqn);
1260 1261
}

1262
static int mlx5e_create_sq_rdy(struct mlx5_core_dev *mdev,
S
Saeed Mahameed 已提交
1263 1264 1265
			       struct mlx5e_sq_param *param,
			       struct mlx5e_create_sq_param *csp,
			       u32 *sqn)
1266
{
1267
	struct mlx5e_modify_sq_param msp = {0};
S
Saeed Mahameed 已提交
1268 1269
	int err;

1270
	err = mlx5e_create_sq(mdev, param, csp, sqn);
S
Saeed Mahameed 已提交
1271 1272 1273 1274 1275
	if (err)
		return err;

	msp.curr_state = MLX5_SQC_STATE_RST;
	msp.next_state = MLX5_SQC_STATE_RDY;
1276
	err = mlx5e_modify_sq(mdev, *sqn, &msp);
S
Saeed Mahameed 已提交
1277
	if (err)
1278
		mlx5e_destroy_sq(mdev, *sqn);
S
Saeed Mahameed 已提交
1279 1280 1281 1282

	return err;
}

1283 1284 1285
static int mlx5e_set_sq_maxrate(struct net_device *dev,
				struct mlx5e_txqsq *sq, u32 rate);

S
Saeed Mahameed 已提交
1286
static int mlx5e_open_txqsq(struct mlx5e_channel *c,
1287
			    u32 tisn,
1288
			    int txq_ix,
1289
			    struct mlx5e_params *params,
S
Saeed Mahameed 已提交
1290
			    struct mlx5e_sq_param *param,
1291 1292
			    struct mlx5e_txqsq *sq,
			    int tc)
S
Saeed Mahameed 已提交
1293 1294
{
	struct mlx5e_create_sq_param csp = {};
1295
	u32 tx_rate;
1296 1297
	int err;

1298
	err = mlx5e_alloc_txqsq(c, txq_ix, params, param, sq, tc);
1299 1300 1301
	if (err)
		return err;

1302
	csp.tisn            = tisn;
S
Saeed Mahameed 已提交
1303
	csp.tis_lst_sz      = 1;
1304 1305 1306
	csp.cqn             = sq->cq.mcq.cqn;
	csp.wq_ctrl         = &sq->wq_ctrl;
	csp.min_inline_mode = sq->min_inline_mode;
1307
	err = mlx5e_create_sq_rdy(c->mdev, param, &csp, &sq->sqn);
1308
	if (err)
S
Saeed Mahameed 已提交
1309
		goto err_free_txqsq;
1310

1311
	tx_rate = c->priv->tx_rates[sq->txq_ix];
1312
	if (tx_rate)
1313
		mlx5e_set_sq_maxrate(c->netdev, sq, tx_rate);
1314

1315 1316 1317
	if (params->tx_dim_enabled)
		sq->state |= BIT(MLX5E_SQ_STATE_AM);

1318 1319
	return 0;

S
Saeed Mahameed 已提交
1320 1321
err_free_txqsq:
	mlx5e_free_txqsq(sq);
1322 1323 1324 1325

	return err;
}

1326
void mlx5e_activate_txqsq(struct mlx5e_txqsq *sq)
1327
{
1328
	sq->txq = netdev_get_tx_queue(sq->channel->netdev, sq->txq_ix);
1329 1330 1331 1332 1333
	set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
	netdev_tx_reset_queue(sq->txq);
	netif_tx_start_queue(sq->txq);
}

1334
void mlx5e_tx_disable_queue(struct netdev_queue *txq)
1335 1336 1337 1338 1339 1340
{
	__netif_tx_lock_bh(txq);
	netif_tx_stop_queue(txq);
	__netif_tx_unlock_bh(txq);
}

1341
static void mlx5e_deactivate_txqsq(struct mlx5e_txqsq *sq)
1342
{
1343
	struct mlx5e_channel *c = sq->channel;
1344
	struct mlx5_wq_cyc *wq = &sq->wq;
1345

1346
	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
1347
	/* prevent netif_tx_wake_queue */
1348
	napi_synchronize(&c->napi);
1349

1350
	mlx5e_tx_disable_queue(sq->txq);
1351

S
Saeed Mahameed 已提交
1352
	/* last doorbell out, godspeed .. */
1353 1354
	if (mlx5e_wqc_has_room_for(wq, sq->cc, sq->pc, 1)) {
		u16 pi = mlx5_wq_cyc_ctr2ix(wq, sq->pc);
1355
		struct mlx5e_tx_wqe_info *wi;
S
Saeed Mahameed 已提交
1356
		struct mlx5e_tx_wqe *nop;
1357

1358 1359 1360 1361
		wi = &sq->db.wqe_info[pi];

		memset(wi, 0, sizeof(*wi));
		wi->num_wqebbs = 1;
1362 1363
		nop = mlx5e_post_nop(wq, sq->sqn, &sq->pc);
		mlx5e_notify_hw(wq, sq->pc, sq->uar_map, &nop->ctrl);
1364
	}
1365 1366 1367 1368 1369
}

static void mlx5e_close_txqsq(struct mlx5e_txqsq *sq)
{
	struct mlx5e_channel *c = sq->channel;
1370
	struct mlx5_core_dev *mdev = c->mdev;
1371
	struct mlx5_rate_limit rl = {0};
1372

1373
	cancel_work_sync(&sq->dim.work);
1374
	cancel_work_sync(&sq->recover_work);
1375
	mlx5e_destroy_sq(mdev, sq->sqn);
1376 1377 1378 1379
	if (sq->rate_limit) {
		rl.rate = sq->rate_limit;
		mlx5_rl_remove_rate(mdev, &rl);
	}
S
Saeed Mahameed 已提交
1380 1381 1382 1383
	mlx5e_free_txqsq_descs(sq);
	mlx5e_free_txqsq(sq);
}

1384
static void mlx5e_tx_err_cqe_work(struct work_struct *recover_work)
1385
{
1386 1387
	struct mlx5e_txqsq *sq = container_of(recover_work, struct mlx5e_txqsq,
					      recover_work);
1388

1389
	mlx5e_reporter_tx_err_cqe(sq);
1390 1391
}

1392 1393
int mlx5e_open_icosq(struct mlx5e_channel *c, struct mlx5e_params *params,
		     struct mlx5e_sq_param *param, struct mlx5e_icosq *sq)
S
Saeed Mahameed 已提交
1394 1395 1396 1397
{
	struct mlx5e_create_sq_param csp = {};
	int err;

1398
	err = mlx5e_alloc_icosq(c, param, sq);
S
Saeed Mahameed 已提交
1399 1400 1401 1402 1403
	if (err)
		return err;

	csp.cqn             = sq->cq.mcq.cqn;
	csp.wq_ctrl         = &sq->wq_ctrl;
1404
	csp.min_inline_mode = params->tx_min_inline_mode;
1405
	err = mlx5e_create_sq_rdy(c->mdev, param, &csp, &sq->sqn);
S
Saeed Mahameed 已提交
1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416
	if (err)
		goto err_free_icosq;

	return 0;

err_free_icosq:
	mlx5e_free_icosq(sq);

	return err;
}

1417
void mlx5e_activate_icosq(struct mlx5e_icosq *icosq)
S
Saeed Mahameed 已提交
1418
{
1419 1420
	set_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
}
S
Saeed Mahameed 已提交
1421

1422
void mlx5e_deactivate_icosq(struct mlx5e_icosq *icosq)
1423 1424 1425 1426
{
	struct mlx5e_channel *c = icosq->channel;

	clear_bit(MLX5E_SQ_STATE_ENABLED, &icosq->state);
S
Saeed Mahameed 已提交
1427
	napi_synchronize(&c->napi);
1428 1429 1430 1431 1432
}

void mlx5e_close_icosq(struct mlx5e_icosq *sq)
{
	struct mlx5e_channel *c = sq->channel;
S
Saeed Mahameed 已提交
1433

1434
	mlx5e_destroy_sq(c->mdev, sq->sqn);
S
Saeed Mahameed 已提交
1435 1436 1437
	mlx5e_free_icosq(sq);
}

1438 1439 1440
int mlx5e_open_xdpsq(struct mlx5e_channel *c, struct mlx5e_params *params,
		     struct mlx5e_sq_param *param, struct xdp_umem *umem,
		     struct mlx5e_xdpsq *sq, bool is_redirect)
S
Saeed Mahameed 已提交
1441 1442 1443 1444
{
	struct mlx5e_create_sq_param csp = {};
	int err;

1445
	err = mlx5e_alloc_xdpsq(c, params, umem, param, sq, is_redirect);
S
Saeed Mahameed 已提交
1446 1447 1448 1449
	if (err)
		return err;

	csp.tis_lst_sz      = 1;
1450
	csp.tisn            = c->priv->tisn[c->lag_port][0]; /* tc = 0 */
S
Saeed Mahameed 已提交
1451 1452 1453 1454
	csp.cqn             = sq->cq.mcq.cqn;
	csp.wq_ctrl         = &sq->wq_ctrl;
	csp.min_inline_mode = sq->min_inline_mode;
	set_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
1455
	err = mlx5e_create_sq_rdy(c->mdev, param, &csp, &sq->sqn);
S
Saeed Mahameed 已提交
1456 1457 1458
	if (err)
		goto err_free_xdpsq;

1459 1460 1461 1462 1463 1464
	mlx5e_set_xmit_fp(sq, param->is_mpw);

	if (!param->is_mpw) {
		unsigned int ds_cnt = MLX5E_XDP_TX_DS_COUNT;
		unsigned int inline_hdr_sz = 0;
		int i;
S
Saeed Mahameed 已提交
1465

1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477
		if (sq->min_inline_mode != MLX5_INLINE_MODE_NONE) {
			inline_hdr_sz = MLX5E_XDP_MIN_INLINE;
			ds_cnt++;
		}

		/* Pre initialize fixed WQE fields */
		for (i = 0; i < mlx5_wq_cyc_get_size(&sq->wq); i++) {
			struct mlx5e_xdp_wqe_info *wi  = &sq->db.wqe_info[i];
			struct mlx5e_tx_wqe      *wqe  = mlx5_wq_cyc_get_wqe(&sq->wq, i);
			struct mlx5_wqe_ctrl_seg *cseg = &wqe->ctrl;
			struct mlx5_wqe_eth_seg  *eseg = &wqe->eth;
			struct mlx5_wqe_data_seg *dseg;
S
Saeed Mahameed 已提交
1478

1479 1480
			cseg->qpn_ds = cpu_to_be32((sq->sqn << 8) | ds_cnt);
			eseg->inline_hdr.sz = cpu_to_be16(inline_hdr_sz);
S
Saeed Mahameed 已提交
1481

1482 1483
			dseg = (struct mlx5_wqe_data_seg *)cseg + (ds_cnt - 1);
			dseg->lkey = sq->mkey_be;
1484

1485
			wi->num_wqebbs = 1;
1486
			wi->num_pkts   = 1;
1487
		}
S
Saeed Mahameed 已提交
1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498
	}

	return 0;

err_free_xdpsq:
	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
	mlx5e_free_xdpsq(sq);

	return err;
}

1499
void mlx5e_close_xdpsq(struct mlx5e_xdpsq *sq)
S
Saeed Mahameed 已提交
1500 1501 1502 1503 1504 1505
{
	struct mlx5e_channel *c = sq->channel;

	clear_bit(MLX5E_SQ_STATE_ENABLED, &sq->state);
	napi_synchronize(&c->napi);

1506
	mlx5e_destroy_sq(c->mdev, sq->sqn);
1507
	mlx5e_free_xdpsq_descs(sq);
S
Saeed Mahameed 已提交
1508
	mlx5e_free_xdpsq(sq);
1509 1510
}

1511 1512 1513
static int mlx5e_alloc_cq_common(struct mlx5_core_dev *mdev,
				 struct mlx5e_cq_param *param,
				 struct mlx5e_cq *cq)
1514 1515 1516
{
	struct mlx5_core_cq *mcq = &cq->mcq;
	int eqn_not_used;
1517
	unsigned int irqn;
1518 1519 1520
	int err;
	u32 i;

1521 1522 1523 1524
	err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn);
	if (err)
		return err;

1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545
	err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
			       &cq->wq_ctrl);
	if (err)
		return err;

	mcq->cqe_sz     = 64;
	mcq->set_ci_db  = cq->wq_ctrl.db.db;
	mcq->arm_db     = cq->wq_ctrl.db.db + 1;
	*mcq->set_ci_db = 0;
	*mcq->arm_db    = 0;
	mcq->vector     = param->eq_ix;
	mcq->comp       = mlx5e_completion_event;
	mcq->event      = mlx5e_cq_error_event;
	mcq->irqn       = irqn;

	for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) {
		struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(&cq->wq, i);

		cqe->op_own = 0xf1;
	}

1546
	cq->mdev = mdev;
1547 1548 1549 1550

	return 0;
}

1551 1552 1553 1554 1555 1556 1557
static int mlx5e_alloc_cq(struct mlx5e_channel *c,
			  struct mlx5e_cq_param *param,
			  struct mlx5e_cq *cq)
{
	struct mlx5_core_dev *mdev = c->priv->mdev;
	int err;

1558 1559
	param->wq.buf_numa_node = cpu_to_node(c->cpu);
	param->wq.db_numa_node  = cpu_to_node(c->cpu);
1560 1561 1562 1563 1564 1565 1566 1567 1568 1569
	param->eq_ix   = c->ix;

	err = mlx5e_alloc_cq_common(mdev, param, cq);

	cq->napi    = &c->napi;
	cq->channel = c;

	return err;
}

1570
static void mlx5e_free_cq(struct mlx5e_cq *cq)
1571
{
1572
	mlx5_wq_destroy(&cq->wq_ctrl);
1573 1574
}

1575
static int mlx5e_create_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param)
1576
{
1577
	u32 out[MLX5_ST_SZ_DW(create_cq_out)];
1578
	struct mlx5_core_dev *mdev = cq->mdev;
1579 1580 1581 1582 1583
	struct mlx5_core_cq *mcq = &cq->mcq;

	void *in;
	void *cqc;
	int inlen;
1584
	unsigned int irqn_not_used;
1585 1586 1587
	int eqn;
	int err;

1588 1589 1590 1591
	err = mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used);
	if (err)
		return err;

1592
	inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
1593
		sizeof(u64) * cq->wq_ctrl.buf.npages;
1594
	in = kvzalloc(inlen, GFP_KERNEL);
1595 1596 1597 1598 1599 1600 1601
	if (!in)
		return -ENOMEM;

	cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);

	memcpy(cqc, param->cqc, sizeof(param->cqc));

1602
	mlx5_fill_page_frag_array(&cq->wq_ctrl.buf,
1603
				  (__be64 *)MLX5_ADDR_OF(create_cq_in, in, pas));
1604

T
Tariq Toukan 已提交
1605
	MLX5_SET(cqc,   cqc, cq_period_mode, param->cq_period_mode);
1606
	MLX5_SET(cqc,   cqc, c_eqn,         eqn);
E
Eli Cohen 已提交
1607
	MLX5_SET(cqc,   cqc, uar_page,      mdev->priv.uar->index);
1608
	MLX5_SET(cqc,   cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
1609
					    MLX5_ADAPTER_PAGE_SHIFT);
1610 1611
	MLX5_SET64(cqc, cqc, dbr_addr,      cq->wq_ctrl.db.dma);

1612
	err = mlx5_core_create_cq(mdev, mcq, in, inlen, out, sizeof(out));
1613 1614 1615 1616 1617 1618 1619 1620 1621 1622 1623

	kvfree(in);

	if (err)
		return err;

	mlx5e_cq_arm(cq);

	return 0;
}

1624
static void mlx5e_destroy_cq(struct mlx5e_cq *cq)
1625
{
1626
	mlx5_core_destroy_cq(cq->mdev, &cq->mcq);
1627 1628
}

1629
int mlx5e_open_cq(struct mlx5e_channel *c, struct dim_cq_moder moder,
1630
		  struct mlx5e_cq_param *param, struct mlx5e_cq *cq)
1631
{
1632
	struct mlx5_core_dev *mdev = c->mdev;
1633 1634
	int err;

1635
	err = mlx5e_alloc_cq(c, param, cq);
1636 1637 1638
	if (err)
		return err;

1639
	err = mlx5e_create_cq(cq, param);
1640
	if (err)
1641
		goto err_free_cq;
1642

1643
	if (MLX5_CAP_GEN(mdev, cq_moderation))
1644
		mlx5_core_modify_cq_moderation(mdev, &cq->mcq, moder.usec, moder.pkts);
1645 1646
	return 0;

1647 1648
err_free_cq:
	mlx5e_free_cq(cq);
1649 1650 1651 1652

	return err;
}

1653
void mlx5e_close_cq(struct mlx5e_cq *cq)
1654 1655
{
	mlx5e_destroy_cq(cq);
1656
	mlx5e_free_cq(cq);
1657 1658 1659
}

static int mlx5e_open_tx_cqs(struct mlx5e_channel *c,
1660
			     struct mlx5e_params *params,
1661 1662 1663 1664 1665 1666
			     struct mlx5e_channel_param *cparam)
{
	int err;
	int tc;

	for (tc = 0; tc < c->num_tc; tc++) {
1667 1668
		err = mlx5e_open_cq(c, params->tx_cq_moderation,
				    &cparam->tx_cq, &c->sq[tc].cq);
1669 1670 1671 1672 1673 1674 1675 1676 1677 1678 1679 1680 1681 1682 1683 1684 1685 1686 1687 1688 1689 1690
		if (err)
			goto err_close_tx_cqs;
	}

	return 0;

err_close_tx_cqs:
	for (tc--; tc >= 0; tc--)
		mlx5e_close_cq(&c->sq[tc].cq);

	return err;
}

static void mlx5e_close_tx_cqs(struct mlx5e_channel *c)
{
	int tc;

	for (tc = 0; tc < c->num_tc; tc++)
		mlx5e_close_cq(&c->sq[tc].cq);
}

static int mlx5e_open_sqs(struct mlx5e_channel *c,
1691
			  struct mlx5e_params *params,
1692 1693
			  struct mlx5e_channel_param *cparam)
{
1694
	int err, tc;
1695

1696
	for (tc = 0; tc < params->num_tc; tc++) {
1697
		int txq_ix = c->ix + tc * params->num_channels;
1698

1699
		err = mlx5e_open_txqsq(c, c->priv->tisn[c->lag_port][tc], txq_ix,
1700
				       params, &cparam->sq, &c->sq[tc], tc);
1701 1702 1703 1704 1705 1706 1707 1708
		if (err)
			goto err_close_sqs;
	}

	return 0;

err_close_sqs:
	for (tc--; tc >= 0; tc--)
S
Saeed Mahameed 已提交
1709
		mlx5e_close_txqsq(&c->sq[tc]);
1710 1711 1712 1713 1714 1715 1716 1717 1718

	return err;
}

static void mlx5e_close_sqs(struct mlx5e_channel *c)
{
	int tc;

	for (tc = 0; tc < c->num_tc; tc++)
S
Saeed Mahameed 已提交
1719
		mlx5e_close_txqsq(&c->sq[tc]);
1720 1721
}

1722
static int mlx5e_set_sq_maxrate(struct net_device *dev,
S
Saeed Mahameed 已提交
1723
				struct mlx5e_txqsq *sq, u32 rate)
1724 1725 1726
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;
1727
	struct mlx5e_modify_sq_param msp = {0};
1728
	struct mlx5_rate_limit rl = {0};
1729 1730 1731 1732 1733 1734 1735
	u16 rl_index = 0;
	int err;

	if (rate == sq->rate_limit)
		/* nothing to do */
		return 0;

1736 1737
	if (sq->rate_limit) {
		rl.rate = sq->rate_limit;
1738
		/* remove current rl index to free space to next ones */
1739 1740
		mlx5_rl_remove_rate(mdev, &rl);
	}
1741 1742 1743 1744

	sq->rate_limit = 0;

	if (rate) {
1745 1746
		rl.rate = rate;
		err = mlx5_rl_add_rate(mdev, &rl_index, &rl);
1747 1748 1749 1750 1751 1752 1753
		if (err) {
			netdev_err(dev, "Failed configuring rate %u: %d\n",
				   rate, err);
			return err;
		}
	}

1754 1755 1756 1757
	msp.curr_state = MLX5_SQC_STATE_RDY;
	msp.next_state = MLX5_SQC_STATE_RDY;
	msp.rl_index   = rl_index;
	msp.rl_update  = true;
1758
	err = mlx5e_modify_sq(mdev, sq->sqn, &msp);
1759 1760 1761 1762 1763
	if (err) {
		netdev_err(dev, "Failed configuring rate %u: %d\n",
			   rate, err);
		/* remove the rate from the table */
		if (rate)
1764
			mlx5_rl_remove_rate(mdev, &rl);
1765 1766 1767 1768 1769 1770 1771 1772 1773 1774 1775
		return err;
	}

	sq->rate_limit = rate;
	return 0;
}

static int mlx5e_set_tx_maxrate(struct net_device *dev, int index, u32 rate)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;
1776
	struct mlx5e_txqsq *sq = priv->txq2sq[index];
1777 1778 1779 1780 1781 1782 1783 1784 1785 1786 1787 1788 1789 1790 1791 1792 1793 1794 1795 1796 1797 1798 1799 1800 1801 1802
	int err = 0;

	if (!mlx5_rl_is_supported(mdev)) {
		netdev_err(dev, "Rate limiting is not supported on this device\n");
		return -EINVAL;
	}

	/* rate is given in Mb/sec, HW config is in Kb/sec */
	rate = rate << 10;

	/* Check whether rate in valid range, 0 is always valid */
	if (rate && !mlx5_rl_is_in_range(mdev, rate)) {
		netdev_err(dev, "TX rate %u, is not in range\n", rate);
		return -ERANGE;
	}

	mutex_lock(&priv->state_lock);
	if (test_bit(MLX5E_STATE_OPENED, &priv->state))
		err = mlx5e_set_sq_maxrate(dev, sq, rate);
	if (!err)
		priv->tx_rates[index] = rate;
	mutex_unlock(&priv->state_lock);

	return err;
}

1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815 1816 1817 1818 1819 1820 1821 1822 1823 1824 1825
static int mlx5e_alloc_xps_cpumask(struct mlx5e_channel *c,
				   struct mlx5e_params *params)
{
	int num_comp_vectors = mlx5_comp_vectors_count(c->mdev);
	int irq;

	if (!zalloc_cpumask_var(&c->xps_cpumask, GFP_KERNEL))
		return -ENOMEM;

	for (irq = c->ix; irq < num_comp_vectors; irq += params->num_channels) {
		int cpu = cpumask_first(mlx5_comp_irq_get_affinity_mask(c->mdev, irq));

		cpumask_set_cpu(cpu, c->xps_cpumask);
	}

	return 0;
}

static void mlx5e_free_xps_cpumask(struct mlx5e_channel *c)
{
	free_cpumask_var(c->xps_cpumask);
}

1826 1827 1828
static int mlx5e_open_queues(struct mlx5e_channel *c,
			     struct mlx5e_params *params,
			     struct mlx5e_channel_param *cparam)
1829
{
1830
	struct dim_cq_moder icocq_moder = {0, 0};
1831 1832
	int err;

1833
	err = mlx5e_open_cq(c, icocq_moder, &cparam->icosq_cq, &c->icosq.cq);
1834
	if (err)
1835
		return err;
1836

1837
	err = mlx5e_open_tx_cqs(c, params, cparam);
T
Tariq Toukan 已提交
1838 1839 1840
	if (err)
		goto err_close_icosq_cq;

1841
	err = mlx5e_open_cq(c, params->tx_cq_moderation, &cparam->tx_cq, &c->xdpsq.cq);
1842 1843 1844
	if (err)
		goto err_close_tx_cqs;

1845 1846 1847 1848
	err = mlx5e_open_cq(c, params->rx_cq_moderation, &cparam->rx_cq, &c->rq.cq);
	if (err)
		goto err_close_xdp_tx_cqs;

1849
	/* XDP SQ CQ params are same as normal TXQ sq CQ params */
1850
	err = c->xdp ? mlx5e_open_cq(c, params->tx_cq_moderation,
1851
				     &cparam->tx_cq, &c->rq_xdpsq.cq) : 0;
1852 1853 1854
	if (err)
		goto err_close_rx_cq;

1855 1856
	napi_enable(&c->napi);

1857
	err = mlx5e_open_icosq(c, params, &cparam->icosq, &c->icosq);
1858 1859 1860
	if (err)
		goto err_disable_napi;

1861
	err = mlx5e_open_sqs(c, params, cparam);
T
Tariq Toukan 已提交
1862 1863 1864
	if (err)
		goto err_close_icosq;

1865
	if (c->xdp) {
1866
		err = mlx5e_open_xdpsq(c, params, &cparam->xdp_sq, NULL,
1867 1868 1869 1870
				       &c->rq_xdpsq, false);
		if (err)
			goto err_close_sqs;
	}
1871

1872
	err = mlx5e_open_rq(c, params, &cparam->rq, NULL, NULL, &c->rq);
1873
	if (err)
1874
		goto err_close_xdp_sq;
1875

1876
	err = mlx5e_open_xdpsq(c, params, &cparam->xdp_sq, NULL, &c->xdpsq, true);
1877 1878 1879
	if (err)
		goto err_close_rq;

1880
	return 0;
1881 1882 1883 1884

err_close_rq:
	mlx5e_close_rq(&c->rq);

1885
err_close_xdp_sq:
1886
	if (c->xdp)
1887
		mlx5e_close_xdpsq(&c->rq_xdpsq);
1888 1889 1890 1891

err_close_sqs:
	mlx5e_close_sqs(c);

T
Tariq Toukan 已提交
1892
err_close_icosq:
S
Saeed Mahameed 已提交
1893
	mlx5e_close_icosq(&c->icosq);
T
Tariq Toukan 已提交
1894

1895 1896
err_disable_napi:
	napi_disable(&c->napi);
1897

1898
	if (c->xdp)
1899
		mlx5e_close_cq(&c->rq_xdpsq.cq);
1900 1901

err_close_rx_cq:
1902 1903
	mlx5e_close_cq(&c->rq.cq);

1904 1905 1906
err_close_xdp_tx_cqs:
	mlx5e_close_cq(&c->xdpsq.cq);

1907 1908 1909
err_close_tx_cqs:
	mlx5e_close_tx_cqs(c);

T
Tariq Toukan 已提交
1910 1911 1912
err_close_icosq_cq:
	mlx5e_close_cq(&c->icosq.cq);

1913 1914 1915 1916 1917 1918 1919 1920 1921 1922 1923 1924 1925 1926 1927 1928 1929 1930 1931 1932
	return err;
}

static void mlx5e_close_queues(struct mlx5e_channel *c)
{
	mlx5e_close_xdpsq(&c->xdpsq);
	mlx5e_close_rq(&c->rq);
	if (c->xdp)
		mlx5e_close_xdpsq(&c->rq_xdpsq);
	mlx5e_close_sqs(c);
	mlx5e_close_icosq(&c->icosq);
	napi_disable(&c->napi);
	if (c->xdp)
		mlx5e_close_cq(&c->rq_xdpsq.cq);
	mlx5e_close_cq(&c->rq.cq);
	mlx5e_close_cq(&c->xdpsq.cq);
	mlx5e_close_tx_cqs(c);
	mlx5e_close_cq(&c->icosq.cq);
}

1933 1934 1935 1936 1937 1938 1939
static u8 mlx5e_enumerate_lag_port(struct mlx5_core_dev *mdev, int ix)
{
	u16 port_aff_bias = mlx5_core_is_pf(mdev) ? 0 : MLX5_CAP_GEN(mdev, vhca_id);

	return (ix + port_aff_bias) % mlx5e_get_num_lag_ports(mdev);
}

1940 1941 1942
static int mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
			      struct mlx5e_params *params,
			      struct mlx5e_channel_param *cparam,
1943
			      struct xdp_umem *umem,
1944 1945 1946 1947
			      struct mlx5e_channel **cp)
{
	int cpu = cpumask_first(mlx5_comp_irq_get_affinity_mask(priv->mdev, ix));
	struct net_device *netdev = priv->netdev;
1948
	struct mlx5e_xsk_param xsk;
1949 1950 1951 1952 1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973
	struct mlx5e_channel *c;
	unsigned int irq;
	int err;
	int eqn;

	err = mlx5_vector2eqn(priv->mdev, ix, &eqn, &irq);
	if (err)
		return err;

	c = kvzalloc_node(sizeof(*c), GFP_KERNEL, cpu_to_node(cpu));
	if (!c)
		return -ENOMEM;

	c->priv     = priv;
	c->mdev     = priv->mdev;
	c->tstamp   = &priv->tstamp;
	c->ix       = ix;
	c->cpu      = cpu;
	c->pdev     = priv->mdev->device;
	c->netdev   = priv->netdev;
	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;
	c->irq_desc = irq_to_desc(irq);
1974
	c->lag_port = mlx5e_enumerate_lag_port(priv->mdev, ix);
1975 1976 1977 1978 1979 1980 1981 1982 1983 1984 1985

	err = mlx5e_alloc_xps_cpumask(c, params);
	if (err)
		goto err_free_channel;

	netif_napi_add(netdev, &c->napi, mlx5e_napi_poll, 64);

	err = mlx5e_open_queues(c, params, cparam);
	if (unlikely(err))
		goto err_napi_del;

1986 1987 1988 1989 1990 1991 1992
	if (umem) {
		mlx5e_build_xsk_param(umem, &xsk);
		err = mlx5e_open_xsk(priv, params, &xsk, umem, c);
		if (unlikely(err))
			goto err_close_queues;
	}

1993 1994 1995 1996
	*cp = c;

	return 0;

1997 1998 1999
err_close_queues:
	mlx5e_close_queues(c);

2000 2001
err_napi_del:
	netif_napi_del(&c->napi);
2002 2003 2004
	mlx5e_free_xps_cpumask(c);

err_free_channel:
2005
	kvfree(c);
2006 2007 2008 2009

	return err;
}

2010 2011 2012 2013 2014 2015
static void mlx5e_activate_channel(struct mlx5e_channel *c)
{
	int tc;

	for (tc = 0; tc < c->num_tc; tc++)
		mlx5e_activate_txqsq(&c->sq[tc]);
2016
	mlx5e_activate_icosq(&c->icosq);
2017
	mlx5e_activate_rq(&c->rq);
2018
	netif_set_xps_queue(c->netdev, c->xps_cpumask, c->ix);
2019 2020 2021

	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
		mlx5e_activate_xsk(c);
2022 2023 2024 2025 2026 2027
}

static void mlx5e_deactivate_channel(struct mlx5e_channel *c)
{
	int tc;

2028 2029 2030
	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
		mlx5e_deactivate_xsk(c);

2031
	mlx5e_deactivate_rq(&c->rq);
2032
	mlx5e_deactivate_icosq(&c->icosq);
2033 2034 2035 2036
	for (tc = 0; tc < c->num_tc; tc++)
		mlx5e_deactivate_txqsq(&c->sq[tc]);
}

2037 2038
static void mlx5e_close_channel(struct mlx5e_channel *c)
{
2039 2040
	if (test_bit(MLX5E_CHANNEL_STATE_XSK, c->state))
		mlx5e_close_xsk(c);
2041
	mlx5e_close_queues(c);
2042
	netif_napi_del(&c->napi);
2043
	mlx5e_free_xps_cpumask(c);
E
Eric Dumazet 已提交
2044

2045
	kvfree(c);
2046 2047
}

2048 2049 2050 2051
#define DEFAULT_FRAG_SIZE (2048)

static void mlx5e_build_rq_frags_info(struct mlx5_core_dev *mdev,
				      struct mlx5e_params *params,
2052
				      struct mlx5e_xsk_param *xsk,
2053 2054 2055 2056 2057 2058 2059 2060 2061 2062 2063 2064
				      struct mlx5e_rq_frags_info *info)
{
	u32 byte_count = MLX5E_SW2HW_MTU(params, params->sw_mtu);
	int frag_size_max = DEFAULT_FRAG_SIZE;
	u32 buf_size = 0;
	int i;

#ifdef CONFIG_MLX5_EN_IPSEC
	if (MLX5_IPSEC_DEV(mdev))
		byte_count += MLX5E_METADATA_ETHER_LEN;
#endif

2065
	if (mlx5e_rx_is_linear_skb(params, xsk)) {
2066 2067
		int frag_stride;

2068
		frag_stride = mlx5e_rx_get_linear_frag_sz(params, xsk);
2069 2070 2071 2072 2073 2074 2075 2076 2077 2078 2079 2080 2081 2082 2083 2084 2085 2086 2087 2088 2089 2090 2091 2092 2093 2094 2095 2096 2097 2098 2099 2100 2101 2102 2103
		frag_stride = roundup_pow_of_two(frag_stride);

		info->arr[0].frag_size = byte_count;
		info->arr[0].frag_stride = frag_stride;
		info->num_frags = 1;
		info->wqe_bulk = PAGE_SIZE / frag_stride;
		goto out;
	}

	if (byte_count > PAGE_SIZE +
	    (MLX5E_MAX_RX_FRAGS - 1) * frag_size_max)
		frag_size_max = PAGE_SIZE;

	i = 0;
	while (buf_size < byte_count) {
		int frag_size = byte_count - buf_size;

		if (i < MLX5E_MAX_RX_FRAGS - 1)
			frag_size = min(frag_size, frag_size_max);

		info->arr[i].frag_size = frag_size;
		info->arr[i].frag_stride = roundup_pow_of_two(frag_size);

		buf_size += frag_size;
		i++;
	}
	info->num_frags = i;
	/* number of different wqes sharing a page */
	info->wqe_bulk = 1 + (info->num_frags % 2);

out:
	info->wqe_bulk = max_t(u8, info->wqe_bulk, 8);
	info->log_num_frags = order_base_2(info->num_frags);
}

2104 2105 2106 2107 2108 2109 2110 2111 2112 2113 2114 2115 2116 2117 2118
static inline u8 mlx5e_get_rqwq_log_stride(u8 wq_type, int ndsegs)
{
	int sz = sizeof(struct mlx5_wqe_data_seg) * ndsegs;

	switch (wq_type) {
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
		sz += sizeof(struct mlx5e_rx_wqe_ll);
		break;
	default: /* MLX5_WQ_TYPE_CYCLIC */
		sz += sizeof(struct mlx5e_rx_wqe_cyc);
	}

	return order_base_2(sz);
}

2119 2120 2121 2122 2123 2124 2125
static u8 mlx5e_get_rq_log_wq_sz(void *rqc)
{
	void *wq = MLX5_ADDR_OF(rqc, rqc, wq);

	return MLX5_GET(wq, wq, log_wq_sz);
}

2126 2127 2128 2129
void mlx5e_build_rq_param(struct mlx5e_priv *priv,
			  struct mlx5e_params *params,
			  struct mlx5e_xsk_param *xsk,
			  struct mlx5e_rq_param *param)
2130
{
2131
	struct mlx5_core_dev *mdev = priv->mdev;
2132 2133
	void *rqc = param->rqc;
	void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
2134
	int ndsegs = 1;
2135

2136
	switch (params->rq_wq_type) {
2137
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
2138
		MLX5_SET(wq, wq, log_wqe_num_of_strides,
2139
			 mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk) -
2140
			 MLX5_MPWQE_LOG_NUM_STRIDES_BASE);
2141
		MLX5_SET(wq, wq, log_wqe_stride_size,
2142
			 mlx5e_mpwqe_get_log_stride_size(mdev, params, xsk) -
2143
			 MLX5_MPWQE_LOG_STRIDE_SZ_BASE);
2144
		MLX5_SET(wq, wq, log_wq_sz, mlx5e_mpwqe_get_log_rq_size(params, xsk));
2145
		break;
2146
	default: /* MLX5_WQ_TYPE_CYCLIC */
2147
		MLX5_SET(wq, wq, log_wq_sz, params->log_rq_mtu_frames);
2148
		mlx5e_build_rq_frags_info(mdev, params, xsk, &param->frags_info);
2149
		ndsegs = param->frags_info.num_frags;
2150 2151
	}

2152
	MLX5_SET(wq, wq, wq_type,          params->rq_wq_type);
2153
	MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);
2154 2155
	MLX5_SET(wq, wq, log_wq_stride,
		 mlx5e_get_rqwq_log_stride(params->rq_wq_type, ndsegs));
2156
	MLX5_SET(wq, wq, pd,               mdev->mlx5e_res.pdn);
2157
	MLX5_SET(rqc, rqc, counter_set_id, priv->q_counter);
2158
	MLX5_SET(rqc, rqc, vsd,            params->vlan_strip_disable);
2159
	MLX5_SET(rqc, rqc, scatter_fcs,    params->scatter_fcs_en);
2160

2161
	param->wq.buf_numa_node = dev_to_node(mdev->device);
2162 2163
}

2164
static void mlx5e_build_drop_rq_param(struct mlx5e_priv *priv,
2165
				      struct mlx5e_rq_param *param)
2166
{
2167
	struct mlx5_core_dev *mdev = priv->mdev;
2168 2169 2170
	void *rqc = param->rqc;
	void *wq = MLX5_ADDR_OF(rqc, rqc, wq);

2171 2172 2173
	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
	MLX5_SET(wq, wq, log_wq_stride,
		 mlx5e_get_rqwq_log_stride(MLX5_WQ_TYPE_CYCLIC, 1));
2174
	MLX5_SET(rqc, rqc, counter_set_id, priv->drop_rq_q_counter);
2175

2176
	param->wq.buf_numa_node = dev_to_node(mdev->device);
2177 2178
}

2179 2180
void mlx5e_build_sq_param_common(struct mlx5e_priv *priv,
				 struct mlx5e_sq_param *param)
2181 2182 2183 2184 2185
{
	void *sqc = param->sqc;
	void *wq = MLX5_ADDR_OF(sqc, sqc, wq);

	MLX5_SET(wq, wq, log_wq_stride, ilog2(MLX5_SEND_WQE_BB));
2186
	MLX5_SET(wq, wq, pd,            priv->mdev->mlx5e_res.pdn);
2187

2188
	param->wq.buf_numa_node = dev_to_node(priv->mdev->device);
T
Tariq Toukan 已提交
2189 2190 2191
}

static void mlx5e_build_sq_param(struct mlx5e_priv *priv,
2192
				 struct mlx5e_params *params,
T
Tariq Toukan 已提交
2193 2194 2195 2196
				 struct mlx5e_sq_param *param)
{
	void *sqc = param->sqc;
	void *wq = MLX5_ADDR_OF(sqc, sqc, wq);
2197
	bool allow_swp;
T
Tariq Toukan 已提交
2198

2199 2200
	allow_swp = mlx5_geneve_tx_allowed(priv->mdev) ||
		    !!MLX5_IPSEC_DEV(priv->mdev);
T
Tariq Toukan 已提交
2201
	mlx5e_build_sq_param_common(priv, param);
2202
	MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size);
2203
	MLX5_SET(sqc, sqc, allow_swp, allow_swp);
2204 2205 2206 2207 2208 2209 2210
}

static void mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
					struct mlx5e_cq_param *param)
{
	void *cqc = param->cqc;

E
Eli Cohen 已提交
2211
	MLX5_SET(cqc, cqc, uar_page, priv->mdev->priv.uar->index);
2212 2213
	if (MLX5_CAP_GEN(priv->mdev, cqe_128_always) && cache_line_size() >= 128)
		MLX5_SET(cqc, cqc, cqe_sz, CQE_STRIDE_128_PAD);
2214 2215
}

2216 2217 2218 2219
void mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
			     struct mlx5e_params *params,
			     struct mlx5e_xsk_param *xsk,
			     struct mlx5e_cq_param *param)
2220
{
2221
	struct mlx5_core_dev *mdev = priv->mdev;
2222
	void *cqc = param->cqc;
2223
	u8 log_cq_size;
2224

2225
	switch (params->rq_wq_type) {
2226
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
2227 2228
		log_cq_size = mlx5e_mpwqe_get_log_rq_size(params, xsk) +
			mlx5e_mpwqe_get_log_num_strides(mdev, params, xsk);
2229
		break;
2230
	default: /* MLX5_WQ_TYPE_CYCLIC */
2231
		log_cq_size = params->log_rq_mtu_frames;
2232 2233 2234
	}

	MLX5_SET(cqc, cqc, log_cq_size, log_cq_size);
2235
	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)) {
T
Tariq Toukan 已提交
2236 2237 2238
		MLX5_SET(cqc, cqc, mini_cqe_res_format, MLX5_CQE_FORMAT_CSUM);
		MLX5_SET(cqc, cqc, cqe_comp_en, 1);
	}
2239 2240

	mlx5e_build_common_cq_param(priv, param);
2241
	param->cq_period_mode = params->rx_cq_moderation.cq_period_mode;
2242 2243
}

2244 2245 2246
void mlx5e_build_tx_cq_param(struct mlx5e_priv *priv,
			     struct mlx5e_params *params,
			     struct mlx5e_cq_param *param)
2247 2248 2249
{
	void *cqc = param->cqc;

2250
	MLX5_SET(cqc, cqc, log_cq_size, params->log_sq_size);
2251 2252

	mlx5e_build_common_cq_param(priv, param);
2253
	param->cq_period_mode = params->tx_cq_moderation.cq_period_mode;
2254 2255
}

2256 2257 2258
void mlx5e_build_ico_cq_param(struct mlx5e_priv *priv,
			      u8 log_wq_size,
			      struct mlx5e_cq_param *param)
T
Tariq Toukan 已提交
2259 2260 2261 2262 2263 2264
{
	void *cqc = param->cqc;

	MLX5_SET(cqc, cqc, log_cq_size, log_wq_size);

	mlx5e_build_common_cq_param(priv, param);
T
Tariq Toukan 已提交
2265

2266
	param->cq_period_mode = DIM_CQ_PERIOD_MODE_START_FROM_EQE;
T
Tariq Toukan 已提交
2267 2268
}

2269 2270 2271
void mlx5e_build_icosq_param(struct mlx5e_priv *priv,
			     u8 log_wq_size,
			     struct mlx5e_sq_param *param)
T
Tariq Toukan 已提交
2272 2273 2274 2275 2276 2277 2278
{
	void *sqc = param->sqc;
	void *wq = MLX5_ADDR_OF(sqc, sqc, wq);

	mlx5e_build_sq_param_common(priv, param);

	MLX5_SET(wq, wq, log_wq_sz, log_wq_size);
2279
	MLX5_SET(sqc, sqc, reg_umr, MLX5_CAP_ETH(priv->mdev, reg_umr_sq));
T
Tariq Toukan 已提交
2280 2281
}

2282 2283 2284
void mlx5e_build_xdpsq_param(struct mlx5e_priv *priv,
			     struct mlx5e_params *params,
			     struct mlx5e_sq_param *param)
2285 2286 2287 2288 2289
{
	void *sqc = param->sqc;
	void *wq = MLX5_ADDR_OF(sqc, sqc, wq);

	mlx5e_build_sq_param_common(priv, param);
2290
	MLX5_SET(wq, wq, log_wq_sz, params->log_sq_size);
2291
	param->is_mpw = MLX5E_GET_PFLAG(params, MLX5E_PFLAG_XDP_TX_MPWQE);
2292 2293
}

2294 2295 2296 2297 2298 2299 2300 2301 2302 2303 2304 2305
static u8 mlx5e_build_icosq_log_wq_sz(struct mlx5e_params *params,
				      struct mlx5e_rq_param *rqp)
{
	switch (params->rq_wq_type) {
	case MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ:
		return order_base_2(MLX5E_UMR_WQEBBS) +
			mlx5e_get_rq_log_wq_sz(rqp->rqc);
	default: /* MLX5_WQ_TYPE_CYCLIC */
		return MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE;
	}
}

2306 2307 2308
static void mlx5e_build_channel_param(struct mlx5e_priv *priv,
				      struct mlx5e_params *params,
				      struct mlx5e_channel_param *cparam)
2309
{
2310
	u8 icosq_log_wq_sz;
T
Tariq Toukan 已提交
2311

2312
	mlx5e_build_rq_param(priv, params, NULL, &cparam->rq);
2313 2314 2315

	icosq_log_wq_sz = mlx5e_build_icosq_log_wq_sz(params, &cparam->rq);

2316 2317 2318
	mlx5e_build_sq_param(priv, params, &cparam->sq);
	mlx5e_build_xdpsq_param(priv, params, &cparam->xdp_sq);
	mlx5e_build_icosq_param(priv, icosq_log_wq_sz, &cparam->icosq);
2319
	mlx5e_build_rx_cq_param(priv, params, NULL, &cparam->rx_cq);
2320 2321
	mlx5e_build_tx_cq_param(priv, params, &cparam->tx_cq);
	mlx5e_build_ico_cq_param(priv, icosq_log_wq_sz, &cparam->icosq_cq);
2322 2323
}

2324 2325
int mlx5e_open_channels(struct mlx5e_priv *priv,
			struct mlx5e_channels *chs)
2326
{
2327
	struct mlx5e_channel_param *cparam;
2328
	int err = -ENOMEM;
2329 2330
	int i;

2331
	chs->num = chs->params.num_channels;
2332

2333
	chs->c = kcalloc(chs->num, sizeof(struct mlx5e_channel *), GFP_KERNEL);
2334
	cparam = kvzalloc(sizeof(struct mlx5e_channel_param), GFP_KERNEL);
2335 2336
	if (!chs->c || !cparam)
		goto err_free;
2337

2338
	mlx5e_build_channel_param(priv, &chs->params, cparam);
2339
	for (i = 0; i < chs->num; i++) {
2340 2341 2342 2343 2344 2345
		struct xdp_umem *umem = NULL;

		if (chs->params.xdp_prog)
			umem = mlx5e_xsk_get_umem(&chs->params, chs->params.xsk, i);

		err = mlx5e_open_channel(priv, i, &chs->params, cparam, umem, &chs->c[i]);
2346 2347 2348 2349
		if (err)
			goto err_close_channels;
	}

2350
	mlx5e_health_channels_update(priv);
2351
	kvfree(cparam);
2352 2353 2354 2355
	return 0;

err_close_channels:
	for (i--; i >= 0; i--)
2356
		mlx5e_close_channel(chs->c[i]);
2357

2358
err_free:
2359
	kfree(chs->c);
2360
	kvfree(cparam);
2361
	chs->num = 0;
2362 2363 2364
	return err;
}

2365
static void mlx5e_activate_channels(struct mlx5e_channels *chs)
2366 2367 2368
{
	int i;

2369 2370 2371 2372
	for (i = 0; i < chs->num; i++)
		mlx5e_activate_channel(chs->c[i]);
}

2373 2374
#define MLX5E_RQ_WQES_TIMEOUT 20000 /* msecs */

2375 2376 2377 2378 2379
static int mlx5e_wait_channels_min_rx_wqes(struct mlx5e_channels *chs)
{
	int err = 0;
	int i;

2380 2381 2382 2383
	for (i = 0; i < chs->num; i++) {
		int timeout = err ? 0 : MLX5E_RQ_WQES_TIMEOUT;

		err |= mlx5e_wait_for_min_rx_wqes(&chs->c[i]->rq, timeout);
2384 2385 2386 2387

		/* Don't wait on the XSK RQ, because the newer xdpsock sample
		 * doesn't provide any Fill Ring entries at the setup stage.
		 */
2388
	}
2389

2390
	return err ? -ETIMEDOUT : 0;
2391 2392 2393 2394 2395 2396 2397 2398 2399 2400
}

static void mlx5e_deactivate_channels(struct mlx5e_channels *chs)
{
	int i;

	for (i = 0; i < chs->num; i++)
		mlx5e_deactivate_channel(chs->c[i]);
}

2401
void mlx5e_close_channels(struct mlx5e_channels *chs)
2402 2403
{
	int i;
2404

2405 2406
	for (i = 0; i < chs->num; i++)
		mlx5e_close_channel(chs->c[i]);
2407

2408 2409
	kfree(chs->c);
	chs->num = 0;
2410 2411
}

2412 2413
static int
mlx5e_create_rqt(struct mlx5e_priv *priv, int sz, struct mlx5e_rqt *rqt)
2414 2415 2416 2417 2418
{
	struct mlx5_core_dev *mdev = priv->mdev;
	void *rqtc;
	int inlen;
	int err;
T
Tariq Toukan 已提交
2419
	u32 *in;
2420
	int i;
2421 2422

	inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;
2423
	in = kvzalloc(inlen, GFP_KERNEL);
2424 2425 2426 2427 2428 2429 2430 2431
	if (!in)
		return -ENOMEM;

	rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);

	MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
	MLX5_SET(rqtc, rqtc, rqt_max_size, sz);

2432 2433
	for (i = 0; i < sz; i++)
		MLX5_SET(rqtc, rqtc, rq_num[i], priv->drop_rq.rqn);
2434

2435 2436 2437
	err = mlx5_core_create_rqt(mdev, in, inlen, &rqt->rqtn);
	if (!err)
		rqt->enabled = true;
2438 2439

	kvfree(in);
T
Tariq Toukan 已提交
2440 2441 2442
	return err;
}

2443
void mlx5e_destroy_rqt(struct mlx5e_priv *priv, struct mlx5e_rqt *rqt)
T
Tariq Toukan 已提交
2444
{
2445 2446
	rqt->enabled = false;
	mlx5_core_destroy_rqt(priv->mdev, rqt->rqtn);
T
Tariq Toukan 已提交
2447 2448
}

2449
int mlx5e_create_indirect_rqt(struct mlx5e_priv *priv)
2450 2451
{
	struct mlx5e_rqt *rqt = &priv->indir_rqt;
2452
	int err;
2453

2454 2455 2456 2457
	err = mlx5e_create_rqt(priv, MLX5E_INDIR_RQT_SIZE, rqt);
	if (err)
		mlx5_core_warn(priv->mdev, "create indirect rqts failed, %d\n", err);
	return err;
2458 2459
}

2460
int mlx5e_create_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
T
Tariq Toukan 已提交
2461 2462 2463 2464
{
	int err;
	int ix;

2465
	for (ix = 0; ix < priv->max_nch; ix++) {
2466 2467
		err = mlx5e_create_rqt(priv, 1 /*size */, &tirs[ix].rqt);
		if (unlikely(err))
T
Tariq Toukan 已提交
2468 2469 2470 2471 2472 2473
			goto err_destroy_rqts;
	}

	return 0;

err_destroy_rqts:
2474
	mlx5_core_warn(priv->mdev, "create rqts failed, %d\n", err);
T
Tariq Toukan 已提交
2475
	for (ix--; ix >= 0; ix--)
2476
		mlx5e_destroy_rqt(priv, &tirs[ix].rqt);
T
Tariq Toukan 已提交
2477

2478 2479 2480
	return err;
}

2481
void mlx5e_destroy_direct_rqts(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
2482 2483 2484
{
	int i;

2485
	for (i = 0; i < priv->max_nch; i++)
2486
		mlx5e_destroy_rqt(priv, &tirs[i].rqt);
2487 2488
}

2489 2490 2491 2492 2493 2494 2495
static int mlx5e_rx_hash_fn(int hfunc)
{
	return (hfunc == ETH_RSS_HASH_TOP) ?
	       MLX5_RX_HASH_FN_TOEPLITZ :
	       MLX5_RX_HASH_FN_INVERTED_XOR8;
}

2496
int mlx5e_bits_invert(unsigned long a, int size)
2497 2498 2499 2500 2501 2502 2503 2504 2505 2506 2507 2508 2509 2510 2511 2512 2513 2514 2515 2516 2517 2518 2519 2520
{
	int inv = 0;
	int i;

	for (i = 0; i < size; i++)
		inv |= (test_bit(size - i - 1, &a) ? 1 : 0) << i;

	return inv;
}

static void mlx5e_fill_rqt_rqns(struct mlx5e_priv *priv, int sz,
				struct mlx5e_redirect_rqt_param rrp, void *rqtc)
{
	int i;

	for (i = 0; i < sz; i++) {
		u32 rqn;

		if (rrp.is_rss) {
			int ix = i;

			if (rrp.rss.hfunc == ETH_RSS_HASH_XOR)
				ix = mlx5e_bits_invert(i, ilog2(sz));

2521
			ix = priv->rss_params.indirection_rqt[ix];
2522 2523 2524 2525 2526 2527 2528 2529 2530 2531
			rqn = rrp.rss.channels->c[ix]->rq.rqn;
		} else {
			rqn = rrp.rqn;
		}
		MLX5_SET(rqtc, rqtc, rq_num[i], rqn);
	}
}

int mlx5e_redirect_rqt(struct mlx5e_priv *priv, u32 rqtn, int sz,
		       struct mlx5e_redirect_rqt_param rrp)
2532 2533 2534 2535
{
	struct mlx5_core_dev *mdev = priv->mdev;
	void *rqtc;
	int inlen;
T
Tariq Toukan 已提交
2536
	u32 *in;
2537 2538 2539
	int err;

	inlen = MLX5_ST_SZ_BYTES(modify_rqt_in) + sizeof(u32) * sz;
2540
	in = kvzalloc(inlen, GFP_KERNEL);
2541 2542 2543 2544 2545 2546 2547
	if (!in)
		return -ENOMEM;

	rqtc = MLX5_ADDR_OF(modify_rqt_in, in, ctx);

	MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
	MLX5_SET(modify_rqt_in, in, bitmask.rqn_list, 1);
2548
	mlx5e_fill_rqt_rqns(priv, sz, rrp, rqtc);
T
Tariq Toukan 已提交
2549
	err = mlx5_core_modify_rqt(mdev, rqtn, in, inlen);
2550 2551 2552 2553 2554

	kvfree(in);
	return err;
}

2555 2556 2557 2558 2559 2560 2561 2562 2563 2564 2565 2566 2567 2568
static u32 mlx5e_get_direct_rqn(struct mlx5e_priv *priv, int ix,
				struct mlx5e_redirect_rqt_param rrp)
{
	if (!rrp.is_rss)
		return rrp.rqn;

	if (ix >= rrp.rss.channels->num)
		return priv->drop_rq.rqn;

	return rrp.rss.channels->c[ix]->rq.rqn;
}

static void mlx5e_redirect_rqts(struct mlx5e_priv *priv,
				struct mlx5e_redirect_rqt_param rrp)
2569
{
T
Tariq Toukan 已提交
2570 2571 2572
	u32 rqtn;
	int ix;

2573
	if (priv->indir_rqt.enabled) {
2574
		/* RSS RQ table */
2575
		rqtn = priv->indir_rqt.rqtn;
2576
		mlx5e_redirect_rqt(priv, rqtn, MLX5E_INDIR_RQT_SIZE, rrp);
2577 2578
	}

2579
	for (ix = 0; ix < priv->max_nch; ix++) {
2580 2581
		struct mlx5e_redirect_rqt_param direct_rrp = {
			.is_rss = false,
2582 2583 2584
			{
				.rqn    = mlx5e_get_direct_rqn(priv, ix, rrp)
			},
2585 2586 2587
		};

		/* Direct RQ Tables */
2588 2589
		if (!priv->direct_tir[ix].rqt.enabled)
			continue;
2590

2591
		rqtn = priv->direct_tir[ix].rqt.rqtn;
2592
		mlx5e_redirect_rqt(priv, rqtn, 1, direct_rrp);
T
Tariq Toukan 已提交
2593
	}
2594 2595
}

2596 2597 2598 2599 2600
static void mlx5e_redirect_rqts_to_channels(struct mlx5e_priv *priv,
					    struct mlx5e_channels *chs)
{
	struct mlx5e_redirect_rqt_param rrp = {
		.is_rss        = true,
2601 2602 2603
		{
			.rss = {
				.channels  = chs,
2604
				.hfunc     = priv->rss_params.hfunc,
2605 2606
			}
		},
2607 2608 2609 2610 2611 2612 2613 2614 2615
	};

	mlx5e_redirect_rqts(priv, rrp);
}

static void mlx5e_redirect_rqts_to_drop(struct mlx5e_priv *priv)
{
	struct mlx5e_redirect_rqt_param drop_rrp = {
		.is_rss = false,
2616 2617 2618
		{
			.rqn = priv->drop_rq.rqn,
		},
2619 2620 2621 2622 2623
	};

	mlx5e_redirect_rqts(priv, drop_rrp);
}

2624 2625 2626 2627 2628 2629 2630 2631 2632 2633 2634 2635 2636 2637 2638 2639 2640 2641 2642 2643 2644 2645 2646 2647 2648 2649 2650 2651 2652 2653 2654 2655 2656 2657 2658 2659 2660 2661 2662 2663 2664 2665 2666 2667 2668 2669 2670 2671
static const struct mlx5e_tirc_config tirc_default_config[MLX5E_NUM_INDIR_TIRS] = {
	[MLX5E_TT_IPV4_TCP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
				.l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
				.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
	},
	[MLX5E_TT_IPV6_TCP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
				.l4_prot_type = MLX5_L4_PROT_TYPE_TCP,
				.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
	},
	[MLX5E_TT_IPV4_UDP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
				.l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
				.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
	},
	[MLX5E_TT_IPV6_UDP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
				.l4_prot_type = MLX5_L4_PROT_TYPE_UDP,
				.rx_hash_fields = MLX5_HASH_IP_L4PORTS,
	},
	[MLX5E_TT_IPV4_IPSEC_AH] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
				     .l4_prot_type = 0,
				     .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
	},
	[MLX5E_TT_IPV6_IPSEC_AH] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
				     .l4_prot_type = 0,
				     .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
	},
	[MLX5E_TT_IPV4_IPSEC_ESP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
				      .l4_prot_type = 0,
				      .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
	},
	[MLX5E_TT_IPV6_IPSEC_ESP] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
				      .l4_prot_type = 0,
				      .rx_hash_fields = MLX5_HASH_IP_IPSEC_SPI,
	},
	[MLX5E_TT_IPV4] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV4,
			    .l4_prot_type = 0,
			    .rx_hash_fields = MLX5_HASH_IP,
	},
	[MLX5E_TT_IPV6] = { .l3_prot_type = MLX5_L3_PROT_TYPE_IPV6,
			    .l4_prot_type = 0,
			    .rx_hash_fields = MLX5_HASH_IP,
	},
};

struct mlx5e_tirc_config mlx5e_tirc_get_default_config(enum mlx5e_traffic_types tt)
{
	return tirc_default_config[tt];
}

2672
static void mlx5e_build_tir_ctx_lro(struct mlx5e_params *params, void *tirc)
2673
{
2674
	if (!params->lro_en)
2675 2676 2677 2678 2679 2680 2681 2682
		return;

#define ROUGH_MAX_L2_L3_HDR_SZ 256

	MLX5_SET(tirc, tirc, lro_enable_mask,
		 MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
		 MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
	MLX5_SET(tirc, tirc, lro_max_ip_payload_size,
2683
		 (MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ - ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
2684
	MLX5_SET(tirc, tirc, lro_timeout_period_usecs, params->lro_timeout);
2685 2686
}

2687
void mlx5e_build_indir_tir_ctx_hash(struct mlx5e_rss_params *rss_params,
2688
				    const struct mlx5e_tirc_config *ttconfig,
2689
				    void *tirc, bool inner)
2690
{
2691 2692
	void *hfso = inner ? MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_inner) :
			     MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
2693

2694 2695
	MLX5_SET(tirc, tirc, rx_hash_fn, mlx5e_rx_hash_fn(rss_params->hfunc));
	if (rss_params->hfunc == ETH_RSS_HASH_TOP) {
2696 2697 2698 2699 2700 2701
		void *rss_key = MLX5_ADDR_OF(tirc, tirc,
					     rx_hash_toeplitz_key);
		size_t len = MLX5_FLD_SZ_BYTES(tirc,
					       rx_hash_toeplitz_key);

		MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
2702
		memcpy(rss_key, rss_params->toeplitz_hash_key, len);
2703
	}
2704 2705 2706 2707 2708 2709
	MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
		 ttconfig->l3_prot_type);
	MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
		 ttconfig->l4_prot_type);
	MLX5_SET(rx_hash_field_select, hfso, selected_fields,
		 ttconfig->rx_hash_fields);
2710 2711
}

2712 2713 2714 2715 2716 2717 2718 2719
static void mlx5e_update_rx_hash_fields(struct mlx5e_tirc_config *ttconfig,
					enum mlx5e_traffic_types tt,
					u32 rx_hash_fields)
{
	*ttconfig                = tirc_default_config[tt];
	ttconfig->rx_hash_fields = rx_hash_fields;
}

2720 2721 2722
void mlx5e_modify_tirs_hash(struct mlx5e_priv *priv, void *in, int inlen)
{
	void *tirc = MLX5_ADDR_OF(modify_tir_in, in, ctx);
2723
	struct mlx5e_rss_params *rss = &priv->rss_params;
2724 2725
	struct mlx5_core_dev *mdev = priv->mdev;
	int ctxlen = MLX5_ST_SZ_BYTES(tirc);
2726
	struct mlx5e_tirc_config ttconfig;
2727 2728 2729 2730 2731 2732
	int tt;

	MLX5_SET(modify_tir_in, in, bitmask.hash, 1);

	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
		memset(tirc, 0, ctxlen);
2733 2734 2735
		mlx5e_update_rx_hash_fields(&ttconfig, tt,
					    rss->rx_hash_fields[tt]);
		mlx5e_build_indir_tir_ctx_hash(rss, &ttconfig, tirc, false);
2736 2737 2738 2739 2740 2741 2742 2743
		mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in, inlen);
	}

	if (!mlx5e_tunnel_inner_ft_supported(priv->mdev))
		return;

	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
		memset(tirc, 0, ctxlen);
2744 2745 2746
		mlx5e_update_rx_hash_fields(&ttconfig, tt,
					    rss->rx_hash_fields[tt]);
		mlx5e_build_indir_tir_ctx_hash(rss, &ttconfig, tirc, true);
2747 2748 2749 2750 2751
		mlx5_core_modify_tir(mdev, priv->inner_indir_tir[tt].tirn, in,
				     inlen);
	}
}

T
Tariq Toukan 已提交
2752
static int mlx5e_modify_tirs_lro(struct mlx5e_priv *priv)
2753 2754 2755 2756 2757 2758 2759
{
	struct mlx5_core_dev *mdev = priv->mdev;

	void *in;
	void *tirc;
	int inlen;
	int err;
T
Tariq Toukan 已提交
2760
	int tt;
T
Tariq Toukan 已提交
2761
	int ix;
2762 2763

	inlen = MLX5_ST_SZ_BYTES(modify_tir_in);
2764
	in = kvzalloc(inlen, GFP_KERNEL);
2765 2766 2767 2768 2769 2770
	if (!in)
		return -ENOMEM;

	MLX5_SET(modify_tir_in, in, bitmask.lro, 1);
	tirc = MLX5_ADDR_OF(modify_tir_in, in, ctx);

2771
	mlx5e_build_tir_ctx_lro(&priv->channels.params, tirc);
2772

T
Tariq Toukan 已提交
2773
	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
2774
		err = mlx5_core_modify_tir(mdev, priv->indir_tir[tt].tirn, in,
T
Tariq Toukan 已提交
2775
					   inlen);
T
Tariq Toukan 已提交
2776
		if (err)
T
Tariq Toukan 已提交
2777
			goto free_in;
T
Tariq Toukan 已提交
2778
	}
2779

2780
	for (ix = 0; ix < priv->max_nch; ix++) {
T
Tariq Toukan 已提交
2781 2782 2783 2784 2785 2786 2787
		err = mlx5_core_modify_tir(mdev, priv->direct_tir[ix].tirn,
					   in, inlen);
		if (err)
			goto free_in;
	}

free_in:
2788 2789 2790 2791 2792
	kvfree(in);

	return err;
}

2793 2794
static int mlx5e_set_mtu(struct mlx5_core_dev *mdev,
			 struct mlx5e_params *params, u16 mtu)
2795
{
2796
	u16 hw_mtu = MLX5E_SW2HW_MTU(params, mtu);
2797 2798
	int err;

2799
	err = mlx5_set_port_mtu(mdev, hw_mtu, 1);
2800 2801 2802
	if (err)
		return err;

2803 2804 2805 2806
	/* Update vport context MTU */
	mlx5_modify_nic_vport_mtu(mdev, hw_mtu);
	return 0;
}
2807

2808 2809
static void mlx5e_query_mtu(struct mlx5_core_dev *mdev,
			    struct mlx5e_params *params, u16 *mtu)
2810 2811 2812
{
	u16 hw_mtu = 0;
	int err;
2813

2814 2815 2816 2817
	err = mlx5_query_nic_vport_mtu(mdev, &hw_mtu);
	if (err || !hw_mtu) /* fallback to port oper mtu */
		mlx5_query_port_oper_mtu(mdev, &hw_mtu, 1);

2818
	*mtu = MLX5E_HW2SW_MTU(params, hw_mtu);
2819 2820
}

2821
int mlx5e_set_dev_port_mtu(struct mlx5e_priv *priv)
2822
{
2823
	struct mlx5e_params *params = &priv->channels.params;
2824
	struct net_device *netdev = priv->netdev;
2825
	struct mlx5_core_dev *mdev = priv->mdev;
2826 2827 2828
	u16 mtu;
	int err;

2829
	err = mlx5e_set_mtu(mdev, params, params->sw_mtu);
2830 2831
	if (err)
		return err;
2832

2833 2834
	mlx5e_query_mtu(mdev, params, &mtu);
	if (mtu != params->sw_mtu)
2835
		netdev_warn(netdev, "%s: VPort MTU %d is different than netdev mtu %d\n",
2836
			    __func__, mtu, params->sw_mtu);
2837

2838
	params->sw_mtu = mtu;
2839 2840 2841
	return 0;
}

2842 2843 2844 2845 2846 2847 2848 2849 2850 2851 2852 2853 2854 2855 2856
void mlx5e_set_netdev_mtu_boundaries(struct mlx5e_priv *priv)
{
	struct mlx5e_params *params = &priv->channels.params;
	struct net_device *netdev   = priv->netdev;
	struct mlx5_core_dev *mdev  = priv->mdev;
	u16 max_mtu;

	/* MTU range: 68 - hw-specific max */
	netdev->min_mtu = ETH_MIN_MTU;

	mlx5_query_port_max_mtu(mdev, &max_mtu, 1);
	netdev->max_mtu = min_t(unsigned int, MLX5E_HW2SW_MTU(params, max_mtu),
				ETH_MAX_MTU);
}

2857 2858 2859
static void mlx5e_netdev_set_tcs(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
2860 2861
	int nch = priv->channels.params.num_channels;
	int ntc = priv->channels.params.num_tc;
2862 2863 2864 2865 2866 2867 2868 2869 2870
	int tc;

	netdev_reset_tc(netdev);

	if (ntc == 1)
		return;

	netdev_set_num_tc(netdev, ntc);

2871 2872 2873
	/* Map netdev TCs to offset 0
	 * We have our own UP to TXQ mapping for QoS
	 */
2874
	for (tc = 0; tc < ntc; tc++)
2875
		netdev_set_tc_queue(netdev, tc, nch, 0);
2876 2877
}

2878
static void mlx5e_build_txq_maps(struct mlx5e_priv *priv)
2879
{
2880
	int i, ch;
2881

2882
	ch = priv->channels.num;
2883

2884 2885 2886 2887 2888 2889
	for (i = 0; i < ch; i++) {
		int tc;

		for (tc = 0; tc < priv->channels.params.num_tc; tc++) {
			struct mlx5e_channel *c = priv->channels.c[i];
			struct mlx5e_txqsq *sq = &c->sq[tc];
2890 2891

			priv->txq2sq[sq->txq_ix] = sq;
2892
			priv->channel_tc2realtxq[i][tc] = i + tc * ch;
2893 2894 2895 2896
		}
	}
}

2897
void mlx5e_activate_priv_channels(struct mlx5e_priv *priv)
2898
{
2899
	int num_txqs = priv->channels.num * priv->channels.params.num_tc;
2900
	int num_rxqs = priv->channels.num * priv->profile->rq_groups;
2901 2902 2903
	struct net_device *netdev = priv->netdev;

	mlx5e_netdev_set_tcs(netdev);
2904
	netif_set_real_num_tx_queues(netdev, num_txqs);
2905
	netif_set_real_num_rx_queues(netdev, num_rxqs);
2906

2907
	mlx5e_build_txq_maps(priv);
2908
	mlx5e_activate_channels(&priv->channels);
2909
	mlx5e_xdp_tx_enable(priv);
2910
	netif_tx_start_all_queues(priv->netdev);
2911

2912
	if (mlx5e_is_vport_rep(priv))
2913 2914
		mlx5e_add_sqs_fwd_rules(priv);

2915
	mlx5e_wait_channels_min_rx_wqes(&priv->channels);
2916
	mlx5e_redirect_rqts_to_channels(priv, &priv->channels);
2917 2918

	mlx5e_xsk_redirect_rqts_to_channels(priv, &priv->channels);
2919 2920
}

2921
void mlx5e_deactivate_priv_channels(struct mlx5e_priv *priv)
2922
{
2923 2924
	mlx5e_xsk_redirect_rqts_to_drop(priv, &priv->channels);

2925 2926
	mlx5e_redirect_rqts_to_drop(priv);

2927
	if (mlx5e_is_vport_rep(priv))
2928 2929
		mlx5e_remove_sqs_fwd_rules(priv);

2930 2931 2932 2933 2934
	/* FIXME: This is a W/A only for tx timeout watch dog false alarm when
	 * polling for inactive tx queues.
	 */
	netif_tx_stop_all_queues(priv->netdev);
	netif_tx_disable(priv->netdev);
2935
	mlx5e_xdp_tx_disable(priv);
2936 2937 2938
	mlx5e_deactivate_channels(&priv->channels);
}

2939 2940 2941
static void mlx5e_switch_priv_channels(struct mlx5e_priv *priv,
				       struct mlx5e_channels *new_chs,
				       mlx5e_fp_hw_modify hw_modify)
2942 2943 2944
{
	struct net_device *netdev = priv->netdev;
	int new_num_txqs;
2945
	int carrier_ok;
2946

2947 2948
	new_num_txqs = new_chs->num * new_chs->params.num_tc;

2949
	carrier_ok = netif_carrier_ok(netdev);
2950 2951 2952 2953 2954 2955 2956 2957 2958 2959
	netif_carrier_off(netdev);

	if (new_num_txqs < netdev->real_num_tx_queues)
		netif_set_real_num_tx_queues(netdev, new_num_txqs);

	mlx5e_deactivate_priv_channels(priv);
	mlx5e_close_channels(&priv->channels);

	priv->channels = *new_chs;

2960 2961 2962 2963
	/* New channels are ready to roll, modify HW settings if needed */
	if (hw_modify)
		hw_modify(priv);

2964
	priv->profile->update_rx(priv);
2965 2966
	mlx5e_activate_priv_channels(priv);

2967 2968 2969
	/* return carrier back if needed */
	if (carrier_ok)
		netif_carrier_on(netdev);
2970 2971
}

2972 2973 2974 2975 2976 2977 2978 2979 2980 2981 2982 2983 2984 2985
int mlx5e_safe_switch_channels(struct mlx5e_priv *priv,
			       struct mlx5e_channels *new_chs,
			       mlx5e_fp_hw_modify hw_modify)
{
	int err;

	err = mlx5e_open_channels(priv, new_chs);
	if (err)
		return err;

	mlx5e_switch_priv_channels(priv, new_chs, hw_modify);
	return 0;
}

2986 2987 2988 2989 2990 2991 2992 2993
int mlx5e_safe_reopen_channels(struct mlx5e_priv *priv)
{
	struct mlx5e_channels new_channels = {};

	new_channels.params = priv->channels.params;
	return mlx5e_safe_switch_channels(priv, &new_channels, NULL);
}

2994
void mlx5e_timestamp_init(struct mlx5e_priv *priv)
2995 2996 2997 2998 2999
{
	priv->tstamp.tx_type   = HWTSTAMP_TX_OFF;
	priv->tstamp.rx_filter = HWTSTAMP_FILTER_NONE;
}

3000 3001 3002 3003 3004 3005 3006
int mlx5e_open_locked(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

	set_bit(MLX5E_STATE_OPENED, &priv->state);

3007
	err = mlx5e_open_channels(priv, &priv->channels);
3008
	if (err)
3009
		goto err_clear_state_opened_flag;
3010

3011
	priv->profile->update_rx(priv);
3012
	mlx5e_activate_priv_channels(priv);
3013 3014
	if (priv->profile->update_carrier)
		priv->profile->update_carrier(priv);
3015

3016
	mlx5e_queue_update_stats(priv);
3017
	return 0;
3018 3019 3020 3021

err_clear_state_opened_flag:
	clear_bit(MLX5E_STATE_OPENED, &priv->state);
	return err;
3022 3023
}

3024
int mlx5e_open(struct net_device *netdev)
3025 3026 3027 3028 3029 3030
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

	mutex_lock(&priv->state_lock);
	err = mlx5e_open_locked(netdev);
3031 3032
	if (!err)
		mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
3033 3034
	mutex_unlock(&priv->state_lock);

3035
	if (mlx5_vxlan_allowed(priv->mdev->vxlan))
3036 3037
		udp_tunnel_get_rx_info(netdev);

3038 3039 3040 3041 3042 3043 3044
	return err;
}

int mlx5e_close_locked(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

3045 3046 3047 3048 3049 3050
	/* May already be CLOSED in case a previous configuration operation
	 * (e.g RX/TX queue size change) that involves close&open failed.
	 */
	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
		return 0;

3051 3052 3053
	clear_bit(MLX5E_STATE_OPENED, &priv->state);

	netif_carrier_off(priv->netdev);
3054 3055
	mlx5e_deactivate_priv_channels(priv);
	mlx5e_close_channels(&priv->channels);
3056 3057 3058 3059

	return 0;
}

3060
int mlx5e_close(struct net_device *netdev)
3061 3062 3063 3064
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

3065 3066 3067
	if (!netif_device_present(netdev))
		return -ENODEV;

3068
	mutex_lock(&priv->state_lock);
3069
	mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN);
3070 3071 3072 3073 3074 3075
	err = mlx5e_close_locked(netdev);
	mutex_unlock(&priv->state_lock);

	return err;
}

3076
static int mlx5e_alloc_drop_rq(struct mlx5_core_dev *mdev,
3077 3078
			       struct mlx5e_rq *rq,
			       struct mlx5e_rq_param *param)
3079 3080 3081 3082 3083 3084 3085
{
	void *rqc = param->rqc;
	void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
	int err;

	param->wq.db_numa_node = param->wq.buf_numa_node;

3086 3087
	err = mlx5_wq_cyc_create(mdev, &param->wq, rqc_wq, &rq->wqe.wq,
				 &rq->wq_ctrl);
3088 3089 3090
	if (err)
		return err;

3091 3092 3093
	/* Mark as unused given "Drop-RQ" packets never reach XDP */
	xdp_rxq_info_unused(&rq->xdp_rxq);

3094
	rq->mdev = mdev;
3095 3096 3097 3098

	return 0;
}

3099
static int mlx5e_alloc_drop_cq(struct mlx5_core_dev *mdev,
3100 3101
			       struct mlx5e_cq *cq,
			       struct mlx5e_cq_param *param)
3102
{
3103 3104
	param->wq.buf_numa_node = dev_to_node(mdev->device);
	param->wq.db_numa_node  = dev_to_node(mdev->device);
3105

3106
	return mlx5e_alloc_cq_common(mdev, param, cq);
3107 3108
}

3109 3110
int mlx5e_open_drop_rq(struct mlx5e_priv *priv,
		       struct mlx5e_rq *drop_rq)
3111
{
3112
	struct mlx5_core_dev *mdev = priv->mdev;
3113 3114 3115
	struct mlx5e_cq_param cq_param = {};
	struct mlx5e_rq_param rq_param = {};
	struct mlx5e_cq *cq = &drop_rq->cq;
3116 3117
	int err;

3118
	mlx5e_build_drop_rq_param(priv, &rq_param);
3119

3120
	err = mlx5e_alloc_drop_cq(mdev, cq, &cq_param);
3121 3122 3123
	if (err)
		return err;

3124
	err = mlx5e_create_cq(cq, &cq_param);
3125
	if (err)
3126
		goto err_free_cq;
3127

3128
	err = mlx5e_alloc_drop_rq(mdev, drop_rq, &rq_param);
3129
	if (err)
3130
		goto err_destroy_cq;
3131

3132
	err = mlx5e_create_rq(drop_rq, &rq_param);
3133
	if (err)
3134
		goto err_free_rq;
3135

3136 3137 3138 3139
	err = mlx5e_modify_rq_state(drop_rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
	if (err)
		mlx5_core_warn(priv->mdev, "modify_rq_state failed, rx_if_down_packets won't be counted %d\n", err);

3140 3141
	return 0;

3142
err_free_rq:
3143
	mlx5e_free_rq(drop_rq);
3144 3145

err_destroy_cq:
3146
	mlx5e_destroy_cq(cq);
3147

3148
err_free_cq:
3149
	mlx5e_free_cq(cq);
3150

3151 3152 3153
	return err;
}

3154
void mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq)
3155
{
3156 3157 3158 3159
	mlx5e_destroy_rq(drop_rq);
	mlx5e_free_rq(drop_rq);
	mlx5e_destroy_cq(&drop_rq->cq);
	mlx5e_free_cq(&drop_rq->cq);
3160 3161
}

3162
int mlx5e_create_tis(struct mlx5_core_dev *mdev, void *in, u32 *tisn)
3163 3164 3165
{
	void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);

3166
	MLX5_SET(tisc, tisc, transport_domain, mdev->mlx5e_res.td.tdn);
3167

3168 3169 3170
	if (MLX5_GET(tisc, tisc, tls_en))
		MLX5_SET(tisc, tisc, pd, mdev->mlx5e_res.pdn);

3171 3172 3173
	if (mlx5_lag_is_lacp_owner(mdev))
		MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);

3174
	return mlx5_core_create_tis(mdev, in, MLX5_ST_SZ_BYTES(create_tis_in), tisn);
3175 3176
}

3177
void mlx5e_destroy_tis(struct mlx5_core_dev *mdev, u32 tisn)
3178
{
3179
	mlx5_core_destroy_tis(mdev, tisn);
3180 3181
}

3182 3183
void mlx5e_destroy_tises(struct mlx5e_priv *priv)
{
3184
	int tc, i;
3185

3186 3187 3188 3189 3190 3191 3192 3193
	for (i = 0; i < mlx5e_get_num_lag_ports(priv->mdev); i++)
		for (tc = 0; tc < priv->profile->max_tc; tc++)
			mlx5e_destroy_tis(priv->mdev, priv->tisn[i][tc]);
}

static bool mlx5e_lag_should_assign_affinity(struct mlx5_core_dev *mdev)
{
	return MLX5_CAP_GEN(mdev, lag_tx_port_affinity) && mlx5e_get_num_lag_ports(mdev) > 1;
3194 3195
}

3196
int mlx5e_create_tises(struct mlx5e_priv *priv)
3197
{
3198
	int tc, i;
3199 3200
	int err;

3201 3202 3203 3204
	for (i = 0; i < mlx5e_get_num_lag_ports(priv->mdev); i++) {
		for (tc = 0; tc < priv->profile->max_tc; tc++) {
			u32 in[MLX5_ST_SZ_DW(create_tis_in)] = {};
			void *tisc;
3205

3206
			tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
3207

3208
			MLX5_SET(tisc, tisc, prio, tc << 1);
3209

3210 3211 3212 3213 3214 3215 3216
			if (mlx5e_lag_should_assign_affinity(priv->mdev))
				MLX5_SET(tisc, tisc, lag_tx_port_affinity, i + 1);

			err = mlx5e_create_tis(priv->mdev, in, &priv->tisn[i][tc]);
			if (err)
				goto err_close_tises;
		}
3217 3218 3219 3220 3221
	}

	return 0;

err_close_tises:
3222 3223 3224 3225 3226
	for (; i >= 0; i--) {
		for (tc--; tc >= 0; tc--)
			mlx5e_destroy_tis(priv->mdev, priv->tisn[i][tc]);
		tc = priv->profile->max_tc;
	}
3227 3228 3229 3230

	return err;
}

3231
static void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv)
3232
{
3233
	mlx5e_destroy_tises(priv);
3234 3235
}

3236 3237
static void mlx5e_build_indir_tir_ctx_common(struct mlx5e_priv *priv,
					     u32 rqtn, u32 *tirc)
3238
{
3239
	MLX5_SET(tirc, tirc, transport_domain, priv->mdev->mlx5e_res.td.tdn);
3240 3241
	MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
	MLX5_SET(tirc, tirc, indirect_table, rqtn);
3242 3243
	MLX5_SET(tirc, tirc, tunneled_offload_en,
		 priv->channels.params.tunneled_offload_en);
3244

3245
	mlx5e_build_tir_ctx_lro(&priv->channels.params, tirc);
3246
}
3247

3248 3249 3250 3251 3252
static void mlx5e_build_indir_tir_ctx(struct mlx5e_priv *priv,
				      enum mlx5e_traffic_types tt,
				      u32 *tirc)
{
	mlx5e_build_indir_tir_ctx_common(priv, priv->indir_rqt.rqtn, tirc);
3253
	mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
3254
				       &tirc_default_config[tt], tirc, false);
3255 3256
}

3257
static void mlx5e_build_direct_tir_ctx(struct mlx5e_priv *priv, u32 rqtn, u32 *tirc)
3258
{
3259
	mlx5e_build_indir_tir_ctx_common(priv, rqtn, tirc);
T
Tariq Toukan 已提交
3260 3261 3262
	MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_INVERTED_XOR8);
}

3263 3264 3265 3266 3267 3268 3269 3270 3271
static void mlx5e_build_inner_indir_tir_ctx(struct mlx5e_priv *priv,
					    enum mlx5e_traffic_types tt,
					    u32 *tirc)
{
	mlx5e_build_indir_tir_ctx_common(priv, priv->indir_rqt.rqtn, tirc);
	mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
				       &tirc_default_config[tt], tirc, true);
}

3272
int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)
T
Tariq Toukan 已提交
3273
{
3274
	struct mlx5e_tir *tir;
3275 3276
	void *tirc;
	int inlen;
3277
	int i = 0;
3278
	int err;
T
Tariq Toukan 已提交
3279 3280
	u32 *in;
	int tt;
3281 3282

	inlen = MLX5_ST_SZ_BYTES(create_tir_in);
3283
	in = kvzalloc(inlen, GFP_KERNEL);
3284 3285 3286
	if (!in)
		return -ENOMEM;

T
Tariq Toukan 已提交
3287 3288
	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++) {
		memset(in, 0, inlen);
3289
		tir = &priv->indir_tir[tt];
T
Tariq Toukan 已提交
3290
		tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
3291
		mlx5e_build_indir_tir_ctx(priv, tt, tirc);
3292
		err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
3293 3294 3295 3296
		if (err) {
			mlx5_core_warn(priv->mdev, "create indirect tirs failed, %d\n", err);
			goto err_destroy_inner_tirs;
		}
3297 3298
	}

3299
	if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314
		goto out;

	for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++) {
		memset(in, 0, inlen);
		tir = &priv->inner_indir_tir[i];
		tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
		mlx5e_build_inner_indir_tir_ctx(priv, i, tirc);
		err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
		if (err) {
			mlx5_core_warn(priv->mdev, "create inner indirect tirs failed, %d\n", err);
			goto err_destroy_inner_tirs;
		}
	}

out:
3315 3316 3317 3318
	kvfree(in);

	return 0;

3319 3320 3321 3322
err_destroy_inner_tirs:
	for (i--; i >= 0; i--)
		mlx5e_destroy_tir(priv->mdev, &priv->inner_indir_tir[i]);

3323 3324 3325 3326 3327 3328 3329 3330
	for (tt--; tt >= 0; tt--)
		mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[tt]);

	kvfree(in);

	return err;
}

3331
int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
3332 3333 3334 3335
{
	struct mlx5e_tir *tir;
	void *tirc;
	int inlen;
3336
	int err = 0;
3337 3338 3339 3340
	u32 *in;
	int ix;

	inlen = MLX5_ST_SZ_BYTES(create_tir_in);
3341
	in = kvzalloc(inlen, GFP_KERNEL);
3342 3343 3344
	if (!in)
		return -ENOMEM;

3345
	for (ix = 0; ix < priv->max_nch; ix++) {
T
Tariq Toukan 已提交
3346
		memset(in, 0, inlen);
3347
		tir = &tirs[ix];
T
Tariq Toukan 已提交
3348
		tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
3349
		mlx5e_build_direct_tir_ctx(priv, tir->rqt.rqtn, tirc);
3350
		err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
3351
		if (unlikely(err))
T
Tariq Toukan 已提交
3352 3353 3354
			goto err_destroy_ch_tirs;
	}

3355
	goto out;
3356

T
Tariq Toukan 已提交
3357
err_destroy_ch_tirs:
3358
	mlx5_core_warn(priv->mdev, "create tirs failed, %d\n", err);
T
Tariq Toukan 已提交
3359
	for (ix--; ix >= 0; ix--)
3360
		mlx5e_destroy_tir(priv->mdev, &tirs[ix]);
T
Tariq Toukan 已提交
3361

3362
out:
T
Tariq Toukan 已提交
3363
	kvfree(in);
3364 3365 3366 3367

	return err;
}

3368
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)
3369 3370 3371
{
	int i;

T
Tariq Toukan 已提交
3372
	for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
3373
		mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[i]);
3374

3375
	if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
3376 3377 3378 3379
		return;

	for (i = 0; i < MLX5E_NUM_INDIR_TIRS; i++)
		mlx5e_destroy_tir(priv->mdev, &priv->inner_indir_tir[i]);
3380 3381
}

3382
void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
3383 3384 3385
{
	int i;

3386
	for (i = 0; i < priv->max_nch; i++)
3387
		mlx5e_destroy_tir(priv->mdev, &tirs[i]);
3388 3389
}

3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403
static int mlx5e_modify_channels_scatter_fcs(struct mlx5e_channels *chs, bool enable)
{
	int err = 0;
	int i;

	for (i = 0; i < chs->num; i++) {
		err = mlx5e_modify_rq_scatter_fcs(&chs->c[i]->rq, enable);
		if (err)
			return err;
	}

	return 0;
}

3404
static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
3405 3406 3407 3408
{
	int err = 0;
	int i;

3409 3410
	for (i = 0; i < chs->num; i++) {
		err = mlx5e_modify_rq_vsd(&chs->c[i]->rq, vsd);
3411 3412 3413 3414 3415 3416 3417
		if (err)
			return err;
	}

	return 0;
}

3418
static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
3419
				 struct tc_mqprio_qopt *mqprio)
3420
{
S
Saeed Mahameed 已提交
3421
	struct mlx5e_channels new_channels = {};
3422
	u8 tc = mqprio->num_tc;
3423 3424
	int err = 0;

3425 3426
	mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;

3427 3428 3429 3430 3431
	if (tc && tc != MLX5E_MAX_NUM_TC)
		return -EINVAL;

	mutex_lock(&priv->state_lock);

S
Saeed Mahameed 已提交
3432 3433
	new_channels.params = priv->channels.params;
	new_channels.params.num_tc = tc ? tc : 1;
3434

S
Saeed Mahameed 已提交
3435
	if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
S
Saeed Mahameed 已提交
3436 3437 3438
		priv->channels.params = new_channels.params;
		goto out;
	}
3439

3440
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
S
Saeed Mahameed 已提交
3441 3442
	if (err)
		goto out;
3443

3444 3445
	priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
				    new_channels.params.num_tc);
S
Saeed Mahameed 已提交
3446
out:
3447 3448 3449 3450
	mutex_unlock(&priv->state_lock);
	return err;
}

3451
#ifdef CONFIG_MLX5_ESWITCH
3452
static int mlx5e_setup_tc_cls_flower(struct mlx5e_priv *priv,
3453
				     struct flow_cls_offload *cls_flower,
3454
				     unsigned long flags)
3455
{
3456
	switch (cls_flower->command) {
3457
	case FLOW_CLS_REPLACE:
3458 3459
		return mlx5e_configure_flower(priv->netdev, priv, cls_flower,
					      flags);
3460
	case FLOW_CLS_DESTROY:
3461 3462
		return mlx5e_delete_flower(priv->netdev, priv, cls_flower,
					   flags);
3463
	case FLOW_CLS_STATS:
3464 3465
		return mlx5e_stats_flower(priv->netdev, priv, cls_flower,
					  flags);
3466
	default:
3467
		return -EOPNOTSUPP;
3468 3469
	}
}
3470

3471 3472
static int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
				   void *cb_priv)
3473
{
3474
	unsigned long flags = MLX5_TC_FLAG(INGRESS) | MLX5_TC_FLAG(NIC_OFFLOAD);
3475 3476 3477 3478
	struct mlx5e_priv *priv = cb_priv;

	switch (type) {
	case TC_SETUP_CLSFLOWER:
3479
		return mlx5e_setup_tc_cls_flower(priv, type_data, flags);
3480 3481 3482 3483
	default:
		return -EOPNOTSUPP;
	}
}
3484
#endif
3485

3486 3487
static LIST_HEAD(mlx5e_block_cb_list);

3488 3489
static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
			  void *type_data)
3490
{
3491 3492
	struct mlx5e_priv *priv = netdev_priv(dev);

3493
	switch (type) {
3494
#ifdef CONFIG_MLX5_ESWITCH
3495 3496 3497
	case TC_SETUP_BLOCK: {
		struct flow_block_offload *f = type_data;

3498
		f->unlocked_driver_cb = true;
3499 3500
		return flow_block_cb_setup_simple(type_data,
						  &mlx5e_block_cb_list,
3501 3502
						  mlx5e_setup_tc_block_cb,
						  priv, priv, true);
3503
	}
3504
#endif
3505
	case TC_SETUP_QDISC_MQPRIO:
3506
		return mlx5e_setup_tc_mqprio(priv, type_data);
3507 3508 3509
	default:
		return -EOPNOTSUPP;
	}
3510 3511
}

3512
void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
3513 3514 3515
{
	int i;

3516
	for (i = 0; i < priv->max_nch; i++) {
3517
		struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i];
3518
		struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
3519 3520 3521
		struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
		int j;

3522 3523
		s->rx_packets   += rq_stats->packets + xskrq_stats->packets;
		s->rx_bytes     += rq_stats->bytes + xskrq_stats->bytes;
3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534

		for (j = 0; j < priv->max_opened_tc; j++) {
			struct mlx5e_sq_stats *sq_stats = &channel_stats->sq[j];

			s->tx_packets    += sq_stats->packets;
			s->tx_bytes      += sq_stats->bytes;
			s->tx_dropped    += sq_stats->dropped;
		}
	}
}

3535
void
3536 3537 3538 3539
mlx5e_get_stats(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5e_vport_stats *vstats = &priv->stats.vport;
3540
	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
3541

3542 3543 3544 3545
	if (!mlx5e_monitor_counter_supported(priv)) {
		/* update HW stats in background for next time */
		mlx5e_queue_update_stats(priv);
	}
3546

3547 3548 3549 3550 3551 3552
	if (mlx5e_is_uplink_rep(priv)) {
		stats->rx_packets = PPORT_802_3_GET(pstats, a_frames_received_ok);
		stats->rx_bytes   = PPORT_802_3_GET(pstats, a_octets_received_ok);
		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 {
3553
		mlx5e_fold_sw_stats64(priv, stats);
3554
	}
3555 3556 3557 3558

	stats->rx_dropped = priv->stats.qcnt.rx_out_of_buffer;

	stats->rx_length_errors =
3559 3560 3561
		PPORT_802_3_GET(pstats, a_in_range_length_errors) +
		PPORT_802_3_GET(pstats, a_out_of_range_length_field) +
		PPORT_802_3_GET(pstats, a_frame_too_long_errors);
3562
	stats->rx_crc_errors =
3563 3564 3565
		PPORT_802_3_GET(pstats, a_frame_check_sequence_errors);
	stats->rx_frame_errors = PPORT_802_3_GET(pstats, a_alignment_errors);
	stats->tx_aborted_errors = PPORT_2863_GET(pstats, if_out_discards);
3566 3567 3568 3569 3570 3571 3572
	stats->rx_errors = stats->rx_length_errors + stats->rx_crc_errors +
			   stats->rx_frame_errors;
	stats->tx_errors = stats->tx_aborted_errors + stats->tx_carrier_errors;

	/* vport multicast also counts packets that are dropped due to steering
	 * or rx out of buffer
	 */
3573 3574
	stats->multicast =
		VPORT_COUNTER_GET(vstats, received_eth_multicast.packets);
3575 3576 3577 3578 3579 3580
}

static void mlx5e_set_rx_mode(struct net_device *dev)
{
	struct mlx5e_priv *priv = netdev_priv(dev);

3581
	queue_work(priv->wq, &priv->set_rx_mode_work);
3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595
}

static int mlx5e_set_mac(struct net_device *netdev, void *addr)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct sockaddr *saddr = addr;

	if (!is_valid_ether_addr(saddr->sa_data))
		return -EADDRNOTAVAIL;

	netif_addr_lock_bh(netdev);
	ether_addr_copy(netdev->dev_addr, saddr->sa_data);
	netif_addr_unlock_bh(netdev);

3596
	queue_work(priv->wq, &priv->set_rx_mode_work);
3597 3598 3599 3600

	return 0;
}

3601
#define MLX5E_SET_FEATURE(features, feature, enable)	\
3602 3603
	do {						\
		if (enable)				\
3604
			*features |= feature;		\
3605
		else					\
3606
			*features &= ~feature;		\
3607 3608 3609 3610 3611
	} while (0)

typedef int (*mlx5e_feature_handler)(struct net_device *netdev, bool enable);

static int set_feature_lro(struct net_device *netdev, bool enable)
3612 3613
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3614
	struct mlx5_core_dev *mdev = priv->mdev;
3615
	struct mlx5e_channels new_channels = {};
3616
	struct mlx5e_params *old_params;
3617 3618
	int err = 0;
	bool reset;
3619 3620 3621

	mutex_lock(&priv->state_lock);

3622 3623 3624 3625 3626 3627 3628
	if (enable && priv->xsk.refcnt) {
		netdev_warn(netdev, "LRO is incompatible with AF_XDP (%hu XSKs are active)\n",
			    priv->xsk.refcnt);
		err = -EINVAL;
		goto out;
	}

3629
	old_params = &priv->channels.params;
3630 3631 3632 3633 3634 3635
	if (enable && !MLX5E_GET_PFLAG(old_params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
		netdev_warn(netdev, "can't set LRO with legacy RQ\n");
		err = -EINVAL;
		goto out;
	}

3636
	reset = test_bit(MLX5E_STATE_OPENED, &priv->state);
3637

3638
	new_channels.params = *old_params;
3639 3640
	new_channels.params.lro_en = enable;

3641
	if (old_params->rq_wq_type != MLX5_WQ_TYPE_CYCLIC) {
3642 3643
		if (mlx5e_rx_mpwqe_is_linear_skb(mdev, old_params, NULL) ==
		    mlx5e_rx_mpwqe_is_linear_skb(mdev, &new_channels.params, NULL))
3644 3645 3646
			reset = false;
	}

3647
	if (!reset) {
3648
		*old_params = new_channels.params;
3649 3650
		err = mlx5e_modify_tirs_lro(priv);
		goto out;
3651
	}
3652

3653
	err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_modify_tirs_lro);
3654
out:
3655
	mutex_unlock(&priv->state_lock);
3656 3657 3658
	return err;
}

3659
static int set_feature_cvlan_filter(struct net_device *netdev, bool enable)
3660 3661 3662 3663
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (enable)
3664
		mlx5e_enable_cvlan_filter(priv);
3665
	else
3666
		mlx5e_disable_cvlan_filter(priv);
3667 3668 3669 3670

	return 0;
}

3671
#ifdef CONFIG_MLX5_ESWITCH
3672 3673 3674
static int set_feature_tc_num_filters(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3675

3676
	if (!enable && mlx5e_tc_num_filters(priv, MLX5_TC_FLAG(NIC_OFFLOAD))) {
3677 3678 3679 3680 3681
		netdev_err(netdev,
			   "Active offloaded tc filters, can't turn hw_tc_offload off\n");
		return -EINVAL;
	}

3682 3683
	return 0;
}
3684
#endif
3685

3686 3687 3688 3689 3690 3691 3692 3693
static int set_feature_rx_all(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_set_port_fcs(mdev, !enable);
}

3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710
static int set_feature_rx_fcs(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

	mutex_lock(&priv->state_lock);

	priv->channels.params.scatter_fcs_en = enable;
	err = mlx5e_modify_channels_scatter_fcs(&priv->channels, enable);
	if (err)
		priv->channels.params.scatter_fcs_en = !enable;

	mutex_unlock(&priv->state_lock);

	return err;
}

3711 3712 3713
static int set_feature_rx_vlan(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3714
	int err = 0;
3715 3716 3717

	mutex_lock(&priv->state_lock);

3718
	priv->channels.params.vlan_strip_disable = !enable;
3719 3720 3721 3722
	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
		goto unlock;

	err = mlx5e_modify_channels_vsd(&priv->channels, !enable);
3723
	if (err)
3724
		priv->channels.params.vlan_strip_disable = enable;
3725

3726
unlock:
3727 3728 3729 3730 3731
	mutex_unlock(&priv->state_lock);

	return err;
}

3732
#ifdef CONFIG_MLX5_EN_ARFS
3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746
static int set_feature_arfs(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

	if (enable)
		err = mlx5e_arfs_enable(priv);
	else
		err = mlx5e_arfs_disable(priv);

	return err;
}
#endif

3747
static int mlx5e_handle_feature(struct net_device *netdev,
3748
				netdev_features_t *features,
3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761
				netdev_features_t wanted_features,
				netdev_features_t feature,
				mlx5e_feature_handler feature_handler)
{
	netdev_features_t changes = wanted_features ^ netdev->features;
	bool enable = !!(wanted_features & feature);
	int err;

	if (!(changes & feature))
		return 0;

	err = feature_handler(netdev, enable);
	if (err) {
3762 3763
		netdev_err(netdev, "%s feature %pNF failed, err %d\n",
			   enable ? "Enable" : "Disable", &feature, err);
3764 3765 3766
		return err;
	}

3767
	MLX5E_SET_FEATURE(features, feature, enable);
3768 3769 3770
	return 0;
}

3771
int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
3772
{
3773
	netdev_features_t oper_features = netdev->features;
3774 3775 3776 3777
	int err = 0;

#define MLX5E_HANDLE_FEATURE(feature, handler) \
	mlx5e_handle_feature(netdev, &oper_features, features, feature, handler)
3778

3779 3780
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro);
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER,
3781
				    set_feature_cvlan_filter);
3782
#ifdef CONFIG_MLX5_ESWITCH
3783
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters);
3784
#endif
3785 3786 3787
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXALL, set_feature_rx_all);
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_RXFCS, set_feature_rx_fcs);
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_RX, set_feature_rx_vlan);
3788
#ifdef CONFIG_MLX5_EN_ARFS
3789
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_NTUPLE, set_feature_arfs);
3790
#endif
3791

3792 3793 3794 3795 3796 3797
	if (err) {
		netdev->features = oper_features;
		return -EINVAL;
	}

	return 0;
3798 3799
}

3800 3801 3802 3803
static netdev_features_t mlx5e_fix_features(struct net_device *netdev,
					    netdev_features_t features)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3804
	struct mlx5e_params *params;
3805 3806

	mutex_lock(&priv->state_lock);
3807
	params = &priv->channels.params;
3808 3809 3810 3811 3812
	if (!bitmap_empty(priv->fs.vlan.active_svlans, VLAN_N_VID)) {
		/* HW strips the outer C-tag header, this is a problem
		 * for S-tag traffic.
		 */
		features &= ~NETIF_F_HW_VLAN_CTAG_RX;
3813
		if (!params->vlan_strip_disable)
3814 3815
			netdev_warn(netdev, "Dropping C-tag vlan stripping offload due to S-tag vlan\n");
	}
3816
	if (!MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
3817
		if (features & NETIF_F_LRO) {
3818
			netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n");
3819 3820
			features &= ~NETIF_F_LRO;
		}
3821 3822
	}

3823 3824 3825 3826 3827 3828
	if (MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS)) {
		features &= ~NETIF_F_RXHASH;
		if (netdev->features & NETIF_F_RXHASH)
			netdev_warn(netdev, "Disabling rxhash, not supported when CQE compress is active\n");
	}

3829 3830 3831 3832 3833
	mutex_unlock(&priv->state_lock);

	return features;
}

3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870
static bool mlx5e_xsk_validate_mtu(struct net_device *netdev,
				   struct mlx5e_channels *chs,
				   struct mlx5e_params *new_params,
				   struct mlx5_core_dev *mdev)
{
	u16 ix;

	for (ix = 0; ix < chs->params.num_channels; ix++) {
		struct xdp_umem *umem = mlx5e_xsk_get_umem(&chs->params, chs->params.xsk, ix);
		struct mlx5e_xsk_param xsk;

		if (!umem)
			continue;

		mlx5e_build_xsk_param(umem, &xsk);

		if (!mlx5e_validate_xsk_param(new_params, &xsk, mdev)) {
			u32 hr = mlx5e_get_linear_rq_headroom(new_params, &xsk);
			int max_mtu_frame, max_mtu_page, max_mtu;

			/* Two criteria must be met:
			 * 1. HW MTU + all headrooms <= XSK frame size.
			 * 2. Size of SKBs allocated on XDP_PASS <= PAGE_SIZE.
			 */
			max_mtu_frame = MLX5E_HW2SW_MTU(new_params, xsk.chunk_size - hr);
			max_mtu_page = mlx5e_xdp_max_mtu(new_params, &xsk);
			max_mtu = min(max_mtu_frame, max_mtu_page);

			netdev_err(netdev, "MTU %d is too big for an XSK running on channel %hu. Try MTU <= %d\n",
				   new_params->sw_mtu, ix, max_mtu);
			return false;
		}
	}

	return true;
}

3871 3872
int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
		     change_hw_mtu_cb set_mtu_cb)
3873 3874
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3875
	struct mlx5e_channels new_channels = {};
3876
	struct mlx5e_params *params;
3877
	int err = 0;
3878
	bool reset;
3879 3880

	mutex_lock(&priv->state_lock);
3881

3882
	params = &priv->channels.params;
3883

3884
	reset = !params->lro_en;
3885
	reset = reset && test_bit(MLX5E_STATE_OPENED, &priv->state);
3886

3887 3888 3889
	new_channels.params = *params;
	new_channels.params.sw_mtu = new_mtu;

3890
	if (params->xdp_prog &&
3891
	    !mlx5e_rx_is_linear_skb(&new_channels.params, NULL)) {
3892
		netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n",
3893
			   new_mtu, mlx5e_xdp_max_mtu(params, NULL));
3894 3895 3896 3897
		err = -EINVAL;
		goto out;
	}

3898 3899 3900
	if (priv->xsk.refcnt &&
	    !mlx5e_xsk_validate_mtu(netdev, &priv->channels,
				    &new_channels.params, priv->mdev)) {
3901 3902 3903 3904
		err = -EINVAL;
		goto out;
	}

3905
	if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
3906 3907 3908 3909 3910 3911 3912 3913
		bool is_linear = mlx5e_rx_mpwqe_is_linear_skb(priv->mdev,
							      &new_channels.params,
							      NULL);
		u8 ppw_old = mlx5e_mpwqe_log_pkts_per_wqe(params, NULL);
		u8 ppw_new = mlx5e_mpwqe_log_pkts_per_wqe(&new_channels.params, NULL);

		/* If XSK is active, XSK RQs are linear. */
		is_linear |= priv->xsk.refcnt;
3914

3915
		/* Always reset in linear mode - hw_mtu is used in data path. */
3916
		reset = reset && (is_linear || (ppw_old != ppw_new));
3917 3918
	}

3919
	if (!reset) {
3920
		params->sw_mtu = new_mtu;
3921 3922
		if (set_mtu_cb)
			set_mtu_cb(priv);
3923
		netdev->mtu = params->sw_mtu;
3924 3925
		goto out;
	}
3926

3927
	err = mlx5e_safe_switch_channels(priv, &new_channels, set_mtu_cb);
3928
	if (err)
3929 3930
		goto out;

3931
	netdev->mtu = new_channels.params.sw_mtu;
3932

3933 3934
out:
	mutex_unlock(&priv->state_lock);
3935 3936 3937
	return err;
}

3938 3939 3940 3941 3942
static int mlx5e_change_nic_mtu(struct net_device *netdev, int new_mtu)
{
	return mlx5e_change_mtu(netdev, new_mtu, mlx5e_set_dev_port_mtu);
}

3943 3944 3945 3946 3947
int mlx5e_hwstamp_set(struct mlx5e_priv *priv, struct ifreq *ifr)
{
	struct hwtstamp_config config;
	int err;

3948 3949
	if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz) ||
	    (mlx5_clock_get_ptp_index(priv->mdev) == -1))
3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986
		return -EOPNOTSUPP;

	if (copy_from_user(&config, ifr->ifr_data, sizeof(config)))
		return -EFAULT;

	/* TX HW timestamp */
	switch (config.tx_type) {
	case HWTSTAMP_TX_OFF:
	case HWTSTAMP_TX_ON:
		break;
	default:
		return -ERANGE;
	}

	mutex_lock(&priv->state_lock);
	/* RX HW timestamp */
	switch (config.rx_filter) {
	case HWTSTAMP_FILTER_NONE:
		/* Reset CQE compression to Admin default */
		mlx5e_modify_rx_cqe_compression_locked(priv, priv->channels.params.rx_cqe_compress_def);
		break;
	case HWTSTAMP_FILTER_ALL:
	case HWTSTAMP_FILTER_SOME:
	case HWTSTAMP_FILTER_PTP_V1_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L4_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L4_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_L2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_L2_DELAY_REQ:
	case HWTSTAMP_FILTER_PTP_V2_EVENT:
	case HWTSTAMP_FILTER_PTP_V2_SYNC:
	case HWTSTAMP_FILTER_PTP_V2_DELAY_REQ:
	case HWTSTAMP_FILTER_NTP_ALL:
		/* Disable CQE compression */
3987 3988
		if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS))
			netdev_warn(priv->netdev, "Disabling RX cqe compression\n");
3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004
		err = mlx5e_modify_rx_cqe_compression_locked(priv, false);
		if (err) {
			netdev_err(priv->netdev, "Failed disabling cqe compression err=%d\n", err);
			mutex_unlock(&priv->state_lock);
			return err;
		}
		config.rx_filter = HWTSTAMP_FILTER_ALL;
		break;
	default:
		mutex_unlock(&priv->state_lock);
		return -ERANGE;
	}

	memcpy(&priv->tstamp, &config, sizeof(config));
	mutex_unlock(&priv->state_lock);

4005 4006 4007
	/* might need to fix some features */
	netdev_update_features(priv->netdev);

4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021
	return copy_to_user(ifr->ifr_data, &config,
			    sizeof(config)) ? -EFAULT : 0;
}

int mlx5e_hwstamp_get(struct mlx5e_priv *priv, struct ifreq *ifr)
{
	struct hwtstamp_config *cfg = &priv->tstamp;

	if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz))
		return -EOPNOTSUPP;

	return copy_to_user(ifr->ifr_data, cfg, sizeof(*cfg)) ? -EFAULT : 0;
}

4022 4023
static int mlx5e_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
4024 4025
	struct mlx5e_priv *priv = netdev_priv(dev);

4026 4027
	switch (cmd) {
	case SIOCSHWTSTAMP:
4028
		return mlx5e_hwstamp_set(priv, ifr);
4029
	case SIOCGHWTSTAMP:
4030
		return mlx5e_hwstamp_get(priv, ifr);
4031 4032 4033 4034 4035
	default:
		return -EOPNOTSUPP;
	}
}

4036
#ifdef CONFIG_MLX5_ESWITCH
4037
int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
4038 4039 4040 4041 4042 4043 4044
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_eswitch_set_vport_mac(mdev->priv.eswitch, vf + 1, mac);
}

4045 4046
static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
			     __be16 vlan_proto)
4047 4048 4049 4050
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

4051 4052 4053
	if (vlan_proto != htons(ETH_P_8021Q))
		return -EPROTONOSUPPORT;

4054 4055 4056 4057
	return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1,
					   vlan, qos);
}

4058 4059 4060 4061 4062 4063 4064 4065
static int mlx5e_set_vf_spoofchk(struct net_device *dev, int vf, bool setting)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_eswitch_set_vport_spoofchk(mdev->priv.eswitch, vf + 1, setting);
}

4066 4067 4068 4069 4070 4071 4072
static int mlx5e_set_vf_trust(struct net_device *dev, int vf, bool setting)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_eswitch_set_vport_trust(mdev->priv.eswitch, vf + 1, setting);
}
4073

4074 4075
int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
		      int max_tx_rate)
4076 4077 4078 4079 4080
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_eswitch_set_vport_rate(mdev->priv.eswitch, vf + 1,
4081
					   max_tx_rate, min_tx_rate);
4082 4083
}

4084 4085 4086
static int mlx5_vport_link2ifla(u8 esw_link)
{
	switch (esw_link) {
4087
	case MLX5_VPORT_ADMIN_STATE_DOWN:
4088
		return IFLA_VF_LINK_STATE_DISABLE;
4089
	case MLX5_VPORT_ADMIN_STATE_UP:
4090 4091 4092 4093 4094 4095 4096 4097 4098
		return IFLA_VF_LINK_STATE_ENABLE;
	}
	return IFLA_VF_LINK_STATE_AUTO;
}

static int mlx5_ifla_link2vport(u8 ifla_link)
{
	switch (ifla_link) {
	case IFLA_VF_LINK_STATE_DISABLE:
4099
		return MLX5_VPORT_ADMIN_STATE_DOWN;
4100
	case IFLA_VF_LINK_STATE_ENABLE:
4101
		return MLX5_VPORT_ADMIN_STATE_UP;
4102
	}
4103
	return MLX5_VPORT_ADMIN_STATE_AUTO;
4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115
}

static int mlx5e_set_vf_link_state(struct net_device *dev, int vf,
				   int link_state)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_eswitch_set_vport_state(mdev->priv.eswitch, vf + 1,
					    mlx5_ifla_link2vport(link_state));
}

4116 4117
int mlx5e_get_vf_config(struct net_device *dev,
			int vf, struct ifla_vf_info *ivi)
4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;
	int err;

	err = mlx5_eswitch_get_vport_config(mdev->priv.eswitch, vf + 1, ivi);
	if (err)
		return err;
	ivi->linkstate = mlx5_vport_link2ifla(ivi->linkstate);
	return 0;
}

4130 4131
int mlx5e_get_vf_stats(struct net_device *dev,
		       int vf, struct ifla_vf_stats *vf_stats)
4132 4133 4134 4135 4136 4137 4138
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

	return mlx5_eswitch_get_vport_stats(mdev->priv.eswitch, vf + 1,
					    vf_stats);
}
4139
#endif
4140

4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154
struct mlx5e_vxlan_work {
	struct work_struct	work;
	struct mlx5e_priv	*priv;
	u16			port;
};

static void mlx5e_vxlan_add_work(struct work_struct *work)
{
	struct mlx5e_vxlan_work *vxlan_work =
		container_of(work, struct mlx5e_vxlan_work, work);
	struct mlx5e_priv *priv = vxlan_work->priv;
	u16 port = vxlan_work->port;

	mutex_lock(&priv->state_lock);
4155
	mlx5_vxlan_add_port(priv->mdev->vxlan, port);
4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168
	mutex_unlock(&priv->state_lock);

	kfree(vxlan_work);
}

static void mlx5e_vxlan_del_work(struct work_struct *work)
{
	struct mlx5e_vxlan_work *vxlan_work =
		container_of(work, struct mlx5e_vxlan_work, work);
	struct mlx5e_priv *priv         = vxlan_work->priv;
	u16 port = vxlan_work->port;

	mutex_lock(&priv->state_lock);
4169
	mlx5_vxlan_del_port(priv->mdev->vxlan, port);
4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191
	mutex_unlock(&priv->state_lock);
	kfree(vxlan_work);
}

static void mlx5e_vxlan_queue_work(struct mlx5e_priv *priv, u16 port, int add)
{
	struct mlx5e_vxlan_work *vxlan_work;

	vxlan_work = kmalloc(sizeof(*vxlan_work), GFP_ATOMIC);
	if (!vxlan_work)
		return;

	if (add)
		INIT_WORK(&vxlan_work->work, mlx5e_vxlan_add_work);
	else
		INIT_WORK(&vxlan_work->work, mlx5e_vxlan_del_work);

	vxlan_work->priv = priv;
	vxlan_work->port = port;
	queue_work(priv->wq, &vxlan_work->work);
}

4192
void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
4193 4194 4195
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

4196 4197 4198
	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
		return;

4199
	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4200 4201
		return;

4202
	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
4203 4204
}

4205
void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
4206 4207 4208
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

4209 4210 4211
	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
		return;

4212
	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4213 4214
		return;

4215
	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
4216 4217
}

4218 4219 4220
static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
						     struct sk_buff *skb,
						     netdev_features_t features)
4221
{
4222
	unsigned int offset = 0;
4223
	struct udphdr *udph;
4224 4225
	u8 proto;
	u16 port;
4226 4227 4228 4229 4230 4231

	switch (vlan_get_protocol(skb)) {
	case htons(ETH_P_IP):
		proto = ip_hdr(skb)->protocol;
		break;
	case htons(ETH_P_IPV6):
4232
		proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL);
4233 4234 4235 4236 4237
		break;
	default:
		goto out;
	}

4238 4239
	switch (proto) {
	case IPPROTO_GRE:
4240
		return features;
4241 4242
	case IPPROTO_IPIP:
	case IPPROTO_IPV6:
4243 4244 4245
		if (mlx5e_tunnel_proto_supported(priv->mdev, IPPROTO_IPIP))
			return features;
		break;
4246
	case IPPROTO_UDP:
4247 4248 4249
		udph = udp_hdr(skb);
		port = be16_to_cpu(udph->dest);

4250
		/* Verify if UDP port is being offloaded by HW */
4251
		if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
4252
			return features;
4253 4254 4255 4256 4257 4258

#if IS_ENABLED(CONFIG_GENEVE)
		/* Support Geneve offload for default UDP port */
		if (port == GENEVE_UDP_PORT && mlx5_geneve_tx_allowed(priv->mdev))
			return features;
#endif
4259
	}
4260 4261 4262 4263 4264 4265

out:
	/* Disable CSUM and GSO if the udp dport is not offloaded by HW */
	return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}

4266 4267 4268
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
				       struct net_device *netdev,
				       netdev_features_t features)
4269 4270 4271 4272 4273 4274
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	features = vlan_features_check(skb, features);
	features = vxlan_features_check(skb, features);

4275 4276 4277 4278 4279
#ifdef CONFIG_MLX5_EN_IPSEC
	if (mlx5e_ipsec_feature_check(skb, netdev, features))
		return features;
#endif

4280 4281 4282
	/* Validate if the tunneled packet is being offloaded by HW */
	if (skb->encapsulation &&
	    (features & NETIF_F_CSUM_MASK || features & NETIF_F_GSO_MASK))
4283
		return mlx5e_tunnel_features_check(priv, skb, features);
4284 4285 4286 4287

	return features;
}

4288
static void mlx5e_tx_timeout_work(struct work_struct *work)
4289
{
4290 4291
	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
					       tx_timeout_work);
4292 4293 4294
	bool report_failed = false;
	int err;
	int i;
4295

4296 4297 4298 4299 4300
	rtnl_lock();
	mutex_lock(&priv->state_lock);

	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
		goto unlock;
4301

4302
	for (i = 0; i < priv->channels.num * priv->channels.params.num_tc; i++) {
4303 4304
		struct netdev_queue *dev_queue =
			netdev_get_tx_queue(priv->netdev, i);
4305
		struct mlx5e_txqsq *sq = priv->txq2sq[i];
4306

4307
		if (!netif_xmit_stopped(dev_queue))
4308
			continue;
4309

4310
		if (mlx5e_reporter_tx_timeout(sq))
4311
			report_failed = true;
4312 4313
	}

4314
	if (!report_failed)
4315 4316
		goto unlock;

4317
	err = mlx5e_safe_reopen_channels(priv);
4318 4319
	if (err)
		netdev_err(priv->netdev,
4320
			   "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
4321 4322
			   err);

4323 4324 4325 4326 4327
unlock:
	mutex_unlock(&priv->state_lock);
	rtnl_unlock();
}

4328
static void mlx5e_tx_timeout(struct net_device *dev, unsigned int txqueue)
4329 4330 4331 4332 4333
{
	struct mlx5e_priv *priv = netdev_priv(dev);

	netdev_err(dev, "TX timeout detected\n");
	queue_work(priv->wq, &priv->tx_timeout_work);
4334 4335
}

4336
static int mlx5e_xdp_allowed(struct mlx5e_priv *priv, struct bpf_prog *prog)
4337 4338
{
	struct net_device *netdev = priv->netdev;
4339
	struct mlx5e_channels new_channels = {};
4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350

	if (priv->channels.params.lro_en) {
		netdev_warn(netdev, "can't set XDP while LRO is on, disable LRO first\n");
		return -EINVAL;
	}

	if (MLX5_IPSEC_DEV(priv->mdev)) {
		netdev_warn(netdev, "can't set XDP with IPSec offload\n");
		return -EINVAL;
	}

4351 4352 4353
	new_channels.params = priv->channels.params;
	new_channels.params.xdp_prog = prog;

4354 4355 4356 4357
	/* No XSK params: AF_XDP can't be enabled yet at the point of setting
	 * the XDP program.
	 */
	if (!mlx5e_rx_is_linear_skb(&new_channels.params, NULL)) {
4358
		netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n",
4359
			    new_channels.params.sw_mtu,
4360
			    mlx5e_xdp_max_mtu(&new_channels.params, NULL));
4361 4362 4363
		return -EINVAL;
	}

4364 4365 4366
	return 0;
}

4367 4368 4369 4370 4371
static int mlx5e_xdp_set(struct net_device *netdev, struct bpf_prog *prog)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct bpf_prog *old_prog;
	bool reset, was_opened;
4372
	int err = 0;
4373 4374 4375 4376
	int i;

	mutex_lock(&priv->state_lock);

4377
	if (prog) {
4378
		err = mlx5e_xdp_allowed(priv, prog);
4379 4380
		if (err)
			goto unlock;
4381 4382
	}

4383 4384
	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
	/* no need for full reset when exchanging programs */
4385
	reset = (!priv->channels.params.xdp_prog || !prog);
4386

4387
	if (was_opened && !reset)
4388 4389 4390
		/* num_channels is invariant here, so we can take the
		 * batched reference right upfront.
		 */
4391
		bpf_prog_add(prog, priv->channels.num);
4392

4393 4394 4395 4396 4397 4398 4399 4400
	if (was_opened && reset) {
		struct mlx5e_channels new_channels = {};

		new_channels.params = priv->channels.params;
		new_channels.params.xdp_prog = prog;
		mlx5e_set_rq_type(priv->mdev, &new_channels.params);
		old_prog = priv->channels.params.xdp_prog;

4401
		err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
4402 4403 4404 4405 4406 4407 4408 4409 4410
		if (err)
			goto unlock;
	} else {
		/* exchange programs, extra prog reference we got from caller
		 * as long as we don't fail from this point onwards.
		 */
		old_prog = xchg(&priv->channels.params.xdp_prog, prog);
	}

4411 4412 4413
	if (old_prog)
		bpf_prog_put(old_prog);

4414
	if (!was_opened && reset) /* change RQ type according to priv->xdp_prog */
4415
		mlx5e_set_rq_type(priv->mdev, &priv->channels.params);
4416

4417
	if (!was_opened || reset)
4418 4419 4420 4421 4422
		goto unlock;

	/* exchanging programs w/o reset, we update ref counts on behalf
	 * of the channels RQs here.
	 */
4423 4424
	for (i = 0; i < priv->channels.num; i++) {
		struct mlx5e_channel *c = priv->channels.c[i];
4425
		bool xsk_open = test_bit(MLX5E_CHANNEL_STATE_XSK, c->state);
4426

4427
		clear_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
4428 4429
		if (xsk_open)
			clear_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
4430 4431 4432 4433
		napi_synchronize(&c->napi);
		/* prevent mlx5e_poll_rx_cq from accessing rq->xdp_prog */

		old_prog = xchg(&c->rq.xdp_prog, prog);
4434 4435 4436 4437 4438 4439 4440 4441
		if (old_prog)
			bpf_prog_put(old_prog);

		if (xsk_open) {
			old_prog = xchg(&c->xskrq.xdp_prog, prog);
			if (old_prog)
				bpf_prog_put(old_prog);
		}
4442

4443
		set_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
4444 4445
		if (xsk_open)
			set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
4446 4447 4448 4449 4450 4451 4452 4453 4454
		/* napi_schedule in case we have missed anything */
		napi_schedule(&c->napi);
	}

unlock:
	mutex_unlock(&priv->state_lock);
	return err;
}

4455
static u32 mlx5e_xdp_query(struct net_device *dev)
4456 4457
{
	struct mlx5e_priv *priv = netdev_priv(dev);
4458 4459
	const struct bpf_prog *xdp_prog;
	u32 prog_id = 0;
4460

4461 4462 4463 4464 4465 4466 4467
	mutex_lock(&priv->state_lock);
	xdp_prog = priv->channels.params.xdp_prog;
	if (xdp_prog)
		prog_id = xdp_prog->aux->id;
	mutex_unlock(&priv->state_lock);

	return prog_id;
4468 4469
}

4470
static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
4471 4472 4473 4474 4475
{
	switch (xdp->command) {
	case XDP_SETUP_PROG:
		return mlx5e_xdp_set(dev, xdp->prog);
	case XDP_QUERY_PROG:
4476
		xdp->prog_id = mlx5e_xdp_query(dev);
4477
		return 0;
4478 4479 4480
	case XDP_SETUP_XSK_UMEM:
		return mlx5e_xsk_setup_umem(dev, xdp->xsk.umem,
					    xdp->xsk.queue_id);
4481 4482 4483 4484 4485
	default:
		return -EINVAL;
	}
}

4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540
#ifdef CONFIG_MLX5_ESWITCH
static int mlx5e_bridge_getlink(struct sk_buff *skb, u32 pid, u32 seq,
				struct net_device *dev, u32 filter_mask,
				int nlflags)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;
	u8 mode, setting;
	int err;

	err = mlx5_eswitch_get_vepa(mdev->priv.eswitch, &setting);
	if (err)
		return err;
	mode = setting ? BRIDGE_MODE_VEPA : BRIDGE_MODE_VEB;
	return ndo_dflt_bridge_getlink(skb, pid, seq, dev,
				       mode,
				       0, 0, nlflags, filter_mask, NULL);
}

static int mlx5e_bridge_setlink(struct net_device *dev, struct nlmsghdr *nlh,
				u16 flags, struct netlink_ext_ack *extack)
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;
	struct nlattr *attr, *br_spec;
	u16 mode = BRIDGE_MODE_UNDEF;
	u8 setting;
	int rem;

	br_spec = nlmsg_find_attr(nlh, sizeof(struct ifinfomsg), IFLA_AF_SPEC);
	if (!br_spec)
		return -EINVAL;

	nla_for_each_nested(attr, br_spec, rem) {
		if (nla_type(attr) != IFLA_BRIDGE_MODE)
			continue;

		if (nla_len(attr) < sizeof(mode))
			return -EINVAL;

		mode = nla_get_u16(attr);
		if (mode > BRIDGE_MODE_VEPA)
			return -EINVAL;

		break;
	}

	if (mode == BRIDGE_MODE_UNDEF)
		return -EINVAL;

	setting = (mode == BRIDGE_MODE_VEPA) ?  1 : 0;
	return mlx5_eswitch_set_vepa(mdev->priv.eswitch, setting);
}
#endif

4541
const struct net_device_ops mlx5e_netdev_ops = {
4542 4543 4544
	.ndo_open                = mlx5e_open,
	.ndo_stop                = mlx5e_close,
	.ndo_start_xmit          = mlx5e_xmit,
4545
	.ndo_setup_tc            = mlx5e_setup_tc,
4546
	.ndo_select_queue        = mlx5e_select_queue,
4547 4548 4549
	.ndo_get_stats64         = mlx5e_get_stats,
	.ndo_set_rx_mode         = mlx5e_set_rx_mode,
	.ndo_set_mac_address     = mlx5e_set_mac,
4550 4551
	.ndo_vlan_rx_add_vid     = mlx5e_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid    = mlx5e_vlan_rx_kill_vid,
4552
	.ndo_set_features        = mlx5e_set_features,
4553
	.ndo_fix_features        = mlx5e_fix_features,
4554
	.ndo_change_mtu          = mlx5e_change_nic_mtu,
4555
	.ndo_do_ioctl            = mlx5e_ioctl,
4556
	.ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
4557 4558 4559
	.ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
	.ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
	.ndo_features_check      = mlx5e_features_check,
4560
	.ndo_tx_timeout          = mlx5e_tx_timeout,
4561
	.ndo_bpf		 = mlx5e_xdp,
4562
	.ndo_xdp_xmit            = mlx5e_xdp_xmit,
4563
	.ndo_xsk_wakeup          = mlx5e_xsk_wakeup,
4564 4565 4566
#ifdef CONFIG_MLX5_EN_ARFS
	.ndo_rx_flow_steer	 = mlx5e_rx_flow_steer,
#endif
4567
#ifdef CONFIG_MLX5_ESWITCH
4568 4569 4570
	.ndo_bridge_setlink      = mlx5e_bridge_setlink,
	.ndo_bridge_getlink      = mlx5e_bridge_getlink,

4571
	/* SRIOV E-Switch NDOs */
4572 4573
	.ndo_set_vf_mac          = mlx5e_set_vf_mac,
	.ndo_set_vf_vlan         = mlx5e_set_vf_vlan,
4574
	.ndo_set_vf_spoofchk     = mlx5e_set_vf_spoofchk,
4575
	.ndo_set_vf_trust        = mlx5e_set_vf_trust,
4576
	.ndo_set_vf_rate         = mlx5e_set_vf_rate,
4577 4578 4579
	.ndo_get_vf_config       = mlx5e_get_vf_config,
	.ndo_set_vf_link_state   = mlx5e_set_vf_link_state,
	.ndo_get_vf_stats        = mlx5e_get_vf_stats,
4580
#endif
4581 4582 4583 4584 4585
};

static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
{
	if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
4586
		return -EOPNOTSUPP;
4587 4588 4589 4590 4591
	if (!MLX5_CAP_GEN(mdev, eth_net_offloads) ||
	    !MLX5_CAP_GEN(mdev, nic_flow_table) ||
	    !MLX5_CAP_ETH(mdev, csum_cap) ||
	    !MLX5_CAP_ETH(mdev, max_lso_cap) ||
	    !MLX5_CAP_ETH(mdev, vlan_cap) ||
4592 4593 4594 4595
	    !MLX5_CAP_ETH(mdev, rss_ind_tbl_cap) ||
	    MLX5_CAP_FLOWTABLE(mdev,
			       flow_table_properties_nic_receive.max_ft_level)
			       < 3) {
4596 4597
		mlx5_core_warn(mdev,
			       "Not creating net device, some required device capabilities are missing\n");
4598
		return -EOPNOTSUPP;
4599
	}
4600 4601
	if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable))
		mlx5_core_warn(mdev, "Self loop back prevention is not supported\n");
4602
	if (!MLX5_CAP_GEN(mdev, cq_moderation))
4603
		mlx5_core_warn(mdev, "CQ moderation is not supported\n");
4604

4605 4606 4607
	return 0;
}

4608
void mlx5e_build_default_indir_rqt(u32 *indirection_rqt, int len,
4609 4610 4611 4612 4613 4614 4615 4616
				   int num_channels)
{
	int i;

	for (i = 0; i < len; i++)
		indirection_rqt[i] = i % num_channels;
}

4617
static bool slow_pci_heuristic(struct mlx5_core_dev *mdev)
4618
{
4619 4620
	u32 link_speed = 0;
	u32 pci_bw = 0;
4621

4622
	mlx5e_port_max_linkspeed(mdev, &link_speed);
4623
	pci_bw = pcie_bandwidth_available(mdev->pdev, NULL, NULL, NULL);
4624 4625 4626 4627 4628 4629 4630
	mlx5_core_dbg_once(mdev, "Max link speed = %d, PCI BW = %d\n",
			   link_speed, pci_bw);

#define MLX5E_SLOW_PCI_RATIO (2)

	return link_speed && pci_bw &&
		link_speed > MLX5E_SLOW_PCI_RATIO * pci_bw;
4631 4632
}

4633
static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
4634
{
4635
	struct dim_cq_moder moder;
4636 4637 4638 4639 4640 4641 4642 4643 4644

	moder.cq_period_mode = cq_period_mode;
	moder.pkts = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
	moder.usec = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC;
	if (cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE)
		moder.usec = MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC_FROM_CQE;

	return moder;
}
4645

4646
static struct dim_cq_moder mlx5e_get_def_rx_moderation(u8 cq_period_mode)
4647
{
4648
	struct dim_cq_moder moder;
4649

4650 4651 4652
	moder.cq_period_mode = cq_period_mode;
	moder.pkts = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS;
	moder.usec = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC;
4653
	if (cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE)
4654 4655 4656 4657 4658 4659 4660 4661
		moder.usec = MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE;

	return moder;
}

static u8 mlx5_to_net_dim_cq_period_mode(u8 cq_period_mode)
{
	return cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE ?
4662 4663
		DIM_CQ_PERIOD_MODE_START_FROM_CQE :
		DIM_CQ_PERIOD_MODE_START_FROM_EQE;
4664 4665 4666 4667 4668 4669 4670 4671 4672 4673 4674
}

void mlx5e_set_tx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
{
	if (params->tx_dim_enabled) {
		u8 dim_period_mode = mlx5_to_net_dim_cq_period_mode(cq_period_mode);

		params->tx_cq_moderation = net_dim_get_def_tx_moderation(dim_period_mode);
	} else {
		params->tx_cq_moderation = mlx5e_get_def_tx_moderation(cq_period_mode);
	}
4675 4676 4677 4678 4679 4680

	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_TX_CQE_BASED_MODER,
			params->tx_cq_moderation.cq_period_mode ==
				MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
}

T
Tariq Toukan 已提交
4681 4682
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
{
4683
	if (params->rx_dim_enabled) {
4684 4685 4686 4687 4688
		u8 dim_period_mode = mlx5_to_net_dim_cq_period_mode(cq_period_mode);

		params->rx_cq_moderation = net_dim_get_def_rx_moderation(dim_period_mode);
	} else {
		params->rx_cq_moderation = mlx5e_get_def_rx_moderation(cq_period_mode);
4689
	}
4690

4691
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_BASED_MODER,
4692 4693
			params->rx_cq_moderation.cq_period_mode ==
				MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
T
Tariq Toukan 已提交
4694 4695
}

4696
static u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout)
4697 4698 4699 4700 4701 4702 4703 4704 4705 4706 4707
{
	int i;

	/* The supported periods are organized in ascending order */
	for (i = 0; i < MLX5E_LRO_TIMEOUT_ARR_SIZE - 1; i++)
		if (MLX5_CAP_ETH(mdev, lro_timer_supported_periods[i]) >= wanted_timeout)
			break;

	return MLX5_CAP_ETH(mdev, lro_timer_supported_periods[i]);
}

4708 4709 4710 4711 4712 4713 4714
void mlx5e_build_rq_params(struct mlx5_core_dev *mdev,
			   struct mlx5e_params *params)
{
	/* Prefer Striding RQ, unless any of the following holds:
	 * - Striding RQ configuration is not possible/supported.
	 * - Slow PCI heuristic.
	 * - Legacy RQ would use linear SKB while Striding RQ would use non-linear.
4715 4716
	 *
	 * No XSK params: checking the availability of striding RQ in general.
4717 4718 4719
	 */
	if (!slow_pci_heuristic(mdev) &&
	    mlx5e_striding_rq_possible(mdev, params) &&
4720 4721
	    (mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL) ||
	     !mlx5e_rx_is_linear_skb(params, NULL)))
4722 4723 4724 4725 4726
		MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ, true);
	mlx5e_set_rq_type(mdev, params);
	mlx5e_init_rq_type_params(mdev, params);
}

4727 4728
void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
			    u16 num_channels)
4729
{
4730 4731
	enum mlx5e_traffic_types tt;

4732
	rss_params->hfunc = ETH_RSS_HASH_TOP;
4733 4734 4735 4736
	netdev_rss_key_fill(rss_params->toeplitz_hash_key,
			    sizeof(rss_params->toeplitz_hash_key));
	mlx5e_build_default_indir_rqt(rss_params->indirection_rqt,
				      MLX5E_INDIR_RQT_SIZE, num_channels);
4737 4738 4739
	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
		rss_params->rx_hash_fields[tt] =
			tirc_default_config[tt].rx_hash_fields;
4740 4741
}

4742
void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
4743
			    struct mlx5e_xsk *xsk,
4744
			    struct mlx5e_rss_params *rss_params,
4745
			    struct mlx5e_params *params,
4746
			    u16 max_channels, u16 mtu)
4747
{
4748
	u8 rx_cq_period_mode;
4749

4750 4751
	params->sw_mtu = mtu;
	params->hard_mtu = MLX5E_ETH_HARD_MTU;
4752 4753
	params->num_channels = max_channels;
	params->num_tc       = 1;
4754

4755 4756
	/* SQ */
	params->log_sq_size = is_kdump_kernel() ?
4757 4758
		MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE :
		MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
4759

4760 4761 4762 4763
	/* XDP SQ */
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_XDP_TX_MPWQE,
			MLX5_CAP_ETH(mdev, enhanced_multi_pkt_send_wqe));

4764
	/* set CQE compression */
4765
	params->rx_cqe_compress_def = false;
4766
	if (MLX5_CAP_GEN(mdev, cqe_compression) &&
4767
	    MLX5_CAP_GEN(mdev, vport_group_manager))
4768
		params->rx_cqe_compress_def = slow_pci_heuristic(mdev);
4769

4770
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
4771
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE, false);
4772 4773

	/* RQ */
4774
	mlx5e_build_rq_params(mdev, params);
4775

4776
	/* HW LRO */
4777

4778
	/* TODO: && MLX5_CAP_ETH(mdev, lro_cap) */
4779 4780 4781
	if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
		/* No XSK params: checking the availability of striding RQ in general. */
		if (!mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL))
4782
			params->lro_en = !slow_pci_heuristic(mdev);
4783
	}
4784
	params->lro_timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT);
4785

4786
	/* CQ moderation params */
4787
	rx_cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
4788 4789
			MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
			MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
4790
	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
4791
	params->tx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
4792 4793
	mlx5e_set_rx_cq_mode_params(params, rx_cq_period_mode);
	mlx5e_set_tx_cq_mode_params(params, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
T
Tariq Toukan 已提交
4794

4795
	/* TX inline */
4796
	mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
4797

4798
	/* RSS */
4799
	mlx5e_build_rss_params(rss_params, params->num_channels);
4800 4801
	params->tunneled_offload_en =
		mlx5e_tunnel_inner_ft_supported(mdev);
4802 4803 4804

	/* AF_XDP */
	params->xsk = xsk;
4805
}
4806 4807 4808 4809 4810

static void mlx5e_set_netdev_dev_addr(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

4811
	mlx5_query_mac_address(priv->mdev, netdev->dev_addr);
4812 4813 4814 4815 4816
	if (is_zero_ether_addr(netdev->dev_addr) &&
	    !MLX5_CAP_GEN(priv->mdev, vport_group_manager)) {
		eth_hw_addr_random(netdev);
		mlx5_core_info(priv->mdev, "Assigned random MAC address %pM\n", netdev->dev_addr);
	}
4817 4818
}

4819
static void mlx5e_build_nic_netdev(struct net_device *netdev)
4820 4821 4822
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;
4823 4824
	bool fcs_supported;
	bool fcs_enabled;
4825

4826
	SET_NETDEV_DEV(netdev, mdev->device);
4827

4828 4829
	netdev->netdev_ops = &mlx5e_netdev_ops;

4830
#ifdef CONFIG_MLX5_CORE_EN_DCB
4831 4832
	if (MLX5_CAP_GEN(mdev, vport_group_manager) && MLX5_CAP_GEN(mdev, qos))
		netdev->dcbnl_ops = &mlx5e_dcbnl_ops;
4833
#endif
4834

4835 4836 4837 4838
	netdev->watchdog_timeo    = 15 * HZ;

	netdev->ethtool_ops	  = &mlx5e_ethtool_ops;

S
Saeed Mahameed 已提交
4839
	netdev->vlan_features    |= NETIF_F_SG;
4840
	netdev->vlan_features    |= NETIF_F_HW_CSUM;
4841 4842 4843 4844 4845 4846
	netdev->vlan_features    |= NETIF_F_GRO;
	netdev->vlan_features    |= NETIF_F_TSO;
	netdev->vlan_features    |= NETIF_F_TSO6;
	netdev->vlan_features    |= NETIF_F_RXCSUM;
	netdev->vlan_features    |= NETIF_F_RXHASH;

4847 4848 4849 4850 4851
	netdev->mpls_features    |= NETIF_F_SG;
	netdev->mpls_features    |= NETIF_F_HW_CSUM;
	netdev->mpls_features    |= NETIF_F_TSO;
	netdev->mpls_features    |= NETIF_F_TSO6;

4852 4853 4854
	netdev->hw_enc_features  |= NETIF_F_HW_VLAN_CTAG_TX;
	netdev->hw_enc_features  |= NETIF_F_HW_VLAN_CTAG_RX;

4855 4856
	if (!!MLX5_CAP_ETH(mdev, lro_cap) &&
	    mlx5e_check_fragmented_striding_rq_cap(mdev))
4857 4858 4859
		netdev->vlan_features    |= NETIF_F_LRO;

	netdev->hw_features       = netdev->vlan_features;
4860
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_TX;
4861 4862
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_RX;
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_FILTER;
4863
	netdev->hw_features      |= NETIF_F_HW_VLAN_STAG_TX;
4864

4865
	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
4866
	    mlx5e_any_tunnel_proto_supported(mdev)) {
4867
		netdev->hw_enc_features |= NETIF_F_HW_CSUM;
4868 4869
		netdev->hw_enc_features |= NETIF_F_TSO;
		netdev->hw_enc_features |= NETIF_F_TSO6;
4870 4871 4872
		netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
	}

4873
	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
4874 4875 4876 4877
		netdev->hw_features     |= NETIF_F_GSO_UDP_TUNNEL |
					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
		netdev->hw_enc_features |= NETIF_F_GSO_UDP_TUNNEL |
					   NETIF_F_GSO_UDP_TUNNEL_CSUM;
4878
		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
4879 4880
	}

4881
	if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_GRE)) {
4882 4883 4884 4885 4886 4887 4888 4889
		netdev->hw_features     |= NETIF_F_GSO_GRE |
					   NETIF_F_GSO_GRE_CSUM;
		netdev->hw_enc_features |= NETIF_F_GSO_GRE |
					   NETIF_F_GSO_GRE_CSUM;
		netdev->gso_partial_features |= NETIF_F_GSO_GRE |
						NETIF_F_GSO_GRE_CSUM;
	}

4890 4891 4892 4893 4894 4895 4896 4897 4898
	if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_IPIP)) {
		netdev->hw_features |= NETIF_F_GSO_IPXIP4 |
				       NETIF_F_GSO_IPXIP6;
		netdev->hw_enc_features |= NETIF_F_GSO_IPXIP4 |
					   NETIF_F_GSO_IPXIP6;
		netdev->gso_partial_features |= NETIF_F_GSO_IPXIP4 |
						NETIF_F_GSO_IPXIP6;
	}

4899 4900 4901 4902 4903
	netdev->hw_features	                 |= NETIF_F_GSO_PARTIAL;
	netdev->gso_partial_features             |= NETIF_F_GSO_UDP_L4;
	netdev->hw_features                      |= NETIF_F_GSO_UDP_L4;
	netdev->features                         |= NETIF_F_GSO_UDP_L4;

4904 4905 4906 4907 4908
	mlx5_query_port_fcs(mdev, &fcs_supported, &fcs_enabled);

	if (fcs_supported)
		netdev->hw_features |= NETIF_F_RXALL;

4909 4910 4911
	if (MLX5_CAP_ETH(mdev, scatter_fcs))
		netdev->hw_features |= NETIF_F_RXFCS;

4912
	netdev->features          = netdev->hw_features;
4913
	if (!priv->channels.params.lro_en)
4914 4915
		netdev->features  &= ~NETIF_F_LRO;

4916 4917 4918
	if (fcs_enabled)
		netdev->features  &= ~NETIF_F_RXALL;

4919 4920 4921
	if (!priv->channels.params.scatter_fcs_en)
		netdev->features  &= ~NETIF_F_RXFCS;

4922 4923 4924 4925
	/* prefere CQE compression over rxhash */
	if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS))
		netdev->features &= ~NETIF_F_RXHASH;

4926 4927 4928 4929
#define FT_CAP(f) MLX5_CAP_FLOWTABLE(mdev, flow_table_properties_nic_receive.f)
	if (FT_CAP(flow_modify_en) &&
	    FT_CAP(modify_root) &&
	    FT_CAP(identified_miss_table_mode) &&
4930
	    FT_CAP(flow_table_modify)) {
4931
#ifdef CONFIG_MLX5_ESWITCH
4932
		netdev->hw_features      |= NETIF_F_HW_TC;
4933
#endif
4934
#ifdef CONFIG_MLX5_EN_ARFS
4935 4936 4937
		netdev->hw_features	 |= NETIF_F_NTUPLE;
#endif
	}
4938

4939
	netdev->features         |= NETIF_F_HIGHDMA;
4940
	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
4941 4942 4943 4944

	netdev->priv_flags       |= IFF_UNICAST_FLT;

	mlx5e_set_netdev_dev_addr(netdev);
4945
	mlx5e_ipsec_build_netdev(priv);
4946
	mlx5e_tls_build_netdev(priv);
4947 4948
}

4949
void mlx5e_create_q_counters(struct mlx5e_priv *priv)
4950 4951 4952 4953 4954 4955 4956 4957 4958
{
	struct mlx5_core_dev *mdev = priv->mdev;
	int err;

	err = mlx5_core_alloc_q_counter(mdev, &priv->q_counter);
	if (err) {
		mlx5_core_warn(mdev, "alloc queue counter failed, %d\n", err);
		priv->q_counter = 0;
	}
4959 4960 4961 4962 4963 4964

	err = mlx5_core_alloc_q_counter(mdev, &priv->drop_rq_q_counter);
	if (err) {
		mlx5_core_warn(mdev, "alloc drop RQ counter failed, %d\n", err);
		priv->drop_rq_q_counter = 0;
	}
4965 4966
}

4967
void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
4968
{
4969 4970
	if (priv->q_counter)
		mlx5_core_dealloc_q_counter(priv->mdev, priv->q_counter);
4971

4972 4973
	if (priv->drop_rq_q_counter)
		mlx5_core_dealloc_q_counter(priv->mdev, priv->drop_rq_q_counter);
4974 4975
}

4976 4977 4978 4979
static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
			  struct net_device *netdev,
			  const struct mlx5e_profile *profile,
			  void *ppriv)
4980 4981
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
4982
	struct mlx5e_rss_params *rss = &priv->rss_params;
4983
	int err;
4984

4985
	err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
4986 4987 4988
	if (err)
		return err;

4989
	mlx5e_build_nic_params(mdev, &priv->xsk, rss, &priv->channels.params,
4990
			       priv->max_nch, netdev->mtu);
4991 4992 4993

	mlx5e_timestamp_init(priv);

4994 4995 4996
	err = mlx5e_ipsec_init(priv);
	if (err)
		mlx5_core_err(mdev, "IPSec initialization failed, %d\n", err);
4997 4998 4999
	err = mlx5e_tls_init(priv);
	if (err)
		mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
5000
	mlx5e_build_nic_netdev(netdev);
5001
	mlx5e_health_create_reporters(priv);
5002 5003

	return 0;
5004 5005 5006 5007
}

static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
5008
	mlx5e_health_destroy_reporters(priv);
5009
	mlx5e_tls_cleanup(priv);
5010
	mlx5e_ipsec_cleanup(priv);
5011
	mlx5e_netdev_cleanup(priv->netdev, priv);
5012 5013 5014 5015 5016 5017 5018
}

static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	int err;

5019 5020 5021 5022 5023 5024 5025 5026
	mlx5e_create_q_counters(priv);

	err = mlx5e_open_drop_rq(priv, &priv->drop_rq);
	if (err) {
		mlx5_core_err(mdev, "open drop rq failed, %d\n", err);
		goto err_destroy_q_counters;
	}

5027 5028
	err = mlx5e_create_indirect_rqt(priv);
	if (err)
5029
		goto err_close_drop_rq;
5030

5031
	err = mlx5e_create_direct_rqts(priv, priv->direct_tir);
5032
	if (err)
5033 5034
		goto err_destroy_indirect_rqts;

5035
	err = mlx5e_create_indirect_tirs(priv, true);
5036
	if (err)
5037 5038
		goto err_destroy_direct_rqts;

5039
	err = mlx5e_create_direct_tirs(priv, priv->direct_tir);
5040
	if (err)
5041 5042
		goto err_destroy_indirect_tirs;

5043 5044 5045 5046 5047 5048 5049 5050
	err = mlx5e_create_direct_rqts(priv, priv->xsk_tir);
	if (unlikely(err))
		goto err_destroy_direct_tirs;

	err = mlx5e_create_direct_tirs(priv, priv->xsk_tir);
	if (unlikely(err))
		goto err_destroy_xsk_rqts;

5051 5052 5053
	err = mlx5e_create_flow_steering(priv);
	if (err) {
		mlx5_core_warn(mdev, "create flow steering failed, %d\n", err);
5054
		goto err_destroy_xsk_tirs;
5055 5056
	}

5057
	err = mlx5e_tc_nic_init(priv);
5058 5059 5060 5061 5062 5063 5064
	if (err)
		goto err_destroy_flow_steering;

	return 0;

err_destroy_flow_steering:
	mlx5e_destroy_flow_steering(priv);
5065 5066 5067 5068
err_destroy_xsk_tirs:
	mlx5e_destroy_direct_tirs(priv, priv->xsk_tir);
err_destroy_xsk_rqts:
	mlx5e_destroy_direct_rqts(priv, priv->xsk_tir);
5069
err_destroy_direct_tirs:
5070
	mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
5071
err_destroy_indirect_tirs:
5072
	mlx5e_destroy_indirect_tirs(priv, true);
5073
err_destroy_direct_rqts:
5074
	mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
5075 5076
err_destroy_indirect_rqts:
	mlx5e_destroy_rqt(priv, &priv->indir_rqt);
5077 5078 5079 5080
err_close_drop_rq:
	mlx5e_close_drop_rq(&priv->drop_rq);
err_destroy_q_counters:
	mlx5e_destroy_q_counters(priv);
5081 5082 5083 5084 5085
	return err;
}

static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv)
{
5086
	mlx5e_tc_nic_cleanup(priv);
5087
	mlx5e_destroy_flow_steering(priv);
5088 5089 5090
	mlx5e_destroy_direct_tirs(priv, priv->xsk_tir);
	mlx5e_destroy_direct_rqts(priv, priv->xsk_tir);
	mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
5091
	mlx5e_destroy_indirect_tirs(priv, true);
5092
	mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
5093
	mlx5e_destroy_rqt(priv, &priv->indir_rqt);
5094 5095
	mlx5e_close_drop_rq(&priv->drop_rq);
	mlx5e_destroy_q_counters(priv);
5096 5097 5098 5099 5100 5101 5102 5103 5104 5105 5106 5107 5108
}

static int mlx5e_init_nic_tx(struct mlx5e_priv *priv)
{
	int err;

	err = mlx5e_create_tises(priv);
	if (err) {
		mlx5_core_warn(priv->mdev, "create tises failed, %d\n", err);
		return err;
	}

#ifdef CONFIG_MLX5_CORE_EN_DCB
5109
	mlx5e_dcbnl_initialize(priv);
5110 5111 5112 5113 5114 5115 5116 5117
#endif
	return 0;
}

static void mlx5e_nic_enable(struct mlx5e_priv *priv)
{
	struct net_device *netdev = priv->netdev;
	struct mlx5_core_dev *mdev = priv->mdev;
5118 5119 5120

	mlx5e_init_l2_addr(priv);

5121 5122 5123 5124
	/* Marking the link as currently not needed by the Driver */
	if (!netif_running(netdev))
		mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);

5125
	mlx5e_set_netdev_mtu_boundaries(priv);
5126
	mlx5e_set_dev_port_mtu(priv);
5127

5128 5129
	mlx5_lag_add(mdev, netdev);

5130
	mlx5e_enable_async_events(priv);
5131 5132
	if (mlx5e_monitor_counter_supported(priv))
		mlx5e_monitor_counter_init(priv);
5133

5134
	mlx5e_hv_vhca_stats_create(priv);
5135 5136
	if (netdev->reg_state != NETREG_REGISTERED)
		return;
5137 5138 5139
#ifdef CONFIG_MLX5_CORE_EN_DCB
	mlx5e_dcbnl_init_app(priv);
#endif
5140 5141

	queue_work(priv->wq, &priv->set_rx_mode_work);
5142 5143 5144 5145 5146 5147

	rtnl_lock();
	if (netif_running(netdev))
		mlx5e_open(netdev);
	netif_device_attach(netdev);
	rtnl_unlock();
5148 5149 5150 5151
}

static void mlx5e_nic_disable(struct mlx5e_priv *priv)
{
5152 5153
	struct mlx5_core_dev *mdev = priv->mdev;

5154 5155 5156 5157 5158
#ifdef CONFIG_MLX5_CORE_EN_DCB
	if (priv->netdev->reg_state == NETREG_REGISTERED)
		mlx5e_dcbnl_delete_app(priv);
#endif

5159 5160 5161 5162 5163 5164
	rtnl_lock();
	if (netif_running(priv->netdev))
		mlx5e_close(priv->netdev);
	netif_device_detach(priv->netdev);
	rtnl_unlock();

5165
	queue_work(priv->wq, &priv->set_rx_mode_work);
5166

5167
	mlx5e_hv_vhca_stats_destroy(priv);
5168 5169 5170
	if (mlx5e_monitor_counter_supported(priv))
		mlx5e_monitor_counter_cleanup(priv);

5171
	mlx5e_disable_async_events(priv);
5172
	mlx5_lag_remove(mdev);
5173 5174
}

5175 5176 5177 5178 5179
int mlx5e_update_nic_rx(struct mlx5e_priv *priv)
{
	return mlx5e_refresh_tirs(priv, false);
}

5180 5181 5182 5183 5184 5185 5186 5187 5188
static const struct mlx5e_profile mlx5e_nic_profile = {
	.init		   = mlx5e_nic_init,
	.cleanup	   = mlx5e_nic_cleanup,
	.init_rx	   = mlx5e_init_nic_rx,
	.cleanup_rx	   = mlx5e_cleanup_nic_rx,
	.init_tx	   = mlx5e_init_nic_tx,
	.cleanup_tx	   = mlx5e_cleanup_nic_tx,
	.enable		   = mlx5e_nic_enable,
	.disable	   = mlx5e_nic_disable,
5189
	.update_rx	   = mlx5e_update_nic_rx,
5190
	.update_stats	   = mlx5e_update_ndo_stats,
5191
	.update_carrier	   = mlx5e_update_carrier,
5192 5193
	.rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe,
	.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
5194
	.max_tc		   = MLX5E_MAX_NUM_TC,
5195
	.rq_groups	   = MLX5E_NUM_RQ_GROUPS(XSK),
5196 5197
};

5198 5199
/* mlx5e generic netdev management API (move to en_common.c) */

5200
/* mlx5e_netdev_init/cleanup must be called from profile->init/cleanup callbacks */
5201 5202 5203 5204 5205
int mlx5e_netdev_init(struct net_device *netdev,
		      struct mlx5e_priv *priv,
		      struct mlx5_core_dev *mdev,
		      const struct mlx5e_profile *profile,
		      void *ppriv)
5206
{
5207 5208 5209 5210 5211 5212
	/* priv init */
	priv->mdev        = mdev;
	priv->netdev      = netdev;
	priv->profile     = profile;
	priv->ppriv       = ppriv;
	priv->msglevel    = MLX5E_MSG_LEVEL;
5213
	priv->max_nch     = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
5214
	priv->max_opened_tc = 1;
5215

5216 5217 5218 5219
	mutex_init(&priv->state_lock);
	INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
	INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);
	INIT_WORK(&priv->tx_timeout_work, mlx5e_tx_timeout_work);
5220
	INIT_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
5221

5222 5223 5224 5225
	priv->wq = create_singlethread_workqueue("mlx5e");
	if (!priv->wq)
		return -ENOMEM;

5226 5227 5228 5229
	/* netdev init */
	netif_carrier_off(netdev);

#ifdef CONFIG_MLX5_EN_ARFS
5230
	netdev->rx_cpu_rmap =  mlx5_eq_table_get_rmap(mdev);
5231 5232
#endif

5233 5234 5235 5236 5237 5238 5239 5240
	return 0;
}

void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv)
{
	destroy_workqueue(priv->wq);
}

5241 5242
struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
				       const struct mlx5e_profile *profile,
5243
				       int nch,
5244
				       void *ppriv)
5245 5246
{
	struct net_device *netdev;
5247
	int err;
5248

5249
	netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
5250
				    nch * profile->max_tc,
5251
				    nch * profile->rq_groups);
5252 5253 5254 5255 5256
	if (!netdev) {
		mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n");
		return NULL;
	}

5257 5258 5259 5260 5261
	err = profile->init(mdev, netdev, profile, ppriv);
	if (err) {
		mlx5_core_err(mdev, "failed to init mlx5e profile %d\n", err);
		goto err_free_netdev;
	}
5262 5263 5264

	return netdev;

5265
err_free_netdev:
5266 5267 5268 5269 5270
	free_netdev(netdev);

	return NULL;
}

5271
int mlx5e_attach_netdev(struct mlx5e_priv *priv)
5272 5273
{
	const struct mlx5e_profile *profile;
5274
	int max_nch;
5275 5276 5277 5278
	int err;

	profile = priv->profile;
	clear_bit(MLX5E_STATE_DESTROYING, &priv->state);
5279

5280 5281 5282 5283 5284
	/* max number of channels may have changed */
	max_nch = mlx5e_get_max_num_channels(priv->mdev);
	if (priv->channels.params.num_channels > max_nch) {
		mlx5_core_warn(priv->mdev, "MLX5E: Reducing number of channels to %d\n", max_nch);
		priv->channels.params.num_channels = max_nch;
5285
		mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
5286 5287 5288
					      MLX5E_INDIR_RQT_SIZE, max_nch);
	}

5289 5290
	err = profile->init_tx(priv);
	if (err)
T
Tariq Toukan 已提交
5291
		goto out;
5292

5293 5294
	err = profile->init_rx(priv);
	if (err)
5295
		goto err_cleanup_tx;
5296

5297 5298
	if (profile->enable)
		profile->enable(priv);
5299

5300
	return 0;
5301

5302
err_cleanup_tx:
5303
	profile->cleanup_tx(priv);
5304

5305 5306
out:
	return err;
5307 5308
}

5309
void mlx5e_detach_netdev(struct mlx5e_priv *priv)
5310 5311 5312 5313 5314
{
	const struct mlx5e_profile *profile = priv->profile;

	set_bit(MLX5E_STATE_DESTROYING, &priv->state);

5315 5316 5317 5318
	if (profile->disable)
		profile->disable(priv);
	flush_workqueue(priv->wq);

5319 5320
	profile->cleanup_rx(priv);
	profile->cleanup_tx(priv);
5321
	cancel_work_sync(&priv->update_stats_work);
5322 5323
}

5324 5325 5326 5327 5328 5329 5330 5331 5332 5333
void mlx5e_destroy_netdev(struct mlx5e_priv *priv)
{
	const struct mlx5e_profile *profile = priv->profile;
	struct net_device *netdev = priv->netdev;

	if (profile->cleanup)
		profile->cleanup(priv);
	free_netdev(netdev);
}

5334 5335 5336 5337 5338 5339 5340 5341 5342 5343 5344 5345 5346 5347 5348 5349
/* mlx5e_attach and mlx5e_detach scope should be only creating/destroying
 * hardware contexts and to connect it to the current netdev.
 */
static int mlx5e_attach(struct mlx5_core_dev *mdev, void *vpriv)
{
	struct mlx5e_priv *priv = vpriv;
	struct net_device *netdev = priv->netdev;
	int err;

	if (netif_device_present(netdev))
		return 0;

	err = mlx5e_create_mdev_resources(mdev);
	if (err)
		return err;

5350
	err = mlx5e_attach_netdev(priv);
5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363
	if (err) {
		mlx5e_destroy_mdev_resources(mdev);
		return err;
	}

	return 0;
}

static void mlx5e_detach(struct mlx5_core_dev *mdev, void *vpriv)
{
	struct mlx5e_priv *priv = vpriv;
	struct net_device *netdev = priv->netdev;

5364 5365 5366 5367 5368
#ifdef CONFIG_MLX5_ESWITCH
	if (MLX5_ESWITCH_MANAGER(mdev) && vpriv == mdev)
		return;
#endif

5369 5370 5371
	if (!netif_device_present(netdev))
		return;

5372
	mlx5e_detach_netdev(priv);
5373 5374 5375
	mlx5e_destroy_mdev_resources(mdev);
}

5376 5377
static void *mlx5e_add(struct mlx5_core_dev *mdev)
{
5378
	struct net_device *netdev;
5379 5380
	void *priv;
	int err;
5381
	int nch;
5382

5383 5384
	err = mlx5e_check_required_hca_cap(mdev);
	if (err)
5385 5386
		return NULL;

5387 5388
#ifdef CONFIG_MLX5_ESWITCH
	if (MLX5_ESWITCH_MANAGER(mdev) &&
5389
	    mlx5_eswitch_mode(mdev->priv.eswitch) == MLX5_ESWITCH_OFFLOADS) {
5390 5391 5392 5393 5394
		mlx5e_rep_register_vport_reps(mdev);
		return mdev;
	}
#endif

5395
	nch = mlx5e_get_max_num_channels(mdev);
5396
	netdev = mlx5e_create_netdev(mdev, &mlx5e_nic_profile, nch, NULL);
5397 5398
	if (!netdev) {
		mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
5399
		return NULL;
5400 5401
	}

5402
	dev_net_set(netdev, mlx5_core_net(mdev));
5403 5404 5405 5406 5407 5408 5409 5410 5411 5412 5413 5414
	priv = netdev_priv(netdev);

	err = mlx5e_attach(mdev, priv);
	if (err) {
		mlx5_core_err(mdev, "mlx5e_attach failed, %d\n", err);
		goto err_destroy_netdev;
	}

	err = register_netdev(netdev);
	if (err) {
		mlx5_core_err(mdev, "register_netdev failed, %d\n", err);
		goto err_detach;
5415
	}
5416

5417 5418 5419
#ifdef CONFIG_MLX5_CORE_EN_DCB
	mlx5e_dcbnl_init_app(priv);
#endif
5420 5421 5422 5423 5424
	return priv;

err_detach:
	mlx5e_detach(mdev, priv);
err_destroy_netdev:
5425
	mlx5e_destroy_netdev(priv);
5426
	return NULL;
5427 5428 5429 5430
}

static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
{
5431
	struct mlx5e_priv *priv;
5432

5433 5434 5435 5436 5437 5438 5439
#ifdef CONFIG_MLX5_ESWITCH
	if (MLX5_ESWITCH_MANAGER(mdev) && vpriv == mdev) {
		mlx5e_rep_unregister_vport_reps(mdev);
		return;
	}
#endif
	priv = vpriv;
5440 5441 5442
#ifdef CONFIG_MLX5_CORE_EN_DCB
	mlx5e_dcbnl_delete_app(priv);
#endif
5443
	unregister_netdev(priv->netdev);
5444
	mlx5e_detach(mdev, vpriv);
5445
	mlx5e_destroy_netdev(priv);
5446 5447
}

5448
static struct mlx5_interface mlx5e_interface = {
5449 5450
	.add       = mlx5e_add,
	.remove    = mlx5e_remove,
5451 5452
	.attach    = mlx5e_attach,
	.detach    = mlx5e_detach,
5453 5454 5455 5456 5457
	.protocol  = MLX5_INTERFACE_PROTOCOL_ETH,
};

void mlx5e_init(void)
{
5458
	mlx5e_ipsec_build_inverse_table();
5459
	mlx5e_build_ptys2ethtool_map();
5460 5461 5462 5463 5464 5465 5466
	mlx5_register_interface(&mlx5e_interface);
}

void mlx5e_cleanup(void)
{
	mlx5_unregister_interface(&mlx5e_interface);
}