xref: /freebsd/sys/dev/mlx5/mlx5_en/mlx5_en_main.c (revision 2830819497fb2deae3dd71574592ace55f2fbdba)
1 /*-
2  * Copyright (c) 2015 Mellanox Technologies. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS `AS IS' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  *
25  * $FreeBSD$
26  */
27 
28 #include "en.h"
29 
30 #include <sys/sockio.h>
31 #include <machine/atomic.h>
32 
33 #define	ETH_DRIVER_VERSION	"3.1.0-dev"
34 char mlx5e_version[] = "Mellanox Ethernet driver"
35     " (" ETH_DRIVER_VERSION ")";
36 
37 struct mlx5e_rq_param {
38 	u32	rqc [MLX5_ST_SZ_DW(rqc)];
39 	struct mlx5_wq_param wq;
40 };
41 
42 struct mlx5e_sq_param {
43 	u32	sqc [MLX5_ST_SZ_DW(sqc)];
44 	struct mlx5_wq_param wq;
45 };
46 
47 struct mlx5e_cq_param {
48 	u32	cqc [MLX5_ST_SZ_DW(cqc)];
49 	struct mlx5_wq_param wq;
50 	u16	eq_ix;
51 };
52 
53 struct mlx5e_channel_param {
54 	struct mlx5e_rq_param rq;
55 	struct mlx5e_sq_param sq;
56 	struct mlx5e_cq_param rx_cq;
57 	struct mlx5e_cq_param tx_cq;
58 };
59 
60 static const struct {
61 	u32	subtype;
62 	u64	baudrate;
63 }	mlx5e_mode_table[MLX5E_LINK_MODES_NUMBER] = {
64 
65 	[MLX5E_1000BASE_CX_SGMII] = {
66 		.subtype = IFM_1000_CX_SGMII,
67 		.baudrate = IF_Mbps(1000ULL),
68 	},
69 	[MLX5E_1000BASE_KX] = {
70 		.subtype = IFM_1000_KX,
71 		.baudrate = IF_Mbps(1000ULL),
72 	},
73 	[MLX5E_10GBASE_CX4] = {
74 		.subtype = IFM_10G_CX4,
75 		.baudrate = IF_Gbps(10ULL),
76 	},
77 	[MLX5E_10GBASE_KX4] = {
78 		.subtype = IFM_10G_KX4,
79 		.baudrate = IF_Gbps(10ULL),
80 	},
81 	[MLX5E_10GBASE_KR] = {
82 		.subtype = IFM_10G_KR,
83 		.baudrate = IF_Gbps(10ULL),
84 	},
85 	[MLX5E_20GBASE_KR2] = {
86 		.subtype = IFM_20G_KR2,
87 		.baudrate = IF_Gbps(20ULL),
88 	},
89 	[MLX5E_40GBASE_CR4] = {
90 		.subtype = IFM_40G_CR4,
91 		.baudrate = IF_Gbps(40ULL),
92 	},
93 	[MLX5E_40GBASE_KR4] = {
94 		.subtype = IFM_40G_KR4,
95 		.baudrate = IF_Gbps(40ULL),
96 	},
97 	[MLX5E_56GBASE_R4] = {
98 		.subtype = IFM_56G_R4,
99 		.baudrate = IF_Gbps(56ULL),
100 	},
101 	[MLX5E_10GBASE_CR] = {
102 		.subtype = IFM_10G_CR1,
103 		.baudrate = IF_Gbps(10ULL),
104 	},
105 	[MLX5E_10GBASE_SR] = {
106 		.subtype = IFM_10G_SR,
107 		.baudrate = IF_Gbps(10ULL),
108 	},
109 	[MLX5E_10GBASE_ER] = {
110 		.subtype = IFM_10G_ER,
111 		.baudrate = IF_Gbps(10ULL),
112 	},
113 	[MLX5E_40GBASE_SR4] = {
114 		.subtype = IFM_40G_SR4,
115 		.baudrate = IF_Gbps(40ULL),
116 	},
117 	[MLX5E_40GBASE_LR4] = {
118 		.subtype = IFM_40G_LR4,
119 		.baudrate = IF_Gbps(40ULL),
120 	},
121 	[MLX5E_100GBASE_CR4] = {
122 		.subtype = IFM_100G_CR4,
123 		.baudrate = IF_Gbps(100ULL),
124 	},
125 	[MLX5E_100GBASE_SR4] = {
126 		.subtype = IFM_100G_SR4,
127 		.baudrate = IF_Gbps(100ULL),
128 	},
129 	[MLX5E_100GBASE_KR4] = {
130 		.subtype = IFM_100G_KR4,
131 		.baudrate = IF_Gbps(100ULL),
132 	},
133 	[MLX5E_100GBASE_LR4] = {
134 		.subtype = IFM_100G_LR4,
135 		.baudrate = IF_Gbps(100ULL),
136 	},
137 	[MLX5E_100BASE_TX] = {
138 		.subtype = IFM_100_TX,
139 		.baudrate = IF_Mbps(100ULL),
140 	},
141 	[MLX5E_100BASE_T] = {
142 		.subtype = IFM_100_T,
143 		.baudrate = IF_Mbps(100ULL),
144 	},
145 	[MLX5E_10GBASE_T] = {
146 		.subtype = IFM_10G_T,
147 		.baudrate = IF_Gbps(10ULL),
148 	},
149 	[MLX5E_25GBASE_CR] = {
150 		.subtype = IFM_25G_CR,
151 		.baudrate = IF_Gbps(25ULL),
152 	},
153 	[MLX5E_25GBASE_KR] = {
154 		.subtype = IFM_25G_KR,
155 		.baudrate = IF_Gbps(25ULL),
156 	},
157 	[MLX5E_25GBASE_SR] = {
158 		.subtype = IFM_25G_SR,
159 		.baudrate = IF_Gbps(25ULL),
160 	},
161 	[MLX5E_50GBASE_CR2] = {
162 		.subtype = IFM_50G_CR2,
163 		.baudrate = IF_Gbps(50ULL),
164 	},
165 	[MLX5E_50GBASE_KR2] = {
166 		.subtype = IFM_50G_KR2,
167 		.baudrate = IF_Gbps(50ULL),
168 	},
169 };
170 
171 MALLOC_DEFINE(M_MLX5EN, "MLX5EN", "MLX5 Ethernet");
172 
173 static void
174 mlx5e_update_carrier(struct mlx5e_priv *priv)
175 {
176 	struct mlx5_core_dev *mdev = priv->mdev;
177 	u32 out[MLX5_ST_SZ_DW(ptys_reg)];
178 	u32 eth_proto_oper;
179 	int error;
180 	u8 port_state;
181 	u8 i;
182 
183 	port_state = mlx5_query_vport_state(mdev,
184 	    MLX5_QUERY_VPORT_STATE_IN_OP_MOD_VNIC_VPORT);
185 
186 	if (port_state == VPORT_STATE_UP) {
187 		priv->media_status_last |= IFM_ACTIVE;
188 	} else {
189 		priv->media_status_last &= ~IFM_ACTIVE;
190 		priv->media_active_last = IFM_ETHER;
191 		if_link_state_change(priv->ifp, LINK_STATE_DOWN);
192 		return;
193 	}
194 
195 	error = mlx5_query_port_ptys(mdev, out, sizeof(out), MLX5_PTYS_EN);
196 	if (error) {
197 		priv->media_active_last = IFM_ETHER;
198 		priv->ifp->if_baudrate = 1;
199 		if_printf(priv->ifp, "%s: query port ptys failed: 0x%x\n",
200 		    __func__, error);
201 		return;
202 	}
203 	eth_proto_oper = MLX5_GET(ptys_reg, out, eth_proto_oper);
204 
205 	for (i = 0; i != MLX5E_LINK_MODES_NUMBER; i++) {
206 		if (mlx5e_mode_table[i].baudrate == 0)
207 			continue;
208 		if (MLX5E_PROT_MASK(i) & eth_proto_oper) {
209 			priv->ifp->if_baudrate =
210 			    mlx5e_mode_table[i].baudrate;
211 			priv->media_active_last =
212 			    mlx5e_mode_table[i].subtype | IFM_ETHER | IFM_FDX;
213 		}
214 	}
215 	if_link_state_change(priv->ifp, LINK_STATE_UP);
216 }
217 
218 static void
219 mlx5e_media_status(struct ifnet *dev, struct ifmediareq *ifmr)
220 {
221 	struct mlx5e_priv *priv = dev->if_softc;
222 
223 	ifmr->ifm_status = priv->media_status_last;
224 	ifmr->ifm_active = priv->media_active_last |
225 	    (priv->params_ethtool.rx_pauseframe_control ? IFM_ETH_RXPAUSE : 0) |
226 	    (priv->params_ethtool.tx_pauseframe_control ? IFM_ETH_TXPAUSE : 0);
227 
228 }
229 
230 static u32
231 mlx5e_find_link_mode(u32 subtype)
232 {
233 	u32 i;
234 	u32 link_mode = 0;
235 
236 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
237 		if (mlx5e_mode_table[i].baudrate == 0)
238 			continue;
239 		if (mlx5e_mode_table[i].subtype == subtype)
240 			link_mode |= MLX5E_PROT_MASK(i);
241 	}
242 
243 	return (link_mode);
244 }
245 
246 static int
247 mlx5e_media_change(struct ifnet *dev)
248 {
249 	struct mlx5e_priv *priv = dev->if_softc;
250 	struct mlx5_core_dev *mdev = priv->mdev;
251 	u32 eth_proto_cap;
252 	u32 link_mode;
253 	int locked;
254 	int error;
255 
256 	locked = PRIV_LOCKED(priv);
257 	if (!locked)
258 		PRIV_LOCK(priv);
259 
260 	if (IFM_TYPE(priv->media.ifm_media) != IFM_ETHER) {
261 		error = EINVAL;
262 		goto done;
263 	}
264 
265 	link_mode = mlx5e_find_link_mode(IFM_SUBTYPE(priv->media.ifm_media));
266 
267 	error = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
268 	if (error) {
269 		if_printf(dev, "Query port media capability failed\n");
270 		goto done;
271 	}
272 	if (IFM_SUBTYPE(priv->media.ifm_media) == IFM_AUTO)
273 		link_mode = eth_proto_cap;
274 	else
275 		link_mode = link_mode & eth_proto_cap;
276 
277 	if (!link_mode) {
278 		if_printf(dev, "Not supported link mode requested\n");
279 		error = EINVAL;
280 		goto done;
281 	}
282 
283 	mlx5_set_port_status(mdev, MLX5_PORT_DOWN);
284 	mlx5_set_port_proto(mdev, link_mode, MLX5_PTYS_EN);
285 	mlx5_set_port_status(mdev, MLX5_PORT_UP);
286 
287 done:
288 	if (!locked)
289 		PRIV_UNLOCK(priv);
290 	return (error);
291 }
292 
293 static void
294 mlx5e_update_carrier_work(struct work_struct *work)
295 {
296 	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
297 	    update_carrier_work);
298 
299 	PRIV_LOCK(priv);
300 	if (test_bit(MLX5E_STATE_OPENED, &priv->state))
301 		mlx5e_update_carrier(priv);
302 	PRIV_UNLOCK(priv);
303 }
304 
305 static void
306 mlx5e_update_pport_counters(struct mlx5e_priv *priv)
307 {
308 	struct mlx5_core_dev *mdev = priv->mdev;
309 	struct mlx5e_pport_stats *s = &priv->stats.pport;
310 	struct mlx5e_port_stats_debug *s_debug = &priv->stats.port_stats_debug;
311 	u32 *in;
312 	u32 *out;
313 	u64 *ptr;
314 	unsigned sz = MLX5_ST_SZ_BYTES(ppcnt_reg);
315 	unsigned x;
316 	unsigned y;
317 
318 	in  = mlx5_vzalloc(sz);
319 	out = mlx5_vzalloc(sz);
320 	if (in == NULL || out == NULL)
321 		goto free_out;
322 
323 	ptr = (uint64_t *)MLX5_ADDR_OF(ppcnt_reg, out, counter_set);
324 
325 	MLX5_SET(ppcnt_reg, in, local_port, 1);
326 
327 	MLX5_SET(ppcnt_reg, in, grp, MLX5_IEEE_802_3_COUNTERS_GROUP);
328 	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
329 	for (x = y = 0; x != MLX5E_PPORT_IEEE802_3_STATS_NUM; x++, y++)
330 		s->arg[y] = be64toh(ptr[x]);
331 
332 	MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2819_COUNTERS_GROUP);
333 	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
334 	for (x = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM; x++, y++)
335 		s->arg[y] = be64toh(ptr[x]);
336 	for (y = 0; x != MLX5E_PPORT_RFC2819_STATS_NUM +
337 	   MLX5E_PPORT_RFC2819_STATS_DEBUG_NUM; x++, y++)
338 		s_debug->arg[y] = be64toh(ptr[x]);
339 
340 	MLX5_SET(ppcnt_reg, in, grp, MLX5_RFC_2863_COUNTERS_GROUP);
341 	mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
342 	for (x = 0; x != MLX5E_PPORT_RFC2863_STATS_DEBUG_NUM; x++, y++)
343 		s_debug->arg[y] = be64toh(ptr[x]);
344 
345 	MLX5_SET(ppcnt_reg, in, grp, MLX5_PHYSICAL_LAYER_COUNTERS_GROUP);
346         mlx5_core_access_reg(mdev, in, sz, out, sz, MLX5_REG_PPCNT, 0, 0);
347         for (x = 0; x != MLX5E_PPORT_PHYSICAL_LAYER_STATS_DEBUG_NUM; x++, y++)
348 		s_debug->arg[y] = be64toh(ptr[x]);
349 free_out:
350 	kvfree(in);
351 	kvfree(out);
352 }
353 
354 static void
355 mlx5e_update_stats_work(struct work_struct *work)
356 {
357 	struct mlx5e_priv *priv = container_of(work, struct mlx5e_priv,
358 	    update_stats_work);
359 	struct mlx5_core_dev *mdev = priv->mdev;
360 	struct mlx5e_vport_stats *s = &priv->stats.vport;
361 	struct mlx5e_rq_stats *rq_stats;
362 	struct mlx5e_sq_stats *sq_stats;
363 	struct buf_ring *sq_br;
364 #if (__FreeBSD_version < 1100000)
365 	struct ifnet *ifp = priv->ifp;
366 #endif
367 	u32 in[MLX5_ST_SZ_DW(query_vport_counter_in)];
368 	u32 *out;
369 	int outlen = MLX5_ST_SZ_BYTES(query_vport_counter_out);
370 	u64 tso_packets = 0;
371 	u64 tso_bytes = 0;
372 	u64 tx_queue_dropped = 0;
373 	u64 tx_defragged = 0;
374 	u64 tx_offload_none = 0;
375 	u64 lro_packets = 0;
376 	u64 lro_bytes = 0;
377 	u64 sw_lro_queued = 0;
378 	u64 sw_lro_flushed = 0;
379 	u64 rx_csum_none = 0;
380 	u64 rx_wqe_err = 0;
381 	u32 out_of_rx_buffer = 0;
382 	int i;
383 	int j;
384 
385 	PRIV_LOCK(priv);
386 	out = mlx5_vzalloc(outlen);
387 	if (out == NULL)
388 		goto free_out;
389 	if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
390 		goto free_out;
391 
392 	/* Collect firts the SW counters and then HW for consistency */
393 	for (i = 0; i < priv->params.num_channels; i++) {
394 		struct mlx5e_rq *rq = &priv->channel[i]->rq;
395 
396 		rq_stats = &priv->channel[i]->rq.stats;
397 
398 		/* collect stats from LRO */
399 		rq_stats->sw_lro_queued = rq->lro.lro_queued;
400 		rq_stats->sw_lro_flushed = rq->lro.lro_flushed;
401 		sw_lro_queued += rq_stats->sw_lro_queued;
402 		sw_lro_flushed += rq_stats->sw_lro_flushed;
403 		lro_packets += rq_stats->lro_packets;
404 		lro_bytes += rq_stats->lro_bytes;
405 		rx_csum_none += rq_stats->csum_none;
406 		rx_wqe_err += rq_stats->wqe_err;
407 
408 		for (j = 0; j < priv->num_tc; j++) {
409 			sq_stats = &priv->channel[i]->sq[j].stats;
410 			sq_br = priv->channel[i]->sq[j].br;
411 
412 			tso_packets += sq_stats->tso_packets;
413 			tso_bytes += sq_stats->tso_bytes;
414 			tx_queue_dropped += sq_stats->dropped;
415 			tx_queue_dropped += sq_br->br_drops;
416 			tx_defragged += sq_stats->defragged;
417 			tx_offload_none += sq_stats->csum_offload_none;
418 		}
419 	}
420 
421 	/* update counters */
422 	s->tso_packets = tso_packets;
423 	s->tso_bytes = tso_bytes;
424 	s->tx_queue_dropped = tx_queue_dropped;
425 	s->tx_defragged = tx_defragged;
426 	s->lro_packets = lro_packets;
427 	s->lro_bytes = lro_bytes;
428 	s->sw_lro_queued = sw_lro_queued;
429 	s->sw_lro_flushed = sw_lro_flushed;
430 	s->rx_csum_none = rx_csum_none;
431 	s->rx_wqe_err = rx_wqe_err;
432 
433 	/* HW counters */
434 	memset(in, 0, sizeof(in));
435 
436 	MLX5_SET(query_vport_counter_in, in, opcode,
437 	    MLX5_CMD_OP_QUERY_VPORT_COUNTER);
438 	MLX5_SET(query_vport_counter_in, in, op_mod, 0);
439 	MLX5_SET(query_vport_counter_in, in, other_vport, 0);
440 
441 	memset(out, 0, outlen);
442 
443 	if (mlx5_cmd_exec(mdev, in, sizeof(in), out, outlen))
444 		goto free_out;
445 
446 #define	MLX5_GET_CTR(out, x) \
447 	MLX5_GET64(query_vport_counter_out, out, x)
448 
449 	s->rx_error_packets =
450 	    MLX5_GET_CTR(out, received_errors.packets);
451 	s->rx_error_bytes =
452 	    MLX5_GET_CTR(out, received_errors.octets);
453 	s->tx_error_packets =
454 	    MLX5_GET_CTR(out, transmit_errors.packets);
455 	s->tx_error_bytes =
456 	    MLX5_GET_CTR(out, transmit_errors.octets);
457 
458 	s->rx_unicast_packets =
459 	    MLX5_GET_CTR(out, received_eth_unicast.packets);
460 	s->rx_unicast_bytes =
461 	    MLX5_GET_CTR(out, received_eth_unicast.octets);
462 	s->tx_unicast_packets =
463 	    MLX5_GET_CTR(out, transmitted_eth_unicast.packets);
464 	s->tx_unicast_bytes =
465 	    MLX5_GET_CTR(out, transmitted_eth_unicast.octets);
466 
467 	s->rx_multicast_packets =
468 	    MLX5_GET_CTR(out, received_eth_multicast.packets);
469 	s->rx_multicast_bytes =
470 	    MLX5_GET_CTR(out, received_eth_multicast.octets);
471 	s->tx_multicast_packets =
472 	    MLX5_GET_CTR(out, transmitted_eth_multicast.packets);
473 	s->tx_multicast_bytes =
474 	    MLX5_GET_CTR(out, transmitted_eth_multicast.octets);
475 
476 	s->rx_broadcast_packets =
477 	    MLX5_GET_CTR(out, received_eth_broadcast.packets);
478 	s->rx_broadcast_bytes =
479 	    MLX5_GET_CTR(out, received_eth_broadcast.octets);
480 	s->tx_broadcast_packets =
481 	    MLX5_GET_CTR(out, transmitted_eth_broadcast.packets);
482 	s->tx_broadcast_bytes =
483 	    MLX5_GET_CTR(out, transmitted_eth_broadcast.octets);
484 
485 	s->rx_packets =
486 	    s->rx_unicast_packets +
487 	    s->rx_multicast_packets +
488 	    s->rx_broadcast_packets;
489 	s->rx_bytes =
490 	    s->rx_unicast_bytes +
491 	    s->rx_multicast_bytes +
492 	    s->rx_broadcast_bytes;
493 	s->tx_packets =
494 	    s->tx_unicast_packets +
495 	    s->tx_multicast_packets +
496 	    s->tx_broadcast_packets;
497 	s->tx_bytes =
498 	    s->tx_unicast_bytes +
499 	    s->tx_multicast_bytes +
500 	    s->tx_broadcast_bytes;
501 
502 	/* Update calculated offload counters */
503 	s->tx_csum_offload = s->tx_packets - tx_offload_none;
504 	s->rx_csum_good = s->rx_packets - s->rx_csum_none;
505 
506 #if (__FreeBSD_version < 1100000)
507 	/* no get_counters interface in fbsd 10 */
508 	ifp->if_ipackets = s->rx_packets;
509 	ifp->if_ierrors  = s->rx_error_packets;
510 	ifp->if_opackets = s->tx_packets;
511 	ifp->if_oerrors = s->tx_error_packets;
512 	ifp->if_snd.ifq_drops = s->tx_queue_dropped;
513 	ifp->if_ibytes = s->rx_bytes;
514 	ifp->if_obytes = s->tx_bytes;
515 #endif
516 
517 	mlx5_vport_query_out_of_rx_buffer(mdev, priv->counter_set_id,
518 	    &out_of_rx_buffer);
519 
520 	/* Update per port counters */
521 	mlx5e_update_pport_counters(priv);
522 	priv->stats.pport.out_of_rx_buffer = (u64)out_of_rx_buffer;
523 free_out:
524 	kvfree(out);
525 	PRIV_UNLOCK(priv);
526 }
527 
528 static void
529 mlx5e_update_stats(void *arg)
530 {
531 	struct mlx5e_priv *priv = arg;
532 
533 	schedule_work(&priv->update_stats_work);
534 
535 	callout_reset(&priv->watchdog, hz, &mlx5e_update_stats, priv);
536 }
537 
538 static void
539 mlx5e_async_event_sub(struct mlx5e_priv *priv,
540     enum mlx5_dev_event event)
541 {
542 	switch (event) {
543 	case MLX5_DEV_EVENT_PORT_UP:
544 	case MLX5_DEV_EVENT_PORT_DOWN:
545 		schedule_work(&priv->update_carrier_work);
546 		break;
547 
548 	default:
549 		break;
550 	}
551 }
552 
553 static void
554 mlx5e_async_event(struct mlx5_core_dev *mdev, void *vpriv,
555     enum mlx5_dev_event event, unsigned long param)
556 {
557 	struct mlx5e_priv *priv = vpriv;
558 
559 	mtx_lock(&priv->async_events_mtx);
560 	if (test_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state))
561 		mlx5e_async_event_sub(priv, event);
562 	mtx_unlock(&priv->async_events_mtx);
563 }
564 
565 static void
566 mlx5e_enable_async_events(struct mlx5e_priv *priv)
567 {
568 	set_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state);
569 }
570 
571 static void
572 mlx5e_disable_async_events(struct mlx5e_priv *priv)
573 {
574 	mtx_lock(&priv->async_events_mtx);
575 	clear_bit(MLX5E_STATE_ASYNC_EVENTS_ENABLE, &priv->state);
576 	mtx_unlock(&priv->async_events_mtx);
577 }
578 
579 static const char *mlx5e_rq_stats_desc[] = {
580 	MLX5E_RQ_STATS(MLX5E_STATS_DESC)
581 };
582 
583 static int
584 mlx5e_create_rq(struct mlx5e_channel *c,
585     struct mlx5e_rq_param *param,
586     struct mlx5e_rq *rq)
587 {
588 	struct mlx5e_priv *priv = c->priv;
589 	struct mlx5_core_dev *mdev = priv->mdev;
590 	char buffer[16];
591 	void *rqc = param->rqc;
592 	void *rqc_wq = MLX5_ADDR_OF(rqc, rqc, wq);
593 	int wq_sz;
594 	int err;
595 	int i;
596 
597 	/* Create DMA descriptor TAG */
598 	if ((err = -bus_dma_tag_create(
599 		bus_get_dma_tag(mdev->pdev->dev.bsddev),
600 		1,			/* any alignment */
601 		0,			/* no boundary */
602 	        BUS_SPACE_MAXADDR,	/* lowaddr */
603 		BUS_SPACE_MAXADDR,	/* highaddr */
604 		NULL, NULL,		/* filter, filterarg */
605 		MJUM16BYTES,		/* maxsize */
606 		1,			/* nsegments */
607 		MJUM16BYTES,		/* maxsegsize */
608 		0,			/* flags */
609 		NULL, NULL,		/* lockfunc, lockfuncarg */
610 		&rq->dma_tag)))
611 		goto done;
612 
613 	err = mlx5_wq_ll_create(mdev, &param->wq, rqc_wq, &rq->wq,
614 	    &rq->wq_ctrl);
615 	if (err)
616 		goto err_free_dma_tag;
617 
618 	rq->wq.db = &rq->wq.db[MLX5_RCV_DBR];
619 
620 	if (priv->params.hw_lro_en)  {
621 		rq->wqe_sz = priv->params.lro_wqe_sz;
622 	}
623 	else {
624 		rq->wqe_sz = MLX5E_SW2MB_MTU(priv->ifp->if_mtu);
625 	}
626 	if (rq->wqe_sz > MJUM16BYTES) {
627 		err = -ENOMEM;
628 		goto err_rq_wq_destroy;
629 	} else if (rq->wqe_sz > MJUM9BYTES) {
630 		rq->wqe_sz = MJUM16BYTES;
631 	} else if (rq->wqe_sz > MJUMPAGESIZE) {
632 		rq->wqe_sz = MJUM9BYTES;
633 	} else if (rq->wqe_sz > MCLBYTES) {
634 		rq->wqe_sz = MJUMPAGESIZE;
635 	} else {
636 		rq->wqe_sz = MCLBYTES;
637 	}
638 
639 	wq_sz = mlx5_wq_ll_get_size(&rq->wq);
640 	rq->mbuf = malloc(wq_sz * sizeof(rq->mbuf[0]), M_MLX5EN, M_WAITOK | M_ZERO);
641 	if (rq->mbuf == NULL) {
642 		err = -ENOMEM;
643 		goto err_rq_wq_destroy;
644 	}
645 
646 	for (i = 0; i != wq_sz; i++) {
647 		struct mlx5e_rx_wqe *wqe = mlx5_wq_ll_get_wqe(&rq->wq, i);
648 		uint32_t byte_count = rq->wqe_sz - MLX5E_NET_IP_ALIGN;
649 
650 		err = -bus_dmamap_create(rq->dma_tag, 0, &rq->mbuf[i].dma_map);
651 		if (err != 0) {
652 			while (i--)
653 				bus_dmamap_destroy(rq->dma_tag, rq->mbuf[i].dma_map);
654 			goto err_rq_mbuf_free;
655 		}
656 		wqe->data.lkey = c->mkey_be;
657 		wqe->data.byte_count = cpu_to_be32(byte_count | MLX5_HW_START_PADDING);
658 	}
659 
660 	rq->pdev = c->pdev;
661 	rq->ifp = c->ifp;
662 	rq->channel = c;
663 	rq->ix = c->ix;
664 
665 	snprintf(buffer, sizeof(buffer), "rxstat%d", c->ix);
666 	mlx5e_create_stats(&rq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
667 	    buffer, mlx5e_rq_stats_desc, MLX5E_RQ_STATS_NUM,
668 	    rq->stats.arg);
669 
670 #ifdef HAVE_TURBO_LRO
671 	if (tcp_tlro_init(&rq->lro, c->ifp, MLX5E_BUDGET_MAX) != 0)
672 		rq->lro.mbuf = NULL;
673 #else
674 	if (tcp_lro_init(&rq->lro))
675 		rq->lro.lro_cnt = 0;
676 	else
677 		rq->lro.ifp = c->ifp;
678 #endif
679 	return (0);
680 
681 err_rq_mbuf_free:
682 	free(rq->mbuf, M_MLX5EN);
683 err_rq_wq_destroy:
684 	mlx5_wq_destroy(&rq->wq_ctrl);
685 err_free_dma_tag:
686 	bus_dma_tag_destroy(rq->dma_tag);
687 done:
688 	return (err);
689 }
690 
691 static void
692 mlx5e_destroy_rq(struct mlx5e_rq *rq)
693 {
694 	int wq_sz;
695 	int i;
696 
697 	/* destroy all sysctl nodes */
698 	sysctl_ctx_free(&rq->stats.ctx);
699 
700 	/* free leftover LRO packets, if any */
701 #ifdef HAVE_TURBO_LRO
702 	tcp_tlro_free(&rq->lro);
703 #else
704 	tcp_lro_free(&rq->lro);
705 #endif
706 	wq_sz = mlx5_wq_ll_get_size(&rq->wq);
707 	for (i = 0; i != wq_sz; i++) {
708 		if (rq->mbuf[i].mbuf != NULL) {
709 			bus_dmamap_unload(rq->dma_tag,
710 			    rq->mbuf[i].dma_map);
711 			m_freem(rq->mbuf[i].mbuf);
712 		}
713 		bus_dmamap_destroy(rq->dma_tag, rq->mbuf[i].dma_map);
714 	}
715 	free(rq->mbuf, M_MLX5EN);
716 	mlx5_wq_destroy(&rq->wq_ctrl);
717 }
718 
719 static int
720 mlx5e_enable_rq(struct mlx5e_rq *rq, struct mlx5e_rq_param *param)
721 {
722 	struct mlx5e_channel *c = rq->channel;
723 	struct mlx5e_priv *priv = c->priv;
724 	struct mlx5_core_dev *mdev = priv->mdev;
725 
726 	void *in;
727 	void *rqc;
728 	void *wq;
729 	int inlen;
730 	int err;
731 
732 	inlen = MLX5_ST_SZ_BYTES(create_rq_in) +
733 	    sizeof(u64) * rq->wq_ctrl.buf.npages;
734 	in = mlx5_vzalloc(inlen);
735 	if (in == NULL)
736 		return (-ENOMEM);
737 
738 	rqc = MLX5_ADDR_OF(create_rq_in, in, ctx);
739 	wq = MLX5_ADDR_OF(rqc, rqc, wq);
740 
741 	memcpy(rqc, param->rqc, sizeof(param->rqc));
742 
743 	MLX5_SET(rqc, rqc, cqn, c->rq.cq.mcq.cqn);
744 	MLX5_SET(rqc, rqc, state, MLX5_RQC_STATE_RST);
745 	MLX5_SET(rqc, rqc, flush_in_error_en, 1);
746 	if (priv->counter_set_id >= 0)
747 		MLX5_SET(rqc,  rqc, counter_set_id, priv->counter_set_id);
748 	MLX5_SET(wq, wq, log_wq_pg_sz, rq->wq_ctrl.buf.page_shift -
749 	    PAGE_SHIFT);
750 	MLX5_SET64(wq, wq, dbr_addr, rq->wq_ctrl.db.dma);
751 
752 	mlx5_fill_page_array(&rq->wq_ctrl.buf,
753 	    (__be64 *) MLX5_ADDR_OF(wq, wq, pas));
754 
755 	err = mlx5_core_create_rq(mdev, in, inlen, &rq->rqn);
756 
757 	kvfree(in);
758 
759 	return (err);
760 }
761 
762 static int
763 mlx5e_modify_rq(struct mlx5e_rq *rq, int curr_state, int next_state)
764 {
765 	struct mlx5e_channel *c = rq->channel;
766 	struct mlx5e_priv *priv = c->priv;
767 	struct mlx5_core_dev *mdev = priv->mdev;
768 
769 	void *in;
770 	void *rqc;
771 	int inlen;
772 	int err;
773 
774 	inlen = MLX5_ST_SZ_BYTES(modify_rq_in);
775 	in = mlx5_vzalloc(inlen);
776 	if (in == NULL)
777 		return (-ENOMEM);
778 
779 	rqc = MLX5_ADDR_OF(modify_rq_in, in, ctx);
780 
781 	MLX5_SET(modify_rq_in, in, rqn, rq->rqn);
782 	MLX5_SET(modify_rq_in, in, rq_state, curr_state);
783 	MLX5_SET(rqc, rqc, state, next_state);
784 
785 	err = mlx5_core_modify_rq(mdev, in, inlen);
786 
787 	kvfree(in);
788 
789 	return (err);
790 }
791 
792 static void
793 mlx5e_disable_rq(struct mlx5e_rq *rq)
794 {
795 	struct mlx5e_channel *c = rq->channel;
796 	struct mlx5e_priv *priv = c->priv;
797 	struct mlx5_core_dev *mdev = priv->mdev;
798 
799 	mlx5_core_destroy_rq(mdev, rq->rqn);
800 }
801 
802 static int
803 mlx5e_wait_for_min_rx_wqes(struct mlx5e_rq *rq)
804 {
805 	struct mlx5e_channel *c = rq->channel;
806 	struct mlx5e_priv *priv = c->priv;
807 	struct mlx5_wq_ll *wq = &rq->wq;
808 	int i;
809 
810 	for (i = 0; i < 1000; i++) {
811 		if (wq->cur_sz >= priv->params.min_rx_wqes)
812 			return (0);
813 
814 		msleep(4);
815 	}
816 	return (-ETIMEDOUT);
817 }
818 
819 static int
820 mlx5e_open_rq(struct mlx5e_channel *c,
821     struct mlx5e_rq_param *param,
822     struct mlx5e_rq *rq)
823 {
824 	int err;
825 	int i;
826 
827 	err = mlx5e_create_rq(c, param, rq);
828 	if (err)
829 		return (err);
830 
831 	err = mlx5e_enable_rq(rq, param);
832 	if (err)
833 		goto err_destroy_rq;
834 
835 	err = mlx5e_modify_rq(rq, MLX5_RQC_STATE_RST, MLX5_RQC_STATE_RDY);
836 	if (err)
837 		goto err_disable_rq;
838 
839 	c->rq.enabled = 1;
840 
841 	/*
842 	 * Test send queues, which will trigger
843 	 * "mlx5e_post_rx_wqes()":
844 	 */
845 	for (i = 0; i != c->num_tc; i++)
846 		mlx5e_send_nop(&c->sq[i], 1, true);
847 	return (0);
848 
849 err_disable_rq:
850 	mlx5e_disable_rq(rq);
851 err_destroy_rq:
852 	mlx5e_destroy_rq(rq);
853 
854 	return (err);
855 }
856 
857 static void
858 mlx5e_close_rq(struct mlx5e_rq *rq)
859 {
860 	rq->enabled = 0;
861 	mlx5e_modify_rq(rq, MLX5_RQC_STATE_RDY, MLX5_RQC_STATE_ERR);
862 }
863 
864 static void
865 mlx5e_close_rq_wait(struct mlx5e_rq *rq)
866 {
867 	/* wait till RQ is empty */
868 	while (!mlx5_wq_ll_is_empty(&rq->wq)) {
869 		msleep(4);
870 		rq->cq.mcq.comp(&rq->cq.mcq);
871 	}
872 
873 	mlx5e_disable_rq(rq);
874 	mlx5e_destroy_rq(rq);
875 }
876 
877 static void
878 mlx5e_free_sq_db(struct mlx5e_sq *sq)
879 {
880 	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
881 	int x;
882 
883 	for (x = 0; x != wq_sz; x++)
884 		bus_dmamap_destroy(sq->dma_tag, sq->mbuf[x].dma_map);
885 	free(sq->mbuf, M_MLX5EN);
886 }
887 
888 static int
889 mlx5e_alloc_sq_db(struct mlx5e_sq *sq)
890 {
891 	int wq_sz = mlx5_wq_cyc_get_size(&sq->wq);
892 	int err;
893 	int x;
894 
895 	sq->mbuf = malloc(wq_sz * sizeof(sq->mbuf[0]), M_MLX5EN, M_WAITOK | M_ZERO);
896 	if (sq->mbuf == NULL)
897 		return (-ENOMEM);
898 
899 	/* Create DMA descriptor MAPs */
900 	for (x = 0; x != wq_sz; x++) {
901 		err = -bus_dmamap_create(sq->dma_tag, 0, &sq->mbuf[x].dma_map);
902 		if (err != 0) {
903 			while (x--)
904 				bus_dmamap_destroy(sq->dma_tag, sq->mbuf[x].dma_map);
905 			free(sq->mbuf, M_MLX5EN);
906 			return (err);
907 		}
908 	}
909 	return (0);
910 }
911 
912 static const char *mlx5e_sq_stats_desc[] = {
913 	MLX5E_SQ_STATS(MLX5E_STATS_DESC)
914 };
915 
916 static int
917 mlx5e_create_sq(struct mlx5e_channel *c,
918     int tc,
919     struct mlx5e_sq_param *param,
920     struct mlx5e_sq *sq)
921 {
922 	struct mlx5e_priv *priv = c->priv;
923 	struct mlx5_core_dev *mdev = priv->mdev;
924 	char buffer[16];
925 
926 	void *sqc = param->sqc;
927 	void *sqc_wq = MLX5_ADDR_OF(sqc, sqc, wq);
928 	int err;
929 
930 	/* Create DMA descriptor TAG */
931 	if ((err = -bus_dma_tag_create(
932 		bus_get_dma_tag(mdev->pdev->dev.bsddev),
933 		1,				/* any alignment */
934 		0,				/* no boundary */
935 	        BUS_SPACE_MAXADDR,		/* lowaddr */
936 		BUS_SPACE_MAXADDR,		/* highaddr */
937 		NULL, NULL,			/* filter, filterarg */
938 		MLX5E_MAX_TX_PAYLOAD_SIZE,	/* maxsize */
939 		MLX5E_MAX_TX_MBUF_FRAGS,	/* nsegments */
940 		MLX5E_MAX_TX_MBUF_SIZE,		/* maxsegsize */
941 		0,				/* flags */
942 		NULL, NULL,			/* lockfunc, lockfuncarg */
943 		&sq->dma_tag)))
944 		goto done;
945 
946 	err = mlx5_alloc_map_uar(mdev, &sq->uar);
947 	if (err)
948 		goto err_free_dma_tag;
949 
950 	err = mlx5_wq_cyc_create(mdev, &param->wq, sqc_wq, &sq->wq,
951 	    &sq->wq_ctrl);
952 	if (err)
953 		goto err_unmap_free_uar;
954 
955 	sq->wq.db = &sq->wq.db[MLX5_SND_DBR];
956 	sq->uar_map = sq->uar.map;
957 	sq->uar_bf_map  = sq->uar.bf_map;
958 	sq->bf_buf_size = (1 << MLX5_CAP_GEN(mdev, log_bf_reg_size)) / 2;
959 
960 	err = mlx5e_alloc_sq_db(sq);
961 	if (err)
962 		goto err_sq_wq_destroy;
963 
964 	sq->pdev = c->pdev;
965 	sq->mkey_be = c->mkey_be;
966 	sq->channel = c;
967 	sq->tc = tc;
968 
969 	sq->br = buf_ring_alloc(MLX5E_SQ_TX_QUEUE_SIZE, M_MLX5EN,
970 	    M_WAITOK, &sq->lock);
971 	if (sq->br == NULL) {
972 		if_printf(c->ifp, "%s: Failed allocating sq drbr buffer\n",
973 		    __func__);
974 		err = -ENOMEM;
975 		goto err_free_sq_db;
976 	}
977 
978 	sq->sq_tq = taskqueue_create_fast("mlx5e_que", M_WAITOK,
979 	    taskqueue_thread_enqueue, &sq->sq_tq);
980 	if (sq->sq_tq == NULL) {
981 		if_printf(c->ifp, "%s: Failed allocating taskqueue\n",
982 		    __func__);
983 		err = -ENOMEM;
984 		goto err_free_drbr;
985 	}
986 	TASK_INIT(&sq->sq_task, 0, mlx5e_tx_que, sq);
987 	taskqueue_start_threads(&sq->sq_tq, 1, PI_NET, "%s tx sq",
988 		c->ifp->if_xname);
989 
990 
991 	snprintf(buffer, sizeof(buffer), "txstat%dtc%d", c->ix, tc);
992 	mlx5e_create_stats(&sq->stats.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
993 	    buffer, mlx5e_sq_stats_desc, MLX5E_SQ_STATS_NUM,
994 	    sq->stats.arg);
995 
996 	return (0);
997 
998 err_free_drbr:
999 	buf_ring_free(sq->br, M_MLX5EN);
1000 err_free_sq_db:
1001 	mlx5e_free_sq_db(sq);
1002 err_sq_wq_destroy:
1003 	mlx5_wq_destroy(&sq->wq_ctrl);
1004 
1005 err_unmap_free_uar:
1006 	mlx5_unmap_free_uar(mdev, &sq->uar);
1007 
1008 err_free_dma_tag:
1009 	bus_dma_tag_destroy(sq->dma_tag);
1010 done:
1011 	return (err);
1012 }
1013 
1014 static void
1015 mlx5e_destroy_sq(struct mlx5e_sq *sq)
1016 {
1017 	struct mlx5e_channel *c = sq->channel;
1018 	struct mlx5e_priv *priv = c->priv;
1019 
1020 	/* destroy all sysctl nodes */
1021 	sysctl_ctx_free(&sq->stats.ctx);
1022 
1023 	mlx5e_free_sq_db(sq);
1024 	mlx5_wq_destroy(&sq->wq_ctrl);
1025 	mlx5_unmap_free_uar(priv->mdev, &sq->uar);
1026 	taskqueue_drain(sq->sq_tq, &sq->sq_task);
1027 	taskqueue_free(sq->sq_tq);
1028 	buf_ring_free(sq->br, M_MLX5EN);
1029 }
1030 
1031 static int
1032 mlx5e_enable_sq(struct mlx5e_sq *sq, struct mlx5e_sq_param *param)
1033 {
1034 	struct mlx5e_channel *c = sq->channel;
1035 	struct mlx5e_priv *priv = c->priv;
1036 	struct mlx5_core_dev *mdev = priv->mdev;
1037 
1038 	void *in;
1039 	void *sqc;
1040 	void *wq;
1041 	int inlen;
1042 	int err;
1043 
1044 	inlen = MLX5_ST_SZ_BYTES(create_sq_in) +
1045 	    sizeof(u64) * sq->wq_ctrl.buf.npages;
1046 	in = mlx5_vzalloc(inlen);
1047 	if (in == NULL)
1048 		return (-ENOMEM);
1049 
1050 	sqc = MLX5_ADDR_OF(create_sq_in, in, ctx);
1051 	wq = MLX5_ADDR_OF(sqc, sqc, wq);
1052 
1053 	memcpy(sqc, param->sqc, sizeof(param->sqc));
1054 
1055 	MLX5_SET(sqc, sqc, tis_num_0, priv->tisn[sq->tc]);
1056 	MLX5_SET(sqc, sqc, cqn, c->sq[sq->tc].cq.mcq.cqn);
1057 	MLX5_SET(sqc, sqc, state, MLX5_SQC_STATE_RST);
1058 	MLX5_SET(sqc, sqc, tis_lst_sz, 1);
1059 	MLX5_SET(sqc, sqc, flush_in_error_en, 1);
1060 
1061 	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_CYCLIC);
1062 	MLX5_SET(wq, wq, uar_page, sq->uar.index);
1063 	MLX5_SET(wq, wq, log_wq_pg_sz, sq->wq_ctrl.buf.page_shift -
1064 	    PAGE_SHIFT);
1065 	MLX5_SET64(wq, wq, dbr_addr, sq->wq_ctrl.db.dma);
1066 
1067 	mlx5_fill_page_array(&sq->wq_ctrl.buf,
1068 	    (__be64 *) MLX5_ADDR_OF(wq, wq, pas));
1069 
1070 	err = mlx5_core_create_sq(mdev, in, inlen, &sq->sqn);
1071 
1072 	kvfree(in);
1073 
1074 	return (err);
1075 }
1076 
1077 static int
1078 mlx5e_modify_sq(struct mlx5e_sq *sq, int curr_state, int next_state)
1079 {
1080 	struct mlx5e_channel *c = sq->channel;
1081 	struct mlx5e_priv *priv = c->priv;
1082 	struct mlx5_core_dev *mdev = priv->mdev;
1083 
1084 	void *in;
1085 	void *sqc;
1086 	int inlen;
1087 	int err;
1088 
1089 	inlen = MLX5_ST_SZ_BYTES(modify_sq_in);
1090 	in = mlx5_vzalloc(inlen);
1091 	if (in == NULL)
1092 		return (-ENOMEM);
1093 
1094 	sqc = MLX5_ADDR_OF(modify_sq_in, in, ctx);
1095 
1096 	MLX5_SET(modify_sq_in, in, sqn, sq->sqn);
1097 	MLX5_SET(modify_sq_in, in, sq_state, curr_state);
1098 	MLX5_SET(sqc, sqc, state, next_state);
1099 
1100 	err = mlx5_core_modify_sq(mdev, in, inlen);
1101 
1102 	kvfree(in);
1103 
1104 	return (err);
1105 }
1106 
1107 static void
1108 mlx5e_disable_sq(struct mlx5e_sq *sq)
1109 {
1110 	struct mlx5e_channel *c = sq->channel;
1111 	struct mlx5e_priv *priv = c->priv;
1112 	struct mlx5_core_dev *mdev = priv->mdev;
1113 
1114 	mlx5_core_destroy_sq(mdev, sq->sqn);
1115 }
1116 
1117 static int
1118 mlx5e_open_sq(struct mlx5e_channel *c,
1119     int tc,
1120     struct mlx5e_sq_param *param,
1121     struct mlx5e_sq *sq)
1122 {
1123 	int err;
1124 
1125 	err = mlx5e_create_sq(c, tc, param, sq);
1126 	if (err)
1127 		return (err);
1128 
1129 	err = mlx5e_enable_sq(sq, param);
1130 	if (err)
1131 		goto err_destroy_sq;
1132 
1133 	err = mlx5e_modify_sq(sq, MLX5_SQC_STATE_RST, MLX5_SQC_STATE_RDY);
1134 	if (err)
1135 		goto err_disable_sq;
1136 
1137 	atomic_store_rel_int(&sq->queue_state, MLX5E_SQ_READY);
1138 
1139 	return (0);
1140 
1141 err_disable_sq:
1142 	mlx5e_disable_sq(sq);
1143 err_destroy_sq:
1144 	mlx5e_destroy_sq(sq);
1145 
1146 	return (err);
1147 }
1148 
1149 static void
1150 mlx5e_close_sq(struct mlx5e_sq *sq)
1151 {
1152 
1153 	/* ensure hw is notified of all pending wqes */
1154 	if (mlx5e_sq_has_room_for(sq, 1))
1155 		mlx5e_send_nop(sq, 1, true);
1156 
1157 	mlx5e_modify_sq(sq, MLX5_SQC_STATE_RDY, MLX5_SQC_STATE_ERR);
1158 }
1159 
1160 static void
1161 mlx5e_close_sq_wait(struct mlx5e_sq *sq)
1162 {
1163 	/* wait till SQ is empty */
1164 	while (sq->cc != sq->pc) {
1165 		msleep(4);
1166 		sq->cq.mcq.comp(&sq->cq.mcq);
1167 	}
1168 
1169 	mlx5e_disable_sq(sq);
1170 	mlx5e_destroy_sq(sq);
1171 }
1172 
1173 static int
1174 mlx5e_create_cq(struct mlx5e_channel *c,
1175     struct mlx5e_cq_param *param,
1176     struct mlx5e_cq *cq,
1177     mlx5e_cq_comp_t *comp)
1178 {
1179 	struct mlx5e_priv *priv = c->priv;
1180 	struct mlx5_core_dev *mdev = priv->mdev;
1181 	struct mlx5_core_cq *mcq = &cq->mcq;
1182 	int eqn_not_used;
1183 	int irqn;
1184 	int err;
1185 	u32 i;
1186 
1187 	param->wq.buf_numa_node = 0;
1188 	param->wq.db_numa_node = 0;
1189 	param->eq_ix = c->ix;
1190 
1191 	err = mlx5_cqwq_create(mdev, &param->wq, param->cqc, &cq->wq,
1192 	    &cq->wq_ctrl);
1193 	if (err)
1194 		return (err);
1195 
1196 	mlx5_vector2eqn(mdev, param->eq_ix, &eqn_not_used, &irqn);
1197 
1198 	mcq->cqe_sz = 64;
1199 	mcq->set_ci_db = cq->wq_ctrl.db.db;
1200 	mcq->arm_db = cq->wq_ctrl.db.db + 1;
1201 	*mcq->set_ci_db = 0;
1202 	*mcq->arm_db = 0;
1203 	mcq->vector = param->eq_ix;
1204 	mcq->comp = comp;
1205 	mcq->event = mlx5e_cq_error_event;
1206 	mcq->irqn = irqn;
1207 	mcq->uar = &priv->cq_uar;
1208 
1209 	for (i = 0; i < mlx5_cqwq_get_size(&cq->wq); i++) {
1210 		struct mlx5_cqe64 *cqe = mlx5_cqwq_get_wqe(&cq->wq, i);
1211 
1212 		cqe->op_own = 0xf1;
1213 	}
1214 
1215 	cq->channel = c;
1216 
1217 	return (0);
1218 }
1219 
1220 static void
1221 mlx5e_destroy_cq(struct mlx5e_cq *cq)
1222 {
1223 	mlx5_wq_destroy(&cq->wq_ctrl);
1224 }
1225 
1226 static int
1227 mlx5e_enable_cq(struct mlx5e_cq *cq, struct mlx5e_cq_param *param,
1228     u8 moderation_mode)
1229 {
1230 	struct mlx5e_channel *c = cq->channel;
1231 	struct mlx5e_priv *priv = c->priv;
1232 	struct mlx5_core_dev *mdev = priv->mdev;
1233 	struct mlx5_core_cq *mcq = &cq->mcq;
1234 	void *in;
1235 	void *cqc;
1236 	int inlen;
1237 	int irqn_not_used;
1238 	int eqn;
1239 	int err;
1240 
1241 	inlen = MLX5_ST_SZ_BYTES(create_cq_in) +
1242 	    sizeof(u64) * cq->wq_ctrl.buf.npages;
1243 	in = mlx5_vzalloc(inlen);
1244 	if (in == NULL)
1245 		return (-ENOMEM);
1246 
1247 	cqc = MLX5_ADDR_OF(create_cq_in, in, cq_context);
1248 
1249 	memcpy(cqc, param->cqc, sizeof(param->cqc));
1250 
1251 	mlx5_fill_page_array(&cq->wq_ctrl.buf,
1252 	    (__be64 *) MLX5_ADDR_OF(create_cq_in, in, pas));
1253 
1254 	mlx5_vector2eqn(mdev, param->eq_ix, &eqn, &irqn_not_used);
1255 
1256 	MLX5_SET(cqc, cqc, cq_period_mode, moderation_mode);
1257 	MLX5_SET(cqc, cqc, c_eqn, eqn);
1258 	MLX5_SET(cqc, cqc, uar_page, mcq->uar->index);
1259 	MLX5_SET(cqc, cqc, log_page_size, cq->wq_ctrl.buf.page_shift -
1260 	    PAGE_SHIFT);
1261 	MLX5_SET64(cqc, cqc, dbr_addr, cq->wq_ctrl.db.dma);
1262 
1263 	err = mlx5_core_create_cq(mdev, mcq, in, inlen);
1264 
1265 	kvfree(in);
1266 
1267 	if (err)
1268 		return (err);
1269 
1270 	mlx5e_cq_arm(cq);
1271 
1272 	return (0);
1273 }
1274 
1275 static void
1276 mlx5e_disable_cq(struct mlx5e_cq *cq)
1277 {
1278 	struct mlx5e_channel *c = cq->channel;
1279 	struct mlx5e_priv *priv = c->priv;
1280 	struct mlx5_core_dev *mdev = priv->mdev;
1281 
1282 	mlx5_core_destroy_cq(mdev, &cq->mcq);
1283 }
1284 
1285 static int
1286 mlx5e_open_cq(struct mlx5e_channel *c,
1287     struct mlx5e_cq_param *param,
1288     struct mlx5e_cq *cq,
1289     mlx5e_cq_comp_t *comp,
1290     u8 moderation_mode)
1291 {
1292 	int err;
1293 
1294 	err = mlx5e_create_cq(c, param, cq, comp);
1295 	if (err)
1296 		return (err);
1297 
1298 	err = mlx5e_enable_cq(cq, param, moderation_mode);
1299 	if (err)
1300 		goto err_destroy_cq;
1301 
1302 	return (0);
1303 
1304 err_destroy_cq:
1305 	mlx5e_destroy_cq(cq);
1306 
1307 	return (err);
1308 }
1309 
1310 static void
1311 mlx5e_close_cq(struct mlx5e_cq *cq)
1312 {
1313 	mlx5e_disable_cq(cq);
1314 	mlx5e_destroy_cq(cq);
1315 }
1316 
1317 static int
1318 mlx5e_open_tx_cqs(struct mlx5e_channel *c,
1319     struct mlx5e_channel_param *cparam)
1320 {
1321 	int err;
1322 	int tc;
1323 
1324 	for (tc = 0; tc < c->num_tc; tc++) {
1325 		/* open completion queue */
1326 		err = mlx5e_open_cq(c, &cparam->tx_cq, &c->sq[tc].cq,
1327 		    &mlx5e_tx_cq_comp, MLX5_CQ_PERIOD_MODE_START_FROM_EQE);
1328 		if (err)
1329 			goto err_close_tx_cqs;
1330 	}
1331 	return (0);
1332 
1333 err_close_tx_cqs:
1334 	for (tc--; tc >= 0; tc--)
1335 		mlx5e_close_cq(&c->sq[tc].cq);
1336 
1337 	return (err);
1338 }
1339 
1340 static void
1341 mlx5e_close_tx_cqs(struct mlx5e_channel *c)
1342 {
1343 	int tc;
1344 
1345 	for (tc = 0; tc < c->num_tc; tc++)
1346 		mlx5e_close_cq(&c->sq[tc].cq);
1347 }
1348 
1349 static int
1350 mlx5e_open_sqs(struct mlx5e_channel *c,
1351     struct mlx5e_channel_param *cparam)
1352 {
1353 	int err;
1354 	int tc;
1355 
1356 	for (tc = 0; tc < c->num_tc; tc++) {
1357 		err = mlx5e_open_sq(c, tc, &cparam->sq, &c->sq[tc]);
1358 		if (err)
1359 			goto err_close_sqs;
1360 	}
1361 
1362 	return (0);
1363 
1364 err_close_sqs:
1365 	for (tc--; tc >= 0; tc--) {
1366 		mlx5e_close_sq(&c->sq[tc]);
1367 		mlx5e_close_sq_wait(&c->sq[tc]);
1368 	}
1369 
1370 	return (err);
1371 }
1372 
1373 static void
1374 mlx5e_close_sqs(struct mlx5e_channel *c)
1375 {
1376 	int tc;
1377 
1378 	for (tc = 0; tc < c->num_tc; tc++)
1379 		mlx5e_close_sq(&c->sq[tc]);
1380 }
1381 
1382 static void
1383 mlx5e_close_sqs_wait(struct mlx5e_channel *c)
1384 {
1385 	int tc;
1386 
1387 	for (tc = 0; tc < c->num_tc; tc++)
1388 		mlx5e_close_sq_wait(&c->sq[tc]);
1389 }
1390 
1391 static void
1392 mlx5e_chan_mtx_init(struct mlx5e_channel *c)
1393 {
1394 	int tc;
1395 
1396 	mtx_init(&c->rq.mtx, "mlx5rx", MTX_NETWORK_LOCK, MTX_DEF);
1397 
1398 	for (tc = 0; tc < c->num_tc; tc++) {
1399 		mtx_init(&c->sq[tc].lock, "mlx5tx", MTX_NETWORK_LOCK, MTX_DEF);
1400 		mtx_init(&c->sq[tc].comp_lock, "mlx5comp", MTX_NETWORK_LOCK,
1401 		    MTX_DEF);
1402 	}
1403 }
1404 
1405 static void
1406 mlx5e_chan_mtx_destroy(struct mlx5e_channel *c)
1407 {
1408 	int tc;
1409 
1410 	mtx_destroy(&c->rq.mtx);
1411 
1412 	for (tc = 0; tc < c->num_tc; tc++) {
1413 		mtx_destroy(&c->sq[tc].lock);
1414 		mtx_destroy(&c->sq[tc].comp_lock);
1415 	}
1416 }
1417 
1418 static int
1419 mlx5e_open_channel(struct mlx5e_priv *priv, int ix,
1420     struct mlx5e_channel_param *cparam,
1421     struct mlx5e_channel * volatile *cp)
1422 {
1423 	struct mlx5e_channel *c;
1424 	u8 rx_moderation_mode;
1425 	int err;
1426 
1427 	c = malloc(sizeof(*c), M_MLX5EN, M_WAITOK | M_ZERO);
1428 	if (c == NULL)
1429 		return (-ENOMEM);
1430 
1431 	c->priv = priv;
1432 	c->ix = ix;
1433 	c->cpu = 0;
1434 	c->pdev = &priv->mdev->pdev->dev;
1435 	c->ifp = priv->ifp;
1436 	c->mkey_be = cpu_to_be32(priv->mr.key);
1437 	c->num_tc = priv->num_tc;
1438 
1439 	/* init mutexes */
1440 	mlx5e_chan_mtx_init(c);
1441 
1442 	/* open transmit completion queue */
1443 	err = mlx5e_open_tx_cqs(c, cparam);
1444 	if (err)
1445 		goto err_free;
1446 
1447 	switch (priv->params.rx_cq_moderation_mode) {
1448 	case 0:
1449 		rx_moderation_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
1450 		break;
1451 	default:
1452 		if (MLX5_CAP_GEN(priv->mdev, cq_period_start_from_cqe))
1453 			rx_moderation_mode = MLX5_CQ_PERIOD_MODE_START_FROM_CQE;
1454 		else
1455 			rx_moderation_mode = MLX5_CQ_PERIOD_MODE_START_FROM_EQE;
1456 		break;
1457 	}
1458 
1459 	/* open receive completion queue */
1460 	err = mlx5e_open_cq(c, &cparam->rx_cq, &c->rq.cq,
1461 	    &mlx5e_rx_cq_comp, rx_moderation_mode);
1462 	if (err)
1463 		goto err_close_tx_cqs;
1464 
1465 	err = mlx5e_open_sqs(c, cparam);
1466 	if (err)
1467 		goto err_close_rx_cq;
1468 
1469 	err = mlx5e_open_rq(c, &cparam->rq, &c->rq);
1470 	if (err)
1471 		goto err_close_sqs;
1472 
1473 	/* store channel pointer */
1474 	*cp = c;
1475 
1476 	/* poll receive queue initially */
1477 	c->rq.cq.mcq.comp(&c->rq.cq.mcq);
1478 
1479 	return (0);
1480 
1481 err_close_sqs:
1482 	mlx5e_close_sqs(c);
1483 	mlx5e_close_sqs_wait(c);
1484 
1485 err_close_rx_cq:
1486 	mlx5e_close_cq(&c->rq.cq);
1487 
1488 err_close_tx_cqs:
1489 	mlx5e_close_tx_cqs(c);
1490 
1491 err_free:
1492 	/* destroy mutexes */
1493 	mlx5e_chan_mtx_destroy(c);
1494 	free(c, M_MLX5EN);
1495 	return (err);
1496 }
1497 
1498 static void
1499 mlx5e_close_channel(struct mlx5e_channel * volatile *pp)
1500 {
1501 	struct mlx5e_channel *c = *pp;
1502 
1503 	/* check if channel is already closed */
1504 	if (c == NULL)
1505 		return;
1506 	mlx5e_close_rq(&c->rq);
1507 	mlx5e_close_sqs(c);
1508 }
1509 
1510 static void
1511 mlx5e_close_channel_wait(struct mlx5e_channel * volatile *pp)
1512 {
1513 	struct mlx5e_channel *c = *pp;
1514 
1515 	/* check if channel is already closed */
1516 	if (c == NULL)
1517 		return;
1518 	/* ensure channel pointer is no longer used */
1519 	*pp = NULL;
1520 
1521 	mlx5e_close_rq_wait(&c->rq);
1522 	mlx5e_close_sqs_wait(c);
1523 	mlx5e_close_cq(&c->rq.cq);
1524 	mlx5e_close_tx_cqs(c);
1525 	/* destroy mutexes */
1526 	mlx5e_chan_mtx_destroy(c);
1527 	free(c, M_MLX5EN);
1528 }
1529 
1530 static void
1531 mlx5e_build_rq_param(struct mlx5e_priv *priv,
1532     struct mlx5e_rq_param *param)
1533 {
1534 	void *rqc = param->rqc;
1535 	void *wq = MLX5_ADDR_OF(rqc, rqc, wq);
1536 
1537 	MLX5_SET(wq, wq, wq_type, MLX5_WQ_TYPE_LINKED_LIST);
1538 	MLX5_SET(wq, wq, end_padding_mode, MLX5_WQ_END_PAD_MODE_ALIGN);
1539 	MLX5_SET(wq, wq, log_wq_stride, ilog2(sizeof(struct mlx5e_rx_wqe)));
1540 	MLX5_SET(wq, wq, log_wq_sz, priv->params.log_rq_size);
1541 	MLX5_SET(wq, wq, pd, priv->pdn);
1542 
1543 	param->wq.buf_numa_node = 0;
1544 	param->wq.db_numa_node = 0;
1545 	param->wq.linear = 1;
1546 }
1547 
1548 static void
1549 mlx5e_build_sq_param(struct mlx5e_priv *priv,
1550     struct mlx5e_sq_param *param)
1551 {
1552 	void *sqc = param->sqc;
1553 	void *wq = MLX5_ADDR_OF(sqc, sqc, wq);
1554 
1555 	MLX5_SET(wq, wq, log_wq_sz, priv->params.log_sq_size);
1556 	MLX5_SET(wq, wq, log_wq_stride, ilog2(MLX5_SEND_WQE_BB));
1557 	MLX5_SET(wq, wq, pd, priv->pdn);
1558 
1559 	param->wq.buf_numa_node = 0;
1560 	param->wq.db_numa_node = 0;
1561 	param->wq.linear = 1;
1562 }
1563 
1564 static void
1565 mlx5e_build_common_cq_param(struct mlx5e_priv *priv,
1566     struct mlx5e_cq_param *param)
1567 {
1568 	void *cqc = param->cqc;
1569 
1570 	MLX5_SET(cqc, cqc, uar_page, priv->cq_uar.index);
1571 }
1572 
1573 static void
1574 mlx5e_build_rx_cq_param(struct mlx5e_priv *priv,
1575     struct mlx5e_cq_param *param)
1576 {
1577 	void *cqc = param->cqc;
1578 
1579 	MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_rq_size);
1580 	MLX5_SET(cqc, cqc, cq_period, priv->params.rx_cq_moderation_usec);
1581 	MLX5_SET(cqc, cqc, cq_max_count, priv->params.rx_cq_moderation_pkts);
1582 
1583 	mlx5e_build_common_cq_param(priv, param);
1584 }
1585 
1586 static void
1587 mlx5e_build_tx_cq_param(struct mlx5e_priv *priv,
1588     struct mlx5e_cq_param *param)
1589 {
1590 	void *cqc = param->cqc;
1591 
1592 	MLX5_SET(cqc, cqc, log_cq_size, priv->params.log_sq_size);
1593 	MLX5_SET(cqc, cqc, cq_period, priv->params.tx_cq_moderation_usec);
1594 	MLX5_SET(cqc, cqc, cq_max_count, priv->params.tx_cq_moderation_pkts);
1595 
1596 	mlx5e_build_common_cq_param(priv, param);
1597 }
1598 
1599 static void
1600 mlx5e_build_channel_param(struct mlx5e_priv *priv,
1601     struct mlx5e_channel_param *cparam)
1602 {
1603 	memset(cparam, 0, sizeof(*cparam));
1604 
1605 	mlx5e_build_rq_param(priv, &cparam->rq);
1606 	mlx5e_build_sq_param(priv, &cparam->sq);
1607 	mlx5e_build_rx_cq_param(priv, &cparam->rx_cq);
1608 	mlx5e_build_tx_cq_param(priv, &cparam->tx_cq);
1609 }
1610 
1611 static int
1612 mlx5e_open_channels(struct mlx5e_priv *priv)
1613 {
1614 	struct mlx5e_channel_param cparam;
1615 	void *ptr;
1616 	int err;
1617 	int i;
1618 	int j;
1619 
1620 	priv->channel = malloc(priv->params.num_channels *
1621 	    sizeof(struct mlx5e_channel *), M_MLX5EN, M_WAITOK | M_ZERO);
1622 	if (priv->channel == NULL)
1623 		return (-ENOMEM);
1624 
1625 	mlx5e_build_channel_param(priv, &cparam);
1626 	for (i = 0; i < priv->params.num_channels; i++) {
1627 		err = mlx5e_open_channel(priv, i, &cparam, &priv->channel[i]);
1628 		if (err)
1629 			goto err_close_channels;
1630 	}
1631 
1632 	for (j = 0; j < priv->params.num_channels; j++) {
1633 		err = mlx5e_wait_for_min_rx_wqes(&priv->channel[j]->rq);
1634 		if (err)
1635 			goto err_close_channels;
1636 	}
1637 
1638 	return (0);
1639 
1640 err_close_channels:
1641 	for (i--; i >= 0; i--) {
1642 		mlx5e_close_channel(&priv->channel[i]);
1643 		mlx5e_close_channel_wait(&priv->channel[i]);
1644 	}
1645 
1646 	/* remove "volatile" attribute from "channel" pointer */
1647 	ptr = __DECONST(void *, priv->channel);
1648 	priv->channel = NULL;
1649 
1650 	free(ptr, M_MLX5EN);
1651 
1652 	return (err);
1653 }
1654 
1655 static void
1656 mlx5e_close_channels(struct mlx5e_priv *priv)
1657 {
1658 	void *ptr;
1659 	int i;
1660 
1661 	if (priv->channel == NULL)
1662 		return;
1663 
1664 	for (i = 0; i < priv->params.num_channels; i++)
1665 		mlx5e_close_channel(&priv->channel[i]);
1666 	for (i = 0; i < priv->params.num_channels; i++)
1667 		mlx5e_close_channel_wait(&priv->channel[i]);
1668 
1669 	/* remove "volatile" attribute from "channel" pointer */
1670 	ptr = __DECONST(void *, priv->channel);
1671 	priv->channel = NULL;
1672 
1673 	free(ptr, M_MLX5EN);
1674 }
1675 
1676 static int
1677 mlx5e_open_tis(struct mlx5e_priv *priv, int tc)
1678 {
1679 	struct mlx5_core_dev *mdev = priv->mdev;
1680 	u32 in[MLX5_ST_SZ_DW(create_tis_in)];
1681 	void *tisc = MLX5_ADDR_OF(create_tis_in, in, ctx);
1682 
1683 	memset(in, 0, sizeof(in));
1684 
1685 	MLX5_SET(tisc, tisc, prio, tc);
1686 	MLX5_SET(tisc, tisc, transport_domain, priv->tdn);
1687 
1688 	return (mlx5_core_create_tis(mdev, in, sizeof(in), &priv->tisn[tc]));
1689 }
1690 
1691 static void
1692 mlx5e_close_tis(struct mlx5e_priv *priv, int tc)
1693 {
1694 	mlx5_core_destroy_tis(priv->mdev, priv->tisn[tc]);
1695 }
1696 
1697 static int
1698 mlx5e_open_tises(struct mlx5e_priv *priv)
1699 {
1700 	int num_tc = priv->num_tc;
1701 	int err;
1702 	int tc;
1703 
1704 	for (tc = 0; tc < num_tc; tc++) {
1705 		err = mlx5e_open_tis(priv, tc);
1706 		if (err)
1707 			goto err_close_tises;
1708 	}
1709 
1710 	return (0);
1711 
1712 err_close_tises:
1713 	for (tc--; tc >= 0; tc--)
1714 		mlx5e_close_tis(priv, tc);
1715 
1716 	return (err);
1717 }
1718 
1719 static void
1720 mlx5e_close_tises(struct mlx5e_priv *priv)
1721 {
1722 	int num_tc = priv->num_tc;
1723 	int tc;
1724 
1725 	for (tc = 0; tc < num_tc; tc++)
1726 		mlx5e_close_tis(priv, tc);
1727 }
1728 
1729 static int
1730 mlx5e_open_rqt(struct mlx5e_priv *priv)
1731 {
1732 	struct mlx5_core_dev *mdev = priv->mdev;
1733 	u32 *in;
1734 	u32 out[MLX5_ST_SZ_DW(create_rqt_out)];
1735 	void *rqtc;
1736 	int inlen;
1737 	int err;
1738 	int sz;
1739 	int i;
1740 
1741 	sz = 1 << priv->params.rx_hash_log_tbl_sz;
1742 
1743 	inlen = MLX5_ST_SZ_BYTES(create_rqt_in) + sizeof(u32) * sz;
1744 	in = mlx5_vzalloc(inlen);
1745 	if (in == NULL)
1746 		return (-ENOMEM);
1747 	rqtc = MLX5_ADDR_OF(create_rqt_in, in, rqt_context);
1748 
1749 	MLX5_SET(rqtc, rqtc, rqt_actual_size, sz);
1750 	MLX5_SET(rqtc, rqtc, rqt_max_size, sz);
1751 
1752 	for (i = 0; i < sz; i++) {
1753 		int ix = i % priv->params.num_channels;
1754 
1755 		MLX5_SET(rqtc, rqtc, rq_num[i], priv->channel[ix]->rq.rqn);
1756 	}
1757 
1758 	MLX5_SET(create_rqt_in, in, opcode, MLX5_CMD_OP_CREATE_RQT);
1759 
1760 	memset(out, 0, sizeof(out));
1761 	err = mlx5_cmd_exec_check_status(mdev, in, inlen, out, sizeof(out));
1762 	if (!err)
1763 		priv->rqtn = MLX5_GET(create_rqt_out, out, rqtn);
1764 
1765 	kvfree(in);
1766 
1767 	return (err);
1768 }
1769 
1770 static void
1771 mlx5e_close_rqt(struct mlx5e_priv *priv)
1772 {
1773 	u32 in[MLX5_ST_SZ_DW(destroy_rqt_in)];
1774 	u32 out[MLX5_ST_SZ_DW(destroy_rqt_out)];
1775 
1776 	memset(in, 0, sizeof(in));
1777 
1778 	MLX5_SET(destroy_rqt_in, in, opcode, MLX5_CMD_OP_DESTROY_RQT);
1779 	MLX5_SET(destroy_rqt_in, in, rqtn, priv->rqtn);
1780 
1781 	mlx5_cmd_exec_check_status(priv->mdev, in, sizeof(in), out,
1782 	    sizeof(out));
1783 }
1784 
1785 static void
1786 mlx5e_build_tir_ctx(struct mlx5e_priv *priv, u32 * tirc, int tt)
1787 {
1788 	void *hfso = MLX5_ADDR_OF(tirc, tirc, rx_hash_field_selector_outer);
1789 	__be32 *hkey;
1790 
1791 	MLX5_SET(tirc, tirc, transport_domain, priv->tdn);
1792 
1793 #define	ROUGH_MAX_L2_L3_HDR_SZ 256
1794 
1795 #define	MLX5_HASH_IP     (MLX5_HASH_FIELD_SEL_SRC_IP   |\
1796 			  MLX5_HASH_FIELD_SEL_DST_IP)
1797 
1798 #define	MLX5_HASH_ALL    (MLX5_HASH_FIELD_SEL_SRC_IP   |\
1799 			  MLX5_HASH_FIELD_SEL_DST_IP   |\
1800 			  MLX5_HASH_FIELD_SEL_L4_SPORT |\
1801 			  MLX5_HASH_FIELD_SEL_L4_DPORT)
1802 
1803 #define	MLX5_HASH_IP_IPSEC_SPI	(MLX5_HASH_FIELD_SEL_SRC_IP   |\
1804 				 MLX5_HASH_FIELD_SEL_DST_IP   |\
1805 				 MLX5_HASH_FIELD_SEL_IPSEC_SPI)
1806 
1807 	if (priv->params.hw_lro_en) {
1808 	    MLX5_SET(tirc, tirc, lro_enable_mask,
1809 	         MLX5_TIRC_LRO_ENABLE_MASK_IPV4_LRO |
1810 	         MLX5_TIRC_LRO_ENABLE_MASK_IPV6_LRO);
1811 	    MLX5_SET(tirc, tirc, lro_max_msg_sz,
1812 	         (priv->params.lro_wqe_sz -
1813 	         ROUGH_MAX_L2_L3_HDR_SZ) >> 8);
1814 		/* TODO: add the option to choose timer value dynamically */
1815 	    MLX5_SET(tirc, tirc, lro_timeout_period_usecs,
1816 	         MLX5_CAP_ETH(priv->mdev,
1817 	         lro_timer_supported_periods[2]));
1818 	}
1819 
1820 
1821 	switch (tt) {
1822 	case MLX5E_TT_ANY:
1823 		MLX5_SET(tirc, tirc, disp_type,
1824 		    MLX5_TIRC_DISP_TYPE_DIRECT);
1825 		MLX5_SET(tirc, tirc, inline_rqn,
1826 		    priv->channel[0]->rq.rqn);
1827 		break;
1828 	default:
1829 		MLX5_SET(tirc, tirc, disp_type,
1830 		    MLX5_TIRC_DISP_TYPE_INDIRECT);
1831 		MLX5_SET(tirc, tirc, indirect_table,
1832 		    priv->rqtn);
1833 		MLX5_SET(tirc, tirc, rx_hash_fn,
1834 		    MLX5_TIRC_RX_HASH_FN_HASH_TOEPLITZ);
1835 		MLX5_SET(tirc, tirc, rx_hash_symmetric, 1);
1836 		hkey = (__be32 *) MLX5_ADDR_OF(tirc, tirc, rx_hash_toeplitz_key);
1837 		hkey[0] = cpu_to_be32(0xD181C62C);
1838 		hkey[1] = cpu_to_be32(0xF7F4DB5B);
1839 		hkey[2] = cpu_to_be32(0x1983A2FC);
1840 		hkey[3] = cpu_to_be32(0x943E1ADB);
1841 		hkey[4] = cpu_to_be32(0xD9389E6B);
1842 		hkey[5] = cpu_to_be32(0xD1039C2C);
1843 		hkey[6] = cpu_to_be32(0xA74499AD);
1844 		hkey[7] = cpu_to_be32(0x593D56D9);
1845 		hkey[8] = cpu_to_be32(0xF3253C06);
1846 		hkey[9] = cpu_to_be32(0x2ADC1FFC);
1847 		break;
1848 	}
1849 
1850 	switch (tt) {
1851 	case MLX5E_TT_IPV4_TCP:
1852 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1853 		    MLX5_L3_PROT_TYPE_IPV4);
1854 		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
1855 		    MLX5_L4_PROT_TYPE_TCP);
1856 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1857 		    MLX5_HASH_ALL);
1858 		break;
1859 
1860 	case MLX5E_TT_IPV6_TCP:
1861 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1862 		    MLX5_L3_PROT_TYPE_IPV6);
1863 		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
1864 		    MLX5_L4_PROT_TYPE_TCP);
1865 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1866 		    MLX5_HASH_ALL);
1867 		break;
1868 
1869 	case MLX5E_TT_IPV4_UDP:
1870 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1871 		    MLX5_L3_PROT_TYPE_IPV4);
1872 		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
1873 		    MLX5_L4_PROT_TYPE_UDP);
1874 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1875 		    MLX5_HASH_ALL);
1876 		break;
1877 
1878 	case MLX5E_TT_IPV6_UDP:
1879 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1880 		    MLX5_L3_PROT_TYPE_IPV6);
1881 		MLX5_SET(rx_hash_field_select, hfso, l4_prot_type,
1882 		    MLX5_L4_PROT_TYPE_UDP);
1883 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1884 		    MLX5_HASH_ALL);
1885 		break;
1886 
1887 	case MLX5E_TT_IPV4_IPSEC_AH:
1888 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1889 		    MLX5_L3_PROT_TYPE_IPV4);
1890 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1891 		    MLX5_HASH_IP_IPSEC_SPI);
1892 		break;
1893 
1894 	case MLX5E_TT_IPV6_IPSEC_AH:
1895 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1896 		    MLX5_L3_PROT_TYPE_IPV6);
1897 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1898 		    MLX5_HASH_IP_IPSEC_SPI);
1899 		break;
1900 
1901 	case MLX5E_TT_IPV4_IPSEC_ESP:
1902 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1903 		    MLX5_L3_PROT_TYPE_IPV4);
1904 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1905 		    MLX5_HASH_IP_IPSEC_SPI);
1906 		break;
1907 
1908 	case MLX5E_TT_IPV6_IPSEC_ESP:
1909 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1910 		    MLX5_L3_PROT_TYPE_IPV6);
1911 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1912 		    MLX5_HASH_IP_IPSEC_SPI);
1913 		break;
1914 
1915 	case MLX5E_TT_IPV4:
1916 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1917 		    MLX5_L3_PROT_TYPE_IPV4);
1918 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1919 		    MLX5_HASH_IP);
1920 		break;
1921 
1922 	case MLX5E_TT_IPV6:
1923 		MLX5_SET(rx_hash_field_select, hfso, l3_prot_type,
1924 		    MLX5_L3_PROT_TYPE_IPV6);
1925 		MLX5_SET(rx_hash_field_select, hfso, selected_fields,
1926 		    MLX5_HASH_IP);
1927 		break;
1928 
1929 	default:
1930 		break;
1931 	}
1932 }
1933 
1934 static int
1935 mlx5e_open_tir(struct mlx5e_priv *priv, int tt)
1936 {
1937 	struct mlx5_core_dev *mdev = priv->mdev;
1938 	u32 *in;
1939 	void *tirc;
1940 	int inlen;
1941 	int err;
1942 
1943 	inlen = MLX5_ST_SZ_BYTES(create_tir_in);
1944 	in = mlx5_vzalloc(inlen);
1945 	if (in == NULL)
1946 		return (-ENOMEM);
1947 	tirc = MLX5_ADDR_OF(create_tir_in, in, tir_context);
1948 
1949 	mlx5e_build_tir_ctx(priv, tirc, tt);
1950 
1951 	err = mlx5_core_create_tir(mdev, in, inlen, &priv->tirn[tt]);
1952 
1953 	kvfree(in);
1954 
1955 	return (err);
1956 }
1957 
1958 static void
1959 mlx5e_close_tir(struct mlx5e_priv *priv, int tt)
1960 {
1961 	mlx5_core_destroy_tir(priv->mdev, priv->tirn[tt]);
1962 }
1963 
1964 static int
1965 mlx5e_open_tirs(struct mlx5e_priv *priv)
1966 {
1967 	int err;
1968 	int i;
1969 
1970 	for (i = 0; i < MLX5E_NUM_TT; i++) {
1971 		err = mlx5e_open_tir(priv, i);
1972 		if (err)
1973 			goto err_close_tirs;
1974 	}
1975 
1976 	return (0);
1977 
1978 err_close_tirs:
1979 	for (i--; i >= 0; i--)
1980 		mlx5e_close_tir(priv, i);
1981 
1982 	return (err);
1983 }
1984 
1985 static void
1986 mlx5e_close_tirs(struct mlx5e_priv *priv)
1987 {
1988 	int i;
1989 
1990 	for (i = 0; i < MLX5E_NUM_TT; i++)
1991 		mlx5e_close_tir(priv, i);
1992 }
1993 
1994 /*
1995  * SW MTU does not include headers,
1996  * HW MTU includes all headers and checksums.
1997  */
1998 static int
1999 mlx5e_set_dev_port_mtu(struct ifnet *ifp, int sw_mtu)
2000 {
2001 	struct mlx5e_priv *priv = ifp->if_softc;
2002 	struct mlx5_core_dev *mdev = priv->mdev;
2003 	int hw_mtu;
2004 	int min_mtu;
2005 	int err;
2006 
2007 	/*
2008 	 * Trying to set MTU to zero, in order
2009 	 * to find out the FW's minimal MTU
2010 	 */
2011 	err = mlx5_set_port_mtu(mdev, 0);
2012 	if (err)
2013 		return (err);
2014 	err = mlx5_query_port_oper_mtu(mdev, &min_mtu);
2015 	if (err) {
2016 		if_printf(ifp, "Query port minimal MTU failed\n");
2017 		return (err);
2018 	}
2019 
2020 	if (sw_mtu < MLX5E_HW2SW_MTU(min_mtu)) {
2021 		ifp->if_mtu = sw_mtu;
2022 		return (0);
2023 	}
2024 
2025 	err = mlx5_set_port_mtu(mdev, MLX5E_SW2HW_MTU(sw_mtu));
2026 	if (err)
2027 		return (err);
2028 
2029 	err = mlx5_query_port_oper_mtu(mdev, &hw_mtu);
2030 	if (!err) {
2031 		ifp->if_mtu = MLX5E_HW2SW_MTU(hw_mtu);
2032 
2033 		if (ifp->if_mtu != sw_mtu) {
2034 			if_printf(ifp, "Port MTU %d is different than "
2035 			    "ifp mtu %d\n", sw_mtu, (int)ifp->if_mtu);
2036 		}
2037 	} else {
2038 		if_printf(ifp, "Query port MTU, after setting new "
2039 		    "MTU value, failed\n");
2040 		ifp->if_mtu = sw_mtu;
2041 	}
2042 	return (0);
2043 }
2044 
2045 int
2046 mlx5e_open_locked(struct ifnet *ifp)
2047 {
2048 	struct mlx5e_priv *priv = ifp->if_softc;
2049 	int err;
2050 
2051 	/* check if already opened */
2052 	if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0)
2053 		return (0);
2054 
2055 	err = mlx5e_open_tises(priv);
2056 	if (err) {
2057 		if_printf(ifp, "%s: mlx5e_open_tises failed, %d\n",
2058 		    __func__, err);
2059 		return (err);
2060 	}
2061 	err = mlx5_vport_alloc_q_counter(priv->mdev, &priv->counter_set_id);
2062 	if (err) {
2063 		if_printf(priv->ifp,
2064 		    "%s: mlx5_vport_alloc_q_counter failed: %d\n",
2065 		    __func__, err);
2066 		goto err_close_tises;
2067 	}
2068 	err = mlx5e_open_channels(priv);
2069 	if (err) {
2070 		if_printf(ifp, "%s: mlx5e_open_channels failed, %d\n",
2071 		    __func__, err);
2072 		goto err_dalloc_q_counter;
2073 	}
2074 	err = mlx5e_open_rqt(priv);
2075 	if (err) {
2076 		if_printf(ifp, "%s: mlx5e_open_rqt failed, %d\n",
2077 		    __func__, err);
2078 		goto err_close_channels;
2079 	}
2080 	err = mlx5e_open_tirs(priv);
2081 	if (err) {
2082 		if_printf(ifp, "%s: mlx5e_open_tir failed, %d\n",
2083 		    __func__, err);
2084 		goto err_close_rqls;
2085 	}
2086 	err = mlx5e_open_flow_table(priv);
2087 	if (err) {
2088 		if_printf(ifp, "%s: mlx5e_open_flow_table failed, %d\n",
2089 		    __func__, err);
2090 		goto err_close_tirs;
2091 	}
2092 	err = mlx5e_add_all_vlan_rules(priv);
2093 	if (err) {
2094 		if_printf(ifp, "%s: mlx5e_add_all_vlan_rules failed, %d\n",
2095 		    __func__, err);
2096 		goto err_close_flow_table;
2097 	}
2098 	set_bit(MLX5E_STATE_OPENED, &priv->state);
2099 
2100 	mlx5e_update_carrier(priv);
2101 	mlx5e_set_rx_mode_core(priv);
2102 
2103 	return (0);
2104 
2105 err_close_flow_table:
2106 	mlx5e_close_flow_table(priv);
2107 
2108 err_close_tirs:
2109 	mlx5e_close_tirs(priv);
2110 
2111 err_close_rqls:
2112 	mlx5e_close_rqt(priv);
2113 
2114 err_close_channels:
2115 	mlx5e_close_channels(priv);
2116 
2117 err_dalloc_q_counter:
2118 	mlx5_vport_dealloc_q_counter(priv->mdev, priv->counter_set_id);
2119 
2120 err_close_tises:
2121 	mlx5e_close_tises(priv);
2122 
2123 	return (err);
2124 }
2125 
2126 static void
2127 mlx5e_open(void *arg)
2128 {
2129 	struct mlx5e_priv *priv = arg;
2130 
2131 	PRIV_LOCK(priv);
2132 	if (mlx5_set_port_status(priv->mdev, MLX5_PORT_UP))
2133 		if_printf(priv->ifp,
2134 		    "%s: Setting port status to up failed\n",
2135 		    __func__);
2136 
2137 	mlx5e_open_locked(priv->ifp);
2138 	priv->ifp->if_drv_flags |= IFF_DRV_RUNNING;
2139 	PRIV_UNLOCK(priv);
2140 }
2141 
2142 int
2143 mlx5e_close_locked(struct ifnet *ifp)
2144 {
2145 	struct mlx5e_priv *priv = ifp->if_softc;
2146 
2147 	/* check if already closed */
2148 	if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
2149 		return (0);
2150 
2151 	clear_bit(MLX5E_STATE_OPENED, &priv->state);
2152 
2153 	mlx5e_set_rx_mode_core(priv);
2154 	mlx5e_del_all_vlan_rules(priv);
2155 	if_link_state_change(priv->ifp, LINK_STATE_DOWN);
2156 	mlx5e_close_flow_table(priv);
2157 	mlx5e_close_tirs(priv);
2158 	mlx5e_close_rqt(priv);
2159 	mlx5e_close_channels(priv);
2160 	mlx5_vport_dealloc_q_counter(priv->mdev, priv->counter_set_id);
2161 	mlx5e_close_tises(priv);
2162 
2163 	return (0);
2164 }
2165 
2166 #if (__FreeBSD_version >= 1100000)
2167 static uint64_t
2168 mlx5e_get_counter(struct ifnet *ifp, ift_counter cnt)
2169 {
2170 	struct mlx5e_priv *priv = ifp->if_softc;
2171 	u64 retval;
2172 
2173 	/* PRIV_LOCK(priv); XXX not allowed */
2174 	switch (cnt) {
2175 	case IFCOUNTER_IPACKETS:
2176 		retval = priv->stats.vport.rx_packets;
2177 		break;
2178 	case IFCOUNTER_IERRORS:
2179 		retval = priv->stats.vport.rx_error_packets;
2180 		break;
2181 	case IFCOUNTER_OPACKETS:
2182 		retval = priv->stats.vport.tx_packets;
2183 		break;
2184 	case IFCOUNTER_OERRORS:
2185 		retval = priv->stats.vport.tx_error_packets;
2186 		break;
2187 	case IFCOUNTER_IBYTES:
2188 		retval = priv->stats.vport.rx_bytes;
2189 		break;
2190 	case IFCOUNTER_OBYTES:
2191 		retval = priv->stats.vport.tx_bytes;
2192 		break;
2193 	case IFCOUNTER_IMCASTS:
2194 		retval = priv->stats.vport.rx_multicast_packets;
2195 		break;
2196 	case IFCOUNTER_OMCASTS:
2197 		retval = priv->stats.vport.tx_multicast_packets;
2198 		break;
2199 	case IFCOUNTER_OQDROPS:
2200 		retval = priv->stats.vport.tx_queue_dropped;
2201 		break;
2202 	default:
2203 		retval = if_get_counter_default(ifp, cnt);
2204 		break;
2205 	}
2206 	/* PRIV_UNLOCK(priv); XXX not allowed */
2207 	return (retval);
2208 }
2209 #endif
2210 
2211 static void
2212 mlx5e_set_rx_mode(struct ifnet *ifp)
2213 {
2214 	struct mlx5e_priv *priv = ifp->if_softc;
2215 
2216 	schedule_work(&priv->set_rx_mode_work);
2217 }
2218 
2219 static int
2220 mlx5e_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
2221 {
2222 	struct mlx5e_priv *priv;
2223 	struct ifreq *ifr;
2224 	struct ifi2creq i2c;
2225 	int error = 0;
2226 	int mask = 0;
2227 	int size_read = 0;
2228 	int module_num;
2229 	int max_mtu;
2230 
2231 	priv = ifp->if_softc;
2232 
2233 	/* check if detaching */
2234 	if (priv == NULL || priv->gone != 0)
2235 		return (ENXIO);
2236 
2237 	switch (command) {
2238 	case SIOCSIFMTU:
2239 		ifr = (struct ifreq *)data;
2240 
2241 		PRIV_LOCK(priv);
2242 		mlx5_query_port_max_mtu(priv->mdev, &max_mtu);
2243 
2244 		if (ifr->ifr_mtu >= MLX5E_MTU_MIN &&
2245 		    ifr->ifr_mtu <= MIN(MLX5E_MTU_MAX, max_mtu)) {
2246 			int was_opened;
2247 
2248 			was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
2249 			if (was_opened)
2250 				mlx5e_close_locked(ifp);
2251 
2252 			/* set new MTU */
2253 			mlx5e_set_dev_port_mtu(ifp, ifr->ifr_mtu);
2254 
2255 			if (was_opened)
2256 				mlx5e_open_locked(ifp);
2257 		} else {
2258 			error = EINVAL;
2259 			if_printf(ifp, "Invalid MTU value. Min val: %d, Max val: %d\n",
2260 			    MLX5E_MTU_MIN, MIN(MLX5E_MTU_MAX, max_mtu));
2261 		}
2262 		PRIV_UNLOCK(priv);
2263 		break;
2264 	case SIOCSIFFLAGS:
2265 		if ((ifp->if_flags & IFF_UP) &&
2266 		    (ifp->if_drv_flags & IFF_DRV_RUNNING)) {
2267 			mlx5e_set_rx_mode(ifp);
2268 			break;
2269 		}
2270 		PRIV_LOCK(priv);
2271 		if (ifp->if_flags & IFF_UP) {
2272 			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
2273 				if (test_bit(MLX5E_STATE_OPENED, &priv->state) == 0)
2274 					mlx5e_open_locked(ifp);
2275 				ifp->if_drv_flags |= IFF_DRV_RUNNING;
2276 				mlx5_set_port_status(priv->mdev, MLX5_PORT_UP);
2277 			}
2278 		} else {
2279 			if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
2280 				mlx5_set_port_status(priv->mdev,
2281 				    MLX5_PORT_DOWN);
2282 				if (test_bit(MLX5E_STATE_OPENED, &priv->state) != 0)
2283 					mlx5e_close_locked(ifp);
2284 				mlx5e_update_carrier(priv);
2285 				ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
2286 			}
2287 		}
2288 		PRIV_UNLOCK(priv);
2289 		break;
2290 	case SIOCADDMULTI:
2291 	case SIOCDELMULTI:
2292 		mlx5e_set_rx_mode(ifp);
2293 		break;
2294 	case SIOCSIFMEDIA:
2295 	case SIOCGIFMEDIA:
2296 	case SIOCGIFXMEDIA:
2297 		ifr = (struct ifreq *)data;
2298 		error = ifmedia_ioctl(ifp, ifr, &priv->media, command);
2299 		break;
2300 	case SIOCSIFCAP:
2301 		ifr = (struct ifreq *)data;
2302 		PRIV_LOCK(priv);
2303 		mask = ifr->ifr_reqcap ^ ifp->if_capenable;
2304 
2305 		if (mask & IFCAP_TXCSUM) {
2306 			ifp->if_capenable ^= IFCAP_TXCSUM;
2307 			ifp->if_hwassist ^= (CSUM_TCP | CSUM_UDP | CSUM_IP);
2308 
2309 			if (IFCAP_TSO4 & ifp->if_capenable &&
2310 			    !(IFCAP_TXCSUM & ifp->if_capenable)) {
2311 				ifp->if_capenable &= ~IFCAP_TSO4;
2312 				ifp->if_hwassist &= ~CSUM_IP_TSO;
2313 				if_printf(ifp,
2314 				    "tso4 disabled due to -txcsum.\n");
2315 			}
2316 		}
2317 		if (mask & IFCAP_TXCSUM_IPV6) {
2318 			ifp->if_capenable ^= IFCAP_TXCSUM_IPV6;
2319 			ifp->if_hwassist ^= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
2320 
2321 			if (IFCAP_TSO6 & ifp->if_capenable &&
2322 			    !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
2323 				ifp->if_capenable &= ~IFCAP_TSO6;
2324 				ifp->if_hwassist &= ~CSUM_IP6_TSO;
2325 				if_printf(ifp,
2326 				    "tso6 disabled due to -txcsum6.\n");
2327 			}
2328 		}
2329 		if (mask & IFCAP_RXCSUM)
2330 			ifp->if_capenable ^= IFCAP_RXCSUM;
2331 		if (mask & IFCAP_RXCSUM_IPV6)
2332 			ifp->if_capenable ^= IFCAP_RXCSUM_IPV6;
2333 
2334 		if (mask & IFCAP_TSO4) {
2335 			if (!(IFCAP_TSO4 & ifp->if_capenable) &&
2336 			    !(IFCAP_TXCSUM & ifp->if_capenable)) {
2337 				if_printf(ifp, "enable txcsum first.\n");
2338 				error = EAGAIN;
2339 				goto out;
2340 			}
2341 			ifp->if_capenable ^= IFCAP_TSO4;
2342 			ifp->if_hwassist ^= CSUM_IP_TSO;
2343 		}
2344 		if (mask & IFCAP_TSO6) {
2345 			if (!(IFCAP_TSO6 & ifp->if_capenable) &&
2346 			    !(IFCAP_TXCSUM_IPV6 & ifp->if_capenable)) {
2347 				if_printf(ifp, "enable txcsum6 first.\n");
2348 				error = EAGAIN;
2349 				goto out;
2350 			}
2351 			ifp->if_capenable ^= IFCAP_TSO6;
2352 			ifp->if_hwassist ^= CSUM_IP6_TSO;
2353 		}
2354 
2355 		if (mask & IFCAP_VLAN_HWFILTER) {
2356 			if (ifp->if_capenable & IFCAP_VLAN_HWFILTER)
2357 				mlx5e_disable_vlan_filter(priv);
2358 			else
2359 				mlx5e_enable_vlan_filter(priv);
2360 
2361 			ifp->if_capenable ^= IFCAP_VLAN_HWFILTER;
2362 		}
2363 		if (mask & IFCAP_VLAN_HWTAGGING)
2364 			ifp->if_capenable ^= IFCAP_VLAN_HWTAGGING;
2365 
2366 		if (mask & IFCAP_WOL_MAGIC)
2367 			ifp->if_capenable ^= IFCAP_WOL_MAGIC;
2368 
2369 		VLAN_CAPABILITIES(ifp);
2370 		/* turn off LRO means also turn of HW LRO - if it's on */
2371 		if (mask & IFCAP_LRO ) {
2372 			int was_opened = test_bit(MLX5E_STATE_OPENED, &priv->state);
2373 			bool need_restart = false;
2374 
2375 			ifp->if_capenable ^= IFCAP_LRO;
2376 			if (!(ifp->if_capenable & IFCAP_LRO)) {
2377 				if (priv->params.hw_lro_en) {
2378 					priv->params.hw_lro_en = false;
2379 					need_restart = true;
2380 					/* Not sure this is the correct way */
2381 					priv->params_ethtool.hw_lro  = priv->params.hw_lro_en;
2382 				}
2383 			}
2384 			if (was_opened && need_restart) {
2385 				mlx5e_close_locked(ifp);
2386 				mlx5e_open_locked(ifp);
2387 			}
2388 		}
2389 out:
2390 		PRIV_UNLOCK(priv);
2391 		break;
2392 
2393 	case SIOCGI2C:
2394 		ifr = (struct ifreq *)data;
2395 
2396 		/* Copy from the user-space address ifr_data to the kernel-space address i2c */
2397 		error = copyin(ifr->ifr_data, &i2c, sizeof(i2c));
2398 		if (error)
2399 			break;
2400 
2401 		if (i2c.len > sizeof(i2c.data)) {
2402 			error = EINVAL;
2403 			break;
2404 		}
2405 
2406 		PRIV_LOCK(priv);
2407 		/* Get module_num which is required for the query_eeprom */
2408 		error = mlx5_query_module_num(priv->mdev, &module_num);
2409 		if (error) {
2410 			if_printf(ifp, "Query module num failed, eeprom "
2411 			    "reading is not supported\n");
2412 			goto err_i2c;
2413 		}
2414 
2415 		/*
2416 		 * Note that we ignore i2c.addr here. The driver hardcodes
2417 		 * the address to 0x50, while standard expects it to be 0xA0.
2418 		 */
2419 		error = mlx5_query_eeprom(priv->mdev,
2420 		    MLX5E_I2C_ADDR_LOW, MLX5E_EEPROM_LOW_PAGE,
2421 		    (uint32_t)i2c.offset, (uint32_t)i2c.len, module_num,
2422 		    (uint32_t *)i2c.data, &size_read);
2423 		if (error) {
2424 			if_printf(ifp, "Query eeprom failed, eeprom "
2425 			    "reading is not supported\n");
2426 			goto err_i2c;
2427 		}
2428 
2429 		if (i2c.len > MLX5_EEPROM_MAX_BYTES) {
2430 			error = mlx5_query_eeprom(priv->mdev,
2431 			    MLX5E_I2C_ADDR_LOW, MLX5E_EEPROM_LOW_PAGE,
2432 			    (uint32_t)(i2c.offset + size_read),
2433 			    (uint32_t)(i2c.len - size_read), module_num,
2434 			    (uint32_t *)(i2c.data + size_read), &size_read);
2435 		}
2436 		if (error) {
2437 			if_printf(ifp, "Query eeprom failed, eeprom "
2438 			    "reading is not supported\n");
2439 			goto err_i2c;
2440 		}
2441 
2442 		error = copyout(&i2c, ifr->ifr_data, sizeof(i2c));
2443 err_i2c:
2444 		PRIV_UNLOCK(priv);
2445 		break;
2446 
2447 	default:
2448 		error = ether_ioctl(ifp, command, data);
2449 		break;
2450 	}
2451 	return (error);
2452 }
2453 
2454 static int
2455 mlx5e_check_required_hca_cap(struct mlx5_core_dev *mdev)
2456 {
2457 	/*
2458 	 * TODO: uncoment once FW really sets all these bits if
2459 	 * (!mdev->caps.eth.rss_ind_tbl_cap || !mdev->caps.eth.csum_cap ||
2460 	 * !mdev->caps.eth.max_lso_cap || !mdev->caps.eth.vlan_cap ||
2461 	 * !(mdev->caps.gen.flags & MLX5_DEV_CAP_FLAG_SCQE_BRK_MOD)) return
2462 	 * -ENOTSUPP;
2463 	 */
2464 
2465 	/* TODO: add more must-to-have features */
2466 
2467 	return (0);
2468 }
2469 
2470 static void
2471 mlx5e_build_ifp_priv(struct mlx5_core_dev *mdev,
2472     struct mlx5e_priv *priv,
2473     int num_comp_vectors)
2474 {
2475 	/*
2476 	 * TODO: Consider link speed for setting "log_sq_size",
2477 	 * "log_rq_size" and "cq_moderation_xxx":
2478 	 */
2479 	priv->params.log_sq_size =
2480 	    MLX5E_PARAMS_DEFAULT_LOG_SQ_SIZE;
2481 	priv->params.log_rq_size =
2482 	    MLX5E_PARAMS_DEFAULT_LOG_RQ_SIZE;
2483 	priv->params.rx_cq_moderation_usec =
2484 	    MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ?
2485 	    MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC_FROM_CQE :
2486 	    MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_USEC;
2487 	priv->params.rx_cq_moderation_mode =
2488 	    MLX5_CAP_GEN(mdev, cq_period_start_from_cqe) ? 1 : 0;
2489 	priv->params.rx_cq_moderation_pkts =
2490 	    MLX5E_PARAMS_DEFAULT_RX_CQ_MODERATION_PKTS;
2491 	priv->params.tx_cq_moderation_usec =
2492 	    MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_USEC;
2493 	priv->params.tx_cq_moderation_pkts =
2494 	    MLX5E_PARAMS_DEFAULT_TX_CQ_MODERATION_PKTS;
2495 	priv->params.min_rx_wqes =
2496 	    MLX5E_PARAMS_DEFAULT_MIN_RX_WQES;
2497 	priv->params.rx_hash_log_tbl_sz =
2498 	    (order_base_2(num_comp_vectors) >
2499 	    MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ) ?
2500 	    order_base_2(num_comp_vectors) :
2501 	    MLX5E_PARAMS_DEFAULT_RX_HASH_LOG_TBL_SZ;
2502 	priv->params.num_tc = 1;
2503 	priv->params.default_vlan_prio = 0;
2504 	priv->counter_set_id = -1;
2505 
2506 	/*
2507 	 * hw lro is currently defaulted to off.
2508 	 * when it won't anymore we will consider the
2509 	 * HW capability: "!!MLX5_CAP_ETH(mdev, lro_cap)"
2510 	*/
2511 	priv->params.hw_lro_en = false;
2512 	priv->params.lro_wqe_sz = MLX5E_PARAMS_DEFAULT_LRO_WQE_SZ;
2513 
2514 	priv->mdev = mdev;
2515 	priv->params.num_channels = num_comp_vectors;
2516 	priv->order_base_2_num_channels = order_base_2(num_comp_vectors);
2517 	priv->queue_mapping_channel_mask =
2518 	    roundup_pow_of_two(num_comp_vectors) - 1;
2519 	priv->num_tc = priv->params.num_tc;
2520 	priv->default_vlan_prio = priv->params.default_vlan_prio;
2521 
2522 	INIT_WORK(&priv->update_stats_work, mlx5e_update_stats_work);
2523 	INIT_WORK(&priv->update_carrier_work, mlx5e_update_carrier_work);
2524 	INIT_WORK(&priv->set_rx_mode_work, mlx5e_set_rx_mode_work);
2525 }
2526 
2527 static int
2528 mlx5e_create_mkey(struct mlx5e_priv *priv, u32 pdn,
2529     struct mlx5_core_mr *mr)
2530 {
2531 	struct ifnet *ifp = priv->ifp;
2532 	struct mlx5_core_dev *mdev = priv->mdev;
2533 	struct mlx5_create_mkey_mbox_in *in;
2534 	int err;
2535 
2536 	in = mlx5_vzalloc(sizeof(*in));
2537 	if (in == NULL) {
2538 		if_printf(ifp, "%s: failed to allocate inbox\n", __func__);
2539 		return (-ENOMEM);
2540 	}
2541 	in->seg.flags = MLX5_PERM_LOCAL_WRITE |
2542 	    MLX5_PERM_LOCAL_READ |
2543 	    MLX5_ACCESS_MODE_PA;
2544 	in->seg.flags_pd = cpu_to_be32(pdn | MLX5_MKEY_LEN64);
2545 	in->seg.qpn_mkey7_0 = cpu_to_be32(0xffffff << 8);
2546 
2547 	err = mlx5_core_create_mkey(mdev, mr, in, sizeof(*in), NULL, NULL,
2548 	    NULL);
2549 	if (err)
2550 		if_printf(ifp, "%s: mlx5_core_create_mkey failed, %d\n",
2551 		    __func__, err);
2552 
2553 	kvfree(in);
2554 
2555 	return (err);
2556 }
2557 
2558 static const char *mlx5e_vport_stats_desc[] = {
2559 	MLX5E_VPORT_STATS(MLX5E_STATS_DESC)
2560 };
2561 
2562 static const char *mlx5e_pport_stats_desc[] = {
2563 	MLX5E_PPORT_STATS(MLX5E_STATS_DESC)
2564 };
2565 
2566 static void
2567 mlx5e_priv_mtx_init(struct mlx5e_priv *priv)
2568 {
2569 	mtx_init(&priv->async_events_mtx, "mlx5async", MTX_NETWORK_LOCK, MTX_DEF);
2570 	sx_init(&priv->state_lock, "mlx5state");
2571 	callout_init_mtx(&priv->watchdog, &priv->async_events_mtx, 0);
2572 }
2573 
2574 static void
2575 mlx5e_priv_mtx_destroy(struct mlx5e_priv *priv)
2576 {
2577 	mtx_destroy(&priv->async_events_mtx);
2578 	sx_destroy(&priv->state_lock);
2579 }
2580 
2581 static int
2582 sysctl_firmware(SYSCTL_HANDLER_ARGS)
2583 {
2584 	/* %d.%d%.d the string format.
2585 	 * fw_rev_{maj,min,sub} return u16, 2^16 = 65536.
2586 	 * We need at most 5 chars to store that.
2587 	 * it also has: two "." and NULL at the end.
2588 	 * Which means we need 18 (5*3 + 3) chars at most.
2589 	 */
2590 	char fw[18];
2591 	struct mlx5e_priv *priv = arg1;
2592 	int error;
2593 
2594 	snprintf(fw, sizeof(fw), "%d.%d.%d", fw_rev_maj(priv->mdev), fw_rev_min(priv->mdev),
2595 	    fw_rev_sub(priv->mdev));
2596 	error = sysctl_handle_string(oidp, fw, sizeof(fw), req);
2597 	return (error);
2598 }
2599 
2600 static void
2601 mlx5e_add_hw_stats(struct mlx5e_priv *priv)
2602 {
2603 	SYSCTL_ADD_PROC(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw),
2604 	    OID_AUTO, "fw_version", CTLTYPE_STRING | CTLFLAG_RD, priv, 0,
2605 	    sysctl_firmware, "A", "HCA firmware version");
2606 
2607 	SYSCTL_ADD_STRING(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_hw),
2608 	    OID_AUTO, "board_id", CTLFLAG_RD, priv->mdev->board_id, 0,
2609 	    "Board ID");
2610 }
2611 
2612 static void *
2613 mlx5e_create_ifp(struct mlx5_core_dev *mdev)
2614 {
2615 	static volatile int mlx5_en_unit;
2616 	struct ifnet *ifp;
2617 	struct mlx5e_priv *priv;
2618 	u8 dev_addr[ETHER_ADDR_LEN] __aligned(4);
2619 	struct sysctl_oid_list *child;
2620 	int ncv = mdev->priv.eq_table.num_comp_vectors;
2621 	char unit[16];
2622 	int err;
2623 	int i;
2624 	u32 eth_proto_cap;
2625 
2626 	if (mlx5e_check_required_hca_cap(mdev)) {
2627 		mlx5_core_dbg(mdev, "mlx5e_check_required_hca_cap() failed\n");
2628 		return (NULL);
2629 	}
2630 	priv = malloc(sizeof(*priv), M_MLX5EN, M_WAITOK | M_ZERO);
2631 	if (priv == NULL) {
2632 		mlx5_core_err(mdev, "malloc() failed\n");
2633 		return (NULL);
2634 	}
2635 	mlx5e_priv_mtx_init(priv);
2636 
2637 	ifp = priv->ifp = if_alloc(IFT_ETHER);
2638 	if (ifp == NULL) {
2639 		mlx5_core_err(mdev, "if_alloc() failed\n");
2640 		goto err_free_priv;
2641 	}
2642 	ifp->if_softc = priv;
2643 	if_initname(ifp, "mce", atomic_fetchadd_int(&mlx5_en_unit, 1));
2644 	ifp->if_mtu = ETHERMTU;
2645 	ifp->if_init = mlx5e_open;
2646 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
2647 	ifp->if_ioctl = mlx5e_ioctl;
2648 	ifp->if_transmit = mlx5e_xmit;
2649 	ifp->if_qflush = if_qflush;
2650 #if (__FreeBSD_version >= 1100000)
2651 	ifp->if_get_counter = mlx5e_get_counter;
2652 #endif
2653 	ifp->if_snd.ifq_maxlen = ifqmaxlen;
2654 	/*
2655          * Set driver features
2656          */
2657 	ifp->if_capabilities |= IFCAP_HWCSUM | IFCAP_HWCSUM_IPV6;
2658 	ifp->if_capabilities |= IFCAP_VLAN_MTU | IFCAP_VLAN_HWTAGGING;
2659 	ifp->if_capabilities |= IFCAP_VLAN_HWCSUM | IFCAP_VLAN_HWFILTER;
2660 	ifp->if_capabilities |= IFCAP_LINKSTATE | IFCAP_JUMBO_MTU;
2661 	ifp->if_capabilities |= IFCAP_LRO;
2662 	ifp->if_capabilities |= IFCAP_TSO | IFCAP_VLAN_HWTSO;
2663 
2664 	/* set TSO limits so that we don't have to drop TX packets */
2665 	ifp->if_hw_tsomax = MLX5E_MAX_TX_PAYLOAD_SIZE - (ETHER_HDR_LEN + ETHER_VLAN_ENCAP_LEN);
2666 	ifp->if_hw_tsomaxsegcount = MLX5E_MAX_TX_MBUF_FRAGS - 1 /* hdr */;
2667 	ifp->if_hw_tsomaxsegsize = MLX5E_MAX_TX_MBUF_SIZE;
2668 
2669 	ifp->if_capenable = ifp->if_capabilities;
2670 	ifp->if_hwassist = 0;
2671 	if (ifp->if_capenable & IFCAP_TSO)
2672 		ifp->if_hwassist |= CSUM_TSO;
2673 	if (ifp->if_capenable & IFCAP_TXCSUM)
2674 		ifp->if_hwassist |= (CSUM_TCP | CSUM_UDP | CSUM_IP);
2675 	if (ifp->if_capenable & IFCAP_TXCSUM_IPV6)
2676 		ifp->if_hwassist |= (CSUM_UDP_IPV6 | CSUM_TCP_IPV6);
2677 
2678 	/* ifnet sysctl tree */
2679 	sysctl_ctx_init(&priv->sysctl_ctx);
2680 	priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_STATIC_CHILDREN(_dev),
2681 	    OID_AUTO, ifp->if_dname, CTLFLAG_RD, 0, "MLX5 ethernet - interface name");
2682 	if (priv->sysctl_ifnet == NULL) {
2683 		mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n");
2684 		goto err_free_sysctl;
2685 	}
2686 	snprintf(unit, sizeof(unit), "%d", ifp->if_dunit);
2687 	priv->sysctl_ifnet = SYSCTL_ADD_NODE(&priv->sysctl_ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
2688 	    OID_AUTO, unit, CTLFLAG_RD, 0, "MLX5 ethernet - interface unit");
2689 	if (priv->sysctl_ifnet == NULL) {
2690 		mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n");
2691 		goto err_free_sysctl;
2692 	}
2693 	/* HW sysctl tree */
2694 	child = SYSCTL_CHILDREN(device_get_sysctl_tree(mdev->pdev->dev.bsddev));
2695 	priv->sysctl_hw = SYSCTL_ADD_NODE(&priv->sysctl_ctx, child,
2696 	    OID_AUTO, "hw", CTLFLAG_RD, 0, "MLX5 ethernet dev hw");
2697 	if (priv->sysctl_hw == NULL) {
2698 		mlx5_core_err(mdev, "SYSCTL_ADD_NODE() failed\n");
2699 		goto err_free_sysctl;
2700 	}
2701 
2702 	mlx5e_build_ifp_priv(mdev, priv, ncv);
2703 
2704 	err = mlx5_alloc_map_uar(mdev, &priv->cq_uar);
2705 	if (err) {
2706 		if_printf(ifp, "%s: mlx5_alloc_map_uar failed, %d\n",
2707 		    __func__, err);
2708 		goto err_free_sysctl;
2709 	}
2710 	err = mlx5_core_alloc_pd(mdev, &priv->pdn);
2711 	if (err) {
2712 		if_printf(ifp, "%s: mlx5_core_alloc_pd failed, %d\n",
2713 		    __func__, err);
2714 		goto err_unmap_free_uar;
2715 	}
2716 
2717 	err = mlx5_alloc_transport_domain(mdev, &priv->tdn);
2718 
2719 	if (err) {
2720 		if_printf(ifp, "%s: mlx5_alloc_transport_domain failed, %d\n",
2721 			  __func__, err);
2722 		goto err_dealloc_pd;
2723 	}
2724 
2725 	err = mlx5e_create_mkey(priv, priv->pdn, &priv->mr);
2726 	if (err) {
2727 		if_printf(ifp, "%s: mlx5e_create_mkey failed, %d\n",
2728 		    __func__, err);
2729 		goto err_dealloc_transport_domain;
2730 	}
2731 	mlx5_query_nic_vport_mac_address(priv->mdev, 0, dev_addr);
2732 
2733 	/* set default MTU */
2734 	mlx5e_set_dev_port_mtu(ifp, ifp->if_mtu);
2735 
2736 	/* Set desc */
2737 	device_set_desc(mdev->pdev->dev.bsddev, mlx5e_version);
2738 
2739 	/* Set default media status */
2740 	priv->media_status_last = IFM_AVALID;
2741 	priv->media_active_last = IFM_ETHER | IFM_AUTO;
2742 
2743 	/* Pauseframes are enabled by default */
2744 	priv->params_ethtool.tx_pauseframe_control = 1;
2745 	priv->params_ethtool.rx_pauseframe_control = 1;
2746 
2747 	err = mlx5_query_port_proto_cap(mdev, &eth_proto_cap, MLX5_PTYS_EN);
2748 	if (err) {
2749 		eth_proto_cap = 0;
2750 		if_printf(ifp, "%s: Query port media capability failed, %d\n",
2751 		    __func__, err);
2752 	}
2753 
2754 	/* Setup supported medias */
2755 	ifmedia_init(&priv->media, IFM_IMASK | IFM_ETH_FMASK,
2756 	    mlx5e_media_change, mlx5e_media_status);
2757 
2758 	for (i = 0; i < MLX5E_LINK_MODES_NUMBER; ++i) {
2759 		if (mlx5e_mode_table[i].baudrate == 0)
2760 			continue;
2761 		if (MLX5E_PROT_MASK(i) & eth_proto_cap)
2762 			ifmedia_add(&priv->media,
2763 			    IFM_ETHER | mlx5e_mode_table[i].subtype |
2764 			    IFM_FDX, 0, NULL);
2765 	}
2766 
2767 	ifmedia_add(&priv->media, IFM_ETHER | IFM_AUTO, 0, NULL);
2768 	ifmedia_set(&priv->media, IFM_ETHER | IFM_AUTO);
2769 	ether_ifattach(ifp, dev_addr);
2770 
2771 	/* Register for VLAN events */
2772 	priv->vlan_attach = EVENTHANDLER_REGISTER(vlan_config,
2773 	    mlx5e_vlan_rx_add_vid, priv, EVENTHANDLER_PRI_FIRST);
2774 	priv->vlan_detach = EVENTHANDLER_REGISTER(vlan_unconfig,
2775 	    mlx5e_vlan_rx_kill_vid, priv, EVENTHANDLER_PRI_FIRST);
2776 
2777 	/* Link is down by default */
2778 	if_link_state_change(ifp, LINK_STATE_DOWN);
2779 
2780 	mlx5e_enable_async_events(priv);
2781 
2782 	mlx5e_add_hw_stats(priv);
2783 
2784 	mlx5e_create_stats(&priv->stats.vport.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
2785 	    "vstats", mlx5e_vport_stats_desc, MLX5E_VPORT_STATS_NUM,
2786 	    priv->stats.vport.arg);
2787 
2788 	mlx5e_create_stats(&priv->stats.pport.ctx, SYSCTL_CHILDREN(priv->sysctl_ifnet),
2789 	    "pstats", mlx5e_pport_stats_desc, MLX5E_PPORT_STATS_NUM,
2790 	    priv->stats.pport.arg);
2791 
2792 	mlx5e_create_ethtool(priv);
2793 
2794 	mtx_lock(&priv->async_events_mtx);
2795 	mlx5e_update_stats(priv);
2796 	mtx_unlock(&priv->async_events_mtx);
2797 
2798 	return (priv);
2799 
2800 err_dealloc_transport_domain:
2801 	mlx5_dealloc_transport_domain(mdev, priv->tdn);
2802 
2803 err_dealloc_pd:
2804 	mlx5_core_dealloc_pd(mdev, priv->pdn);
2805 
2806 err_unmap_free_uar:
2807 	mlx5_unmap_free_uar(mdev, &priv->cq_uar);
2808 
2809 err_free_sysctl:
2810 	sysctl_ctx_free(&priv->sysctl_ctx);
2811 
2812 	if_free(ifp);
2813 
2814 err_free_priv:
2815 	mlx5e_priv_mtx_destroy(priv);
2816 	free(priv, M_MLX5EN);
2817 	return (NULL);
2818 }
2819 
2820 static void
2821 mlx5e_destroy_ifp(struct mlx5_core_dev *mdev, void *vpriv)
2822 {
2823 	struct mlx5e_priv *priv = vpriv;
2824 	struct ifnet *ifp = priv->ifp;
2825 
2826 	/* don't allow more IOCTLs */
2827 	priv->gone = 1;
2828 
2829 	/* XXX wait a bit to allow IOCTL handlers to complete */
2830 	pause("W", hz);
2831 
2832 	/* stop watchdog timer */
2833 	callout_drain(&priv->watchdog);
2834 
2835 	if (priv->vlan_attach != NULL)
2836 		EVENTHANDLER_DEREGISTER(vlan_config, priv->vlan_attach);
2837 	if (priv->vlan_detach != NULL)
2838 		EVENTHANDLER_DEREGISTER(vlan_unconfig, priv->vlan_detach);
2839 
2840 	/* make sure device gets closed */
2841 	PRIV_LOCK(priv);
2842 	mlx5e_close_locked(ifp);
2843 	PRIV_UNLOCK(priv);
2844 
2845 	/* unregister device */
2846 	ifmedia_removeall(&priv->media);
2847 	ether_ifdetach(ifp);
2848 	if_free(ifp);
2849 
2850 	/* destroy all remaining sysctl nodes */
2851 	if (priv->sysctl_debug)
2852 		sysctl_ctx_free(&priv->stats.port_stats_debug.ctx);
2853 	sysctl_ctx_free(&priv->stats.vport.ctx);
2854 	sysctl_ctx_free(&priv->stats.pport.ctx);
2855 	sysctl_ctx_free(&priv->sysctl_ctx);
2856 
2857 	mlx5_core_destroy_mkey(priv->mdev, &priv->mr);
2858 	mlx5_dealloc_transport_domain(priv->mdev, priv->tdn);
2859 	mlx5_core_dealloc_pd(priv->mdev, priv->pdn);
2860 	mlx5_unmap_free_uar(priv->mdev, &priv->cq_uar);
2861 	mlx5e_disable_async_events(priv);
2862 	flush_scheduled_work();
2863 	mlx5e_priv_mtx_destroy(priv);
2864 	free(priv, M_MLX5EN);
2865 }
2866 
2867 static void *
2868 mlx5e_get_ifp(void *vpriv)
2869 {
2870 	struct mlx5e_priv *priv = vpriv;
2871 
2872 	return (priv->ifp);
2873 }
2874 
2875 static struct mlx5_interface mlx5e_interface = {
2876 	.add = mlx5e_create_ifp,
2877 	.remove = mlx5e_destroy_ifp,
2878 	.event = mlx5e_async_event,
2879 	.protocol = MLX5_INTERFACE_PROTOCOL_ETH,
2880 	.get_dev = mlx5e_get_ifp,
2881 };
2882 
2883 void
2884 mlx5e_init(void)
2885 {
2886 	mlx5_register_interface(&mlx5e_interface);
2887 }
2888 
2889 void
2890 mlx5e_cleanup(void)
2891 {
2892 	mlx5_unregister_interface(&mlx5e_interface);
2893 }
2894 
2895 module_init_order(mlx5e_init, SI_ORDER_THIRD);
2896 module_exit_order(mlx5e_cleanup, SI_ORDER_THIRD);
2897 
2898 #if (__FreeBSD_version >= 1100000)
2899 MODULE_DEPEND(mlx5en, linuxkpi, 1, 1, 1);
2900 #endif
2901 MODULE_DEPEND(mlx5en, mlx5, 1, 1, 1);
2902 MODULE_VERSION(mlx5en, 1);
2903