GUI: Fix Tomato RAF theme for all builds. Compilation typo.
[tomato.git] / release / src-rt-6.x.4708 / cfe / cfe / dev / dev_tulip.c
blob18f6ca9ca68e622eefd94edda9c96d76a985d217
1 /* *********************************************************************
2 * Broadcom Common Firmware Environment (CFE)
4 * DC21x4x Ethernet Driver File: dev_tulip.c
5 *
6 *********************************************************************
8 * Copyright 2000,2001,2002,2003
9 * Broadcom Corporation. All rights reserved.
11 * This software is furnished under license and may be used and
12 * copied only in accordance with the following terms and
13 * conditions. Subject to these conditions, you may download,
14 * copy, install, use, modify and distribute modified or unmodified
15 * copies of this software in source and/or binary form. No title
16 * or ownership is transferred hereby.
18 * 1) Any source code used, modified or distributed must reproduce
19 * and retain this copyright notice and list of conditions
20 * as they appear in the source file.
22 * 2) No right is granted to use any trade name, trademark, or
23 * logo of Broadcom Corporation. The "Broadcom Corporation"
24 * name may not be used to endorse or promote products derived
25 * from this software without the prior written permission of
26 * Broadcom Corporation.
28 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR
29 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED
30 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
31 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT
32 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN
33 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT,
34 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
35 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
36 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
37 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
38 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
39 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF
40 * THE POSSIBILITY OF SUCH DAMAGE.
41 ********************************************************************* */
43 #include "sbmips.h"
45 #ifndef _SB_MAKE64
46 #define _SB_MAKE64(x) ((uint64_t)(x))
47 #endif
48 #ifndef _SB_MAKEMASK1
49 #define _SB_MAKEMASK1(n) (_SB_MAKE64(1) << _SB_MAKE64(n))
50 #endif
52 #include "lib_types.h"
53 #include "lib_physio.h"
54 #include "lib_malloc.h"
55 #include "lib_string.h"
56 #define blockcopy memcpy
57 #include "lib_printf.h"
58 #include "lib_queue.h"
60 #include "cfe_iocb.h"
61 #include "cfe_device.h"
62 #include "cfe_ioctl.h"
63 #include "cfe_timer.h"
64 #include "cfe_error.h"
65 #include "cfe_irq.h"
67 #include "pcivar.h"
68 #include "pcireg.h"
70 #include "dc21143.h"
71 #include "mii.h"
73 /* This is a driver for specific configurations of the DC21040, DC21041,
74 DC21140A and DC21143, not a generic Tulip driver. The prefix
75 "tulip_" is used to indicate generic Tulip functions, while
76 "dc21040_", "dc21041_", "dc21140_" or "dc21143_" indicates functions
77 specific to a chip variant.
79 The 21041 driver assumes a 10BT HD interface, since autonegotiation
80 is known to be broken in the early revisons of that chip. Example
81 cards come from DEC and SMC. Essentially the same driver is used
82 for 21040 cards.
84 The 21140 driver assumes that the PHY uses a standard MII interface
85 for both 100BT and 10BT. Example cards come from DEC (National DP83840
86 plus Twister PHY) and Netgear (Level One PHY).
88 Some early 21140 boards are exceptions and use SYM plus SRL
89 with different PHY chips for 10 and 100 (limited support).
91 The 21143 driver assumes by default that the PHY uses the SYM ("5
92 wire") interface for 100BT with pass-through for 10BT. Example
93 cards come from DEC (MicroLinear ML6694 PHY) and Znyx (QS6611 or
94 Kendin KS8761 PHY). It also supports an MII interface for
95 recognized adapters. An example card comes from Adaptec (National
96 DP83840A and Twister PHY). There is no support for AUI interfaces.
98 This SB1250 version takes advantage of DMA coherence and uses
99 "preserve bit lanes" addresses for all accesses that cross the
100 ZBbus-PCI bridge. */
102 #ifndef TULIP_DEBUG
103 #define TULIP_DEBUG 0
104 #endif
106 /* Set IPOLL to drive processing through the pseudo-interrupt
107 dispatcher. Set XPOLL to drive processing by an external polling
108 agent. Setting both is ok. */
110 #ifndef IPOLL
111 #define IPOLL 0
112 #endif
113 #ifndef XPOLL
114 #define XPOLL 1
115 #endif
117 #define ENET_ADDR_LEN 6 /* size of an ethernet address */
118 #define MAX_ETHER_PACK 1518 /* max size of a packet */
119 #define CRC_SIZE 4 /* size of CRC field */
121 /* Packet buffers. For tulip, the packet must be aligned to a 32-bit
122 word boundary, and we would like it aligned to a cache line
123 boundary for performance. */
125 #define CACHE_ALIGN 32
127 #if __long64
128 typedef struct eth_pkt_s {
129 queue_t next; /* 16 */
130 uint8_t *buffer; /* 8 */
131 uint32_t flags; /* 4 */
132 int32_t length; /* 4 */
133 uint8_t data[MAX_ETHER_PACK];
134 } eth_pkt_t;
135 #else
136 typedef struct eth_pkt_s {
137 queue_t next; /* 8 */
138 uint8_t *buffer; /* 4 */
139 uint32_t flags; /* 4 */
140 int32_t length; /* 4 */
141 uint32_t unused[3]; /* 12 */
142 uint8_t data[MAX_ETHER_PACK];
143 } eth_pkt_t;
144 #endif
146 #define ETH_PKTBUF_LINES ((sizeof(eth_pkt_t) + (CACHE_ALIGN-1))/CACHE_ALIGN)
147 #define ETH_PKTBUF_SIZE (ETH_PKTBUF_LINES*CACHE_ALIGN)
148 #define ETH_PKTBUF_OFFSET (offsetof(eth_pkt_t, data))
150 #define ETH_PKT_BASE(data) ((eth_pkt_t *)((data) - ETH_PKTBUF_OFFSET))
152 /* packet flags */
153 #define ETH_TX_SETUP 1 /* assumes Perfect Filtering format */
155 static void
156 show_packet(char c, eth_pkt_t *pkt)
158 int i;
159 int n = (pkt->length < 32 ? pkt->length : 32);
161 xprintf("%c[%4d]:", c, pkt->length);
162 for (i = 0; i < n; i++) {
163 if (i % 4 == 0)
164 xprintf(" ");
165 xprintf("%02x", pkt->buffer[i]);
167 xprintf("\n");
171 /* Descriptor structures */
173 typedef struct rx_dscr {
174 uint32_t rxd_flags;
175 uint32_t rxd_bufsize;
176 pci_addr_t rxd_bufaddr1;
177 pci_addr_t rxd_bufaddr2;
178 } rx_dscr;
180 typedef struct tx_dscr {
181 uint32_t txd_flags;
182 uint32_t txd_bufsize;
183 pci_addr_t txd_bufaddr1;
184 pci_addr_t txd_bufaddr2;
185 } tx_dscr;
187 /* CAM structure */
189 typedef union {
190 struct {
191 uint32_t physical[CAM_PERFECT_ENTRIES][3];
192 } p;
193 struct {
194 uint32_t hash[32];
195 uint32_t mbz[7];
196 uint32_t physical[3];
197 } h;
198 } tulip_cam;
201 /* Driver data structures */
203 typedef enum {
204 eth_state_uninit,
205 eth_state_setup,
206 eth_state_off,
207 eth_state_on,
208 eth_state_broken
209 } eth_state_t;
211 #define ETH_PKTPOOL_SIZE 32
212 #define ETH_PKT_SIZE MAX_ETHER_PACK
214 typedef struct tulip_softc {
215 uint32_t membase;
216 uint8_t irq; /* interrupt mapping (used if IPOLL) */
217 pcitag_t tag; /* tag for configuration registers */
219 uint8_t hwaddr[ENET_ADDR_LEN];
220 uint16_t device; /* chip device code */
221 uint8_t revision; /* chip revision and step (Table 3-7) */
223 /* current state */
224 eth_state_t state;
226 /* These fields are the chip startup values. */
227 // uint16_t media; /* media type */
228 uint32_t opmode; /* operating mode */
229 uint32_t intmask; /* interrupt mask */
230 uint32_t gpdata; /* output bits for csr15 (21143) */
232 /* These fields are set before calling dc21x4x_hwinit */
233 int linkspeed; /* encodings from cfe_ioctl */
234 int loopback;
236 /* Packet free list */
237 queue_t freelist;
238 uint8_t *pktpool;
239 queue_t rxqueue;
241 /* The descriptor tables */
242 uint8_t *rxdscrmem; /* receive descriptors */
243 uint8_t *txdscrmem; /* transmit descriptors */
245 /* These fields keep track of where we are in tx/rx processing */
246 volatile rx_dscr *rxdscr_start; /* beginning of ring */
247 volatile rx_dscr *rxdscr_end; /* end of ring */
248 volatile rx_dscr *rxdscr_remove; /* next one we expect tulip to use */
249 volatile rx_dscr *rxdscr_add; /* next place to put a buffer */
250 int rxdscr_onring;
252 volatile tx_dscr *txdscr_start; /* beginning of ring */
253 volatile tx_dscr *txdscr_end; /* end of ring */
254 volatile tx_dscr *txdscr_remove; /* next one we will use for tx */
255 volatile tx_dscr *txdscr_add; /* next place to put a buffer */
257 cfe_devctx_t *devctx;
259 /* These fields describe the PHY */
260 enum {SRL, MII, SYM} phy_type;
261 int mii_addr;
263 /* Statistics */
264 uint32_t inpkts;
265 uint32_t outpkts;
266 uint32_t interrupts;
267 uint32_t rx_interrupts;
268 uint32_t tx_interrupts;
269 uint32_t bus_errors;
270 } tulip_softc;
273 /* Entry to and exit from critical sections (currently relative to
274 interrupts only, not SMP) */
276 #if CFG_INTERRUPTS
277 #define CS_ENTER(sc) cfe_disable_irq(sc->irq)
278 #define CS_EXIT(sc) cfe_enable_irq(sc->irq)
279 #else
280 #define CS_ENTER(sc) ((void)0)
281 #define CS_EXIT(sc) ((void)0)
282 #endif
285 /* Driver parameterization */
287 #define MAXRXDSCR 32
288 #define MAXTXDSCR 32
289 #define MINRXRING 8
291 #define MEDIA_UNKNOWN 0
292 #define MEDIA_AUI 1
293 #define MEDIA_BNC 2
294 #define MEDIA_UTP_FULL_DUPLEX 3
295 #define MEDIA_UTP_NO_LINK_TEST 4
296 #define MEDIA_UTP 5
298 /* Prototypes */
300 static void tulip_ether_probe(cfe_driver_t *drv,
301 unsigned long probe_a, unsigned long probe_b,
302 void *probe_ptr);
305 /* Address mapping macros */
307 /* Note that PTR_TO_PHYS only works with 32-bit addresses, but then
308 so does the Tulip. */
309 #define PTR_TO_PHYS(x) (K0_TO_PHYS((uintptr_t)(x)))
310 #define PHYS_TO_PTR(a) ((uint8_t *)PHYS_TO_K0(a))
312 /* All mappings through the PCI host bridge use match bits mode. */
313 #define PHYS_TO_PCI(a) ((uint32_t) (a) | 0x20000000)
314 #define PCI_TO_PHYS(a) ((uint32_t) (a) & 0x1FFFFFFF)
316 #define PCI_TO_PTR(a) (PHYS_TO_PTR(PCI_TO_PHYS(a)))
317 #define PTR_TO_PCI(x) (PHYS_TO_PCI(PTR_TO_PHYS(x)))
319 #define READCSR(sc,csr) phys_read32((sc)->membase + (csr))
320 #define WRITECSR(sc,csr,val) phys_write32((sc)->membase + (csr), (val))
323 #define RESET_ADAPTER(sc) \
325 WRITECSR((sc), R_CSR_BUSMODE, M_CSR0_SWRESET); \
326 cfe_sleep(CFE_HZ/10); \
330 /* Debugging */
332 static void
333 dumpstat(tulip_softc *sc)
335 xprintf("-- CSR 5 = %08X CSR 6 = %08x\n",
336 READCSR(sc, R_CSR_STATUS), READCSR(sc, R_CSR_OPMODE));
339 static void
340 dumpcsrs(tulip_softc *sc)
342 int idx;
344 xprintf("-------------\n");
345 for (idx = 0; idx < 16; idx++) {
346 xprintf("CSR %2d = %08X\n", idx, READCSR(sc, idx*8));
348 xprintf("-------------\n");
352 /* Packet management */
354 /* *********************************************************************
355 * ETH_ALLOC_PKT(sc)
357 * Allocate a packet from the free list.
359 * Input parameters:
360 * sc - eth structure
362 * Return value:
363 * pointer to packet structure, or NULL if none available
364 ********************************************************************* */
365 static eth_pkt_t *
366 eth_alloc_pkt(tulip_softc *sc)
368 eth_pkt_t *pkt;
370 CS_ENTER(sc);
371 pkt = (eth_pkt_t *) q_deqnext(&sc->freelist);
372 CS_EXIT(sc);
373 if (!pkt) return NULL;
375 pkt->buffer = pkt->data;
376 pkt->length = ETH_PKT_SIZE;
377 pkt->flags = 0;
379 return pkt;
383 /* *********************************************************************
384 * ETH_FREE_PKT(sc,pkt)
386 * Return a packet to the free list
388 * Input parameters:
389 * sc - sbmac structure
390 * pkt - packet to return
392 * Return value:
393 * nothing
394 ********************************************************************* */
395 static void
396 eth_free_pkt(tulip_softc *sc, eth_pkt_t *pkt)
398 CS_ENTER(sc);
399 q_enqueue(&sc->freelist, &pkt->next);
400 CS_EXIT(sc);
404 /* *********************************************************************
405 * ETH_INITFREELIST(sc)
407 * Initialize the buffer free list for this mac. The memory
408 * allocated to the free list is carved up and placed on a linked
409 * list of buffers for use by the mac.
411 * Input parameters:
412 * sc - eth structure
414 * Return value:
415 * nothing
416 ********************************************************************* */
417 static void
418 eth_initfreelist(tulip_softc *sc)
420 int idx;
421 uint8_t *ptr;
422 eth_pkt_t *pkt;
424 q_init(&sc->freelist);
426 ptr = sc->pktpool;
427 for (idx = 0; idx < ETH_PKTPOOL_SIZE; idx++) {
428 pkt = (eth_pkt_t *) ptr;
429 eth_free_pkt(sc, pkt);
430 ptr += ETH_PKTBUF_SIZE;
435 /* Utilities */
437 static const char *
438 tulip_devname(tulip_softc *sc)
440 return (sc->devctx != NULL ? cfe_device_name(sc->devctx) : "eth?");
444 /* Descriptor ring management */
446 static int
447 tulip_add_rcvbuf(tulip_softc *sc, eth_pkt_t *pkt)
449 volatile rx_dscr *rxd;
450 volatile rx_dscr *nextrxd;
451 uint32_t ctrl = 0;
453 rxd = sc->rxdscr_add;
455 /* Figure out where the next descriptor will go */
456 nextrxd = rxd+1;
457 if (nextrxd == sc->rxdscr_end) {
458 nextrxd = sc->rxdscr_start;
459 ctrl = M_RDES1_ENDOFRING;
463 * If the next one is the same as our remove pointer,
464 * the ring is considered full. (it actually has room for
465 * one more, but we reserve the remove == add case for "empty")
467 if (nextrxd == sc->rxdscr_remove) return -1;
469 rxd->rxd_bufsize = V_RDES1_BUF1SIZE(1520) | ctrl;
470 rxd->rxd_bufaddr1 = PTR_TO_PCI(pkt->buffer);
471 rxd->rxd_bufaddr2 = 0;
472 rxd->rxd_flags = M_RDES0_OWNADAP;
474 /* success, advance the pointer */
475 sc->rxdscr_add = nextrxd;
476 CS_ENTER(sc);
477 sc->rxdscr_onring++;
478 CS_EXIT(sc);
480 return 0;
483 static void
484 tulip_fillrxring(tulip_softc *sc)
486 eth_pkt_t *pkt;
488 while (1) {
489 CS_ENTER(sc);
490 if (sc->rxdscr_onring >= MINRXRING) {
491 CS_EXIT(sc);
492 break;
494 CS_EXIT(sc);
495 pkt = eth_alloc_pkt(sc);
496 if (pkt == NULL) {
497 /* could not allocate a buffer */
498 break;
500 if (tulip_add_rcvbuf(sc, pkt) != 0) {
501 /* could not add buffer to ring */
502 eth_free_pkt(sc, pkt);
503 break;
509 /* *********************************************************************
510 * TULIP_RX_CALLBACK(sc, pkt)
512 * Receive callback routine. This routine is invoked when a
513 * buffer queued for receives is filled. In this simple driver,
514 * all we do is add the packet to a per-MAC queue for later
515 * processing, and try to put a new packet in the place of the one
516 * that was removed from the queue.
518 * Input parameters:
519 * sc - interface
520 * ptk - packet context (eth_pkt structure)
522 * Return value:
523 * nothing
524 ********************************************************************* */
525 static void
526 tulip_rx_callback(tulip_softc *sc, eth_pkt_t *pkt)
528 if (TULIP_DEBUG) show_packet('>', pkt); /* debug */
530 CS_ENTER(sc);
531 q_enqueue(&sc->rxqueue, &pkt->next);
532 CS_EXIT(sc);
533 sc->inpkts++;
535 tulip_fillrxring(sc);
539 static void
540 tulip_procrxring(tulip_softc *sc)
542 volatile rx_dscr *rxd;
543 eth_pkt_t *pkt;
544 eth_pkt_t *newpkt;
545 uint32_t flags;
547 for (;;) {
548 rxd = (volatile rx_dscr *) sc->rxdscr_remove;
550 flags = rxd->rxd_flags;
551 if (flags & M_RDES0_OWNADAP) {
552 /* end of ring, no more packets */
553 break;
556 pkt = ETH_PKT_BASE(PCI_TO_PTR(rxd->rxd_bufaddr1));
558 /* Drop error packets */
559 if (flags & M_RDES0_ERRORSUM) {
560 xprintf("%s: rx error %04X\n", tulip_devname(sc), flags & 0xFFFF);
561 tulip_add_rcvbuf(sc, pkt);
562 goto next;
565 /* Pass up the packet */
566 pkt->length = G_RDES0_FRAMELEN(flags) - CRC_SIZE;
567 tulip_rx_callback(sc, pkt);
569 /* put a buffer back on the ring to replace this one */
570 newpkt = eth_alloc_pkt(sc);
571 if (newpkt) tulip_add_rcvbuf(sc, newpkt);
573 next:
574 /* update the pointer, accounting for buffer wrap. */
575 rxd++;
576 if (rxd == sc->rxdscr_end)
577 rxd = sc->rxdscr_start;
579 sc->rxdscr_remove = (rx_dscr *) rxd;
580 CS_ENTER(sc);
581 sc->rxdscr_onring--;
582 CS_EXIT(sc);
587 static int
588 tulip_add_txbuf(tulip_softc *sc, eth_pkt_t *pkt)
590 volatile tx_dscr *txd;
591 volatile tx_dscr *nexttxd;
592 uint32_t bufsize = 0;
594 txd = sc->txdscr_add;
596 /* Figure out where the next descriptor will go */
597 nexttxd = (txd+1);
598 if (nexttxd == sc->txdscr_end) {
599 nexttxd = sc->txdscr_start;
600 bufsize = M_TDES1_ENDOFRING;
603 /* If the next one is the same as our remove pointer,
604 the ring is considered full. (it actually has room for
605 one more, but we reserve the remove == add case for "empty") */
607 if (nexttxd == sc->txdscr_remove) return -1;
609 bufsize |= V_TDES1_BUF1SIZE(pkt->length) |
610 M_TDES1_FIRSTSEG | M_TDES1_LASTSEG | M_TDES1_INTERRUPT;
611 if (pkt->flags & ETH_TX_SETUP) {
612 /* For a setup packet, FIRSTSEG and LASTSEG should be clear (!) */
613 bufsize ^= M_TDES1_SETUP | M_TDES1_FIRSTSEG | M_TDES1_LASTSEG;
615 txd->txd_bufsize = bufsize;
616 txd->txd_bufaddr1 = PTR_TO_PCI(pkt->buffer);
617 txd->txd_bufaddr2 = 0;
618 txd->txd_flags = M_TDES0_OWNADAP;
620 /* success, advance the pointer */
621 sc->txdscr_add = nexttxd;
623 return 0;
627 static int
628 tulip_transmit(tulip_softc *sc,eth_pkt_t *pkt)
630 int rv;
632 if (TULIP_DEBUG) show_packet('<', pkt); /* debug */
634 rv = tulip_add_txbuf(sc, pkt);
635 sc->outpkts++;
637 WRITECSR(sc, R_CSR_TXPOLL, 1);
638 return rv;
642 static void
643 tulip_proctxring(tulip_softc *sc)
645 volatile tx_dscr *txd;
646 eth_pkt_t *pkt;
647 uint32_t flags;
649 for (;;) {
650 txd = (volatile tx_dscr *) sc->txdscr_remove;
652 if (txd == sc->txdscr_add) {
653 /* ring is empty, no buffers to process */
654 break;
657 flags = txd->txd_flags;
658 if (flags & M_TDES0_OWNADAP) {
659 /* Reached a packet still being transmitted */
660 break;
663 /* Check for a completed setup packet */
664 pkt = ETH_PKT_BASE(PCI_TO_PTR(txd->txd_bufaddr1));
665 if (pkt->flags & ETH_TX_SETUP) {
666 if (sc->state == eth_state_setup) {
667 uint32_t opmode;
669 /* check flag bits */
670 opmode = READCSR(sc, R_CSR_OPMODE);
671 opmode |= M_CSR6_RXSTART;
672 WRITECSR(sc, R_CSR_OPMODE, opmode);
673 sc->inpkts = sc->outpkts = 0;
674 sc->state = eth_state_on;
676 pkt->flags &=~ ETH_TX_SETUP;
679 /* Just free the packet */
680 eth_free_pkt(sc, pkt);
682 /* update the pointer, accounting for buffer wrap. */
683 txd++;
684 if (txd == sc->txdscr_end)
685 txd = sc->txdscr_start;
687 sc->txdscr_remove = (tx_dscr *) txd;
692 static void
693 tulip_initrings(tulip_softc *sc)
695 volatile tx_dscr *txd;
696 volatile rx_dscr *rxd;
698 /* Claim ownership of all descriptors for the driver */
700 for (txd = sc->txdscr_start; txd != sc->txdscr_end; txd++)
701 txd->txd_flags = 0;
702 for (rxd = sc->rxdscr_start; rxd != sc->rxdscr_end; rxd++)
703 rxd->rxd_flags = 0;
705 /* Init the ring pointers */
707 sc->txdscr_add = sc->txdscr_remove = sc->txdscr_start;
708 sc->rxdscr_add = sc->rxdscr_remove = sc->rxdscr_start;
709 sc->rxdscr_onring = 0;
711 /* Add stuff to the receive ring */
713 tulip_fillrxring(sc);
717 static int
718 tulip_init(tulip_softc *sc)
720 /* Allocate descriptor rings */
721 sc->rxdscrmem = KMALLOC(MAXRXDSCR*sizeof(rx_dscr), sizeof(rx_dscr));
722 sc->txdscrmem = KMALLOC(MAXTXDSCR*sizeof(tx_dscr), sizeof(tx_dscr));
724 /* Allocate buffer pool */
725 sc->pktpool = KMALLOC(ETH_PKTPOOL_SIZE*ETH_PKTBUF_SIZE, CACHE_ALIGN);
726 eth_initfreelist(sc);
727 q_init(&sc->rxqueue);
729 /* Fill in pointers to the rings */
730 sc->rxdscr_start = (rx_dscr *) (sc->rxdscrmem);
731 sc->rxdscr_end = sc->rxdscr_start + MAXRXDSCR;
732 sc->rxdscr_add = sc->rxdscr_start;
733 sc->rxdscr_remove = sc->rxdscr_start;
734 sc->rxdscr_onring = 0;
736 sc->txdscr_start = (tx_dscr *) (sc->txdscrmem);
737 sc->txdscr_end = sc->txdscr_start + MAXTXDSCR;
738 sc->txdscr_add = sc->txdscr_start;
739 sc->txdscr_remove = sc->txdscr_start;
741 tulip_initrings(sc);
743 return 0;
747 static void
748 tulip_resetrings(tulip_softc *sc)
750 volatile tx_dscr *txd;
751 volatile rx_dscr *rxd;
752 eth_pkt_t *pkt;
754 /* Free already-sent descriptors and buffers */
755 tulip_proctxring(sc);
757 /* Free any pending but unsent */
758 txd = (volatile tx_dscr *) sc->txdscr_remove;
759 while (txd != sc->txdscr_add) {
760 txd->txd_flags &=~ M_TDES0_OWNADAP;
761 pkt = ETH_PKT_BASE(PCI_TO_PTR(txd->txd_bufaddr1));
762 eth_free_pkt(sc, pkt);
764 txd++;
765 if (txd == sc->txdscr_end)
766 txd = sc->txdscr_start;
768 sc->txdscr_add = sc->txdscr_remove;
770 /* Discard any received packets as well as all free buffers */
771 rxd = (volatile rx_dscr *) sc->rxdscr_remove;
772 while (rxd != sc->rxdscr_add) {
773 rxd->rxd_flags &=~ M_RDES0_OWNADAP;
774 pkt = ETH_PKT_BASE(PCI_TO_PTR(rxd->rxd_bufaddr1));
775 eth_free_pkt(sc, pkt);
777 rxd++;
778 if (rxd == sc->rxdscr_end)
779 rxd = sc->rxdscr_start;
780 CS_ENTER(sc);
781 sc->rxdscr_onring--;
782 CS_EXIT(sc);
785 /* Reestablish the initial state. */
786 tulip_initrings(sc);
790 /* CRCs */
792 #define IEEE_CRC32_POLY 0xEDB88320UL /* CRC-32 Poly -- either endian */
794 static uint32_t
795 tulip_crc32(const uint8_t *databuf, unsigned int datalen)
797 unsigned int idx, bit, data;
798 uint32_t crc;
800 crc = 0xFFFFFFFFUL;
801 for (idx = 0; idx < datalen; idx++)
802 for (data = *databuf++, bit = 0; bit < 8; bit++, data >>= 1)
803 crc = (crc >> 1) ^ (((crc ^ data) & 1) ? IEEE_CRC32_POLY : 0);
804 return crc;
807 #define tulip_mchash(mca) (tulip_crc32((mca), 6) & 0x1FF)
810 /* Serial ROM access */
813 * Delays below (nsec) are chosen to meet specs for NS93C64 (slow M variant).
814 * Current parts are faster.
815 * Reference: NS Memory Data Book, 1994
818 #define SROM_SIZE 128
819 #define SROM_MAX_CYCLES 32
821 #define SROM_CMD_BITS 3
822 #define SROM_ADDR_BITS 6
824 #define K_SROM_READ_CMD 06
825 #define K_SROM_WRITE_CMD 05
826 #define K_SROM_WEN_CMD 04 /* WEN, WDS, also WRAL, ERAL */
828 #define SROM_VENDOR_INDEX 0x00
829 #define SROM_FORMAT_INDEX 0x12
830 #define SROM_ADDR_INDEX 0x14
832 #define SROM_DEVICE0_INDEX 0x1A
833 #define SROM_LEAF0_OFFSET_INDEX 0x1B
835 #define SROM_CRC_INDEX (SROM_SIZE-2)
836 /* Note recent chips supporting wake-on-lan have CRC in bytes 94, 95 */
838 #define SROM_WORD(rom,offset) ((rom)[offset] | ((rom)[offset+1] << 8))
840 static void
841 srom_idle_state(tulip_softc *sc)
843 uint32_t csr9;
844 unsigned int i;
846 csr9 = READCSR(sc, R_CSR_ROM_MII);
848 csr9 |= M_CSR9_SROMCHIPSEL;
849 WRITECSR(sc, R_CSR_ROM_MII, csr9);
850 cfe_nsleep(100); /* CS setup (Tcss=100) */
852 /* Run the clock through the maximum number of pending read cycles */
853 for (i = 0; i < SROM_MAX_CYCLES*2; i++) {
854 csr9 ^= M_CSR9_SROMCLOCK;
855 WRITECSR(sc, R_CSR_ROM_MII, csr9);
856 cfe_nsleep(1000); /* SK period (Fsk=0.5MHz) */
859 /* Deassert SROM Chip Select */
860 csr9 &=~ M_CSR9_SROMCHIPSEL;
861 WRITECSR(sc, R_CSR_ROM_MII, csr9);
862 cfe_nsleep(50); /* CS recovery (Tsks=50) */
865 static void
866 srom_write_bit(tulip_softc *sc, unsigned int data)
868 uint32_t csr9;
870 csr9 = READCSR(sc, R_CSR_ROM_MII);
872 /* Place the data bit on the bus */
873 if (data == 1)
874 csr9 |= M_CSR9_SROMDATAIN;
875 else
876 csr9 &=~ M_CSR9_SROMDATAIN;
878 WRITECSR(sc, R_CSR_ROM_MII, csr9);
879 cfe_nsleep(360); /* setup: Tdis=200 */
881 /* Now clock the data into the SROM */
882 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_SROMCLOCK);
883 cfe_nsleep(900); /* clock high, Tskh=500 */
884 WRITECSR(sc, R_CSR_ROM_MII, csr9);
885 cfe_nsleep(450); /* clock low, Tskl=250 */
887 /* Now clear the data bit */
888 csr9 &=~ M_CSR9_SROMDATAIN; /* data invalid, Tidh=20 for SK^ */
889 WRITECSR(sc, R_CSR_ROM_MII, csr9);
890 cfe_nsleep(270); /* min cycle, 1/Fsk=2000 */
893 static uint16_t
894 srom_read_bit(tulip_softc *sc)
896 uint32_t csr9;
898 csr9 = READCSR(sc, R_CSR_ROM_MII);
900 /* Generate a clock cycle before doing a read */
901 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_SROMCLOCK); /* rising edge */
902 cfe_nsleep(1000); /* clock high, Tskh=500, Tpd=1000 */
903 WRITECSR(sc, R_CSR_ROM_MII, csr9); /* falling edge */
904 cfe_nsleep(1000); /* clock low, 1/Fsk=2000 */
906 csr9 = READCSR(sc, R_CSR_ROM_MII);
907 return ((csr9 & M_CSR9_SROMDATAOUT) != 0 ? 1 : 0);
910 #define CMD_BIT_MASK (1 << (SROM_CMD_BITS+SROM_ADDR_BITS-1))
912 static uint16_t
913 srom_read_word(tulip_softc *sc, unsigned int index)
915 uint16_t command, word;
916 uint32_t csr9;
917 unsigned int i;
919 csr9 = READCSR(sc, R_CSR_ROM_MII) | M_CSR9_SROMCHIPSEL;
921 /* Assert the SROM CS line */
922 WRITECSR(sc, R_CSR_ROM_MII, csr9);
923 cfe_nsleep(100); /* CS setup, Tcss = 100 */
925 /* Send the read command to the SROM */
926 command = (K_SROM_READ_CMD << SROM_ADDR_BITS) | index;
927 for (i = 0; i < SROM_CMD_BITS+SROM_ADDR_BITS; i++) {
928 srom_write_bit(sc, (command & CMD_BIT_MASK) != 0 ? 1 : 0);
929 command <<= 1;
932 /* Now read the bits from the SROM (MSB first) */
933 word = 0;
934 for (i = 0; i < 16; ++i) {
935 word <<= 1;
936 word |= srom_read_bit(sc);
939 /* Clear the SROM CS Line, CS hold, Tcsh = 0 */
940 WRITECSR(sc, R_CSR_ROM_MII, csr9 &~ M_CSR9_SROMCHIPSEL);
942 return word;
946 /****************************************************************************
947 * srom_calc_crc()
949 * Calculate the CRC of the SROM and return it. We compute the
950 * CRC per Appendix A of the 21140A ROM/external register data
951 * sheet (EC-QPQWA-TE).
952 ***************************************************************************/
954 static uint16_t
955 srom_calc_crc(tulip_softc *sc, uint8_t srom[], int length)
957 uint32_t crc = tulip_crc32(srom, length) ^ 0xFFFFFFFF;
959 return (uint16_t)(crc & 0xFFFF);
962 /****************************************************************************
963 * srom_read_all(sc, uint8_t dest)
965 * Read the entire SROM into the srom array
967 * Input parameters:
968 * sc - tulip state
969 ***************************************************************************/
971 static int
972 srom_read_all(tulip_softc *sc, uint8_t dest[])
974 int i;
975 uint16_t crc, temp;
977 WRITECSR(sc, R_CSR_ROM_MII, M_CSR9_SERROMSEL|M_CSR9_ROMREAD);
979 srom_idle_state(sc);
981 for (i = 0; i < SROM_SIZE/2; i++) {
982 temp = srom_read_word(sc, i);
983 dest[2*i] = temp & 0xFF;
984 dest[2*i+1] =temp >> 8;
987 WRITECSR(sc, R_CSR_ROM_MII, 0); /* CS hold, Tcsh=0 */
989 crc = srom_calc_crc(sc, dest, SROM_CRC_INDEX);
990 if (crc != SROM_WORD(dest, SROM_CRC_INDEX)) {
991 crc = srom_calc_crc(sc, dest, 94); /* "alternative" */
992 if (crc != SROM_WORD(dest, 94)) {
993 xprintf("%s: Invalid SROM CRC, calc %04x, stored %04x\n",
994 tulip_devname(sc), crc, SROM_WORD(dest, 94));
995 return 0/*-1*/;
998 return 0;
1001 static int
1002 srom_read_addr(tulip_softc *sc, uint8_t buf[])
1004 uint8_t srom[SROM_SIZE];
1006 if (srom_read_all(sc, srom) == 0) {
1007 memcpy(buf, &srom[SROM_ADDR_INDEX], ENET_ADDR_LEN);
1008 return 0;
1011 return -1;
1015 /****************************************************************************
1016 * earom_read_all(sc, uint8_t dest)
1018 * Read the entire Ethernet address ROM into the srom array (21040 only)
1020 * Input parameters:
1021 * sc - tulip state
1022 ***************************************************************************/
1024 static int
1025 earom_read_all(tulip_softc *sc, uint8_t dest[])
1027 int i;
1028 uint32_t csr9;
1030 WRITECSR(sc, R_CSR_ROM_MII, 0); /* reset pointer */
1032 for (i = 0; i < SROM_SIZE; i++) {
1033 for (;;) {
1034 csr9 = READCSR(sc, R_CSR_ROM_MII);
1035 if ((csr9 & M_CSR9_DATANOTVALID) == 0)
1036 break;
1037 POLL();
1039 dest[i] = G_CSR9_ROMDATA(csr9);
1042 return 0;
1045 static int
1046 earom_read_addr(tulip_softc *sc, uint8_t buf[])
1048 uint8_t srom[SROM_SIZE];
1050 if (earom_read_all(sc, srom) == 0) {
1051 memcpy(buf, &srom[0], ENET_ADDR_LEN);
1052 return 0;
1055 return -1;
1059 static int
1060 rom_read_all(tulip_softc *sc, uint8_t buf[])
1062 if (sc->device == K_PCI_ID_DC21040)
1063 return earom_read_all(sc, buf);
1064 else
1065 return srom_read_all(sc, buf);
1068 static int
1069 rom_read_addr(tulip_softc *sc, uint8_t buf[])
1071 if (sc->device == K_PCI_ID_DC21040)
1072 return earom_read_addr(sc, buf);
1073 else
1074 return srom_read_addr(sc, buf);
1077 #define rom_dump(srom)
1080 /****************************************************************************
1081 * MII access utility routines
1082 ***************************************************************************/
1084 /* MII clock limited to 2.5 MHz, transactions end with MDIO tristated */
1086 static void
1087 mii_write_bits(tulip_softc *sc, uint32_t data, unsigned int count)
1089 uint32_t csr9;
1090 uint32_t bitmask;
1092 csr9 = READCSR(sc, R_CSR_ROM_MII) &~ (M_CSR9_MDC | M_CSR9_MIIMODE);
1094 for (bitmask = 1 << (count-1); bitmask != 0; bitmask >>= 1) {
1095 csr9 &=~ M_CSR9_MDO;
1096 if ((data & bitmask) != 0) csr9 |= M_CSR9_MDO;
1097 WRITECSR(sc, R_CSR_ROM_MII, csr9);
1099 cfe_nsleep(2000); /* setup */
1100 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_MDC);
1101 cfe_nsleep(2000); /* hold */
1102 WRITECSR(sc, R_CSR_ROM_MII, csr9);
1106 static void
1107 mii_turnaround(tulip_softc *sc)
1109 uint32_t csr9;
1111 csr9 = READCSR(sc, R_CSR_ROM_MII) | M_CSR9_MIIMODE;
1113 /* stop driving data */
1114 WRITECSR(sc, R_CSR_ROM_MII, csr9);
1115 cfe_nsleep(2000); /* setup */
1116 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_MDC);
1117 cfe_nsleep(2000); /* clock high */
1118 WRITECSR(sc, R_CSR_ROM_MII, csr9);
1120 /* read back and check for 0 here? */
1123 /****************************************************************************
1124 * mii_read_register
1126 * This routine reads a register from the PHY chip using the MII
1127 * serial management interface.
1129 * Input parameters:
1130 * index - index of register to read (0-31)
1132 * Return value:
1133 * word read from register
1134 ***************************************************************************/
1136 static uint16_t
1137 mii_read_register(tulip_softc *sc, unsigned int index)
1139 /* Send the command and address to the PHY. The sequence is
1140 a synchronization sequence (32 1 bits)
1141 a "start" command (2 bits)
1142 a "read" command (2 bits)
1143 the PHY addr (5 bits)
1144 the register index (5 bits)
1146 uint32_t csr9;
1147 uint16_t word;
1148 int i;
1150 mii_write_bits(sc, 0xFF, 8);
1151 mii_write_bits(sc, 0xFFFFFFFF, 32);
1152 mii_write_bits(sc, MII_COMMAND_START, 2);
1153 mii_write_bits(sc, MII_COMMAND_READ, 2);
1154 mii_write_bits(sc, sc->mii_addr, 5);
1155 mii_write_bits(sc, index, 5);
1157 mii_turnaround(sc);
1159 csr9 = (READCSR(sc, R_CSR_ROM_MII) &~ M_CSR9_MDC) | M_CSR9_MIIMODE;
1160 word = 0;
1162 for (i = 0; i < 16; i++) {
1163 WRITECSR(sc, R_CSR_ROM_MII, csr9);
1164 cfe_nsleep(2000); /* clock width low */
1165 WRITECSR(sc, R_CSR_ROM_MII, csr9 | M_CSR9_MDC);
1166 cfe_nsleep(2000); /* clock width high */
1167 WRITECSR(sc, R_CSR_ROM_MII, csr9);
1168 cfe_nsleep(1000); /* output delay */
1169 word <<= 1;
1170 if ((READCSR(sc, R_CSR_ROM_MII) & M_CSR9_MDI) != 0)
1171 word |= 0x0001;
1174 return word;
1176 /* reset to output mode? */
1179 /****************************************************************************
1180 * mii_write_register
1182 * This routine writes a register in the PHY chip using the MII
1183 * serial management interface.
1185 * Input parameters:
1186 * index - index of register to write (0-31)
1187 * value - word to write
1188 ***************************************************************************/
1190 static void
1191 mii_write_register(tulip_softc *sc, unsigned int index, uint16_t value)
1193 mii_write_bits(sc, 0xFF, 8);
1194 mii_write_bits(sc, 0xFFFFFFFF, 32);
1195 mii_write_bits(sc, MII_COMMAND_START, 2);
1196 mii_write_bits(sc, MII_COMMAND_WRITE, 2);
1197 mii_write_bits(sc, sc->mii_addr, 5);
1198 mii_write_bits(sc, index, 5);
1199 mii_write_bits(sc, MII_COMMAND_ACK, 2);
1200 mii_write_bits(sc, value, 16);
1202 /* reset to input mode? */
1206 static int
1207 mii_probe(tulip_softc *sc)
1209 int i;
1210 uint16_t id1, id2;
1212 for (i = 0; i < 32; i++) {
1213 sc->mii_addr = i;
1214 id1 = mii_read_register(sc, MII_PHYIDR1);
1215 id2 = mii_read_register(sc, MII_PHYIDR2);
1216 if ((id1 != 0x0000 && id1 != 0xFFFF) ||
1217 (id2 != 0x0000 && id2 != 0xFFFF)) {
1218 return 0;
1221 return -1;
1224 #define mii_dump(sc,label)
1227 /* The following functions are suitable for all tulips with MII
1228 interfaces. */
1230 static void
1231 mii_set_speed(tulip_softc *sc, int speed, int autoneg)
1233 uint16_t control;
1234 uint16_t pcr;
1235 uint32_t opmode = 0;
1237 /* This is really just for NS DP83840/A. Needed? */
1238 pcr = mii_read_register(sc, 0x17);
1239 pcr |= (0x400|0x100|0x40|0x20);
1240 mii_write_register(sc, 0x17, pcr);
1242 control = mii_read_register(sc, MII_BMCR);
1244 if (!autoneg) {
1245 control &=~ (BMCR_ANENABLE | BMCR_RESTARTAN);
1246 mii_write_register(sc, MII_BMCR, control);
1247 control &=~ (BMCR_SPEED0 | BMCR_SPEED1 | BMCR_DUPLEX);
1250 switch (speed) {
1251 case ETHER_SPEED_10HDX:
1252 default:
1253 opmode = M_CSR6_SPEED_10_MII;
1254 break;
1255 case ETHER_SPEED_10FDX:
1256 control |= BMCR_DUPLEX;
1257 opmode = M_CSR6_SPEED_10_MII | M_CSR6_FULLDUPLEX;
1258 break;
1259 case ETHER_SPEED_100HDX:
1260 control |= BMCR_SPEED100;
1261 opmode = M_CSR6_SPEED_100_MII;
1262 break;
1263 case ETHER_SPEED_100FDX:
1264 control |= BMCR_SPEED100 | BMCR_DUPLEX ;
1265 opmode = M_CSR6_SPEED_100_MII | M_CSR6_FULLDUPLEX;
1266 break;
1269 if (!autoneg)
1270 mii_write_register(sc, MII_BMCR, control);
1272 opmode |= M_CSR6_MBO;
1273 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72);
1274 WRITECSR(sc, R_CSR_OPMODE, opmode);
1275 mii_dump(sc, "setspeed PHY");
1278 static void
1279 mii_autonegotiate(tulip_softc *sc)
1281 uint16_t control, status, cap;
1282 unsigned int timeout;
1283 int linkspeed;
1284 int autoneg;
1286 linkspeed = ETHER_SPEED_UNKNOWN;
1288 /* Read twice to clear latching bits */
1289 status = mii_read_register(sc, MII_BMSR);
1290 status = mii_read_register(sc, MII_BMSR);
1291 mii_dump(sc, "query PHY");
1293 if ((status & (BMSR_AUTONEG | BMSR_LINKSTAT)) ==
1294 (BMSR_AUTONEG | BMSR_LINKSTAT))
1295 control = mii_read_register(sc, MII_BMCR);
1296 else {
1297 /* reset the PHY */
1298 mii_write_register(sc, MII_BMCR, BMCR_RESET);
1299 timeout = 3000;
1300 for (;;) {
1301 control = mii_read_register(sc, MII_BMCR);
1302 if ((control && BMCR_RESET) == 0) break;
1303 cfe_sleep(CFE_HZ/2);
1304 timeout -= 500;
1305 if (timeout <= 0) break;
1307 if ((control & BMCR_RESET) != 0) {
1308 xprintf("%s: PHY reset failed\n", tulip_devname(sc));
1309 return;
1312 status = mii_read_register(sc, MII_BMSR);
1313 cap = ((status >> 6) & (ANAR_TXFD | ANAR_TXHD | ANAR_10FD | ANAR_10HD))
1314 | PSB_802_3;
1315 mii_write_register(sc, MII_ANAR, cap);
1316 control |= (BMCR_ANENABLE | BMCR_RESTARTAN);
1317 mii_write_register(sc, MII_BMCR, control);
1319 timeout = 3000;
1320 for (;;) {
1321 status = mii_read_register(sc, MII_BMSR);
1322 if ((status & BMSR_ANCOMPLETE) != 0) break;
1323 cfe_sleep(CFE_HZ/2);
1324 timeout -= 500;
1325 if (timeout <= 0) break;
1327 mii_dump(sc, "done PHY");
1330 xprintf("%s: Link speed: ", tulip_devname(sc));
1331 if ((status & BMSR_ANCOMPLETE) != 0) {
1332 /* A link partner was negogiated... */
1334 uint16_t remote = mii_read_register(sc, MII_ANLPAR);
1336 autoneg = 1;
1337 if ((remote & ANLPAR_TXFD) != 0) {
1338 xprintf("100BaseT FDX");
1339 linkspeed = ETHER_SPEED_100FDX;
1341 else if ((remote & ANLPAR_TXHD) != 0) {
1342 xprintf("100BaseT HDX");
1343 linkspeed = ETHER_SPEED_100HDX;
1345 else if ((remote & ANLPAR_10FD) != 0) {
1346 xprintf("10BaseT FDX");
1347 linkspeed = ETHER_SPEED_10FDX;
1349 else if ((remote & ANLPAR_10HD) != 0) {
1350 xprintf("10BaseT HDX");
1351 linkspeed = ETHER_SPEED_10HDX;
1353 xprintf("\n");
1355 else {
1356 /* no link partner negotiation */
1358 autoneg = 0;
1359 xprintf("Unknown, assuming 10BaseT\n");
1360 control &=~ (BMCR_ANENABLE | BMCR_RESTARTAN);
1361 mii_write_register(sc, MII_BMCR, control);
1362 linkspeed = ETHER_SPEED_10HDX;
1365 if ((status & BMSR_LINKSTAT) == 0)
1366 mii_write_register(sc, MII_BMCR, control);
1367 mii_set_speed(sc, linkspeed, autoneg);
1369 status = mii_read_register(sc, MII_BMSR); /* clear latching bits */
1370 mii_dump(sc, "final PHY");
1374 /* Chip specific code */
1376 static void
1377 dc21143_set_speed(tulip_softc *sc, int speed)
1379 uint32_t opmode = 0;
1381 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1383 switch (speed) {
1384 case ETHER_SPEED_AUTO:
1385 break;
1386 case ETHER_SPEED_10HDX:
1387 default:
1388 WRITECSR(sc, R_CSR_SIAMODE1, M_CSR14_10BT_HD);
1389 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata);
1390 opmode = M_CSR6_SPEED_10;
1391 break;
1392 case ETHER_SPEED_10FDX:
1393 WRITECSR(sc, R_CSR_SIAMODE1, M_CSR14_10BT_FD);
1394 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata);
1395 opmode = M_CSR6_SPEED_10 | M_CSR6_FULLDUPLEX;
1396 break;
1397 case ETHER_SPEED_100HDX:
1398 WRITECSR(sc, R_CSR_SIAMODE1, 0);
1399 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata);
1400 opmode = M_CSR6_SPEED_100;
1401 break;
1402 case ETHER_SPEED_100FDX:
1403 WRITECSR(sc, R_CSR_SIAMODE1, 0);
1404 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata);
1405 opmode = M_CSR6_SPEED_100 | M_CSR6_FULLDUPLEX;
1406 break;
1409 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET);
1411 opmode |= M_CSR6_MBO;
1412 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72);
1413 WRITECSR(sc, R_CSR_OPMODE, opmode);
1416 static void
1417 dc21143_autonegotiate(tulip_softc *sc)
1419 uint32_t opmode;
1420 uint32_t tempword;
1421 int count;
1422 int linkspeed;
1424 linkspeed = ETHER_SPEED_UNKNOWN;
1426 /* Program the media setup into the CSRs. */
1427 /* reset SIA */
1428 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1430 /* set to speed_10, fullduplex to start_nway */
1431 opmode =
1432 M_CSR6_SPEED_10 |
1433 M_CSR6_FULLDUPLEX |
1434 M_CSR6_MBO;
1435 WRITECSR(sc, R_CSR_OPMODE, opmode);
1437 /* Choose advertised capabilities */
1438 tempword =
1439 M_CSR14_100BASETHALFDUP |
1440 M_CSR14_100BASETFULLDUP |
1441 M_CSR14_HALFDUPLEX10BASET;
1442 WRITECSR(sc, R_CSR_SIAMODE1, tempword);
1444 /* Enable autonegotiation */
1445 tempword |= M_CSR14_AUTONEGOTIATE | 0xFFFF;
1446 WRITECSR(sc, R_CSR_SIAMODE1, tempword);
1447 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata);
1448 WRITECSR(sc, R_CSR_OPMODE, opmode);
1449 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET);
1451 /* STATE check nway, poll until a valid 10/100mbs signal seen */
1452 WRITECSR(sc, R_CSR_STATUS, M_CSR5_LINKPASS); /* try to clear this... */
1454 /* (Re)start negotiation */
1455 tempword = READCSR(sc, R_CSR_SIASTATUS);
1456 tempword &=~ M_CSR12_AUTONEGARBIT;
1457 tempword |= V_CSR12_AUTONEGARBIT(0x1);
1459 for (count = 0; count <= 13; count++) {
1460 tempword = READCSR(sc, R_CSR_STATUS);
1461 if (tempword & M_CSR5_LINKPASS)
1462 break;
1463 cfe_sleep(CFE_HZ/10);
1466 if (count > 13)
1467 xprintf("%s: Link autonegotiation failed\n", tulip_devname(sc));
1469 /* STATE configure nway, check to see if any abilities common to us.
1470 If they do, set to highest mode, if not, we will see if the partner
1471 will do 100mb or 10mb - then set it */
1473 tempword = READCSR(sc, R_CSR_SIASTATUS);
1474 /* clear the autonegogiate complete bit */
1475 WRITECSR(sc, R_CSR_STATUS, M_CSR5_LINKPASS);
1477 if (tempword & M_CSR12_LINKPARTNEG) {
1478 /* A link partner was negogiated... */
1480 xprintf("%s: Link speed: ", tulip_devname(sc));
1481 if (tempword & 0x01000000) { /* 100FD */
1482 xprintf("100BaseT FDX");
1483 linkspeed = ETHER_SPEED_100FDX;
1485 else if (tempword & 0x00800000) { /* 100HD */
1486 xprintf("100BaseT HDX");
1487 linkspeed = ETHER_SPEED_100HDX;
1489 else if (tempword & 0x00400000) { /* 10FD */
1490 xprintf("10BaseT FDX");
1491 linkspeed = ETHER_SPEED_10FDX;
1493 else if (tempword & 0x00200000) { /* 10HD */
1494 xprintf("10BaseT HDX");
1495 linkspeed = ETHER_SPEED_10HDX;
1497 xprintf("\n");
1499 else {
1500 /* no link partner negotiation */
1501 /* disable link for 1.3 seconds to break any existing connections */
1503 xprintf("%s: ", tulip_devname(sc));
1504 dc21143_set_speed(sc, ETHER_SPEED_10HDX);
1505 cfe_sleep(CFE_HZ/8);
1507 tempword = READCSR(sc, R_CSR_SIASTATUS);
1509 if ((tempword & 0x02) == 0) {
1510 /* 100 mb signal present set to 100mb */
1511 xprintf("No link partner... setting to 100BaseT HDX\n");
1512 linkspeed = ETHER_SPEED_100HDX;
1514 else if ((tempword & 0x04) == 0) {
1515 /* 10 mb signal present */
1516 xprintf("No link partner... setting to 10BaseT HDX\n");
1517 linkspeed = ETHER_SPEED_10HDX;
1519 else {
1520 /* couldn't determine line speed, so set to 10mbs */
1521 xprintf("Unknown; defaulting to 10BaseT HDX\n");
1522 linkspeed = ETHER_SPEED_10HDX;
1526 dc21143_set_speed(sc, linkspeed);
1529 static void
1530 dc21143_set_loopback(tulip_softc *sc, int mode)
1532 uint32_t v;
1534 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1535 if (mode == ETHER_LOOPBACK_EXT) {
1536 /* deal with CSRs 13-15 */
1538 cfe_sleep(CFE_HZ/10); /* check this */
1540 /* Update the SIA registers */
1541 v = READCSR(sc, R_CSR_SIAMODE0);
1542 WRITECSR(sc, R_CSR_SIAMODE0, v &~ 0xFFFF);
1543 v = READCSR(sc, R_CSR_SIAMODE1);
1544 WRITECSR(sc, R_CSR_SIAMODE1, v &~ 0xFFFF);
1545 v = READCSR(sc, R_CSR_SIAMODE2);
1546 WRITECSR(sc, R_CSR_SIAMODE2, v | 0xC000); /* WC of HCKR, RMP */
1547 if (mode == ETHER_LOOPBACK_OFF)
1548 WRITECSR(sc, R_CSR_SIAMODE2, sc->gpdata);
1549 else
1550 WRITECSR(sc, R_CSR_SIAMODE2, (v &~ 0xFFFF) | M_CSR15_GP_AUIBNC);
1552 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET);
1554 sc->loopback = mode;
1557 /* Known vendors with cards requiring special initialization. */
1558 #define K_PCI_VENDOR_COGENT 0x1109 /* inherited by Adaptec */
1559 #define K_PCI_VENDOR_PHOBOS 0x13D8
1560 #define K_PCI_VENDOR_ZNYZ 0x110D
1561 #define K_PCI_VENDOR_KINGSTON 0x2646
1563 static void
1564 dc21143_hwinit(tulip_softc *sc, uint8_t srom[])
1566 uint32_t v;
1567 uint32_t csr6word, csr14word;
1569 if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_COGENT) {
1570 /* Cogent/Adaptec MII (ANA-6911A). */
1571 sc->phy_type = MII;
1572 WRITECSR(sc, R_CSR_SIAMODE2, 0x0821 << 16);
1573 WRITECSR(sc, R_CSR_SIAMODE2, 0x0001 << 16);
1574 cfe_sleep(CFE_HZ/10);
1575 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000 << 16);
1576 cfe_sleep(CFE_HZ/2);
1577 sc->gpdata = 0;
1579 else if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_ZNYZ) {
1580 /* Znyz 34xQ adapters */
1581 sc->phy_type = SYM;
1583 /* The ZX345Q with wake-on-LAN enabled apparently clears ANE and
1584 TAS on power up (but not cold reset) */
1585 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFFFFFF);
1587 WRITECSR(sc, R_CSR_SIAMODE2,
1588 M_CSR15_GP_CONTROLWRITE |
1589 0xF0000 | /* all outputs */
1590 M_CSR15_GP_LED1 |
1591 M_CSR15_GP_AUIBNC);
1592 cfe_sleep(CFE_HZ/5);
1593 WRITECSR(sc, R_CSR_SIAMODE2, 0x40000); /* release reset */
1594 cfe_sleep(CFE_HZ/5);
1595 sc->gpdata = 0x40000 | M_CSR15_GP_AUIBNC;
1597 else if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_KINGSTON) {
1598 /* Kingston KNE100TX */
1599 sc->phy_type = MII;
1600 sc->gpdata = 0;
1602 else if (SROM_WORD(srom, SROM_VENDOR_INDEX) == K_PCI_VENDOR_PHOBOS) {
1603 /* Phobos 430TX quad card */
1604 sc->phy_type = MII;
1605 WRITECSR(sc, R_CSR_SIAMODE2, 0x0821 << 16);
1606 WRITECSR(sc, R_CSR_SIAMODE2, 0x0001 << 16);
1607 cfe_sleep(CFE_HZ/10);
1608 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000 << 16);
1609 cfe_sleep(CFE_HZ/2);
1610 sc->gpdata = 0;
1612 else {
1613 /* Most 21143 cards use the SYM interface. */
1614 sc->phy_type = SYM;
1615 WRITECSR(sc, R_CSR_SIAMODE2, M_CSR15_CONFIG_GEPS_LEDS);
1616 sc->gpdata = M_CSR15_DEFAULT_VALUE;
1619 if (sc->phy_type == MII) {
1620 mii_probe(sc);
1623 /* CSR0 - bus mode */
1624 v = V_CSR0_SKIPLEN(0) |
1625 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) |
1626 M_CSR0_READMULTENAB | M_CSR0_READLINEENAB |
1627 M_CSR0_WRITEINVALENAB |
1628 V_CSR0_BURSTLEN(K_CSR0_BURSTANY);
1629 #ifdef __MIPSEB
1630 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */
1631 #endif
1632 WRITECSR(sc, R_CSR_BUSMODE, v);
1634 /* CSR6 - operation mode */
1635 v = M_CSR6_PORTSEL |
1636 V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72) |
1637 M_CSR6_MBO;
1638 if (sc->phy_type == SYM)
1639 v |= M_CSR6_PCSFUNC |M_CSR6_SCRAMMODE;
1640 WRITECSR(sc, R_CSR_OPMODE, v);
1642 /* About to muck with the SIA, reset it.(?) */
1643 /* WRITECSR(sc, R_CSR_SIASTATUS, 0); */
1645 /* Must shut off all transmit/receive in order to attempt to
1646 achieve Full Duplex */
1647 csr6word = READCSR(sc, R_CSR_OPMODE);
1648 WRITECSR(sc, R_CSR_OPMODE, csr6word &~ (M_CSR6_TXSTART | M_CSR6_RXSTART));
1649 csr6word = READCSR(sc, R_CSR_OPMODE);
1651 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start));
1652 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start));
1654 if (sc->phy_type == MII) {
1655 if (sc->linkspeed == ETHER_SPEED_AUTO)
1656 mii_autonegotiate(sc);
1657 else
1658 mii_set_speed(sc, sc->linkspeed, 0);
1660 else {
1661 if (sc->linkspeed == ETHER_SPEED_AUTO) {
1662 dc21143_autonegotiate(sc);
1664 else {
1665 /* disable autonegotiate so we can set full duplex to on */
1666 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1667 csr14word = READCSR(sc, R_CSR_SIAMODE1);
1668 csr14word &=~ M_CSR14_AUTONEGOTIATE;
1669 WRITECSR(sc, R_CSR_SIAMODE1, csr14word);
1670 WRITECSR(sc, R_CSR_SIAMODE0, M_CSR13_CONN_NOT_RESET);
1672 dc21143_set_speed(sc, sc->linkspeed);
1678 static void
1679 dc21140_set_speed(tulip_softc *sc, int speed, int autoneg)
1681 mii_set_speed(sc, speed, autoneg);
1684 static void
1685 dc21140_set_loopback(tulip_softc *sc, int mode)
1687 if (mode == ETHER_LOOPBACK_EXT) {
1688 xprintf("%s: external loopback mode NYI\n", tulip_devname(sc));
1689 mode = ETHER_LOOPBACK_OFF;
1691 else if (mode != ETHER_LOOPBACK_INT)
1692 mode = ETHER_LOOPBACK_OFF;
1694 sc->loopback = mode;
1697 static void
1698 dc21140_hwinit(tulip_softc *sc, uint8_t srom[])
1700 uint16_t leaf;
1701 uint8_t gpr_control, gpr_data;
1702 uint32_t v;
1703 uint32_t opmode;
1705 if (srom[SROM_FORMAT_INDEX] == 0 || srom[SROM_FORMAT_INDEX] > 4) {
1706 gpr_control = 0x1F;
1707 gpr_data = 0x00;
1708 sc->phy_type = MII; /* Most 21140 cards use MII */
1710 else if (srom[SROM_ADDR_INDEX+0] == 0x00 && srom[SROM_ADDR_INDEX+1] == 0xC0
1711 && srom[SROM_ADDR_INDEX+2] == 0x95) {
1712 /* Znyx 34x apparently has non-standard leaf info. */
1713 gpr_control = 0x00; /* All inputs, per Znyx docs */
1714 gpr_data = 0x00;
1715 sc->phy_type = MII;
1717 else {
1718 leaf = SROM_WORD(srom, SROM_LEAF0_OFFSET_INDEX);
1719 gpr_control = srom[leaf+2];
1720 if ((srom[leaf+4] & 0x80) == 0) {
1721 gpr_data = 0x85; /* SYM, 100 Mb/s */
1722 sc->phy_type = SYM;
1724 else {
1725 gpr_data = 0x00; /* MII */
1726 sc->phy_type = MII;
1730 /* Assume that we will use MII or SYM interface */
1731 WRITECSR(sc, R_CSR_OPMODE, M_CSR6_PORTSEL);
1732 RESET_ADAPTER(sc);
1734 WRITECSR(sc, R_CSR_GENPORT, M_CSR12_CONTROL | gpr_control);
1735 cfe_nsleep(100); /* CS setup (Tcss=100) */
1736 WRITECSR(sc, R_CSR_GENPORT, gpr_data); /* setup PHY */
1738 if (sc->phy_type == MII) {
1739 mii_probe(sc);
1742 /* CSR0 - bus mode */
1743 v = V_CSR0_SKIPLEN(0) |
1744 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) |
1745 M_CSR0_READMULTENAB | M_CSR0_READLINEENAB |
1746 M_CSR0_WRITEINVALENAB |
1747 V_CSR0_BURSTLEN(K_CSR0_BURSTANY);
1748 #ifdef __MIPSEB
1749 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */
1750 #endif
1751 WRITECSR(sc, R_CSR_BUSMODE, v);
1753 /* CSR6 - operation mode */
1754 v = M_CSR6_PORTSEL |
1755 V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72) |
1756 M_CSR6_MBO;
1757 WRITECSR(sc, R_CSR_OPMODE, v);
1759 /* Must shut off all transmit/receive in order to attempt to
1760 achieve Full Duplex */
1761 opmode = READCSR(sc, R_CSR_OPMODE);
1762 WRITECSR(sc, R_CSR_OPMODE, opmode &~ (M_CSR6_TXSTART | M_CSR6_RXSTART));
1763 opmode = READCSR(sc, R_CSR_OPMODE);
1765 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start));
1766 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start));
1768 if (sc->phy_type == MII) {
1769 if (sc->linkspeed == ETHER_SPEED_AUTO)
1770 mii_autonegotiate(sc);
1771 else
1772 mii_set_speed(sc, sc->linkspeed, 0);
1774 else {
1775 switch (sc->linkspeed) {
1776 default:
1777 sc->linkspeed = ETHER_SPEED_100HDX; /* for now */
1778 /* fall through */
1779 case ETHER_SPEED_100HDX:
1780 opmode |= M_CSR6_SPEED_100;
1781 break;
1782 case ETHER_SPEED_100FDX:
1783 opmode |= M_CSR6_SPEED_100 | M_CSR6_FULLDUPLEX;
1784 break;
1787 WRITECSR(sc, R_CSR_OPMODE, opmode);
1792 static void
1793 dc21041_set_speed(tulip_softc *sc, int speed)
1795 uint32_t opmode = 0;
1797 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1799 /* For now, always force 10BT, HDX (21041, Table 3-62) */
1800 switch (speed) {
1801 case ETHER_SPEED_10HDX:
1802 default:
1803 WRITECSR(sc, R_CSR_SIAMODE1, 0x7F3F);
1804 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008);
1805 opmode = M_CSR6_SPEED_10;
1806 break;
1809 WRITECSR(sc, R_CSR_SIAMODE0, 0xEF00 | M_CSR13_CONN_NOT_RESET);
1810 cfe_sleep(CFE_HZ/10);
1812 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72);
1813 WRITECSR(sc, R_CSR_OPMODE, opmode);
1816 static void
1817 dc21041_set_loopback(tulip_softc *sc, int mode)
1819 /* For now, always assume 10BT */
1820 uint32_t mode0;
1822 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1823 cfe_sleep(CFE_HZ/10); /* check this */
1825 /* Update the SIA registers */
1826 if (mode == ETHER_LOOPBACK_EXT) {
1827 /* NB: this is really just internal but through the 10BT endec */
1828 WRITECSR(sc, R_CSR_SIAMODE1, 0x7A3F);
1829 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008);
1830 mode0 = 0;
1832 else if (mode == ETHER_LOOPBACK_INT) {
1833 /* MAC internal loopback, no SIA */
1834 WRITECSR(sc, R_CSR_SIAMODE1, 0x0000);
1835 WRITECSR(sc, R_CSR_SIAMODE2, 0x000E);
1836 mode0 = M_CSR13_CONN_AUI_10BT;
1838 else {
1839 mode = ETHER_LOOPBACK_OFF;
1840 WRITECSR(sc, R_CSR_SIAMODE1, 0x7F3F);
1841 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008);
1842 mode0 = 0;
1845 WRITECSR(sc, R_CSR_SIAMODE0, 0xEF00 | mode0 | M_CSR13_CONN_NOT_RESET );
1847 sc->loopback = mode;
1850 static void
1851 dc21041_hwinit(tulip_softc *sc, uint8_t srom[])
1853 uint32_t v;
1855 sc->phy_type = SRL;
1857 /* CSR0 - bus mode */
1858 v = V_CSR0_SKIPLEN(0) |
1859 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) |
1860 V_CSR0_BURSTLEN(K_CSR0_BURSTANY);
1861 #ifdef __MIPSEB
1862 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */
1863 #endif
1864 WRITECSR(sc, R_CSR_BUSMODE, v);
1866 WRITECSR(sc, R_CSR_INTMASK, 0);
1868 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start));
1869 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start));
1871 /* For now, always force 10BT, HDX (21041, Table 3-62) */
1872 dc21041_set_speed(sc, ETHER_SPEED_10HDX);
1876 static void
1877 dc21040_set_speed(tulip_softc *sc, int speed)
1879 uint32_t opmode = 0;
1881 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1883 /* For now, force 10BT, HDX unless FDX requested (21040, Table 3-53) */
1884 switch (speed) {
1885 case ETHER_SPEED_10HDX:
1886 default:
1887 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFF);
1888 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000);
1889 opmode = 0;
1890 break;
1891 case ETHER_SPEED_10FDX:
1892 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFD);
1893 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000);
1894 opmode = M_CSR6_FULLDUPLEX;
1895 break;
1898 WRITECSR(sc, R_CSR_SIAMODE0, 0xEF00 | M_CSR13_CONN_NOT_RESET);
1899 cfe_sleep(CFE_HZ/10);
1901 opmode |= V_CSR6_THRESHCONTROL(K_CSR6_TXTHRES_128_72);
1902 WRITECSR(sc, R_CSR_OPMODE, opmode);
1905 static void
1906 dc21040_set_loopback(tulip_softc *sc, int mode)
1908 WRITECSR(sc, R_CSR_SIAMODE0, 0);
1909 cfe_sleep(CFE_HZ/10); /* check this */
1911 /* Update the SIA registers */
1912 if (mode == ETHER_LOOPBACK_EXT) {
1913 /* NB: this is on-chip loopback through the 10BT endec */
1914 WRITECSR(sc, R_CSR_SIAMODE1, 0xFEFB);
1915 WRITECSR(sc, R_CSR_SIAMODE2, 0x0008);
1917 else if (mode == ETHER_LOOPBACK_INT) {
1918 /* MAC internal loopback, no SIA */
1919 WRITECSR(sc, R_CSR_SIAMODE1, 0x0000);
1920 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000);
1922 else {
1923 mode = ETHER_LOOPBACK_OFF;
1924 WRITECSR(sc, R_CSR_SIAMODE1, 0xFFFF);
1925 WRITECSR(sc, R_CSR_SIAMODE2, 0x0000);
1928 WRITECSR(sc, R_CSR_SIAMODE0, 0x8F00 | M_CSR13_CONN_NOT_RESET );
1930 sc->loopback = mode;
1933 static void
1934 dc21040_hwinit(tulip_softc *sc, uint8_t srom[])
1936 uint32_t v;
1938 sc->phy_type = SRL;
1940 /* CSR0 - bus mode */
1941 v = V_CSR0_SKIPLEN(0) |
1942 V_CSR0_CACHEALIGN(K_CSR0_ALIGN32) |
1943 V_CSR0_BURSTLEN(K_CSR0_BURST32);
1944 #ifdef __MIPSEB
1945 v |= M_CSR0_BIGENDIAN; /* big-endian data serialization */
1946 #endif
1947 WRITECSR(sc, R_CSR_BUSMODE, v);
1949 WRITECSR(sc, R_CSR_INTMASK, 0);
1951 dc21040_set_speed(sc, sc->linkspeed);
1955 static void
1956 tulip_hwinit(tulip_softc *sc)
1958 if (sc->state == eth_state_uninit) {
1959 uint8_t srom[SROM_SIZE];
1961 /* Wake-on-LAN apparently powers up with PORTSEL = 1 */
1962 WRITECSR(sc, R_CSR_OPMODE,
1963 READCSR(sc, R_CSR_OPMODE) &~ M_CSR6_PORTSEL);
1965 RESET_ADAPTER(sc);
1966 sc->state = eth_state_off;
1967 sc->bus_errors = 0;
1969 rom_read_all(sc, srom);
1970 rom_dump(srom);
1972 switch (sc->device) {
1973 case K_PCI_ID_DC21040:
1974 dc21040_hwinit(sc, srom);
1975 break;
1976 case K_PCI_ID_DC21041:
1977 dc21041_hwinit(sc, srom);
1978 break;
1979 case K_PCI_ID_DC21140:
1980 dc21140_hwinit(sc, srom);
1981 break;
1982 case K_PCI_ID_DC21143:
1983 dc21143_hwinit(sc, srom);
1984 break;
1985 default:
1986 break;
1991 static void
1992 tulip_setaddr(tulip_softc *sc)
1994 int idx;
1995 tulip_cam *cam;
1996 eth_pkt_t *pkt;
1998 pkt = eth_alloc_pkt(sc);
1999 if (pkt) {
2000 pkt->length = CAM_SETUP_BUFFER_SIZE;
2001 cam = (tulip_cam *) pkt->buffer;
2003 #ifdef __MIPSEB
2004 cam->p.physical[0][0] = (((uint32_t) sc->hwaddr[0] << 8) |
2005 (uint32_t) sc->hwaddr[1]) << 16;
2006 cam->p.physical[0][1] = (((uint32_t) sc->hwaddr[2] << 8) |
2007 (uint32_t) sc->hwaddr[3]) << 16;
2008 cam->p.physical[0][2] = (((uint32_t) sc->hwaddr[4] << 8) |
2009 (uint32_t) sc->hwaddr[5]) << 16;
2010 for (idx = 1; idx < CAM_PERFECT_ENTRIES; idx++) {
2011 cam->p.physical[idx][0] = 0xFFFF0000;
2012 cam->p.physical[idx][1] = 0xFFFF0000;
2013 cam->p.physical[idx][2] = 0xFFFF0000;
2015 #else
2016 cam->p.physical[0][0] = ((uint32_t) sc->hwaddr[0]) |
2017 (((uint32_t) sc->hwaddr[1]) << 8);
2018 cam->p.physical[0][1] = ((uint32_t) sc->hwaddr[2]) |
2019 (((uint32_t) sc->hwaddr[3]) << 8);
2020 cam->p.physical[0][2] = ((uint32_t) sc->hwaddr[4]) |
2021 (((uint32_t) sc->hwaddr[5]) << 8);
2022 for (idx = 1; idx < CAM_PERFECT_ENTRIES; idx++) {
2023 cam->p.physical[idx][0] = 0x0000FFFF;
2024 cam->p.physical[idx][1] = 0x0000FFFF;
2025 cam->p.physical[idx][2] = 0x0000FFFF;
2027 #endif
2029 pkt->flags |= ETH_TX_SETUP;
2030 sc->state = eth_state_setup;
2031 if (tulip_transmit(sc, pkt) != 0) {
2032 xprintf("%s: failed setup\n", tulip_devname(sc));
2033 dumpstat(sc);
2034 eth_free_pkt(sc, pkt);
2039 static void
2040 tulip_setspeed(tulip_softc *sc, int speed)
2042 switch (sc->device) {
2043 case K_PCI_ID_DC21040:
2044 dc21040_set_speed(sc, speed);
2045 break;
2046 case K_PCI_ID_DC21041:
2047 dc21041_set_speed(sc, speed);
2048 break;
2049 case K_PCI_ID_DC21140:
2050 dc21140_set_speed(sc, speed, 0);
2051 break;
2052 case K_PCI_ID_DC21143:
2053 dc21143_set_speed(sc, speed);
2054 break;
2055 default:
2056 break;
2060 static void
2061 tulip_setloopback(tulip_softc *sc, int mode)
2063 switch (sc->device) {
2064 case K_PCI_ID_DC21040:
2065 dc21040_set_loopback(sc, mode);
2066 break;
2067 case K_PCI_ID_DC21041:
2068 dc21041_set_loopback(sc, mode);
2069 break;
2070 case K_PCI_ID_DC21140:
2071 dc21140_set_loopback(sc, mode);
2072 break;
2073 case K_PCI_ID_DC21143:
2074 dc21143_set_loopback(sc, mode);
2075 break;
2076 default:
2077 break;
2079 cfe_sleep(CFE_HZ/10);
2083 static void
2084 tulip_isr(void *arg)
2086 uint32_t status;
2087 uint32_t csr5;
2088 tulip_softc *sc = (tulip_softc *)arg;
2090 #if IPOLL
2091 sc->interrupts++;
2092 #endif
2094 for (;;) {
2096 /* Read the interrupt status. */
2097 csr5 = READCSR(sc, R_CSR_STATUS);
2098 status = csr5 & (
2099 M_CSR5_RXINT | M_CSR5_RXBUFUNAVAIL |
2100 M_CSR5_TXINT | M_CSR5_TXUNDERFLOW |
2101 M_CSR5_FATALBUSERROR);
2103 /* if there are no more interrupts, leave now. */
2104 if (status == 0) break;
2106 /* Clear the pending interrupt. */
2107 WRITECSR(sc, R_CSR_STATUS, status);
2109 /* Now, test each unmasked bit in the interrupt register and
2110 handle each interrupt type appropriately. */
2112 if (status & M_CSR5_FATALBUSERROR) {
2113 WRITECSR(sc, R_CSR_INTMASK, 0);
2115 xprintf("%s: bus error %02x\n",
2116 tulip_devname(sc), G_CSR5_ERRORBITS(csr5));
2117 dumpstat(sc);
2118 sc->bus_errors++;
2119 if (sc->bus_errors >= 2) {
2120 dumpcsrs(sc);
2121 RESET_ADAPTER(sc);
2122 sc->state = eth_state_off;
2123 sc->bus_errors = 0;
2125 #if IPOLL
2126 else
2127 WRITECSR(sc, R_CSR_INTMASK, sc->intmask);
2128 #endif
2131 if (status & M_CSR5_RXINT) {
2132 #if IPOLL
2133 sc->rx_interrupts++;
2134 #endif
2135 tulip_procrxring(sc);
2138 if (status & M_CSR5_TXINT) {
2139 #if IPOLL
2140 sc->tx_interrupts++;
2141 #endif
2142 tulip_proctxring(sc);
2145 if (status & (M_CSR5_TXUNDERFLOW | M_CSR5_RXBUFUNAVAIL)) {
2146 if (status & M_CSR5_TXUNDERFLOW) {
2147 xprintf("%s: tx underrun, %08x\n", tulip_devname(sc), csr5);
2148 /* Try to restart */
2149 WRITECSR(sc, R_CSR_TXPOLL, 1);
2151 if (status & M_CSR5_RXBUFUNAVAIL) {
2152 /* Try to restart */
2153 WRITECSR(sc, R_CSR_RXPOLL, 1);
2160 static void
2161 tulip_start(tulip_softc *sc)
2163 uint32_t opmode;
2165 tulip_hwinit(sc);
2167 WRITECSR(sc, R_CSR_RXRING, PTR_TO_PCI(sc->rxdscr_start));
2168 WRITECSR(sc, R_CSR_TXRING, PTR_TO_PCI(sc->txdscr_start));
2170 opmode = READCSR(sc, R_CSR_OPMODE);
2171 opmode &=~ M_CSR6_OPMODE; /* no loopback */
2172 if (sc->loopback != ETHER_LOOPBACK_OFF) {
2173 opmode &=~ M_CSR6_FULLDUPLEX;
2174 opmode |= M_CSR6_PORTSEL;
2175 if (sc->loopback == ETHER_LOOPBACK_EXT)
2176 opmode |= M_CSR6_EXTLOOPBACK;
2177 else
2178 opmode |= M_CSR6_INTLOOPBACK;
2181 sc->intmask = 0;
2182 WRITECSR(sc, R_CSR_INTMASK, 0); /* no interrupts */
2183 WRITECSR(sc, R_CSR_STATUS, 0x1FFFF); /* clear any pending */
2184 READCSR(sc, R_CSR_STATUS); /* push the write */
2186 sc->interrupts = 0;
2187 sc->rx_interrupts = sc->tx_interrupts = 0;
2189 #if IPOLL
2190 cfe_request_irq(sc->irq, tulip_isr, sc, CFE_IRQ_FLAGS_SHARED, 0);
2192 sc->intmask = M_CSR7_RXINT | M_CSR7_TXINT |
2193 M_CSR7_NORMALINT;
2194 sc->intmask |= M_CSR7_FATALBUSERROR | M_CSR7_TXUNDERFLOW |
2195 M_CSR7_ABNORMALINT;
2196 WRITECSR(sc, R_CSR_INTMASK, sc->intmask);
2197 #endif
2199 if (sc->loopback == ETHER_LOOPBACK_OFF) {
2200 opmode |= M_CSR6_TXSTART;
2201 WRITECSR(sc, R_CSR_OPMODE, opmode);
2202 tulip_setaddr(sc);
2204 else {
2205 opmode |= M_CSR6_TXSTART | M_CSR6_RXSTART;
2206 WRITECSR(sc, R_CSR_OPMODE, opmode);
2210 static void
2211 tulip_stop(tulip_softc *sc)
2213 uint32_t opmode;
2214 uint32_t status;
2215 int count;
2217 WRITECSR(sc, R_CSR_INTMASK, 0);
2218 sc->intmask = 0;
2219 #if IPOLL
2220 cfe_free_irq(sc->irq, 0);
2221 #endif
2222 WRITECSR(sc, R_CSR_STATUS, 0x1FFFF);
2223 opmode = READCSR(sc, R_CSR_OPMODE);
2224 opmode &=~ (M_CSR6_TXSTART | M_CSR6_RXSTART);
2225 WRITECSR(sc, R_CSR_OPMODE, opmode);
2227 /* wait for any DMA activity to terminate */
2228 for (count = 0; count <= 13; count++) {
2229 status = READCSR(sc, R_CSR_STATUS);
2230 if ((status & (M_CSR5_RXPROCSTATE | M_CSR5_TXPROCSTATE)) == 0)
2231 break;
2232 cfe_sleep(CFE_HZ/10);
2234 if (count > 13) {
2235 xprintf("%s: idle state not achieved\n", tulip_devname(sc));
2236 dumpstat(sc);
2237 RESET_ADAPTER(sc);
2238 sc->state = eth_state_uninit;
2239 sc->linkspeed = ETHER_SPEED_AUTO;
2241 else if (sc->loopback != ETHER_LOOPBACK_OFF) {
2242 tulip_setloopback(sc, ETHER_LOOPBACK_OFF);
2243 opmode &=~ M_CSR6_OPMODE;
2244 WRITECSR(sc, R_CSR_OPMODE, opmode);
2247 if (sc->outpkts > 1) {
2248 /* heuristic: suppress stats for initial mode changes */
2249 xprintf("%s: %d sent, %d received, %d interrupts\n",
2250 tulip_devname(sc), sc->outpkts, sc->inpkts, sc->interrupts);
2251 xprintf(" %d rx interrupts, %d tx interrupts\n",
2252 sc->rx_interrupts, sc->tx_interrupts);
2257 /* *********************************************************************
2258 * ETH_PARSE_XDIGIT(c)
2260 * Parse a hex digit, returning its value
2262 * Input parameters:
2263 * c - character
2265 * Return value:
2266 * hex value, or -1 if invalid
2267 ********************************************************************* */
2268 static int
2269 eth_parse_xdigit(char c)
2271 int digit;
2273 if ((c >= '0') && (c <= '9')) digit = c - '0';
2274 else if ((c >= 'a') && (c <= 'f')) digit = c - 'a' + 10;
2275 else if ((c >= 'A') && (c <= 'F')) digit = c - 'A' + 10;
2276 else digit = -1;
2278 return digit;
2281 /* *********************************************************************
2282 * ETH_PARSE_HWADDR(str,hwaddr)
2284 * Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte
2285 * Ethernet address.
2287 * Input parameters:
2288 * str - string
2289 * hwaddr - pointer to hardware address
2291 * Return value:
2292 * 0 if ok, else -1
2293 ********************************************************************* */
2294 static int
2295 eth_parse_hwaddr(char *str, uint8_t *hwaddr)
2297 int digit1, digit2;
2298 int idx = ENET_ADDR_LEN;
2300 while (*str && (idx > 0)) {
2301 digit1 = eth_parse_xdigit(*str);
2302 if (digit1 < 0) return -1;
2303 str++;
2304 if (!*str) return -1;
2306 if ((*str == ':') || (*str == '-')) {
2307 digit2 = digit1;
2308 digit1 = 0;
2310 else {
2311 digit2 = eth_parse_xdigit(*str);
2312 if (digit2 < 0) return -1;
2313 str++;
2316 *hwaddr++ = (digit1 << 4) | digit2;
2317 idx--;
2319 if ((*str == ':') || (*str == '-'))
2320 str++;
2322 return 0;
2325 /* *********************************************************************
2326 * ETH_INCR_HWADDR(hwaddr,incr)
2328 * Increment a 6-byte Ethernet hardware address, with carries
2330 * Input parameters:
2331 * hwaddr - pointer to hardware address
2332 * incr - desired increment
2334 * Return value:
2335 * none
2336 ********************************************************************* */
2337 static void
2338 eth_incr_hwaddr(uint8_t *hwaddr, unsigned incr)
2340 int idx;
2341 int carry;
2343 idx = 5;
2344 carry = incr;
2345 while (idx >= 0 && carry != 0) {
2346 unsigned sum = hwaddr[idx] + carry;
2348 hwaddr[idx] = sum & 0xFF;
2349 carry = sum >> 8;
2350 idx--;
2355 /* *********************************************************************
2356 * Declarations for CFE Device Driver Interface routines
2357 ********************************************************************* */
2359 static int tulip_ether_open(cfe_devctx_t *ctx);
2360 static int tulip_ether_read(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
2361 static int tulip_ether_inpstat(cfe_devctx_t *ctx,iocb_inpstat_t *inpstat);
2362 static int tulip_ether_write(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
2363 static int tulip_ether_ioctl(cfe_devctx_t *ctx,iocb_buffer_t *buffer);
2364 static int tulip_ether_close(cfe_devctx_t *ctx);
2366 /* *********************************************************************
2367 * CFE Device Driver dispatch structure
2368 ********************************************************************* */
2370 const static cfe_devdisp_t tulip_ether_dispatch = {
2371 tulip_ether_open,
2372 tulip_ether_read,
2373 tulip_ether_inpstat,
2374 tulip_ether_write,
2375 tulip_ether_ioctl,
2376 tulip_ether_close,
2377 NULL, /* tulip_ether_poll */
2378 NULL /* tulip_ether_reset */
2381 /* *********************************************************************
2382 * CFE Device Driver descriptor
2383 ********************************************************************* */
2385 const cfe_driver_t dc21143drv = {
2386 "DC21x4x Ethernet",
2387 "eth",
2388 CFE_DEV_NETWORK,
2389 &tulip_ether_dispatch,
2390 tulip_ether_probe
2394 static int
2395 tulip_ether_attach(cfe_driver_t *drv,
2396 pcitag_t tag, int index, uint8_t hwaddr[])
2398 tulip_softc *sc;
2399 uint32_t device;
2400 uint32_t class;
2401 uint32_t reg;
2402 phys_addr_t pa;
2403 const char *devname;
2404 char descr[100];
2405 uint8_t romaddr[ENET_ADDR_LEN];
2407 device = pci_conf_read(tag, R_CFG_CFID);
2408 class = pci_conf_read(tag, R_CFG_CFRV);
2410 reg = pci_conf_read(tag, R_CFG_CPMS);
2412 reg = pci_conf_read(tag, R_CFG_CFDD);
2413 pci_conf_write(tag, R_CFG_CFDD, 0);
2414 reg = pci_conf_read(tag, R_CFG_CFDD);
2416 /* Use memory space for the CSRs */
2417 pci_map_mem(tag, R_CFG_CBMA, PCI_MATCH_BITS, &pa);
2419 sc = (tulip_softc *) KMALLOC(sizeof(tulip_softc), 0);
2420 if (sc == NULL) {
2421 xprintf("DC21x4x: No memory to complete probe\n");
2422 return 0;
2424 memset(sc, 0, sizeof(*sc));
2426 sc->membase = (uint32_t)pa;
2427 sc->irq = pci_conf_read(tag, R_CFG_CFIT) & 0xFF;
2429 sc->tag = tag;
2430 sc->device = PCI_PRODUCT(device);
2431 sc->revision = PCI_REVISION(class);
2432 sc->devctx = NULL;
2434 sc->linkspeed = ETHER_SPEED_AUTO; /* select autonegotiation */
2435 sc->loopback = ETHER_LOOPBACK_OFF;
2436 memcpy(sc->hwaddr, hwaddr, ENET_ADDR_LEN);
2438 tulip_init(sc);
2440 /* Prefer address in srom */
2441 if (rom_read_addr(sc, romaddr) == 0) {
2442 memcpy(sc->hwaddr, romaddr, ENET_ADDR_LEN);
2445 sc->state = eth_state_uninit;
2447 switch (sc->device) {
2448 case K_PCI_ID_DC21040:
2449 devname = "DC21040"; break;
2450 case K_PCI_ID_DC21041:
2451 devname = "DC21041"; break;
2452 case K_PCI_ID_DC21140:
2453 devname = "DC21140"; break;
2454 case K_PCI_ID_DC21143:
2455 devname = "DC21143"; break;
2456 default:
2457 devname = "DC21x4x"; break;
2460 xsprintf(descr, "%s Ethernet at 0x%X (%02X-%02X-%02X-%02X-%02X-%02X)",
2461 devname, sc->membase,
2462 sc->hwaddr[0], sc->hwaddr[1], sc->hwaddr[2],
2463 sc->hwaddr[3], sc->hwaddr[4], sc->hwaddr[5]);
2465 cfe_attach(drv, sc, NULL, descr);
2466 return 1;
2470 /* *********************************************************************
2471 * TULIP_ETHER_PROBE(drv,probe_a,probe_b,probe_ptr)
2473 * Probe and install drivers for all DC21x4x Ethernet controllers.
2474 * For each, create a context structure and attach to the
2475 * specified network device.
2477 * Input parameters:
2478 * drv - driver descriptor
2479 * probe_a - not used
2480 * probe_b - not used
2481 * probe_ptr - string pointer to hardware address for the first
2482 * MAC, in the form xx:xx:xx:xx:xx:xx
2484 * Return value:
2485 * nothing
2486 ********************************************************************* */
2487 static void
2488 tulip_ether_probe(cfe_driver_t *drv,
2489 unsigned long probe_a, unsigned long probe_b,
2490 void *probe_ptr)
2492 int index;
2493 int n;
2494 uint8_t hwaddr[ENET_ADDR_LEN];
2496 if (probe_ptr)
2497 eth_parse_hwaddr((char *) probe_ptr, hwaddr);
2498 else {
2499 /* use default address 40-00-00-10-11-11 */
2500 hwaddr[0] = 0x40; hwaddr[1] = 0x00; hwaddr[2] = 0x00;
2501 hwaddr[3] = 0x10; hwaddr[4] = 0x11; hwaddr[5] = 0x11;
2504 n = 0;
2505 index = 0;
2506 for (;;) {
2507 pcitag_t tag;
2508 pcireg_t device;
2510 if (pci_find_class(PCI_CLASS_NETWORK, index, &tag) != 0)
2511 break;
2513 index++;
2515 device = pci_conf_read(tag, R_CFG_CFID);
2516 if (PCI_VENDOR(device) == K_PCI_VENDOR_DEC) {
2517 if (PCI_PRODUCT(device) == K_PCI_ID_DC21040 ||
2518 PCI_PRODUCT(device) == K_PCI_ID_DC21041 ||
2519 PCI_PRODUCT(device) == K_PCI_ID_DC21140 ||
2520 PCI_PRODUCT(device) == K_PCI_ID_DC21143) {
2522 tulip_ether_attach(drv, tag, n, hwaddr);
2523 n++;
2524 eth_incr_hwaddr(hwaddr, 1);
2531 /* The functions below are called via the dispatch vector for the 21x4x. */
2533 /* *********************************************************************
2534 * TULIP_ETHER_OPEN(ctx)
2536 * Open the Ethernet device. The MAC is reset, initialized, and
2537 * prepared to receive and send packets.
2539 * Input parameters:
2540 * ctx - device context (includes ptr to our softc)
2542 * Return value:
2543 * status, 0 = ok
2544 ********************************************************************* */
2545 static int
2546 tulip_ether_open(cfe_devctx_t *ctx)
2548 tulip_softc *sc = ctx->dev_softc;
2550 if (sc->state == eth_state_on)
2551 tulip_stop(sc);
2553 sc->devctx = ctx;
2554 tulip_start(sc);
2556 #if XPOLL
2557 tulip_isr(sc);
2558 #endif
2560 return 0;
2563 /* *********************************************************************
2564 * TULIP_ETHER_READ(ctx,buffer)
2566 * Read a packet from the Ethernet device. If no packets are
2567 * available, the read will succeed but return 0 bytes.
2569 * Input parameters:
2570 * ctx - device context (includes ptr to our softc)
2571 * buffer - pointer to buffer descriptor.
2573 * Return value:
2574 * status, 0 = ok
2575 ********************************************************************* */
2576 static int
2577 tulip_ether_read(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
2579 tulip_softc *sc = ctx->dev_softc;
2580 eth_pkt_t *pkt;
2581 int blen;
2583 #if XPOLL
2584 tulip_isr(sc);
2585 #endif
2587 if (sc->state != eth_state_on) return -1;
2589 CS_ENTER(sc);
2590 pkt = (eth_pkt_t *) q_deqnext(&(sc->rxqueue));
2591 CS_EXIT(sc);
2593 if (pkt == NULL) {
2594 buffer->buf_retlen = 0;
2595 return 0;
2598 blen = buffer->buf_length;
2599 if (blen > pkt->length) blen = pkt->length;
2601 blockcopy(buffer->buf_ptr, pkt->buffer, blen);
2602 buffer->buf_retlen = blen;
2604 eth_free_pkt(sc, pkt);
2605 tulip_fillrxring(sc);
2607 #if XPOLL
2608 tulip_isr(sc);
2609 #endif
2611 return 0;
2614 /* *********************************************************************
2615 * TULIP_ETHER_INPSTAT(ctx,inpstat)
2617 * Check for received packets on the Ethernet device
2619 * Input parameters:
2620 * ctx - device context (includes ptr to our softc)
2621 * inpstat - pointer to input status structure
2623 * Return value:
2624 * status, 0 = ok
2625 ********************************************************************* */
2626 static int
2627 tulip_ether_inpstat(cfe_devctx_t *ctx, iocb_inpstat_t *inpstat)
2629 tulip_softc *sc = ctx->dev_softc;
2631 #if XPOLL
2632 tulip_isr(sc);
2633 #endif
2635 if (sc->state != eth_state_on) return -1;
2637 /* We avoid an interlock here because the result is a hint and an
2638 interrupt cannot turn a non-empty queue into an empty one. */
2639 inpstat->inp_status = (q_isempty(&(sc->rxqueue))) ? 0 : 1;
2641 return 0;
2644 /* *********************************************************************
2645 * TULIP_ETHER_WRITE(ctx,buffer)
2647 * Write a packet to the Ethernet device.
2649 * Input parameters:
2650 * ctx - device context (includes ptr to our softc)
2651 * buffer - pointer to buffer descriptor.
2653 * Return value:
2654 * status, 0 = ok
2655 ********************************************************************* */
2656 static int
2657 tulip_ether_write(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
2659 tulip_softc *sc = ctx->dev_softc;
2660 eth_pkt_t *pkt;
2661 int blen;
2663 #if XPOLL
2664 tulip_isr(sc);
2665 #endif
2667 if (sc->state != eth_state_on) return -1;
2669 pkt = eth_alloc_pkt(sc);
2670 if (!pkt) return CFE_ERR_NOMEM;
2672 blen = buffer->buf_length;
2673 if (blen > pkt->length) blen = pkt->length;
2675 blockcopy(pkt->buffer, buffer->buf_ptr, blen);
2676 pkt->length = blen;
2678 if (tulip_transmit(sc, pkt) != 0) {
2679 eth_free_pkt(sc,pkt);
2680 return CFE_ERR_IOERR;
2683 #if XPOLL
2684 tulip_isr(sc);
2685 #endif
2687 return 0;
2690 /* *********************************************************************
2691 * TULIP_ETHER_IOCTL(ctx,buffer)
2693 * Do device-specific I/O control operations for the device
2695 * Input parameters:
2696 * ctx - device context (includes ptr to our softc)
2697 * buffer - pointer to buffer descriptor.
2699 * Return value:
2700 * status, 0 = ok
2701 ********************************************************************* */
2702 static int
2703 tulip_ether_ioctl(cfe_devctx_t *ctx, iocb_buffer_t *buffer)
2705 tulip_softc *sc = ctx->dev_softc;
2706 int *argp;
2707 int mode;
2708 int speed;
2710 switch ((int)buffer->buf_ioctlcmd) {
2711 case IOCTL_ETHER_GETHWADDR:
2712 memcpy(buffer->buf_ptr, sc->hwaddr, sizeof(sc->hwaddr));
2713 return 0;
2715 case IOCTL_ETHER_SETHWADDR:
2716 return -1; /* not supported */
2718 case IOCTL_ETHER_GETSPEED:
2719 argp = (int *) buffer->buf_ptr;
2720 *argp = sc->linkspeed;
2721 return 0;
2723 case IOCTL_ETHER_SETSPEED:
2724 tulip_stop(sc);
2725 tulip_resetrings(sc);
2726 speed = *((int *) buffer->buf_ptr);
2727 tulip_setspeed(sc, speed);
2728 tulip_start(sc);
2729 sc->state = eth_state_on;
2730 return 0;
2732 case IOCTL_ETHER_GETLINK:
2733 argp = (int *) buffer->buf_ptr;
2734 *argp = sc->linkspeed;
2735 return 0;
2737 case IOCTL_ETHER_GETLOOPBACK:
2738 *((int *) buffer) = sc->loopback;
2739 return 0;
2741 case IOCTL_ETHER_SETLOOPBACK:
2742 tulip_stop(sc);
2743 tulip_resetrings(sc);
2744 mode = *((int *) buffer->buf_ptr);
2745 sc->loopback = ETHER_LOOPBACK_OFF; /* default */
2746 if (mode == ETHER_LOOPBACK_INT || mode == ETHER_LOOPBACK_EXT) {
2747 tulip_setloopback(sc, mode);
2749 tulip_start(sc);
2750 sc->state = eth_state_on;
2751 return 0;
2753 default:
2754 return -1;
2758 /* *********************************************************************
2759 * TULIP_ETHER_CLOSE(ctx)
2761 * Close the Ethernet device.
2763 * Input parameters:
2764 * ctx - device context (includes ptr to our softc)
2766 * Return value:
2767 * status, 0 = ok
2768 ********************************************************************* */
2769 static int
2770 tulip_ether_close(cfe_devctx_t *ctx)
2772 tulip_softc *sc = ctx->dev_softc;
2774 sc->state = eth_state_off;
2775 tulip_stop(sc);
2777 /* resynchronize descriptor rings */
2778 tulip_resetrings(sc);
2780 sc->devctx = NULL;
2781 return 0;