source: rtems/c/src/libchip/network/elnk.c @ 6542918f

4.104.114.84.9
Last change on this file since 6542918f was 6542918f, checked in by Ralf Corsepius <ralf.corsepius@…>, on Apr 1, 2007 at 4:00:10 AM

i386-specific adjustments to pci-API changes.

  • Property mode set to 100644
File size: 98.8 KB
Line 
1/*
2 *  RTEMS driver for Etherlink based Ethernet Controllers
3 *
4 *  Copyright (C) 2003, Gregory Menke, NASA/GSFC
5 *
6 *  The license and distribution terms for this file may be
7 *  found in found in the file LICENSE in this distribution or at
8 *  http://www.rtems.com/license/LICENSE.
9 *
10 * elnk.c
11 *
12 *
13 */
14
15
16/*
17 * Portions of this driver are taken from the Freebsd if_xl.c driver,
18 * version "1.133 2003/03/19 01:48:14" and are covered by the license
19 * text included below that was taken verbatim from the original file.
20 * More particularly, all structures, variables, and #defines prefixed
21 * with XL_ or xl_, along with their associated comments were taken
22 * directly from the Freebsd driver and modified as required to suit the
23 * purposes of this one.  Additionally, much of the device setup &
24 * manipulation logic was also copied and modified to suit.  All types
25 * and functions beginning with elnk are either my own creations or were
26 * adapted from other RTEMS components, and regardless, are subject to
27 * the standard OAR licensing terms given in the comments at the top of
28 * this file.
29 *
30 * Greg Menke, 6/11/2003
31 */
32
33 /*
34 * Copyright (c) 1997, 1998, 1999
35 *      Bill Paul <wpaul@ctr.columbia.edu>.  All rights reserved.
36 *
37 * Redistribution and use in source and binary forms, with or without
38 * modification, are permitted provided that the following conditions
39 * are met:
40 * 1. Redistributions of source code must retain the above copyright
41 *    notice, this list of conditions and the following disclaimer.
42 * 2. Redistributions in binary form must reproduce the above copyright
43 *    notice, this list of conditions and the following disclaimer in the
44 *    documentation and/or other materials provided with the distribution.
45 * 3. All advertising materials mentioning features or use of this software
46 *    must display the following acknowledgement:
47 *      This product includes software developed by Bill Paul.
48 * 4. Neither the name of the author nor the names of any co-contributors
49 *    may be used to endorse or promote products derived from this software
50 *    without specific prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED.  IN NO EVENT SHALL Bill Paul OR THE VOICES IN HIS HEAD
56 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
57 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
58 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
59 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
62 * THE POSSIBILITY OF SUCH DAMAGE.
63 */
64
65#include <rtems.h>
66
67/*
68 *  This driver only supports architectures with the new style
69 *  exception processing.  The following checks try to keep this
70 *  from being compiled on systems which can't support this driver.
71 */
72
73#if defined(__i386__)
74#define ELNK_SUPPORTED
75#endif
76
77#if defined(__PPC__) && (defined(mpc604) || defined(mpc750) || defined(mpc603e))
78#define ELNK_SUPPORTED
79#endif
80
81/* #undef ELNK_SUPPORTED */
82
83
84#if defined(ELNK_SUPPORTED)
85#include <bsp.h>
86#include <rtems/pci.h>
87
88#if defined(__PPC__)
89#include <libcpu/byteorder.h>
90#include <libcpu/io.h>
91#endif
92
93#if defined(__i386__)
94#include <libcpu/byteorder.h>
95#endif
96
97#include <stdlib.h>
98#include <stdio.h>
99#include <stdarg.h>
100#include <string.h>
101#include <errno.h>
102#include <rtems/error.h>
103#include <rtems/bspIo.h>
104#include <rtems/rtems_bsdnet.h>
105
106#include <sys/param.h>
107#include <sys/mbuf.h>
108
109#include <sys/socket.h>
110#include <sys/sockio.h>
111#include <net/if.h>
112#include <netinet/in.h>
113#include <netinet/if_ether.h>
114
115#include <net/if_media.h>
116#include <dev/mii/mii.h>
117#include <bsp/irq.h>
118
119#if defined(__i386__)
120#define IO_MASK   0x3
121#define MEM_MASK  0xF
122#endif
123
124#ifdef malloc
125#undef malloc
126#endif
127#ifdef free
128#undef free
129#endif
130
131#define ELNK_DEBUG
132
133
134#define DRIVER_PREFIX   "elnk"
135
136
137
138
139
140/*
141* These buffers allocated for each unit, so ensure
142*
143*   rtems_bsdnet_config.mbuf_bytecount
144*   rtems_bsdnet_config.mbuf_cluster_bytecount
145*
146* are adequately sized to provide enough clusters and mbufs for all the
147* units.  The default bsdnet configuration is sufficient for one unit,
148* but will be nearing exhaustion with 2 or more.  Although a little
149* expensive in memory, the following configuration should eliminate all
150* mbuf/cluster issues;
151*
152*   rtems_bsdnet_config.mbuf_bytecount           = 128*1024;
153*   rtems_bsdnet_config.mbuf_cluster_bytecount   = 256*1024;
154*
155* The default size in buffers of the rx & tx rings are given below.
156* This driver honors the rtems_bsdnet_ifconfig fields 'rbuf_count' and
157* 'xbuf_count', allowing the user to specify something else.
158*/
159
160#define RX_RING_SIZE 16 /* default number of receive buffers */
161#define TX_RING_SIZE 16 /* default number of transmit buffers */
162
163
164/*
165 * Number of boards supported by this driver
166 */
167#define NUM_UNITS       8
168
169/*
170 * Receive buffer size -- Allow for a full ethernet packet including CRC
171 */
172#define XL_PACKET_SIZE  1540
173
174
175/*
176** Events, one per unit.  The event is sent to the rx task from the isr
177** or from the stack to the tx task whenever a unit needs service.  The
178** rx/tx tasks identify the requesting unit(s) by their particular
179** events so only requesting units are serviced.
180*/
181
182static rtems_event_set unit_signals[NUM_UNITS]= { RTEMS_EVENT_1,
183                                                  RTEMS_EVENT_2,
184                                                  RTEMS_EVENT_3,
185                                                  RTEMS_EVENT_4,
186                                                  RTEMS_EVENT_5,
187                                                  RTEMS_EVENT_6,
188                                                  RTEMS_EVENT_7,
189                                                  RTEMS_EVENT_8 };
190
191
192
193
194#if defined(__PPC__)
195#define phys_to_bus(address) ((unsigned int)((address)) + PCI_DRAM_OFFSET)
196#define bus_to_phys(address) ((unsigned int)((address)) - PCI_DRAM_OFFSET)
197#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PPC_CACHE_ALIGNMENT
198#else
199extern void Wait_X_ms( unsigned int timeToWait );
200#define phys_to_bus(address) ((unsigned int) ((address)))
201#define bus_to_phys(address) ((unsigned int) ((address)))
202#define rtems_bsp_delay_in_bus_cycles(cycle) Wait_X_ms( cycle/100 )
203#define CPU_CACHE_ALIGNMENT_FOR_BUFFER PG_SIZE
204#endif
205
206/* the actual duration waited in DELAY is not especially predictable,
207 * though it will be consistent on a given host.  It should not be
208 * relied upon for specific timing given the vague per-bsp,
209 * per-architecture implementation of the actual delay function.  It
210 * would probably be helpful to make this more accurate at some point...
211 */
212#define DELAY(n)        rtems_bsp_delay_in_bus_cycles( n*20  )
213
214
215
216
217/*
218 * Register layouts.
219 */
220#define XL_COMMAND              0x0E
221#define XL_STATUS               0x0E
222
223#define XL_TX_STATUS            0x1B
224#define XL_TX_FREE              0x1C
225#define XL_DMACTL               0x20
226#define XL_DOWNLIST_PTR         0x24
227#define XL_DOWN_POLL            0x2D /* 3c90xB only */
228#define XL_TX_FREETHRESH        0x2F
229#define XL_UPLIST_PTR           0x38
230#define XL_UPLIST_STATUS        0x30
231#define XL_UP_POLL              0x3D /* 3c90xB only */
232
233#define XL_PKTSTAT_UP_STALLED           0x00002000
234#define XL_PKTSTAT_UP_ERROR             0x00004000
235#define XL_PKTSTAT_UP_CMPLT             0x00008000
236
237#define XL_DMACTL_DN_CMPLT_REQ          0x00000002
238#define XL_DMACTL_DOWN_STALLED          0x00000004
239#define XL_DMACTL_UP_CMPLT              0x00000008
240#define XL_DMACTL_DOWN_CMPLT            0x00000010
241#define XL_DMACTL_UP_RX_EARLY           0x00000020
242#define XL_DMACTL_ARM_COUNTDOWN         0x00000040
243#define XL_DMACTL_DOWN_INPROG           0x00000080
244#define XL_DMACTL_COUNTER_SPEED         0x00000100
245#define XL_DMACTL_DOWNDOWN_MODE         0x00000200
246#define XL_DMACTL_TARGET_ABORT          0x40000000
247#define XL_DMACTL_MASTER_ABORT          0x80000000
248
249/*
250 * Command codes. Some command codes require that we wait for
251 * the CMD_BUSY flag to clear. Those codes are marked as 'mustwait.'
252 */
253#define XL_CMD_RESET            0x0000  /* mustwait */
254#define XL_CMD_WINSEL           0x0800
255#define XL_CMD_COAX_START       0x1000
256#define XL_CMD_RX_DISABLE       0x1800
257#define XL_CMD_RX_ENABLE        0x2000
258#define XL_CMD_RX_RESET         0x2800  /* mustwait */
259#define XL_CMD_UP_STALL         0x3000  /* mustwait */
260#define XL_CMD_UP_UNSTALL       0x3001
261#define XL_CMD_DOWN_STALL       0x3002  /* mustwait */
262#define XL_CMD_DOWN_UNSTALL     0x3003
263#define XL_CMD_RX_DISCARD       0x4000
264#define XL_CMD_TX_ENABLE        0x4800
265#define XL_CMD_TX_DISABLE       0x5000
266#define XL_CMD_TX_RESET         0x5800  /* mustwait */
267#define XL_CMD_INTR_FAKE        0x6000
268#define XL_CMD_INTR_ACK         0x6800
269#define XL_CMD_INTR_ENB         0x7000
270#define XL_CMD_STAT_ENB         0x7800
271#define XL_CMD_RX_SET_FILT      0x8000
272#define XL_CMD_RX_SET_THRESH    0x8800
273#define XL_CMD_TX_SET_THRESH    0x9000
274#define XL_CMD_TX_SET_START     0x9800
275#define XL_CMD_DMA_UP           0xA000
276#define XL_CMD_DMA_STOP         0xA001
277#define XL_CMD_STATS_ENABLE     0xA800
278#define XL_CMD_STATS_DISABLE    0xB000
279#define XL_CMD_COAX_STOP        0xB800
280
281#define XL_CMD_SET_TX_RECLAIM   0xC000 /* 3c905B only */
282#define XL_CMD_RX_SET_HASH      0xC800 /* 3c905B only */
283
284#define XL_HASH_SET             0x0400
285#define XL_HASHFILT_SIZE        256
286
287/*
288 * status codes
289 * Note that bits 15 to 13 indicate the currently visible register window
290 * which may be anything from 0 to 7.
291 */
292#define XL_STAT_INTLATCH        0x0001  /* 0 */
293#define XL_STAT_ADFAIL          0x0002  /* 1 */
294#define XL_STAT_TX_COMPLETE     0x0004  /* 2 */
295#define XL_STAT_TX_AVAIL        0x0008  /* 3 first generation */
296#define XL_STAT_RX_COMPLETE     0x0010  /* 4 */
297#define XL_STAT_RX_EARLY        0x0020  /* 5 */
298#define XL_STAT_INTREQ          0x0040  /* 6 */
299#define XL_STAT_STATSOFLOW      0x0080  /* 7 */
300#define XL_STAT_DMADONE         0x0100  /* 8 first generation */
301#define XL_STAT_LINKSTAT        0x0100  /* 8 3c509B */
302#define XL_STAT_DOWN_COMPLETE   0x0200  /* 9 */
303#define XL_STAT_UP_COMPLETE     0x0400  /* 10 */
304#define XL_STAT_DMABUSY         0x0800  /* 11 first generation */
305#define XL_STAT_CMDBUSY         0x1000  /* 12 */
306
307/*
308 * Interrupts we normally want enabled.
309 */
310#define XL_INTRS        \
311                  (XL_STAT_UP_COMPLETE | XL_STAT_STATSOFLOW | XL_STAT_ADFAIL|   \
312                   XL_STAT_DOWN_COMPLETE | XL_STAT_TX_COMPLETE | XL_STAT_INTLATCH)
313
314
315
316/*
317 * General constants that are fun to know.
318 *
319 * 3Com PCI vendor ID
320 */
321#define TC_VENDORID             0x10B7
322
323/*
324 * 3Com chip device IDs.
325 */
326#define TC_DEVICEID_BOOMERANG_10BT              0x9000
327#define TC_DEVICEID_BOOMERANG_10BT_COMBO        0x9001
328#define TC_DEVICEID_BOOMERANG_10_100BT          0x9050
329#define TC_DEVICEID_BOOMERANG_100BT4            0x9051
330#define TC_DEVICEID_KRAKATOA_10BT               0x9004
331#define TC_DEVICEID_KRAKATOA_10BT_COMBO         0x9005
332#define TC_DEVICEID_KRAKATOA_10BT_TPC           0x9006
333#define TC_DEVICEID_CYCLONE_10FL                0x900A
334#define TC_DEVICEID_HURRICANE_10_100BT          0x9055
335#define TC_DEVICEID_CYCLONE_10_100BT4           0x9056
336#define TC_DEVICEID_CYCLONE_10_100_COMBO        0x9058
337#define TC_DEVICEID_CYCLONE_10_100FX            0x905A
338#define TC_DEVICEID_TORNADO_10_100BT            0x9200
339#define TC_DEVICEID_TORNADO_10_100BT_920B       0x9201
340#define TC_DEVICEID_HURRICANE_10_100BT_SERV     0x9800
341#define TC_DEVICEID_TORNADO_10_100BT_SERV       0x9805
342#define TC_DEVICEID_HURRICANE_SOHO100TX         0x7646
343#define TC_DEVICEID_TORNADO_HOMECONNECT         0x4500
344#define TC_DEVICEID_HURRICANE_555               0x5055
345#define TC_DEVICEID_HURRICANE_556               0x6055
346#define TC_DEVICEID_HURRICANE_556B              0x6056
347#define TC_DEVICEID_HURRICANE_575A              0x5057
348#define TC_DEVICEID_HURRICANE_575B              0x5157
349#define TC_DEVICEID_HURRICANE_575C              0x5257
350#define TC_DEVICEID_HURRICANE_656               0x6560
351#define TC_DEVICEID_HURRICANE_656B              0x6562
352#define TC_DEVICEID_TORNADO_656C                0x6564
353
354
355
356#define XL_RXSTAT_LENMASK       0x00001FFF
357#define XL_RXSTAT_UP_ERROR      0x00004000
358#define XL_RXSTAT_UP_CMPLT      0x00008000
359#define XL_RXSTAT_UP_OVERRUN    0x00010000
360#define XL_RXSTAT_RUNT          0x00020000
361#define XL_RXSTAT_ALIGN         0x00040000
362#define XL_RXSTAT_CRC           0x00080000
363#define XL_RXSTAT_OVERSIZE      0x00100000
364#define XL_RXSTAT_DRIBBLE       0x00800000
365#define XL_RXSTAT_UP_OFLOW      0x01000000
366#define XL_RXSTAT_IPCKERR       0x02000000      /* 3c905B only */
367#define XL_RXSTAT_TCPCKERR      0x04000000      /* 3c905B only */
368#define XL_RXSTAT_UDPCKERR      0x08000000      /* 3c905B only */
369#define XL_RXSTAT_BUFEN         0x10000000      /* 3c905B only */
370#define XL_RXSTAT_IPCKOK        0x20000000      /* 3c905B only */
371#define XL_RXSTAT_TCPCOK        0x40000000      /* 3c905B only */
372#define XL_RXSTAT_UDPCKOK       0x80000000      /* 3c905B only */
373
374#define XL_TXSTAT_LENMASK       0x00001FFF
375#define XL_TXSTAT_CRCDIS        0x00002000
376#define XL_TXSTAT_TX_INTR       0x00008000
377#define XL_TXSTAT_DL_COMPLETE   0x00010000
378#define XL_TXSTAT_IPCKSUM       0x02000000      /* 3c905B only */
379#define XL_TXSTAT_TCPCKSUM      0x04000000      /* 3c905B only */
380#define XL_TXSTAT_UDPCKSUM      0x08000000      /* 3c905B only */
381#define XL_TXSTAT_RND_DEFEAT    0x10000000      /* 3c905B only */
382#define XL_TXSTAT_EMPTY         0x20000000      /* 3c905B only */
383#define XL_TXSTAT_DL_INTR       0x80000000
384
385
386#define XL_FLAG_FUNCREG                 0x0001
387#define XL_FLAG_PHYOK                   0x0002
388#define XL_FLAG_EEPROM_OFFSET_30        0x0004
389#define XL_FLAG_WEIRDRESET              0x0008
390#define XL_FLAG_8BITROM                 0x0010
391#define XL_FLAG_INVERT_LED_PWR          0x0020
392#define XL_FLAG_INVERT_MII_PWR          0x0040
393#define XL_FLAG_NO_XCVR_PWR             0x0080
394#define XL_FLAG_USE_MMIO                0x0100
395
396
397
398#define XL_EE_READ      0x0080  /* read, 5 bit address */
399#define XL_EE_WRITE     0x0040  /* write, 5 bit address */
400#define XL_EE_ERASE     0x00c0  /* erase, 5 bit address */
401#define XL_EE_EWEN      0x0030  /* erase, no data needed */
402#define XL_EE_8BIT_READ 0x0200  /* read, 8 bit address */
403#define XL_EE_BUSY      0x8000
404
405#define XL_EE_EADDR0    0x00    /* station address, first word */
406#define XL_EE_EADDR1    0x01    /* station address, next word, */
407#define XL_EE_EADDR2    0x02    /* station address, last word */
408#define XL_EE_PRODID    0x03    /* product ID code */
409#define XL_EE_MDATA_DATE        0x04    /* manufacturing data, date */
410#define XL_EE_MDATA_DIV         0x05    /* manufacturing data, division */
411#define XL_EE_MDATA_PCODE       0x06    /* manufacturing data, product code */
412#define XL_EE_MFG_ID    0x07
413#define XL_EE_PCI_PARM  0x08
414#define XL_EE_ROM_ONFO  0x09
415#define XL_EE_OEM_ADR0  0x0A
416#define XL_EE_OEM_ADR1  0x0B
417#define XL_EE_OEM_ADR2  0x0C
418#define XL_EE_SOFTINFO1 0x0D
419#define XL_EE_COMPAT    0x0E
420#define XL_EE_SOFTINFO2 0x0F
421#define XL_EE_CAPS      0x10    /* capabilities word */
422#define XL_EE_RSVD0     0x11
423#define XL_EE_ICFG_0    0x12
424#define XL_EE_ICFG_1    0x13
425#define XL_EE_RSVD1     0x14
426#define XL_EE_SOFTINFO3 0x15
427#define XL_EE_RSVD_2    0x16
428
429/*
430 * Bits in the capabilities word
431 */
432#define XL_CAPS_PNP             0x0001
433#define XL_CAPS_FULL_DUPLEX     0x0002
434#define XL_CAPS_LARGE_PKTS      0x0004
435#define XL_CAPS_SLAVE_DMA       0x0008
436#define XL_CAPS_SECOND_DMA      0x0010
437#define XL_CAPS_FULL_BM         0x0020
438#define XL_CAPS_FRAG_BM         0x0040
439#define XL_CAPS_CRC_PASSTHRU    0x0080
440#define XL_CAPS_TXDONE          0x0100
441#define XL_CAPS_NO_TXLENGTH     0x0200
442#define XL_CAPS_RX_REPEAT       0x0400
443#define XL_CAPS_SNOOPING        0x0800
444#define XL_CAPS_100MBPS         0x1000
445#define XL_CAPS_PWRMGMT         0x2000
446
447
448
449/*
450 * Window 0 registers
451 */
452#define XL_W0_EE_DATA           0x0C
453#define XL_W0_EE_CMD            0x0A
454#define XL_W0_RSRC_CFG          0x08
455#define XL_W0_ADDR_CFG          0x06
456#define XL_W0_CFG_CTRL          0x04
457
458#define XL_W0_PROD_ID           0x02
459#define XL_W0_MFG_ID            0x00
460
461/*
462 * Window 1
463 */
464
465#define XL_W1_TX_FIFO           0x10
466
467#define XL_W1_FREE_TX           0x0C
468#define XL_W1_TX_STATUS         0x0B
469#define XL_W1_TX_TIMER          0x0A
470#define XL_W1_RX_STATUS         0x08
471#define XL_W1_RX_FIFO           0x00
472
473/*
474 * RX status codes
475 */
476#define XL_RXSTATUS_OVERRUN     0x01
477#define XL_RXSTATUS_RUNT        0x02
478#define XL_RXSTATUS_ALIGN       0x04
479#define XL_RXSTATUS_CRC         0x08
480#define XL_RXSTATUS_OVERSIZE    0x10
481#define XL_RXSTATUS_DRIBBLE     0x20
482
483/*
484 * TX status codes
485 */
486#define XL_TXSTATUS_RECLAIM     0x02 /* 3c905B only */
487#define XL_TXSTATUS_OVERFLOW    0x04
488#define XL_TXSTATUS_MAXCOLS     0x08
489#define XL_TXSTATUS_UNDERRUN    0x10
490#define XL_TXSTATUS_JABBER      0x20
491#define XL_TXSTATUS_INTREQ      0x40
492#define XL_TXSTATUS_COMPLETE    0x80
493
494/*
495 * Window 2
496 */
497#define XL_W2_RESET_OPTIONS     0x0C    /* 3c905B only */
498#define XL_W2_STATION_MASK_HI   0x0A
499#define XL_W2_STATION_MASK_MID  0x08
500#define XL_W2_STATION_MASK_LO   0x06
501#define XL_W2_STATION_ADDR_HI   0x04
502#define XL_W2_STATION_ADDR_MID  0x02
503#define XL_W2_STATION_ADDR_LO   0x00
504
505#define XL_RESETOPT_FEATUREMASK 0x0001|0x0002|0x004
506#define XL_RESETOPT_D3RESETDIS  0x0008
507#define XL_RESETOPT_DISADVFD    0x0010
508#define XL_RESETOPT_DISADV100   0x0020
509#define XL_RESETOPT_DISAUTONEG  0x0040
510#define XL_RESETOPT_DEBUGMODE   0x0080
511#define XL_RESETOPT_FASTAUTO    0x0100
512#define XL_RESETOPT_FASTEE      0x0200
513#define XL_RESETOPT_FORCEDCONF  0x0400
514#define XL_RESETOPT_TESTPDTPDR  0x0800
515#define XL_RESETOPT_TEST100TX   0x1000
516#define XL_RESETOPT_TEST100RX   0x2000
517
518#define XL_RESETOPT_INVERT_LED  0x0010
519#define XL_RESETOPT_INVERT_MII  0x4000
520
521/*
522 * Window 3 (fifo management)
523 */
524#define XL_W3_INTERNAL_CFG      0x00
525#define XL_W3_MAXPKTSIZE        0x04    /* 3c905B only */
526#define XL_W3_RESET_OPT         0x08
527#define XL_W3_FREE_TX           0x0C
528#define XL_W3_FREE_RX           0x0A
529#define XL_W3_MAC_CTRL          0x06
530
531#define XL_ICFG_CONNECTOR_MASK  0x00F00000
532#define XL_ICFG_CONNECTOR_BITS  20
533
534#define XL_ICFG_RAMSIZE_MASK    0x00000007
535#define XL_ICFG_RAMWIDTH        0x00000008
536#define XL_ICFG_ROMSIZE_MASK    (0x00000040|0x00000080)
537#define XL_ICFG_DISABLE_BASSD   0x00000100
538#define XL_ICFG_RAMLOC          0x00000200
539#define XL_ICFG_RAMPART         (0x00010000|0x00020000)
540#define XL_ICFG_XCVRSEL         (0x00100000|0x00200000|0x00400000)
541#define XL_ICFG_AUTOSEL         0x01000000
542
543#define XL_XCVR_10BT            0x00
544#define XL_XCVR_AUI             0x01
545#define XL_XCVR_RSVD_0          0x02
546#define XL_XCVR_COAX            0x03
547#define XL_XCVR_100BTX          0x04
548#define XL_XCVR_100BFX          0x05
549#define XL_XCVR_MII             0x06
550#define XL_XCVR_RSVD_1          0x07
551#define XL_XCVR_AUTO            0x08    /* 3c905B only */
552
553#define XL_MACCTRL_DEFER_EXT_END        0x0001
554#define XL_MACCTRL_DEFER_0              0x0002
555#define XL_MACCTRL_DEFER_1              0x0004
556#define XL_MACCTRL_DEFER_2              0x0008
557#define XL_MACCTRL_DEFER_3              0x0010
558#define XL_MACCTRL_DUPLEX               0x0020
559#define XL_MACCTRL_ALLOW_LARGE_PACK     0x0040
560#define XL_MACCTRL_EXTEND_AFTER_COL     0x0080 (3c905B only)
561#define XL_MACCTRL_FLOW_CONTROL_ENB     0x0100 (3c905B only)
562#define XL_MACCTRL_VLT_END              0x0200 (3c905B only)
563
564/*
565 * The 'reset options' register contains power-on reset values
566 * loaded from the EEPROM. This includes the supported media
567 * types on the card. It is also known as the media options register.
568 */
569#define XL_W3_MEDIA_OPT         0x08
570
571#define XL_MEDIAOPT_BT4         0x0001  /* MII */
572#define XL_MEDIAOPT_BTX         0x0002  /* on-chip */
573#define XL_MEDIAOPT_BFX         0x0004  /* on-chip */
574#define XL_MEDIAOPT_BT          0x0008  /* on-chip */
575#define XL_MEDIAOPT_BNC         0x0010  /* on-chip */
576#define XL_MEDIAOPT_AUI         0x0020  /* on-chip */
577#define XL_MEDIAOPT_MII         0x0040  /* MII */
578#define XL_MEDIAOPT_VCO         0x0100  /* 1st gen chip only */
579
580#define XL_MEDIAOPT_10FL        0x0100  /* 3x905B only, on-chip */
581#define XL_MEDIAOPT_MASK        0x01FF
582
583/*
584 * Window 4 (diagnostics)
585 */
586#define XL_W4_UPPERBYTESOK      0x0D
587#define XL_W4_BADSSD            0x0C
588#define XL_W4_MEDIA_STATUS      0x0A
589#define XL_W4_PHY_MGMT          0x08
590#define XL_W4_NET_DIAG          0x06
591#define XL_W4_FIFO_DIAG         0x04
592#define XL_W4_VCO_DIAG          0x02
593
594#define XL_W4_CTRLR_STAT        0x08
595#define XL_W4_TX_DIAG           0x00
596
597#define XL_MII_CLK              0x01
598#define XL_MII_DATA             0x02
599#define XL_MII_DIR              0x04
600
601#define XL_MEDIA_SQE            0x0008
602#define XL_MEDIA_10TP           0x00C0
603#define XL_MEDIA_LNK            0x0080
604#define XL_MEDIA_LNKBEAT        0x0800
605
606#define XL_MEDIASTAT_CRCSTRIP   0x0004
607#define XL_MEDIASTAT_SQEENB     0x0008
608#define XL_MEDIASTAT_COLDET     0x0010
609#define XL_MEDIASTAT_CARRIER    0x0020
610#define XL_MEDIASTAT_JABGUARD   0x0040
611#define XL_MEDIASTAT_LINKBEAT   0x0080
612#define XL_MEDIASTAT_JABDETECT  0x0200
613#define XL_MEDIASTAT_POLREVERS  0x0400
614#define XL_MEDIASTAT_LINKDETECT 0x0800
615#define XL_MEDIASTAT_TXINPROG   0x1000
616#define XL_MEDIASTAT_DCENB      0x4000
617#define XL_MEDIASTAT_AUIDIS     0x8000
618
619#define XL_NETDIAG_TEST_LOWVOLT         0x0001
620#define XL_NETDIAG_ASIC_REVMASK         (0x0002|0x0004|0x0008|0x0010|0x0020)
621#define XL_NETDIAG_UPPER_BYTES_ENABLE   0x0040
622#define XL_NETDIAG_STATS_ENABLED        0x0080
623#define XL_NETDIAG_TX_FATALERR          0x0100
624#define XL_NETDIAG_TRANSMITTING         0x0200
625#define XL_NETDIAG_RX_ENABLED           0x0400
626#define XL_NETDIAG_TX_ENABLED           0x0800
627#define XL_NETDIAG_FIFO_LOOPBACK        0x1000
628#define XL_NETDIAG_MAC_LOOPBACK         0x2000
629#define XL_NETDIAG_ENDEC_LOOPBACK       0x4000
630#define XL_NETDIAG_EXTERNAL_LOOP        0x8000
631
632/*
633 * Window 5
634 */
635#define XL_W5_STAT_ENB          0x0C
636#define XL_W5_INTR_ENB          0x0A
637#define XL_W5_RECLAIM_THRESH    0x09    /* 3c905B only */
638#define XL_W5_RX_FILTER         0x08
639#define XL_W5_RX_EARLYTHRESH    0x06
640#define XL_W5_TX_AVAILTHRESH    0x02
641#define XL_W5_TX_STARTTHRESH    0x00
642
643/*
644 * RX filter bits
645 */
646#define XL_RXFILTER_INDIVIDUAL  0x01
647#define XL_RXFILTER_ALLMULTI    0x02
648#define XL_RXFILTER_BROADCAST   0x04
649#define XL_RXFILTER_ALLFRAMES   0x08
650#define XL_RXFILTER_MULTIHASH   0x10 /* 3c905B only */
651
652/*
653 * Window 6 (stats)
654 */
655#define XL_W6_TX_BYTES_OK       0x0C
656#define XL_W6_RX_BYTES_OK       0x0A
657#define XL_W6_UPPER_FRAMES_OK   0x09
658#define XL_W6_DEFERRED          0x08
659#define XL_W6_RX_OK             0x07
660#define XL_W6_TX_OK             0x06
661#define XL_W6_RX_OVERRUN        0x05
662#define XL_W6_COL_LATE          0x04
663#define XL_W6_COL_SINGLE        0x03
664#define XL_W6_COL_MULTIPLE      0x02
665#define XL_W6_SQE_ERRORS        0x01
666#define XL_W6_CARRIER_LOST      0x00
667
668/*
669 * Window 7 (bus master control)
670 */
671#define XL_W7_BM_ADDR           0x00
672#define XL_W7_BM_LEN            0x06
673#define XL_W7_BM_STATUS         0x0B
674#define XL_W7_BM_TIMEr          0x0A
675
676/*
677 * bus master control registers
678 */
679#define XL_BM_PKTSTAT           0x20
680#define XL_BM_DOWNLISTPTR       0x24
681#define XL_BM_FRAGADDR          0x28
682#define XL_BM_FRAGLEN           0x2C
683#define XL_BM_TXFREETHRESH      0x2F
684#define XL_BM_UPPKTSTAT         0x30
685#define XL_BM_UPLISTPTR         0x38
686
687
688
689
690
691
692
693
694struct xl_mii_frame {
695        u_int8_t                mii_stdelim;
696        u_int8_t                mii_opcode;
697        u_int8_t                mii_phyaddr;
698        u_int8_t                mii_regaddr;
699        u_int8_t                mii_turnaround;
700        u_int16_t               mii_data;
701};
702
703/*
704 * MII constants
705 */
706#define XL_MII_STARTDELIM       0x01
707#define XL_MII_READOP           0x02
708#define XL_MII_WRITEOP          0x01
709#define XL_MII_TURNAROUND       0x02
710
711
712
713/*
714 * The 3C905B adapters implement a few features that we want to
715 * take advantage of, namely the multicast hash filter. With older
716 * chips, you only have the option of turning on reception of all
717 * multicast frames, which is kind of lame.
718 *
719 * We also use this to decide on a transmit strategy. For the 3c90xB
720 * cards, we can use polled descriptor mode, which reduces CPU overhead.
721 */
722#define XL_TYPE_905B    1
723#define XL_TYPE_90X     2
724
725#define XL_FLAG_FUNCREG                 0x0001
726#define XL_FLAG_PHYOK                   0x0002
727#define XL_FLAG_EEPROM_OFFSET_30        0x0004
728#define XL_FLAG_WEIRDRESET              0x0008
729#define XL_FLAG_8BITROM                 0x0010
730#define XL_FLAG_INVERT_LED_PWR          0x0020
731#define XL_FLAG_INVERT_MII_PWR          0x0040
732#define XL_FLAG_NO_XCVR_PWR             0x0080
733#define XL_FLAG_USE_MMIO                0x0100
734
735#define XL_NO_XCVR_PWR_MAGICBITS        0x0900
736
737
738#define XL_MIN_FRAMELEN         60
739
740#define XL_LAST_FRAG            0x80000000
741
742
743
744
745
746
747
748struct xl_stats
749{
750      /* accumulated stats */
751      u_int16_t         xl_carrier_lost;
752      u_int16_t         xl_sqe_errs;
753      u_int16_t         xl_tx_multi_collision;
754      u_int16_t         xl_tx_single_collision;
755      u_int16_t         xl_tx_late_collision;
756      u_int16_t         xl_rx_overrun;
757      u_int16_t         xl_tx_deferred;
758
759      u_int32_t         xl_rx_bytes_ok;
760      u_int32_t         xl_tx_bytes_ok;
761
762      u_int32_t         xl_tx_frames_ok;
763      u_int32_t         xl_rx_frames_ok;
764
765      u_int16_t         xl_badssd;
766
767      /* non-accumulated stats */
768      u_int16_t         intstatus;
769      u_int16_t         rxstatus;
770      u_int8_t          txstatus;
771      u_int16_t         mediastatus;
772
773      u_int32_t         txcomplete_ints;
774
775      u_int16_t         miianr, miipar, miistatus, miicmd;
776
777      u_int32_t         device_interrupts;
778      u_int32_t         internalconfig;
779      u_int16_t         mac_control;
780
781      u_int16_t         smbstatus;
782      u_int32_t         dmactl;
783      u_int16_t         txfree;
784};
785
786
787
788struct xl_type
789{
790      u_int16_t         xl_vid;
791      u_int16_t         xl_did;
792      char              *xl_name;
793};
794
795
796
797/*
798 * Various supported device vendors/types and their names.
799 */
800static struct xl_type xl_devs[] = {
801        { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
802                "3Com 3c900-TPO Etherlink XL" },
803        { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
804                "3Com 3c900-COMBO Etherlink XL" },
805        { TC_VENDORID, TC_DEVICEID_BOOMERANG_10_100BT,
806                "3Com 3c905-TX Fast Etherlink XL" },
807        { TC_VENDORID, TC_DEVICEID_BOOMERANG_100BT4,
808                "3Com 3c905-T4 Fast Etherlink XL" },
809        { TC_VENDORID, TC_DEVICEID_KRAKATOA_10BT,
810                "3Com 3c900B-TPO Etherlink XL" },
811        { TC_VENDORID, TC_DEVICEID_KRAKATOA_10BT_COMBO,
812                "3Com 3c900B-COMBO Etherlink XL" },
813        { TC_VENDORID, TC_DEVICEID_KRAKATOA_10BT_TPC,
814                "3Com 3c900B-TPC Etherlink XL" },
815        { TC_VENDORID, TC_DEVICEID_CYCLONE_10FL,
816                "3Com 3c900B-FL Etherlink XL" },
817        { TC_VENDORID, TC_DEVICEID_HURRICANE_10_100BT,
818                "3Com 3c905B-TX Fast Etherlink XL" },
819        { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100BT4,
820                "3Com 3c905B-T4 Fast Etherlink XL" },
821        { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100FX,
822                "3Com 3c905B-FX/SC Fast Etherlink XL" },
823        { TC_VENDORID, TC_DEVICEID_CYCLONE_10_100_COMBO,
824                "3Com 3c905B-COMBO Fast Etherlink XL" },
825        { TC_VENDORID, TC_DEVICEID_TORNADO_10_100BT,
826                "3Com 3c905C-TX Fast Etherlink XL" },
827        { TC_VENDORID, TC_DEVICEID_TORNADO_10_100BT_920B,
828                "3Com 3c920B-EMB Integrated Fast Etherlink XL" },
829        { TC_VENDORID, TC_DEVICEID_HURRICANE_10_100BT_SERV,
830                "3Com 3c980 Fast Etherlink XL" },
831        { TC_VENDORID, TC_DEVICEID_TORNADO_10_100BT_SERV,
832                "3Com 3c980C Fast Etherlink XL" },
833        { TC_VENDORID, TC_DEVICEID_HURRICANE_SOHO100TX,
834                "3Com 3cSOHO100-TX OfficeConnect" },
835        { TC_VENDORID, TC_DEVICEID_TORNADO_HOMECONNECT,
836                "3Com 3c450-TX HomeConnect" },
837        { TC_VENDORID, TC_DEVICEID_HURRICANE_555,
838                "3Com 3c555 Fast Etherlink XL" },
839        { TC_VENDORID, TC_DEVICEID_HURRICANE_556,
840                "3Com 3c556 Fast Etherlink XL" },
841        { TC_VENDORID, TC_DEVICEID_HURRICANE_556B,
842                "3Com 3c556B Fast Etherlink XL" },
843        { TC_VENDORID, TC_DEVICEID_HURRICANE_575A,
844                "3Com 3c575TX Fast Etherlink XL" },
845        { TC_VENDORID, TC_DEVICEID_HURRICANE_575B,
846                "3Com 3c575B Fast Etherlink XL" },
847        { TC_VENDORID, TC_DEVICEID_HURRICANE_575C,
848                "3Com 3c575C Fast Etherlink XL" },
849        { TC_VENDORID, TC_DEVICEID_HURRICANE_656,
850                "3Com 3c656 Fast Etherlink XL" },
851        { TC_VENDORID, TC_DEVICEID_HURRICANE_656B,
852                "3Com 3c656B Fast Etherlink XL" },
853        { TC_VENDORID, TC_DEVICEID_TORNADO_656C,
854                "3Com 3c656C Fast Etherlink XL" },
855        { 0, 0, NULL }
856};
857
858
859#define XL_TIMEOUT              1000
860
861
862
863
864
865
866/* rx message descriptor entry, ensure the struct is aligned to 8 bytes */
867struct RXMD
868{
869      /* used by hardware */
870      volatile uint32_t   next;
871      volatile uint32_t   status;
872      volatile uint32_t   addr;
873      volatile uint32_t   length;
874      /* used by software */
875      struct mbuf       *mbuf;        /* scratch variable used in the tx ring */
876      struct RXMD       *next_md;
877} __attribute__ ((aligned (8), packed));
878
879
880
881
882
883#define NUM_FRAGS       6
884
885/*
886 * tx message descriptor entry, ensure the struct is aligned to 8 bytes
887 */
888
889struct tfrag
890{
891      volatile uint32_t   addr;
892      volatile uint32_t   length;
893} __attribute__ ((packed));
894
895struct TXMD
896{
897      /* used by hardware */
898      volatile uint32_t   next;
899      volatile uint32_t   status;
900      struct tfrag        txfrags[NUM_FRAGS];
901      /* used by software */
902      struct mbuf       *mbuf;        /* scratch variable used in the tx ring */
903      struct TXMD       *next_md, *chainptr;
904} __attribute__ ((aligned (8), packed));
905
906
907
908
909
910#define NUM_CHAIN_LENGTHS       50
911
912
913
914/*
915 * Per-device data
916 */
917struct elnk_softc
918{
919      struct arpcom             arpcom;
920
921      rtems_irq_connect_data    irqInfo;
922      rtems_event_set           ioevent;
923      unsigned int              ioaddr;
924
925      unsigned char             *bufferBase, *ringBase;
926
927      struct RXMD      *rx_ring, *curr_rx_md;
928      struct TXMD      *tx_ring, *last_tx_md, *last_txchain_head;
929
930      rtems_id                  stat_timer_id;
931      uint32_t                  stats_update_ticks;
932
933      struct xl_stats           xl_stats;
934
935      u_int8_t                  xl_unit;        /* interface number */
936      u_int8_t                  xl_type;
937      int                       xl_flags;
938      u_int16_t                 xl_media;
939      u_int16_t                 xl_caps;
940      u_int32_t                 xl_xcvr;
941      u_int8_t                  xl_stats_no_timeout;
942      u_int16_t                 xl_tx_thresh;
943
944      int                       tx_idle;
945
946      short                     chain_lengths[NUM_CHAIN_LENGTHS];
947      int                       chlenIndex;
948
949      unsigned short            vendorID, deviceID;
950      int                       acceptBroadcast;
951      int                       numTxbuffers, numRxbuffers;
952};
953
954static struct elnk_softc elnk_softc[NUM_UNITS];
955static rtems_id rxDaemonTid;
956static rtems_id txDaemonTid;
957static rtems_id chainRecoveryQueue;
958
959
960
961
962
963
964
965#if defined(__i386__)
966
967#define CSR_WRITE_4(sc, reg, val)       i386_outport_long( sc->ioaddr + reg, val )
968#define CSR_WRITE_2(sc, reg, val)       i386_outport_word( sc->ioaddr + reg, val )
969#define CSR_WRITE_1(sc, reg, val)       i386_outport_byte( sc->ioaddr + reg, val )
970
971
972inline unsigned int CSR_READ_4( struct elnk_softc *sc, int reg)
973{
974   unsigned int myval;
975   i386_inport_long( sc->ioaddr + reg, myval );
976   return myval;
977}
978
979inline unsigned short  CSR_READ_2( struct elnk_softc *sc, int reg)
980{
981   unsigned short myval;
982   i386_inport_word( sc->ioaddr + reg, myval );
983   return myval;
984}
985
986inline unsigned char CSR_READ_1( struct elnk_softc *sc, int reg)
987{
988   unsigned char myval;
989   i386_inport_byte( sc->ioaddr + reg, myval );
990   return myval;
991}
992
993#endif
994
995#if defined(__PPC__)
996
997#define CSR_WRITE_4(sc, reg, val)       outl( val, sc->ioaddr + reg)
998#define CSR_WRITE_2(sc, reg, val)       outw( val, sc->ioaddr + reg)
999#define CSR_WRITE_1(sc, reg, val)       outb( val, sc->ioaddr + reg)
1000
1001#define CSR_READ_4(sc, reg)             inl(sc->ioaddr + reg)
1002#define CSR_READ_2(sc, reg)             inw(sc->ioaddr + reg)
1003#define CSR_READ_1(sc, reg)             inb(sc->ioaddr + reg)
1004
1005#endif
1006
1007
1008#define XL_SEL_WIN(x)                   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_WINSEL | x)
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020/*
1021 * Murphy's law says that it's possible the chip can wedge and
1022 * the 'command in progress' bit may never clear. Hence, we wait
1023 * only a finite amount of time to avoid getting caught in an
1024 * infinite loop. Normally this delay routine would be a macro,
1025 * but it isn't called during normal operation so we can afford
1026 * to make it a function.
1027 */
1028static void
1029xl_wait(sc)
1030   struct elnk_softc    *sc;
1031{
1032   register int         i;
1033
1034   for(i = 0; i < XL_TIMEOUT; i++)
1035   {
1036      if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
1037         break;
1038   }
1039
1040   if (i == XL_TIMEOUT)
1041      printk("etherlink : unit elnk%d command never completed\n", sc->xl_unit );
1042   return;
1043}
1044
1045
1046
1047
1048
1049
1050/*
1051 * MII access routines are provided for adapters with external
1052 * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
1053 * autoneg logic that's faked up to look like a PHY (3c905B-TX).
1054 * Note: if you don't perform the MDIO operations just right,
1055 * it's possible to end up with code that works correctly with
1056 * some chips/CPUs/processor speeds/bus speeds/etc but not
1057 * with others.
1058 */
1059#define MII_SET(x)                                      \
1060        CSR_WRITE_2(sc, XL_W4_PHY_MGMT,                 \
1061                CSR_READ_2(sc, XL_W4_PHY_MGMT) | (x))
1062
1063#define MII_CLR(x)                                      \
1064        CSR_WRITE_2(sc, XL_W4_PHY_MGMT,                 \
1065                CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~(x))
1066
1067/*
1068 * Sync the PHYs by setting data bit and strobing the clock 32 times.
1069 */
1070static void
1071xl_mii_sync(sc)
1072   struct elnk_softc            *sc;
1073{
1074   register int         i;
1075
1076   XL_SEL_WIN(4);
1077   MII_SET(XL_MII_DIR|XL_MII_DATA);
1078
1079   for (i = 0; i < 32; i++) {
1080      MII_SET(XL_MII_CLK);
1081      MII_SET(XL_MII_DATA);
1082      MII_CLR(XL_MII_CLK);
1083      MII_SET(XL_MII_DATA);
1084   }
1085
1086   return;
1087}
1088
1089/*
1090 * Clock a series of bits through the MII.
1091 */
1092static void
1093xl_mii_send(sc, bits, cnt)
1094   struct elnk_softc            *sc;
1095   u_int32_t            bits;
1096   int                  cnt;
1097{
1098   int                  i;
1099
1100   XL_SEL_WIN(4);
1101   MII_CLR(XL_MII_CLK);
1102
1103   for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
1104      if (bits & i) {
1105         MII_SET(XL_MII_DATA);
1106      } else {
1107         MII_CLR(XL_MII_DATA);
1108      }
1109      MII_CLR(XL_MII_CLK);
1110      MII_SET(XL_MII_CLK);
1111   }
1112}
1113
1114/*
1115 * Read an PHY register through the MII.
1116 */
1117static int
1118xl_mii_readreg(sc, frame)
1119   struct elnk_softc            *sc;
1120   struct xl_mii_frame  *frame;
1121
1122{
1123   int                  i, ack;
1124
1125   /*
1126    * Set up frame for RX.
1127    */
1128   frame->mii_stdelim = XL_MII_STARTDELIM;
1129   frame->mii_opcode = XL_MII_READOP;
1130   frame->mii_turnaround = 0;
1131   frame->mii_data = 0;
1132
1133   /*
1134    * Select register window 4.
1135    */
1136
1137   XL_SEL_WIN(4);
1138
1139   CSR_WRITE_2(sc, XL_W4_PHY_MGMT, 0);
1140   /*
1141    * Turn on data xmit.
1142    */
1143   MII_SET(XL_MII_DIR);
1144
1145   xl_mii_sync(sc);
1146
1147   /*
1148    * Send command/address info.
1149    */
1150   xl_mii_send(sc, frame->mii_stdelim, 2);
1151   xl_mii_send(sc, frame->mii_opcode, 2);
1152   xl_mii_send(sc, frame->mii_phyaddr, 5);
1153   xl_mii_send(sc, frame->mii_regaddr, 5);
1154
1155   /* Idle bit */
1156   MII_CLR((XL_MII_CLK|XL_MII_DATA));
1157   MII_SET(XL_MII_CLK);
1158
1159   /* Turn off xmit. */
1160   MII_CLR(XL_MII_DIR);
1161
1162   /* Check for ack */
1163   MII_CLR(XL_MII_CLK);
1164   ack = CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA;
1165   MII_SET(XL_MII_CLK);
1166
1167   /*
1168    * Now try reading data bits. If the ack failed, we still
1169    * need to clock through 16 cycles to keep the PHY(s) in sync.
1170    */
1171   if (ack) {
1172      for(i = 0; i < 16; i++) {
1173         MII_CLR(XL_MII_CLK);
1174         MII_SET(XL_MII_CLK);
1175      }
1176      goto fail;
1177   }
1178
1179   for (i = 0x8000; i; i >>= 1) {
1180      MII_CLR(XL_MII_CLK);
1181      if (!ack) {
1182         if (CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA)
1183            frame->mii_data |= i;
1184      }
1185      MII_SET(XL_MII_CLK);
1186   }
1187
1188  fail:
1189
1190   MII_CLR(XL_MII_CLK);
1191   MII_SET(XL_MII_CLK);
1192
1193   if (ack)
1194      return(1);
1195   return(0);
1196}
1197
1198/*
1199 * Write to a PHY register through the MII.
1200 */
1201static int
1202xl_mii_writereg(sc, frame)
1203   struct elnk_softc            *sc;
1204   struct xl_mii_frame  *frame;
1205
1206{
1207   /*
1208    * Set up frame for TX.
1209    */
1210
1211   frame->mii_stdelim = XL_MII_STARTDELIM;
1212   frame->mii_opcode = XL_MII_WRITEOP;
1213   frame->mii_turnaround = XL_MII_TURNAROUND;
1214
1215   /*
1216    * Select the window 4.
1217    */
1218   XL_SEL_WIN(4);
1219
1220   /*
1221    * Turn on data output.
1222    */
1223   MII_SET(XL_MII_DIR);
1224
1225   xl_mii_sync(sc);
1226
1227   xl_mii_send(sc, frame->mii_stdelim, 2);
1228   xl_mii_send(sc, frame->mii_opcode, 2);
1229   xl_mii_send(sc, frame->mii_phyaddr, 5);
1230   xl_mii_send(sc, frame->mii_regaddr, 5);
1231   xl_mii_send(sc, frame->mii_turnaround, 2);
1232   xl_mii_send(sc, frame->mii_data, 16);
1233
1234   /* Idle bit. */
1235   MII_SET(XL_MII_CLK);
1236   MII_CLR(XL_MII_CLK);
1237
1238   /*
1239    * Turn off xmit.
1240    */
1241   MII_CLR(XL_MII_DIR);
1242
1243   return(0);
1244}
1245
1246static int
1247xl_miibus_readreg(sc, phy, reg)
1248   struct elnk_softc    *sc;
1249   int                  phy, reg;
1250{
1251   struct xl_mii_frame  frame;
1252
1253   /*
1254    * Pretend that PHYs are only available at MII address 24.
1255    * This is to guard against problems with certain 3Com ASIC
1256    * revisions that incorrectly map the internal transceiver
1257    * control registers at all MII addresses. This can cause
1258    * the miibus code to attach the same PHY several times over.
1259    */
1260   if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
1261   {
1262      printk("etherlink : unit elnk%d xl_miibus_readreg returned\n", sc->xl_unit);
1263      return(0);
1264   }
1265
1266   memset((char *)&frame, 0, sizeof(frame));
1267
1268   frame.mii_phyaddr = phy;
1269   frame.mii_regaddr = reg;
1270   xl_mii_readreg(sc, &frame);
1271
1272   return(frame.mii_data);
1273}
1274
1275static int
1276xl_miibus_writereg(sc, phy, reg, data)
1277   struct elnk_softc            *sc;
1278   int                  phy, reg, data;
1279{
1280   struct xl_mii_frame  frame;
1281
1282   if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
1283   {
1284      printk("etherlink : unit elnk%d xl_miibus_writereg returned\n", sc->xl_unit);
1285      return(0);
1286   }
1287
1288   memset((char *)&frame, 0, sizeof(frame));
1289
1290   frame.mii_phyaddr = phy;
1291   frame.mii_regaddr = reg;
1292   frame.mii_data = data;
1293
1294   xl_mii_writereg(sc, &frame);
1295
1296   return(0);
1297}
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307/*
1308 * The EEPROM is slow: give it time to come ready after issuing
1309 * it a command.
1310 */
1311static int
1312xl_eeprom_wait(sc)
1313   struct elnk_softc            *sc;
1314{
1315   int                  i;
1316
1317   for (i = 0; i < 100; i++) {
1318      if (CSR_READ_2(sc, XL_W0_EE_CMD) & XL_EE_BUSY)
1319         DELAY(162);
1320      else
1321         break;
1322   }
1323
1324   if (i == 100) {
1325      printk("etherlink : unit elnk%d eeprom failed to come ready\n", sc->xl_unit);
1326      return(1);
1327   }
1328
1329   return(0);
1330}
1331
1332/*
1333 * Read a sequence of words from the EEPROM. Note that ethernet address
1334 * data is stored in the EEPROM in network byte order.
1335 */
1336static int
1337xl_read_eeprom(sc, dest, off, cnt, swap)
1338   struct elnk_softc            *sc;
1339   caddr_t                      dest;
1340   int                  off;
1341   int                  cnt;
1342   int                  swap;
1343{
1344   int                  err = 0, i;
1345   u_int16_t            word = 0, *ptr;
1346#define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F))
1347#define EEPROM_8BIT_OFFSET(A) ((A) & 0x003F)
1348   /* WARNING! DANGER!
1349    * It's easy to accidentally overwrite the rom content!
1350    * Note: the 3c575 uses 8bit EEPROM offsets.
1351    */
1352   XL_SEL_WIN(0);
1353
1354   if (xl_eeprom_wait(sc))
1355      return(1);
1356
1357   if (sc->xl_flags & XL_FLAG_EEPROM_OFFSET_30)
1358      off += 0x30;
1359
1360   for (i = 0; i < cnt; i++) {
1361      if (sc->xl_flags & XL_FLAG_8BITROM)
1362         CSR_WRITE_2(sc, XL_W0_EE_CMD,
1363                     XL_EE_8BIT_READ | EEPROM_8BIT_OFFSET(off + i));
1364      else
1365         CSR_WRITE_2(sc, XL_W0_EE_CMD,
1366                     XL_EE_READ | EEPROM_5BIT_OFFSET(off + i));
1367      err = xl_eeprom_wait(sc);
1368      if (err)
1369         break;
1370      word = CSR_READ_2(sc, XL_W0_EE_DATA);
1371      ptr = (u_int16_t*)(dest + (i * 2));
1372      if (swap)
1373         *ptr = ntohs(word);
1374      else
1375         *ptr = word;
1376   }
1377
1378   return(err ? 1 : 0);
1379}
1380
1381
1382
1383
1384static void
1385xl_stats_update(timerid,xsc)
1386   rtems_id timerid;
1387   void *xsc;
1388{
1389   struct elnk_softc    *sc = (struct elnk_softc *)xsc;
1390   struct ifnet         *ifp = &sc->arpcom.ac_if;
1391   u_int32_t            t1;
1392
1393   sc->xl_stats.intstatus = CSR_READ_2(sc, XL_STATUS);
1394
1395   sc->xl_stats.miianr    = xl_miibus_readreg(sc, 0x18, MII_ANAR );
1396   sc->xl_stats.miipar    = xl_miibus_readreg(sc, 0x18, MII_ANLPAR );
1397   sc->xl_stats.miistatus = xl_miibus_readreg(sc, 0x18, MII_BMSR );
1398   sc->xl_stats.miicmd    = xl_miibus_readreg(sc, 0x18, MII_BMCR );
1399
1400   XL_SEL_WIN(1);
1401   sc->xl_stats.rxstatus  = CSR_READ_2(sc, XL_W1_RX_STATUS );
1402   sc->xl_stats.txstatus  = CSR_READ_1(sc, XL_W1_TX_STATUS );
1403   sc->xl_stats.smbstatus = CSR_READ_2(sc, 2 );
1404
1405   XL_SEL_WIN(3);
1406   sc->xl_stats.internalconfig = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
1407   sc->xl_stats.mac_control    = CSR_READ_2(sc, XL_W3_MAC_CTRL);
1408   sc->xl_stats.txfree         = CSR_READ_2(sc, XL_W3_FREE_TX );
1409
1410
1411   /* Read all the stats registers. */
1412   XL_SEL_WIN(6);
1413
1414   sc->xl_stats.xl_carrier_lost              += CSR_READ_1(sc, XL_W6_CARRIER_LOST);
1415   sc->xl_stats.xl_sqe_errs                  += CSR_READ_1(sc, XL_W6_SQE_ERRORS);
1416   sc->xl_stats.xl_tx_multi_collision        += CSR_READ_1(sc, XL_W6_COL_MULTIPLE);
1417   sc->xl_stats.xl_tx_single_collision       += CSR_READ_1(sc, XL_W6_COL_SINGLE);
1418   sc->xl_stats.xl_tx_late_collision         += CSR_READ_1(sc, XL_W6_COL_LATE);
1419   sc->xl_stats.xl_rx_overrun                += CSR_READ_1(sc, XL_W6_RX_OVERRUN);
1420   sc->xl_stats.xl_tx_deferred               += CSR_READ_1(sc, XL_W6_DEFERRED);
1421
1422   sc->xl_stats.xl_tx_frames_ok              += CSR_READ_1(sc, XL_W6_TX_OK);
1423   sc->xl_stats.xl_rx_frames_ok              += CSR_READ_1(sc, XL_W6_RX_OK);
1424
1425   sc->xl_stats.xl_rx_bytes_ok               += CSR_READ_2(sc, XL_W6_TX_BYTES_OK );
1426   sc->xl_stats.xl_tx_bytes_ok               += CSR_READ_2(sc, XL_W6_RX_BYTES_OK );
1427
1428   t1 = CSR_READ_1(sc, XL_W6_UPPER_FRAMES_OK);
1429   sc->xl_stats.xl_rx_frames_ok +=  ((t1 & 0x3) << 8);
1430   sc->xl_stats.xl_tx_frames_ok +=  (((t1 >> 4) & 0x3) << 8);
1431
1432
1433   ifp->if_ierrors += sc->xl_stats.xl_rx_overrun;
1434
1435   ifp->if_collisions += sc->xl_stats.xl_tx_multi_collision +
1436      sc->xl_stats.xl_tx_single_collision +
1437      sc->xl_stats.xl_tx_late_collision;
1438
1439   /*
1440    * Boomerang and cyclone chips have an extra stats counter
1441    * in window 4 (BadSSD). We have to read this too in order
1442    * to clear out all the stats registers and avoid a statsoflow
1443    * interrupt.
1444    */
1445   XL_SEL_WIN(4);
1446
1447   t1 = CSR_READ_1(sc, XL_W4_UPPERBYTESOK);
1448   sc->xl_stats.xl_rx_bytes_ok += ((t1 & 0xf) << 16);
1449   sc->xl_stats.xl_tx_bytes_ok += (((t1 >> 4) & 0xf) << 16);
1450
1451   sc->xl_stats.xl_badssd               += CSR_READ_1(sc, XL_W4_BADSSD);
1452
1453   sc->xl_stats.mediastatus             = CSR_READ_2(sc, XL_W4_MEDIA_STATUS );
1454   sc->xl_stats.dmactl                  = CSR_READ_4(sc, XL_DMACTL );
1455
1456
1457   XL_SEL_WIN(7);
1458
1459   if (!sc->xl_stats_no_timeout)
1460      rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );
1461   return;
1462}
1463
1464
1465
1466
1467
1468
1469
1470static void
1471xl_reset(sc)
1472   struct elnk_softc            *sc;
1473{
1474   register int         i;
1475
1476   XL_SEL_WIN(0);
1477   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
1478               ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
1479                XL_RESETOPT_DISADVFD:0));
1480
1481   for (i = 0; i < XL_TIMEOUT; i++) {
1482      DELAY(10);
1483      if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
1484         break;
1485   }
1486
1487   if (i == XL_TIMEOUT)
1488      printk("etherlink : unit elnk%d reset didn't complete\n", sc->xl_unit);
1489
1490   /* Reset TX and RX. */
1491   /* Note: the RX reset takes an absurd amount of time
1492    * on newer versions of the Tornado chips such as those
1493    * on the 3c905CX and newer 3c908C cards. We wait an
1494    * extra amount of time so that xl_wait() doesn't complain
1495    * and annoy the users.
1496    */
1497   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
1498   DELAY(100000);
1499   xl_wait(sc);
1500   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
1501   xl_wait(sc);
1502
1503   if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR ||
1504       sc->xl_flags & XL_FLAG_INVERT_MII_PWR)
1505   {
1506      XL_SEL_WIN(2);
1507      CSR_WRITE_2(sc, XL_W2_RESET_OPTIONS, CSR_READ_2(sc,
1508                                                      XL_W2_RESET_OPTIONS)
1509                  | ((sc->xl_flags & XL_FLAG_INVERT_LED_PWR)?XL_RESETOPT_INVERT_LED:0)
1510                  | ((sc->xl_flags & XL_FLAG_INVERT_MII_PWR)?XL_RESETOPT_INVERT_MII:0)
1511         );
1512   }
1513
1514   /* Wait a little while for the chip to get its brains in order. */
1515   DELAY(100000);
1516   return;
1517}
1518
1519
1520
1521
1522static void
1523xl_stop(sc)
1524   struct elnk_softc            *sc;
1525{
1526   struct ifnet         *ifp;
1527
1528   ifp = &sc->arpcom.ac_if;
1529   ifp->if_timer = 0;
1530
1531   rtems_timer_cancel( sc->stat_timer_id );
1532
1533   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);
1534   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
1535   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB);
1536   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISCARD);
1537   xl_wait(sc);
1538   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
1539   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
1540   DELAY(800);
1541
1542   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|XL_STAT_INTLATCH);
1543   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|0);
1544   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
1545
1546   return;
1547}
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563static void
1564xl_setcfg(sc)
1565   struct elnk_softc            *sc;
1566{
1567   u_int32_t            icfg;
1568
1569   XL_SEL_WIN(3);
1570   icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
1571
1572   icfg &= ~XL_ICFG_CONNECTOR_MASK;
1573
1574   if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BT4)
1575      icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
1576
1577   if (sc->xl_media & XL_MEDIAOPT_BTX)
1578      icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
1579
1580   CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
1581   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
1582
1583   XL_SEL_WIN(7);
1584   return;
1585}
1586
1587
1588
1589static void
1590xl_setmode(sc, media)
1591   struct elnk_softc    *sc;
1592   int                  media;
1593{
1594   u_int32_t            icfg;
1595   u_int16_t            mediastat;
1596
1597   printk("etherlink : unit elnk%d selecting ", sc->xl_unit);
1598
1599   XL_SEL_WIN(4);
1600   mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
1601   XL_SEL_WIN(3);
1602   icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
1603
1604   if (sc->xl_media & XL_MEDIAOPT_BT) {
1605      if (IFM_SUBTYPE(media) == IFM_10_T) {
1606         printk("10baseT transceiver, ");
1607         sc->xl_xcvr = XL_XCVR_10BT;
1608         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1609         icfg |= (XL_XCVR_10BT << XL_ICFG_CONNECTOR_BITS);
1610         mediastat |= XL_MEDIASTAT_LINKBEAT|
1611            XL_MEDIASTAT_JABGUARD;
1612         mediastat &= ~XL_MEDIASTAT_SQEENB;
1613      }
1614   }
1615
1616   if (sc->xl_media & XL_MEDIAOPT_BFX) {
1617      if (IFM_SUBTYPE(media) == IFM_100_FX) {
1618         printk("100baseFX port, ");
1619         sc->xl_xcvr = XL_XCVR_100BFX;
1620         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1621         icfg |= (XL_XCVR_100BFX << XL_ICFG_CONNECTOR_BITS);
1622         mediastat |= XL_MEDIASTAT_LINKBEAT;
1623         mediastat &= ~XL_MEDIASTAT_SQEENB;
1624      }
1625   }
1626
1627   if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
1628      if (IFM_SUBTYPE(media) == IFM_10_5) {
1629         printk("AUI port, ");
1630         sc->xl_xcvr = XL_XCVR_AUI;
1631         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1632         icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
1633         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
1634                        XL_MEDIASTAT_JABGUARD);
1635         mediastat |= ~XL_MEDIASTAT_SQEENB;
1636      }
1637      if (IFM_SUBTYPE(media) == IFM_10_FL) {
1638         printk("10baseFL transceiver, ");
1639         sc->xl_xcvr = XL_XCVR_AUI;
1640         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1641         icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
1642         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
1643                        XL_MEDIASTAT_JABGUARD);
1644         mediastat |= ~XL_MEDIASTAT_SQEENB;
1645      }
1646   }
1647
1648   if (sc->xl_media & XL_MEDIAOPT_BNC) {
1649      if (IFM_SUBTYPE(media) == IFM_10_2) {
1650         printk("BNC port, ");
1651         sc->xl_xcvr = XL_XCVR_COAX;
1652         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1653         icfg |= (XL_XCVR_COAX << XL_ICFG_CONNECTOR_BITS);
1654         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
1655                        XL_MEDIASTAT_JABGUARD|
1656                        XL_MEDIASTAT_SQEENB);
1657      }
1658   }
1659
1660   if ((media & IFM_GMASK) == IFM_FDX ||
1661       IFM_SUBTYPE(media) == IFM_100_FX) {
1662      printk("full duplex\n");
1663      XL_SEL_WIN(3);
1664      CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);
1665   } else {
1666      printk("half duplex\n");
1667      XL_SEL_WIN(3);
1668      CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
1669                  (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));
1670   }
1671
1672   if (IFM_SUBTYPE(media) == IFM_10_2)
1673      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
1674   else
1675      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
1676
1677   CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
1678   XL_SEL_WIN(4);
1679   CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);
1680   DELAY(800);
1681   XL_SEL_WIN(7);
1682
1683   return;
1684}
1685
1686
1687
1688
1689
1690
1691
1692static void
1693xl_choose_xcvr(sc, verbose)
1694   struct elnk_softc    *sc;
1695   int                  verbose;
1696{
1697   u_int16_t            devid;
1698
1699   /*
1700    * Read the device ID from the EEPROM.
1701    * This is what's loaded into the PCI device ID register, so it has
1702    * to be correct otherwise we wouldn't have gotten this far.
1703    */
1704   xl_read_eeprom(sc, (caddr_t)&devid, XL_EE_PRODID, 1, 0);
1705
1706   switch(devid) {
1707      case TC_DEVICEID_BOOMERANG_10BT:  /* 3c900-TPO */
1708      case TC_DEVICEID_KRAKATOA_10BT:           /* 3c900B-TPO */
1709         sc->xl_media = XL_MEDIAOPT_BT;
1710         sc->xl_xcvr = XL_XCVR_10BT;
1711         if (verbose)
1712            printk("etherlink : unit elnk%d guessing 10BaseT "
1713                   "transceiver\n", sc->xl_unit);
1714         break;
1715      case TC_DEVICEID_BOOMERANG_10BT_COMBO:    /* 3c900-COMBO */
1716      case TC_DEVICEID_KRAKATOA_10BT_COMBO:     /* 3c900B-COMBO */
1717         sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
1718         sc->xl_xcvr = XL_XCVR_10BT;
1719         if (verbose)
1720            printk("etherlink : unit elnk%d guessing COMBO "
1721                   "(AUI/BNC/TP)\n", sc->xl_unit);
1722         break;
1723      case TC_DEVICEID_KRAKATOA_10BT_TPC:       /* 3c900B-TPC */
1724         sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
1725         sc->xl_xcvr = XL_XCVR_10BT;
1726         if (verbose)
1727            printk("etherlink : unit elnk%d guessing TPC (BNC/TP)\n", sc->xl_unit);
1728         break;
1729      case TC_DEVICEID_CYCLONE_10FL:            /* 3c900B-FL */
1730         sc->xl_media = XL_MEDIAOPT_10FL;
1731         sc->xl_xcvr = XL_XCVR_AUI;
1732         if (verbose)
1733            printk("etherlink : unit elnk%d guessing 10baseFL\n", sc->xl_unit);
1734         break;
1735      case TC_DEVICEID_BOOMERANG_10_100BT:      /* 3c905-TX */
1736      case TC_DEVICEID_HURRICANE_555:           /* 3c555 */
1737      case TC_DEVICEID_HURRICANE_556:           /* 3c556 */
1738      case TC_DEVICEID_HURRICANE_556B:  /* 3c556B */
1739      case TC_DEVICEID_HURRICANE_575A:  /* 3c575TX */
1740      case TC_DEVICEID_HURRICANE_575B:  /* 3c575B */
1741      case TC_DEVICEID_HURRICANE_575C:  /* 3c575C */
1742      case TC_DEVICEID_HURRICANE_656:           /* 3c656 */
1743      case TC_DEVICEID_HURRICANE_656B:  /* 3c656B */
1744      case TC_DEVICEID_TORNADO_656C:            /* 3c656C */
1745      case TC_DEVICEID_TORNADO_10_100BT_920B:   /* 3c920B-EMB */
1746         sc->xl_media = XL_MEDIAOPT_MII;
1747         sc->xl_xcvr = XL_XCVR_MII;
1748         if (verbose)
1749            printk("etherlink : unit elnk%d guessing MII\n", sc->xl_unit);
1750         break;
1751      case TC_DEVICEID_BOOMERANG_100BT4:        /* 3c905-T4 */
1752      case TC_DEVICEID_CYCLONE_10_100BT4:       /* 3c905B-T4 */
1753         sc->xl_media = XL_MEDIAOPT_BT4;
1754         sc->xl_xcvr = XL_XCVR_MII;
1755         if (verbose)
1756            printk("etherlink : unit elnk%d guessing 100BaseT4/MII\n", sc->xl_unit);
1757         break;
1758      case TC_DEVICEID_HURRICANE_10_100BT:      /* 3c905B-TX */
1759      case TC_DEVICEID_HURRICANE_10_100BT_SERV:/*3c980-TX */
1760      case TC_DEVICEID_TORNADO_10_100BT_SERV:   /* 3c980C-TX */
1761      case TC_DEVICEID_HURRICANE_SOHO100TX:     /* 3cSOHO100-TX */
1762      case TC_DEVICEID_TORNADO_10_100BT:        /* 3c905C-TX */
1763      case TC_DEVICEID_TORNADO_HOMECONNECT:     /* 3c450-TX */
1764         sc->xl_media = XL_MEDIAOPT_BTX;
1765         sc->xl_xcvr = XL_XCVR_AUTO;
1766         if (verbose)
1767            printk("etherlink : unit elnk%d guessing 10/100 internal\n", sc->xl_unit);
1768         break;
1769      case TC_DEVICEID_CYCLONE_10_100_COMBO:    /* 3c905B-COMBO */
1770         sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
1771         sc->xl_xcvr = XL_XCVR_AUTO;
1772         if (verbose)
1773            printk("etherlink : unit elnk%d guessing 10/100 "
1774                   "plus BNC/AUI\n", sc->xl_unit);
1775         break;
1776      default:
1777         printk("etherlink : unit elnk%d unknown device ID: %x -- "
1778                "defaulting to 10baseT\n", sc->xl_unit, devid);
1779         sc->xl_media = XL_MEDIAOPT_BT;
1780         break;
1781   }
1782
1783   return;
1784}
1785
1786
1787
1788
1789
1790
1791
1792/*
1793 * This routine is a kludge to work around possible hardware faults
1794 * or manufacturing defects that can cause the media options register
1795 * (or reset options register, as it's called for the first generation
1796 * 3c90x adapters) to return an incorrect result. I have encountered
1797 * one Dell Latitude laptop docking station with an integrated 3c905-TX
1798 * which doesn't have any of the 'mediaopt' bits set. This screws up
1799 * the attach routine pretty badly because it doesn't know what media
1800 * to look for. If we find ourselves in this predicament, this routine
1801 * will try to guess the media options values and warn the user of a
1802 * possible manufacturing defect with his adapter/system/whatever.
1803 */
1804static void
1805xl_mediacheck(sc)
1806   struct elnk_softc            *sc;
1807{
1808
1809   xl_choose_xcvr(sc, 1);
1810
1811   /*
1812    * If some of the media options bits are set, assume they are
1813    * correct. If not, try to figure it out down below.
1814    * XXX I should check for 10baseFL, but I don't have an adapter
1815    * to test with.
1816    */
1817   if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {
1818      /*
1819       * Check the XCVR value. If it's not in the normal range
1820       * of values, we need to fake it up here.
1821       */
1822      if (sc->xl_xcvr <= XL_XCVR_AUTO)
1823         return;
1824      else {
1825         printk("etherlink : unit elnk%d bogus xcvr value "
1826                "in EEPROM (%x)\n", sc->xl_unit, sc->xl_xcvr);
1827         printk("etherlink : unit elnk%d choosing new default based "
1828                "on card type\n", sc->xl_unit);
1829      }
1830   } else {
1831      if (sc->xl_type == XL_TYPE_905B &&
1832          sc->xl_media & XL_MEDIAOPT_10FL)
1833         return;
1834      printk("etherlink : unit elnk%d WARNING: no media options bits set in "
1835             "the media options register!!\n", sc->xl_unit);
1836      printk("etherlink : unit elnk%d this could be a manufacturing defect in "
1837             "your adapter or system\n", sc->xl_unit);
1838      printk("etherlink : unit elnk%d attempting to guess media type; you "
1839             "should probably consult your vendor\n", sc->xl_unit);
1840   }
1841
1842   return;
1843}
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869static void no_op(const rtems_irq_connect_data* irq)
1870{
1871   return;
1872}
1873
1874
1875
1876
1877static int elnkIsOn(const rtems_irq_connect_data* irq)
1878{
1879  return BSP_irq_enabled_at_i8259s (irq->name);
1880}
1881
1882
1883
1884
1885
1886
1887static void
1888elnk_start_txchain( struct elnk_softc *sc, struct TXMD *chainhead )
1889{
1890   xl_wait(sc);
1891   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
1892
1893   /* save the address of the TX list */
1894   sc->last_txchain_head = chainhead;
1895   sc->tx_idle = 0;
1896
1897   xl_wait(sc);
1898
1899   CSR_WRITE_4(sc, XL_DOWNLIST_PTR, phys_to_bus( sc->last_txchain_head ));
1900   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
1901}
1902
1903
1904
1905
1906
1907/*
1908 * ELNK interrupt handler
1909 */
1910static rtems_isr
1911elnk_interrupt_handler ( struct elnk_softc *sc )
1912{
1913   struct ifnet         *ifp = &sc->arpcom.ac_if;
1914   u_int16_t            status;
1915
1916   while( ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS) && status != 0xFFFF)
1917   {
1918      sc->xl_stats.device_interrupts++;
1919
1920      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK | (status & XL_INTRS));
1921
1922#if 0
1923      printk("etherlink : unit elnk%d intstatus %04x\n", sc->xl_unit, status  );
1924#endif
1925
1926      if (status & XL_STAT_UP_COMPLETE)
1927      {
1928#if 0
1929         printk("etherlink : unit elnk%d rx\n", sc->xl_unit );
1930#endif
1931         /* received packets */
1932         rtems_event_send(rxDaemonTid, sc->ioevent);
1933      }
1934
1935      if( (status & XL_STAT_DOWN_COMPLETE) || (status & XL_STAT_TX_COMPLETE) )
1936      {
1937         /* all packets uploaded to the device */
1938         struct TXMD *chaintailmd = NULL;
1939
1940
1941         if( status & XL_STAT_TX_COMPLETE )
1942         {
1943            /* if we got a tx complete error, count it, then reset the
1944               transmitter.  Consider the entire chain lost.. */
1945
1946            ifp->if_oerrors++;
1947            sc->xl_stats.txcomplete_ints++;
1948
1949            printk("etherlink : unit elnk%d transmit error\n", sc->xl_unit );
1950
1951            /* reset, re-enable fifo */
1952
1953            xl_wait(sc);
1954            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
1955
1956            xl_wait(sc);
1957            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET | 1 );
1958
1959            xl_wait(sc);
1960            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
1961
1962            xl_wait(sc);
1963         }
1964
1965
1966         /* send the chain head to the tx task which will recover the
1967            whole chain */
1968         rtems_message_queue_send( chainRecoveryQueue, &sc->last_txchain_head, sizeof(struct TXMD *));
1969
1970
1971         /* set up the next chain */
1972         if( sc->last_txchain_head->chainptr )
1973         {
1974            /* check the head of the chain of packets we just finished,
1975             * if != 0, either this is a chain of 2 or more packets or
1976             * its a single packet chain and another chain is ready to
1977             * send.
1978             */
1979            if( (int)sc->last_txchain_head->chainptr == -1 )
1980            {
1981               /*
1982               ** single packet was sent so no indirection to the last
1983               ** entry in the chain.  since chainptr is != 0, then
1984               ** another chain is ready starting from the packet AFTER
1985               ** the chain we just finished. - in this case the last
1986               ** chain's head == its tail
1987               */
1988               chaintailmd = sc->last_txchain_head;
1989            }
1990            else
1991            {
1992               /*
1993               ** otherwise, this is a pointer to the last packet in the
1994               ** chain of 2 or more packets.  If the chain's last
1995               ** packet's chainptr is != 0, then another chain is ready
1996               ** to send.
1997               */
1998               chaintailmd = sc->last_txchain_head->chainptr;
1999               if( !chaintailmd->chainptr ) chaintailmd = NULL;
2000            }
2001         }
2002
2003         if( chaintailmd )
2004         {
2005            /* the next MD is the start of another chain */
2006            elnk_start_txchain(sc, chaintailmd->next_md );
2007         }
2008         else
2009         {
2010            /* otherwise nothing to send, so go idle */
2011            sc->tx_idle = -1;
2012
2013            /* wake up the tx daemon once so we're sure this last chain
2014               will be freed */
2015            rtems_event_send( txDaemonTid, sc->ioevent );
2016#if 0
2017            printk("unit elnk%d tx done\n", sc->xl_unit );
2018#endif
2019         }
2020      }
2021
2022
2023      if (status & XL_STAT_ADFAIL)
2024      {
2025         printk("etherlink : unit elnk%d Catastrophic bus failure\n", sc->xl_unit );
2026      }
2027      if (status & XL_STAT_STATSOFLOW)
2028      {
2029         sc->xl_stats_no_timeout = 1;
2030         xl_stats_update(sc->stat_timer_id,sc);
2031         sc->xl_stats_no_timeout = 0;
2032      }
2033   }
2034
2035
2036#if 0
2037   {
2038      uint16_t   intstatus, intenable, indenable;
2039
2040      intstatus = CSR_READ_2(sc, XL_STATUS );
2041
2042      XL_SEL_WIN(5);
2043      intenable = CSR_READ_2(sc, XL_W5_INTR_ENB );
2044      indenable = CSR_READ_2(sc, XL_W5_STAT_ENB );
2045      XL_SEL_WIN(7);
2046      printk("etherlink : unit elnk%d istat %04x, ien %04x, ind %04x\n", sc->xl_unit, intstatus, intenable, indenable  );
2047   }
2048#endif
2049}
2050
2051
2052
2053
2054
2055static rtems_isr
2056elnk_interrupt_handler_entry()
2057{
2058   int i;
2059
2060   /*
2061   ** Check all the initialized units for interrupt service
2062   */
2063
2064   for(i=0; i< NUM_UNITS; i++ )
2065   {
2066      if( elnk_softc[i].ioaddr )
2067         elnk_interrupt_handler( &elnk_softc[i] );
2068   }
2069}
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081/*
2082 * Initialize the ethernet hardware
2083 */
2084static void
2085elnk_initialize_hardware (struct elnk_softc *sc)
2086{
2087   unsigned char *cp;
2088   int i, j, rxsize, txsize, ringsize;
2089
2090   /*
2091    * Init RX ring
2092    */
2093   cp = (unsigned char *)malloc( (ringsize = ((rxsize = (sc->numRxbuffers * sizeof(struct RXMD))) +
2094                                              (txsize = (sc->numTxbuffers * sizeof(struct TXMD)))) ) +
2095                                 + CPU_CACHE_ALIGNMENT_FOR_BUFFER);
2096   sc->bufferBase = cp;
2097   cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp) & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
2098#if defined(__i386__)
2099#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
2100   if (_CPU_is_paging_enabled())
2101      _CPU_change_memory_mapping_attribute
2102         (NULL, cp, ringsize, PTE_CACHE_DISABLE | PTE_WRITABLE);
2103#endif
2104#endif
2105   sc->ringBase = cp;
2106
2107   /* build tx and rx rings */
2108
2109   sc->rx_ring = (struct RXMD *)sc->ringBase;
2110   sc->tx_ring = (struct TXMD *)&sc->ringBase[ rxsize ];
2111
2112   {
2113      struct mbuf    *m;
2114      struct RXMD    *nxtmd;
2115      /*
2116       * The rx ring is easy as its just an array of RXMD structs.  New
2117       * mbuf entries are allocated from the stack whenever the rx
2118       * daemon forwards an incoming packet into it.  Here, we
2119       * pre-allocate the rx mbufs for the rx ring entries.
2120       */
2121      for(i=0 ; i<sc->numRxbuffers; i++)
2122      {
2123         if( ((uint32_t)&sc->rx_ring[i] & 0x7) )
2124         {
2125            rtems_panic ("etherlink : unit elnk%d rx ring entry %d not aligned to 8 bytes\n", sc->xl_unit, i );
2126         }
2127
2128         /* allocate an mbuf for each receive descriptor */
2129         MGETHDR (m, M_WAIT, MT_DATA);
2130         MCLGET (m, M_WAIT);
2131         m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
2132
2133         if( i == sc->numRxbuffers-1 )
2134            nxtmd = &sc->rx_ring[0];
2135         else
2136            nxtmd = &sc->rx_ring[i+1];
2137
2138         sc->rx_ring[i].next_md = nxtmd;
2139         sc->rx_ring[i].mbuf = m;
2140
2141         st_le32( &sc->rx_ring[i].status, 0);
2142         st_le32( &sc->rx_ring[i].next, (uint32_t)phys_to_bus( nxtmd ));
2143         st_le32( &sc->rx_ring[i].addr, (uint32_t)phys_to_bus( mtod(m, void *) ));
2144         st_le32( &sc->rx_ring[i].length, XL_LAST_FRAG | XL_PACKET_SIZE );
2145      }
2146      sc->curr_rx_md = &sc->rx_ring[0];
2147   }
2148
2149
2150   {
2151      struct TXMD *thismd, *nxtmd;
2152      /*
2153       * The tx ring is more complex. Each MD has an array of fragment
2154       * descriptors that are loaded from each packet as they arrive
2155       * from the stack.  Each packet gets one ring entry, this allows
2156       * the lanboard to efficiently assemble the piecemeal packets into
2157       * a contiguous unit at transmit time, rather than spending
2158       * cputime concatenating them first.  Although the next_md fields
2159       * form a ring, the DPD next is filled only when packets are added
2160       * to the tx chain, thus last entry of a series of packets has the
2161       * requisite dpd->next value == 0 to terminate the dma.  mbuf
2162       * holds the packet info so it can be freed once the packet has
2163       * been sent.  chainptr is used to link the head & tail of a chain
2164       * of 2 or more packets.  A chain is formed when the tx daemon
2165       * gets 2 or more packets from the stack's queue in a service
2166       * period, so higher outgoing loads are handled as efficiently as
2167       * possible.
2168       */
2169
2170      for(i=0 ; i<sc->numTxbuffers; i++)
2171      {
2172         if( ((uint32_t)&sc->tx_ring[i] & 0x7) )
2173         {
2174            rtems_panic ("etherlink : unit elnk%d tx ring entry %d not aligned to 8 bytes\n", sc->xl_unit, i );
2175         }
2176
2177         if( i == sc->numTxbuffers-1 )
2178            nxtmd = &sc->tx_ring[0];
2179         else
2180            nxtmd = &sc->tx_ring[i+1];
2181
2182         thismd = &sc->tx_ring[i];
2183
2184         thismd->next_md = nxtmd;
2185         thismd->chainptr = NULL;
2186         thismd->mbuf = NULL;
2187
2188         st_le32( &thismd->status, XL_TXSTAT_DL_COMPLETE );
2189         st_le32( &thismd->next, 0);
2190
2191         for(j=0; j< NUM_FRAGS; j++)
2192         {
2193            st_le32( &thismd->txfrags[j].addr, 0 );
2194            st_le32( &thismd->txfrags[j].length, 0 );
2195         }
2196      }
2197      sc->last_tx_md = &sc->tx_ring[0];
2198   }
2199
2200
2201
2202
2203#ifdef ELNK_DEBUG
2204   printk("etherlink : %02x:%02x:%02x:%02x:%02x:%02x   name 'elnk%d', io %x, int %d\n",
2205          sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
2206          sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
2207          sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
2208          sc->xl_unit,
2209          (unsigned)sc->ioaddr, sc->irqInfo.name );
2210#endif
2211
2212
2213   sc->irqInfo.hdl  = (rtems_irq_hdl)elnk_interrupt_handler_entry;
2214   sc->irqInfo.on   = no_op;
2215   sc->irqInfo.off  = no_op;
2216   sc->irqInfo.isOn = elnkIsOn;
2217
2218   if( sc->irqInfo.name != 255 )
2219   {
2220      int st;
2221
2222#ifdef BSP_SHARED_HANDLER_SUPPORT
2223      st = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );
2224#else
2225      st = BSP_install_rtems_irq_handler( &sc->irqInfo );
2226#endif
2227      if (!st)
2228         rtems_panic ("etherlink : unit elnk%d Interrupt name %d already in use\n", sc->xl_unit, sc->irqInfo.name );
2229   }
2230   else
2231   {
2232      printk("etherlink : unit elnk%d Interrupt not specified by device\n", sc->xl_unit );
2233   }
2234}
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246static void
2247elnk_rxDaemon (void *arg)
2248{
2249   struct elnk_softc     *sc;
2250   struct ether_header   *eh;
2251   struct mbuf           *m;
2252   struct RXMD           *rmd;
2253   unsigned int          i,len, rxstat;
2254   rtems_event_set       events;
2255
2256   for (;;)
2257   {
2258
2259      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
2260                                  RTEMS_WAIT|RTEMS_EVENT_ANY,
2261                                  RTEMS_NO_TIMEOUT,
2262                                  &events);
2263
2264      for(;;)
2265      {
2266         for(i=0; i< NUM_UNITS; i++ )
2267         {
2268            sc = &elnk_softc[i];
2269            if( sc->ioaddr )
2270            {
2271               if( events & sc->ioevent )
2272               {
2273                  struct ifnet *ifp = &sc->arpcom.ac_if;
2274
2275                  rmd   = sc->curr_rx_md;
2276
2277                  /*
2278                  ** Read off all the packets we've received on this unit
2279                  */
2280                  while( (rxstat = ld_le32(&rmd->status)) )
2281                  {
2282                     if (rxstat & XL_RXSTAT_UP_ERROR)
2283                     {
2284                        printk("unit %i up error\n", sc->xl_unit );
2285                        ifp->if_ierrors++;
2286                     }
2287
2288                     if( (rxstat & XL_RXSTAT_UP_CMPLT) )
2289                     {
2290
2291#if 0
2292                        {
2293                           char *pkt, *delim;
2294                           int  i;
2295                           pkt = mtod(rmd->mbuf, char *);
2296                           printk("unit %i rx  pkt (%08x) ", sc->xl_unit, pkt );
2297                           for(delim="", i=0; i < sizeof(struct ether_header)+8; i++, delim=":")
2298                              printk("%s%02x", delim, (char) pkt[i] );
2299                           printk("\n");
2300                        }
2301#endif
2302
2303                        /* pass on the packet in the mbuf */
2304                        len = ( ld_le32(&rmd->status) & XL_RXSTAT_LENMASK);
2305                        m = rmd->mbuf;
2306                        m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
2307                        eh = mtod(m, struct ether_header *);
2308                        m->m_data += sizeof(struct ether_header);
2309
2310                        ether_input(ifp, eh, m);
2311
2312                        /* get a new mbuf */
2313                        MGETHDR (m, M_WAIT, MT_DATA);
2314                        MCLGET (m, M_WAIT);
2315                        m->m_pkthdr.rcvif = ifp;
2316                        rmd->mbuf   = m;
2317                        st_le32( &rmd->status, 0 );
2318                        st_le32( &rmd->addr, (uint32_t)phys_to_bus(mtod(m, void *)) );
2319                     }
2320                     else
2321                     {
2322                        /* some kind of packet failure */
2323                        printk("etherlink : unit elnk%d bad receive status -- packet dropped\n", sc->xl_unit);
2324                        ifp->if_ierrors++;
2325                     }
2326                     /* clear descriptor status */
2327                     rmd->status = 0;
2328
2329                     rmd = rmd->next_md;
2330                  }
2331
2332                  sc->curr_rx_md = rmd;
2333               }
2334            }
2335         }
2336
2337         /*
2338         ** If more events are pending, service them before we go back to sleep
2339         */
2340         if( rtems_event_receive( RTEMS_ALL_EVENTS,
2341                                  RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
2342                                  0,
2343                                  &events ) == RTEMS_UNSATISFIED ) break;
2344      }
2345   }
2346}
2347
2348
2349
2350
2351
2352
2353
2354
2355/*
2356 * Driver transmit daemon
2357 */
2358void
2359elnk_txDaemon (void *arg)
2360{
2361   struct elnk_softc     *sc;
2362   struct ifnet          *ifp;
2363   struct mbuf           *m;
2364   struct TXMD           *lastmd, *nextmd, *firstmd;
2365   int                   chainCount,i;
2366   rtems_event_set       events;
2367
2368   for (;;)
2369   {
2370      /*
2371       * Wait for any unit's signal to wake us up
2372       */
2373      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
2374                                  RTEMS_EVENT_ANY | RTEMS_WAIT,
2375                                  RTEMS_NO_TIMEOUT, &events);
2376
2377      for(i=0; i< NUM_UNITS; i++ )
2378      {
2379         sc  = &elnk_softc[i];
2380         if( sc->ioaddr )
2381         {
2382            if( events & sc->ioevent )
2383            {
2384               ifp = &sc->arpcom.ac_if;
2385
2386               /*
2387                * Send packets till queue is empty or tx ring is full
2388                */
2389
2390               chainCount = 0;
2391               firstmd = NULL;
2392
2393               lastmd = sc->last_tx_md;
2394
2395               for(;;)
2396               {
2397                  /*
2398                  ** Check the chain recovery queue whenever the tx
2399                  ** daemon services the stack.  Note this routine does
2400                  ** not assume the context of one of the lanboard units
2401                  ** because used tx mbufs are no longer associated with
2402                  ** any unit.
2403                  */
2404                  {
2405                     struct TXMD *chainhead, *chaintail;
2406                     size_t esize;
2407
2408                     if( rtems_message_queue_receive( chainRecoveryQueue, &chainhead, &esize,
2409                                                      RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL )
2410                     {
2411                        /* get a pointer to the tail */
2412                        chaintail = chainhead->chainptr;
2413
2414                        /* if the tail points somewhere, free the entire
2415                           chain */
2416                        if( chaintail && (int)chaintail != -1 )
2417                        {
2418                           for(;;)
2419                           {
2420                              m_freem( chainhead->mbuf );
2421                              st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
2422                              chainhead->mbuf = NULL;
2423
2424                              if(  chainhead == chaintail ) break;
2425                              chainhead = chainhead->next_md;
2426                           }
2427                        }
2428                        else
2429                        {
2430                           /* a single packet chain */
2431                           m_freem( chainhead->mbuf );
2432                           st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
2433                           chainhead->mbuf = NULL;
2434                        }
2435                     }
2436                  }
2437
2438                  nextmd = lastmd->next_md;
2439
2440                  /* stop when ring is full */
2441                  if( ! (ld_le32(&nextmd->status) & XL_TXSTAT_DL_COMPLETE) )
2442                  {
2443                     printk("etherlink : unit elnk%d tx ring full!\n", sc->xl_unit);
2444                     break;
2445                  }
2446                  /* sanity check the next packet descriptor */
2447                  if( nextmd->mbuf )
2448                  {
2449                     printk("etherlink : unit elnk%d tx ring corrupt!\n", sc->xl_unit);
2450                     break;
2451                  }
2452
2453
2454
2455                  IF_DEQUEUE(&ifp->if_snd, m);
2456                  if( !m ) break;
2457
2458                  {
2459                     int i;
2460
2461                     nextmd->mbuf = m;
2462
2463                     for(i=0; i< NUM_FRAGS; i++)
2464                     {
2465                        st_le32( &nextmd->txfrags[i].length, ((m->m_next)?0:XL_LAST_FRAG) | ( m->m_len & XL_TXSTAT_LENMASK) );
2466                        st_le32( &nextmd->txfrags[i].addr, (uint32_t)phys_to_bus( m->m_data ) );
2467                        if ((m = m->m_next) == NULL)
2468                           break;
2469                     }
2470                     if( m )
2471                     {
2472                        printk("etherlink : unit elnk%d tx fragments exhausted, truncating packet!\n", sc->xl_unit);
2473                        st_le32( &nextmd->txfrags[NUM_FRAGS-1].length, XL_LAST_FRAG |
2474                                 ld_le32( &nextmd->txfrags[NUM_FRAGS-1].length) );
2475                     }
2476                  }
2477
2478#if 0
2479                  {
2480                     char *pkt = bus_to_phys( ld_le32( &nextmd->txfrags[i].addr )), *delim;
2481                     int  i;
2482                     printk("unit %d queued  pkt (%08x) ", sc->xl_unit, (uint32_t)pkt );
2483                     for(delim="", i=0; i < sizeof(struct ether_header); i++, delim=":")
2484                        printk("%s%02x", delim, (char) pkt[i] );
2485                     printk("\n");
2486                  }
2487#endif
2488
2489
2490                  /* this packet will be the new end of the list */
2491                  st_le32( &nextmd->next, 0);
2492                  st_le32( &nextmd->status, 0);
2493
2494                  if( !firstmd )
2495                  {
2496                     /* keep track of the first packet we add to the chain */
2497                     firstmd = nextmd;
2498
2499                     /*
2500                      ** use the chainbuf pointer of the last packet of
2501                      ** the previous chain as a flag so when a
2502                      ** dnComplete interrupt indicates the card is
2503                      ** finished downloading the chain, the isr can
2504                      ** immediately start the next which always begins
2505                      ** with the next packet in the ring.  Note several
2506                      ** chains of packets may be assembled this way.
2507                      */
2508                     lastmd->chainptr = (struct TXMD *)-1;
2509                  }
2510                  else
2511                  {
2512                     /* hook this packet to the previous one */
2513                     st_le32( &lastmd->next, (uint32_t)phys_to_bus( nextmd ));
2514                  }
2515
2516                  ++chainCount;
2517                  lastmd = nextmd;
2518               }
2519
2520
2521
2522
2523
2524               if( firstmd )
2525               {
2526                  /* only enter if we've queued one or more packets */
2527
2528                  /* save the last descriptor we set up in the chain */
2529                  sc->last_tx_md = lastmd;
2530
2531                  /*
2532                   * We've added one or more packets to a chain, flag
2533                   * the last packet so we get an dnComplete interrupt
2534                   * when the card finishes accepting the chain
2535                   */
2536                  st_le32( &lastmd->status, XL_TXSTAT_DL_INTR );
2537
2538                  /*
2539                   * point the chain head's chainptr to the tail so we
2540                   * can jump to the next chain to send inside the isr.
2541                   * If we're only sending one packet, then don't bother
2542                   * with the link, as the chainptr value will either be
2543                   * 0 if theres no next chain or -1 if there is.
2544                   */
2545                  if( chainCount > 1 )
2546                  {
2547                     firstmd->chainptr = lastmd;
2548
2549                     sc->chain_lengths[sc->chlenIndex]= (short)chainCount;
2550                     if( ++sc->chlenIndex == NUM_CHAIN_LENGTHS ) sc->chlenIndex = 0;
2551                  }
2552
2553                  /*
2554                  ** clear the last packet's chainptr flag.  If another
2555                  ** chain is added later but before this chain is
2556                  ** finished being sent, this flag on this packet will
2557                  ** be re-set to -1
2558                  */
2559                  lastmd->chainptr = NULL;
2560
2561#if 0
2562                  printk("unit %d queued %d pkts, lastpkt status %08X\n",
2563                         sc->xl_unit,
2564                         chainCount,
2565                         (uint32_t)ld_le32( &lastmd->status) );
2566#endif
2567
2568                  if( sc->tx_idle == 0 && CSR_READ_4(sc, XL_DOWNLIST_PTR) == 0 )
2569                  {
2570                     printk("etherlink : unit elnk%d tx forced!\n", sc->xl_unit);
2571                     sc->tx_idle = -1;
2572                  }
2573
2574                  /*
2575                  ** start sending this chain of packets if tx isn't
2576                  ** busy, else the dnComplete interrupt will see there
2577                  ** is another chain waiting and begin it immediately.
2578                  */
2579                  if( sc->tx_idle )
2580                  {
2581#if 0
2582                     printk("etherlink : unit elnk%d tx started %d packets\n", sc->xl_unit, chainCount );
2583#endif
2584                     elnk_start_txchain(sc, firstmd);
2585                  }
2586               }
2587
2588
2589               ifp->if_flags &= ~IFF_OACTIVE;
2590            }
2591         }
2592      }
2593   }
2594}
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606static void
2607elnk_start (struct ifnet *ifp)
2608{
2609   struct elnk_softc *sc = ifp->if_softc;
2610#if 0
2611   printk("unit %i tx signaled\n", sc->xl_unit );
2612#endif
2613   ifp->if_flags |= IFF_OACTIVE;
2614   rtems_event_send( txDaemonTid, sc->ioevent );
2615}
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631/*
2632 * Initialize and start the device
2633 */
2634static void
2635elnk_init (void *arg)
2636{
2637   int i;
2638   struct elnk_softc *sc = arg;
2639   struct ifnet *ifp = &sc->arpcom.ac_if;
2640
2641   if( !(ifp->if_flags & IFF_RUNNING) )
2642   {
2643      xl_stop(sc);
2644      xl_reset(sc);
2645      sc->tx_idle = -1;
2646
2647      {
2648         uint32_t   cr,sr;
2649
2650         xl_miibus_writereg(sc, 0x18, MII_BMCR, BMCR_RESET );
2651
2652         while( (cr = xl_miibus_readreg(sc, 0x18, MII_BMCR )) & BMCR_RESET )
2653         {
2654            DELAY(100000);
2655         }
2656
2657         xl_miibus_writereg(sc, 0x18, MII_ANAR, ANAR_10 | ANAR_TX | ANAR_10_FD | ANAR_TX_FD );  /*  ANAR_T4 */
2658         xl_miibus_writereg(sc, 0x18, MII_BMCR, BMCR_STARTNEG | BMCR_AUTOEN );
2659
2660         for (i=0; ((sr = xl_miibus_readreg(sc, 0x18, MII_BMSR)) & BMSR_ACOMP) == 0 && i < 20; i++) 
2661            DELAY(10000);
2662      }
2663
2664
2665      /*
2666       * Set up hardware if its not already been done
2667       */
2668      if( !sc->irqInfo.hdl )
2669      {
2670         elnk_initialize_hardware(sc);
2671      }
2672
2673      /*
2674       * Enable the card
2675       */
2676      {
2677         u_int8_t               rxfilt;
2678
2679         /* Init our MAC address */
2680         XL_SEL_WIN(2);
2681         for (i = 0; i < ETHER_ADDR_LEN; i++)
2682         {
2683            CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i, sc->arpcom.ac_enaddr[i]);
2684         }
2685
2686         {
2687            int  media = IFM_ETHER|IFM_100_TX|IFM_FDX;
2688
2689            xl_mediacheck(sc);
2690
2691            /* Choose a default media. */
2692            switch(sc->xl_xcvr) {
2693               case XL_XCVR_10BT:
2694                  media = IFM_ETHER|IFM_10_T;
2695                  xl_setmode(sc, media);
2696                  break;
2697               case XL_XCVR_AUI:
2698                  if (sc->xl_type == XL_TYPE_905B &&
2699                      sc->xl_media == XL_MEDIAOPT_10FL) {
2700                     media = IFM_ETHER|IFM_10_FL;
2701                     xl_setmode(sc, media);
2702                  } else {
2703                     media = IFM_ETHER|IFM_10_5;
2704                     xl_setmode(sc, media);
2705                  }
2706                  break;
2707               case XL_XCVR_COAX:
2708                  media = IFM_ETHER|IFM_10_2;
2709                  xl_setmode(sc, media);
2710                  break;
2711               case XL_XCVR_AUTO:
2712               case XL_XCVR_100BTX:
2713                  xl_setcfg(sc);
2714                  break;
2715               case XL_XCVR_MII:
2716                  printk("etherlink : unit elnk%d MII media not supported!\n", sc->xl_unit);
2717                  break;
2718               case XL_XCVR_100BFX:
2719                  media = IFM_ETHER|IFM_100_FX;
2720                  break;
2721               default:
2722                  printk("etherlink : unit elnk%d unknown XCVR type: %d\n", sc->xl_unit, sc->xl_xcvr);
2723                  /*
2724                   * This will probably be wrong, but it prevents
2725                   * the ifmedia code from panicking.
2726                   */
2727                  media = IFM_ETHER|IFM_10_T;
2728                  break;
2729            }
2730
2731
2732            if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
2733               XL_SEL_WIN(0);
2734               CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
2735            }
2736         }
2737
2738
2739
2740         XL_SEL_WIN(2);
2741         /* Clear the station mask. */
2742         for (i = 0; i < 3; i++)
2743            CSR_WRITE_2(sc, XL_W2_STATION_MASK_LO + (i * 2), 0);
2744
2745         /*
2746          * Set the TX freethresh value.
2747          * Note that this has no effect on 3c905B "cyclone"
2748          * cards but is required for 3c900/3c905 "boomerang"
2749          * cards in order to enable the download engine.
2750          */
2751         CSR_WRITE_1(sc, XL_TX_FREETHRESH, XL_PACKET_SIZE >> 8);
2752
2753         /* Set the TX start threshold for best performance. */
2754         sc->xl_tx_thresh = XL_MIN_FRAMELEN;
2755         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_SET_START|sc->xl_tx_thresh);
2756
2757         /*
2758          * If this is a 3c905B, also set the tx reclaim threshold.
2759          * This helps cut down on the number of tx reclaim errors
2760          * that could happen on a busy network. The chip multiplies
2761          * the register value by 16 to obtain the actual threshold
2762          * in bytes, so we divide by 16 when setting the value here.
2763          * The existing threshold value can be examined by reading
2764          * the register at offset 9 in window 5.
2765          */
2766         if (sc->xl_type == XL_TYPE_905B) {
2767            CSR_WRITE_2(sc, XL_COMMAND,
2768                        XL_CMD_SET_TX_RECLAIM|(XL_PACKET_SIZE >> 4));
2769         }
2770
2771         /* Set RX filter bits. */
2772         XL_SEL_WIN(5);
2773         rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
2774
2775         /* Set the individual bit to receive frames for this host only. */
2776         rxfilt |= XL_RXFILTER_INDIVIDUAL;
2777
2778         /* If we want promiscuous mode, set the allframes bit. */
2779         if (ifp->if_flags & IFF_PROMISC) {
2780            rxfilt |= XL_RXFILTER_ALLFRAMES;
2781            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2782         } else {
2783            rxfilt &= ~XL_RXFILTER_ALLFRAMES;
2784            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2785         }
2786
2787         /*
2788          * Set capture broadcast bit to capture broadcast frames.
2789          */
2790         if (ifp->if_flags & IFF_BROADCAST) {
2791            rxfilt |= XL_RXFILTER_BROADCAST;
2792            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2793         } else {
2794            rxfilt &= ~XL_RXFILTER_BROADCAST;
2795            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2796         }
2797
2798#if 0
2799         /*
2800          * Program the multicast filter, if necessary.
2801          */
2802         if (sc->xl_type == XL_TYPE_905B)
2803            xl_setmulti_hash(sc);
2804         else
2805            xl_setmulti(sc);
2806#endif
2807         /*
2808          * Load the address of the RX list. We have to
2809          * stall the upload engine before we can manipulate
2810          * the uplist pointer register, then unstall it when
2811          * we're finished. We also have to wait for the
2812          * stall command to complete before proceeding.
2813          * Note that we have to do this after any RX resets
2814          * have completed since the uplist register is cleared
2815          * by a reset.
2816          */
2817         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
2818         xl_wait(sc);
2819         CSR_WRITE_4(sc, XL_UPLIST_PTR, phys_to_bus( sc->curr_rx_md ));
2820         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
2821         xl_wait(sc);
2822
2823
2824#if 0
2825         if (sc->xl_type == XL_TYPE_905B) {
2826            /* Set polling interval */
2827            CSR_WRITE_1(sc, XL_DOWN_POLL, 64);
2828            xl_wait(sc);
2829            printk("etherlink : unit elnk%d tx polling enabled\n", sc->xl_unit );
2830         }
2831#endif
2832
2833         /*
2834          * If the coax transceiver is on, make sure to enable
2835          * the DC-DC converter.
2836          */
2837         XL_SEL_WIN(3);
2838         if (sc->xl_xcvr == XL_XCVR_COAX)
2839            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
2840         else
2841            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
2842
2843         /* increase packet size to allow reception of 802.1q or ISL packets */
2844         if (sc->xl_type == XL_TYPE_905B)
2845            CSR_WRITE_2(sc, XL_W3_MAXPKTSIZE, XL_PACKET_SIZE);
2846         /* Clear out the stats counters. */
2847
2848         memset( &sc->xl_stats, 0, sizeof(struct xl_stats));
2849
2850         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
2851         sc->xl_stats_no_timeout = 1;
2852         xl_stats_update(sc->stat_timer_id,sc);
2853         sc->xl_stats_no_timeout = 0;
2854         XL_SEL_WIN(4);
2855         CSR_WRITE_2(sc, XL_W4_NET_DIAG, XL_NETDIAG_UPPER_BYTES_ENABLE);
2856         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_ENABLE);
2857
2858
2859         /*
2860          * Enable interrupts.
2861          */
2862         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
2863         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
2864         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
2865
2866         /* Set the RX early threshold */
2867         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2));
2868         CSR_WRITE_4(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY );
2869
2870         /* Enable receiver and transmitter. */
2871         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
2872         xl_wait(sc);
2873         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
2874         xl_wait(sc);
2875
2876         /* Select window 7 for normal operations. */
2877         XL_SEL_WIN(7);
2878
2879         /* schedule the stats update timer */
2880         rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );
2881      }
2882
2883      /*
2884       * Tell the world that we're running.
2885       */
2886      ifp->if_flags |= IFF_RUNNING;
2887   }
2888}
2889
2890
2891
2892
2893
2894
2895
2896/*
2897 * Stop the device
2898 */
2899static void
2900elnk_stop (struct elnk_softc *sc)
2901{
2902   struct ifnet *ifp = &sc->arpcom.ac_if;
2903   int i;
2904
2905   /*
2906    * Stop the transmitter
2907    */
2908   xl_stop(sc);
2909   xl_reset(sc);
2910   sc->tx_idle = -1;
2911
2912   ifp->if_flags &= ~IFF_RUNNING;
2913
2914   /*
2915   ** Clear out the rx & tx rings
2916   */
2917   {
2918      struct TXMD *chainhead;
2919      size_t esize;
2920
2921      while( rtems_message_queue_receive( chainRecoveryQueue, &chainhead, &esize,
2922                                          RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL );
2923   }
2924
2925   for(i=0 ; i<sc->numRxbuffers; i++)
2926   {
2927      st_le32( &sc->rx_ring[i].status, 0);
2928      st_le32( &sc->rx_ring[i].length, XL_LAST_FRAG | XL_PACKET_SIZE );
2929   }
2930
2931   for(i=0 ; i<sc->numTxbuffers; i++)
2932   {
2933      st_le32( &sc->tx_ring[i].status, XL_TXSTAT_DL_COMPLETE );
2934      st_le32( &sc->tx_ring[i].next, 0);
2935      if( sc->tx_ring[i].mbuf )
2936      {
2937         m_free( sc->tx_ring[i].mbuf );
2938         sc->tx_ring[i].mbuf = NULL;
2939      }
2940   }
2941}
2942
2943
2944
2945
2946/*
2947 * Show interface statistics
2948 */
2949static void
2950elnk_stats (struct elnk_softc *sc)
2951{
2952   printf("    MII PHY data { anr:%04x  lpar:%04x  stat:%04x  ctl:%04x }\n",
2953          sc->xl_stats.miianr,
2954          sc->xl_stats.miipar,
2955          sc->xl_stats.miistatus,
2956          sc->xl_stats.miicmd);
2957
2958   printf("         internalcfg:%08x            macctl:%04x      dmactl:%08x\n",
2959          sc->xl_stats.internalconfig,
2960          sc->xl_stats.mac_control,
2961          sc->xl_stats.dmactl);
2962
2963   printf("            rxstatus:%04x              txstatus:%02x       smbstat:%04x\n",
2964          sc->xl_stats.rxstatus,
2965          sc->xl_stats.txstatus,
2966          sc->xl_stats.smbstatus);
2967
2968   printf("              txfree:%04X             intstatus:%04x   mediastat:%04x\n",
2969          sc->xl_stats.txfree,
2970          sc->xl_stats.intstatus,
2971          sc->xl_stats.mediastatus);
2972
2973
2974   {
2975      int       i, totalLengths= 0, numLengths= 0;
2976
2977      for(i=0; i< NUM_CHAIN_LENGTHS; i++)
2978      {
2979         if( sc->chain_lengths[i] > -1 )
2980         {
2981            totalLengths += sc->chain_lengths[i];
2982            ++numLengths;
2983         }
2984      }
2985
2986      printf("          interrupts:%-9d       txcmp_ints:%-5d  avg_chain_len:%-4d\n",
2987             sc->xl_stats.device_interrupts,
2988             sc->xl_stats.txcomplete_ints,
2989             numLengths ? (totalLengths / numLengths) : -1 );
2990   }
2991
2992   printf("        carrier_lost:%-5d             sqe_errs:%-5d\n",
2993          sc->xl_stats.xl_carrier_lost,
2994          sc->xl_stats.xl_sqe_errs);
2995
2996   printf("  tx_multi_collision:%-5d  tx_single_collision:%-5d\n",
2997          sc->xl_stats.xl_tx_multi_collision,
2998          sc->xl_stats.xl_tx_single_collision);
2999
3000   printf("   tx_late_collision:%-5d           rx_overrun:%-5d\n",
3001          sc->xl_stats.xl_tx_late_collision,
3002          sc->xl_stats.xl_rx_overrun);
3003
3004   printf("         tx_deferred:%-5d               badssd:%-5d\n",
3005          sc->xl_stats.xl_tx_deferred,
3006          sc->xl_stats.xl_badssd);
3007
3008   printf("        rx_frames_ok:%-9d     tx_frames_ok:%-9d\n",
3009          sc->xl_stats.xl_rx_frames_ok,
3010          sc->xl_stats.xl_tx_frames_ok);
3011
3012   printf("         rx_bytes_ok:%-9d      tx_bytes_ok:%-9d\n",
3013          sc->xl_stats.xl_rx_bytes_ok,
3014          sc->xl_stats.xl_tx_bytes_ok );
3015}
3016
3017
3018
3019
3020
3021
3022
3023/*
3024 * Driver ioctl handler
3025 */
3026static int
3027elnk_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
3028{
3029   struct elnk_softc *sc = ifp->if_softc;
3030   int error = 0;
3031
3032   switch (command) {
3033      case SIOCGIFADDR:
3034      case SIOCSIFADDR:
3035         ether_ioctl (ifp, command, data);
3036         break;
3037
3038      case SIOCSIFFLAGS:
3039         switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
3040            case IFF_RUNNING:
3041               elnk_stop (sc);
3042               break;
3043
3044            case IFF_UP:
3045               elnk_init (sc);
3046               break;
3047
3048            case IFF_UP | IFF_RUNNING:
3049               elnk_stop (sc);
3050               elnk_init (sc);
3051               break;
3052
3053            default:
3054               break;
3055         }
3056         break;
3057
3058      case SIO_RTEMS_SHOW_STATS:
3059         elnk_stats (sc);
3060         break;
3061
3062         /*
3063          * FIXME: All sorts of multicast commands need to be added here!
3064          */
3065      default:
3066         error = EINVAL;
3067         break;
3068   }
3069
3070   return error;
3071}
3072
3073
3074
3075
3076
3077
3078
3079
3080#if 0
3081static int iftap(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m )
3082{
3083   int i;
3084   char *delim, *pkt;
3085
3086   printk("unit %i, src ", ifp->if_unit );
3087   for(delim= "", i=0; i< ETHER_ADDR_LEN; i++, delim=":")
3088      printk("%s%02x", delim, (char) eh->ether_shost[i] );
3089
3090   printk(" dest ");
3091
3092   for(delim= "", i=0; i< ETHER_ADDR_LEN; i++, delim=":")
3093      printk("%s%02x", delim, (char) eh->ether_dhost[i] );
3094   printk("  pkt ");
3095
3096   pkt = (char *)eh;
3097   for(delim="", i=0; i < sizeof(struct ether_header); i++, delim=":")
3098      printk("%s%02x", delim, (char) pkt[i] );
3099
3100   printk("\n");
3101   return 0;
3102}
3103#endif
3104
3105
3106
3107struct el_boards
3108{
3109      int pbus,pdev,pfun, vid, did, tindex;
3110};
3111
3112/*
3113 * Attach an ELNK driver to the system
3114 */
3115int
3116rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
3117{
3118   struct elnk_softc *sc;
3119   struct ifnet *ifp;
3120   char         *unitName;
3121   int          unitNumber;
3122   int          mtu, i;
3123   unsigned char cvalue;
3124   struct el_boards         sysboards[NUM_UNITS];
3125   int                      numFound = 0;
3126   int          pbus, pdev, pfun;
3127#if defined(__i386__)
3128   uint32_t     value;
3129   uint8_t      interrupt;
3130#endif
3131#if defined(__PPC__)
3132   uint32_t     lvalue;
3133#endif
3134
3135
3136   /*
3137    * Get the instance number for the board we're going to configure
3138    * from the user.
3139    */
3140   if( (unitNumber = rtems_bsdnet_parse_driver_name( config, &unitName)) == -1 )
3141   {
3142      return 0;
3143   }
3144
3145   if( strcmp(unitName, DRIVER_PREFIX) )
3146   {
3147      printk("etherlink : invalid unit name '%s'\n", unitName );
3148      return 0;
3149   }
3150
3151   if ((unitNumber < 1) || (unitNumber > NUM_UNITS))
3152   {
3153      printk("etherlink : unit %i is invalid, must be (1 <= n <= %d)\n", unitNumber, NUM_UNITS);
3154      return 0;
3155   }
3156
3157
3158   {
3159      int  done= 0, unum;
3160
3161      /*
3162       * Run thru the list of boards, finding all that are present in
3163       * the system.  Sort by slot,dev - and then use the unitNumber-1
3164       * to index the list and select the device.  Yucky.
3165       */
3166      for( i=0; !done && xl_devs[i].xl_vid; i++)
3167      {
3168         for(unum= 1; !done &&
3169                pci_find_device( xl_devs[i].xl_vid, xl_devs[i].xl_did, unum-1,
3170                                         &sysboards[numFound].pbus,
3171                                         &sysboards[numFound].pdev,
3172                                                  &sysboards[numFound].pfun)==0; unum++)
3173         {
3174            if( numFound == NUM_UNITS )
3175            {
3176               printk("etherlink : Maximum of %d units found, extra devices ignored.\n", NUM_UNITS );
3177               done=-1;
3178            }
3179            else
3180            {
3181               sysboards[numFound].vid = xl_devs[i].xl_vid;
3182               sysboards[numFound].did = xl_devs[i].xl_did;
3183               sysboards[numFound].tindex = i;
3184               ++numFound;
3185            }
3186         }
3187      }
3188
3189      if( ! numFound )
3190      {
3191         printk("etherlink : No Etherlink devices found\n");
3192         return 0;
3193      }
3194
3195      if( unitNumber-1 >= numFound )
3196      {
3197         printk("etherlink : device '%s' not found\n", config->name );
3198         return 0;
3199      }
3200
3201      /*
3202      * Got the list of etherlink boards in the system, now sort by
3203      * slot,device.  bubble sorts aren't all that wonderful, but this
3204      * is a short & infrequently sorted list.
3205      */
3206      if( numFound > 1 )
3207      {
3208         struct el_boards       tboard;
3209         int                    didsort;
3210
3211         do
3212         {
3213            didsort = 0;
3214
3215            for(i=1; i<numFound; i++)
3216            {
3217               if( sysboards[i-1].pbus > sysboards[i].pbus ||
3218                   (sysboards[i-1].pbus == sysboards[i].pbus && sysboards[i-1].pdev > sysboards[i].pdev) )
3219               {
3220                  memcpy(&tboard, &sysboards[i-1], sizeof(struct el_boards));
3221                  memcpy(&sysboards[i-1], &sysboards[i], sizeof(struct el_boards));
3222                  memcpy(&sysboards[i], &tboard, sizeof(struct el_boards));
3223                  didsort++;
3224               }
3225            }
3226         }
3227         while( didsort );
3228      }
3229
3230      /*
3231      ** board list is sorted, now select the unit
3232      */
3233
3234      pbus = sysboards[unitNumber-1].pbus;
3235      pdev = sysboards[unitNumber-1].pdev;
3236      pfun = sysboards[unitNumber-1].pfun;
3237   }
3238
3239   sc = &elnk_softc[unitNumber - 1];
3240   ifp = &sc->arpcom.ac_if;
3241   if (ifp->if_softc != NULL)
3242   {
3243      printk("etherlink : unit %i already in use.\n", unitNumber );
3244      return 0;
3245   }
3246
3247   /*
3248   ** Save various things
3249   */
3250   sc->xl_unit = unitNumber;
3251   sc->xl_type = sysboards[ unitNumber-1 ].tindex;
3252
3253   sc->vendorID = sysboards[numFound].vid;
3254   sc->deviceID = sysboards[numFound].did;
3255
3256   sc->numRxbuffers = (config->rbuf_count) ? config->rbuf_count : RX_RING_SIZE;
3257   sc->numTxbuffers = (config->xbuf_count) ? config->xbuf_count : TX_RING_SIZE;
3258
3259
3260   for(i=0; i< NUM_CHAIN_LENGTHS; i++) sc->chain_lengths[i]= -1;
3261   sc->chlenIndex = 0;
3262
3263
3264   if (config->mtu)
3265      mtu = config->mtu;
3266   else
3267      mtu = ETHERMTU;
3268
3269   sc->acceptBroadcast = !config->ignore_broadcast;
3270
3271
3272
3273#ifdef ELNK_DEBUG
3274   printk("etherlink : device '%s', name 'elnk%d', pci %02x:%02x.%02x, %d rx/%d tx buffers\n",
3275          xl_devs[sc->xl_type].xl_name, sc->xl_unit,
3276          pbus, pdev, pfun,
3277          sc->numRxbuffers, sc->numTxbuffers);
3278#endif
3279
3280
3281   /*
3282   ** Create this unit's stats timer
3283   */
3284   if( rtems_timer_create( rtems_build_name( 'X', 'L', 't', (char)(sc->xl_unit & 255)),
3285                           &sc->stat_timer_id ) != RTEMS_SUCCESSFUL )
3286   {
3287      printk("etherlink : unit elnk%d unable to create stats timer\n", sc->xl_unit );
3288      return 0;
3289   }
3290
3291   /* update stats 1 times/second if things aren't incrementing fast
3292    * enough to trigger stats interrupts
3293    */
3294   rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &sc->stats_update_ticks );
3295
3296
3297   /*
3298   ** Get this unit's rx/tx event
3299   */
3300   sc->ioevent = unit_signals[unitNumber-1];
3301
3302
3303#if defined(__i386__)
3304   pci_read_config_dword(pbus, pdev, pfun, 16, &value);
3305   sc->ioaddr = value & ~IO_MASK;
3306
3307   pci_read_config_byte(pbus, pdev, pfun, 60, &interrupt);
3308   cvalue = interrupt;
3309#endif
3310#if defined(__PPC__)
3311   /*
3312   ** Prep the board
3313   */
3314   pci_write_config_word(pbus, pdev, pfun,
3315                         PCI_COMMAND,
3316                         (uint16_t)( PCI_COMMAND_IO |
3317                                       PCI_COMMAND_MASTER |
3318                                       PCI_COMMAND_INVALIDATE |
3319                                       PCI_COMMAND_WAIT ) );
3320   /*
3321    * Get the device's base address
3322    */
3323   pci_read_config_dword(pbus, pdev, pfun,
3324                         PCI_BASE_ADDRESS_0,
3325                         &lvalue);
3326
3327   sc->ioaddr = (uint32_t)lvalue & PCI_BASE_ADDRESS_IO_MASK;
3328   /*
3329   ** Store the interrupt name, we'll use it later when we initialize
3330   ** the board.
3331   */
3332   pci_read_config_byte(pbus, pdev, pfun,
3333                        PCI_INTERRUPT_LINE,
3334                        &cvalue);
3335#endif
3336
3337   memset(&sc->irqInfo,0,sizeof(rtems_irq_connect_data));
3338   sc->irqInfo.name = cvalue;
3339
3340
3341   /*
3342   ** Establish basic board config, set node address from config or
3343   ** board eeprom, do stuff with additional device properties
3344   */
3345
3346   {
3347      uint8_t   pci_latency;
3348      uint8_t   new_latency = 248;
3349
3350      /* Check the PCI latency value.  On the 3c590 series the latency timer
3351         must be set to the maximum value to avoid data corruption that occurs
3352         when the timer expires during a transfer.  This bug exists the Vortex
3353         chip only. */
3354#if defined(__i386__)
3355      pci_read_config_byte(pbus, pdev, pfun, 0x0d, &pci_latency);
3356#endif
3357#if defined(__PPC__)
3358      pci_read_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, &pci_latency);
3359#endif
3360      if (pci_latency < new_latency)
3361      {
3362         printk("etherlink : unit elnk%d Overriding PCI latency, timer (CFLT) setting of %d, new value is %d.\n", sc->xl_unit, pci_latency, new_latency );
3363#if defined(__i386__)
3364         pci_write_config_byte(pbus, pdev, pfun, 0x0d, new_latency);
3365#endif
3366#if defined(__PPC__)
3367         pci_write_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, new_latency);
3368#endif
3369      }
3370   }
3371
3372   /* Reset the adapter. */
3373   xl_reset(sc);
3374
3375
3376   {
3377      u_int16_t         xcvr[2];
3378      u_char            eaddr[ETHER_ADDR_LEN];
3379
3380      sc->xl_flags = 0;
3381      if (sc->deviceID == TC_DEVICEID_HURRICANE_555)
3382         sc->xl_flags |= XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_PHYOK;
3383      if (sc->deviceID == TC_DEVICEID_HURRICANE_556 ||
3384          sc->deviceID == TC_DEVICEID_HURRICANE_556B)
3385         sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
3386            XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_WEIRDRESET |
3387            XL_FLAG_INVERT_LED_PWR | XL_FLAG_INVERT_MII_PWR;
3388      if (sc->deviceID == TC_DEVICEID_HURRICANE_555 ||
3389          sc->deviceID == TC_DEVICEID_HURRICANE_556)
3390         sc->xl_flags |= XL_FLAG_8BITROM;
3391      if (sc->deviceID == TC_DEVICEID_HURRICANE_556B)
3392         sc->xl_flags |= XL_FLAG_NO_XCVR_PWR;
3393
3394      if (sc->deviceID == TC_DEVICEID_HURRICANE_575A ||
3395          sc->deviceID == TC_DEVICEID_HURRICANE_575B ||
3396          sc->deviceID == TC_DEVICEID_HURRICANE_575C ||
3397          sc->deviceID == TC_DEVICEID_HURRICANE_656B ||
3398          sc->deviceID == TC_DEVICEID_TORNADO_656C)
3399         sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
3400            XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM;
3401      if (sc->deviceID == TC_DEVICEID_HURRICANE_656)
3402         sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK;
3403      if (sc->deviceID == TC_DEVICEID_HURRICANE_575B)
3404         sc->xl_flags |= XL_FLAG_INVERT_LED_PWR;
3405      if (sc->deviceID == TC_DEVICEID_HURRICANE_575C)
3406         sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
3407      if (sc->deviceID == TC_DEVICEID_TORNADO_656C)
3408         sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
3409      if (sc->deviceID == TC_DEVICEID_HURRICANE_656 ||
3410          sc->deviceID == TC_DEVICEID_HURRICANE_656B)
3411         sc->xl_flags |= XL_FLAG_INVERT_MII_PWR |
3412            XL_FLAG_INVERT_LED_PWR;
3413      if (sc->deviceID == TC_DEVICEID_TORNADO_10_100BT_920B)
3414         sc->xl_flags |= XL_FLAG_PHYOK;
3415
3416
3417      if (config->hardware_address)
3418      {
3419         memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
3420      }
3421      else
3422      {
3423         if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1))
3424         {
3425            printk("etherlink : unit elnk%d Failed to read station address\n", sc->xl_unit );
3426            return 0;
3427         }
3428         memcpy((char *)&sc->arpcom.ac_enaddr, eaddr, ETHER_ADDR_LEN);
3429      }
3430
3431      /*
3432       * Figure out the card type. 3c905B adapters have the
3433       * 'supportsNoTxLength' bit set in the capabilities
3434       * word in the EEPROM.
3435       */
3436      xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
3437      if (sc->xl_caps & XL_CAPS_NO_TXLENGTH)
3438         sc->xl_type = XL_TYPE_905B;
3439      else
3440         sc->xl_type = XL_TYPE_90X;
3441
3442
3443      /*
3444       * Now we have to see what sort of media we have.
3445       * This includes probing for an MII interace and a
3446       * possible PHY.
3447       */
3448      XL_SEL_WIN(3);
3449      sc->xl_media = CSR_READ_2(sc, XL_W3_MEDIA_OPT);
3450
3451      xl_read_eeprom(sc, (char *)&xcvr, XL_EE_ICFG_0, 2, 0);
3452      sc->xl_xcvr = xcvr[0] | xcvr[1] << 16;
3453      sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
3454      sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
3455
3456#if 0
3457      printk("etherlink : unit elnk%d EEPROM set xcvr to 0x%x\n", sc->xl_unit, sc->xl_xcvr);
3458#endif
3459
3460      {
3461         char   msg[255];
3462         int    i;
3463
3464         struct _availmedia
3465         {
3466               int bit;
3467               char *name;
3468         } _am[]= {{ XL_MEDIAOPT_BT4, "100BaseT4" },
3469                   { XL_MEDIAOPT_BTX, "100BaseTX" },
3470                   { XL_MEDIAOPT_BFX, "100BaseFX" },
3471                   { XL_MEDIAOPT_BT,  "10BaseT" },
3472                   { XL_MEDIAOPT_BNC, "10Base2" },
3473                   { XL_MEDIAOPT_AUI, "10mbps AUI"},
3474                   { XL_MEDIAOPT_MII, "MII"},
3475                   { 0, NULL }};
3476
3477         msg[0]= 0;
3478         for( i=0; _am[i].bit; i++)
3479         {
3480            if( sc->xl_media & _am[i].bit )
3481               sprintf( &msg[strlen(msg)], ",%s", _am[i].name );
3482         }
3483         if( !strlen(msg) ) strcpy( &msg[1], "<no media bits>");
3484
3485         printk("etherlink : unit elnk%d available media : %s\n", sc->xl_unit, &msg[1]);
3486      }
3487
3488      XL_SEL_WIN(7);
3489   }
3490
3491
3492
3493   /*
3494    * Set up network interface
3495    */
3496   ifp->if_softc = sc;
3497   ifp->if_name = unitName;
3498   ifp->if_unit = sc->xl_unit;
3499   ifp->if_mtu = mtu;
3500   ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
3501   if (ifp->if_snd.ifq_maxlen == 0)
3502      ifp->if_snd.ifq_maxlen = ifqmaxlen;
3503   ifp->if_init = elnk_init;
3504   ifp->if_start = elnk_start;
3505   ifp->if_ioctl = elnk_ioctl;
3506   ifp->if_output = ether_output;
3507
3508#if 0
3509   ifp->if_tap = iftap;
3510#endif
3511
3512   /*
3513    * Attach the interface
3514    */
3515   if_attach (ifp);
3516   ether_ifattach (ifp);
3517
3518#ifdef ELNK_DEBUG
3519   printk( "etherlink : unit elnk%d driver attached\n", sc->xl_unit );
3520#endif
3521
3522   /*
3523    * Start driver tasks if this is the first unit initialized
3524    */
3525   if (txDaemonTid == 0)
3526   {
3527      if( rtems_message_queue_create( rtems_build_name('X','L','c','r'),
3528                                      sc->numTxbuffers+1,
3529                                      sizeof(struct TXMD *),
3530                                      RTEMS_FIFO | RTEMS_LOCAL,
3531                                      &chainRecoveryQueue ) != RTEMS_SUCCESSFUL )
3532      {
3533         rtems_panic( "etherlink : Unable to create TX buffer recovery queue\n" );
3534      }
3535
3536
3537      rxDaemonTid = rtems_bsdnet_newproc( "XLrx", 4096,
3538                                          elnk_rxDaemon, NULL);
3539
3540      txDaemonTid = rtems_bsdnet_newproc( "XLtx", 4096,
3541                                          elnk_txDaemon, NULL);
3542#ifdef ELNK_DEBUG
3543      printk( "etherlink : driver tasks created\n" );
3544#endif
3545   }
3546
3547   return 1;
3548};
3549
3550#endif /* ELNK_SUPPORTED */
3551
3552/* eof */
Note: See TracBrowser for help on using the repository browser.