1f91fca5bSJohn Baldwin /*-
2f91fca5bSJohn Baldwin * Copyright (c) 2015-2016 Chelsio Communications, Inc.
3f91fca5bSJohn Baldwin * All rights reserved.
4f91fca5bSJohn Baldwin * Written by: John Baldwin <jhb@FreeBSD.org>
5f91fca5bSJohn Baldwin *
6f91fca5bSJohn Baldwin * Redistribution and use in source and binary forms, with or without
7f91fca5bSJohn Baldwin * modification, are permitted provided that the following conditions
8f91fca5bSJohn Baldwin * are met:
9f91fca5bSJohn Baldwin * 1. Redistributions of source code must retain the above copyright
10f91fca5bSJohn Baldwin * notice, this list of conditions and the following disclaimer.
11f91fca5bSJohn Baldwin * 2. Redistributions in binary form must reproduce the above copyright
12f91fca5bSJohn Baldwin * notice, this list of conditions and the following disclaimer in the
13f91fca5bSJohn Baldwin * documentation and/or other materials provided with the distribution.
14f91fca5bSJohn Baldwin *
15f91fca5bSJohn Baldwin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16f91fca5bSJohn Baldwin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17f91fca5bSJohn Baldwin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18f91fca5bSJohn Baldwin * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19f91fca5bSJohn Baldwin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20f91fca5bSJohn Baldwin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21f91fca5bSJohn Baldwin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22f91fca5bSJohn Baldwin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23f91fca5bSJohn Baldwin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24f91fca5bSJohn Baldwin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25f91fca5bSJohn Baldwin * SUCH DAMAGE.
26f91fca5bSJohn Baldwin */
27f91fca5bSJohn Baldwin
28f91fca5bSJohn Baldwin #include <sys/param.h>
29f91fca5bSJohn Baldwin #include <sys/bus.h>
30f91fca5bSJohn Baldwin #include <sys/kernel.h>
31f91fca5bSJohn Baldwin #include <sys/module.h>
321389314dSKristof Provost #include <sys/socket.h>
33f91fca5bSJohn Baldwin #include <sys/systm.h>
341389314dSKristof Provost #include <sys/iov.h>
35f91fca5bSJohn Baldwin #include <dev/pci/pcivar.h>
361389314dSKristof Provost #include <net/if.h>
371389314dSKristof Provost #include <net/if_vlan_var.h>
38f91fca5bSJohn Baldwin
39f91fca5bSJohn Baldwin #ifdef PCI_IOV
40f91fca5bSJohn Baldwin #include <sys/nv.h>
41f91fca5bSJohn Baldwin #include <sys/iov_schema.h>
42f91fca5bSJohn Baldwin #include <dev/pci/pci_iov.h>
43f91fca5bSJohn Baldwin #endif
44f91fca5bSJohn Baldwin
450ed5eff9SJohn Baldwin #include "common/common.h"
46de0a3472SNavdeep Parhar #include "common/t4_regs.h"
47f91fca5bSJohn Baldwin #include "t4_if.h"
48f91fca5bSJohn Baldwin
49f91fca5bSJohn Baldwin struct t4iov_softc {
50f91fca5bSJohn Baldwin device_t sc_dev;
51f91fca5bSJohn Baldwin device_t sc_main;
52f91fca5bSJohn Baldwin bool sc_attached;
53de0a3472SNavdeep Parhar
54de0a3472SNavdeep Parhar int pf;
55de0a3472SNavdeep Parhar int regs_rid;
56de0a3472SNavdeep Parhar struct resource *regs_res;
57de0a3472SNavdeep Parhar bus_space_handle_t bh;
58de0a3472SNavdeep Parhar bus_space_tag_t bt;
59f91fca5bSJohn Baldwin };
60f91fca5bSJohn Baldwin
61f91fca5bSJohn Baldwin struct {
62f91fca5bSJohn Baldwin uint16_t device;
63f91fca5bSJohn Baldwin char *desc;
64f91fca5bSJohn Baldwin } t4iov_pciids[] = {
65f91fca5bSJohn Baldwin {0x4000, "Chelsio T440-dbg"},
66f91fca5bSJohn Baldwin {0x4001, "Chelsio T420-CR"},
67f91fca5bSJohn Baldwin {0x4002, "Chelsio T422-CR"},
68f91fca5bSJohn Baldwin {0x4003, "Chelsio T440-CR"},
69f91fca5bSJohn Baldwin {0x4004, "Chelsio T420-BCH"},
70f91fca5bSJohn Baldwin {0x4005, "Chelsio T440-BCH"},
71f91fca5bSJohn Baldwin {0x4006, "Chelsio T440-CH"},
72f91fca5bSJohn Baldwin {0x4007, "Chelsio T420-SO"},
73f91fca5bSJohn Baldwin {0x4008, "Chelsio T420-CX"},
74f91fca5bSJohn Baldwin {0x4009, "Chelsio T420-BT"},
75f91fca5bSJohn Baldwin {0x400a, "Chelsio T404-BT"},
76f91fca5bSJohn Baldwin {0x400e, "Chelsio T440-LP-CR"},
77f91fca5bSJohn Baldwin }, t5iov_pciids[] = {
78f91fca5bSJohn Baldwin {0x5000, "Chelsio T580-dbg"},
79f91fca5bSJohn Baldwin {0x5001, "Chelsio T520-CR"}, /* 2 x 10G */
80f91fca5bSJohn Baldwin {0x5002, "Chelsio T522-CR"}, /* 2 x 10G, 2 X 1G */
81f91fca5bSJohn Baldwin {0x5003, "Chelsio T540-CR"}, /* 4 x 10G */
82f91fca5bSJohn Baldwin {0x5007, "Chelsio T520-SO"}, /* 2 x 10G, nomem */
83f91fca5bSJohn Baldwin {0x5009, "Chelsio T520-BT"}, /* 2 x 10GBaseT */
84f91fca5bSJohn Baldwin {0x500a, "Chelsio T504-BT"}, /* 4 x 1G */
85f91fca5bSJohn Baldwin {0x500d, "Chelsio T580-CR"}, /* 2 x 40G */
86f91fca5bSJohn Baldwin {0x500e, "Chelsio T540-LP-CR"}, /* 4 x 10G */
87f91fca5bSJohn Baldwin {0x5010, "Chelsio T580-LP-CR"}, /* 2 x 40G */
88f91fca5bSJohn Baldwin {0x5011, "Chelsio T520-LL-CR"}, /* 2 x 10G */
89f91fca5bSJohn Baldwin {0x5012, "Chelsio T560-CR"}, /* 1 x 40G, 2 x 10G */
90f91fca5bSJohn Baldwin {0x5014, "Chelsio T580-LP-SO-CR"}, /* 2 x 40G, nomem */
91f91fca5bSJohn Baldwin {0x5015, "Chelsio T502-BT"}, /* 2 x 1G */
925877e649SNavdeep Parhar {0x5018, "Chelsio T540-BT"}, /* 4 x 10GBaseT */
935877e649SNavdeep Parhar {0x5019, "Chelsio T540-LP-BT"}, /* 4 x 10GBaseT */
945877e649SNavdeep Parhar {0x501a, "Chelsio T540-SO-BT"}, /* 4 x 10GBaseT, nomem */
955877e649SNavdeep Parhar {0x501b, "Chelsio T540-SO-CR"}, /* 4 x 10G, nomem */
96e6b81479SNavdeep Parhar }, t6iov_pciids[] = {
9763febe64SNavdeep Parhar {0x6000, "Chelsio T6-DBG-25"}, /* 2 x 10/25G, debug */
98e6b81479SNavdeep Parhar {0x6001, "Chelsio T6225-CR"}, /* 2 x 10/25G */
99e6b81479SNavdeep Parhar {0x6002, "Chelsio T6225-SO-CR"}, /* 2 x 10/25G, nomem */
10063febe64SNavdeep Parhar {0x6003, "Chelsio T6425-CR"}, /* 4 x 10/25G */
10149c0beb6SNavdeep Parhar {0x6004, "Chelsio T6425-SO-CR"}, /* 4 x 10/25G, nomem */
102*5c150949SNavdeep Parhar {0x6005, "Chelsio T6225-SO-OCP3"}, /* 2 x 10/25G, nomem */
103*5c150949SNavdeep Parhar {0x6006, "Chelsio T6225-OCP3"}, /* 2 x 10/25G */
104e6b81479SNavdeep Parhar {0x6007, "Chelsio T62100-LP-CR"}, /* 2 x 40/50/100G */
105e6b81479SNavdeep Parhar {0x6008, "Chelsio T62100-SO-CR"}, /* 2 x 40/50/100G, nomem */
10663febe64SNavdeep Parhar {0x6009, "Chelsio T6210-BT"}, /* 2 x 10GBASE-T */
107e6b81479SNavdeep Parhar {0x600d, "Chelsio T62100-CR"}, /* 2 x 40/50/100G */
10863febe64SNavdeep Parhar {0x6010, "Chelsio T6-DBG-100"}, /* 2 x 40/50/100G, debug */
10963febe64SNavdeep Parhar {0x6011, "Chelsio T6225-LL-CR"}, /* 2 x 10/25G */
110*5c150949SNavdeep Parhar {0x6014, "Chelsio T62100-SO-OCP3"}, /* 2 x 40/50/100G, nomem */
11163febe64SNavdeep Parhar {0x6015, "Chelsio T6201-BT"}, /* 2 x 1000BASE-T */
11263febe64SNavdeep Parhar
11363febe64SNavdeep Parhar /* Custom */
11463febe64SNavdeep Parhar {0x6080, "Chelsio T6225 80"},
11563febe64SNavdeep Parhar {0x6081, "Chelsio T62100 81"},
1165877e649SNavdeep Parhar {0x6082, "Chelsio T6225-CR 82"},
1175877e649SNavdeep Parhar {0x6083, "Chelsio T62100-CR 83"},
1185877e649SNavdeep Parhar {0x6084, "Chelsio T64100-CR 84"},
1195877e649SNavdeep Parhar {0x6085, "Chelsio T6240-SO 85"},
1205877e649SNavdeep Parhar {0x6086, "Chelsio T6225-SO-CR 86"},
1215877e649SNavdeep Parhar {0x6087, "Chelsio T6225-CR 87"},
122f91fca5bSJohn Baldwin };
123f91fca5bSJohn Baldwin
124de0a3472SNavdeep Parhar static inline uint32_t
t4iov_read_reg(struct t4iov_softc * sc,uint32_t reg)125de0a3472SNavdeep Parhar t4iov_read_reg(struct t4iov_softc *sc, uint32_t reg)
126de0a3472SNavdeep Parhar {
127de0a3472SNavdeep Parhar
128de0a3472SNavdeep Parhar return bus_space_read_4(sc->bt, sc->bh, reg);
129de0a3472SNavdeep Parhar }
130de0a3472SNavdeep Parhar
131f91fca5bSJohn Baldwin static int t4iov_attach_child(device_t dev);
132f91fca5bSJohn Baldwin
133f91fca5bSJohn Baldwin static int
t4iov_probe(device_t dev)134f91fca5bSJohn Baldwin t4iov_probe(device_t dev)
135f91fca5bSJohn Baldwin {
136f91fca5bSJohn Baldwin uint16_t d;
137f91fca5bSJohn Baldwin size_t i;
138f91fca5bSJohn Baldwin
1390ed5eff9SJohn Baldwin if (pci_get_vendor(dev) != PCI_VENDOR_ID_CHELSIO)
1400ed5eff9SJohn Baldwin return (ENXIO);
1410ed5eff9SJohn Baldwin
142f91fca5bSJohn Baldwin d = pci_get_device(dev);
143f91fca5bSJohn Baldwin for (i = 0; i < nitems(t4iov_pciids); i++) {
144f91fca5bSJohn Baldwin if (d == t4iov_pciids[i].device) {
145f91fca5bSJohn Baldwin device_set_desc(dev, t4iov_pciids[i].desc);
146847bfa8eSJohn Baldwin device_quiet(dev);
147f91fca5bSJohn Baldwin return (BUS_PROBE_DEFAULT);
148f91fca5bSJohn Baldwin }
149f91fca5bSJohn Baldwin }
150f91fca5bSJohn Baldwin return (ENXIO);
151f91fca5bSJohn Baldwin }
152f91fca5bSJohn Baldwin
153f91fca5bSJohn Baldwin static int
t5iov_probe(device_t dev)154f91fca5bSJohn Baldwin t5iov_probe(device_t dev)
155f91fca5bSJohn Baldwin {
156f91fca5bSJohn Baldwin uint16_t d;
157f91fca5bSJohn Baldwin size_t i;
158f91fca5bSJohn Baldwin
1590ed5eff9SJohn Baldwin if (pci_get_vendor(dev) != PCI_VENDOR_ID_CHELSIO)
1600ed5eff9SJohn Baldwin return (ENXIO);
1610ed5eff9SJohn Baldwin
162f91fca5bSJohn Baldwin d = pci_get_device(dev);
163f91fca5bSJohn Baldwin for (i = 0; i < nitems(t5iov_pciids); i++) {
164f91fca5bSJohn Baldwin if (d == t5iov_pciids[i].device) {
165f91fca5bSJohn Baldwin device_set_desc(dev, t5iov_pciids[i].desc);
166847bfa8eSJohn Baldwin device_quiet(dev);
167f91fca5bSJohn Baldwin return (BUS_PROBE_DEFAULT);
168f91fca5bSJohn Baldwin }
169f91fca5bSJohn Baldwin }
170f91fca5bSJohn Baldwin return (ENXIO);
171f91fca5bSJohn Baldwin }
172f91fca5bSJohn Baldwin
173f91fca5bSJohn Baldwin static int
t6iov_probe(device_t dev)174e6b81479SNavdeep Parhar t6iov_probe(device_t dev)
175e6b81479SNavdeep Parhar {
176e6b81479SNavdeep Parhar uint16_t d;
177e6b81479SNavdeep Parhar size_t i;
178e6b81479SNavdeep Parhar
1790ed5eff9SJohn Baldwin if (pci_get_vendor(dev) != PCI_VENDOR_ID_CHELSIO)
1800ed5eff9SJohn Baldwin return (ENXIO);
1810ed5eff9SJohn Baldwin
182e6b81479SNavdeep Parhar d = pci_get_device(dev);
183e6b81479SNavdeep Parhar for (i = 0; i < nitems(t6iov_pciids); i++) {
184e6b81479SNavdeep Parhar if (d == t6iov_pciids[i].device) {
185e6b81479SNavdeep Parhar device_set_desc(dev, t6iov_pciids[i].desc);
186e6b81479SNavdeep Parhar device_quiet(dev);
187e6b81479SNavdeep Parhar return (BUS_PROBE_DEFAULT);
188e6b81479SNavdeep Parhar }
189e6b81479SNavdeep Parhar }
190e6b81479SNavdeep Parhar return (ENXIO);
191e6b81479SNavdeep Parhar }
192e6b81479SNavdeep Parhar
193e6b81479SNavdeep Parhar static int
t4iov_attach(device_t dev)194f91fca5bSJohn Baldwin t4iov_attach(device_t dev)
195f91fca5bSJohn Baldwin {
196f91fca5bSJohn Baldwin struct t4iov_softc *sc;
197de0a3472SNavdeep Parhar uint32_t pl_rev, whoami;
198d2070e5fSJohn Baldwin int error;
199f91fca5bSJohn Baldwin
200f91fca5bSJohn Baldwin sc = device_get_softc(dev);
201f91fca5bSJohn Baldwin sc->sc_dev = dev;
202f91fca5bSJohn Baldwin
203de0a3472SNavdeep Parhar sc->regs_rid = PCIR_BAR(0);
204de0a3472SNavdeep Parhar sc->regs_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
205de0a3472SNavdeep Parhar &sc->regs_rid, RF_ACTIVE);
206de0a3472SNavdeep Parhar if (sc->regs_res == NULL) {
207de0a3472SNavdeep Parhar device_printf(dev, "cannot map registers.\n");
208de0a3472SNavdeep Parhar return (ENXIO);
209de0a3472SNavdeep Parhar }
210de0a3472SNavdeep Parhar sc->bt = rman_get_bustag(sc->regs_res);
211de0a3472SNavdeep Parhar sc->bh = rman_get_bushandle(sc->regs_res);
212de0a3472SNavdeep Parhar
213de0a3472SNavdeep Parhar pl_rev = t4iov_read_reg(sc, A_PL_REV);
214de0a3472SNavdeep Parhar whoami = t4iov_read_reg(sc, A_PL_WHOAMI);
215de0a3472SNavdeep Parhar if (G_CHIPID(pl_rev) <= CHELSIO_T5)
216de0a3472SNavdeep Parhar sc->pf = G_SOURCEPF(whoami);
217de0a3472SNavdeep Parhar else
218de0a3472SNavdeep Parhar sc->pf = G_T6_SOURCEPF(whoami);
219de0a3472SNavdeep Parhar
220f91fca5bSJohn Baldwin sc->sc_main = pci_find_dbsf(pci_get_domain(dev), pci_get_bus(dev),
221f91fca5bSJohn Baldwin pci_get_slot(dev), 4);
222d2070e5fSJohn Baldwin if (sc->sc_main == NULL) {
223d2070e5fSJohn Baldwin bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid,
224d2070e5fSJohn Baldwin sc->regs_res);
2250ed5eff9SJohn Baldwin return (ENXIO);
226d2070e5fSJohn Baldwin }
227d2070e5fSJohn Baldwin if (T4_IS_MAIN_READY(sc->sc_main) == 0) {
228d2070e5fSJohn Baldwin error = t4iov_attach_child(dev);
229d2070e5fSJohn Baldwin if (error != 0)
230d2070e5fSJohn Baldwin bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid,
231d2070e5fSJohn Baldwin sc->regs_res);
232d2070e5fSJohn Baldwin return (error);
233d2070e5fSJohn Baldwin }
234f91fca5bSJohn Baldwin return (0);
235f91fca5bSJohn Baldwin }
236f91fca5bSJohn Baldwin
237f91fca5bSJohn Baldwin static int
t4iov_attach_child(device_t dev)238f91fca5bSJohn Baldwin t4iov_attach_child(device_t dev)
239f91fca5bSJohn Baldwin {
240f91fca5bSJohn Baldwin struct t4iov_softc *sc;
241f91fca5bSJohn Baldwin #ifdef PCI_IOV
242f91fca5bSJohn Baldwin nvlist_t *pf_schema, *vf_schema;
243f91fca5bSJohn Baldwin #endif
244847bfa8eSJohn Baldwin device_t pdev;
245847bfa8eSJohn Baldwin int error;
246f91fca5bSJohn Baldwin
247f91fca5bSJohn Baldwin sc = device_get_softc(dev);
248f91fca5bSJohn Baldwin MPASS(!sc->sc_attached);
249f91fca5bSJohn Baldwin
250f91fca5bSJohn Baldwin /*
251f91fca5bSJohn Baldwin * PF0-3 are associated with a specific port on the NIC (PF0
252847bfa8eSJohn Baldwin * with port 0, etc.). Ask the PF4 driver for the device for
253847bfa8eSJohn Baldwin * this function's associated port to determine if the port is
254847bfa8eSJohn Baldwin * present.
255f91fca5bSJohn Baldwin */
256847bfa8eSJohn Baldwin error = T4_READ_PORT_DEVICE(sc->sc_main, pci_get_function(dev), &pdev);
257f91fca5bSJohn Baldwin if (error)
258f91fca5bSJohn Baldwin return (0);
259f91fca5bSJohn Baldwin
260f91fca5bSJohn Baldwin #ifdef PCI_IOV
261f91fca5bSJohn Baldwin pf_schema = pci_iov_schema_alloc_node();
262f91fca5bSJohn Baldwin vf_schema = pci_iov_schema_alloc_node();
263de0a3472SNavdeep Parhar pci_iov_schema_add_unicast_mac(vf_schema, "mac-addr", 0, NULL);
2641389314dSKristof Provost pci_iov_schema_add_vlan(vf_schema, "vlan", 0, 0);
265847bfa8eSJohn Baldwin error = pci_iov_attach_name(dev, pf_schema, vf_schema, "%s",
266847bfa8eSJohn Baldwin device_get_nameunit(pdev));
267f91fca5bSJohn Baldwin if (error) {
268f91fca5bSJohn Baldwin device_printf(dev, "Failed to initialize SR-IOV: %d\n", error);
269f91fca5bSJohn Baldwin return (0);
270f91fca5bSJohn Baldwin }
271f91fca5bSJohn Baldwin #endif
272f91fca5bSJohn Baldwin
273f91fca5bSJohn Baldwin sc->sc_attached = true;
274f91fca5bSJohn Baldwin return (0);
275f91fca5bSJohn Baldwin }
276f91fca5bSJohn Baldwin
277f91fca5bSJohn Baldwin static int
t4iov_detach_child(device_t dev)278f91fca5bSJohn Baldwin t4iov_detach_child(device_t dev)
279f91fca5bSJohn Baldwin {
280f91fca5bSJohn Baldwin struct t4iov_softc *sc;
281f91fca5bSJohn Baldwin #ifdef PCI_IOV
282f91fca5bSJohn Baldwin int error;
283f91fca5bSJohn Baldwin #endif
284f91fca5bSJohn Baldwin
285f91fca5bSJohn Baldwin sc = device_get_softc(dev);
286f91fca5bSJohn Baldwin if (!sc->sc_attached)
287f91fca5bSJohn Baldwin return (0);
288f91fca5bSJohn Baldwin
289f91fca5bSJohn Baldwin #ifdef PCI_IOV
290f91fca5bSJohn Baldwin error = pci_iov_detach(dev);
291f91fca5bSJohn Baldwin if (error != 0) {
292f91fca5bSJohn Baldwin device_printf(dev, "Failed to disable SR-IOV\n");
293f91fca5bSJohn Baldwin return (error);
294f91fca5bSJohn Baldwin }
295f91fca5bSJohn Baldwin #endif
296f91fca5bSJohn Baldwin
297f91fca5bSJohn Baldwin sc->sc_attached = false;
298f91fca5bSJohn Baldwin return (0);
299f91fca5bSJohn Baldwin }
300f91fca5bSJohn Baldwin
301f91fca5bSJohn Baldwin static int
t4iov_detach(device_t dev)302f91fca5bSJohn Baldwin t4iov_detach(device_t dev)
303f91fca5bSJohn Baldwin {
304f91fca5bSJohn Baldwin struct t4iov_softc *sc;
305bc32f054SJohn Baldwin int error;
306f91fca5bSJohn Baldwin
307f91fca5bSJohn Baldwin sc = device_get_softc(dev);
308bc32f054SJohn Baldwin if (sc->sc_attached) {
309bc32f054SJohn Baldwin error = t4iov_detach_child(dev);
310bc32f054SJohn Baldwin if (error)
311bc32f054SJohn Baldwin return (error);
312bc32f054SJohn Baldwin }
313de0a3472SNavdeep Parhar if (sc->regs_res) {
314de0a3472SNavdeep Parhar bus_release_resource(dev, SYS_RES_MEMORY, sc->regs_rid,
315de0a3472SNavdeep Parhar sc->regs_res);
316de0a3472SNavdeep Parhar }
317f91fca5bSJohn Baldwin return (0);
318f91fca5bSJohn Baldwin }
319f91fca5bSJohn Baldwin
320f91fca5bSJohn Baldwin #ifdef PCI_IOV
321f91fca5bSJohn Baldwin static int
t4iov_iov_init(device_t dev,uint16_t num_vfs,const struct nvlist * config)322f91fca5bSJohn Baldwin t4iov_iov_init(device_t dev, uint16_t num_vfs, const struct nvlist *config)
323f91fca5bSJohn Baldwin {
324f91fca5bSJohn Baldwin
325f91fca5bSJohn Baldwin /* XXX: The Linux driver sets up a vf_monitor task on T4 adapters. */
326f91fca5bSJohn Baldwin return (0);
327f91fca5bSJohn Baldwin }
328f91fca5bSJohn Baldwin
329f91fca5bSJohn Baldwin static void
t4iov_iov_uninit(device_t dev)330f91fca5bSJohn Baldwin t4iov_iov_uninit(device_t dev)
331f91fca5bSJohn Baldwin {
332f91fca5bSJohn Baldwin }
333f91fca5bSJohn Baldwin
334f91fca5bSJohn Baldwin static int
t4iov_add_vf(device_t dev,uint16_t vfnum,const struct nvlist * config)335f91fca5bSJohn Baldwin t4iov_add_vf(device_t dev, uint16_t vfnum, const struct nvlist *config)
336f91fca5bSJohn Baldwin {
337de0a3472SNavdeep Parhar const void *mac;
338de0a3472SNavdeep Parhar struct t4iov_softc *sc;
339de0a3472SNavdeep Parhar struct adapter *adap;
340de0a3472SNavdeep Parhar uint8_t ma[ETHER_ADDR_LEN];
341de0a3472SNavdeep Parhar size_t size;
342de0a3472SNavdeep Parhar int rc;
343de0a3472SNavdeep Parhar
344de0a3472SNavdeep Parhar sc = device_get_softc(dev);
345de0a3472SNavdeep Parhar MPASS(sc->sc_attached);
346de0a3472SNavdeep Parhar MPASS(sc->sc_main != NULL);
347de0a3472SNavdeep Parhar adap = device_get_softc(sc->sc_main);
3481389314dSKristof Provost
3491389314dSKristof Provost if (nvlist_exists_binary(config, "mac-addr")) {
3501389314dSKristof Provost mac = nvlist_get_binary(config, "mac-addr", &size);
3511389314dSKristof Provost bcopy(mac, ma, ETHER_ADDR_LEN);
3521389314dSKristof Provost
353de0a3472SNavdeep Parhar if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK,
354de0a3472SNavdeep Parhar "t4vfma") != 0)
355de0a3472SNavdeep Parhar return (ENXIO);
356de0a3472SNavdeep Parhar rc = -t4_set_vf_mac(adap, sc->pf, vfnum + 1, 1, ma);
357de0a3472SNavdeep Parhar end_synchronized_op(adap, 0);
358de0a3472SNavdeep Parhar if (rc != 0) {
359de0a3472SNavdeep Parhar device_printf(dev,
360de0a3472SNavdeep Parhar "Failed to set VF%d MAC address to "
361de0a3472SNavdeep Parhar "%02x:%02x:%02x:%02x:%02x:%02x, rc = %d\n", vfnum,
362de0a3472SNavdeep Parhar ma[0], ma[1], ma[2], ma[3], ma[4], ma[5], rc);
363de0a3472SNavdeep Parhar return (rc);
364de0a3472SNavdeep Parhar }
365de0a3472SNavdeep Parhar }
366f91fca5bSJohn Baldwin
3671389314dSKristof Provost if (nvlist_exists_number(config, "vlan")) {
3681389314dSKristof Provost uint16_t vlan = nvlist_get_number(config, "vlan");
3691389314dSKristof Provost
3701389314dSKristof Provost /* We can't restrict to VID 0 */
3711389314dSKristof Provost if (vlan == DOT1Q_VID_NULL)
3721389314dSKristof Provost return (ENOTSUP);
3731389314dSKristof Provost
3741389314dSKristof Provost if (vlan == VF_VLAN_TRUNK)
3751389314dSKristof Provost vlan = DOT1Q_VID_NULL;
3761389314dSKristof Provost
3771389314dSKristof Provost if (begin_synchronized_op(adap, NULL, SLEEP_OK | INTR_OK,
3781389314dSKristof Provost "t4vfvl") != 0)
3791389314dSKristof Provost return (ENXIO);
3801389314dSKristof Provost rc = t4_set_vlan_acl(adap, sc->pf, vfnum + 1, vlan);
3811389314dSKristof Provost end_synchronized_op(adap, 0);
3821389314dSKristof Provost if (rc != 0) {
3831389314dSKristof Provost device_printf(dev,
3841389314dSKristof Provost "Failed to set VF%d VLAN to %d, rc = %d\n",
3851389314dSKristof Provost vfnum, vlan, rc);
3861389314dSKristof Provost return (rc);
3871389314dSKristof Provost }
3881389314dSKristof Provost }
3891389314dSKristof Provost
390f91fca5bSJohn Baldwin return (0);
391f91fca5bSJohn Baldwin }
392f91fca5bSJohn Baldwin #endif
393f91fca5bSJohn Baldwin
394f91fca5bSJohn Baldwin static device_method_t t4iov_methods[] = {
395f91fca5bSJohn Baldwin DEVMETHOD(device_probe, t4iov_probe),
396f91fca5bSJohn Baldwin DEVMETHOD(device_attach, t4iov_attach),
397f91fca5bSJohn Baldwin DEVMETHOD(device_detach, t4iov_detach),
398f91fca5bSJohn Baldwin
399f91fca5bSJohn Baldwin #ifdef PCI_IOV
400f91fca5bSJohn Baldwin DEVMETHOD(pci_iov_init, t4iov_iov_init),
401f91fca5bSJohn Baldwin DEVMETHOD(pci_iov_uninit, t4iov_iov_uninit),
402f91fca5bSJohn Baldwin DEVMETHOD(pci_iov_add_vf, t4iov_add_vf),
403f91fca5bSJohn Baldwin #endif
404f91fca5bSJohn Baldwin
405f91fca5bSJohn Baldwin DEVMETHOD(t4_attach_child, t4iov_attach_child),
406f91fca5bSJohn Baldwin DEVMETHOD(t4_detach_child, t4iov_detach_child),
407f91fca5bSJohn Baldwin
408f91fca5bSJohn Baldwin DEVMETHOD_END
409f91fca5bSJohn Baldwin };
410f91fca5bSJohn Baldwin
411f91fca5bSJohn Baldwin static driver_t t4iov_driver = {
412f91fca5bSJohn Baldwin "t4iov",
413f91fca5bSJohn Baldwin t4iov_methods,
414f91fca5bSJohn Baldwin sizeof(struct t4iov_softc)
415f91fca5bSJohn Baldwin };
416f91fca5bSJohn Baldwin
417f91fca5bSJohn Baldwin static device_method_t t5iov_methods[] = {
418f91fca5bSJohn Baldwin DEVMETHOD(device_probe, t5iov_probe),
419f91fca5bSJohn Baldwin DEVMETHOD(device_attach, t4iov_attach),
420f91fca5bSJohn Baldwin DEVMETHOD(device_detach, t4iov_detach),
421f91fca5bSJohn Baldwin
422f91fca5bSJohn Baldwin #ifdef PCI_IOV
423f91fca5bSJohn Baldwin DEVMETHOD(pci_iov_init, t4iov_iov_init),
424f91fca5bSJohn Baldwin DEVMETHOD(pci_iov_uninit, t4iov_iov_uninit),
425f91fca5bSJohn Baldwin DEVMETHOD(pci_iov_add_vf, t4iov_add_vf),
426f91fca5bSJohn Baldwin #endif
427f91fca5bSJohn Baldwin
428f91fca5bSJohn Baldwin DEVMETHOD(t4_attach_child, t4iov_attach_child),
429f91fca5bSJohn Baldwin DEVMETHOD(t4_detach_child, t4iov_detach_child),
430f91fca5bSJohn Baldwin
431f91fca5bSJohn Baldwin DEVMETHOD_END
432f91fca5bSJohn Baldwin };
433f91fca5bSJohn Baldwin
434f91fca5bSJohn Baldwin static driver_t t5iov_driver = {
435f91fca5bSJohn Baldwin "t5iov",
436f91fca5bSJohn Baldwin t5iov_methods,
437f91fca5bSJohn Baldwin sizeof(struct t4iov_softc)
438f91fca5bSJohn Baldwin };
439f91fca5bSJohn Baldwin
440e6b81479SNavdeep Parhar static device_method_t t6iov_methods[] = {
441e6b81479SNavdeep Parhar DEVMETHOD(device_probe, t6iov_probe),
442e6b81479SNavdeep Parhar DEVMETHOD(device_attach, t4iov_attach),
443e6b81479SNavdeep Parhar DEVMETHOD(device_detach, t4iov_detach),
444e6b81479SNavdeep Parhar
445e6b81479SNavdeep Parhar #ifdef PCI_IOV
446e6b81479SNavdeep Parhar DEVMETHOD(pci_iov_init, t4iov_iov_init),
447e6b81479SNavdeep Parhar DEVMETHOD(pci_iov_uninit, t4iov_iov_uninit),
448e6b81479SNavdeep Parhar DEVMETHOD(pci_iov_add_vf, t4iov_add_vf),
449e6b81479SNavdeep Parhar #endif
450e6b81479SNavdeep Parhar
451e6b81479SNavdeep Parhar DEVMETHOD(t4_attach_child, t4iov_attach_child),
452e6b81479SNavdeep Parhar DEVMETHOD(t4_detach_child, t4iov_detach_child),
453e6b81479SNavdeep Parhar
454e6b81479SNavdeep Parhar DEVMETHOD_END
455e6b81479SNavdeep Parhar };
456e6b81479SNavdeep Parhar
457e6b81479SNavdeep Parhar static driver_t t6iov_driver = {
458e6b81479SNavdeep Parhar "t6iov",
459e6b81479SNavdeep Parhar t6iov_methods,
460e6b81479SNavdeep Parhar sizeof(struct t4iov_softc)
461e6b81479SNavdeep Parhar };
462e6b81479SNavdeep Parhar
463e8d1145dSJohn Baldwin DRIVER_MODULE(t4iov, pci, t4iov_driver, 0, 0);
464f91fca5bSJohn Baldwin MODULE_VERSION(t4iov, 1);
465f91fca5bSJohn Baldwin
466e8d1145dSJohn Baldwin DRIVER_MODULE(t5iov, pci, t5iov_driver, 0, 0);
467f91fca5bSJohn Baldwin MODULE_VERSION(t5iov, 1);
468e6b81479SNavdeep Parhar
469e8d1145dSJohn Baldwin DRIVER_MODULE(t6iov, pci, t6iov_driver, 0, 0);
470e6b81479SNavdeep Parhar MODULE_VERSION(t6iov, 1);
471