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