source: bootcd/isolinux/syslinux-6.03/gpxe/src/drivers/net/sundance.c

Last change on this file was e16e8f2, checked in by Edwin Eefting <edwin@datux.nl>, 3 years ago

bootstuff

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