source: bootcd/isolinux/syslinux-6.03/gpxe/src/drivers/net/epic100.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: 14.1 KB
Line 
1
2/* epic100.c: A SMC 83c170 EPIC/100 fast ethernet driver for Etherboot */
3
4FILE_LICENCE ( GPL2_OR_LATER );
5
6/* 05/06/2003   timlegge        Fixed relocation and implemented Multicast */
7#define LINUX_OUT_MACROS
8
9#include "etherboot.h"
10#include <gpxe/pci.h>
11#include <gpxe/ethernet.h>
12#include "nic.h"
13#include "console.h"
14#include "epic100.h"
15
16/* Condensed operations for readability */
17#define virt_to_le32desc(addr)  cpu_to_le32(virt_to_bus(addr))
18#define le32desc_to_virt(addr)  bus_to_virt(le32_to_cpu(addr))
19
20#define TX_RING_SIZE    2       /* use at least 2 buffers for TX */
21#define RX_RING_SIZE    2
22
23#define PKT_BUF_SZ      1536    /* Size of each temporary Tx/Rx buffer.*/
24
25/*
26#define DEBUG_RX
27#define DEBUG_TX
28#define DEBUG_EEPROM
29*/
30
31#define EPIC_DEBUG 0    /* debug level */
32
33/* The EPIC100 Rx and Tx buffer descriptors. */
34struct epic_rx_desc {
35    unsigned long status;
36    unsigned long bufaddr;
37    unsigned long buflength;
38    unsigned long next;
39};
40/* description of the tx descriptors control bits commonly used */
41#define TD_STDFLAGS     TD_LASTDESC
42
43struct epic_tx_desc {
44    unsigned long status;
45    unsigned long bufaddr;
46    unsigned long buflength;
47    unsigned long  next;
48};
49
50#define delay(nanosec)   do { int _i = 3; while (--_i > 0) \
51                                     { __SLOW_DOWN_IO; }} while (0)
52
53static void     epic100_open(void);
54static void     epic100_init_ring(void);
55static void     epic100_disable(struct nic *nic);
56static int      epic100_poll(struct nic *nic, int retrieve);
57static void     epic100_transmit(struct nic *nic, const char *destaddr,
58                                 unsigned int type, unsigned int len, const char *data);
59#ifdef  DEBUG_EEPROM
60static int      read_eeprom(int location);
61#endif
62static int      mii_read(int phy_id, int location);
63static void     epic100_irq(struct nic *nic, irq_action_t action);
64
65static struct nic_operations epic100_operations;
66
67static int      ioaddr;
68
69static int      command;
70static int      intstat;
71static int      intmask;
72static int      genctl ;
73static int      eectl  ;
74static int      test   ;
75static int      mmctl  ;
76static int      mmdata ;
77static int      lan0   ;
78static int      mc0    ;
79static int      rxcon  ;
80static int      txcon  ;
81static int      prcdar ;
82static int      ptcdar ;
83static int      eththr ;
84
85static unsigned int     cur_rx, cur_tx;         /* The next free ring entry */
86#ifdef  DEBUG_EEPROM
87static unsigned short   eeprom[64];
88#endif
89static signed char      phys[4];                /* MII device addresses. */
90struct {
91        struct epic_rx_desc     rx_ring[RX_RING_SIZE]
92        __attribute__ ((aligned(4)));
93        struct epic_tx_desc     tx_ring[TX_RING_SIZE]
94        __attribute__ ((aligned(4)));
95        unsigned char           rx_packet[PKT_BUF_SZ * RX_RING_SIZE];
96        unsigned char           tx_packet[PKT_BUF_SZ * TX_RING_SIZE];
97} epic100_bufs __shared;
98#define rx_ring epic100_bufs.rx_ring
99#define tx_ring epic100_bufs.tx_ring
100#define rx_packet epic100_bufs.rx_packet
101#define tx_packet epic100_bufs.tx_packet
102
103/***********************************************************************/
104/*                    Externally visible functions                     */
105/***********************************************************************/
106
107
108static int
109epic100_probe ( struct nic *nic, struct pci_device *pci ) {
110
111    int i;
112    unsigned short* ap;
113    unsigned int phy, phy_idx;
114
115    if (pci->ioaddr == 0)
116        return 0;
117
118    /* Ideally we would detect all network cards in slot order.  That would
119       be best done a central PCI probe dispatch, which wouldn't work
120       well with the current structure.  So instead we detect just the
121       Epic cards in slot order. */
122
123    ioaddr = pci->ioaddr;
124
125    nic->irqno  = 0;
126    nic->ioaddr = pci->ioaddr & ~3;
127
128    /* compute all used static epic100 registers address */
129    command = ioaddr + COMMAND;         /* Control Register */
130    intstat = ioaddr + INTSTAT;         /* Interrupt Status */
131    intmask = ioaddr + INTMASK;         /* Interrupt Mask */
132    genctl  = ioaddr + GENCTL;          /* General Control */
133    eectl   = ioaddr + EECTL;           /* EEPROM Control  */
134    test    = ioaddr + TEST;            /* Test register (clocks) */
135    mmctl   = ioaddr + MMCTL;           /* MII Management Interface Control */
136    mmdata  = ioaddr + MMDATA;          /* MII Management Interface Data */
137    lan0    = ioaddr + LAN0;            /* MAC address. (0x40-0x48) */
138    mc0     = ioaddr + MC0;             /* Multicast Control */
139    rxcon   = ioaddr + RXCON;           /* Receive Control */
140    txcon   = ioaddr + TXCON;           /* Transmit Control */
141    prcdar  = ioaddr + PRCDAR;          /* PCI Receive Current Descr Address */
142    ptcdar  = ioaddr + PTCDAR;          /* PCI Transmit Current Descr Address */
143    eththr  = ioaddr + ETHTHR;          /* Early Transmit Threshold */
144
145    /* Reset the chip & bring it out of low-power mode. */
146    outl(GC_SOFT_RESET, genctl);
147
148    /* Disable ALL interrupts by setting the interrupt mask. */
149    outl(INTR_DISABLE, intmask);
150
151    /*
152     * set the internal clocks:
153     * Application Note 7.15 says:
154     *    In order to set the CLOCK TEST bit in the TEST register,
155     *    perform the following:
156     *
157     *        Write 0x0008 to the test register at least sixteen
158     *        consecutive times.
159     *
160     * The CLOCK TEST bit is Write-Only. Writing it several times
161     * consecutively insures a successful write to the bit...
162     */
163
164    for (i = 0; i < 16; i++) {
165        outl(0x00000008, test);
166    }
167
168#ifdef  DEBUG_EEPROM
169{
170    unsigned short sum = 0;
171    unsigned short value;
172    for (i = 0; i < 64; i++) {
173        value = read_eeprom(i);
174        eeprom[i] = value;
175        sum += value;
176    }
177}
178
179#if     (EPIC_DEBUG > 1)
180    printf("EEPROM contents\n");
181    for (i = 0; i < 64; i++) {
182        printf(" %hhX%s", eeprom[i], i % 16 == 15 ? "\n" : "");
183    }
184#endif
185#endif
186
187    /* This could also be read from the EEPROM. */
188    ap = (unsigned short*)nic->node_addr;
189    for (i = 0; i < 3; i++)
190        *ap++ = inw(lan0 + i*4);
191
192    DBG ( " I/O %4.4x %s ", ioaddr, eth_ntoa ( nic->node_addr ) );
193
194    /* Find the connected MII xcvrs. */
195    for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(phys); phy++) {
196        int mii_status = mii_read(phy, 0);
197
198        if (mii_status != 0xffff  && mii_status != 0x0000) {
199            phys[phy_idx++] = phy;
200#if     (EPIC_DEBUG > 1)
201            printf("MII transceiver found at address %d.\n", phy);
202#endif
203        }
204    }
205    if (phy_idx == 0) {
206#if     (EPIC_DEBUG > 1)
207        printf("***WARNING***: No MII transceiver found!\n");
208#endif
209        /* Use the known PHY address of the EPII. */
210        phys[0] = 3;
211    }
212
213    epic100_open();
214    nic->nic_op = &epic100_operations;
215
216    return 1;
217}
218
219static void set_rx_mode(void)
220{
221        unsigned char mc_filter[8];
222        int i;
223        memset(mc_filter, 0xff, sizeof(mc_filter));
224        outl(0x0C, rxcon);
225        for(i = 0; i < 4; i++)
226                outw(((unsigned short *)mc_filter)[i], mc0 + i*4);
227        return;
228}
229       
230   static void
231epic100_open(void)
232{
233    int mii_reg5;
234    int full_duplex = 0;
235    unsigned long tmp;
236
237    epic100_init_ring();
238
239    /* Pull the chip out of low-power mode, and set for PCI read multiple. */
240    outl(GC_RX_FIFO_THR_64 | GC_MRC_READ_MULT | GC_ONE_COPY, genctl);
241
242    outl(TX_FIFO_THRESH, eththr);
243
244    tmp = TC_EARLY_TX_ENABLE | TX_SLOT_TIME;
245
246    mii_reg5 = mii_read(phys[0], 5);
247    if (mii_reg5 != 0xffff && (mii_reg5 & 0x0100)) {
248        full_duplex = 1;
249        printf(" full-duplex mode");
250        tmp |= TC_LM_FULL_DPX;
251    } else
252        tmp |= TC_LM_NORMAL;
253
254    outl(tmp, txcon);
255
256    /* Give adress of RX and TX ring to the chip */
257    outl(virt_to_le32desc(&rx_ring), prcdar);
258    outl(virt_to_le32desc(&tx_ring), ptcdar);
259
260    /* Start the chip's Rx process: receive unicast and broadcast */
261    set_rx_mode();
262    outl(CR_START_RX | CR_QUEUE_RX, command);
263
264    putchar('\n');
265}
266
267/* Initialize the Rx and Tx rings. */
268    static void
269epic100_init_ring(void)
270{
271    int i;
272
273    cur_rx = cur_tx = 0;
274
275    for (i = 0; i < RX_RING_SIZE; i++) {
276        rx_ring[i].status    = cpu_to_le32(RRING_OWN);  /* Owned by Epic chip */
277        rx_ring[i].buflength = cpu_to_le32(PKT_BUF_SZ);
278        rx_ring[i].bufaddr   = virt_to_bus(&rx_packet[i * PKT_BUF_SZ]);
279        rx_ring[i].next      = virt_to_le32desc(&rx_ring[i + 1]) ;
280    }
281    /* Mark the last entry as wrapping the ring. */
282    rx_ring[i-1].next = virt_to_le32desc(&rx_ring[0]);
283
284    /*
285     *The Tx buffer descriptor is filled in as needed,
286     * but we do need to clear the ownership bit.
287     */
288
289    for (i = 0; i < TX_RING_SIZE; i++) {
290        tx_ring[i].status  = 0x0000;                    /* Owned by CPU */
291        tx_ring[i].buflength = 0x0000 | cpu_to_le32(TD_STDFLAGS << 16);
292        tx_ring[i].bufaddr = virt_to_bus(&tx_packet[i * PKT_BUF_SZ]);
293        tx_ring[i].next    = virt_to_le32desc(&tx_ring[i + 1]);
294    }
295        tx_ring[i-1].next    = virt_to_le32desc(&tx_ring[0]);
296}
297
298/* function: epic100_transmit
299 * This transmits a packet.
300 *
301 * Arguments: char d[6]:          destination ethernet address.
302 *            unsigned short t:   ethernet protocol type.
303 *            unsigned short s:   size of the data-part of the packet.
304 *            char *p:            the data for the packet.
305 * returns:   void.
306 */
307    static void
308epic100_transmit(struct nic *nic, const char *destaddr, unsigned int type,
309                 unsigned int len, const char *data)
310{
311    unsigned short nstype;
312    unsigned char *txp;
313    int entry;
314    unsigned long ct;
315
316    /* Calculate the next Tx descriptor entry. */
317    entry = cur_tx % TX_RING_SIZE;
318
319    if ((tx_ring[entry].status & TRING_OWN) == TRING_OWN) {
320        printf("eth_transmit: Unable to transmit. status=%4.4lx. Resetting...\n",
321               tx_ring[entry].status);
322
323        epic100_open();
324        return;
325    }
326
327    txp = tx_packet + (entry * PKT_BUF_SZ);
328
329    memcpy(txp, destaddr, ETH_ALEN);
330    memcpy(txp + ETH_ALEN, nic->node_addr, ETH_ALEN);
331    nstype = htons(type);
332    memcpy(txp + 12, (char*)&nstype, 2);
333    memcpy(txp + ETH_HLEN, data, len);
334
335    len += ETH_HLEN;
336        len &= 0x0FFF;
337        while(len < ETH_ZLEN)
338                txp[len++] = '\0';
339    /*
340     * Caution: the write order is important here,
341     * set the base address with the "ownership"
342     * bits last.
343     */
344   
345    tx_ring[entry].buflength |= cpu_to_le32(len);
346    tx_ring[entry].status = cpu_to_le32(len << 16) |
347            cpu_to_le32(TRING_OWN);     /* Pass ownership to the chip. */
348
349    cur_tx++;
350
351    /* Trigger an immediate transmit demand. */
352    outl(CR_QUEUE_TX, command);
353
354    ct = currticks();
355    /* timeout 10 ms for transmit */
356    while ((le32_to_cpu(tx_ring[entry].status) & (TRING_OWN)) &&
357                ct + 10*1000 < currticks())
358        /* Wait */;
359
360    if ((le32_to_cpu(tx_ring[entry].status) & TRING_OWN) != 0)
361        printf("Oops, transmitter timeout, status=%4.4lX\n",
362            tx_ring[entry].status);
363}
364
365/* function: epic100_poll / eth_poll
366 * This receives a packet from the network.
367 *
368 * Arguments: none
369 *
370 * returns:   1 if a packet was received.
371 *            0 if no pacet was received.
372 * side effects:
373 *            returns the packet in the array nic->packet.
374 *            returns the length of the packet in nic->packetlen.
375 */
376
377    static int
378epic100_poll(struct nic *nic, int retrieve)
379{
380    int entry;
381    int retcode;
382    int status;
383    entry = cur_rx % RX_RING_SIZE;
384
385    if ((rx_ring[entry].status & cpu_to_le32(RRING_OWN)) == RRING_OWN)
386        return (0);
387
388    if ( ! retrieve ) return 1;
389
390    status = le32_to_cpu(rx_ring[entry].status);
391    /* We own the next entry, it's a new packet. Send it up. */
392
393#if     (EPIC_DEBUG > 4)
394    printf("epic_poll: entry %d status %hX\n", entry, status);
395#endif
396
397    cur_rx++;
398    if (status & 0x2000) {
399        printf("epic_poll: Giant packet\n");
400        retcode = 0;
401    } else if (status & 0x0006) {
402        /* Rx Frame errors are counted in hardware. */
403        printf("epic_poll: Frame received with errors\n");
404        retcode = 0;
405    } else {
406        /* Omit the four octet CRC from the length. */
407        nic->packetlen = le32_to_cpu((rx_ring[entry].buflength))- 4;
408        memcpy(nic->packet, &rx_packet[entry * PKT_BUF_SZ], nic->packetlen);
409        retcode = 1;
410    }
411
412    /* Clear all error sources. */
413    outl(status & INTR_CLEARERRS, intstat);
414
415    /* Give the descriptor back to the chip */
416    rx_ring[entry].status = RRING_OWN;
417
418    /* Restart Receiver */
419    outl(CR_START_RX | CR_QUEUE_RX, command);
420
421    return retcode;
422}
423
424
425static void epic100_disable ( struct nic *nic __unused ) {
426        /* Soft reset the chip. */
427        outl(GC_SOFT_RESET, genctl);
428}
429
430static void epic100_irq(struct nic *nic __unused, irq_action_t action __unused)
431{
432  switch ( action ) {
433  case DISABLE :
434    break;
435  case ENABLE :
436    break;
437  case FORCE :
438    break;
439  }
440}
441
442#ifdef  DEBUG_EEPROM
443/* Serial EEPROM section. */
444
445/*  EEPROM_Ctrl bits. */
446#define EE_SHIFT_CLK    0x04    /* EEPROM shift clock. */
447#define EE_CS           0x02    /* EEPROM chip select. */
448#define EE_DATA_WRITE   0x08    /* EEPROM chip data in. */
449#define EE_WRITE_0      0x01
450#define EE_WRITE_1      0x09
451#define EE_DATA_READ    0x10    /* EEPROM chip data out. */
452#define EE_ENB          (0x0001 | EE_CS)
453
454/* The EEPROM commands include the alway-set leading bit. */
455#define EE_WRITE_CMD    (5 << 6)
456#define EE_READ_CMD     (6 << 6)
457#define EE_ERASE_CMD    (7 << 6)
458
459#define eeprom_delay(n) delay(n)
460
461    static int
462read_eeprom(int location)
463{
464    int i;
465    int retval = 0;
466    int read_cmd = location | EE_READ_CMD;
467
468    outl(EE_ENB & ~EE_CS, eectl);
469    outl(EE_ENB, eectl);
470
471    /* Shift the read command bits out. */
472    for (i = 10; i >= 0; i--) {
473        short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
474        outl(EE_ENB | dataval, eectl);
475        eeprom_delay(100);
476        outl(EE_ENB | dataval | EE_SHIFT_CLK, eectl);
477        eeprom_delay(150);
478        outl(EE_ENB | dataval, eectl);  /* Finish EEPROM a clock tick. */
479        eeprom_delay(250);
480    }
481    outl(EE_ENB, eectl);
482
483    for (i = 16; i > 0; i--) {
484        outl(EE_ENB | EE_SHIFT_CLK, eectl);
485        eeprom_delay(100);
486        retval = (retval << 1) | ((inl(eectl) & EE_DATA_READ) ? 1 : 0);
487        outl(EE_ENB, eectl);
488        eeprom_delay(100);
489    }
490
491    /* Terminate the EEPROM access. */
492    outl(EE_ENB & ~EE_CS, eectl);
493    return retval;
494}
495#endif
496
497
498#define MII_READOP      1
499#define MII_WRITEOP     2
500
501    static int
502mii_read(int phy_id, int location)
503{
504    int i;
505
506    outl((phy_id << 9) | (location << 4) | MII_READOP, mmctl);
507    /* Typical operation takes < 50 ticks. */
508
509    for (i = 4000; i > 0; i--)
510        if ((inl(mmctl) & MII_READOP) == 0)
511            break;
512    return inw(mmdata);
513}
514
515static struct nic_operations epic100_operations = {
516        .connect        = dummy_connect,
517        .poll           = epic100_poll,
518        .transmit       = epic100_transmit,
519        .irq            = epic100_irq,
520
521};
522
523static struct pci_device_id epic100_nics[] = {
524PCI_ROM(0x10b8, 0x0005, "epic100",    "SMC EtherPowerII", 0),           /* SMC 83c170 EPIC/100 */
525PCI_ROM(0x10b8, 0x0006, "smc-83c175", "SMC EPIC/C 83c175", 0),
526};
527
528PCI_DRIVER ( epic100_driver, epic100_nics, PCI_NO_CLASS );
529
530DRIVER ( "EPIC100", nic_driver, pci_driver, epic100_driver,
531         epic100_probe, epic100_disable );
532
533/*
534 * Local variables:
535 *  c-basic-offset: 8
536 *  c-indent-level: 8
537 *  tab-width: 8
538 * End:
539 */
Note: See TracBrowser for help on using the repository browser.