mlx5_en_main.c revision 331590
1153187Spjd/*-
2153187Spjd * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
3153187Spjd *
4153187Spjd * Redistribution and use in source and binary forms, with or without
5153187Spjd * modification, are permitted provided that the following conditions
6153187Spjd * are met:
7153187Spjd * 1. Redistributions of source code must retain the above copyright
8153187Spjd *    notice, this list of conditions and the following disclaimer.
9153187Spjd * 2. Redistributions in binary form must reproduce the above copyright
10153187Spjd *    notice, this list of conditions and the following disclaimer in the
11293438Sngie *    documentation and/or other materials provided with the distribution.
12293438Sngie *
13153187Spjd * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14293438Sngie * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15293438Sngie * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16293438Sngie * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17293438Sngie * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18153187Spjd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19153187Spjd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20293438Sngie * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21153187Spjd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22153187Spjd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23153187Spjd * SUCH DAMAGE.
24153187Spjd *
25153187Spjd * $FreeBSD: stable/11/sys/dev/mlx5/mlx5_en/mlx5_en_main.c 331590 2018-03-26 21:04:47Z hselasky $
26153187Spjd */
27153187Spjd
28153187Spjd#include "en.h"
29153187Spjd
30153187Spjd#include <sys/sockio.h>
31153187Spjd#include <machine/atomic.h>
32153187Spjd
33153187Spjd#define	ETH_DRIVER_VERSION	"3.1.0-dev"
34153187Spjdchar mlx5e_version[] = "Mellanox Ethernet driver"
35153187Spjd    " (" ETH_DRIVER_VERSION ")";
36153187Spjd
37struct mlx5e_channel_param {
38	struct mlx5e_rq_param rq;
39	struct mlx5e_sq_param sq;
40	struct mlx5e_cq_param rx_cq;
41	struct mlx5e_cq_param tx_cq;
42};
43
44static const struct {
45	u32	subtype;
46	u64	baudrate;
47}	mlx5e_mode_table[MLX5E_LINK_MODES_NUMBER] = {
48
49	[MLX5E_1000BASE_CX_SGMII] = {
50		.subtype = IFM_1000_CX_SGMII,
51		.baudrate = IF_Mbps(1000ULL),
52	},
53	[MLX5E_1000BASE_KX] = {
54		.subtype = IFM_1000_KX,
55		.baudrate = IF_Mbps(1000ULL),
56	},
57	[MLX5E_10GBASE_CX4] = {
58		.subtype = IFM_10G_CX4,
59		.baudrate = IF_Gbps(10ULL),
60	},
61	[MLX5E_10GBASE_KX4] = {
62		.subtype = IFM_10G_KX4,
63		.baudrate = IF_Gbps(10ULL),
64	},
65	[MLX5E_10GBASE_KR] = {
66		.subtype = IFM_10G_KR,
67		.baudrate = IF_Gbps(10ULL),
68	},
69	[MLX5E_20GBASE_KR2] = {
70		.subtype = IFM_20G_KR2,
71		.baudrate = IF_Gbps(20ULL),
72	},
73	[MLX5E_40GBASE_CR4] = {
74		.subtype = IFM_40G_CR4,
75		.baudrate = IF_Gbps(40ULL),
76	},
77	[MLX5E_40GBASE_KR4] = {
78		.subtype = IFM_40G_KR4,
79		.baudrate = IF_Gbps(40ULL),
80	},
81	[MLX5E_56GBASE_R4] = {
82		.subtype = IFM_56G_R4,
83		.baudrate = IF_Gbps(56ULL),
84	},
85	[MLX5E_10GBASE_CR] = {
86		.subtype = IFM_10G_CR1,
87		.baudrate = IF_Gbps(10ULL),
88	},
89	[MLX5E_10GBASE_SR] = {
90		.subtype = IFM_10G_SR,
91		.baudrate = IF_Gbps(10ULL),
92	},
93	[MLX5E_10GBASE_ER] = {
94		.subtype = IFM_10G_ER,
95		.baudrate = IF_Gbps(10ULL),
96	},
97	[MLX5E_40GBASE_SR4] = {
98		.subtype = IFM_40G_SR4,
99		.baudrate = IF_Gbps(40ULL),
100	},
101	[MLX5E_40GBASE_LR4] = {
102		.subtype = IFM_40G_LR4,
103		.baudrate = IF_Gbps(40ULL),
104	},
105	[MLX5E_100GBASE_CR4] = {
106		.subtype = IFM_100G_CR4,
107		.baudrate = IF_Gbps(100ULL),
108	},
109	[MLX5E_100GBASE_SR4] = {
110		.subtype = IFM_100G_SR4,
111		.baudrate = IF_Gbps(100ULL),
112	},
113	[MLX5E_100GBASE_KR4] = {
114		.subtype = IFM_100G_KR4,
115		.baudrate = IF_Gbps(100ULL),
116	},
117	[MLX5E_100GBASE_LR4] = {
118		.subtype = IFM_100G_LR4,
119		.baudrate = IF_Gbps(100ULL),
120	},
121	[MLX5E_100BASE_TX] = {
122		.subtype = IFM_100_TX,
123		.baudrate = IF_Mbps(100ULL),
124	},
125	[MLX5E_1000BASE_T] = {
126		.subtype = IFM_1000_T,
127		.baudrate = IF_Mbps(1000ULL),
128	},
129	[MLX5E_10GBASE_T] = {
130		.subtype = IFM_10G_T,
131		.baudrate = IF_Gbps(10ULL),
132	},
133	[MLX5E_25GBASE_CR] = {
134		.subtype = IFM_25G_CR,
135		.baudrate = IF_Gbps(25ULL),
136	},
137	[MLX5E_25GBASE_KR] = {
138		.subtype = IFM_25G_KR,
139		.baudrate = IF_Gbps(25ULL),
140	},
141	[MLX5E_25GBASE_SR] = {
142		.subtype = IFM_25G_SR,
143		.baudrate = IF_Gbps(25ULL),
144	},
145	[MLX5E_50GBASE_CR2] = {
146		.subtype = IFM_50G_CR2,
147		.baudrate = IF_Gbps(50ULL),
148	},
149	[MLX5E_50GBASE_KR2] = {
150		.subtype = IFM_50G_KR2,
151		.baudrate = IF_Gbps(50ULL),
152	},
153};
154
155MALLOC_DEFINE(M_MLX5EN, "MLX5EN", "MLX5 Ethernet");
156
157static void
158mlx5e_update_carrier(struct mlx5e_priv *priv)
159{
160	struct mlx5_core_dev *mdev = priv->mdev;
161	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
162	u32 eth_proto_oper;
163	int error;
164	u8 port_state;
165	u8 i;
166
167	port_state = mlx5_query_vport_state(mdev,
168	    MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT, 0);
169
170	if (port_state == VPORT_STATE_UP) {
171		priv->media_status_last |= IFM_ACTIVE;
172	} else {
173		priv->media_status_last &= ~IFM_ACTIVE;
174		priv->media_active_last = IFM_ETHER;
175		if_link_state_change(priv->ifp, LINK_STATE_DOWN);
176		return;
177	}
178
179	error = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN, 1);
180	if (error) {
181		priv->media_active_last = IFM_ETHER;
182		priv->ifp->if_baudrate = 1;
183		if_printf(priv->ifp, "%s: query port ptys failed: 0x%x\n",
184		    __func__, error);
185		return;
186	}
187	eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
188
189	for (i = 0; i != MLX5E_LINK_MODES_NUMBER; i++) {
190		if (mlx5e_mode_table[i].baudrate == 0)
191			continue;
192		if (MLX5E_PROT_MASK(i) & eth_proto_oper) {
193			priv->ifp->if_baudrate =
194			    mlx5e_mode_table[i].baudrate;
195			priv->media_active_last =
196			    mlx5e_mode_table[i].subtype | IFM_ETHER | IFM_FDX;
197		}
198	}
199	if_link_state_change(priv->ifp, LINK_STATE_UP);
200}
201
202static void
203mlx5e_media_status(struct ifnet *dev, struct ifmediareq *ifmr)
204{
205	struct mlx5e_priv *priv = dev->if_softc;
206
207	ifmr->ifm_status = priv->media_status_last;
208	ifmr->ifm_active = priv->media_active_last |
209	    (priv->params.rx_pauseframe_control ? IFM_ETH_RXPAUSE : 0) |
210	    (priv->params.tx_pauseframe_control ? IFM_ETH_TXPAUSE : 0);
211
212}
213
214static u32
215mlx5e_find_link_mode(u32 subtype)
216{
217	u32 i;
218	u32 link_mode = 0;
219
220	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
221		if (mlx5e_mode_table[i].baudrate == 0)
222			continue;
223		if (mlx5e_mode_table[i].subtype == subtype)
224			link_mode |= MLX5E_PROT_MASK(i);
225	}
226
227	return (link_mode);
228}
229
230static int
231mlx5e_set_port_pause_and_pfc(struct mlx5e_priv *priv)
232{
233	return (mlx5_set_port_pause_and_pfc(priv->mdev, 1,
234	    priv->params.rx_pauseframe_control,
235	    priv->params.tx_pauseframe_control,
236	    priv->params.rx_priority_flow_control,
237	    priv->params.tx_priority_flow_control));
238}
239
240static int
241mlx5e_set_port_pfc(struct mlx5e_priv *priv)
242{
243	int error;
244
245	if (priv->params.rx_pauseframe_control ||
246	    priv->params.tx_pauseframe_control) {
247		if_printf(priv->ifp,
248		    "Global pauseframes must be disabled before enabling PFC.\n");
249		error = -EINVAL;
250	} else {
251		error = mlx5e_set_port_pause_and_pfc(priv);
252	}
253	return (error);
254}
255
256static int
257mlx5e_media_change(struct ifnet *dev)
258{
259	struct mlx5e_priv *priv = dev->if_softc;
260	struct mlx5_core_dev *mdev = priv->mdev;
261	u32 eth_proto_cap;
262	u32 link_mode;
263	int was_opened;
264	int locked;
265	int error;
266
267	locked = PRIV_LOCKED(priv);
268	if (!locked)
269		PRIV_LOCK(priv);
270
271	if (IFM_TYPE(priv->media.ifm_media) != IFM_ETHER) {
272		error = EINVAL;
273		goto done;
274	}
275	link_mode = mlx5e_find_link_mode(IFM_SUBTYPE(priv->media.ifm_media));
276
277	/* query supported capabilities */
278	error = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
279	if (error != 0) {
280		if_printf(dev, "Query port media capability failed\n");
281		goto done;
282	}
283	/* check for autoselect */
284	if (IFM_SUBTYPE(priv->media.ifm_media) == IFM_AUTO) {
285		link_mode = eth_proto_cap;
286		if (link_mode == 0) {
287			if_printf(dev, "Port media capability is zero\n");
288			error = EINVAL;
289			goto done;
290		}
291	} else {
292		link_mode = link_mode & eth_proto_cap;
293		if (link_mode == 0) {
294			if_printf(dev, "Not supported link mode requested\n");
295			error = EINVAL;
296			goto done;
297		}
298	}
299	if (priv->media.ifm_media & (IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE)) {
300		/* check if PFC is enabled */
301		if (priv->params.rx_priority_flow_control ||
302		    priv->params.tx_priority_flow_control) {
303			if_printf(dev, "PFC must be disabled before enabling global pauseframes.\n");
304			error = EINVAL;
305			goto done;
306		}
307	}
308	/* update pauseframe control bits */
309	priv->params.rx_pauseframe_control =
310	    (priv->media.ifm_media & IFM_ETH_RXPAUSE) ? 1 : 0;
311	priv->params.tx_pauseframe_control =
312	    (priv->media.ifm_media & IFM_ETH_TXPAUSE) ? 1 : 0;
313
314	/* check if device is opened */
315	was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
316
317	/* reconfigure the hardware */
318	mlx5_set_port_status(mdev, MLX5_PORT_DOWN);
319	mlx5_set_port_proto(mdev, link_mode, MLX5_PTYS_EN);
320	error = -mlx5e_set_port_pause_and_pfc(priv);
321	if (was_opened)
322		mlx5_set_port_status(mdev, MLX5_PORT_UP);
323
324done:
325	if (!locked)
326		PRIV_UNLOCK(priv);
327	return (error);
328}
329
330static void
331mlx5e_update_carrier_work(struct work_struct *work)
332{
333	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
334	    update_carrier_work);
335
336	PRIV_LOCK(priv);
337	if (test_bit(MLX5E_STATE_OPENED, &priv->state))
338		mlx5e_update_carrier(priv);
339	PRIV_UNLOCK(priv);
340}
341
342/*
343 * This function reads the physical port counters from the firmware
344 * using a pre-defined layout defined by various MLX5E_PPORT_XXX()
345 * macros. The output is converted from big-endian 64-bit values into
346 * host endian ones and stored in the "priv->stats.pport" structure.
347 */
348static void
349mlx5e_update_pport_counters(struct mlx5e_priv *priv)
350{
351	struct mlx5_core_dev *mdev = priv->mdev;
352	struct mlx5e_pport_stats *s = &priv->stats.pport;
353	struct mlx5e_port_stats_debug *s_debug = &priv->stats.port_stats_debug;
354	u32 *in;
355	u32 *out;
356	const u64 *ptr;
357	unsigned sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
358	unsigned x;
359	unsigned y;
360	unsigned z;
361
362	/* allocate firmware request structures */
363	in = mlx5_vzalloc(sz);
364	out = mlx5_vzalloc(sz);
365	if (in == NULL || out == NULL)
366		goto free_out;
367
368	/*
369	 * Get pointer to the 64-bit counter set which is located at a
370	 * fixed offset in the output firmware request structure:
371	 */
372	ptr = (const uint64_t *)MLX5_ADDR_OF(ppcnt_reg, out, counter_set);
373
374	MLX5_SET(ppcnt_reg, in, local_port, 1);
375
376	/* read IEEE802_3 counter group using predefined counter layout */
377	MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP);
378	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
379	for (x = 0, y = MLX5E_PPORT_PER_PRIO_STATS_NUM;
380	     x != MLX5E_PPORT_IEEE802_3_STATS_NUM; x++, y++)
381		s->arg[y] = be64toh(ptr[x]);
382
383	/* read RFC2819 counter group using predefined counter layout */
384	MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP);
385	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
386	for (x = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM; x++, y++)
387		s->arg[y] = be64toh(ptr[x]);
388	for (y = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM +
389	    MLX5E_PPORT_RFC2819_STATS_DEBUG_NUM; x++, y++)
390		s_debug->arg[y] = be64toh(ptr[x]);
391
392	/* read RFC2863 counter group using predefined counter layout */
393	MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP);
394	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
395	for (x = 0; x != MLX5E_PPORT_RFC2863_STATS_DEBUG_NUM; x++, y++)
396		s_debug->arg[y] = be64toh(ptr[x]);
397
398	/* read physical layer stats counter group using predefined counter layout */
399	MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_COUNTERS_GROUP);
400	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
401	for (x = 0; x != MLX5E_PPORT_PHYSICAL_LAYER_STATS_DEBUG_NUM; x++, y++)
402		s_debug->arg[y] = be64toh(ptr[x]);
403
404	/* read per-priority counters */
405	MLX5_SET(ppcnt_reg, in, grp, MLX5_PER_PRIORITY_COUNTERS_GROUP);
406
407	/* iterate all the priorities */
408	for (y = z = 0; z != MLX5E_PPORT_PER_PRIO_STATS_NUM_PRIO; z++) {
409		MLX5_SET(ppcnt_reg, in, prio_tc, z);
410		mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
411
412		/* read per priority stats counter group using predefined counter layout */
413		for (x = 0; x != (MLX5E_PPORT_PER_PRIO_STATS_NUM /
414		    MLX5E_PPORT_PER_PRIO_STATS_NUM_PRIO); x++, y++)
415			s->arg[y] = be64toh(ptr[x]);
416	}
417free_out:
418	/* free firmware request structures */
419	kvfree(in);
420	kvfree(out);
421}
422
423/*
424 * This function is called regularly to collect all statistics
425 * counters from the firmware. The values can be viewed through the
426 * sysctl interface. Execution is serialized using the priv's global
427 * configuration lock.
428 */
429static void
430mlx5e_update_stats_work(struct work_struct *work)
431{
432	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
433	    update_stats_work);
434	struct mlx5_core_dev *mdev = priv->mdev;
435	struct mlx5e_vport_stats *s = &priv->stats.vport;
436	struct mlx5e_rq_stats *rq_stats;
437	struct mlx5e_sq_stats *sq_stats;
438	struct buf_ring *sq_br;
439#if (__FreeBSD_version < 1100000)
440	struct ifnet *ifp = priv->ifp;
441#endif
442
443	u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)];
444	u32 *out;
445	int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
446	u64 tso_packets = 0;
447	u64 tso_bytes = 0;
448	u64 tx_queue_dropped = 0;
449	u64 tx_defragged = 0;
450	u64 tx_offload_none = 0;
451	u64 lro_packets = 0;
452	u64 lro_bytes = 0;
453	u64 sw_lro_queued = 0;
454	u64 sw_lro_flushed = 0;
455	u64 rx_csum_none = 0;
456	u64 rx_wqe_err = 0;
457	u32 rx_out_of_buffer = 0;
458	int i;
459	int j;
460
461	PRIV_LOCK(priv);
462	out = mlx5_vzalloc(outlen);
463	if (out == NULL)
464		goto free_out;
465	if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
466		goto free_out;
467
468	/* Collect firts the SW counters and then HW for consistency */
469	for (i = 0; i < priv->params.num_channels; i++) {
470		struct mlx5e_rq *rq = &priv->channel[i]->rq;
471
472		rq_stats = &priv->channel[i]->rq.stats;
473
474		/* collect stats from LRO */
475		rq_stats->sw_lro_queued = rq->lro.lro_queued;
476		rq_stats->sw_lro_flushed = rq->lro.lro_flushed;
477		sw_lro_queued += rq_stats->sw_lro_queued;
478		sw_lro_flushed += rq_stats->sw_lro_flushed;
479		lro_packets += rq_stats->lro_packets;
480		lro_bytes += rq_stats->lro_bytes;
481		rx_csum_none += rq_stats->csum_none;
482		rx_wqe_err += rq_stats->wqe_err;
483
484		for (j = 0; j < priv->num_tc; j++) {
485			sq_stats = &priv->channel[i]->sq[j].stats;
486			sq_br = priv->channel[i]->sq[j].br;
487
488			tso_packets += sq_stats->tso_packets;
489			tso_bytes += sq_stats->tso_bytes;
490			tx_queue_dropped += sq_stats->dropped;
491			if (sq_br != NULL)
492				tx_queue_dropped += sq_br->br_drops;
493			tx_defragged += sq_stats->defragged;
494			tx_offload_none += sq_stats->csum_offload_none;
495		}
496	}
497
498	/* update counters */
499	s->tso_packets = tso_packets;
500	s->tso_bytes = tso_bytes;
501	s->tx_queue_dropped = tx_queue_dropped;
502	s->tx_defragged = tx_defragged;
503	s->lro_packets = lro_packets;
504	s->lro_bytes = lro_bytes;
505	s->sw_lro_queued = sw_lro_queued;
506	s->sw_lro_flushed = sw_lro_flushed;
507	s->rx_csum_none = rx_csum_none;
508	s->rx_wqe_err = rx_wqe_err;
509
510	/* HW counters */
511	memset(in, 0, sizeof(in));
512
513	MLX5_SET(query_vport_counter_in, in, opcode,
514	    MLX5_CMD_OP_QUERY_VPORT_COUNTER);
515	MLX5_SET(query_vport_counter_in, in, op_mod, 0);
516	MLX5_SET(query_vport_counter_in, in, other_vport, 0);
517
518	memset(out, 0, outlen);
519
520	/* get number of out-of-buffer drops first */
521	if (mlx5_vport_query_out_of_rx_buffer(mdev, priv->counter_set_id,
522	    &rx_out_of_buffer))
523		goto free_out;
524
525	/* accumulate difference into a 64-bit counter */
526	s->rx_out_of_buffer += (u64)(u32)(rx_out_of_buffer - s->rx_out_of_buffer_prev);
527	s->rx_out_of_buffer_prev = rx_out_of_buffer;
528
529	/* get port statistics */
530	if (mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen))
531		goto free_out;
532
533#define	MLX5_GET_CTR(out, x) \
534	MLX5_GET64(query_vport_counter_out, out, x)
535
536	s->rx_error_packets =
537	    MLX5_GET_CTR(out, received_errors.packets);
538	s->rx_error_bytes =
539	    MLX5_GET_CTR(out, received_errors.octets);
540	s->tx_error_packets =
541	    MLX5_GET_CTR(out, transmit_errors.packets);
542	s->tx_error_bytes =
543	    MLX5_GET_CTR(out, transmit_errors.octets);
544
545	s->rx_unicast_packets =
546	    MLX5_GET_CTR(out, received_eth_unicast.packets);
547	s->rx_unicast_bytes =
548	    MLX5_GET_CTR(out, received_eth_unicast.octets);
549	s->tx_unicast_packets =
550	    MLX5_GET_CTR(out, transmitted_eth_unicast.packets);
551	s->tx_unicast_bytes =
552	    MLX5_GET_CTR(out, transmitted_eth_unicast.octets);
553
554	s->rx_multicast_packets =
555	    MLX5_GET_CTR(out, received_eth_multicast.packets);
556	s->rx_multicast_bytes =
557	    MLX5_GET_CTR(out, received_eth_multicast.octets);
558	s->tx_multicast_packets =
559	    MLX5_GET_CTR(out, transmitted_eth_multicast.packets);
560	s->tx_multicast_bytes =
561	    MLX5_GET_CTR(out, transmitted_eth_multicast.octets);
562
563	s->rx_broadcast_packets =
564	    MLX5_GET_CTR(out, received_eth_broadcast.packets);
565	s->rx_broadcast_bytes =
566	    MLX5_GET_CTR(out, received_eth_broadcast.octets);
567	s->tx_broadcast_packets =
568	    MLX5_GET_CTR(out, transmitted_eth_broadcast.packets);
569	s->tx_broadcast_bytes =
570	    MLX5_GET_CTR(out, transmitted_eth_broadcast.octets);
571
572	s->rx_packets =
573	    s->rx_unicast_packets +
574	    s->rx_multicast_packets +
575	    s->rx_broadcast_packets -
576	    s->rx_out_of_buffer;
577	s->rx_bytes =
578	    s->rx_unicast_bytes +
579	    s->rx_multicast_bytes +
580	    s->rx_broadcast_bytes;
581	s->tx_packets =
582	    s->tx_unicast_packets +
583	    s->tx_multicast_packets +
584	    s->tx_broadcast_packets;
585	s->tx_bytes =
586	    s->tx_unicast_bytes +
587	    s->tx_multicast_bytes +
588	    s->tx_broadcast_bytes;
589
590	/* Update calculated offload counters */
591	s->tx_csum_offload = s->tx_packets - tx_offload_none;
592	s->rx_csum_good = s->rx_packets - s->rx_csum_none;
593
594	/* Get physical port counters */
595	mlx5e_update_pport_counters(priv);
596
597#if (__FreeBSD_version < 1100000)
598	/* no get_counters interface in fbsd 10 */
599	ifp->if_ipackets = s->rx_packets;
600	ifp->if_ierrors = s->rx_error_packets +
601	    priv->stats.pport.alignment_err +
602	    priv->stats.pport.check_seq_err +
603	    priv->stats.pport.crc_align_errors +
604	    priv->stats.pport.in_range_len_errors +
605	    priv->stats.pport.jabbers +
606	    priv->stats.pport.out_of_range_len +
607	    priv->stats.pport.oversize_pkts +
608	    priv->stats.pport.symbol_err +
609	    priv->stats.pport.too_long_errors +
610	    priv->stats.pport.undersize_pkts +
611	    priv->stats.pport.unsupported_op_rx;
612	ifp->if_iqdrops = s->rx_out_of_buffer +
613	    priv->stats.pport.drop_events;
614	ifp->if_opackets = s->tx_packets;
615	ifp->if_oerrors = s->tx_error_packets;
616	ifp->if_snd.ifq_drops = s->tx_queue_dropped;
617	ifp->if_ibytes = s->rx_bytes;
618	ifp->if_obytes = s->tx_bytes;
619	ifp->if_collisions =
620	    priv->stats.pport.collisions;
621#endif
622
623free_out:
624	kvfree(out);
625
626	/* Update diagnostics, if any */
627	if (priv->params_ethtool.diag_pci_enable ||
628	    priv->params_ethtool.diag_general_enable) {
629		int error = mlx5_core_get_diagnostics_full(mdev,
630		    priv->params_ethtool.diag_pci_enable ? &priv->params_pci : NULL,
631		    priv->params_ethtool.diag_general_enable ? &priv->params_general : NULL);
632		if (error != 0)
633			if_printf(priv->ifp, "Failed reading diagnostics: %d\n", error);
634	}
635	PRIV_UNLOCK(priv);
636}
637
638static void
639mlx5e_update_stats(void *arg)
640{
641	struct mlx5e_priv *priv = arg;
642
643	schedule_work(&priv->update_stats_work);
644
645	callout_reset(&priv->watchdog, hz, &mlx5e_update_stats, priv);
646}
647
648static void
649mlx5e_async_event_sub(struct mlx5e_priv *priv,
650    enum mlx5_dev_event event)
651{
652	switch (event) {
653	case MLX5_DEV_EVENT_PORT_UP:
654	case MLX5_DEV_EVENT_PORT_DOWN:
655		schedule_work(&priv->update_carrier_work);
656		break;
657
658	default:
659		break;
660	}
661}
662
663static void
664mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv,
665    enum mlx5_dev_event event, unsigned long param)
666{
667	struct mlx5e_priv *priv = vpriv;
668
669	mtx_lock(&priv->async_events_mtx);
670	if (test_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state))
671		mlx5e_async_event_sub(priv, event);
672	mtx_unlock(&priv->async_events_mtx);
673}
674
675static void
676mlx5e_enable_async_events(struct mlx5e_priv *priv)
677{
678	set_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state);
679}
680
681static void
682mlx5e_disable_async_events(struct mlx5e_priv *priv)
683{
684	mtx_lock(&priv->async_events_mtx);
685	clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state);
686	mtx_unlock(&priv->async_events_mtx);
687}
688
689static const char *mlx5e_rq_stats_desc[] = {
690	MLX5E_RQ_STATS(MLX5E_STATS_DESC)
691};
692
693static int
694mlx5e_create_rq(struct mlx5e_channel *c,
695    struct mlx5e_rq_param *param,
696    struct mlx5e_rq *rq)
697{
698	struct mlx5e_priv *priv = c->priv;
699	struct mlx5_core_dev *mdev = priv->mdev;
700	char buffer[16];
701	void *rqc = param->rqc;
702	void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
703	int wq_sz;
704	int err;
705	int i;
706
707	/* Create DMA descriptor TAG */
708	if ((err = -bus_dma_tag_create(
709	    bus_get_dma_tag(mdev->pdev->dev.bsddev),
710	    1,				/* any alignment */
711	    0,				/* no boundary */
712	    BUS_SPACE_MAXADDR,		/* lowaddr */
713	    BUS_SPACE_MAXADDR,		/* highaddr */
714	    NULL, NULL,			/* filter, filterarg */
715	    MJUM16BYTES,		/* maxsize */
716	    1,				/* nsegments */
717	    MJUM16BYTES,		/* maxsegsize */
718	    0,				/* flags */
719	    NULL, NULL,			/* lockfunc, lockfuncarg */
720	    &rq->dma_tag)))
721		goto done;
722
723	err = mlx5_wq_ll_create(mdev, &param->wq, rqc_wq, &rq->wq,
724	    &rq->wq_ctrl);
725	if (err)
726		goto err_free_dma_tag;
727
728	rq->wq.db = &rq->wq.db[MLX5_RCV_DBR];
729
730	if (priv->params.hw_lro_en) {
731		rq->wqe_sz = priv->params.lro_wqe_sz;
732	} else {
733		rq->wqe_sz = MLX5E_SW2MB_MTU(priv->ifp->if_mtu);
734	}
735	if (rq->wqe_sz > MJUM16BYTES) {
736		err = -ENOMEM;
737		goto err_rq_wq_destroy;
738	} else if (rq->wqe_sz > MJUM9BYTES) {
739		rq->wqe_sz = MJUM16BYTES;
740	} else if (rq->wqe_sz > MJUMPAGESIZE) {
741		rq->wqe_sz = MJUM9BYTES;
742	} else if (rq->wqe_sz > MCLBYTES) {
743		rq->wqe_sz = MJUMPAGESIZE;
744	} else {
745		rq->wqe_sz = MCLBYTES;
746	}
747
748	wq_sz = mlx5_wq_ll_get_size(&rq->wq);
749
750	err = -tcp_lro_init_args(&rq->lro, c->ifp, TCP_LRO_ENTRIES, wq_sz);
751	if (err)
752		goto err_rq_wq_destroy;
753
754	rq->mbuf = malloc(wq_sz * sizeof(rq->mbuf[0]), M_MLX5EN, M_WAITOK | M_ZERO);
755	for (i = 0; i != wq_sz; i++) {
756		struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, i);
757		uint32_t byte_count = rq->wqe_sz - MLX5E_NET_IP_ALIGN;
758
759		err = -bus_dmamap_create(rq->dma_tag, 0, &rq->mbuf[i].dma_map);
760		if (err != 0) {
761			while (i--)
762				bus_dmamap_destroy(rq->dma_tag, rq->mbuf[i].dma_map);
763			goto err_rq_mbuf_free;
764		}
765		wqe->data.lkey = c->mkey_be;
766		wqe->data.byte_count = cpu_to_be32(byte_count | MLX5_HW_START_PADDING);
767	}
768
769	rq->ifp = c->ifp;
770	rq->channel = c;
771	rq->ix = c->ix;
772
773	snprintf(buffer, sizeof(buffer), "rxstat%d", c->ix);
774	mlx5e_create_stats(&rq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
775	    buffer, mlx5e_rq_stats_desc, MLX5E_RQ_STATS_NUM,
776	    rq->stats.arg);
777	return (0);
778
779err_rq_mbuf_free:
780	free(rq->mbuf, M_MLX5EN);
781	tcp_lro_free(&rq->lro);
782err_rq_wq_destroy:
783	mlx5_wq_destroy(&rq->wq_ctrl);
784err_free_dma_tag:
785	bus_dma_tag_destroy(rq->dma_tag);
786done:
787	return (err);
788}
789
790static void
791mlx5e_destroy_rq(struct mlx5e_rq *rq)
792{
793	int wq_sz;
794	int i;
795
796	/* destroy all sysctl nodes */
797	sysctl_ctx_free(&rq->stats.ctx);
798
799	/* free leftover LRO packets, if any */
800	tcp_lro_free(&rq->lro);
801
802	wq_sz = mlx5_wq_ll_get_size(&rq->wq);
803	for (i = 0; i != wq_sz; i++) {
804		if (rq->mbuf[i].mbuf != NULL) {
805			bus_dmamap_unload(rq->dma_tag,
806			    rq->mbuf[i].dma_map);
807			m_freem(rq->mbuf[i].mbuf);
808		}
809		bus_dmamap_destroy(rq->dma_tag, rq->mbuf[i].dma_map);
810	}
811	free(rq->mbuf, M_MLX5EN);
812	mlx5_wq_destroy(&rq->wq_ctrl);
813}
814
815static int
816mlx5e_enable_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param)
817{
818	struct mlx5e_channel *c = rq->channel;
819	struct mlx5e_priv *priv = c->priv;
820	struct mlx5_core_dev *mdev = priv->mdev;
821
822	void *in;
823	void *rqc;
824	void *wq;
825	int inlen;
826	int err;
827
828	inlen = MLX5_ST_SZ_BYTES(create_rq_in) +
829	    sizeof(u64) * rq->wq_ctrl.buf.npages;
830	in = mlx5_vzalloc(inlen);
831	if (in == NULL)
832		return (-ENOMEM);
833
834	rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
835	wq = MLX5_ADDR_OF(rqc, rqc, wq);
836
837	memcpy(rqc, param->rqc, sizeof(param->rqc));
838
839	MLX5_SET(rqc, rqc, cqn, c->rq.cq.mcq.cqn);
840	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);
841	MLX5_SET(rqc, rqc, flush_in_error_en, 1);
842	if (priv->counter_set_id >= 0)
843		MLX5_SET(rqc, rqc, counter_set_id, priv->counter_set_id);
844	MLX5_SET(wq, wq, log_wq_pg_sz, rq->wq_ctrl.buf.page_shift -
845	    PAGE_SHIFT);
846	MLX5_SET64(wq, wq, dbr_addr, rq->wq_ctrl.db.dma);
847
848	mlx5_fill_page_array(&rq->wq_ctrl.buf,
849	    (__be64 *) MLX5_ADDR_OF(wq, wq, pas));
850
851	err = mlx5_core_create_rq(mdev, in, inlen, &rq->rqn);
852
853	kvfree(in);
854
855	return (err);
856}
857
858static int
859mlx5e_modify_rq(struct mlx5e_rq *rq, int curr_state, int next_state)
860{
861	struct mlx5e_channel *c = rq->channel;
862	struct mlx5e_priv *priv = c->priv;
863	struct mlx5_core_dev *mdev = priv->mdev;
864
865	void *in;
866	void *rqc;
867	int inlen;
868	int err;
869
870	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
871	in = mlx5_vzalloc(inlen);
872	if (in == NULL)
873		return (-ENOMEM);
874
875	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
876
877	MLX5_SET(modify_rq_in, in, rqn, rq->rqn);
878	MLX5_SET(modify_rq_in, in, rq_state, curr_state);
879	MLX5_SET(rqc, rqc, state, next_state);
880
881	err = mlx5_core_modify_rq(mdev, in, inlen);
882
883	kvfree(in);
884
885	return (err);
886}
887
888static void
889mlx5e_disable_rq(struct mlx5e_rq *rq)
890{
891	struct mlx5e_channel *c = rq->channel;
892	struct mlx5e_priv *priv = c->priv;
893	struct mlx5_core_dev *mdev = priv->mdev;
894
895	mlx5_core_destroy_rq(mdev, rq->rqn);
896}
897
898static int
899mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq)
900{
901	struct mlx5e_channel *c = rq->channel;
902	struct mlx5e_priv *priv = c->priv;
903	struct mlx5_wq_ll *wq = &rq->wq;
904	int i;
905
906	for (i = 0; i < 1000; i++) {
907		if (wq->cur_sz >= priv->params.min_rx_wqes)
908			return (0);
909
910		msleep(4);
911	}
912	return (-ETIMEDOUT);
913}
914
915static int
916mlx5e_open_rq(struct mlx5e_channel *c,
917    struct mlx5e_rq_param *param,
918    struct mlx5e_rq *rq)
919{
920	int err;
921
922	err = mlx5e_create_rq(c, param, rq);
923	if (err)
924		return (err);
925
926	err = mlx5e_enable_rq(rq, param);
927	if (err)
928		goto err_destroy_rq;
929
930	err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
931	if (err)
932		goto err_disable_rq;
933
934	c->rq.enabled = 1;
935
936	return (0);
937
938err_disable_rq:
939	mlx5e_disable_rq(rq);
940err_destroy_rq:
941	mlx5e_destroy_rq(rq);
942
943	return (err);
944}
945
946static void
947mlx5e_close_rq(struct mlx5e_rq *rq)
948{
949	mtx_lock(&rq->mtx);
950	rq->enabled = 0;
951	callout_stop(&rq->watchdog);
952	mtx_unlock(&rq->mtx);
953
954	callout_drain(&rq->watchdog);
955
956	mlx5e_modify_rq(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR);
957}
958
959static void
960mlx5e_close_rq_wait(struct mlx5e_rq *rq)
961{
962	/* wait till RQ is empty */
963	while (!mlx5_wq_ll_is_empty(&rq->wq)) {
964		msleep(4);
965		rq->cq.mcq.comp(&rq->cq.mcq);
966	}
967
968	mlx5e_disable_rq(rq);
969	mlx5e_destroy_rq(rq);
970}
971
972void
973mlx5e_free_sq_db(struct mlx5e_sq *sq)
974{
975	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
976	int x;
977
978	for (x = 0; x != wq_sz; x++)
979		bus_dmamap_destroy(sq->dma_tag, sq->mbuf[x].dma_map);
980	free(sq->mbuf, M_MLX5EN);
981}
982
983int
984mlx5e_alloc_sq_db(struct mlx5e_sq *sq)
985{
986	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
987	int err;
988	int x;
989
990	sq->mbuf = malloc(wq_sz * sizeof(sq->mbuf[0]), M_MLX5EN, M_WAITOK | M_ZERO);
991
992	/* Create DMA descriptor MAPs */
993	for (x = 0; x != wq_sz; x++) {
994		err = -bus_dmamap_create(sq->dma_tag, 0, &sq->mbuf[x].dma_map);
995		if (err != 0) {
996			while (x--)
997				bus_dmamap_destroy(sq->dma_tag, sq->mbuf[x].dma_map);
998			free(sq->mbuf, M_MLX5EN);
999			return (err);
1000		}
1001	}
1002	return (0);
1003}
1004
1005static const char *mlx5e_sq_stats_desc[] = {
1006	MLX5E_SQ_STATS(MLX5E_STATS_DESC)
1007};
1008
1009static int
1010mlx5e_create_sq(struct mlx5e_channel *c,
1011    int tc,
1012    struct mlx5e_sq_param *param,
1013    struct mlx5e_sq *sq)
1014{
1015	struct mlx5e_priv *priv = c->priv;
1016	struct mlx5_core_dev *mdev = priv->mdev;
1017	char buffer[16];
1018
1019	void *sqc = param->sqc;
1020	void *sqc_wq = MLX5_ADDR_OF(sqc, sqc, wq);
1021#ifdef RSS
1022	cpuset_t cpu_mask;
1023	int cpu_id;
1024#endif
1025	int err;
1026
1027	/* Create DMA descriptor TAG */
1028	if ((err = -bus_dma_tag_create(
1029	    bus_get_dma_tag(mdev->pdev->dev.bsddev),
1030	    1,				/* any alignment */
1031	    0,				/* no boundary */
1032	    BUS_SPACE_MAXADDR,		/* lowaddr */
1033	    BUS_SPACE_MAXADDR,		/* highaddr */
1034	    NULL, NULL,			/* filter, filterarg */
1035	    MLX5E_MAX_TX_PAYLOAD_SIZE,	/* maxsize */
1036	    MLX5E_MAX_TX_MBUF_FRAGS,	/* nsegments */
1037	    MLX5E_MAX_TX_MBUF_SIZE,	/* maxsegsize */
1038	    0,				/* flags */
1039	    NULL, NULL,			/* lockfunc, lockfuncarg */
1040	    &sq->dma_tag)))
1041		goto done;
1042
1043	err = mlx5_alloc_map_uar(mdev, &sq->uar);
1044	if (err)
1045		goto err_free_dma_tag;
1046
1047	err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq,
1048	    &sq->wq_ctrl);
1049	if (err)
1050		goto err_unmap_free_uar;
1051
1052	sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
1053	sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
1054
1055	err = mlx5e_alloc_sq_db(sq);
1056	if (err)
1057		goto err_sq_wq_destroy;
1058
1059	sq->mkey_be = c->mkey_be;
1060	sq->ifp = priv->ifp;
1061	sq->priv = priv;
1062	sq->tc = tc;
1063
1064	/* check if we should allocate a second packet buffer */
1065	if (priv->params_ethtool.tx_bufring_disable == 0) {
1066		sq->br = buf_ring_alloc(MLX5E_SQ_TX_QUEUE_SIZE, M_MLX5EN,
1067		    M_WAITOK, &sq->lock);
1068		if (sq->br == NULL) {
1069			if_printf(c->ifp, "%s: Failed allocating sq drbr buffer\n",
1070			    __func__);
1071			err = -ENOMEM;
1072			goto err_free_sq_db;
1073		}
1074
1075		sq->sq_tq = taskqueue_create_fast("mlx5e_que", M_WAITOK,
1076		    taskqueue_thread_enqueue, &sq->sq_tq);
1077		if (sq->sq_tq == NULL) {
1078			if_printf(c->ifp, "%s: Failed allocating taskqueue\n",
1079			    __func__);
1080			err = -ENOMEM;
1081			goto err_free_drbr;
1082		}
1083
1084		TASK_INIT(&sq->sq_task, 0, mlx5e_tx_que, sq);
1085#ifdef RSS
1086		cpu_id = rss_getcpu(c->ix % rss_getnumbuckets());
1087		CPU_SETOF(cpu_id, &cpu_mask);
1088		taskqueue_start_threads_cpuset(&sq->sq_tq, 1, PI_NET, &cpu_mask,
1089		    "%s TX SQ%d.%d CPU%d", c->ifp->if_xname, c->ix, tc, cpu_id);
1090#else
1091		taskqueue_start_threads(&sq->sq_tq, 1, PI_NET,
1092		    "%s TX SQ%d.%d", c->ifp->if_xname, c->ix, tc);
1093#endif
1094	}
1095	snprintf(buffer, sizeof(buffer), "txstat%dtc%d", c->ix, tc);
1096	mlx5e_create_stats(&sq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
1097	    buffer, mlx5e_sq_stats_desc, MLX5E_SQ_STATS_NUM,
1098	    sq->stats.arg);
1099
1100	return (0);
1101
1102err_free_drbr:
1103	buf_ring_free(sq->br, M_MLX5EN);
1104err_free_sq_db:
1105	mlx5e_free_sq_db(sq);
1106err_sq_wq_destroy:
1107	mlx5_wq_destroy(&sq->wq_ctrl);
1108
1109err_unmap_free_uar:
1110	mlx5_unmap_free_uar(mdev, &sq->uar);
1111
1112err_free_dma_tag:
1113	bus_dma_tag_destroy(sq->dma_tag);
1114done:
1115	return (err);
1116}
1117
1118static void
1119mlx5e_destroy_sq(struct mlx5e_sq *sq)
1120{
1121	/* destroy all sysctl nodes */
1122	sysctl_ctx_free(&sq->stats.ctx);
1123
1124	mlx5e_free_sq_db(sq);
1125	mlx5_wq_destroy(&sq->wq_ctrl);
1126	mlx5_unmap_free_uar(sq->priv->mdev, &sq->uar);
1127	if (sq->sq_tq != NULL) {
1128		taskqueue_drain(sq->sq_tq, &sq->sq_task);
1129		taskqueue_free(sq->sq_tq);
1130	}
1131	if (sq->br != NULL)
1132		buf_ring_free(sq->br, M_MLX5EN);
1133}
1134
1135int
1136mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param,
1137    int tis_num)
1138{
1139	void *in;
1140	void *sqc;
1141	void *wq;
1142	int inlen;
1143	int err;
1144
1145	inlen = MLX5_ST_SZ_BYTES(create_sq_in) +
1146	    sizeof(u64) * sq->wq_ctrl.buf.npages;
1147	in = mlx5_vzalloc(inlen);
1148	if (in == NULL)
1149		return (-ENOMEM);
1150
1151	sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
1152	wq = MLX5_ADDR_OF(sqc, sqc, wq);
1153
1154	memcpy(sqc, param->sqc, sizeof(param->sqc));
1155
1156	MLX5_SET(sqc, sqc, tis_num_0, tis_num);
1157	MLX5_SET(sqc, sqc, cqn, sq->cq.mcq.cqn);
1158	MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
1159	MLX5_SET(sqc, sqc, tis_lst_sz, 1);
1160	MLX5_SET(sqc, sqc, flush_in_error_en, 1);
1161
1162	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
1163	MLX5_SET(wq, wq, uar_page, sq->uar.index);
1164	MLX5_SET(wq, wq, log_wq_pg_sz, sq->wq_ctrl.buf.page_shift -
1165	    PAGE_SHIFT);
1166	MLX5_SET64(wq, wq, dbr_addr, sq->wq_ctrl.db.dma);
1167
1168	mlx5_fill_page_array(&sq->wq_ctrl.buf,
1169	    (__be64 *) MLX5_ADDR_OF(wq, wq, pas));
1170
1171	err = mlx5_core_create_sq(sq->priv->mdev, in, inlen, &sq->sqn);
1172
1173	kvfree(in);
1174
1175	return (err);
1176}
1177
1178int
1179mlx5e_modify_sq(struct mlx5e_sq *sq, int curr_state, int next_state)
1180{
1181	void *in;
1182	void *sqc;
1183	int inlen;
1184	int err;
1185
1186	inlen = MLX5_ST_SZ_BYTES(modify_sq_in);
1187	in = mlx5_vzalloc(inlen);
1188	if (in == NULL)
1189		return (-ENOMEM);
1190
1191	sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
1192
1193	MLX5_SET(modify_sq_in, in, sqn, sq->sqn);
1194	MLX5_SET(modify_sq_in, in, sq_state, curr_state);
1195	MLX5_SET(sqc, sqc, state, next_state);
1196
1197	err = mlx5_core_modify_sq(sq->priv->mdev, in, inlen);
1198
1199	kvfree(in);
1200
1201	return (err);
1202}
1203
1204void
1205mlx5e_disable_sq(struct mlx5e_sq *sq)
1206{
1207
1208	mlx5_core_destroy_sq(sq->priv->mdev, sq->sqn);
1209}
1210
1211static int
1212mlx5e_open_sq(struct mlx5e_channel *c,
1213    int tc,
1214    struct mlx5e_sq_param *param,
1215    struct mlx5e_sq *sq)
1216{
1217	int err;
1218
1219	err = mlx5e_create_sq(c, tc, param, sq);
1220	if (err)
1221		return (err);
1222
1223	err = mlx5e_enable_sq(sq, param, c->priv->tisn[tc]);
1224	if (err)
1225		goto err_destroy_sq;
1226
1227	err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST, MLX5_SQC_STATE_RDY);
1228	if (err)
1229		goto err_disable_sq;
1230
1231	atomic_store_rel_int(&sq->queue_state, MLX5E_SQ_READY);
1232
1233	return (0);
1234
1235err_disable_sq:
1236	mlx5e_disable_sq(sq);
1237err_destroy_sq:
1238	mlx5e_destroy_sq(sq);
1239
1240	return (err);
1241}
1242
1243static void
1244mlx5e_sq_send_nops_locked(struct mlx5e_sq *sq, int can_sleep)
1245{
1246	/* fill up remainder with NOPs */
1247	while (sq->cev_counter != 0) {
1248		while (!mlx5e_sq_has_room_for(sq, 1)) {
1249			if (can_sleep != 0) {
1250				mtx_unlock(&sq->lock);
1251				msleep(4);
1252				mtx_lock(&sq->lock);
1253			} else {
1254				goto done;
1255			}
1256		}
1257		/* send a single NOP */
1258		mlx5e_send_nop(sq, 1);
1259		atomic_thread_fence_rel();
1260	}
1261done:
1262	/* Check if we need to write the doorbell */
1263	if (likely(sq->doorbell.d64 != 0)) {
1264		mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
1265		sq->doorbell.d64 = 0;
1266	}
1267}
1268
1269void
1270mlx5e_sq_cev_timeout(void *arg)
1271{
1272	struct mlx5e_sq *sq = arg;
1273
1274	mtx_assert(&sq->lock, MA_OWNED);
1275
1276	/* check next state */
1277	switch (sq->cev_next_state) {
1278	case MLX5E_CEV_STATE_SEND_NOPS:
1279		/* fill TX ring with NOPs, if any */
1280		mlx5e_sq_send_nops_locked(sq, 0);
1281
1282		/* check if completed */
1283		if (sq->cev_counter == 0) {
1284			sq->cev_next_state = MLX5E_CEV_STATE_INITIAL;
1285			return;
1286		}
1287		break;
1288	default:
1289		/* send NOPs on next timeout */
1290		sq->cev_next_state = MLX5E_CEV_STATE_SEND_NOPS;
1291		break;
1292	}
1293
1294	/* restart timer */
1295	callout_reset_curcpu(&sq->cev_callout, hz, mlx5e_sq_cev_timeout, sq);
1296}
1297
1298void
1299mlx5e_drain_sq(struct mlx5e_sq *sq)
1300{
1301	int error;
1302
1303	/*
1304	 * Check if already stopped.
1305	 *
1306	 * NOTE: The "stopped" variable is only written when both the
1307	 * priv's configuration lock and the SQ's lock is locked. It
1308	 * can therefore safely be read when only one of the two locks
1309	 * is locked. This function is always called when the priv's
1310	 * configuration lock is locked.
1311	 */
1312	if (sq->stopped != 0)
1313		return;
1314
1315	mtx_lock(&sq->lock);
1316
1317	/* don't put more packets into the SQ */
1318	sq->stopped = 1;
1319
1320	/* teardown event factor timer, if any */
1321	sq->cev_next_state = MLX5E_CEV_STATE_HOLD_NOPS;
1322	callout_stop(&sq->cev_callout);
1323
1324	/* send dummy NOPs in order to flush the transmit ring */
1325	mlx5e_sq_send_nops_locked(sq, 1);
1326	mtx_unlock(&sq->lock);
1327
1328	/* make sure it is safe to free the callout */
1329	callout_drain(&sq->cev_callout);
1330
1331	/* wait till SQ is empty or link is down */
1332	mtx_lock(&sq->lock);
1333	while (sq->cc != sq->pc &&
1334	    (sq->priv->media_status_last & IFM_ACTIVE) != 0) {
1335		mtx_unlock(&sq->lock);
1336		msleep(1);
1337		sq->cq.mcq.comp(&sq->cq.mcq);
1338		mtx_lock(&sq->lock);
1339	}
1340	mtx_unlock(&sq->lock);
1341
1342	/* error out remaining requests */
1343	error = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, MLX5_SQC_STATE_ERR);
1344	if (error != 0) {
1345		if_printf(sq->ifp,
1346		    "mlx5e_modify_sq() from RDY to ERR failed: %d\n", error);
1347	}
1348
1349	/* wait till SQ is empty */
1350	mtx_lock(&sq->lock);
1351	while (sq->cc != sq->pc) {
1352		mtx_unlock(&sq->lock);
1353		msleep(1);
1354		sq->cq.mcq.comp(&sq->cq.mcq);
1355		mtx_lock(&sq->lock);
1356	}
1357	mtx_unlock(&sq->lock);
1358}
1359
1360static void
1361mlx5e_close_sq_wait(struct mlx5e_sq *sq)
1362{
1363
1364	mlx5e_drain_sq(sq);
1365	mlx5e_disable_sq(sq);
1366	mlx5e_destroy_sq(sq);
1367}
1368
1369static int
1370mlx5e_create_cq(struct mlx5e_priv *priv,
1371    struct mlx5e_cq_param *param,
1372    struct mlx5e_cq *cq,
1373    mlx5e_cq_comp_t *comp,
1374    int eq_ix)
1375{
1376	struct mlx5_core_dev *mdev = priv->mdev;
1377	struct mlx5_core_cq *mcq = &cq->mcq;
1378	int eqn_not_used;
1379	int irqn;
1380	int err;
1381	u32 i;
1382
1383	param->wq.buf_numa_node = 0;
1384	param->wq.db_numa_node = 0;
1385
1386	err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
1387	    &cq->wq_ctrl);
1388	if (err)
1389		return (err);
1390
1391	mlx5_vector2eqn(mdev, eq_ix, &eqn_not_used, &irqn);
1392
1393	mcq->cqe_sz = 64;
1394	mcq->set_ci_db = cq->wq_ctrl.db.db;
1395	mcq->arm_db = cq->wq_ctrl.db.db + 1;
1396	*mcq->set_ci_db = 0;
1397	*mcq->arm_db = 0;
1398	mcq->vector = eq_ix;
1399	mcq->comp = comp;
1400	mcq->event = mlx5e_cq_error_event;
1401	mcq->irqn = irqn;
1402	mcq->uar = &priv->cq_uar;
1403
1404	for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) {
1405		struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(&cq->wq, i);
1406
1407		cqe->op_own = 0xf1;
1408	}
1409
1410	cq->priv = priv;
1411
1412	return (0);
1413}
1414
1415static void
1416mlx5e_destroy_cq(struct mlx5e_cq *cq)
1417{
1418	mlx5_wq_destroy(&cq->wq_ctrl);
1419}
1420
1421static int
1422mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param, int eq_ix)
1423{
1424	struct mlx5_core_cq *mcq = &cq->mcq;
1425	void *in;
1426	void *cqc;
1427	int inlen;
1428	int irqn_not_used;
1429	int eqn;
1430	int err;
1431
1432	inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
1433	    sizeof(u64) * cq->wq_ctrl.buf.npages;
1434	in = mlx5_vzalloc(inlen);
1435	if (in == NULL)
1436		return (-ENOMEM);
1437
1438	cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
1439
1440	memcpy(cqc, param->cqc, sizeof(param->cqc));
1441
1442	mlx5_fill_page_array(&cq->wq_ctrl.buf,
1443	    (__be64 *) MLX5_ADDR_OF(create_cq_in, in, pas));
1444
1445	mlx5_vector2eqn(cq->priv->mdev, eq_ix, &eqn, &irqn_not_used);
1446
1447	MLX5_SET(cqc, cqc, c_eqn, eqn);
1448	MLX5_SET(cqc, cqc, uar_page, mcq->uar->index);
1449	MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
1450	    PAGE_SHIFT);
1451	MLX5_SET64(cqc, cqc, dbr_addr, cq->wq_ctrl.db.dma);
1452
1453	err = mlx5_core_create_cq(cq->priv->mdev, mcq, in, inlen);
1454
1455	kvfree(in);
1456
1457	if (err)
1458		return (err);
1459
1460	mlx5e_cq_arm(cq, MLX5_GET_DOORBELL_LOCK(&cq->priv->doorbell_lock));
1461
1462	return (0);
1463}
1464
1465static void
1466mlx5e_disable_cq(struct mlx5e_cq *cq)
1467{
1468
1469	mlx5_core_destroy_cq(cq->priv->mdev, &cq->mcq);
1470}
1471
1472int
1473mlx5e_open_cq(struct mlx5e_priv *priv,
1474    struct mlx5e_cq_param *param,
1475    struct mlx5e_cq *cq,
1476    mlx5e_cq_comp_t *comp,
1477    int eq_ix)
1478{
1479	int err;
1480
1481	err = mlx5e_create_cq(priv, param, cq, comp, eq_ix);
1482	if (err)
1483		return (err);
1484
1485	err = mlx5e_enable_cq(cq, param, eq_ix);
1486	if (err)
1487		goto err_destroy_cq;
1488
1489	return (0);
1490
1491err_destroy_cq:
1492	mlx5e_destroy_cq(cq);
1493
1494	return (err);
1495}
1496
1497void
1498mlx5e_close_cq(struct mlx5e_cq *cq)
1499{
1500	mlx5e_disable_cq(cq);
1501	mlx5e_destroy_cq(cq);
1502}
1503
1504static int
1505mlx5e_open_tx_cqs(struct mlx5e_channel *c,
1506    struct mlx5e_channel_param *cparam)
1507{
1508	int err;
1509	int tc;
1510
1511	for (tc = 0; tc < c->num_tc; tc++) {
1512		/* open completion queue */
1513		err = mlx5e_open_cq(c->priv, &cparam->tx_cq, &c->sq[tc].cq,
1514		    &mlx5e_tx_cq_comp, c->ix);
1515		if (err)
1516			goto err_close_tx_cqs;
1517	}
1518	return (0);
1519
1520err_close_tx_cqs:
1521	for (tc--; tc >= 0; tc--)
1522		mlx5e_close_cq(&c->sq[tc].cq);
1523
1524	return (err);
1525}
1526
1527static void
1528mlx5e_close_tx_cqs(struct mlx5e_channel *c)
1529{
1530	int tc;
1531
1532	for (tc = 0; tc < c->num_tc; tc++)
1533		mlx5e_close_cq(&c->sq[tc].cq);
1534}
1535
1536static int
1537mlx5e_open_sqs(struct mlx5e_channel *c,
1538    struct mlx5e_channel_param *cparam)
1539{
1540	int err;
1541	int tc;
1542
1543	for (tc = 0; tc < c->num_tc; tc++) {
1544		err = mlx5e_open_sq(c, tc, &cparam->sq, &c->sq[tc]);
1545		if (err)
1546			goto err_close_sqs;
1547	}
1548
1549	return (0);
1550
1551err_close_sqs:
1552	for (tc--; tc >= 0; tc--)
1553		mlx5e_close_sq_wait(&c->sq[tc]);
1554
1555	return (err);
1556}
1557
1558static void
1559mlx5e_close_sqs_wait(struct mlx5e_channel *c)
1560{
1561	int tc;
1562
1563	for (tc = 0; tc < c->num_tc; tc++)
1564		mlx5e_close_sq_wait(&c->sq[tc]);
1565}
1566
1567static void
1568mlx5e_chan_mtx_init(struct mlx5e_channel *c)
1569{
1570	int tc;
1571
1572	mtx_init(&c->rq.mtx, "mlx5rx", MTX_NETWORK_LOCK, MTX_DEF);
1573
1574	callout_init_mtx(&c->rq.watchdog, &c->rq.mtx, 0);
1575
1576	for (tc = 0; tc < c->num_tc; tc++) {
1577		struct mlx5e_sq *sq = c->sq + tc;
1578
1579		mtx_init(&sq->lock, "mlx5tx",
1580		    MTX_NETWORK_LOCK " TX", MTX_DEF);
1581		mtx_init(&sq->comp_lock, "mlx5comp",
1582		    MTX_NETWORK_LOCK " TX", MTX_DEF);
1583
1584		callout_init_mtx(&sq->cev_callout, &sq->lock, 0);
1585
1586		sq->cev_factor = c->priv->params_ethtool.tx_completion_fact;
1587
1588		/* ensure the TX completion event factor is not zero */
1589		if (sq->cev_factor == 0)
1590			sq->cev_factor = 1;
1591	}
1592}
1593
1594static void
1595mlx5e_chan_mtx_destroy(struct mlx5e_channel *c)
1596{
1597	int tc;
1598
1599	mtx_destroy(&c->rq.mtx);
1600
1601	for (tc = 0; tc < c->num_tc; tc++) {
1602		mtx_destroy(&c->sq[tc].lock);
1603		mtx_destroy(&c->sq[tc].comp_lock);
1604	}
1605}
1606
1607static int
1608mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
1609    struct mlx5e_channel_param *cparam,
1610    struct mlx5e_channel *volatile *cp)
1611{
1612	struct mlx5e_channel *c;
1613	int err;
1614
1615	c = malloc(sizeof(*c), M_MLX5EN, M_WAITOK | M_ZERO);
1616	c->priv = priv;
1617	c->ix = ix;
1618	c->cpu = 0;
1619	c->ifp = priv->ifp;
1620	c->mkey_be = cpu_to_be32(priv->mr.key);
1621	c->num_tc = priv->num_tc;
1622
1623	/* init mutexes */
1624	mlx5e_chan_mtx_init(c);
1625
1626	/* open transmit completion queue */
1627	err = mlx5e_open_tx_cqs(c, cparam);
1628	if (err)
1629		goto err_free;
1630
1631	/* open receive completion queue */
1632	err = mlx5e_open_cq(c->priv, &cparam->rx_cq, &c->rq.cq,
1633	    &mlx5e_rx_cq_comp, c->ix);
1634	if (err)
1635		goto err_close_tx_cqs;
1636
1637	err = mlx5e_open_sqs(c, cparam);
1638	if (err)
1639		goto err_close_rx_cq;
1640
1641	err = mlx5e_open_rq(c, &cparam->rq, &c->rq);
1642	if (err)
1643		goto err_close_sqs;
1644
1645	/* store channel pointer */
1646	*cp = c;
1647
1648	/* poll receive queue initially */
1649	c->rq.cq.mcq.comp(&c->rq.cq.mcq);
1650
1651	return (0);
1652
1653err_close_sqs:
1654	mlx5e_close_sqs_wait(c);
1655
1656err_close_rx_cq:
1657	mlx5e_close_cq(&c->rq.cq);
1658
1659err_close_tx_cqs:
1660	mlx5e_close_tx_cqs(c);
1661
1662err_free:
1663	/* destroy mutexes */
1664	mlx5e_chan_mtx_destroy(c);
1665	free(c, M_MLX5EN);
1666	return (err);
1667}
1668
1669static void
1670mlx5e_close_channel(struct mlx5e_channel *volatile *pp)
1671{
1672	struct mlx5e_channel *c = *pp;
1673
1674	/* check if channel is already closed */
1675	if (c == NULL)
1676		return;
1677	mlx5e_close_rq(&c->rq);
1678}
1679
1680static void
1681mlx5e_close_channel_wait(struct mlx5e_channel *volatile *pp)
1682{
1683	struct mlx5e_channel *c = *pp;
1684
1685	/* check if channel is already closed */
1686	if (c == NULL)
1687		return;
1688	/* ensure channel pointer is no longer used */
1689	*pp = NULL;
1690
1691	mlx5e_close_rq_wait(&c->rq);
1692	mlx5e_close_sqs_wait(c);
1693	mlx5e_close_cq(&c->rq.cq);
1694	mlx5e_close_tx_cqs(c);
1695	/* destroy mutexes */
1696	mlx5e_chan_mtx_destroy(c);
1697	free(c, M_MLX5EN);
1698}
1699
1700static void
1701mlx5e_build_rq_param(struct mlx5e_priv *priv,
1702    struct mlx5e_rq_param *param)
1703{
1704	void *rqc = param->rqc;
1705	void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
1706
1707	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST);
1708	MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);
1709	MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe)));
1710	MLX5_SET(wq, wq, log_wq_sz, priv->params.log_rq_size);
1711	MLX5_SET(wq, wq, pd, priv->pdn);
1712
1713	param->wq.buf_numa_node = 0;
1714	param->wq.db_numa_node = 0;
1715	param->wq.linear = 1;
1716}
1717
1718static void
1719mlx5e_build_sq_param(struct mlx5e_priv *priv,
1720    struct mlx5e_sq_param *param)
1721{
1722	void *sqc = param->sqc;
1723	void *wq = MLX5_ADDR_OF(sqc, sqc, wq);
1724
1725	MLX5_SET(wq, wq, log_wq_sz, priv->params.log_sq_size);
1726	MLX5_SET(wq, wq, log_wq_stride, ilog2(MLX5_SEND_WQE_BB));
1727	MLX5_SET(wq, wq, pd, priv->pdn);
1728
1729	param->wq.buf_numa_node = 0;
1730	param->wq.db_numa_node = 0;
1731	param->wq.linear = 1;
1732}
1733
1734static void
1735mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
1736    struct mlx5e_cq_param *param)
1737{
1738	void *cqc = param->cqc;
1739
1740	MLX5_SET(cqc, cqc, uar_page, priv->cq_uar.index);
1741}
1742
1743static void
1744mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
1745    struct mlx5e_cq_param *param)
1746{
1747	void *cqc = param->cqc;
1748
1749
1750	/*
1751	 * TODO The sysctl to control on/off is a bool value for now, which means
1752	 * we only support CSUM, once HASH is implemnted we'll need to address that.
1753	 */
1754	if (priv->params.cqe_zipping_en) {
1755		MLX5_SET(cqc, cqc, mini_cqe_res_format, MLX5_CQE_FORMAT_CSUM);
1756		MLX5_SET(cqc, cqc, cqe_compression_en, 1);
1757	}
1758
1759	MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_rq_size);
1760	MLX5_SET(cqc, cqc, cq_period, priv->params.rx_cq_moderation_usec);
1761	MLX5_SET(cqc, cqc, cq_max_count, priv->params.rx_cq_moderation_pkts);
1762
1763	switch (priv->params.rx_cq_moderation_mode) {
1764	case 0:
1765		MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
1766		break;
1767	default:
1768		if (MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe))
1769			MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
1770		else
1771			MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
1772		break;
1773	}
1774
1775	mlx5e_build_common_cq_param(priv, param);
1776}
1777
1778static void
1779mlx5e_build_tx_cq_param(struct mlx5e_priv *priv,
1780    struct mlx5e_cq_param *param)
1781{
1782	void *cqc = param->cqc;
1783
1784	MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_sq_size);
1785	MLX5_SET(cqc, cqc, cq_period, priv->params.tx_cq_moderation_usec);
1786	MLX5_SET(cqc, cqc, cq_max_count, priv->params.tx_cq_moderation_pkts);
1787
1788	switch (priv->params.tx_cq_moderation_mode) {
1789	case 0:
1790		MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
1791		break;
1792	default:
1793		if (MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe))
1794			MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_CQE);
1795		else
1796			MLX5_SET(cqc, cqc, cq_period_mode, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
1797		break;
1798	}
1799
1800	mlx5e_build_common_cq_param(priv, param);
1801}
1802
1803static void
1804mlx5e_build_channel_param(struct mlx5e_priv *priv,
1805    struct mlx5e_channel_param *cparam)
1806{
1807	memset(cparam, 0, sizeof(*cparam));
1808
1809	mlx5e_build_rq_param(priv, &cparam->rq);
1810	mlx5e_build_sq_param(priv, &cparam->sq);
1811	mlx5e_build_rx_cq_param(priv, &cparam->rx_cq);
1812	mlx5e_build_tx_cq_param(priv, &cparam->tx_cq);
1813}
1814
1815static int
1816mlx5e_open_channels(struct mlx5e_priv *priv)
1817{
1818	struct mlx5e_channel_param cparam;
1819	void *ptr;
1820	int err;
1821	int i;
1822	int j;
1823
1824	priv->channel = malloc(priv->params.num_channels *
1825	    sizeof(struct mlx5e_channel *), M_MLX5EN, M_WAITOK | M_ZERO);
1826
1827	mlx5e_build_channel_param(priv, &cparam);
1828	for (i = 0; i < priv->params.num_channels; i++) {
1829		err = mlx5e_open_channel(priv, i, &cparam, &priv->channel[i]);
1830		if (err)
1831			goto err_close_channels;
1832	}
1833
1834	for (j = 0; j < priv->params.num_channels; j++) {
1835		err = mlx5e_wait_for_min_rx_wqes(&priv->channel[j]->rq);
1836		if (err)
1837			goto err_close_channels;
1838	}
1839
1840	return (0);
1841
1842err_close_channels:
1843	for (i--; i >= 0; i--) {
1844		mlx5e_close_channel(&priv->channel[i]);
1845		mlx5e_close_channel_wait(&priv->channel[i]);
1846	}
1847
1848	/* remove "volatile" attribute from "channel" pointer */
1849	ptr = __DECONST(void *, priv->channel);
1850	priv->channel = NULL;
1851
1852	free(ptr, M_MLX5EN);
1853
1854	return (err);
1855}
1856
1857static void
1858mlx5e_close_channels(struct mlx5e_priv *priv)
1859{
1860	void *ptr;
1861	int i;
1862
1863	if (priv->channel == NULL)
1864		return;
1865
1866	for (i = 0; i < priv->params.num_channels; i++)
1867		mlx5e_close_channel(&priv->channel[i]);
1868	for (i = 0; i < priv->params.num_channels; i++)
1869		mlx5e_close_channel_wait(&priv->channel[i]);
1870
1871	/* remove "volatile" attribute from "channel" pointer */
1872	ptr = __DECONST(void *, priv->channel);
1873	priv->channel = NULL;
1874
1875	free(ptr, M_MLX5EN);
1876}
1877
1878static int
1879mlx5e_refresh_sq_params(struct mlx5e_priv *priv, struct mlx5e_sq *sq)
1880{
1881
1882	if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) {
1883		uint8_t cq_mode;
1884
1885		switch (priv->params.tx_cq_moderation_mode) {
1886		case 0:
1887			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
1888			break;
1889		default:
1890			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
1891			break;
1892		}
1893
1894		return (mlx5_core_modify_cq_moderation_mode(priv->mdev, &sq->cq.mcq,
1895		    priv->params.tx_cq_moderation_usec,
1896		    priv->params.tx_cq_moderation_pkts,
1897		    cq_mode));
1898	}
1899
1900	return (mlx5_core_modify_cq_moderation(priv->mdev, &sq->cq.mcq,
1901	    priv->params.tx_cq_moderation_usec,
1902	    priv->params.tx_cq_moderation_pkts));
1903}
1904
1905static int
1906mlx5e_refresh_rq_params(struct mlx5e_priv *priv, struct mlx5e_rq *rq)
1907{
1908
1909	if (MLX5_CAP_GEN(priv->mdev, cq_period_mode_modify)) {
1910		uint8_t cq_mode;
1911		int retval;
1912
1913		switch (priv->params.rx_cq_moderation_mode) {
1914		case 0:
1915			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
1916			break;
1917		default:
1918			cq_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
1919			break;
1920		}
1921
1922		retval = mlx5_core_modify_cq_moderation_mode(priv->mdev, &rq->cq.mcq,
1923		    priv->params.rx_cq_moderation_usec,
1924		    priv->params.rx_cq_moderation_pkts,
1925		    cq_mode);
1926
1927		return (retval);
1928	}
1929
1930	return (mlx5_core_modify_cq_moderation(priv->mdev, &rq->cq.mcq,
1931	    priv->params.rx_cq_moderation_usec,
1932	    priv->params.rx_cq_moderation_pkts));
1933}
1934
1935static int
1936mlx5e_refresh_channel_params_sub(struct mlx5e_priv *priv, struct mlx5e_channel *c)
1937{
1938	int err;
1939	int i;
1940
1941	if (c == NULL)
1942		return (EINVAL);
1943
1944	err = mlx5e_refresh_rq_params(priv, &c->rq);
1945	if (err)
1946		goto done;
1947
1948	for (i = 0; i != c->num_tc; i++) {
1949		err = mlx5e_refresh_sq_params(priv, &c->sq[i]);
1950		if (err)
1951			goto done;
1952	}
1953done:
1954	return (err);
1955}
1956
1957int
1958mlx5e_refresh_channel_params(struct mlx5e_priv *priv)
1959{
1960	int i;
1961
1962	if (priv->channel == NULL)
1963		return (EINVAL);
1964
1965	for (i = 0; i < priv->params.num_channels; i++) {
1966		int err;
1967
1968		err = mlx5e_refresh_channel_params_sub(priv, priv->channel[i]);
1969		if (err)
1970			return (err);
1971	}
1972	return (0);
1973}
1974
1975static int
1976mlx5e_open_tis(struct mlx5e_priv *priv, int tc)
1977{
1978	struct mlx5_core_dev *mdev = priv->mdev;
1979	u32 in[MLX5_ST_SZ_DW(create_tis_in)];
1980	void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
1981
1982	memset(in, 0, sizeof(in));
1983
1984	MLX5_SET(tisc, tisc, prio, tc);
1985	MLX5_SET(tisc, tisc, transport_domain, priv->tdn);
1986
1987	return (mlx5_core_create_tis(mdev, in, sizeof(in), &priv->tisn[tc]));
1988}
1989
1990static void
1991mlx5e_close_tis(struct mlx5e_priv *priv, int tc)
1992{
1993	mlx5_core_destroy_tis(priv->mdev, priv->tisn[tc]);
1994}
1995
1996static int
1997mlx5e_open_tises(struct mlx5e_priv *priv)
1998{
1999	int num_tc = priv->num_tc;
2000	int err;
2001	int tc;
2002
2003	for (tc = 0; tc < num_tc; tc++) {
2004		err = mlx5e_open_tis(priv, tc);
2005		if (err)
2006			goto err_close_tises;
2007	}
2008
2009	return (0);
2010
2011err_close_tises:
2012	for (tc--; tc >= 0; tc--)
2013		mlx5e_close_tis(priv, tc);
2014
2015	return (err);
2016}
2017
2018static void
2019mlx5e_close_tises(struct mlx5e_priv *priv)
2020{
2021	int num_tc = priv->num_tc;
2022	int tc;
2023
2024	for (tc = 0; tc < num_tc; tc++)
2025		mlx5e_close_tis(priv, tc);
2026}
2027
2028static int
2029mlx5e_open_rqt(struct mlx5e_priv *priv)
2030{
2031	struct mlx5_core_dev *mdev = priv->mdev;
2032	u32 *in;
2033	u32 out[MLX5_ST_SZ_DW(create_rqt_out)];
2034	void *rqtc;
2035	int inlen;
2036	int err;
2037	int sz;
2038	int i;
2039
2040	sz = 1 << priv->params.rx_hash_log_tbl_sz;
2041
2042	inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;
2043	in = mlx5_vzalloc(inlen);
2044	if (in == NULL)
2045		return (-ENOMEM);
2046	rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
2047
2048	MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
2049	MLX5_SET(rqtc, rqtc, rqt_max_size, sz);
2050
2051	for (i = 0; i < sz; i++) {
2052		int ix;
2053#ifdef RSS
2054		ix = rss_get_indirection_to_bucket(i);
2055#else
2056		ix = i;
2057#endif
2058		/* ensure we don't overflow */
2059		ix %= priv->params.num_channels;
2060		MLX5_SET(rqtc, rqtc, rq_num[i], priv->channel[ix]->rq.rqn);
2061	}
2062
2063	MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT);
2064
2065	memset(out, 0, sizeof(out));
2066	err = mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out));
2067	if (!err)
2068		priv->rqtn = MLX5_GET(create_rqt_out, out, rqtn);
2069
2070	kvfree(in);
2071
2072	return (err);
2073}
2074
2075static void
2076mlx5e_close_rqt(struct mlx5e_priv *priv)
2077{
2078	u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)];
2079	u32 out[MLX5_ST_SZ_DW(destroy_rqt_out)];
2080
2081	memset(in, 0, sizeof(in));
2082
2083	MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT);
2084	MLX5_SET(destroy_rqt_in, in, rqtn, priv->rqtn);
2085
2086	mlx5_cmd_exec_check_status(priv->mdev, in, sizeof(in), out,
2087	    sizeof(out));
2088}
2089
2090static void
2091mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt)
2092{
2093	void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
2094	__be32 *hkey;
2095
2096	MLX5_SET(tirc, tirc, transport_domain, priv->tdn);
2097
2098#define	ROUGH_MAX_L2_L3_HDR_SZ 256
2099
2100#define	MLX5_HASH_IP     (MLX5_HASH_FIELD_SEL_SRC_IP   |\
2101			  MLX5_HASH_FIELD_SEL_DST_IP)
2102
2103#define	MLX5_HASH_ALL    (MLX5_HASH_FIELD_SEL_SRC_IP   |\
2104			  MLX5_HASH_FIELD_SEL_DST_IP   |\
2105			  MLX5_HASH_FIELD_SEL_L4_SPORT |\
2106			  MLX5_HASH_FIELD_SEL_L4_DPORT)
2107
2108#define	MLX5_HASH_IP_IPSEC_SPI	(MLX5_HASH_FIELD_SEL_SRC_IP   |\
2109				 MLX5_HASH_FIELD_SEL_DST_IP   |\
2110				 MLX5_HASH_FIELD_SEL_IPSEC_SPI)
2111
2112	if (priv->params.hw_lro_en) {
2113		MLX5_SET(tirc, tirc, lro_enable_mask,
2114		    MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
2115		    MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
2116		MLX5_SET(tirc, tirc, lro_max_msg_sz,
2117		    (priv->params.lro_wqe_sz -
2118		    ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
2119		/* TODO: add the option to choose timer value dynamically */
2120		MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
2121		    MLX5_CAP_ETH(priv->mdev,
2122		    lro_timer_supported_periods[2]));
2123	}
2124
2125	/* setup parameters for hashing TIR type, if any */
2126	switch (tt) {
2127	case MLX5E_TT_ANY:
2128		MLX5_SET(tirc, tirc, disp_type,
2129		    MLX5_TIRC_DISP_TYPE_DIRECT);
2130		MLX5_SET(tirc, tirc, inline_rqn,
2131		    priv->channel[0]->rq.rqn);
2132		break;
2133	default:
2134		MLX5_SET(tirc, tirc, disp_type,
2135		    MLX5_TIRC_DISP_TYPE_INDIRECT);
2136		MLX5_SET(tirc, tirc, indirect_table,
2137		    priv->rqtn);
2138		MLX5_SET(tirc, tirc, rx_hash_fn,
2139		    MLX5_TIRC_RX_HASH_FN_HASH_TOEPLITZ);
2140		hkey = (__be32 *) MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
2141#ifdef RSS
2142		/*
2143		 * The FreeBSD RSS implementation does currently not
2144		 * support symmetric Toeplitz hashes:
2145		 */
2146		MLX5_SET(tirc, tirc, rx_hash_symmetric, 0);
2147		rss_getkey((uint8_t *)hkey);
2148#else
2149		MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
2150		hkey[0] = cpu_to_be32(0xD181C62C);
2151		hkey[1] = cpu_to_be32(0xF7F4DB5B);
2152		hkey[2] = cpu_to_be32(0x1983A2FC);
2153		hkey[3] = cpu_to_be32(0x943E1ADB);
2154		hkey[4] = cpu_to_be32(0xD9389E6B);
2155		hkey[5] = cpu_to_be32(0xD1039C2C);
2156		hkey[6] = cpu_to_be32(0xA74499AD);
2157		hkey[7] = cpu_to_be32(0x593D56D9);
2158		hkey[8] = cpu_to_be32(0xF3253C06);
2159		hkey[9] = cpu_to_be32(0x2ADC1FFC);
2160#endif
2161		break;
2162	}
2163
2164	switch (tt) {
2165	case MLX5E_TT_IPV4_TCP:
2166		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2167		    MLX5_L3_PROT_TYPE_IPV4);
2168		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
2169		    MLX5_L4_PROT_TYPE_TCP);
2170#ifdef RSS
2171		if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_TCP_IPV4)) {
2172			MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2173			    MLX5_HASH_IP);
2174		} else
2175#endif
2176		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2177		    MLX5_HASH_ALL);
2178		break;
2179
2180	case MLX5E_TT_IPV6_TCP:
2181		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2182		    MLX5_L3_PROT_TYPE_IPV6);
2183		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
2184		    MLX5_L4_PROT_TYPE_TCP);
2185#ifdef RSS
2186		if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_TCP_IPV6)) {
2187			MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2188			    MLX5_HASH_IP);
2189		} else
2190#endif
2191		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2192		    MLX5_HASH_ALL);
2193		break;
2194
2195	case MLX5E_TT_IPV4_UDP:
2196		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2197		    MLX5_L3_PROT_TYPE_IPV4);
2198		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
2199		    MLX5_L4_PROT_TYPE_UDP);
2200#ifdef RSS
2201		if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_UDP_IPV4)) {
2202			MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2203			    MLX5_HASH_IP);
2204		} else
2205#endif
2206		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2207		    MLX5_HASH_ALL);
2208		break;
2209
2210	case MLX5E_TT_IPV6_UDP:
2211		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2212		    MLX5_L3_PROT_TYPE_IPV6);
2213		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
2214		    MLX5_L4_PROT_TYPE_UDP);
2215#ifdef RSS
2216		if (!(rss_gethashconfig() & RSS_HASHTYPE_RSS_UDP_IPV6)) {
2217			MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2218			    MLX5_HASH_IP);
2219		} else
2220#endif
2221		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2222		    MLX5_HASH_ALL);
2223		break;
2224
2225	case MLX5E_TT_IPV4_IPSEC_AH:
2226		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2227		    MLX5_L3_PROT_TYPE_IPV4);
2228		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2229		    MLX5_HASH_IP_IPSEC_SPI);
2230		break;
2231
2232	case MLX5E_TT_IPV6_IPSEC_AH:
2233		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2234		    MLX5_L3_PROT_TYPE_IPV6);
2235		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2236		    MLX5_HASH_IP_IPSEC_SPI);
2237		break;
2238
2239	case MLX5E_TT_IPV4_IPSEC_ESP:
2240		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2241		    MLX5_L3_PROT_TYPE_IPV4);
2242		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2243		    MLX5_HASH_IP_IPSEC_SPI);
2244		break;
2245
2246	case MLX5E_TT_IPV6_IPSEC_ESP:
2247		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2248		    MLX5_L3_PROT_TYPE_IPV6);
2249		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2250		    MLX5_HASH_IP_IPSEC_SPI);
2251		break;
2252
2253	case MLX5E_TT_IPV4:
2254		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2255		    MLX5_L3_PROT_TYPE_IPV4);
2256		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2257		    MLX5_HASH_IP);
2258		break;
2259
2260	case MLX5E_TT_IPV6:
2261		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
2262		    MLX5_L3_PROT_TYPE_IPV6);
2263		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
2264		    MLX5_HASH_IP);
2265		break;
2266
2267	default:
2268		break;
2269	}
2270}
2271
2272static int
2273mlx5e_open_tir(struct mlx5e_priv *priv, int tt)
2274{
2275	struct mlx5_core_dev *mdev = priv->mdev;
2276	u32 *in;
2277	void *tirc;
2278	int inlen;
2279	int err;
2280
2281	inlen = MLX5_ST_SZ_BYTES(create_tir_in);
2282	in = mlx5_vzalloc(inlen);
2283	if (in == NULL)
2284		return (-ENOMEM);
2285	tirc = MLX5_ADDR_OF(create_tir_in, in, tir_context);
2286
2287	mlx5e_build_tir_ctx(priv, tirc, tt);
2288
2289	err = mlx5_core_create_tir(mdev, in, inlen, &priv->tirn[tt]);
2290
2291	kvfree(in);
2292
2293	return (err);
2294}
2295
2296static void
2297mlx5e_close_tir(struct mlx5e_priv *priv, int tt)
2298{
2299	mlx5_core_destroy_tir(priv->mdev, priv->tirn[tt]);
2300}
2301
2302static int
2303mlx5e_open_tirs(struct mlx5e_priv *priv)
2304{
2305	int err;
2306	int i;
2307
2308	for (i = 0; i < MLX5E_NUM_TT; i++) {
2309		err = mlx5e_open_tir(priv, i);
2310		if (err)
2311			goto err_close_tirs;
2312	}
2313
2314	return (0);
2315
2316err_close_tirs:
2317	for (i--; i >= 0; i--)
2318		mlx5e_close_tir(priv, i);
2319
2320	return (err);
2321}
2322
2323static void
2324mlx5e_close_tirs(struct mlx5e_priv *priv)
2325{
2326	int i;
2327
2328	for (i = 0; i < MLX5E_NUM_TT; i++)
2329		mlx5e_close_tir(priv, i);
2330}
2331
2332/*
2333 * SW MTU does not include headers,
2334 * HW MTU includes all headers and checksums.
2335 */
2336static int
2337mlx5e_set_dev_port_mtu(struct ifnet *ifp, int sw_mtu)
2338{
2339	struct mlx5e_priv *priv = ifp->if_softc;
2340	struct mlx5_core_dev *mdev = priv->mdev;
2341	int hw_mtu;
2342	int err;
2343
2344	hw_mtu = MLX5E_SW2HW_MTU(sw_mtu);
2345
2346	err = mlx5_set_port_mtu(mdev, hw_mtu);
2347	if (err) {
2348		if_printf(ifp, "%s: mlx5_set_port_mtu failed setting %d, err=%d\n",
2349		    __func__, sw_mtu, err);
2350		return (err);
2351	}
2352
2353	/* Update vport context MTU */
2354	err = mlx5_set_vport_mtu(mdev, hw_mtu);
2355	if (err) {
2356		if_printf(ifp, "%s: Failed updating vport context with MTU size, err=%d\n",
2357		    __func__, err);
2358	}
2359
2360	ifp->if_mtu = sw_mtu;
2361
2362	err = mlx5_query_vport_mtu(mdev, &hw_mtu);
2363	if (err || !hw_mtu) {
2364		/* fallback to port oper mtu */
2365		err = mlx5_query_port_oper_mtu(mdev, &hw_mtu);
2366	}
2367	if (err) {
2368		if_printf(ifp, "Query port MTU, after setting new "
2369		    "MTU value, failed\n");
2370		return (err);
2371	} else if (MLX5E_HW2SW_MTU(hw_mtu) < sw_mtu) {
2372		err = -E2BIG,
2373		if_printf(ifp, "Port MTU %d is smaller than "
2374                    "ifp mtu %d\n", hw_mtu, sw_mtu);
2375	} else if (MLX5E_HW2SW_MTU(hw_mtu) > sw_mtu) {
2376		err = -EINVAL;
2377                if_printf(ifp, "Port MTU %d is bigger than "
2378                    "ifp mtu %d\n", hw_mtu, sw_mtu);
2379	}
2380	priv->params_ethtool.hw_mtu = hw_mtu;
2381
2382	return (err);
2383}
2384
2385int
2386mlx5e_open_locked(struct ifnet *ifp)
2387{
2388	struct mlx5e_priv *priv = ifp->if_softc;
2389	int err;
2390	u16 set_id;
2391
2392	/* check if already opened */
2393	if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0)
2394		return (0);
2395
2396#ifdef RSS
2397	if (rss_getnumbuckets() > priv->params.num_channels) {
2398		if_printf(ifp, "NOTE: There are more RSS buckets(%u) than "
2399		    "channels(%u) available\n", rss_getnumbuckets(),
2400		    priv->params.num_channels);
2401	}
2402#endif
2403	err = mlx5e_open_tises(priv);
2404	if (err) {
2405		if_printf(ifp, "%s: mlx5e_open_tises failed, %d\n",
2406		    __func__, err);
2407		return (err);
2408	}
2409	err = mlx5_vport_alloc_q_counter(priv->mdev,
2410	    MLX5_INTERFACE_PROTOCOL_ETH, &set_id);
2411	if (err) {
2412		if_printf(priv->ifp,
2413		    "%s: mlx5_vport_alloc_q_counter failed: %d\n",
2414		    __func__, err);
2415		goto err_close_tises;
2416	}
2417	/* store counter set ID */
2418	priv->counter_set_id = set_id;
2419
2420	err = mlx5e_open_channels(priv);
2421	if (err) {
2422		if_printf(ifp, "%s: mlx5e_open_channels failed, %d\n",
2423		    __func__, err);
2424		goto err_dalloc_q_counter;
2425	}
2426	err = mlx5e_open_rqt(priv);
2427	if (err) {
2428		if_printf(ifp, "%s: mlx5e_open_rqt failed, %d\n",
2429		    __func__, err);
2430		goto err_close_channels;
2431	}
2432	err = mlx5e_open_tirs(priv);
2433	if (err) {
2434		if_printf(ifp, "%s: mlx5e_open_tir failed, %d\n",
2435		    __func__, err);
2436		goto err_close_rqls;
2437	}
2438	err = mlx5e_open_flow_table(priv);
2439	if (err) {
2440		if_printf(ifp, "%s: mlx5e_open_flow_table failed, %d\n",
2441		    __func__, err);
2442		goto err_close_tirs;
2443	}
2444	err = mlx5e_add_all_vlan_rules(priv);
2445	if (err) {
2446		if_printf(ifp, "%s: mlx5e_add_all_vlan_rules failed, %d\n",
2447		    __func__, err);
2448		goto err_close_flow_table;
2449	}
2450	set_bit(MLX5E_STATE_OPENED, &priv->state);
2451
2452	mlx5e_update_carrier(priv);
2453	mlx5e_set_rx_mode_core(priv);
2454
2455	return (0);
2456
2457err_close_flow_table:
2458	mlx5e_close_flow_table(priv);
2459
2460err_close_tirs:
2461	mlx5e_close_tirs(priv);
2462
2463err_close_rqls:
2464	mlx5e_close_rqt(priv);
2465
2466err_close_channels:
2467	mlx5e_close_channels(priv);
2468
2469err_dalloc_q_counter:
2470	mlx5_vport_dealloc_q_counter(priv->mdev,
2471	    MLX5_INTERFACE_PROTOCOL_ETH, priv->counter_set_id);
2472
2473err_close_tises:
2474	mlx5e_close_tises(priv);
2475
2476	return (err);
2477}
2478
2479static void
2480mlx5e_open(void *arg)
2481{
2482	struct mlx5e_priv *priv = arg;
2483
2484	PRIV_LOCK(priv);
2485	if (mlx5_set_port_status(priv->mdev, MLX5_PORT_UP))
2486		if_printf(priv->ifp,
2487		    "%s: Setting port status to up failed\n",
2488		    __func__);
2489
2490	mlx5e_open_locked(priv->ifp);
2491	priv->ifp->if_drv_flags |= IFF_DRV_RUNNING;
2492	PRIV_UNLOCK(priv);
2493}
2494
2495int
2496mlx5e_close_locked(struct ifnet *ifp)
2497{
2498	struct mlx5e_priv *priv = ifp->if_softc;
2499
2500	/* check if already closed */
2501	if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
2502		return (0);
2503
2504	clear_bit(MLX5E_STATE_OPENED, &priv->state);
2505
2506	mlx5e_set_rx_mode_core(priv);
2507	mlx5e_del_all_vlan_rules(priv);
2508	if_link_state_change(priv->ifp, LINK_STATE_DOWN);
2509	mlx5e_close_flow_table(priv);
2510	mlx5e_close_tirs(priv);
2511	mlx5e_close_rqt(priv);
2512	mlx5e_close_channels(priv);
2513	mlx5_vport_dealloc_q_counter(priv->mdev,
2514	    MLX5_INTERFACE_PROTOCOL_ETH, priv->counter_set_id);
2515	mlx5e_close_tises(priv);
2516
2517	return (0);
2518}
2519
2520#if (__FreeBSD_version >= 1100000)
2521static uint64_t
2522mlx5e_get_counter(struct ifnet *ifp, ift_counter cnt)
2523{
2524	struct mlx5e_priv *priv = ifp->if_softc;
2525	u64 retval;
2526
2527	/* PRIV_LOCK(priv); XXX not allowed */
2528	switch (cnt) {
2529	case IFCOUNTER_IPACKETS:
2530		retval = priv->stats.vport.rx_packets;
2531		break;
2532	case IFCOUNTER_IERRORS:
2533		retval = priv->stats.vport.rx_error_packets +
2534		    priv->stats.pport.alignment_err +
2535		    priv->stats.pport.check_seq_err +
2536		    priv->stats.pport.crc_align_errors +
2537		    priv->stats.pport.in_range_len_errors +
2538		    priv->stats.pport.jabbers +
2539		    priv->stats.pport.out_of_range_len +
2540		    priv->stats.pport.oversize_pkts +
2541		    priv->stats.pport.symbol_err +
2542		    priv->stats.pport.too_long_errors +
2543		    priv->stats.pport.undersize_pkts +
2544		    priv->stats.pport.unsupported_op_rx;
2545		break;
2546	case IFCOUNTER_IQDROPS:
2547		retval = priv->stats.vport.rx_out_of_buffer +
2548		    priv->stats.pport.drop_events;
2549		break;
2550	case IFCOUNTER_OPACKETS:
2551		retval = priv->stats.vport.tx_packets;
2552		break;
2553	case IFCOUNTER_OERRORS:
2554		retval = priv->stats.vport.tx_error_packets;
2555		break;
2556	case IFCOUNTER_IBYTES:
2557		retval = priv->stats.vport.rx_bytes;
2558		break;
2559	case IFCOUNTER_OBYTES:
2560		retval = priv->stats.vport.tx_bytes;
2561		break;
2562	case IFCOUNTER_IMCASTS:
2563		retval = priv->stats.vport.rx_multicast_packets;
2564		break;
2565	case IFCOUNTER_OMCASTS:
2566		retval = priv->stats.vport.tx_multicast_packets;
2567		break;
2568	case IFCOUNTER_OQDROPS:
2569		retval = priv->stats.vport.tx_queue_dropped;
2570		break;
2571	case IFCOUNTER_COLLISIONS:
2572		retval = priv->stats.pport.collisions;
2573		break;
2574	default:
2575		retval = if_get_counter_default(ifp, cnt);
2576		break;
2577	}
2578	/* PRIV_UNLOCK(priv); XXX not allowed */
2579	return (retval);
2580}
2581#endif
2582
2583static void
2584mlx5e_set_rx_mode(struct ifnet *ifp)
2585{
2586	struct mlx5e_priv *priv = ifp->if_softc;
2587
2588	schedule_work(&priv->set_rx_mode_work);
2589}
2590
2591static int
2592mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
2593{
2594	struct mlx5e_priv *priv;
2595	struct ifreq *ifr;
2596	struct ifi2creq i2c;
2597	int error = 0;
2598	int mask = 0;
2599	int size_read = 0;
2600	int module_status;
2601	int module_num;
2602	int max_mtu;
2603	uint8_t read_addr;
2604
2605	priv = ifp->if_softc;
2606
2607	/* check if detaching */
2608	if (priv == NULL || priv->gone != 0)
2609		return (ENXIO);
2610
2611	switch (command) {
2612	case SIOCSIFMTU:
2613		ifr = (struct ifreq *)data;
2614
2615		PRIV_LOCK(priv);
2616		mlx5_query_port_max_mtu(priv->mdev, &max_mtu);
2617
2618		if (ifr->ifr_mtu >= MLX5E_MTU_MIN &&
2619		    ifr->ifr_mtu <= MIN(MLX5E_MTU_MAX, max_mtu)) {
2620			int was_opened;
2621
2622			was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
2623			if (was_opened)
2624				mlx5e_close_locked(ifp);
2625
2626			/* set new MTU */
2627			mlx5e_set_dev_port_mtu(ifp, ifr->ifr_mtu);
2628
2629			if (was_opened)
2630				mlx5e_open_locked(ifp);
2631		} else {
2632			error = EINVAL;
2633			if_printf(ifp, "Invalid MTU value. Min val: %d, Max val: %d\n",
2634			    MLX5E_MTU_MIN, MIN(MLX5E_MTU_MAX, max_mtu));
2635		}
2636		PRIV_UNLOCK(priv);
2637		break;
2638	case SIOCSIFFLAGS:
2639		if ((ifp->if_flags & IFF_UP) &&
2640		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
2641			mlx5e_set_rx_mode(ifp);
2642			break;
2643		}
2644		PRIV_LOCK(priv);
2645		if (ifp->if_flags & IFF_UP) {
2646			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
2647				if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
2648					mlx5e_open_locked(ifp);
2649				ifp->if_drv_flags |= IFF_DRV_RUNNING;
2650				mlx5_set_port_status(priv->mdev, MLX5_PORT_UP);
2651			}
2652		} else {
2653			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2654				mlx5_set_port_status(priv->mdev,
2655				    MLX5_PORT_DOWN);
2656				if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0)
2657					mlx5e_close_locked(ifp);
2658				mlx5e_update_carrier(priv);
2659				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2660			}
2661		}
2662		PRIV_UNLOCK(priv);
2663		break;
2664	case SIOCADDMULTI:
2665	case SIOCDELMULTI:
2666		mlx5e_set_rx_mode(ifp);
2667		break;
2668	case SIOCSIFMEDIA:
2669	case SIOCGIFMEDIA:
2670	case SIOCGIFXMEDIA:
2671		ifr = (struct ifreq *)data;
2672		error = ifmedia_ioctl(ifp, ifr, &priv->media, command);
2673		break;
2674	case SIOCSIFCAP:
2675		ifr = (struct ifreq *)data;
2676		PRIV_LOCK(priv);
2677		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
2678
2679		if (mask & IFCAP_TXCSUM) {
2680			ifp->if_capenable ^= IFCAP_TXCSUM;
2681			ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
2682
2683			if (IFCAP_TSO4 & ifp->if_capenable &&
2684			    !(IFCAP_TXCSUM & ifp->if_capenable)) {
2685				ifp->if_capenable &= ~IFCAP_TSO4;
2686				ifp->if_hwassist &= ~CSUM_IP_TSO;
2687				if_printf(ifp,
2688				    "tso4 disabled due to -txcsum.\n");
2689			}
2690		}
2691		if (mask & IFCAP_TXCSUM_IPV6) {
2692			ifp->if_capenable ^= IFCAP_TXCSUM_IPV6;
2693			ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
2694
2695			if (IFCAP_TSO6 & ifp->if_capenable &&
2696			    !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
2697				ifp->if_capenable &= ~IFCAP_TSO6;
2698				ifp->if_hwassist &= ~CSUM_IP6_TSO;
2699				if_printf(ifp,
2700				    "tso6 disabled due to -txcsum6.\n");
2701			}
2702		}
2703		if (mask & IFCAP_RXCSUM)
2704			ifp->if_capenable ^= IFCAP_RXCSUM;
2705		if (mask & IFCAP_RXCSUM_IPV6)
2706			ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
2707		if (mask & IFCAP_TSO4) {
2708			if (!(IFCAP_TSO4 & ifp->if_capenable) &&
2709			    !(IFCAP_TXCSUM & ifp->if_capenable)) {
2710				if_printf(ifp, "enable txcsum first.\n");
2711				error = EAGAIN;
2712				goto out;
2713			}
2714			ifp->if_capenable ^= IFCAP_TSO4;
2715			ifp->if_hwassist ^= CSUM_IP_TSO;
2716		}
2717		if (mask & IFCAP_TSO6) {
2718			if (!(IFCAP_TSO6 & ifp->if_capenable) &&
2719			    !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
2720				if_printf(ifp, "enable txcsum6 first.\n");
2721				error = EAGAIN;
2722				goto out;
2723			}
2724			ifp->if_capenable ^= IFCAP_TSO6;
2725			ifp->if_hwassist ^= CSUM_IP6_TSO;
2726		}
2727		if (mask & IFCAP_VLAN_HWFILTER) {
2728			if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
2729				mlx5e_disable_vlan_filter(priv);
2730			else
2731				mlx5e_enable_vlan_filter(priv);
2732
2733			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
2734		}
2735		if (mask & IFCAP_VLAN_HWTAGGING)
2736			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
2737		if (mask & IFCAP_WOL_MAGIC)
2738			ifp->if_capenable ^= IFCAP_WOL_MAGIC;
2739
2740		VLAN_CAPABILITIES(ifp);
2741		/* turn off LRO means also turn of HW LRO - if it's on */
2742		if (mask & IFCAP_LRO) {
2743			int was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
2744			bool need_restart = false;
2745
2746			ifp->if_capenable ^= IFCAP_LRO;
2747			if (!(ifp->if_capenable & IFCAP_LRO)) {
2748				if (priv->params.hw_lro_en) {
2749					priv->params.hw_lro_en = false;
2750					need_restart = true;
2751					/* Not sure this is the correct way */
2752					priv->params_ethtool.hw_lro = priv->params.hw_lro_en;
2753				}
2754			}
2755			if (was_opened && need_restart) {
2756				mlx5e_close_locked(ifp);
2757				mlx5e_open_locked(ifp);
2758			}
2759		}
2760out:
2761		PRIV_UNLOCK(priv);
2762		break;
2763
2764	case SIOCGI2C:
2765		ifr = (struct ifreq *)data;
2766
2767		/*
2768		 * Copy from the user-space address ifr_data to the
2769		 * kernel-space address i2c
2770		 */
2771		error = copyin(ifr->ifr_data, &i2c, sizeof(i2c));
2772		if (error)
2773			break;
2774
2775		if (i2c.len > sizeof(i2c.data)) {
2776			error = EINVAL;
2777			break;
2778		}
2779
2780		PRIV_LOCK(priv);
2781		/* Get module_num which is required for the query_eeprom */
2782		error = mlx5_query_module_num(priv->mdev, &module_num);
2783		if (error) {
2784			if_printf(ifp, "Query module num failed, eeprom "
2785			    "reading is not supported\n");
2786			error = EINVAL;
2787			goto err_i2c;
2788		}
2789		/* Check if module is present before doing an access */
2790		module_status = mlx5_query_module_status(priv->mdev, module_num);
2791		if (module_status != MLX5_MODULE_STATUS_PLUGGED_ENABLED &&
2792		    module_status != MLX5_MODULE_STATUS_PLUGGED_DISABLED) {
2793			error = EINVAL;
2794			goto err_i2c;
2795		}
2796		/*
2797		 * Currently 0XA0 and 0xA2 are the only addresses permitted.
2798		 * The internal conversion is as follows:
2799		 */
2800		if (i2c.dev_addr == 0xA0)
2801			read_addr = MLX5E_I2C_ADDR_LOW;
2802		else if (i2c.dev_addr == 0xA2)
2803			read_addr = MLX5E_I2C_ADDR_HIGH;
2804		else {
2805			if_printf(ifp, "Query eeprom failed, "
2806			    "Invalid Address: %X\n", i2c.dev_addr);
2807			error = EINVAL;
2808			goto err_i2c;
2809		}
2810		error = mlx5_query_eeprom(priv->mdev,
2811		    read_addr, MLX5E_EEPROM_LOW_PAGE,
2812		    (uint32_t)i2c.offset, (uint32_t)i2c.len, module_num,
2813		    (uint32_t *)i2c.data, &size_read);
2814		if (error) {
2815			if_printf(ifp, "Query eeprom failed, eeprom "
2816			    "reading is not supported\n");
2817			error = EINVAL;
2818			goto err_i2c;
2819		}
2820
2821		if (i2c.len > MLX5_EEPROM_MAX_BYTES) {
2822			error = mlx5_query_eeprom(priv->mdev,
2823			    read_addr, MLX5E_EEPROM_LOW_PAGE,
2824			    (uint32_t)(i2c.offset + size_read),
2825			    (uint32_t)(i2c.len - size_read), module_num,
2826			    (uint32_t *)(i2c.data + size_read), &size_read);
2827		}
2828		if (error) {
2829			if_printf(ifp, "Query eeprom failed, eeprom "
2830			    "reading is not supported\n");
2831			error = EINVAL;
2832			goto err_i2c;
2833		}
2834
2835		error = copyout(&i2c, ifr->ifr_data, sizeof(i2c));
2836err_i2c:
2837		PRIV_UNLOCK(priv);
2838		break;
2839
2840	default:
2841		error = ether_ioctl(ifp, command, data);
2842		break;
2843	}
2844	return (error);
2845}
2846
2847static int
2848mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
2849{
2850	/*
2851	 * TODO: uncoment once FW really sets all these bits if
2852	 * (!mdev->caps.eth.rss_ind_tbl_cap || !mdev->caps.eth.csum_cap ||
2853	 * !mdev->caps.eth.max_lso_cap || !mdev->caps.eth.vlan_cap ||
2854	 * !(mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_SCQE_BRK_MOD)) return
2855	 * -ENOTSUPP;
2856	 */
2857
2858	/* TODO: add more must-to-have features */
2859
2860	if (MLX5_CAP_GEN(mdev, port_type) != MLX5_CAP_PORT_TYPE_ETH)
2861		return (-ENODEV);
2862
2863	return (0);
2864}
2865
2866static void
2867mlx5e_build_ifp_priv(struct mlx5_core_dev *mdev,
2868    struct mlx5e_priv *priv,
2869    int num_comp_vectors)
2870{
2871	/*
2872	 * TODO: Consider link speed for setting "log_sq_size",
2873	 * "log_rq_size" and "cq_moderation_xxx":
2874	 */
2875	priv->params.log_sq_size =
2876	    MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
2877	priv->params.log_rq_size =
2878	    MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
2879	priv->params.rx_cq_moderation_usec =
2880	    MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
2881	    MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE :
2882	    MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC;
2883	priv->params.rx_cq_moderation_mode =
2884	    MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? 1 : 0;
2885	priv->params.rx_cq_moderation_pkts =
2886	    MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS;
2887	priv->params.tx_cq_moderation_usec =
2888	    MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC;
2889	priv->params.tx_cq_moderation_pkts =
2890	    MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
2891	priv->params.min_rx_wqes =
2892	    MLX5E_PARAMS_DEFAULT_MIN_RX_WQES;
2893	priv->params.rx_hash_log_tbl_sz =
2894	    (order_base_2(num_comp_vectors) >
2895	    MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ) ?
2896	    order_base_2(num_comp_vectors) :
2897	    MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ;
2898	priv->params.num_tc = 1;
2899	priv->params.default_vlan_prio = 0;
2900	priv->counter_set_id = -1;
2901
2902	/*
2903	 * hw lro is currently defaulted to off. when it won't anymore we
2904	 * will consider the HW capability: "!!MLX5_CAP_ETH(mdev, lro_cap)"
2905	 */
2906	priv->params.hw_lro_en = false;
2907	priv->params.lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
2908
2909	priv->params.cqe_zipping_en = !!MLX5_CAP_GEN(mdev, cqe_compression);
2910
2911	priv->mdev = mdev;
2912	priv->params.num_channels = num_comp_vectors;
2913	priv->order_base_2_num_channels = order_base_2(num_comp_vectors);
2914	priv->queue_mapping_channel_mask =
2915	    roundup_pow_of_two(num_comp_vectors) - 1;
2916	priv->num_tc = priv->params.num_tc;
2917	priv->default_vlan_prio = priv->params.default_vlan_prio;
2918
2919	INIT_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
2920	INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
2921	INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);
2922}
2923
2924static int
2925mlx5e_create_mkey(struct mlx5e_priv *priv, u32 pdn,
2926    struct mlx5_core_mr *mr)
2927{
2928	struct ifnet *ifp = priv->ifp;
2929	struct mlx5_core_dev *mdev = priv->mdev;
2930	struct mlx5_create_mkey_mbox_in *in;
2931	int err;
2932
2933	in = mlx5_vzalloc(sizeof(*in));
2934	if (in == NULL) {
2935		if_printf(ifp, "%s: failed to allocate inbox\n", __func__);
2936		return (-ENOMEM);
2937	}
2938	in->seg.flags = MLX5_PERM_LOCAL_WRITE |
2939	    MLX5_PERM_LOCAL_READ |
2940	    MLX5_ACCESS_MODE_PA;
2941	in->seg.flags_pd = cpu_to_be32(pdn | MLX5_MKEY_LEN64);
2942	in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
2943
2944	err = mlx5_core_create_mkey(mdev, mr, in, sizeof(*in), NULL, NULL,
2945	    NULL);
2946	if (err)
2947		if_printf(ifp, "%s: mlx5_core_create_mkey failed, %d\n",
2948		    __func__, err);
2949
2950	kvfree(in);
2951
2952	return (err);
2953}
2954
2955static const char *mlx5e_vport_stats_desc[] = {
2956	MLX5E_VPORT_STATS(MLX5E_STATS_DESC)
2957};
2958
2959static const char *mlx5e_pport_stats_desc[] = {
2960	MLX5E_PPORT_STATS(MLX5E_STATS_DESC)
2961};
2962
2963static void
2964mlx5e_priv_mtx_init(struct mlx5e_priv *priv)
2965{
2966	mtx_init(&priv->async_events_mtx, "mlx5async", MTX_NETWORK_LOCK, MTX_DEF);
2967	sx_init(&priv->state_lock, "mlx5state");
2968	callout_init_mtx(&priv->watchdog, &priv->async_events_mtx, 0);
2969	MLX5_INIT_DOORBELL_LOCK(&priv->doorbell_lock);
2970}
2971
2972static void
2973mlx5e_priv_mtx_destroy(struct mlx5e_priv *priv)
2974{
2975	mtx_destroy(&priv->async_events_mtx);
2976	sx_destroy(&priv->state_lock);
2977}
2978
2979static int
2980sysctl_firmware(SYSCTL_HANDLER_ARGS)
2981{
2982	/*
2983	 * %d.%d%.d the string format.
2984	 * fw_rev_{maj,min,sub} return u16, 2^16 = 65536.
2985	 * We need at most 5 chars to store that.
2986	 * It also has: two "." and NULL at the end, which means we need 18
2987	 * (5*3 + 3) chars at most.
2988	 */
2989	char fw[18];
2990	struct mlx5e_priv *priv = arg1;
2991	int error;
2992
2993	snprintf(fw, sizeof(fw), "%d.%d.%d", fw_rev_maj(priv->mdev), fw_rev_min(priv->mdev),
2994	    fw_rev_sub(priv->mdev));
2995	error = sysctl_handle_string(oidp, fw, sizeof(fw), req);
2996	return (error);
2997}
2998
2999static void
3000mlx5e_disable_tx_dma(struct mlx5e_channel *ch)
3001{
3002	int i;
3003
3004	for (i = 0; i < ch->num_tc; i++)
3005		mlx5e_drain_sq(&ch->sq[i]);
3006}
3007
3008static void
3009mlx5e_reset_sq_doorbell_record(struct mlx5e_sq *sq)
3010{
3011
3012	sq->doorbell.d32[0] = cpu_to_be32(MLX5_OPCODE_NOP);
3013	sq->doorbell.d32[1] = cpu_to_be32(sq->sqn << 8);
3014	mlx5e_tx_notify_hw(sq, sq->doorbell.d32, 0);
3015	sq->doorbell.d64 = 0;
3016}
3017
3018void
3019mlx5e_resume_sq(struct mlx5e_sq *sq)
3020{
3021	int err;
3022
3023	/* check if already enabled */
3024	if (sq->stopped == 0)
3025		return;
3026
3027	err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_ERR,
3028	    MLX5_SQC_STATE_RST);
3029	if (err != 0) {
3030		if_printf(sq->ifp,
3031		    "mlx5e_modify_sq() from ERR to RST failed: %d\n", err);
3032	}
3033
3034	sq->cc = 0;
3035	sq->pc = 0;
3036
3037	/* reset doorbell prior to moving from RST to RDY */
3038	mlx5e_reset_sq_doorbell_record(sq);
3039
3040	err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST,
3041	    MLX5_SQC_STATE_RDY);
3042	if (err != 0) {
3043		if_printf(sq->ifp,
3044		    "mlx5e_modify_sq() from RST to RDY failed: %d\n", err);
3045	}
3046
3047	mtx_lock(&sq->lock);
3048	sq->cev_next_state = MLX5E_CEV_STATE_INITIAL;
3049	sq->stopped = 0;
3050	mtx_unlock(&sq->lock);
3051
3052}
3053
3054static void
3055mlx5e_enable_tx_dma(struct mlx5e_channel *ch)
3056{
3057        int i;
3058
3059	for (i = 0; i < ch->num_tc; i++)
3060		mlx5e_resume_sq(&ch->sq[i]);
3061}
3062
3063static void
3064mlx5e_disable_rx_dma(struct mlx5e_channel *ch)
3065{
3066	struct mlx5e_rq *rq = &ch->rq;
3067	int err;
3068
3069	mtx_lock(&rq->mtx);
3070	rq->enabled = 0;
3071	callout_stop(&rq->watchdog);
3072	mtx_unlock(&rq->mtx);
3073
3074	callout_drain(&rq->watchdog);
3075
3076	err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR);
3077	if (err != 0) {
3078		if_printf(rq->ifp,
3079		    "mlx5e_modify_rq() from RDY to RST failed: %d\n", err);
3080	}
3081
3082	while (!mlx5_wq_ll_is_empty(&rq->wq)) {
3083		msleep(1);
3084		rq->cq.mcq.comp(&rq->cq.mcq);
3085	}
3086
3087	/*
3088	 * Transitioning into RST state will allow the FW to track less ERR state queues,
3089	 * thus reducing the recv queue flushing time
3090	 */
3091	err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_ERR, MLX5_RQC_STATE_RST);
3092	if (err != 0) {
3093		if_printf(rq->ifp,
3094		    "mlx5e_modify_rq() from ERR to RST failed: %d\n", err);
3095	}
3096}
3097
3098static void
3099mlx5e_enable_rx_dma(struct mlx5e_channel *ch)
3100{
3101	struct mlx5e_rq *rq = &ch->rq;
3102	int err;
3103
3104	rq->wq.wqe_ctr = 0;
3105	mlx5_wq_ll_update_db_record(&rq->wq);
3106	err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
3107	if (err != 0) {
3108		if_printf(rq->ifp,
3109		    "mlx5e_modify_rq() from RST to RDY failed: %d\n", err);
3110        }
3111
3112	rq->enabled = 1;
3113
3114	rq->cq.mcq.comp(&rq->cq.mcq);
3115}
3116
3117void
3118mlx5e_modify_tx_dma(struct mlx5e_priv *priv, uint8_t value)
3119{
3120	int i;
3121
3122	if (priv->channel == NULL)
3123		return;
3124
3125	for (i = 0; i < priv->params.num_channels; i++) {
3126
3127		if (!priv->channel[i])
3128			continue;
3129
3130		if (value)
3131			mlx5e_disable_tx_dma(priv->channel[i]);
3132		else
3133			mlx5e_enable_tx_dma(priv->channel[i]);
3134	}
3135}
3136
3137void
3138mlx5e_modify_rx_dma(struct mlx5e_priv *priv, uint8_t value)
3139{
3140	int i;
3141
3142	if (priv->channel == NULL)
3143		return;
3144
3145	for (i = 0; i < priv->params.num_channels; i++) {
3146
3147		if (!priv->channel[i])
3148			continue;
3149
3150		if (value)
3151			mlx5e_disable_rx_dma(priv->channel[i]);
3152		else
3153			mlx5e_enable_rx_dma(priv->channel[i]);
3154	}
3155}
3156
3157static void
3158mlx5e_add_hw_stats(struct mlx5e_priv *priv)
3159{
3160	SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw),
3161	    OID_AUTO, "fw_version", CTLTYPE_STRING | CTLFLAG_RD, priv, 0,
3162	    sysctl_firmware, "A", "HCA firmware version");
3163
3164	SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw),
3165	    OID_AUTO, "board_id", CTLFLAG_RD, priv->mdev->board_id, 0,
3166	    "Board ID");
3167}
3168
3169static int
3170mlx5e_sysctl_tx_priority_flow_control(SYSCTL_HANDLER_ARGS)
3171{
3172	struct mlx5e_priv *priv = arg1;
3173	uint32_t tx_pfc;
3174	uint32_t value;
3175	int error;
3176
3177	PRIV_LOCK(priv);
3178
3179	tx_pfc = priv->params.tx_priority_flow_control;
3180
3181	/* get current value */
3182	value = (tx_pfc >> arg2) & 1;
3183
3184	error = sysctl_handle_32(oidp, &value, 0, req);
3185
3186	/* range check value */
3187	if (value != 0)
3188		priv->params.tx_priority_flow_control |= (1 << arg2);
3189	else
3190		priv->params.tx_priority_flow_control &= ~(1 << arg2);
3191
3192	/* check if update is required */
3193	if (error == 0 && priv->gone == 0 &&
3194	    tx_pfc != priv->params.tx_priority_flow_control) {
3195		error = -mlx5e_set_port_pfc(priv);
3196		/* restore previous value */
3197		if (error != 0)
3198			priv->params.tx_priority_flow_control= tx_pfc;
3199	}
3200	PRIV_UNLOCK(priv);
3201
3202	return (error);
3203}
3204
3205static int
3206mlx5e_sysctl_rx_priority_flow_control(SYSCTL_HANDLER_ARGS)
3207{
3208	struct mlx5e_priv *priv = arg1;
3209	uint32_t rx_pfc;
3210	uint32_t value;
3211	int error;
3212
3213	PRIV_LOCK(priv);
3214
3215	rx_pfc = priv->params.rx_priority_flow_control;
3216
3217	/* get current value */
3218	value = (rx_pfc >> arg2) & 1;
3219
3220	error = sysctl_handle_32(oidp, &value, 0, req);
3221
3222	/* range check value */
3223	if (value != 0)
3224		priv->params.rx_priority_flow_control |= (1 << arg2);
3225	else
3226		priv->params.rx_priority_flow_control &= ~(1 << arg2);
3227
3228	/* check if update is required */
3229	if (error == 0 && priv->gone == 0 &&
3230	    rx_pfc != priv->params.rx_priority_flow_control) {
3231		error = -mlx5e_set_port_pfc(priv);
3232		/* restore previous value */
3233		if (error != 0)
3234			priv->params.rx_priority_flow_control= rx_pfc;
3235	}
3236	PRIV_UNLOCK(priv);
3237
3238	return (error);
3239}
3240
3241static void
3242mlx5e_setup_pauseframes(struct mlx5e_priv *priv)
3243{
3244	unsigned int x;
3245	char path[96];
3246	int error;
3247
3248	/* Only receiving pauseframes is enabled by default */
3249	priv->params.tx_pauseframe_control = 0;
3250	priv->params.rx_pauseframe_control = 1;
3251
3252	/* disable ports flow control, PFC, by default */
3253	priv->params.tx_priority_flow_control = 0;
3254	priv->params.rx_priority_flow_control = 0;
3255
3256#if (__FreeBSD_version < 1100000)
3257	/* compute path for sysctl */
3258	snprintf(path, sizeof(path), "dev.mce.%d.tx_pauseframe_control",
3259	    device_get_unit(priv->mdev->pdev->dev.bsddev));
3260
3261	/* try to fetch tunable, if any */
3262	TUNABLE_INT_FETCH(path, &priv->params.tx_pauseframe_control);
3263
3264	/* compute path for sysctl */
3265	snprintf(path, sizeof(path), "dev.mce.%d.rx_pauseframe_control",
3266	    device_get_unit(priv->mdev->pdev->dev.bsddev));
3267
3268	/* try to fetch tunable, if any */
3269	TUNABLE_INT_FETCH(path, &priv->params.rx_pauseframe_control);
3270
3271	for (x = 0; x != 8; x++) {
3272
3273		/* compute path for sysctl */
3274		snprintf(path, sizeof(path), "dev.mce.%d.tx_priority_flow_control_%u",
3275		    device_get_unit(priv->mdev->pdev->dev.bsddev), x);
3276
3277		/* try to fetch tunable, if any */
3278		if (TUNABLE_INT_FETCH(path, &value) == 0 && value != 0)
3279			priv->params.tx_priority_flow_control |= 1 << x;
3280
3281		/* compute path for sysctl */
3282		snprintf(path, sizeof(path), "dev.mce.%d.rx_priority_flow_control_%u",
3283		    device_get_unit(priv->mdev->pdev->dev.bsddev), x);
3284
3285		/* try to fetch tunable, if any */
3286		if (TUNABLE_INT_FETCH(path, &value) == 0 && value != 0)
3287			priv->params.rx_priority_flow_control |= 1 << x;
3288	}
3289#endif
3290
3291	/* register pauseframe SYSCTLs */
3292	SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3293	    OID_AUTO, "tx_pauseframe_control", CTLFLAG_RDTUN,
3294	    &priv->params.tx_pauseframe_control, 0,
3295	    "Set to enable TX pause frames. Clear to disable.");
3296
3297	SYSCTL_ADD_INT(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3298	    OID_AUTO, "rx_pauseframe_control", CTLFLAG_RDTUN,
3299	    &priv->params.rx_pauseframe_control, 0,
3300	    "Set to enable RX pause frames. Clear to disable.");
3301
3302	/* register priority_flow control, PFC, SYSCTLs */
3303	for (x = 0; x != 8; x++) {
3304		snprintf(path, sizeof(path), "tx_priority_flow_control_%u", x);
3305
3306		SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3307		    OID_AUTO, path, CTLTYPE_UINT | CTLFLAG_RWTUN |
3308		    CTLFLAG_MPSAFE, priv, x, &mlx5e_sysctl_tx_priority_flow_control, "IU",
3309		    "Set to enable TX ports flow control frames for given priority. Clear to disable.");
3310
3311		snprintf(path, sizeof(path), "rx_priority_flow_control_%u", x);
3312
3313		SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3314		    OID_AUTO, path, CTLTYPE_UINT | CTLFLAG_RWTUN |
3315		    CTLFLAG_MPSAFE, priv, x, &mlx5e_sysctl_rx_priority_flow_control, "IU",
3316		    "Set to enable RX ports flow control frames for given priority. Clear to disable.");
3317	}
3318
3319	PRIV_LOCK(priv);
3320
3321	/* range check */
3322	priv->params.tx_pauseframe_control =
3323	    priv->params.tx_pauseframe_control ? 1 : 0;
3324	priv->params.rx_pauseframe_control =
3325	    priv->params.rx_pauseframe_control ? 1 : 0;
3326
3327	/* update firmware */
3328	error = mlx5e_set_port_pause_and_pfc(priv);
3329	if (error == -EINVAL) {
3330		if_printf(priv->ifp,
3331		    "Global pauseframes must be disabled before enabling PFC.\n");
3332		priv->params.rx_priority_flow_control = 0;
3333		priv->params.tx_priority_flow_control = 0;
3334
3335		/* update firmware */
3336		(void) mlx5e_set_port_pause_and_pfc(priv);
3337	}
3338	PRIV_UNLOCK(priv);
3339}
3340
3341static void *
3342mlx5e_create_ifp(struct mlx5_core_dev *mdev)
3343{
3344	struct ifnet *ifp;
3345	struct mlx5e_priv *priv;
3346	u8 dev_addr[ETHER_ADDR_LEN] __aligned(4);
3347	struct sysctl_oid_list *child;
3348	int ncv = mdev->priv.eq_table.num_comp_vectors;
3349	char unit[16];
3350	int err;
3351	int i;
3352	u32 eth_proto_cap;
3353
3354	if (mlx5e_check_required_hca_cap(mdev)) {
3355		mlx5_core_dbg(mdev, "mlx5e_check_required_hca_cap() failed\n");
3356		return (NULL);
3357	}
3358	priv = malloc(sizeof(*priv), M_MLX5EN, M_WAITOK | M_ZERO);
3359	mlx5e_priv_mtx_init(priv);
3360
3361	ifp = priv->ifp = if_alloc(IFT_ETHER);
3362	if (ifp == NULL) {
3363		mlx5_core_err(mdev, "if_alloc() failed\n");
3364		goto err_free_priv;
3365	}
3366	ifp->if_softc = priv;
3367	if_initname(ifp, "mce", device_get_unit(mdev->pdev->dev.bsddev));
3368	ifp->if_mtu = ETHERMTU;
3369	ifp->if_init = mlx5e_open;
3370	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
3371	ifp->if_ioctl = mlx5e_ioctl;
3372	ifp->if_transmit = mlx5e_xmit;
3373	ifp->if_qflush = if_qflush;
3374#if (__FreeBSD_version >= 1100000)
3375	ifp->if_get_counter = mlx5e_get_counter;
3376#endif
3377	ifp->if_snd.ifq_maxlen = ifqmaxlen;
3378	/*
3379         * Set driver features
3380         */
3381	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6;
3382	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING;
3383	ifp->if_capabilities |= IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER;
3384	ifp->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU;
3385	ifp->if_capabilities |= IFCAP_LRO;
3386	ifp->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO;
3387	ifp->if_capabilities |= IFCAP_HWSTATS;
3388
3389	/* set TSO limits so that we don't have to drop TX packets */
3390	ifp->if_hw_tsomax = MLX5E_MAX_TX_PAYLOAD_SIZE - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
3391	ifp->if_hw_tsomaxsegcount = MLX5E_MAX_TX_MBUF_FRAGS - 1 /* hdr */;
3392	ifp->if_hw_tsomaxsegsize = MLX5E_MAX_TX_MBUF_SIZE;
3393
3394	ifp->if_capenable = ifp->if_capabilities;
3395	ifp->if_hwassist = 0;
3396	if (ifp->if_capenable & IFCAP_TSO)
3397		ifp->if_hwassist |= CSUM_TSO;
3398	if (ifp->if_capenable & IFCAP_TXCSUM)
3399		ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP);
3400	if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
3401		ifp->if_hwassist |= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
3402
3403	/* ifnet sysctl tree */
3404	sysctl_ctx_init(&priv->sysctl_ctx);
3405	priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_dev),
3406	    OID_AUTO, ifp->if_dname, CTLFLAG_RD, 0, "MLX5 ethernet - interface name");
3407	if (priv->sysctl_ifnet == NULL) {
3408		mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n");
3409		goto err_free_sysctl;
3410	}
3411	snprintf(unit, sizeof(unit), "%d", ifp->if_dunit);
3412	priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3413	    OID_AUTO, unit, CTLFLAG_RD, 0, "MLX5 ethernet - interface unit");
3414	if (priv->sysctl_ifnet == NULL) {
3415		mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n");
3416		goto err_free_sysctl;
3417	}
3418
3419	/* HW sysctl tree */
3420	child = SYSCTL_CHILDREN(device_get_sysctl_tree(mdev->pdev->dev.bsddev));
3421	priv->sysctl_hw = SYSCTL_ADD_NODE(&priv->sysctl_ctx, child,
3422	    OID_AUTO, "hw", CTLFLAG_RD, 0, "MLX5 ethernet dev hw");
3423	if (priv->sysctl_hw == NULL) {
3424		mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n");
3425		goto err_free_sysctl;
3426	}
3427	mlx5e_build_ifp_priv(mdev, priv, ncv);
3428	err = mlx5_alloc_map_uar(mdev, &priv->cq_uar);
3429	if (err) {
3430		if_printf(ifp, "%s: mlx5_alloc_map_uar failed, %d\n",
3431		    __func__, err);
3432		goto err_free_sysctl;
3433	}
3434	err = mlx5_core_alloc_pd(mdev, &priv->pdn);
3435	if (err) {
3436		if_printf(ifp, "%s: mlx5_core_alloc_pd failed, %d\n",
3437		    __func__, err);
3438		goto err_unmap_free_uar;
3439	}
3440	err = mlx5_alloc_transport_domain(mdev, &priv->tdn);
3441	if (err) {
3442		if_printf(ifp, "%s: mlx5_alloc_transport_domain failed, %d\n",
3443		    __func__, err);
3444		goto err_dealloc_pd;
3445	}
3446	err = mlx5e_create_mkey(priv, priv->pdn, &priv->mr);
3447	if (err) {
3448		if_printf(ifp, "%s: mlx5e_create_mkey failed, %d\n",
3449		    __func__, err);
3450		goto err_dealloc_transport_domain;
3451	}
3452	mlx5_query_nic_vport_mac_address(priv->mdev, 0, dev_addr);
3453
3454	/* check if we should generate a random MAC address */
3455	if (MLX5_CAP_GEN(priv->mdev, vport_group_manager) == 0 &&
3456	    is_zero_ether_addr(dev_addr)) {
3457		random_ether_addr(dev_addr);
3458		if_printf(ifp, "Assigned random MAC address\n");
3459	}
3460
3461	/* set default MTU */
3462	mlx5e_set_dev_port_mtu(ifp, ifp->if_mtu);
3463
3464	/* Set desc */
3465	device_set_desc(mdev->pdev->dev.bsddev, mlx5e_version);
3466
3467	/* Set default media status */
3468	priv->media_status_last = IFM_AVALID;
3469	priv->media_active_last = IFM_ETHER | IFM_AUTO |
3470	    IFM_ETH_RXPAUSE | IFM_FDX;
3471
3472	/* setup default pauseframes configuration */
3473	mlx5e_setup_pauseframes(priv);
3474
3475	err = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
3476	if (err) {
3477		eth_proto_cap = 0;
3478		if_printf(ifp, "%s: Query port media capability failed, %d\n",
3479		    __func__, err);
3480	}
3481
3482	/* Setup supported medias */
3483	ifmedia_init(&priv->media, IFM_IMASK | IFM_ETH_FMASK,
3484	    mlx5e_media_change, mlx5e_media_status);
3485
3486	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
3487		if (mlx5e_mode_table[i].baudrate == 0)
3488			continue;
3489		if (MLX5E_PROT_MASK(i) & eth_proto_cap) {
3490			ifmedia_add(&priv->media,
3491			    mlx5e_mode_table[i].subtype |
3492			    IFM_ETHER, 0, NULL);
3493			ifmedia_add(&priv->media,
3494			    mlx5e_mode_table[i].subtype |
3495			    IFM_ETHER | IFM_FDX |
3496			    IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
3497		}
3498	}
3499
3500	ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO, 0, NULL);
3501	ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO | IFM_FDX |
3502	    IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE, 0, NULL);
3503
3504	/* Set autoselect by default */
3505	ifmedia_set(&priv->media, IFM_ETHER | IFM_AUTO | IFM_FDX |
3506	    IFM_ETH_RXPAUSE | IFM_ETH_TXPAUSE);
3507	ether_ifattach(ifp, dev_addr);
3508
3509	/* Register for VLAN events */
3510	priv->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
3511	    mlx5e_vlan_rx_add_vid, priv, EVENTHANDLER_PRI_FIRST);
3512	priv->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
3513	    mlx5e_vlan_rx_kill_vid, priv, EVENTHANDLER_PRI_FIRST);
3514
3515	/* Link is down by default */
3516	if_link_state_change(ifp, LINK_STATE_DOWN);
3517
3518	mlx5e_enable_async_events(priv);
3519
3520	mlx5e_add_hw_stats(priv);
3521
3522	mlx5e_create_stats(&priv->stats.vport.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3523	    "vstats", mlx5e_vport_stats_desc, MLX5E_VPORT_STATS_NUM,
3524	    priv->stats.vport.arg);
3525
3526	mlx5e_create_stats(&priv->stats.pport.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
3527	    "pstats", mlx5e_pport_stats_desc, MLX5E_PPORT_STATS_NUM,
3528	    priv->stats.pport.arg);
3529
3530	mlx5e_create_ethtool(priv);
3531
3532	mtx_lock(&priv->async_events_mtx);
3533	mlx5e_update_stats(priv);
3534	mtx_unlock(&priv->async_events_mtx);
3535
3536	return (priv);
3537
3538err_dealloc_transport_domain:
3539	mlx5_dealloc_transport_domain(mdev, priv->tdn);
3540
3541err_dealloc_pd:
3542	mlx5_core_dealloc_pd(mdev, priv->pdn);
3543
3544err_unmap_free_uar:
3545	mlx5_unmap_free_uar(mdev, &priv->cq_uar);
3546
3547err_free_sysctl:
3548	sysctl_ctx_free(&priv->sysctl_ctx);
3549
3550	if_free(ifp);
3551
3552err_free_priv:
3553	mlx5e_priv_mtx_destroy(priv);
3554	free(priv, M_MLX5EN);
3555	return (NULL);
3556}
3557
3558static void
3559mlx5e_destroy_ifp(struct mlx5_core_dev *mdev, void *vpriv)
3560{
3561	struct mlx5e_priv *priv = vpriv;
3562	struct ifnet *ifp = priv->ifp;
3563
3564	/* don't allow more IOCTLs */
3565	priv->gone = 1;
3566
3567	/*
3568	 * Clear the device description to avoid use after free,
3569	 * because the bsddev is not destroyed when this module is
3570	 * unloaded:
3571	 */
3572	device_set_desc(mdev->pdev->dev.bsddev, NULL);
3573
3574	/* XXX wait a bit to allow IOCTL handlers to complete */
3575	pause("W", hz);
3576
3577	/* stop watchdog timer */
3578	callout_drain(&priv->watchdog);
3579
3580	if (priv->vlan_attach != NULL)
3581		EVENTHANDLER_DEREGISTER(vlan_config, priv->vlan_attach);
3582	if (priv->vlan_detach != NULL)
3583		EVENTHANDLER_DEREGISTER(vlan_unconfig, priv->vlan_detach);
3584
3585	/* make sure device gets closed */
3586	PRIV_LOCK(priv);
3587	mlx5e_close_locked(ifp);
3588	PRIV_UNLOCK(priv);
3589
3590	/* unregister device */
3591	ifmedia_removeall(&priv->media);
3592	ether_ifdetach(ifp);
3593	if_free(ifp);
3594
3595	/* destroy all remaining sysctl nodes */
3596	if (priv->sysctl_debug)
3597		sysctl_ctx_free(&priv->stats.port_stats_debug.ctx);
3598	sysctl_ctx_free(&priv->stats.vport.ctx);
3599	sysctl_ctx_free(&priv->stats.pport.ctx);
3600	sysctl_ctx_free(&priv->sysctl_ctx);
3601
3602	mlx5_core_destroy_mkey(priv->mdev, &priv->mr);
3603	mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
3604	mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
3605	mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
3606	mlx5e_disable_async_events(priv);
3607	flush_scheduled_work();
3608	mlx5e_priv_mtx_destroy(priv);
3609	free(priv, M_MLX5EN);
3610}
3611
3612static void *
3613mlx5e_get_ifp(void *vpriv)
3614{
3615	struct mlx5e_priv *priv = vpriv;
3616
3617	return (priv->ifp);
3618}
3619
3620static struct mlx5_interface mlx5e_interface = {
3621	.add = mlx5e_create_ifp,
3622	.remove = mlx5e_destroy_ifp,
3623	.event = mlx5e_async_event,
3624	.protocol = MLX5_INTERFACE_PROTOCOL_ETH,
3625	.get_dev = mlx5e_get_ifp,
3626};
3627
3628void
3629mlx5e_init(void)
3630{
3631	mlx5_register_interface(&mlx5e_interface);
3632}
3633
3634void
3635mlx5e_cleanup(void)
3636{
3637	mlx5_unregister_interface(&mlx5e_interface);
3638}
3639
3640module_init_order(mlx5e_init, SI_ORDER_THIRD);
3641module_exit_order(mlx5e_cleanup, SI_ORDER_THIRD);
3642
3643#if (__FreeBSD_version >= 1100000)
3644MODULE_DEPEND(mlx5en, linuxkpi, 1, 1, 1);
3645#endif
3646MODULE_DEPEND(mlx5en, mlx5, 1, 1, 1);
3647MODULE_VERSION(mlx5en, 1);
3648