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