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