source: rtems/c/src/libchip/network/elnk.c @ 9f55bfb

5
Last change on this file since 9f55bfb was 9f55bfb, checked in by Joel Sherrill <joel@…>, on 04/21/17 at 01:49:07

elnk.c: rtems_elnk_driver_attach() prototype added

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