~smartboyhw/wubi/bug-1080090-new

« back to all changes in this revision

Viewing changes to src/grub4dos/netboot/.svn/text-base/eepro100.c.svn-base

  • Committer: Howard Chan
  • Date: 2012-11-20 10:16:05 UTC
  • Revision ID: smartboyhw@gmail.com-20121120101605-qfmjfsdynpzg9an9
Added images

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * eepro100.c -- This file implements the eepro100 driver for etherboot.
3
 
 *
4
 
 *
5
 
 * Copyright (C) AW Computer Systems.
6
 
 * written by R.E.Wolff -- R.E.Wolff@BitWizard.nl
7
 
 *
8
 
 *
9
 
 * AW Computer Systems is contributing to the free software community
10
 
 * by paying for this driver and then putting the result under GPL.
11
 
 *
12
 
 * If you need a Linux device driver, please contact BitWizard for a
13
 
 * quote.
14
 
 *
15
 
 *
16
 
 * This program is free software; you can redistribute it and/or
17
 
 * modify it under the terms of the GNU General Public License as
18
 
 * published by the Free Software Foundation; either version 2, or (at
19
 
 * your option) any later version.
20
 
 *
21
 
 * This program is distributed in the hope that it will be useful, but
22
 
 * WITHOUT ANY WARRANTY; without even the implied warranty of
23
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
24
 
 * General Public License for more details.
25
 
 *
26
 
 * You should have received a copy of the GNU General Public License
27
 
 * along with this program; if not, write to the Free Software
28
 
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29
 
 *
30
 
 *
31
 
 *              date       version  by   what
32
 
 *  Written:    May 29 1997  V0.10  REW  Initial revision.
33
 
 * changes:     May 31 1997  V0.90  REW  Works!
34
 
 *              Jun 1  1997  V0.91  REW  Cleanup
35
 
 *              Jun 2  1997  V0.92  REW  Add some code documentation
36
 
 *              Jul 25 1997  V1.00  REW  Tested by AW to work in a PROM
37
 
 *                                       Cleanup for publication
38
 
 *
39
 
 * This is the etherboot intel etherexpress Pro/100B driver.
40
 
 *
41
 
 * It was written from scratch, with Donald Beckers eepro100.c kernel
42
 
 * driver as a guideline. Mostly the 82557 related definitions and the
43
 
 * lower level routines have been cut-and-pasted into this source.
44
 
 *
45
 
 * The driver was finished before Intel got the NDA out of the closet.
46
 
 * I still don't have the docs.
47
 
 * */
48
 
 
49
 
/* Philosophy of this driver.
50
 
 *
51
 
 * Probing:
52
 
 *
53
 
 * Using the pci.c functions of the Etherboot code, the 82557 chip is detected.
54
 
 * It is verified that the BIOS initialized everything properly and if
55
 
 * something is missing it is done now.
56
 
 *
57
 
 *
58
 
 * Initialization:
59
 
 *
60
 
 *
61
 
 * The chip is then initialized to "know" its ethernet address, and to
62
 
 * start recieving packets. The Linux driver has a whole transmit and
63
 
 * recieve ring of buffers. This is neat if you need high performance:
64
 
 * you can write the buffers asynchronously to the chip reading the
65
 
 * buffers and transmitting them over the network.  Performance is NOT
66
 
 * an issue here. We can boot a 400k kernel in about two
67
 
 * seconds. (Theory: 0.4 seconds). Booting a system is going to take
68
 
 * about half a minute anyway, so getting 10 times closer to the
69
 
 * theoretical limit is going to make a difference of a few percent.
70
 
 *
71
 
 *
72
 
 * Transmitting and recieving.
73
 
 *
74
 
 * We have only one transmit descriptor. It has two buffer descriptors:
75
 
 * one for the header, and the other for the data.
76
 
 * We have only one receive buffer. The chip is told to recieve packets,
77
 
 * and suspend itself once it got one. The recieve (poll) routine simply
78
 
 * looks at the recieve buffer to see if there is already a packet there.
79
 
 * if there is, the buffer is copied, and the reciever is restarted.
80
 
 *
81
 
 * Caveats:
82
 
 *
83
 
 * The etherboot framework moves the code to the 32k segment from
84
 
 * 0x98000 to 0xa0000. There is just a little room between the end of
85
 
 * this driver and the 0xa0000 address. If you compile in too many
86
 
 * features, this will overflow.
87
 
 * The number under "hex" in the output of size that scrolls by while
88
 
 * compiling should be less than 8000. Maybe even the stack is up there,
89
 
 * so that you need even more headroom.
90
 
 */
91
 
 
92
 
/* The etherboot authors seem to dislike the argument ordering in
93
 
 * outb macros that Linux uses. I disklike the confusion that this
94
 
 * has caused even more.... This file uses the Linux argument ordering.  */
95
 
/* Sorry not us. It's inherted code from FreeBSD. [The authors] */
96
 
 
97
 
#include "etherboot.h"
98
 
#include "nic.h"
99
 
#include "pci.h"
100
 
#include "cards.h"
101
 
#include "timer.h"
102
 
 
103
 
#undef  virt_to_bus
104
 
#define virt_to_bus(x)  ((unsigned long)x)
105
 
 
106
 
static int ioaddr;
107
 
 
108
 
typedef unsigned char  u8;
109
 
typedef   signed char  s8;
110
 
typedef unsigned short u16;
111
 
typedef   signed short s16;
112
 
typedef unsigned int   u32;
113
 
typedef   signed int   s32;
114
 
 
115
 
enum speedo_offsets {
116
 
  SCBStatus = 0, SCBCmd = 2,      /* Rx/Command Unit command and status. */
117
 
  SCBPointer = 4,                 /* General purpose pointer. */
118
 
  SCBPort = 8,                    /* Misc. commands and operands.  */
119
 
  SCBflash = 12, SCBeeprom = 14,  /* EEPROM and flash memory control. */
120
 
  SCBCtrlMDI = 16,                /* MDI interface control. */
121
 
  SCBEarlyRx = 20,                /* Early receive byte count. */
122
 
};
123
 
 
124
 
static int do_eeprom_cmd(int cmd, int cmd_len);
125
 
void hd(void *where, int n);
126
 
 
127
 
/***********************************************************************/
128
 
/*                       I82557 related defines                        */
129
 
/***********************************************************************/
130
 
 
131
 
/* Serial EEPROM section.
132
 
   A "bit" grungy, but we work our way through bit-by-bit :->. */
133
 
/*  EEPROM_Ctrl bits. */
134
 
#define EE_SHIFT_CLK    0x01    /* EEPROM shift clock. */
135
 
#define EE_CS           0x02    /* EEPROM chip select. */
136
 
#define EE_DATA_WRITE   0x04    /* EEPROM chip data in. */
137
 
#define EE_DATA_READ    0x08    /* EEPROM chip data out. */
138
 
#define EE_WRITE_0      0x4802
139
 
#define EE_WRITE_1      0x4806
140
 
#define EE_ENB          (0x4800 | EE_CS)
141
 
 
142
 
#define udelay(n)       waiton_timer2(((n)*TICKS_PER_MS)/1000)
143
 
 
144
 
/* The EEPROM commands include the alway-set leading bit. */
145
 
#define EE_READ_CMD     6
146
 
 
147
 
/* The SCB accepts the following controls for the Tx and Rx units: */
148
 
#define  CU_START       0x0010
149
 
#define  CU_RESUME      0x0020
150
 
#define  CU_STATSADDR   0x0040
151
 
#define  CU_SHOWSTATS   0x0050  /* Dump statistics counters. */
152
 
#define  CU_CMD_BASE    0x0060  /* Base address to add to add CU commands. */
153
 
#define  CU_DUMPSTATS   0x0070  /* Dump then reset stats counters. */
154
 
 
155
 
#define  RX_START       0x0001
156
 
#define  RX_RESUME      0x0002
157
 
#define  RX_ABORT       0x0004
158
 
#define  RX_ADDR_LOAD   0x0006
159
 
#define  RX_RESUMENR    0x0007
160
 
#define INT_MASK        0x0100
161
 
#define DRVR_INT        0x0200          /* Driver generated interrupt. */
162
 
 
163
 
enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
164
 
                                         S80C24, PhyUndefined, DP83840A=10, };
165
 
 
166
 
/* Commands that can be put in a command list entry. */
167
 
enum commands {
168
 
  CmdNOp = 0,
169
 
  CmdIASetup = 1,
170
 
  CmdConfigure = 2,
171
 
  CmdMulticastList = 3,
172
 
  CmdTx = 4,
173
 
  CmdTDR = 5,
174
 
  CmdDump = 6,
175
 
  CmdDiagnose = 7,
176
 
 
177
 
  /* And some extra flags: */
178
 
  CmdSuspend = 0x4000,      /* Suspend after completion. */
179
 
  CmdIntr = 0x2000,         /* Interrupt after completion. */
180
 
  CmdTxFlex = 0x0008,       /* Use "Flexible mode" for CmdTx command. */
181
 
};
182
 
 
183
 
/* How to wait for the command unit to accept a command.
184
 
   Typically this takes 0 ticks. */
185
 
static inline void wait_for_cmd_done(int cmd_ioaddr)
186
 
{
187
 
  short wait = 100;
188
 
  do   ;
189
 
  while(inb(cmd_ioaddr) && --wait >= 0);
190
 
}
191
 
 
192
 
/* Elements of the dump_statistics block. This block must be lword aligned. */
193
 
static struct speedo_stats {
194
 
        u32 tx_good_frames;
195
 
        u32 tx_coll16_errs;
196
 
        u32 tx_late_colls;
197
 
        u32 tx_underruns;
198
 
        u32 tx_lost_carrier;
199
 
        u32 tx_deferred;
200
 
        u32 tx_one_colls;
201
 
        u32 tx_multi_colls;
202
 
        u32 tx_total_colls;
203
 
        u32 rx_good_frames;
204
 
        u32 rx_crc_errs;
205
 
        u32 rx_align_errs;
206
 
        u32 rx_resource_errs;
207
 
        u32 rx_overrun_errs;
208
 
        u32 rx_colls_errs;
209
 
        u32 rx_runt_errs;
210
 
        u32 done_marker;
211
 
} lstats;
212
 
 
213
 
/* A speedo3 TX buffer descriptor with two buffers... */
214
 
static struct TxFD {
215
 
  volatile s16 status;
216
 
  s16 command;
217
 
  u32 link;          /* void * */
218
 
  u32 tx_desc_addr;  /* (almost) Always points to the tx_buf_addr element. */
219
 
  s32 count;         /* # of TBD (=2), Tx start thresh., etc. */
220
 
                     /* This constitutes two "TBD" entries: hdr and data */
221
 
  u32 tx_buf_addr0;  /* void *, header of frame to be transmitted.  */
222
 
  s32 tx_buf_size0;  /* Length of Tx hdr. */
223
 
  u32 tx_buf_addr1;  /* void *, data to be transmitted.  */
224
 
  s32 tx_buf_size1;  /* Length of Tx data. */
225
 
} txfd;
226
 
 
227
 
struct RxFD {               /* Receive frame descriptor. */
228
 
  volatile s16 status;
229
 
  s16 command;
230
 
  u32 link;                 /* struct RxFD * */
231
 
  u32 rx_buf_addr;          /* void * */
232
 
  u16 count;
233
 
  u16 size;
234
 
  char packet[1518];
235
 
};
236
 
 
237
 
#ifdef  USE_LOWMEM_BUFFER
238
 
#define rxfd ((struct RxFD *)(0x10000 - sizeof(struct RxFD)))
239
 
#define ACCESS(x) x->
240
 
#else
241
 
static struct RxFD rxfd;
242
 
#define ACCESS(x) x.
243
 
#endif
244
 
 
245
 
static int congenb = 0;         /* Enable congestion control in the DP83840. */
246
 
static int txfifo = 8;          /* Tx FIFO threshold in 4 byte units, 0-15 */
247
 
static int rxfifo = 8;          /* Rx FIFO threshold, default 32 bytes. */
248
 
static int txdmacount = 0;      /* Tx DMA burst length, 0-127, default 0. */
249
 
static int rxdmacount = 0;      /* Rx DMA length, 0 means no preemption. */
250
 
 
251
 
/* I don't understand a byte in this structure. It was copied from the
252
 
 * Linux kernel initialization for the eepro100. -- REW */
253
 
static struct ConfCmd {
254
 
  s16 status;
255
 
  s16 command;
256
 
  u32 link;
257
 
  unsigned char data[22];
258
 
} confcmd = {
259
 
  0, CmdConfigure,
260
 
  (u32) & txfd,
261
 
  {22, 0x08, 0, 0,  0, 0x80, 0x32, 0x03,  1, /* 1=Use MII  0=Use AUI */
262
 
   0, 0x2E, 0,  0x60, 0,
263
 
   0xf2, 0x48,   0, 0x40, 0xf2, 0x80,        /* 0x40=Force full-duplex */
264
 
   0x3f, 0x05, }
265
 
};
266
 
 
267
 
/***********************************************************************/
268
 
/*                       Locally used functions                        */
269
 
/***********************************************************************/
270
 
 
271
 
/* Support function: mdio_write
272
 
 *
273
 
 * This probably writes to the "physical media interface chip".
274
 
 * -- REW
275
 
 */
276
 
 
277
 
static int mdio_write(int phy_id, int location, int value)
278
 
{
279
 
  int val, boguscnt = 64*4;         /* <64 usec. to complete, typ 27 ticks */
280
 
 
281
 
  outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
282
 
       ioaddr + SCBCtrlMDI);
283
 
  do {
284
 
    udelay(16);
285
 
 
286
 
    val = inl(ioaddr + SCBCtrlMDI);
287
 
    if (--boguscnt < 0) {
288
 
      printf(" mdio_write() timed out with val = %X.\n", val);
289
 
    }
290
 
  } while (! (val & 0x10000000));
291
 
  return val & 0xffff;
292
 
}
293
 
 
294
 
/* Support function: mdio_read
295
 
 *
296
 
 * This probably reads a register in the "physical media interface chip".
297
 
 * -- REW
298
 
 */
299
 
static int mdio_read(int phy_id, int location)
300
 
{
301
 
  int val, boguscnt = 64*4;               /* <64 usec. to complete, typ 27 ticks */
302
 
  outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
303
 
  do {
304
 
    udelay(16);
305
 
 
306
 
    val = inl(ioaddr + SCBCtrlMDI);
307
 
    if (--boguscnt < 0) {
308
 
      printf( " mdio_read() timed out with val = %X.\n", val);
309
 
    }
310
 
  } while (! (val & 0x10000000));
311
 
  return val & 0xffff;
312
 
}
313
 
 
314
 
/* The fixes for the code were kindly provided by Dragan Stancevic
315
 
   <visitor@valinux.com> to strictly follow Intel specifications of EEPROM
316
 
   access timing.
317
 
   The publicly available sheet 64486302 (sec. 3.1) specifies 1us access
318
 
   interval for serial EEPROM.  However, it looks like that there is an
319
 
   additional requirement dictating larger udelay's in the code below.
320
 
   2000/05/24  SAW */
321
 
static int do_eeprom_cmd(int cmd, int cmd_len)
322
 
{
323
 
        unsigned retval = 0;
324
 
        long ee_addr = ioaddr + SCBeeprom;
325
 
 
326
 
        outw(EE_ENB, ee_addr); udelay(2);
327
 
        outw(EE_ENB | EE_SHIFT_CLK, ee_addr); udelay(2);
328
 
 
329
 
        /* Shift the command bits out. */
330
 
        do {
331
 
                short dataval = (cmd & (1 << cmd_len)) ? EE_WRITE_1 : EE_WRITE_0;
332
 
                outw(dataval, ee_addr); udelay(2);
333
 
                outw(dataval | EE_SHIFT_CLK, ee_addr); udelay(2);
334
 
                retval = (retval << 1) | ((inw(ee_addr) & EE_DATA_READ) ? 1 : 0);
335
 
        } while (--cmd_len >= 0);
336
 
        outw(EE_ENB, ee_addr); udelay(2);
337
 
 
338
 
        /* Terminate the EEPROM access. */
339
 
        outw(EE_ENB & ~EE_CS, ee_addr);
340
 
        return retval;
341
 
}
342
 
 
343
 
static inline void whereami (const char *str)
344
 
{
345
 
#if     0
346
 
  printf ("%s\n", str);
347
 
  sleep (2);
348
 
#endif
349
 
}
350
 
 
351
 
/* function: eepro100_reset
352
 
 * resets the card. This is used to allow Etherboot to probe the card again
353
 
 * from a "virginal" state....
354
 
 * Arguments: none
355
 
 *
356
 
 * returns:   void.
357
 
 */
358
 
 
359
 
static void eepro100_reset(struct nic *nic)
360
 
{
361
 
  outl(0, ioaddr + SCBPort);
362
 
}
363
 
 
364
 
/* function: eepro100_transmit
365
 
 * This transmits a packet.
366
 
 *
367
 
 * Arguments: char d[6]:          destination ethernet address.
368
 
 *            unsigned short t:   ethernet protocol type.
369
 
 *            unsigned short s:   size of the data-part of the packet.
370
 
 *            char *p:            the data for the packet.
371
 
 * returns:   void.
372
 
 */
373
 
 
374
 
static void eepro100_transmit(struct nic *nic, const char *d, unsigned int t, unsigned int s, const char *p)
375
 
{
376
 
  struct eth_hdr {
377
 
    unsigned char dst_addr[ETH_ALEN];
378
 
    unsigned char src_addr[ETH_ALEN];
379
 
    unsigned short type;
380
 
  } hdr;
381
 
  unsigned short status;
382
 
  int to;
383
 
  int s1, s2;
384
 
 
385
 
  status = inw(ioaddr + SCBStatus);
386
 
  /* Acknowledge all of the current interrupt sources ASAP. */
387
 
  outw(status & 0xfc00, ioaddr + SCBStatus);
388
 
 
389
 
#ifdef  DEBUG
390
 
  printf ("transmitting type %hX packet (%d bytes). status = %hX, cmd=%hX\n",
391
 
          t, s, status, inw (ioaddr + SCBCmd));
392
 
#endif
393
 
 
394
 
  memcpy (&hdr.dst_addr, d, ETH_ALEN);
395
 
  memcpy (&hdr.src_addr, nic->node_addr, ETH_ALEN);
396
 
 
397
 
  hdr.type = htons (t);
398
 
 
399
 
  txfd.status = 0;
400
 
  txfd.command = CmdSuspend | CmdTx | CmdTxFlex;
401
 
  txfd.link   = virt_to_bus (&txfd);
402
 
  txfd.count   = 0x02208000;
403
 
  txfd.tx_desc_addr = (u32)&txfd.tx_buf_addr0;
404
 
 
405
 
  txfd.tx_buf_addr0 = virt_to_bus (&hdr);
406
 
  txfd.tx_buf_size0 = sizeof (hdr);
407
 
 
408
 
  txfd.tx_buf_addr1 = virt_to_bus (p);
409
 
  txfd.tx_buf_size1 = s;
410
 
 
411
 
#ifdef  DEBUG
412
 
  printf ("txfd: \n");
413
 
  hd (&txfd, sizeof (txfd));
414
 
#endif
415
 
 
416
 
  outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
417
 
  outw(INT_MASK | CU_START, ioaddr + SCBCmd);
418
 
  wait_for_cmd_done(ioaddr + SCBCmd);
419
 
 
420
 
  s1 = inw (ioaddr + SCBStatus);
421
 
  load_timer2(10*TICKS_PER_MS);         /* timeout 10 ms for transmit */
422
 
  while (!txfd.status && timer2_running())
423
 
    /* Wait */;
424
 
  s2 = inw (ioaddr + SCBStatus);
425
 
 
426
 
#ifdef  DEBUG
427
 
  printf ("s1 = %hX, s2 = %hX.\n", s1, s2);
428
 
#endif
429
 
}
430
 
 
431
 
/* function: eepro100_poll / eth_poll
432
 
 * This recieves a packet from the network.
433
 
 *
434
 
 * Arguments: none
435
 
 *
436
 
 * returns:   1 if a packet was recieved.
437
 
 *            0 if no pacet was recieved.
438
 
 * side effects:
439
 
 *            returns the packet in the array nic->packet.
440
 
 *            returns the length of the packet in nic->packetlen.
441
 
 */
442
 
 
443
 
static int eepro100_poll(struct nic *nic)
444
 
{
445
 
  if (!ACCESS(rxfd)status)
446
 
    return 0;
447
 
 
448
 
  /* Ok. We got a packet. Now restart the reciever.... */
449
 
  ACCESS(rxfd)status = 0;
450
 
  ACCESS(rxfd)command = 0xc000;
451
 
  outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
452
 
  outw(INT_MASK | RX_START, ioaddr + SCBCmd);
453
 
  wait_for_cmd_done(ioaddr + SCBCmd);
454
 
 
455
 
#ifdef  DEBUG
456
 
  printf ("Got a packet: Len = %d.\n", ACCESS(rxfd)count & 0x3fff);
457
 
#endif
458
 
  nic->packetlen =  ACCESS(rxfd)count & 0x3fff;
459
 
  memcpy (nic->packet, ACCESS(rxfd)packet, nic->packetlen);
460
 
#ifdef  DEBUG
461
 
  hd (nic->packet, 0x30);
462
 
#endif
463
 
  return 1;
464
 
}
465
 
 
466
 
static void eepro100_disable(struct nic *nic)
467
 
{
468
 
    /* See if this PartialReset solves the problem with interfering with
469
 
       kernel operation after Etherboot hands over. - Ken 20001102 */
470
 
    outl(2, ioaddr + SCBPort);
471
 
}
472
 
 
473
 
/* exported function: eepro100_probe / eth_probe
474
 
 * initializes a card
475
 
 *
476
 
 * side effects:
477
 
 *            leaves the ioaddress of the 82557 chip in the variable ioaddr.
478
 
 *            leaves the 82557 initialized, and ready to recieve packets.
479
 
 */
480
 
 
481
 
struct nic *eepro100_probe(struct nic *nic, unsigned short *probeaddrs, struct pci_device *p)
482
 
{
483
 
        unsigned short sum = 0;
484
 
        int i;
485
 
        int read_cmd, ee_size;
486
 
        unsigned short value;
487
 
        int options;
488
 
        int promisc;
489
 
 
490
 
        /* we cache only the first few words of the EEPROM data
491
 
           be careful not to access beyond this array */
492
 
        unsigned short eeprom[16];
493
 
 
494
 
        if (probeaddrs == 0 || probeaddrs[0] == 0)
495
 
                return 0;
496
 
        ioaddr = probeaddrs[0] & ~3; /* Mask the bit that says "this is an io addr" */
497
 
 
498
 
        adjust_pci_device(p);
499
 
 
500
 
        if ((do_eeprom_cmd(EE_READ_CMD << 24, 27) & 0xffe0000)
501
 
                == 0xffe0000) {
502
 
                ee_size = 0x100;
503
 
                read_cmd = EE_READ_CMD << 24;
504
 
        } else {
505
 
                ee_size = 0x40;
506
 
                read_cmd = EE_READ_CMD << 22;
507
 
        }
508
 
 
509
 
        for (i = 0, sum = 0; i < ee_size; i++) {
510
 
                unsigned short value = do_eeprom_cmd(read_cmd | (i << 16), 27);
511
 
                if (i < (int)(sizeof(eeprom)/sizeof(eeprom[0])))
512
 
                        eeprom[i] = value;
513
 
                sum += value;
514
 
        }
515
 
 
516
 
  for (i=0;i<ETH_ALEN;i++) {
517
 
        nic->node_addr[i] =  (eeprom[i/2] >> (8*(i&1))) & 0xff;
518
 
  }
519
 
  printf ("Ethernet addr: %!\n", nic->node_addr);
520
 
 
521
 
  if (sum != 0xBABA)
522
 
        printf("eepro100: Invalid EEPROM checksum %#hX, "
523
 
               "check settings before activating this device!\n", sum);
524
 
  outl(0, ioaddr + SCBPort);
525
 
  udelay (10000);
526
 
 
527
 
  whereami ("Got eeprom.");
528
 
 
529
 
  outl(virt_to_bus(&lstats), ioaddr + SCBPointer);
530
 
  outw(INT_MASK | CU_STATSADDR, ioaddr + SCBCmd);
531
 
  wait_for_cmd_done(ioaddr + SCBCmd);
532
 
 
533
 
  whereami ("set stats addr.");
534
 
  /* INIT RX stuff. */
535
 
 
536
 
  /* Base = 0 */
537
 
  outl(0, ioaddr + SCBPointer);
538
 
  outw(INT_MASK | RX_ADDR_LOAD, ioaddr + SCBCmd);
539
 
  wait_for_cmd_done(ioaddr + SCBCmd);
540
 
 
541
 
  whereami ("set rx base addr.");
542
 
 
543
 
  ACCESS(rxfd)status  = 0x0001;
544
 
  ACCESS(rxfd)command = 0x0000;
545
 
  ACCESS(rxfd)link    = virt_to_bus(&(ACCESS(rxfd)status));
546
 
  ACCESS(rxfd)rx_buf_addr = (int) &nic->packet;
547
 
  ACCESS(rxfd)count   = 0;
548
 
  ACCESS(rxfd)size    = 1528;
549
 
 
550
 
  outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
551
 
  outw(INT_MASK | RX_START, ioaddr + SCBCmd);
552
 
  wait_for_cmd_done(ioaddr + SCBCmd);
553
 
 
554
 
  whereami ("started RX process.");
555
 
 
556
 
  /* Start the reciever.... */
557
 
  ACCESS(rxfd)status = 0;
558
 
  ACCESS(rxfd)command = 0xc000;
559
 
  outl(virt_to_bus(&(ACCESS(rxfd)status)), ioaddr + SCBPointer);
560
 
  outw(INT_MASK | RX_START, ioaddr + SCBCmd);
561
 
 
562
 
  /* INIT TX stuff. */
563
 
 
564
 
  /* Base = 0 */
565
 
  outl(0, ioaddr + SCBPointer);
566
 
  outw(INT_MASK | CU_CMD_BASE, ioaddr + SCBCmd);
567
 
  wait_for_cmd_done(ioaddr + SCBCmd);
568
 
 
569
 
  whereami ("set TX base addr.");
570
 
 
571
 
  txfd.command      = (CmdIASetup);
572
 
  txfd.status       = 0x0000;
573
 
  txfd.link         = virt_to_bus (&confcmd);
574
 
 
575
 
  {
576
 
        char *t = (char *)&txfd.tx_desc_addr;
577
 
 
578
 
        for (i=0;i<ETH_ALEN;i++)
579
 
                t[i] = nic->node_addr[i];
580
 
  }
581
 
 
582
 
#ifdef  DEBUG
583
 
  printf ("Setup_eaddr:\n");
584
 
  hd (&txfd, 0x20);
585
 
#endif
586
 
  /*      options = 0x40; */ /* 10mbps half duplex... */
587
 
  options = 0x00;            /* Autosense */
588
 
 
589
 
  promisc = 0;
590
 
 
591
 
  if (   ((eeprom[6]>>8) & 0x3f) == DP83840
592
 
          || ((eeprom[6]>>8) & 0x3f) == DP83840A) {
593
 
        int mdi_reg23 = mdio_read(eeprom[6] & 0x1f, 23) | 0x0422;
594
 
        if (congenb)
595
 
          mdi_reg23 |= 0x0100;
596
 
        printf("  DP83840 specific setup, setting register 23 to %hX.\n",
597
 
               mdi_reg23);
598
 
        mdio_write(eeprom[6] & 0x1f, 23, mdi_reg23);
599
 
  }
600
 
  whereami ("Done DP8340 special setup.");
601
 
  if (options != 0) {
602
 
        mdio_write(eeprom[6] & 0x1f, 0,
603
 
                   ((options & 0x20) ? 0x2000 : 0) |    /* 100mbps? */
604
 
                   ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
605
 
        whereami ("set mdio_register.");
606
 
  }
607
 
 
608
 
  confcmd.command  = CmdSuspend | CmdConfigure;
609
 
  confcmd.status   = 0x0000;
610
 
  confcmd.link     = virt_to_bus (&txfd);
611
 
  confcmd.data[1]  = (txfifo << 4) | rxfifo;
612
 
  confcmd.data[4]  = rxdmacount;
613
 
  confcmd.data[5]  = txdmacount + 0x80;
614
 
  confcmd.data[15] = promisc ? 0x49: 0x48;
615
 
  confcmd.data[19] = (options & 0x10) ? 0xC0 : 0x80;
616
 
  confcmd.data[21] = promisc ? 0x0D: 0x05;
617
 
 
618
 
  outl(virt_to_bus(&txfd), ioaddr + SCBPointer);
619
 
  outw(INT_MASK | CU_START, ioaddr + SCBCmd);
620
 
  wait_for_cmd_done(ioaddr + SCBCmd);
621
 
 
622
 
  whereami ("started TX thingy (config, iasetup).");
623
 
 
624
 
  load_timer2(10*TICKS_PER_MS);
625
 
  while (!txfd.status && timer2_running())
626
 
        /* Wait */;
627
 
 
628
 
  nic->reset = eepro100_reset;
629
 
  nic->poll = eepro100_poll;
630
 
  nic->transmit = eepro100_transmit;
631
 
  nic->disable = eepro100_disable;
632
 
  return nic;
633
 
}
634
 
 
635
 
/*********************************************************************/
636
 
 
637
 
#ifdef  DEBUG
638
 
 
639
 
/* Hexdump a number of bytes from memory... */
640
 
void hd (void *where, int n)
641
 
{
642
 
  int i;
643
 
 
644
 
  while (n > 0) {
645
 
    printf ("%X ", where);
646
 
    for (i=0;i < ( (n>16)?16:n);i++)
647
 
      printf (" %hhX", ((char *)where)[i]);
648
 
    printf ("\n");
649
 
    n -= 16;
650
 
    where += 16;
651
 
  }
652
 
}
653
 
#endif
654