xref: /freebsd/sys/powerpc/pseries/phyp_llan.c (revision 22cf89c938886d14f5796fc49f9f020c23ea8eaf)
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause
3  *
4  * Copyright 2013 Nathan Whitehorn
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  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26  * SUCH DAMAGE.
27  */
28 
29 #include <sys/cdefs.h>
30 #include <sys/param.h>
31 #include <sys/systm.h>
32 #include <sys/sockio.h>
33 #include <sys/endian.h>
34 #include <sys/lock.h>
35 #include <sys/mbuf.h>
36 #include <sys/module.h>
37 #include <sys/malloc.h>
38 #include <sys/mutex.h>
39 #include <sys/kernel.h>
40 #include <sys/socket.h>
41 
42 #include <net/bpf.h>
43 #include <net/if.h>
44 #include <net/if_var.h>
45 #include <net/ethernet.h>
46 #include <net/if_dl.h>
47 #include <net/if_media.h>
48 #include <net/if_types.h>
49 
50 #include <dev/ofw/openfirm.h>
51 #include <dev/ofw/ofw_bus.h>
52 #include <dev/ofw/ofw_bus_subr.h>
53 #include <machine/bus.h>
54 #include <machine/resource.h>
55 #include <sys/bus.h>
56 #include <sys/rman.h>
57 
58 #include <powerpc/pseries/phyp-hvcall.h>
59 
60 #define LLAN_MAX_RX_PACKETS	100
61 #define LLAN_MAX_TX_PACKETS	100
62 #define LLAN_RX_BUF_LEN		8*PAGE_SIZE
63 
64 #define LLAN_BUFDESC_VALID	(1ULL << 63)
65 #define LLAN_ADD_MULTICAST	0x1
66 #define LLAN_DEL_MULTICAST	0x2
67 #define LLAN_CLEAR_MULTICAST	0x3
68 
69 struct llan_xfer {
70 	struct mbuf *rx_mbuf;
71 	bus_dmamap_t rx_dmamap;
72 	uint64_t rx_bufdesc;
73 };
74 
75 struct llan_receive_queue_entry { /* PAPR page 539 */
76 	uint8_t control;
77 	uint8_t reserved;
78 	uint16_t offset;
79 	uint32_t length;
80 	uint64_t handle;
81 } __packed;
82 
83 struct llan_softc {
84 	device_t	dev;
85 	struct mtx	io_lock;
86 
87 	cell_t		unit;
88 	uint8_t		mac_address[8];
89 
90 	struct ifmedia	media;
91 
92 	int		irqid;
93 	struct resource	*irq;
94 	void		*irq_cookie;
95 
96 	bus_dma_tag_t	rx_dma_tag;
97 	bus_dma_tag_t	rxbuf_dma_tag;
98 	bus_dma_tag_t	tx_dma_tag;
99 
100 	bus_dmamap_t	tx_dma_map;
101 
102 	struct llan_receive_queue_entry *rx_buf;
103 	int		rx_dma_slot;
104 	int		rx_valid_val;
105 	bus_dmamap_t	rx_buf_map;
106 	bus_addr_t	rx_buf_phys;
107 	bus_size_t	rx_buf_len;
108 	bus_addr_t	input_buf_phys;
109 	bus_addr_t	filter_buf_phys;
110 	struct llan_xfer rx_xfer[LLAN_MAX_RX_PACKETS];
111 
112 	struct ifnet	*ifp;
113 };
114 
115 static int	llan_probe(device_t);
116 static int	llan_attach(device_t);
117 static void	llan_intr(void *xsc);
118 static void	llan_init(void *xsc);
119 static void	llan_start(struct ifnet *ifp);
120 static int	llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
121 static void	llan_media_status(struct ifnet *ifp, struct ifmediareq *ifmr);
122 static int	llan_media_change(struct ifnet *ifp);
123 static void	llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs,
124 		    int err);
125 static int	llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx);
126 static int	llan_set_multicast(struct llan_softc *sc);
127 
128 static device_method_t  llan_methods[] = {
129         DEVMETHOD(device_probe,         llan_probe),
130         DEVMETHOD(device_attach,        llan_attach),
131 
132         DEVMETHOD_END
133 };
134 
135 static driver_t llan_driver = {
136         "llan",
137         llan_methods,
138         sizeof(struct llan_softc)
139 };
140 
141 DRIVER_MODULE(llan, vdevice, llan_driver, 0, 0);
142 
143 static int
144 llan_probe(device_t dev)
145 {
146 	if (!ofw_bus_is_compatible(dev,"IBM,l-lan"))
147 		return (ENXIO);
148 
149 	device_set_desc(dev, "POWER Hypervisor Virtual Ethernet");
150 	return (0);
151 }
152 
153 static int
154 llan_attach(device_t dev)
155 {
156 	struct llan_softc *sc;
157 	phandle_t node;
158 	int i;
159 	ssize_t len;
160 
161 	sc = device_get_softc(dev);
162 	sc->dev = dev;
163 
164 	/* Get firmware properties */
165 	node = ofw_bus_get_node(dev);
166 	len = OF_getprop(node, "local-mac-address", sc->mac_address,
167 	    sizeof(sc->mac_address));
168 	/* If local-mac-address property has only 6 bytes (ETHER_ADDR_LEN)
169 	 * instead of 8 (sizeof(sc->mac_address)), then its value must be
170 	 * shifted 2 bytes to the right. */
171 	if (len == ETHER_ADDR_LEN) {
172 		bcopy(sc->mac_address, &sc->mac_address[2], len);
173 		/* Zero out the first 2 bytes. */
174 		bzero(sc->mac_address, 2);
175 	}
176 	OF_getencprop(node, "reg", &sc->unit, sizeof(sc->unit));
177 
178 	mtx_init(&sc->io_lock, "llan", NULL, MTX_DEF);
179 
180         /* Setup interrupt */
181 	sc->irqid = 0;
182 	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
183 	    RF_ACTIVE);
184 
185 	if (!sc->irq) {
186 		device_printf(dev, "Could not allocate IRQ\n");
187 		mtx_destroy(&sc->io_lock);
188 		return (ENXIO);
189 	}
190 
191 	bus_setup_intr(dev, sc->irq, INTR_TYPE_NET | INTR_MPSAFE |
192 	    INTR_ENTROPY, NULL, llan_intr, sc, &sc->irq_cookie);
193 
194 	/* Setup DMA */
195 	bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0,
196             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
197 	    LLAN_RX_BUF_LEN, 1, BUS_SPACE_MAXSIZE_32BIT,
198 	    0, NULL, NULL, &sc->rx_dma_tag);
199 	bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0,
200             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
201 	    BUS_SPACE_MAXSIZE, 1, BUS_SPACE_MAXSIZE_32BIT,
202 	    0, NULL, NULL, &sc->rxbuf_dma_tag);
203 	bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
204             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
205 	    BUS_SPACE_MAXSIZE, 6, BUS_SPACE_MAXSIZE_32BIT, 0,
206 	    busdma_lock_mutex, &sc->io_lock, &sc->tx_dma_tag);
207 
208 	bus_dmamem_alloc(sc->rx_dma_tag, (void **)&sc->rx_buf,
209 	    BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx_buf_map);
210 	bus_dmamap_load(sc->rx_dma_tag, sc->rx_buf_map, sc->rx_buf,
211 	    LLAN_RX_BUF_LEN, llan_rx_load_cb, sc, 0);
212 
213 	/* TX DMA maps */
214 	bus_dmamap_create(sc->tx_dma_tag, 0, &sc->tx_dma_map);
215 
216 	/* RX DMA */
217 	for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) {
218 		bus_dmamap_create(sc->rxbuf_dma_tag, 0,
219 		    &sc->rx_xfer[i].rx_dmamap);
220 		sc->rx_xfer[i].rx_mbuf = NULL;
221 	}
222 
223 	/* Attach to network stack */
224 	sc->ifp = if_alloc(IFT_ETHER);
225 	if_setsoftc(sc->ifp, sc);
226 
227 	if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev));
228 	if_setmtu(sc->ifp, ETHERMTU); /* XXX max-frame-size from OF? */
229 	if_setflags(sc->ifp, IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST);
230 	if_sethwassist(sc->ifp, 0); /* XXX: ibm,illan-options */
231 	if_setcapabilities(sc->ifp, 0);
232 	if_setcapenable(sc->ifp, 0);
233 	if_setstartfn(sc->ifp, llan_start);
234 	if_setioctlfn(sc->ifp, llan_ioctl);
235 	if_setinitfn(sc->ifp, llan_init);
236 
237 	ifmedia_init(&sc->media, IFM_IMASK, llan_media_change,
238 	    llan_media_status);
239 	ifmedia_add(&sc->media, IFM_ETHER | IFM_AUTO, 0, NULL);
240 	ifmedia_set(&sc->media, IFM_ETHER | IFM_AUTO);
241 
242 	if_setsendqlen(sc->ifp, LLAN_MAX_RX_PACKETS);
243 	if_setsendqready(sc->ifp);
244 
245 	ether_ifattach(sc->ifp, &sc->mac_address[2]);
246 
247 	/* We don't have link state reporting, so make it always up */
248 	if_link_state_change(sc->ifp, LINK_STATE_UP);
249 
250 	return (0);
251 }
252 
253 static int
254 llan_media_change(struct ifnet *ifp)
255 {
256 	struct llan_softc *sc = if_getsoftc(ifp);
257 
258 	if (IFM_TYPE(sc->media.ifm_media) != IFM_ETHER)
259 		return (EINVAL);
260 
261 	if (IFM_SUBTYPE(sc->media.ifm_media) != IFM_AUTO)
262 		return (EINVAL);
263 
264 	return (0);
265 }
266 
267 static void
268 llan_media_status(struct ifnet *ifp, struct ifmediareq *ifmr)
269 {
270 
271 	ifmr->ifm_status = IFM_AVALID | IFM_ACTIVE | IFM_UNKNOWN | IFM_FDX;
272 	ifmr->ifm_active = IFM_ETHER;
273 }
274 
275 static void
276 llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int err)
277 {
278 	struct llan_softc *sc = xsc;
279 
280 	sc->rx_buf_phys = segs[0].ds_addr;
281 	sc->rx_buf_len = segs[0].ds_len - 2*PAGE_SIZE;
282 	sc->input_buf_phys = segs[0].ds_addr + segs[0].ds_len - PAGE_SIZE;
283 	sc->filter_buf_phys = segs[0].ds_addr + segs[0].ds_len - 2*PAGE_SIZE;
284 }
285 
286 static void
287 llan_init(void *xsc)
288 {
289 	struct llan_softc *sc = xsc;
290 	uint64_t rx_buf_desc;
291 	uint64_t macaddr;
292 	int i;
293 
294 	mtx_lock(&sc->io_lock);
295 
296 	phyp_hcall(H_FREE_LOGICAL_LAN, sc->unit);
297 
298 	/* Create buffers (page 539) */
299 	sc->rx_dma_slot = 0;
300 	sc->rx_valid_val = 1;
301 
302 	rx_buf_desc = LLAN_BUFDESC_VALID;
303 	rx_buf_desc |= (sc->rx_buf_len << 32);
304 	rx_buf_desc |= sc->rx_buf_phys;
305 	memcpy(&macaddr, sc->mac_address, 8);
306 	phyp_hcall(H_REGISTER_LOGICAL_LAN, sc->unit, sc->input_buf_phys,
307 	    rx_buf_desc, sc->filter_buf_phys, macaddr);
308 
309 	for (i = 0; i < LLAN_MAX_RX_PACKETS; i++)
310 		llan_add_rxbuf(sc, &sc->rx_xfer[i]);
311 
312 	phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */
313 
314 	/* Tell stack we're up */
315 	if_setdrvflagbits(sc->ifp, IFF_DRV_RUNNING, IFF_DRV_OACTIVE);
316 
317 	mtx_unlock(&sc->io_lock);
318 
319 	/* Check for pending receives scheduled before interrupt enable */
320 	llan_intr(sc);
321 }
322 
323 static int
324 llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx)
325 {
326 	struct mbuf *m;
327 	bus_dma_segment_t segs[1];
328 	int error, nsegs;
329 
330 	mtx_assert(&sc->io_lock, MA_OWNED);
331 
332 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
333 	if (m == NULL)
334 		return (ENOBUFS);
335 
336 	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
337 	if (rx->rx_mbuf != NULL) {
338 		bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap,
339 		    BUS_DMASYNC_POSTREAD);
340 		bus_dmamap_unload(sc->rxbuf_dma_tag, rx->rx_dmamap);
341 	}
342 
343 	/* Save pointer to buffer structure */
344 	m_copyback(m, 0, 8, (void *)&rx);
345 
346 	error = bus_dmamap_load_mbuf_sg(sc->rxbuf_dma_tag, rx->rx_dmamap, m,
347 	    segs, &nsegs, BUS_DMA_NOWAIT);
348 	if (error != 0) {
349 		device_printf(sc->dev,
350 		    "cannot load RX DMA map %p, error = %d\n", rx, error);
351 		m_freem(m);
352 		return (error);
353 	}
354 
355 	/* If nsegs is wrong then the stack is corrupt. */
356 	KASSERT(nsegs == 1,
357 	    ("%s: too many DMA segments (%d)", __func__, nsegs));
358 	rx->rx_mbuf = m;
359 
360 	bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap, BUS_DMASYNC_PREREAD);
361 
362 	rx->rx_bufdesc = LLAN_BUFDESC_VALID;
363 	rx->rx_bufdesc |= (((uint64_t)segs[0].ds_len) << 32);
364 	rx->rx_bufdesc |= segs[0].ds_addr;
365 	error = phyp_hcall(H_ADD_LOGICAL_LAN_BUFFER, sc->unit, rx->rx_bufdesc);
366 	if (error != 0) {
367 		m_freem(m);
368 		rx->rx_mbuf = NULL;
369 		return (ENOBUFS);
370 	}
371 
372         return (0);
373 }
374 
375 static void
376 llan_intr(void *xsc)
377 {
378 	struct llan_softc *sc = xsc;
379 	struct llan_xfer *rx;
380 	struct mbuf *m;
381 
382 	mtx_lock(&sc->io_lock);
383 restart:
384 	phyp_hcall(H_VIO_SIGNAL, sc->unit, 0);
385 
386 	while ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val) {
387 		rx = (struct llan_xfer *)sc->rx_buf[sc->rx_dma_slot].handle;
388 		m = rx->rx_mbuf;
389 		m_adj(m, sc->rx_buf[sc->rx_dma_slot].offset - 8);
390 		m->m_len = sc->rx_buf[sc->rx_dma_slot].length;
391 
392 		/* llan_add_rxbuf does DMA sync and unload as well as requeue */
393 		if (llan_add_rxbuf(sc, rx) != 0) {
394 			if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
395 			continue;
396 		}
397 
398 		if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
399 		m_adj(m, sc->rx_buf[sc->rx_dma_slot].offset);
400 		m->m_len = sc->rx_buf[sc->rx_dma_slot].length;
401 		m->m_pkthdr.rcvif = sc->ifp;
402 		m->m_pkthdr.len = m->m_len;
403 		sc->rx_dma_slot++;
404 
405 		if (sc->rx_dma_slot >= sc->rx_buf_len/sizeof(sc->rx_buf[0])) {
406 			sc->rx_dma_slot = 0;
407 			sc->rx_valid_val = !sc->rx_valid_val;
408 		}
409 
410 		mtx_unlock(&sc->io_lock);
411 		if_input(sc->ifp, m);
412 		mtx_lock(&sc->io_lock);
413 	}
414 
415 	phyp_hcall(H_VIO_SIGNAL, sc->unit, 1);
416 
417 	/*
418 	 * H_VIO_SIGNAL enables interrupts for future packets only.
419 	 * Make sure none were queued between the end of the loop and the
420 	 * enable interrupts call.
421 	 */
422 	if ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val)
423 		goto restart;
424 
425 	mtx_unlock(&sc->io_lock);
426 }
427 
428 static void
429 llan_send_packet(void *xsc, bus_dma_segment_t *segs, int nsegs,
430     bus_size_t mapsize, int error)
431 {
432 	struct llan_softc *sc = xsc;
433 	uint64_t bufdescs[6];
434 	int i, err;
435 
436 	bzero(bufdescs, sizeof(bufdescs));
437 
438 	for (i = 0; i < nsegs; i++) {
439 		bufdescs[i] = LLAN_BUFDESC_VALID;
440 		bufdescs[i] |= (((uint64_t)segs[i].ds_len) << 32);
441 		bufdescs[i] |= segs[i].ds_addr;
442 	}
443 
444 	err = phyp_hcall(H_SEND_LOGICAL_LAN, sc->unit, bufdescs[0],
445 	    bufdescs[1], bufdescs[2], bufdescs[3], bufdescs[4], bufdescs[5], 0);
446 	/*
447 	 * The hypercall returning implies completion -- or that the call will
448 	 * not complete. In principle, we should try a few times if we get back
449 	 * H_BUSY based on the continuation token in R4. For now, just drop
450 	 * the packet in such cases.
451 	 */
452 	if (err == H_SUCCESS)
453 		if_inc_counter(sc->ifp, IFCOUNTER_OPACKETS, 1);
454 	else
455 		if_inc_counter(sc->ifp, IFCOUNTER_OERRORS, 1);
456 }
457 
458 static void
459 llan_start_locked(struct ifnet *ifp)
460 {
461 	struct llan_softc *sc = if_getsoftc(ifp);
462 	int nsegs;
463 	struct mbuf *mb_head, *m;
464 
465 	mtx_assert(&sc->io_lock, MA_OWNED);
466 
467 	if ((if_getdrvflags(ifp) & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
468 	    IFF_DRV_RUNNING)
469 		return;
470 
471 	while (!if_sendq_empty(ifp)) {
472 		mb_head = if_dequeue(ifp);
473 
474 		if (mb_head == NULL)
475 			break;
476 
477 		BPF_MTAP(ifp, mb_head);
478 
479 		for (m = mb_head, nsegs = 0; m != NULL; m = m->m_next)
480 			nsegs++;
481 		if (nsegs > 6) {
482 			m = m_collapse(mb_head, M_NOWAIT, 6);
483 			if (m == NULL) {
484 				m_freem(mb_head);
485 				continue;
486 			}
487 		}
488 
489 		bus_dmamap_load_mbuf(sc->tx_dma_tag, sc->tx_dma_map,
490 			mb_head, llan_send_packet, sc, 0);
491 		bus_dmamap_unload(sc->tx_dma_tag, sc->tx_dma_map);
492 		m_freem(mb_head);
493 	}
494 }
495 
496 static void
497 llan_start(struct ifnet *ifp)
498 {
499 	struct llan_softc *sc = if_getsoftc(ifp);
500 
501 	mtx_lock(&sc->io_lock);
502 	llan_start_locked(ifp);
503 	mtx_unlock(&sc->io_lock);
504 }
505 
506 static u_int
507 llan_set_maddr(void *arg, struct sockaddr_dl *sdl, u_int cnt)
508 {
509 	struct llan_softc *sc = arg;
510 	uint64_t macaddr = 0;
511 
512 	memcpy((uint8_t *)&macaddr + 2, LLADDR(sdl), 6);
513 	phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_ADD_MULTICAST, macaddr);
514 
515 	return (1);
516 }
517 
518 static int
519 llan_set_multicast(struct llan_softc *sc)
520 {
521 	struct ifnet *ifp = sc->ifp;
522 
523 	mtx_assert(&sc->io_lock, MA_OWNED);
524 
525 	phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_CLEAR_MULTICAST, 0);
526 
527 	if_foreach_llmaddr(ifp, llan_set_maddr, sc);
528 
529 	return (0);
530 }
531 
532 static int
533 llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
534 {
535 	int err = 0;
536 	struct llan_softc *sc = if_getsoftc(ifp);
537 
538 	switch (cmd) {
539 	case SIOCADDMULTI:
540 	case SIOCDELMULTI:
541 		mtx_lock(&sc->io_lock);
542 		if ((if_getdrvflags(sc->ifp) & IFF_DRV_RUNNING) != 0)
543 			llan_set_multicast(sc);
544 		mtx_unlock(&sc->io_lock);
545 		break;
546 	case SIOCGIFMEDIA:
547 	case SIOCSIFMEDIA:
548 		err = ifmedia_ioctl(ifp, (struct ifreq *)data, &sc->media, cmd);
549 		break;
550 	case SIOCSIFFLAGS:
551 	default:
552 		err = ether_ioctl(ifp, cmd, data);
553 		break;
554 	}
555 
556 	return (err);
557 }
558