xref: /freebsd/sys/powerpc/pseries/phyp_llan.c (revision 5b9c547c)
1 /*-
2  * Copyright 2013 Nathan Whitehorn
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  *
14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24  * SUCH DAMAGE.
25  */
26 
27 #include <sys/cdefs.h>
28 __FBSDID("$FreeBSD$");
29 
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 	int		irqid;
91 	struct resource	*irq;
92 	void		*irq_cookie;
93 
94 	bus_dma_tag_t	rx_dma_tag;
95 	bus_dma_tag_t	rxbuf_dma_tag;
96 	bus_dma_tag_t	tx_dma_tag;
97 
98 	bus_dmamap_t	tx_dma_map;
99 
100 	struct llan_receive_queue_entry *rx_buf;
101 	int		rx_dma_slot;
102 	int		rx_valid_val;
103 	bus_dmamap_t	rx_buf_map;
104 	bus_addr_t	rx_buf_phys;
105 	bus_size_t	rx_buf_len;
106 	bus_addr_t	input_buf_phys;
107 	bus_addr_t	filter_buf_phys;
108 	struct llan_xfer rx_xfer[LLAN_MAX_RX_PACKETS];
109 
110 	struct ifnet	*ifp;
111 };
112 
113 static int	llan_probe(device_t);
114 static int	llan_attach(device_t);
115 static void	llan_intr(void *xsc);
116 static void	llan_init(void *xsc);
117 static void	llan_start(struct ifnet *ifp);
118 static int	llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
119 static void	llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs,
120 		    int err);
121 static int	llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx);
122 static int	llan_set_multicast(struct llan_softc *sc);
123 
124 static devclass_t       llan_devclass;
125 static device_method_t  llan_methods[] = {
126         DEVMETHOD(device_probe,         llan_probe),
127         DEVMETHOD(device_attach,        llan_attach),
128 
129         DEVMETHOD_END
130 };
131 static driver_t llan_driver = {
132         "llan",
133         llan_methods,
134         sizeof(struct llan_softc)
135 };
136 DRIVER_MODULE(llan, vdevice, llan_driver, llan_devclass, 0, 0);
137 
138 static int
139 llan_probe(device_t dev)
140 {
141 	if (!ofw_bus_is_compatible(dev,"IBM,l-lan"))
142 		return (ENXIO);
143 
144 	device_set_desc(dev, "POWER Hypervisor Virtual Ethernet");
145 	return (0);
146 }
147 
148 static int
149 llan_attach(device_t dev)
150 {
151 	struct llan_softc *sc;
152 	phandle_t node;
153 	int error, i;
154 
155 	sc = device_get_softc(dev);
156 	sc->dev = dev;
157 
158 	/* Get firmware properties */
159 	node = ofw_bus_get_node(dev);
160 	OF_getprop(node, "local-mac-address", sc->mac_address,
161 	    sizeof(sc->mac_address));
162 	OF_getprop(node, "reg", &sc->unit, sizeof(sc->unit));
163 
164 	mtx_init(&sc->io_lock, "llan", NULL, MTX_DEF);
165 
166         /* Setup interrupt */
167 	sc->irqid = 0;
168 	sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irqid,
169 	    RF_ACTIVE);
170 
171 	if (!sc->irq) {
172 		device_printf(dev, "Could not allocate IRQ\n");
173 		mtx_destroy(&sc->io_lock);
174 		return (ENXIO);
175 	}
176 
177 	bus_setup_intr(dev, sc->irq, INTR_TYPE_MISC | INTR_MPSAFE |
178 	    INTR_ENTROPY, NULL, llan_intr, sc, &sc->irq_cookie);
179 
180 	/* Setup DMA */
181 	error = bus_dma_tag_create(bus_get_dma_tag(dev), 16, 0,
182             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
183 	    LLAN_RX_BUF_LEN, 1, BUS_SPACE_MAXSIZE_32BIT,
184 	    0, NULL, NULL, &sc->rx_dma_tag);
185 	error = bus_dma_tag_create(bus_get_dma_tag(dev), 4, 0,
186             BUS_SPACE_MAXADDR, BUS_SPACE_MAXADDR, NULL, NULL,
187 	    BUS_SPACE_MAXSIZE, 1, BUS_SPACE_MAXSIZE_32BIT,
188 	    0, NULL, NULL, &sc->rxbuf_dma_tag);
189 	error = bus_dma_tag_create(bus_get_dma_tag(dev), 1, 0,
190             BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
191 	    BUS_SPACE_MAXSIZE, 6, BUS_SPACE_MAXSIZE_32BIT, 0,
192 	    busdma_lock_mutex, &sc->io_lock, &sc->tx_dma_tag);
193 
194 	error = bus_dmamem_alloc(sc->rx_dma_tag, (void **)&sc->rx_buf,
195 	    BUS_DMA_WAITOK | BUS_DMA_ZERO, &sc->rx_buf_map);
196 	error = bus_dmamap_load(sc->rx_dma_tag, sc->rx_buf_map, sc->rx_buf,
197 	    LLAN_RX_BUF_LEN, llan_rx_load_cb, sc, 0);
198 
199 	/* TX DMA maps */
200 	bus_dmamap_create(sc->tx_dma_tag, 0, &sc->tx_dma_map);
201 
202 	/* RX DMA */
203 	for (i = 0; i < LLAN_MAX_RX_PACKETS; i++) {
204 		error = bus_dmamap_create(sc->rxbuf_dma_tag, 0,
205 		    &sc->rx_xfer[i].rx_dmamap);
206 		sc->rx_xfer[i].rx_mbuf = NULL;
207 	}
208 
209 	/* Attach to network stack */
210 	sc->ifp = if_alloc(IFT_ETHER);
211 	sc->ifp->if_softc = sc;
212 
213 	if_initname(sc->ifp, device_get_name(dev), device_get_unit(dev));
214 	sc->ifp->if_mtu = ETHERMTU; /* XXX max-frame-size from OF? */
215 	sc->ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
216 	sc->ifp->if_hwassist = 0; /* XXX: ibm,illan-options */
217 	sc->ifp->if_capabilities = 0;
218 	sc->ifp->if_capenable = 0;
219 	sc->ifp->if_start = llan_start;
220 	sc->ifp->if_ioctl = llan_ioctl;
221 	sc->ifp->if_init = llan_init;
222 
223 	IFQ_SET_MAXLEN(&sc->ifp->if_snd, LLAN_MAX_TX_PACKETS);
224 	sc->ifp->if_snd.ifq_drv_maxlen = LLAN_MAX_TX_PACKETS;
225 	IFQ_SET_READY(&sc->ifp->if_snd);
226 
227 	ether_ifattach(sc->ifp, &sc->mac_address[2]);
228 
229 	return (0);
230 }
231 
232 static void
233 llan_rx_load_cb(void *xsc, bus_dma_segment_t *segs, int nsegs, int err)
234 {
235 	struct llan_softc *sc = xsc;
236 
237 	sc->rx_buf_phys = segs[0].ds_addr;
238 	sc->rx_buf_len = segs[0].ds_len - 2*PAGE_SIZE;
239 	sc->input_buf_phys = segs[0].ds_addr + segs[0].ds_len - PAGE_SIZE;
240 	sc->filter_buf_phys = segs[0].ds_addr + segs[0].ds_len - 2*PAGE_SIZE;
241 }
242 
243 static void
244 llan_init(void *xsc)
245 {
246 	struct llan_softc *sc = xsc;
247 	uint64_t rx_buf_desc;
248 	uint64_t macaddr;
249 	int err, i;
250 
251 	mtx_lock(&sc->io_lock);
252 
253 	phyp_hcall(H_FREE_LOGICAL_LAN, sc->unit);
254 
255 	/* Create buffers (page 539) */
256 	sc->rx_dma_slot = 0;
257 	sc->rx_valid_val = 1;
258 
259 	rx_buf_desc = LLAN_BUFDESC_VALID;
260 	rx_buf_desc |= (sc->rx_buf_len << 32);
261 	rx_buf_desc |= sc->rx_buf_phys;
262 	memcpy(&macaddr, sc->mac_address, 8);
263 	err = phyp_hcall(H_REGISTER_LOGICAL_LAN, sc->unit, sc->input_buf_phys,
264 	    rx_buf_desc, sc->filter_buf_phys, macaddr);
265 
266 	for (i = 0; i < LLAN_MAX_RX_PACKETS; i++)
267 		llan_add_rxbuf(sc, &sc->rx_xfer[i]);
268 
269 	phyp_hcall(H_VIO_SIGNAL, sc->unit, 1); /* Enable interrupts */
270 
271 	/* Tell stack we're up */
272 	sc->ifp->if_drv_flags |= IFF_DRV_RUNNING;
273 	sc->ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
274 
275 	mtx_unlock(&sc->io_lock);
276 
277 	/* Check for pending receives scheduled before interrupt enable */
278 	llan_intr(sc);
279 }
280 
281 static int
282 llan_add_rxbuf(struct llan_softc *sc, struct llan_xfer *rx)
283 {
284 	struct mbuf *m;
285 	bus_dma_segment_t segs[1];
286 	int error, nsegs;
287 
288 	mtx_assert(&sc->io_lock, MA_OWNED);
289 
290 	m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
291 	if (m == NULL)
292 		return (ENOBUFS);
293 
294 	m->m_len = m->m_pkthdr.len = m->m_ext.ext_size;
295 	if (rx->rx_mbuf != NULL) {
296 		bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap,
297 		    BUS_DMASYNC_POSTREAD);
298 		bus_dmamap_unload(sc->rxbuf_dma_tag, rx->rx_dmamap);
299 	}
300 
301 	/* Save pointer to buffer structure */
302 	m_copyback(m, 0, 8, (void *)&rx);
303 
304 	error = bus_dmamap_load_mbuf_sg(sc->rxbuf_dma_tag, rx->rx_dmamap, m,
305 	    segs, &nsegs, BUS_DMA_NOWAIT);
306 	if (error != 0) {
307 		device_printf(sc->dev,
308 		    "cannot load RX DMA map %p, error = %d\n", rx, error);
309 		m_freem(m);
310 		return (error);
311 	}
312 
313 	/* If nsegs is wrong then the stack is corrupt. */
314 	KASSERT(nsegs == 1,
315 	    ("%s: too many DMA segments (%d)", __func__, nsegs));
316 	rx->rx_mbuf = m;
317 
318 	bus_dmamap_sync(sc->rxbuf_dma_tag, rx->rx_dmamap, BUS_DMASYNC_PREREAD);
319 
320 	rx->rx_bufdesc = LLAN_BUFDESC_VALID;
321 	rx->rx_bufdesc |= (((uint64_t)segs[0].ds_len) << 32);
322 	rx->rx_bufdesc |= segs[0].ds_addr;
323 	error = phyp_hcall(H_ADD_LOGICAL_LAN_BUFFER, sc->unit, rx->rx_bufdesc);
324 	if (error != 0) {
325 		m_freem(m);
326 		rx->rx_mbuf = NULL;
327 		return (ENOBUFS);
328 	}
329 
330         return (0);
331 }
332 
333 static void
334 llan_intr(void *xsc)
335 {
336 	struct llan_softc *sc = xsc;
337 	struct llan_xfer *rx;
338 	struct mbuf *m;
339 
340 	mtx_lock(&sc->io_lock);
341 restart:
342 	phyp_hcall(H_VIO_SIGNAL, sc->unit, 0);
343 
344 	while ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val) {
345 		rx = (struct llan_xfer *)sc->rx_buf[sc->rx_dma_slot].handle;
346 		m = rx->rx_mbuf;
347 		m_adj(m, sc->rx_buf[sc->rx_dma_slot].offset - 8);
348 		m->m_len = sc->rx_buf[sc->rx_dma_slot].length;
349 
350 		/* llan_add_rxbuf does DMA sync and unload as well as requeue */
351 		if (llan_add_rxbuf(sc, rx) != 0) {
352 			if_inc_counter(sc->ifp, IFCOUNTER_IERRORS, 1);
353 			phyp_hcall(H_ADD_LOGICAL_LAN_BUFFER, sc->unit,
354 			    rx->rx_bufdesc);
355 			continue;
356 		}
357 
358 		if_inc_counter(sc->ifp, IFCOUNTER_IPACKETS, 1);
359 		m_adj(m, sc->rx_buf[sc->rx_dma_slot].offset);
360 		m->m_len = sc->rx_buf[sc->rx_dma_slot].length;
361 		m->m_pkthdr.rcvif = sc->ifp;
362 		m->m_pkthdr.len = m->m_len;
363 		sc->rx_dma_slot++;
364 
365 		if (sc->rx_dma_slot >= sc->rx_buf_len/sizeof(sc->rx_buf[0])) {
366 			sc->rx_dma_slot = 0;
367 			sc->rx_valid_val = !sc->rx_valid_val;
368 		}
369 
370 		mtx_unlock(&sc->io_lock);
371 		(*sc->ifp->if_input)(sc->ifp, m);
372 		mtx_lock(&sc->io_lock);
373 	}
374 
375 	phyp_hcall(H_VIO_SIGNAL, sc->unit, 1);
376 
377 	/*
378 	 * H_VIO_SIGNAL enables interrupts for future packets only.
379 	 * Make sure none were queued between the end of the loop and the
380 	 * enable interrupts call.
381 	 */
382 	if ((sc->rx_buf[sc->rx_dma_slot].control >> 7) == sc->rx_valid_val)
383 		goto restart;
384 
385 	mtx_unlock(&sc->io_lock);
386 }
387 
388 static void
389 llan_send_packet(void *xsc, bus_dma_segment_t *segs, int nsegs,
390     bus_size_t mapsize, int error)
391 {
392 	struct llan_softc *sc = xsc;
393 	uint64_t bufdescs[6];
394 	int i;
395 
396 	bzero(bufdescs, sizeof(bufdescs));
397 
398 	for (i = 0; i < nsegs; i++) {
399 		bufdescs[i] = LLAN_BUFDESC_VALID;
400 		bufdescs[i] |= (((uint64_t)segs[i].ds_len) << 32);
401 		bufdescs[i] |= segs[i].ds_addr;
402 	}
403 
404 	phyp_hcall(H_SEND_LOGICAL_LAN, sc->unit, bufdescs[0],
405 	    bufdescs[1], bufdescs[2], bufdescs[3], bufdescs[4], bufdescs[5], 0);
406 	/*
407 	 * The hypercall returning implies completion -- or that the call will
408 	 * not complete. In principle, we should try a few times if we get back
409 	 * H_BUSY based on the continuation token in R4. For now, just drop
410 	 * the packet in such cases.
411 	 */
412 }
413 
414 static void
415 llan_start_locked(struct ifnet *ifp)
416 {
417 	struct llan_softc *sc = ifp->if_softc;
418 	bus_addr_t first;
419 	int nsegs;
420 	struct mbuf *mb_head, *m;
421 
422 	mtx_assert(&sc->io_lock, MA_OWNED);
423 	first = 0;
424 
425 	if ((ifp->if_drv_flags & (IFF_DRV_RUNNING | IFF_DRV_OACTIVE)) !=
426 	    IFF_DRV_RUNNING)
427 		return;
428 
429 	while (!IFQ_DRV_IS_EMPTY(&ifp->if_snd)) {
430 		IFQ_DRV_DEQUEUE(&ifp->if_snd, mb_head);
431 
432 		if (mb_head == NULL)
433 			break;
434 
435 		BPF_MTAP(ifp, mb_head);
436 
437 		for (m = mb_head, nsegs = 0; m != NULL; m = m->m_next)
438 			nsegs++;
439 		if (nsegs > 6) {
440 			m = m_collapse(mb_head, M_NOWAIT, 6);
441 			if (m == NULL) {
442 				m_freem(mb_head);
443 				continue;
444 			}
445 		}
446 
447 		bus_dmamap_load_mbuf(sc->tx_dma_tag, sc->tx_dma_map,
448 			mb_head, llan_send_packet, sc, 0);
449 		bus_dmamap_unload(sc->tx_dma_tag, sc->tx_dma_map);
450 		m_freem(mb_head);
451 	}
452 }
453 
454 static void
455 llan_start(struct ifnet *ifp)
456 {
457 	struct llan_softc *sc = ifp->if_softc;
458 
459 	mtx_lock(&sc->io_lock);
460 	llan_start_locked(ifp);
461 	mtx_unlock(&sc->io_lock);
462 }
463 
464 static int
465 llan_set_multicast(struct llan_softc *sc)
466 {
467 	struct ifnet *ifp = sc->ifp;
468 	struct ifmultiaddr *inm;
469 	uint64_t macaddr;
470 
471 	mtx_assert(&sc->io_lock, MA_OWNED);
472 
473 	phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_CLEAR_MULTICAST, 0);
474 
475 	if_maddr_rlock(ifp);
476 	TAILQ_FOREACH(inm, &ifp->if_multiaddrs, ifma_link) {
477 		if (inm->ifma_addr->sa_family != AF_LINK)
478 			continue;
479 
480 		memcpy((uint8_t *)&macaddr + 2,
481 		    LLADDR((struct sockaddr_dl *)inm->ifma_addr), 6);
482 		phyp_hcall(H_MULTICAST_CTRL, sc->unit, LLAN_ADD_MULTICAST,
483 		    macaddr);
484 	}
485 	if_maddr_runlock(ifp);
486 
487 	return (0);
488 }
489 
490 static int
491 llan_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
492 {
493 	int err = 0;
494 	struct llan_softc *sc = ifp->if_softc;
495 
496 	switch (cmd) {
497 	case SIOCADDMULTI:
498 	case SIOCDELMULTI:
499 		mtx_lock(&sc->io_lock);
500 		if ((sc->ifp->if_drv_flags & IFF_DRV_RUNNING) != 0)
501 			llan_set_multicast(sc);
502 		mtx_unlock(&sc->io_lock);
503 		break;
504 	case SIOCSIFFLAGS:
505 	default:
506 		err = ether_ioctl(ifp, cmd, data);
507 		break;
508 	}
509 
510 	return (err);
511 }
512 
513