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

4.104.114.84.95
Last change on this file since ee4f57d was ee4f57d, checked in by Ralf Corsepius <ralf.corsepius@…>, on 03/23/04 at 09:59:52

2004-03-23 Ralf Corsepius <ralf_corsepius@…>

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