1 |
27 |
unneback |
#ifndef _CYGONCE_ETH_CL_CS8900_H_
|
2 |
|
|
#define _CYGONCE_ETH_CL_CS8900_H_
|
3 |
|
|
//==========================================================================
|
4 |
|
|
//
|
5 |
|
|
// dev/cs8900.h
|
6 |
|
|
//
|
7 |
|
|
// Cirrus Logic CS8900 Ethernet chip
|
8 |
|
|
//
|
9 |
|
|
//==========================================================================
|
10 |
|
|
//####ECOSGPLCOPYRIGHTBEGIN####
|
11 |
|
|
// -------------------------------------------
|
12 |
|
|
// This file is part of eCos, the Embedded Configurable Operating System.
|
13 |
|
|
// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
|
14 |
|
|
//
|
15 |
|
|
// eCos is free software; you can redistribute it and/or modify it under
|
16 |
|
|
// the terms of the GNU General Public License as published by the Free
|
17 |
|
|
// Software Foundation; either version 2 or (at your option) any later version.
|
18 |
|
|
//
|
19 |
|
|
// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
|
20 |
|
|
// WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
21 |
|
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
22 |
|
|
// for more details.
|
23 |
|
|
//
|
24 |
|
|
// You should have received a copy of the GNU General Public License along
|
25 |
|
|
// with eCos; if not, write to the Free Software Foundation, Inc.,
|
26 |
|
|
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
|
27 |
|
|
//
|
28 |
|
|
// As a special exception, if other files instantiate templates or use macros
|
29 |
|
|
// or inline functions from this file, or you compile this file and link it
|
30 |
|
|
// with other works to produce a work based on this file, this file does not
|
31 |
|
|
// by itself cause the resulting work to be covered by the GNU General Public
|
32 |
|
|
// License. However the source code for this file must still be made available
|
33 |
|
|
// in accordance with section (3) of the GNU General Public License.
|
34 |
|
|
//
|
35 |
|
|
// This exception does not invalidate any other reasons why a work based on
|
36 |
|
|
// this file might be covered by the GNU General Public License.
|
37 |
|
|
//
|
38 |
|
|
// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
|
39 |
|
|
// at http://sources.redhat.com/ecos/ecos-license/
|
40 |
|
|
// -------------------------------------------
|
41 |
|
|
//####ECOSGPLCOPYRIGHTEND####
|
42 |
|
|
//####BSDCOPYRIGHTBEGIN####
|
43 |
|
|
//
|
44 |
|
|
// -------------------------------------------
|
45 |
|
|
//
|
46 |
|
|
// Portions of this software may have been derived from OpenBSD or other sources,
|
47 |
|
|
// and are covered by the appropriate copyright disclaimers included herein.
|
48 |
|
|
//
|
49 |
|
|
// -------------------------------------------
|
50 |
|
|
//
|
51 |
|
|
//####BSDCOPYRIGHTEND####
|
52 |
|
|
//==========================================================================
|
53 |
|
|
//#####DESCRIPTIONBEGIN####
|
54 |
|
|
//
|
55 |
|
|
// Author(s): gthomas
|
56 |
|
|
// Contributors: gthomas, jskov
|
57 |
|
|
// Date: 2001-11-07
|
58 |
|
|
// Purpose:
|
59 |
|
|
// Description:
|
60 |
|
|
//
|
61 |
|
|
//####DESCRIPTIONEND####
|
62 |
|
|
//
|
63 |
|
|
//==========================================================================
|
64 |
|
|
|
65 |
|
|
#include <cyg/infra/cyg_type.h>
|
66 |
|
|
|
67 |
|
|
#include <cyg/hal/hal_io.h>
|
68 |
|
|
#include <pkgconf/devs_eth_cl_cs8900a.h>
|
69 |
|
|
|
70 |
|
|
#define __WANT_CONFIG
|
71 |
|
|
#include CYGDAT_DEVS_ETH_CL_CS8900A_INL
|
72 |
|
|
#undef __WANT_CONFIG
|
73 |
|
|
|
74 |
|
|
// ------------------------------------------------------------------------
|
75 |
|
|
// Debugging details
|
76 |
|
|
|
77 |
|
|
// Set to perms of:
|
78 |
|
|
// 0 disables all debug output
|
79 |
|
|
// 1 for process debug output
|
80 |
|
|
// 2 for added data IO output: get_reg, put_reg
|
81 |
|
|
// 4 for packet allocation/free output
|
82 |
|
|
// 8 for only startup status, so we can tell we're installed OK
|
83 |
|
|
#define DEBUG 0x0
|
84 |
|
|
|
85 |
|
|
#if DEBUG & 1
|
86 |
|
|
#define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
|
87 |
|
|
#define DEBUG_LINE() do { diag_printf("%d\n", __LINE__); } while (0)
|
88 |
|
|
#else
|
89 |
|
|
#define DEBUG_FUNCTION() do {} while(0)
|
90 |
|
|
#define DEBUG_LINE() do {} while(0)
|
91 |
|
|
#endif
|
92 |
|
|
|
93 |
|
|
// ------------------------------------------------------------------------
|
94 |
|
|
// Macros for keeping track of statistics
|
95 |
|
|
#if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
|
96 |
|
|
#define KEEP_STATISTICS
|
97 |
|
|
#endif
|
98 |
|
|
|
99 |
|
|
#ifdef KEEP_STATISTICS
|
100 |
|
|
#define INCR_STAT( _x_ ) (cpd->stats. _x_ ++)
|
101 |
|
|
#else
|
102 |
|
|
#define INCR_STAT( _x_ ) CYG_EMPTY_STATEMENT
|
103 |
|
|
#endif
|
104 |
|
|
|
105 |
|
|
// ------------------------------------------------------------------------
|
106 |
|
|
// Private driver structure
|
107 |
|
|
struct cs8900a_priv_data;
|
108 |
|
|
typedef cyg_bool (*provide_esa_t)(struct cs8900a_priv_data* cpd);
|
109 |
|
|
|
110 |
|
|
typedef struct cs8900a_priv_data {
|
111 |
|
|
bool txbusy, hardwired_esa;
|
112 |
|
|
int rxmode;
|
113 |
|
|
cyg_uint8 esa[6];
|
114 |
|
|
provide_esa_t provide_esa;
|
115 |
|
|
cyg_vector_t interrupt; // Interrupt vector used by controller
|
116 |
|
|
cyg_handle_t interrupt_handle;
|
117 |
|
|
cyg_interrupt interrupt_object;
|
118 |
|
|
cyg_addrword_t base;
|
119 |
|
|
cyg_uint32 txkey; // Used to ack when packet sent
|
120 |
|
|
struct cyg_netdevtab_entry *tab;
|
121 |
|
|
#ifdef CYGPKG_KERNEL
|
122 |
|
|
cyg_tick_count_t txstart;
|
123 |
|
|
#endif
|
124 |
|
|
} cs8900a_priv_data_t;
|
125 |
|
|
|
126 |
|
|
// ------------------------------------------------------------------------
|
127 |
|
|
// Macros for accessing CS registers
|
128 |
|
|
// These can be overridden by the platform header
|
129 |
|
|
|
130 |
|
|
#ifndef CS_IN
|
131 |
|
|
# define CS_IN(_b_, _o_, _d_) HAL_READ_UINT16 ((cyg_addrword_t)(_b_)+(_o_), (_d_))
|
132 |
|
|
# define CS_OUT(_b_, _o_, _d_) HAL_WRITE_UINT16((cyg_addrword_t)(_b_)+(_o_), (_d_))
|
133 |
|
|
#endif
|
134 |
|
|
|
135 |
|
|
// ------------------------------------------------------------------------
|
136 |
|
|
// Macros allowing platform to customize some of the driver details
|
137 |
|
|
|
138 |
|
|
#ifndef CYGHWR_CL_CS8900A_PLF_RESET
|
139 |
|
|
# define CYGHWR_CL_CS8900A_PLF_RESET(_b_) do { } while (0)
|
140 |
|
|
#endif
|
141 |
|
|
|
142 |
|
|
#ifndef CYGHWR_CL_CS8900A_PLF_POST_RESET
|
143 |
|
|
# define CYGHWR_CL_CS8900A_PLF_POST_RESET(_b_) do { } while (0)
|
144 |
|
|
#endif
|
145 |
|
|
|
146 |
|
|
#ifndef CYGHWR_CL_CS8900A_PLF_INT_CLEAR
|
147 |
|
|
# define CYGHWR_CL_CS8900A_PLF_INT_CLEAR(_cdp_)
|
148 |
|
|
#endif
|
149 |
|
|
|
150 |
|
|
#ifndef CYGHWR_CL_CS8900A_PLF_INIT
|
151 |
|
|
#define CYGHWR_CL_CS8900A_PLF_INIT(_cdp_) do { } while (0)
|
152 |
|
|
#endif
|
153 |
|
|
|
154 |
|
|
|
155 |
|
|
// ------------------------------------------------------------------------
|
156 |
|
|
// Directly visible registers.
|
157 |
|
|
// Platform can override stepping or layout if necessary.
|
158 |
|
|
#ifndef CS8900A_step
|
159 |
|
|
# define CS8900A_step 2
|
160 |
|
|
#endif
|
161 |
|
|
#ifndef CS8900A_RTDATA
|
162 |
|
|
# define CS8900A_RTDATA (0*CS8900A_step)
|
163 |
|
|
# define CS8900A_TxCMD (2*CS8900A_step)
|
164 |
|
|
# define CS8900A_TxLEN (3*CS8900A_step)
|
165 |
|
|
# define CS8900A_ISQ (4*CS8900A_step)
|
166 |
|
|
# define CS8900A_PPTR (5*CS8900A_step)
|
167 |
|
|
# define CS8900A_PDATA (6*CS8900A_step)
|
168 |
|
|
#endif
|
169 |
|
|
|
170 |
|
|
#define ISQ_RxEvent 0x04
|
171 |
|
|
#define ISQ_TxEvent 0x08
|
172 |
|
|
#define ISQ_BufEvent 0x0C
|
173 |
|
|
#define ISQ_RxMissEvent 0x10
|
174 |
|
|
#define ISQ_TxColEvent 0x12
|
175 |
|
|
#define ISQ_EventMask 0x3F
|
176 |
|
|
|
177 |
|
|
// ------------------------------------------------------------------------
|
178 |
|
|
// Registers available via "page pointer" (indirect access)
|
179 |
|
|
#define PP_ChipID 0x0000 // Chip identifier - must be 0x630E
|
180 |
|
|
#define PP_ChipRev 0x0002 // Chip revision, model codes
|
181 |
|
|
|
182 |
|
|
#define PP_IntReg 0x0022 // Interrupt configuration
|
183 |
|
|
#define PP_IntReg_IRQ0 0x0000 // Use INTR0 pin
|
184 |
|
|
#define PP_IntReg_IRQ1 0x0001 // Use INTR1 pin
|
185 |
|
|
#define PP_IntReg_IRQ2 0x0002 // Use INTR2 pin
|
186 |
|
|
#define PP_IntReg_IRQ3 0x0003 // Use INTR3 pin
|
187 |
|
|
|
188 |
|
|
#define PP_RxCFG 0x0102 // Receiver configuration
|
189 |
|
|
#define PP_RxCFG_Skip1 0x0040 // Skip (i.e. discard) current frame
|
190 |
|
|
#define PP_RxCFG_Stream 0x0080 // Enable streaming mode
|
191 |
|
|
#define PP_RxCFG_RxOK 0x0100 // RxOK interrupt enable
|
192 |
|
|
#define PP_RxCFG_RxDMAonly 0x0200 // Use RxDMA for all frames
|
193 |
|
|
#define PP_RxCFG_AutoRxDMA 0x0400 // Select RxDMA automatically
|
194 |
|
|
#define PP_RxCFG_BufferCRC 0x0800 // Include CRC characters in frame
|
195 |
|
|
#define PP_RxCFG_CRC 0x1000 // Enable interrupt on CRC error
|
196 |
|
|
#define PP_RxCFG_RUNT 0x2000 // Enable interrupt on RUNT frames
|
197 |
|
|
#define PP_RxCFG_EXTRA 0x4000 // Enable interrupt on frames with extra data
|
198 |
|
|
|
199 |
|
|
#define PP_RxCTL 0x0104 // Receiver control
|
200 |
|
|
#define PP_RxCTL_IAHash 0x0040 // Accept frames that match hash
|
201 |
|
|
#define PP_RxCTL_Promiscuous 0x0080 // Accept any frame
|
202 |
|
|
#define PP_RxCTL_RxOK 0x0100 // Accept well formed frames
|
203 |
|
|
#define PP_RxCTL_Multicast 0x0200 // Accept multicast frames
|
204 |
|
|
#define PP_RxCTL_IA 0x0400 // Accept frame that matches IA
|
205 |
|
|
#define PP_RxCTL_Broadcast 0x0800 // Accept broadcast frames
|
206 |
|
|
#define PP_RxCTL_CRC 0x1000 // Accept frames with bad CRC
|
207 |
|
|
#define PP_RxCTL_RUNT 0x2000 // Accept runt frames
|
208 |
|
|
#define PP_RxCTL_EXTRA 0x4000 // Accept frames that are too long
|
209 |
|
|
|
210 |
|
|
#define PP_TxCFG 0x0106 // Transmit configuration
|
211 |
|
|
#define PP_TxCFG_CRS 0x0040 // Enable interrupt on loss of carrier
|
212 |
|
|
#define PP_TxCFG_SQE 0x0080 // Enable interrupt on Signal Quality Error
|
213 |
|
|
#define PP_TxCFG_TxOK 0x0100 // Enable interrupt on successful xmits
|
214 |
|
|
#define PP_TxCFG_Late 0x0200 // Enable interrupt on "out of window"
|
215 |
|
|
#define PP_TxCFG_Jabber 0x0400 // Enable interrupt on jabber detect
|
216 |
|
|
#define PP_TxCFG_Collision 0x0800 // Enable interrupt if collision
|
217 |
|
|
#define PP_TxCFG_16Collisions 0x8000 // Enable interrupt if > 16 collisions
|
218 |
|
|
|
219 |
|
|
#define PP_TxCmd 0x0108 // Transmit command status
|
220 |
|
|
#define PP_TxCmd_TxStart_5 0x0000 // Start after 5 bytes in buffer
|
221 |
|
|
#define PP_TxCmd_TxStart_381 0x0040 // Start after 381 bytes in buffer
|
222 |
|
|
#define PP_TxCmd_TxStart_1021 0x0080 // Start after 1021 bytes in buffer
|
223 |
|
|
#define PP_TxCmd_TxStart_Full 0x00C0 // Start after all bytes loaded
|
224 |
|
|
#define PP_TxCmd_Force 0x0100 // Discard any pending packets
|
225 |
|
|
#define PP_TxCmd_OneCollision 0x0200 // Abort after a single collision
|
226 |
|
|
#define PP_TxCmd_NoCRC 0x1000 // Do not add CRC
|
227 |
|
|
#define PP_TxCmd_NoPad 0x2000 // Do not pad short packets
|
228 |
|
|
|
229 |
|
|
#define PP_BufCFG 0x010A // Buffer configuration
|
230 |
|
|
#define PP_BufCFG_SWI 0x0040 // Force interrupt via software
|
231 |
|
|
#define PP_BufCFG_RxDMA 0x0080 // Enable interrupt on Rx DMA
|
232 |
|
|
#define PP_BufCFG_TxRDY 0x0100 // Enable interrupt when ready for Tx
|
233 |
|
|
#define PP_BufCFG_TxUE 0x0200 // Enable interrupt in Tx underrun
|
234 |
|
|
#define PP_BufCFG_RxMiss 0x0400 // Enable interrupt on missed Rx packets
|
235 |
|
|
#define PP_BufCFG_Rx128 0x0800 // Enable Rx interrupt after 128 bytes
|
236 |
|
|
#define PP_BufCFG_TxCol 0x1000 // Enable int on Tx collision ctr overflow
|
237 |
|
|
#define PP_BufCFG_Miss 0x2000 // Enable int on Rx miss ctr overflow
|
238 |
|
|
#define PP_BufCFG_RxDest 0x8000 // Enable int on Rx dest addr match
|
239 |
|
|
|
240 |
|
|
#define PP_LineCTL 0x0112 // Line control
|
241 |
|
|
#define PP_LineCTL_Rx 0x0040 // Enable receiver
|
242 |
|
|
#define PP_LineCTL_Tx 0x0080 // Enable transmitter
|
243 |
|
|
|
244 |
|
|
#define PP_RER 0x0124 // Receive event
|
245 |
|
|
#define PP_RER_IAHash 0x0040 // Frame hash match
|
246 |
|
|
#define PP_RER_Dribble 0x0080 // Frame had 1-7 extra bits after last byte
|
247 |
|
|
#define PP_RER_RxOK 0x0100 // Frame received with no errors
|
248 |
|
|
#define PP_RER_Hashed 0x0200 // Frame address hashed OK
|
249 |
|
|
#define PP_RER_IA 0x0400 // Frame address matched IA
|
250 |
|
|
#define PP_RER_Broadcast 0x0800 // Broadcast frame
|
251 |
|
|
#define PP_RER_CRC 0x1000 // Frame had CRC error
|
252 |
|
|
#define PP_RER_RUNT 0x2000 // Runt frame
|
253 |
|
|
#define PP_RER_EXTRA 0x4000 // Frame was too long
|
254 |
|
|
|
255 |
|
|
#define PP_TER 0x0128 // Transmit event
|
256 |
|
|
#define PP_TER_CRS 0x0040 // Carrier lost
|
257 |
|
|
#define PP_TER_SQE 0x0080 // Signal Quality Error
|
258 |
|
|
#define PP_TER_TxOK 0x0100 // Packet sent without error
|
259 |
|
|
#define PP_TER_Late 0x0200 // Out of window
|
260 |
|
|
#define PP_TER_Jabber 0x0400 // Stuck transmit?
|
261 |
|
|
#define PP_TER_NumCollisions 0x7800 // Number of collisions
|
262 |
|
|
#define PP_TER_16Collisions 0x8000 // > 16 collisions
|
263 |
|
|
|
264 |
|
|
#define PP_SelfCtl 0x0114 // Chip control
|
265 |
|
|
#define PP_SelfCtl_Reset 0x0040 // Self-clearing reset
|
266 |
|
|
|
267 |
|
|
#define PP_BusCtl 0x0116 // Bus control
|
268 |
|
|
#define PP_BusCtl_ResetRxDMA 0x0040 // Reset receiver DMA engine
|
269 |
|
|
#define PP_BusCtl_DMAextend 0x0100
|
270 |
|
|
#define PP_BusCtl_UseSA 0x0200
|
271 |
|
|
#define PP_BusCtl_MemoryE 0x0400 // Enable "memory mode"
|
272 |
|
|
#define PP_BusCtl_DMAburst 0x0800
|
273 |
|
|
#define PP_BusCtl_IOCH_RDYE 0x1000
|
274 |
|
|
#define PP_BusCtl_RxDMAsize 0x2000
|
275 |
|
|
#define PP_BusCtl_EnableIRQ 0x8000 // Enable interrupts
|
276 |
|
|
|
277 |
|
|
#define PP_LineStat 0x0134 // Line status
|
278 |
|
|
#define PP_LineStat_LinkOK 0x0080 // Line is connected and working
|
279 |
|
|
#define PP_LineStat_AUI 0x0100 // Connected via AUI
|
280 |
|
|
#define PP_LineStat_10BT 0x0200 // Connected via twisted pair
|
281 |
|
|
#define PP_LineStat_Polarity 0x1000 // Line polarity OK (10BT only)
|
282 |
|
|
#define PP_LineStat_CRS 0x4000 // Frame being received
|
283 |
|
|
|
284 |
|
|
#define PP_SelfStat 0x0136 // Chip status
|
285 |
|
|
#define PP_SelfStat_InitD 0x0080 // Chip initialization complete
|
286 |
|
|
#define PP_SelfStat_SIBSY 0x0100 // EEPROM is busy
|
287 |
|
|
#define PP_SelfStat_EEPROM 0x0200 // EEPROM present
|
288 |
|
|
#define PP_SelfStat_EEPROM_OK 0x0400 // EEPROM checks out
|
289 |
|
|
#define PP_SelfStat_ELPresent 0x0800 // External address latch logic available
|
290 |
|
|
#define PP_SelfStat_EEsize 0x1000 // Size of EEPROM
|
291 |
|
|
|
292 |
|
|
#define PP_BusStat 0x0138 // Bus status
|
293 |
|
|
#define PP_BusStat_TxBid 0x0080 // Tx error
|
294 |
|
|
#define PP_BusStat_TxRDY 0x0100 // Ready for Tx data
|
295 |
|
|
|
296 |
|
|
#define PP_LAF 0x0150 // Logical address filter (6 bytes)
|
297 |
|
|
#define PP_IA 0x0158 // Individual address (MAC)
|
298 |
|
|
|
299 |
|
|
// ------------------------------------------------------------------------
|
300 |
|
|
// "page pointer" access functions
|
301 |
|
|
static __inline__ cyg_uint16
|
302 |
|
|
get_reg(cyg_addrword_t base, int regno)
|
303 |
|
|
{
|
304 |
|
|
cyg_uint16 val;
|
305 |
|
|
HAL_WRITE_UINT16(base+CS8900A_PPTR, regno);
|
306 |
|
|
HAL_READ_UINT16(base+CS8900A_PDATA, val);
|
307 |
|
|
#if DEBUG & 2
|
308 |
|
|
diag_printf("get_reg(%p, %d) => 0x%04x\n", base, regno, val);
|
309 |
|
|
#endif
|
310 |
|
|
return val;
|
311 |
|
|
}
|
312 |
|
|
|
313 |
|
|
static __inline__ void
|
314 |
|
|
put_reg(cyg_addrword_t base, int regno, cyg_uint16 val)
|
315 |
|
|
{
|
316 |
|
|
#if DEBUG & 2
|
317 |
|
|
diag_printf("put_reg(%p, %d, 0x%04x)\n", base, regno, val);
|
318 |
|
|
#endif
|
319 |
|
|
HAL_WRITE_UINT16(base+CS8900A_PPTR, regno);
|
320 |
|
|
HAL_WRITE_UINT16(base+CS8900A_PDATA, val);
|
321 |
|
|
}
|
322 |
|
|
|
323 |
|
|
#endif // _CYGONCE_ETH_CL_CS8900_H_
|