en_main.c 137.8 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
int mlx5e_open_locked(struct net_device *netdev)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3003
	bool is_xdp = priv->channels.params.xdp_prog;
3004 3005 3006
	int err;

	set_bit(MLX5E_STATE_OPENED, &priv->state);
3007 3008
	if (is_xdp)
		mlx5e_xdp_set_open(priv);
3009

3010
	err = mlx5e_open_channels(priv, &priv->channels);
3011
	if (err)
3012
		goto err_clear_state_opened_flag;
3013

3014
	priv->profile->update_rx(priv);
3015
	mlx5e_activate_priv_channels(priv);
3016 3017
	if (priv->profile->update_carrier)
		priv->profile->update_carrier(priv);
3018

3019
	mlx5e_queue_update_stats(priv);
3020
	return 0;
3021 3022

err_clear_state_opened_flag:
3023 3024
	if (is_xdp)
		mlx5e_xdp_set_closed(priv);
3025 3026
	clear_bit(MLX5E_STATE_OPENED, &priv->state);
	return err;
3027 3028
}

3029
int mlx5e_open(struct net_device *netdev)
3030 3031 3032 3033 3034 3035
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

	mutex_lock(&priv->state_lock);
	err = mlx5e_open_locked(netdev);
3036 3037
	if (!err)
		mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_UP);
3038 3039
	mutex_unlock(&priv->state_lock);

3040
	if (mlx5_vxlan_allowed(priv->mdev->vxlan))
3041 3042
		udp_tunnel_get_rx_info(netdev);

3043 3044 3045 3046 3047 3048 3049
	return err;
}

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

3050 3051 3052 3053 3054 3055
	/* 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;

3056 3057
	if (priv->channels.params.xdp_prog)
		mlx5e_xdp_set_closed(priv);
3058 3059 3060
	clear_bit(MLX5E_STATE_OPENED, &priv->state);

	netif_carrier_off(priv->netdev);
3061 3062
	mlx5e_deactivate_priv_channels(priv);
	mlx5e_close_channels(&priv->channels);
3063 3064 3065 3066

	return 0;
}

3067
int mlx5e_close(struct net_device *netdev)
3068 3069 3070 3071
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	int err;

3072 3073 3074
	if (!netif_device_present(netdev))
		return -ENODEV;

3075
	mutex_lock(&priv->state_lock);
3076
	mlx5_set_port_admin_status(priv->mdev, MLX5_PORT_DOWN);
3077 3078 3079 3080 3081 3082
	err = mlx5e_close_locked(netdev);
	mutex_unlock(&priv->state_lock);

	return err;
}

3083
static int mlx5e_alloc_drop_rq(struct mlx5_core_dev *mdev,
3084 3085
			       struct mlx5e_rq *rq,
			       struct mlx5e_rq_param *param)
3086 3087 3088 3089 3090 3091 3092
{
	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;

3093 3094
	err = mlx5_wq_cyc_create(mdev, &param->wq, rqc_wq, &rq->wqe.wq,
				 &rq->wq_ctrl);
3095 3096 3097
	if (err)
		return err;

3098 3099 3100
	/* Mark as unused given "Drop-RQ" packets never reach XDP */
	xdp_rxq_info_unused(&rq->xdp_rxq);

3101
	rq->mdev = mdev;
3102 3103 3104 3105

	return 0;
}

3106
static int mlx5e_alloc_drop_cq(struct mlx5_core_dev *mdev,
3107 3108
			       struct mlx5e_cq *cq,
			       struct mlx5e_cq_param *param)
3109
{
3110 3111
	param->wq.buf_numa_node = dev_to_node(mdev->device);
	param->wq.db_numa_node  = dev_to_node(mdev->device);
3112

3113
	return mlx5e_alloc_cq_common(mdev, param, cq);
3114 3115
}

3116 3117
int mlx5e_open_drop_rq(struct mlx5e_priv *priv,
		       struct mlx5e_rq *drop_rq)
3118
{
3119
	struct mlx5_core_dev *mdev = priv->mdev;
3120 3121 3122
	struct mlx5e_cq_param cq_param = {};
	struct mlx5e_rq_param rq_param = {};
	struct mlx5e_cq *cq = &drop_rq->cq;
3123 3124
	int err;

3125
	mlx5e_build_drop_rq_param(priv, &rq_param);
3126

3127
	err = mlx5e_alloc_drop_cq(mdev, cq, &cq_param);
3128 3129 3130
	if (err)
		return err;

3131
	err = mlx5e_create_cq(cq, &cq_param);
3132
	if (err)
3133
		goto err_free_cq;
3134

3135
	err = mlx5e_alloc_drop_rq(mdev, drop_rq, &rq_param);
3136
	if (err)
3137
		goto err_destroy_cq;
3138

3139
	err = mlx5e_create_rq(drop_rq, &rq_param);
3140
	if (err)
3141
		goto err_free_rq;
3142

3143 3144 3145 3146
	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);

3147 3148
	return 0;

3149
err_free_rq:
3150
	mlx5e_free_rq(drop_rq);
3151 3152

err_destroy_cq:
3153
	mlx5e_destroy_cq(cq);
3154

3155
err_free_cq:
3156
	mlx5e_free_cq(cq);
3157

3158 3159 3160
	return err;
}

3161
void mlx5e_close_drop_rq(struct mlx5e_rq *drop_rq)
3162
{
3163 3164 3165 3166
	mlx5e_destroy_rq(drop_rq);
	mlx5e_free_rq(drop_rq);
	mlx5e_destroy_cq(&drop_rq->cq);
	mlx5e_free_cq(&drop_rq->cq);
3167 3168
}

3169
int mlx5e_create_tis(struct mlx5_core_dev *mdev, void *in, u32 *tisn)
3170 3171 3172
{
	void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);

3173
	MLX5_SET(tisc, tisc, transport_domain, mdev->mlx5e_res.td.tdn);
3174

3175 3176 3177
	if (MLX5_GET(tisc, tisc, tls_en))
		MLX5_SET(tisc, tisc, pd, mdev->mlx5e_res.pdn);

3178 3179 3180
	if (mlx5_lag_is_lacp_owner(mdev))
		MLX5_SET(tisc, tisc, strict_lag_tx_port_affinity, 1);

3181
	return mlx5_core_create_tis(mdev, in, MLX5_ST_SZ_BYTES(create_tis_in), tisn);
3182 3183
}

3184
void mlx5e_destroy_tis(struct mlx5_core_dev *mdev, u32 tisn)
3185
{
3186
	mlx5_core_destroy_tis(mdev, tisn);
3187 3188
}

3189 3190
void mlx5e_destroy_tises(struct mlx5e_priv *priv)
{
3191
	int tc, i;
3192

3193 3194 3195 3196 3197 3198 3199 3200
	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;
3201 3202
}

3203
int mlx5e_create_tises(struct mlx5e_priv *priv)
3204
{
3205
	int tc, i;
3206 3207
	int err;

3208 3209 3210 3211
	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;
3212

3213
			tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
3214

3215
			MLX5_SET(tisc, tisc, prio, tc << 1);
3216

3217 3218 3219 3220 3221 3222 3223
			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;
		}
3224 3225 3226 3227 3228
	}

	return 0;

err_close_tises:
3229 3230 3231 3232 3233
	for (; i >= 0; i--) {
		for (tc--; tc >= 0; tc--)
			mlx5e_destroy_tis(priv->mdev, priv->tisn[i][tc]);
		tc = priv->profile->max_tc;
	}
3234 3235 3236 3237

	return err;
}

3238
static void mlx5e_cleanup_nic_tx(struct mlx5e_priv *priv)
3239
{
3240
	mlx5e_destroy_tises(priv);
3241 3242
}

3243 3244
static void mlx5e_build_indir_tir_ctx_common(struct mlx5e_priv *priv,
					     u32 rqtn, u32 *tirc)
3245
{
3246
	MLX5_SET(tirc, tirc, transport_domain, priv->mdev->mlx5e_res.td.tdn);
3247 3248
	MLX5_SET(tirc, tirc, disp_type, MLX5_TIRC_DISP_TYPE_INDIRECT);
	MLX5_SET(tirc, tirc, indirect_table, rqtn);
3249 3250
	MLX5_SET(tirc, tirc, tunneled_offload_en,
		 priv->channels.params.tunneled_offload_en);
3251

3252
	mlx5e_build_tir_ctx_lro(&priv->channels.params, tirc);
3253
}
3254

3255 3256 3257 3258 3259
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);
3260
	mlx5e_build_indir_tir_ctx_hash(&priv->rss_params,
3261
				       &tirc_default_config[tt], tirc, false);
3262 3263
}

3264
static void mlx5e_build_direct_tir_ctx(struct mlx5e_priv *priv, u32 rqtn, u32 *tirc)
3265
{
3266
	mlx5e_build_indir_tir_ctx_common(priv, rqtn, tirc);
T
Tariq Toukan 已提交
3267 3268 3269
	MLX5_SET(tirc, tirc, rx_hash_fn, MLX5_RX_HASH_FN_INVERTED_XOR8);
}

3270 3271 3272 3273 3274 3275 3276 3277 3278
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);
}

3279
int mlx5e_create_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)
T
Tariq Toukan 已提交
3280
{
3281
	struct mlx5e_tir *tir;
3282 3283
	void *tirc;
	int inlen;
3284
	int i = 0;
3285
	int err;
T
Tariq Toukan 已提交
3286 3287
	u32 *in;
	int tt;
3288 3289

	inlen = MLX5_ST_SZ_BYTES(create_tir_in);
3290
	in = kvzalloc(inlen, GFP_KERNEL);
3291 3292 3293
	if (!in)
		return -ENOMEM;

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

3306
	if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321
		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:
3322 3323 3324 3325
	kvfree(in);

	return 0;

3326 3327 3328 3329
err_destroy_inner_tirs:
	for (i--; i >= 0; i--)
		mlx5e_destroy_tir(priv->mdev, &priv->inner_indir_tir[i]);

3330 3331 3332 3333 3334 3335 3336 3337
	for (tt--; tt >= 0; tt--)
		mlx5e_destroy_tir(priv->mdev, &priv->indir_tir[tt]);

	kvfree(in);

	return err;
}

3338
int mlx5e_create_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
3339 3340 3341 3342
{
	struct mlx5e_tir *tir;
	void *tirc;
	int inlen;
3343
	int err = 0;
3344 3345 3346 3347
	u32 *in;
	int ix;

	inlen = MLX5_ST_SZ_BYTES(create_tir_in);
3348
	in = kvzalloc(inlen, GFP_KERNEL);
3349 3350 3351
	if (!in)
		return -ENOMEM;

3352
	for (ix = 0; ix < priv->max_nch; ix++) {
T
Tariq Toukan 已提交
3353
		memset(in, 0, inlen);
3354
		tir = &tirs[ix];
T
Tariq Toukan 已提交
3355
		tirc = MLX5_ADDR_OF(create_tir_in, in, ctx);
3356
		mlx5e_build_direct_tir_ctx(priv, tir->rqt.rqtn, tirc);
3357
		err = mlx5e_create_tir(priv->mdev, tir, in, inlen);
3358
		if (unlikely(err))
T
Tariq Toukan 已提交
3359 3360 3361
			goto err_destroy_ch_tirs;
	}

3362
	goto out;
3363

T
Tariq Toukan 已提交
3364
err_destroy_ch_tirs:
3365
	mlx5_core_warn(priv->mdev, "create tirs failed, %d\n", err);
T
Tariq Toukan 已提交
3366
	for (ix--; ix >= 0; ix--)
3367
		mlx5e_destroy_tir(priv->mdev, &tirs[ix]);
T
Tariq Toukan 已提交
3368

3369
out:
T
Tariq Toukan 已提交
3370
	kvfree(in);
3371 3372 3373 3374

	return err;
}

3375
void mlx5e_destroy_indirect_tirs(struct mlx5e_priv *priv, bool inner_ttc)
3376 3377 3378
{
	int i;

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

3382
	if (!inner_ttc || !mlx5e_tunnel_inner_ft_supported(priv->mdev))
3383 3384 3385 3386
		return;

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

3389
void mlx5e_destroy_direct_tirs(struct mlx5e_priv *priv, struct mlx5e_tir *tirs)
3390 3391 3392
{
	int i;

3393
	for (i = 0; i < priv->max_nch; i++)
3394
		mlx5e_destroy_tir(priv->mdev, &tirs[i]);
3395 3396
}

3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410
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;
}

3411
static int mlx5e_modify_channels_vsd(struct mlx5e_channels *chs, bool vsd)
3412 3413 3414 3415
{
	int err = 0;
	int i;

3416 3417
	for (i = 0; i < chs->num; i++) {
		err = mlx5e_modify_rq_vsd(&chs->c[i]->rq, vsd);
3418 3419 3420 3421 3422 3423 3424
		if (err)
			return err;
	}

	return 0;
}

3425
static int mlx5e_setup_tc_mqprio(struct mlx5e_priv *priv,
3426
				 struct tc_mqprio_qopt *mqprio)
3427
{
S
Saeed Mahameed 已提交
3428
	struct mlx5e_channels new_channels = {};
3429
	u8 tc = mqprio->num_tc;
3430 3431
	int err = 0;

3432 3433
	mqprio->hw = TC_MQPRIO_HW_OFFLOAD_TCS;

3434 3435 3436 3437 3438
	if (tc && tc != MLX5E_MAX_NUM_TC)
		return -EINVAL;

	mutex_lock(&priv->state_lock);

S
Saeed Mahameed 已提交
3439 3440
	new_channels.params = priv->channels.params;
	new_channels.params.num_tc = tc ? tc : 1;
3441

S
Saeed Mahameed 已提交
3442
	if (!test_bit(MLX5E_STATE_OPENED, &priv->state)) {
S
Saeed Mahameed 已提交
3443 3444 3445
		priv->channels.params = new_channels.params;
		goto out;
	}
3446

3447
	err = mlx5e_safe_switch_channels(priv, &new_channels, NULL);
S
Saeed Mahameed 已提交
3448 3449
	if (err)
		goto out;
3450

3451 3452
	priv->max_opened_tc = max_t(u8, priv->max_opened_tc,
				    new_channels.params.num_tc);
S
Saeed Mahameed 已提交
3453
out:
3454 3455 3456 3457
	mutex_unlock(&priv->state_lock);
	return err;
}

3458
#ifdef CONFIG_MLX5_ESWITCH
3459
static int mlx5e_setup_tc_cls_flower(struct mlx5e_priv *priv,
3460
				     struct flow_cls_offload *cls_flower,
3461
				     unsigned long flags)
3462
{
3463
	switch (cls_flower->command) {
3464
	case FLOW_CLS_REPLACE:
3465 3466
		return mlx5e_configure_flower(priv->netdev, priv, cls_flower,
					      flags);
3467
	case FLOW_CLS_DESTROY:
3468 3469
		return mlx5e_delete_flower(priv->netdev, priv, cls_flower,
					   flags);
3470
	case FLOW_CLS_STATS:
3471 3472
		return mlx5e_stats_flower(priv->netdev, priv, cls_flower,
					  flags);
3473
	default:
3474
		return -EOPNOTSUPP;
3475 3476
	}
}
3477

3478 3479
static int mlx5e_setup_tc_block_cb(enum tc_setup_type type, void *type_data,
				   void *cb_priv)
3480
{
3481
	unsigned long flags = MLX5_TC_FLAG(INGRESS) | MLX5_TC_FLAG(NIC_OFFLOAD);
3482 3483 3484 3485
	struct mlx5e_priv *priv = cb_priv;

	switch (type) {
	case TC_SETUP_CLSFLOWER:
3486
		return mlx5e_setup_tc_cls_flower(priv, type_data, flags);
3487 3488 3489 3490
	default:
		return -EOPNOTSUPP;
	}
}
3491
#endif
3492

3493 3494
static LIST_HEAD(mlx5e_block_cb_list);

3495 3496
static int mlx5e_setup_tc(struct net_device *dev, enum tc_setup_type type,
			  void *type_data)
3497
{
3498 3499
	struct mlx5e_priv *priv = netdev_priv(dev);

3500
	switch (type) {
3501
#ifdef CONFIG_MLX5_ESWITCH
3502 3503 3504
	case TC_SETUP_BLOCK: {
		struct flow_block_offload *f = type_data;

3505
		f->unlocked_driver_cb = true;
3506 3507
		return flow_block_cb_setup_simple(type_data,
						  &mlx5e_block_cb_list,
3508 3509
						  mlx5e_setup_tc_block_cb,
						  priv, priv, true);
3510
	}
3511
#endif
3512
	case TC_SETUP_QDISC_MQPRIO:
3513
		return mlx5e_setup_tc_mqprio(priv, type_data);
3514 3515 3516
	default:
		return -EOPNOTSUPP;
	}
3517 3518
}

3519
void mlx5e_fold_sw_stats64(struct mlx5e_priv *priv, struct rtnl_link_stats64 *s)
3520 3521 3522
{
	int i;

3523
	for (i = 0; i < priv->max_nch; i++) {
3524
		struct mlx5e_channel_stats *channel_stats = &priv->channel_stats[i];
3525
		struct mlx5e_rq_stats *xskrq_stats = &channel_stats->xskrq;
3526 3527 3528
		struct mlx5e_rq_stats *rq_stats = &channel_stats->rq;
		int j;

3529 3530
		s->rx_packets   += rq_stats->packets + xskrq_stats->packets;
		s->rx_bytes     += rq_stats->bytes + xskrq_stats->bytes;
3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541

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

3542
void
3543 3544 3545 3546
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;
3547
	struct mlx5e_pport_stats *pstats = &priv->stats.pport;
3548

3549 3550 3551 3552
	if (!mlx5e_monitor_counter_supported(priv)) {
		/* update HW stats in background for next time */
		mlx5e_queue_update_stats(priv);
	}
3553

3554 3555 3556 3557 3558 3559
	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 {
3560
		mlx5e_fold_sw_stats64(priv, stats);
3561
	}
3562 3563 3564 3565

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

	stats->rx_length_errors =
3566 3567 3568
		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);
3569
	stats->rx_crc_errors =
3570 3571 3572
		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);
3573 3574 3575 3576 3577 3578 3579
	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
	 */
3580 3581
	stats->multicast =
		VPORT_COUNTER_GET(vstats, received_eth_multicast.packets);
3582 3583 3584 3585 3586 3587
}

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

3588
	queue_work(priv->wq, &priv->set_rx_mode_work);
3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602
}

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

3603
	queue_work(priv->wq, &priv->set_rx_mode_work);
3604 3605 3606 3607

	return 0;
}

3608
#define MLX5E_SET_FEATURE(features, feature, enable)	\
3609 3610
	do {						\
		if (enable)				\
3611
			*features |= feature;		\
3612
		else					\
3613
			*features &= ~feature;		\
3614 3615 3616 3617 3618
	} while (0)

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

static int set_feature_lro(struct net_device *netdev, bool enable)
3619 3620
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3621
	struct mlx5_core_dev *mdev = priv->mdev;
3622
	struct mlx5e_channels new_channels = {};
3623
	struct mlx5e_params *old_params;
3624 3625
	int err = 0;
	bool reset;
3626 3627 3628

	mutex_lock(&priv->state_lock);

3629 3630 3631 3632 3633 3634 3635
	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;
	}

3636
	old_params = &priv->channels.params;
3637 3638 3639 3640 3641 3642
	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;
	}

3643
	reset = test_bit(MLX5E_STATE_OPENED, &priv->state);
3644

3645
	new_channels.params = *old_params;
3646 3647
	new_channels.params.lro_en = enable;

3648
	if (old_params->rq_wq_type != MLX5_WQ_TYPE_CYCLIC) {
3649 3650
		if (mlx5e_rx_mpwqe_is_linear_skb(mdev, old_params, NULL) ==
		    mlx5e_rx_mpwqe_is_linear_skb(mdev, &new_channels.params, NULL))
3651 3652 3653
			reset = false;
	}

3654
	if (!reset) {
3655
		*old_params = new_channels.params;
3656 3657
		err = mlx5e_modify_tirs_lro(priv);
		goto out;
3658
	}
3659

3660
	err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_modify_tirs_lro);
3661
out:
3662
	mutex_unlock(&priv->state_lock);
3663 3664 3665
	return err;
}

3666
static int set_feature_cvlan_filter(struct net_device *netdev, bool enable)
3667 3668 3669 3670
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

	if (enable)
3671
		mlx5e_enable_cvlan_filter(priv);
3672
	else
3673
		mlx5e_disable_cvlan_filter(priv);
3674 3675 3676 3677

	return 0;
}

3678
#ifdef CONFIG_MLX5_ESWITCH
3679 3680 3681
static int set_feature_tc_num_filters(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3682

3683
	if (!enable && mlx5e_tc_num_filters(priv, MLX5_TC_FLAG(NIC_OFFLOAD))) {
3684 3685 3686 3687 3688
		netdev_err(netdev,
			   "Active offloaded tc filters, can't turn hw_tc_offload off\n");
		return -EINVAL;
	}

3689 3690
	return 0;
}
3691
#endif
3692

3693 3694 3695 3696 3697 3698 3699 3700
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);
}

3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717
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;
}

3718 3719 3720
static int set_feature_rx_vlan(struct net_device *netdev, bool enable)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3721
	int err = 0;
3722 3723 3724

	mutex_lock(&priv->state_lock);

3725
	priv->channels.params.vlan_strip_disable = !enable;
3726 3727 3728 3729
	if (!test_bit(MLX5E_STATE_OPENED, &priv->state))
		goto unlock;

	err = mlx5e_modify_channels_vsd(&priv->channels, !enable);
3730
	if (err)
3731
		priv->channels.params.vlan_strip_disable = enable;
3732

3733
unlock:
3734 3735 3736 3737 3738
	mutex_unlock(&priv->state_lock);

	return err;
}

3739
#ifdef CONFIG_MLX5_EN_ARFS
3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753
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

3754
static int mlx5e_handle_feature(struct net_device *netdev,
3755
				netdev_features_t *features,
3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768
				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) {
3769 3770
		netdev_err(netdev, "%s feature %pNF failed, err %d\n",
			   enable ? "Enable" : "Disable", &feature, err);
3771 3772 3773
		return err;
	}

3774
	MLX5E_SET_FEATURE(features, feature, enable);
3775 3776 3777
	return 0;
}

3778
int mlx5e_set_features(struct net_device *netdev, netdev_features_t features)
3779
{
3780
	netdev_features_t oper_features = netdev->features;
3781 3782 3783 3784
	int err = 0;

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

3786 3787
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_LRO, set_feature_lro);
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_VLAN_CTAG_FILTER,
3788
				    set_feature_cvlan_filter);
3789
#ifdef CONFIG_MLX5_ESWITCH
3790
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_HW_TC, set_feature_tc_num_filters);
3791
#endif
3792 3793 3794
	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);
3795
#ifdef CONFIG_MLX5_EN_ARFS
3796
	err |= MLX5E_HANDLE_FEATURE(NETIF_F_NTUPLE, set_feature_arfs);
3797
#endif
3798

3799 3800 3801 3802 3803 3804
	if (err) {
		netdev->features = oper_features;
		return -EINVAL;
	}

	return 0;
3805 3806
}

3807 3808 3809 3810
static netdev_features_t mlx5e_fix_features(struct net_device *netdev,
					    netdev_features_t features)
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3811
	struct mlx5e_params *params;
3812 3813

	mutex_lock(&priv->state_lock);
3814
	params = &priv->channels.params;
3815 3816 3817 3818 3819
	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;
3820
		if (!params->vlan_strip_disable)
3821 3822
			netdev_warn(netdev, "Dropping C-tag vlan stripping offload due to S-tag vlan\n");
	}
3823
	if (!MLX5E_GET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ)) {
3824
		if (features & NETIF_F_LRO) {
3825
			netdev_warn(netdev, "Disabling LRO, not supported in legacy RQ\n");
3826 3827
			features &= ~NETIF_F_LRO;
		}
3828 3829
	}

3830 3831 3832 3833 3834 3835
	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");
	}

3836 3837 3838 3839 3840
	mutex_unlock(&priv->state_lock);

	return features;
}

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 3871 3872 3873 3874 3875 3876 3877
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;
}

3878 3879
int mlx5e_change_mtu(struct net_device *netdev, int new_mtu,
		     change_hw_mtu_cb set_mtu_cb)
3880 3881
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
3882
	struct mlx5e_channels new_channels = {};
3883
	struct mlx5e_params *params;
3884
	int err = 0;
3885
	bool reset;
3886 3887

	mutex_lock(&priv->state_lock);
3888

3889
	params = &priv->channels.params;
3890

3891
	reset = !params->lro_en;
3892
	reset = reset && test_bit(MLX5E_STATE_OPENED, &priv->state);
3893

3894 3895 3896
	new_channels.params = *params;
	new_channels.params.sw_mtu = new_mtu;

3897
	if (params->xdp_prog &&
3898
	    !mlx5e_rx_is_linear_skb(&new_channels.params, NULL)) {
3899
		netdev_err(netdev, "MTU(%d) > %d is not allowed while XDP enabled\n",
3900
			   new_mtu, mlx5e_xdp_max_mtu(params, NULL));
3901 3902 3903 3904
		err = -EINVAL;
		goto out;
	}

3905 3906 3907
	if (priv->xsk.refcnt &&
	    !mlx5e_xsk_validate_mtu(netdev, &priv->channels,
				    &new_channels.params, priv->mdev)) {
3908 3909 3910 3911
		err = -EINVAL;
		goto out;
	}

3912
	if (params->rq_wq_type == MLX5_WQ_TYPE_LINKED_LIST_STRIDING_RQ) {
3913 3914 3915 3916 3917 3918 3919 3920
		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;
3921

3922
		/* Always reset in linear mode - hw_mtu is used in data path. */
3923
		reset = reset && (is_linear || (ppw_old != ppw_new));
3924 3925
	}

3926
	if (!reset) {
3927
		params->sw_mtu = new_mtu;
3928 3929
		if (set_mtu_cb)
			set_mtu_cb(priv);
3930
		netdev->mtu = params->sw_mtu;
3931 3932
		goto out;
	}
3933

3934
	err = mlx5e_safe_switch_channels(priv, &new_channels, set_mtu_cb);
3935
	if (err)
3936 3937
		goto out;

3938
	netdev->mtu = new_channels.params.sw_mtu;
3939

3940 3941
out:
	mutex_unlock(&priv->state_lock);
3942 3943 3944
	return err;
}

3945 3946 3947 3948 3949
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);
}

3950 3951 3952 3953 3954
int mlx5e_hwstamp_set(struct mlx5e_priv *priv, struct ifreq *ifr)
{
	struct hwtstamp_config config;
	int err;

3955 3956
	if (!MLX5_CAP_GEN(priv->mdev, device_frequency_khz) ||
	    (mlx5_clock_get_ptp_index(priv->mdev) == -1))
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 3987 3988 3989 3990 3991 3992 3993
		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 */
3994 3995
		if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS))
			netdev_warn(priv->netdev, "Disabling RX cqe compression\n");
3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011
		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);

4012 4013 4014
	/* might need to fix some features */
	netdev_update_features(priv->netdev);

4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028
	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;
}

4029 4030
static int mlx5e_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
{
4031 4032
	struct mlx5e_priv *priv = netdev_priv(dev);

4033 4034
	switch (cmd) {
	case SIOCSHWTSTAMP:
4035
		return mlx5e_hwstamp_set(priv, ifr);
4036
	case SIOCGHWTSTAMP:
4037
		return mlx5e_hwstamp_get(priv, ifr);
4038 4039 4040 4041 4042
	default:
		return -EOPNOTSUPP;
	}
}

4043
#ifdef CONFIG_MLX5_ESWITCH
4044
int mlx5e_set_vf_mac(struct net_device *dev, int vf, u8 *mac)
4045 4046 4047 4048 4049 4050 4051
{
	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);
}

4052 4053
static int mlx5e_set_vf_vlan(struct net_device *dev, int vf, u16 vlan, u8 qos,
			     __be16 vlan_proto)
4054 4055 4056 4057
{
	struct mlx5e_priv *priv = netdev_priv(dev);
	struct mlx5_core_dev *mdev = priv->mdev;

4058 4059 4060
	if (vlan_proto != htons(ETH_P_8021Q))
		return -EPROTONOSUPPORT;

4061 4062 4063 4064
	return mlx5_eswitch_set_vport_vlan(mdev->priv.eswitch, vf + 1,
					   vlan, qos);
}

4065 4066 4067 4068 4069 4070 4071 4072
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);
}

4073 4074 4075 4076 4077 4078 4079
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);
}
4080

4081 4082
int mlx5e_set_vf_rate(struct net_device *dev, int vf, int min_tx_rate,
		      int max_tx_rate)
4083 4084 4085 4086 4087
{
	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,
4088
					   max_tx_rate, min_tx_rate);
4089 4090
}

4091 4092 4093
static int mlx5_vport_link2ifla(u8 esw_link)
{
	switch (esw_link) {
4094
	case MLX5_VPORT_ADMIN_STATE_DOWN:
4095
		return IFLA_VF_LINK_STATE_DISABLE;
4096
	case MLX5_VPORT_ADMIN_STATE_UP:
4097 4098 4099 4100 4101 4102 4103 4104 4105
		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:
4106
		return MLX5_VPORT_ADMIN_STATE_DOWN;
4107
	case IFLA_VF_LINK_STATE_ENABLE:
4108
		return MLX5_VPORT_ADMIN_STATE_UP;
4109
	}
4110
	return MLX5_VPORT_ADMIN_STATE_AUTO;
4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122
}

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

4123 4124
int mlx5e_get_vf_config(struct net_device *dev,
			int vf, struct ifla_vf_info *ivi)
4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136
{
	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;
}

4137 4138
int mlx5e_get_vf_stats(struct net_device *dev,
		       int vf, struct ifla_vf_stats *vf_stats)
4139 4140 4141 4142 4143 4144 4145
{
	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);
}
4146
#endif
4147

4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161
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);
4162
	mlx5_vxlan_add_port(priv->mdev->vxlan, port);
4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175
	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);
4176
	mlx5_vxlan_del_port(priv->mdev->vxlan, port);
4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198
	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);
}

4199
void mlx5e_add_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
4200 4201 4202
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

4203 4204 4205
	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
		return;

4206
	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4207 4208
		return;

4209
	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 1);
4210 4211
}

4212
void mlx5e_del_vxlan_port(struct net_device *netdev, struct udp_tunnel_info *ti)
4213 4214 4215
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

4216 4217 4218
	if (ti->type != UDP_TUNNEL_TYPE_VXLAN)
		return;

4219
	if (!mlx5_vxlan_allowed(priv->mdev->vxlan))
4220 4221
		return;

4222
	mlx5e_vxlan_queue_work(priv, be16_to_cpu(ti->port), 0);
4223 4224
}

4225 4226 4227
static netdev_features_t mlx5e_tunnel_features_check(struct mlx5e_priv *priv,
						     struct sk_buff *skb,
						     netdev_features_t features)
4228
{
4229
	unsigned int offset = 0;
4230
	struct udphdr *udph;
4231 4232
	u8 proto;
	u16 port;
4233 4234 4235 4236 4237 4238

	switch (vlan_get_protocol(skb)) {
	case htons(ETH_P_IP):
		proto = ip_hdr(skb)->protocol;
		break;
	case htons(ETH_P_IPV6):
4239
		proto = ipv6_find_hdr(skb, &offset, -1, NULL, NULL);
4240 4241 4242 4243 4244
		break;
	default:
		goto out;
	}

4245 4246
	switch (proto) {
	case IPPROTO_GRE:
4247
		return features;
4248 4249
	case IPPROTO_IPIP:
	case IPPROTO_IPV6:
4250 4251 4252
		if (mlx5e_tunnel_proto_supported(priv->mdev, IPPROTO_IPIP))
			return features;
		break;
4253
	case IPPROTO_UDP:
4254 4255 4256
		udph = udp_hdr(skb);
		port = be16_to_cpu(udph->dest);

4257
		/* Verify if UDP port is being offloaded by HW */
4258
		if (mlx5_vxlan_lookup_port(priv->mdev->vxlan, port))
4259
			return features;
4260 4261 4262 4263 4264 4265

#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
4266
	}
4267 4268 4269 4270 4271 4272

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

4273 4274 4275
netdev_features_t mlx5e_features_check(struct sk_buff *skb,
				       struct net_device *netdev,
				       netdev_features_t features)
4276 4277 4278 4279 4280 4281
{
	struct mlx5e_priv *priv = netdev_priv(netdev);

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

4282 4283 4284 4285 4286
#ifdef CONFIG_MLX5_EN_IPSEC
	if (mlx5e_ipsec_feature_check(skb, netdev, features))
		return features;
#endif

4287 4288 4289
	/* Validate if the tunneled packet is being offloaded by HW */
	if (skb->encapsulation &&
	    (features & NETIF_F_CSUM_MASK || features & NETIF_F_GSO_MASK))
4290
		return mlx5e_tunnel_features_check(priv, skb, features);
4291 4292 4293 4294

	return features;
}

4295
static void mlx5e_tx_timeout_work(struct work_struct *work)
4296
{
4297 4298
	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
					       tx_timeout_work);
4299 4300 4301
	bool report_failed = false;
	int err;
	int i;
4302

4303 4304 4305 4306 4307
	rtnl_lock();
	mutex_lock(&priv->state_lock);

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

4309
	for (i = 0; i < priv->channels.num * priv->channels.params.num_tc; i++) {
4310 4311
		struct netdev_queue *dev_queue =
			netdev_get_tx_queue(priv->netdev, i);
4312
		struct mlx5e_txqsq *sq = priv->txq2sq[i];
4313

4314
		if (!netif_xmit_stopped(dev_queue))
4315
			continue;
4316

4317
		if (mlx5e_reporter_tx_timeout(sq))
4318
			report_failed = true;
4319 4320
	}

4321
	if (!report_failed)
4322 4323
		goto unlock;

4324
	err = mlx5e_safe_reopen_channels(priv);
4325 4326
	if (err)
		netdev_err(priv->netdev,
4327
			   "mlx5e_safe_reopen_channels failed recovering from a tx_timeout, err(%d).\n",
4328 4329
			   err);

4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340
unlock:
	mutex_unlock(&priv->state_lock);
	rtnl_unlock();
}

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

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

4343
static int mlx5e_xdp_allowed(struct mlx5e_priv *priv, struct bpf_prog *prog)
4344 4345
{
	struct net_device *netdev = priv->netdev;
4346
	struct mlx5e_channels new_channels = {};
4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357

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

4358 4359 4360
	new_channels.params = priv->channels.params;
	new_channels.params.xdp_prog = prog;

4361 4362 4363 4364
	/* 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)) {
4365
		netdev_warn(netdev, "XDP is not allowed with MTU(%d) > %d\n",
4366
			    new_channels.params.sw_mtu,
4367
			    mlx5e_xdp_max_mtu(&new_channels.params, NULL));
4368 4369 4370
		return -EINVAL;
	}

4371 4372 4373
	return 0;
}

4374 4375 4376 4377 4378 4379 4380 4381 4382 4383
static int mlx5e_xdp_update_state(struct mlx5e_priv *priv)
{
	if (priv->channels.params.xdp_prog)
		mlx5e_xdp_set_open(priv);
	else
		mlx5e_xdp_set_closed(priv);

	return 0;
}

4384 4385 4386 4387 4388
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;
4389
	int err = 0;
4390 4391 4392 4393
	int i;

	mutex_lock(&priv->state_lock);

4394
	if (prog) {
4395
		err = mlx5e_xdp_allowed(priv, prog);
4396 4397
		if (err)
			goto unlock;
4398 4399
	}

4400 4401
	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
	/* no need for full reset when exchanging programs */
4402
	reset = (!priv->channels.params.xdp_prog || !prog);
4403

4404
	if (was_opened && !reset)
4405 4406 4407
		/* num_channels is invariant here, so we can take the
		 * batched reference right upfront.
		 */
4408
		bpf_prog_add(prog, priv->channels.num);
4409

4410 4411 4412 4413 4414 4415 4416 4417
	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;

4418
		err = mlx5e_safe_switch_channels(priv, &new_channels, mlx5e_xdp_update_state);
4419 4420 4421 4422 4423 4424 4425 4426 4427
		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);
	}

4428 4429 4430
	if (old_prog)
		bpf_prog_put(old_prog);

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

4434
	if (!was_opened || reset)
4435 4436 4437 4438 4439
		goto unlock;

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

4444
		clear_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
4445 4446
		if (xsk_open)
			clear_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
4447 4448 4449 4450
		napi_synchronize(&c->napi);
		/* prevent mlx5e_poll_rx_cq from accessing rq->xdp_prog */

		old_prog = xchg(&c->rq.xdp_prog, prog);
4451 4452 4453 4454 4455 4456 4457 4458
		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);
		}
4459

4460
		set_bit(MLX5E_RQ_STATE_ENABLED, &c->rq.state);
4461 4462
		if (xsk_open)
			set_bit(MLX5E_RQ_STATE_ENABLED, &c->xskrq.state);
4463 4464 4465 4466 4467 4468 4469 4470 4471
		/* napi_schedule in case we have missed anything */
		napi_schedule(&c->napi);
	}

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

4472
static u32 mlx5e_xdp_query(struct net_device *dev)
4473 4474
{
	struct mlx5e_priv *priv = netdev_priv(dev);
4475 4476
	const struct bpf_prog *xdp_prog;
	u32 prog_id = 0;
4477

4478 4479 4480 4481 4482 4483 4484
	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;
4485 4486
}

4487
static int mlx5e_xdp(struct net_device *dev, struct netdev_bpf *xdp)
4488 4489 4490 4491 4492
{
	switch (xdp->command) {
	case XDP_SETUP_PROG:
		return mlx5e_xdp_set(dev, xdp->prog);
	case XDP_QUERY_PROG:
4493
		xdp->prog_id = mlx5e_xdp_query(dev);
4494
		return 0;
4495 4496 4497
	case XDP_SETUP_XSK_UMEM:
		return mlx5e_xsk_setup_umem(dev, xdp->xsk.umem,
					    xdp->xsk.queue_id);
4498 4499 4500 4501 4502
	default:
		return -EINVAL;
	}
}

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 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557
#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

4558
const struct net_device_ops mlx5e_netdev_ops = {
4559 4560 4561
	.ndo_open                = mlx5e_open,
	.ndo_stop                = mlx5e_close,
	.ndo_start_xmit          = mlx5e_xmit,
4562
	.ndo_setup_tc            = mlx5e_setup_tc,
4563
	.ndo_select_queue        = mlx5e_select_queue,
4564 4565 4566
	.ndo_get_stats64         = mlx5e_get_stats,
	.ndo_set_rx_mode         = mlx5e_set_rx_mode,
	.ndo_set_mac_address     = mlx5e_set_mac,
4567 4568
	.ndo_vlan_rx_add_vid     = mlx5e_vlan_rx_add_vid,
	.ndo_vlan_rx_kill_vid    = mlx5e_vlan_rx_kill_vid,
4569
	.ndo_set_features        = mlx5e_set_features,
4570
	.ndo_fix_features        = mlx5e_fix_features,
4571
	.ndo_change_mtu          = mlx5e_change_nic_mtu,
4572
	.ndo_do_ioctl            = mlx5e_ioctl,
4573
	.ndo_set_tx_maxrate      = mlx5e_set_tx_maxrate,
4574 4575 4576
	.ndo_udp_tunnel_add      = mlx5e_add_vxlan_port,
	.ndo_udp_tunnel_del      = mlx5e_del_vxlan_port,
	.ndo_features_check      = mlx5e_features_check,
4577
	.ndo_tx_timeout          = mlx5e_tx_timeout,
4578
	.ndo_bpf		 = mlx5e_xdp,
4579
	.ndo_xdp_xmit            = mlx5e_xdp_xmit,
4580
	.ndo_xsk_wakeup          = mlx5e_xsk_wakeup,
4581 4582 4583
#ifdef CONFIG_MLX5_EN_ARFS
	.ndo_rx_flow_steer	 = mlx5e_rx_flow_steer,
#endif
4584
#ifdef CONFIG_MLX5_ESWITCH
4585 4586 4587
	.ndo_bridge_setlink      = mlx5e_bridge_setlink,
	.ndo_bridge_getlink      = mlx5e_bridge_getlink,

4588
	/* SRIOV E-Switch NDOs */
4589 4590
	.ndo_set_vf_mac          = mlx5e_set_vf_mac,
	.ndo_set_vf_vlan         = mlx5e_set_vf_vlan,
4591
	.ndo_set_vf_spoofchk     = mlx5e_set_vf_spoofchk,
4592
	.ndo_set_vf_trust        = mlx5e_set_vf_trust,
4593
	.ndo_set_vf_rate         = mlx5e_set_vf_rate,
4594 4595 4596
	.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,
4597
#endif
4598 4599 4600 4601 4602
};

static int mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
{
	if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
4603
		return -EOPNOTSUPP;
4604 4605 4606 4607 4608
	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) ||
4609 4610 4611 4612
	    !MLX5_CAP_ETH(mdev, rss_ind_tbl_cap) ||
	    MLX5_CAP_FLOWTABLE(mdev,
			       flow_table_properties_nic_receive.max_ft_level)
			       < 3) {
4613 4614
		mlx5_core_warn(mdev,
			       "Not creating net device, some required device capabilities are missing\n");
4615
		return -EOPNOTSUPP;
4616
	}
4617 4618
	if (!MLX5_CAP_ETH(mdev, self_lb_en_modifiable))
		mlx5_core_warn(mdev, "Self loop back prevention is not supported\n");
4619
	if (!MLX5_CAP_GEN(mdev, cq_moderation))
4620
		mlx5_core_warn(mdev, "CQ moderation is not supported\n");
4621

4622 4623 4624
	return 0;
}

4625
void mlx5e_build_default_indir_rqt(u32 *indirection_rqt, int len,
4626 4627 4628 4629 4630 4631 4632 4633
				   int num_channels)
{
	int i;

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

4634
static bool slow_pci_heuristic(struct mlx5_core_dev *mdev)
4635
{
4636 4637
	u32 link_speed = 0;
	u32 pci_bw = 0;
4638

4639
	mlx5e_port_max_linkspeed(mdev, &link_speed);
4640
	pci_bw = pcie_bandwidth_available(mdev->pdev, NULL, NULL, NULL);
4641 4642 4643 4644 4645 4646 4647
	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;
4648 4649
}

4650
static struct dim_cq_moder mlx5e_get_def_tx_moderation(u8 cq_period_mode)
4651
{
4652
	struct dim_cq_moder moder;
4653 4654 4655 4656 4657 4658 4659 4660 4661

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

4663
static struct dim_cq_moder mlx5e_get_def_rx_moderation(u8 cq_period_mode)
4664
{
4665
	struct dim_cq_moder moder;
4666

4667 4668 4669
	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;
4670
	if (cq_period_mode == MLX5_CQ_PERIOD_MODE_START_FROM_CQE)
4671 4672 4673 4674 4675 4676 4677 4678
		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 ?
4679 4680
		DIM_CQ_PERIOD_MODE_START_FROM_CQE :
		DIM_CQ_PERIOD_MODE_START_FROM_EQE;
4681 4682 4683 4684 4685 4686 4687 4688 4689 4690 4691
}

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);
	}
4692 4693 4694 4695 4696 4697

	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 已提交
4698 4699
void mlx5e_set_rx_cq_mode_params(struct mlx5e_params *params, u8 cq_period_mode)
{
4700
	if (params->rx_dim_enabled) {
4701 4702 4703 4704 4705
		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);
4706
	}
4707

4708
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_BASED_MODER,
4709 4710
			params->rx_cq_moderation.cq_period_mode ==
				MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
T
Tariq Toukan 已提交
4711 4712
}

4713
static u32 mlx5e_choose_lro_timeout(struct mlx5_core_dev *mdev, u32 wanted_timeout)
4714 4715 4716 4717 4718 4719 4720 4721 4722 4723 4724
{
	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]);
}

4725 4726 4727 4728 4729 4730 4731
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.
4732 4733
	 *
	 * No XSK params: checking the availability of striding RQ in general.
4734 4735 4736
	 */
	if (!slow_pci_heuristic(mdev) &&
	    mlx5e_striding_rq_possible(mdev, params) &&
4737 4738
	    (mlx5e_rx_mpwqe_is_linear_skb(mdev, params, NULL) ||
	     !mlx5e_rx_is_linear_skb(params, NULL)))
4739 4740 4741 4742 4743
		MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_STRIDING_RQ, true);
	mlx5e_set_rq_type(mdev, params);
	mlx5e_init_rq_type_params(mdev, params);
}

4744 4745
void mlx5e_build_rss_params(struct mlx5e_rss_params *rss_params,
			    u16 num_channels)
4746
{
4747 4748
	enum mlx5e_traffic_types tt;

4749
	rss_params->hfunc = ETH_RSS_HASH_TOP;
4750 4751 4752 4753
	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);
4754 4755 4756
	for (tt = 0; tt < MLX5E_NUM_INDIR_TIRS; tt++)
		rss_params->rx_hash_fields[tt] =
			tirc_default_config[tt].rx_hash_fields;
4757 4758
}

4759
void mlx5e_build_nic_params(struct mlx5_core_dev *mdev,
4760
			    struct mlx5e_xsk *xsk,
4761
			    struct mlx5e_rss_params *rss_params,
4762
			    struct mlx5e_params *params,
4763
			    u16 max_channels, u16 mtu)
4764
{
4765
	u8 rx_cq_period_mode;
4766

4767 4768
	params->sw_mtu = mtu;
	params->hard_mtu = MLX5E_ETH_HARD_MTU;
4769 4770
	params->num_channels = max_channels;
	params->num_tc       = 1;
4771

4772 4773
	/* SQ */
	params->log_sq_size = is_kdump_kernel() ?
4774 4775
		MLX5E_PARAMS_MINIMUM_LOG_SQ_SIZE :
		MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
4776

4777 4778 4779 4780
	/* XDP SQ */
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_XDP_TX_MPWQE,
			MLX5_CAP_ETH(mdev, enhanced_multi_pkt_send_wqe));

4781
	/* set CQE compression */
4782
	params->rx_cqe_compress_def = false;
4783
	if (MLX5_CAP_GEN(mdev, cqe_compression) &&
4784
	    MLX5_CAP_GEN(mdev, vport_group_manager))
4785
		params->rx_cqe_compress_def = slow_pci_heuristic(mdev);
4786

4787
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_CQE_COMPRESS, params->rx_cqe_compress_def);
4788
	MLX5E_SET_PFLAG(params, MLX5E_PFLAG_RX_NO_CSUM_COMPLETE, false);
4789 4790

	/* RQ */
4791
	mlx5e_build_rq_params(mdev, params);
4792

4793
	/* HW LRO */
4794

4795
	/* TODO: && MLX5_CAP_ETH(mdev, lro_cap) */
4796 4797 4798
	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))
4799
			params->lro_en = !slow_pci_heuristic(mdev);
4800
	}
4801
	params->lro_timeout = mlx5e_choose_lro_timeout(mdev, MLX5E_DEFAULT_LRO_TIMEOUT);
4802

4803
	/* CQ moderation params */
4804
	rx_cq_period_mode = MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
4805 4806
			MLX5_CQ_PERIOD_MODE_START_FROM_CQE :
			MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
4807
	params->rx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
4808
	params->tx_dim_enabled = MLX5_CAP_GEN(mdev, cq_moderation);
4809 4810
	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 已提交
4811

4812
	/* TX inline */
4813
	mlx5_query_min_inline(mdev, &params->tx_min_inline_mode);
4814

4815
	/* RSS */
4816
	mlx5e_build_rss_params(rss_params, params->num_channels);
4817 4818
	params->tunneled_offload_en =
		mlx5e_tunnel_inner_ft_supported(mdev);
4819 4820 4821

	/* AF_XDP */
	params->xsk = xsk;
4822
}
4823 4824 4825 4826 4827

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

4828
	mlx5_query_mac_address(priv->mdev, netdev->dev_addr);
4829 4830 4831 4832 4833
	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);
	}
4834 4835
}

4836
static void mlx5e_build_nic_netdev(struct net_device *netdev)
4837 4838 4839
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
	struct mlx5_core_dev *mdev = priv->mdev;
4840 4841
	bool fcs_supported;
	bool fcs_enabled;
4842

4843
	SET_NETDEV_DEV(netdev, mdev->device);
4844

4845 4846
	netdev->netdev_ops = &mlx5e_netdev_ops;

4847
#ifdef CONFIG_MLX5_CORE_EN_DCB
4848 4849
	if (MLX5_CAP_GEN(mdev, vport_group_manager) && MLX5_CAP_GEN(mdev, qos))
		netdev->dcbnl_ops = &mlx5e_dcbnl_ops;
4850
#endif
4851

4852 4853 4854 4855
	netdev->watchdog_timeo    = 15 * HZ;

	netdev->ethtool_ops	  = &mlx5e_ethtool_ops;

S
Saeed Mahameed 已提交
4856
	netdev->vlan_features    |= NETIF_F_SG;
4857
	netdev->vlan_features    |= NETIF_F_HW_CSUM;
4858 4859 4860 4861 4862 4863
	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;

4864 4865 4866 4867 4868
	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;

4869 4870 4871
	netdev->hw_enc_features  |= NETIF_F_HW_VLAN_CTAG_TX;
	netdev->hw_enc_features  |= NETIF_F_HW_VLAN_CTAG_RX;

4872 4873
	if (!!MLX5_CAP_ETH(mdev, lro_cap) &&
	    mlx5e_check_fragmented_striding_rq_cap(mdev))
4874 4875 4876
		netdev->vlan_features    |= NETIF_F_LRO;

	netdev->hw_features       = netdev->vlan_features;
4877
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_TX;
4878 4879
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_RX;
	netdev->hw_features      |= NETIF_F_HW_VLAN_CTAG_FILTER;
4880
	netdev->hw_features      |= NETIF_F_HW_VLAN_STAG_TX;
4881

4882
	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev) ||
4883
	    mlx5e_any_tunnel_proto_supported(mdev)) {
4884
		netdev->hw_enc_features |= NETIF_F_HW_CSUM;
4885 4886
		netdev->hw_enc_features |= NETIF_F_TSO;
		netdev->hw_enc_features |= NETIF_F_TSO6;
4887 4888 4889
		netdev->hw_enc_features |= NETIF_F_GSO_PARTIAL;
	}

4890
	if (mlx5_vxlan_allowed(mdev->vxlan) || mlx5_geneve_tx_allowed(mdev)) {
4891 4892 4893 4894
		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;
4895
		netdev->gso_partial_features = NETIF_F_GSO_UDP_TUNNEL_CSUM;
4896 4897
	}

4898
	if (mlx5e_tunnel_proto_supported(mdev, IPPROTO_GRE)) {
4899 4900 4901 4902 4903 4904 4905 4906
		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;
	}

4907 4908 4909 4910 4911 4912 4913 4914 4915
	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;
	}

4916 4917 4918 4919 4920
	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;

4921 4922 4923 4924 4925
	mlx5_query_port_fcs(mdev, &fcs_supported, &fcs_enabled);

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

4926 4927 4928
	if (MLX5_CAP_ETH(mdev, scatter_fcs))
		netdev->hw_features |= NETIF_F_RXFCS;

4929
	netdev->features          = netdev->hw_features;
4930
	if (!priv->channels.params.lro_en)
4931 4932
		netdev->features  &= ~NETIF_F_LRO;

4933 4934 4935
	if (fcs_enabled)
		netdev->features  &= ~NETIF_F_RXALL;

4936 4937 4938
	if (!priv->channels.params.scatter_fcs_en)
		netdev->features  &= ~NETIF_F_RXFCS;

4939 4940 4941 4942
	/* prefere CQE compression over rxhash */
	if (MLX5E_GET_PFLAG(&priv->channels.params, MLX5E_PFLAG_RX_CQE_COMPRESS))
		netdev->features &= ~NETIF_F_RXHASH;

4943 4944 4945 4946
#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) &&
4947
	    FT_CAP(flow_table_modify)) {
4948
#ifdef CONFIG_MLX5_ESWITCH
4949
		netdev->hw_features      |= NETIF_F_HW_TC;
4950
#endif
4951
#ifdef CONFIG_MLX5_EN_ARFS
4952 4953 4954
		netdev->hw_features	 |= NETIF_F_NTUPLE;
#endif
	}
4955

4956
	netdev->features         |= NETIF_F_HIGHDMA;
4957
	netdev->features         |= NETIF_F_HW_VLAN_STAG_FILTER;
4958 4959 4960 4961

	netdev->priv_flags       |= IFF_UNICAST_FLT;

	mlx5e_set_netdev_dev_addr(netdev);
4962
	mlx5e_ipsec_build_netdev(priv);
4963
	mlx5e_tls_build_netdev(priv);
4964 4965
}

4966
void mlx5e_create_q_counters(struct mlx5e_priv *priv)
4967 4968 4969 4970 4971 4972 4973 4974 4975
{
	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;
	}
4976 4977 4978 4979 4980 4981

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

4984
void mlx5e_destroy_q_counters(struct mlx5e_priv *priv)
4985
{
4986 4987
	if (priv->q_counter)
		mlx5_core_dealloc_q_counter(priv->mdev, priv->q_counter);
4988

4989 4990
	if (priv->drop_rq_q_counter)
		mlx5_core_dealloc_q_counter(priv->mdev, priv->drop_rq_q_counter);
4991 4992
}

4993 4994 4995 4996
static int mlx5e_nic_init(struct mlx5_core_dev *mdev,
			  struct net_device *netdev,
			  const struct mlx5e_profile *profile,
			  void *ppriv)
4997 4998
{
	struct mlx5e_priv *priv = netdev_priv(netdev);
4999
	struct mlx5e_rss_params *rss = &priv->rss_params;
5000
	int err;
5001

5002
	err = mlx5e_netdev_init(netdev, priv, mdev, profile, ppriv);
5003 5004 5005
	if (err)
		return err;

5006
	mlx5e_build_nic_params(mdev, &priv->xsk, rss, &priv->channels.params,
5007
			       priv->max_nch, netdev->mtu);
5008 5009 5010

	mlx5e_timestamp_init(priv);

5011 5012 5013
	err = mlx5e_ipsec_init(priv);
	if (err)
		mlx5_core_err(mdev, "IPSec initialization failed, %d\n", err);
5014 5015 5016
	err = mlx5e_tls_init(priv);
	if (err)
		mlx5_core_err(mdev, "TLS initialization failed, %d\n", err);
5017
	mlx5e_build_nic_netdev(netdev);
5018
	mlx5e_health_create_reporters(priv);
5019 5020

	return 0;
5021 5022 5023 5024
}

static void mlx5e_nic_cleanup(struct mlx5e_priv *priv)
{
5025
	mlx5e_health_destroy_reporters(priv);
5026
	mlx5e_tls_cleanup(priv);
5027
	mlx5e_ipsec_cleanup(priv);
5028
	mlx5e_netdev_cleanup(priv->netdev, priv);
5029 5030 5031 5032 5033 5034 5035
}

static int mlx5e_init_nic_rx(struct mlx5e_priv *priv)
{
	struct mlx5_core_dev *mdev = priv->mdev;
	int err;

5036 5037 5038 5039 5040 5041 5042 5043
	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;
	}

5044 5045
	err = mlx5e_create_indirect_rqt(priv);
	if (err)
5046
		goto err_close_drop_rq;
5047

5048
	err = mlx5e_create_direct_rqts(priv, priv->direct_tir);
5049
	if (err)
5050 5051
		goto err_destroy_indirect_rqts;

5052
	err = mlx5e_create_indirect_tirs(priv, true);
5053
	if (err)
5054 5055
		goto err_destroy_direct_rqts;

5056
	err = mlx5e_create_direct_tirs(priv, priv->direct_tir);
5057
	if (err)
5058 5059
		goto err_destroy_indirect_tirs;

5060 5061 5062 5063 5064 5065 5066 5067
	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;

5068 5069 5070
	err = mlx5e_create_flow_steering(priv);
	if (err) {
		mlx5_core_warn(mdev, "create flow steering failed, %d\n", err);
5071
		goto err_destroy_xsk_tirs;
5072 5073
	}

5074
	err = mlx5e_tc_nic_init(priv);
5075 5076 5077 5078 5079 5080 5081
	if (err)
		goto err_destroy_flow_steering;

	return 0;

err_destroy_flow_steering:
	mlx5e_destroy_flow_steering(priv);
5082 5083 5084 5085
err_destroy_xsk_tirs:
	mlx5e_destroy_direct_tirs(priv, priv->xsk_tir);
err_destroy_xsk_rqts:
	mlx5e_destroy_direct_rqts(priv, priv->xsk_tir);
5086
err_destroy_direct_tirs:
5087
	mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
5088
err_destroy_indirect_tirs:
5089
	mlx5e_destroy_indirect_tirs(priv, true);
5090
err_destroy_direct_rqts:
5091
	mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
5092 5093
err_destroy_indirect_rqts:
	mlx5e_destroy_rqt(priv, &priv->indir_rqt);
5094 5095 5096 5097
err_close_drop_rq:
	mlx5e_close_drop_rq(&priv->drop_rq);
err_destroy_q_counters:
	mlx5e_destroy_q_counters(priv);
5098 5099 5100 5101 5102
	return err;
}

static void mlx5e_cleanup_nic_rx(struct mlx5e_priv *priv)
{
5103
	mlx5e_tc_nic_cleanup(priv);
5104
	mlx5e_destroy_flow_steering(priv);
5105 5106 5107
	mlx5e_destroy_direct_tirs(priv, priv->xsk_tir);
	mlx5e_destroy_direct_rqts(priv, priv->xsk_tir);
	mlx5e_destroy_direct_tirs(priv, priv->direct_tir);
5108
	mlx5e_destroy_indirect_tirs(priv, true);
5109
	mlx5e_destroy_direct_rqts(priv, priv->direct_tir);
5110
	mlx5e_destroy_rqt(priv, &priv->indir_rqt);
5111 5112
	mlx5e_close_drop_rq(&priv->drop_rq);
	mlx5e_destroy_q_counters(priv);
5113 5114 5115 5116 5117 5118 5119 5120 5121 5122 5123 5124 5125
}

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
5126
	mlx5e_dcbnl_initialize(priv);
5127 5128 5129 5130 5131 5132 5133 5134
#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;
5135 5136 5137

	mlx5e_init_l2_addr(priv);

5138 5139 5140 5141
	/* Marking the link as currently not needed by the Driver */
	if (!netif_running(netdev))
		mlx5_set_port_admin_status(mdev, MLX5_PORT_DOWN);

5142
	mlx5e_set_netdev_mtu_boundaries(priv);
5143
	mlx5e_set_dev_port_mtu(priv);
5144

5145 5146
	mlx5_lag_add(mdev, netdev);

5147
	mlx5e_enable_async_events(priv);
5148 5149
	if (mlx5e_monitor_counter_supported(priv))
		mlx5e_monitor_counter_init(priv);
5150

5151
	mlx5e_hv_vhca_stats_create(priv);
5152 5153
	if (netdev->reg_state != NETREG_REGISTERED)
		return;
5154 5155 5156
#ifdef CONFIG_MLX5_CORE_EN_DCB
	mlx5e_dcbnl_init_app(priv);
#endif
5157 5158

	queue_work(priv->wq, &priv->set_rx_mode_work);
5159 5160 5161 5162 5163 5164

	rtnl_lock();
	if (netif_running(netdev))
		mlx5e_open(netdev);
	netif_device_attach(netdev);
	rtnl_unlock();
5165 5166 5167 5168
}

static void mlx5e_nic_disable(struct mlx5e_priv *priv)
{
5169 5170
	struct mlx5_core_dev *mdev = priv->mdev;

5171 5172 5173 5174 5175
#ifdef CONFIG_MLX5_CORE_EN_DCB
	if (priv->netdev->reg_state == NETREG_REGISTERED)
		mlx5e_dcbnl_delete_app(priv);
#endif

5176 5177 5178 5179 5180 5181
	rtnl_lock();
	if (netif_running(priv->netdev))
		mlx5e_close(priv->netdev);
	netif_device_detach(priv->netdev);
	rtnl_unlock();

5182
	queue_work(priv->wq, &priv->set_rx_mode_work);
5183

5184
	mlx5e_hv_vhca_stats_destroy(priv);
5185 5186 5187
	if (mlx5e_monitor_counter_supported(priv))
		mlx5e_monitor_counter_cleanup(priv);

5188
	mlx5e_disable_async_events(priv);
5189
	mlx5_lag_remove(mdev);
5190 5191
}

5192 5193 5194 5195 5196
int mlx5e_update_nic_rx(struct mlx5e_priv *priv)
{
	return mlx5e_refresh_tirs(priv, false);
}

5197 5198 5199 5200 5201 5202 5203 5204 5205
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,
5206
	.update_rx	   = mlx5e_update_nic_rx,
5207
	.update_stats	   = mlx5e_update_ndo_stats,
5208
	.update_carrier	   = mlx5e_update_carrier,
5209 5210
	.rx_handlers.handle_rx_cqe       = mlx5e_handle_rx_cqe,
	.rx_handlers.handle_rx_cqe_mpwqe = mlx5e_handle_rx_cqe_mpwrq,
5211
	.max_tc		   = MLX5E_MAX_NUM_TC,
5212
	.rq_groups	   = MLX5E_NUM_RQ_GROUPS(XSK),
5213 5214
};

5215 5216
/* mlx5e generic netdev management API (move to en_common.c) */

5217
/* mlx5e_netdev_init/cleanup must be called from profile->init/cleanup callbacks */
5218 5219 5220 5221 5222
int mlx5e_netdev_init(struct net_device *netdev,
		      struct mlx5e_priv *priv,
		      struct mlx5_core_dev *mdev,
		      const struct mlx5e_profile *profile,
		      void *ppriv)
5223
{
5224 5225 5226 5227 5228 5229
	/* priv init */
	priv->mdev        = mdev;
	priv->netdev      = netdev;
	priv->profile     = profile;
	priv->ppriv       = ppriv;
	priv->msglevel    = MLX5E_MSG_LEVEL;
5230
	priv->max_nch     = netdev->num_rx_queues / max_t(u8, profile->rq_groups, 1);
5231
	priv->max_opened_tc = 1;
5232

5233 5234 5235 5236
	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);
5237
	INIT_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
5238

5239 5240 5241 5242
	priv->wq = create_singlethread_workqueue("mlx5e");
	if (!priv->wq)
		return -ENOMEM;

5243 5244 5245 5246
	/* netdev init */
	netif_carrier_off(netdev);

#ifdef CONFIG_MLX5_EN_ARFS
5247
	netdev->rx_cpu_rmap =  mlx5_eq_table_get_rmap(mdev);
5248 5249
#endif

5250 5251 5252 5253 5254 5255 5256 5257
	return 0;
}

void mlx5e_netdev_cleanup(struct net_device *netdev, struct mlx5e_priv *priv)
{
	destroy_workqueue(priv->wq);
}

5258 5259
struct net_device *mlx5e_create_netdev(struct mlx5_core_dev *mdev,
				       const struct mlx5e_profile *profile,
5260
				       int nch,
5261
				       void *ppriv)
5262 5263
{
	struct net_device *netdev;
5264
	int err;
5265

5266
	netdev = alloc_etherdev_mqs(sizeof(struct mlx5e_priv),
5267
				    nch * profile->max_tc,
5268
				    nch * profile->rq_groups);
5269 5270 5271 5272 5273
	if (!netdev) {
		mlx5_core_err(mdev, "alloc_etherdev_mqs() failed\n");
		return NULL;
	}

5274 5275 5276 5277 5278
	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;
	}
5279 5280 5281

	return netdev;

5282
err_free_netdev:
5283 5284 5285 5286 5287
	free_netdev(netdev);

	return NULL;
}

5288
int mlx5e_attach_netdev(struct mlx5e_priv *priv)
5289 5290
{
	const struct mlx5e_profile *profile;
5291
	int max_nch;
5292 5293 5294 5295
	int err;

	profile = priv->profile;
	clear_bit(MLX5E_STATE_DESTROYING, &priv->state);
5296

5297 5298 5299 5300 5301
	/* 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;
5302
		mlx5e_build_default_indir_rqt(priv->rss_params.indirection_rqt,
5303 5304 5305
					      MLX5E_INDIR_RQT_SIZE, max_nch);
	}

5306 5307
	err = profile->init_tx(priv);
	if (err)
T
Tariq Toukan 已提交
5308
		goto out;
5309

5310 5311
	err = profile->init_rx(priv);
	if (err)
5312
		goto err_cleanup_tx;
5313

5314 5315
	if (profile->enable)
		profile->enable(priv);
5316

5317
	return 0;
5318

5319
err_cleanup_tx:
5320
	profile->cleanup_tx(priv);
5321

5322 5323
out:
	return err;
5324 5325
}

5326
void mlx5e_detach_netdev(struct mlx5e_priv *priv)
5327 5328 5329 5330 5331
{
	const struct mlx5e_profile *profile = priv->profile;

	set_bit(MLX5E_STATE_DESTROYING, &priv->state);

5332 5333 5334 5335
	if (profile->disable)
		profile->disable(priv);
	flush_workqueue(priv->wq);

5336 5337
	profile->cleanup_rx(priv);
	profile->cleanup_tx(priv);
5338
	cancel_work_sync(&priv->update_stats_work);
5339 5340
}

5341 5342 5343 5344 5345 5346 5347 5348 5349 5350
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);
}

5351 5352 5353 5354 5355 5356 5357 5358 5359 5360 5361 5362 5363 5364 5365 5366
/* 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;

5367
	err = mlx5e_attach_netdev(priv);
5368 5369 5370 5371 5372 5373 5374 5375 5376 5377 5378 5379 5380
	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;

5381 5382 5383 5384 5385
#ifdef CONFIG_MLX5_ESWITCH
	if (MLX5_ESWITCH_MANAGER(mdev) && vpriv == mdev)
		return;
#endif

5386 5387 5388
	if (!netif_device_present(netdev))
		return;

5389
	mlx5e_detach_netdev(priv);
5390 5391 5392
	mlx5e_destroy_mdev_resources(mdev);
}

5393 5394
static void *mlx5e_add(struct mlx5_core_dev *mdev)
{
5395
	struct net_device *netdev;
5396 5397
	void *priv;
	int err;
5398
	int nch;
5399

5400 5401
	err = mlx5e_check_required_hca_cap(mdev);
	if (err)
5402 5403
		return NULL;

5404 5405
#ifdef CONFIG_MLX5_ESWITCH
	if (MLX5_ESWITCH_MANAGER(mdev) &&
5406
	    mlx5_eswitch_mode(mdev->priv.eswitch) == MLX5_ESWITCH_OFFLOADS) {
5407 5408 5409 5410 5411
		mlx5e_rep_register_vport_reps(mdev);
		return mdev;
	}
#endif

5412
	nch = mlx5e_get_max_num_channels(mdev);
5413
	netdev = mlx5e_create_netdev(mdev, &mlx5e_nic_profile, nch, NULL);
5414 5415
	if (!netdev) {
		mlx5_core_err(mdev, "mlx5e_create_netdev failed\n");
5416
		return NULL;
5417 5418
	}

5419
	dev_net_set(netdev, mlx5_core_net(mdev));
5420 5421 5422 5423 5424 5425 5426 5427 5428 5429 5430 5431
	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;
5432
	}
5433

5434 5435 5436
#ifdef CONFIG_MLX5_CORE_EN_DCB
	mlx5e_dcbnl_init_app(priv);
#endif
5437 5438 5439 5440 5441
	return priv;

err_detach:
	mlx5e_detach(mdev, priv);
err_destroy_netdev:
5442
	mlx5e_destroy_netdev(priv);
5443
	return NULL;
5444 5445 5446 5447
}

static void mlx5e_remove(struct mlx5_core_dev *mdev, void *vpriv)
{
5448
	struct mlx5e_priv *priv;
5449

5450 5451 5452 5453 5454 5455 5456
#ifdef CONFIG_MLX5_ESWITCH
	if (MLX5_ESWITCH_MANAGER(mdev) && vpriv == mdev) {
		mlx5e_rep_unregister_vport_reps(mdev);
		return;
	}
#endif
	priv = vpriv;
5457 5458 5459
#ifdef CONFIG_MLX5_CORE_EN_DCB
	mlx5e_dcbnl_delete_app(priv);
#endif
5460
	unregister_netdev(priv->netdev);
5461
	mlx5e_detach(mdev, vpriv);
5462
	mlx5e_destroy_netdev(priv);
5463 5464
}

5465
static struct mlx5_interface mlx5e_interface = {
5466 5467
	.add       = mlx5e_add,
	.remove    = mlx5e_remove,
5468 5469
	.attach    = mlx5e_attach,
	.detach    = mlx5e_detach,
5470 5471 5472 5473 5474
	.protocol  = MLX5_INTERFACE_PROTOCOL_ETH,
};

void mlx5e_init(void)
{
5475
	mlx5e_ipsec_build_inverse_table();
5476
	mlx5e_build_ptys2ethtool_map();
5477 5478 5479 5480 5481 5482 5483
	mlx5_register_interface(&mlx5e_interface);
}

void mlx5e_cleanup(void)
{
	mlx5_unregister_interface(&mlx5e_interface);
}