Merge branch 'master' of git://github.com/illumos/illumos-gate
[unleashed.git] / usr / src / grub / grub-0.97 / netboot / sundance.c
blob04ace8b804ec5d0e2d7b2ea3a82f62757b9fe13c
1 /**************************************************************************
3 * sundance.c -- Etherboot device driver for the Sundance ST201 "Alta".
4 * Written 2002-2002 by Timothy Legge <tlegge@rogers.com>
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 * Portions of this code based on:
21 * sundance.c: A Linux device driver for the Sundance ST201 "Alta"
22 * Written 1999-2002 by Donald Becker
24 * tulip.c: Tulip and Clone Etherboot Driver
25 * By Marty Conner
26 * Copyright (C) 2001 Entity Cyber, Inc.
28 * Linux Driver Version LK1.09a, 10-Jul-2003 (2.4.25)
30 * REVISION HISTORY:
31 * ================
32 * v1.1 01-01-2003 timlegge Initial implementation
33 * v1.7 04-10-2003 timlegge Transfers Linux Kernel (30 sec)
34 * v1.8 04-13-2003 timlegge Fix multiple transmission bug
35 * v1.9 08-19-2003 timlegge Support Multicast
36 * v1.10 01-17-2004 timlegge Initial driver output cleanup
37 * v1.11 03-21-2004 timlegge Remove unused variables
38 * v1.12 03-21-2004 timlegge Remove excess MII defines
39 * v1.13 03-24-2004 timlegge Update to Linux 2.4.25 driver
41 ****************************************************************************/
43 /* to get some global routines like printf */
44 #include "etherboot.h"
45 /* to get the interface to the body of the program */
46 #include "nic.h"
47 /* to get the PCI support functions, if this is a PCI NIC */
48 #include "pci.h"
49 #include "timer.h"
50 #include "mii.h"
52 #define drv_version "v1.12"
53 #define drv_date "2004-03-21"
55 typedef unsigned char u8;
56 typedef signed char s8;
57 typedef unsigned short u16;
58 typedef signed short s16;
59 typedef unsigned int u32;
60 typedef signed int s32;
62 #define HZ 100
64 /* Condensed operations for readability. */
65 #define virt_to_le32desc(addr) cpu_to_le32(virt_to_bus(addr))
66 #define le32desc_to_virt(addr) bus_to_virt(le32_to_cpu(addr))
68 /* May need to be moved to mii.h */
69 struct mii_if_info {
70 int phy_id;
71 int advertising;
72 unsigned int full_duplex:1; /* is full duplex? */
75 //#define EDEBUG
76 #ifdef EDEBUG
77 #define dprintf(x) printf x
78 #else
79 #define dprintf(x)
80 #endif
82 #if defined(__sun)
83 /* Hack: use grub_strcmp since strcasecmp is undefined */
84 #define strcasecmp grub_strcmp
85 #endif
88 /* Set the mtu */
89 static int mtu = 1514;
91 /* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
92 The sundance uses a 64 element hash table based on the Ethernet CRC. */
93 // static int multicast_filter_limit = 32;
95 /* Set the copy breakpoint for the copy-only-tiny-frames scheme.
96 Setting to > 1518 effectively disables this feature.
97 This chip can receive into any byte alignment buffers, so word-oriented
98 archs do not need a copy-align of the IP header. */
99 static int rx_copybreak = 0;
100 static int flowctrl = 1;
102 /* Allow forcing the media type */
103 /* media[] specifies the media type the NIC operates at.
104 autosense Autosensing active media.
105 10mbps_hd 10Mbps half duplex.
106 10mbps_fd 10Mbps full duplex.
107 100mbps_hd 100Mbps half duplex.
108 100mbps_fd 100Mbps full duplex.
110 static char media[] = "autosense";
112 /* Operational parameters that are set at compile time. */
114 /* As Etherboot uses a Polling driver we can keep the number of rings
115 to the minimum number required. In general that is 1 transmit and 4 receive receive rings. However some cards require that
116 there be a minimum of 2 rings */
117 #define TX_RING_SIZE 2
118 #define TX_QUEUE_LEN 10 /* Limit ring entries actually used. */
119 #define RX_RING_SIZE 4
122 /* Operational parameters that usually are not changed. */
123 /* Time in jiffies before concluding the transmitter is hung. */
124 #define TX_TIME_OUT (4*HZ)
125 #define PKT_BUF_SZ 1536
127 /* Offsets to the device registers.
128 Unlike software-only systems, device drivers interact with complex hardware.
129 It's not useful to define symbolic names for every register bit in the
130 device. The name can only partially document the semantics and make
131 the driver longer and more difficult to read.
132 In general, only the important configuration values or bits changed
133 multiple times should be defined symbolically.
135 enum alta_offsets {
136 DMACtrl = 0x00,
137 TxListPtr = 0x04,
138 TxDMABurstThresh = 0x08,
139 TxDMAUrgentThresh = 0x09,
140 TxDMAPollPeriod = 0x0a,
141 RxDMAStatus = 0x0c,
142 RxListPtr = 0x10,
143 DebugCtrl0 = 0x1a,
144 DebugCtrl1 = 0x1c,
145 RxDMABurstThresh = 0x14,
146 RxDMAUrgentThresh = 0x15,
147 RxDMAPollPeriod = 0x16,
148 LEDCtrl = 0x1a,
149 ASICCtrl = 0x30,
150 EEData = 0x34,
151 EECtrl = 0x36,
152 TxStartThresh = 0x3c,
153 RxEarlyThresh = 0x3e,
154 FlashAddr = 0x40,
155 FlashData = 0x44,
156 TxStatus = 0x46,
157 TxFrameId = 0x47,
158 DownCounter = 0x18,
159 IntrClear = 0x4a,
160 IntrEnable = 0x4c,
161 IntrStatus = 0x4e,
162 MACCtrl0 = 0x50,
163 MACCtrl1 = 0x52,
164 StationAddr = 0x54,
165 MaxFrameSize = 0x5A,
166 RxMode = 0x5c,
167 MIICtrl = 0x5e,
168 MulticastFilter0 = 0x60,
169 MulticastFilter1 = 0x64,
170 RxOctetsLow = 0x68,
171 RxOctetsHigh = 0x6a,
172 TxOctetsLow = 0x6c,
173 TxOctetsHigh = 0x6e,
174 TxFramesOK = 0x70,
175 RxFramesOK = 0x72,
176 StatsCarrierError = 0x74,
177 StatsLateColl = 0x75,
178 StatsMultiColl = 0x76,
179 StatsOneColl = 0x77,
180 StatsTxDefer = 0x78,
181 RxMissed = 0x79,
182 StatsTxXSDefer = 0x7a,
183 StatsTxAbort = 0x7b,
184 StatsBcastTx = 0x7c,
185 StatsBcastRx = 0x7d,
186 StatsMcastTx = 0x7e,
187 StatsMcastRx = 0x7f,
188 /* Aliased and bogus values! */
189 RxStatus = 0x0c,
191 enum ASICCtrl_HiWord_bit {
192 GlobalReset = 0x0001,
193 RxReset = 0x0002,
194 TxReset = 0x0004,
195 DMAReset = 0x0008,
196 FIFOReset = 0x0010,
197 NetworkReset = 0x0020,
198 HostReset = 0x0040,
199 ResetBusy = 0x0400,
202 /* Bits in the interrupt status/mask registers. */
203 enum intr_status_bits {
204 IntrSummary = 0x0001, IntrPCIErr = 0x0002, IntrMACCtrl = 0x0008,
205 IntrTxDone = 0x0004, IntrRxDone = 0x0010, IntrRxStart = 0x0020,
206 IntrDrvRqst = 0x0040,
207 StatsMax = 0x0080, LinkChange = 0x0100,
208 IntrTxDMADone = 0x0200, IntrRxDMADone = 0x0400,
211 /* Bits in the RxMode register. */
212 enum rx_mode_bits {
213 AcceptAllIPMulti = 0x20, AcceptMultiHash = 0x10, AcceptAll = 0x08,
214 AcceptBroadcast = 0x04, AcceptMulticast = 0x02, AcceptMyPhys =
215 0x01,
217 /* Bits in MACCtrl. */
218 enum mac_ctrl0_bits {
219 EnbFullDuplex = 0x20, EnbRcvLargeFrame = 0x40,
220 EnbFlowCtrl = 0x100, EnbPassRxCRC = 0x200,
222 enum mac_ctrl1_bits {
223 StatsEnable = 0x0020, StatsDisable = 0x0040, StatsEnabled = 0x0080,
224 TxEnable = 0x0100, TxDisable = 0x0200, TxEnabled = 0x0400,
225 RxEnable = 0x0800, RxDisable = 0x1000, RxEnabled = 0x2000,
228 /* The Rx and Tx buffer descriptors.
229 Using only 32 bit fields simplifies software endian correction.
230 This structure must be aligned, and should avoid spanning cache lines.
232 struct netdev_desc {
233 u32 next_desc;
234 u32 status;
235 u32 addr;
236 u32 length;
239 /* Bits in netdev_desc.status */
240 enum desc_status_bits {
241 DescOwn = 0x8000,
242 DescEndPacket = 0x4000,
243 DescEndRing = 0x2000,
244 LastFrag = 0x80000000,
245 DescIntrOnTx = 0x8000,
246 DescIntrOnDMADone = 0x80000000,
247 DisableAlign = 0x00000001,
250 /**********************************************
251 * Descriptor Ring and Buffer defination
252 ***********************************************/
253 /* Define the TX Descriptor */
254 static struct netdev_desc tx_ring[TX_RING_SIZE];
256 /* Create a static buffer of size PKT_BUF_SZ for each TX Descriptor.
257 All descriptors point to a part of this buffer */
258 static unsigned char txb[PKT_BUF_SZ * TX_RING_SIZE];
260 /* Define the RX Descriptor */
261 static struct netdev_desc rx_ring[RX_RING_SIZE];
263 /* Create a static buffer of size PKT_BUF_SZ for each RX Descriptor.
264 All descriptors point to a part of this buffer */
265 static unsigned char rxb[RX_RING_SIZE * PKT_BUF_SZ];
267 /* FIXME: Move BASE to the private structure */
268 static u32 BASE;
269 #define EEPROM_SIZE 128
271 enum pci_id_flags_bits {
272 PCI_USES_IO = 1, PCI_USES_MEM = 2, PCI_USES_MASTER = 4,
273 PCI_ADDR0 = 0 << 4, PCI_ADDR1 = 1 << 4, PCI_ADDR2 =
274 2 << 4, PCI_ADDR3 = 3 << 4,
277 enum chip_capability_flags { CanHaveMII = 1, KendinPktDropBug = 2, };
278 #define PCI_IOTYPE (PCI_USES_MASTER | PCI_USES_IO | PCI_ADDR0)
280 #define MII_CNT 4
281 struct sundance_private {
282 const char *nic_name;
283 /* Frequently used values */
285 unsigned int cur_rx; /* Producer/consumer ring indicies */
286 unsigned int mtu;
288 /* These values keep track of the tranceiver/media in use */
289 unsigned int flowctrl:1;
290 unsigned int an_enable:1;
292 unsigned int speed;
294 /* MII tranceiver section */
295 struct mii_if_info mii_if;
296 int mii_preamble_required;
297 unsigned char phys[MII_CNT];
298 unsigned char pci_rev_id;
299 } sdx;
301 static struct sundance_private *sdc;
303 /* Station Address location within the EEPROM */
304 #define EEPROM_SA_OFFSET 0x10
305 #define DEFAULT_INTR (IntrRxDMADone | IntrPCIErr | \
306 IntrDrvRqst | IntrTxDone | StatsMax | \
307 LinkChange)
309 static int eeprom_read(long ioaddr, int location);
310 static int mdio_read(struct nic *nic, int phy_id, unsigned int location);
311 static void mdio_write(struct nic *nic, int phy_id, unsigned int location,
312 int value);
313 static void set_rx_mode(struct nic *nic);
315 static void check_duplex(struct nic *nic)
317 int mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA);
318 int negotiated = mii_lpa & sdc->mii_if.advertising;
319 int duplex;
321 /* Force media */
322 if (!sdc->an_enable || mii_lpa == 0xffff) {
323 if (sdc->mii_if.full_duplex)
324 outw(inw(BASE + MACCtrl0) | EnbFullDuplex,
325 BASE + MACCtrl0);
326 return;
329 /* Autonegotiation */
330 duplex = (negotiated & 0x0100) || (negotiated & 0x01C0) == 0x0040;
331 if (sdc->mii_if.full_duplex != duplex) {
332 sdc->mii_if.full_duplex = duplex;
333 dprintf(("%s: Setting %s-duplex based on MII #%d "
334 "negotiated capability %4.4x.\n", sdc->nic_name,
335 duplex ? "full" : "half", sdc->phys[0],
336 negotiated));
337 outw(inw(BASE + MACCtrl0) | duplex ? 0x20 : 0,
338 BASE + MACCtrl0);
343 /**************************************************************************
344 * init_ring - setup the tx and rx descriptors
345 *************************************************************************/
346 static void init_ring(struct nic *nic __unused)
348 int i;
350 sdc->cur_rx = 0;
352 /* Initialize all the Rx descriptors */
353 for (i = 0; i < RX_RING_SIZE; i++) {
354 rx_ring[i].next_desc = virt_to_le32desc(&rx_ring[i + 1]);
355 rx_ring[i].status = 0;
356 rx_ring[i].length = 0;
357 rx_ring[i].addr = 0;
360 /* Mark the last entry as wrapping the ring */
361 rx_ring[i - 1].next_desc = virt_to_le32desc(&rx_ring[0]);
363 for (i = 0; i < RX_RING_SIZE; i++) {
364 rx_ring[i].addr = virt_to_le32desc(&rxb[i * PKT_BUF_SZ]);
365 rx_ring[i].length = cpu_to_le32(PKT_BUF_SZ | LastFrag);
368 /* We only use one transmit buffer, but two
369 * descriptors so transmit engines have somewhere
370 * to point should they feel the need */
371 tx_ring[0].status = 0x00000000;
372 tx_ring[0].addr = virt_to_bus(&txb[0]);
373 tx_ring[0].next_desc = 0; /* virt_to_bus(&tx_ring[1]); */
375 /* This descriptor is never used */
376 tx_ring[1].status = 0x00000000;
377 tx_ring[1].addr = 0; /*virt_to_bus(&txb[0]); */
378 tx_ring[1].next_desc = 0;
380 /* Mark the last entry as wrapping the ring,
381 * though this should never happen */
382 tx_ring[1].length = cpu_to_le32(LastFrag | PKT_BUF_SZ);
385 /**************************************************************************
386 * RESET - Reset Adapter
387 * ***********************************************************************/
388 static void sundance_reset(struct nic *nic)
390 int i;
392 init_ring(nic);
394 outl(virt_to_le32desc(&rx_ring[0]), BASE + RxListPtr);
395 /* The Tx List Pointer is written as packets are queued */
397 /* Initialize other registers. */
398 /* __set_mac_addr(dev); */
400 u16 addr16;
402 addr16 = (nic->node_addr[0] | (nic->node_addr[1] << 8));
403 outw(addr16, BASE + StationAddr);
404 addr16 = (nic->node_addr[2] | (nic->node_addr[3] << 8));
405 outw(addr16, BASE + StationAddr + 2);
406 addr16 = (nic->node_addr[4] | (nic->node_addr[5] << 8));
407 outw(addr16, BASE + StationAddr + 4);
410 outw(sdc->mtu + 14, BASE + MaxFrameSize);
411 if (sdc->mtu > 2047) /* this will never happen with default options */
412 outl(inl(BASE + ASICCtrl) | 0x0c, BASE + ASICCtrl);
414 set_rx_mode(nic);
416 outw(0, BASE + DownCounter);
417 /* Set the chip to poll every N*30nsec */
418 outb(100, BASE + RxDMAPollPeriod);
420 /* Fix DFE-580TX packet drop issue */
421 if (sdc->pci_rev_id >= 0x14)
422 writeb(0x01, BASE + DebugCtrl1);
424 outw(RxEnable | TxEnable, BASE + MACCtrl1);
426 /* Construct a perfect filter frame with the mac address as first match
427 * and broadcast for all others */
428 for (i = 0; i < 192; i++)
429 txb[i] = 0xFF;
431 txb[0] = nic->node_addr[0];
432 txb[1] = nic->node_addr[1];
433 txb[2] = nic->node_addr[2];
434 txb[3] = nic->node_addr[3];
435 txb[4] = nic->node_addr[4];
436 txb[5] = nic->node_addr[5];
438 dprintf(("%s: Done sundance_reset, status: Rx %hX Tx %hX "
439 "MAC Control %hX, %hX %hX\n",
440 sdc->nic_name, (int) inl(BASE + RxStatus),
441 (int) inw(BASE + TxStatus), (int) inl(BASE + MACCtrl0),
442 (int) inw(BASE + MACCtrl1), (int) inw(BASE + MACCtrl0)));
445 /**************************************************************************
446 IRQ - Wait for a frame
447 ***************************************************************************/
448 void sundance_irq ( struct nic *nic, irq_action_t action ) {
449 unsigned int intr_status;
451 switch ( action ) {
452 case DISABLE :
453 case ENABLE :
454 intr_status = inw(nic->ioaddr + IntrStatus);
455 intr_status = intr_status & ~DEFAULT_INTR;
456 if ( action == ENABLE )
457 intr_status = intr_status | DEFAULT_INTR;
458 outw(intr_status, nic->ioaddr + IntrEnable);
459 break;
460 case FORCE :
461 outw(0x0200, BASE + ASICCtrl);
462 break;
465 /**************************************************************************
466 POLL - Wait for a frame
467 ***************************************************************************/
468 static int sundance_poll(struct nic *nic, int retreive)
470 /* return true if there's an ethernet packet ready to read */
471 /* nic->packet should contain data on return */
472 /* nic->packetlen should contain length of data */
473 int entry = sdc->cur_rx % RX_RING_SIZE;
474 u32 frame_status = le32_to_cpu(rx_ring[entry].status);
475 int intr_status;
476 int pkt_len = 0;
478 if (!(frame_status & DescOwn))
479 return 0;
481 /* There is a packet ready */
482 if(!retreive)
483 return 1;
485 intr_status = inw(nic->ioaddr + IntrStatus);
486 outw(intr_status, nic->ioaddr + IntrStatus);
488 pkt_len = frame_status & 0x1fff;
490 if (frame_status & 0x001f4000) {
491 dprintf(("Polling frame_status error\n")); /* Do we really care about this */
492 } else {
493 if (pkt_len < rx_copybreak) {
494 /* FIXME: What should happen Will this ever occur */
495 printf("Poll Error: pkt_len < rx_copybreak");
496 } else {
497 nic->packetlen = pkt_len;
498 memcpy(nic->packet, rxb +
499 (sdc->cur_rx * PKT_BUF_SZ), nic->packetlen);
503 rx_ring[entry].length = cpu_to_le32(PKT_BUF_SZ | LastFrag);
504 rx_ring[entry].status = 0;
505 entry++;
506 sdc->cur_rx = entry % RX_RING_SIZE;
507 outw(DEFAULT_INTR & ~(IntrRxDone|IntrRxDMADone),
508 nic->ioaddr + IntrStatus);
509 return 1;
512 /**************************************************************************
513 TRANSMIT - Transmit a frame
514 ***************************************************************************/
515 static void sundance_transmit(struct nic *nic, const char *d, /* Destination */
516 unsigned int t, /* Type */
517 unsigned int s, /* size */
518 const char *p)
519 { /* Packet */
520 u16 nstype;
521 u32 to;
523 /* Disable the Tx */
524 outw(TxDisable, BASE + MACCtrl1);
526 memcpy(txb, d, ETH_ALEN);
527 memcpy(txb + ETH_ALEN, nic->node_addr, ETH_ALEN);
528 nstype = htons((u16) t);
529 memcpy(txb + 2 * ETH_ALEN, (u8 *) & nstype, 2);
530 memcpy(txb + ETH_HLEN, p, s);
532 s += ETH_HLEN;
533 s &= 0x0FFF;
534 while (s < ETH_ZLEN)
535 txb[s++] = '\0';
537 /* Setup the transmit descriptor */
538 tx_ring[0].length = cpu_to_le32(s | LastFrag);
539 tx_ring[0].status = cpu_to_le32(0x00000001);
541 /* Point to transmit descriptor */
542 outl(virt_to_le32desc(&tx_ring[0]), BASE + TxListPtr);
544 /* Enable Tx */
545 outw(TxEnable, BASE + MACCtrl1);
546 /* Trigger an immediate send */
547 outw(0, BASE + TxStatus);
549 to = currticks() + TX_TIME_OUT;
550 while (!(tx_ring[0].status & 0x00010000) && (currticks() < to)); /* wait */
552 if (currticks() >= to) {
553 printf("TX Time Out");
555 /* Disable Tx */
556 outw(TxDisable, BASE + MACCtrl1);
560 /**************************************************************************
561 DISABLE - Turn off ethernet interface
562 ***************************************************************************/
563 static void sundance_disable(struct dev *dev __unused)
565 /* put the card in its initial state */
566 /* This function serves 3 purposes.
567 * This disables DMA and interrupts so we don't receive
568 * unexpected packets or interrupts from the card after
569 * etherboot has finished.
570 * This frees resources so etherboot may use
571 * this driver on another interface
572 * This allows etherboot to reinitialize the interface
573 * if something is something goes wrong.
575 outw(0x0000, BASE + IntrEnable);
576 /* Stop the Chipchips Tx and Rx Status */
577 outw(TxDisable | RxDisable | StatsDisable, BASE + MACCtrl1);
582 /**************************************************************************
583 PROBE - Look for an adapter, this routine's visible to the outside
584 ***************************************************************************/
585 static int sundance_probe(struct dev *dev, struct pci_device *pci)
587 struct nic *nic = (struct nic *) dev;
588 u8 ee_data[EEPROM_SIZE];
589 u16 mii_ctl;
590 int i;
591 int speed;
593 if (pci->ioaddr == 0)
594 return 0;
596 /* BASE is used throughout to address the card */
597 BASE = pci->ioaddr;
598 printf(" sundance.c: Found %s Vendor=0x%hX Device=0x%hX\n",
599 pci->name, pci->vendor, pci->dev_id);
601 /* Get the MAC Address by reading the EEPROM */
602 for (i = 0; i < 3; i++) {
603 ((u16 *) ee_data)[i] =
604 le16_to_cpu(eeprom_read(BASE, i + EEPROM_SA_OFFSET));
606 /* Update the nic structure with the MAC Address */
607 for (i = 0; i < ETH_ALEN; i++) {
608 nic->node_addr[i] = ee_data[i];
611 /* Set the card as PCI Bus Master */
612 adjust_pci_device(pci);
614 // sdc->mii_if.dev = pci;
615 // sdc->mii_if.phy_id_mask = 0x1f;
616 // sdc->mii_if.reg_num_mask = 0x1f;
618 /* point to private storage */
619 sdc = &sdx;
621 sdc->nic_name = pci->name;
622 sdc->mtu = mtu;
624 pci_read_config_byte(pci, PCI_REVISION_ID, &sdc->pci_rev_id);
625 dprintf(("Device revision id: %hx\n", sdc->pci_rev_id));
626 /* Print out some hardware info */
627 printf("%s: %! at ioaddr %hX, ", pci->name, nic->node_addr, BASE);
628 sdc->mii_preamble_required = 0;
629 if (1) {
630 int phy, phy_idx = 0;
631 sdc->phys[0] = 1; /* Default Setting */
632 sdc->mii_preamble_required++;
633 for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
634 int mii_status = mdio_read(nic, phy, MII_BMSR);
635 if (mii_status != 0xffff && mii_status != 0x0000) {
636 sdc->phys[phy_idx++] = phy;
637 sdc->mii_if.advertising =
638 mdio_read(nic, phy, MII_ADVERTISE);
639 if ((mii_status & 0x0040) == 0)
640 sdc->mii_preamble_required++;
641 dprintf
642 (("%s: MII PHY found at address %d, status " "%hX advertising %hX\n", sdc->nic_name, phy, mii_status, sdc->mii_if.advertising));
645 sdc->mii_preamble_required--;
646 if (phy_idx == 0)
647 printf("%s: No MII transceiver found!\n",
648 sdc->nic_name);
649 sdc->mii_if.phy_id = sdc->phys[0];
652 /* Parse override configuration */
653 sdc->an_enable = 1;
654 if (strcasecmp(media, "autosense") != 0) {
655 sdc->an_enable = 0;
656 if (strcasecmp(media, "100mbps_fd") == 0 ||
657 strcasecmp(media, "4") == 0) {
658 sdc->speed = 100;
659 sdc->mii_if.full_duplex = 1;
660 } else if (strcasecmp(media, "100mbps_hd") == 0
661 || strcasecmp(media, "3") == 0) {
662 sdc->speed = 100;
663 sdc->mii_if.full_duplex = 0;
664 } else if (strcasecmp(media, "10mbps_fd") == 0 ||
665 strcasecmp(media, "2") == 0) {
666 sdc->speed = 10;
667 sdc->mii_if.full_duplex = 1;
668 } else if (strcasecmp(media, "10mbps_hd") == 0 ||
669 strcasecmp(media, "1") == 0) {
670 sdc->speed = 10;
671 sdc->mii_if.full_duplex = 0;
672 } else {
673 sdc->an_enable = 1;
676 if (flowctrl == 1)
677 sdc->flowctrl = 1;
679 /* Fibre PHY? */
680 if (inl(BASE + ASICCtrl) & 0x80) {
681 /* Default 100Mbps Full */
682 if (sdc->an_enable) {
683 sdc->speed = 100;
684 sdc->mii_if.full_duplex = 1;
685 sdc->an_enable = 0;
689 /* The Linux driver uses flow control and resets the link here. This means the
690 mii section from above would need to be re done I believe. Since it serves
691 no real purpose leave it out. */
693 /* Force media type */
694 if (!sdc->an_enable) {
695 mii_ctl = 0;
696 mii_ctl |= (sdc->speed == 100) ? BMCR_SPEED100 : 0;
697 mii_ctl |= (sdc->mii_if.full_duplex) ? BMCR_FULLDPLX : 0;
698 mdio_write(nic, sdc->phys[0], MII_BMCR, mii_ctl);
699 printf("Override speed=%d, %s duplex\n",
700 sdc->speed,
701 sdc->mii_if.full_duplex ? "Full" : "Half");
704 /* Reset the chip to erase previous misconfiguration */
705 dprintf(("ASIC Control is %x.\n", inl(BASE + ASICCtrl)));
706 outw(0x007f, BASE + ASICCtrl + 2);
707 dprintf(("ASIC Control is now %x.\n", inl(BASE + ASICCtrl)));
709 sundance_reset(nic);
710 if (sdc->an_enable) {
711 u16 mii_advertise, mii_lpa;
712 mii_advertise =
713 mdio_read(nic, sdc->phys[0], MII_ADVERTISE);
714 mii_lpa = mdio_read(nic, sdc->phys[0], MII_LPA);
715 mii_advertise &= mii_lpa;
716 if (mii_advertise & ADVERTISE_100FULL)
717 sdc->speed = 100;
718 else if (mii_advertise & ADVERTISE_100HALF)
719 sdc->speed = 100;
720 else if (mii_advertise & ADVERTISE_10FULL)
721 sdc->speed = 10;
722 else if (mii_advertise & ADVERTISE_10HALF)
723 sdc->speed = 10;
724 } else {
725 mii_ctl = mdio_read(nic, sdc->phys[0], MII_BMCR);
726 speed = (mii_ctl & BMCR_SPEED100) ? 100 : 10;
727 sdc->speed = speed;
728 printf("%s: Link changed: %dMbps ,", sdc->nic_name, speed);
729 printf("%s duplex.\n", (mii_ctl & BMCR_FULLDPLX) ?
730 "full" : "half");
732 check_duplex(nic);
733 if (sdc->flowctrl && sdc->mii_if.full_duplex) {
734 outw(inw(BASE + MulticastFilter1 + 2) | 0x0200,
735 BASE + MulticastFilter1 + 2);
736 outw(inw(BASE + MACCtrl0) | EnbFlowCtrl, BASE + MACCtrl0);
738 printf("%dMbps, %s-Duplex\n", sdc->speed,
739 sdc->mii_if.full_duplex ? "Full" : "Half");
741 /* point to NIC specific routines */
742 dev->disable = sundance_disable;
743 nic->poll = sundance_poll;
744 nic->transmit = sundance_transmit;
745 nic->irqno = pci->irq;
746 nic->irq = sundance_irq;
747 nic->ioaddr = BASE;
749 return 1;
753 /* Read the EEPROM and MII Management Data I/O (MDIO) interfaces. */
754 static int eeprom_read(long ioaddr, int location)
756 int boguscnt = 10000; /* Typical 1900 ticks */
757 outw(0x0200 | (location & 0xff), ioaddr + EECtrl);
758 do {
759 if (!(inw(ioaddr + EECtrl) & 0x8000)) {
760 return inw(ioaddr + EEData);
763 while (--boguscnt > 0);
764 return 0;
767 /* MII transceiver control section.
768 Read and write the MII registers using software-generated serial
769 MDIO protocol. See the MII specifications or DP83840A data sheet
770 for details.
772 The maximum data clock rate is 2.5 Mhz.
773 The timing is decoupled from the processor clock by flushing the write
774 from the CPU write buffer with a following read, and using PCI
775 transaction time. */
777 #define mdio_in(mdio_addr) inb(mdio_addr)
778 #define mdio_out(value, mdio_addr) outb(value, mdio_addr)
779 #define mdio_delay(mdio_addr) inb(mdio_addr)
781 enum mii_reg_bits {
782 MDIO_ShiftClk = 0x0001, MDIO_Data = 0x0002, MDIO_EnbOutput =
783 0x0004,
785 #define MDIO_EnbIn (0)
786 #define MDIO_WRITE0 (MDIO_EnbOutput)
787 #define MDIO_WRITE1 (MDIO_Data | MDIO_EnbOutput)
789 /* Generate the preamble required for initial synchronization and
790 a few older transceivers. */
791 static void mdio_sync(long mdio_addr)
793 int bits = 32;
795 /* Establish sync by sending at least 32 logic ones. */
796 while (--bits >= 0) {
797 mdio_out(MDIO_WRITE1, mdio_addr);
798 mdio_delay(mdio_addr);
799 mdio_out(MDIO_WRITE1 | MDIO_ShiftClk, mdio_addr);
800 mdio_delay(mdio_addr);
804 static int
805 mdio_read(struct nic *nic __unused, int phy_id, unsigned int location)
807 long mdio_addr = BASE + MIICtrl;
808 int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
809 int i, retval = 0;
811 if (sdc->mii_preamble_required)
812 mdio_sync(mdio_addr);
814 /* Shift the read command bits out. */
815 for (i = 15; i >= 0; i--) {
816 int dataval =
817 (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
819 mdio_out(dataval, mdio_addr);
820 mdio_delay(mdio_addr);
821 mdio_out(dataval | MDIO_ShiftClk, mdio_addr);
822 mdio_delay(mdio_addr);
824 /* Read the two transition, 16 data, and wire-idle bits. */
825 for (i = 19; i > 0; i--) {
826 mdio_out(MDIO_EnbIn, mdio_addr);
827 mdio_delay(mdio_addr);
828 retval = (retval << 1) | ((mdio_in(mdio_addr) & MDIO_Data)
829 ? 1 : 0);
830 mdio_out(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
831 mdio_delay(mdio_addr);
833 return (retval >> 1) & 0xffff;
836 static void
837 mdio_write(struct nic *nic __unused, int phy_id,
838 unsigned int location, int value)
840 long mdio_addr = BASE + MIICtrl;
841 int mii_cmd =
842 (0x5002 << 16) | (phy_id << 23) | (location << 18) | value;
843 int i;
845 if (sdc->mii_preamble_required)
846 mdio_sync(mdio_addr);
848 /* Shift the command bits out. */
849 for (i = 31; i >= 0; i--) {
850 int dataval =
851 (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
852 mdio_out(dataval, mdio_addr);
853 mdio_delay(mdio_addr);
854 mdio_out(dataval | MDIO_ShiftClk, mdio_addr);
855 mdio_delay(mdio_addr);
857 /* Clear out extra bits. */
858 for (i = 2; i > 0; i--) {
859 mdio_out(MDIO_EnbIn, mdio_addr);
860 mdio_delay(mdio_addr);
861 mdio_out(MDIO_EnbIn | MDIO_ShiftClk, mdio_addr);
862 mdio_delay(mdio_addr);
864 return;
867 static void set_rx_mode(struct nic *nic __unused)
869 int i;
870 u16 mc_filter[4]; /* Multicast hash filter */
871 u32 rx_mode;
873 memset(mc_filter, 0xff, sizeof(mc_filter));
874 rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
876 if (sdc->mii_if.full_duplex && sdc->flowctrl)
877 mc_filter[3] |= 0x0200;
878 for (i = 0; i < 4; i++)
879 outw(mc_filter[i], BASE + MulticastFilter0 + i * 2);
880 outb(rx_mode, BASE + RxMode);
881 return;
884 static struct pci_id sundance_nics[] = {
885 PCI_ROM(0x13f0, 0x0201, "sundance", "ST201 Sundance 'Alta' based Adaptor"),
886 PCI_ROM(0x1186, 0x1002, "dfe530txs", "D-Link DFE530TXS (Sundance ST201 Alta)"),
889 struct pci_driver sundance_driver = {
890 .type = NIC_DRIVER,
891 .name = "SUNDANCE/PCI",
892 .probe = sundance_probe,
893 .ids = sundance_nics,
894 .id_count = sizeof(sundance_nics) / sizeof(sundance_nics[0]),
895 .class = 0,