1/*  *********************************************************************
2    *  Broadcom Common Firmware Environment (CFE)
3    *
4    *  Broadcom BCM4401 Ethernet Driver		      File: dev_bcm4401.c
5    *
6    *  Author:  Ed Satterthwaite
7    *
8    *********************************************************************
9    *
10    *  Copyright 2000,2001,2002,2003
11    *  Broadcom Corporation. All rights reserved.
12    *
13    *  This software is furnished under license and may be used and
14    *  copied only in accordance with the following terms and
15    *  conditions.  Subject to these conditions, you may download,
16    *  copy, install, use, modify and distribute modified or unmodified
17    *  copies of this software in source and/or binary form.  No title
18    *  or ownership is transferred hereby.
19    *
20    *  1) Any source code used, modified or distributed must reproduce
21    *     and retain this copyright notice and list of conditions
22    *     as they appear in the source file.
23    *
24    *  2) No right is granted to use any trade name, trademark, or
25    *     logo of Broadcom Corporation.  The "Broadcom Corporation"
26    *     name may not be used to endorse or promote products derived
27    *     from this software without the prior written permission of
28    *     Broadcom Corporation.
29    *
30    *  3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
31    *     IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
32    *     WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
33    *     PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
34    *     SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
35    *     PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
36    *     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
37    *     (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
38    *     GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
39    *     BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
40    *     OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
41    *     TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
42    *     THE POSSIBILITY OF SUCH DAMAGE.
43    ********************************************************************* */
44
45
46#include "cfe.h"
47#include "lib_try.h"
48#include "lib_physio.h"
49#ifdef CPUCFG_MEMCPY
50#error "this is broken now."
51extern void *CPUCFG_MEMCPY(void *dest, const void *src, size_t cnt);
52#define blockcopy CPUCFG_MEMCPY
53#else
54#define blockcopy memcpy
55#endif
56#include "cfe_irq.h"
57
58#include "net_enet.h"
59
60#include "pcivar.h"
61#include "pcireg.h"
62
63#include "bcm4401.h"
64#include "mii.h"
65
66
67/* This is a driver for the Broadcom 4401 10/100 MAC with integrated PHY.
68
69   This SB1250 version takes advantage of DMA coherence.  The BCM4401
70   does not have a big-endian mode for DMA.  This driver therefore
71   uses "preserve byte lanes" addresses for all DMA accesses that
72   cross the ZBbus-PCI bridge.  Descriptors and packets headers as
73   seen by a big-endian CPU must be byte-swapped for the DMA engine.  */
74
75#ifndef B44_DEBUG
76#define B44_DEBUG 0
77#endif
78
79#if ((ENDIAN_BIG + ENDIAN_LITTLE) != 1)
80#error "dev_bcm4401: system endian not set"
81#endif
82
83/* Temporary, until configs supply MATCH_BYTES */
84#if defined(MPC824X)  /* any machine without preserve-bits for PIO */
85#define MATCH_BYTES  1
86#else
87#define MATCH_BYTES  0
88#endif
89
90/* Set IPOLL to drive processing through the pseudo-interrupt
91   dispatcher.  Set XPOLL to drive processing by an external polling
92   agent.  Setting both is ok. */
93
94#ifndef IPOLL
95#define IPOLL 0
96#endif
97#ifndef XPOLL
98#define XPOLL 1
99#endif
100
101#define CACHE_ALIGN       32
102#define PAGE_ALIGN        4096
103#define ALIGN(n,align)    (((n)+((align)-1)) & ~((align)-1))
104
105#define MIN_ETHER_PACK  (ENET_MIN_PKT+ENET_CRC_SIZE)   /* size of min packet */
106#define MAX_ETHER_PACK  (ENET_MAX_PKT+ENET_CRC_SIZE)   /* size of max packet */
107
108/* Packet buffers.  For the BCM4401, an rx packet is preceded by
109   status information written into the rx buffer.  The packet itself
110   begins at a programmable offset (PKTBUF_RX_OFFSET), which must be
111   at least 28.  The DMA engine allows arbitrary buffer and packet
112   alignment, but aligning to a cache line boundary can reduce lines
113   touched on the copies. */
114
115#define PKTBUF_RX_OFFSET    CACHE_ALIGN
116#define ETH_PKTBUF_LEN      ALIGN(PKTBUF_RX_OFFSET+MAX_ETHER_PACK, CACHE_ALIGN)
117#define ETH_PKTPOOL_SIZE    32
118
119typedef struct eth_pkt_s {
120    queue_t next;			/*  8 */
121    uint8_t *buffer;			/*  4 */
122    uint32_t flags;			/*  4 */
123    int32_t length;			/*  4 */
124    uint32_t unused[3];			/* 12 */
125    uint8_t data[ETH_PKTBUF_LEN];
126} eth_pkt_t;
127
128#define ETH_PKTBUF_SIZE   ALIGN(sizeof(eth_pkt_t), CACHE_ALIGN)
129#define ETH_PKTBUF_OFFSET (offsetof(eth_pkt_t, data))
130
131#define ETH_PKT_BASE(data) ((eth_pkt_t *)((data) - ETH_PKTBUF_OFFSET))
132
133static void
134show_packet(char c, eth_pkt_t *pkt, int offset)
135{
136    int i;
137    int n = (pkt->length < 32 ? pkt->length : 32);
138
139    xprintf("%c[%4d]:", c, pkt->length);
140    for (i = 0; i < n; i++) {
141	if (i % 4 == 0)
142	    xprintf(" ");
143	xprintf("%02x", pkt->buffer[offset+i]);
144	}
145    xprintf("\n");
146}
147
148
149/* Descriptor structures.  The descriptor ring must begin on a 4K
150   boundary and cannot exceed 512 entries.  Note that descriptors are
151   referenced by the DMA engine using match-bytes addresses. */
152
153typedef struct rx_dscr {
154    uint32_t   rxd_cmdsts;
155    pci_addr_t rxd_bufptr;
156} rx_dscr;
157
158typedef struct tx_dscr {
159    uint32_t   txd_cmdsts;
160    pci_addr_t txd_bufptr;
161} tx_dscr;
162
163
164/* Driver data structures */
165
166typedef enum {
167    eth_state_uninit,
168    eth_state_off,
169    eth_state_on,
170    eth_state_broken
171} eth_state_t;
172
173typedef struct bcm4401_softc {
174    uint32_t membase;
175    uint8_t irq;		/* interrupt mapping (used if IPOLL) */
176    pcitag_t tag;               /* tag for configuration registers */
177
178    uint8_t hwaddr[ENET_ADDR_LEN];
179    uint16_t device;            /* chip device code */
180    uint8_t revision;		/* chip revision and step */
181
182    eth_state_t state;          /* current state */
183    uint32_t intmask;           /* interrupt mask */
184
185    /* These fields are set before calling bcm4401_hwinit */
186    int linkspeed;		/* encodings from cfe_ioctl */
187    int loopback;
188
189    /* Packet free list */
190    queue_t freelist;
191    uint8_t *pktpool;
192    queue_t rxqueue;
193
194    /* The descriptor tables */
195    uint8_t    *rxdscrmem;	/* receive descriptors */
196    uint8_t    *txdscrmem;	/* transmit descriptors */
197
198    /* These fields keep track of where we are in tx/rx processing */
199    volatile rx_dscr *rxdscr_start;	/* beginning of ring */
200    volatile rx_dscr *rxdscr_end;	/* end of ring */
201    volatile rx_dscr *rxdscr_remove;	/* oldest one owned by DMA */
202    volatile rx_dscr *rxdscr_add;	/* next place to put a buffer */
203    int      rxdscr_onring;
204
205    volatile tx_dscr *txdscr_start;	/* beginning of ring */
206    volatile tx_dscr *txdscr_end;	/* end of ring */
207    volatile tx_dscr *txdscr_remove;	/* oldest one owned by DMA */
208    volatile tx_dscr *txdscr_add;	/* next place to put a buffer */
209
210    cfe_devctx_t *devctx;
211
212    int phy_addr;
213    int slow_poll;
214    uint32_t phy_vendor;
215    uint16_t phy_device;
216
217    /* Statistics */
218    uint32_t inpkts;
219    uint32_t outpkts;
220    uint32_t interrupts;
221    uint32_t rx_interrupts;
222    uint32_t tx_interrupts;
223} bcm4401_softc;
224
225
226/* Entry to and exit from critical sections (currently relative to
227   interrupts only, not SMP) */
228
229#if CFG_INTERRUPTS
230#define CS_ENTER(sc) cfe_disable_irq(sc->irq)
231#define CS_EXIT(sc)  cfe_enable_irq(sc->irq)
232#else
233#define CS_ENTER(sc) ((void)0)
234#define CS_EXIT(sc)  ((void)0)
235#endif
236
237
238/* Chip parameterization */
239
240#define GP_TIMER_HZ    62500000
241
242
243/* Driver parameterization */
244
245#define MAXRXDSCR      32
246#define MAXTXDSCR      32
247#define MINRXRING	8
248
249
250/* Prototypes */
251
252static void bcm4401_ether_probe(cfe_driver_t *drv,
253				unsigned long probe_a, unsigned long probe_b,
254				void *probe_ptr);
255
256
257/* Address mapping macros.  Accesses in which the BCM4401 is the
258   target are to registers and use match bits mode.  Accesses in which
259   it is the initiator always assume little-endian responses and must
260   use match bytes, per the macros below.  For big-endian hosts, the
261   DMA status word must be byte-swapped.   Also, the PCI interface
262   does address translation so that DMA addresses must be offset.  */
263
264/* Note that PTR_TO_PHYS only works with 32-bit addresses, but then
265   so does the BCM4401. */
266#define PTR_TO_PHYS(x) (PHYSADDR((uintptr_t)(x)))
267#define PHYS_TO_PTR(a) ((uint8_t *)KERNADDR(a))
268
269/* The DMA engine does not have a big-endian option for descriptors
270   and data.  All its accesses through the host bridge use match bytes
271   mode.  The CPU must construct descriptors and headers accordingly.
272   PIO accesses to the configuration and host interface registers use
273   match bits.  In addition, the PCI interface does address shifting.
274   Thus the definitions used for most other device drivers don't work
275   here. */
276#undef PHYS_TO_PCI
277#undef PCI_TO_PHYS
278#define PHYS_TO_PCI(a) ((uint32_t) (a) + 0x40000000)
279#define PCI_TO_PHYS(a) ((uint32_t) (a) - 0x40000000)
280
281#define PCI_TO_PTR(a)  (PHYS_TO_PTR(PCI_TO_PHYS(a)))
282#define PTR_TO_PCI(x)  (PHYS_TO_PCI(PTR_TO_PHYS(x)))
283
284#if (ENDIAN_BIG && MATCH_BYTES)
285#define CSR_MATCH_MODE       PCI_MATCH_BYTES
286#define READCSR(sc,csr)      (phys_read32_swapped((sc)->membase + (csr)))
287#define WRITECSR(sc,csr,val) (phys_write32_swapped((sc)->membase + (csr), (val)))
288#else
289#define CSR_MATCH_MODE       PCI_MATCH_BITS
290#define READCSR(sc,csr)      (phys_read32((sc)->membase + (csr)))
291#define WRITECSR(sc,csr,val) (phys_write32((sc)->membase + (csr), (val)))
292#endif
293
294/* Byte swap utilities: host to/from little-endian */
295
296#if ENDIAN_BIG
297#define HTOL4(x) \
298    ((((x) & 0x00FF) << 24) | \
299     (((x) & 0xFF00) << 8)  | \
300     (((x) >> 8) & 0xFF00)  | \
301     (((x) >> 24) & 0x00FF))
302
303static uint32_t
304htol4(uint32_t x)
305{
306    uint32_t t;
307
308    t = ((x & 0xFF00FF00) >> 8) | ((x & 0x00FF00FF) << 8);
309    return (t >> 16) | ((t & 0xFFFF) << 16);
310}
311#else
312#define HTOL4(x) (x)
313#define htol4(x) (x)
314#endif
315
316#define ltoh4 htol4   /* self-inverse */
317
318
319/* Packet management */
320
321static eth_pkt_t *
322eth_alloc_pkt(bcm4401_softc *sc)
323{
324    eth_pkt_t *pkt;
325
326    CS_ENTER(sc);
327    pkt = (eth_pkt_t *) q_deqnext(&sc->freelist);
328    CS_EXIT(sc);
329    if (!pkt) return NULL;
330
331    pkt->buffer = pkt->data;
332    pkt->length = ETH_PKTBUF_LEN;
333    pkt->flags = 0;
334
335    return pkt;
336}
337
338static void
339eth_free_pkt(bcm4401_softc *sc, eth_pkt_t *pkt)
340{
341    CS_ENTER(sc);
342    q_enqueue(&sc->freelist, &pkt->next);
343    CS_EXIT(sc);
344}
345
346
347static void
348eth_initfreelist(bcm4401_softc *sc)
349{
350    int idx;
351    uint8_t *ptr;
352    eth_pkt_t *pkt;
353
354    q_init(&sc->freelist);
355
356    ptr = sc->pktpool;
357    for (idx = 0; idx < ETH_PKTPOOL_SIZE; idx++) {
358	pkt = (eth_pkt_t *) ptr;
359	eth_free_pkt(sc, pkt);
360	ptr += ETH_PKTBUF_SIZE;
361	}
362}
363
364
365/* Utilities */
366
367static const char *
368bcm4401_devname(bcm4401_softc *sc)
369{
370    return (sc->devctx != NULL ? cfe_device_name(sc->devctx) : "eth?");
371}
372
373
374/* Descriptor ring management */
375
376static int
377bcm4401_add_rcvbuf(bcm4401_softc *sc, eth_pkt_t *pkt)
378{
379    volatile rx_dscr *rxd;
380    volatile rx_dscr *nextrxd;
381
382    rxd = sc->rxdscr_add;
383
384    nextrxd = rxd+1;
385    if (nextrxd == sc->rxdscr_end) {
386	nextrxd = sc->rxdscr_start;
387	}
388
389    /* If the next one is the same as our remove pointer, the ring is
390       considered full.  */
391    if (nextrxd == sc->rxdscr_remove) return -1;
392
393    /* Only the buffer pointer needs updating. */
394    rxd->rxd_bufptr = htol4(V_DSCR1_DB(PTR_TO_PCI(pkt->buffer)));
395
396    sc->rxdscr_add = nextrxd;
397
398    WRITECSR(sc, R_RCV_PTR, V_RPTR_LD(PTR_TO_PCI(nextrxd) & 0xFFF));
399
400    return 0;
401}
402
403static void
404bcm4401_fillrxring(bcm4401_softc *sc)
405{
406    eth_pkt_t *pkt;
407
408    CS_ENTER(sc);
409    while (1) {
410	if (sc->rxdscr_onring >= MINRXRING) {
411	    CS_EXIT(sc);
412	    break;
413	    }
414	CS_EXIT(sc);
415	pkt = eth_alloc_pkt(sc);
416	if (pkt == NULL) {
417	    /* could not allocate a buffer */
418	    break;
419	    }
420	if (bcm4401_add_rcvbuf(sc, pkt) != 0) {
421	    /* could not add buffer to ring */
422	    eth_free_pkt(sc, pkt);
423	    break;
424	    }
425	CS_ENTER(sc);
426	sc->rxdscr_onring++;
427	}
428}
429
430
431/*  Receive buffer processing. */
432
433static void
434bcm4401_rx_callback(bcm4401_softc *sc, eth_pkt_t *pkt)
435{
436    if (B44_DEBUG) show_packet('>', pkt, PKTBUF_RX_OFFSET);
437
438    CS_ENTER(sc);
439    q_enqueue(&sc->rxqueue, &pkt->next);
440    CS_EXIT(sc);
441    sc->inpkts++;
442}
443
444static void
445bcm4401_procrxring(bcm4401_softc *sc)
446{
447    uint32_t rxstat;
448    volatile rx_dscr *rxcurr;
449    volatile rx_dscr *rxd;
450    eth_pkt_t *pkt;
451    eth_pkt_t *newpkt;
452    uint32_t hdr0;
453
454    rxstat = READCSR(sc, R_RCV_STATUS);
455    rxcurr = (volatile rx_dscr *)
456               ((uint8_t *)sc->rxdscr_start + G_RSTAT_CD(rxstat));
457
458    for (;;) {
459	rxd = sc->rxdscr_remove;
460
461	if (rxd == rxcurr) {
462	    /* all packets processed */
463	    break;
464	    }
465
466	pkt = ETH_PKT_BASE(PCI_TO_PTR(ltoh4(rxd->rxd_bufptr)));
467
468	hdr0 = ltoh4(*(uint32_t *)(pkt->buffer));
469	/* Drop error packets */
470	/* The header word apparently reports this (undocumented for 4401).
471                MISC    (1 << 7)    Promiscuous mode enabled.
472                BRDCAST (1 << 6)    Broadcast dest
473                MULT    (1 << 5)    Multicast dest
474		LG      (1 << 4)    Overlength
475		NO      (1 << 3)    Odd number of nibbles
476		RXER    (1 << 2)    Symbol error
477		CRC     (1 << 1)    CRC error
478		OV      (1 << 0)    FIFO overflow
479	 */
480	if (hdr0 & M_RCVHDR0_ERRORS) {
481	    xprintf("BCM4401: rx error %08X\n", hdr0);
482	    newpkt = pkt;           /* recycle the buffer */
483	    }
484	else {
485	    /* Pass up the packet */
486	    pkt->length = G_RCVHDR0_CD(hdr0) - ENET_CRC_SIZE;
487	    bcm4401_rx_callback(sc, pkt);
488	    /* put a buffer back on the ring to replace this one */
489	    newpkt = eth_alloc_pkt(sc);
490	    }
491
492	/* update the pointer, accounting for buffer wrap. */
493	rxd++;
494	if (rxd == sc->rxdscr_end)
495	    rxd = sc->rxdscr_start;
496	sc->rxdscr_remove = rxd;
497
498	if (newpkt) {
499	    /* The ring must have space now. */
500	    bcm4401_add_rcvbuf(sc, newpkt);
501	    }
502	else {
503	    CS_ENTER(sc);
504	    sc->rxdscr_onring--;
505	    CS_EXIT(sc);
506	    }
507	}
508
509    /* XXX Check for error stops. */
510}
511
512
513/*  Transmit ring processing. */
514
515static int
516bcm4401_add_txbuf(bcm4401_softc *sc, eth_pkt_t *pkt)
517{
518    volatile tx_dscr *txd;
519    volatile tx_dscr *nexttxd;
520    uint32_t cmdsts;
521
522    txd = sc->txdscr_add;
523    cmdsts = M_DSCR0_SF | M_DSCR0_EF | M_DSCR0_IC;
524    nexttxd = (txd+1);
525    if (nexttxd == sc->txdscr_end) {
526	cmdsts |= M_DSCR0_ET;
527	nexttxd = sc->txdscr_start;
528	}
529
530    /* If the next one is the same as our remove pointer, the ring is
531       considered full.  */
532    if (nexttxd == sc->txdscr_remove) return -1;
533
534    txd->txd_bufptr = htol4(V_DSCR1_DB(PTR_TO_PCI(pkt->buffer)));
535    cmdsts |= V_DSCR0_BC(pkt->length);
536    txd->txd_cmdsts = htol4(cmdsts);
537
538    sc->txdscr_add = nexttxd;
539
540    return 0;
541}
542
543
544static int
545bcm4401_transmit(bcm4401_softc *sc, eth_pkt_t *pkt)
546{
547    int rv;
548
549    if (B44_DEBUG) show_packet('<', pkt, 0);
550
551    rv = bcm4401_add_txbuf(sc, pkt);
552    if (rv == 0) {
553	WRITECSR(sc, R_XMT_PTR, V_XPTR_LD(PTR_TO_PCI(sc->txdscr_add) & 0xFFF));
554	}
555
556    sc->outpkts++;
557    return rv;
558}
559
560static void
561bcm4401_proctxring(bcm4401_softc *sc)
562{
563    uint32_t txstat;
564    volatile tx_dscr *txcurr;
565    volatile tx_dscr *txd;
566    eth_pkt_t *pkt;
567
568    txstat = READCSR(sc, R_XMT_STATUS);
569    txcurr = (volatile tx_dscr *)
570               ((uint8_t *)sc->txdscr_start + G_XSTAT_CD(txstat));
571
572    for (;;) {
573	txd = sc->txdscr_remove;
574
575	if (txd == txcurr) {
576	    /* ring is empty, no buffers to process */
577	    break;
578	    }
579
580	/* Just free the packet */
581	pkt = ETH_PKT_BASE(PCI_TO_PTR(V_DSCR1_DB(ltoh4(txd->txd_bufptr))));
582	eth_free_pkt(sc, pkt);
583
584	/* update the pointer, accounting for buffer wrap. */
585	txd++;
586	if (txd == sc->txdscr_end)
587	    txd = sc->txdscr_start;
588
589	sc->txdscr_remove = txd;
590	}
591
592    /* XXX Check for error halt. */
593}
594
595
596static void
597bcm4401_initrings(bcm4401_softc *sc)
598{
599    volatile tx_dscr *txd;
600    volatile rx_dscr *rxd;
601
602    for (txd = sc->txdscr_start; txd != sc->txdscr_end; txd++) {
603        txd->txd_cmdsts = HTOL4(M_DSCR0_SF | M_DSCR0_EF | M_DSCR0_IC);
604	txd->txd_bufptr = 0;
605	}
606    (txd-1)->txd_cmdsts |= HTOL4(M_DSCR0_ET);
607
608    for (rxd = sc->rxdscr_start; rxd != sc->rxdscr_end; rxd++) {
609	rxd->rxd_cmdsts = HTOL4(M_DSCR0_SF | M_DSCR0_EF     /* XXX needed? */
610				| V_DSCR0_BC(ETH_PKTBUF_LEN));
611	rxd->rxd_bufptr = 0;
612	}
613    (rxd-1)->rxd_cmdsts |= HTOL4(M_DSCR0_ET);
614
615    sc->txdscr_add = sc->txdscr_remove = sc->txdscr_start;
616    sc->rxdscr_add = sc->rxdscr_remove = sc->rxdscr_start;
617    sc->rxdscr_onring = 0;
618
619    /* Precharge the receive ring */
620    bcm4401_fillrxring(sc);
621}
622
623
624static int
625bcm4401_init(bcm4401_softc *sc)
626{
627    /* Allocate descriptor rings */
628    sc->rxdscrmem = KMALLOC(MAXRXDSCR*sizeof(rx_dscr), PAGE_ALIGN);
629    sc->txdscrmem = KMALLOC(MAXTXDSCR*sizeof(tx_dscr), PAGE_ALIGN);
630
631    /* Allocate buffer pool */
632    sc->pktpool = KMALLOC(ETH_PKTPOOL_SIZE*ETH_PKTBUF_SIZE, CACHE_ALIGN);
633    if (sc->pktpool == NULL) {
634	xprintf("%s: No buffer memory available.\n", bcm4401_devname(sc));
635	return -1;
636	}
637    eth_initfreelist(sc);
638    q_init(&sc->rxqueue);
639
640    /* Fill in pointers to the rings */
641    sc->rxdscr_start = (volatile rx_dscr *) (sc->rxdscrmem);
642    sc->rxdscr_end = sc->rxdscr_start + MAXRXDSCR;
643
644    sc->txdscr_start = (volatile tx_dscr *) (sc->txdscrmem);
645    sc->txdscr_end = sc->txdscr_start + MAXTXDSCR;
646
647    bcm4401_initrings(sc);
648
649    return 0;
650}
651
652
653static void
654bcm4401_resetrings(bcm4401_softc *sc)
655{
656    volatile tx_dscr *txd;
657    volatile rx_dscr *rxd;
658    eth_pkt_t *pkt;
659
660    /* Free any pending transmit packets (sent and unsent) */
661    txd = sc->txdscr_remove;
662    while (txd != sc->txdscr_add) {
663	pkt = ETH_PKT_BASE(PCI_TO_PTR(ltoh4(txd->txd_bufptr)));
664	eth_free_pkt(sc, pkt);
665
666	txd++;
667	if (txd == sc->txdscr_end)
668	    txd = sc->txdscr_start;
669        }
670    sc->txdscr_remove = txd;
671
672    /* Discard any received packets as well as all free buffers */
673    rxd = sc->rxdscr_remove;
674    while (rxd != sc->rxdscr_add) {
675	pkt = ETH_PKT_BASE(PCI_TO_PTR(ltoh4(rxd->rxd_bufptr)));
676	eth_free_pkt(sc, pkt);
677
678	rxd++;
679	if (rxd == sc->rxdscr_end)
680	    rxd = sc->rxdscr_start;
681	CS_ENTER(sc);
682	sc->rxdscr_onring--;
683	CS_EXIT(sc);
684	}
685    sc->rxdscr_remove = rxd;
686
687    /* Reestablish the initial state. */
688    bcm4401_initrings(sc);
689}
690
691
692/* CRC */
693
694
695/* MII access */
696
697static void
698mii_enable(bcm4401_softc *sc)
699{
700    uint32_t devctl;
701
702    WRITECSR(sc, R_MII_STATUS_CONTROL, M_MIICTL_PR | V_MIICTL_MD(0xD));
703    devctl = READCSR(sc, R_DEV_CONTROL);
704    if ((devctl & M_DVCTL_ER) != 0) {
705	devctl &= ~M_DVCTL_ER;
706	WRITECSR(sc, R_DEV_CONTROL, devctl);
707	cfe_usleep(100);
708	}
709}
710
711static uint16_t
712mii_read(bcm4401_softc *sc, int reg)
713{
714    uint32_t cmd, status;
715    uint32_t data;
716    int timeout;
717
718    WRITECSR(sc, R_ENET_INT_STATUS, M_EINT_MI);
719    cmd = (V_MIIDATA_OP(K_MII_OP_READ) | V_MIIDATA_TA(K_TA_VALID) |
720           V_MIIDATA_RA(reg) | V_MIIDATA_PM(sc->phy_addr));
721    WRITECSR(sc, R_MII_DATA, cmd | V_MIIDATA_SB(K_MII_START));
722
723    for (timeout = 5000; timeout > 0; timeout -= 100) {
724	status = READCSR(sc, R_ENET_INT_STATUS);
725	if ((status & M_EINT_MI) != 0)
726	    break;
727	cfe_usleep(100);
728	}
729
730    if (timeout <= 0)
731	return 0xFFFF;
732
733    data = G_MIIDATA_D(READCSR(sc, R_MII_DATA));
734    return data;
735}
736
737static void
738mii_write(bcm4401_softc *sc, int reg, uint16_t value)
739{
740    uint32_t cmd, status;
741    int timeout;
742
743    WRITECSR(sc, R_ENET_INT_STATUS, M_EINT_MI);
744    cmd = (V_MIIDATA_OP(K_MII_OP_WRITE) | V_MIIDATA_TA(0x2) |
745           V_MIIDATA_RA(reg) | V_MIIDATA_PM(sc->phy_addr) |
746	   V_MIIDATA_D(value));
747    WRITECSR(sc, R_MII_DATA, cmd | V_MIIDATA_SB(K_MII_START));
748
749    for (timeout = 5000; timeout > 0; timeout -= 100) {
750	status = READCSR(sc, R_ENET_INT_STATUS);
751	if ((status & M_EINT_MI) != 0)
752	    break;
753	cfe_usleep(100);
754	}
755}
756
757static int
758mii_probe(bcm4401_softc *sc)
759{
760    int i;
761    uint16_t id1, id2;
762
763    for (i = 1; i < 32; i++) {
764        sc->phy_addr = i;
765        id1 = mii_read(sc, R_PHYIDR1);
766	id2 = mii_read(sc, R_PHYIDR2);
767	if ((id1 != 0x0000 && id1 != 0xFFFF) ||
768	    (id2 != 0x0000 && id2 != 0xFFFF)) {
769	    if (id1 != id2) {
770		sc->phy_vendor = ((uint32_t)id1 << 6) | ((id2 >> 10) & 0x3F);
771		sc->phy_device = (id2 >> 4) & 0x3F;
772	        return 0;
773		}
774	    }
775	}
776    xprintf("mii_probe: No PHY found\n");
777    sc->phy_addr = 0x1;   /* Try the default internal PHY */
778    sc->phy_vendor = sc->phy_device = 0;
779    return -1;
780}
781
782static void
783mii_set_leds(bcm4401_softc *sc)
784{
785    uint16_t aux2;
786
787    aux2 = mii_read(sc, R_AUX_MODE_2);
788    aux2 |= M_PHYAUX2_TM;
789    mii_write(sc, R_AUX_MODE_2, aux2);
790}
791
792static void
793mii_set_speed(bcm4401_softc *sc, int speed)
794{
795    /* NYI */
796    (void)mii_write;
797}
798
799static uint16_t
800mii_interrupt(bcm4401_softc *sc)
801{
802    /* The read also clears any interrupt bits. */
803    return mii_read(sc, R_INTERRUPT);
804}
805
806
807static void
808mii_autonegotiate(bcm4401_softc *sc)
809{
810    uint16_t  control, status, remote;
811    unsigned int  timeout;
812    int linkspeed;
813
814    linkspeed = ETHER_SPEED_UNKNOWN;
815
816    /* Read twice to clear latching bits */
817    status = mii_read(sc, MII_BMSR);
818    status = mii_read(sc, MII_BMSR);
819
820    if ((status & (BMSR_AUTONEG | BMSR_LINKSTAT)) ==
821        (BMSR_AUTONEG | BMSR_LINKSTAT))
822	control = mii_read(sc, MII_BMCR);
823    else {
824	for (timeout = 4*CFE_HZ; timeout > 0; timeout -= CFE_HZ/2) {
825	    status = mii_read(sc, MII_BMSR);
826	    if ((status & BMSR_ANCOMPLETE) != 0)
827		break;
828	    cfe_sleep(CFE_HZ/2);
829	    }
830	}
831
832    xprintf("%s: Link speed: ", bcm4401_devname(sc));
833    remote = mii_read(sc, MII_ANLPAR);
834    if ((status & BMSR_ANCOMPLETE) != 0) {
835	/* A link partner was negotiated... */
836
837	if ((remote & ANLPAR_TXFD) != 0) {
838	    xprintf("100BaseT FDX\n");
839	    linkspeed = ETHER_SPEED_100FDX;
840	    }
841	else if ((remote & ANLPAR_TXHD) != 0) {
842	    xprintf("100BaseT HDX\n");
843	    linkspeed = ETHER_SPEED_100HDX;
844	    }
845	else if ((remote & ANLPAR_10FD) != 0) {
846	    xprintf("10BaseT FDX\n");
847	    linkspeed = ETHER_SPEED_10FDX;
848	    }
849	else if ((remote & ANLPAR_10HD) != 0) {
850	    xprintf("10BaseT HDX\n");
851	    linkspeed = ETHER_SPEED_10HDX;
852	    }
853	}
854    else {
855	/* no link partner convergence */
856	xprintf("Unknown\n");
857	linkspeed = ETHER_SPEED_UNKNOWN;
858	}
859    sc->linkspeed = linkspeed;
860
861    /* clear latching bits */
862    status = mii_read(sc, MII_BMSR);
863}
864
865
866static int
867bcm4401_reset(bcm4401_softc *sc)
868{
869    return 0;
870}
871
872
873/* SPROM access routines.  Random read access to the SPROM will
874   produce a bus error due to PCI timeouts.  As an apparent
875   (undocumented) side effect, the requested word will be fetched to a
876   local buffer so that the next access will succeed.  */
877
878#define SPROM_SIZE     0x80
879
880static int
881sprom_read_all(bcm4401_softc *sc, uint8_t dest[])
882{
883    int i;
884    uint32_t t;
885    jmpbuf_t *jb;
886
887    jb = exc_initialize_block();
888    if (jb == NULL)
889	return -1;
890
891    for (i = 0; i < SPROM_SIZE; i += 4) {
892	if (exc_try(jb) == 0) {
893	    /* On pass 2 parts, the following read gets a bus error */
894	    t = READCSR(sc, SPROM_BASE + i);
895	    cfe_usleep(10000);
896	    /* the read with valid data (pass 1). */
897	    t = READCSR(sc, SPROM_BASE + i);
898	    }
899	else {
900	    /* and this one doesn't (pass 2). */
901	    cfe_usleep(10000);   /* Delay needed; value is empirical. */
902	    t = READCSR(sc, SPROM_BASE + i);
903	    }
904
905	dest[i+0] = (t >> 8) & 0xFF;  dest[i+1] = (t >> 0) & 0xFF;
906	t >>= 16;
907	dest[i+2] = (t >> 8) & 0xFF;  dest[i+3] = (t >> 0) & 0xFF;
908
909	/* The following is a kludge, but otherwise setjmp is a one-shot. */
910	exc_handler.catch_exc = 1;
911	}
912
913    exc_cleanup_block(jb);
914    return 0;
915}
916
917static void
918sprom_dump(uint8_t srom[])
919{
920    int  i;
921
922    xprintf("BCM4401: SPROM data:");
923    for (i = 0; i < SPROM_SIZE; i++) {
924	if (i % 16 == 0)
925	    xprintf("\n %02x: ", i);
926	xprintf(" %02x", srom[i]);
927	}
928    xprintf("\n");
929}
930
931
932static int
933bcm4401_set_hw_addr(bcm4401_softc *sc, uint8_t addr[])
934{
935    uint32_t enet_upper, enet_lower;
936    int timeout;
937
938    enet_upper = (addr[0] << 8) | addr[1];
939    enet_lower = (addr[2] << 24) | (addr[3] << 16) | (addr[4] << 8) | addr[5];
940
941    WRITECSR(sc, R_CAM_DATA_H, M_CAM_VB | V_CAM_CD_H(enet_upper));
942    WRITECSR(sc, R_CAM_DATA_L, V_CAM_CD_L(enet_lower));
943
944    WRITECSR(sc, R_CAM_CONTROL, V_CAMCTL_IX(0) | M_CAMCTL_CW);
945    for (timeout = CFE_HZ; timeout > 0; timeout -= CFE_HZ/10) {
946	if ((READCSR(sc, R_CAM_CONTROL) & M_CAMCTL_CB) != 0)
947	    break;
948	cfe_sleep(1);
949	}
950    if (timeout <= 0)
951        return -1;
952
953    return 0;
954}
955
956
957static void
958bcm4401_pciconfig(bcm4401_softc *sc)
959{
960    uint32_t oldsb;
961    uint32_t idhigh;
962    uint32_t xlat;
963
964    oldsb = pci_conf_read(sc->tag, PCI_PCIBAR0WINDOW_REG);
965    pci_conf_write(sc->tag, PCI_PCIBAR0WINDOW_REG, SB_PCI_BASE);
966    (void)pci_conf_read(sc->tag, PCI_PCIBAR0WINDOW_REG);   /* push */
967
968    idhigh = READCSR(sc, R_SBIDHIGH);
969    if (G_SBID_RV(idhigh) < 6) {
970	/* A0 and A1 parts */
971	WRITECSR(sc, R_SBINTVEC, V_SBINT_MK(K_SBINT_ENET_MAC));
972	}
973    else {
974	/* B0 parts (PCI Rev 2.3 support) */
975	uint32_t mask;
976
977	mask = pci_conf_read(sc->tag, PCI_PCIINTMASK_REG);
978	mask |= V_SBINT_IM(K_SBINT_ENET_MAC);
979	pci_conf_write(sc->tag, PCI_PCIINTMASK_REG, mask);
980	}
981
982    xlat = READCSR(sc, R_SB_TO_PCI_TRANSLATION2);
983    xlat |= (M_SBXLAT_PE | M_SBXLAT_WB);
984    WRITECSR(sc, R_SB_TO_PCI_TRANSLATION2, xlat);
985
986    (void)READCSR(sc, R_SB_TO_PCI_TRANSLATION2);           /* push */
987
988    pci_conf_write(sc->tag, PCI_PCIBAR0WINDOW_REG, oldsb);
989    (void)pci_conf_read(sc->tag, PCI_PCIBAR0WINDOW_REG);   /* push */
990}
991
992
993static void
994bcm4401_set_linkspeed(bcm4401_softc *sc)
995{
996    uint32_t ctrl;
997
998    ctrl = READCSR(sc, R_XMT_CONTROL1);
999    switch (sc->linkspeed) {
1000	case ETHER_SPEED_100FDX:
1001	case ETHER_SPEED_10FDX:
1002	    ctrl |= (M_TCTL_FD | M_TCTL_SB);
1003	    break;
1004	default:
1005	    ctrl &= ~(M_TCTL_FD | M_TCTL_SB);
1006	    break;
1007	}
1008    WRITECSR(sc, R_XMT_CONTROL1, ctrl);
1009}
1010
1011static void
1012bcm4401_hwinit(bcm4401_softc *sc)
1013{
1014    if (sc->state == eth_state_uninit) {
1015	uint32_t ctrl;
1016
1017	bcm4401_reset(sc);
1018
1019	mii_probe(sc);
1020	mii_write(sc, R_INTERRUPT, M_PHYINT_IE);
1021	mii_autonegotiate(sc);
1022	mii_set_leds(sc);
1023	(void)mii_read(sc, R_INTERRUPT);  /* clear any pending */
1024
1025	bcm4401_set_hw_addr(sc, sc->hwaddr);
1026	WRITECSR(sc, R_CAM_CONTROL, M_CAMCTL_CE);
1027
1028	/* XXX Set the transmit watermark here, if needed. */
1029
1030	/* Initialize the receive channel. */
1031	WRITECSR(sc, R_RCV_PTR, 0);
1032	WRITECSR(sc, R_RCV_CONTROL, M_RCTL_RE | V_RCTL_RO(PKTBUF_RX_OFFSET));
1033	WRITECSR(sc, R_RCV_ADDR, PTR_TO_PCI(sc->rxdscrmem));
1034	WRITECSR(sc, R_RCV_PTR, PTR_TO_PCI(sc->rxdscr_add) & 0xFFF);
1035
1036	/* Initialize the transmit channel. */
1037	WRITECSR(sc, R_XMT_PTR, 0);
1038	WRITECSR(sc, R_XMT_CONTROL, M_XCTL_XE);
1039	WRITECSR(sc, R_XMT_ADDR, PTR_TO_PCI(sc->txdscrmem));
1040
1041	/* Modify Ethernet RX MAC settings (probably obsolete). */
1042	WRITECSR(sc, R_EMAC_XMT_MAX_BURST, 32);
1043	WRITECSR(sc, R_EMAC_RCV_MAX_BURST, 32);
1044#if 0
1045	WRITECSR(sc, R_RCV_CONFIG, M_RCFG_AM);   /* All multicast */
1046#else
1047	WRITECSR(sc, R_RCV_CONFIG, 0);
1048#endif
1049	WRITECSR(sc, R_RCV_MAX_LENGTH, MAX_ETHER_PACK);
1050
1051	ctrl = READCSR(sc, R_EMAC_CONTROL);
1052	ctrl |= M_EMCTL_CC;
1053	WRITECSR(sc, R_EMAC_CONTROL, ctrl);
1054
1055	bcm4401_set_linkspeed(sc);
1056
1057	WRITECSR(sc, R_XMT_MAX_LENGTH, MAX_ETHER_PACK);
1058
1059	WRITECSR(sc, R_INT_RECV_LAZY, V_INTLZY_FC(1) | V_INTLZY_TO(100));
1060
1061	/* Enable the MAC */
1062	ctrl = READCSR(sc, R_ENET_CONTROL);
1063	ctrl |= M_ECTL_EE;
1064	WRITECSR(sc, R_ENET_CONTROL, ctrl);
1065
1066	sc->state = eth_state_on;
1067	}
1068}
1069
1070
1071static void
1072bcm4401_setspeed(bcm4401_softc *sc, int speed)
1073{
1074    /* XXX Not yet implemented - autonegotiation only. */
1075    (void)mii_set_speed;
1076}
1077
1078static void
1079bcm4401_setloopback(bcm4401_softc *sc, int mode)
1080{
1081    /* XXX Not yet implemented. */
1082}
1083
1084
1085static void
1086bcm4401_isr(void *arg)
1087{
1088    bcm4401_softc *sc = (bcm4401_softc *)arg;
1089    uint32_t status;
1090
1091#if IPOLL
1092    sc->interrupts++;
1093#endif
1094
1095    for (;;) {
1096
1097	/* Read and clear the interrupt status. */
1098	status = READCSR(sc, R_INT_STATUS);
1099	status &= sc->intmask;
1100	if (status == 0)
1101	    break;
1102
1103	WRITECSR(sc, R_INT_STATUS, status);  /* write-to-clear */
1104
1105	/* XXX Handle SERR, etc. */
1106
1107	if (status & M_INT_RI) {
1108#if IPOLL
1109	    sc->rx_interrupts++;
1110#endif
1111	    bcm4401_procrxring(sc);
1112	    }
1113
1114	if (status & M_INT_XI) {
1115#if IPOLL
1116	    sc->tx_interrupts++;
1117#endif
1118	    bcm4401_proctxring(sc);
1119	    }
1120
1121	if (status & M_INT_TO) {
1122	    sc->slow_poll = 1;
1123	    }
1124
1125	if (status & (M_INT_XU | M_INT_RO)) {
1126	    if (status & M_INT_XU) {
1127		xprintf("BCM4401: tx underrun, %08x\n", status);
1128		/* XXX Try to restart */
1129		}
1130	    if (status & M_INT_RO) {
1131		xprintf("BCM4401: rx overrun, %08x\n", status);
1132		/* XXX Try to restart */
1133		}
1134	    }
1135	}
1136}
1137
1138
1139static void
1140bcm4401_start(bcm4401_softc *sc)
1141{
1142    bcm4401_hwinit(sc);
1143
1144    /* Set up loopback here */
1145
1146    WRITECSR(sc, R_GP_TIMER, 0);             /* stop the timer */
1147
1148    sc->intmask = 0;
1149    WRITECSR(sc, R_INT_MASK, 0);
1150    (void)READCSR(sc, R_INT_STATUS);         /* clear any pending */
1151
1152    sc->intmask =  (M_INT_RI | M_INT_XI | M_INT_TO);    /* XXX add errors */
1153
1154#if IPOLL
1155    cfe_request_irq(sc->irq, bcm4401_isr, sc, CFE_IRQ_FLAGS_SHARED, 0);
1156    WRITECSR(sc, R_INT_MASK, sc->intmask);
1157#endif
1158
1159    sc->slow_poll = 0;
1160    WRITECSR(sc, R_GP_TIMER, GP_TIMER_HZ/4);
1161
1162    sc->state = eth_state_on;
1163}
1164
1165static void
1166bcm4401_stop(bcm4401_softc *sc)
1167{
1168    uint32_t ctl, status;
1169    int i;
1170
1171    /* Cancel the timer */
1172    WRITECSR(sc, R_GP_TIMER, 0);
1173    (void)READCSR(sc, R_GP_TIMER);
1174    sc->slow_poll = 0;
1175
1176    /* Make sure that no further interrupts will be processed. */
1177    sc->intmask = 0;
1178    WRITECSR(sc, R_INT_MASK, 0);
1179    (void)READCSR(sc, R_INT_MASK);  /* push */
1180    (void)READCSR(sc, R_INT_STATUS);
1181
1182    /* Shut down MAC */
1183    WRITECSR(sc, R_ENET_CONTROL, M_ECTL_ED);
1184    for (i = 1000; i > 0; i--) {
1185	ctl = READCSR(sc, R_ENET_CONTROL);
1186	if ((ctl & M_ECTL_ED) == 0)
1187	    break;
1188	cfe_usleep(100);
1189	}
1190    if (i == 0)
1191	xprintf("%s: cannot clear MAC\n", bcm4401_devname(sc));
1192
1193    /* Shut down DMA engines */
1194    WRITECSR(sc, R_XMT_CONTROL, 0);
1195    for (i = 1000; i > 0; i--) {
1196	status = READCSR(sc, R_XMT_STATUS);
1197	if (G_XSTAT_XS(status) == K_XS_DISABLED)
1198	    break;
1199	cfe_usleep(100);
1200	}
1201    if (i == 0)
1202	xprintf("%s: cannot clear tx DMA\n", bcm4401_devname(sc));
1203
1204    WRITECSR(sc, R_RCV_CONTROL, 0);
1205    for (i = 1000; i > 0; i--) {
1206	status = READCSR(sc, R_RCV_STATUS);
1207	if (G_RSTAT_RS(status) == K_RS_DISABLED)
1208	    break;
1209	cfe_usleep(100);
1210	}
1211    if (i == 0)
1212	xprintf("%s: cannot clear rx DMA\n", bcm4401_devname(sc));
1213
1214    status = READCSR(sc, R_INT_STATUS);
1215    WRITECSR(sc, R_INT_STATUS, status);
1216#if IPOLL
1217    cfe_free_irq(sc->irq, 0);
1218#endif
1219
1220    /* Leave the mii inteface enabled */
1221    mii_enable(sc);
1222}
1223
1224
1225/* Declarations for CFE Device Driver Interface routines */
1226
1227static int bcm4401_ether_open(cfe_devctx_t *ctx);
1228static int bcm4401_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
1229static int bcm4401_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
1230static int bcm4401_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
1231static int bcm4401_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
1232static int bcm4401_ether_close(cfe_devctx_t *ctx);
1233static void bcm4401_ether_poll(cfe_devctx_t *ctx, int64_t ticks);
1234static void bcm4401_ether_reset(void *softc);
1235
1236
1237/* CFE Device Driver dispatch structure */
1238
1239const static cfe_devdisp_t bcm4401_ether_dispatch = {
1240    bcm4401_ether_open,
1241    bcm4401_ether_read,
1242    bcm4401_ether_inpstat,
1243    bcm4401_ether_write,
1244    bcm4401_ether_ioctl,
1245    bcm4401_ether_close,
1246    bcm4401_ether_poll,
1247    bcm4401_ether_reset
1248};
1249
1250
1251/* CFE Device Driver descriptor */
1252
1253const cfe_driver_t bcm4401drv = {
1254    "BCM4401 Ethernet",
1255    "eth",
1256    CFE_DEV_NETWORK,
1257    &bcm4401_ether_dispatch,
1258    bcm4401_ether_probe
1259};
1260
1261
1262/* CFE Device Driver probe functions. */
1263
1264static int
1265bcm4401_ether_attach(cfe_driver_t *drv, pcitag_t tag)
1266{
1267    bcm4401_softc *sc;
1268    uint32_t device;
1269    uint32_t class;
1270    phys_addr_t pa;
1271    uint8_t sprom[SPROM_SIZE];
1272    char descr[100];
1273
1274    device = pci_conf_read(tag, PCI_ID_REG);
1275    class = pci_conf_read(tag, PCI_CLASS_REG);
1276
1277    /* Use memory space for the CSRs */
1278    pci_map_mem(tag, PCI_MAPREG(0), CSR_MATCH_MODE, &pa);
1279
1280    sc = (bcm4401_softc *) KMALLOC(sizeof(bcm4401_softc), 0);
1281
1282    if (sc == NULL) {
1283	xprintf("BCM4401: No memory to complete probe\n");
1284	return 0;
1285	}
1286    memset(sc, 0, sizeof(*sc));
1287
1288    sc->membase = (uint32_t)pa;
1289    sc->irq = pci_conf_read(tag, PCI_BPARAM_INTERRUPT_REG) & 0xFF;
1290    sc->tag = tag;
1291    sc->device = PCI_PRODUCT(device);
1292    sc->revision = PCI_REVISION(class);
1293    sc->devctx = NULL;
1294
1295#if 1
1296    sc->linkspeed = ETHER_SPEED_AUTO;    /* select autonegotiation */
1297#else
1298    sc->linkspeed = ETHER_SPEED_100FDX;  /* 100 Mbps, full duplex */
1299#endif
1300    sc->loopback = ETHER_LOOPBACK_OFF;
1301
1302    /* Enable the core by enabling the core clocks and then clearing
1303       RESET.  The backplane mapping registers have been initialized
1304       from the SPROM, but a more paranoid implementation would
1305       reconfigure at this point. */
1306    WRITECSR(sc, R_SBTMSTATELOW, M_SBTS_RS | M_SBTS_CE | M_SBTS_FC);
1307    (void)READCSR(sc, R_SBTMSTATELOW);   /* push */
1308    cfe_usleep(100);
1309
1310    /* "PR3158 workaround - not fixed in any chip yet" */
1311    if ((READCSR(sc, R_SBTMSTATEHI) & M_SBTS_SE) != 0) {
1312	WRITECSR(sc, R_SBTMSTATEHI, 0);
1313	}
1314    if ((READCSR(sc, R_SBIMSTATE) & (M_SBIS_IE | M_SBIS_TO)) != 0) {
1315	uint32_t sbis;
1316	sbis = READCSR(sc, R_SBIMSTATE);
1317	sbis &= ~(M_SBIS_IE | M_SBIS_TO);
1318	WRITECSR(sc, R_SBIMSTATE, sbis);
1319	}
1320    /* End of workaround */
1321
1322    WRITECSR(sc, R_SBTMSTATELOW, M_SBTS_CE | M_SBTS_FC);
1323    (void)READCSR(sc, R_SBTMSTATELOW);   /* push */
1324    cfe_usleep(100);
1325    WRITECSR(sc, R_SBTMSTATELOW, M_SBTS_CE);
1326    (void)READCSR(sc, R_SBTMSTATELOW);   /* push */
1327    cfe_usleep(100);
1328
1329    bcm4401_pciconfig(sc);
1330
1331    mii_enable(sc);
1332
1333    bcm4401_init(sc);
1334
1335    sprom_read_all(sc, sprom);
1336    if (B44_DEBUG) sprom_dump(sprom);
1337
1338    /* Use the address in EEPROM.  */
1339    memcpy(sc->hwaddr, &sprom[SPROM_MAC_ADDR], ENET_ADDR_LEN);
1340    sc->phy_addr = sprom[SPROM_PHY_ADDR] & 0x1F;
1341
1342    sc->state = eth_state_uninit;
1343
1344    xsprintf(descr, "%s at 0x%X (%a)",
1345	     drv->drv_description, sc->membase, sc->hwaddr);
1346
1347    cfe_attach(drv, sc, NULL, descr);
1348    return 1;
1349}
1350
1351static void
1352bcm4401_ether_probe(cfe_driver_t *drv,
1353		    unsigned long probe_a, unsigned long probe_b,
1354		    void *probe_ptr)
1355{
1356    int index;
1357
1358    index = 0;
1359    for (;;) {
1360	pcitag_t tag;
1361	pcireg_t device;
1362
1363	if (pci_find_class(PCI_CLASS_NETWORK, index, &tag) != 0)
1364	    break;
1365
1366	index++;
1367
1368	device = pci_conf_read(tag, PCI_ID_REG);
1369	if (PCI_VENDOR(device) == K_PCI_VENDOR_BROADCOM) {
1370	    switch (PCI_PRODUCT(device)) {
1371		case K_PCI_ID_BCM4401:
1372	        case K_PCI_ID_BCM4401_B:
1373		case K_PCI_ID_BCM4402:
1374		    bcm4401_ether_attach(drv, tag);
1375		    break;
1376		default:
1377		    break;
1378		}
1379	    }
1380	}
1381}
1382
1383
1384/* The functions below are called via the dispatch vector for the 4401. */
1385
1386static int
1387bcm4401_ether_open(cfe_devctx_t *ctx)
1388{
1389    bcm4401_softc *sc = ctx->dev_softc;
1390
1391    if (sc->state == eth_state_on)
1392	bcm4401_stop(sc);
1393
1394    sc->devctx = ctx;
1395
1396    sc->inpkts = sc->outpkts = 0;
1397    sc->interrupts = 0;
1398    sc->rx_interrupts = sc->tx_interrupts = 0;
1399
1400    bcm4401_start(sc);
1401
1402#if XPOLL
1403    bcm4401_isr(sc);
1404#endif
1405
1406    return 0;
1407}
1408
1409static int
1410bcm4401_ether_read(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
1411{
1412    bcm4401_softc *sc = ctx->dev_softc;
1413    eth_pkt_t *pkt;
1414    int blen;
1415
1416#if XPOLL
1417    bcm4401_isr(sc);
1418#endif
1419
1420    if (sc->state != eth_state_on) return -1;
1421
1422    CS_ENTER(sc);
1423    pkt = (eth_pkt_t *) q_deqnext(&(sc->rxqueue));
1424    CS_EXIT(sc);
1425
1426    if (pkt == NULL) {
1427	buffer->buf_retlen = 0;
1428	return 0;
1429	}
1430
1431    blen = buffer->buf_length;
1432    if (blen > pkt->length) blen = pkt->length;
1433
1434    hs_memcpy_to_hs(buffer->buf_ptr, pkt->buffer+PKTBUF_RX_OFFSET, blen);
1435    buffer->buf_retlen = blen;
1436
1437    eth_free_pkt(sc, pkt);
1438    bcm4401_fillrxring(sc);
1439
1440#if XPOLL
1441    bcm4401_isr(sc);
1442#endif
1443
1444    return 0;
1445}
1446
1447static int
1448bcm4401_ether_inpstat(cfe_devctx_t *ctx, iocb_inpstat_t *inpstat)
1449{
1450    bcm4401_softc *sc = ctx->dev_softc;
1451
1452#if XPOLL
1453    bcm4401_isr(sc);
1454#endif
1455
1456    if (sc->state != eth_state_on) return -1;
1457
1458    /* We avoid an interlock here because the result is a hint and an
1459       interrupt cannot turn a non-empty queue into an empty one. */
1460    inpstat->inp_status = (q_isempty(&(sc->rxqueue))) ? 0 : 1;
1461
1462    return 0;
1463}
1464
1465static int
1466bcm4401_ether_write(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
1467{
1468    bcm4401_softc *sc = ctx->dev_softc;
1469    eth_pkt_t *pkt;
1470    int blen;
1471
1472#if XPOLL
1473    bcm4401_isr(sc);
1474#endif
1475
1476    if (sc->state != eth_state_on) return -1;
1477
1478    pkt = eth_alloc_pkt(sc);
1479    if (!pkt) return CFE_ERR_NOMEM;
1480
1481    blen = buffer->buf_length;
1482    if (blen > pkt->length) blen = pkt->length;
1483
1484    hs_memcpy_from_hs(pkt->buffer, buffer->buf_ptr, blen);
1485    pkt->length = blen;
1486
1487    if (bcm4401_transmit(sc, pkt) != 0) {
1488	eth_free_pkt(sc,pkt);
1489	return CFE_ERR_IOERR;
1490	}
1491
1492#if XPOLL
1493    bcm4401_isr(sc);
1494#endif
1495
1496    return 0;
1497}
1498
1499static int
1500bcm4401_ether_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
1501{
1502    bcm4401_softc *sc = ctx->dev_softc;
1503    int   mode;
1504    int   speed;
1505
1506    switch ((int)buffer->buf_ioctlcmd) {
1507	case IOCTL_ETHER_GETHWADDR:
1508	    hs_memcpy_to_hs(buffer->buf_ptr, sc->hwaddr, sizeof(sc->hwaddr));
1509	    return 0;
1510
1511	case IOCTL_ETHER_SETHWADDR:
1512	    return -1;    /* not supported */
1513
1514	case IOCTL_ETHER_GETSPEED:
1515	    speed = sc->linkspeed;
1516	    hs_memcpy_to_hs(buffer->buf_ptr,&speed,sizeof(int));
1517	    return 0;
1518
1519	case IOCTL_ETHER_SETSPEED:
1520	    hs_memcpy_from_hs(&speed,buffer->buf_ptr,sizeof(int));
1521	    bcm4401_setspeed(sc, speed);
1522	    return -1;    /* not supported yet */
1523
1524	case IOCTL_ETHER_GETLINK:
1525	    speed = sc->linkspeed;
1526	    hs_memcpy_to_hs(buffer->buf_ptr,&speed,sizeof(int));
1527	    return 0;
1528
1529	case IOCTL_ETHER_GETLOOPBACK:
1530	    mode = sc->loopback;
1531	    hs_memcpy_to_hs(buffer->buf_ptr,&mode,sizeof(int));
1532	    return 0;
1533
1534	case IOCTL_ETHER_SETLOOPBACK:
1535	    hs_memcpy_from_hs(&mode,buffer->buf_ptr,sizeof(int));
1536	    sc->loopback = ETHER_LOOPBACK_OFF;  /* default */
1537	    if (mode == ETHER_LOOPBACK_INT || mode == ETHER_LOOPBACK_EXT) {
1538		bcm4401_setloopback(sc, mode);
1539		}
1540	    return -1;    /* not supported yet */
1541
1542	default:
1543	    return -1;
1544	}
1545}
1546
1547static int
1548bcm4401_ether_close(cfe_devctx_t *ctx)
1549{
1550    bcm4401_softc *sc = ctx->dev_softc;
1551
1552    sc->state = eth_state_off;
1553    bcm4401_stop(sc);
1554
1555    xprintf("%s: %d sent, %d received, %d interrupts\n",
1556	    bcm4401_devname(sc), sc->outpkts, sc->inpkts, sc->interrupts);
1557    if (IPOLL) {
1558	xprintf("  %d tx interrupts, %d rx interrupts\n",
1559		sc->tx_interrupts, sc->rx_interrupts);
1560	}
1561
1562    /* resynchronize descriptor rings */
1563    bcm4401_resetrings(sc);
1564
1565    sc->devctx = NULL;
1566#if 1 /* XXX Redo partitioning among hwinit, start and stop */
1567    sc->state = eth_state_uninit;
1568#endif
1569    return 0;
1570}
1571
1572static void
1573bcm4401_ether_poll(cfe_devctx_t *ctx, int64_t ticks)
1574{
1575    bcm4401_softc *sc = (bcm4401_softc *)ctx->dev_softc;
1576    uint16_t phy_isr;
1577
1578    /* The PHY Interrupt register appears to work as claimed with
1579       respect to link status changes, but I've had no luck clearing
1580       the MIIInt bit in the EnetIntStatus register.  We therefore use
1581       polling but reduce the frequency since reading MII registers is
1582       expensive.  */
1583    if (sc->slow_poll) {
1584	sc->slow_poll = 0;
1585	phy_isr = mii_interrupt(sc);
1586	if ((phy_isr & (M_PHYINT_LC | M_PHYINT_SP | M_PHYINT_DC)) != 0) {
1587	    mii_autonegotiate(sc);
1588	    bcm4401_set_linkspeed(sc);
1589	    }
1590	}
1591}
1592
1593static void
1594bcm4401_ether_reset(void *softc)
1595{
1596    bcm4401_softc *sc = (bcm4401_softc *)softc;
1597
1598    /* Turn off the Ethernet interface. */
1599    if (sc->state == eth_state_on)
1600	bcm4401_stop(sc);
1601    bcm4401_reset(sc);
1602
1603    sc->state = eth_state_uninit;
1604}
1605