source: rtems/bsps/powerpc/beatnik/net/if_gfe/if_gfe.c @ 031df391

5
Last change on this file since 031df391 was 031df391, checked in by Sebastian Huber <sebastian.huber@…>, on 04/23/18 at 07:53:31

bsps: Move legacy network drivers to bsps

This patch is a part of the BSP source reorganization.

Update #3285.

  • Property mode set to 100644
File size: 66.5 KB
RevLine 
[b7a6d23a]1/*      $NetBSD: if_gfe.c,v 1.13.8.1 2005/04/29 11:28:56 kent Exp $     */
2
3/*
4 * Copyright (c) 2002 Allegro Networks, Inc., Wasabi Systems, Inc.
5 * All rights reserved.
6 *
7 * Copyright 2004: Enable hardware cache snooping. Kate Feng <feng1@bnl.gov>
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 *    notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 *    notice, this list of conditions and the following disclaimer in the
16 *    documentation and/or other materials provided with the distribution.
17 * 3. All advertising materials mentioning features or use of this software
18 *    must display the following acknowledgement:
19 *      This product includes software developed for the NetBSD Project by
20 *      Allegro Networks, Inc., and Wasabi Systems, Inc.
21 * 4. The name of Allegro Networks, Inc. may not be used to endorse
22 *    or promote products derived from this software without specific prior
23 *    written permission.
24 * 5. The name of Wasabi Systems, Inc. may not be used to endorse
25 *    or promote products derived from this software without specific prior
26 *    written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY ALLEGRO NETWORKS, INC. AND
29 * WASABI SYSTEMS, INC. ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
32 * IN NO EVENT SHALL EITHER ALLEGRO NETWORKS, INC. OR WASABI SYSTEMS, INC.
33 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
34 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
35 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
36 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
37 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
38 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
39 * POSSIBILITY OF SUCH DAMAGE.
40 */
41
42/*
43 * if_gfe.c -- GT ethernet MAC driver
44 */
45
46/* Enable hardware cache snooping;
47 * Copyright Shuchen K. Feng <feng1@bnl.gov>, 2004
48 */
49
50#ifdef __rtems__
[efb893f]51#include "rtemscompat_defs.h"
52#include "../porting/rtemscompat.h"
[b7a6d23a]53#include <string.h>
54#include <stdio.h>
55#include <inttypes.h>
56#endif
57
58#include <sys/cdefs.h>
59#ifndef __rtems__
60__KERNEL_RCSID(0, "$NetBSD: if_gfe.c,v 1.13.8.1 2005/04/29 11:28:56 kent Exp $");
61
62#include "opt_inet.h"
63#include "bpfilter.h"
64#endif
65
66#include <sys/param.h>
67#include <sys/types.h>
68#ifndef __rtems__
69#include <sys/inttypes.h>
70#include <sys/queue.h>
71#endif
72
73#ifndef __rtems__
74#include <uvm/uvm_extern.h>
75
76#include <sys/callout.h>
77#include <sys/device.h>
78#endif
79#include <sys/errno.h>
80#include <sys/mbuf.h>
81#include <sys/socket.h>
[787f51f]82#include <sys/sockio.h>
[b7a6d23a]83
84#ifndef __rtems__
85#include <machine/bus.h>
86#endif
87
88#include <net/if.h>
89#include <net/if_dl.h>
90#include <net/if_media.h>
91#ifndef __rtems__
92#include <net/if_ether.h>
93#else
94#include <netinet/in.h>
95#include <netinet/if_ether.h>
96#include <net/ethernet.h>
97#include <rtems/rtems_mii_ioctl.h>
98#endif
99
100#ifdef INET
101#include <netinet/in.h>
102#ifndef __rtems__
103#include <netinet/if_inarp.h>
104#endif
105#endif
106#if NBPFILTER > 0
107#include <net/bpf.h>
108#endif
109
110#ifndef __rtems__
111#include <dev/mii/miivar.h>
112
113#include <dev/marvell/gtintrreg.h>
114#include <dev/marvell/gtethreg.h>
115
116#include <dev/marvell/gtvar.h>
117#include <dev/marvell/if_gfevar.h>
118#else
119#include        <bsp/gtintrreg.h>
120#include        <bsp/gtreg.h>
121#include        "gtethreg.h"
122
123#include        "gtvar.h"
124#include        "if_gfevar.h"
[efb893f]125#include        "../porting/rtemscompat1.h"
[b7a6d23a]126#define         ether_sprintf ether_sprintf_macro
127#endif
128
129#define GE_READ(sc, reg) \
130        bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg)
131#define GE_WRITE(sc, reg, v) \
132        bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_memh, ETH__ ## reg, (v))
133
134#define GT_READ(sc, reg) \
135        bus_space_read_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg)
136#define GT_WRITE(sc, reg, v) \
137        bus_space_write_4((sc)->sc_gt_memt, (sc)->sc_gt_memh, reg, (v))
138
139#define GE_DEBUG
140#if 0
141#define GE_NOHASH
142#define GE_NORX
143#endif
144
145#ifdef GE_DEBUG
146#define GE_DPRINTF(sc, a)       do \
147                                  if ((sc)->sc_ec.ec_if.if_flags & IFF_DEBUG) \
148                                    printf a; \
149                                while (0)
150#define GE_FUNC_ENTER(sc, func) GE_DPRINTF(sc, ("[" func))
151#define GE_FUNC_EXIT(sc, str)   GE_DPRINTF(sc, (str "]"))
152#else
153#define GE_DPRINTF(sc, a)       do { } while (0)
154#define GE_FUNC_ENTER(sc, func) do { } while (0)
155#define GE_FUNC_EXIT(sc, str)   do { } while (0)
156#endif
157enum gfe_whack_op {
158        GE_WHACK_START,         GE_WHACK_RESTART,
159        GE_WHACK_CHANGE,        GE_WHACK_STOP
160};
161
162enum gfe_hash_op {
163        GE_HASH_ADD,            GE_HASH_REMOVE,
164};
165
166
167#if 1
168#define htogt32(a)              htobe32(a)
169#define gt32toh(a)              be32toh(a)
170#else
171#define htogt32(a)              htole32(a)
172#define gt32toh(a)              le32toh(a)
173#endif
174
175#ifdef __rtems__
176#define htobe32 htonl
177#define be32toh ntohl
178#endif
179
180#define GE_RXDSYNC(sc, rxq, n, ops) \
181        bus_dmamap_sync((sc)->sc_dmat, (rxq)->rxq_desc_mem.gdm_map, \
182            (n) * sizeof((rxq)->rxq_descs[0]), sizeof((rxq)->rxq_descs[0]), \
183            (ops))
184#define GE_RXDPRESYNC(sc, rxq, n) \
185        GE_RXDSYNC(sc, rxq, n, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
186#define GE_RXDPOSTSYNC(sc, rxq, n) \
187        GE_RXDSYNC(sc, rxq, n, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
188
189#define GE_TXDSYNC(sc, txq, n, ops) \
190        bus_dmamap_sync((sc)->sc_dmat, (txq)->txq_desc_mem.gdm_map, \
191            (n) * sizeof((txq)->txq_descs[0]), sizeof((txq)->txq_descs[0]), \
192            (ops))
193#define GE_TXDPRESYNC(sc, txq, n) \
194        GE_TXDSYNC(sc, txq, n, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE)
195#define GE_TXDPOSTSYNC(sc, txq, n) \
196        GE_TXDSYNC(sc, txq, n, BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE)
197
198#define STATIC
199
200#ifndef __rtems__
201STATIC int gfe_match (struct device *, struct cfdata *, void *);
202STATIC void gfe_attach (struct device *, struct device *, void *);
203#else
204STATIC int gfe_probe (device_t);
205STATIC int gfe_attach (device_t);
206STATIC void gfe_init (void*);
207#endif
208
209STATIC int gfe_dmamem_alloc(struct gfe_softc *, struct gfe_dmamem *, int,
210        size_t, int);
211STATIC void gfe_dmamem_free(struct gfe_softc *, struct gfe_dmamem *);
212
213#ifndef __rtems__
214STATIC int gfe_ifioctl (struct ifnet *, u_long, caddr_t);
215#else
216STATIC int gfe_ifioctl (struct ifnet *, ioctl_command_t, caddr_t);
217#endif
218STATIC void gfe_ifstart (struct ifnet *);
219STATIC void gfe_ifwatchdog (struct ifnet *);
220
221#ifndef __rtems__
222STATIC int gfe_mii_mediachange (struct ifnet *);
223STATIC void gfe_mii_mediastatus (struct ifnet *, struct ifmediareq *);
224STATIC int gfe_mii_read (struct device *, int, int);
225STATIC void gfe_mii_write (struct device *, int, int, int);
226STATIC void gfe_mii_statchg (struct device *);
227#endif
228
229STATIC void gfe_tick(void *arg);
230
231STATIC void gfe_tx_restart(void *);
232STATIC int gfe_tx_enqueue(struct gfe_softc *, enum gfe_txprio);
233STATIC uint32_t gfe_tx_done(struct gfe_softc *, enum gfe_txprio, uint32_t);
234STATIC void gfe_tx_cleanup(struct gfe_softc *, enum gfe_txprio, int);
235STATIC int gfe_tx_txqalloc(struct gfe_softc *, enum gfe_txprio);
236STATIC int gfe_tx_start(struct gfe_softc *, enum gfe_txprio);
237STATIC void gfe_tx_stop(struct gfe_softc *, enum gfe_whack_op);
238
239STATIC void gfe_rx_cleanup(struct gfe_softc *, enum gfe_rxprio);
240STATIC void gfe_rx_get(struct gfe_softc *, enum gfe_rxprio);
241STATIC int gfe_rx_prime(struct gfe_softc *);
242STATIC uint32_t gfe_rx_process(struct gfe_softc *, uint32_t, uint32_t);
243STATIC int gfe_rx_rxqalloc(struct gfe_softc *, enum gfe_rxprio);
244STATIC int gfe_rx_rxqinit(struct gfe_softc *, enum gfe_rxprio);
245STATIC void gfe_rx_stop(struct gfe_softc *, enum gfe_whack_op);
246
247STATIC int gfe_intr(void *);
248
249STATIC int gfe_whack(struct gfe_softc *, enum gfe_whack_op);
250
251STATIC int gfe_hash_compute(struct gfe_softc *, const uint8_t [ETHER_ADDR_LEN]);
252STATIC int gfe_hash_entry_op(struct gfe_softc *, enum gfe_hash_op,
253        enum gfe_rxprio, const uint8_t [ETHER_ADDR_LEN]);
254#ifndef __rtems__
255STATIC int gfe_hash_multichg(struct ethercom *, const struct ether_multi *,
256        u_long);
257#endif
258STATIC int gfe_hash_fill(struct gfe_softc *);
259STATIC int gfe_hash_alloc(struct gfe_softc *);
260
261#ifndef __rtems__
262/* Linkup to the rest of the kernel */
263CFATTACH_DECL(gfe, sizeof(struct gfe_softc),
264    gfe_match, gfe_attach, NULL, NULL);
265#else
266net_drv_tbl_t METHODS = {
267    n_probe  : gfe_probe,
268    n_attach : gfe_attach,
269    n_detach : 0,
270    n_intr   : (void (*)(void*))gfe_intr,
271};
272
273int
274gfe_mii_read(int phy, void *arg, unsigned reg, uint32_t *pval);
275int
276gfe_mii_write(int phy, void *arg, unsigned reg, uint32_t val);
277
278struct rtems_mdio_info
279gfe_mdio_access = {
280        mdio_r: gfe_mii_read,
281        mdio_w: gfe_mii_write,
282        has_gmii: 0
283};
284
285#endif
286
287extern struct cfdriver gfe_cd;
288
289#ifndef __rtems__
290int
291gfe_match(struct device *parent, struct cfdata *cf, void *aux)
292{
293        struct gt_softc *gt = (struct gt_softc *) parent;
294        struct gt_attach_args *ga = aux;
295        uint8_t enaddr[6];
296
297        if (!GT_ETHEROK(gt, ga, &gfe_cd))
298                return 0;
299
300        if (gtget_macaddr(gt, ga->ga_unit, enaddr) < 0)
301                return 0;
302
303        if (enaddr[0] == 0 && enaddr[1] == 0 && enaddr[2] == 0 &&
304            enaddr[3] == 0 && enaddr[4] == 0 && enaddr[5] == 0)
305                return 0;
306
307        return 1;
308}
309#else
310int
311gfe_probe(device_t dev)
312{
313        switch ( BSP_getDiscoveryVersion(0) ) {
314                case GT_64260_A:
315                case GT_64260_B:
316                        return 0;
317                default:
318                        break;
319        }
320        return -1;
321}
322
323void
324gfe_init(void *arg)
325{
326struct gfe_softc *sc = arg;
327        if ( sc->sc_ec.ec_if.if_flags & IFF_RUNNING )
328                gfe_whack(sc, GE_WHACK_RESTART);
329        else
330                gfe_whack(sc, GE_WHACK_START);
331}
332#endif
333
334/*
335 * Attach this instance, and then all the sub-devices
336 */
337#ifndef __rtems__
338void
339gfe_attach(struct device *parent, struct device *self, void *aux)
340#else
341int
342gfe_attach(device_t dev)
343#endif
344{
345#ifndef __rtems__
346        struct gt_attach_args * const ga = aux;
347        struct gt_softc * const gt = (struct gt_softc *) parent;
348        struct gfe_softc * const sc = (struct gfe_softc *) self;
349#else
350        struct gfe_softc * const sc = device_get_softc(dev);
351#endif
352        struct ifnet * const ifp = &sc->sc_ec.ec_if;
353        uint32_t data;
354        uint8_t enaddr[6];
355        int phyaddr;
356        uint32_t sdcr;
357        int error;
358#ifdef __rtems__
359        SPRINTFVARDECL;
360#endif
361
362#ifndef __rtems__
363        GT_ETHERFOUND(gt, ga);
364
365        sc->sc_gt_memt = ga->ga_memt;
366        sc->sc_gt_memh = ga->ga_memh;
367        sc->sc_dmat = ga->ga_dmat;
368        sc->sc_macno = ga->ga_unit;
369
370        if (bus_space_subregion(sc->sc_gt_memt, sc->sc_gt_memh,
371                    ETH_BASE(sc->sc_macno), ETH_SIZE, &sc->sc_memh)) {
372                aprint_error(": failed to map registers\n");
373        }
374       
375        callout_init(&sc->sc_co);
376#else
377        /* sc_macno, irq_no and sc_gt_memh must be filled in by 'setup' */
378
379        /* make ring sizes even numbers so that we have always multiple
380         * cache lines (paranoia)
381         */
382        if ( (sc->num_rxdesc = dev->d_ifconfig->rbuf_count) & 1 )
383                sc->num_rxdesc++;
384        if ( 0 == sc->num_rxdesc )
385                sc->num_rxdesc = 64;
386
387        if ( (sc->num_txdesc = dev->d_ifconfig->xbuf_count) & 1 )
388                sc->num_txdesc++;
389        if ( 0 == sc->num_txdesc )
390                sc->num_txdesc = 256;
391
392        /* Enable hardware cache snooping;
393         * Copyright Shuchen K. Feng <feng1@bnl.gov>, 2004
394         */
395        /* regs are eth0: 0xf200/0xf204, eth1 0xf220/0xf224, eth2: 0xf240/0xf244 */
396        {
397        uint32_t v;
398        v = GT_READ(sc, ETH_ACTL_0_LO + (sc->sc_macno<<5));
399        v |= RxBSnoopEn|TxBSnoopEn|RxDSnoopEn|TxDSnoopEn;
400        GT_WRITE(sc, ETH_ACTL_0_LO + (sc->sc_macno<<5), v);
401
402        v = GT_READ(sc, ETH_ACTL_0_HI + (sc->sc_macno<<5));
403        v |= HashSnoopEn;
404        GT_WRITE(sc, ETH_ACTL_0_HI + (sc->sc_macno<<5), v);
405        }
406
407#endif
408
409        data = bus_space_read_4(sc->sc_gt_memt, sc->sc_gt_memh, ETH_EPAR);
410#ifdef __rtems__
411        sc->sc_phyaddr =
412#endif
413        phyaddr = ETH_EPAR_PhyAD_GET(data, sc->sc_macno);
414
415#ifndef __rtems__
416        gtget_macaddr(gt, sc->sc_macno, enaddr);
417#else
418        memset( enaddr, 0, ETHER_ADDR_LEN );
419        if ( !memcmp(enaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN) ) {
420                aprint_error(": MAC address not set (pass to rtems_gfe_setup())\n");
421                return -1;
422        }
423        /* mac address needs to be provided by 'setup' */
424        memcpy(enaddr, sc->arpcom.ac_enaddr, ETHER_ADDR_LEN);
425#endif
426
427        sc->sc_pcr = GE_READ(sc, EPCR);
428        sc->sc_pcxr = GE_READ(sc, EPCXR);
429        sc->sc_intrmask = GE_READ(sc, EIMR) | ETH_IR_MIIPhySTC;
430
431        aprint_normal(": address %s", ether_sprintf(enaddr));
432
433#if defined(DEBUG)
434        aprint_normal(", pcr %#x, pcxr %#x", sc->sc_pcr, sc->sc_pcxr);
435#endif
436
437        sc->sc_pcxr &= ~ETH_EPCXR_PRIOrx_Override;
438#ifndef __rtems__
439        if (sc->sc_dev.dv_cfdata->cf_flags & 1) {
440                aprint_normal(", phy %d (rmii)", phyaddr);
441                sc->sc_pcxr |= ETH_EPCXR_RMIIEn;
442        } else
443#endif
444        {
445                aprint_normal(", phy %d (mii)", phyaddr);
446                sc->sc_pcxr &= ~ETH_EPCXR_RMIIEn;
447        }
448#ifndef __rtems__
449        if (sc->sc_dev.dv_cfdata->cf_flags & 2)
450                sc->sc_flags |= GE_NOFREE;
451#endif
452        sc->sc_pcxr &= ~(3 << 14);
453        sc->sc_pcxr |= (ETH_EPCXR_MFL_1536 << 14);
454
455        if (sc->sc_pcr & ETH_EPCR_EN) {
456                int tries = 1000;
457                /*
458                 * Abort transmitter and receiver and wait for them to quiese
459                 */
460                GE_WRITE(sc, ESDCMR, ETH_ESDCMR_AR|ETH_ESDCMR_AT);
461                do {
462                        delay(100);
463                } while (tries-- > 0 && (GE_READ(sc, ESDCMR) & (ETH_ESDCMR_AR|ETH_ESDCMR_AT)));
464        }
465
466        sc->sc_pcr &= ~(ETH_EPCR_EN | ETH_EPCR_RBM | ETH_EPCR_PM | ETH_EPCR_PBF);
467
468#if defined(DEBUG)
469        aprint_normal(", pcr %#x, pcxr %#x", sc->sc_pcr, sc->sc_pcxr);
470#endif
471
472        /*
473         * Now turn off the GT.  If it didn't quiese, too ***ing bad.
474         */
475        GE_WRITE(sc, EPCR, sc->sc_pcr);
476#ifndef __rtems__
477        GE_WRITE(sc, EIMR, sc->sc_intrmask);
478#else
479        GE_WRITE(sc, EICR, 0);
480        GE_WRITE(sc, EIMR, 0);
481#endif
482        sdcr = GE_READ(sc, ESDCR);
483        ETH_ESDCR_BSZ_SET(sdcr, ETH_ESDCR_BSZ_4);
484        sdcr |= ETH_ESDCR_RIFB;
485        GE_WRITE(sc, ESDCR, sdcr);
486        sc->sc_max_frame_length = 1536;
487
488        aprint_normal("\n");
489#ifndef __rtems__
490        sc->sc_mii.mii_ifp = ifp;
491        sc->sc_mii.mii_readreg = gfe_mii_read;
492        sc->sc_mii.mii_writereg = gfe_mii_write;
493        sc->sc_mii.mii_statchg = gfe_mii_statchg;
494
495        ifmedia_init(&sc->sc_mii.mii_media, 0, gfe_mii_mediachange,
496                gfe_mii_mediastatus);
497
498        mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, phyaddr,
499                MII_OFFSET_ANY, MIIF_NOISOLATE);
500        if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) {
501                ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL);
502                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE);
503        } else {
504                ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO);
505        }
506
507        strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
508#else
509        if_initname(ifp, device_get_name(dev), device_get_unit(dev));
510        ifp->if_mtu   = ETHERMTU;
511        ifp->if_output = ether_output;
512        ifp->if_init   = gfe_init;
513        ifp->if_snd.ifq_maxlen = GE_TXDESC_MAX - 1;
514        ifp->if_baudrate = 10000000;
515#endif
516        ifp->if_softc = sc;
517        /* ifp->if_mowner = &sc->sc_mowner; */
518        ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
519#if 0
520        ifp->if_flags |= IFF_DEBUG;
521#endif
522        ifp->if_ioctl = gfe_ifioctl;
523        ifp->if_start = gfe_ifstart;
524        ifp->if_watchdog = gfe_ifwatchdog;
525
526        if (sc->sc_flags & GE_NOFREE) {
527                error = gfe_rx_rxqalloc(sc, GE_RXPRIO_HI);
528                if (!error)
529                        error = gfe_rx_rxqalloc(sc, GE_RXPRIO_MEDHI);
530                if (!error)
531                        error = gfe_rx_rxqalloc(sc, GE_RXPRIO_MEDLO);
532                if (!error)
533                        error = gfe_rx_rxqalloc(sc, GE_RXPRIO_LO);
534                if (!error)
535                        error = gfe_tx_txqalloc(sc, GE_TXPRIO_HI);
536                if (!error)
537                        error = gfe_hash_alloc(sc);
538                if (error)
539                        aprint_error(
540                            "%s: failed to allocate resources: %d\n",
541                            ifp->if_xname, error);
542        }
543
544        if_attach(ifp);
545#ifndef __rtems__
546        ether_ifattach(ifp, enaddr);
547#else
548        ether_ifattach(ifp);
549#endif
550#if NBPFILTER > 0
551        bpfattach(ifp, DLT_EN10MB, sizeof(struct ether_header));
552#endif
553#if NRND > 0
554        rnd_attach_source(&sc->sc_rnd_source, self->dv_xname, RND_TYPE_NET, 0);
555#endif
556#ifndef __rtems__
557        intr_establish(IRQ_ETH0 + sc->sc_macno, IST_LEVEL, IPL_NET,
558            gfe_intr, sc);
559#else
560        return 0;
561#endif
562}
563
564int
565gfe_dmamem_alloc(struct gfe_softc *sc, struct gfe_dmamem *gdm, int maxsegs,
566        size_t size, int flags)
567{
568        int error = 0;
569        GE_FUNC_ENTER(sc, "gfe_dmamem_alloc");
570
571        KASSERT(gdm->gdm_kva == NULL);
572        gdm->gdm_size = size;
573        gdm->gdm_maxsegs = maxsegs;
574
575#ifndef __rtems__
576        error = bus_dmamem_alloc(sc->sc_dmat, gdm->gdm_size, PAGE_SIZE,
577            gdm->gdm_size, gdm->gdm_segs, gdm->gdm_maxsegs, &gdm->gdm_nsegs,
578            BUS_DMA_NOWAIT);
579        if (error)
580                goto fail;
581
582        error = bus_dmamem_map(sc->sc_dmat, gdm->gdm_segs, gdm->gdm_nsegs,
583            gdm->gdm_size, &gdm->gdm_kva, flags | BUS_DMA_NOWAIT);
584        if (error)
585                goto fail;
586
587        error = bus_dmamap_create(sc->sc_dmat, gdm->gdm_size, gdm->gdm_nsegs,
588            gdm->gdm_size, 0, BUS_DMA_ALLOCNOW|BUS_DMA_NOWAIT, &gdm->gdm_map);
589        if (error)
590                goto fail;
591
592        error = bus_dmamap_load(sc->sc_dmat, gdm->gdm_map, gdm->gdm_kva,
593            gdm->gdm_size, NULL, BUS_DMA_NOWAIT);
594        if (error)
595                goto fail;
596#else
597        gdm->gdm_segs[0].ds_len   = size;
598
599        /* FIXME: probably we can relax the alignment */
600        if ( ! ( gdm->gdm_unaligned_buf = malloc( size + PAGE_SIZE - 1, M_DEVBUF, M_NOWAIT ) ) )
601                goto fail;
602
603        gdm->gdm_map   = gdm;
604        gdm->gdm_nsegs = 1;
605        gdm->gdm_kva   = (caddr_t)(gdm->gdm_segs[0].ds_addr = _DO_ALIGN(gdm->gdm_unaligned_buf, PAGE_SIZE));
606#endif
607
608        /* invalidate from cache */
609        bus_dmamap_sync(sc->sc_dmat, gdm->gdm_map, 0, gdm->gdm_size,
610            BUS_DMASYNC_PREREAD);
611fail:
612        if (error) {
613                gfe_dmamem_free(sc, gdm);
614                GE_DPRINTF(sc, (":err=%d", error));
615        }
616        GE_DPRINTF(sc, (":kva=%p/%#x,map=%p,nsegs=%d,pa=%" PRIx32 "/%" PRIx32,
617            gdm->gdm_kva, gdm->gdm_size, gdm->gdm_map, gdm->gdm_map->dm_nsegs,
618            gdm->gdm_map->dm_segs->ds_addr, gdm->gdm_map->dm_segs->ds_len));
619        GE_FUNC_EXIT(sc, "");
620        return error;
621}
622
623void
624gfe_dmamem_free(struct gfe_softc *sc, struct gfe_dmamem *gdm)
625{
626        GE_FUNC_ENTER(sc, "gfe_dmamem_free");
627#ifndef __rtems__
628        if (gdm->gdm_map)
629                bus_dmamap_destroy(sc->sc_dmat, gdm->gdm_map);
630        if (gdm->gdm_kva)
631                bus_dmamem_unmap(sc->sc_dmat, gdm->gdm_kva, gdm->gdm_size);
632        if (gdm->gdm_nsegs > 0)
633                bus_dmamem_free(sc->sc_dmat, gdm->gdm_segs, gdm->gdm_nsegs);
634#else
635        if (gdm->gdm_nsegs > 0)
636                free(gdm->gdm_unaligned_buf, M_DEVBUF);
637#endif
638        gdm->gdm_map = NULL;
639        gdm->gdm_kva = NULL;
640        gdm->gdm_nsegs = 0;
641        GE_FUNC_EXIT(sc, "");
642}
643
644#ifndef __rtems__
645int
646gfe_ifioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
647#else
648int
649gfe_ifioctl(struct ifnet *ifp, ioctl_command_t cmd, caddr_t data)
650#endif
651{
652        struct gfe_softc * const sc = ifp->if_softc;
653        struct ifreq *ifr = (struct ifreq *) data;
654#ifndef __rtems__
655        struct ifaddr *ifa = (struct ifaddr *) data;
656#endif
657        int s, error = 0;
658
659        GE_FUNC_ENTER(sc, "gfe_ifioctl");
660        s = splnet();
661
662        switch (cmd) {
663#ifndef __rtems__
664        case SIOCSIFADDR:
665                ifp->if_flags |= IFF_UP;
666                switch (ifa->ifa_addr->sa_family) {
667#ifdef INET
668                case AF_INET:
669                        error = gfe_whack(sc, GE_WHACK_START);
670                        if (error == 0)
671                                arp_ifinit(ifp, ifa);
672                        break;
673#endif
674                default:
675                        error = gfe_whack(sc, GE_WHACK_START);
676                        break;
677                }
678                break;
679#endif
680
681        case SIOCSIFFLAGS:
682                if ((sc->sc_ec.ec_if.if_flags & IFF_PROMISC) == 0)
683                        sc->sc_pcr &= ~ETH_EPCR_PM;
684                else
685                        sc->sc_pcr |=  ETH_EPCR_PM;
686                switch (ifp->if_flags & (IFF_UP|IFF_RUNNING)) {
687                case IFF_UP|IFF_RUNNING:/* active->active, update */
688                        error = gfe_whack(sc, GE_WHACK_CHANGE);
689                        break;
690                case IFF_RUNNING:       /* not up, so we stop */
691                        error = gfe_whack(sc, GE_WHACK_STOP);
692                        break;
693                case IFF_UP:            /* not running, so we start */
694                        error = gfe_whack(sc, GE_WHACK_START);
695                        break;
696                case 0:                 /* idle->idle: do nothing */
697                        break;
698                }
699                break;
700
701        case SIOCADDMULTI:
702        case SIOCDELMULTI:
703                error = (cmd == SIOCADDMULTI)
704                    ? ether_addmulti(ifr, &sc->sc_ec)
705                    : ether_delmulti(ifr, &sc->sc_ec);
706                if (error == ENETRESET) {
707                        if (ifp->if_flags & IFF_RUNNING)
708#if !defined(__rtems__)
709                                error = gfe_whack(sc, GE_WHACK_CHANGE);
710#else
711                        /* doing GE_WHACK_CHANGE seems wrong - that
712                         * doesn't do anything to the hash table.
713                         * Therefore we perform a stop/start sequence.
714                         */
715                        {
716                                error = gfe_whack(sc, GE_WHACK_STOP);
717                                if ( error )
718                                        break;
719                                error = gfe_whack(sc, GE_WHACK_START);
720                        }
721#endif
722                        else
723                                error = 0;
724                }
725                break;
726
727        case SIOCSIFMTU:
728                if (ifr->ifr_mtu > ETHERMTU || ifr->ifr_mtu < ETHERMIN) {
729                        error = EINVAL;
730                        break;
731                }
732                ifp->if_mtu = ifr->ifr_mtu;
733                break;
734
735        case SIOCSIFMEDIA:
736        case SIOCGIFMEDIA:
737#ifndef __rtems__
738                error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd);
739#else
740                error = rtems_mii_ioctl(&gfe_mdio_access, sc, cmd, &ifr->ifr_media);
741#endif
742                break;
743
744        default:
745#ifndef __rtems__
746        error = EINVAL;
747#else
748        error = ether_ioctl(ifp, cmd, data);
749#endif
750                break;
751        }
752        splx(s);
753        GE_FUNC_EXIT(sc, "");
754        return error;
755}
756
757void
758gfe_ifstart(struct ifnet *ifp)
759{
760        struct gfe_softc * const sc = ifp->if_softc;
761        struct mbuf *m;
762
763        GE_FUNC_ENTER(sc, "gfe_ifstart");
764
765        if ((ifp->if_flags & IFF_RUNNING) == 0) {
766                GE_FUNC_EXIT(sc, "$");
767                return;
768        }
769
770        for (;;) {
771                IF_DEQUEUE(&ifp->if_snd, m);
772                if (m == NULL) {
773                        ifp->if_flags &= ~IFF_OACTIVE;
774                        GE_FUNC_EXIT(sc, "");
775                        return;
776                }
777
778                /*
779                 * No space in the pending queue?  try later.
780                 */
781                if (IF_QFULL(&sc->sc_txq[GE_TXPRIO_HI].txq_pendq))
782                        break;
783
784                /*
785                 * Try to enqueue a mbuf to the device. If that fails, we
786                 * can always try to map the next mbuf.
787                 */
788                IF_ENQUEUE(&sc->sc_txq[GE_TXPRIO_HI].txq_pendq, m);
789                GE_DPRINTF(sc, (">"));
790#ifndef GE_NOTX
791                (void) gfe_tx_enqueue(sc, GE_TXPRIO_HI);
792#endif
793        }
794
795        /*
796         * Attempt to queue the mbuf for send failed.
797         */
798        IF_PREPEND(&ifp->if_snd, m);
799        ifp->if_flags |= IFF_OACTIVE;
800        GE_FUNC_EXIT(sc, "%%");
801}
802
803void
804gfe_ifwatchdog(struct ifnet *ifp)
805{
806        struct gfe_softc * const sc = ifp->if_softc;
807        struct gfe_txqueue * const txq = &sc->sc_txq[GE_TXPRIO_HI];
808
809        GE_FUNC_ENTER(sc, "gfe_ifwatchdog");
810        printf("%s: device timeout", sc->sc_dev.dv_xname);
811        if (ifp->if_flags & IFF_RUNNING) {
812                uint32_t curtxdnum = (bus_space_read_4(sc->sc_gt_memt, sc->sc_gt_memh, txq->txq_ectdp) - txq->txq_desc_busaddr) / sizeof(txq->txq_descs[0]);
813                GE_TXDPOSTSYNC(sc, txq, txq->txq_fi);
814                GE_TXDPOSTSYNC(sc, txq, curtxdnum);
[4f5d1c9f]815                printf(" (fi=%d(%#" PRIx32 "),lo=%d,cur=%" PRIx32 "(%#" PRIx32 "),icm=%#" PRIx32 ") ",
[b7a6d23a]816                    txq->txq_fi, txq->txq_descs[txq->txq_fi].ed_cmdsts,
817                    txq->txq_lo, curtxdnum, txq->txq_descs[curtxdnum].ed_cmdsts,
818                    GE_READ(sc, EICR));
819                GE_TXDPRESYNC(sc, txq, txq->txq_fi);
820                GE_TXDPRESYNC(sc, txq, curtxdnum);
821        }
822        printf("\n");
823        ifp->if_oerrors++;
824        (void) gfe_whack(sc, GE_WHACK_RESTART);
825        GE_FUNC_EXIT(sc, "");
826}
827
828#ifdef __rtems__
829static struct mbuf *
830gfe_newbuf(struct mbuf *m)
831{
832        if ( !m ) {
833                MGETHDR(m, M_DONTWAIT, MT_DATA);
834                if ( !m )
835                        return 0;
836                MCLGET(m, M_DONTWAIT);
837                if ( !(M_EXT & m->m_flags) ) {
838                        m_freem(m);
839                        return 0;
840                }
841        } else {
842                m->m_data = m->m_ext.ext_buf;
843        }
844        m->m_len = m->m_pkthdr.len = MCLBYTES;
845#if 0
846        m_adj(m, 2); /* so payload is 16-byte aligned */
847#endif
848        return m;
849}
850#endif
851
852int
853gfe_rx_rxqalloc(struct gfe_softc *sc, enum gfe_rxprio rxprio)
854{
855        struct gfe_rxqueue * const rxq = &sc->sc_rxq[rxprio];
856        int error;
857
858        GE_FUNC_ENTER(sc, "gfe_rx_rxqalloc");
859        GE_DPRINTF(sc, ("(%d)", rxprio));
860
861        error = gfe_dmamem_alloc(sc, &rxq->rxq_desc_mem, 1,
862            GE_RXDESC_MEMSIZE, BUS_DMA_NOCACHE);
863        if (error) {
864                GE_FUNC_EXIT(sc, "!!");
865                return error;
866        }
867
868#ifndef __rtems__
869        error = gfe_dmamem_alloc(sc, &rxq->rxq_buf_mem, GE_RXBUF_NSEGS,
870            GE_RXBUF_MEMSIZE, 0);
871#else
872        if ( ! (rxq->rxq_bufs = malloc( sizeof(*rxq->rxq_bufs) * GE_RXDESC_MAX, M_DEVBUF, M_NOWAIT ) ) ) {
873                error = -1;
874        } else {
875                int i;
876                for ( i = 0; i<GE_RXDESC_MAX; i++ ) {
877                        if ( !(rxq->rxq_bufs[i] = gfe_newbuf(0)) ) {
878                                fprintf(stderr,"gfe: Not enough mbuf clusters to initialize RX ring!\n");
879                                while (--i >=0 ) {
880                                        m_freem(rxq->rxq_bufs[i]);
881                                }
882                                free(rxq->rxq_bufs, M_DEVBUF);
883                                rxq->rxq_bufs = 0;
884                                error = -1;
885                                break;
886                        }
887                }
888        }
889#endif
890        if (error) {
891                GE_FUNC_EXIT(sc, "!!!");
892                return error;
893        }
894        GE_FUNC_EXIT(sc, "");
895        return error;
896}
897
898int
899gfe_rx_rxqinit(struct gfe_softc *sc, enum gfe_rxprio rxprio)
900{
901        struct gfe_rxqueue * const rxq = &sc->sc_rxq[rxprio];
902        volatile struct gt_eth_desc *rxd;
903#ifndef __rtems__
904        const bus_dma_segment_t *ds;
905#endif
906        int idx;
907        bus_addr_t nxtaddr;
908#ifndef __rtems__
909        bus_size_t boff;
910#endif
911
912        GE_FUNC_ENTER(sc, "gfe_rx_rxqinit");
913        GE_DPRINTF(sc, ("(%d)", rxprio));
914
915        if ((sc->sc_flags & GE_NOFREE) == 0) {
916                int error = gfe_rx_rxqalloc(sc, rxprio);
917                if (error) {
918                        GE_FUNC_EXIT(sc, "!");
919                        return error;
920                }
921        } else {
922                KASSERT(rxq->rxq_desc_mem.gdm_kva != NULL);
923#ifndef __rtems__
924                KASSERT(rxq->rxq_buf_mem.gdm_kva != NULL);
925#else
926                KASSERT(rxq->rxq_bufs != NULL);
927#endif
928        }
929
930        memset(rxq->rxq_desc_mem.gdm_kva, 0, GE_RXDESC_MEMSIZE);
931
932        rxq->rxq_descs =
933            (volatile struct gt_eth_desc *) rxq->rxq_desc_mem.gdm_kva;
934        rxq->rxq_desc_busaddr = rxq->rxq_desc_mem.gdm_map->dm_segs[0].ds_addr;
935#ifndef __rtems__
936        rxq->rxq_bufs = (struct gfe_rxbuf *) rxq->rxq_buf_mem.gdm_kva;
937#endif
938        rxq->rxq_fi = 0;
939        rxq->rxq_active = GE_RXDESC_MAX;
940        for (idx = 0, rxd = rxq->rxq_descs,
941#ifndef __rtems__
942                boff = 0, ds = rxq->rxq_buf_mem.gdm_map->dm_segs,
943#endif
944                nxtaddr = rxq->rxq_desc_busaddr + sizeof(*rxd);
945             idx < GE_RXDESC_MAX;
946             idx++, rxd++, nxtaddr += sizeof(*rxd)) {
947#ifndef __rtems__
948                rxd->ed_lencnt = htogt32(GE_RXBUF_SIZE << 16);
949#else
950                rxd->ed_lencnt = htogt32(MCLBYTES << 16);
951#endif
952                rxd->ed_cmdsts = htogt32(RX_CMD_F|RX_CMD_L|RX_CMD_O|RX_CMD_EI);
953#ifndef __rtems__
954                rxd->ed_bufptr = htogt32(ds->ds_addr + boff);
955#else
956                rxd->ed_bufptr = htogt32(mtod(rxq->rxq_bufs[idx], uint32_t));
957#endif
958                /*
959                 * update the nxtptr to point to the next txd.
960                 */
961                if (idx == GE_RXDESC_MAX - 1)
962                        nxtaddr = rxq->rxq_desc_busaddr;
963                rxd->ed_nxtptr = htogt32(nxtaddr);
964#ifndef __rtems__
965                boff += GE_RXBUF_SIZE;
966                if (boff == ds->ds_len) {
967                        ds++;
968                        boff = 0;
969                }
970#endif
971        }
972        bus_dmamap_sync(sc->sc_dmat, rxq->rxq_desc_mem.gdm_map, 0,
973                        rxq->rxq_desc_mem.gdm_map->dm_mapsize,
974                        BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
975#ifndef __rtems__
976        bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map, 0,
977                        rxq->rxq_buf_mem.gdm_map->dm_mapsize,
978                        BUS_DMASYNC_PREREAD);
979#else
980        /* FIXME: we leave this call in here so compilation fails
981         *        if bus_dmamap_sync() is ever fleshed-out to implement
982         *        software cache coherency...
983         */
984        bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map, 0,
985                        rxq->rxq_buf_mem.gdm_map->dm_mapsize,
986                        BUS_DMASYNC_PREREAD);
987#endif
988
989        rxq->rxq_intrbits = ETH_IR_RxBuffer|ETH_IR_RxError;
990        switch (rxprio) {
991        case GE_RXPRIO_HI:
992                rxq->rxq_intrbits |= ETH_IR_RxBuffer_3|ETH_IR_RxError_3;
993                rxq->rxq_efrdp = ETH_EFRDP3(sc->sc_macno);
994                rxq->rxq_ecrdp = ETH_ECRDP3(sc->sc_macno);
995                break;
996        case GE_RXPRIO_MEDHI:
997                rxq->rxq_intrbits |= ETH_IR_RxBuffer_2|ETH_IR_RxError_2;
998                rxq->rxq_efrdp = ETH_EFRDP2(sc->sc_macno);
999                rxq->rxq_ecrdp = ETH_ECRDP2(sc->sc_macno);
1000                break;
1001        case GE_RXPRIO_MEDLO:
1002                rxq->rxq_intrbits |= ETH_IR_RxBuffer_1|ETH_IR_RxError_1;
1003                rxq->rxq_efrdp = ETH_EFRDP1(sc->sc_macno);
1004                rxq->rxq_ecrdp = ETH_ECRDP1(sc->sc_macno);
1005                break;
1006        case GE_RXPRIO_LO:
1007                rxq->rxq_intrbits |= ETH_IR_RxBuffer_0|ETH_IR_RxError_0;
1008                rxq->rxq_efrdp = ETH_EFRDP0(sc->sc_macno);
1009                rxq->rxq_ecrdp = ETH_ECRDP0(sc->sc_macno);
1010                break;
1011        }
1012        GE_FUNC_EXIT(sc, "");
1013        return 0;
1014}
1015
1016void
1017gfe_rx_get(struct gfe_softc *sc, enum gfe_rxprio rxprio)
1018{
1019        struct ifnet * const ifp = &sc->sc_ec.ec_if;
1020        struct gfe_rxqueue * const rxq = &sc->sc_rxq[rxprio];
1021#ifndef __rtems__
1022        struct mbuf *m = rxq->rxq_curpkt;
1023#else
1024        struct mbuf *m;
1025#endif
1026
1027        GE_FUNC_ENTER(sc, "gfe_rx_get");
1028        GE_DPRINTF(sc, ("(%d)", rxprio));
1029
1030        while (rxq->rxq_active > 0) {
1031                volatile struct gt_eth_desc *rxd = &rxq->rxq_descs[rxq->rxq_fi];
1032#ifndef __rtems__
1033                struct gfe_rxbuf *rxb = &rxq->rxq_bufs[rxq->rxq_fi];
1034#else
1035                struct mbuf             **rxb = &rxq->rxq_bufs[rxq->rxq_fi];
1036#endif
1037                const struct ether_header *eh;
1038                unsigned int cmdsts;
1039                size_t buflen;
1040
1041                GE_RXDPOSTSYNC(sc, rxq, rxq->rxq_fi);
1042                cmdsts = gt32toh(rxd->ed_cmdsts);
1043                GE_DPRINTF(sc, (":%d=%#x", rxq->rxq_fi, cmdsts));
1044                rxq->rxq_cmdsts = cmdsts;
1045                /*
1046                 * Sometimes the GE "forgets" to reset the ownership bit.
1047                 * But if the length has been rewritten, the packet is ours
1048                 * so pretend the O bit is set.
1049                 */
1050                buflen = gt32toh(rxd->ed_lencnt) & 0xffff;
1051                if ((cmdsts & RX_CMD_O) && buflen == 0) {
1052                        GE_RXDPRESYNC(sc, rxq, rxq->rxq_fi);
1053                        break;
1054                }
1055
1056                /*
1057                 * If this is not a single buffer packet with no errors
1058                 * or for some reason it's bigger than our frame size,
1059                 * ignore it and go to the next packet.
1060                 */
1061                if ((cmdsts & (RX_CMD_F|RX_CMD_L|RX_STS_ES)) !=
1062                            (RX_CMD_F|RX_CMD_L) ||
1063                    buflen > sc->sc_max_frame_length) {
1064                        GE_DPRINTF(sc, ("!"));
1065                        --rxq->rxq_active;
1066                        ifp->if_ipackets++;
1067                        ifp->if_ierrors++;
1068                       
1069                        *rxb = gfe_newbuf(*rxb);
1070                        goto give_it_back;
1071                }
1072
1073                /* CRC is included with the packet; trim it off. */
1074                buflen -= ETHER_CRC_LEN;
1075
1076#ifndef __rtems__
1077                if (m == NULL) {
1078                        MGETHDR(m, M_DONTWAIT, MT_DATA);
1079                        if (m == NULL) {
1080                                GE_DPRINTF(sc, ("?"));
1081                                break;
1082                        }
1083                }
1084                if ((m->m_flags & M_EXT) == 0 && buflen > MHLEN - 2) {
1085                        MCLGET(m, M_DONTWAIT);
1086                        if ((m->m_flags & M_EXT) == 0) {
1087                                GE_DPRINTF(sc, ("?"));
1088                                break;
1089                        }
1090                }
1091                m->m_data += 2;
1092                m->m_len = 0;
1093                m->m_pkthdr.len = 0;
1094                m->m_pkthdr.rcvif = ifp;
1095#else
1096                if ( ! (m=gfe_newbuf(0)) ) {
1097                        /* recycle old buffer */
1098                        *rxb = gfe_newbuf(*rxb);
1099                        goto give_it_back;
1100                }
1101                /* swap mbufs */
1102                {
1103                struct mbuf *tmp = *rxb;
1104                *rxb = m;
1105                m    = tmp;
1106                rxd->ed_bufptr = htogt32(mtod(*rxb, uint32_t));
1107                }
1108#endif
1109                rxq->rxq_cmdsts = cmdsts;
1110                --rxq->rxq_active;
1111
1112#ifdef __rtems__
1113                /* FIXME: we leave this call in here so compilation fails
1114                 *        if bus_dmamap_sync() is ever fleshed-out to implement
1115                 *        software cache coherency...
1116                 */
1117                bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map,
1118                    rxq->rxq_fi * sizeof(*rxb), buflen, BUS_DMASYNC_POSTREAD);
1119#else
1120                bus_dmamap_sync(sc->sc_dmat, rxq->rxq_buf_mem.gdm_map,
1121                    rxq->rxq_fi * sizeof(*rxb), buflen, BUS_DMASYNC_POSTREAD);
1122
1123                KASSERT(m->m_len == 0 && m->m_pkthdr.len == 0);
1124                memcpy(m->m_data + m->m_len, rxb->rb_data, buflen);
1125#endif
1126
1127                m->m_len = buflen;
1128                m->m_pkthdr.len = buflen;
1129
1130                ifp->if_ipackets++;
1131#if NBPFILTER > 0
1132                if (ifp->if_bpf != NULL)
1133                        bpf_mtap(ifp->if_bpf, m);
1134#endif
1135
1136                eh = (const struct ether_header *) m->m_data;
1137                if ((ifp->if_flags & IFF_PROMISC) ||
1138                    (rxq->rxq_cmdsts & RX_STS_M) == 0 ||
1139                    (rxq->rxq_cmdsts & RX_STS_HE) ||
1140                    (eh->ether_dhost[0] & 1) != 0 ||
1141                    memcmp(eh->ether_dhost,
1142#ifndef __rtems__
1143                                LLADDR(ifp->if_sadl),
1144#else
1145                                sc->sc_ec.ac_enaddr,
1146#endif
1147                        ETHER_ADDR_LEN) == 0) {
1148#ifndef __rtems__
1149                        (*ifp->if_input)(ifp, m);
1150                        m = NULL;
1151#else
1152                        DO_ETHER_INPUT_SKIPPING_ETHER_HEADER(ifp,m);
1153#endif
1154                        GE_DPRINTF(sc, (">"));
1155                } else {
1156#ifndef __rtems__
1157                        m->m_len = 0;
1158                        m->m_pkthdr.len = 0;
1159#else
1160                        m_freem(m);
1161#endif
1162                        GE_DPRINTF(sc, ("+"));
1163                }
1164                rxq->rxq_cmdsts = 0;
1165
1166           give_it_back:
1167                rxd->ed_lencnt &= ~0xffff;      /* zero out length */
1168                rxd->ed_cmdsts = htogt32(RX_CMD_F|RX_CMD_L|RX_CMD_O|RX_CMD_EI);
1169#if 0
1170                GE_DPRINTF(sc, ("([%d]->%08lx.%08lx.%08lx.%08lx)",
1171                    rxq->rxq_fi,
1172                    ((unsigned long *)rxd)[0], ((unsigned long *)rxd)[1],
1173                    ((unsigned long *)rxd)[2], ((unsigned long *)rxd)[3]));
1174#endif
1175                GE_RXDPRESYNC(sc, rxq, rxq->rxq_fi);
1176                if (++rxq->rxq_fi == GE_RXDESC_MAX)
1177                        rxq->rxq_fi = 0;
1178                rxq->rxq_active++;
1179        }
1180#ifndef __rtems__
1181        rxq->rxq_curpkt = m;
1182#endif
1183        GE_FUNC_EXIT(sc, "");
1184}
1185
1186uint32_t
1187gfe_rx_process(struct gfe_softc *sc, uint32_t cause, uint32_t intrmask)
1188{
1189        struct ifnet * const ifp = &sc->sc_ec.ec_if;
1190        struct gfe_rxqueue *rxq;
1191        uint32_t rxbits;
1192#define RXPRIO_DECODER  0xffffaa50
1193        GE_FUNC_ENTER(sc, "gfe_rx_process");
1194
1195        rxbits = ETH_IR_RxBuffer_GET(cause);
1196        while (rxbits) {
1197                enum gfe_rxprio rxprio = (RXPRIO_DECODER >> (rxbits * 2)) & 3;
1198                GE_DPRINTF(sc, ("%1" PRIx32, rxbits));
1199                rxbits &= ~(1 << rxprio);
1200                gfe_rx_get(sc, rxprio);
1201        }
1202
1203        rxbits = ETH_IR_RxError_GET(cause);
1204        while (rxbits) {
1205                enum gfe_rxprio rxprio = (RXPRIO_DECODER >> (rxbits * 2)) & 3;
1206                uint32_t masks[(GE_RXDESC_MAX + 31) / 32];
1207                int idx;
1208                rxbits &= ~(1 << rxprio);
1209                rxq = &sc->sc_rxq[rxprio];
1210                sc->sc_idlemask |= (rxq->rxq_intrbits & ETH_IR_RxBits);
1211                intrmask &= ~(rxq->rxq_intrbits & ETH_IR_RxBits);
1212                if ((sc->sc_tickflags & GE_TICK_RX_RESTART) == 0) {
1213                        sc->sc_tickflags |= GE_TICK_RX_RESTART;
1214                        callout_reset(&sc->sc_co, 1, gfe_tick, sc);
1215                }
1216                ifp->if_ierrors++;
1217                GE_DPRINTF(sc, ("%s: rx queue %d filled at %u\n",
1218                    sc->sc_dev.dv_xname, rxprio, rxq->rxq_fi));
1219                memset(masks, 0, sizeof(masks));
1220                bus_dmamap_sync(sc->sc_dmat, rxq->rxq_desc_mem.gdm_map,
1221                    0, rxq->rxq_desc_mem.gdm_size,
1222                    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
1223                for (idx = 0; idx < GE_RXDESC_MAX; idx++) {
1224                        volatile struct gt_eth_desc *rxd = &rxq->rxq_descs[idx];
1225
1226                        if (RX_CMD_O & gt32toh(rxd->ed_cmdsts))
1227                                masks[idx/32] |= 1 << (idx & 31);
1228                }
1229                bus_dmamap_sync(sc->sc_dmat, rxq->rxq_desc_mem.gdm_map,
1230                    0, rxq->rxq_desc_mem.gdm_size,
1231                    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1232#if defined(DEBUG)
1233                printf("%s: rx queue %d filled at %u=%#x(%#x/%#x)\n",
1234                    sc->sc_dev.dv_xname, rxprio, rxq->rxq_fi,
1235                    rxq->rxq_cmdsts, masks[0], masks[1]);
1236#endif
1237        }
1238        if ((intrmask & ETH_IR_RxBits) == 0)
1239                intrmask &= ~(ETH_IR_RxBuffer|ETH_IR_RxError);
1240
1241        GE_FUNC_EXIT(sc, "");
1242        return intrmask;
1243}
1244
1245int
1246gfe_rx_prime(struct gfe_softc *sc)
1247{
1248        struct gfe_rxqueue *rxq;
1249        int error;
1250
1251        GE_FUNC_ENTER(sc, "gfe_rx_prime");
1252
1253        error = gfe_rx_rxqinit(sc, GE_RXPRIO_HI);
1254        if (error)
1255                goto bail;
1256        rxq = &sc->sc_rxq[GE_RXPRIO_HI];
1257        if ((sc->sc_flags & GE_RXACTIVE) == 0) {
1258                GE_WRITE(sc, EFRDP3, rxq->rxq_desc_busaddr);
1259                GE_WRITE(sc, ECRDP3, rxq->rxq_desc_busaddr);
1260        }
1261        sc->sc_intrmask |= rxq->rxq_intrbits;
1262
1263        error = gfe_rx_rxqinit(sc, GE_RXPRIO_MEDHI);
1264        if (error)
1265                goto bail;
1266        if ((sc->sc_flags & GE_RXACTIVE) == 0) {
1267                rxq = &sc->sc_rxq[GE_RXPRIO_MEDHI];
1268                GE_WRITE(sc, EFRDP2, rxq->rxq_desc_busaddr);
1269                GE_WRITE(sc, ECRDP2, rxq->rxq_desc_busaddr);
1270                sc->sc_intrmask |= rxq->rxq_intrbits;
1271        }
1272
1273        error = gfe_rx_rxqinit(sc, GE_RXPRIO_MEDLO);
1274        if (error)
1275                goto bail;
1276        if ((sc->sc_flags & GE_RXACTIVE) == 0) {
1277                rxq = &sc->sc_rxq[GE_RXPRIO_MEDLO];
1278                GE_WRITE(sc, EFRDP1, rxq->rxq_desc_busaddr);
1279                GE_WRITE(sc, ECRDP1, rxq->rxq_desc_busaddr);
1280                sc->sc_intrmask |= rxq->rxq_intrbits;
1281        }
1282
1283        error = gfe_rx_rxqinit(sc, GE_RXPRIO_LO);
1284        if (error)
1285                goto bail;
1286        if ((sc->sc_flags & GE_RXACTIVE) == 0) {
1287                rxq = &sc->sc_rxq[GE_RXPRIO_LO];
1288                GE_WRITE(sc, EFRDP0, rxq->rxq_desc_busaddr);
1289                GE_WRITE(sc, ECRDP0, rxq->rxq_desc_busaddr);
1290                sc->sc_intrmask |= rxq->rxq_intrbits;
1291        }
1292
1293  bail:
1294        GE_FUNC_EXIT(sc, "");
1295        return error;
1296}
1297
1298void
1299gfe_rx_cleanup(struct gfe_softc *sc, enum gfe_rxprio rxprio)
1300{
1301        struct gfe_rxqueue *rxq = &sc->sc_rxq[rxprio];
1302        GE_FUNC_ENTER(sc, "gfe_rx_cleanup");
1303        if (rxq == NULL) {
1304                GE_FUNC_EXIT(sc, "");
1305                return;
1306        }
1307
1308#ifndef __rtems__
1309        if (rxq->rxq_curpkt)
1310                m_freem(rxq->rxq_curpkt);
1311#endif
1312        if ((sc->sc_flags & GE_NOFREE) == 0) {
1313                gfe_dmamem_free(sc, &rxq->rxq_desc_mem);
1314#ifndef __rtems__
1315                gfe_dmamem_free(sc, &rxq->rxq_buf_mem);
1316#else
1317                if ( rxq->rxq_bufs ) {
1318                        int i;
1319                        for ( i=0; i<GE_RXDESC_MAX; i++ ) {
1320                                if ( rxq->rxq_bufs[i] ) {
1321                                        m_freem(rxq->rxq_bufs[i]);
1322                                }
1323                        }
1324                        free(rxq->rxq_bufs, M_DEVBUF);
1325                }
1326#endif
1327        }
1328        GE_FUNC_EXIT(sc, "");
1329}
1330
1331void
1332gfe_rx_stop(struct gfe_softc *sc, enum gfe_whack_op op)
1333{
1334        GE_FUNC_ENTER(sc, "gfe_rx_stop");
1335        sc->sc_flags &= ~GE_RXACTIVE;
1336        sc->sc_idlemask &= ~(ETH_IR_RxBits|ETH_IR_RxBuffer|ETH_IR_RxError);
1337        sc->sc_intrmask &= ~(ETH_IR_RxBits|ETH_IR_RxBuffer|ETH_IR_RxError);
1338        GE_WRITE(sc, EIMR, sc->sc_intrmask);
1339        GE_WRITE(sc, ESDCMR, ETH_ESDCMR_AR);
1340        do {
1341                delay(10);
1342        } while (GE_READ(sc, ESDCMR) & ETH_ESDCMR_AR);
1343        gfe_rx_cleanup(sc, GE_RXPRIO_HI);
1344        gfe_rx_cleanup(sc, GE_RXPRIO_MEDHI);
1345        gfe_rx_cleanup(sc, GE_RXPRIO_MEDLO);
1346        gfe_rx_cleanup(sc, GE_RXPRIO_LO);
1347        GE_FUNC_EXIT(sc, "");
1348}
1349
1350void
1351gfe_tick(void *arg)
1352{
1353        struct gfe_softc * const sc = arg;
1354        uint32_t intrmask;
1355        unsigned int tickflags;
1356        int s;
1357
1358        GE_FUNC_ENTER(sc, "gfe_tick");
1359
1360        s = splnet();
1361
1362        tickflags = sc->sc_tickflags;
1363        sc->sc_tickflags = 0;
1364        intrmask = sc->sc_intrmask;
1365        if (tickflags & GE_TICK_TX_IFSTART)
1366                gfe_ifstart(&sc->sc_ec.ec_if);
1367        if (tickflags & GE_TICK_RX_RESTART) {
1368                intrmask |= sc->sc_idlemask;
1369                if (sc->sc_idlemask & (ETH_IR_RxBuffer_3|ETH_IR_RxError_3)) {
1370                        struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_HI];
1371                        rxq->rxq_fi = 0;
1372                        GE_WRITE(sc, EFRDP3, rxq->rxq_desc_busaddr);
1373                        GE_WRITE(sc, ECRDP3, rxq->rxq_desc_busaddr);
1374                }
1375                if (sc->sc_idlemask & (ETH_IR_RxBuffer_2|ETH_IR_RxError_2)) {
1376                        struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_MEDHI];
1377                        rxq->rxq_fi = 0;
1378                        GE_WRITE(sc, EFRDP2, rxq->rxq_desc_busaddr);
1379                        GE_WRITE(sc, ECRDP2, rxq->rxq_desc_busaddr);
1380                }
1381                if (sc->sc_idlemask & (ETH_IR_RxBuffer_1|ETH_IR_RxError_1)) {
1382                        struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_MEDLO];
1383                        rxq->rxq_fi = 0;
1384                        GE_WRITE(sc, EFRDP1, rxq->rxq_desc_busaddr);
1385                        GE_WRITE(sc, ECRDP1, rxq->rxq_desc_busaddr);
1386                }
1387                if (sc->sc_idlemask & (ETH_IR_RxBuffer_0|ETH_IR_RxError_0)) {
1388                        struct gfe_rxqueue *rxq = &sc->sc_rxq[GE_RXPRIO_LO];
1389                        rxq->rxq_fi = 0;
1390                        GE_WRITE(sc, EFRDP0, rxq->rxq_desc_busaddr);
1391                        GE_WRITE(sc, ECRDP0, rxq->rxq_desc_busaddr);
1392                }
1393                sc->sc_idlemask = 0;
1394        }
1395        if (intrmask != sc->sc_intrmask) {
1396                sc->sc_intrmask = intrmask;
1397                GE_WRITE(sc, EIMR, sc->sc_intrmask);
1398        }
1399        gfe_intr(sc);
1400        splx(s);
1401
1402        GE_FUNC_EXIT(sc, "");
1403}
1404
1405static int
1406gfe_free_slots(struct gfe_softc *sc, struct gfe_txqueue *const txq)
1407{
1408        struct ifnet * const ifp = &sc->sc_ec.ec_if;
1409#ifndef __rtems__
1410        const int dcache_line_size = curcpu()->ci_ci.dcache_line_size;
1411#endif
1412        int                                                      got = 0;
1413        int                                                       fi = txq->txq_fi;
1414        volatile struct gt_eth_desc *txd = &txq->txq_descs[fi];
1415        uint32_t cmdsts;
1416#ifndef __rtems__
1417        size_t pktlen;
1418#endif
1419
1420        GE_FUNC_ENTER(sc, "gfe_free_slots");
1421
1422#ifdef __rtems__
1423        do {
1424#endif
1425                GE_TXDPOSTSYNC(sc, txq, fi);
1426                if ((cmdsts = gt32toh(txd->ed_cmdsts)) & TX_CMD_O) {
1427                        int nextin;
1428
1429                        if (txq->txq_nactive == 1) {
1430                                GE_TXDPRESYNC(sc, txq, fi);
1431                                GE_FUNC_EXIT(sc, "");
1432                                return -1;
1433                        }
1434                        /*
1435                         * Sometimes the Discovery forgets to update the
1436                         * ownership bit in the descriptor.  See if we own the
1437                         * descriptor after it (since we know we've turned
1438                         * that to the Discovery and if we own it now then the
1439                         * Discovery gave it back).  If we do, we know the
1440                         * Discovery gave back this one but forgot to mark it
1441                         * as ours.
1442                         */
1443                        nextin = fi + 1;
1444                        if (nextin == GE_TXDESC_MAX)
1445                                nextin = 0;
1446                        GE_TXDPOSTSYNC(sc, txq, nextin);
1447                        if (gt32toh(txq->txq_descs[nextin].ed_cmdsts) & TX_CMD_O) {
1448                                GE_TXDPRESYNC(sc, txq, fi);
1449                                GE_TXDPRESYNC(sc, txq, nextin);
1450                                GE_FUNC_EXIT(sc, "");
1451                                return -1;
1452                        }
1453#ifdef DEBUG
1454                        printf("%s: gfe_free_slots: transmitter resynced at %d\n",
1455                                        sc->sc_dev.dv_xname, fi);
1456#endif
1457                }
1458                got++;
1459#ifdef __rtems__
1460                txd++;
1461                fi++;
1462        } while ( ! ( TX_CMD_LAST & cmdsts ) );
1463
1464        { struct mbuf *m;
1465                IF_DEQUEUE(&txq->txq_sentq, m);
1466                m_freem(m);
1467        }
1468#endif
1469#if 0
1470        GE_DPRINTF(sc, ("([%d]<-%08lx.%08lx.%08lx.%08lx)",
1471                                txq->txq_lo,
1472                                ((unsigned long *)txd)[0], ((unsigned long *)txd)[1],
1473                                ((unsigned long *)txd)[2], ((unsigned long *)txd)[3]));
1474#endif
1475        GE_DPRINTF(sc, ("(%d)", fi));
1476        txq->txq_fi = fi;
1477        if ( txq->txq_fi >= GE_TXDESC_MAX)
1478                txq->txq_fi -= GE_TXDESC_MAX;
1479#ifndef __rtems__
1480        txq->txq_inptr = gt32toh(txd->ed_bufptr) - txq->txq_buf_busaddr;
1481        pktlen = (gt32toh(txd->ed_lencnt) >> 16) & 0xffff;
1482        bus_dmamap_sync(sc->sc_dmat, txq->txq_buf_mem.gdm_map,
1483                        txq->txq_inptr, pktlen, BUS_DMASYNC_POSTWRITE);
1484        txq->txq_inptr += roundup(pktlen, dcache_line_size);
1485#endif
1486
1487        /* statistics */
1488        ifp->if_opackets++;
1489#ifdef __rtems__
1490        /* FIXME: should we check errors on every fragment? */
1491#endif
1492        if (cmdsts & TX_STS_ES)
1493                ifp->if_oerrors++;
1494
1495        /* txd->ed_bufptr = 0; */
1496
1497        txq->txq_nactive -= got;
1498
1499        GE_FUNC_EXIT(sc, "");
1500
1501        return got;
1502}
1503
1504#ifndef __rtems__
1505int
1506gfe_tx_enqueue(struct gfe_softc *sc, enum gfe_txprio txprio)
1507{
1508#ifndef __rtems__
1509        const int dcache_line_size = curcpu()->ci_ci.dcache_line_size;
1510#else
1511#ifndef PPC_CACHE_ALIGNMENT
1512#error  "Unknown cache alignment for your CPU"
1513#endif
1514        const int dcache_line_size = PPC_CACHE_ALIGNMENT;
1515#endif
1516        struct ifnet * const ifp = &sc->sc_ec.ec_if;
1517        struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
1518        volatile struct gt_eth_desc * const txd = &txq->txq_descs[txq->txq_lo];
1519        uint32_t intrmask = sc->sc_intrmask;
1520        size_t buflen;
1521        struct mbuf *m;
1522
1523        GE_FUNC_ENTER(sc, "gfe_tx_enqueue");
1524
1525        /*
1526         * Anything in the pending queue to enqueue?  if not, punt. Likewise
1527         * if the txq is not yet created.
1528         * otherwise grab its dmamap.
1529         */
1530        if (txq == NULL || (m = txq->txq_pendq.ifq_head) == NULL) {
1531                GE_FUNC_EXIT(sc, "-");
1532                return 0;
1533        }
1534
1535        /*
1536         * Have we [over]consumed our limit of descriptors?
1537         * Do we have enough free descriptors?
1538         */
1539        if (GE_TXDESC_MAX == txq->txq_nactive + 2) {
1540                if ( gfe_free_slots(sc, txq) <= 0 )
1541                        return 0;
1542        }
1543
1544        buflen = roundup(m->m_pkthdr.len, dcache_line_size);
1545
1546        /*
1547         * If this packet would wrap around the end of the buffer, reset back
1548         * to the beginning.
1549         */
1550        if (txq->txq_outptr + buflen > GE_TXBUF_SIZE) {
1551                txq->txq_ei_gapcount += GE_TXBUF_SIZE - txq->txq_outptr;
1552                txq->txq_outptr = 0;
1553        }
1554
1555        /*
1556         * Make sure the output packet doesn't run over the beginning of
1557         * what we've already given the GT.
1558         */
1559        if (txq->txq_nactive > 0 && txq->txq_outptr <= txq->txq_inptr &&
1560            txq->txq_outptr + buflen > txq->txq_inptr) {
1561                intrmask |= txq->txq_intrbits &
1562                    (ETH_IR_TxBufferHigh|ETH_IR_TxBufferLow);
1563                if (sc->sc_intrmask != intrmask) {
1564                        sc->sc_intrmask = intrmask;
1565                        GE_WRITE(sc, EIMR, sc->sc_intrmask);
1566                }
1567                GE_FUNC_EXIT(sc, "#");
1568                return 0;
1569        }
1570
1571        /*
1572         * The end-of-list descriptor we put on last time is the starting point
1573         * for this packet.  The GT is supposed to terminate list processing on
1574         * a NULL nxtptr but that currently is broken so a CPU-owned descriptor
1575         * must terminate the list.
1576         */
1577        intrmask = sc->sc_intrmask;
1578
1579        m_copydata(m, 0, m->m_pkthdr.len,
1580            txq->txq_buf_mem.gdm_kva + txq->txq_outptr);
1581        bus_dmamap_sync(sc->sc_dmat, txq->txq_buf_mem.gdm_map,
1582            txq->txq_outptr, buflen, BUS_DMASYNC_PREWRITE);
1583        txd->ed_bufptr = htogt32(txq->txq_buf_busaddr + txq->txq_outptr);
1584        txd->ed_lencnt = htogt32(m->m_pkthdr.len << 16);
1585        GE_TXDPRESYNC(sc, txq, txq->txq_lo);
1586
1587        /*
1588         * Request a buffer interrupt every 2/3 of the way thru the transmit
1589         * buffer.
1590         */
1591        txq->txq_ei_gapcount += buflen;
1592        if (txq->txq_ei_gapcount > 2 * GE_TXBUF_SIZE / 3) {
1593                txd->ed_cmdsts = htogt32(TX_CMD_FIRST|TX_CMD_LAST|TX_CMD_EI);
1594                txq->txq_ei_gapcount = 0;
1595        } else {
1596                txd->ed_cmdsts = htogt32(TX_CMD_FIRST|TX_CMD_LAST);
1597        }
1598#if 0
1599        GE_DPRINTF(sc, ("([%d]->%08lx.%08lx.%08lx.%08lx)", txq->txq_lo,
1600            ((unsigned long *)txd)[0], ((unsigned long *)txd)[1],
1601            ((unsigned long *)txd)[2], ((unsigned long *)txd)[3]));
1602#endif
1603        GE_TXDPRESYNC(sc, txq, txq->txq_lo);
1604
1605        txq->txq_outptr += buflen;
1606        /*
1607         * Tell the SDMA engine to "Fetch!"
1608         */
1609        GE_WRITE(sc, ESDCMR,
1610                 txq->txq_esdcmrbits & (ETH_ESDCMR_TXDH|ETH_ESDCMR_TXDL));
1611
1612        GE_DPRINTF(sc, ("(%d)", txq->txq_lo));
1613
1614        /*
1615         * Update the last out appropriately.
1616         */
1617        txq->txq_nactive++;
1618        if (++txq->txq_lo == GE_TXDESC_MAX)
1619                txq->txq_lo = 0;
1620
1621        /*
1622         * Move mbuf from the pending queue to the snd queue.
1623         */
1624        IF_DEQUEUE(&txq->txq_pendq, m);
1625#if NBPFILTER > 0
1626        if (ifp->if_bpf != NULL)
1627                bpf_mtap(ifp->if_bpf, m);
1628#endif
1629        m_freem(m);
1630        ifp->if_flags &= ~IFF_OACTIVE;
1631
1632        /*
1633         * Since we have put an item into the packet queue, we now want
1634         * an interrupt when the transmit queue finishes processing the
1635         * list.  But only update the mask if needs changing.
1636         */
1637        intrmask |= txq->txq_intrbits & (ETH_IR_TxEndHigh|ETH_IR_TxEndLow);
1638        if (sc->sc_intrmask != intrmask) {
1639                sc->sc_intrmask = intrmask;
1640                GE_WRITE(sc, EIMR, sc->sc_intrmask);
1641        }
1642        if (ifp->if_timer == 0)
1643                ifp->if_timer = 5;
1644        GE_FUNC_EXIT(sc, "*");
1645        return 1;
1646}
1647
1648#else
1649
1650#ifdef __PPC__
1651static inline void membarrier(void)
1652{
1653        asm volatile("sync":::"memory");
1654}
1655#else
1656#error "memory synchronization for your CPU not implemented"
1657#endif
1658
1659
1660void
1661gfe_assign_desc(volatile struct gt_eth_desc *const d, struct mbuf *m, uint32_t flags)
1662{
1663        d->ed_cmdsts = htogt32(flags | TX_CMD_GC | TX_CMD_P);
1664        d->ed_bufptr = htogt32(mtod(m, uint32_t));
1665        d->ed_lencnt = htogt32(m->m_len << 16);
1666}
1667
1668int
1669gfe_tx_enqueue(struct gfe_softc *sc, enum gfe_txprio txprio)
1670{
1671        struct ifnet * const ifp = &sc->sc_ec.ec_if;
1672        struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
1673        volatile struct gt_eth_desc * const txd = &txq->txq_descs[txq->txq_lo];
1674#define NEXT_TXD(d)     ((d)+1 < &txq->txq_descs[GE_TXDESC_MAX] ? (d)+1 : txq->txq_descs)
1675        volatile struct gt_eth_desc *l,*d;
1676        uint32_t intrmask = sc->sc_intrmask;
1677        struct mbuf *m_head,*m,*m1;
1678        int                                                                     avail, used;
1679
1680        GE_FUNC_ENTER(sc, "gfe_tx_enqueue");
1681
1682        /*
1683         * Anything in the pending queue to enqueue?  if not, punt. Likewise
1684         * if the txq is not yet created.
1685         * otherwise grab its dmamap.
1686         */
1687        if (txq == NULL || (m_head = txq->txq_pendq.ifq_head) == NULL) {
1688                GE_FUNC_EXIT(sc, "-");
1689                return 0;
1690        }
1691
1692        /* find 1st mbuf with actual data; m_head is not NULL at this point */
1693        for ( m1=m_head; 0 == m1->m_len; ) {
1694                if ( ! (m1=m1->m_next) ) {
1695                        /* nothing to send */
1696                        IF_DEQUEUE(&txq->txq_pendq, m_head);
1697                        m_freem(m_head);
1698                        return 0;
1699                }
1700        }
1701
1702        avail = GE_TXDESC_MAX - 1 - txq->txq_nactive;
1703
1704        if ( avail < 1 && (avail += gfe_free_slots(sc, txq)) < 1 )
1705                return 0;
1706
1707        avail--;
1708
1709        l = txd;
1710        d = NEXT_TXD(txd);
1711
1712        for ( m=m1->m_next, used = 1; m; m=m->m_next ) {
1713                if ( 0 == m->m_len )
1714                        continue; /* skip empty mbufs */
1715
1716                if ( avail < 1 && (avail += gfe_free_slots(sc, txq)) < 1 ) {
1717                        /* not enough descriptors; cleanup */
1718                        for ( l = NEXT_TXD(txd); l!=d; l = NEXT_TXD(l) ) {
1719                                l->ed_cmdsts = 0;
1720                                avail++;
1721                        }
1722                        avail++;
1723                        if ( used >= GE_TXDESC_MAX-1 )
1724                                panic("mbuf chain (#%i) longer than TX ring (#%i); configuration error!",
1725                                        used, GE_TXDESC_MAX-1);
1726                        return 0;
1727                }
1728                used++;
1729                avail--;
1730
1731                /* fill this slot */
1732                gfe_assign_desc(d, m, TX_CMD_O);
1733
1734                bus_dmamap_sync(sc->sc_dmat, /* TODO */,
1735                         mtod(m, uint32_t), m->m_len, BUS_DMASYNC_PREWRITE);
1736
1737                l = d;
1738                d = NEXT_TXD(d);
1739
1740                GE_TXDPRESYNC(sc, txq, l - txq->txq_descs);
1741        }
1742
1743        /* fill first slot */
1744        gfe_assign_desc(txd, m1, TX_CMD_F);
1745
1746        bus_dmamap_sync(sc->sc_dmat, /* TODO */,
1747                         mtod(m1, uint32_t), m1->m_len, BUS_DMASYNC_PREWRITE);
1748       
1749        /* tag last slot; this covers where 1st = last */
1750        l->ed_cmdsts    |= htonl(TX_CMD_L | TX_CMD_EI);
1751
1752        GE_TXDPRESYNC(sc, txq, l - txq->txq_descs);
1753
1754        /*
1755         * The end-of-list descriptor we put on last time is the starting point
1756         * for this packet.  The GT is supposed to terminate list processing on
1757         * a NULL nxtptr but that currently is broken so a CPU-owned descriptor
1758         * must terminate the list.
1759         */
1760        d = NEXT_TXD(l);
1761
[2d5c486]1762        out_be32((uint32_t*)&d->ed_cmdsts,0);
[b7a6d23a]1763
1764        GE_TXDPRESYNC(sc, txq, d - txq->txq_descs);
1765
1766        membarrier();
1767
1768        /* turn over the whole chain by flipping the ownership of the first desc */
1769        txd->ed_cmdsts |= htonl(TX_CMD_O);
1770
1771        GE_TXDPRESYNC(sc, txq, txq->txq_lo);
1772
1773
1774        intrmask = sc->sc_intrmask;
1775
1776#if 0
1777        GE_DPRINTF(sc, ("([%d]->%08lx.%08lx.%08lx.%08lx)", txq->txq_lo,
1778            ((unsigned long *)txd)[0], ((unsigned long *)txd)[1],
1779            ((unsigned long *)txd)[2], ((unsigned long *)txd)[3]));
1780#endif
1781
1782        membarrier();
1783
1784        /*
1785         * Tell the SDMA engine to "Fetch!"
1786         */
1787        GE_WRITE(sc, ESDCMR,
1788                 txq->txq_esdcmrbits & (ETH_ESDCMR_TXDH|ETH_ESDCMR_TXDL));
1789
1790        GE_DPRINTF(sc, ("(%d)", txq->txq_lo));
1791
1792        /*
1793         * Update the last out appropriately.
1794         */
1795        txq->txq_nactive += used;
1796        txq->txq_lo      += used;
1797        if ( txq->txq_lo >= GE_TXDESC_MAX )
1798                txq->txq_lo -= GE_TXDESC_MAX;
1799
1800        /*
1801         * Move mbuf from the pending queue to the snd queue.
1802         */
1803        IF_DEQUEUE(&txq->txq_pendq, m_head);
1804
1805        IF_ENQUEUE(&txq->txq_sentq, m_head);
1806
1807#if NBPFILTER > 0
1808        if (ifp->if_bpf != NULL)
1809                bpf_mtap(ifp->if_bpf, m_head);
1810#endif
1811        ifp->if_flags &= ~IFF_OACTIVE;
1812
1813        /*
1814         * Since we have put an item into the packet queue, we now want
1815         * an interrupt when the transmit queue finishes processing the
1816         * list.  But only update the mask if needs changing.
1817         */
1818        intrmask |= txq->txq_intrbits & (ETH_IR_TxEndHigh|ETH_IR_TxEndLow);
1819        if (sc->sc_intrmask != intrmask) {
1820                sc->sc_intrmask = intrmask;
1821                GE_WRITE(sc, EIMR, sc->sc_intrmask);
1822        }
1823        if (ifp->if_timer == 0)
1824                ifp->if_timer = 5;
1825        GE_FUNC_EXIT(sc, "*");
1826        return 1;
1827}
1828#endif
1829
1830uint32_t
1831gfe_tx_done(struct gfe_softc *sc, enum gfe_txprio txprio, uint32_t intrmask)
1832{
1833        struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
1834        struct ifnet * const ifp = &sc->sc_ec.ec_if;
1835
1836        GE_FUNC_ENTER(sc, "gfe_tx_done");
1837
1838        if (txq == NULL) {
1839                GE_FUNC_EXIT(sc, "");
1840                return intrmask;
1841        }
1842
1843        while (txq->txq_nactive > 0) {
1844                if ( gfe_free_slots(sc, txq) < 0 )
1845                        return intrmask;
1846                ifp->if_timer = 5;
1847        }
1848        if (txq->txq_nactive != 0)
1849                panic("%s: transmit fifo%d empty but active count (%d) not 0!",
1850                    sc->sc_dev.dv_xname, txprio, txq->txq_nactive);
1851        ifp->if_timer = 0;
1852        intrmask &= ~(txq->txq_intrbits & (ETH_IR_TxEndHigh|ETH_IR_TxEndLow));
1853        intrmask &= ~(txq->txq_intrbits & (ETH_IR_TxBufferHigh|ETH_IR_TxBufferLow));
1854        GE_FUNC_EXIT(sc, "");
1855        return intrmask;
1856}
1857
1858int
1859gfe_tx_txqalloc(struct gfe_softc *sc, enum gfe_txprio txprio)
1860{
1861        struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
1862        int error;
1863
1864        GE_FUNC_ENTER(sc, "gfe_tx_txqalloc");
1865
1866        error = gfe_dmamem_alloc(sc, &txq->txq_desc_mem, 1,
1867            GE_TXDESC_MEMSIZE, BUS_DMA_NOCACHE);
1868        if (error) {
1869                GE_FUNC_EXIT(sc, "");
1870                return error;
1871        }
1872#ifndef __rtems__
1873        error = gfe_dmamem_alloc(sc, &txq->txq_buf_mem, 1, GE_TXBUF_SIZE, 0);
1874        if (error) {
1875                gfe_dmamem_free(sc, &txq->txq_desc_mem);
1876                GE_FUNC_EXIT(sc, "");
1877                return error;
1878        }
1879#endif
1880        GE_FUNC_EXIT(sc, "");
1881        return 0;
1882}
1883
1884int
1885gfe_tx_start(struct gfe_softc *sc, enum gfe_txprio txprio)
1886{
1887        struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
1888        volatile struct gt_eth_desc *txd;
1889        unsigned int i;
1890        bus_addr_t addr;
1891
1892        GE_FUNC_ENTER(sc, "gfe_tx_start");
1893
1894        sc->sc_intrmask &= ~(ETH_IR_TxEndHigh|ETH_IR_TxBufferHigh|
1895                             ETH_IR_TxEndLow |ETH_IR_TxBufferLow);
1896
1897        if (sc->sc_flags & GE_NOFREE) {
1898                KASSERT(txq->txq_desc_mem.gdm_kva != NULL);
1899#ifndef __rtems__
1900                KASSERT(txq->txq_buf_mem.gdm_kva != NULL);
1901#endif
1902        } else {
1903                int error = gfe_tx_txqalloc(sc, txprio);
1904                if (error) {
1905                        GE_FUNC_EXIT(sc, "!");
1906                        return error;
1907                }
1908        }
1909
1910        txq->txq_descs =
1911            (volatile struct gt_eth_desc *) txq->txq_desc_mem.gdm_kva;
1912        txq->txq_desc_busaddr = txq->txq_desc_mem.gdm_map->dm_segs[0].ds_addr;
1913#ifndef __rtems__
1914        txq->txq_buf_busaddr = txq->txq_buf_mem.gdm_map->dm_segs[0].ds_addr;
1915#else
1916        /* never used */
1917        memset(&txq->txq_pendq,0,sizeof(txq->txq_pendq));
1918        memset(&txq->txq_sentq,0,sizeof(txq->txq_sentq));
1919        txq->txq_sentq.ifq_maxlen = 100000;
1920#endif
1921
1922        txq->txq_pendq.ifq_maxlen = 10;
1923#ifndef __rtems__
1924        txq->txq_ei_gapcount = 0;
1925#endif
1926        txq->txq_nactive = 0;
1927        txq->txq_fi = 0;
1928        txq->txq_lo = 0;
1929#ifndef __rtems__
1930        txq->txq_ei_gapcount = 0;
1931        txq->txq_inptr = GE_TXBUF_SIZE;
1932        txq->txq_outptr = 0;
1933#endif
1934        for (i = 0, txd = txq->txq_descs,
1935             addr = txq->txq_desc_busaddr + sizeof(*txd);
1936                        i < GE_TXDESC_MAX - 1;
1937                        i++, txd++, addr += sizeof(*txd)) {
1938                /*
1939                 * update the nxtptr to point to the next txd.
1940                 */
1941                txd->ed_cmdsts = 0;
1942                txd->ed_nxtptr = htogt32(addr);
1943        }
1944        txq->txq_descs[GE_TXDESC_MAX-1].ed_nxtptr =
1945            htogt32(txq->txq_desc_busaddr);
1946        bus_dmamap_sync(sc->sc_dmat, txq->txq_desc_mem.gdm_map, 0,
1947            GE_TXDESC_MEMSIZE, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1948
1949        switch (txprio) {
1950        case GE_TXPRIO_HI:
1951                txq->txq_intrbits = ETH_IR_TxEndHigh|ETH_IR_TxBufferHigh;
1952                txq->txq_esdcmrbits = ETH_ESDCMR_TXDH;
1953                txq->txq_epsrbits = ETH_EPSR_TxHigh;
1954                txq->txq_ectdp = ETH_ECTDP1(sc->sc_macno);
1955                GE_WRITE(sc, ECTDP1, txq->txq_desc_busaddr);
1956                break;
1957
1958        case GE_TXPRIO_LO:
1959                txq->txq_intrbits = ETH_IR_TxEndLow|ETH_IR_TxBufferLow;
1960                txq->txq_esdcmrbits = ETH_ESDCMR_TXDL;
1961                txq->txq_epsrbits = ETH_EPSR_TxLow;
1962                txq->txq_ectdp = ETH_ECTDP0(sc->sc_macno);
1963                GE_WRITE(sc, ECTDP0, txq->txq_desc_busaddr);
1964                break;
1965
1966        case GE_TXPRIO_NONE:
1967                break;
1968        }
1969#if 0
1970        GE_DPRINTF(sc, ("(ectdp=%#x", txq->txq_ectdp));
1971        gt_write(sc->sc_dev.dv_parent, txq->txq_ectdp, txq->txq_desc_busaddr);
1972        GE_DPRINTF(sc, (")"));
1973#endif
1974
1975        /*
1976         * If we are restarting, there may be packets in the pending queue
1977         * waiting to be enqueued.  Try enqueuing packets from both priority
1978         * queues until the pending queue is empty or there no room for them
1979         * on the device.
1980         */
1981        while (gfe_tx_enqueue(sc, txprio))
1982                continue;
1983
1984        GE_FUNC_EXIT(sc, "");
1985        return 0;
1986}
1987
1988void
1989gfe_tx_cleanup(struct gfe_softc *sc, enum gfe_txprio txprio, int flush)
1990{
1991        struct gfe_txqueue * const txq = &sc->sc_txq[txprio];
1992
1993        GE_FUNC_ENTER(sc, "gfe_tx_cleanup");
1994        if (txq == NULL) {
1995                GE_FUNC_EXIT(sc, "");
1996                return;
1997        }
1998
1999        if (!flush) {
2000                GE_FUNC_EXIT(sc, "");
2001                return;
2002        }
2003
2004#ifdef __rtems__
2005        /* reclaim mbufs that were never sent */
2006        {
2007        struct mbuf *m;
2008                while ( txq->txq_sentq.ifq_head ) {
2009                        IF_DEQUEUE(&txq->txq_sentq, m);
2010                        m_freem(m);
2011                }
2012        }
2013#endif
2014
2015        if ((sc->sc_flags & GE_NOFREE) == 0) {
2016                gfe_dmamem_free(sc, &txq->txq_desc_mem);
2017#ifndef __rtems__
2018                gfe_dmamem_free(sc, &txq->txq_buf_mem);
2019#endif
2020        }
2021        GE_FUNC_EXIT(sc, "-F");
2022}
2023
2024void
2025gfe_tx_stop(struct gfe_softc *sc, enum gfe_whack_op op)
2026{
2027        GE_FUNC_ENTER(sc, "gfe_tx_stop");
2028
2029        GE_WRITE(sc, ESDCMR, ETH_ESDCMR_STDH|ETH_ESDCMR_STDL);
2030
2031        sc->sc_intrmask = gfe_tx_done(sc, GE_TXPRIO_HI, sc->sc_intrmask);
2032        sc->sc_intrmask = gfe_tx_done(sc, GE_TXPRIO_LO, sc->sc_intrmask);
2033        sc->sc_intrmask &= ~(ETH_IR_TxEndHigh|ETH_IR_TxBufferHigh|
2034                             ETH_IR_TxEndLow |ETH_IR_TxBufferLow);
2035
2036        gfe_tx_cleanup(sc, GE_TXPRIO_HI, op == GE_WHACK_STOP);
2037        gfe_tx_cleanup(sc, GE_TXPRIO_LO, op == GE_WHACK_STOP);
2038
2039        sc->sc_ec.ec_if.if_timer = 0;
2040        GE_FUNC_EXIT(sc, "");
2041}
2042
2043int
2044gfe_intr(void *arg)
2045{
2046        struct gfe_softc * const sc = arg;
2047        uint32_t cause;
2048        uint32_t intrmask = sc->sc_intrmask;
2049        int claim = 0;
2050        int cnt;
2051
2052        GE_FUNC_ENTER(sc, "gfe_intr");
2053
2054        for (cnt = 0; cnt < 4; cnt++) {
2055                if (sc->sc_intrmask != intrmask) {
2056                        sc->sc_intrmask = intrmask;
2057                        GE_WRITE(sc, EIMR, sc->sc_intrmask);
2058                }
2059                cause = GE_READ(sc, EICR);
2060                cause &= sc->sc_intrmask;
2061                GE_DPRINTF(sc, (".%#" PRIx32, cause));
2062                if (cause == 0)
2063                        break;
2064
2065                claim = 1;
2066
2067                GE_WRITE(sc, EICR, ~cause);
2068#ifndef GE_NORX
2069                if (cause & (ETH_IR_RxBuffer|ETH_IR_RxError))
2070                        intrmask = gfe_rx_process(sc, cause, intrmask);
2071#endif
2072
2073#ifndef GE_NOTX
2074                if (cause & (ETH_IR_TxBufferHigh|ETH_IR_TxEndHigh))
2075                        intrmask = gfe_tx_done(sc, GE_TXPRIO_HI, intrmask);
2076                if (cause & (ETH_IR_TxBufferLow|ETH_IR_TxEndLow))
2077                        intrmask = gfe_tx_done(sc, GE_TXPRIO_LO, intrmask);
2078#endif
2079                if (cause & ETH_IR_MIIPhySTC) {
2080                        sc->sc_flags |= GE_PHYSTSCHG;
2081                        /* intrmask &= ~ETH_IR_MIIPhySTC; */
2082                }
2083        }
2084
2085        while (gfe_tx_enqueue(sc, GE_TXPRIO_HI))
2086                continue;
2087        while (gfe_tx_enqueue(sc, GE_TXPRIO_LO))
2088                continue;
2089
2090        GE_FUNC_EXIT(sc, "");
2091        return claim;
2092}
2093
2094#ifndef __rtems__
2095int
2096gfe_mii_mediachange (struct ifnet *ifp)
2097{
2098        struct gfe_softc *sc = ifp->if_softc;
2099
2100        if (ifp->if_flags & IFF_UP)
2101                mii_mediachg(&sc->sc_mii);
2102
2103        return (0);
2104}
2105void
2106gfe_mii_mediastatus (struct ifnet *ifp, struct ifmediareq *ifmr)
2107{
2108        struct gfe_softc *sc = ifp->if_softc;
2109
2110        if (sc->sc_flags & GE_PHYSTSCHG) {
2111                sc->sc_flags &= ~GE_PHYSTSCHG;
2112                mii_pollstat(&sc->sc_mii);
2113        }
2114        ifmr->ifm_status = sc->sc_mii.mii_media_status;
2115        ifmr->ifm_active = sc->sc_mii.mii_media_active;
2116}
2117
2118int
2119gfe_mii_read (struct device *self, int phy, int reg)
2120{
2121        return gt_mii_read(self, self->dv_parent, phy, reg);
2122}
2123
2124void
2125gfe_mii_write (struct device *self, int phy, int reg, int value)
2126{
2127        gt_mii_write(self, self->dv_parent, phy, reg, value);
2128}
2129
2130void
2131gfe_mii_statchg (struct device *self)
2132{
2133        /* struct gfe_softc *sc = (struct gfe_softc *) self; */
2134        /* do nothing? */
2135}
2136
2137#else
2138int
2139gfe_mii_read(int phy, void *arg, unsigned reg, uint32_t *pval)
2140{
2141        struct gfe_softc *sc = arg;
2142        uint32_t data;
2143        int count = 10000;
2144
2145        if ( 0 != phy )
2146                return -1; /* invalid index */
2147
2148        phy = sc->sc_phyaddr;
2149
2150        do {
2151                DELAY(10);
2152                data = GT_READ(sc, ETH_ESMIR);
2153        } while ((data & ETH_ESMIR_Busy) && count-- > 0);
2154
2155        if (count == 0) {
2156                fprintf(stderr,"%s: mii read for phy %d reg %d busied out\n",
2157                        sc->sc_dev.dv_xname, phy, reg);
2158                *pval = ETH_ESMIR_Value_GET(data);
2159                return -1;
2160        }
2161
2162        GT_WRITE(sc, ETH_ESMIR, ETH_ESMIR_READ(phy, reg));
2163
2164        count = 10000;
2165        do {
2166                DELAY(10);
2167                data = GT_READ(sc, ETH_ESMIR);
2168        } while ((data & ETH_ESMIR_ReadValid) == 0 && count-- > 0);
2169
2170        if (count == 0)
2171                printf("%s: mii read for phy %d reg %d timed out\n",
2172                        sc->sc_dev.dv_xname, phy, reg);
2173#if defined(GTMIIDEBUG)
2174        printf("%s: mii_read(%d, %d): %#x data %#x\n",
2175                sc->sc_dev.dv_xname, phy, reg,
2176                data, ETH_ESMIR_Value_GET(data));
2177#endif
2178        *pval = ETH_ESMIR_Value_GET(data);
2179        return 0;
2180}
2181
2182int
2183gfe_mii_write(int phy, void *arg, unsigned reg, uint32_t value)
2184{
2185        struct gfe_softc *sc = arg;
2186        uint32_t data;
2187        int count = 10000;
2188
2189        if ( 0 != phy )
2190                return -1; /* invalid index */
2191
2192        phy = sc->sc_phyaddr;
2193
2194        do {
2195                DELAY(10);
2196                data = GT_READ(sc, ETH_ESMIR);
2197        } while ((data & ETH_ESMIR_Busy) && count-- > 0);
2198
2199        if (count == 0) {
2200                fprintf(stderr, "%s: mii write for phy %d reg %d busied out (busy)\n",
2201                        sc->sc_dev.dv_xname, phy, reg);
2202                return -1;
2203        }
2204
2205        GT_WRITE(sc, ETH_ESMIR,
2206                 ETH_ESMIR_WRITE(phy, reg, value));
2207
2208        count = 10000;
2209        do {
2210                DELAY(10);
2211                data = GT_READ(sc, ETH_ESMIR);
2212        } while ((data & ETH_ESMIR_Busy) && count-- > 0);
2213
2214        if (count == 0)
2215                printf("%s: mii write for phy %d reg %d timed out\n",
2216                        sc->sc_dev.dv_xname, phy, reg);
2217#if defined(GTMIIDEBUG)
2218        printf("%s: mii_write(%d, %d, %#x)\n",
2219                sc->sc_dev.dv_xname, phy, reg, value);
2220#endif
2221        return 0;
2222}
2223
2224#endif
2225int
2226gfe_whack(struct gfe_softc *sc, enum gfe_whack_op op)
2227{
2228        int error = 0;
2229        GE_FUNC_ENTER(sc, "gfe_whack");
2230
2231        switch (op) {
2232        case GE_WHACK_RESTART:
2233#ifndef GE_NOTX
2234                gfe_tx_stop(sc, op);
2235#endif
2236                /* sc->sc_ec.ec_if.if_flags &= ~IFF_RUNNING; */
2237                /* FALLTHROUGH */
2238        case GE_WHACK_START:
2239#ifndef GE_NOHASH
2240                if (error == 0 && sc->sc_hashtable == NULL) {
2241                        error = gfe_hash_alloc(sc);
2242                        if (error)
2243                                break;
2244                }
2245                if (op != GE_WHACK_RESTART)
2246                        gfe_hash_fill(sc);
2247#endif
2248#ifndef GE_NORX
2249                if (op != GE_WHACK_RESTART) {
2250                        error = gfe_rx_prime(sc);
2251                        if (error)
2252                                break;
2253                }
2254#endif
2255#ifndef GE_NOTX
2256                error = gfe_tx_start(sc, GE_TXPRIO_HI);
2257                if (error)
2258                        break;
2259#endif
2260                sc->sc_ec.ec_if.if_flags |= IFF_RUNNING;
2261                GE_WRITE(sc, EPCR, sc->sc_pcr | ETH_EPCR_EN);
2262                GE_WRITE(sc, EPCXR, sc->sc_pcxr);
2263                GE_WRITE(sc, EICR, 0);
2264                GE_WRITE(sc, EIMR, sc->sc_intrmask);
2265#ifndef GE_NOHASH
2266                GE_WRITE(sc, EHTPR, sc->sc_hash_mem.gdm_map->dm_segs->ds_addr);
2267#endif
2268#ifndef GE_NORX
2269                GE_WRITE(sc, ESDCMR, ETH_ESDCMR_ERD);
2270                sc->sc_flags |= GE_RXACTIVE;
2271#endif
2272                /* FALLTHROUGH */
2273        case GE_WHACK_CHANGE:
[4f5d1c9f]2274                GE_DPRINTF(sc, ("(pcr=%#" PRIx32 ",imr=%#" PRIx32 ")",
[b7a6d23a]2275                    GE_READ(sc, EPCR), GE_READ(sc, EIMR)));
2276                GE_WRITE(sc, EPCR, sc->sc_pcr | ETH_EPCR_EN);
2277                GE_WRITE(sc, EIMR, sc->sc_intrmask);
2278                gfe_ifstart(&sc->sc_ec.ec_if);
[4f5d1c9f]2279                GE_DPRINTF(sc, ("(ectdp0=%#" PRIx32 ", ectdp1=%#" PRIx32 ")",
[b7a6d23a]2280                    GE_READ(sc, ECTDP0), GE_READ(sc, ECTDP1)));
2281                GE_FUNC_EXIT(sc, "");
2282                return error;
2283        case GE_WHACK_STOP:
2284                break;
2285        }
2286
2287#ifdef GE_DEBUG
2288        if (error)
2289                GE_DPRINTF(sc, (" failed: %d\n", error));
2290#endif
2291        GE_WRITE(sc, EPCR, sc->sc_pcr);
2292        GE_WRITE(sc, EIMR, 0);
2293        sc->sc_ec.ec_if.if_flags &= ~IFF_RUNNING;
2294#ifndef GE_NOTX
2295        gfe_tx_stop(sc, GE_WHACK_STOP);
2296#endif
2297#ifndef GE_NORX
2298        gfe_rx_stop(sc, GE_WHACK_STOP);
2299#endif
2300#ifndef GE_NOHASH
2301        if ((sc->sc_flags & GE_NOFREE) == 0) {
2302                gfe_dmamem_free(sc, &sc->sc_hash_mem);
2303                sc->sc_hashtable = NULL;
2304        }
2305#endif
2306
2307        GE_FUNC_EXIT(sc, "");
2308        return error;
2309}
2310
2311int
2312gfe_hash_compute(struct gfe_softc *sc, const uint8_t eaddr[ETHER_ADDR_LEN])
2313{
2314        uint32_t w0, add0, add1;
2315        uint32_t result;
2316#ifdef __rtems__
2317        SPRINTFVARDECL;
2318#endif
2319
2320        GE_FUNC_ENTER(sc, "gfe_hash_compute");
2321        add0 = ((uint32_t) eaddr[5] <<  0) |
2322               ((uint32_t) eaddr[4] <<  8) |
2323               ((uint32_t) eaddr[3] << 16);
2324
2325        add0 = ((add0 & 0x00f0f0f0) >> 4) | ((add0 & 0x000f0f0f) << 4);
2326        add0 = ((add0 & 0x00cccccc) >> 2) | ((add0 & 0x00333333) << 2);
2327        add0 = ((add0 & 0x00aaaaaa) >> 1) | ((add0 & 0x00555555) << 1);
2328
2329        add1 = ((uint32_t) eaddr[2] <<  0) |
2330               ((uint32_t) eaddr[1] <<  8) |
2331               ((uint32_t) eaddr[0] << 16);
2332
2333        add1 = ((add1 & 0x00f0f0f0) >> 4) | ((add1 & 0x000f0f0f) << 4);
2334        add1 = ((add1 & 0x00cccccc) >> 2) | ((add1 & 0x00333333) << 2);
2335        add1 = ((add1 & 0x00aaaaaa) >> 1) | ((add1 & 0x00555555) << 1);
2336
2337        GE_DPRINTF(sc, ("%s=", ether_sprintf(eaddr)));
2338        /*
2339         * hashResult is the 15 bits Hash entry address.
2340         * ethernetADD is a 48 bit number, which is derived from the Ethernet
2341         *      MAC address, by nibble swapping in every byte (i.e MAC address
2342         *      of 0x123456789abc translates to ethernetADD of 0x21436587a9cb).
2343         */
2344
2345        if ((sc->sc_pcr & ETH_EPCR_HM) == 0) {
2346                /*
2347                 * hashResult[14:0] = hashFunc0(ethernetADD[47:0])
2348                 *
2349                 * hashFunc0 calculates the hashResult in the following manner:
2350                 *   hashResult[ 8:0] = ethernetADD[14:8,1,0]
2351                 *              XOR ethernetADD[23:15] XOR ethernetADD[32:24]
2352                 */
2353                result = (add0 & 3) | ((add0 >> 6) & ~3);
2354                result ^= (add0 >> 15) ^ (add1 >>  0);
2355                result &= 0x1ff;
2356                /*
2357                 *   hashResult[14:9] = ethernetADD[7:2]
2358                 */
2359                result |= (add0 & ~3) << 7;     /* excess bits will be masked */
2360                GE_DPRINTF(sc, ("0(%#"PRIx32")", result & 0x7fff));
2361        } else {
2362#define TRIBITFLIP      073516240       /* yes its in octal */
2363                /*
2364                 * hashResult[14:0] = hashFunc1(ethernetADD[47:0])
2365                 *
2366                 * hashFunc1 calculates the hashResult in the following manner:
2367                 *   hashResult[08:00] = ethernetADD[06:14]
2368                 *              XOR ethernetADD[15:23] XOR ethernetADD[24:32]
2369                 */
2370                w0 = ((add0 >> 6) ^ (add0 >> 15) ^ (add1)) & 0x1ff;
2371                /*
2372                 * Now bitswap those 9 bits
2373                 */
2374                result = 0;
2375                result |= ((TRIBITFLIP >> (((w0 >> 0) & 7) * 3)) & 7) << 6;
2376                result |= ((TRIBITFLIP >> (((w0 >> 3) & 7) * 3)) & 7) << 3;
2377                result |= ((TRIBITFLIP >> (((w0 >> 6) & 7) * 3)) & 7) << 0;
2378
2379                /*
2380                 *   hashResult[14:09] = ethernetADD[00:05]
2381                 */
2382                result |= ((TRIBITFLIP >> (((add0 >> 0) & 7) * 3)) & 7) << 12;
2383                result |= ((TRIBITFLIP >> (((add0 >> 3) & 7) * 3)) & 7) << 9;
2384                GE_DPRINTF(sc, ("1(%#"PRIx32")", result));
2385        }
2386        GE_FUNC_EXIT(sc, "");
2387        return result & ((sc->sc_pcr & ETH_EPCR_HS_512) ? 0x7ff : 0x7fff);
2388}
2389
2390int
2391gfe_hash_entry_op(struct gfe_softc *sc, enum gfe_hash_op op,
2392        enum gfe_rxprio prio, const uint8_t eaddr[ETHER_ADDR_LEN])
2393{
2394        uint64_t he;
2395        uint64_t *maybe_he_p = NULL;
2396        int limit;
2397        int hash;
2398        int maybe_hash = 0;
2399
2400        GE_FUNC_ENTER(sc, "gfe_hash_entry_op");
2401
2402        hash = gfe_hash_compute(sc, eaddr);
2403
2404        if (sc->sc_hashtable == NULL) {
2405                panic("%s:%d: hashtable == NULL!", sc->sc_dev.dv_xname,
2406                        __LINE__);
2407        }
2408
2409        /*
2410         * Assume we are going to insert so create the hash entry we
2411         * are going to insert.  We also use it to match entries we
2412         * will be removing.
2413         */
2414        he = ((uint64_t) eaddr[5] << 43) |
2415             ((uint64_t) eaddr[4] << 35) |
2416             ((uint64_t) eaddr[3] << 27) |
2417             ((uint64_t) eaddr[2] << 19) |
2418             ((uint64_t) eaddr[1] << 11) |
2419             ((uint64_t) eaddr[0] <<  3) |
2420             HSH_PRIO_INS(prio) | HSH_V | HSH_R;
2421
2422        /*
2423         * The GT will search upto 12 entries for a hit, so we must mimic that.
2424         */
2425        hash &= sc->sc_hashmask / sizeof(he);
2426        for (limit = HSH_LIMIT; limit > 0 ; --limit) {
2427                /*
2428                 * Does the GT wrap at the end, stop at the, or overrun the
2429                 * end?  Assume it wraps for now.  Stash a copy of the
2430                 * current hash entry.
2431                 */
2432                uint64_t *he_p = &sc->sc_hashtable[hash];
2433                uint64_t thishe = *he_p;
2434
2435                /*
2436                 * If the hash entry isn't valid, that break the chain.  And
2437                 * this entry a good candidate for reuse.
2438                 */
2439                if ((thishe & HSH_V) == 0) {
2440                        maybe_he_p = he_p;
2441                        break;
2442                }
2443
2444                /*
2445                 * If the hash entry has the same address we are looking for
2446                 * then ...  if we are removing and the skip bit is set, its
2447                 * already been removed.  if are adding and the skip bit is
2448                 * clear, then its already added.  In either return EBUSY
2449                 * indicating the op has already been done.  Otherwise flip
2450                 * the skip bit and return 0.
2451                 */
2452                if (((he ^ thishe) & HSH_ADDR_MASK) == 0) {
2453                        if (((op == GE_HASH_REMOVE) && (thishe & HSH_S)) ||
2454                            ((op == GE_HASH_ADD) && (thishe & HSH_S) == 0))
2455                                return EBUSY;
2456                        *he_p = thishe ^ HSH_S;
2457                        bus_dmamap_sync(sc->sc_dmat, sc->sc_hash_mem.gdm_map,
2458                            hash * sizeof(he), sizeof(he),
2459                            BUS_DMASYNC_PREWRITE);
2460                        GE_FUNC_EXIT(sc, "^");
2461                        return 0;
2462                }
2463
2464                /*
2465                 * If we haven't found a slot for the entry and this entry
2466                 * is currently being skipped, return this entry.
2467                 */
2468                if (maybe_he_p == NULL && (thishe & HSH_S)) {
2469                        maybe_he_p = he_p;
2470                        maybe_hash = hash;
2471                }
2472
2473                hash = (hash + 1) & (sc->sc_hashmask / sizeof(he));
2474        }
2475
2476        /*
2477         * If we got here, then there was no entry to remove.
2478         */
2479        if (op == GE_HASH_REMOVE) {
2480                GE_FUNC_EXIT(sc, "?");
2481                return ENOENT;
2482        }
2483
2484        /*
2485         * If we couldn't find a slot, return an error.
2486         */
2487        if (maybe_he_p == NULL) {
2488                GE_FUNC_EXIT(sc, "!");
2489                return ENOSPC;
2490        }
2491
2492        /* Update the entry.
2493         */
2494        *maybe_he_p = he;
2495        bus_dmamap_sync(sc->sc_dmat, sc->sc_hash_mem.gdm_map,
2496            maybe_hash * sizeof(he), sizeof(he), BUS_DMASYNC_PREWRITE);
2497        GE_FUNC_EXIT(sc, "+");
2498        return 0;
2499}
2500
2501#ifndef __rtems__
2502int
2503gfe_hash_multichg(struct ethercom *ec, const struct ether_multi *enm, u_long cmd)
2504{
2505        struct gfe_softc * const sc = ec->ec_if.if_softc;
2506        int error;
2507        enum gfe_hash_op op;
2508        enum gfe_rxprio prio;
2509#ifdef __rtems__
2510        SPRINTFVARDECL;
2511#endif
2512
2513        GE_FUNC_ENTER(sc, "hash_multichg");
2514        /*
2515         * Is this a wildcard entry?  If so and its being removed, recompute.
2516         */
2517        if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN) != 0) {
2518                if (cmd == SIOCDELMULTI) {
2519                        GE_FUNC_EXIT(sc, "");
2520                        return ENETRESET;
2521                }
2522
2523                /*
2524                 * Switch in
2525                 */
2526                sc->sc_flags |= GE_ALLMULTI;
2527                if ((sc->sc_pcr & ETH_EPCR_PM) == 0) {
2528                        sc->sc_pcr |= ETH_EPCR_PM;
2529                        GE_WRITE(sc, EPCR, sc->sc_pcr);
2530                        GE_FUNC_EXIT(sc, "");
2531                        return 0;
2532                }
2533                GE_FUNC_EXIT(sc, "");
2534                return ENETRESET;
2535        }
2536
2537        prio = GE_RXPRIO_MEDLO;
2538        op = (cmd == SIOCDELMULTI ? GE_HASH_REMOVE : GE_HASH_ADD);
2539
2540        if (sc->sc_hashtable == NULL) {
2541                GE_FUNC_EXIT(sc, "");
2542                return 0;
2543        }
2544
2545        error = gfe_hash_entry_op(sc, op, prio, enm->enm_addrlo);
2546        if (error == EBUSY) {
2547                printf("%s: multichg: tried to %s %s again\n",
2548                       sc->sc_dev.dv_xname,
2549                       cmd == SIOCDELMULTI ? "remove" : "add",
2550                       ether_sprintf(enm->enm_addrlo));
2551                GE_FUNC_EXIT(sc, "");
2552                return 0;
2553        }
2554
2555        if (error == ENOENT) {
2556                printf("%s: multichg: failed to remove %s: not in table\n",
2557                       sc->sc_dev.dv_xname,
2558                       ether_sprintf(enm->enm_addrlo));
2559                GE_FUNC_EXIT(sc, "");
2560                return 0;
2561        }
2562
2563        if (error == ENOSPC) {
2564                printf("%s: multichg: failed to add %s: no space; regenerating table\n",
2565                       sc->sc_dev.dv_xname,
2566                       ether_sprintf(enm->enm_addrlo));
2567                GE_FUNC_EXIT(sc, "");
2568                return ENETRESET;
2569        }
2570        GE_DPRINTF(sc, ("%s: multichg: %s: %s succeeded\n",
2571               sc->sc_dev.dv_xname,
2572               cmd == SIOCDELMULTI ? "remove" : "add",
2573               ether_sprintf(enm->enm_addrlo)));
2574        GE_FUNC_EXIT(sc, "");
2575        return 0;
2576}
2577#endif
2578
2579int
2580gfe_hash_fill(struct gfe_softc *sc)
2581{
2582        struct ether_multistep step;
2583        struct ether_multi *enm;
2584        int error;
2585
2586        GE_FUNC_ENTER(sc, "gfe_hash_fill");
2587
2588#ifndef __rtems__
2589        error = gfe_hash_entry_op(sc, GE_HASH_ADD, GE_RXPRIO_HI,
2590            LLADDR(sc->sc_ec.ec_if.if_sadl));
2591#else
2592        error = gfe_hash_entry_op(sc, GE_HASH_ADD, GE_RXPRIO_HI, sc->sc_ec.ac_enaddr);
2593#endif
2594        if (error) {
2595                GE_FUNC_EXIT(sc, "!");
2596                return error;
2597        }
2598
2599        sc->sc_flags &= ~GE_ALLMULTI;
2600        if ((sc->sc_ec.ec_if.if_flags & IFF_PROMISC) == 0)
2601                sc->sc_pcr &= ~ETH_EPCR_PM;
2602        else
2603                sc->sc_pcr |=  ETH_EPCR_PM;
2604        ETHER_FIRST_MULTI(step, &sc->sc_ec, enm);
2605        while (enm != NULL) {
2606                if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
2607                        sc->sc_flags |= GE_ALLMULTI;
2608                        sc->sc_pcr |= ETH_EPCR_PM;
2609                } else {
2610                        error = gfe_hash_entry_op(sc, GE_HASH_ADD,
2611                            GE_RXPRIO_MEDLO, enm->enm_addrlo);
2612                        if (error == ENOSPC)
2613                                break;
2614                }
2615                ETHER_NEXT_MULTI(step, enm);
2616        }
2617
2618        GE_FUNC_EXIT(sc, "");
2619        return error;
2620}
2621
2622int
2623gfe_hash_alloc(struct gfe_softc *sc)
2624{
2625        int error;
2626        GE_FUNC_ENTER(sc, "gfe_hash_alloc");
2627        sc->sc_hashmask = (sc->sc_pcr & ETH_EPCR_HS_512 ? 16 : 256)*1024 - 1;
2628        error = gfe_dmamem_alloc(sc, &sc->sc_hash_mem, 1, sc->sc_hashmask + 1,
2629            BUS_DMA_NOCACHE);
2630        if (error) {
2631                printf("%s: failed to allocate %d bytes for hash table: %d\n",
2632                    sc->sc_dev.dv_xname, sc->sc_hashmask + 1, error);
2633                GE_FUNC_EXIT(sc, "");
2634                return error;
2635        }
2636        sc->sc_hashtable = (uint64_t *) sc->sc_hash_mem.gdm_kva;
2637        memset(sc->sc_hashtable, 0, sc->sc_hashmask + 1);
2638        bus_dmamap_sync(sc->sc_dmat, sc->sc_hash_mem.gdm_map,
2639            0, sc->sc_hashmask + 1, BUS_DMASYNC_PREWRITE);
2640        GE_FUNC_EXIT(sc, "");
2641        return 0;
2642}
Note: See TracBrowser for help on using the repository browser.