xref: /freebsd-13-stable/sys/mips/nlm/dev/net/xlpge.c (revision 3bc80996974a61a4223eae4c1ccd47b6ee32a48a)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright (c) 2003-2012 Broadcom Corporation
5  * All Rights Reserved
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * THIS SOFTWARE IS PROVIDED BY BROADCOM ``AS IS'' AND ANY EXPRESS OR
19  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21  * ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM OR CONTRIBUTORS BE LIABLE
22  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30 
31 #include <sys/cdefs.h>
32 #include <sys/param.h>
33 #include <sys/endian.h>
34 #include <sys/systm.h>
35 #include <sys/sockio.h>
36 #include <sys/lock.h>
37 #include <sys/mutex.h>
38 #include <sys/proc.h>
39 #include <sys/limits.h>
40 #include <sys/bus.h>
41 #include <sys/mbuf.h>
42 #include <sys/malloc.h>
43 #include <sys/kernel.h>
44 #include <sys/module.h>
45 #include <sys/socket.h>
46 #define __RMAN_RESOURCE_VISIBLE
47 #include <sys/rman.h>
48 #include <sys/taskqueue.h>
49 
50 #include <net/if.h>
51 #include <net/if_var.h>
52 #include <net/if_arp.h>
53 #include <net/ethernet.h>
54 #include <net/if_dl.h>
55 #include <net/if_media.h>
56 #include <net/bpf.h>
57 #include <net/if_types.h>
58 #include <net/if_vlan_var.h>
59 
60 #include <dev/pci/pcivar.h>
61 
62 #include <netinet/in_systm.h>
63 #include <netinet/in.h>
64 #include <netinet/ip.h>
65 
66 #include <vm/vm.h>
67 #include <vm/pmap.h>
68 #include <vm/uma.h>
69 
70 #include <machine/cpu.h>
71 #include <machine/mips_opcode.h>
72 #include <machine/asm.h>
73 #include <machine/cpuregs.h>
74 
75 #include <machine/intr_machdep.h>
76 #include <machine/clock.h>	/* for DELAY */
77 #include <machine/bus.h>
78 #include <machine/resource.h>
79 #include <mips/nlm/hal/haldefs.h>
80 #include <mips/nlm/hal/iomap.h>
81 #include <mips/nlm/hal/mips-extns.h>
82 #include <mips/nlm/hal/cop2.h>
83 #include <mips/nlm/hal/fmn.h>
84 #include <mips/nlm/hal/sys.h>
85 #include <mips/nlm/hal/nae.h>
86 #include <mips/nlm/hal/mdio.h>
87 #include <mips/nlm/hal/sgmii.h>
88 #include <mips/nlm/hal/xaui.h>
89 #include <mips/nlm/hal/poe.h>
90 #include <ucore_app_bin.h>
91 #include <mips/nlm/hal/ucore_loader.h>
92 #include <mips/nlm/xlp.h>
93 #include <mips/nlm/board.h>
94 #include <mips/nlm/msgring.h>
95 
96 #include <dev/mii/mii.h>
97 #include <dev/mii/miivar.h>
98 #include "miidevs.h"
99 #include <dev/mii/brgphyreg.h>
100 #include "miibus_if.h"
101 #include <sys/sysctl.h>
102 
103 #include <mips/nlm/dev/net/xlpge.h>
104 
105 /*#define XLP_DRIVER_LOOPBACK*/
106 
107 static struct nae_port_config nae_port_config[64];
108 
109 int poe_cl_tbl[MAX_POE_CLASSES] = {
110 	0x0, 0x249249,
111 	0x492492, 0x6db6db,
112 	0x924924, 0xb6db6d,
113 	0xdb6db6, 0xffffff
114 };
115 
116 /* #define DUMP_PACKET */
117 
118 static uint64_t
nlm_paddr_ld(uint64_t paddr)119 nlm_paddr_ld(uint64_t paddr)
120 {
121 	uint64_t xkaddr = 0x9800000000000000 | paddr;
122 
123 	return (nlm_load_dword_daddr(xkaddr));
124 }
125 
126 struct nlm_xlp_portdata ifp_ports[64];
127 static uma_zone_t nl_tx_desc_zone;
128 
129 /* This implementation will register the following tree of device
130  * registration:
131  *                      pcibus
132  *                       |
133  *                      xlpnae (1 instance - virtual entity)
134  *                       |
135  *                     xlpge
136  *      (18 sgmii / 4 xaui / 2 interlaken instances)
137  *                       |
138  *                    miibus
139  */
140 
141 static int nlm_xlpnae_probe(device_t);
142 static int nlm_xlpnae_attach(device_t);
143 static int nlm_xlpnae_detach(device_t);
144 static int nlm_xlpnae_suspend(device_t);
145 static int nlm_xlpnae_resume(device_t);
146 static int nlm_xlpnae_shutdown(device_t);
147 
148 static device_method_t nlm_xlpnae_methods[] = {
149 	/* Methods from the device interface */
150 	DEVMETHOD(device_probe,		nlm_xlpnae_probe),
151 	DEVMETHOD(device_attach,	nlm_xlpnae_attach),
152 	DEVMETHOD(device_detach,	nlm_xlpnae_detach),
153 	DEVMETHOD(device_suspend,	nlm_xlpnae_suspend),
154 	DEVMETHOD(device_resume,	nlm_xlpnae_resume),
155 	DEVMETHOD(device_shutdown,	nlm_xlpnae_shutdown),
156 
157 	DEVMETHOD(bus_driver_added,	bus_generic_driver_added),
158 
159 	DEVMETHOD_END
160 };
161 
162 static driver_t nlm_xlpnae_driver = {
163 	"xlpnae",
164 	nlm_xlpnae_methods,
165 	sizeof(struct nlm_xlpnae_softc)
166 };
167 
168 static devclass_t nlm_xlpnae_devclass;
169 
170 static int nlm_xlpge_probe(device_t);
171 static int nlm_xlpge_attach(device_t);
172 static int nlm_xlpge_detach(device_t);
173 static int nlm_xlpge_suspend(device_t);
174 static int nlm_xlpge_resume(device_t);
175 static int nlm_xlpge_shutdown(device_t);
176 
177 /* mii override functions */
178 static int nlm_xlpge_mii_read(device_t, int, int);
179 static int nlm_xlpge_mii_write(device_t, int, int, int);
180 static void nlm_xlpge_mii_statchg(device_t);
181 
182 static device_method_t nlm_xlpge_methods[] = {
183 	/* Methods from the device interface */
184 	DEVMETHOD(device_probe,		nlm_xlpge_probe),
185 	DEVMETHOD(device_attach,	nlm_xlpge_attach),
186 	DEVMETHOD(device_detach,	nlm_xlpge_detach),
187 	DEVMETHOD(device_suspend,	nlm_xlpge_suspend),
188 	DEVMETHOD(device_resume,	nlm_xlpge_resume),
189 	DEVMETHOD(device_shutdown,	nlm_xlpge_shutdown),
190 
191 	/* Methods from the nexus bus needed for explicitly
192 	 * probing children when driver is loaded as a kernel module
193 	 */
194 	DEVMETHOD(miibus_readreg,	nlm_xlpge_mii_read),
195 	DEVMETHOD(miibus_writereg,	nlm_xlpge_mii_write),
196 	DEVMETHOD(miibus_statchg,	nlm_xlpge_mii_statchg),
197 
198 	/* Terminate method list */
199 	DEVMETHOD_END
200 };
201 
202 static driver_t nlm_xlpge_driver = {
203 	"xlpge",
204 	nlm_xlpge_methods,
205 	sizeof(struct nlm_xlpge_softc)
206 };
207 
208 static devclass_t nlm_xlpge_devclass;
209 
210 DRIVER_MODULE(xlpnae, pci, nlm_xlpnae_driver, nlm_xlpnae_devclass, 0, 0);
211 DRIVER_MODULE(xlpge, xlpnae, nlm_xlpge_driver, nlm_xlpge_devclass, 0, 0);
212 DRIVER_MODULE(miibus, xlpge, miibus_driver, miibus_devclass, 0, 0);
213 
214 MODULE_DEPEND(pci, xlpnae, 1, 1, 1);
215 MODULE_DEPEND(xlpnae, xlpge, 1, 1, 1);
216 MODULE_DEPEND(xlpge, ether, 1, 1, 1);
217 MODULE_DEPEND(xlpge, miibus, 1, 1, 1);
218 
219 #define SGMII_RCV_CONTEXT_WIDTH 8
220 
221 /* prototypes */
222 static void nlm_xlpge_msgring_handler(int vc, int size,
223     int code, int srcid, struct nlm_fmn_msg *msg, void *data);
224 static void nlm_xlpge_submit_rx_free_desc(struct nlm_xlpge_softc *sc, int num);
225 static void nlm_xlpge_init(void *addr);
226 static void nlm_xlpge_port_disable(struct nlm_xlpge_softc *sc);
227 static void nlm_xlpge_port_enable(struct nlm_xlpge_softc *sc);
228 
229 /* globals */
230 int dbg_on = 1;
231 int cntx2port[524];
232 
233 static __inline void
atomic_incr_long(unsigned long * addr)234 atomic_incr_long(unsigned long *addr)
235 {
236 	atomic_add_long(addr, 1);
237 }
238 
239 /*
240  * xlpnae driver implementation
241  */
242 static int
nlm_xlpnae_probe(device_t dev)243 nlm_xlpnae_probe(device_t dev)
244 {
245 	if (pci_get_vendor(dev) != PCI_VENDOR_NETLOGIC ||
246 	    pci_get_device(dev) != PCI_DEVICE_ID_NLM_NAE)
247 		return (ENXIO);
248 
249 	return (BUS_PROBE_DEFAULT);
250 }
251 
252 static void
nlm_xlpnae_print_frin_desc_carving(struct nlm_xlpnae_softc * sc)253 nlm_xlpnae_print_frin_desc_carving(struct nlm_xlpnae_softc *sc)
254 {
255 	int intf;
256 	uint32_t value;
257 	int start, size;
258 
259 	/* XXXJC: use max_ports instead of 20 ? */
260 	for (intf = 0; intf < 20; intf++) {
261 		nlm_write_nae_reg(sc->base, NAE_FREE_IN_FIFO_CFG,
262 		    (0x80000000 | intf));
263 		value = nlm_read_nae_reg(sc->base, NAE_FREE_IN_FIFO_CFG);
264 		size = 2 * ((value >> 20) & 0x3ff);
265 		start = 2 * ((value >> 8) & 0x1ff);
266 	}
267 }
268 
269 static void
nlm_config_egress(struct nlm_xlpnae_softc * sc,int nblock,int context_base,int hwport,int max_channels)270 nlm_config_egress(struct nlm_xlpnae_softc *sc, int nblock,
271     int context_base, int hwport, int max_channels)
272 {
273 	int offset, num_channels;
274 	uint32_t data;
275 
276 	num_channels = sc->portcfg[hwport].num_channels;
277 
278 	data = (2048 << 12) | (hwport << 4) | 1;
279 	nlm_write_nae_reg(sc->base, NAE_TX_IF_BURSTMAX_CMD, data);
280 
281 	data = ((context_base + num_channels - 1) << 22) |
282 	    (context_base << 12) | (hwport << 4) | 1;
283 	nlm_write_nae_reg(sc->base, NAE_TX_DDR_ACTVLIST_CMD, data);
284 
285 	config_egress_fifo_carvings(sc->base, hwport,
286 	    context_base, num_channels, max_channels, sc->portcfg);
287 	config_egress_fifo_credits(sc->base, hwport,
288 	    context_base, num_channels, max_channels, sc->portcfg);
289 
290 	data = nlm_read_nae_reg(sc->base, NAE_DMA_TX_CREDIT_TH);
291 	data |= (1 << 25) | (1 << 24);
292 	nlm_write_nae_reg(sc->base, NAE_DMA_TX_CREDIT_TH, data);
293 
294 	for (offset = 0; offset < num_channels; offset++) {
295 		nlm_write_nae_reg(sc->base, NAE_TX_SCHED_MAP_CMD1,
296 		    NAE_DRR_QUANTA);
297 		data = (hwport << 15) | ((context_base + offset) << 5);
298 		if (sc->cmplx_type[nblock] == ILC)
299 			data |= (offset << 20);
300 		nlm_write_nae_reg(sc->base, NAE_TX_SCHED_MAP_CMD0, data | 1);
301 		nlm_write_nae_reg(sc->base, NAE_TX_SCHED_MAP_CMD0, data);
302 	}
303 }
304 
305 static int
xlpnae_get_maxchannels(struct nlm_xlpnae_softc * sc)306 xlpnae_get_maxchannels(struct nlm_xlpnae_softc *sc)
307 {
308 	int maxchans = 0;
309 	int i;
310 
311 	for (i = 0; i < sc->max_ports; i++) {
312 		if (sc->portcfg[i].type == UNKNOWN)
313 			continue;
314 		maxchans += sc->portcfg[i].num_channels;
315 	}
316 
317 	return (maxchans);
318 }
319 
320 static void
nlm_setup_interface(struct nlm_xlpnae_softc * sc,int nblock,int port,uint32_t cur_flow_base,uint32_t flow_mask,int max_channels,int context)321 nlm_setup_interface(struct nlm_xlpnae_softc *sc, int nblock,
322     int port, uint32_t cur_flow_base, uint32_t flow_mask,
323     int max_channels, int context)
324 {
325 	uint64_t nae_base = sc->base;
326 	int mtu = 1536;			/* XXXJC: don't hard code */
327 	uint32_t ucore_mask;
328 
329 	if (sc->cmplx_type[nblock] == XAUIC)
330 		nlm_config_xaui(nae_base, nblock, mtu,
331 		    mtu, sc->portcfg[port].vlan_pri_en);
332 	nlm_config_freein_fifo_uniq_cfg(nae_base,
333 	    port, sc->portcfg[port].free_desc_sizes);
334 	nlm_config_ucore_iface_mask_cfg(nae_base,
335 	    port, sc->portcfg[port].ucore_mask);
336 
337 	nlm_program_flow_cfg(nae_base, port, cur_flow_base, flow_mask);
338 
339 	if (sc->cmplx_type[nblock] == SGMIIC)
340 		nlm_configure_sgmii_interface(nae_base, nblock, port, mtu, 0);
341 
342 	nlm_config_egress(sc, nblock, context, port, max_channels);
343 
344 	nlm_nae_init_netior(nae_base, sc->nblocks);
345 	nlm_nae_open_if(nae_base, nblock, sc->cmplx_type[nblock], port,
346 	    sc->portcfg[port].free_desc_sizes);
347 
348 	/*  XXXJC: check mask calculation */
349 	ucore_mask = (1 << sc->nucores) - 1;
350 	nlm_nae_init_ucore(nae_base, port, ucore_mask);
351 }
352 
353 static void
nlm_setup_interfaces(struct nlm_xlpnae_softc * sc)354 nlm_setup_interfaces(struct nlm_xlpnae_softc *sc)
355 {
356 	uint64_t nae_base;
357 	uint32_t cur_slot, cur_slot_base;
358 	uint32_t cur_flow_base, port, flow_mask;
359 	int max_channels;
360 	int i, context;
361 
362 	cur_slot = 0;
363 	cur_slot_base = 0;
364 	cur_flow_base = 0;
365 	nae_base = sc->base;
366 	flow_mask = nlm_get_flow_mask(sc->total_num_ports);
367 	/* calculate max_channels */
368 	max_channels = xlpnae_get_maxchannels(sc);
369 
370 	port = 0;
371 	context = 0;
372 	for (i = 0; i < sc->max_ports; i++) {
373 		if (sc->portcfg[i].type == UNKNOWN)
374 			continue;
375 		nlm_setup_interface(sc, sc->portcfg[i].block, i, cur_flow_base,
376 		    flow_mask, max_channels, context);
377 		cur_flow_base += sc->per_port_num_flows;
378 		context += sc->portcfg[i].num_channels;
379 	}
380 }
381 
382 static void
nlm_xlpnae_init(int node,struct nlm_xlpnae_softc * sc)383 nlm_xlpnae_init(int node, struct nlm_xlpnae_softc *sc)
384 {
385 	uint64_t nae_base;
386 	uint32_t ucoremask = 0;
387 	uint32_t val;
388 	int i;
389 
390 	nae_base = sc->base;
391 
392 	nlm_nae_flush_free_fifo(nae_base, sc->nblocks);
393 	nlm_deflate_frin_fifo_carving(nae_base, sc->max_ports);
394 	nlm_reset_nae(node);
395 
396 	for (i = 0; i < sc->nucores; i++)	/* XXXJC: code repeated below */
397 		ucoremask |= (0x1 << i);
398 	printf("Loading 0x%x ucores with microcode\n", ucoremask);
399 	nlm_ucore_load_all(nae_base, ucoremask, 1);
400 
401 	val = nlm_set_device_frequency(node, DFS_DEVICE_NAE, sc->freq);
402 	printf("Setup NAE frequency to %dMHz\n", val);
403 
404 	nlm_mdio_reset_all(nae_base);
405 
406 	printf("Initialze SGMII PCS for blocks 0x%x\n", sc->sgmiimask);
407 	nlm_sgmii_pcs_init(nae_base, sc->sgmiimask);
408 
409 	printf("Initialze XAUI PCS for blocks 0x%x\n", sc->xauimask);
410 	nlm_xaui_pcs_init(nae_base, sc->xauimask);
411 
412 	/* clear NETIOR soft reset */
413 	nlm_write_nae_reg(nae_base, NAE_LANE_CFG_SOFTRESET, 0x0);
414 
415 	/* Disable RX enable bit in RX_CONFIG */
416 	val = nlm_read_nae_reg(nae_base, NAE_RX_CONFIG);
417 	val &= 0xfffffffe;
418 	nlm_write_nae_reg(nae_base, NAE_RX_CONFIG, val);
419 
420 	if (nlm_is_xlp8xx_ax() == 0) {
421 		val = nlm_read_nae_reg(nae_base, NAE_TX_CONFIG);
422 		val &= ~(1 << 3);
423 		nlm_write_nae_reg(nae_base, NAE_TX_CONFIG, val);
424 	}
425 
426 	nlm_setup_poe_class_config(nae_base, MAX_POE_CLASSES,
427 	    sc->ncontexts, poe_cl_tbl);
428 
429 	nlm_setup_vfbid_mapping(nae_base);
430 
431 	nlm_setup_flow_crc_poly(nae_base, sc->flow_crc_poly);
432 
433 	nlm_setup_rx_cal_cfg(nae_base, sc->max_ports, sc->portcfg);
434 	/* note: xlp8xx Ax does not have Tx Calendering */
435 	if (!nlm_is_xlp8xx_ax())
436 		nlm_setup_tx_cal_cfg(nae_base, sc->max_ports, sc->portcfg);
437 
438 	nlm_setup_interfaces(sc);
439 	nlm_config_poe(sc->poe_base, sc->poedv_base);
440 
441 	if (sc->hw_parser_en)
442 		nlm_enable_hardware_parser(nae_base);
443 
444 	if (sc->prepad_en)
445 		nlm_prepad_enable(nae_base, sc->prepad_size);
446 
447 	if (sc->ieee_1588_en)
448 		nlm_setup_1588_timer(sc->base, sc->portcfg);
449 }
450 
451 static void
nlm_xlpnae_update_pde(void * dummy __unused)452 nlm_xlpnae_update_pde(void *dummy __unused)
453 {
454 	struct nlm_xlpnae_softc *sc;
455 	uint32_t dv[NUM_WORDS_PER_DV];
456 	device_t dev;
457 	int vec;
458 
459 	dev = devclass_get_device(devclass_find("xlpnae"), 0);
460 	sc = device_get_softc(dev);
461 
462 	nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 0);
463 	for (vec = 0; vec < NUM_DIST_VEC; vec++) {
464 		if (nlm_get_poe_distvec(vec, dv) != 0)
465 			continue;
466 
467 		nlm_write_poe_distvec(sc->poedv_base, vec, dv);
468 	}
469 	nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 1);
470 }
471 
472 SYSINIT(nlm_xlpnae_update_pde, SI_SUB_SMP, SI_ORDER_ANY,
473     nlm_xlpnae_update_pde, NULL);
474 
475 /* configuration common for sgmii, xaui, ilaken goes here */
476 static void
nlm_setup_portcfg(struct nlm_xlpnae_softc * sc,struct xlp_nae_ivars * naep,int block,int port)477 nlm_setup_portcfg(struct nlm_xlpnae_softc *sc, struct xlp_nae_ivars *naep,
478     int block, int port)
479 {
480 	int i;
481 	uint32_t ucore_mask = 0;
482 	struct xlp_block_ivars *bp;
483 	struct xlp_port_ivars *p;
484 
485 	bp = &(naep->block_ivars[block]);
486 	p  = &(bp->port_ivars[port & 0x3]);
487 
488 	sc->portcfg[port].node = p->node;
489 	sc->portcfg[port].block = p->block;
490 	sc->portcfg[port].port = p->port;
491 	sc->portcfg[port].type = p->type;
492 	sc->portcfg[port].mdio_bus = p->mdio_bus;
493 	sc->portcfg[port].phy_addr = p->phy_addr;
494 	sc->portcfg[port].loopback_mode = p->loopback_mode;
495 	sc->portcfg[port].num_channels = p->num_channels;
496 	if (p->free_desc_sizes != MCLBYTES) {
497 		printf("[%d, %d] Error: free_desc_sizes %d != %d\n",
498 		    block, port, p->free_desc_sizes, MCLBYTES);
499 		return;
500 	}
501 	sc->portcfg[port].free_desc_sizes = p->free_desc_sizes;
502 	for (i = 0; i < sc->nucores; i++)	/* XXXJC: configure this */
503 		ucore_mask |= (0x1 << i);
504 	sc->portcfg[port].ucore_mask = ucore_mask;
505 	sc->portcfg[port].vlan_pri_en = p->vlan_pri_en;
506 	sc->portcfg[port].num_free_descs = p->num_free_descs;
507 	sc->portcfg[port].iface_fifo_size = p->iface_fifo_size;
508 	sc->portcfg[port].rxbuf_size = p->rxbuf_size;
509 	sc->portcfg[port].rx_slots_reqd = p->rx_slots_reqd;
510 	sc->portcfg[port].tx_slots_reqd = p->tx_slots_reqd;
511 	sc->portcfg[port].pseq_fifo_size = p->pseq_fifo_size;
512 
513 	sc->portcfg[port].stg2_fifo_size = p->stg2_fifo_size;
514 	sc->portcfg[port].eh_fifo_size = p->eh_fifo_size;
515 	sc->portcfg[port].frout_fifo_size = p->frout_fifo_size;
516 	sc->portcfg[port].ms_fifo_size = p->ms_fifo_size;
517 	sc->portcfg[port].pkt_fifo_size = p->pkt_fifo_size;
518 	sc->portcfg[port].pktlen_fifo_size = p->pktlen_fifo_size;
519 	sc->portcfg[port].max_stg2_offset = p->max_stg2_offset;
520 	sc->portcfg[port].max_eh_offset = p->max_eh_offset;
521 	sc->portcfg[port].max_frout_offset = p->max_frout_offset;
522 	sc->portcfg[port].max_ms_offset = p->max_ms_offset;
523 	sc->portcfg[port].max_pmem_offset = p->max_pmem_offset;
524 	sc->portcfg[port].stg1_2_credit = p->stg1_2_credit;
525 	sc->portcfg[port].stg2_eh_credit = p->stg2_eh_credit;
526 	sc->portcfg[port].stg2_frout_credit = p->stg2_frout_credit;
527 	sc->portcfg[port].stg2_ms_credit = p->stg2_ms_credit;
528 	sc->portcfg[port].ieee1588_inc_intg = p->ieee1588_inc_intg;
529 	sc->portcfg[port].ieee1588_inc_den = p->ieee1588_inc_den;
530 	sc->portcfg[port].ieee1588_inc_num = p->ieee1588_inc_num;
531 	sc->portcfg[port].ieee1588_userval = p->ieee1588_userval;
532 	sc->portcfg[port].ieee1588_ptpoff = p->ieee1588_ptpoff;
533 	sc->portcfg[port].ieee1588_tmr1 = p->ieee1588_tmr1;
534 	sc->portcfg[port].ieee1588_tmr2 = p->ieee1588_tmr2;
535 	sc->portcfg[port].ieee1588_tmr3 = p->ieee1588_tmr3;
536 
537 	sc->total_free_desc += sc->portcfg[port].free_desc_sizes;
538 	sc->total_num_ports++;
539 }
540 
541 static int
nlm_xlpnae_attach(device_t dev)542 nlm_xlpnae_attach(device_t dev)
543 {
544 	struct xlp_nae_ivars	*nae_ivars;
545 	struct nlm_xlpnae_softc *sc;
546 	device_t tmpd;
547 	uint32_t dv[NUM_WORDS_PER_DV];
548 	int port, i, j, nchan, nblock, node, qstart, qnum;
549 	int offset, context, txq_base, rxvcbase;
550 	uint64_t poe_pcibase, nae_pcibase;
551 
552 	node = pci_get_slot(dev) / 8;
553 	nae_ivars = &xlp_board_info.nodes[node].nae_ivars;
554 
555 	sc = device_get_softc(dev);
556 	sc->xlpnae_dev = dev;
557 	sc->node = nae_ivars->node;
558 	sc->base = nlm_get_nae_regbase(sc->node);
559 	sc->poe_base = nlm_get_poe_regbase(sc->node);
560 	sc->poedv_base = nlm_get_poedv_regbase(sc->node);
561 	sc->portcfg = nae_port_config;
562 	sc->blockmask = nae_ivars->blockmask;
563 	sc->ilmask = nae_ivars->ilmask;
564 	sc->xauimask = nae_ivars->xauimask;
565 	sc->sgmiimask = nae_ivars->sgmiimask;
566 	sc->nblocks = nae_ivars->nblocks;
567 	sc->freq = nae_ivars->freq;
568 
569 	/* flow table generation is done by CRC16 polynomial */
570 	sc->flow_crc_poly = nae_ivars->flow_crc_poly;
571 
572 	sc->hw_parser_en = nae_ivars->hw_parser_en;
573 	sc->prepad_en = nae_ivars->prepad_en;
574 	sc->prepad_size = nae_ivars->prepad_size;
575 	sc->ieee_1588_en = nae_ivars->ieee_1588_en;
576 
577 	nae_pcibase = nlm_get_nae_pcibase(sc->node);
578 	sc->ncontexts = nlm_read_reg(nae_pcibase, XLP_PCI_DEVINFO_REG5);
579 	sc->nucores = nlm_num_uengines(nae_pcibase);
580 
581 	for (nblock = 0; nblock < sc->nblocks; nblock++) {
582 		sc->cmplx_type[nblock] = nae_ivars->block_ivars[nblock].type;
583 		sc->portmask[nblock] = nae_ivars->block_ivars[nblock].portmask;
584 	}
585 
586 	for (i = 0; i < sc->ncontexts; i++)
587 		cntx2port[i] = 18;	/* 18 is an invalid port */
588 
589 	if (sc->nblocks == 5)
590 		sc->max_ports = 18;	/* 8xx has a block 4 with 2 ports */
591 	else
592 		sc->max_ports = sc->nblocks * PORTS_PER_CMPLX;
593 
594 	for (i = 0; i < sc->max_ports; i++)
595 		sc->portcfg[i].type = UNKNOWN; /* Port Not Present */
596 	/*
597 	 * Now setup all internal fifo carvings based on
598 	 * total number of ports in the system
599 	 */
600 	sc->total_free_desc = 0;
601 	sc->total_num_ports = 0;
602 	port = 0;
603 	context = 0;
604 	txq_base = nlm_qidstart(nae_pcibase);
605 	rxvcbase = txq_base + sc->ncontexts;
606 	for (i = 0; i < sc->nblocks; i++) {
607 		uint32_t portmask;
608 
609 		if ((nae_ivars->blockmask & (1 << i)) == 0) {
610 			port += 4;
611 			continue;
612 		}
613 		portmask = nae_ivars->block_ivars[i].portmask;
614 		for (j = 0; j < PORTS_PER_CMPLX; j++, port++) {
615 			if ((portmask & (1 << j)) == 0)
616 				continue;
617 			nlm_setup_portcfg(sc, nae_ivars, i, port);
618 			nchan = sc->portcfg[port].num_channels;
619 			for (offset = 0; offset < nchan; offset++)
620 				cntx2port[context + offset] = port;
621 			sc->portcfg[port].txq = txq_base + context;
622 			sc->portcfg[port].rxfreeq = rxvcbase + port;
623 			context += nchan;
624 		}
625 	}
626 
627 	poe_pcibase = nlm_get_poe_pcibase(sc->node);
628 	sc->per_port_num_flows =
629 	    nlm_poe_max_flows(poe_pcibase) / sc->total_num_ports;
630 
631 	/* zone for P2P descriptors */
632 	nl_tx_desc_zone = uma_zcreate("NL Tx Desc",
633 	    sizeof(struct xlpge_tx_desc), NULL, NULL, NULL, NULL,
634 	    NAE_CACHELINE_SIZE, 0);
635 
636 	/* NAE FMN messages have CMS src station id's in the
637 	 * range of qstart to qnum.
638 	 */
639 	qstart = nlm_qidstart(nae_pcibase);
640 	qnum = nlm_qnum(nae_pcibase);
641 	if (register_msgring_handler(qstart, qstart + qnum - 1,
642 	    nlm_xlpge_msgring_handler, sc)) {
643 		panic("Couldn't register NAE msgring handler\n");
644 	}
645 
646 	/* POE FMN messages have CMS src station id's in the
647 	 * range of qstart to qnum.
648 	 */
649 	qstart = nlm_qidstart(poe_pcibase);
650 	qnum = nlm_qnum(poe_pcibase);
651 	if (register_msgring_handler(qstart, qstart + qnum - 1,
652 	    nlm_xlpge_msgring_handler, sc)) {
653 		panic("Couldn't register POE msgring handler\n");
654 	}
655 
656 	nlm_xlpnae_init(node, sc);
657 
658 	for (i = 0; i < sc->max_ports; i++) {
659 		char desc[32];
660 		int block, port;
661 
662 		if (sc->portcfg[i].type == UNKNOWN)
663 			continue;
664 		block = sc->portcfg[i].block;
665 		port = sc->portcfg[i].port;
666 		tmpd = device_add_child(dev, "xlpge", i);
667 		device_set_ivars(tmpd,
668 		    &(nae_ivars->block_ivars[block].port_ivars[port]));
669 		sprintf(desc, "XLP NAE Port %d,%d", block, port);
670 		device_set_desc_copy(tmpd, desc);
671 	}
672 	nlm_setup_iface_fifo_cfg(sc->base, sc->max_ports, sc->portcfg);
673 	nlm_setup_rx_base_config(sc->base, sc->max_ports, sc->portcfg);
674 	nlm_setup_rx_buf_config(sc->base, sc->max_ports, sc->portcfg);
675 	nlm_setup_freein_fifo_cfg(sc->base, sc->portcfg);
676 	nlm_program_nae_parser_seq_fifo(sc->base, sc->max_ports, sc->portcfg);
677 
678 	nlm_xlpnae_print_frin_desc_carving(sc);
679 	bus_generic_probe(dev);
680 	bus_generic_attach(dev);
681 
682 	/*
683 	 * Enable only boot cpu at this point, full distribution comes
684 	 * only after SMP is started
685 	 */
686 	nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 0);
687 	nlm_calc_poe_distvec(0x1, 0, 0, 0, 0x1 << XLPGE_RX_VC, dv);
688 	nlm_write_poe_distvec(sc->poedv_base, 0, dv);
689 	nlm_write_poe_reg(sc->poe_base, POE_DISTR_EN, 1);
690 
691 	return (0);
692 }
693 
694 static int
nlm_xlpnae_detach(device_t dev)695 nlm_xlpnae_detach(device_t dev)
696 {
697 	/*  TODO - free zone here */
698 	return (0);
699 }
700 
701 static int
nlm_xlpnae_suspend(device_t dev)702 nlm_xlpnae_suspend(device_t dev)
703 {
704 	return (0);
705 }
706 
707 static int
nlm_xlpnae_resume(device_t dev)708 nlm_xlpnae_resume(device_t dev)
709 {
710 	return (0);
711 }
712 
713 static int
nlm_xlpnae_shutdown(device_t dev)714 nlm_xlpnae_shutdown(device_t dev)
715 {
716 	return (0);
717 }
718 
719 /*
720  * xlpge driver implementation
721  */
722 
723 static void
nlm_xlpge_mac_set_rx_mode(struct nlm_xlpge_softc * sc)724 nlm_xlpge_mac_set_rx_mode(struct nlm_xlpge_softc *sc)
725 {
726 	if (sc->if_flags & IFF_PROMISC) {
727 		if (sc->type == SGMIIC)
728 			nlm_nae_setup_rx_mode_sgmii(sc->base_addr,
729 			    sc->block, sc->port, sc->type, 1 /* broadcast */,
730 			    1/* multicast */, 0 /* pause */, 1 /* promisc */);
731 		else
732 			nlm_nae_setup_rx_mode_xaui(sc->base_addr,
733 			    sc->block, sc->port, sc->type, 1 /* broadcast */,
734 			    1/* multicast */, 0 /* pause */, 1 /* promisc */);
735 	} else {
736 		if (sc->type == SGMIIC)
737 			nlm_nae_setup_rx_mode_sgmii(sc->base_addr,
738 			    sc->block, sc->port, sc->type, 1 /* broadcast */,
739 			    1/* multicast */, 0 /* pause */, 0 /* promisc */);
740 		else
741 			nlm_nae_setup_rx_mode_xaui(sc->base_addr,
742 			    sc->block, sc->port, sc->type, 1 /* broadcast */,
743 			    1/* multicast */, 0 /* pause */, 0 /* promisc */);
744 	}
745 }
746 
747 static int
nlm_xlpge_ioctl(struct ifnet * ifp,u_long command,caddr_t data)748 nlm_xlpge_ioctl(struct ifnet *ifp, u_long command, caddr_t data)
749 {
750 	struct mii_data		*mii;
751 	struct nlm_xlpge_softc	*sc;
752 	struct ifreq		*ifr;
753 	int			error;
754 
755 	sc = ifp->if_softc;
756 	error = 0;
757 	ifr = (struct ifreq *)data;
758 
759 	switch (command) {
760 	case SIOCSIFFLAGS:
761 		XLPGE_LOCK(sc);
762 		sc->if_flags = ifp->if_flags;
763 		if (ifp->if_flags & IFF_UP) {
764 			if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0)
765 				nlm_xlpge_init(sc);
766 			else
767 				nlm_xlpge_port_enable(sc);
768 			nlm_xlpge_mac_set_rx_mode(sc);
769 			sc->link = NLM_LINK_UP;
770 		} else {
771 			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
772 				nlm_xlpge_port_disable(sc);
773 			sc->link = NLM_LINK_DOWN;
774 		}
775 		XLPGE_UNLOCK(sc);
776 		error = 0;
777 		break;
778 	case SIOCGIFMEDIA:
779 	case SIOCSIFMEDIA:
780 		if (sc->mii_bus != NULL) {
781 			mii = device_get_softc(sc->mii_bus);
782 			error = ifmedia_ioctl(ifp, ifr, &mii->mii_media,
783 			    command);
784 		}
785 		break;
786 	default:
787 		error = ether_ioctl(ifp, command, data);
788 		break;
789 	}
790 
791 	return (error);
792 }
793 
794 static int
xlpge_tx(struct ifnet * ifp,struct mbuf * mbuf_chain)795 xlpge_tx(struct ifnet *ifp, struct mbuf *mbuf_chain)
796 {
797 	struct nlm_fmn_msg	msg;
798 	struct xlpge_tx_desc	*p2p;
799 	struct nlm_xlpge_softc	*sc;
800 	struct mbuf	*m;
801 	vm_paddr_t      paddr;
802 	int		fbid, dst, pos, err;
803 	int		ret = 0, tx_msgstatus, retries;
804 
805 	err = 0;
806 	if (mbuf_chain == NULL)
807 		return (0);
808 
809 	sc = ifp->if_softc;
810 	p2p = NULL;
811 	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) ||
812 	    ifp->if_drv_flags & IFF_DRV_OACTIVE) {
813 		err = ENXIO;
814 		goto fail;
815 	}
816 
817 	/* free a few in coming messages on the fb vc */
818 	xlp_handle_msg_vc(1 << XLPGE_FB_VC, 2);
819 
820 	/* vfb id table is setup to map cpu to vc 3 of the cpu */
821 	fbid = nlm_cpuid();
822 	dst = sc->txq;
823 
824 	pos = 0;
825 	p2p = uma_zalloc(nl_tx_desc_zone, M_NOWAIT);
826 	if (p2p == NULL) {
827 		printf("alloc fail\n");
828 		err = ENOBUFS;
829 		goto fail;
830 	}
831 
832 	for (m = mbuf_chain; m != NULL; m = m->m_next) {
833 		vm_offset_t buf = (vm_offset_t) m->m_data;
834 		int	len = m->m_len;
835 		int	frag_sz;
836 		uint64_t desc;
837 
838 		/*printf("m_data = %p len %d\n", m->m_data, len); */
839 		while (len) {
840 			if (pos == XLP_NTXFRAGS - 3) {
841 				device_printf(sc->xlpge_dev,
842 				    "packet defrag %d\n",
843 				    m_length(mbuf_chain, NULL));
844 				err = ENOBUFS; /* TODO fix error */
845 				goto fail;
846 			}
847 			paddr = vtophys(buf);
848 			frag_sz = PAGE_SIZE - (buf & PAGE_MASK);
849 			if (len < frag_sz)
850 				frag_sz = len;
851 			desc = nae_tx_desc(P2D_NEOP, 0, 127,
852 			    frag_sz, paddr);
853 			p2p->frag[pos] = htobe64(desc);
854 			pos++;
855 			len -= frag_sz;
856 			buf += frag_sz;
857 		}
858 	}
859 
860 	KASSERT(pos != 0, ("Zero-length mbuf chain?\n"));
861 
862 	/* Make the last one P2D EOP */
863 	p2p->frag[pos-1] |= htobe64((uint64_t)P2D_EOP << 62);
864 
865 	/* stash useful pointers in the desc */
866 	p2p->frag[XLP_NTXFRAGS-3] = 0xf00bad;
867 	p2p->frag[XLP_NTXFRAGS-2] = (uintptr_t)p2p;
868 	p2p->frag[XLP_NTXFRAGS-1] = (uintptr_t)mbuf_chain;
869 
870 	paddr = vtophys(p2p);
871 	msg.msg[0] = nae_tx_desc(P2P, 0, fbid, pos, paddr);
872 
873 	for (retries = 16;  retries > 0; retries--) {
874 		ret = nlm_fmn_msgsend(dst, 1, FMN_SWCODE_NAE, &msg);
875 		if (ret == 0)
876 			return (0);
877 	}
878 
879 fail:
880 	if (ret != 0) {
881 		tx_msgstatus = nlm_read_c2_txmsgstatus();
882 		if ((tx_msgstatus >> 24) & 0x1)
883 			device_printf(sc->xlpge_dev, "Transmit queue full - ");
884 		if ((tx_msgstatus >> 3) & 0x1)
885 			device_printf(sc->xlpge_dev, "ECC error - ");
886 		if ((tx_msgstatus >> 2) & 0x1)
887 			device_printf(sc->xlpge_dev, "Pending Sync - ");
888 		if ((tx_msgstatus >> 1) & 0x1)
889 			device_printf(sc->xlpge_dev,
890 			    "Insufficient input queue credits - ");
891 		if (tx_msgstatus & 0x1)
892 			device_printf(sc->xlpge_dev,
893 			    "Insufficient output queue credits - ");
894 	}
895 	device_printf(sc->xlpge_dev, "Send failed! err = %d\n", err);
896 	if (p2p)
897 		uma_zfree(nl_tx_desc_zone, p2p);
898 	m_freem(mbuf_chain);
899 	if_inc_counter(ifp, IFCOUNTER_IQDROPS, 1);
900 	return (err);
901 }
902 
903 static int
nlm_xlpge_gmac_config_speed(struct nlm_xlpge_softc * sc)904 nlm_xlpge_gmac_config_speed(struct nlm_xlpge_softc *sc)
905 {
906 	struct mii_data *mii;
907 
908 	if (sc->type == XAUIC || sc->type == ILC)
909 		return (0);
910 
911 	if (sc->mii_bus) {
912 		mii = device_get_softc(sc->mii_bus);
913 		mii_pollstat(mii);
914 	}
915 
916 	return (0);
917 }
918 
919 static void
nlm_xlpge_port_disable(struct nlm_xlpge_softc * sc)920 nlm_xlpge_port_disable(struct nlm_xlpge_softc *sc)
921 {
922 	struct ifnet   *ifp;
923 
924 	ifp = sc->xlpge_if;
925 	ifp->if_drv_flags &= ~IFF_DRV_RUNNING;
926 
927 	callout_stop(&sc->xlpge_callout);
928 	nlm_mac_disable(sc->base_addr, sc->block, sc->type, sc->port);
929 }
930 
931 static void
nlm_mii_pollstat(void * arg)932 nlm_mii_pollstat(void *arg)
933 {
934 	struct nlm_xlpge_softc *sc = (struct nlm_xlpge_softc *)arg;
935 	struct mii_data *mii = NULL;
936 
937 	if (sc->mii_bus) {
938 		mii = device_get_softc(sc->mii_bus);
939 
940 		KASSERT(mii != NULL, ("mii ptr is NULL"));
941 
942 		mii_pollstat(mii);
943 
944 		callout_reset(&sc->xlpge_callout, hz,
945 		    nlm_mii_pollstat, sc);
946 	}
947 }
948 
949 static void
nlm_xlpge_port_enable(struct nlm_xlpge_softc * sc)950 nlm_xlpge_port_enable(struct nlm_xlpge_softc *sc)
951 {
952 	if ((sc->type != SGMIIC) && (sc->type != XAUIC))
953 		return;
954 	nlm_mac_enable(sc->base_addr, sc->block, sc->type, sc->port);
955 	nlm_mii_pollstat((void *)sc);
956 }
957 
958 static void
nlm_xlpge_init(void * addr)959 nlm_xlpge_init(void *addr)
960 {
961 	struct nlm_xlpge_softc *sc;
962 	struct ifnet   *ifp;
963 	struct mii_data *mii = NULL;
964 
965 	sc = (struct nlm_xlpge_softc *)addr;
966 	ifp = sc->xlpge_if;
967 
968 	if (ifp->if_drv_flags & IFF_DRV_RUNNING)
969 		return;
970 
971 	if (sc->mii_bus) {
972 		mii = device_get_softc(sc->mii_bus);
973 		mii_mediachg(mii);
974 	}
975 
976 	nlm_xlpge_gmac_config_speed(sc);
977 	ifp->if_drv_flags |= IFF_DRV_RUNNING;
978 	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
979 	nlm_xlpge_port_enable(sc);
980 
981 	/* start the callout */
982 	callout_reset(&sc->xlpge_callout, hz, nlm_mii_pollstat, sc);
983 }
984 
985 /*
986  * Read the MAC address from FDT or board eeprom.
987  */
988 static void
xlpge_read_mac_addr(struct nlm_xlpge_softc * sc)989 xlpge_read_mac_addr(struct nlm_xlpge_softc *sc)
990 {
991 
992 	xlpge_get_macaddr(sc->dev_addr);
993 	/* last octet is port specific */
994 	sc->dev_addr[5] += (sc->block * 4) + sc->port;
995 
996 	if (sc->type == SGMIIC)
997 		nlm_nae_setup_mac_addr_sgmii(sc->base_addr, sc->block,
998 		    sc->port, sc->type, sc->dev_addr);
999 	else if (sc->type == XAUIC)
1000 		nlm_nae_setup_mac_addr_xaui(sc->base_addr, sc->block,
1001 		    sc->port, sc->type, sc->dev_addr);
1002 }
1003 
1004 static int
xlpge_mediachange(struct ifnet * ifp)1005 xlpge_mediachange(struct ifnet *ifp)
1006 {
1007 	return (0);
1008 }
1009 
1010 static void
xlpge_mediastatus(struct ifnet * ifp,struct ifmediareq * ifmr)1011 xlpge_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr)
1012 {
1013 	struct nlm_xlpge_softc *sc;
1014 	struct mii_data *md;
1015 
1016 	md = NULL;
1017 	sc = ifp->if_softc;
1018 
1019 	if (sc->mii_bus)
1020 		md = device_get_softc(sc->mii_bus);
1021 
1022 	ifmr->ifm_status = IFM_AVALID;
1023 	ifmr->ifm_active = IFM_ETHER;
1024 
1025 	if (sc->link == NLM_LINK_DOWN)
1026 		return;
1027 
1028 	if (md != NULL)
1029 		ifmr->ifm_active = md->mii_media.ifm_cur->ifm_media;
1030 	ifmr->ifm_status |= IFM_ACTIVE;
1031 }
1032 
1033 static int
nlm_xlpge_ifinit(struct nlm_xlpge_softc * sc)1034 nlm_xlpge_ifinit(struct nlm_xlpge_softc *sc)
1035 {
1036 	struct ifnet *ifp;
1037 	device_t dev;
1038 	int port = sc->block * 4 + sc->port;
1039 
1040 	dev = sc->xlpge_dev;
1041 	ifp = sc->xlpge_if = if_alloc(IFT_ETHER);
1042 	/*(sc->network_sc)->ifp_ports[port].xlpge_if = ifp;*/
1043 	ifp_ports[port].xlpge_if = ifp;
1044 
1045 	if (ifp == NULL) {
1046 		device_printf(dev, "cannot if_alloc()\n");
1047 		return (ENOSPC);
1048 	}
1049 	ifp->if_softc = sc;
1050 	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
1051 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
1052 	sc->if_flags = ifp->if_flags;
1053 	/*ifp->if_capabilities = IFCAP_TXCSUM | IFCAP_VLAN_HWTAGGING;*/
1054 	ifp->if_capabilities = 0;
1055 	ifp->if_capenable = ifp->if_capabilities;
1056 	ifp->if_ioctl = nlm_xlpge_ioctl;
1057 	ifp->if_init  = nlm_xlpge_init ;
1058 	ifp->if_hwassist = 0;
1059 	ifp->if_snd.ifq_drv_maxlen = NLM_XLPGE_TXQ_SIZE; /* TODO: make this a sysint */
1060 	IFQ_SET_MAXLEN(&ifp->if_snd, ifp->if_snd.ifq_drv_maxlen);
1061 	IFQ_SET_READY(&ifp->if_snd);
1062 
1063 	ifmedia_init(&sc->xlpge_mii.mii_media, 0, xlpge_mediachange,
1064 	    xlpge_mediastatus);
1065 	ifmedia_add(&sc->xlpge_mii.mii_media, IFM_ETHER | IFM_AUTO, 0, NULL);
1066 	ifmedia_set(&sc->xlpge_mii.mii_media, IFM_ETHER | IFM_AUTO);
1067 	sc->xlpge_mii.mii_media.ifm_media =
1068 	    sc->xlpge_mii.mii_media.ifm_cur->ifm_media;
1069 	xlpge_read_mac_addr(sc);
1070 
1071 	ether_ifattach(ifp, sc->dev_addr);
1072 
1073 	/* override if_transmit : per ifnet(9), do it after if_attach */
1074 	ifp->if_transmit = xlpge_tx;
1075 
1076 	return (0);
1077 }
1078 
1079 static int
nlm_xlpge_probe(device_t dev)1080 nlm_xlpge_probe(device_t dev)
1081 {
1082 	return (BUS_PROBE_DEFAULT);
1083 }
1084 
1085 static void *
get_buf(void)1086 get_buf(void)
1087 {
1088 	struct mbuf     *m_new;
1089 	uint64_t        *md;
1090 #ifdef INVARIANTS
1091 	vm_paddr_t      temp1, temp2;
1092 #endif
1093 
1094 	if ((m_new = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR)) == NULL)
1095 		return (NULL);
1096 	m_new->m_len = m_new->m_pkthdr.len = MCLBYTES;
1097 	KASSERT(((uintptr_t)m_new->m_data & (NAE_CACHELINE_SIZE - 1)) == 0,
1098 	    ("m_new->m_data is not cacheline aligned"));
1099 	md = (uint64_t *)m_new->m_data;
1100 	md[0] = (intptr_t)m_new;        /* Back Ptr */
1101 	md[1] = 0xf00bad;
1102 	m_adj(m_new, NAE_CACHELINE_SIZE);
1103 
1104 #ifdef INVARIANTS
1105 	temp1 = vtophys((vm_offset_t) m_new->m_data);
1106 	temp2 = vtophys((vm_offset_t) m_new->m_data + 1536);
1107 	KASSERT((temp1 + 1536) == temp2,
1108 	    ("Alloced buffer is not contiguous"));
1109 #endif
1110 	return ((void *)m_new->m_data);
1111 }
1112 
1113 static void
nlm_xlpge_mii_init(device_t dev,struct nlm_xlpge_softc * sc)1114 nlm_xlpge_mii_init(device_t dev, struct nlm_xlpge_softc *sc)
1115 {
1116 	int error;
1117 
1118 	error = mii_attach(dev, &sc->mii_bus, sc->xlpge_if,
1119 			xlpge_mediachange, xlpge_mediastatus,
1120 			BMSR_DEFCAPMASK, sc->phy_addr, MII_OFFSET_ANY, 0);
1121 
1122 	if (error) {
1123 		device_printf(dev, "attaching PHYs failed\n");
1124 		sc->mii_bus = NULL;
1125 	}
1126 
1127 	if (sc->mii_bus != NULL) {
1128 		/* enable MDIO interrupts in the PHY */
1129 		/* XXXJC: TODO */
1130 	}
1131 }
1132 
1133 static int
xlpge_stats_sysctl(SYSCTL_HANDLER_ARGS)1134 xlpge_stats_sysctl(SYSCTL_HANDLER_ARGS)
1135 {
1136 	struct nlm_xlpge_softc *sc;
1137 	uint32_t val;
1138 	int reg, field;
1139 
1140 	sc = arg1;
1141 	field = arg2;
1142 	reg = SGMII_STATS_MLR(sc->block, sc->port) + field;
1143 	val = nlm_read_nae_reg(sc->base_addr, reg);
1144 	return (sysctl_handle_int(oidp, &val, 0, req));
1145 }
1146 
1147 static void
nlm_xlpge_setup_stats_sysctl(device_t dev,struct nlm_xlpge_softc * sc)1148 nlm_xlpge_setup_stats_sysctl(device_t dev, struct nlm_xlpge_softc *sc)
1149 {
1150 	struct sysctl_ctx_list *ctx;
1151 	struct sysctl_oid_list *child;
1152 	struct sysctl_oid *tree;
1153 
1154 	ctx = device_get_sysctl_ctx(dev);
1155 	tree = device_get_sysctl_tree(dev);
1156 	child = SYSCTL_CHILDREN(tree);
1157 
1158 #define XLPGE_STAT(name, offset, desc)				\
1159 	SYSCTL_ADD_PROC(ctx, child, OID_AUTO, name,		\
1160 	    CTLTYPE_UINT | CTLFLAG_RD | CTLFLAG_NEEDGIANT,	\
1161 	    sc, offset,	xlpge_stats_sysctl, "IU", desc)
1162 
1163 	XLPGE_STAT("tr127", nlm_sgmii_stats_tr127, "TxRx 64 - 127 Bytes");
1164 	XLPGE_STAT("tr255", nlm_sgmii_stats_tr255, "TxRx 128 - 255 Bytes");
1165 	XLPGE_STAT("tr511", nlm_sgmii_stats_tr511, "TxRx 256 - 511 Bytes");
1166 	XLPGE_STAT("tr1k",  nlm_sgmii_stats_tr1k,  "TxRx 512 - 1023 Bytes");
1167 	XLPGE_STAT("trmax", nlm_sgmii_stats_trmax, "TxRx 1024 - 1518 Bytes");
1168 	XLPGE_STAT("trmgv", nlm_sgmii_stats_trmgv, "TxRx 1519 - 1522 Bytes");
1169 
1170 	XLPGE_STAT("rbyt", nlm_sgmii_stats_rbyt, "Rx Bytes");
1171 	XLPGE_STAT("rpkt", nlm_sgmii_stats_rpkt, "Rx Packets");
1172 	XLPGE_STAT("rfcs", nlm_sgmii_stats_rfcs, "Rx FCS Error");
1173 	XLPGE_STAT("rmca", nlm_sgmii_stats_rmca, "Rx Multicast Packets");
1174 	XLPGE_STAT("rbca", nlm_sgmii_stats_rbca, "Rx Broadcast Packets");
1175 	XLPGE_STAT("rxcf", nlm_sgmii_stats_rxcf, "Rx Control Frames");
1176 	XLPGE_STAT("rxpf", nlm_sgmii_stats_rxpf, "Rx Pause Frames");
1177 	XLPGE_STAT("rxuo", nlm_sgmii_stats_rxuo, "Rx Unknown Opcode");
1178 	XLPGE_STAT("raln", nlm_sgmii_stats_raln, "Rx Alignment Errors");
1179 	XLPGE_STAT("rflr", nlm_sgmii_stats_rflr, "Rx Framelength Errors");
1180 	XLPGE_STAT("rcde", nlm_sgmii_stats_rcde, "Rx Code Errors");
1181 	XLPGE_STAT("rcse", nlm_sgmii_stats_rcse, "Rx Carrier Sense Errors");
1182 	XLPGE_STAT("rund", nlm_sgmii_stats_rund, "Rx Undersize Packet Errors");
1183 	XLPGE_STAT("rovr", nlm_sgmii_stats_rovr, "Rx Oversize Packet Errors");
1184 	XLPGE_STAT("rfrg", nlm_sgmii_stats_rfrg, "Rx Fragments");
1185 	XLPGE_STAT("rjbr", nlm_sgmii_stats_rjbr, "Rx Jabber");
1186 
1187 	XLPGE_STAT("tbyt", nlm_sgmii_stats_tbyt, "Tx Bytes");
1188 	XLPGE_STAT("tpkt", nlm_sgmii_stats_tpkt, "Tx Packets");
1189 	XLPGE_STAT("tmca", nlm_sgmii_stats_tmca, "Tx Multicast Packets");
1190 	XLPGE_STAT("tbca", nlm_sgmii_stats_tbca, "Tx Broadcast Packets");
1191 	XLPGE_STAT("txpf", nlm_sgmii_stats_txpf, "Tx Pause Frame");
1192 	XLPGE_STAT("tdfr", nlm_sgmii_stats_tdfr, "Tx Deferral Packets");
1193 	XLPGE_STAT("tedf", nlm_sgmii_stats_tedf, "Tx Excessive Deferral Pkts");
1194 	XLPGE_STAT("tscl", nlm_sgmii_stats_tscl, "Tx Single Collisions");
1195 	XLPGE_STAT("tmcl", nlm_sgmii_stats_tmcl, "Tx Multiple Collisions");
1196 	XLPGE_STAT("tlcl", nlm_sgmii_stats_tlcl, "Tx Late Collision Pkts");
1197 	XLPGE_STAT("txcl", nlm_sgmii_stats_txcl, "Tx Excessive Collisions");
1198 	XLPGE_STAT("tncl", nlm_sgmii_stats_tncl, "Tx Total Collisions");
1199 	XLPGE_STAT("tjbr", nlm_sgmii_stats_tjbr, "Tx Jabber Frames");
1200 	XLPGE_STAT("tfcs", nlm_sgmii_stats_tfcs, "Tx FCS Errors");
1201 	XLPGE_STAT("txcf", nlm_sgmii_stats_txcf, "Tx Control Frames");
1202 	XLPGE_STAT("tovr", nlm_sgmii_stats_tovr, "Tx Oversize Frames");
1203 	XLPGE_STAT("tund", nlm_sgmii_stats_tund, "Tx Undersize Frames");
1204 	XLPGE_STAT("tfrg", nlm_sgmii_stats_tfrg, "Tx Fragments");
1205 #undef XLPGE_STAT
1206 }
1207 
1208 static int
nlm_xlpge_attach(device_t dev)1209 nlm_xlpge_attach(device_t dev)
1210 {
1211 	struct xlp_port_ivars *pv;
1212 	struct nlm_xlpge_softc *sc;
1213 	int port;
1214 
1215 	pv = device_get_ivars(dev);
1216 	sc = device_get_softc(dev);
1217 	sc->xlpge_dev = dev;
1218 	sc->mii_bus = NULL;
1219 	sc->block = pv->block;
1220 	sc->node = pv->node;
1221 	sc->port = pv->port;
1222 	sc->type = pv->type;
1223 	sc->xlpge_if = NULL;
1224 	sc->phy_addr = pv->phy_addr;
1225 	sc->mdio_bus = pv->mdio_bus;
1226 	sc->portcfg = nae_port_config;
1227 	sc->hw_parser_en = pv->hw_parser_en;
1228 
1229 	/* default settings */
1230 	sc->speed = NLM_SGMII_SPEED_10;
1231 	sc->duplexity = NLM_SGMII_DUPLEX_FULL;
1232 	sc->link = NLM_LINK_DOWN;
1233 	sc->flowctrl = NLM_FLOWCTRL_DISABLED;
1234 
1235 	sc->network_sc = device_get_softc(device_get_parent(dev));
1236 	sc->base_addr = sc->network_sc->base;
1237 	sc->prepad_en = sc->network_sc->prepad_en;
1238 	sc->prepad_size = sc->network_sc->prepad_size;
1239 
1240 	callout_init(&sc->xlpge_callout, 1);
1241 
1242 	XLPGE_LOCK_INIT(sc, device_get_nameunit(dev));
1243 
1244 	port = (sc->block*4)+sc->port;
1245 	sc->nfree_desc = nae_port_config[port].num_free_descs;
1246 	sc->txq = nae_port_config[port].txq;
1247 	sc->rxfreeq = nae_port_config[port].rxfreeq;
1248 
1249 	nlm_xlpge_submit_rx_free_desc(sc, sc->nfree_desc);
1250 	if (sc->hw_parser_en)
1251 		nlm_enable_hardware_parser_per_port(sc->base_addr,
1252 		    sc->block, sc->port);
1253 
1254 	nlm_xlpge_ifinit(sc);
1255 	ifp_ports[port].xlpge_sc = sc;
1256 	nlm_xlpge_mii_init(dev, sc);
1257 
1258 	nlm_xlpge_setup_stats_sysctl(dev, sc);
1259 
1260 	return (0);
1261 }
1262 
1263 static int
nlm_xlpge_detach(device_t dev)1264 nlm_xlpge_detach(device_t dev)
1265 {
1266 	return (0);
1267 }
1268 
1269 static int
nlm_xlpge_suspend(device_t dev)1270 nlm_xlpge_suspend(device_t dev)
1271 {
1272 	return (0);
1273 }
1274 
1275 static int
nlm_xlpge_resume(device_t dev)1276 nlm_xlpge_resume(device_t dev)
1277 {
1278 	return (0);
1279 }
1280 
1281 static int
nlm_xlpge_shutdown(device_t dev)1282 nlm_xlpge_shutdown(device_t dev)
1283 {
1284 	return (0);
1285 }
1286 
1287 /*
1288  * miibus function with custom implementation
1289  */
1290 static int
nlm_xlpge_mii_read(device_t dev,int phyaddr,int regidx)1291 nlm_xlpge_mii_read(device_t dev, int phyaddr, int regidx)
1292 {
1293 	struct nlm_xlpge_softc *sc;
1294 	int val;
1295 
1296 	sc = device_get_softc(dev);
1297 	if (sc->type == SGMIIC)
1298 		val = nlm_gmac_mdio_read(sc->base_addr, sc->mdio_bus,
1299 		    BLOCK_7, LANE_CFG, phyaddr, regidx);
1300 	else
1301 		val = 0xffff;
1302 
1303 	return (val);
1304 }
1305 
1306 static int
nlm_xlpge_mii_write(device_t dev,int phyaddr,int regidx,int val)1307 nlm_xlpge_mii_write(device_t dev, int phyaddr, int regidx, int val)
1308 {
1309 	struct nlm_xlpge_softc *sc;
1310 
1311 	sc = device_get_softc(dev);
1312 	if (sc->type == SGMIIC)
1313 		nlm_gmac_mdio_write(sc->base_addr, sc->mdio_bus, BLOCK_7,
1314 		    LANE_CFG, phyaddr, regidx, val);
1315 
1316 	return (0);
1317 }
1318 
1319 static void
nlm_xlpge_mii_statchg(device_t dev)1320 nlm_xlpge_mii_statchg(device_t dev)
1321 {
1322 	struct nlm_xlpge_softc *sc;
1323 	struct mii_data *mii;
1324 	char *speed, *duplexity;
1325 
1326 	sc = device_get_softc(dev);
1327 	if (sc->mii_bus == NULL)
1328 		return;
1329 
1330 	mii = device_get_softc(sc->mii_bus);
1331 	if (mii->mii_media_status & IFM_ACTIVE) {
1332 		if (IFM_SUBTYPE(mii->mii_media_active) ==  IFM_10_T) {
1333 			sc->speed = NLM_SGMII_SPEED_10;
1334 			speed =  "10Mbps";
1335 		} else if (IFM_SUBTYPE(mii->mii_media_active) == IFM_100_TX) {
1336 			sc->speed = NLM_SGMII_SPEED_100;
1337 			speed = "100Mbps";
1338 		} else { /* default to 1G */
1339 			sc->speed = NLM_SGMII_SPEED_1000;
1340 			speed =  "1Gbps";
1341 		}
1342 
1343 		if ((mii->mii_media_active & IFM_GMASK) == IFM_FDX) {
1344 			sc->duplexity = NLM_SGMII_DUPLEX_FULL;
1345 			duplexity =  "full";
1346 		} else {
1347 			sc->duplexity = NLM_SGMII_DUPLEX_HALF;
1348 			duplexity = "half";
1349 		}
1350 
1351 		printf("Port [%d, %d] setup with speed=%s duplex=%s\n",
1352 		    sc->block, sc->port, speed, duplexity);
1353 
1354 		nlm_nae_setup_mac(sc->base_addr, sc->block, sc->port, 0, 1, 1,
1355 		    sc->speed, sc->duplexity);
1356 	}
1357 }
1358 
1359 /*
1360  * xlpge support function implementations
1361  */
1362 static void
nlm_xlpge_release_mbuf(uint64_t paddr)1363 nlm_xlpge_release_mbuf(uint64_t paddr)
1364 {
1365 	uint64_t	mag, desc, mbuf;
1366 
1367 	paddr += (XLP_NTXFRAGS - 3) * sizeof(uint64_t);
1368 	mag = nlm_paddr_ld(paddr);
1369 	desc = nlm_paddr_ld(paddr + sizeof(uint64_t));
1370 	mbuf = nlm_paddr_ld(paddr + 2 * sizeof(uint64_t));
1371 
1372 	if (mag != 0xf00bad) {
1373 		/* somebody else packet Error - FIXME in intialization */
1374 		printf("cpu %d: ERR Tx packet paddr %jx, mag %jx, desc %jx mbuf %jx\n",
1375 		    nlm_cpuid(), (uintmax_t)paddr, (uintmax_t)mag,
1376 		    (intmax_t)desc, (uintmax_t)mbuf);
1377 		return;
1378 	}
1379 	m_freem((struct mbuf *)(uintptr_t)mbuf);
1380 	uma_zfree(nl_tx_desc_zone, (void *)(uintptr_t)desc);
1381 }
1382 
1383 static void
nlm_xlpge_rx(struct nlm_xlpge_softc * sc,int port,vm_paddr_t paddr,int len)1384 nlm_xlpge_rx(struct nlm_xlpge_softc *sc, int port, vm_paddr_t paddr, int len)
1385 {
1386 	struct ifnet	*ifp;
1387 	struct mbuf	*m;
1388 	vm_offset_t	temp;
1389 	unsigned long	mag;
1390 	int		prepad_size;
1391 
1392 	ifp = sc->xlpge_if;
1393 	temp = nlm_paddr_ld(paddr - NAE_CACHELINE_SIZE);
1394 	mag = nlm_paddr_ld(paddr - NAE_CACHELINE_SIZE + sizeof(uint64_t));
1395 
1396 	m = (struct mbuf *)(intptr_t)temp;
1397 	if (mag != 0xf00bad) {
1398 		/* somebody else packet Error - FIXME in intialization */
1399 		printf("cpu %d: ERR Rx packet paddr %jx, temp %p, mag %lx\n",
1400 		    nlm_cpuid(), (uintmax_t)paddr, (void *)temp, mag);
1401 		return;
1402 	}
1403 
1404 	m->m_pkthdr.rcvif = ifp;
1405 
1406 #ifdef DUMP_PACKET
1407 	{
1408 		int     i = 0, j = 64;
1409 		unsigned char *buf = (char *)m->m_data;
1410 		printf("(cpu_%d: nlge_rx, !RX_COPY) Rx Packet: length=%d\n",
1411 				nlm_cpuid(), len);
1412 		if (len < j)
1413 			j = len;
1414 		if (sc->prepad_en)
1415 			j += ((sc->prepad_size + 1) * 16);
1416 		for (i = 0; i < j; i++) {
1417 			if (i && (i % 16) == 0)
1418 				printf("\n");
1419 			printf("%02x ", buf[i]);
1420 		}
1421 		printf("\n");
1422 	}
1423 #endif
1424 
1425 	if (sc->prepad_en) {
1426 		prepad_size = ((sc->prepad_size + 1) * 16);
1427 		m->m_data += prepad_size;
1428 		m->m_pkthdr.len = m->m_len = (len - prepad_size);
1429 	} else
1430 		m->m_pkthdr.len = m->m_len = len;
1431 
1432 	if_inc_counter(ifp, IFCOUNTER_IPACKETS, 1);
1433 #ifdef XLP_DRIVER_LOOPBACK
1434 	if (port == 16 || port == 17)
1435 		(*ifp->if_input)(ifp, m);
1436 	else
1437 		xlpge_tx(ifp, m);
1438 #else
1439 	(*ifp->if_input)(ifp, m);
1440 #endif
1441 }
1442 
1443 void
nlm_xlpge_submit_rx_free_desc(struct nlm_xlpge_softc * sc,int num)1444 nlm_xlpge_submit_rx_free_desc(struct nlm_xlpge_softc *sc, int num)
1445 {
1446 	int i, size, ret, n;
1447 	struct nlm_fmn_msg msg;
1448 	void *ptr;
1449 
1450 	for(i = 0; i < num; i++) {
1451 		memset(&msg, 0, sizeof(msg));
1452 		ptr = get_buf();
1453 		if (!ptr) {
1454 			device_printf(sc->xlpge_dev, "Cannot allocate mbuf\n");
1455 			break;
1456 		}
1457 
1458 		msg.msg[0] = vtophys(ptr);
1459 		if (msg.msg[0] == 0) {
1460 			printf("Bad ptr for %p\n", ptr);
1461 			break;
1462 		}
1463 		size = 1;
1464 
1465 		n = 0;
1466 		while (1) {
1467 			/* on success returns 1, else 0 */
1468 			ret = nlm_fmn_msgsend(sc->rxfreeq, size, 0, &msg);
1469 			if (ret == 0)
1470 				break;
1471 			if (n++ > 10000) {
1472 				printf("Too many credit fails for send free desc\n");
1473 				break;
1474 			}
1475 		}
1476 	}
1477 }
1478 
1479 void
nlm_xlpge_msgring_handler(int vc,int size,int code,int src_id,struct nlm_fmn_msg * msg,void * data)1480 nlm_xlpge_msgring_handler(int vc, int size, int code, int src_id,
1481     struct nlm_fmn_msg *msg, void *data)
1482 {
1483 	uint64_t phys_addr;
1484 	struct nlm_xlpnae_softc *sc;
1485 	struct nlm_xlpge_softc *xlpge_sc;
1486 	struct ifnet *ifp;
1487 	uint32_t context;
1488 	uint32_t port = 0;
1489 	uint32_t length;
1490 
1491 	sc = (struct nlm_xlpnae_softc *)data;
1492 	KASSERT(sc != NULL, ("Null sc in msgring handler"));
1493 
1494 	if (size == 1) { /* process transmit complete */
1495 		phys_addr = msg->msg[0] & 0xffffffffffULL;
1496 
1497 		/* context is SGMII_RCV_CONTEXT_NUM + three bit vlan type
1498 		 * or vlan priority
1499 		 */
1500 		context = (msg->msg[0] >> 40) & 0x3fff;
1501 		port = cntx2port[context];
1502 
1503 		if (port >= XLP_MAX_PORTS) {
1504 			printf("%s:%d Bad port %d (context=%d)\n",
1505 				__func__, __LINE__, port, context);
1506 			return;
1507 		}
1508 		ifp = ifp_ports[port].xlpge_if;
1509 		xlpge_sc = ifp_ports[port].xlpge_sc;
1510 
1511 		nlm_xlpge_release_mbuf(phys_addr);
1512 
1513 		if_inc_counter(ifp, IFCOUNTER_OPACKETS, 1);
1514 
1515 	} else if (size > 1) { /* Recieve packet */
1516 		phys_addr = msg->msg[1] & 0xffffffffc0ULL;
1517 		length = (msg->msg[1] >> 40) & 0x3fff;
1518 		length -= MAC_CRC_LEN;
1519 
1520 		/* context is SGMII_RCV_CONTEXT_NUM + three bit vlan type
1521 		 * or vlan priority
1522 		 */
1523 		context = (msg->msg[1] >> 54) & 0x3ff;
1524 		port = cntx2port[context];
1525 
1526 		if (port >= XLP_MAX_PORTS) {
1527 			printf("%s:%d Bad port %d (context=%d)\n",
1528 				__func__, __LINE__, port, context);
1529 			return;
1530 		}
1531 
1532 		ifp = ifp_ports[port].xlpge_if;
1533 		xlpge_sc = ifp_ports[port].xlpge_sc;
1534 
1535 		nlm_xlpge_rx(xlpge_sc, port, phys_addr, length);
1536 		/* return back a free descriptor to NA */
1537 		nlm_xlpge_submit_rx_free_desc(xlpge_sc, 1);
1538 	}
1539 }
1540