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