Home | History | Annotate | Line # | Download | only in pci
if_xge.c revision 1.2.18.2
      1  1.2.18.2  yamt /*      $NetBSD: if_xge.c,v 1.2.18.2 2006/06/21 15:05:05 yamt Exp $ */
      2  1.2.18.2  yamt 
      3  1.2.18.2  yamt /*
      4  1.2.18.2  yamt  * Copyright (c) 2004, SUNET, Swedish University Computer Network.
      5  1.2.18.2  yamt  * All rights reserved.
      6  1.2.18.2  yamt  *
      7  1.2.18.2  yamt  * Written by Anders Magnusson for SUNET, Swedish University Computer Network.
      8  1.2.18.2  yamt  *
      9  1.2.18.2  yamt  * Redistribution and use in source and binary forms, with or without
     10  1.2.18.2  yamt  * modification, are permitted provided that the following conditions
     11  1.2.18.2  yamt  * are met:
     12  1.2.18.2  yamt  * 1. Redistributions of source code must retain the above copyright
     13  1.2.18.2  yamt  *    notice, this list of conditions and the following disclaimer.
     14  1.2.18.2  yamt  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.2.18.2  yamt  *    notice, this list of conditions and the following disclaimer in the
     16  1.2.18.2  yamt  *    documentation and/or other materials provided with the distribution.
     17  1.2.18.2  yamt  * 3. All advertising materials mentioning features or use of this software
     18  1.2.18.2  yamt  *    must display the following acknowledgement:
     19  1.2.18.2  yamt  *      This product includes software developed for the NetBSD Project by
     20  1.2.18.2  yamt  *      SUNET, Swedish University Computer Network.
     21  1.2.18.2  yamt  * 4. The name of SUNET may not be used to endorse or promote products
     22  1.2.18.2  yamt  *    derived from this software without specific prior written permission.
     23  1.2.18.2  yamt  *
     24  1.2.18.2  yamt  * THIS SOFTWARE IS PROVIDED BY SUNET ``AS IS'' AND
     25  1.2.18.2  yamt  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     26  1.2.18.2  yamt  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     27  1.2.18.2  yamt  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL SUNET
     28  1.2.18.2  yamt  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     29  1.2.18.2  yamt  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     30  1.2.18.2  yamt  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     31  1.2.18.2  yamt  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     32  1.2.18.2  yamt  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     33  1.2.18.2  yamt  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     34  1.2.18.2  yamt  * POSSIBILITY OF SUCH DAMAGE.
     35  1.2.18.2  yamt  */
     36  1.2.18.2  yamt 
     37  1.2.18.2  yamt /*
     38  1.2.18.2  yamt  * Device driver for the S2io Xframe Ten Gigabit Ethernet controller.
     39  1.2.18.2  yamt  *
     40  1.2.18.2  yamt  * TODO (in no specific order):
     41  1.2.18.2  yamt  *	HW VLAN support.
     42  1.2.18.2  yamt  *	IPv6 HW cksum.
     43  1.2.18.2  yamt  */
     44  1.2.18.2  yamt 
     45  1.2.18.2  yamt #include <sys/cdefs.h>
     46  1.2.18.2  yamt __KERNEL_RCSID(0, "$NetBSD: if_xge.c,v 1.2.18.2 2006/06/21 15:05:05 yamt Exp $");
     47  1.2.18.2  yamt 
     48  1.2.18.2  yamt #include "bpfilter.h"
     49  1.2.18.2  yamt #include "rnd.h"
     50  1.2.18.2  yamt 
     51  1.2.18.2  yamt #include <sys/param.h>
     52  1.2.18.2  yamt #include <sys/systm.h>
     53  1.2.18.2  yamt #include <sys/mbuf.h>
     54  1.2.18.2  yamt #include <sys/malloc.h>
     55  1.2.18.2  yamt #include <sys/kernel.h>
     56  1.2.18.2  yamt #include <sys/socket.h>
     57  1.2.18.2  yamt #include <sys/device.h>
     58  1.2.18.2  yamt 
     59  1.2.18.2  yamt #if NRND > 0
     60  1.2.18.2  yamt #include <sys/rnd.h>
     61  1.2.18.2  yamt #endif
     62  1.2.18.2  yamt 
     63  1.2.18.2  yamt #include <net/if.h>
     64  1.2.18.2  yamt #include <net/if_dl.h>
     65  1.2.18.2  yamt #include <net/if_media.h>
     66  1.2.18.2  yamt #include <net/if_ether.h>
     67  1.2.18.2  yamt 
     68  1.2.18.2  yamt #if NBPFILTER > 0
     69  1.2.18.2  yamt #include <net/bpf.h>
     70  1.2.18.2  yamt #endif
     71  1.2.18.2  yamt 
     72  1.2.18.2  yamt #include <machine/bus.h>
     73  1.2.18.2  yamt #include <machine/intr.h>
     74  1.2.18.2  yamt #include <machine/endian.h>
     75  1.2.18.2  yamt 
     76  1.2.18.2  yamt #include <dev/mii/mii.h>
     77  1.2.18.2  yamt #include <dev/mii/miivar.h>
     78  1.2.18.2  yamt 
     79  1.2.18.2  yamt #include <dev/pci/pcivar.h>
     80  1.2.18.2  yamt #include <dev/pci/pcireg.h>
     81  1.2.18.2  yamt #include <dev/pci/pcidevs.h>
     82  1.2.18.2  yamt 
     83  1.2.18.2  yamt #include <sys/lock.h>
     84  1.2.18.2  yamt #include <sys/proc.h>
     85  1.2.18.2  yamt 
     86  1.2.18.2  yamt #include <dev/pci/if_xgereg.h>
     87  1.2.18.2  yamt 
     88  1.2.18.2  yamt /*
     89  1.2.18.2  yamt  * Some tunable constants, tune with care!
     90  1.2.18.2  yamt  */
     91  1.2.18.2  yamt #define RX_MODE		RX_MODE_1  /* Receive mode (buffer usage, see below) */
     92  1.2.18.2  yamt #define NRXDESCS	1016	   /* # of receive descriptors (requested) */
     93  1.2.18.2  yamt #define NTXDESCS	8192	   /* Number of transmit descriptors */
     94  1.2.18.2  yamt #define NTXFRAGS	100	   /* Max fragments per packet */
     95  1.2.18.2  yamt #define XGE_EVENT_COUNTERS	   /* Instrumentation */
     96  1.2.18.2  yamt 
     97  1.2.18.2  yamt /*
     98  1.2.18.2  yamt  * Receive buffer modes; 1, 3 or 5 buffers.
     99  1.2.18.2  yamt  */
    100  1.2.18.2  yamt #define RX_MODE_1 1
    101  1.2.18.2  yamt #define RX_MODE_3 3
    102  1.2.18.2  yamt #define RX_MODE_5 5
    103  1.2.18.2  yamt 
    104  1.2.18.2  yamt /*
    105  1.2.18.2  yamt  * Use clever macros to avoid a bunch of #ifdef's.
    106  1.2.18.2  yamt  */
    107  1.2.18.2  yamt #define XCONCAT3(x,y,z) x ## y ## z
    108  1.2.18.2  yamt #define CONCAT3(x,y,z) XCONCAT3(x,y,z)
    109  1.2.18.2  yamt #define NDESC_BUFMODE CONCAT3(NDESC_,RX_MODE,BUFMODE)
    110  1.2.18.2  yamt #define rxd_4k CONCAT3(rxd,RX_MODE,_4k)
    111  1.2.18.2  yamt #define rxdesc ___CONCAT(rxd,RX_MODE)
    112  1.2.18.2  yamt 
    113  1.2.18.2  yamt #define NEXTTX(x)	(((x)+1) % NTXDESCS)
    114  1.2.18.2  yamt #define NRXFRAGS	RX_MODE /* hardware imposed frags */
    115  1.2.18.2  yamt #define NRXPAGES	((NRXDESCS/NDESC_BUFMODE)+1)
    116  1.2.18.2  yamt #define NRXREAL		(NRXPAGES*NDESC_BUFMODE)
    117  1.2.18.2  yamt #define RXMAPSZ		(NRXPAGES*PAGE_SIZE)
    118  1.2.18.2  yamt 
    119  1.2.18.2  yamt #ifdef XGE_EVENT_COUNTERS
    120  1.2.18.2  yamt #define XGE_EVCNT_INCR(ev)	(ev)->ev_count++
    121  1.2.18.2  yamt #else
    122  1.2.18.2  yamt #define XGE_EVCNT_INCR(ev)	/* nothing */
    123  1.2.18.2  yamt #endif
    124  1.2.18.2  yamt 
    125  1.2.18.2  yamt /*
    126  1.2.18.2  yamt  * Magics to fix a bug when the mac address can't be read correctly.
    127  1.2.18.2  yamt  * Comes from the Linux driver.
    128  1.2.18.2  yamt  */
    129  1.2.18.2  yamt static uint64_t fix_mac[] = {
    130  1.2.18.2  yamt 	0x0060000000000000ULL, 0x0060600000000000ULL,
    131  1.2.18.2  yamt 	0x0040600000000000ULL, 0x0000600000000000ULL,
    132  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    133  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    134  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    135  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    136  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    137  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    138  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    139  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    140  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    141  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0060600000000000ULL,
    142  1.2.18.2  yamt 	0x0020600000000000ULL, 0x0000600000000000ULL,
    143  1.2.18.2  yamt 	0x0040600000000000ULL, 0x0060600000000000ULL,
    144  1.2.18.2  yamt };
    145  1.2.18.2  yamt 
    146  1.2.18.2  yamt 
    147  1.2.18.2  yamt struct xge_softc {
    148  1.2.18.2  yamt 	struct device sc_dev;
    149  1.2.18.2  yamt 	struct ethercom sc_ethercom;
    150  1.2.18.2  yamt #define sc_if sc_ethercom.ec_if
    151  1.2.18.2  yamt 	bus_dma_tag_t sc_dmat;
    152  1.2.18.2  yamt 	bus_space_tag_t sc_st;
    153  1.2.18.2  yamt 	bus_space_handle_t sc_sh;
    154  1.2.18.2  yamt 	bus_space_tag_t sc_txt;
    155  1.2.18.2  yamt 	bus_space_handle_t sc_txh;
    156  1.2.18.2  yamt 	void *sc_ih;
    157  1.2.18.2  yamt 
    158  1.2.18.2  yamt 	struct ifmedia xena_media;
    159  1.2.18.2  yamt 	pcireg_t sc_pciregs[16];
    160  1.2.18.2  yamt 
    161  1.2.18.2  yamt 	/* Transmit structures */
    162  1.2.18.2  yamt 	struct txd *sc_txd[NTXDESCS];	/* transmit frags array */
    163  1.2.18.2  yamt 	bus_addr_t sc_txdp[NTXDESCS];	/* bus address of transmit frags */
    164  1.2.18.2  yamt 	bus_dmamap_t sc_txm[NTXDESCS];	/* transmit frags map */
    165  1.2.18.2  yamt 	struct mbuf *sc_txb[NTXDESCS];	/* transmit mbuf pointer */
    166  1.2.18.2  yamt 	int sc_nexttx, sc_lasttx;
    167  1.2.18.2  yamt 	bus_dmamap_t sc_txmap;		/* transmit descriptor map */
    168  1.2.18.2  yamt 
    169  1.2.18.2  yamt 	/* Receive data */
    170  1.2.18.2  yamt 	bus_dmamap_t sc_rxmap;		/* receive descriptor map */
    171  1.2.18.2  yamt 	struct rxd_4k *sc_rxd_4k[NRXPAGES]; /* receive desc pages */
    172  1.2.18.2  yamt 	bus_dmamap_t sc_rxm[NRXREAL];	/* receive buffer map */
    173  1.2.18.2  yamt 	struct mbuf *sc_rxb[NRXREAL];	/* mbufs on receive descriptors */
    174  1.2.18.2  yamt 	int sc_nextrx;			/* next descriptor to check */
    175  1.2.18.2  yamt 
    176  1.2.18.2  yamt #ifdef XGE_EVENT_COUNTERS
    177  1.2.18.2  yamt 	struct evcnt sc_intr;	/* # of interrupts */
    178  1.2.18.2  yamt 	struct evcnt sc_txintr;	/* # of transmit interrupts */
    179  1.2.18.2  yamt 	struct evcnt sc_rxintr;	/* # of receive interrupts */
    180  1.2.18.2  yamt 	struct evcnt sc_txqe;	/* # of xmit intrs when board queue empty */
    181  1.2.18.2  yamt #endif
    182  1.2.18.2  yamt };
    183  1.2.18.2  yamt 
    184  1.2.18.2  yamt static int xge_match(struct device *parent, struct cfdata *cf, void *aux);
    185  1.2.18.2  yamt static void xge_attach(struct device *parent, struct device *self, void *aux);
    186  1.2.18.2  yamt static int xge_alloc_txmem(struct xge_softc *);
    187  1.2.18.2  yamt static int xge_alloc_rxmem(struct xge_softc *);
    188  1.2.18.2  yamt static void xge_start(struct ifnet *);
    189  1.2.18.2  yamt static void xge_stop(struct ifnet *, int);
    190  1.2.18.2  yamt static int xge_add_rxbuf(struct xge_softc *, int);
    191  1.2.18.2  yamt static void xge_mcast_filter(struct xge_softc *sc);
    192  1.2.18.2  yamt static int xge_setup_xgxs(struct xge_softc *sc);
    193  1.2.18.2  yamt static int xge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data);
    194  1.2.18.2  yamt static int xge_init(struct ifnet *ifp);
    195  1.2.18.2  yamt static void xge_ifmedia_status(struct ifnet *, struct ifmediareq *);
    196  1.2.18.2  yamt static int xge_xgmii_mediachange(struct ifnet *);
    197  1.2.18.2  yamt static int xge_intr(void  *);
    198  1.2.18.2  yamt 
    199  1.2.18.2  yamt /*
    200  1.2.18.2  yamt  * Helpers to address registers.
    201  1.2.18.2  yamt  */
    202  1.2.18.2  yamt #define PIF_WCSR(csr, val)	pif_wcsr(sc, csr, val)
    203  1.2.18.2  yamt #define PIF_RCSR(csr)		pif_rcsr(sc, csr)
    204  1.2.18.2  yamt #define TXP_WCSR(csr, val)	txp_wcsr(sc, csr, val)
    205  1.2.18.2  yamt #define PIF_WKEY(csr, val)	pif_wkey(sc, csr, val)
    206  1.2.18.2  yamt 
    207  1.2.18.2  yamt static inline void
    208  1.2.18.2  yamt pif_wcsr(struct xge_softc *sc, bus_size_t csr, uint64_t val)
    209  1.2.18.2  yamt {
    210  1.2.18.2  yamt 	uint32_t lval, hval;
    211  1.2.18.2  yamt 
    212  1.2.18.2  yamt 	lval = val&0xffffffff;
    213  1.2.18.2  yamt 	hval = val>>32;
    214  1.2.18.2  yamt 	bus_space_write_4(sc->sc_st, sc->sc_sh, csr, lval);
    215  1.2.18.2  yamt 	bus_space_write_4(sc->sc_st, sc->sc_sh, csr+4, hval);
    216  1.2.18.2  yamt }
    217  1.2.18.2  yamt 
    218  1.2.18.2  yamt static inline uint64_t
    219  1.2.18.2  yamt pif_rcsr(struct xge_softc *sc, bus_size_t csr)
    220  1.2.18.2  yamt {
    221  1.2.18.2  yamt 	uint64_t val, val2;
    222  1.2.18.2  yamt 	val = bus_space_read_4(sc->sc_st, sc->sc_sh, csr);
    223  1.2.18.2  yamt 	val2 = bus_space_read_4(sc->sc_st, sc->sc_sh, csr+4);
    224  1.2.18.2  yamt 	val |= (val2 << 32);
    225  1.2.18.2  yamt 	return val;
    226  1.2.18.2  yamt }
    227  1.2.18.2  yamt 
    228  1.2.18.2  yamt static inline void
    229  1.2.18.2  yamt txp_wcsr(struct xge_softc *sc, bus_size_t csr, uint64_t val)
    230  1.2.18.2  yamt {
    231  1.2.18.2  yamt 	uint32_t lval, hval;
    232  1.2.18.2  yamt 
    233  1.2.18.2  yamt 	lval = val&0xffffffff;
    234  1.2.18.2  yamt 	hval = val>>32;
    235  1.2.18.2  yamt 	bus_space_write_4(sc->sc_txt, sc->sc_txh, csr, lval);
    236  1.2.18.2  yamt 	bus_space_write_4(sc->sc_txt, sc->sc_txh, csr+4, hval);
    237  1.2.18.2  yamt }
    238  1.2.18.2  yamt 
    239  1.2.18.2  yamt 
    240  1.2.18.2  yamt static inline void
    241  1.2.18.2  yamt pif_wkey(struct xge_softc *sc, bus_size_t csr, uint64_t val)
    242  1.2.18.2  yamt {
    243  1.2.18.2  yamt 	uint32_t lval, hval;
    244  1.2.18.2  yamt 
    245  1.2.18.2  yamt 	lval = val&0xffffffff;
    246  1.2.18.2  yamt 	hval = val>>32;
    247  1.2.18.2  yamt 	PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE);
    248  1.2.18.2  yamt 	bus_space_write_4(sc->sc_st, sc->sc_sh, csr, lval);
    249  1.2.18.2  yamt 	PIF_WCSR(RMAC_CFG_KEY, RMAC_KEY_VALUE);
    250  1.2.18.2  yamt 	bus_space_write_4(sc->sc_st, sc->sc_sh, csr+4, hval);
    251  1.2.18.2  yamt }
    252  1.2.18.2  yamt 
    253  1.2.18.2  yamt 
    254  1.2.18.2  yamt CFATTACH_DECL(xge, sizeof(struct xge_softc),
    255  1.2.18.2  yamt     xge_match, xge_attach, NULL, NULL);
    256  1.2.18.2  yamt 
    257  1.2.18.2  yamt #define XNAME sc->sc_dev.dv_xname
    258  1.2.18.2  yamt 
    259  1.2.18.2  yamt #define XGE_RXSYNC(desc, what) \
    260  1.2.18.2  yamt 	bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap, \
    261  1.2.18.2  yamt 	(desc/NDESC_BUFMODE) * XGE_PAGE + sizeof(struct rxdesc) * \
    262  1.2.18.2  yamt 	(desc%NDESC_BUFMODE), sizeof(struct rxdesc), what)
    263  1.2.18.2  yamt #define XGE_RXD(desc)	&sc->sc_rxd_4k[desc/NDESC_BUFMODE]-> \
    264  1.2.18.2  yamt 	r4_rxd[desc%NDESC_BUFMODE]
    265  1.2.18.2  yamt 
    266  1.2.18.2  yamt /*
    267  1.2.18.2  yamt  * Non-tunable constants.
    268  1.2.18.2  yamt  */
    269  1.2.18.2  yamt #define XGE_MAX_MTU		9600
    270  1.2.18.2  yamt #define	XGE_IP_MAXPACKET	65535	/* same as IP_MAXPACKET */
    271  1.2.18.2  yamt 
    272  1.2.18.2  yamt static int
    273  1.2.18.2  yamt xge_match(struct device *parent, struct cfdata *cf, void *aux)
    274  1.2.18.2  yamt {
    275  1.2.18.2  yamt 	struct pci_attach_args *pa = aux;
    276  1.2.18.2  yamt 
    277  1.2.18.2  yamt 	if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_S2IO &&
    278  1.2.18.2  yamt 	    PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_S2IO_XFRAME)
    279  1.2.18.2  yamt 		return (1);
    280  1.2.18.2  yamt 
    281  1.2.18.2  yamt 	return (0);
    282  1.2.18.2  yamt }
    283  1.2.18.2  yamt 
    284  1.2.18.2  yamt void
    285  1.2.18.2  yamt xge_attach(struct device *parent, struct device *self, void *aux)
    286  1.2.18.2  yamt {
    287  1.2.18.2  yamt 	struct pci_attach_args *pa = aux;
    288  1.2.18.2  yamt 	struct xge_softc *sc;
    289  1.2.18.2  yamt 	struct ifnet *ifp;
    290  1.2.18.2  yamt 	pcireg_t memtype;
    291  1.2.18.2  yamt 	pci_intr_handle_t ih;
    292  1.2.18.2  yamt 	const char *intrstr = NULL;
    293  1.2.18.2  yamt 	pci_chipset_tag_t pc = pa->pa_pc;
    294  1.2.18.2  yamt 	uint8_t enaddr[ETHER_ADDR_LEN];
    295  1.2.18.2  yamt 	uint64_t val;
    296  1.2.18.2  yamt 	int i;
    297  1.2.18.2  yamt 
    298  1.2.18.2  yamt 	sc = (struct xge_softc *)self;
    299  1.2.18.2  yamt 
    300  1.2.18.2  yamt 	sc->sc_dmat = pa->pa_dmat;
    301  1.2.18.2  yamt 
    302  1.2.18.2  yamt 	/* Get BAR0 address */
    303  1.2.18.2  yamt 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, XGE_PIF_BAR);
    304  1.2.18.2  yamt 	if (pci_mapreg_map(pa, XGE_PIF_BAR, memtype, 0,
    305  1.2.18.2  yamt 	    &sc->sc_st, &sc->sc_sh, 0, 0)) {
    306  1.2.18.2  yamt 		aprint_error("%s: unable to map PIF BAR registers\n", XNAME);
    307  1.2.18.2  yamt 		return;
    308  1.2.18.2  yamt 	}
    309  1.2.18.2  yamt 
    310  1.2.18.2  yamt 	memtype = pci_mapreg_type(pa->pa_pc, pa->pa_tag, XGE_TXP_BAR);
    311  1.2.18.2  yamt 	if (pci_mapreg_map(pa, XGE_TXP_BAR, memtype, 0,
    312  1.2.18.2  yamt 	    &sc->sc_txt, &sc->sc_txh, 0, 0)) {
    313  1.2.18.2  yamt 		aprint_error("%s: unable to map TXP BAR registers\n", XNAME);
    314  1.2.18.2  yamt 		return;
    315  1.2.18.2  yamt 	}
    316  1.2.18.2  yamt 
    317  1.2.18.2  yamt 	/* Save PCI config space */
    318  1.2.18.2  yamt 	for (i = 0; i < 64; i += 4)
    319  1.2.18.2  yamt 		sc->sc_pciregs[i/4] = pci_conf_read(pa->pa_pc, pa->pa_tag, i);
    320  1.2.18.2  yamt 
    321  1.2.18.2  yamt #if BYTE_ORDER == LITTLE_ENDIAN
    322  1.2.18.2  yamt 	val = (uint64_t)0xFFFFFFFFFFFFFFFFULL;
    323  1.2.18.2  yamt 	val &= ~(TxF_R_SE|RxF_W_SE);
    324  1.2.18.2  yamt 	PIF_WCSR(SWAPPER_CTRL, val);
    325  1.2.18.2  yamt 	PIF_WCSR(SWAPPER_CTRL, val);
    326  1.2.18.2  yamt #elif BYTE_ORDER == BIG_ENDIAN
    327  1.2.18.2  yamt 	/* do nothing */
    328  1.2.18.2  yamt #else
    329  1.2.18.2  yamt #error bad endianness!
    330  1.2.18.2  yamt #endif
    331  1.2.18.2  yamt 
    332  1.2.18.2  yamt 	if ((val = PIF_RCSR(PIF_RD_SWAPPER_Fb)) != SWAPPER_MAGIC)
    333  1.2.18.2  yamt 		return printf("%s: failed configuring endian, %llx != %llx!\n",
    334  1.2.18.2  yamt 		    XNAME, (unsigned long long)val, SWAPPER_MAGIC);
    335  1.2.18.2  yamt 
    336  1.2.18.2  yamt 	/*
    337  1.2.18.2  yamt 	 * The MAC addr may be all FF's, which is not good.
    338  1.2.18.2  yamt 	 * Resolve it by writing some magics to GPIO_CONTROL and
    339  1.2.18.2  yamt 	 * force a chip reset to read in the serial eeprom again.
    340  1.2.18.2  yamt 	 */
    341  1.2.18.2  yamt 	for (i = 0; i < sizeof(fix_mac)/sizeof(fix_mac[0]); i++) {
    342  1.2.18.2  yamt 		PIF_WCSR(GPIO_CONTROL, fix_mac[i]);
    343  1.2.18.2  yamt 		PIF_RCSR(GPIO_CONTROL);
    344  1.2.18.2  yamt 	}
    345  1.2.18.2  yamt 
    346  1.2.18.2  yamt 	/*
    347  1.2.18.2  yamt 	 * Reset the chip and restore the PCI registers.
    348  1.2.18.2  yamt 	 */
    349  1.2.18.2  yamt 	PIF_WCSR(SW_RESET, 0xa5a5a50000000000ULL);
    350  1.2.18.2  yamt 	DELAY(500000);
    351  1.2.18.2  yamt 	for (i = 0; i < 64; i += 4)
    352  1.2.18.2  yamt 		pci_conf_write(pa->pa_pc, pa->pa_tag, i, sc->sc_pciregs[i/4]);
    353  1.2.18.2  yamt 
    354  1.2.18.2  yamt 	/*
    355  1.2.18.2  yamt 	 * Restore the byte order registers.
    356  1.2.18.2  yamt 	 */
    357  1.2.18.2  yamt #if BYTE_ORDER == LITTLE_ENDIAN
    358  1.2.18.2  yamt 	val = (uint64_t)0xFFFFFFFFFFFFFFFFULL;
    359  1.2.18.2  yamt 	val &= ~(TxF_R_SE|RxF_W_SE);
    360  1.2.18.2  yamt 	PIF_WCSR(SWAPPER_CTRL, val);
    361  1.2.18.2  yamt 	PIF_WCSR(SWAPPER_CTRL, val);
    362  1.2.18.2  yamt #elif BYTE_ORDER == BIG_ENDIAN
    363  1.2.18.2  yamt 	/* do nothing */
    364  1.2.18.2  yamt #else
    365  1.2.18.2  yamt #error bad endianness!
    366  1.2.18.2  yamt #endif
    367  1.2.18.2  yamt 
    368  1.2.18.2  yamt 	if ((val = PIF_RCSR(PIF_RD_SWAPPER_Fb)) != SWAPPER_MAGIC)
    369  1.2.18.2  yamt 		return printf("%s: failed configuring endian2, %llx != %llx!\n",
    370  1.2.18.2  yamt 		    XNAME, (unsigned long long)val, SWAPPER_MAGIC);
    371  1.2.18.2  yamt 
    372  1.2.18.2  yamt 	/*
    373  1.2.18.2  yamt 	 * XGXS initialization.
    374  1.2.18.2  yamt 	 */
    375  1.2.18.2  yamt 	/* 29, reset */
    376  1.2.18.2  yamt 	PIF_WCSR(SW_RESET, 0);
    377  1.2.18.2  yamt 	DELAY(500000);
    378  1.2.18.2  yamt 
    379  1.2.18.2  yamt 	/* 30, configure XGXS transceiver */
    380  1.2.18.2  yamt 	xge_setup_xgxs(sc);
    381  1.2.18.2  yamt 
    382  1.2.18.2  yamt 	/* 33, program MAC address (not needed here) */
    383  1.2.18.2  yamt 	/* Get ethernet address */
    384  1.2.18.2  yamt 	PIF_WCSR(RMAC_ADDR_CMD_MEM,
    385  1.2.18.2  yamt 	    RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(0));
    386  1.2.18.2  yamt 	while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
    387  1.2.18.2  yamt 		;
    388  1.2.18.2  yamt 	val = PIF_RCSR(RMAC_ADDR_DATA0_MEM);
    389  1.2.18.2  yamt 	for (i = 0; i < ETHER_ADDR_LEN; i++)
    390  1.2.18.2  yamt 		enaddr[i] = (uint8_t)(val >> (56 - (8*i)));
    391  1.2.18.2  yamt 
    392  1.2.18.2  yamt 	/*
    393  1.2.18.2  yamt 	 * Get memory for transmit descriptor lists.
    394  1.2.18.2  yamt 	 */
    395  1.2.18.2  yamt 	if (xge_alloc_txmem(sc))
    396  1.2.18.2  yamt 		return printf("%s: failed allocating txmem.\n", XNAME);
    397  1.2.18.2  yamt 
    398  1.2.18.2  yamt 	/* 9 and 10 - set FIFO number/prio */
    399  1.2.18.2  yamt 	PIF_WCSR(TX_FIFO_P0, TX_FIFO_LEN0(NTXDESCS));
    400  1.2.18.2  yamt 	PIF_WCSR(TX_FIFO_P1, 0ULL);
    401  1.2.18.2  yamt 	PIF_WCSR(TX_FIFO_P2, 0ULL);
    402  1.2.18.2  yamt 	PIF_WCSR(TX_FIFO_P3, 0ULL);
    403  1.2.18.2  yamt 
    404  1.2.18.2  yamt 	/* 11, XXX set round-robin prio? */
    405  1.2.18.2  yamt 
    406  1.2.18.2  yamt 	/* 12, enable transmit FIFO */
    407  1.2.18.2  yamt 	val = PIF_RCSR(TX_FIFO_P0);
    408  1.2.18.2  yamt 	val |= TX_FIFO_ENABLE;
    409  1.2.18.2  yamt 	PIF_WCSR(TX_FIFO_P0, val);
    410  1.2.18.2  yamt 
    411  1.2.18.2  yamt 	/* 13, disable some error checks */
    412  1.2.18.2  yamt 	PIF_WCSR(TX_PA_CFG,
    413  1.2.18.2  yamt 	    TX_PA_CFG_IFR|TX_PA_CFG_ISO|TX_PA_CFG_ILC|TX_PA_CFG_ILE);
    414  1.2.18.2  yamt 
    415  1.2.18.2  yamt 	/*
    416  1.2.18.2  yamt 	 * Create transmit DMA maps.
    417  1.2.18.2  yamt 	 * Make them large for TSO.
    418  1.2.18.2  yamt 	 */
    419  1.2.18.2  yamt 	for (i = 0; i < NTXDESCS; i++) {
    420  1.2.18.2  yamt 		if (bus_dmamap_create(sc->sc_dmat, XGE_IP_MAXPACKET,
    421  1.2.18.2  yamt 		    NTXFRAGS, MCLBYTES, 0, 0, &sc->sc_txm[i]))
    422  1.2.18.2  yamt 			return printf("%s: cannot create TX DMA maps\n", XNAME);
    423  1.2.18.2  yamt 	}
    424  1.2.18.2  yamt 
    425  1.2.18.2  yamt 	sc->sc_lasttx = NTXDESCS-1;
    426  1.2.18.2  yamt 
    427  1.2.18.2  yamt 	/*
    428  1.2.18.2  yamt 	 * RxDMA initialization.
    429  1.2.18.2  yamt 	 * Only use one out of 8 possible receive queues.
    430  1.2.18.2  yamt 	 */
    431  1.2.18.2  yamt 	if (xge_alloc_rxmem(sc))	/* allocate rx descriptor memory */
    432  1.2.18.2  yamt 		return printf("%s: failed allocating rxmem\n", XNAME);
    433  1.2.18.2  yamt 
    434  1.2.18.2  yamt 	/* Create receive buffer DMA maps */
    435  1.2.18.2  yamt 	for (i = 0; i < NRXREAL; i++) {
    436  1.2.18.2  yamt 		if (bus_dmamap_create(sc->sc_dmat, XGE_MAX_MTU,
    437  1.2.18.2  yamt 		    NRXFRAGS, MCLBYTES, 0, 0, &sc->sc_rxm[i]))
    438  1.2.18.2  yamt 			return printf("%s: cannot create RX DMA maps\n", XNAME);
    439  1.2.18.2  yamt 	}
    440  1.2.18.2  yamt 
    441  1.2.18.2  yamt 	/* allocate mbufs to receive descriptors */
    442  1.2.18.2  yamt 	for (i = 0; i < NRXREAL; i++)
    443  1.2.18.2  yamt 		if (xge_add_rxbuf(sc, i))
    444  1.2.18.2  yamt 			panic("out of mbufs too early");
    445  1.2.18.2  yamt 
    446  1.2.18.2  yamt 	/* 14, setup receive ring priority */
    447  1.2.18.2  yamt 	PIF_WCSR(RX_QUEUE_PRIORITY, 0ULL); /* only use one ring */
    448  1.2.18.2  yamt 
    449  1.2.18.2  yamt 	/* 15, setup receive ring round-robin calendar */
    450  1.2.18.2  yamt 	PIF_WCSR(RX_W_ROUND_ROBIN_0, 0ULL); /* only use one ring */
    451  1.2.18.2  yamt 	PIF_WCSR(RX_W_ROUND_ROBIN_1, 0ULL);
    452  1.2.18.2  yamt 	PIF_WCSR(RX_W_ROUND_ROBIN_2, 0ULL);
    453  1.2.18.2  yamt 	PIF_WCSR(RX_W_ROUND_ROBIN_3, 0ULL);
    454  1.2.18.2  yamt 	PIF_WCSR(RX_W_ROUND_ROBIN_4, 0ULL);
    455  1.2.18.2  yamt 
    456  1.2.18.2  yamt 	/* 16, write receive ring start address */
    457  1.2.18.2  yamt 	PIF_WCSR(PRC_RXD0_0, (uint64_t)sc->sc_rxmap->dm_segs[0].ds_addr);
    458  1.2.18.2  yamt 	/* PRC_RXD0_[1-7] are not used */
    459  1.2.18.2  yamt 
    460  1.2.18.2  yamt 	/* 17, Setup alarm registers */
    461  1.2.18.2  yamt 	PIF_WCSR(PRC_ALARM_ACTION, 0ULL); /* Default everything to retry */
    462  1.2.18.2  yamt 
    463  1.2.18.2  yamt 	/* 18, init receive ring controller */
    464  1.2.18.2  yamt #if RX_MODE == RX_MODE_1
    465  1.2.18.2  yamt 	val = RING_MODE_1;
    466  1.2.18.2  yamt #elif RX_MODE == RX_MODE_3
    467  1.2.18.2  yamt 	val = RING_MODE_3;
    468  1.2.18.2  yamt #else /* RX_MODE == RX_MODE_5 */
    469  1.2.18.2  yamt 	val = RING_MODE_5;
    470  1.2.18.2  yamt #endif
    471  1.2.18.2  yamt 	PIF_WCSR(PRC_CTRL_0, RC_IN_SVC|val);
    472  1.2.18.2  yamt 	/* leave 1-7 disabled */
    473  1.2.18.2  yamt 	/* XXXX snoop configuration? */
    474  1.2.18.2  yamt 
    475  1.2.18.2  yamt 	/* 19, set chip memory assigned to the queue */
    476  1.2.18.2  yamt 	PIF_WCSR(RX_QUEUE_CFG, MC_QUEUE(0, 64)); /* all 64M to queue 0 */
    477  1.2.18.2  yamt 
    478  1.2.18.2  yamt 	/* 20, setup RLDRAM parameters */
    479  1.2.18.2  yamt 	/* do not touch it for now */
    480  1.2.18.2  yamt 
    481  1.2.18.2  yamt 	/* 21, setup pause frame thresholds */
    482  1.2.18.2  yamt 	/* so not touch the defaults */
    483  1.2.18.2  yamt 	/* XXX - must 0xff be written as stated in the manual? */
    484  1.2.18.2  yamt 
    485  1.2.18.2  yamt 	/* 22, configure RED */
    486  1.2.18.2  yamt 	/* we do not want to drop packets, so ignore */
    487  1.2.18.2  yamt 
    488  1.2.18.2  yamt 	/* 23, initiate RLDRAM */
    489  1.2.18.2  yamt 	val = PIF_RCSR(MC_RLDRAM_MRS);
    490  1.2.18.2  yamt 	val |= MC_QUEUE_SIZE_ENABLE|MC_RLDRAM_MRS_ENABLE;
    491  1.2.18.2  yamt 	PIF_WCSR(MC_RLDRAM_MRS, val);
    492  1.2.18.2  yamt 	DELAY(1000);
    493  1.2.18.2  yamt 
    494  1.2.18.2  yamt 	/*
    495  1.2.18.2  yamt 	 * Setup interrupt policies.
    496  1.2.18.2  yamt 	 */
    497  1.2.18.2  yamt 	/* 40, Transmit interrupts */
    498  1.2.18.2  yamt 	PIF_WCSR(TTI_DATA1_MEM, TX_TIMER_VAL(0x1ff) | TX_TIMER_AC |
    499  1.2.18.2  yamt 	    TX_URNG_A(5) | TX_URNG_B(20) | TX_URNG_C(48));
    500  1.2.18.2  yamt 	PIF_WCSR(TTI_DATA2_MEM,
    501  1.2.18.2  yamt 	    TX_UFC_A(25) | TX_UFC_B(64) | TX_UFC_C(128) | TX_UFC_D(512));
    502  1.2.18.2  yamt 	PIF_WCSR(TTI_COMMAND_MEM, TTI_CMD_MEM_WE | TTI_CMD_MEM_STROBE);
    503  1.2.18.2  yamt 	while (PIF_RCSR(TTI_COMMAND_MEM) & TTI_CMD_MEM_STROBE)
    504  1.2.18.2  yamt 		;
    505  1.2.18.2  yamt 
    506  1.2.18.2  yamt 	/* 41, Receive interrupts */
    507  1.2.18.2  yamt 	PIF_WCSR(RTI_DATA1_MEM, RX_TIMER_VAL(0x800) | RX_TIMER_AC |
    508  1.2.18.2  yamt 	    RX_URNG_A(5) | RX_URNG_B(20) | RX_URNG_C(50));
    509  1.2.18.2  yamt 	PIF_WCSR(RTI_DATA2_MEM,
    510  1.2.18.2  yamt 	    RX_UFC_A(64) | RX_UFC_B(128) | RX_UFC_C(256) | RX_UFC_D(512));
    511  1.2.18.2  yamt 	PIF_WCSR(RTI_COMMAND_MEM, RTI_CMD_MEM_WE | RTI_CMD_MEM_STROBE);
    512  1.2.18.2  yamt 	while (PIF_RCSR(RTI_COMMAND_MEM) & RTI_CMD_MEM_STROBE)
    513  1.2.18.2  yamt 		;
    514  1.2.18.2  yamt 
    515  1.2.18.2  yamt 	/*
    516  1.2.18.2  yamt 	 * Setup media stuff.
    517  1.2.18.2  yamt 	 */
    518  1.2.18.2  yamt 	ifmedia_init(&sc->xena_media, IFM_IMASK, xge_xgmii_mediachange,
    519  1.2.18.2  yamt 	    xge_ifmedia_status);
    520  1.2.18.2  yamt 	ifmedia_add(&sc->xena_media, IFM_ETHER|IFM_10G_LR, 0, NULL);
    521  1.2.18.2  yamt 	ifmedia_set(&sc->xena_media, IFM_ETHER|IFM_10G_LR);
    522  1.2.18.2  yamt 
    523  1.2.18.2  yamt 	aprint_normal("%s: Ethernet address %s\n", XNAME,
    524  1.2.18.2  yamt 	    ether_sprintf(enaddr));
    525  1.2.18.2  yamt 
    526  1.2.18.2  yamt 	ifp = &sc->sc_ethercom.ec_if;
    527  1.2.18.2  yamt 	strcpy(ifp->if_xname, sc->sc_dev.dv_xname);
    528  1.2.18.2  yamt 	ifp->if_baudrate = 10000000000LL;
    529  1.2.18.2  yamt 	ifp->if_init = xge_init;
    530  1.2.18.2  yamt 	ifp->if_stop = xge_stop;
    531  1.2.18.2  yamt 	ifp->if_softc = sc;
    532  1.2.18.2  yamt 	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
    533  1.2.18.2  yamt 	ifp->if_ioctl = xge_ioctl;
    534  1.2.18.2  yamt 	ifp->if_start = xge_start;
    535  1.2.18.2  yamt 	IFQ_SET_MAXLEN(&ifp->if_snd, max(NTXDESCS - 1, IFQ_MAXLEN));
    536  1.2.18.2  yamt 	IFQ_SET_READY(&ifp->if_snd);
    537  1.2.18.2  yamt 
    538  1.2.18.2  yamt 	/*
    539  1.2.18.2  yamt 	 * Offloading capabilities.
    540  1.2.18.2  yamt 	 */
    541  1.2.18.2  yamt 	sc->sc_ethercom.ec_capabilities |=
    542  1.2.18.2  yamt 	    ETHERCAP_JUMBO_MTU | ETHERCAP_VLAN_MTU;
    543  1.2.18.2  yamt 	ifp->if_capabilities |=
    544  1.2.18.2  yamt 	    IFCAP_CSUM_IPv4_Rx | IFCAP_CSUM_IPv4_Tx |
    545  1.2.18.2  yamt 	    IFCAP_CSUM_TCPv4_Rx | IFCAP_CSUM_TCPv4_Tx |
    546  1.2.18.2  yamt 	    IFCAP_CSUM_UDPv4_Rx | IFCAP_CSUM_UDPv4_Tx | IFCAP_TSOv4;
    547  1.2.18.2  yamt 
    548  1.2.18.2  yamt 	/*
    549  1.2.18.2  yamt 	 * Attach the interface.
    550  1.2.18.2  yamt 	 */
    551  1.2.18.2  yamt 	if_attach(ifp);
    552  1.2.18.2  yamt 	ether_ifattach(ifp, enaddr);
    553  1.2.18.2  yamt 
    554  1.2.18.2  yamt 	/*
    555  1.2.18.2  yamt 	 * Setup interrupt vector before initializing.
    556  1.2.18.2  yamt 	 */
    557  1.2.18.2  yamt 	if (pci_intr_map(pa, &ih))
    558  1.2.18.2  yamt 		return aprint_error("%s: unable to map interrupt\n",
    559  1.2.18.2  yamt 		    sc->sc_dev.dv_xname);
    560  1.2.18.2  yamt 	intrstr = pci_intr_string(pc, ih);
    561  1.2.18.2  yamt 	if ((sc->sc_ih =
    562  1.2.18.2  yamt 	    pci_intr_establish(pc, ih, IPL_NET, xge_intr, sc)) == NULL)
    563  1.2.18.2  yamt 		return aprint_error("%s: unable to establish interrupt at %s\n",
    564  1.2.18.2  yamt 		    sc->sc_dev.dv_xname, intrstr ? intrstr : "<unknown>");
    565  1.2.18.2  yamt 	aprint_normal("%s: interrupting at %s\n", sc->sc_dev.dv_xname, intrstr);
    566  1.2.18.2  yamt 
    567  1.2.18.2  yamt #ifdef XGE_EVENT_COUNTERS
    568  1.2.18.2  yamt 	evcnt_attach_dynamic(&sc->sc_intr, EVCNT_TYPE_MISC,
    569  1.2.18.2  yamt 	    NULL, XNAME, "intr");
    570  1.2.18.2  yamt 	evcnt_attach_dynamic(&sc->sc_txintr, EVCNT_TYPE_MISC,
    571  1.2.18.2  yamt 	    NULL, XNAME, "txintr");
    572  1.2.18.2  yamt 	evcnt_attach_dynamic(&sc->sc_rxintr, EVCNT_TYPE_MISC,
    573  1.2.18.2  yamt 	    NULL, XNAME, "rxintr");
    574  1.2.18.2  yamt 	evcnt_attach_dynamic(&sc->sc_txqe, EVCNT_TYPE_MISC,
    575  1.2.18.2  yamt 	    NULL, XNAME, "txqe");
    576  1.2.18.2  yamt #endif
    577  1.2.18.2  yamt }
    578  1.2.18.2  yamt 
    579  1.2.18.2  yamt void
    580  1.2.18.2  yamt xge_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr)
    581  1.2.18.2  yamt {
    582  1.2.18.2  yamt 	struct xge_softc *sc = ifp->if_softc;
    583  1.2.18.2  yamt 	uint64_t reg;
    584  1.2.18.2  yamt 
    585  1.2.18.2  yamt 	ifmr->ifm_status = IFM_AVALID;
    586  1.2.18.2  yamt 	ifmr->ifm_active = IFM_ETHER|IFM_10G_LR;
    587  1.2.18.2  yamt 
    588  1.2.18.2  yamt 	reg = PIF_RCSR(ADAPTER_STATUS);
    589  1.2.18.2  yamt 	if ((reg & (RMAC_REMOTE_FAULT|RMAC_LOCAL_FAULT)) == 0)
    590  1.2.18.2  yamt 		ifmr->ifm_status |= IFM_ACTIVE;
    591  1.2.18.2  yamt }
    592  1.2.18.2  yamt 
    593  1.2.18.2  yamt int
    594  1.2.18.2  yamt xge_xgmii_mediachange(struct ifnet *ifp)
    595  1.2.18.2  yamt {
    596  1.2.18.2  yamt 	return 0;
    597  1.2.18.2  yamt }
    598  1.2.18.2  yamt 
    599  1.2.18.2  yamt static void
    600  1.2.18.2  yamt xge_enable(struct xge_softc *sc)
    601  1.2.18.2  yamt {
    602  1.2.18.2  yamt 	uint64_t val;
    603  1.2.18.2  yamt 
    604  1.2.18.2  yamt 	/* 2, enable adapter */
    605  1.2.18.2  yamt 	val = PIF_RCSR(ADAPTER_CONTROL);
    606  1.2.18.2  yamt 	val |= ADAPTER_EN;
    607  1.2.18.2  yamt 	PIF_WCSR(ADAPTER_CONTROL, val);
    608  1.2.18.2  yamt 
    609  1.2.18.2  yamt 	/* 3, light the card enable led */
    610  1.2.18.2  yamt 	val = PIF_RCSR(ADAPTER_CONTROL);
    611  1.2.18.2  yamt 	val |= LED_ON;
    612  1.2.18.2  yamt 	PIF_WCSR(ADAPTER_CONTROL, val);
    613  1.2.18.2  yamt 	printf("%s: link up\n", XNAME);
    614  1.2.18.2  yamt 
    615  1.2.18.2  yamt }
    616  1.2.18.2  yamt 
    617  1.2.18.2  yamt int
    618  1.2.18.2  yamt xge_init(struct ifnet *ifp)
    619  1.2.18.2  yamt {
    620  1.2.18.2  yamt 	struct xge_softc *sc = ifp->if_softc;
    621  1.2.18.2  yamt 	uint64_t val;
    622  1.2.18.2  yamt 
    623  1.2.18.2  yamt 	if (ifp->if_flags & IFF_RUNNING)
    624  1.2.18.2  yamt 		return 0;
    625  1.2.18.2  yamt 
    626  1.2.18.2  yamt 	/* 31+32, setup MAC config */
    627  1.2.18.2  yamt 	PIF_WKEY(MAC_CFG, TMAC_EN|RMAC_EN|TMAC_APPEND_PAD|RMAC_STRIP_FCS|
    628  1.2.18.2  yamt 	    RMAC_BCAST_EN|RMAC_DISCARD_PFRM|RMAC_PROM_EN);
    629  1.2.18.2  yamt 
    630  1.2.18.2  yamt 	DELAY(1000);
    631  1.2.18.2  yamt 
    632  1.2.18.2  yamt 	/* 54, ensure that the adapter is 'quiescent' */
    633  1.2.18.2  yamt 	val = PIF_RCSR(ADAPTER_STATUS);
    634  1.2.18.2  yamt 	if ((val & QUIESCENT) != QUIESCENT) {
    635  1.2.18.2  yamt 		char buf[200];
    636  1.2.18.2  yamt 		printf("%s: adapter not quiescent, aborting\n", XNAME);
    637  1.2.18.2  yamt 		val = (val & QUIESCENT) ^ QUIESCENT;
    638  1.2.18.2  yamt 		bitmask_snprintf(val, QUIESCENT_BMSK, buf, sizeof buf);
    639  1.2.18.2  yamt 		printf("%s: ADAPTER_STATUS missing bits %s\n", XNAME, buf);
    640  1.2.18.2  yamt 		return 1;
    641  1.2.18.2  yamt 	}
    642  1.2.18.2  yamt 
    643  1.2.18.2  yamt 	/* 56, enable the transmit laser */
    644  1.2.18.2  yamt 	val = PIF_RCSR(ADAPTER_CONTROL);
    645  1.2.18.2  yamt 	val |= EOI_TX_ON;
    646  1.2.18.2  yamt 	PIF_WCSR(ADAPTER_CONTROL, val);
    647  1.2.18.2  yamt 
    648  1.2.18.2  yamt 	xge_enable(sc);
    649  1.2.18.2  yamt 	/*
    650  1.2.18.2  yamt 	 * Enable all interrupts
    651  1.2.18.2  yamt 	 */
    652  1.2.18.2  yamt 	PIF_WCSR(TX_TRAFFIC_MASK, 0);
    653  1.2.18.2  yamt 	PIF_WCSR(RX_TRAFFIC_MASK, 0);
    654  1.2.18.2  yamt 	PIF_WCSR(GENERAL_INT_MASK, 0);
    655  1.2.18.2  yamt 	PIF_WCSR(TXPIC_INT_MASK, 0);
    656  1.2.18.2  yamt 	PIF_WCSR(RXPIC_INT_MASK, 0);
    657  1.2.18.2  yamt 	PIF_WCSR(MAC_INT_MASK, MAC_TMAC_INT); /* only from RMAC */
    658  1.2.18.2  yamt 	PIF_WCSR(MAC_RMAC_ERR_MASK, ~RMAC_LINK_STATE_CHANGE_INT);
    659  1.2.18.2  yamt 
    660  1.2.18.2  yamt 
    661  1.2.18.2  yamt 	/* Done... */
    662  1.2.18.2  yamt 	ifp->if_flags |= IFF_RUNNING;
    663  1.2.18.2  yamt 	ifp->if_flags &= ~IFF_OACTIVE;
    664  1.2.18.2  yamt 
    665  1.2.18.2  yamt 	return 0;
    666  1.2.18.2  yamt }
    667  1.2.18.2  yamt 
    668  1.2.18.2  yamt static void
    669  1.2.18.2  yamt xge_stop(struct ifnet *ifp, int disable)
    670  1.2.18.2  yamt {
    671  1.2.18.2  yamt 	struct xge_softc *sc = ifp->if_softc;
    672  1.2.18.2  yamt 	uint64_t val;
    673  1.2.18.2  yamt 
    674  1.2.18.2  yamt 	val = PIF_RCSR(ADAPTER_CONTROL);
    675  1.2.18.2  yamt 	val &= ~ADAPTER_EN;
    676  1.2.18.2  yamt 	PIF_WCSR(ADAPTER_CONTROL, val);
    677  1.2.18.2  yamt 
    678  1.2.18.2  yamt 	while ((PIF_RCSR(ADAPTER_STATUS) & QUIESCENT) != QUIESCENT)
    679  1.2.18.2  yamt 		;
    680  1.2.18.2  yamt }
    681  1.2.18.2  yamt 
    682  1.2.18.2  yamt int
    683  1.2.18.2  yamt xge_intr(void *pv)
    684  1.2.18.2  yamt {
    685  1.2.18.2  yamt 	struct xge_softc *sc = pv;
    686  1.2.18.2  yamt 	struct txd *txd;
    687  1.2.18.2  yamt 	struct ifnet *ifp = &sc->sc_if;
    688  1.2.18.2  yamt 	bus_dmamap_t dmp;
    689  1.2.18.2  yamt 	uint64_t val;
    690  1.2.18.2  yamt 	int i, lasttx, plen;
    691  1.2.18.2  yamt 
    692  1.2.18.2  yamt 	val = PIF_RCSR(GENERAL_INT_STATUS);
    693  1.2.18.2  yamt 	if (val == 0)
    694  1.2.18.2  yamt 		return 0; /* no interrupt here */
    695  1.2.18.2  yamt 
    696  1.2.18.2  yamt 	XGE_EVCNT_INCR(&sc->sc_intr);
    697  1.2.18.2  yamt 
    698  1.2.18.2  yamt 	PIF_WCSR(GENERAL_INT_STATUS, val);
    699  1.2.18.2  yamt 
    700  1.2.18.2  yamt 	if ((val = PIF_RCSR(MAC_RMAC_ERR_REG)) & RMAC_LINK_STATE_CHANGE_INT) {
    701  1.2.18.2  yamt 		/* Wait for quiescence */
    702  1.2.18.2  yamt 		printf("%s: link down\n", XNAME);
    703  1.2.18.2  yamt 		while ((PIF_RCSR(ADAPTER_STATUS) & QUIESCENT) != QUIESCENT)
    704  1.2.18.2  yamt 			;
    705  1.2.18.2  yamt 		PIF_WCSR(MAC_RMAC_ERR_REG, RMAC_LINK_STATE_CHANGE_INT);
    706  1.2.18.2  yamt 
    707  1.2.18.2  yamt 		val = PIF_RCSR(ADAPTER_STATUS);
    708  1.2.18.2  yamt 		if ((val & (RMAC_REMOTE_FAULT|RMAC_LOCAL_FAULT)) == 0)
    709  1.2.18.2  yamt 			xge_enable(sc); /* Only if link restored */
    710  1.2.18.2  yamt 	}
    711  1.2.18.2  yamt 
    712  1.2.18.2  yamt 	if ((val = PIF_RCSR(TX_TRAFFIC_INT))) {
    713  1.2.18.2  yamt 		XGE_EVCNT_INCR(&sc->sc_txintr);
    714  1.2.18.2  yamt 		PIF_WCSR(TX_TRAFFIC_INT, val); /* clear interrupt bits */
    715  1.2.18.2  yamt 	}
    716  1.2.18.2  yamt 	/*
    717  1.2.18.2  yamt 	 * Collect sent packets.
    718  1.2.18.2  yamt 	 */
    719  1.2.18.2  yamt 	lasttx = sc->sc_lasttx;
    720  1.2.18.2  yamt 	while ((i = NEXTTX(sc->sc_lasttx)) != sc->sc_nexttx) {
    721  1.2.18.2  yamt 		txd = sc->sc_txd[i];
    722  1.2.18.2  yamt 		dmp = sc->sc_txm[i];
    723  1.2.18.2  yamt 
    724  1.2.18.2  yamt 		bus_dmamap_sync(sc->sc_dmat, dmp, 0,
    725  1.2.18.2  yamt 		    dmp->dm_mapsize,
    726  1.2.18.2  yamt 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    727  1.2.18.2  yamt 
    728  1.2.18.2  yamt 		if (txd->txd_control1 & TXD_CTL1_OWN) {
    729  1.2.18.2  yamt 			bus_dmamap_sync(sc->sc_dmat, dmp, 0,
    730  1.2.18.2  yamt 			    dmp->dm_mapsize, BUS_DMASYNC_PREREAD);
    731  1.2.18.2  yamt 			break;
    732  1.2.18.2  yamt 		}
    733  1.2.18.2  yamt 		bus_dmamap_unload(sc->sc_dmat, dmp);
    734  1.2.18.2  yamt 		m_freem(sc->sc_txb[i]);
    735  1.2.18.2  yamt 		ifp->if_opackets++;
    736  1.2.18.2  yamt 		sc->sc_lasttx = i;
    737  1.2.18.2  yamt 	}
    738  1.2.18.2  yamt 	if (i == sc->sc_nexttx) {
    739  1.2.18.2  yamt 		XGE_EVCNT_INCR(&sc->sc_txqe);
    740  1.2.18.2  yamt 	}
    741  1.2.18.2  yamt 
    742  1.2.18.2  yamt 	if (sc->sc_lasttx != lasttx)
    743  1.2.18.2  yamt 		ifp->if_flags &= ~IFF_OACTIVE;
    744  1.2.18.2  yamt 
    745  1.2.18.2  yamt 	xge_start(ifp); /* Try to get more packets on the wire */
    746  1.2.18.2  yamt 
    747  1.2.18.2  yamt 	if ((val = PIF_RCSR(RX_TRAFFIC_INT))) {
    748  1.2.18.2  yamt 		XGE_EVCNT_INCR(&sc->sc_rxintr);
    749  1.2.18.2  yamt 		PIF_WCSR(RX_TRAFFIC_INT, val); /* clear interrupt bits */
    750  1.2.18.2  yamt 	}
    751  1.2.18.2  yamt 
    752  1.2.18.2  yamt 	for (;;) {
    753  1.2.18.2  yamt 		struct rxdesc *rxd;
    754  1.2.18.2  yamt 		struct mbuf *m;
    755  1.2.18.2  yamt 
    756  1.2.18.2  yamt 		XGE_RXSYNC(sc->sc_nextrx,
    757  1.2.18.2  yamt 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
    758  1.2.18.2  yamt 
    759  1.2.18.2  yamt 		rxd = XGE_RXD(sc->sc_nextrx);
    760  1.2.18.2  yamt 		if (rxd->rxd_control1 & RXD_CTL1_OWN) {
    761  1.2.18.2  yamt 			XGE_RXSYNC(sc->sc_nextrx, BUS_DMASYNC_PREREAD);
    762  1.2.18.2  yamt 			break;
    763  1.2.18.2  yamt 		}
    764  1.2.18.2  yamt 
    765  1.2.18.2  yamt 		/* got a packet */
    766  1.2.18.2  yamt 		m = sc->sc_rxb[sc->sc_nextrx];
    767  1.2.18.2  yamt #if RX_MODE == RX_MODE_1
    768  1.2.18.2  yamt 		plen = m->m_len = RXD_CTL2_BUF0SIZ(rxd->rxd_control2);
    769  1.2.18.2  yamt #elif RX_MODE == RX_MODE_3
    770  1.2.18.2  yamt #error Fix rxmodes in xge_intr
    771  1.2.18.2  yamt #elif RX_MODE == RX_MODE_5
    772  1.2.18.2  yamt 		plen = m->m_len = RXD_CTL2_BUF0SIZ(rxd->rxd_control2);
    773  1.2.18.2  yamt 		plen += m->m_next->m_len = RXD_CTL2_BUF1SIZ(rxd->rxd_control2);
    774  1.2.18.2  yamt 		plen += m->m_next->m_next->m_len =
    775  1.2.18.2  yamt 		    RXD_CTL2_BUF2SIZ(rxd->rxd_control2);
    776  1.2.18.2  yamt 		plen += m->m_next->m_next->m_next->m_len =
    777  1.2.18.2  yamt 		    RXD_CTL3_BUF3SIZ(rxd->rxd_control3);
    778  1.2.18.2  yamt 		plen += m->m_next->m_next->m_next->m_next->m_len =
    779  1.2.18.2  yamt 		    RXD_CTL3_BUF4SIZ(rxd->rxd_control3);
    780  1.2.18.2  yamt #endif
    781  1.2.18.2  yamt 		m->m_pkthdr.rcvif = ifp;
    782  1.2.18.2  yamt 		m->m_pkthdr.len = plen;
    783  1.2.18.2  yamt 
    784  1.2.18.2  yamt 		val = rxd->rxd_control1;
    785  1.2.18.2  yamt 
    786  1.2.18.2  yamt 		if (xge_add_rxbuf(sc, sc->sc_nextrx)) {
    787  1.2.18.2  yamt 			/* Failed, recycle this mbuf */
    788  1.2.18.2  yamt #if RX_MODE == RX_MODE_1
    789  1.2.18.2  yamt 			rxd->rxd_control2 = RXD_MKCTL2(MCLBYTES, 0, 0);
    790  1.2.18.2  yamt 			rxd->rxd_control1 = RXD_CTL1_OWN;
    791  1.2.18.2  yamt #elif RX_MODE == RX_MODE_3
    792  1.2.18.2  yamt #elif RX_MODE == RX_MODE_5
    793  1.2.18.2  yamt #endif
    794  1.2.18.2  yamt 			XGE_RXSYNC(sc->sc_nextrx,
    795  1.2.18.2  yamt 			    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    796  1.2.18.2  yamt 			ifp->if_ierrors++;
    797  1.2.18.2  yamt 			break;
    798  1.2.18.2  yamt 		}
    799  1.2.18.2  yamt 
    800  1.2.18.2  yamt 		ifp->if_ipackets++;
    801  1.2.18.2  yamt 
    802  1.2.18.2  yamt 		if (RXD_CTL1_PROTOS(val) & (RXD_CTL1_P_IPv4|RXD_CTL1_P_IPv6)) {
    803  1.2.18.2  yamt 			m->m_pkthdr.csum_flags |= M_CSUM_IPv4;
    804  1.2.18.2  yamt 			if (RXD_CTL1_L3CSUM(val) != 0xffff)
    805  1.2.18.2  yamt 				m->m_pkthdr.csum_flags |= M_CSUM_IPv4_BAD;
    806  1.2.18.2  yamt 		}
    807  1.2.18.2  yamt 		if (RXD_CTL1_PROTOS(val) & RXD_CTL1_P_TCP) {
    808  1.2.18.2  yamt 			m->m_pkthdr.csum_flags |= M_CSUM_TCPv4|M_CSUM_TCPv6;
    809  1.2.18.2  yamt 			if (RXD_CTL1_L4CSUM(val) != 0xffff)
    810  1.2.18.2  yamt 				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
    811  1.2.18.2  yamt 		}
    812  1.2.18.2  yamt 		if (RXD_CTL1_PROTOS(val) & RXD_CTL1_P_UDP) {
    813  1.2.18.2  yamt 			m->m_pkthdr.csum_flags |= M_CSUM_UDPv4|M_CSUM_UDPv6;
    814  1.2.18.2  yamt 			if (RXD_CTL1_L4CSUM(val) != 0xffff)
    815  1.2.18.2  yamt 				m->m_pkthdr.csum_flags |= M_CSUM_TCP_UDP_BAD;
    816  1.2.18.2  yamt 		}
    817  1.2.18.2  yamt 
    818  1.2.18.2  yamt #if NBPFILTER > 0
    819  1.2.18.2  yamt 		if (ifp->if_bpf)
    820  1.2.18.2  yamt 			bpf_mtap(ifp->if_bpf, m);
    821  1.2.18.2  yamt #endif /* NBPFILTER > 0 */
    822  1.2.18.2  yamt 
    823  1.2.18.2  yamt 		(*ifp->if_input)(ifp, m);
    824  1.2.18.2  yamt 
    825  1.2.18.2  yamt 		if (++sc->sc_nextrx == NRXREAL)
    826  1.2.18.2  yamt 			sc->sc_nextrx = 0;
    827  1.2.18.2  yamt 
    828  1.2.18.2  yamt 	}
    829  1.2.18.2  yamt 
    830  1.2.18.2  yamt 	return 0;
    831  1.2.18.2  yamt }
    832  1.2.18.2  yamt 
    833  1.2.18.2  yamt int
    834  1.2.18.2  yamt xge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
    835  1.2.18.2  yamt {
    836  1.2.18.2  yamt 	struct xge_softc *sc = ifp->if_softc;
    837  1.2.18.2  yamt 	struct ifreq *ifr = (struct ifreq *) data;
    838  1.2.18.2  yamt 	int s, error = 0;
    839  1.2.18.2  yamt 
    840  1.2.18.2  yamt 	s = splnet();
    841  1.2.18.2  yamt 
    842  1.2.18.2  yamt 	switch (cmd) {
    843  1.2.18.2  yamt 	case SIOCSIFMTU:
    844  1.2.18.2  yamt 		if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > XGE_MAX_MTU) {
    845  1.2.18.2  yamt 			error = EINVAL;
    846  1.2.18.2  yamt 		} else {
    847  1.2.18.2  yamt 			PIF_WCSR(RMAC_MAX_PYLD_LEN,
    848  1.2.18.2  yamt 			    RMAC_PYLD_LEN(ifr->ifr_mtu));
    849  1.2.18.2  yamt 			ifp->if_mtu = ifr->ifr_mtu;
    850  1.2.18.2  yamt 		}
    851  1.2.18.2  yamt 		break;
    852  1.2.18.2  yamt 
    853  1.2.18.2  yamt 	case SIOCGIFMEDIA:
    854  1.2.18.2  yamt 	case SIOCSIFMEDIA:
    855  1.2.18.2  yamt 		error = ifmedia_ioctl(ifp, ifr, &sc->xena_media, cmd);
    856  1.2.18.2  yamt 		break;
    857  1.2.18.2  yamt 
    858  1.2.18.2  yamt 	default:
    859  1.2.18.2  yamt 		if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET){
    860  1.2.18.2  yamt 			/* Change multicast list */
    861  1.2.18.2  yamt 			xge_mcast_filter(sc);
    862  1.2.18.2  yamt 			error = 0;
    863  1.2.18.2  yamt 		}
    864  1.2.18.2  yamt 		break;
    865  1.2.18.2  yamt 	}
    866  1.2.18.2  yamt 
    867  1.2.18.2  yamt 	splx(s);
    868  1.2.18.2  yamt 	return(error);
    869  1.2.18.2  yamt }
    870  1.2.18.2  yamt 
    871  1.2.18.2  yamt void
    872  1.2.18.2  yamt xge_mcast_filter(struct xge_softc *sc)
    873  1.2.18.2  yamt {
    874  1.2.18.2  yamt 	struct ifnet *ifp = &sc->sc_ethercom.ec_if;
    875  1.2.18.2  yamt 	struct ethercom *ec = &sc->sc_ethercom;
    876  1.2.18.2  yamt 	struct ether_multi *enm;
    877  1.2.18.2  yamt 	struct ether_multistep step;
    878  1.2.18.2  yamt 	int i, numaddr = 1; /* first slot used for card unicast address */
    879  1.2.18.2  yamt 	uint64_t val;
    880  1.2.18.2  yamt 
    881  1.2.18.2  yamt 	ETHER_FIRST_MULTI(step, ec, enm);
    882  1.2.18.2  yamt 	while (enm != NULL) {
    883  1.2.18.2  yamt 		if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) {
    884  1.2.18.2  yamt 			/* Skip ranges */
    885  1.2.18.2  yamt 			goto allmulti;
    886  1.2.18.2  yamt 		}
    887  1.2.18.2  yamt 		if (numaddr == MAX_MCAST_ADDR)
    888  1.2.18.2  yamt 			goto allmulti;
    889  1.2.18.2  yamt 		for (val = 0, i = 0; i < ETHER_ADDR_LEN; i++) {
    890  1.2.18.2  yamt 			val <<= 8;
    891  1.2.18.2  yamt 			val |= enm->enm_addrlo[i];
    892  1.2.18.2  yamt 		}
    893  1.2.18.2  yamt 		PIF_WCSR(RMAC_ADDR_DATA0_MEM, val << 16);
    894  1.2.18.2  yamt 		PIF_WCSR(RMAC_ADDR_DATA1_MEM, 0xFFFFFFFFFFFFFFFFULL);
    895  1.2.18.2  yamt 		PIF_WCSR(RMAC_ADDR_CMD_MEM, RMAC_ADDR_CMD_MEM_WE|
    896  1.2.18.2  yamt 		    RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(numaddr));
    897  1.2.18.2  yamt 		while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
    898  1.2.18.2  yamt 			;
    899  1.2.18.2  yamt 		numaddr++;
    900  1.2.18.2  yamt 		ETHER_NEXT_MULTI(step, enm);
    901  1.2.18.2  yamt 	}
    902  1.2.18.2  yamt 	/* set the remaining entries to the broadcast address */
    903  1.2.18.2  yamt 	for (i = numaddr; i < MAX_MCAST_ADDR; i++) {
    904  1.2.18.2  yamt 		PIF_WCSR(RMAC_ADDR_DATA0_MEM, 0xffffffffffff0000ULL);
    905  1.2.18.2  yamt 		PIF_WCSR(RMAC_ADDR_DATA1_MEM, 0xFFFFFFFFFFFFFFFFULL);
    906  1.2.18.2  yamt 		PIF_WCSR(RMAC_ADDR_CMD_MEM, RMAC_ADDR_CMD_MEM_WE|
    907  1.2.18.2  yamt 		    RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(i));
    908  1.2.18.2  yamt 		while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
    909  1.2.18.2  yamt 			;
    910  1.2.18.2  yamt 	}
    911  1.2.18.2  yamt 	ifp->if_flags &= ~IFF_ALLMULTI;
    912  1.2.18.2  yamt 	return;
    913  1.2.18.2  yamt 
    914  1.2.18.2  yamt allmulti:
    915  1.2.18.2  yamt 	/* Just receive everything with the multicast bit set */
    916  1.2.18.2  yamt 	ifp->if_flags |= IFF_ALLMULTI;
    917  1.2.18.2  yamt 	PIF_WCSR(RMAC_ADDR_DATA0_MEM, 0x8000000000000000ULL);
    918  1.2.18.2  yamt 	PIF_WCSR(RMAC_ADDR_DATA1_MEM, 0xF000000000000000ULL);
    919  1.2.18.2  yamt 	PIF_WCSR(RMAC_ADDR_CMD_MEM, RMAC_ADDR_CMD_MEM_WE|
    920  1.2.18.2  yamt 	    RMAC_ADDR_CMD_MEM_STR|RMAC_ADDR_CMD_MEM_OFF(1));
    921  1.2.18.2  yamt 	while (PIF_RCSR(RMAC_ADDR_CMD_MEM) & RMAC_ADDR_CMD_MEM_STR)
    922  1.2.18.2  yamt 		;
    923  1.2.18.2  yamt }
    924  1.2.18.2  yamt 
    925  1.2.18.2  yamt void
    926  1.2.18.2  yamt xge_start(struct ifnet *ifp)
    927  1.2.18.2  yamt {
    928  1.2.18.2  yamt 	struct xge_softc *sc = ifp->if_softc;
    929  1.2.18.2  yamt 	struct txd *txd = NULL; /* XXX - gcc */
    930  1.2.18.2  yamt 	bus_dmamap_t dmp;
    931  1.2.18.2  yamt 	struct	mbuf *m;
    932  1.2.18.2  yamt 	uint64_t par, lcr;
    933  1.2.18.2  yamt 	int nexttx = 0, ntxd, error, i;
    934  1.2.18.2  yamt 
    935  1.2.18.2  yamt 	if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING)
    936  1.2.18.2  yamt 		return;
    937  1.2.18.2  yamt 
    938  1.2.18.2  yamt 	par = lcr = 0;
    939  1.2.18.2  yamt 	for (;;) {
    940  1.2.18.2  yamt 		IFQ_POLL(&ifp->if_snd, m);
    941  1.2.18.2  yamt 		if (m == NULL)
    942  1.2.18.2  yamt 			break;	/* out of packets */
    943  1.2.18.2  yamt 
    944  1.2.18.2  yamt 		if (sc->sc_nexttx == sc->sc_lasttx)
    945  1.2.18.2  yamt 			break;	/* No more space */
    946  1.2.18.2  yamt 
    947  1.2.18.2  yamt 		nexttx = sc->sc_nexttx;
    948  1.2.18.2  yamt 		dmp = sc->sc_txm[nexttx];
    949  1.2.18.2  yamt 
    950  1.2.18.2  yamt 		if ((error = bus_dmamap_load_mbuf(sc->sc_dmat, dmp, m,
    951  1.2.18.2  yamt 		    BUS_DMA_WRITE|BUS_DMA_NOWAIT)) != 0) {
    952  1.2.18.2  yamt 			printf("%s: bus_dmamap_load_mbuf error %d\n",
    953  1.2.18.2  yamt 			    XNAME, error);
    954  1.2.18.2  yamt 			break;
    955  1.2.18.2  yamt 		}
    956  1.2.18.2  yamt 		IFQ_DEQUEUE(&ifp->if_snd, m);
    957  1.2.18.2  yamt 
    958  1.2.18.2  yamt 		bus_dmamap_sync(sc->sc_dmat, dmp, 0, dmp->dm_mapsize,
    959  1.2.18.2  yamt 		    BUS_DMASYNC_PREWRITE);
    960  1.2.18.2  yamt 
    961  1.2.18.2  yamt 		txd = sc->sc_txd[nexttx];
    962  1.2.18.2  yamt 		sc->sc_txb[nexttx] = m;
    963  1.2.18.2  yamt 		for (i = 0; i < dmp->dm_nsegs; i++) {
    964  1.2.18.2  yamt 			if (dmp->dm_segs[i].ds_len == 0)
    965  1.2.18.2  yamt 				continue;
    966  1.2.18.2  yamt 			txd->txd_control1 = dmp->dm_segs[i].ds_len;
    967  1.2.18.2  yamt 			txd->txd_control2 = 0;
    968  1.2.18.2  yamt 			txd->txd_bufaddr = dmp->dm_segs[i].ds_addr;
    969  1.2.18.2  yamt 			txd++;
    970  1.2.18.2  yamt 		}
    971  1.2.18.2  yamt 		ntxd = txd - sc->sc_txd[nexttx] - 1;
    972  1.2.18.2  yamt 		txd = sc->sc_txd[nexttx];
    973  1.2.18.2  yamt 		txd->txd_control1 |= TXD_CTL1_OWN|TXD_CTL1_GCF;
    974  1.2.18.2  yamt 		txd->txd_control2 = TXD_CTL2_UTIL;
    975  1.2.18.2  yamt 		if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4) {
    976  1.2.18.2  yamt 			txd->txd_control1 |= TXD_CTL1_MSS(m->m_pkthdr.segsz);
    977  1.2.18.2  yamt 			txd->txd_control1 |= TXD_CTL1_LSO;
    978  1.2.18.2  yamt 		}
    979  1.2.18.2  yamt 
    980  1.2.18.2  yamt 		if (m->m_pkthdr.csum_flags & M_CSUM_IPv4)
    981  1.2.18.2  yamt 			txd->txd_control2 |= TXD_CTL2_CIPv4;
    982  1.2.18.2  yamt 		if (m->m_pkthdr.csum_flags & M_CSUM_TCPv4)
    983  1.2.18.2  yamt 			txd->txd_control2 |= TXD_CTL2_CTCP;
    984  1.2.18.2  yamt 		if (m->m_pkthdr.csum_flags & M_CSUM_UDPv4)
    985  1.2.18.2  yamt 			txd->txd_control2 |= TXD_CTL2_CUDP;
    986  1.2.18.2  yamt 		txd[ntxd].txd_control1 |= TXD_CTL1_GCL;
    987  1.2.18.2  yamt 
    988  1.2.18.2  yamt 		bus_dmamap_sync(sc->sc_dmat, dmp, 0, dmp->dm_mapsize,
    989  1.2.18.2  yamt 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
    990  1.2.18.2  yamt 
    991  1.2.18.2  yamt 		par = sc->sc_txdp[nexttx];
    992  1.2.18.2  yamt 		lcr = TXDL_NUMTXD(ntxd) | TXDL_LGC_FIRST | TXDL_LGC_LAST;
    993  1.2.18.2  yamt 		if (m->m_pkthdr.csum_flags & M_CSUM_TSOv4)
    994  1.2.18.2  yamt 			lcr |= TXDL_SFF;
    995  1.2.18.2  yamt 		TXP_WCSR(TXDL_PAR, par);
    996  1.2.18.2  yamt 		TXP_WCSR(TXDL_LCR, lcr);
    997  1.2.18.2  yamt 
    998  1.2.18.2  yamt #if NBPFILTER > 0
    999  1.2.18.2  yamt 		if (ifp->if_bpf)
   1000  1.2.18.2  yamt 			bpf_mtap(ifp->if_bpf, m);
   1001  1.2.18.2  yamt #endif /* NBPFILTER > 0 */
   1002  1.2.18.2  yamt 
   1003  1.2.18.2  yamt 		sc->sc_nexttx = NEXTTX(nexttx);
   1004  1.2.18.2  yamt 	}
   1005  1.2.18.2  yamt }
   1006  1.2.18.2  yamt 
   1007  1.2.18.2  yamt /*
   1008  1.2.18.2  yamt  * Allocate DMA memory for transmit descriptor fragments.
   1009  1.2.18.2  yamt  * Only one map is used for all descriptors.
   1010  1.2.18.2  yamt  */
   1011  1.2.18.2  yamt int
   1012  1.2.18.2  yamt xge_alloc_txmem(struct xge_softc *sc)
   1013  1.2.18.2  yamt {
   1014  1.2.18.2  yamt 	struct txd *txp;
   1015  1.2.18.2  yamt 	bus_dma_segment_t seg;
   1016  1.2.18.2  yamt 	bus_addr_t txdp;
   1017  1.2.18.2  yamt 	caddr_t kva;
   1018  1.2.18.2  yamt 	int i, rseg, state;
   1019  1.2.18.2  yamt 
   1020  1.2.18.2  yamt #define TXMAPSZ (NTXDESCS*NTXFRAGS*sizeof(struct txd))
   1021  1.2.18.2  yamt 	state = 0;
   1022  1.2.18.2  yamt 	if (bus_dmamem_alloc(sc->sc_dmat, TXMAPSZ, PAGE_SIZE, 0,
   1023  1.2.18.2  yamt 	    &seg, 1, &rseg, BUS_DMA_NOWAIT))
   1024  1.2.18.2  yamt 		goto err;
   1025  1.2.18.2  yamt 	state++;
   1026  1.2.18.2  yamt 	if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, TXMAPSZ, &kva,
   1027  1.2.18.2  yamt 	    BUS_DMA_NOWAIT))
   1028  1.2.18.2  yamt 		goto err;
   1029  1.2.18.2  yamt 
   1030  1.2.18.2  yamt 	state++;
   1031  1.2.18.2  yamt 	if (bus_dmamap_create(sc->sc_dmat, TXMAPSZ, 1, TXMAPSZ, 0,
   1032  1.2.18.2  yamt 	    BUS_DMA_NOWAIT, &sc->sc_txmap))
   1033  1.2.18.2  yamt 		goto err;
   1034  1.2.18.2  yamt 	state++;
   1035  1.2.18.2  yamt 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_txmap,
   1036  1.2.18.2  yamt 	    kva, TXMAPSZ, NULL, BUS_DMA_NOWAIT))
   1037  1.2.18.2  yamt 		goto err;
   1038  1.2.18.2  yamt 
   1039  1.2.18.2  yamt 	/* setup transmit array pointers */
   1040  1.2.18.2  yamt 	txp = (struct txd *)kva;
   1041  1.2.18.2  yamt 	txdp = seg.ds_addr;
   1042  1.2.18.2  yamt 	for (txp = (struct txd *)kva, i = 0; i < NTXDESCS; i++) {
   1043  1.2.18.2  yamt 		sc->sc_txd[i] = txp;
   1044  1.2.18.2  yamt 		sc->sc_txdp[i] = txdp;
   1045  1.2.18.2  yamt 		txp += NTXFRAGS;
   1046  1.2.18.2  yamt 		txdp += (NTXFRAGS * sizeof(struct txd));
   1047  1.2.18.2  yamt 	}
   1048  1.2.18.2  yamt 
   1049  1.2.18.2  yamt 	return 0;
   1050  1.2.18.2  yamt 
   1051  1.2.18.2  yamt err:
   1052  1.2.18.2  yamt 	if (state > 2)
   1053  1.2.18.2  yamt 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_txmap);
   1054  1.2.18.2  yamt 	if (state > 1)
   1055  1.2.18.2  yamt 		bus_dmamem_unmap(sc->sc_dmat, kva, TXMAPSZ);
   1056  1.2.18.2  yamt 	if (state > 0)
   1057  1.2.18.2  yamt 		bus_dmamem_free(sc->sc_dmat, &seg, rseg);
   1058  1.2.18.2  yamt 	return ENOBUFS;
   1059  1.2.18.2  yamt }
   1060  1.2.18.2  yamt 
   1061  1.2.18.2  yamt /*
   1062  1.2.18.2  yamt  * Allocate DMA memory for receive descriptor,
   1063  1.2.18.2  yamt  * only one map is used for all descriptors.
   1064  1.2.18.2  yamt  * link receive descriptor pages together.
   1065  1.2.18.2  yamt  */
   1066  1.2.18.2  yamt int
   1067  1.2.18.2  yamt xge_alloc_rxmem(struct xge_softc *sc)
   1068  1.2.18.2  yamt {
   1069  1.2.18.2  yamt 	struct rxd_4k *rxpp;
   1070  1.2.18.2  yamt 	bus_dma_segment_t seg;
   1071  1.2.18.2  yamt 	caddr_t kva;
   1072  1.2.18.2  yamt 	int i, rseg, state;
   1073  1.2.18.2  yamt 
   1074  1.2.18.2  yamt 	/* sanity check */
   1075  1.2.18.2  yamt 	if (sizeof(struct rxd_4k) != XGE_PAGE) {
   1076  1.2.18.2  yamt 		printf("bad compiler struct alignment, %d != %d\n",
   1077  1.2.18.2  yamt 		    (int)sizeof(struct rxd_4k), XGE_PAGE);
   1078  1.2.18.2  yamt 		return EINVAL;
   1079  1.2.18.2  yamt 	}
   1080  1.2.18.2  yamt 
   1081  1.2.18.2  yamt 	state = 0;
   1082  1.2.18.2  yamt 	if (bus_dmamem_alloc(sc->sc_dmat, RXMAPSZ, PAGE_SIZE, 0,
   1083  1.2.18.2  yamt 	    &seg, 1, &rseg, BUS_DMA_NOWAIT))
   1084  1.2.18.2  yamt 		goto err;
   1085  1.2.18.2  yamt 	state++;
   1086  1.2.18.2  yamt 	if (bus_dmamem_map(sc->sc_dmat, &seg, rseg, RXMAPSZ, &kva,
   1087  1.2.18.2  yamt 	    BUS_DMA_NOWAIT))
   1088  1.2.18.2  yamt 		goto err;
   1089  1.2.18.2  yamt 
   1090  1.2.18.2  yamt 	state++;
   1091  1.2.18.2  yamt 	if (bus_dmamap_create(sc->sc_dmat, RXMAPSZ, 1, RXMAPSZ, 0,
   1092  1.2.18.2  yamt 	    BUS_DMA_NOWAIT, &sc->sc_rxmap))
   1093  1.2.18.2  yamt 		goto err;
   1094  1.2.18.2  yamt 	state++;
   1095  1.2.18.2  yamt 	if (bus_dmamap_load(sc->sc_dmat, sc->sc_rxmap,
   1096  1.2.18.2  yamt 	    kva, RXMAPSZ, NULL, BUS_DMA_NOWAIT))
   1097  1.2.18.2  yamt 		goto err;
   1098  1.2.18.2  yamt 
   1099  1.2.18.2  yamt 	/* setup receive page link pointers */
   1100  1.2.18.2  yamt 	for (rxpp = (struct rxd_4k *)kva, i = 0; i < NRXPAGES; i++, rxpp++) {
   1101  1.2.18.2  yamt 		sc->sc_rxd_4k[i] = rxpp;
   1102  1.2.18.2  yamt 		rxpp->r4_next = (uint64_t)sc->sc_rxmap->dm_segs[0].ds_addr +
   1103  1.2.18.2  yamt 		    (i*sizeof(struct rxd_4k)) + sizeof(struct rxd_4k);
   1104  1.2.18.2  yamt 	}
   1105  1.2.18.2  yamt 	sc->sc_rxd_4k[NRXPAGES-1]->r4_next =
   1106  1.2.18.2  yamt 	    (uint64_t)sc->sc_rxmap->dm_segs[0].ds_addr;
   1107  1.2.18.2  yamt 
   1108  1.2.18.2  yamt 	return 0;
   1109  1.2.18.2  yamt 
   1110  1.2.18.2  yamt err:
   1111  1.2.18.2  yamt 	if (state > 2)
   1112  1.2.18.2  yamt 		bus_dmamap_destroy(sc->sc_dmat, sc->sc_txmap);
   1113  1.2.18.2  yamt 	if (state > 1)
   1114  1.2.18.2  yamt 		bus_dmamem_unmap(sc->sc_dmat, kva, TXMAPSZ);
   1115  1.2.18.2  yamt 	if (state > 0)
   1116  1.2.18.2  yamt 		bus_dmamem_free(sc->sc_dmat, &seg, rseg);
   1117  1.2.18.2  yamt 	return ENOBUFS;
   1118  1.2.18.2  yamt }
   1119  1.2.18.2  yamt 
   1120  1.2.18.2  yamt 
   1121  1.2.18.2  yamt /*
   1122  1.2.18.2  yamt  * Add a new mbuf chain to descriptor id.
   1123  1.2.18.2  yamt  */
   1124  1.2.18.2  yamt int
   1125  1.2.18.2  yamt xge_add_rxbuf(struct xge_softc *sc, int id)
   1126  1.2.18.2  yamt {
   1127  1.2.18.2  yamt 	struct rxdesc *rxd;
   1128  1.2.18.2  yamt 	struct mbuf *m[5];
   1129  1.2.18.2  yamt 	int page, desc, error;
   1130  1.2.18.2  yamt #if RX_MODE == RX_MODE_5
   1131  1.2.18.2  yamt 	int i;
   1132  1.2.18.2  yamt #endif
   1133  1.2.18.2  yamt 
   1134  1.2.18.2  yamt 	page = id/NDESC_BUFMODE;
   1135  1.2.18.2  yamt 	desc = id%NDESC_BUFMODE;
   1136  1.2.18.2  yamt 
   1137  1.2.18.2  yamt 	rxd = &sc->sc_rxd_4k[page]->r4_rxd[desc];
   1138  1.2.18.2  yamt 
   1139  1.2.18.2  yamt 	/*
   1140  1.2.18.2  yamt 	 * Allocate mbufs.
   1141  1.2.18.2  yamt 	 * Currently five mbufs and two clusters are used,
   1142  1.2.18.2  yamt 	 * the hardware will put (ethernet, ip, tcp/udp) headers in
   1143  1.2.18.2  yamt 	 * their own buffer and the clusters are only used for data.
   1144  1.2.18.2  yamt 	 */
   1145  1.2.18.2  yamt #if RX_MODE == RX_MODE_1
   1146  1.2.18.2  yamt 	MGETHDR(m[0], M_DONTWAIT, MT_DATA);
   1147  1.2.18.2  yamt 	if (m[0] == NULL)
   1148  1.2.18.2  yamt 		return ENOBUFS;
   1149  1.2.18.2  yamt 	MCLGET(m[0], M_DONTWAIT);
   1150  1.2.18.2  yamt 	if ((m[0]->m_flags & M_EXT) == 0) {
   1151  1.2.18.2  yamt 		m_freem(m[0]);
   1152  1.2.18.2  yamt 		return ENOBUFS;
   1153  1.2.18.2  yamt 	}
   1154  1.2.18.2  yamt 	m[0]->m_len = m[0]->m_pkthdr.len = m[0]->m_ext.ext_size;
   1155  1.2.18.2  yamt #elif RX_MODE == RX_MODE_3
   1156  1.2.18.2  yamt #error missing rxmode 3.
   1157  1.2.18.2  yamt #elif RX_MODE == RX_MODE_5
   1158  1.2.18.2  yamt 	MGETHDR(m[0], M_DONTWAIT, MT_DATA);
   1159  1.2.18.2  yamt 	for (i = 1; i < 5; i++) {
   1160  1.2.18.2  yamt 		MGET(m[i], M_DONTWAIT, MT_DATA);
   1161  1.2.18.2  yamt 	}
   1162  1.2.18.2  yamt 	if (m[3])
   1163  1.2.18.2  yamt 		MCLGET(m[3], M_DONTWAIT);
   1164  1.2.18.2  yamt 	if (m[4])
   1165  1.2.18.2  yamt 		MCLGET(m[4], M_DONTWAIT);
   1166  1.2.18.2  yamt 	if (!m[0] || !m[1] || !m[2] || !m[3] || !m[4] ||
   1167  1.2.18.2  yamt 	    ((m[3]->m_flags & M_EXT) == 0) || ((m[4]->m_flags & M_EXT) == 0)) {
   1168  1.2.18.2  yamt 		/* Out of something */
   1169  1.2.18.2  yamt 		for (i = 0; i < 5; i++)
   1170  1.2.18.2  yamt 			if (m[i] != NULL)
   1171  1.2.18.2  yamt 				m_free(m[i]);
   1172  1.2.18.2  yamt 		return ENOBUFS;
   1173  1.2.18.2  yamt 	}
   1174  1.2.18.2  yamt 	/* Link'em together */
   1175  1.2.18.2  yamt 	m[0]->m_next = m[1];
   1176  1.2.18.2  yamt 	m[1]->m_next = m[2];
   1177  1.2.18.2  yamt 	m[2]->m_next = m[3];
   1178  1.2.18.2  yamt 	m[3]->m_next = m[4];
   1179  1.2.18.2  yamt #else
   1180  1.2.18.2  yamt #error bad mode RX_MODE
   1181  1.2.18.2  yamt #endif
   1182  1.2.18.2  yamt 
   1183  1.2.18.2  yamt 	if (sc->sc_rxb[id])
   1184  1.2.18.2  yamt 		bus_dmamap_unload(sc->sc_dmat, sc->sc_rxm[id]);
   1185  1.2.18.2  yamt 	sc->sc_rxb[id] = m[0];
   1186  1.2.18.2  yamt 
   1187  1.2.18.2  yamt 	error = bus_dmamap_load_mbuf(sc->sc_dmat, sc->sc_rxm[id], m[0],
   1188  1.2.18.2  yamt 	    BUS_DMA_READ|BUS_DMA_NOWAIT);
   1189  1.2.18.2  yamt 	if (error)
   1190  1.2.18.2  yamt 		return error;
   1191  1.2.18.2  yamt 	bus_dmamap_sync(sc->sc_dmat, sc->sc_rxm[id], 0,
   1192  1.2.18.2  yamt 	    sc->sc_rxm[id]->dm_mapsize, BUS_DMASYNC_PREREAD);
   1193  1.2.18.2  yamt 
   1194  1.2.18.2  yamt #if RX_MODE == RX_MODE_1
   1195  1.2.18.2  yamt 	rxd->rxd_control2 = RXD_MKCTL2(m[0]->m_len, 0, 0);
   1196  1.2.18.2  yamt 	rxd->rxd_buf0 = (uint64_t)sc->sc_rxm[id]->dm_segs[0].ds_addr;
   1197  1.2.18.2  yamt 	rxd->rxd_control1 = RXD_CTL1_OWN;
   1198  1.2.18.2  yamt #elif RX_MODE == RX_MODE_3
   1199  1.2.18.2  yamt #elif RX_MODE == RX_MODE_5
   1200  1.2.18.2  yamt 	rxd->rxd_control3 = RXD_MKCTL3(0, m[3]->m_len, m[4]->m_len);
   1201  1.2.18.2  yamt 	rxd->rxd_control2 = RXD_MKCTL2(m[0]->m_len, m[1]->m_len, m[2]->m_len);
   1202  1.2.18.2  yamt 	rxd->rxd_buf0 = (uint64_t)sc->sc_rxm[id]->dm_segs[0].ds_addr;
   1203  1.2.18.2  yamt 	rxd->rxd_buf1 = (uint64_t)sc->sc_rxm[id]->dm_segs[1].ds_addr;
   1204  1.2.18.2  yamt 	rxd->rxd_buf2 = (uint64_t)sc->sc_rxm[id]->dm_segs[2].ds_addr;
   1205  1.2.18.2  yamt 	rxd->rxd_buf3 = (uint64_t)sc->sc_rxm[id]->dm_segs[3].ds_addr;
   1206  1.2.18.2  yamt 	rxd->rxd_buf4 = (uint64_t)sc->sc_rxm[id]->dm_segs[4].ds_addr;
   1207  1.2.18.2  yamt 	rxd->rxd_control1 = RXD_CTL1_OWN;
   1208  1.2.18.2  yamt #endif
   1209  1.2.18.2  yamt 
   1210  1.2.18.2  yamt 	XGE_RXSYNC(id, BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
   1211  1.2.18.2  yamt 	return 0;
   1212  1.2.18.2  yamt }
   1213  1.2.18.2  yamt 
   1214  1.2.18.2  yamt /*
   1215  1.2.18.2  yamt  * These magics comes from the FreeBSD driver.
   1216  1.2.18.2  yamt  */
   1217  1.2.18.2  yamt int
   1218  1.2.18.2  yamt xge_setup_xgxs(struct xge_softc *sc)
   1219  1.2.18.2  yamt {
   1220  1.2.18.2  yamt 	/* The magic numbers are described in the users guide */
   1221  1.2.18.2  yamt 
   1222  1.2.18.2  yamt 	/* Writing to MDIO 0x8000 (Global Config 0) */
   1223  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x8000051500000000ULL); DELAY(50);
   1224  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80000515000000E0ULL); DELAY(50);
   1225  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80000515D93500E4ULL); DELAY(50);
   1226  1.2.18.2  yamt 
   1227  1.2.18.2  yamt 	/* Writing to MDIO 0x8000 (Global Config 1) */
   1228  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x8001051500000000ULL); DELAY(50);
   1229  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80010515000000e0ULL); DELAY(50);
   1230  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80010515001e00e4ULL); DELAY(50);
   1231  1.2.18.2  yamt 
   1232  1.2.18.2  yamt 	/* Reset the Gigablaze */
   1233  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x8002051500000000ULL); DELAY(50);
   1234  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80020515000000E0ULL); DELAY(50);
   1235  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80020515F21000E4ULL); DELAY(50);
   1236  1.2.18.2  yamt 
   1237  1.2.18.2  yamt 	/* read the pole settings */
   1238  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x8000051500000000ULL); DELAY(50);
   1239  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80000515000000e0ULL); DELAY(50);
   1240  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80000515000000ecULL); DELAY(50);
   1241  1.2.18.2  yamt 
   1242  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x8001051500000000ULL); DELAY(50);
   1243  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80010515000000e0ULL); DELAY(50);
   1244  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80010515000000ecULL); DELAY(50);
   1245  1.2.18.2  yamt 
   1246  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x8002051500000000ULL); DELAY(50);
   1247  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80020515000000e0ULL); DELAY(50);
   1248  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x80020515000000ecULL); DELAY(50);
   1249  1.2.18.2  yamt 
   1250  1.2.18.2  yamt 	/* Workaround for TX Lane XAUI initialization error.
   1251  1.2.18.2  yamt 	   Read Xpak PHY register 24 for XAUI lane status */
   1252  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x0018040000000000ULL); DELAY(50);
   1253  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x00180400000000e0ULL); DELAY(50);
   1254  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x00180400000000ecULL); DELAY(50);
   1255  1.2.18.2  yamt 
   1256  1.2.18.2  yamt 	/*
   1257  1.2.18.2  yamt 	 * Reading the MDIO control with value 0x1804001c0F001c
   1258  1.2.18.2  yamt 	 * means the TxLanes were already in sync
   1259  1.2.18.2  yamt 	 * Reading the MDIO control with value 0x1804000c0x001c
   1260  1.2.18.2  yamt 	 * means some TxLanes are not in sync where x is a 4-bit
   1261  1.2.18.2  yamt 	 * value representing each lanes
   1262  1.2.18.2  yamt 	 */
   1263  1.2.18.2  yamt #if 0
   1264  1.2.18.2  yamt 	val = PIF_RCSR(MDIO_CONTROL);
   1265  1.2.18.2  yamt 	if (val != 0x1804001c0F001cULL) {
   1266  1.2.18.2  yamt 		printf("%s: MDIO_CONTROL: %llx != %llx\n",
   1267  1.2.18.2  yamt 		    XNAME, val, 0x1804001c0F001cULL);
   1268  1.2.18.2  yamt 		return 1;
   1269  1.2.18.2  yamt 	}
   1270  1.2.18.2  yamt #endif
   1271  1.2.18.2  yamt 
   1272  1.2.18.2  yamt 	/* Set and remove the DTE XS INTLoopBackN */
   1273  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x0000051500000000ULL); DELAY(50);
   1274  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x00000515604000e0ULL); DELAY(50);
   1275  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x00000515604000e4ULL); DELAY(50);
   1276  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x00000515204000e4ULL); DELAY(50);
   1277  1.2.18.2  yamt 	PIF_WCSR(DTX_CONTROL, 0x00000515204000ecULL); DELAY(50);
   1278  1.2.18.2  yamt 
   1279  1.2.18.2  yamt #if 0
   1280  1.2.18.2  yamt 	/* Reading the DTX control register Should be 0x5152040001c */
   1281  1.2.18.2  yamt 	val = PIF_RCSR(DTX_CONTROL);
   1282  1.2.18.2  yamt 	if (val != 0x5152040001cULL) {
   1283  1.2.18.2  yamt 		printf("%s: DTX_CONTROL: %llx != %llx\n",
   1284  1.2.18.2  yamt 		    XNAME, val, 0x5152040001cULL);
   1285  1.2.18.2  yamt 		return 1;
   1286  1.2.18.2  yamt 	}
   1287  1.2.18.2  yamt #endif
   1288  1.2.18.2  yamt 
   1289  1.2.18.2  yamt 	PIF_WCSR(MDIO_CONTROL, 0x0018040000000000ULL); DELAY(50);
   1290  1.2.18.2  yamt 	PIF_WCSR(MDIO_CONTROL, 0x00180400000000e0ULL); DELAY(50);
   1291  1.2.18.2  yamt 	PIF_WCSR(MDIO_CONTROL, 0x00180400000000ecULL); DELAY(50);
   1292  1.2.18.2  yamt 
   1293  1.2.18.2  yamt #if 0
   1294  1.2.18.2  yamt 	/* Reading the MIOD control should be 0x1804001c0f001c */
   1295  1.2.18.2  yamt 	val = PIF_RCSR(MDIO_CONTROL);
   1296  1.2.18.2  yamt 	if (val != 0x1804001c0f001cULL) {
   1297  1.2.18.2  yamt 		printf("%s: MDIO_CONTROL2: %llx != %llx\n",
   1298  1.2.18.2  yamt 		    XNAME, val, 0x1804001c0f001cULL);
   1299  1.2.18.2  yamt 		return 1;
   1300  1.2.18.2  yamt 	}
   1301  1.2.18.2  yamt #endif
   1302  1.2.18.2  yamt 	return 0;
   1303  1.2.18.2  yamt }
   1304