source: rtems/c/src/libchip/network/elnk.c @ 142025c

4.104.114.95
Last change on this file since 142025c was 142025c, checked in by Ralf Corsepius <ralf.corsepius@…>, on 08/18/08 at 07:22:23

Add missing prototypes.

  • Property mode set to 100644
File size: 98.6 KB
RevLine 
[01b6ca9]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
[94365d9]8 *  http://www.rtems.com/license/LICENSE.
[01b6ca9]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 *
[96e62937]30 * Greg Menke, 6/11/2003
[01b6ca9]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>
[a8e1959]86#include <rtems/pci.h>
87
[01b6ca9]88#if defined(__PPC__)
89#include <libcpu/byteorder.h>
90#include <libcpu/io.h>
91#endif
92
[f82dabae]93#if defined(__i386__)
94#include <libcpu/byteorder.h>
95#endif
96
[01b6ca9]97#include <stdlib.h>
98#include <stdio.h>
99#include <stdarg.h>
100#include <string.h>
[593bc32]101#include <errno.h>
[01b6ca9]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
[750a686]115#include <net/if_media.h>
116#include <dev/mii/mii.h>
[0fd3092]117#include <bsp/irq.h>
[01b6ca9]118
119#if defined(__i386__)
[3584398a]120#define IO_MASK   0x3
121#define MEM_MASK  0xF
[01b6ca9]122#endif
123
124#ifdef malloc
125#undef malloc
126#endif
127#ifdef free
[a3d3d9a]128#undef free
[01b6ca9]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
[a3d3d9a]182static rtems_event_set unit_signals[NUM_UNITS]= { RTEMS_EVENT_1,
[01b6ca9]183                                                  RTEMS_EVENT_2,
[a3d3d9a]184                                                  RTEMS_EVENT_3,
[01b6ca9]185                                                  RTEMS_EVENT_4,
[a3d3d9a]186                                                  RTEMS_EVENT_5,
[01b6ca9]187                                                  RTEMS_EVENT_6,
[a3d3d9a]188                                                  RTEMS_EVENT_7,
[01b6ca9]189                                                  RTEMS_EVENT_8 };
190
191
[96e62937]192
193
[3584398a]194#if defined(__PPC__)
[01b6ca9]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,
[96e62937]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...
[01b6ca9]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        \
[96e62937]311                  (XL_STAT_UP_COMPLETE | XL_STAT_STATSOFLOW | XL_STAT_ADFAIL|   \
312                   XL_STAT_DOWN_COMPLETE | XL_STAT_TX_COMPLETE | XL_STAT_INTLATCH)
[01b6ca9]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
[a3d3d9a]748struct xl_stats
[01b6ca9]749{
[96e62937]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;
[01b6ca9]761
[96e62937]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 */
[01b6ca9]768      u_int16_t         intstatus;
769      u_int16_t         rxstatus;
770      u_int8_t          txstatus;
771      u_int16_t         mediastatus;
772
[3584398a]773      u_int32_t         txcomplete_ints;
774
[01b6ca9]775      u_int16_t         miianr, miipar, miistatus, miicmd;
776
777      u_int32_t         device_interrupts;
[96e62937]778      u_int32_t         internalconfig;
779      u_int16_t         mac_control;
[01b6ca9]780
781      u_int16_t         smbstatus;
[96e62937]782      u_int32_t         dmactl;
783      u_int16_t         txfree;
[01b6ca9]784};
785
786
787
[a3d3d9a]788struct xl_type
[01b6ca9]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
[96e62937]865
866/* rx message descriptor entry, ensure the struct is aligned to 8 bytes */
[a3d3d9a]867struct RXMD
[01b6ca9]868{
869      /* used by hardware */
[ee4f57d]870      volatile uint32_t   next;
871      volatile uint32_t   status;
872      volatile uint32_t   addr;
873      volatile uint32_t   length;
[01b6ca9]874      /* used by software */
875      struct mbuf       *mbuf;        /* scratch variable used in the tx ring */
[96e62937]876      struct RXMD       *next_md;
877} __attribute__ ((aligned (8), packed));
878
879
880
881
882
[3584398a]883#define NUM_FRAGS       6
[96e62937]884
[a3d3d9a]885/*
[96e62937]886 * tx message descriptor entry, ensure the struct is aligned to 8 bytes
887 */
888
889struct tfrag
890{
[ee4f57d]891      volatile uint32_t   addr;
892      volatile uint32_t   length;
[01b6ca9]893} __attribute__ ((packed));
894
[a3d3d9a]895struct TXMD
[96e62937]896{
897      /* used by hardware */
[ee4f57d]898      volatile uint32_t   next;
899      volatile uint32_t   status;
[96e62937]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));
[01b6ca9]905
906
907
908
909
[96e62937]910#define NUM_CHAIN_LENGTHS       50
911
912
[01b6ca9]913
914/*
915 * Per-device data
916 */
[a3d3d9a]917struct elnk_softc
[01b6ca9]918{
919      struct arpcom             arpcom;
920
921      rtems_irq_connect_data    irqInfo;
922      rtems_event_set           ioevent;
923      unsigned int              ioaddr;
924
[96e62937]925      unsigned char             *bufferBase, *ringBase;
[01b6ca9]926
[96e62937]927      struct RXMD      *rx_ring, *curr_rx_md;
928      struct TXMD      *tx_ring, *last_tx_md, *last_txchain_head;
[01b6ca9]929
930      rtems_id                  stat_timer_id;
[ee4f57d]931      uint32_t                  stats_update_ticks;
[01b6ca9]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
[96e62937]946      short                     chain_lengths[NUM_CHAIN_LENGTHS];
947      int                       chlenIndex;
948
[01b6ca9]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;
[96e62937]957static rtems_id chainRecoveryQueue;
[01b6ca9]958
959
960
961
962
963
964
[3584398a]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
[01b6ca9]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
[142025c]1029xl_wait(struct elnk_softc       *sc)
[01b6ca9]1030{
1031   register int         i;
1032
[a3d3d9a]1033   for(i = 0; i < XL_TIMEOUT; i++)
[96e62937]1034   {
[01b6ca9]1035      if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
1036         break;
1037   }
1038
1039   if (i == XL_TIMEOUT)
[96e62937]1040      printk("etherlink : unit elnk%d command never completed\n", sc->xl_unit );
[01b6ca9]1041   return;
1042}
1043
1044
1045
1046
1047
1048
1049/*
1050 * MII access routines are provided for adapters with external
1051 * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
1052 * autoneg logic that's faked up to look like a PHY (3c905B-TX).
1053 * Note: if you don't perform the MDIO operations just right,
1054 * it's possible to end up with code that works correctly with
1055 * some chips/CPUs/processor speeds/bus speeds/etc but not
1056 * with others.
1057 */
1058#define MII_SET(x)                                      \
1059        CSR_WRITE_2(sc, XL_W4_PHY_MGMT,                 \
1060                CSR_READ_2(sc, XL_W4_PHY_MGMT) | (x))
1061
1062#define MII_CLR(x)                                      \
1063        CSR_WRITE_2(sc, XL_W4_PHY_MGMT,                 \
1064                CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~(x))
1065
1066/*
1067 * Sync the PHYs by setting data bit and strobing the clock 32 times.
1068 */
1069static void
[142025c]1070xl_mii_sync(
1071   struct elnk_softc            *sc)
[01b6ca9]1072{
1073   register int         i;
1074
1075   XL_SEL_WIN(4);
1076   MII_SET(XL_MII_DIR|XL_MII_DATA);
1077
1078   for (i = 0; i < 32; i++) {
1079      MII_SET(XL_MII_CLK);
1080      MII_SET(XL_MII_DATA);
1081      MII_CLR(XL_MII_CLK);
1082      MII_SET(XL_MII_DATA);
1083   }
1084
1085   return;
1086}
1087
1088/*
1089 * Clock a series of bits through the MII.
1090 */
1091static void
[142025c]1092xl_mii_send(
1093   struct elnk_softc            *sc,
1094   u_int32_t            bits,
1095   int                  cnt )
[01b6ca9]1096{
1097   int                  i;
1098
1099   XL_SEL_WIN(4);
1100   MII_CLR(XL_MII_CLK);
1101
1102   for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
1103      if (bits & i) {
1104         MII_SET(XL_MII_DATA);
1105      } else {
1106         MII_CLR(XL_MII_DATA);
1107      }
1108      MII_CLR(XL_MII_CLK);
1109      MII_SET(XL_MII_CLK);
1110   }
1111}
1112
1113/*
1114 * Read an PHY register through the MII.
1115 */
1116static int
[142025c]1117xl_mii_readreg(
1118   struct elnk_softc    *sc,
1119   struct xl_mii_frame  *frame )
[01b6ca9]1120{
1121   int                  i, ack;
1122
1123   /*
1124    * Set up frame for RX.
1125    */
1126   frame->mii_stdelim = XL_MII_STARTDELIM;
1127   frame->mii_opcode = XL_MII_READOP;
1128   frame->mii_turnaround = 0;
1129   frame->mii_data = 0;
[a3d3d9a]1130
[01b6ca9]1131   /*
1132    * Select register window 4.
1133    */
1134
1135   XL_SEL_WIN(4);
1136
1137   CSR_WRITE_2(sc, XL_W4_PHY_MGMT, 0);
1138   /*
1139    * Turn on data xmit.
1140    */
1141   MII_SET(XL_MII_DIR);
1142
1143   xl_mii_sync(sc);
1144
1145   /*
1146    * Send command/address info.
1147    */
1148   xl_mii_send(sc, frame->mii_stdelim, 2);
1149   xl_mii_send(sc, frame->mii_opcode, 2);
1150   xl_mii_send(sc, frame->mii_phyaddr, 5);
1151   xl_mii_send(sc, frame->mii_regaddr, 5);
1152
1153   /* Idle bit */
1154   MII_CLR((XL_MII_CLK|XL_MII_DATA));
1155   MII_SET(XL_MII_CLK);
1156
1157   /* Turn off xmit. */
1158   MII_CLR(XL_MII_DIR);
1159
1160   /* Check for ack */
1161   MII_CLR(XL_MII_CLK);
1162   ack = CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA;
1163   MII_SET(XL_MII_CLK);
1164
1165   /*
1166    * Now try reading data bits. If the ack failed, we still
1167    * need to clock through 16 cycles to keep the PHY(s) in sync.
1168    */
1169   if (ack) {
1170      for(i = 0; i < 16; i++) {
1171         MII_CLR(XL_MII_CLK);
1172         MII_SET(XL_MII_CLK);
1173      }
1174      goto fail;
1175   }
1176
1177   for (i = 0x8000; i; i >>= 1) {
1178      MII_CLR(XL_MII_CLK);
1179      if (!ack) {
1180         if (CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA)
1181            frame->mii_data |= i;
1182      }
1183      MII_SET(XL_MII_CLK);
1184   }
1185
1186  fail:
1187
1188   MII_CLR(XL_MII_CLK);
1189   MII_SET(XL_MII_CLK);
1190
1191   if (ack)
1192      return(1);
1193   return(0);
1194}
1195
1196/*
1197 * Write to a PHY register through the MII.
1198 */
1199static int
[142025c]1200xl_mii_writereg(
1201   struct elnk_softc    *sc,
1202   struct xl_mii_frame  *frame )
[01b6ca9]1203{
1204   /*
1205    * Set up frame for TX.
1206    */
1207
1208   frame->mii_stdelim = XL_MII_STARTDELIM;
1209   frame->mii_opcode = XL_MII_WRITEOP;
1210   frame->mii_turnaround = XL_MII_TURNAROUND;
[a3d3d9a]1211
[01b6ca9]1212   /*
1213    * Select the window 4.
1214    */
1215   XL_SEL_WIN(4);
1216
1217   /*
1218    * Turn on data output.
1219    */
1220   MII_SET(XL_MII_DIR);
1221
1222   xl_mii_sync(sc);
1223
1224   xl_mii_send(sc, frame->mii_stdelim, 2);
1225   xl_mii_send(sc, frame->mii_opcode, 2);
1226   xl_mii_send(sc, frame->mii_phyaddr, 5);
1227   xl_mii_send(sc, frame->mii_regaddr, 5);
1228   xl_mii_send(sc, frame->mii_turnaround, 2);
1229   xl_mii_send(sc, frame->mii_data, 16);
1230
1231   /* Idle bit. */
1232   MII_SET(XL_MII_CLK);
1233   MII_CLR(XL_MII_CLK);
1234
1235   /*
1236    * Turn off xmit.
1237    */
1238   MII_CLR(XL_MII_DIR);
1239
1240   return(0);
1241}
1242
1243static int
[142025c]1244xl_miibus_readreg(
1245   struct elnk_softc    *sc,
1246   int                  phy,
1247   int                  reg )
[01b6ca9]1248{
1249   struct xl_mii_frame  frame;
1250
1251   /*
1252    * Pretend that PHYs are only available at MII address 24.
1253    * This is to guard against problems with certain 3Com ASIC
1254    * revisions that incorrectly map the internal transceiver
1255    * control registers at all MII addresses. This can cause
1256    * the miibus code to attach the same PHY several times over.
1257    */
1258   if ((!(sc->xl_flags & XL_FLAG_PHYOK)) && phy != 24)
1259   {
1260      printk("etherlink : unit elnk%d xl_miibus_readreg returned\n", sc->xl_unit);
1261      return(0);
1262   }
1263
[96e62937]1264   memset((char *)&frame, 0, sizeof(frame));
[01b6ca9]1265
1266   frame.mii_phyaddr = phy;
1267   frame.mii_regaddr = reg;
1268   xl_mii_readreg(sc, &frame);
1269
1270   return(frame.mii_data);
1271}
1272
1273static int
[142025c]1274xl_miibus_writereg(
1275   struct elnk_softc            *sc,
1276   int                  phy,
1277   int                  reg,
1278   int                  data )
[01b6ca9]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
[96e62937]1288   memset((char *)&frame, 0, sizeof(frame));
[01b6ca9]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
[142025c]1312xl_eeprom_wait(struct elnk_softc *sc)
[01b6ca9]1313{
1314   int                  i;
1315
1316   for (i = 0; i < 100; i++) {
1317      if (CSR_READ_2(sc, XL_W0_EE_CMD) & XL_EE_BUSY)
1318         DELAY(162);
1319      else
1320         break;
1321   }
1322
1323   if (i == 100) {
1324      printk("etherlink : unit elnk%d eeprom failed to come ready\n", sc->xl_unit);
1325      return(1);
1326   }
1327
1328   return(0);
1329}
1330
1331/*
1332 * Read a sequence of words from the EEPROM. Note that ethernet address
1333 * data is stored in the EEPROM in network byte order.
1334 */
1335static int
[142025c]1336xl_read_eeprom(
1337   struct elnk_softc            *sc,
1338   caddr_t                      dest,
1339   int                  off,
1340   int                  cnt,
1341   int                  swap)
[01b6ca9]1342{
1343   int                  err = 0, i;
1344   u_int16_t            word = 0, *ptr;
1345#define EEPROM_5BIT_OFFSET(A) ((((A) << 2) & 0x7F00) | ((A) & 0x003F))
1346#define EEPROM_8BIT_OFFSET(A) ((A) & 0x003F)
1347   /* WARNING! DANGER!
1348    * It's easy to accidentally overwrite the rom content!
1349    * Note: the 3c575 uses 8bit EEPROM offsets.
1350    */
1351   XL_SEL_WIN(0);
1352
1353   if (xl_eeprom_wait(sc))
1354      return(1);
1355
1356   if (sc->xl_flags & XL_FLAG_EEPROM_OFFSET_30)
1357      off += 0x30;
1358
1359   for (i = 0; i < cnt; i++) {
1360      if (sc->xl_flags & XL_FLAG_8BITROM)
[a3d3d9a]1361         CSR_WRITE_2(sc, XL_W0_EE_CMD,
[01b6ca9]1362                     XL_EE_8BIT_READ | EEPROM_8BIT_OFFSET(off + i));
1363      else
1364         CSR_WRITE_2(sc, XL_W0_EE_CMD,
1365                     XL_EE_READ | EEPROM_5BIT_OFFSET(off + i));
1366      err = xl_eeprom_wait(sc);
1367      if (err)
1368         break;
1369      word = CSR_READ_2(sc, XL_W0_EE_DATA);
[509fec9c]1370      ptr = (u_int16_t*)(dest + (i * 2));
[01b6ca9]1371      if (swap)
1372         *ptr = ntohs(word);
1373      else
[a3d3d9a]1374         *ptr = word;
[01b6ca9]1375   }
1376
1377   return(err ? 1 : 0);
1378}
1379
1380
1381
1382
1383static void
[142025c]1384xl_stats_update(
1385   rtems_id timerid,
1386   void *xsc)
[01b6ca9]1387{
[96e62937]1388   struct elnk_softc    *sc = (struct elnk_softc *)xsc;
1389   struct ifnet         *ifp = &sc->arpcom.ac_if;
1390   u_int32_t            t1;
[01b6ca9]1391
1392   sc->xl_stats.intstatus = CSR_READ_2(sc, XL_STATUS);
[a3d3d9a]1393
[01b6ca9]1394   sc->xl_stats.miianr    = xl_miibus_readreg(sc, 0x18, MII_ANAR );
1395   sc->xl_stats.miipar    = xl_miibus_readreg(sc, 0x18, MII_ANLPAR );
1396   sc->xl_stats.miistatus = xl_miibus_readreg(sc, 0x18, MII_BMSR );
1397   sc->xl_stats.miicmd    = xl_miibus_readreg(sc, 0x18, MII_BMCR );
[a3d3d9a]1398
[01b6ca9]1399   XL_SEL_WIN(1);
[96e62937]1400   sc->xl_stats.rxstatus  = CSR_READ_2(sc, XL_W1_RX_STATUS );
1401   sc->xl_stats.txstatus  = CSR_READ_1(sc, XL_W1_TX_STATUS );
[01b6ca9]1402   sc->xl_stats.smbstatus = CSR_READ_2(sc, 2 );
1403
[96e62937]1404   XL_SEL_WIN(3);
1405   sc->xl_stats.internalconfig = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
1406   sc->xl_stats.mac_control    = CSR_READ_2(sc, XL_W3_MAC_CTRL);
1407   sc->xl_stats.txfree         = CSR_READ_2(sc, XL_W3_FREE_TX );
[a3d3d9a]1408
[96e62937]1409
[01b6ca9]1410   /* Read all the stats registers. */
1411   XL_SEL_WIN(6);
1412
1413   sc->xl_stats.xl_carrier_lost              += CSR_READ_1(sc, XL_W6_CARRIER_LOST);
1414   sc->xl_stats.xl_sqe_errs                  += CSR_READ_1(sc, XL_W6_SQE_ERRORS);
1415   sc->xl_stats.xl_tx_multi_collision        += CSR_READ_1(sc, XL_W6_COL_MULTIPLE);
1416   sc->xl_stats.xl_tx_single_collision       += CSR_READ_1(sc, XL_W6_COL_SINGLE);
1417   sc->xl_stats.xl_tx_late_collision         += CSR_READ_1(sc, XL_W6_COL_LATE);
1418   sc->xl_stats.xl_rx_overrun                += CSR_READ_1(sc, XL_W6_RX_OVERRUN);
[96e62937]1419   sc->xl_stats.xl_tx_deferred               += CSR_READ_1(sc, XL_W6_DEFERRED);
1420
[01b6ca9]1421   sc->xl_stats.xl_tx_frames_ok              += CSR_READ_1(sc, XL_W6_TX_OK);
1422   sc->xl_stats.xl_rx_frames_ok              += CSR_READ_1(sc, XL_W6_RX_OK);
1423
1424   sc->xl_stats.xl_rx_bytes_ok               += CSR_READ_2(sc, XL_W6_TX_BYTES_OK );
1425   sc->xl_stats.xl_tx_bytes_ok               += CSR_READ_2(sc, XL_W6_RX_BYTES_OK );
1426
[96e62937]1427   t1 = CSR_READ_1(sc, XL_W6_UPPER_FRAMES_OK);
1428   sc->xl_stats.xl_rx_frames_ok +=  ((t1 & 0x3) << 8);
1429   sc->xl_stats.xl_tx_frames_ok +=  (((t1 >> 4) & 0x3) << 8);
1430
[01b6ca9]1431
1432   ifp->if_ierrors += sc->xl_stats.xl_rx_overrun;
1433
1434   ifp->if_collisions += sc->xl_stats.xl_tx_multi_collision +
1435      sc->xl_stats.xl_tx_single_collision +
1436      sc->xl_stats.xl_tx_late_collision;
1437
1438   /*
1439    * Boomerang and cyclone chips have an extra stats counter
1440    * in window 4 (BadSSD). We have to read this too in order
1441    * to clear out all the stats registers and avoid a statsoflow
1442    * interrupt.
1443    */
1444   XL_SEL_WIN(4);
[96e62937]1445
1446   t1 = CSR_READ_1(sc, XL_W4_UPPERBYTESOK);
1447   sc->xl_stats.xl_rx_bytes_ok += ((t1 & 0xf) << 16);
1448   sc->xl_stats.xl_tx_bytes_ok += (((t1 >> 4) & 0xf) << 16);
1449
[01b6ca9]1450   sc->xl_stats.xl_badssd               += CSR_READ_1(sc, XL_W4_BADSSD);
[96e62937]1451
1452   sc->xl_stats.mediastatus             = CSR_READ_2(sc, XL_W4_MEDIA_STATUS );
1453   sc->xl_stats.dmactl                  = CSR_READ_4(sc, XL_DMACTL );
1454
[01b6ca9]1455
1456   XL_SEL_WIN(7);
1457
1458   if (!sc->xl_stats_no_timeout)
1459      rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );
1460   return;
1461}
1462
1463
1464
1465
1466
1467
1468
1469static void
[142025c]1470xl_reset(struct elnk_softc *sc)
[01b6ca9]1471{
1472   register int         i;
1473
1474   XL_SEL_WIN(0);
[a3d3d9a]1475   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RESET |
[01b6ca9]1476               ((sc->xl_flags & XL_FLAG_WEIRDRESET) ?
1477                XL_RESETOPT_DISADVFD:0));
1478
1479   for (i = 0; i < XL_TIMEOUT; i++) {
1480      DELAY(10);
1481      if (!(CSR_READ_2(sc, XL_STATUS) & XL_STAT_CMDBUSY))
1482         break;
1483   }
1484
1485   if (i == XL_TIMEOUT)
1486      printk("etherlink : unit elnk%d reset didn't complete\n", sc->xl_unit);
1487
1488   /* Reset TX and RX. */
1489   /* Note: the RX reset takes an absurd amount of time
1490    * on newer versions of the Tornado chips such as those
1491    * on the 3c905CX and newer 3c908C cards. We wait an
1492    * extra amount of time so that xl_wait() doesn't complain
1493    * and annoy the users.
1494    */
1495   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_RESET);
1496   DELAY(100000);
1497   xl_wait(sc);
1498   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET);
1499   xl_wait(sc);
1500
[a3d3d9a]1501   if (sc->xl_flags & XL_FLAG_INVERT_LED_PWR ||
1502       sc->xl_flags & XL_FLAG_INVERT_MII_PWR)
[96e62937]1503   {
[01b6ca9]1504      XL_SEL_WIN(2);
1505      CSR_WRITE_2(sc, XL_W2_RESET_OPTIONS, CSR_READ_2(sc,
[a3d3d9a]1506                                                      XL_W2_RESET_OPTIONS)
[01b6ca9]1507                  | ((sc->xl_flags & XL_FLAG_INVERT_LED_PWR)?XL_RESETOPT_INVERT_LED:0)
1508                  | ((sc->xl_flags & XL_FLAG_INVERT_MII_PWR)?XL_RESETOPT_INVERT_MII:0)
1509         );
1510   }
1511
1512   /* Wait a little while for the chip to get its brains in order. */
1513   DELAY(100000);
1514   return;
1515}
1516
1517
1518
1519
1520static void
[142025c]1521xl_stop(struct elnk_softc *sc)
[01b6ca9]1522{
1523   struct ifnet         *ifp;
1524
1525   ifp = &sc->arpcom.ac_if;
1526   ifp->if_timer = 0;
1527
1528   rtems_timer_cancel( sc->stat_timer_id );
1529
1530   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISABLE);
1531   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
1532   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB);
1533   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_DISCARD);
1534   xl_wait(sc);
1535   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
1536   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
1537   DELAY(800);
1538
1539   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|XL_STAT_INTLATCH);
1540   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|0);
1541   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|0);
1542
1543   return;
1544}
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560static void
[142025c]1561xl_setcfg(struct elnk_softc *sc)
[01b6ca9]1562{
1563   u_int32_t            icfg;
1564
1565   XL_SEL_WIN(3);
1566   icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
[96e62937]1567
[01b6ca9]1568   icfg &= ~XL_ICFG_CONNECTOR_MASK;
[96e62937]1569
1570   if (sc->xl_media & XL_MEDIAOPT_MII || sc->xl_media & XL_MEDIAOPT_BT4)
[01b6ca9]1571      icfg |= (XL_XCVR_MII << XL_ICFG_CONNECTOR_BITS);
[96e62937]1572
[01b6ca9]1573   if (sc->xl_media & XL_MEDIAOPT_BTX)
1574      icfg |= (XL_XCVR_AUTO << XL_ICFG_CONNECTOR_BITS);
1575
1576   CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
1577   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
1578
1579   XL_SEL_WIN(7);
1580   return;
1581}
1582
[96e62937]1583
1584
[01b6ca9]1585static void
[142025c]1586xl_setmode(
1587   struct elnk_softc    *sc,
1588   int                  media)
[01b6ca9]1589{
1590   u_int32_t            icfg;
1591   u_int16_t            mediastat;
1592
1593   printk("etherlink : unit elnk%d selecting ", sc->xl_unit);
1594
1595   XL_SEL_WIN(4);
1596   mediastat = CSR_READ_2(sc, XL_W4_MEDIA_STATUS);
1597   XL_SEL_WIN(3);
1598   icfg = CSR_READ_4(sc, XL_W3_INTERNAL_CFG);
1599
1600   if (sc->xl_media & XL_MEDIAOPT_BT) {
1601      if (IFM_SUBTYPE(media) == IFM_10_T) {
1602         printk("10baseT transceiver, ");
1603         sc->xl_xcvr = XL_XCVR_10BT;
1604         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1605         icfg |= (XL_XCVR_10BT << XL_ICFG_CONNECTOR_BITS);
1606         mediastat |= XL_MEDIASTAT_LINKBEAT|
1607            XL_MEDIASTAT_JABGUARD;
1608         mediastat &= ~XL_MEDIASTAT_SQEENB;
1609      }
1610   }
1611
1612   if (sc->xl_media & XL_MEDIAOPT_BFX) {
1613      if (IFM_SUBTYPE(media) == IFM_100_FX) {
1614         printk("100baseFX port, ");
1615         sc->xl_xcvr = XL_XCVR_100BFX;
1616         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1617         icfg |= (XL_XCVR_100BFX << XL_ICFG_CONNECTOR_BITS);
1618         mediastat |= XL_MEDIASTAT_LINKBEAT;
1619         mediastat &= ~XL_MEDIASTAT_SQEENB;
1620      }
1621   }
1622
1623   if (sc->xl_media & (XL_MEDIAOPT_AUI|XL_MEDIAOPT_10FL)) {
1624      if (IFM_SUBTYPE(media) == IFM_10_5) {
1625         printk("AUI port, ");
1626         sc->xl_xcvr = XL_XCVR_AUI;
1627         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1628         icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
1629         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
1630                        XL_MEDIASTAT_JABGUARD);
1631         mediastat |= ~XL_MEDIASTAT_SQEENB;
1632      }
1633      if (IFM_SUBTYPE(media) == IFM_10_FL) {
1634         printk("10baseFL transceiver, ");
1635         sc->xl_xcvr = XL_XCVR_AUI;
1636         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1637         icfg |= (XL_XCVR_AUI << XL_ICFG_CONNECTOR_BITS);
1638         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
1639                        XL_MEDIASTAT_JABGUARD);
1640         mediastat |= ~XL_MEDIASTAT_SQEENB;
1641      }
1642   }
1643
1644   if (sc->xl_media & XL_MEDIAOPT_BNC) {
1645      if (IFM_SUBTYPE(media) == IFM_10_2) {
1646         printk("BNC port, ");
1647         sc->xl_xcvr = XL_XCVR_COAX;
1648         icfg &= ~XL_ICFG_CONNECTOR_MASK;
1649         icfg |= (XL_XCVR_COAX << XL_ICFG_CONNECTOR_BITS);
1650         mediastat &= ~(XL_MEDIASTAT_LINKBEAT|
1651                        XL_MEDIASTAT_JABGUARD|
1652                        XL_MEDIASTAT_SQEENB);
1653      }
1654   }
1655
1656   if ((media & IFM_GMASK) == IFM_FDX ||
1657       IFM_SUBTYPE(media) == IFM_100_FX) {
1658      printk("full duplex\n");
1659      XL_SEL_WIN(3);
1660      CSR_WRITE_1(sc, XL_W3_MAC_CTRL, XL_MACCTRL_DUPLEX);
1661   } else {
1662      printk("half duplex\n");
1663      XL_SEL_WIN(3);
1664      CSR_WRITE_1(sc, XL_W3_MAC_CTRL,
1665                  (CSR_READ_1(sc, XL_W3_MAC_CTRL) & ~XL_MACCTRL_DUPLEX));
1666   }
1667
1668   if (IFM_SUBTYPE(media) == IFM_10_2)
1669      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
1670   else
1671      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
[96e62937]1672
[01b6ca9]1673   CSR_WRITE_4(sc, XL_W3_INTERNAL_CFG, icfg);
1674   XL_SEL_WIN(4);
1675   CSR_WRITE_2(sc, XL_W4_MEDIA_STATUS, mediastat);
1676   DELAY(800);
1677   XL_SEL_WIN(7);
1678
1679   return;
1680}
1681
1682
1683
1684
1685
1686
1687
1688static void
[142025c]1689xl_choose_xcvr(
1690   struct elnk_softc    *sc,
1691   int                  verbose)
[01b6ca9]1692{
1693   u_int16_t            devid;
1694
1695   /*
1696    * Read the device ID from the EEPROM.
1697    * This is what's loaded into the PCI device ID register, so it has
1698    * to be correct otherwise we wouldn't have gotten this far.
1699    */
1700   xl_read_eeprom(sc, (caddr_t)&devid, XL_EE_PRODID, 1, 0);
1701
1702   switch(devid) {
1703      case TC_DEVICEID_BOOMERANG_10BT:  /* 3c900-TPO */
1704      case TC_DEVICEID_KRAKATOA_10BT:           /* 3c900B-TPO */
1705         sc->xl_media = XL_MEDIAOPT_BT;
1706         sc->xl_xcvr = XL_XCVR_10BT;
1707         if (verbose)
1708            printk("etherlink : unit elnk%d guessing 10BaseT "
1709                   "transceiver\n", sc->xl_unit);
1710         break;
1711      case TC_DEVICEID_BOOMERANG_10BT_COMBO:    /* 3c900-COMBO */
1712      case TC_DEVICEID_KRAKATOA_10BT_COMBO:     /* 3c900B-COMBO */
1713         sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
1714         sc->xl_xcvr = XL_XCVR_10BT;
1715         if (verbose)
1716            printk("etherlink : unit elnk%d guessing COMBO "
1717                   "(AUI/BNC/TP)\n", sc->xl_unit);
1718         break;
1719      case TC_DEVICEID_KRAKATOA_10BT_TPC:       /* 3c900B-TPC */
1720         sc->xl_media = XL_MEDIAOPT_BT|XL_MEDIAOPT_BNC;
1721         sc->xl_xcvr = XL_XCVR_10BT;
1722         if (verbose)
1723            printk("etherlink : unit elnk%d guessing TPC (BNC/TP)\n", sc->xl_unit);
1724         break;
1725      case TC_DEVICEID_CYCLONE_10FL:            /* 3c900B-FL */
1726         sc->xl_media = XL_MEDIAOPT_10FL;
1727         sc->xl_xcvr = XL_XCVR_AUI;
1728         if (verbose)
1729            printk("etherlink : unit elnk%d guessing 10baseFL\n", sc->xl_unit);
1730         break;
1731      case TC_DEVICEID_BOOMERANG_10_100BT:      /* 3c905-TX */
1732      case TC_DEVICEID_HURRICANE_555:           /* 3c555 */
1733      case TC_DEVICEID_HURRICANE_556:           /* 3c556 */
1734      case TC_DEVICEID_HURRICANE_556B:  /* 3c556B */
1735      case TC_DEVICEID_HURRICANE_575A:  /* 3c575TX */
1736      case TC_DEVICEID_HURRICANE_575B:  /* 3c575B */
1737      case TC_DEVICEID_HURRICANE_575C:  /* 3c575C */
1738      case TC_DEVICEID_HURRICANE_656:           /* 3c656 */
1739      case TC_DEVICEID_HURRICANE_656B:  /* 3c656B */
1740      case TC_DEVICEID_TORNADO_656C:            /* 3c656C */
1741      case TC_DEVICEID_TORNADO_10_100BT_920B:   /* 3c920B-EMB */
1742         sc->xl_media = XL_MEDIAOPT_MII;
1743         sc->xl_xcvr = XL_XCVR_MII;
1744         if (verbose)
1745            printk("etherlink : unit elnk%d guessing MII\n", sc->xl_unit);
1746         break;
1747      case TC_DEVICEID_BOOMERANG_100BT4:        /* 3c905-T4 */
1748      case TC_DEVICEID_CYCLONE_10_100BT4:       /* 3c905B-T4 */
1749         sc->xl_media = XL_MEDIAOPT_BT4;
1750         sc->xl_xcvr = XL_XCVR_MII;
1751         if (verbose)
1752            printk("etherlink : unit elnk%d guessing 100BaseT4/MII\n", sc->xl_unit);
1753         break;
1754      case TC_DEVICEID_HURRICANE_10_100BT:      /* 3c905B-TX */
1755      case TC_DEVICEID_HURRICANE_10_100BT_SERV:/*3c980-TX */
1756      case TC_DEVICEID_TORNADO_10_100BT_SERV:   /* 3c980C-TX */
1757      case TC_DEVICEID_HURRICANE_SOHO100TX:     /* 3cSOHO100-TX */
1758      case TC_DEVICEID_TORNADO_10_100BT:        /* 3c905C-TX */
1759      case TC_DEVICEID_TORNADO_HOMECONNECT:     /* 3c450-TX */
1760         sc->xl_media = XL_MEDIAOPT_BTX;
1761         sc->xl_xcvr = XL_XCVR_AUTO;
1762         if (verbose)
1763            printk("etherlink : unit elnk%d guessing 10/100 internal\n", sc->xl_unit);
1764         break;
1765      case TC_DEVICEID_CYCLONE_10_100_COMBO:    /* 3c905B-COMBO */
1766         sc->xl_media = XL_MEDIAOPT_BTX|XL_MEDIAOPT_BNC|XL_MEDIAOPT_AUI;
1767         sc->xl_xcvr = XL_XCVR_AUTO;
1768         if (verbose)
1769            printk("etherlink : unit elnk%d guessing 10/100 "
1770                   "plus BNC/AUI\n", sc->xl_unit);
1771         break;
1772      default:
1773         printk("etherlink : unit elnk%d unknown device ID: %x -- "
1774                "defaulting to 10baseT\n", sc->xl_unit, devid);
1775         sc->xl_media = XL_MEDIAOPT_BT;
1776         break;
1777   }
1778
1779   return;
1780}
1781
1782
1783
1784
1785
1786
1787
1788/*
1789 * This routine is a kludge to work around possible hardware faults
1790 * or manufacturing defects that can cause the media options register
1791 * (or reset options register, as it's called for the first generation
1792 * 3c90x adapters) to return an incorrect result. I have encountered
1793 * one Dell Latitude laptop docking station with an integrated 3c905-TX
1794 * which doesn't have any of the 'mediaopt' bits set. This screws up
1795 * the attach routine pretty badly because it doesn't know what media
1796 * to look for. If we find ourselves in this predicament, this routine
1797 * will try to guess the media options values and warn the user of a
1798 * possible manufacturing defect with his adapter/system/whatever.
1799 */
1800static void
[142025c]1801xl_mediacheck(struct elnk_softc         *sc)
[01b6ca9]1802{
1803
[96e62937]1804   xl_choose_xcvr(sc, 1);
1805
[01b6ca9]1806   /*
1807    * If some of the media options bits are set, assume they are
1808    * correct. If not, try to figure it out down below.
1809    * XXX I should check for 10baseFL, but I don't have an adapter
1810    * to test with.
1811    */
1812   if (sc->xl_media & (XL_MEDIAOPT_MASK & ~XL_MEDIAOPT_VCO)) {
1813      /*
1814       * Check the XCVR value. If it's not in the normal range
1815       * of values, we need to fake it up here.
1816       */
1817      if (sc->xl_xcvr <= XL_XCVR_AUTO)
1818         return;
1819      else {
1820         printk("etherlink : unit elnk%d bogus xcvr value "
1821                "in EEPROM (%x)\n", sc->xl_unit, sc->xl_xcvr);
1822         printk("etherlink : unit elnk%d choosing new default based "
1823                "on card type\n", sc->xl_unit);
1824      }
1825   } else {
1826      if (sc->xl_type == XL_TYPE_905B &&
1827          sc->xl_media & XL_MEDIAOPT_10FL)
1828         return;
1829      printk("etherlink : unit elnk%d WARNING: no media options bits set in "
1830             "the media options register!!\n", sc->xl_unit);
1831      printk("etherlink : unit elnk%d this could be a manufacturing defect in "
1832             "your adapter or system\n", sc->xl_unit);
1833      printk("etherlink : unit elnk%d attempting to guess media type; you "
1834             "should probably consult your vendor\n", sc->xl_unit);
1835   }
1836
1837   return;
1838}
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864static void no_op(const rtems_irq_connect_data* irq)
1865{
1866   return;
1867}
1868
1869
1870
1871
1872static int elnkIsOn(const rtems_irq_connect_data* irq)
1873{
1874  return BSP_irq_enabled_at_i8259s (irq->name);
1875}
1876
1877
1878
1879
1880
1881
[a3d3d9a]1882static void
[96e62937]1883elnk_start_txchain( struct elnk_softc *sc, struct TXMD *chainhead )
[01b6ca9]1884{
[96e62937]1885   xl_wait(sc);
1886   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_STALL);
[01b6ca9]1887
1888   /* save the address of the TX list */
[96e62937]1889   sc->last_txchain_head = chainhead;
1890   sc->tx_idle = 0;
[01b6ca9]1891
1892   xl_wait(sc);
[96e62937]1893
[01b6ca9]1894   CSR_WRITE_4(sc, XL_DOWNLIST_PTR, phys_to_bus( sc->last_txchain_head ));
1895   CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_DOWN_UNSTALL);
1896}
1897
1898
1899
1900
1901
1902/*
1903 * ELNK interrupt handler
1904 */
1905static rtems_isr
1906elnk_interrupt_handler ( struct elnk_softc *sc )
1907{
1908   struct ifnet         *ifp = &sc->arpcom.ac_if;
1909   u_int16_t            status;
1910
[96e62937]1911   while( ((status = CSR_READ_2(sc, XL_STATUS)) & XL_INTRS) && status != 0xFFFF)
[01b6ca9]1912   {
1913      sc->xl_stats.device_interrupts++;
1914
[96e62937]1915      CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK | (status & XL_INTRS));
[01b6ca9]1916
1917#if 0
1918      printk("etherlink : unit elnk%d intstatus %04x\n", sc->xl_unit, status  );
1919#endif
1920
[a3d3d9a]1921      if (status & XL_STAT_UP_COMPLETE)
[01b6ca9]1922      {
1923#if 0
1924         printk("etherlink : unit elnk%d rx\n", sc->xl_unit );
1925#endif
1926         /* received packets */
1927         rtems_event_send(rxDaemonTid, sc->ioevent);
1928      }
1929
[3584398a]1930      if( (status & XL_STAT_DOWN_COMPLETE) || (status & XL_STAT_TX_COMPLETE) )
[01b6ca9]1931      {
1932         /* all packets uploaded to the device */
[96e62937]1933         struct TXMD *chaintailmd = NULL;
1934
[3584398a]1935
1936         if( status & XL_STAT_TX_COMPLETE )
1937         {
1938            /* if we got a tx complete error, count it, then reset the
1939               transmitter.  Consider the entire chain lost.. */
1940
1941            ifp->if_oerrors++;
1942            sc->xl_stats.txcomplete_ints++;
1943
1944            printk("etherlink : unit elnk%d transmit error\n", sc->xl_unit );
1945
1946            /* reset, re-enable fifo */
1947
1948            xl_wait(sc);
1949            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_DISABLE);
1950
1951            xl_wait(sc);
1952            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_RESET | 1 );
1953
1954            xl_wait(sc);
1955            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
1956
1957            xl_wait(sc);
1958         }
1959
1960
[96e62937]1961         /* send the chain head to the tx task which will recover the
1962            whole chain */
1963         rtems_message_queue_send( chainRecoveryQueue, &sc->last_txchain_head, sizeof(struct TXMD *));
[01b6ca9]1964
[3584398a]1965
[96e62937]1966         /* set up the next chain */
1967         if( sc->last_txchain_head->chainptr )
[01b6ca9]1968         {
[96e62937]1969            /* check the head of the chain of packets we just finished,
1970             * if != 0, either this is a chain of 2 or more packets or
1971             * its a single packet chain and another chain is ready to
1972             * send.
[01b6ca9]1973             */
[96e62937]1974            if( (int)sc->last_txchain_head->chainptr == -1 )
[01b6ca9]1975            {
[a3d3d9a]1976               /*
[96e62937]1977               ** single packet was sent so no indirection to the last
1978               ** entry in the chain.  since chainptr is != 0, then
1979               ** another chain is ready starting from the packet AFTER
1980               ** the chain we just finished. - in this case the last
1981               ** chain's head == its tail
1982               */
[01b6ca9]1983               chaintailmd = sc->last_txchain_head;
1984            }
1985            else
1986            {
[96e62937]1987               /*
1988               ** otherwise, this is a pointer to the last packet in the
1989               ** chain of 2 or more packets.  If the chain's last
[3584398a]1990               ** packet's chainptr is != 0, then another chain is ready
1991               ** to send.
[96e62937]1992               */
1993               chaintailmd = sc->last_txchain_head->chainptr;
[3584398a]1994               if( !chaintailmd->chainptr ) chaintailmd = NULL;
[01b6ca9]1995            }
1996         }
1997
1998         if( chaintailmd )
1999         {
2000            /* the next MD is the start of another chain */
2001            elnk_start_txchain(sc, chaintailmd->next_md );
2002         }
2003         else
2004         {
[96e62937]2005            /* otherwise nothing to send, so go idle */
[01b6ca9]2006            sc->tx_idle = -1;
[96e62937]2007
2008            /* wake up the tx daemon once so we're sure this last chain
2009               will be freed */
2010            rtems_event_send( txDaemonTid, sc->ioevent );
2011#if 0
[01b6ca9]2012            printk("unit elnk%d tx done\n", sc->xl_unit );
[96e62937]2013#endif
[01b6ca9]2014         }
2015      }
2016
[96e62937]2017
[a3d3d9a]2018      if (status & XL_STAT_ADFAIL)
[01b6ca9]2019      {
2020         printk("etherlink : unit elnk%d Catastrophic bus failure\n", sc->xl_unit );
2021      }
[a3d3d9a]2022      if (status & XL_STAT_STATSOFLOW)
[01b6ca9]2023      {
2024         sc->xl_stats_no_timeout = 1;
2025         xl_stats_update(sc->stat_timer_id,sc);
2026         sc->xl_stats_no_timeout = 0;
2027      }
2028   }
[a3d3d9a]2029
[01b6ca9]2030
2031#if 0
2032   {
[ee4f57d]2033      uint16_t   intstatus, intenable, indenable;
[01b6ca9]2034
2035      intstatus = CSR_READ_2(sc, XL_STATUS );
2036
2037      XL_SEL_WIN(5);
2038      intenable = CSR_READ_2(sc, XL_W5_INTR_ENB );
2039      indenable = CSR_READ_2(sc, XL_W5_STAT_ENB );
2040      XL_SEL_WIN(7);
2041      printk("etherlink : unit elnk%d istat %04x, ien %04x, ind %04x\n", sc->xl_unit, intstatus, intenable, indenable  );
2042   }
2043#endif
2044}
2045
2046
2047
2048
2049
2050static rtems_isr
[142025c]2051elnk_interrupt_handler_entry(void)
[01b6ca9]2052{
2053   int i;
2054
2055   /*
2056   ** Check all the initialized units for interrupt service
2057   */
2058
2059   for(i=0; i< NUM_UNITS; i++ )
2060   {
2061      if( elnk_softc[i].ioaddr )
2062         elnk_interrupt_handler( &elnk_softc[i] );
2063   }
2064}
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076/*
2077 * Initialize the ethernet hardware
2078 */
2079static void
2080elnk_initialize_hardware (struct elnk_softc *sc)
2081{
[96e62937]2082   unsigned char *cp;
2083   int i, j, rxsize, txsize, ringsize;
[01b6ca9]2084
2085   /*
2086    * Init RX ring
2087    */
[a3d3d9a]2088   cp = (unsigned char *)malloc( (ringsize = ((rxsize = (sc->numRxbuffers * sizeof(struct RXMD))) +
[96e62937]2089                                              (txsize = (sc->numTxbuffers * sizeof(struct TXMD)))) ) +
2090                                 + CPU_CACHE_ALIGNMENT_FOR_BUFFER);
[01b6ca9]2091   sc->bufferBase = cp;
2092   cp += (CPU_CACHE_ALIGNMENT_FOR_BUFFER - (int)cp) & (CPU_CACHE_ALIGNMENT_FOR_BUFFER - 1);
2093#if defined(__i386__)
[a3d3d9a]2094#ifdef PCI_BRIDGE_DOES_NOT_ENSURE_CACHE_COHERENCY_FOR_DMA
[01b6ca9]2095   if (_CPU_is_paging_enabled())
2096      _CPU_change_memory_mapping_attribute
[96e62937]2097         (NULL, cp, ringsize, PTE_CACHE_DISABLE | PTE_WRITABLE);
[01b6ca9]2098#endif
2099#endif
2100   sc->ringBase = cp;
2101
[96e62937]2102   /* build tx and rx rings */
[01b6ca9]2103
[96e62937]2104   sc->rx_ring = (struct RXMD *)sc->ringBase;
2105   sc->tx_ring = (struct TXMD *)&sc->ringBase[ rxsize ];
[01b6ca9]2106
[96e62937]2107   {
2108      struct mbuf    *m;
2109      struct RXMD    *nxtmd;
[a3d3d9a]2110      /*
[96e62937]2111       * The rx ring is easy as its just an array of RXMD structs.  New
2112       * mbuf entries are allocated from the stack whenever the rx
2113       * daemon forwards an incoming packet into it.  Here, we
2114       * pre-allocate the rx mbufs for the rx ring entries.
[01b6ca9]2115       */
2116      for(i=0 ; i<sc->numRxbuffers; i++)
2117      {
[509fec9c]2118         if( ((uint32_t)&sc->rx_ring[i] & 0x7) )
[96e62937]2119         {
2120            rtems_panic ("etherlink : unit elnk%d rx ring entry %d not aligned to 8 bytes\n", sc->xl_unit, i );
2121         }
[a3d3d9a]2122
[01b6ca9]2123         /* allocate an mbuf for each receive descriptor */
2124         MGETHDR (m, M_WAIT, MT_DATA);
2125         MCLGET (m, M_WAIT);
2126         m->m_pkthdr.rcvif = &sc->arpcom.ac_if;
[96e62937]2127
[01b6ca9]2128         if( i == sc->numRxbuffers-1 )
[96e62937]2129            nxtmd = &sc->rx_ring[0];
[01b6ca9]2130         else
[96e62937]2131            nxtmd = &sc->rx_ring[i+1];
[01b6ca9]2132
[96e62937]2133         sc->rx_ring[i].next_md = nxtmd;
2134         sc->rx_ring[i].mbuf = m;
[01b6ca9]2135
[96e62937]2136         st_le32( &sc->rx_ring[i].status, 0);
[509fec9c]2137         st_le32( &sc->rx_ring[i].next, (uint32_t)phys_to_bus( nxtmd ));
2138         st_le32( &sc->rx_ring[i].addr, (uint32_t)phys_to_bus( mtod(m, void *) ));
[96e62937]2139         st_le32( &sc->rx_ring[i].length, XL_LAST_FRAG | XL_PACKET_SIZE );
[01b6ca9]2140      }
[96e62937]2141      sc->curr_rx_md = &sc->rx_ring[0];
2142   }
[01b6ca9]2143
2144
[96e62937]2145   {
2146      struct TXMD *thismd, *nxtmd;
[a3d3d9a]2147      /*
[96e62937]2148       * The tx ring is more complex. Each MD has an array of fragment
2149       * descriptors that are loaded from each packet as they arrive
2150       * from the stack.  Each packet gets one ring entry, this allows
2151       * the lanboard to efficiently assemble the piecemeal packets into
2152       * a contiguous unit at transmit time, rather than spending
2153       * cputime concatenating them first.  Although the next_md fields
2154       * form a ring, the DPD next is filled only when packets are added
2155       * to the tx chain, thus last entry of a series of packets has the
2156       * requisite dpd->next value == 0 to terminate the dma.  mbuf
2157       * holds the packet info so it can be freed once the packet has
2158       * been sent.  chainptr is used to link the head & tail of a chain
2159       * of 2 or more packets.  A chain is formed when the tx daemon
2160       * gets 2 or more packets from the stack's queue in a service
2161       * period, so higher outgoing loads are handled as efficiently as
2162       * possible.
[01b6ca9]2163       */
2164
2165      for(i=0 ; i<sc->numTxbuffers; i++)
2166      {
[509fec9c]2167         if( ((uint32_t)&sc->tx_ring[i] & 0x7) )
[96e62937]2168         {
2169            rtems_panic ("etherlink : unit elnk%d tx ring entry %d not aligned to 8 bytes\n", sc->xl_unit, i );
2170         }
2171
[01b6ca9]2172         if( i == sc->numTxbuffers-1 )
[96e62937]2173            nxtmd = &sc->tx_ring[0];
[01b6ca9]2174         else
[96e62937]2175            nxtmd = &sc->tx_ring[i+1];
[01b6ca9]2176
[96e62937]2177         thismd = &sc->tx_ring[i];
[01b6ca9]2178
2179         thismd->next_md = nxtmd;
[96e62937]2180         thismd->chainptr = NULL;
[01b6ca9]2181         thismd->mbuf = NULL;
2182
2183         st_le32( &thismd->status, XL_TXSTAT_DL_COMPLETE );
[96e62937]2184         st_le32( &thismd->next, 0);
[01b6ca9]2185
[96e62937]2186         for(j=0; j< NUM_FRAGS; j++)
2187         {
2188            st_le32( &thismd->txfrags[j].addr, 0 );
2189            st_le32( &thismd->txfrags[j].length, 0 );
2190         }
2191      }
2192      sc->last_tx_md = &sc->tx_ring[0];
[01b6ca9]2193   }
2194
2195
2196
2197
2198#ifdef ELNK_DEBUG
2199   printk("etherlink : %02x:%02x:%02x:%02x:%02x:%02x   name 'elnk%d', io %x, int %d\n",
2200          sc->arpcom.ac_enaddr[0], sc->arpcom.ac_enaddr[1],
2201          sc->arpcom.ac_enaddr[2], sc->arpcom.ac_enaddr[3],
2202          sc->arpcom.ac_enaddr[4], sc->arpcom.ac_enaddr[5],
[a3d3d9a]2203          sc->xl_unit,
[01b6ca9]2204          (unsigned)sc->ioaddr, sc->irqInfo.name );
2205#endif
2206
2207
2208   sc->irqInfo.hdl  = (rtems_irq_hdl)elnk_interrupt_handler_entry;
2209   sc->irqInfo.on   = no_op;
2210   sc->irqInfo.off  = no_op;
2211   sc->irqInfo.isOn = elnkIsOn;
2212
2213   if( sc->irqInfo.name != 255 )
2214   {
2215      int st;
2216
2217#ifdef BSP_SHARED_HANDLER_SUPPORT
2218      st = BSP_install_rtems_shared_irq_handler( &sc->irqInfo );
2219#else
2220      st = BSP_install_rtems_irq_handler( &sc->irqInfo );
2221#endif
2222      if (!st)
2223         rtems_panic ("etherlink : unit elnk%d Interrupt name %d already in use\n", sc->xl_unit, sc->irqInfo.name );
2224   }
2225   else
2226   {
2227      printk("etherlink : unit elnk%d Interrupt not specified by device\n", sc->xl_unit );
2228   }
2229}
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241static void
2242elnk_rxDaemon (void *arg)
2243{
2244   struct elnk_softc     *sc;
2245   struct ether_header   *eh;
2246   struct mbuf           *m;
[96e62937]2247   struct RXMD           *rmd;
[01b6ca9]2248   unsigned int          i,len, rxstat;
2249   rtems_event_set       events;
2250
2251   for (;;)
2252   {
2253
2254      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
2255                                  RTEMS_WAIT|RTEMS_EVENT_ANY,
2256                                  RTEMS_NO_TIMEOUT,
2257                                  &events);
2258
2259      for(;;)
2260      {
2261         for(i=0; i< NUM_UNITS; i++ )
2262         {
2263            sc = &elnk_softc[i];
2264            if( sc->ioaddr )
2265            {
2266               if( events & sc->ioevent )
2267               {
2268                  struct ifnet *ifp = &sc->arpcom.ac_if;
2269
2270                  rmd   = sc->curr_rx_md;
2271
2272                  /*
2273                  ** Read off all the packets we've received on this unit
2274                  */
2275                  while( (rxstat = ld_le32(&rmd->status)) )
2276                  {
[a3d3d9a]2277                     if (rxstat & XL_RXSTAT_UP_ERROR)
[01b6ca9]2278                     {
2279                        printk("unit %i up error\n", sc->xl_unit );
2280                        ifp->if_ierrors++;
2281                     }
2282
[a3d3d9a]2283                     if( (rxstat & XL_RXSTAT_UP_CMPLT) )
[01b6ca9]2284                     {
2285
2286#if 0
2287                        {
2288                           char *pkt, *delim;
2289                           int  i;
2290                           pkt = mtod(rmd->mbuf, char *);
2291                           printk("unit %i rx  pkt (%08x) ", sc->xl_unit, pkt );
2292                           for(delim="", i=0; i < sizeof(struct ether_header)+8; i++, delim=":")
2293                              printk("%s%02x", delim, (char) pkt[i] );
2294                           printk("\n");
2295                        }
2296#endif
2297
2298                        /* pass on the packet in the mbuf */
2299                        len = ( ld_le32(&rmd->status) & XL_RXSTAT_LENMASK);
2300                        m = rmd->mbuf;
2301                        m->m_len = m->m_pkthdr.len = len - sizeof(struct ether_header);
2302                        eh = mtod(m, struct ether_header *);
2303                        m->m_data += sizeof(struct ether_header);
2304
2305                        ether_input(ifp, eh, m);
2306
2307                        /* get a new mbuf */
2308                        MGETHDR (m, M_WAIT, MT_DATA);
2309                        MCLGET (m, M_WAIT);
2310                        m->m_pkthdr.rcvif = ifp;
2311                        rmd->mbuf   = m;
[96e62937]2312                        st_le32( &rmd->status, 0 );
[509fec9c]2313                        st_le32( &rmd->addr, (uint32_t)phys_to_bus(mtod(m, void *)) );
[01b6ca9]2314                     }
2315                     else
2316                     {
2317                        /* some kind of packet failure */
2318                        printk("etherlink : unit elnk%d bad receive status -- packet dropped\n", sc->xl_unit);
2319                        ifp->if_ierrors++;
2320                     }
2321                     /* clear descriptor status */
2322                     rmd->status = 0;
[a3d3d9a]2323
[01b6ca9]2324                     rmd = rmd->next_md;
2325                  }
2326
2327                  sc->curr_rx_md = rmd;
2328               }
2329            }
2330         }
2331
2332         /*
2333         ** If more events are pending, service them before we go back to sleep
2334         */
2335         if( rtems_event_receive( RTEMS_ALL_EVENTS,
2336                                  RTEMS_NO_WAIT | RTEMS_EVENT_ANY,
2337                                  0,
2338                                  &events ) == RTEMS_UNSATISFIED ) break;
2339      }
2340   }
2341}
2342
2343
2344
2345
2346
2347
2348
2349
2350/*
2351 * Driver transmit daemon
2352 */
2353void
2354elnk_txDaemon (void *arg)
2355{
2356   struct elnk_softc     *sc;
2357   struct ifnet          *ifp;
2358   struct mbuf           *m;
[96e62937]2359   struct TXMD           *lastmd, *nextmd, *firstmd;
2360   int                   chainCount,i;
[01b6ca9]2361   rtems_event_set       events;
2362
[a3d3d9a]2363   for (;;)
[01b6ca9]2364   {
2365      /*
[96e62937]2366       * Wait for any unit's signal to wake us up
[01b6ca9]2367       */
2368      rtems_bsdnet_event_receive( RTEMS_ALL_EVENTS,
[a3d3d9a]2369                                  RTEMS_EVENT_ANY | RTEMS_WAIT,
[01b6ca9]2370                                  RTEMS_NO_TIMEOUT, &events);
2371
2372      for(i=0; i< NUM_UNITS; i++ )
2373      {
2374         sc  = &elnk_softc[i];
2375         if( sc->ioaddr )
2376         {
2377            if( events & sc->ioevent )
2378            {
2379               ifp = &sc->arpcom.ac_if;
2380
2381               /*
2382                * Send packets till queue is empty or tx ring is full
2383                */
[3584398a]2384
[01b6ca9]2385               chainCount = 0;
2386               firstmd = NULL;
[a3d3d9a]2387
[01b6ca9]2388               lastmd = sc->last_tx_md;
2389
[a3d3d9a]2390               for(;;)
[01b6ca9]2391               {
[96e62937]2392                  /*
2393                  ** Check the chain recovery queue whenever the tx
[3584398a]2394                  ** daemon services the stack.  Note this routine does
2395                  ** not assume the context of one of the lanboard units
2396                  ** because used tx mbufs are no longer associated with
2397                  ** any unit.
[96e62937]2398                  */
2399                  {
2400                     struct TXMD *chainhead, *chaintail;
[41a1c334]2401                     size_t esize;
[96e62937]2402
2403                     if( rtems_message_queue_receive( chainRecoveryQueue, &chainhead, &esize,
2404                                                      RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL )
2405                     {
2406                        /* get a pointer to the tail */
2407                        chaintail = chainhead->chainptr;
2408
2409                        /* if the tail points somewhere, free the entire
2410                           chain */
2411                        if( chaintail && (int)chaintail != -1 )
2412                        {
2413                           for(;;)
2414                           {
2415                              m_freem( chainhead->mbuf );
[3584398a]2416                              st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
[96e62937]2417                              chainhead->mbuf = NULL;
2418
2419                              if(  chainhead == chaintail ) break;
2420                              chainhead = chainhead->next_md;
2421                           }
2422                        }
2423                        else
2424                        {
2425                           /* a single packet chain */
2426                           m_freem( chainhead->mbuf );
[3584398a]2427                           st_le32( &chainhead->status, XL_TXSTAT_DL_COMPLETE );
[96e62937]2428                           chainhead->mbuf = NULL;
2429                        }
2430                     }
2431                  }
2432
[01b6ca9]2433                  nextmd = lastmd->next_md;
2434
2435                  /* stop when ring is full */
[3584398a]2436                  if( ! (ld_le32(&nextmd->status) & XL_TXSTAT_DL_COMPLETE) )
[01b6ca9]2437                  {
2438                     printk("etherlink : unit elnk%d tx ring full!\n", sc->xl_unit);
2439                     break;
2440                  }
[3584398a]2441                  /* sanity check the next packet descriptor */
2442                  if( nextmd->mbuf )
2443                  {
2444                     printk("etherlink : unit elnk%d tx ring corrupt!\n", sc->xl_unit);
2445                     break;
2446                  }
2447
[a3d3d9a]2448
[01b6ca9]2449
2450                  IF_DEQUEUE(&ifp->if_snd, m);
2451                  if( !m ) break;
2452
2453                  {
[96e62937]2454                     int i;
[01b6ca9]2455
[96e62937]2456                     nextmd->mbuf = m;
2457
2458                     for(i=0; i< NUM_FRAGS; i++)
2459                     {
2460                        st_le32( &nextmd->txfrags[i].length, ((m->m_next)?0:XL_LAST_FRAG) | ( m->m_len & XL_TXSTAT_LENMASK) );
[509fec9c]2461                        st_le32( &nextmd->txfrags[i].addr, (uint32_t)phys_to_bus( m->m_data ) );
[96e62937]2462                        if ((m = m->m_next) == NULL)
2463                           break;
2464                     }
2465                     if( m )
2466                     {
2467                        printk("etherlink : unit elnk%d tx fragments exhausted, truncating packet!\n", sc->xl_unit);
[a3d3d9a]2468                        st_le32( &nextmd->txfrags[NUM_FRAGS-1].length, XL_LAST_FRAG |
[96e62937]2469                                 ld_le32( &nextmd->txfrags[NUM_FRAGS-1].length) );
2470                     }
2471                  }
[01b6ca9]2472
[96e62937]2473#if 0
[01b6ca9]2474                  {
[3584398a]2475                     char *pkt = bus_to_phys( ld_le32( &nextmd->txfrags[i].addr )), *delim;
[01b6ca9]2476                     int  i;
[509fec9c]2477                     printk("unit %d queued  pkt (%08x) ", sc->xl_unit, (uint32_t)pkt );
[96e62937]2478                     for(delim="", i=0; i < sizeof(struct ether_header); i++, delim=":")
[a3d3d9a]2479                        printk("%s%02x", delim, (char) pkt[i] );
[01b6ca9]2480                     printk("\n");
2481                  }
[96e62937]2482#endif
[01b6ca9]2483
2484
2485                  /* this packet will be the new end of the list */
[96e62937]2486                  st_le32( &nextmd->next, 0);
2487                  st_le32( &nextmd->status, 0);
[01b6ca9]2488
2489                  if( !firstmd )
[a3d3d9a]2490                  {
[01b6ca9]2491                     /* keep track of the first packet we add to the chain */
2492                     firstmd = nextmd;
2493
[96e62937]2494                     /*
2495                      ** use the chainbuf pointer of the last packet of
2496                      ** the previous chain as a flag so when a
2497                      ** dnComplete interrupt indicates the card is
2498                      ** finished downloading the chain, the isr can
2499                      ** immediately start the next which always begins
2500                      ** with the next packet in the ring.  Note several
2501                      ** chains of packets may be assembled this way.
[01b6ca9]2502                      */
[96e62937]2503                     lastmd->chainptr = (struct TXMD *)-1;
[01b6ca9]2504                  }
2505                  else
2506                  {
2507                     /* hook this packet to the previous one */
[509fec9c]2508                     st_le32( &lastmd->next, (uint32_t)phys_to_bus( nextmd ));
[01b6ca9]2509                  }
2510
2511                  ++chainCount;
2512                  lastmd = nextmd;
2513               }
2514
2515
2516
[3584398a]2517
2518
[01b6ca9]2519               if( firstmd )
2520               {
[3584398a]2521                  /* only enter if we've queued one or more packets */
[96e62937]2522
[01b6ca9]2523                  /* save the last descriptor we set up in the chain */
2524                  sc->last_tx_md = lastmd;
2525
[a3d3d9a]2526                  /*
[01b6ca9]2527                   * We've added one or more packets to a chain, flag
2528                   * the last packet so we get an dnComplete interrupt
2529                   * when the card finishes accepting the chain
2530                   */
[96e62937]2531                  st_le32( &lastmd->status, XL_TXSTAT_DL_INTR );
[01b6ca9]2532
[a3d3d9a]2533                  /*
[3584398a]2534                   * point the chain head's chainptr to the tail so we
2535                   * can jump to the next chain to send inside the isr.
2536                   * If we're only sending one packet, then don't bother
2537                   * with the link, as the chainptr value will either be
2538                   * 0 if theres no next chain or -1 if there is.
[01b6ca9]2539                   */
[a3d3d9a]2540                  if( chainCount > 1 )
[96e62937]2541                  {
2542                     firstmd->chainptr = lastmd;
[01b6ca9]2543
[96e62937]2544                     sc->chain_lengths[sc->chlenIndex]= (short)chainCount;
2545                     if( ++sc->chlenIndex == NUM_CHAIN_LENGTHS ) sc->chlenIndex = 0;
2546                  }
2547
[a3d3d9a]2548                  /*
[96e62937]2549                  ** clear the last packet's chainptr flag.  If another
[3584398a]2550                  ** chain is added later but before this chain is
2551                  ** finished being sent, this flag on this packet will
2552                  ** be re-set to -1
[96e62937]2553                  */
2554                  lastmd->chainptr = NULL;
[01b6ca9]2555
[96e62937]2556#if 0
[a3d3d9a]2557                  printk("unit %d queued %d pkts, lastpkt status %08X\n",
2558                         sc->xl_unit,
2559                         chainCount,
[509fec9c]2560                         (uint32_t)ld_le32( &lastmd->status) );
[96e62937]2561#endif
[01b6ca9]2562
[a3d3d9a]2563                  if( sc->tx_idle == 0 && CSR_READ_4(sc, XL_DOWNLIST_PTR) == 0 )
[01b6ca9]2564                  {
2565                     printk("etherlink : unit elnk%d tx forced!\n", sc->xl_unit);
2566                     sc->tx_idle = -1;
2567                  }
2568
[a3d3d9a]2569                  /*
[96e62937]2570                  ** start sending this chain of packets if tx isn't
2571                  ** busy, else the dnComplete interrupt will see there
2572                  ** is another chain waiting and begin it immediately.
2573                  */
[01b6ca9]2574                  if( sc->tx_idle )
2575                  {
[96e62937]2576#if 0
2577                     printk("etherlink : unit elnk%d tx started %d packets\n", sc->xl_unit, chainCount );
2578#endif
[01b6ca9]2579                     elnk_start_txchain(sc, firstmd);
2580                  }
2581               }
2582
[3584398a]2583
[01b6ca9]2584               ifp->if_flags &= ~IFF_OACTIVE;
2585            }
2586         }
2587      }
2588   }
2589}
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601static void
2602elnk_start (struct ifnet *ifp)
2603{
2604   struct elnk_softc *sc = ifp->if_softc;
2605#if 0
2606   printk("unit %i tx signaled\n", sc->xl_unit );
2607#endif
2608   ifp->if_flags |= IFF_OACTIVE;
2609   rtems_event_send( txDaemonTid, sc->ioevent );
2610}
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626/*
2627 * Initialize and start the device
2628 */
2629static void
2630elnk_init (void *arg)
2631{
2632   int i;
2633   struct elnk_softc *sc = arg;
2634   struct ifnet *ifp = &sc->arpcom.ac_if;
2635
[96e62937]2636   if( !(ifp->if_flags & IFF_RUNNING) )
[01b6ca9]2637   {
[96e62937]2638      xl_stop(sc);
2639      xl_reset(sc);
2640      sc->tx_idle = -1;
[01b6ca9]2641
2642      {
[ee4f57d]2643         uint32_t   cr,sr;
[01b6ca9]2644
[96e62937]2645         xl_miibus_writereg(sc, 0x18, MII_BMCR, BMCR_RESET );
[a3d3d9a]2646
[96e62937]2647         while( (cr = xl_miibus_readreg(sc, 0x18, MII_BMCR )) & BMCR_RESET )
2648         {
2649            DELAY(100000);
2650         }
[01b6ca9]2651
[96e62937]2652         xl_miibus_writereg(sc, 0x18, MII_ANAR, ANAR_10 | ANAR_TX | ANAR_10_FD | ANAR_TX_FD );  /*  ANAR_T4 */
2653         xl_miibus_writereg(sc, 0x18, MII_BMCR, BMCR_STARTNEG | BMCR_AUTOEN );
[01b6ca9]2654
[1402d56a]2655         for (i=0; ((sr = xl_miibus_readreg(sc, 0x18, MII_BMSR)) & BMSR_ACOMP) == 0 && i < 20; i++)
2656            DELAY(10000);
[96e62937]2657      }
[01b6ca9]2658
2659
2660      /*
[96e62937]2661       * Set up hardware if its not already been done
[01b6ca9]2662       */
[96e62937]2663      if( !sc->irqInfo.hdl )
[01b6ca9]2664      {
[96e62937]2665         elnk_initialize_hardware(sc);
[01b6ca9]2666      }
2667
2668      /*
[96e62937]2669       * Enable the card
[01b6ca9]2670       */
[96e62937]2671      {
2672         u_int8_t               rxfilt;
[01b6ca9]2673
[96e62937]2674         /* Init our MAC address */
2675         XL_SEL_WIN(2);
[a3d3d9a]2676         for (i = 0; i < ETHER_ADDR_LEN; i++)
[96e62937]2677         {
2678            CSR_WRITE_1(sc, XL_W2_STATION_ADDR_LO + i, sc->arpcom.ac_enaddr[i]);
2679         }
[01b6ca9]2680
[96e62937]2681         {
2682            int  media = IFM_ETHER|IFM_100_TX|IFM_FDX;
2683
2684            xl_mediacheck(sc);
2685
2686            /* Choose a default media. */
2687            switch(sc->xl_xcvr) {
2688               case XL_XCVR_10BT:
2689                  media = IFM_ETHER|IFM_10_T;
2690                  xl_setmode(sc, media);
2691                  break;
2692               case XL_XCVR_AUI:
2693                  if (sc->xl_type == XL_TYPE_905B &&
2694                      sc->xl_media == XL_MEDIAOPT_10FL) {
2695                     media = IFM_ETHER|IFM_10_FL;
2696                     xl_setmode(sc, media);
2697                  } else {
2698                     media = IFM_ETHER|IFM_10_5;
2699                     xl_setmode(sc, media);
2700                  }
2701                  break;
2702               case XL_XCVR_COAX:
2703                  media = IFM_ETHER|IFM_10_2;
2704                  xl_setmode(sc, media);
2705                  break;
2706               case XL_XCVR_AUTO:
2707               case XL_XCVR_100BTX:
2708                  xl_setcfg(sc);
2709                  break;
2710               case XL_XCVR_MII:
2711                  printk("etherlink : unit elnk%d MII media not supported!\n", sc->xl_unit);
2712                  break;
2713               case XL_XCVR_100BFX:
2714                  media = IFM_ETHER|IFM_100_FX;
2715                  break;
2716               default:
2717                  printk("etherlink : unit elnk%d unknown XCVR type: %d\n", sc->xl_unit, sc->xl_xcvr);
2718                  /*
2719                   * This will probably be wrong, but it prevents
2720                   * the ifmedia code from panicking.
2721                   */
2722                  media = IFM_ETHER|IFM_10_T;
2723                  break;
2724            }
[01b6ca9]2725
2726
[96e62937]2727            if (sc->xl_flags & XL_FLAG_NO_XCVR_PWR) {
2728               XL_SEL_WIN(0);
2729               CSR_WRITE_2(sc, XL_W0_MFG_ID, XL_NO_XCVR_PWR_MAGICBITS);
2730            }
2731         }
[01b6ca9]2732
2733
2734
[96e62937]2735         XL_SEL_WIN(2);
2736         /* Clear the station mask. */
2737         for (i = 0; i < 3; i++)
2738            CSR_WRITE_2(sc, XL_W2_STATION_MASK_LO + (i * 2), 0);
[01b6ca9]2739
[96e62937]2740         /*
2741          * Set the TX freethresh value.
2742          * Note that this has no effect on 3c905B "cyclone"
2743          * cards but is required for 3c900/3c905 "boomerang"
2744          * cards in order to enable the download engine.
2745          */
2746         CSR_WRITE_1(sc, XL_TX_FREETHRESH, XL_PACKET_SIZE >> 8);
[01b6ca9]2747
[96e62937]2748         /* Set the TX start threshold for best performance. */
2749         sc->xl_tx_thresh = XL_MIN_FRAMELEN;
2750         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_SET_START|sc->xl_tx_thresh);
[01b6ca9]2751
[96e62937]2752         /*
2753          * If this is a 3c905B, also set the tx reclaim threshold.
2754          * This helps cut down on the number of tx reclaim errors
2755          * that could happen on a busy network. The chip multiplies
2756          * the register value by 16 to obtain the actual threshold
2757          * in bytes, so we divide by 16 when setting the value here.
2758          * The existing threshold value can be examined by reading
2759          * the register at offset 9 in window 5.
2760          */
2761         if (sc->xl_type == XL_TYPE_905B) {
2762            CSR_WRITE_2(sc, XL_COMMAND,
2763                        XL_CMD_SET_TX_RECLAIM|(XL_PACKET_SIZE >> 4));
2764         }
[01b6ca9]2765
[96e62937]2766         /* Set RX filter bits. */
2767         XL_SEL_WIN(5);
2768         rxfilt = CSR_READ_1(sc, XL_W5_RX_FILTER);
[01b6ca9]2769
[96e62937]2770         /* Set the individual bit to receive frames for this host only. */
2771         rxfilt |= XL_RXFILTER_INDIVIDUAL;
[01b6ca9]2772
[96e62937]2773         /* If we want promiscuous mode, set the allframes bit. */
2774         if (ifp->if_flags & IFF_PROMISC) {
2775            rxfilt |= XL_RXFILTER_ALLFRAMES;
2776            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2777         } else {
2778            rxfilt &= ~XL_RXFILTER_ALLFRAMES;
2779            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2780         }
[01b6ca9]2781
[96e62937]2782         /*
2783          * Set capture broadcast bit to capture broadcast frames.
2784          */
2785         if (ifp->if_flags & IFF_BROADCAST) {
2786            rxfilt |= XL_RXFILTER_BROADCAST;
2787            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2788         } else {
2789            rxfilt &= ~XL_RXFILTER_BROADCAST;
2790            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_FILT|rxfilt);
2791         }
[01b6ca9]2792
[96e62937]2793#if 0
2794         /*
2795          * Program the multicast filter, if necessary.
2796          */
2797         if (sc->xl_type == XL_TYPE_905B)
2798            xl_setmulti_hash(sc);
2799         else
2800            xl_setmulti(sc);
2801#endif
2802         /*
2803          * Load the address of the RX list. We have to
2804          * stall the upload engine before we can manipulate
2805          * the uplist pointer register, then unstall it when
2806          * we're finished. We also have to wait for the
2807          * stall command to complete before proceeding.
2808          * Note that we have to do this after any RX resets
2809          * have completed since the uplist register is cleared
2810          * by a reset.
2811          */
2812         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_STALL);
2813         xl_wait(sc);
2814         CSR_WRITE_4(sc, XL_UPLIST_PTR, phys_to_bus( sc->curr_rx_md ));
2815         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_UP_UNSTALL);
2816         xl_wait(sc);
[01b6ca9]2817
2818
2819#if 0
[96e62937]2820         if (sc->xl_type == XL_TYPE_905B) {
2821            /* Set polling interval */
2822            CSR_WRITE_1(sc, XL_DOWN_POLL, 64);
2823            xl_wait(sc);
2824            printk("etherlink : unit elnk%d tx polling enabled\n", sc->xl_unit );
2825         }
2826#endif
[01b6ca9]2827
[96e62937]2828         /*
2829          * If the coax transceiver is on, make sure to enable
2830          * the DC-DC converter.
2831          */
[01b6ca9]2832         XL_SEL_WIN(3);
[96e62937]2833         if (sc->xl_xcvr == XL_XCVR_COAX)
2834            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_START);
2835         else
2836            CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_COAX_STOP);
[01b6ca9]2837
[96e62937]2838         /* increase packet size to allow reception of 802.1q or ISL packets */
[a3d3d9a]2839         if (sc->xl_type == XL_TYPE_905B)
[96e62937]2840            CSR_WRITE_2(sc, XL_W3_MAXPKTSIZE, XL_PACKET_SIZE);
2841         /* Clear out the stats counters. */
[01b6ca9]2842
[96e62937]2843         memset( &sc->xl_stats, 0, sizeof(struct xl_stats));
[01b6ca9]2844
[96e62937]2845         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_DISABLE);
2846         sc->xl_stats_no_timeout = 1;
2847         xl_stats_update(sc->stat_timer_id,sc);
2848         sc->xl_stats_no_timeout = 0;
2849         XL_SEL_WIN(4);
2850         CSR_WRITE_2(sc, XL_W4_NET_DIAG, XL_NETDIAG_UPPER_BYTES_ENABLE);
2851         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STATS_ENABLE);
[01b6ca9]2852
2853
[96e62937]2854         /*
2855          * Enable interrupts.
2856          */
2857         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ACK|0xFF);
2858         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_STAT_ENB|XL_INTRS);
2859         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_INTR_ENB|XL_INTRS);
2860
2861         /* Set the RX early threshold */
2862         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_SET_THRESH|(XL_PACKET_SIZE >>2));
2863         CSR_WRITE_4(sc, XL_DMACTL, XL_DMACTL_UP_RX_EARLY );
2864
2865         /* Enable receiver and transmitter. */
2866         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_TX_ENABLE);
2867         xl_wait(sc);
2868         CSR_WRITE_2(sc, XL_COMMAND, XL_CMD_RX_ENABLE);
2869         xl_wait(sc);
2870
2871         /* Select window 7 for normal operations. */
2872         XL_SEL_WIN(7);
2873
2874         /* schedule the stats update timer */
2875         rtems_timer_fire_after( sc->stat_timer_id, sc->stats_update_ticks, xl_stats_update, (void *)sc );
2876      }
2877
2878      /*
2879       * Tell the world that we're running.
2880       */
2881      ifp->if_flags |= IFF_RUNNING;
2882   }
[01b6ca9]2883}
2884
2885
2886
2887
2888
2889
2890
2891/*
2892 * Stop the device
2893 */
2894static void
2895elnk_stop (struct elnk_softc *sc)
2896{
2897   struct ifnet *ifp = &sc->arpcom.ac_if;
[96e62937]2898   int i;
[01b6ca9]2899
2900   /*
2901    * Stop the transmitter
2902    */
2903   xl_stop(sc);
[96e62937]2904   xl_reset(sc);
2905   sc->tx_idle = -1;
[01b6ca9]2906
2907   ifp->if_flags &= ~IFF_RUNNING;
[96e62937]2908
2909   /*
2910   ** Clear out the rx & tx rings
2911   */
2912   {
2913      struct TXMD *chainhead;
[41a1c334]2914      size_t esize;
[96e62937]2915
2916      while( rtems_message_queue_receive( chainRecoveryQueue, &chainhead, &esize,
2917                                          RTEMS_NO_WAIT, 0) == RTEMS_SUCCESSFUL );
2918   }
2919
2920   for(i=0 ; i<sc->numRxbuffers; i++)
2921   {
2922      st_le32( &sc->rx_ring[i].status, 0);
2923      st_le32( &sc->rx_ring[i].length, XL_LAST_FRAG | XL_PACKET_SIZE );
2924   }
2925
2926   for(i=0 ; i<sc->numTxbuffers; i++)
2927   {
2928      st_le32( &sc->tx_ring[i].status, XL_TXSTAT_DL_COMPLETE );
2929      st_le32( &sc->tx_ring[i].next, 0);
2930      if( sc->tx_ring[i].mbuf )
2931      {
2932         m_free( sc->tx_ring[i].mbuf );
2933         sc->tx_ring[i].mbuf = NULL;
2934      }
2935   }
[01b6ca9]2936}
2937
2938
2939
2940
2941/*
2942 * Show interface statistics
2943 */
2944static void
2945elnk_stats (struct elnk_softc *sc)
2946{
[a3d3d9a]2947   printf("    MII PHY data { anr:%04x  lpar:%04x  stat:%04x  ctl:%04x }\n",
2948          sc->xl_stats.miianr,
2949          sc->xl_stats.miipar,
[01b6ca9]2950          sc->xl_stats.miistatus,
2951          sc->xl_stats.miicmd);
2952
[a3d3d9a]2953   printf("         internalcfg:%08x            macctl:%04x      dmactl:%08x\n",
[96e62937]2954          sc->xl_stats.internalconfig,
2955          sc->xl_stats.mac_control,
2956          sc->xl_stats.dmactl);
[01b6ca9]2957
2958   printf("            rxstatus:%04x              txstatus:%02x       smbstat:%04x\n",
2959          sc->xl_stats.rxstatus,
2960          sc->xl_stats.txstatus,
2961          sc->xl_stats.smbstatus);
2962
[96e62937]2963   printf("              txfree:%04X             intstatus:%04x   mediastat:%04x\n",
2964          sc->xl_stats.txfree,
2965          sc->xl_stats.intstatus,
2966          sc->xl_stats.mediastatus);
2967
2968
2969   {
2970      int       i, totalLengths= 0, numLengths= 0;
2971
2972      for(i=0; i< NUM_CHAIN_LENGTHS; i++)
2973      {
2974         if( sc->chain_lengths[i] > -1 )
2975         {
2976            totalLengths += sc->chain_lengths[i];
2977            ++numLengths;
2978         }
2979      }
2980
[3584398a]2981      printf("          interrupts:%-9d       txcmp_ints:%-5d  avg_chain_len:%-4d\n",
[96e62937]2982             sc->xl_stats.device_interrupts,
[3584398a]2983             sc->xl_stats.txcomplete_ints,
[1402d56a]2984             numLengths ? (totalLengths / numLengths) : -1 );
[96e62937]2985   }
2986
[a3d3d9a]2987   printf("        carrier_lost:%-5d             sqe_errs:%-5d\n",
2988          sc->xl_stats.xl_carrier_lost,
[01b6ca9]2989          sc->xl_stats.xl_sqe_errs);
2990
[a3d3d9a]2991   printf("  tx_multi_collision:%-5d  tx_single_collision:%-5d\n",
2992          sc->xl_stats.xl_tx_multi_collision,
[01b6ca9]2993          sc->xl_stats.xl_tx_single_collision);
2994
[a3d3d9a]2995   printf("   tx_late_collision:%-5d           rx_overrun:%-5d\n",
2996          sc->xl_stats.xl_tx_late_collision,
[01b6ca9]2997          sc->xl_stats.xl_rx_overrun);
2998
[a3d3d9a]2999   printf("         tx_deferred:%-5d               badssd:%-5d\n",
3000          sc->xl_stats.xl_tx_deferred,
[01b6ca9]3001          sc->xl_stats.xl_badssd);
3002
[a3d3d9a]3003   printf("        rx_frames_ok:%-9d     tx_frames_ok:%-9d\n",
[96e62937]3004          sc->xl_stats.xl_rx_frames_ok,
3005          sc->xl_stats.xl_tx_frames_ok);
[01b6ca9]3006
[a3d3d9a]3007   printf("         rx_bytes_ok:%-9d      tx_bytes_ok:%-9d\n",
[96e62937]3008          sc->xl_stats.xl_rx_bytes_ok,
3009          sc->xl_stats.xl_tx_bytes_ok );
[01b6ca9]3010}
3011
3012
3013
3014
3015
3016
3017
3018/*
3019 * Driver ioctl handler
3020 */
3021static int
[bd5a6589]3022elnk_ioctl (struct ifnet *ifp, ioctl_command_t command, caddr_t data)
[01b6ca9]3023{
3024   struct elnk_softc *sc = ifp->if_softc;
3025   int error = 0;
3026
3027   switch (command) {
3028      case SIOCGIFADDR:
3029      case SIOCSIFADDR:
3030         ether_ioctl (ifp, command, data);
3031         break;
3032
3033      case SIOCSIFFLAGS:
3034         switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) {
3035            case IFF_RUNNING:
3036               elnk_stop (sc);
3037               break;
3038
3039            case IFF_UP:
3040               elnk_init (sc);
3041               break;
3042
3043            case IFF_UP | IFF_RUNNING:
3044               elnk_stop (sc);
3045               elnk_init (sc);
3046               break;
3047
3048            default:
3049               break;
3050         }
3051         break;
3052
3053      case SIO_RTEMS_SHOW_STATS:
3054         elnk_stats (sc);
3055         break;
[a3d3d9a]3056
[01b6ca9]3057         /*
3058          * FIXME: All sorts of multicast commands need to be added here!
3059          */
3060      default:
3061         error = EINVAL;
3062         break;
3063   }
3064
3065   return error;
3066}
3067
3068
3069
3070
3071
3072
3073
3074
3075#if 0
3076static int iftap(struct ifnet *ifp, struct ether_header *eh, struct mbuf *m )
3077{
3078   int i;
3079   char *delim, *pkt;
3080
3081   printk("unit %i, src ", ifp->if_unit );
[a3d3d9a]3082   for(delim= "", i=0; i< ETHER_ADDR_LEN; i++, delim=":")
[01b6ca9]3083      printk("%s%02x", delim, (char) eh->ether_shost[i] );
3084
3085   printk(" dest ");
3086
[a3d3d9a]3087   for(delim= "", i=0; i< ETHER_ADDR_LEN; i++, delim=":")
[01b6ca9]3088      printk("%s%02x", delim, (char) eh->ether_dhost[i] );
3089   printk("  pkt ");
3090
3091   pkt = (char *)eh;
3092   for(delim="", i=0; i < sizeof(struct ether_header); i++, delim=":")
3093      printk("%s%02x", delim, (char) pkt[i] );
3094
[a3d3d9a]3095   printk("\n");
[01b6ca9]3096   return 0;
3097}
3098#endif
3099
3100
3101
3102struct el_boards
3103{
3104      int pbus,pdev,pfun, vid, did, tindex;
3105};
3106
3107/*
3108 * Attach an ELNK driver to the system
3109 */
3110int
3111rtems_elnk_driver_attach (struct rtems_bsdnet_ifconfig *config, int attach)
3112{
3113   struct elnk_softc *sc;
3114   struct ifnet *ifp;
3115   char         *unitName;
3116   int          unitNumber;
3117   int          mtu, i;
3118   unsigned char cvalue;
3119   struct el_boards         sysboards[NUM_UNITS];
3120   int                      numFound = 0;
[3584398a]3121   int          pbus, pdev, pfun;
3122#if defined(__i386__)
[6542918f]3123   uint32_t     value;
3124   uint8_t      interrupt;
[3584398a]3125#endif
3126#if defined(__PPC__)
[71cfbb8f]3127   uint32_t     lvalue;
[3584398a]3128#endif
[01b6ca9]3129
3130
3131   /*
3132    * Get the instance number for the board we're going to configure
3133    * from the user.
3134    */
3135   if( (unitNumber = rtems_bsdnet_parse_driver_name( config, &unitName)) == -1 )
3136   {
3137      return 0;
3138   }
3139
3140   if( strcmp(unitName, DRIVER_PREFIX) )
3141   {
3142      printk("etherlink : invalid unit name '%s'\n", unitName );
3143      return 0;
3144   }
3145
3146   if ((unitNumber < 1) || (unitNumber > NUM_UNITS))
3147   {
3148      printk("etherlink : unit %i is invalid, must be (1 <= n <= %d)\n", unitNumber, NUM_UNITS);
3149      return 0;
3150   }
3151
3152
3153   {
3154      int  done= 0, unum;
3155
3156      /*
3157       * Run thru the list of boards, finding all that are present in
3158       * the system.  Sort by slot,dev - and then use the unitNumber-1
3159       * to index the list and select the device.  Yucky.
3160       */
3161      for( i=0; !done && xl_devs[i].xl_vid; i++)
3162      {
[bb9e843]3163         for(unum= 1; !done &&
3164                pci_find_device( xl_devs[i].xl_vid, xl_devs[i].xl_did, unum-1,
[a3d3d9a]3165                                         &sysboards[numFound].pbus,
3166                                         &sysboards[numFound].pdev,
[3584398a]3167                                                  &sysboards[numFound].pfun)==0; unum++)
[01b6ca9]3168         {
3169            if( numFound == NUM_UNITS )
3170            {
3171               printk("etherlink : Maximum of %d units found, extra devices ignored.\n", NUM_UNITS );
3172               done=-1;
3173            }
3174            else
3175            {
3176               sysboards[numFound].vid = xl_devs[i].xl_vid;
3177               sysboards[numFound].did = xl_devs[i].xl_did;
3178               sysboards[numFound].tindex = i;
3179               ++numFound;
3180            }
3181         }
3182      }
3183
3184      if( ! numFound )
3185      {
3186         printk("etherlink : No Etherlink devices found\n");
3187         return 0;
3188      }
3189
3190      if( unitNumber-1 >= numFound )
3191      {
3192         printk("etherlink : device '%s' not found\n", config->name );
3193         return 0;
3194      }
3195
3196      /*
3197      * Got the list of etherlink boards in the system, now sort by
3198      * slot,device.  bubble sorts aren't all that wonderful, but this
3199      * is a short & infrequently sorted list.
3200      */
3201      if( numFound > 1 )
3202      {
3203         struct el_boards       tboard;
3204         int                    didsort;
3205
3206         do
3207         {
3208            didsort = 0;
3209
3210            for(i=1; i<numFound; i++)
3211            {
3212               if( sysboards[i-1].pbus > sysboards[i].pbus ||
3213                   (sysboards[i-1].pbus == sysboards[i].pbus && sysboards[i-1].pdev > sysboards[i].pdev) )
3214               {
3215                  memcpy(&tboard, &sysboards[i-1], sizeof(struct el_boards));
3216                  memcpy(&sysboards[i-1], &sysboards[i], sizeof(struct el_boards));
3217                  memcpy(&sysboards[i], &tboard, sizeof(struct el_boards));
3218                  didsort++;
3219               }
3220            }
3221         }
3222         while( didsort );
3223      }
3224
3225      /*
3226      ** board list is sorted, now select the unit
3227      */
3228
3229      pbus = sysboards[unitNumber-1].pbus;
3230      pdev = sysboards[unitNumber-1].pdev;
3231      pfun = sysboards[unitNumber-1].pfun;
3232   }
3233
3234   sc = &elnk_softc[unitNumber - 1];
3235   ifp = &sc->arpcom.ac_if;
[a3d3d9a]3236   if (ifp->if_softc != NULL)
[01b6ca9]3237   {
3238      printk("etherlink : unit %i already in use.\n", unitNumber );
3239      return 0;
3240   }
3241
3242   /*
3243   ** Save various things
3244   */
3245   sc->xl_unit = unitNumber;
3246   sc->xl_type = sysboards[ unitNumber-1 ].tindex;
3247
3248   sc->vendorID = sysboards[numFound].vid;
3249   sc->deviceID = sysboards[numFound].did;
3250
3251   sc->numRxbuffers = (config->rbuf_count) ? config->rbuf_count : RX_RING_SIZE;
3252   sc->numTxbuffers = (config->xbuf_count) ? config->xbuf_count : TX_RING_SIZE;
3253
[96e62937]3254
3255   for(i=0; i< NUM_CHAIN_LENGTHS; i++) sc->chain_lengths[i]= -1;
3256   sc->chlenIndex = 0;
3257
3258
[01b6ca9]3259   if (config->mtu)
3260      mtu = config->mtu;
3261   else
3262      mtu = ETHERMTU;
3263
3264   sc->acceptBroadcast = !config->ignore_broadcast;
3265
3266
3267
3268#ifdef ELNK_DEBUG
[a3d3d9a]3269   printk("etherlink : device '%s', name 'elnk%d', pci %02x:%02x.%02x, %d rx/%d tx buffers\n",
3270          xl_devs[sc->xl_type].xl_name, sc->xl_unit,
3271          pbus, pdev, pfun,
[01b6ca9]3272          sc->numRxbuffers, sc->numTxbuffers);
3273#endif
3274
3275
3276   /*
3277   ** Create this unit's stats timer
3278   */
3279   if( rtems_timer_create( rtems_build_name( 'X', 'L', 't', (char)(sc->xl_unit & 255)),
3280                           &sc->stat_timer_id ) != RTEMS_SUCCESSFUL )
3281   {
3282      printk("etherlink : unit elnk%d unable to create stats timer\n", sc->xl_unit );
3283      return 0;
3284   }
3285
3286   /* update stats 1 times/second if things aren't incrementing fast
3287    * enough to trigger stats interrupts
3288    */
3289   rtems_clock_get( RTEMS_CLOCK_GET_TICKS_PER_SECOND, &sc->stats_update_ticks );
3290
3291
3292   /*
3293   ** Get this unit's rx/tx event
3294   */
3295   sc->ioevent = unit_signals[unitNumber-1];
3296
3297
[3584398a]3298#if defined(__i386__)
[a8e1959]3299   pci_read_config_dword(pbus, pdev, pfun, 16, &value);
[3584398a]3300   sc->ioaddr = value & ~IO_MASK;
3301
[a8e1959]3302   pci_read_config_byte(pbus, pdev, pfun, 60, &interrupt);
[3584398a]3303   cvalue = interrupt;
3304#endif
3305#if defined(__PPC__)
[01b6ca9]3306   /*
3307   ** Prep the board
3308   */
3309   pci_write_config_word(pbus, pdev, pfun,
3310                         PCI_COMMAND,
[a3d3d9a]3311                         (uint16_t)( PCI_COMMAND_IO |
3312                                       PCI_COMMAND_MASTER |
3313                                       PCI_COMMAND_INVALIDATE |
[96e62937]3314                                       PCI_COMMAND_WAIT ) );
[01b6ca9]3315   /*
[3584398a]3316    * Get the device's base address
[01b6ca9]3317    */
3318   pci_read_config_dword(pbus, pdev, pfun,
3319                         PCI_BASE_ADDRESS_0,
3320                         &lvalue);
3321
[509fec9c]3322   sc->ioaddr = (uint32_t)lvalue & PCI_BASE_ADDRESS_IO_MASK;
[01b6ca9]3323   /*
3324   ** Store the interrupt name, we'll use it later when we initialize
3325   ** the board.
3326   */
3327   pci_read_config_byte(pbus, pdev, pfun,
3328                        PCI_INTERRUPT_LINE,
3329                        &cvalue);
[a3d3d9a]3330#endif
[01b6ca9]3331
3332   memset(&sc->irqInfo,0,sizeof(rtems_irq_connect_data));
3333   sc->irqInfo.name = cvalue;
3334
3335
3336   /*
3337   ** Establish basic board config, set node address from config or
3338   ** board eeprom, do stuff with additional device properties
3339   */
3340
3341   {
[ee4f57d]3342      uint8_t   pci_latency;
3343      uint8_t   new_latency = 248;
[01b6ca9]3344
3345      /* Check the PCI latency value.  On the 3c590 series the latency timer
3346         must be set to the maximum value to avoid data corruption that occurs
3347         when the timer expires during a transfer.  This bug exists the Vortex
3348         chip only. */
[3584398a]3349#if defined(__i386__)
[a8e1959]3350      pci_read_config_byte(pbus, pdev, pfun, 0x0d, &pci_latency);
[3584398a]3351#endif
3352#if defined(__PPC__)
[01b6ca9]3353      pci_read_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, &pci_latency);
[3584398a]3354#endif
[a3d3d9a]3355      if (pci_latency < new_latency)
[01b6ca9]3356      {
3357         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 );
[3584398a]3358#if defined(__i386__)
[a8e1959]3359         pci_write_config_byte(pbus, pdev, pfun, 0x0d, new_latency);
[3584398a]3360#endif
3361#if defined(__PPC__)
[01b6ca9]3362         pci_write_config_byte(pbus,pdev,pfun, PCI_LATENCY_TIMER, new_latency);
[3584398a]3363#endif
[01b6ca9]3364      }
3365   }
3366
3367   /* Reset the adapter. */
3368   xl_reset(sc);
3369
3370
3371   {
3372      u_int16_t         xcvr[2];
3373      u_char            eaddr[ETHER_ADDR_LEN];
3374
3375      sc->xl_flags = 0;
3376      if (sc->deviceID == TC_DEVICEID_HURRICANE_555)
3377         sc->xl_flags |= XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_PHYOK;
3378      if (sc->deviceID == TC_DEVICEID_HURRICANE_556 ||
3379          sc->deviceID == TC_DEVICEID_HURRICANE_556B)
3380         sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
3381            XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_WEIRDRESET |
3382            XL_FLAG_INVERT_LED_PWR | XL_FLAG_INVERT_MII_PWR;
3383      if (sc->deviceID == TC_DEVICEID_HURRICANE_555 ||
3384          sc->deviceID == TC_DEVICEID_HURRICANE_556)
3385         sc->xl_flags |= XL_FLAG_8BITROM;
3386      if (sc->deviceID == TC_DEVICEID_HURRICANE_556B)
3387         sc->xl_flags |= XL_FLAG_NO_XCVR_PWR;
3388
3389      if (sc->deviceID == TC_DEVICEID_HURRICANE_575A ||
3390          sc->deviceID == TC_DEVICEID_HURRICANE_575B ||
3391          sc->deviceID == TC_DEVICEID_HURRICANE_575C ||
3392          sc->deviceID == TC_DEVICEID_HURRICANE_656B ||
3393          sc->deviceID == TC_DEVICEID_TORNADO_656C)
3394         sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK |
3395            XL_FLAG_EEPROM_OFFSET_30 | XL_FLAG_8BITROM;
3396      if (sc->deviceID == TC_DEVICEID_HURRICANE_656)
3397         sc->xl_flags |= XL_FLAG_FUNCREG | XL_FLAG_PHYOK;
3398      if (sc->deviceID == TC_DEVICEID_HURRICANE_575B)
3399         sc->xl_flags |= XL_FLAG_INVERT_LED_PWR;
3400      if (sc->deviceID == TC_DEVICEID_HURRICANE_575C)
3401         sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
3402      if (sc->deviceID == TC_DEVICEID_TORNADO_656C)
3403         sc->xl_flags |= XL_FLAG_INVERT_MII_PWR;
3404      if (sc->deviceID == TC_DEVICEID_HURRICANE_656 ||
3405          sc->deviceID == TC_DEVICEID_HURRICANE_656B)
3406         sc->xl_flags |= XL_FLAG_INVERT_MII_PWR |
3407            XL_FLAG_INVERT_LED_PWR;
3408      if (sc->deviceID == TC_DEVICEID_TORNADO_10_100BT_920B)
3409         sc->xl_flags |= XL_FLAG_PHYOK;
3410
[a3d3d9a]3411
3412      if (config->hardware_address)
[01b6ca9]3413      {
3414         memcpy(sc->arpcom.ac_enaddr, config->hardware_address, ETHER_ADDR_LEN);
3415      }
3416      else
3417      {
3418         if (xl_read_eeprom(sc, (caddr_t)&eaddr, XL_EE_OEM_ADR0, 3, 1))
3419         {
3420            printk("etherlink : unit elnk%d Failed to read station address\n", sc->xl_unit );
3421            return 0;
3422         }
[a3d3d9a]3423         memcpy((char *)&sc->arpcom.ac_enaddr, eaddr, ETHER_ADDR_LEN);
[01b6ca9]3424      }
3425
3426      /*
3427       * Figure out the card type. 3c905B adapters have the
3428       * 'supportsNoTxLength' bit set in the capabilities
3429       * word in the EEPROM.
3430       */
3431      xl_read_eeprom(sc, (caddr_t)&sc->xl_caps, XL_EE_CAPS, 1, 0);
3432      if (sc->xl_caps & XL_CAPS_NO_TXLENGTH)
3433         sc->xl_type = XL_TYPE_905B;
3434      else
3435         sc->xl_type = XL_TYPE_90X;
3436
3437
3438      /*
3439       * Now we have to see what sort of media we have.
3440       * This includes probing for an MII interace and a
3441       * possible PHY.
3442       */
3443      XL_SEL_WIN(3);
3444      sc->xl_media = CSR_READ_2(sc, XL_W3_MEDIA_OPT);
3445
3446      xl_read_eeprom(sc, (char *)&xcvr, XL_EE_ICFG_0, 2, 0);
3447      sc->xl_xcvr = xcvr[0] | xcvr[1] << 16;
3448      sc->xl_xcvr &= XL_ICFG_CONNECTOR_MASK;
3449      sc->xl_xcvr >>= XL_ICFG_CONNECTOR_BITS;
3450
3451#if 0
3452      printk("etherlink : unit elnk%d EEPROM set xcvr to 0x%x\n", sc->xl_unit, sc->xl_xcvr);
3453#endif
3454
3455      {
3456         char   msg[255];
3457         int    i;
3458
3459         struct _availmedia
3460         {
3461               int bit;
3462               char *name;
3463         } _am[]= {{ XL_MEDIAOPT_BT4, "100BaseT4" },
3464                   { XL_MEDIAOPT_BTX, "100BaseTX" },
3465                   { XL_MEDIAOPT_BFX, "100BaseFX" },
3466                   { XL_MEDIAOPT_BT,  "10BaseT" },
3467                   { XL_MEDIAOPT_BNC, "10Base2" },
3468                   { XL_MEDIAOPT_AUI, "10mbps AUI"},
3469                   { XL_MEDIAOPT_MII, "MII"},
3470                   { 0, NULL }};
3471
3472         msg[0]= 0;
3473         for( i=0; _am[i].bit; i++)
3474         {
3475            if( sc->xl_media & _am[i].bit )
3476               sprintf( &msg[strlen(msg)], ",%s", _am[i].name );
3477         }
3478         if( !strlen(msg) ) strcpy( &msg[1], "<no media bits>");
3479
3480         printk("etherlink : unit elnk%d available media : %s\n", sc->xl_unit, &msg[1]);
3481      }
[a3d3d9a]3482
[01b6ca9]3483      XL_SEL_WIN(7);
3484   }
3485
3486
3487
3488   /*
3489    * Set up network interface
3490    */
3491   ifp->if_softc = sc;
3492   ifp->if_name = unitName;
3493   ifp->if_unit = sc->xl_unit;
3494   ifp->if_mtu = mtu;
3495   ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX;
3496   if (ifp->if_snd.ifq_maxlen == 0)
3497      ifp->if_snd.ifq_maxlen = ifqmaxlen;
3498   ifp->if_init = elnk_init;
3499   ifp->if_start = elnk_start;
3500   ifp->if_ioctl = elnk_ioctl;
3501   ifp->if_output = ether_output;
3502
3503#if 0
3504   ifp->if_tap = iftap;
3505#endif
3506
3507   /*
3508    * Attach the interface
3509    */
3510   if_attach (ifp);
3511   ether_ifattach (ifp);
3512
3513#ifdef ELNK_DEBUG
3514   printk( "etherlink : unit elnk%d driver attached\n", sc->xl_unit );
3515#endif
3516
3517   /*
3518    * Start driver tasks if this is the first unit initialized
3519    */
[a3d3d9a]3520   if (txDaemonTid == 0)
[01b6ca9]3521   {
[96e62937]3522      if( rtems_message_queue_create( rtems_build_name('X','L','c','r'),
3523                                      sc->numTxbuffers+1,
3524                                      sizeof(struct TXMD *),
3525                                      RTEMS_FIFO | RTEMS_LOCAL,
3526                                      &chainRecoveryQueue ) != RTEMS_SUCCESSFUL )
3527      {
3528         rtems_panic( "etherlink : Unable to create TX buffer recovery queue\n" );
3529      }
[a3d3d9a]3530
[96e62937]3531
[01b6ca9]3532      rxDaemonTid = rtems_bsdnet_newproc( "XLrx", 4096,
3533                                          elnk_rxDaemon, NULL);
[a3d3d9a]3534
[01b6ca9]3535      txDaemonTid = rtems_bsdnet_newproc( "XLtx", 4096,
3536                                          elnk_txDaemon, NULL);
3537#ifdef ELNK_DEBUG
3538      printk( "etherlink : driver tasks created\n" );
3539#endif
3540   }
3541
3542   return 1;
3543};
3544
3545#endif /* ELNK_SUPPORTED */
3546
3547/* eof */
Note: See TracBrowser for help on using the repository browser.