if_snreg.h revision 54773
150276Speter/*
276726Speter * Copyright (c) 1996 Gardner Buchanan <gbuchanan@shl.com>
350276Speter * All rights reserved.
450276Speter *
550276Speter * Redistribution and use in source and binary forms, with or without
650276Speter * modification, are permitted provided that the following conditions
750276Speter * are met:
850276Speter * 1. Redistributions of source code must retain the above copyright
950276Speter *    notice, this list of conditions and the following disclaimer.
1050276Speter * 2. Redistributions in binary form must reproduce the above copyright
1150276Speter *    notice, this list of conditions and the following disclaimer in the
1250276Speter *    documentation and/or other materials provided with the distribution.
1350276Speter * 3. All advertising materials mentioning features or use of this software
1450276Speter *    must display the following acknowledgement:
1550276Speter *      This product includes software developed by Gardner Buchanan.
1650276Speter * 4. The name of Gardner Buchanan may not be used to endorse or promote
1750276Speter *    products derived from this software without specific prior written
1850276Speter *    permission.
1950276Speter *
2050276Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
2150276Speter * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2250276Speter * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2350276Speter * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2450276Speter * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2550276Speter * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2650276Speter * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2750276Speter * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2850276Speter * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2950276Speter * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3050276Speter *
3150276Speter *   $FreeBSD: head/sys/dev/sn/if_snreg.h 54773 1999-12-18 06:11:22Z imp $
3250276Speter */
3350276Speter
3450276Speter/*
3550276Speter * This file contains register information and access macros for
3650276Speter * the SMC91xxx chipset.
3750276Speter *
3850276Speter * Information contained in this file was obtained from the SMC91C92
3950276Speter * and SMC91C94 manuals from SMC.  You will need one of these in order
4076726Speter * to make any meaningful changes to this driver.  Information about
4150276Speter * obtaining one can be found at http://www.smc.com in the components
4250276Speter * division.
4350276Speter *
4450276Speter * This FreeBSD driver is derived in part from the smc9194 Linux driver
4550276Speter * by Erik Stahlman and is Copyright (C) 1996 by Erik Stahlman.
4650276Speter * It is also derived in part from the FreeBSD ep (3C509) driver which
4750276Speter * is Copyright (c) 1993 Herb Peyerl (hpeyerl@novatel.ca) All rights
4850276Speter * reserved.
4950276Speter *
5050276Speter */
5176726Speter#ifndef _IF_SNREG_H_
5276726Speter#define _IF_SNREG_H_
5350276Speter
5450276Speter#include <net/if_arp.h>
5550276Speter
5650276Speter/*
5750276Speter * Ethernet software status per interface.  The first element MUST
5850276Speter * be the arpcom struct since the address of the arpcom struct is
5950276Speter * used as a backdoor to obtain the address of this whole structure
6050276Speter * in many cases.
6150276Speter */
6250276Speterstruct sn_softc {
6350276Speter	struct arpcom   arpcom;	/* Ethernet common part */
6450276Speter	short           sn_io_addr;	/* i/o bus address (BASE) */
6550276Speter	int             pages_wanted;	/* Size of outstanding MMU ALLOC */
6650276Speter	int             intr_mask;	/* Most recently set interrupt mask */
6750276Speter#if	NCARD > 0
6850276Speter	int		gone;
6950276Speter#endif	/* NCARD > 0 */
7050276Speter};
7150276Speter
7250276Speter
7350276Speter/*
7450276Speter * Wait time for memory to be free.  This probably shouldn't be
7576726Speter * tuned that much, as waiting for this means nothing else happens
7676726Speter * in the system
7750276Speter */
7850276Speter#define	MEMORY_WAIT_TIME	1000
7950276Speter
8050276Speter
8150276Speter/* The SMC91xxx uses 16 I/O ports
8250276Speter */
83#define SMC_IO_EXTENT   16
84
85
86/*
87 * A description of the SMC registers is probably in order here,
88 * although for details, the SMC datasheet is invaluable.
89 * The data sheet I (GB) am using is "SMC91C92 Single Chip Ethernet
90 * Controller With RAM", Rev. 12/0/94.  Constant definitions I give
91 * here are loosely based on the mnemonic names given to them in the
92 * data sheet, but there are many exceptions.
93 *
94 * Basically, the chip has 4 banks of registers (0 to 3), which
95 * are accessed by writing a number into the BANK_SELECT register
96 * (I also use a SMC_SELECT_BANK macro for this).  Registers are
97 * either Byte or Word sized.  My constant definitions end in _B
98 * or _W as appropriate.
99 *
100 * The banks are arranged so that for most purposes, bank 2 is all
101 * that is needed for normal run time tasks.
102 */
103
104/*
105 * Bank Select Register.  This also doubles as
106 * a chip identification register.  This register
107 * is mapped at the same position in all banks.
108 */
109#define BANK_SELECT_REG_W       0x0e
110#define BSR_DETECT_MASK         0xff00
111#define BSR_DETECT_VALUE        0x3300
112
113
114/* BANK 0
115 */
116
117/* Transmit Control Register controls some aspects of the transmit
118 * behavior of the Ethernet Protocol Handler.
119 */
120#define TXMIT_CONTROL_REG_W  0x00
121
122#define TCR_ENABLE      0x0001	/* if this is 1, we can transmit */
123#define TCR_LOOP        0x0002	/* Enable internal analogue loopback */
124#define TCR_FORCOL      0x0004	/* Force Collision on next TX */
125#define TCR_PAD_ENABLE  0x0080	/* Pad short packets to 64 bytes */
126#define TCR_NOCRC       0x0100	/* Do not append CRC */
127#define TCR_MON_CSN     0x0400	/* monitors the carrier status */
128#define TCR_FDUPLX      0x0800	/* receive packets sent out */
129#define TCR_STP_SQET    0x1000	/* stop transmitting if Signal quality error */
130#define TCR_EPH_LOOP    0x2000	/* Enable internal digital loopback */
131
132
133/* Status of the last transmitted frame and instantaneous status of
134 * the Ethernet Protocol Handler jumbled together.  In auto-release
135 * mode this information is simply discarded after each TX.  This info
136 * is copied to the status word of in-memory packets after transmit
137 * where relevent statuses can be checked.
138 */
139#define EPH_STATUS_REG_W 0x02
140
141#define EPHSR_TX_SUC    0x0001	/* Transmit was successful */
142#define EPHSR_SNGLCOL   0x0002	/* Single collision occurred */
143#define EPHSR_MULCOL    0x0004	/* Multiple Collisions occurred */
144#define EPHSR_LTX_MULT  0x0008	/* Transmit was a multicast */
145#define EPHSR_16COL     0x0010	/* 16 Collisions occurred, TX disabled */
146#define EPHSR_SQET      0x0020	/* SQE Test failed, TX disabled */
147#define EPHSR_LTX_BRD   0x0040	/* Transmit was a broadcast */
148#define EPHSR_DEFR      0x0080	/* TX deferred due to carrier det. */
149#define EPHSR_LATCOL    0x0200	/* Late collision detected, TX disabled */
150#define EPHSR_LOST_CAR  0x0400	/* Lost carrier sense, TX disabled */
151#define EPHSR_EXC_DEF   0x0800	/* Excessive deferrals in TX >2 MAXETHER
152				 * times */
153#define EPHSR_CTR_ROL   0x1000	/* Some ECR Counter(s) rolled over */
154#define EPHSR_RX_OVRN   0x2000	/* Receiver overrun, packets dropped */
155#define EPHSR_LINK_OK   0x4000	/* Link integrity is OK */
156#define EPHSR_TXUNRN    0x8000	/* Transmit underrun */
157
158
159/* Receiver Control Register controls some aspects of the receive
160 * behavior of the Ethernet Protocol Handler.
161 */
162#define RECV_CONTROL_REG_W 0x04
163
164#define RCR_RX_ABORT    0x0001	/* Received huge packet */
165#define RCR_PROMISC     0x0002	/* enable promiscuous mode */
166#define RCR_ALMUL       0x0004	/* receive all multicast packets */
167#define RCR_ENABLE      0x0100	/* IFF this is set, we can recieve packets */
168#define RCR_STRIP_CRC   0x0200	/* strips CRC */
169#define RCR_GAIN_BITS   0x0c00	/* PLL Gain control (for testing) */
170#define RCR_FILT_CAR    0x4000	/* Enable 12 bit carrier filter */
171#define RCR_SOFTRESET   0x8000	/* Resets the EPH logic */
172
173
174/* TX Statistics counters
175 */
176#define COUNTER_REG_W   0x06
177
178#define ECR_COLN_MASK   0x000f	/* Vanilla collisions */
179#define ECR_MCOLN_MASK  0x00f0	/* Multiple collisions */
180#define ECR_DTX_MASK    0x0f00	/* Deferred transmits */
181#define ECR_EXDTX_MASK  0xf000	/* Excessively deferred transmits */
182
183/* Memory Information
184 */
185#define MEM_INFO_REG_W  0x08
186
187#define MIR_FREE_MASK   0xff00	/* Free memory pages available */
188#define MIR_TOTAL_MASK  0x00ff	/* Total memory pages available */
189
190/* Memory Configuration
191 */
192#define MEM_CFG_REG_W   0x0a
193
194#define MCR_TXRSV_MASK  0x001f	/* Count of pages reserved for transmit */
195
196
197/* Bank 0, Register 0x0c is unised in the SMC91C92
198 */
199
200
201/* BANK 1
202 */
203
204/* Adapter configuration
205 */
206#define CONFIG_REG_W    0x00
207
208#define CR_INT_SEL0     0x0002	/* Interrupt selector */
209#define CR_INT_SEL1     0x0004	/* Interrupt selector */
210#define CR_DIS_LINK     0x0040	/* Disable 10BaseT Link Test */
211#define CR_16BIT        0x0080	/* Bus width */
212#define CR_AUI_SELECT   0x0100	/* Use external (AUI) Transceiver */
213#define CR_SET_SQLCH    0x0200	/* Squelch level */
214#define CR_FULL_STEP    0x0400	/* AUI signalling mode */
215#define CR_NOW_WAIT_ST  0x1000	/* Disable bus wait states */
216
217/* The contents of this port are used by the adapter
218 * to decode its I/O address.  We use it as a varification
219 * that the adapter is detected properly when probing.
220 */
221#define BASE_ADDR_REG_W 0x02	/* The select IO Base addr. */
222
223/* These registers hold the Ethernet MAC address.
224 */
225#define IAR_ADDR0_REG_W 0x04	/* My Ethernet address */
226#define IAR_ADDR1_REG_W 0x06	/* My Ethernet address */
227#define IAR_ADDR2_REG_W 0x08	/* My Ethernet address */
228
229/* General purpose register used for talking to the EEPROM.
230 */
231#define GENERAL_REG_W   0x0a
232
233/* Control register used for talking to the EEPROM and
234 * setting some EPH functions.
235 */
236#define CONTROL_REG_W    0x0c
237#define CTR_STORE        0x0001	/* Store something to EEPROM */
238#define CTR_RELOAD       0x0002	/* Read EEPROM into registers */
239#define CTR_EEPROM_SEL   0x0004	/* Select registers for Reload/Store */
240#define CTR_TE_ENABLE    0x0020	/* Enable TX Error detection via EPH_INT */
241#define CTR_CR_ENABLE    0x0040	/* Enable Counter Rollover via EPH_INT */
242#define CTR_LE_ENABLE    0x0080	/* Enable Link Error detection via EPH_INT */
243#define CTR_AUTO_RELEASE 0x0800	/* Enable auto release mode for TX */
244#define CTR_POWERDOWN    0x2000	/* Enter powerdown mode */
245#define CTR_RCV_BAD      0x4000	/* Enable receipt of frames with bad CRC */
246
247
248/* BANK 2
249 */
250
251/* Memory Management Unit Control Register
252 * Controls allocation of memory to receive and
253 * transmit functions.
254 */
255#define MMU_CMD_REG_W   0x00
256#define MMUCR_BUSY      0x0001	/* MMU busy performing a release */
257
258/* MMU Commands:
259 */
260#define MMUCR_NOP       0x0000	/* Do nothing */
261#define MMUCR_ALLOC     0x0020	/* Or with number of 256 byte packets - 1 */
262#define MMUCR_RESET     0x0040	/* Reset MMU State */
263#define MMUCR_REMOVE    0x0060	/* Dequeue (but not free) current RX packet */
264#define MMUCR_RELEASE   0x0080	/* Dequeue and free the current RX packet */
265#define MMUCR_FREEPKT   0x00a0	/* Release packet in PNR register */
266#define MMUCR_ENQUEUE   0x00c0	/* Enqueue the packet for transmit */
267#define MMUCR_RESETTX   0x00e0	/* Reset transmit queues */
268
269/* Packet Number at TX Area
270 */
271#define PACKET_NUM_REG_B   0x02
272
273/* Packet number resulting from MMUCR_ALLOC
274 */
275#define ALLOC_RESULT_REG_B 0x03
276#define ARR_FAILED      0x80
277
278/* Transmit and receive queue heads
279 */
280#define FIFO_PORTS_REG_W 0x04
281#define FIFO_REMPTY     0x8000
282#define FIFO_TEMPTY     0x0080
283#define FIFO_RX_MASK    0x7f00
284#define FIFO_TX_MASK    0x007f
285
286/* The address within the packet for reading/writing.  The
287 * PTR_RCV bit is tricky.  When PTR_RCV==1, the packet number
288 * to be read is found in the FIFO_PORTS_REG_W, FIFO_RX_MASK.
289 * When PTR_RCV==0, the packet number to be written is found
290 * in the PACKET_NUM_REG_B.
291 */
292#define POINTER_REG_W   0x06
293#define PTR_READ        0x2000	/* Intended access mode */
294#define PTR_AUTOINC     0x4000	/* Do auto inc after read/write */
295#define PTR_RCV         0x8000	/* FIFO_RX is packet, otherwise PNR is packet */
296
297/* Data I/O register to be used in conjunction with
298 * The pointer register to read and write data from the
299 * card.  The same register can be used for byte and word
300 * ops.
301 */
302#define DATA_REG_W      0x08
303#define DATA_REG_B      0x08
304#define DATA_1_REG_B    0x08
305#define DATA_2_REG_B    0x0a
306
307/* Sense interrupt status (READ)
308 */
309#define INTR_STAT_REG_B 0x0c
310
311/* Acknowledge interrupt sources (WRITE)
312 */
313#define INTR_ACK_REG_B  0x0c
314
315/* Interrupt mask.  Bit set indicates interrupt allowed.
316 */
317#define INTR_MASK_REG_B 0x0d
318
319/* Interrupts
320 */
321#define IM_RCV_INT      0x01	/* A packet has been received */
322#define IM_TX_INT       0x02	/* Packet TX complete */
323#define IM_TX_EMPTY_INT 0x04	/* No packets left to TX  */
324#define IM_ALLOC_INT    0x08	/* Memory allocation completed */
325#define IM_RX_OVRN_INT  0x10	/* Receiver was overrun */
326#define IM_EPH_INT      0x20	/* Misc. EPH conditions (see CONTROL_REG_W) */
327#define IM_ERCV_INT     0x40	/* not on SMC9192 */
328
329/* BANK 3
330 */
331
332/* Multicast subscriptions.
333 * The multicast handling in the SMC90Cxx is quite complicated.  A table
334 * of multicast address subscriptions is provided and a clever way of
335 * speeding the search of that table by hashing is implemented in the
336 * hardware.  I have ignored this and simply subscribed to all multicasts
337 * and let the kernel deal with the results.
338 */
339#define MULTICAST1_REG_W 0x00
340#define MULTICAST2_REG_W 0x02
341#define MULTICAST3_REG_W 0x04
342#define MULTICAST4_REG_W 0x06
343
344/* These registers do not exist on SMC9192, or at least
345 * are not documented in the SMC91C92 data sheet.
346 * The REVISION_REG_W register does however seem to work.
347 */
348#define MGMT_REG_W      0x08
349#define REVISION_REG_W  0x0a	/* (hi: chip id low: rev #) */
350#define ERCV_REG_W      0x0c
351
352/* These are constants expected to be found in the
353 * chip id register.
354 */
355#define CHIP_9190       3
356#define CHIP_9194       4
357#define CHIP_9195       5
358#define CHIP_91100      7
359
360static const char *chip_ids[15] = {
361	NULL, NULL, NULL,
362	 /* 3 */ "SMC91C90/91C92",
363	 /* 4 */ "SMC91C94",
364	 /* 5 */ "SMC91C95",
365	NULL,
366	 /* 7 */ "SMC91C100",
367	NULL, NULL, NULL, NULL,
368	NULL, NULL, NULL
369};
370
371
372/* When packets are stuffed into the card or sucked out of the card
373 * they are set up more or less as follows:
374 *
375 * Addr msbyte   lsbyte
376 * 00   SSSSSSSS SSSSSSSS - STATUS-WORD 16 bit TX or RX status
377 * 02   RRRRR             - RESERVED (unused)
378 * 02        CCC CCCCCCCC - BYTE COUNT (RX: always even, TX: bit 0 ignored)
379 * 04   DDDDDDDD DDDDDDDD - DESTINATION ADDRESS
380 * 06   DDDDDDDD DDDDDDDD        (48 bit Ethernet MAC Address)
381 * 08   DDDDDDDD DDDDDDDD
382 * 0A   SSSSSSSS SSSSSSSS - SOURCE ADDRESS
383 * 0C   SSSSSSSS SSSSSSSS        (48 bit Ethernet MAC Address)
384 * 0E   SSSSSSSS SSSSSSSS
385 * 10   PPPPPPPP PPPPPPPP
386 * ..   PPPPPPPP PPPPPPPP
387 * C-2  CCCCCCCC          - CONTROL BYTE
388 * C-2           PPPPPPPP - Last data byte (If odd length)
389 *
390 * The STATUS_WORD is derived from the EPH_STATUS_REG_W register
391 * during transmit and is composed of another set of bits described
392 * below during receive.
393 */
394
395
396/* Receive status bits.  These values are found in the status word
397 * field of a received packet.  For receive packets I use the RS_ODDFRAME
398 * to detect whether a frame has an extra byte on it.  The CTLB_ODD
399 * bit of the control byte tells the same thing.
400 */
401#define RS_MULTICAST    0x0001	/* Packet is multicast */
402#define RS_HASH_MASK    0x007e	/* Mask of multicast hash value */
403#define RS_TOOSHORT     0x0400	/* Frame was a runt, <64 bytes */
404#define RS_TOOLONG      0x0800	/* Frame was giant, >1518 */
405#define RS_ODDFRAME     0x1000	/* Frame is odd lengthed */
406#define RS_BADCRC       0x2000	/* Frame had CRC error */
407#define RS_ALGNERR      0x8000	/* Frame had alignment error */
408#define RS_ERRORS       (RS_ALGNERR | RS_BADCRC | RS_TOOLONG | RS_TOOSHORT)
409
410#define RLEN_MASK       0x07ff	/* Significant length bits in RX length */
411
412/* The control byte has the following significant bits.
413 * For transmit, the CTLB_ODD bit specifies whether an extra byte
414 * is present in the frame.  Bit 0 of the byte count field is
415 * ignored.  I just pad every frame to even length and forget about
416 * it.
417 */
418#define CTLB_CRC        0x10	/* Add CRC for this packet (TX only) */
419#define CTLB_ODD        0x20	/* The packet length is ODD */
420
421
422/*
423 * I define some macros to make it easier to do somewhat common
424 * or slightly complicated, repeated tasks.
425 */
426
427/* The base I/O address.
428 */
429#define BASE    (sc->sn_io_addr)
430
431/* Select a register bank, 0 to 3
432 */
433#define SMC_SELECT_BANK(x)  { outw( BASE + BANK_SELECT_REG_W, (x) ); }
434
435/* Define a small delay for the reset
436 */
437#define SMC_DELAY() { inw( BASE + RECV_CONTROL_REG_W );\
438                      inw( BASE + RECV_CONTROL_REG_W );\
439                      inw( BASE + RECV_CONTROL_REG_W );  }
440
441/* Define flags
442 */
443
444#define SN_FLAGS_PCCARD		0x0001	/* PCMCIA (PC-card) */
445#define	SN_FLAGS_XJBT10		0x0002	/* Megahertz XJ-BT10 (PCMCIA) */
446
447#endif	/* _IF_SNREG_H_ */
448