added gPXE compatible eepro100. not tested. it just compiles.
[people/indolent/gpxe.git/.git] / src / drivers / net / eepro100.c
1 /* 
2    eepro100.c - gPXE driver for the eepro100 8255x series. 
3 */
4
5 #include <stdint.h>
6 #include <stdlib.h>
7 #include <stdio.h>
8 #include <io.h>
9 #include <errno.h>
10 #include <timer.h>
11 #include <byteswap.h>
12 #include <gpxe/pci.h>
13 #include <gpxe/if_ether.h>
14 #include <gpxe/ethernet.h>
15 #include <gpxe/iobuf.h>
16 #include <gpxe/netdevice.h>
17 #include <gpxe/spi_bit.h>
18 #include <gpxe/threewire.h>
19 #include <gpxe/nvo.h>
20
21
22 #define TX_RING_SIZE 4
23 #define NUM_RX_DESC  4
24 #define RX_BUF_SIZE 1528
25 #define CONFIG_DATA_SIZE 22
26
27 /* Elements of the dump_statistics block. This block must be lword aligned. */
28 struct speedo_stats {
29         u32 tx_good_frames;
30         u32 tx_coll16_errs;
31         u32 tx_late_colls;
32         u32 tx_underruns;
33         u32 tx_lost_carrier;
34         u32 tx_deferred;
35         u32 tx_one_colls;
36         u32 tx_multi_colls;
37         u32 tx_total_colls;
38         u32 rx_good_frames;
39         u32 rx_crc_errs;
40         u32 rx_align_errs;
41         u32 rx_resource_errs;
42         u32 rx_overrun_errs;
43         u32 rx_colls_errs;
44         u32 rx_runt_errs;
45         u32 done_marker;
46 };
47
48 struct speedo_tx {
49         volatile s16 status;
50         s16 command;
51         u32 link;          /* void * */
52         u32 tx_desc_addr;  /* (almost) Always points to the tx_buf_addr element. */
53         s32 count;         /* # of TBD (=2), Tx start thresh., etc. */
54         /* This constitutes two "TBD" entries: hdr and data */
55         u32 tx_buf_addr0;  /* void *, header of frame to be transmitted.  */
56         s32 tx_buf_size0;  /* Length of Tx hdr. */
57         u32 tx_buf_addr1;  /* void *, data to be transmitted.  */
58         s32 tx_buf_size1;  /* Length of Tx data. */
59 };
60
61 struct speedo_rx {
62         volatile s16 status;
63         s16 command;
64         u32 link;                 /* struct RxFD * */
65         u32 rx_buf_addr;          /* void * */
66         u16 count;
67         u16 size;
68         char packet[RX_BUF_SIZE];
69 };
70
71 struct speedo_private {
72         unsigned short ioaddr;
73         unsigned short tx_cur;
74         unsigned short tx_dirty;
75         unsigned short rx_cur;
76         struct speedo_tx txfd[TX_RING_SIZE];
77         struct speedo_rx rxfd[NUM_RX_DESC];
78
79         /* netdev_tx_complete needs pointer to the iobuf of the data so as to free 
80          * it from the memory.
81          */
82         struct io_buffer *tx_iobuf[TX_RING_SIZE];
83         struct speedo_stats lstats;
84         struct spi_bit_basher spibit;
85         struct spi_device eeprom;
86         struct nvo_block nvo;
87 };
88
89 enum speedo_offsets {
90   SCBStatus = 0, SCBCmd = 2,      /* Rx/Command Unit command and status. */
91   SCBPointer = 4,                 /* General purpose pointer. */
92   SCBPort = 8,                    /* Misc. commands and operands.  */
93   SCBflash = 12, SCBeeprom = 14,  /* EEPROM and flash memory control. */
94   SCBCtrlMDI = 16,                /* MDI interface control. */
95   SCBEarlyRx = 20,                /* Early receive byte count. */
96 };
97
98 enum SCBCmdBits {
99         SCBMaskCmdDone=0x8000, SCBMaskRxDone=0x4000, SCBMaskCmdIdle=0x2000,
100         SCBMaskRxSuspend=0x1000, SCBMaskEarlyRx=0x0800, SCBMaskFlowCtl=0x0400,
101         SCBTriggerIntr=0x0200, SCBMaskAll=0x0100,
102         /* The rest are Rx and Tx commands. */
103         CUStart=0x0010, CUResume=0x0020, CUStatsAddr=0x0040, CUShowStats=0x0050,
104         CUCmdBase=0x0060,       /* CU Base address (set to zero) . */
105         CUDumpStats=0x0070, /* Dump then reset stats counters. */
106         RxStart=0x0001, RxResume=0x0002, RxAbort=0x0004, RxAddrLoad=0x0006,
107         RxResumeNoResources=0x0007,
108 };
109
110 static const char i82558_config_cmd[CONFIG_DATA_SIZE] = {
111         22, 0x08, 0, 1,  0, 0, 0x22, 0x03,  1, /* 1=Use MII  0=Use AUI */
112         0, 0x2E, 0,  0x60, 0x08, 0x88,
113         0x68, 0, 0x40, 0xf2, 0x84,              /* Disable FC */
114         0x31, 0x05, };
115
116 unsigned short eeprom[16];
117 /* Serial EEPROM section.
118    A "bit" grungy, but we work our way through bit-by-bit :->. */
119 /*  EEPROM_Ctrl bits. */
120 #define EE_SHIFT_CLK    0x01    /* EEPROM shift clock. */
121 #define EE_CS           0x02    /* EEPROM chip select. */
122 #define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
123 #define EE_DATA_READ    0x08    /* EEPROM chip data out. */
124 #define EE_WRITE_0      0x4802
125 #define EE_WRITE_1      0x4806
126 #define EE_ENB          (0x4800 | EE_CS)
127
128 /* The EEPROM commands include the alway-set leading bit. */
129 #define EE_READ_CMD     6
130
131
132 /* The SCB accepts the following controls for the Tx and Rx units: */
133 #define  CU_START       0x0010
134 #define  CU_RESUME      0x0020
135 #define  CU_STATSADDR   0x0040
136 #define  CU_SHOWSTATS   0x0050  /* Dump statistics counters. */
137 #define  CU_CMD_BASE    0x0060  /* Base address to add to add CU commands. */
138 #define  CU_DUMPSTATS   0x0070  /* Dump then reset stats counters. */
139
140 #define  RX_START       0x0001
141 #define  RX_RESUME      0x0002
142 #define  RX_ABORT       0x0004
143 #define  RX_ADDR_LOAD   0x0006
144 #define  RX_RESUMENR    0x0007
145 #define INT_MASK        0x0100
146 #define DRVR_INT        0x0200          /* Driver generated interrupt. */
147
148 enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
149                                          S80C24, PhyUndefined, DP83840A=10, };
150
151 /* Commands that can be put in a command list entry. */
152 enum commands {
153   CmdNOp = 0,
154   CmdIASetup = 1,
155   CmdConfigure = 2,
156   CmdMulticastList = 3,
157   CmdTx = 4,
158   CmdTDR = 5,
159   CmdDump = 6,
160   CmdDiagnose = 7,
161
162   /* And some extra flags: */
163   CmdSuspend = 0x4000,      /* Suspend after completion. */
164   CmdIntr = 0x2000,         /* Interrupt after completion. */
165   CmdTxFlex = 0x0008,       /* Use "Flexible mode" for CmdTx command. */
166 };
167
168 /* Selected elements of the Tx/RxFD.status word. */
169 enum RxFD_bits {
170         RxComplete=0x8000, RxOK=0x2000,
171         RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010,
172         RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002,
173         TxUnderrun=0x1000,  StatusComplete=0x8000,
174 };
175
176 static int congenb = 0;         /* Enable congestion control in the DP83840. */
177 static int txfifo = 8;          /* Tx FIFO threshold in 4 byte units, 0-15 */
178 static int rxfifo = 8;          /* Rx FIFO threshold, default 32 bytes. */
179 static int txdmacount = 0;      /* Tx DMA burst length, 0-127, default 0. */
180 static int rxdmacount = 0;      /* Rx DMA length, 0 means no preemption. */
181
182
183 /*  Function Prototypes: */
184  
185 static int speedo_open (struct net_device *netdev);
186 static int speedo_transmit (struct net_device *netdev, struct io_buffer *iobuf);
187 static void speedo_poll (struct net_device *netdev);
188 static void speedo_disable ( struct net_device *netdev); 
189
190 /** speedo net device operations */
191 static struct net_device_operations speedo_operations = {
192         .open           = speedo_open,
193         .close          = speedo_disable,
194         .transmit       = speedo_transmit,
195         .poll           = speedo_poll,
196 //      .irq            = speedo_irq,
197 };
198
199 /* How to wait for the command unit to accept a command.
200    Typically this takes 0 ticks. */
201 static inline void wait_for_cmd_done(int cmd_ioaddr)
202 {
203   int wait = 0;
204   int delayed_cmd;
205
206   do
207     if (inb(cmd_ioaddr) == 0) return;
208   while(++wait <= 100);
209   delayed_cmd = inb(cmd_ioaddr);
210   do
211     if (inb(cmd_ioaddr) == 0) break;
212   while(++wait <= 10000);
213   printf("Command %2.2x was not immediately accepted, %d ticks!\n",
214       delayed_cmd, wait);
215 }
216 /* Support function: mdio_write
217  *
218  * This probably writes to the "physical media interface chip".
219  * -- REW
220  */
221
222 static int mdio_write(struct net_device *netdev, int phy_id, int location, int value)
223 {
224         struct speedo_private *sp = netdev->priv;
225         int val, boguscnt = 64*4;         /* <64 usec. to complete, typ 27 ticks */
226
227         outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
228              sp->ioaddr + SCBCtrlMDI);
229         do {
230                 udelay(16);
231
232                 val = inl(sp->ioaddr + SCBCtrlMDI);
233                 if (--boguscnt < 0) {
234                         printf(" mdio_write() timed out with val = %X.\n", val);
235                         break;
236                 }
237         } while (! (val & 0x10000000));
238         return val & 0xffff;
239 }
240
241 /* Support function: mdio_read
242  *
243  * This probably reads a register in the "physical media interface chip".
244  * -- REW
245  */
246 static int mdio_read(struct net_device *netdev,int phy_id, int location)
247 {
248         struct speedo_private *sp = netdev->priv;
249         int val, boguscnt = 64*4;               /* <64 usec. to complete, typ 27 ticks */
250         outl(0x08000000 | (location<<16) | (phy_id<<21), sp->ioaddr + SCBCtrlMDI);
251         do {
252                 udelay(16);
253
254                 val = inl(sp->ioaddr + SCBCtrlMDI);
255
256                 if (--boguscnt < 0) {
257                         printf( " mdio_read() timed out with val = %X.\n", val);
258                         break;
259                 }
260         } while (! (val & 0x10000000));
261         return val & 0xffff;
262 }
263 /* The fixes for the code were kindly provided by Dragan Stancevic
264    <visitor@valinux.com> to strictly follow Intel specifications of EEPROM
265    access timing.
266    The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
267    interval for serial EEPROM.  However, it looks like that there is an
268    additional requirement dictating larger udelay's in the code below.
269    2000/05/24  SAW */
270 static int do_eeprom_cmd(struct net_device *netdev,int cmd, int cmd_len)
271 {
272         struct speedo_private *sp = netdev->priv;
273         unsigned retval = 0;
274         long ee_addr = sp->ioaddr + SCBeeprom;
275
276         outw(EE_ENB, ee_addr); udelay(2);
277         outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
278
279         /* Shift the command bits out. */
280         do {
281                 short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
282                 outw(dataval, ee_addr); udelay(2);
283                 outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
284                 retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
285         } while (--cmd_len >= 0);
286         outw(EE_ENB, ee_addr); udelay(2);
287
288         /* Terminate the EEPROM access. */
289         outw(EE_ENB & ~EE_CS, ee_addr);
290         return retval;
291 }
292
293 /* function: eepro100_disable
294  * resets the card. This is used to allow Etherboot or Linux
295  * to probe the card again from a "virginal" state....
296  * Arguments: none
297  *
298  * returns:   void.
299  */
300 static void speedo_disable ( struct net_device *netdev) {
301         struct speedo_private *sp = netdev->priv;
302 /* from eepro100_reset */
303         outl(0, sp->ioaddr + SCBPort);
304 /* from eepro100_disable */
305         /* See if this PartialReset solves the problem with interfering with
306            kernel operation after Etherboot hands over. - Ken 20001102 */
307         outl(2, sp->ioaddr + SCBPort);
308
309         /* The following is from the Intel e100 driver.
310          * This hopefully solves the problem with hanging hard DOS images. */
311
312         /* wait for the reset to take effect */
313         udelay(20);
314
315         /* Mask off our interrupt line -- it is unmasked after reset */
316         {
317                 u16 intr_status;
318                 /* Disable interrupts on our PCI board by setting the mask bit */
319                 outw(INT_MASK, sp->ioaddr + SCBCmd);
320                 intr_status = inw(sp->ioaddr + SCBStatus);
321                 /* ack and clear intrs */
322                 outw(intr_status, sp->ioaddr + SCBStatus);
323                 inw(sp->ioaddr + SCBStatus);
324         }
325 }
326
327
328 /**
329  * Probe PCI device
330  *
331  * @v pci       PCI device
332  * @v id        PCI ID
333  * @ret rc      Return status code
334  */
335 static int speedo_probe (struct pci_device *pci,
336                        const struct pci_device_id *id __unused) {
337         struct net_device *netdev;
338         struct speedo_private *sp = NULL;
339         int rc;
340         int read_cmd, ee_size;
341         int i, sum;
342
343         /* Allocate net device 
344          */
345         netdev = alloc_etherdev (sizeof (*sp));
346         if (! netdev) 
347                 return -ENOMEM;
348
349         netdev_init (netdev, &speedo_operations);
350         sp = netdev->priv;
351         pci_set_drvdata (pci, netdev);
352         netdev->dev = &pci->dev;
353         memset (sp, 0, sizeof (*sp));
354         sp->ioaddr = pci->ioaddr;
355
356         adjust_pci_device (pci);
357
358         //natsemi_reset (netdev);
359         
360         /* read the MAC Address */
361         if ((do_eeprom_cmd(netdev,EE_READ_CMD << 24, 27) & 0xffe0000)
362                 == 0xffe0000) {
363                 ee_size = 0x100;
364                 read_cmd = EE_READ_CMD << 24;
365         } else {
366                 ee_size = 0x40;
367                 read_cmd = EE_READ_CMD << 22;
368         }
369
370         for (i = 0, sum = 0; i < ee_size; i++) {
371                 unsigned short value = do_eeprom_cmd(netdev,read_cmd | (i << 16), 27);
372                 if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0])))
373                         eeprom[i] = value;
374                 sum += value;
375         }
376
377         for (i=0;i<ETH_ALEN;i++) {
378                 netdev->ll_addr[i] =  (eeprom[i/2] >> (8*(i&1))) & 0xff;
379         }
380
381
382         if ((rc = register_netdev (netdev)) != 0)
383                 goto err_register_netdev;
384
385         return 0;
386
387 err_register_netdev:
388
389         speedo_disable (netdev);
390         netdev_put (netdev);
391         return rc;
392 }
393
394 /**
395  * Open NIC
396  *
397  * @v netdev            Net device
398  * @ret rc              Return status code
399  */
400 static int speedo_open (struct net_device *netdev) { 
401         struct speedo_private *sp = netdev->priv; 
402         int i; 
403         int options = 0x00;
404         int rx_mode=0;
405         /* Set MAC address in NIC */
406         /*TODO
407         for (i = 0 ; i < ETH_ALEN ; i+=2) {
408                 outl (i, np->ioaddr + RxFilterAddr);
409                 outw (netdev->ll_addr[i] + (netdev->ll_addr[i + 1] << 8),
410                        np->ioaddr + RxFilterData);
411         }
412         */
413         /* Setup RX ring
414          */
415         /*TODO check what is required */
416         outl(0, sp->ioaddr + SCBPointer);
417         outw(INT_MASK | RX_ADDR_LOAD, sp->ioaddr + SCBCmd);
418         wait_for_cmd_done(sp->ioaddr + SCBCmd);
419
420         outl(virt_to_bus(&sp->lstats), sp->ioaddr + SCBPointer);
421         outb(CU_STATSADDR, sp->ioaddr + SCBCmd);
422         wait_for_cmd_done(sp->ioaddr + SCBCmd);
423
424
425         sp->rx_cur = 0;
426         for (i = 0 ; i < NUM_RX_DESC ; i++) {
427                 sp->rxfd[i].status      = 0x0000;
428                 sp->rxfd[i].command     = 0x0000;
429                 sp->rxfd[i].rx_buf_addr = 0xFFFFFFFF;
430                 sp->rxfd[i].count       = 0;
431                 sp->rxfd[i].size        = RX_BUF_SIZE;
432                 sp->rxfd[i].link        = virt_to_bus(&sp->rxfd[i+1]);
433         }
434
435         sp->rxfd[NUM_RX_DESC -1].status  = 0x0000;
436         sp->rxfd[NUM_RX_DESC -1].command = 0xC000;
437         sp->rxfd[NUM_RX_DESC -1].link    = virt_to_bus(&sp->rxfd[0]);
438
439
440         outl(virt_to_bus(&sp->rxfd[0]), sp->ioaddr + SCBPointer);
441         outb(RX_START, sp->ioaddr + SCBCmd);
442         wait_for_cmd_done(sp->ioaddr + SCBCmd);
443
444         /* Setup Tx Ring 
445          */
446         /* Base = 0 */
447         outl(0, sp->ioaddr + SCBPointer);
448         outb(CU_CMD_BASE, sp->ioaddr + SCBCmd);
449         wait_for_cmd_done(sp->ioaddr + SCBCmd);
450         sp->tx_cur = 0;
451         sp->tx_dirty = 0;
452         for (i = 0 ; i < TX_RING_SIZE ; i++) {
453                 sp->txfd[i].link   = virt_to_bus ((i + 1 < TX_RING_SIZE) ? &
454                                                    sp->txfd[i + 1] : &sp->txfd[0]);
455                 sp->txfd[i].command = (CmdSuspend);
456                 sp->txfd[i].status = 0;
457                 sp->txfd[i].tx_desc_addr = virt_to_bus(&sp->txfd[i].tx_buf_addr0);
458         }
459
460         
461         /* Setting up the RX mode */
462         /* Set or clear the multicast filter for this adaptor.
463            This is very ugly with Intel chips -- we usually have to execute an
464            entire configuration command, plus process a multicast command.
465            This is complicated.  We must put a large configuration command and
466            an arbitrarily-sized multicast command in the transmit list.
467            To minimize the disruption -- the previous command might have already
468            loaded the link -- we convert the current command block, normally a Tx
469            command, into a no-op and link it to the new command.
470         */
471         
472                 if (   ((eeprom[6]>>8) & 0x3f) == DP83840
473                || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
474                 int mdi_reg23 = mdio_read(netdev,eeprom[6] & 0x1f, 23) | 0x0422;
475                 if (congenb)
476                         mdi_reg23 |= 0x0100;
477                 DBG("  DP83840 specific setup, setting register 23 to %hX.\n",
478                        mdi_reg23);
479                 mdio_write(netdev,eeprom[6] & 0x1f, 23, mdi_reg23);
480         }
481         DBG ("Done DP8340 special setup.\n");
482         if (options != 0) {
483                 mdio_write(netdev,eeprom[6] & 0x1f, 0,
484                            ((options & 0x20) ? 0x2000 : 0) |    /* 100mbps? */
485                            ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
486                 DBG ("set mdio_register.\n");
487         }
488
489         
490         sp->tx_cur++;
491         sp->tx_dirty++;
492         sp->txfd[0].status = (CmdSuspend | CmdConfigure);
493         uint8_t * config_cmd_data;
494         config_cmd_data = (void *)&sp->txfd[0].tx_desc_addr;
495         /* Construct a full CmdConfig frame. */
496         memcpy(config_cmd_data, i82558_config_cmd, CONFIG_DATA_SIZE);   
497         config_cmd_data[1]  = (txfifo << 4) | rxfifo;
498         config_cmd_data[4]  = rxdmacount;
499         config_cmd_data[5]  = txdmacount + 0x80;
500         config_cmd_data[15] = (rx_mode & 2) ? 0x49: 0x48;
501         config_cmd_data[19] = (options & 0x10) ? 0xC0 : 0x80;
502         config_cmd_data[21] = (rx_mode & 1) ? 0x0D: 0x05;
503
504         outl(virt_to_bus(&sp->txfd[0]), sp->ioaddr + SCBPointer);
505         outb(CU_START, sp->ioaddr + SCBCmd);
506         wait_for_cmd_done(sp->ioaddr + SCBCmd);
507
508         /* Read the status register once to disgard stale data */
509         mdio_read(netdev,eeprom[6] & 0x1f, 1);
510         /* Check to see if the network cable is plugged in.
511          * This allows for faster failure if there is nothing
512          * we can do.
513          */
514         if (!(mdio_read(netdev,eeprom[6] & 0x1f, 1) & (1 << 2))) {
515                 printf("Valid link not established\n");
516                 speedo_disable(netdev);
517                 return -1;
518         }
519
520
521         
522
523         return 0;
524                        
525 }
526
527
528 /** 
529  * Transmit packet
530  *
531  * @v netdev    Network device
532  * @v iobuf     I/O buffer
533  * @ret rc      Return status code
534  */
535 static int speedo_transmit (struct net_device *netdev, struct io_buffer *iobuf)
536 {
537         struct speedo_private *sp = netdev->priv;
538         unsigned short status;
539
540         status = inw(sp->ioaddr + SCBStatus);
541         /* Acknowledge all of the current interrupt sources ASAP. */
542         outw(status & 0xfc00, sp->ioaddr + SCBStatus);
543
544         if ((sp->tx_cur + 1)% TX_RING_SIZE == sp->tx_dirty) {
545                 DBG ("TX overflow\n");
546                 return -ENOBUFS;
547         }
548
549         /* Used by netdev_tx_complete ()
550          */
551         sp->tx_iobuf[sp->tx_cur] = iobuf;
552
553         /* Pad and align packet has not been used because its not required 
554          * by the hardware.
555          *      iob_pad (iobuf, ETH_ZLEN); 
556          * can be used to achieve it, if required
557          */
558
559         /* Add the packet to TX ring
560          */
561
562         sp->txfd[sp->tx_cur].status =  0;
563         sp->txfd[sp->tx_cur].command = CmdSuspend | CmdTx | CmdTxFlex;
564         sp->txfd[sp->tx_cur].count =  0x02208000;
565         sp->txfd[sp->tx_cur].tx_buf_addr0 = virt_to_bus (iobuf->data);
566         sp->txfd[sp->tx_cur].tx_buf_size0 = iob_len(iobuf);
567
568         DBG ("TX id %d at %#08lx + %#08x\n", sp->tx_cur,
569              virt_to_bus (&iobuf->data), iob_len (iobuf));
570
571
572         /* start the transmitter 
573          *
574          * Removing suspend from the command of previous packet.  
575          * As linx driver does
576          */
577         sp->txfd[((sp->tx_cur-1) < 0 ? TX_RING_SIZE -1 : sp->tx_cur -1)].command 
578                                                                 &= ~CmdSuspend; 
579         /* We want the time window between clearing suspend flag on the previous
580            command and resuming CU to be as small as possible.
581            Interrupts in between are very undesired.  --SAW */
582         outb(CUResume, sp->ioaddr + SCBCmd);
583
584         /* increment the circular buffer pointer to the next buffer location
585          */
586         sp->tx_cur = (sp->tx_cur + 1) % TX_RING_SIZE;
587
588         return 0;
589 }
590
591
592
593 /*
594  * Sometimes the receiver stops making progress.  This routine knows how to
595  * get it going again, without losing packets or being otherwise nasty like
596  * a chip reset would be.  Previously the driver had a whole sequence
597  * of if RxSuspended, if it's no buffers do one thing, if it's no resources,
598  * do another, etc.  But those things don't really matter.  Separate logic
599  * in the ISR provides for allocating buffers--the other half of operation
600  * is just making sure the receiver is active.  speedo_rx_soft_reset does that.
601  * This problem with the old, more involved algorithm is shown up under
602  * ping floods on the order of 60K packets/second on a 100Mbps fdx network.
603  */
604 static void
605 speedo_rx_soft_reset(struct net_device *netdev)
606 {
607         struct speedo_private *sp = netdev->priv;
608         int i;
609
610
611         DBG("reset\n");
612         wait_for_cmd_done(sp->ioaddr + SCBCmd);
613         /*
614          * Put the hardware into a known state.
615          */
616         outb(RX_ABORT, sp->ioaddr + SCBCmd);
617
618         for (i = 0; i < NUM_RX_DESC; i++) {
619                 sp->rxfd[i].status      = 0;
620                 sp->rxfd[i].rx_buf_addr = 0xffffffff;
621                 sp->rxfd[i].count       = 0;
622                 sp->rxfd[i].size        = RX_BUF_SIZE;
623         }
624
625         wait_for_cmd_done(sp->ioaddr + SCBCmd);
626
627         outl(virt_to_bus(&sp->rxfd[sp->rx_cur]), sp->ioaddr + SCBPointer);
628         outb(RX_START, sp->ioaddr + SCBCmd);
629 }
630
631
632
633
634
635 /** 
636  * Poll for received packets
637  *
638  * @v netdev    Network device
639  */
640 static void speedo_poll (struct net_device *netdev)
641 {
642         struct speedo_private *sp = netdev->priv;
643         uint16_t tx_status;
644         unsigned int rx_status;
645         unsigned int intr_status;
646         unsigned int rx_len;
647         struct io_buffer *rx_iob;
648         int i;
649         
650         /* read the interrupt register TODO
651          */
652         intr_status = inw (sp->ioaddr + SCBStatus);
653
654         //if (!intr_status)
655         //      goto end;
656
657         DBG ("eepro/speedo speedo_poll: intr_status = %#08x\n", intr_status);
658
659         /* Check status of transmitted packets
660          */
661         i = sp->tx_dirty;
662         while (i != sp->tx_cur) {
663                 tx_status = sp->txfd[sp->tx_dirty].status;
664
665                 DBG ("tx_dirty = %d tx_cur=%d tx_status=%#08x\n",
666                      sp->tx_dirty, sp->tx_cur, tx_status);
667                 
668                 if (( tx_status & StatusComplete ) == 0) 
669                         break;
670
671                 netdev_tx_complete (netdev, sp->tx_iobuf[sp->tx_dirty]);
672                 DBG ("Success transmitting packet\n");
673
674                 sp->tx_dirty = (sp->tx_dirty + 1) % TX_RING_SIZE;
675                 i = (i + 1) % TX_RING_SIZE;
676         }
677         
678         /* Process received packets 
679          */
680         rx_status = sp->rxfd[sp->rx_cur].status; 
681         while (rx_status) {
682                 rx_len = sp->rxfd[sp->rx_cur].count & 0x3fff;
683
684                 DBG ("Received packet, rx_curr = %d, rx_status = %#08x, rx_len = %d\n",
685                      sp->rx_cur, rx_status, rx_len);
686                 /* If unable allocate space for this packet,
687                  *  try again next poll
688                  */
689                 rx_iob = alloc_iob (rx_len);
690                 if (! rx_iob) 
691                         break;
692                 memcpy (iob_put (rx_iob, rx_len), 
693                         sp->rxfd[sp->rx_cur].packet, rx_len);
694                 /* Add this packet to the receive queue. 
695                  */
696                 netdev_rx (netdev, rx_iob);
697                 
698                 sp->rxfd[sp->rx_cur].status = 0;
699                 sp->rxfd[sp->rx_cur].command = 0xc000;
700                 sp->rxfd[sp->rx_cur].rx_buf_addr = 0xFFFFFFFF;
701                 sp->rxfd[sp->rx_cur].count = 0;
702                 sp->rxfd[sp->rx_cur].size = RX_BUF_SIZE;
703                 sp->rxfd[(sp->rx_cur-1)% NUM_RX_DESC].command = 0;
704                 sp->rx_cur = (sp->rx_cur + 1) % NUM_RX_DESC;
705                 rx_status = sp->rxfd[sp->rx_cur].status; 
706                 /* Acknowledge all interrupts */
707                 outw(0xff00,sp->ioaddr + SCBStatus);
708
709         }
710
711         /*
712          * The chip may have suspended reception for various reasons.
713          * Check for that, and re-prime it should this be the case.
714          */
715         switch ((inw(sp->ioaddr + SCBStatus) >> 2) & 0xf) {
716                 case 0:  /* Idle */
717                         break;
718                 case 1:  /* Suspended */
719                 case 2:  /* No resources (RxFDs) */
720                 case 9:  /* Suspended with no more RBDs */
721                 case 10: /* No resources due to no RBDs */
722                 case 12: /* Ready with no RBDs */
723                         speedo_rx_soft_reset(netdev);
724                         break;
725                 default:
726                         /* reserved values */
727                         break;
728         }
729
730 }                               
731
732
733 /**
734  * Remove PCI device
735  *
736  * @v pci       PCI device
737  */
738 static void speedo_remove (struct pci_device *pci) {
739         struct net_device *netdev = pci_get_drvdata (pci);
740
741         unregister_netdev (netdev);
742         speedo_disable (netdev);
743         netdev_put (netdev);
744 }
745
746
747 static struct pci_device_id speedo_nics[] = {
748 PCI_ROM(0x8086, 0x1029, "id1029",        "Intel EtherExpressPro100 ID1029"),
749 PCI_ROM(0x8086, 0x1030, "id1030",        "Intel EtherExpressPro100 ID1030"),
750 PCI_ROM(0x8086, 0x1031, "82801cam",      "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
751 PCI_ROM(0x8086, 0x1032, "eepro100-1032", "Intel PRO/100 VE Network Connection"),
752 PCI_ROM(0x8086, 0x1033, "eepro100-1033", "Intel PRO/100 VM Network Connection"),
753 PCI_ROM(0x8086, 0x1034, "eepro100-1034", "Intel PRO/100 VM Network Connection"),
754 PCI_ROM(0x8086, 0x1035, "eepro100-1035", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
755 PCI_ROM(0x8086, 0x1036, "eepro100-1036", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
756 PCI_ROM(0x8086, 0x1037, "eepro100-1037", "Intel 82801CAM (ICH3) Chipset Ethernet Controller"),
757 PCI_ROM(0x8086, 0x1038, "id1038",        "Intel PRO/100 VM Network Connection"),
758 PCI_ROM(0x8086, 0x1039, "82562et",       "Intel PRO100 VE 82562ET"),
759 PCI_ROM(0x8086, 0x103a, "id103a",        "Intel Corporation 82559 InBusiness 10/100"),
760 PCI_ROM(0x8086, 0x103b, "82562etb",      "Intel PRO100 VE 82562ETB"),
761 PCI_ROM(0x8086, 0x103c, "eepro100-103c", "Intel PRO/100 VM Network Connection"),
762 PCI_ROM(0x8086, 0x103d, "eepro100-103d", "Intel PRO/100 VE Network Connection"),
763 PCI_ROM(0x8086, 0x103e, "eepro100-103e", "Intel PRO/100 VM Network Connection"),
764 PCI_ROM(0x8086, 0x1051, "prove",       "Intel PRO/100 VE Network Connection"),
765 PCI_ROM(0x8086, 0x1059, "82551qm",       "Intel PRO/100 M Mobile Connection"),
766 PCI_ROM(0x8086, 0x1209, "82559er",       "Intel EtherExpressPro100 82559ER"),
767 PCI_ROM(0x8086, 0x1227, "82865",         "Intel 82865 EtherExpress PRO/100A"),
768 PCI_ROM(0x8086, 0x1228, "82556",         "Intel 82556 EtherExpress PRO/100 Smart"),
769 PCI_ROM(0x8086, 0x1229, "eepro100",      "Intel EtherExpressPro100"),
770 PCI_ROM(0x8086, 0x2449, "82562em",       "Intel EtherExpressPro100 82562EM"),
771 PCI_ROM(0x8086, 0x2459, "82562-1",       "Intel 82562 based Fast Ethernet Connection"),
772 PCI_ROM(0x8086, 0x245d, "82562-2",       "Intel 82562 based Fast Ethernet Connection"),
773 PCI_ROM(0x8086, 0x1050, "82562ez",       "Intel 82562EZ Network Connection"),
774 PCI_ROM(0x8086, 0x1051, "eepro100-1051", "Intel 82801EB/ER (ICH5/ICH5R) Chipset Ethernet Controller"),
775 PCI_ROM(0x8086, 0x5200, "eepro100-5200", "Intel EtherExpress PRO/100 Intelligent Server"),
776 PCI_ROM(0x8086, 0x5201, "eepro100-5201", "Intel EtherExpress PRO/100 Intelligent Server"),
777 };
778
779 struct pci_driver epro100_driver __pci_driver = {
780         .ids = speedo_nics,
781         .id_count = (sizeof (speedo_nics) / sizeof (speedo_nics[0])),
782         .probe = speedo_probe,
783         .remove = speedo_remove,
784 };