]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/dev/vnic/nic_main.c
mps: Use 64-bit chain structures
[FreeBSD/FreeBSD.git] / sys / dev / vnic / nic_main.c
1 /*
2  * Copyright (C) 2015 Cavium Inc.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  *
26  * $FreeBSD$
27  *
28  */
29
30 /*
31  * Marvell/Cavium ThunderX vnic/bgx network controller
32  *
33  * UNIMPLEMENTED FEATURES
34  * ----------------------
35  * A number of features supported by the hardware are not yet implemented in
36  * this driver:
37  *
38  * - PR223573 multicast rx filter
39  * - PR223575 non-promiscuous mode (driver currently forces promisc)
40  */
41
42 #include <sys/cdefs.h>
43 __FBSDID("$FreeBSD$");
44
45 #include <sys/param.h>
46 #include <sys/systm.h>
47 #include <sys/bitset.h>
48 #include <sys/bitstring.h>
49 #include <sys/bus.h>
50 #include <sys/endian.h>
51 #include <sys/kernel.h>
52 #include <sys/malloc.h>
53 #include <sys/module.h>
54 #include <sys/rman.h>
55 #include <sys/pciio.h>
56 #include <sys/pcpu.h>
57 #include <sys/proc.h>
58 #include <sys/socket.h>
59 #include <sys/sockio.h>
60 #include <sys/cpuset.h>
61 #include <sys/lock.h>
62 #include <sys/mutex.h>
63
64 #include <net/ethernet.h>
65 #include <net/if.h>
66 #include <net/if_media.h>
67
68 #include <machine/bus.h>
69 #include <machine/_inttypes.h>
70
71 #include <dev/pci/pcireg.h>
72 #include <dev/pci/pcivar.h>
73
74 #include <sys/dnv.h>
75 #include <sys/nv.h>
76 #ifdef PCI_IOV
77 #include <sys/iov_schema.h>
78 #include <dev/pci/pci_iov.h>
79 #endif
80
81 #include "thunder_bgx.h"
82 #include "nic_reg.h"
83 #include "nic.h"
84 #include "q_struct.h"
85
86 #define VNIC_PF_DEVSTR          "Cavium Thunder NIC Physical Function Driver"
87
88 #define VNIC_PF_REG_RID         PCIR_BAR(PCI_CFG_REG_BAR_NUM)
89
90 #define NIC_SET_VF_LMAC_MAP(bgx, lmac)          ((((bgx) & 0xF) << 4) | ((lmac) & 0xF))
91 #define NIC_GET_BGX_FROM_VF_LMAC_MAP(map)       (((map) >> 4) & 0xF)
92 #define NIC_GET_LMAC_FROM_VF_LMAC_MAP(map)      ((map) & 0xF)
93
94 /* Structure to be used by the SR-IOV for VF configuration schemas */
95 struct nicvf_info {
96         boolean_t               vf_enabled;
97         int                     vf_flags;
98 };
99
100 struct nicpf {
101         device_t                dev;
102         uint8_t                 node;
103         u_int                   flags;
104         uint8_t                 num_vf_en;      /* No of VF enabled */
105         struct nicvf_info       vf_info[MAX_NUM_VFS_SUPPORTED];
106         struct resource *       reg_base;       /* Register start address */
107         struct pkind_cfg        pkind;
108         uint8_t                 vf_lmac_map[MAX_LMAC];
109         boolean_t               mbx_lock[MAX_NUM_VFS_SUPPORTED];
110
111         struct callout          check_link;
112         struct mtx              check_link_mtx;
113
114         uint8_t                 link[MAX_LMAC];
115         uint8_t                 duplex[MAX_LMAC];
116         uint32_t                speed[MAX_LMAC];
117         uint16_t                cpi_base[MAX_NUM_VFS_SUPPORTED];
118         uint16_t                rssi_base[MAX_NUM_VFS_SUPPORTED];
119         uint16_t                rss_ind_tbl_size;
120
121         /* MSI-X */
122         boolean_t               msix_enabled;
123         uint8_t                 num_vec;
124         struct msix_entry       msix_entries[NIC_PF_MSIX_VECTORS];
125         struct resource *       msix_table_res;
126 };
127
128 static int nicpf_probe(device_t);
129 static int nicpf_attach(device_t);
130 static int nicpf_detach(device_t);
131
132 #ifdef PCI_IOV
133 static int nicpf_iov_init(device_t, uint16_t, const nvlist_t *);
134 static void nicpf_iov_uninit(device_t);
135 static int nicpf_iov_add_vf(device_t, uint16_t, const nvlist_t *);
136 #endif
137
138 static device_method_t nicpf_methods[] = {
139         /* Device interface */
140         DEVMETHOD(device_probe,         nicpf_probe),
141         DEVMETHOD(device_attach,        nicpf_attach),
142         DEVMETHOD(device_detach,        nicpf_detach),
143         /* PCI SR-IOV interface */
144 #ifdef PCI_IOV
145         DEVMETHOD(pci_iov_init,         nicpf_iov_init),
146         DEVMETHOD(pci_iov_uninit,       nicpf_iov_uninit),
147         DEVMETHOD(pci_iov_add_vf,       nicpf_iov_add_vf),
148 #endif
149         DEVMETHOD_END,
150 };
151
152 static driver_t vnicpf_driver = {
153         "vnicpf",
154         nicpf_methods,
155         sizeof(struct nicpf),
156 };
157
158 static devclass_t vnicpf_devclass;
159
160 DRIVER_MODULE(vnicpf, pci, vnicpf_driver, vnicpf_devclass, 0, 0);
161 MODULE_VERSION(vnicpf, 1);
162 MODULE_DEPEND(vnicpf, pci, 1, 1, 1);
163 MODULE_DEPEND(vnicpf, ether, 1, 1, 1);
164 MODULE_DEPEND(vnicpf, thunder_bgx, 1, 1, 1);
165
166 static int nicpf_alloc_res(struct nicpf *);
167 static void nicpf_free_res(struct nicpf *);
168 static void nic_set_lmac_vf_mapping(struct nicpf *);
169 static void nic_init_hw(struct nicpf *);
170 static int nic_sriov_init(device_t, struct nicpf *);
171 static void nic_poll_for_link(void *);
172 static int nic_register_interrupts(struct nicpf *);
173 static void nic_unregister_interrupts(struct nicpf *);
174
175 /*
176  * Device interface
177  */
178 static int
179 nicpf_probe(device_t dev)
180 {
181         uint16_t vendor_id;
182         uint16_t device_id;
183
184         vendor_id = pci_get_vendor(dev);
185         device_id = pci_get_device(dev);
186
187         if (vendor_id == PCI_VENDOR_ID_CAVIUM &&
188             device_id == PCI_DEVICE_ID_THUNDER_NIC_PF) {
189                 device_set_desc(dev, VNIC_PF_DEVSTR);
190                 return (BUS_PROBE_DEFAULT);
191         }
192
193         return (ENXIO);
194 }
195
196 static int
197 nicpf_attach(device_t dev)
198 {
199         struct nicpf *nic;
200         int err;
201
202         nic = device_get_softc(dev);
203         nic->dev = dev;
204
205         /* Enable bus mastering */
206         pci_enable_busmaster(dev);
207
208         /* Allocate PCI resources */
209         err = nicpf_alloc_res(nic);
210         if (err != 0) {
211                 device_printf(dev, "Could not allocate PCI resources\n");
212                 return (err);
213         }
214
215         nic->node = nic_get_node_id(nic->reg_base);
216
217         /* Enable Traffic Network Switch (TNS) bypass mode by default */
218         nic->flags &= ~NIC_TNS_ENABLED;
219         nic_set_lmac_vf_mapping(nic);
220
221         /* Initialize hardware */
222         nic_init_hw(nic);
223
224         /* Set RSS TBL size for each VF */
225         nic->rss_ind_tbl_size = NIC_MAX_RSS_IDR_TBL_SIZE;
226
227         /* Setup interrupts */
228         err = nic_register_interrupts(nic);
229         if (err != 0)
230                 goto err_free_res;
231
232         /* Configure SRIOV */
233         err = nic_sriov_init(dev, nic);
234         if (err != 0)
235                 goto err_free_intr;
236
237         if (nic->flags & NIC_TNS_ENABLED)
238                 return (0);
239
240         mtx_init(&nic->check_link_mtx, "VNIC PF link poll", NULL, MTX_DEF);
241         /* Register physical link status poll callout */
242         callout_init_mtx(&nic->check_link, &nic->check_link_mtx, 0);
243         mtx_lock(&nic->check_link_mtx);
244         nic_poll_for_link(nic);
245         mtx_unlock(&nic->check_link_mtx);
246
247         return (0);
248
249 err_free_intr:
250         nic_unregister_interrupts(nic);
251 err_free_res:
252         nicpf_free_res(nic);
253         pci_disable_busmaster(dev);
254
255         return (err);
256 }
257
258 static int
259 nicpf_detach(device_t dev)
260 {
261         struct nicpf *nic;
262         int err;
263
264         err = 0;
265         nic = device_get_softc(dev);
266
267         callout_drain(&nic->check_link);
268         mtx_destroy(&nic->check_link_mtx);
269
270         nic_unregister_interrupts(nic);
271         nicpf_free_res(nic);
272         pci_disable_busmaster(dev);
273
274 #ifdef PCI_IOV
275         err = pci_iov_detach(dev);
276         if (err != 0)
277                 device_printf(dev, "SR-IOV in use. Detach first.\n");
278 #endif
279         return (err);
280 }
281
282 /*
283  * SR-IOV interface
284  */
285 #ifdef PCI_IOV
286 static int
287 nicpf_iov_init(device_t dev, uint16_t num_vfs, const nvlist_t *params)
288 {
289         struct nicpf *nic;
290
291         nic = device_get_softc(dev);
292
293         if (num_vfs == 0)
294                 return (ENXIO);
295
296         nic->flags |= NIC_SRIOV_ENABLED;
297
298         return (0);
299 }
300
301 static void
302 nicpf_iov_uninit(device_t dev)
303 {
304
305         /* ARM64TODO: Implement this function */
306 }
307
308 static int
309 nicpf_iov_add_vf(device_t dev, uint16_t vfnum, const nvlist_t *params)
310 {
311         const void *mac;
312         struct nicpf *nic;
313         size_t size;
314         int bgx, lmac;
315
316         nic = device_get_softc(dev);
317
318         if ((nic->flags & NIC_SRIOV_ENABLED) == 0)
319                 return (ENXIO);
320
321         if (vfnum > (nic->num_vf_en - 1))
322                 return (EINVAL);
323
324         if (nvlist_exists_binary(params, "mac-addr") != 0) {
325                 mac = nvlist_get_binary(params, "mac-addr", &size);
326                 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vfnum]);
327                 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vfnum]);
328                 bgx_set_lmac_mac(nic->node, bgx, lmac, mac);
329         }
330
331         return (0);
332 }
333 #endif
334
335 /*
336  * Helper routines
337  */
338 static int
339 nicpf_alloc_res(struct nicpf *nic)
340 {
341         device_t dev;
342         int rid;
343
344         dev = nic->dev;
345
346         rid = VNIC_PF_REG_RID;
347         nic->reg_base = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &rid,
348             RF_ACTIVE);
349         if (nic->reg_base == NULL) {
350                 /* For verbose output print some more details */
351                 if (bootverbose) {
352                         device_printf(dev,
353                             "Could not allocate registers memory\n");
354                 }
355                 return (ENXIO);
356         }
357
358         return (0);
359 }
360
361 static void
362 nicpf_free_res(struct nicpf *nic)
363 {
364         device_t dev;
365
366         dev = nic->dev;
367
368         if (nic->reg_base != NULL) {
369                 bus_release_resource(dev, SYS_RES_MEMORY,
370                     rman_get_rid(nic->reg_base), nic->reg_base);
371         }
372 }
373
374 /* Register read/write APIs */
375 static __inline void
376 nic_reg_write(struct nicpf *nic, bus_space_handle_t offset,
377     uint64_t val)
378 {
379
380         bus_write_8(nic->reg_base, offset, val);
381 }
382
383 static __inline uint64_t
384 nic_reg_read(struct nicpf *nic, uint64_t offset)
385 {
386         uint64_t val;
387
388         val = bus_read_8(nic->reg_base, offset);
389         return (val);
390 }
391
392 /* PF -> VF mailbox communication APIs */
393 static void
394 nic_enable_mbx_intr(struct nicpf *nic)
395 {
396
397         /* Enable mailbox interrupt for all 128 VFs */
398         nic_reg_write(nic, NIC_PF_MAILBOX_ENA_W1S, ~0UL);
399         nic_reg_write(nic, NIC_PF_MAILBOX_ENA_W1S + sizeof(uint64_t), ~0UL);
400 }
401
402 static void
403 nic_clear_mbx_intr(struct nicpf *nic, int vf, int mbx_reg)
404 {
405
406         nic_reg_write(nic, NIC_PF_MAILBOX_INT + (mbx_reg << 3), (1UL << vf));
407 }
408
409 static uint64_t
410 nic_get_mbx_addr(int vf)
411 {
412
413         return (NIC_PF_VF_0_127_MAILBOX_0_1 + (vf << NIC_VF_NUM_SHIFT));
414 }
415
416 /*
417  * Send a mailbox message to VF
418  * @vf: vf to which this message to be sent
419  * @mbx: Message to be sent
420  */
421 static void
422 nic_send_msg_to_vf(struct nicpf *nic, int vf, union nic_mbx *mbx)
423 {
424         bus_space_handle_t mbx_addr = nic_get_mbx_addr(vf);
425         uint64_t *msg = (uint64_t *)mbx;
426
427         /*
428          * In first revision HW, mbox interrupt is triggerred
429          * when PF writes to MBOX(1), in next revisions when
430          * PF writes to MBOX(0)
431          */
432         if (pass1_silicon(nic->dev)) {
433                 nic_reg_write(nic, mbx_addr + 0, msg[0]);
434                 nic_reg_write(nic, mbx_addr + 8, msg[1]);
435         } else {
436                 nic_reg_write(nic, mbx_addr + 8, msg[1]);
437                 nic_reg_write(nic, mbx_addr + 0, msg[0]);
438         }
439 }
440
441 /*
442  * Responds to VF's READY message with VF's
443  * ID, node, MAC address e.t.c
444  * @vf: VF which sent READY message
445  */
446 static void
447 nic_mbx_send_ready(struct nicpf *nic, int vf)
448 {
449         union nic_mbx mbx = {};
450         int bgx_idx, lmac;
451         const char *mac;
452
453         mbx.nic_cfg.msg = NIC_MBOX_MSG_READY;
454         mbx.nic_cfg.vf_id = vf;
455
456         if (nic->flags & NIC_TNS_ENABLED)
457                 mbx.nic_cfg.tns_mode = NIC_TNS_MODE;
458         else
459                 mbx.nic_cfg.tns_mode = NIC_TNS_BYPASS_MODE;
460
461         if (vf < MAX_LMAC) {
462                 bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
463                 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
464
465                 mac = bgx_get_lmac_mac(nic->node, bgx_idx, lmac);
466                 if (mac) {
467                         memcpy((uint8_t *)&mbx.nic_cfg.mac_addr, mac,
468                             ETHER_ADDR_LEN);
469                 }
470         }
471         mbx.nic_cfg.node_id = nic->node;
472
473         mbx.nic_cfg.loopback_supported = vf < MAX_LMAC;
474
475         nic_send_msg_to_vf(nic, vf, &mbx);
476 }
477
478 /*
479  * ACKs VF's mailbox message
480  * @vf: VF to which ACK to be sent
481  */
482 static void
483 nic_mbx_send_ack(struct nicpf *nic, int vf)
484 {
485         union nic_mbx mbx = {};
486
487         mbx.msg.msg = NIC_MBOX_MSG_ACK;
488         nic_send_msg_to_vf(nic, vf, &mbx);
489 }
490
491 /*
492  * NACKs VF's mailbox message that PF is not able to
493  * complete the action
494  * @vf: VF to which ACK to be sent
495  */
496 static void
497 nic_mbx_send_nack(struct nicpf *nic, int vf)
498 {
499         union nic_mbx mbx = {};
500
501         mbx.msg.msg = NIC_MBOX_MSG_NACK;
502         nic_send_msg_to_vf(nic, vf, &mbx);
503 }
504
505 /*
506  * Flush all in flight receive packets to memory and
507  * bring down an active RQ
508  */
509 static int
510 nic_rcv_queue_sw_sync(struct nicpf *nic)
511 {
512         uint16_t timeout = ~0x00;
513
514         nic_reg_write(nic, NIC_PF_SW_SYNC_RX, 0x01);
515         /* Wait till sync cycle is finished */
516         while (timeout) {
517                 if (nic_reg_read(nic, NIC_PF_SW_SYNC_RX_DONE) & 0x1)
518                         break;
519                 timeout--;
520         }
521         nic_reg_write(nic, NIC_PF_SW_SYNC_RX, 0x00);
522         if (!timeout) {
523                 device_printf(nic->dev, "Receive queue software sync failed\n");
524                 return (ETIMEDOUT);
525         }
526         return (0);
527 }
528
529 /* Get BGX Rx/Tx stats and respond to VF's request */
530 static void
531 nic_get_bgx_stats(struct nicpf *nic, struct bgx_stats_msg *bgx)
532 {
533         int bgx_idx, lmac;
534         union nic_mbx mbx = {};
535
536         bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[bgx->vf_id]);
537         lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[bgx->vf_id]);
538
539         mbx.bgx_stats.msg = NIC_MBOX_MSG_BGX_STATS;
540         mbx.bgx_stats.vf_id = bgx->vf_id;
541         mbx.bgx_stats.rx = bgx->rx;
542         mbx.bgx_stats.idx = bgx->idx;
543         if (bgx->rx != 0) {
544                 mbx.bgx_stats.stats =
545                     bgx_get_rx_stats(nic->node, bgx_idx, lmac, bgx->idx);
546         } else {
547                 mbx.bgx_stats.stats =
548                     bgx_get_tx_stats(nic->node, bgx_idx, lmac, bgx->idx);
549         }
550         nic_send_msg_to_vf(nic, bgx->vf_id, &mbx);
551 }
552
553 /* Update hardware min/max frame size */
554 static int
555 nic_update_hw_frs(struct nicpf *nic, int new_frs, int vf)
556 {
557
558         if ((new_frs > NIC_HW_MAX_FRS) || (new_frs < NIC_HW_MIN_FRS)) {
559                 device_printf(nic->dev,
560                     "Invalid MTU setting from VF%d rejected, "
561                     "should be between %d and %d\n",
562                     vf, NIC_HW_MIN_FRS, NIC_HW_MAX_FRS);
563                 return (EINVAL);
564         }
565         new_frs += ETHER_HDR_LEN;
566         if (new_frs <= nic->pkind.maxlen)
567                 return (0);
568
569         nic->pkind.maxlen = new_frs;
570         nic_reg_write(nic, NIC_PF_PKIND_0_15_CFG, *(uint64_t *)&nic->pkind);
571         return (0);
572 }
573
574 /* Set minimum transmit packet size */
575 static void
576 nic_set_tx_pkt_pad(struct nicpf *nic, int size)
577 {
578         int lmac;
579         uint64_t lmac_cfg;
580
581         /* Max value that can be set is 60 */
582         if (size > 60)
583                 size = 60;
584
585         for (lmac = 0; lmac < (MAX_BGX_PER_CN88XX * MAX_LMAC_PER_BGX); lmac++) {
586                 lmac_cfg = nic_reg_read(nic, NIC_PF_LMAC_0_7_CFG | (lmac << 3));
587                 lmac_cfg &= ~(0xF << 2);
588                 lmac_cfg |= ((size / 4) << 2);
589                 nic_reg_write(nic, NIC_PF_LMAC_0_7_CFG | (lmac << 3), lmac_cfg);
590         }
591 }
592
593 /*
594  * Function to check number of LMACs present and set VF::LMAC mapping.
595  * Mapping will be used while initializing channels.
596  */
597 static void
598 nic_set_lmac_vf_mapping(struct nicpf *nic)
599 {
600         unsigned bgx_map = bgx_get_map(nic->node);
601         int bgx, next_bgx_lmac = 0;
602         int lmac, lmac_cnt = 0;
603         uint64_t lmac_credit;
604
605         nic->num_vf_en = 0;
606         if (nic->flags & NIC_TNS_ENABLED) {
607                 nic->num_vf_en = DEFAULT_NUM_VF_ENABLED;
608                 return;
609         }
610
611         for (bgx = 0; bgx < NIC_MAX_BGX; bgx++) {
612                 if ((bgx_map & (1 << bgx)) == 0)
613                         continue;
614                 lmac_cnt = bgx_get_lmac_count(nic->node, bgx);
615                 for (lmac = 0; lmac < lmac_cnt; lmac++)
616                         nic->vf_lmac_map[next_bgx_lmac++] =
617                                                 NIC_SET_VF_LMAC_MAP(bgx, lmac);
618                 nic->num_vf_en += lmac_cnt;
619
620                 /* Program LMAC credits */
621                 lmac_credit = (1UL << 1); /* channel credit enable */
622                 lmac_credit |= (0x1ff << 2); /* Max outstanding pkt count */
623                 /* 48KB BGX Tx buffer size, each unit is of size 16bytes */
624                 lmac_credit |= (((((48 * 1024) / lmac_cnt) -
625                     NIC_HW_MAX_FRS) / 16) << 12);
626                 lmac = bgx * MAX_LMAC_PER_BGX;
627                 for (; lmac < lmac_cnt + (bgx * MAX_LMAC_PER_BGX); lmac++) {
628                         nic_reg_write(nic, NIC_PF_LMAC_0_7_CREDIT + (lmac * 8),
629                             lmac_credit);
630                 }
631         }
632 }
633
634 #define TNS_PORT0_BLOCK 6
635 #define TNS_PORT1_BLOCK 7
636 #define BGX0_BLOCK 8
637 #define BGX1_BLOCK 9
638
639 static void
640 nic_init_hw(struct nicpf *nic)
641 {
642         int i;
643
644         /* Enable NIC HW block */
645         nic_reg_write(nic, NIC_PF_CFG, 0x3);
646
647         /* Enable backpressure */
648         nic_reg_write(nic, NIC_PF_BP_CFG, (1UL << 6) | 0x03);
649
650         if (nic->flags & NIC_TNS_ENABLED) {
651                 nic_reg_write(nic, NIC_PF_INTF_0_1_SEND_CFG,
652                     (NIC_TNS_MODE << 7) | TNS_PORT0_BLOCK);
653                 nic_reg_write(nic, NIC_PF_INTF_0_1_SEND_CFG | (1 << 8),
654                     (NIC_TNS_MODE << 7) | TNS_PORT1_BLOCK);
655                 nic_reg_write(nic, NIC_PF_INTF_0_1_BP_CFG,
656                     (1UL << 63) | TNS_PORT0_BLOCK);
657                 nic_reg_write(nic, NIC_PF_INTF_0_1_BP_CFG + (1 << 8),
658                     (1UL << 63) | TNS_PORT1_BLOCK);
659
660         } else {
661                 /* Disable TNS mode on both interfaces */
662                 nic_reg_write(nic, NIC_PF_INTF_0_1_SEND_CFG,
663                     (NIC_TNS_BYPASS_MODE << 7) | BGX0_BLOCK);
664                 nic_reg_write(nic, NIC_PF_INTF_0_1_SEND_CFG | (1 << 8),
665                     (NIC_TNS_BYPASS_MODE << 7) | BGX1_BLOCK);
666                 nic_reg_write(nic, NIC_PF_INTF_0_1_BP_CFG,
667                     (1UL << 63) | BGX0_BLOCK);
668                 nic_reg_write(nic, NIC_PF_INTF_0_1_BP_CFG + (1 << 8),
669                     (1UL << 63) | BGX1_BLOCK);
670         }
671
672         /* PKIND configuration */
673         nic->pkind.minlen = 0;
674         nic->pkind.maxlen = NIC_HW_MAX_FRS + ETHER_HDR_LEN;
675         nic->pkind.lenerr_en = 1;
676         nic->pkind.rx_hdr = 0;
677         nic->pkind.hdr_sl = 0;
678
679         for (i = 0; i < NIC_MAX_PKIND; i++) {
680                 nic_reg_write(nic, NIC_PF_PKIND_0_15_CFG | (i << 3),
681                     *(uint64_t *)&nic->pkind);
682         }
683
684         nic_set_tx_pkt_pad(nic, NIC_HW_MIN_FRS);
685
686         /* Timer config */
687         nic_reg_write(nic, NIC_PF_INTR_TIMER_CFG, NICPF_CLK_PER_INT_TICK);
688
689         /* Enable VLAN ethertype matching and stripping */
690         nic_reg_write(nic, NIC_PF_RX_ETYPE_0_7,
691             (2 << 19) | (ETYPE_ALG_VLAN_STRIP << 16) | ETHERTYPE_VLAN);
692 }
693
694 /* Channel parse index configuration */
695 static void
696 nic_config_cpi(struct nicpf *nic, struct cpi_cfg_msg *cfg)
697 {
698         uint32_t vnic, bgx, lmac, chan;
699         uint32_t padd, cpi_count = 0;
700         uint64_t cpi_base, cpi, rssi_base, rssi;
701         uint8_t qset, rq_idx = 0;
702
703         vnic = cfg->vf_id;
704         bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
705         lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vnic]);
706
707         chan = (lmac * MAX_BGX_CHANS_PER_LMAC) + (bgx * NIC_CHANS_PER_INF);
708         cpi_base = (lmac * NIC_MAX_CPI_PER_LMAC) + (bgx * NIC_CPI_PER_BGX);
709         rssi_base = (lmac * nic->rss_ind_tbl_size) + (bgx * NIC_RSSI_PER_BGX);
710
711         /* Rx channel configuration */
712         nic_reg_write(nic, NIC_PF_CHAN_0_255_RX_BP_CFG | (chan << 3),
713             (1UL << 63) | (vnic << 0));
714         nic_reg_write(nic, NIC_PF_CHAN_0_255_RX_CFG | (chan << 3),
715             ((uint64_t)cfg->cpi_alg << 62) | (cpi_base << 48));
716
717         if (cfg->cpi_alg == CPI_ALG_NONE)
718                 cpi_count = 1;
719         else if (cfg->cpi_alg == CPI_ALG_VLAN) /* 3 bits of PCP */
720                 cpi_count = 8;
721         else if (cfg->cpi_alg == CPI_ALG_VLAN16) /* 3 bits PCP + DEI */
722                 cpi_count = 16;
723         else if (cfg->cpi_alg == CPI_ALG_DIFF) /* 6bits DSCP */
724                 cpi_count = NIC_MAX_CPI_PER_LMAC;
725
726         /* RSS Qset, Qidx mapping */
727         qset = cfg->vf_id;
728         rssi = rssi_base;
729         for (; rssi < (rssi_base + cfg->rq_cnt); rssi++) {
730                 nic_reg_write(nic, NIC_PF_RSSI_0_4097_RQ | (rssi << 3),
731                     (qset << 3) | rq_idx);
732                 rq_idx++;
733         }
734
735         rssi = 0;
736         cpi = cpi_base;
737         for (; cpi < (cpi_base + cpi_count); cpi++) {
738                 /* Determine port to channel adder */
739                 if (cfg->cpi_alg != CPI_ALG_DIFF)
740                         padd = cpi % cpi_count;
741                 else
742                         padd = cpi % 8; /* 3 bits CS out of 6bits DSCP */
743
744                 /* Leave RSS_SIZE as '0' to disable RSS */
745                 if (pass1_silicon(nic->dev)) {
746                         nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3),
747                             (vnic << 24) | (padd << 16) | (rssi_base + rssi));
748                 } else {
749                         /* Set MPI_ALG to '0' to disable MCAM parsing */
750                         nic_reg_write(nic, NIC_PF_CPI_0_2047_CFG | (cpi << 3),
751                             (padd << 16));
752                         /* MPI index is same as CPI if MPI_ALG is not enabled */
753                         nic_reg_write(nic, NIC_PF_MPI_0_2047_CFG | (cpi << 3),
754                             (vnic << 24) | (rssi_base + rssi));
755                 }
756
757                 if ((rssi + 1) >= cfg->rq_cnt)
758                         continue;
759
760                 if (cfg->cpi_alg == CPI_ALG_VLAN)
761                         rssi++;
762                 else if (cfg->cpi_alg == CPI_ALG_VLAN16)
763                         rssi = ((cpi - cpi_base) & 0xe) >> 1;
764                 else if (cfg->cpi_alg == CPI_ALG_DIFF)
765                         rssi = ((cpi - cpi_base) & 0x38) >> 3;
766         }
767         nic->cpi_base[cfg->vf_id] = cpi_base;
768         nic->rssi_base[cfg->vf_id] = rssi_base;
769 }
770
771 /* Responsds to VF with its RSS indirection table size */
772 static void
773 nic_send_rss_size(struct nicpf *nic, int vf)
774 {
775         union nic_mbx mbx = {};
776
777         mbx.rss_size.msg = NIC_MBOX_MSG_RSS_SIZE;
778         mbx.rss_size.ind_tbl_size = nic->rss_ind_tbl_size;
779         nic_send_msg_to_vf(nic, vf, &mbx);
780 }
781
782 /*
783  * Receive side scaling configuration
784  * configure:
785  * - RSS index
786  * - indir table i.e hash::RQ mapping
787  * - no of hash bits to consider
788  */
789 static void
790 nic_config_rss(struct nicpf *nic, struct rss_cfg_msg *cfg)
791 {
792         uint8_t qset, idx;
793         uint64_t cpi_cfg, cpi_base, rssi_base, rssi;
794         uint64_t idx_addr;
795
796         idx = 0;
797         rssi_base = nic->rssi_base[cfg->vf_id] + cfg->tbl_offset;
798
799         rssi = rssi_base;
800         qset = cfg->vf_id;
801
802         for (; rssi < (rssi_base + cfg->tbl_len); rssi++) {
803                 nic_reg_write(nic, NIC_PF_RSSI_0_4097_RQ | (rssi << 3),
804                     (qset << 3) | (cfg->ind_tbl[idx] & 0x7));
805                 idx++;
806         }
807
808         cpi_base = nic->cpi_base[cfg->vf_id];
809         if (pass1_silicon(nic->dev))
810                 idx_addr = NIC_PF_CPI_0_2047_CFG;
811         else
812                 idx_addr = NIC_PF_MPI_0_2047_CFG;
813         cpi_cfg = nic_reg_read(nic, idx_addr | (cpi_base << 3));
814         cpi_cfg &= ~(0xFUL << 20);
815         cpi_cfg |= (cfg->hash_bits << 20);
816         nic_reg_write(nic, idx_addr | (cpi_base << 3), cpi_cfg);
817 }
818
819 /*
820  * 4 level transmit side scheduler configutation
821  * for TNS bypass mode
822  *
823  * Sample configuration for SQ0
824  * VNIC0-SQ0 -> TL4(0)   -> TL3[0]   -> TL2[0]  -> TL1[0] -> BGX0
825  * VNIC1-SQ0 -> TL4(8)   -> TL3[2]   -> TL2[0]  -> TL1[0] -> BGX0
826  * VNIC2-SQ0 -> TL4(16)  -> TL3[4]   -> TL2[1]  -> TL1[0] -> BGX0
827  * VNIC3-SQ0 -> TL4(24)  -> TL3[6]   -> TL2[1]  -> TL1[0] -> BGX0
828  * VNIC4-SQ0 -> TL4(512) -> TL3[128] -> TL2[32] -> TL1[1] -> BGX1
829  * VNIC5-SQ0 -> TL4(520) -> TL3[130] -> TL2[32] -> TL1[1] -> BGX1
830  * VNIC6-SQ0 -> TL4(528) -> TL3[132] -> TL2[33] -> TL1[1] -> BGX1
831  * VNIC7-SQ0 -> TL4(536) -> TL3[134] -> TL2[33] -> TL1[1] -> BGX1
832  */
833 static void
834 nic_tx_channel_cfg(struct nicpf *nic, uint8_t vnic, struct sq_cfg_msg *sq)
835 {
836         uint32_t bgx, lmac, chan;
837         uint32_t tl2, tl3, tl4;
838         uint32_t rr_quantum;
839         uint8_t sq_idx = sq->sq_num;
840         uint8_t pqs_vnic;
841
842         pqs_vnic = vnic;
843
844         bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
845         lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[pqs_vnic]);
846
847         /* 24 bytes for FCS, IPG and preamble */
848         rr_quantum = ((NIC_HW_MAX_FRS + 24) / 4);
849
850         tl4 = (lmac * NIC_TL4_PER_LMAC) + (bgx * NIC_TL4_PER_BGX);
851         tl4 += sq_idx;
852
853         tl3 = tl4 / (NIC_MAX_TL4 / NIC_MAX_TL3);
854         nic_reg_write(nic, NIC_PF_QSET_0_127_SQ_0_7_CFG2 |
855             ((uint64_t)vnic << NIC_QS_ID_SHIFT) |
856             ((uint32_t)sq_idx << NIC_Q_NUM_SHIFT), tl4);
857         nic_reg_write(nic, NIC_PF_TL4_0_1023_CFG | (tl4 << 3),
858             ((uint64_t)vnic << 27) | ((uint32_t)sq_idx << 24) | rr_quantum);
859
860         nic_reg_write(nic, NIC_PF_TL3_0_255_CFG | (tl3 << 3), rr_quantum);
861         chan = (lmac * MAX_BGX_CHANS_PER_LMAC) + (bgx * NIC_CHANS_PER_INF);
862         nic_reg_write(nic, NIC_PF_TL3_0_255_CHAN | (tl3 << 3), chan);
863         /* Enable backpressure on the channel */
864         nic_reg_write(nic, NIC_PF_CHAN_0_255_TX_CFG | (chan << 3), 1);
865
866         tl2 = tl3 >> 2;
867         nic_reg_write(nic, NIC_PF_TL3A_0_63_CFG | (tl2 << 3), tl2);
868         nic_reg_write(nic, NIC_PF_TL2_0_63_CFG | (tl2 << 3), rr_quantum);
869         /* No priorities as of now */
870         nic_reg_write(nic, NIC_PF_TL2_0_63_PRI | (tl2 << 3), 0x00);
871 }
872
873 static int
874 nic_config_loopback(struct nicpf *nic, struct set_loopback *lbk)
875 {
876         int bgx_idx, lmac_idx;
877
878         if (lbk->vf_id > MAX_LMAC)
879                 return (ENXIO);
880
881         bgx_idx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lbk->vf_id]);
882         lmac_idx = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lbk->vf_id]);
883
884         bgx_lmac_internal_loopback(nic->node, bgx_idx, lmac_idx, lbk->enable);
885
886         return (0);
887 }
888
889 /* Interrupt handler to handle mailbox messages from VFs */
890 static void
891 nic_handle_mbx_intr(struct nicpf *nic, int vf)
892 {
893         union nic_mbx mbx = {};
894         uint64_t *mbx_data;
895         uint64_t mbx_addr;
896         uint64_t reg_addr;
897         uint64_t cfg;
898         int bgx, lmac;
899         int i;
900         int ret = 0;
901
902         nic->mbx_lock[vf] = TRUE;
903
904         mbx_addr = nic_get_mbx_addr(vf);
905         mbx_data = (uint64_t *)&mbx;
906
907         for (i = 0; i < NIC_PF_VF_MAILBOX_SIZE; i++) {
908                 *mbx_data = nic_reg_read(nic, mbx_addr);
909                 mbx_data++;
910                 mbx_addr += sizeof(uint64_t);
911         }
912
913         switch (mbx.msg.msg) {
914         case NIC_MBOX_MSG_READY:
915                 nic_mbx_send_ready(nic, vf);
916                 if (vf < MAX_LMAC) {
917                         nic->link[vf] = 0;
918                         nic->duplex[vf] = 0;
919                         nic->speed[vf] = 0;
920                 }
921                 ret = 1;
922                 break;
923         case NIC_MBOX_MSG_QS_CFG:
924                 reg_addr = NIC_PF_QSET_0_127_CFG |
925                     (mbx.qs.num << NIC_QS_ID_SHIFT);
926                 cfg = mbx.qs.cfg;
927                 nic_reg_write(nic, reg_addr, cfg);
928                 break;
929         case NIC_MBOX_MSG_RQ_CFG:
930                 reg_addr = NIC_PF_QSET_0_127_RQ_0_7_CFG |
931                     (mbx.rq.qs_num << NIC_QS_ID_SHIFT) |
932                     (mbx.rq.rq_num << NIC_Q_NUM_SHIFT);
933                 nic_reg_write(nic, reg_addr, mbx.rq.cfg);
934                 break;
935         case NIC_MBOX_MSG_RQ_BP_CFG:
936                 reg_addr = NIC_PF_QSET_0_127_RQ_0_7_BP_CFG |
937                     (mbx.rq.qs_num << NIC_QS_ID_SHIFT) |
938                     (mbx.rq.rq_num << NIC_Q_NUM_SHIFT);
939                 nic_reg_write(nic, reg_addr, mbx.rq.cfg);
940                 break;
941         case NIC_MBOX_MSG_RQ_SW_SYNC:
942                 ret = nic_rcv_queue_sw_sync(nic);
943                 break;
944         case NIC_MBOX_MSG_RQ_DROP_CFG:
945                 reg_addr = NIC_PF_QSET_0_127_RQ_0_7_DROP_CFG |
946                     (mbx.rq.qs_num << NIC_QS_ID_SHIFT) |
947                     (mbx.rq.rq_num << NIC_Q_NUM_SHIFT);
948                 nic_reg_write(nic, reg_addr, mbx.rq.cfg);
949                 break;
950         case NIC_MBOX_MSG_SQ_CFG:
951                 reg_addr = NIC_PF_QSET_0_127_SQ_0_7_CFG |
952                     (mbx.sq.qs_num << NIC_QS_ID_SHIFT) |
953                     (mbx.sq.sq_num << NIC_Q_NUM_SHIFT);
954                 nic_reg_write(nic, reg_addr, mbx.sq.cfg);
955                 nic_tx_channel_cfg(nic, mbx.qs.num, &mbx.sq);
956                 break;
957         case NIC_MBOX_MSG_SET_MAC:
958                 lmac = mbx.mac.vf_id;
959                 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
960                 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[lmac]);
961                 bgx_set_lmac_mac(nic->node, bgx, lmac, mbx.mac.mac_addr);
962                 break;
963         case NIC_MBOX_MSG_SET_MAX_FRS:
964                 ret = nic_update_hw_frs(nic, mbx.frs.max_frs, mbx.frs.vf_id);
965                 break;
966         case NIC_MBOX_MSG_CPI_CFG:
967                 nic_config_cpi(nic, &mbx.cpi_cfg);
968                 break;
969         case NIC_MBOX_MSG_RSS_SIZE:
970                 nic_send_rss_size(nic, vf);
971                 goto unlock;
972         case NIC_MBOX_MSG_RSS_CFG:
973         case NIC_MBOX_MSG_RSS_CFG_CONT: /* fall through */
974                 nic_config_rss(nic, &mbx.rss_cfg);
975                 break;
976         case NIC_MBOX_MSG_CFG_DONE:
977                 /* Last message of VF config msg sequence */
978                 nic->vf_info[vf].vf_enabled = TRUE;
979                 goto unlock;
980         case NIC_MBOX_MSG_SHUTDOWN:
981                 /* First msg in VF teardown sequence */
982                 nic->vf_info[vf].vf_enabled = FALSE;
983                 break;
984         case NIC_MBOX_MSG_BGX_STATS:
985                 nic_get_bgx_stats(nic, &mbx.bgx_stats);
986                 goto unlock;
987         case NIC_MBOX_MSG_LOOPBACK:
988                 ret = nic_config_loopback(nic, &mbx.lbk);
989                 break;
990         default:
991                 device_printf(nic->dev,
992                     "Invalid msg from VF%d, msg 0x%x\n", vf, mbx.msg.msg);
993                 break;
994         }
995
996         if (ret == 0)
997                 nic_mbx_send_ack(nic, vf);
998         else if (mbx.msg.msg != NIC_MBOX_MSG_READY)
999                 nic_mbx_send_nack(nic, vf);
1000 unlock:
1001         nic->mbx_lock[vf] = FALSE;
1002 }
1003
1004 static void
1005 nic_mbx_intr_handler(struct nicpf *nic, int mbx)
1006 {
1007         uint64_t intr;
1008         uint8_t  vf, vf_per_mbx_reg = 64;
1009
1010         intr = nic_reg_read(nic, NIC_PF_MAILBOX_INT + (mbx << 3));
1011         for (vf = 0; vf < vf_per_mbx_reg; vf++) {
1012                 if (intr & (1UL << vf)) {
1013                         nic_handle_mbx_intr(nic, vf + (mbx * vf_per_mbx_reg));
1014                         nic_clear_mbx_intr(nic, vf, mbx);
1015                 }
1016         }
1017 }
1018
1019 static void
1020 nic_mbx0_intr_handler (void *arg)
1021 {
1022         struct nicpf *nic = (struct nicpf *)arg;
1023
1024         nic_mbx_intr_handler(nic, 0);
1025 }
1026
1027 static void
1028 nic_mbx1_intr_handler (void *arg)
1029 {
1030         struct nicpf *nic = (struct nicpf *)arg;
1031
1032         nic_mbx_intr_handler(nic, 1);
1033 }
1034
1035 static int
1036 nic_enable_msix(struct nicpf *nic)
1037 {
1038         struct pci_devinfo *dinfo;
1039         int rid, count;
1040         int ret;
1041
1042         dinfo = device_get_ivars(nic->dev);
1043         rid = dinfo->cfg.msix.msix_table_bar;
1044         nic->msix_table_res =
1045             bus_alloc_resource_any(nic->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
1046         if (nic->msix_table_res == NULL) {
1047                 device_printf(nic->dev,
1048                     "Could not allocate memory for MSI-X table\n");
1049                 return (ENXIO);
1050         }
1051
1052         count = nic->num_vec = NIC_PF_MSIX_VECTORS;
1053
1054         ret = pci_alloc_msix(nic->dev, &count);
1055         if ((ret != 0) || (count != nic->num_vec)) {
1056                 device_printf(nic->dev,
1057                     "Request for #%d msix vectors failed, error: %d\n",
1058                     nic->num_vec, ret);
1059                 return (ret);
1060         }
1061
1062         nic->msix_enabled = 1;
1063         return (0);
1064 }
1065
1066 static void
1067 nic_disable_msix(struct nicpf *nic)
1068 {
1069         if (nic->msix_enabled) {
1070                 pci_release_msi(nic->dev);
1071                 nic->msix_enabled = 0;
1072                 nic->num_vec = 0;
1073         }
1074
1075         bus_release_resource(nic->dev, SYS_RES_MEMORY,
1076             rman_get_rid(nic->msix_table_res), nic->msix_table_res);
1077 }
1078
1079 static void
1080 nic_free_all_interrupts(struct nicpf *nic)
1081 {
1082         int irq;
1083
1084         for (irq = 0; irq < nic->num_vec; irq++) {
1085                 if (nic->msix_entries[irq].irq_res == NULL)
1086                         continue;
1087                 if (nic->msix_entries[irq].handle != NULL) {
1088                         bus_teardown_intr(nic->dev,
1089                             nic->msix_entries[irq].irq_res,
1090                             nic->msix_entries[irq].handle);
1091                 }
1092
1093                 bus_release_resource(nic->dev, SYS_RES_IRQ, irq + 1,
1094                     nic->msix_entries[irq].irq_res);
1095         }
1096 }
1097
1098 static int
1099 nic_register_interrupts(struct nicpf *nic)
1100 {
1101         int irq, rid;
1102         int ret;
1103
1104         /* Enable MSI-X */
1105         ret = nic_enable_msix(nic);
1106         if (ret != 0)
1107                 return (ret);
1108
1109         /* Register mailbox interrupt handlers */
1110         irq = NIC_PF_INTR_ID_MBOX0;
1111         rid = irq + 1;
1112         nic->msix_entries[irq].irq_res = bus_alloc_resource_any(nic->dev,
1113             SYS_RES_IRQ, &rid, (RF_SHAREABLE | RF_ACTIVE));
1114         if (nic->msix_entries[irq].irq_res == NULL) {
1115                 ret = ENXIO;
1116                 goto fail;
1117         }
1118         ret = bus_setup_intr(nic->dev, nic->msix_entries[irq].irq_res,
1119             (INTR_MPSAFE | INTR_TYPE_MISC), NULL, nic_mbx0_intr_handler, nic,
1120             &nic->msix_entries[irq].handle);
1121         if (ret != 0)
1122                 goto fail;
1123
1124         irq = NIC_PF_INTR_ID_MBOX1;
1125         rid = irq + 1;
1126         nic->msix_entries[irq].irq_res = bus_alloc_resource_any(nic->dev,
1127             SYS_RES_IRQ, &rid, (RF_SHAREABLE | RF_ACTIVE));
1128         if (nic->msix_entries[irq].irq_res == NULL) {
1129                 ret = ENXIO;
1130                 goto fail;
1131         }
1132         ret = bus_setup_intr(nic->dev, nic->msix_entries[irq].irq_res,
1133             (INTR_MPSAFE | INTR_TYPE_MISC), NULL, nic_mbx1_intr_handler, nic,
1134             &nic->msix_entries[irq].handle);
1135         if (ret != 0)
1136                 goto fail;
1137
1138         /* Enable mailbox interrupt */
1139         nic_enable_mbx_intr(nic);
1140         return (0);
1141
1142 fail:
1143         nic_free_all_interrupts(nic);
1144         return (ret);
1145 }
1146
1147 static void
1148 nic_unregister_interrupts(struct nicpf *nic)
1149 {
1150
1151         nic_free_all_interrupts(nic);
1152         nic_disable_msix(nic);
1153 }
1154
1155 static int nic_sriov_init(device_t dev, struct nicpf *nic)
1156 {
1157 #ifdef PCI_IOV
1158         nvlist_t *pf_schema, *vf_schema;
1159         int iov_pos;
1160         int err;
1161         uint16_t total_vf_cnt;
1162
1163         err = pci_find_extcap(dev, PCIZ_SRIOV, &iov_pos);
1164         if (err != 0) {
1165                 device_printf(dev,
1166                     "SR-IOV capability is not found in PCIe config space\n");
1167                 return (err);
1168         }
1169         /* Fix-up the number of enabled VFs */
1170         total_vf_cnt = pci_read_config(dev, iov_pos + PCIR_SRIOV_TOTAL_VFS, 2);
1171         if (total_vf_cnt == 0)
1172                 return (ENXIO);
1173
1174         /* Attach SR-IOV */
1175         pf_schema = pci_iov_schema_alloc_node();
1176         vf_schema = pci_iov_schema_alloc_node();
1177         pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
1178         /*
1179          * All VFs can change their MACs.
1180          * This flag will be ignored but we set it just for the record.
1181          */
1182         pci_iov_schema_add_bool(vf_schema, "allow-set-mac",
1183             IOV_SCHEMA_HASDEFAULT, TRUE);
1184
1185         err = pci_iov_attach(dev, pf_schema, vf_schema);
1186         if (err != 0) {
1187                 device_printf(dev,
1188                     "Failed to initialize SR-IOV (error=%d)\n",
1189                     err);
1190                 return (err);
1191         }
1192 #endif
1193         return (0);
1194 }
1195
1196 /*
1197  * Poll for BGX LMAC link status and update corresponding VF
1198  * if there is a change, valid only if internal L2 switch
1199  * is not present otherwise VF link is always treated as up
1200  */
1201 static void
1202 nic_poll_for_link(void *arg)
1203 {
1204         union nic_mbx mbx = {};
1205         struct nicpf *nic;
1206         struct bgx_link_status link;
1207         uint8_t vf, bgx, lmac;
1208
1209         nic = (struct nicpf *)arg;
1210
1211         mbx.link_status.msg = NIC_MBOX_MSG_BGX_LINK_CHANGE;
1212
1213         for (vf = 0; vf < nic->num_vf_en; vf++) {
1214                 /* Poll only if VF is UP */
1215                 if (!nic->vf_info[vf].vf_enabled)
1216                         continue;
1217
1218                 /* Get BGX, LMAC indices for the VF */
1219                 bgx = NIC_GET_BGX_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
1220                 lmac = NIC_GET_LMAC_FROM_VF_LMAC_MAP(nic->vf_lmac_map[vf]);
1221                 /* Get interface link status */
1222                 bgx_get_lmac_link_state(nic->node, bgx, lmac, &link);
1223
1224                 /* Inform VF only if link status changed */
1225                 if (nic->link[vf] == link.link_up)
1226                         continue;
1227
1228                 if (!nic->mbx_lock[vf]) {
1229                         nic->link[vf] = link.link_up;
1230                         nic->duplex[vf] = link.duplex;
1231                         nic->speed[vf] = link.speed;
1232
1233                         /* Send a mbox message to VF with current link status */
1234                         mbx.link_status.link_up = link.link_up;
1235                         mbx.link_status.duplex = link.duplex;
1236                         mbx.link_status.speed = link.speed;
1237                         nic_send_msg_to_vf(nic, vf, &mbx);
1238                 }
1239         }
1240         callout_reset(&nic->check_link, hz * 2, nic_poll_for_link, nic);
1241 }