summaryrefslogtreecommitdiffstats
path: root/bsps/include/libchip/smc91111.h
blob: 7ec83716d0d272da3a9db4f831c723741a4e674b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
#ifndef _SMC91111_H_
#define _SMC91111_H_

#include <libchip/smc91111exp.h>
#include <rtems/bspIo.h>

#define LAN91CXX_TCR         0x00
#define LAN91CXX_EPH_STATUS  0x01
#define LAN91CXX_RCR         0x02
#define LAN91CXX_COUNTER     0x03
#define LAN91CXX_MIR         0x04
#define LAN91CXX_MCR         0x05 /* Other than 91C111*/
#define LAN91CXX_RPCR        0x05 /* 91C111 only*/
#define LAN91CXX_RESERVED_0  0x06
#define LAN91CXX_BS          0x07
#define LAN91CXX_CONFIG      0x08
#define LAN91CXX_BASE_REG    0x09
#define LAN91CXX_IA01        0x0a
#define LAN91CXX_IA23        0x0b
#define LAN91CXX_IA45        0x0c
#define LAN91CXX_GENERAL     0x0d /* 91C96 - was "RESERVED_1" for others*/
#define LAN91CXX_CONTROL     0x0e
#define LAN91CXX_BS2         0x0f
#define LAN91CXX_MMU_COMMAND 0x10
#define LAN91CXX_PNR         0x11
#define LAN91CXX_FIFO_PORTS  0x12
#define LAN91CXX_POINTER     0x13
#define LAN91CXX_DATA_HIGH   0x14
#define LAN91CXX_DATA        0x15
#define LAN91CXX_INTERRUPT   0x16
#define LAN91CXX_BS3         0x17
#define LAN91CXX_MT01        0x18
#define LAN91CXX_MT23        0x19
#define LAN91CXX_MT45        0x1a
#define LAN91CXX_MT67        0x1b
#define LAN91CXX_MGMT        0x1c
#define LAN91CXX_REVISION    0x1d
#define LAN91CXX_ERCV        0x1e
#define LAN91CXX_BS4         0x1f

#define LAN91CXX_RCR_SOFT_RST   0x8000    /* soft reset*/
#define LAN91CXX_RCR_FILT_CAR   0x4000    /* filter carrier*/
#define LAN91CXX_RCR_ABORT_ENB  0x2000    /* abort on collision*/
#define LAN91CXX_RCR_STRIP_CRC  0x0200    /* strip CRC*/
#define LAN91CXX_RCR_RXEN       0x0100    /* enable RX*/
#define LAN91CXX_RCR_ALMUL      0x0004    /* receive all muticasts*/
#define LAN91CXX_RCR_PRMS       0x0002    /* promiscuous*/
#define LAN91CXX_RCR_RX_ABORT   0x0001    /* set when abort due to long frame*/

#define LAN91CXX_TCR_SWFDUP     0x8000    /* Switched Full Duplex mode*/
#define LAN91CXX_TCR_ETEN_TYPE  0x4000    /* ETEN type (91C96) 0 <=> like a 91C94*/
#define LAN91CXX_TCR_EPH_LOOP   0x2000    /* loopback mode*/
#define LAN91CXX_TCR_STP_SQET   0x1000    /* Stop transmission on SQET error*/
#define LAN91CXX_TCR_FDUPLX     0x0800    /* full duplex*/
#define LAN91CXX_TCR_MON_CSN    0x0400    /* monitor carrier during tx (91C96)*/
#define LAN91CXX_TCR_NOCRC      0x0100    /* does not append CRC to frames*/
#define LAN91CXX_TCR_PAD_EN     0x0080    /* pads frames with 00 to min length*/
#define LAN91CXX_TCR_FORCOL     0x0004    /* force collision*/
#define LAN91CXX_TCR_LLOOP      0x0002    /* local loopback (91C96)*/
#define LAN91CXX_TCR_TXENA      0x0001    /* enable*/

#define LAN91CXX_POINTER_RCV        0x8000
#define LAN91CXX_POINTER_AUTO_INCR  0x4000
#define LAN91CXX_POINTER_READ       0x2000
#define LAN91CXX_POINTER_ETEN       0x1000
#define LAN91CXX_POINTER_NOT_EMPTY  0x0800


#define LAN91CXX_INTERRUPT_TX_IDLE_M      0x8000 /* (91C96)*/
#define LAN91CXX_INTERRUPT_ERCV_INT_M     0x4000
#define LAN91CXX_INTERRUPT_EPH_INT_M      0x2000
#define LAN91CXX_INTERRUPT_RX_OVRN_INT_M  0x1000
#define LAN91CXX_INTERRUPT_ALLOC_INT_M    0x0800
#define LAN91CXX_INTERRUPT_TX_EMPTY_INT_M 0x0400
#define LAN91CXX_INTERRUPT_TX_INT_M       0x0200
#define LAN91CXX_INTERRUPT_RCV_INT_M      0x0100
#define LAN91CXX_INTERRUPT_TX_IDLE        0x0080 /* (91C96)*/
#define LAN91CXX_INTERRUPT_ERCV_INT       0x0040 /* also ack*/
#define LAN91CXX_INTERRUPT_EPH_INT        0x0020
#define LAN91CXX_INTERRUPT_RX_OVRN_INT    0x0010 /* also ack*/
#define LAN91CXX_INTERRUPT_ALLOC_INT      0x0008
#define LAN91CXX_INTERRUPT_TX_EMPTY_INT   0x0004 /* also ack*/
#define LAN91CXX_INTERRUPT_TX_INT         0x0002 /* also ack*/
#define LAN91CXX_INTERRUPT_RCV_INT        0x0001

#define LAN91CXX_INTERRUPT_TX_SET         0x0006 /* TX_EMPTY + TX*/
#define LAN91CXX_INTERRUPT_TX_SET_ACK     0x0004 /* TX_EMPTY and not plain TX*/
#define LAN91CXX_INTERRUPT_TX_FIFO_ACK    0x0002 /* TX alone*/
#define LAN91CXX_INTERRUPT_TX_SET_M       0x0600 /* TX_EMPTY + TX*/

#define LAN91CXX_CONTROL_RCV_BAD       0x4000
#define LAN91CXX_CONTROL_AUTO_RELEASE  0x0800
#define LAN91CXX_CONTROL_LE_ENABLE     0x0080
#define LAN91CXX_CONTROL_CR_ENABLE     0x0040
#define LAN91CXX_CONTROL_TE_ENABLE     0x0020

/* These are for setting the MAC address in the 91C96 serial EEPROM*/
#define LAN91CXX_CONTROL_EEPROM_SELECT 0x0004
#define LAN91CXX_CONTROL_RELOAD        0x0002
#define LAN91CXX_CONTROL_STORE         0x0001
#define LAN91CXX_CONTROL_EEPROM_BUSY   0x0003
#define LAN91CXX_ESA_EEPROM_OFFSET     0x0020

#define LAN91CXX_STATUS_TX_UNRN        0x8000
#define LAN91CXX_STATUS_LINK_OK        0x4000
#define LAN91CXX_STATUS_CTR_ROL        0x1000
#define LAN91CXX_STATUS_EXC_DEF        0x0800
#define LAN91CXX_STATUS_LOST_CARR      0x0400
#define LAN91CXX_STATUS_LATCOL         0x0200
#define LAN91CXX_STATUS_WAKEUP         0x0100
#define LAN91CXX_STATUS_TX_DEFR        0x0080
#define LAN91CXX_STATUS_LTX_BRD        0x0040
#define LAN91CXX_STATUS_SQET           0x0020
#define LAN91CXX_STATUS_16COL          0x0010
#define LAN91CXX_STATUS_LTX_MULT       0x0008
#define LAN91CXX_STATUS_MUL_COL        0x0004
#define LAN91CXX_STATUS_SNGL_COL       0x0002
#define LAN91CXX_STATUS_TX_SUC         0x0001

#define LAN91CXX_MMU_COMMAND_BUSY      0x0001

#define LAN91CXX_MMU_noop              0x0000
#define LAN91CXX_MMU_alloc_for_tx      0x0020
#define LAN91CXX_MMU_reset_mmu         0x0040
#define LAN91CXX_MMU_rem_rx_frame      0x0060
#define LAN91CXX_MMU_rem_tx_frame      0x0070 /* (91C96) only when TX stopped*/
#define LAN91CXX_MMU_remrel_rx_frame   0x0080
#define LAN91CXX_MMU_rel_packet        0x00a0
#define LAN91CXX_MMU_enq_packet        0x00c0
#define LAN91CXX_MMU_reset_tx_fifo     0x00e0

#define LAN91CXX_CONTROLBYTE_CRC       0x1000
#define LAN91CXX_CONTROLBYTE_ODD       0x2000
#define LAN91CXX_CONTROLBYTE_RX        0x4000

#define LAN91CXX_RX_STATUS_ALIGNERR    0x8000
#define LAN91CXX_RX_STATUS_BCAST       0x4000
#define LAN91CXX_RX_STATUS_BADCRC      0x2000
#define LAN91CXX_RX_STATUS_ODDFRM      0x1000
#define LAN91CXX_RX_STATUS_TOOLONG     0x0800
#define LAN91CXX_RX_STATUS_TOOSHORT    0x0400
#define LAN91CXX_RX_STATUS_HASHVALMASK 0x007e /* MASK*/
#define LAN91CXX_RX_STATUS_MCAST       0x0001
#define LAN91CXX_RX_STATUS_BAD     \
    (LAN91CXX_RX_STATUS_ALIGNERR | \
     LAN91CXX_RX_STATUS_BADCRC   | \
     LAN91CXX_RX_STATUS_TOOLONG  | \
     LAN91CXX_RX_STATUS_TOOSHORT)

#define LAN91CXX_RX_STATUS_IS_ODD(__cpd,__stat) ((__stat) & LAN91CXX_RX_STATUS_ODDFRM)
#define LAN91CXX_CONTROLBYTE_IS_ODD(__cpd,__val) ((__val) & LAN91CXX_CONTROLBYTE_ODD)

/* Attribute memory registers in PCMCIA mode*/
#define LAN91CXX_ECOR                  0x8000
#define LAN91CXX_ECOR_RESET            (1<<7)
#define LAN91CXX_ECOR_LEVIRQ           (1<<6)
#define LAN91CXX_ECOR_ATTWR            (1<<2)
#define LAN91CXX_ECOR_ENABLE           (1<<0)

#define LAN91CXX_ECSR                  0x8002
#define LAN91CXX_ECSR_IOIS8            (1<<5)
#define LAN91CXX_ECSR_PWRDWN           (1<<2)
#define LAN91CXX_ECSR_INTR             (1<<1)

/* These are for manipulating the MII interface*/
#define LAN91CXX_MGMT_MDO              0x0001
#define LAN91CXX_MGMT_MDI              0x0002
#define LAN91CXX_MGMT_MCLK             0x0004
#define LAN91CXX_MGMT_MDOE             0x0008

/* Internal PHY registers (91c111)*/
#define LAN91CXX_PHY_CTRL              0
#define LAN91CXX_PHY_STAT              1
#define LAN91CXX_PHY_ID1               2
#define LAN91CXX_PHY_ID2               3
#define LAN91CXX_PHY_AUTO_AD           4
#define LAN91CXX_PHY_AUTO_CAP          5
#define LAN91CXX_PHY_CONFIG1          16
#define LAN91CXX_PHY_CONFIG2          17
#define LAN91CXX_PHY_STATUS_OUT       18
#define LAN91CXX_PHY_MASK             19

/* PHY control bits*/
#define LAN91CXX_PHY_CTRL_COLTST      (1 << 7)
#define LAN91CXX_PHY_CTRL_DPLX        (1 << 8)
#define LAN91CXX_PHY_CTRL_ANEG_RST    (1 << 9)
#define LAN91CXX_PHY_CTRL_MII_DIS     (1 << 10)
#define LAN91CXX_PHY_CTRL_PDN         (1 << 11)
#define LAN91CXX_PHY_CTRL_ANEG_EN     (1 << 12)
#define LAN91CXX_PHY_CTRL_SPEED       (1 << 13)
#define LAN91CXX_PHY_CTRL_LPBK        (1 << 14)
#define LAN91CXX_PHY_CTRL_RST         (1 << 15)

/* PHY Configuration Register 1 */
#define PHY_CFG1_LNKDIS		0x8000	/* 1=Rx Link Detect Function disabled */
#define PHY_CFG1_XMTDIS		0x4000	/* 1=TP Transmitter Disabled */
#define PHY_CFG1_XMTPDN		0x2000	/* 1=TP Transmitter Powered Down */
#define PHY_CFG1_BYPSCR		0x0400	/* 1=Bypass scrambler/descrambler */
#define PHY_CFG1_UNSCDS		0x0200	/* 1=Unscramble Idle Reception Disable */
#define PHY_CFG1_EQLZR		0x0100	/* 1=Rx Equalizer Disabled */
#define PHY_CFG1_CABLE		0x0080	/* 1=STP(150ohm), 0=UTP(100ohm) */
#define PHY_CFG1_RLVL0		0x0040	/* 1=Rx Squelch level reduced by 4.5db */
#define PHY_CFG1_TLVL_SHIFT	2	/* Transmit Output Level Adjust */
#define PHY_CFG1_TLVL_MASK	0x003C
#define PHY_CFG1_TRF_MASK	0x0003	/* Transmitter Rise/Fall time */

/* PHY Configuration Register 2 */
#define PHY_CFG2_REG		0x11
#define PHY_CFG2_APOLDIS	0x0020	/* 1=Auto Polarity Correction disabled */
#define PHY_CFG2_JABDIS		0x0010	/* 1=Jabber disabled */
#define PHY_CFG2_MREG		0x0008	/* 1=Multiple register access (MII mgt) */
#define PHY_CFG2_INTMDIO	0x0004	/* 1=Interrupt signaled with MDIO pulseo */

/* PHY Status Output (and Interrupt status) Register */
#define PHY_INT_REG		0x12	/* Status Output (Interrupt Status) */
#define PHY_INT_INT		0x8000	/* 1=bits have changed since last read */
#define	PHY_INT_LNKFAIL		0x4000	/* 1=Link Not detected */
#define PHY_INT_LOSSSYNC	0x2000	/* 1=Descrambler has lost sync */
#define PHY_INT_CWRD		0x1000	/* 1=Invalid 4B5B code detected on rx */
#define PHY_INT_SSD		0x0800	/* 1=No Start Of Stream detected on rx */
#define PHY_INT_ESD		0x0400	/* 1=No End Of Stream detected on rx */
#define PHY_INT_RPOL		0x0200	/* 1=Reverse Polarity detected */
#define PHY_INT_JAB		0x0100	/* 1=Jabber detected */
#define PHY_INT_SPDDET		0x0080	/* 1=100Base-TX mode, 0=10Base-T mode */
#define PHY_INT_DPLXDET		0x0040	/* 1=Device in Full Duplex */

/* PHY Interrupt/Status Mask Register */
#define PHY_MASK_REG		0x13	/* Interrupt Mask */

#define LAN91CXX_RPCR_LEDA_LINK       (0 << 2)
#define LAN91CXX_RPCR_LEDA_TXRX       (4 << 2)
#define LAN91CXX_RPCR_LEDA_RX         (6 << 2)
#define LAN91CXX_RPCR_LEDA_TX         (7 << 2)
#define LAN91CXX_RPCR_LEDB_LINK       (0 << 5)
#define LAN91CXX_RPCR_LEDB_TXRX       (4 << 5)
#define LAN91CXX_RPCR_LEDB_RX         (6 << 5)
#define LAN91CXX_RPCR_LEDB_TX         (7 << 5)
#define LAN91CXX_RPCR_ANEG            (1 << 11)
#define LAN91CXX_RPCR_DPLX            (1 << 12)
#define LAN91CXX_RPCR_SPEED           (1 << 13)

/* PHY Control Register */
#define PHY_CNTL_REG		0x00
#define PHY_CNTL_RST		0x8000	/* 1=PHY Reset */
#define PHY_CNTL_LPBK		0x4000	/* 1=PHY Loopback */
#define PHY_CNTL_SPEED		0x2000	/* 1=100Mbps, 0=10Mpbs */
#define PHY_CNTL_ANEG_EN	0x1000 /* 1=Enable Auto negotiation */
#define PHY_CNTL_PDN		0x0800	/* 1=PHY Power Down mode */
#define PHY_CNTL_MII_DIS	0x0400	/* 1=MII 4 bit interface disabled */
#define PHY_CNTL_ANEG_RST	0x0200 /* 1=Reset Auto negotiate */
#define PHY_CNTL_DPLX		0x0100	/* 1=Full Duplex, 0=Half Duplex */
#define PHY_CNTL_COLTST		0x0080	/* 1= MII Colision Test */

/* PHY Status Register */
#define PHY_STAT_REG		0x01
#define PHY_STAT_CAP_T4		0x8000	/* 1=100Base-T4 capable */
#define PHY_STAT_CAP_TXF	0x4000	/* 1=100Base-X full duplex capable */
#define PHY_STAT_CAP_TXH	0x2000	/* 1=100Base-X half duplex capable */
#define PHY_STAT_CAP_TF		0x1000	/* 1=10Mbps full duplex capable */
#define PHY_STAT_CAP_TH		0x0800	/* 1=10Mbps half duplex capable */
#define PHY_STAT_CAP_SUPR	0x0040	/* 1=recv mgmt frames with not preamble */
#define PHY_STAT_ANEG_ACK	0x0020	/* 1=ANEG has completed */
#define PHY_STAT_REM_FLT	0x0010	/* 1=Remote Fault detected */
#define PHY_STAT_CAP_ANEG	0x0008	/* 1=Auto negotiate capable */
#define PHY_STAT_LINK		0x0004	/* 1=valid link */
#define PHY_STAT_JAB		0x0002	/* 1=10Mbps jabber condition */
#define PHY_STAT_EXREG		0x0001	/* 1=extended registers implemented */
#define PHY_STAT_RESERVED   0x0780  /* Reserved bits mask. */

/* PHY Identifier Registers */
#define PHY_ID1_REG		0x02	/* PHY Identifier 1 */
#define PHY_ID2_REG		0x03	/* PHY Identifier 2 */

/* PHY Auto-Negotiation Advertisement Register */
#define PHY_AD_REG		0x04
#define PHY_AD_NP		0x8000	/* 1=PHY requests exchange of Next Page */
#define PHY_AD_ACK		0x4000	/* 1=got link code word from remote */
#define PHY_AD_RF		0x2000	/* 1=advertise remote fault */
#define PHY_AD_T4		0x0200	/* 1=PHY is capable of 100Base-T4 */
#define PHY_AD_TX_FDX		0x0100	/* 1=PHY is capable of 100Base-TX FDPLX */
#define PHY_AD_TX_HDX		0x0080	/* 1=PHY is capable of 100Base-TX HDPLX */
#define PHY_AD_10_FDX		0x0040	/* 1=PHY is capable of 10Base-T FDPLX */
#define PHY_AD_10_HDX		0x0020	/* 1=PHY is capable of 10Base-T HDPLX */
#define PHY_AD_CSMA		0x0001	/* 1=PHY is capable of 802.3 CMSA */


static int debugflag_out = 0;

#define dbc_printf(lvl,format, args...) do { \
  if (!debugflag_out) { \
    if (lvl & DEBUG) { \
      printk(format,##args); \
    } \
  } \
} while(0)

#define db64_printf(format, args...) dbc_printf(64,format,##args);
#define db16_printf(format, args...) dbc_printf(16,format,##args);
#define db9_printf(format, args...) dbc_printf(9,format,##args);
#define db4_printf(format, args...) dbc_printf(4,format,##args);
#define db2_printf(format, args...) dbc_printf(2,format,##args);
#define db1_printf(format, args...) dbc_printf(1,format,##args);
#define db_printf(format, args...) dbc_printf(0xffff,format,##args);

#if DEBUG & 1
#define DEBUG_FUNCTION() do { db_printf("# %s\n", __FUNCTION__); } while (0)
#else
#define DEBUG_FUNCTION() do {} while(0)
#endif


/* ------------------------------------------------------------------------*/

struct smsc_lan91cxx_stats {
    unsigned int tx_good             ;
    unsigned int tx_max_collisions   ;
    unsigned int tx_late_collisions  ;
    unsigned int tx_underrun         ;
    unsigned int tx_carrier_loss     ;
    unsigned int tx_deferred         ;
    unsigned int tx_sqetesterrors    ;
    unsigned int tx_single_collisions;
    unsigned int tx_mult_collisions  ;
    unsigned int tx_total_collisions ;
    unsigned int rx_good             ;
    unsigned int rx_crc_errors       ;
    unsigned int rx_align_errors     ;
    unsigned int rx_resource_errors  ;
    unsigned int rx_overrun_errors   ;
    unsigned int rx_collisions       ;
    unsigned int rx_short_frames     ;
    unsigned int rx_too_long_frames  ;
    unsigned int rx_symbol_errors    ;
    unsigned int interrupts          ;
    unsigned int rx_count            ;
    unsigned int rx_deliver          ;
    unsigned int rx_resource         ;
    unsigned int rx_restart          ;
    unsigned int tx_count            ;
    unsigned int tx_complete         ;
    unsigned int tx_dropped          ;
};
#define INCR_STAT(c,n) (((c)->stats.n)++)

struct lan91cxx_priv_data;

typedef struct lan91cxx_priv_data {

    /* frontend */
    struct arpcom arpcom;
    rtems_id rxDaemonTid;
    rtems_id txDaemonTid;

    scmv91111_configuration_t config;

    /* backend */
    int rpc_cur_mode;
    int autoneg_active;
    int phyaddr;
    unsigned int lastPhy18;

    int txbusy;                         /* A packet has been sent*/
    unsigned long txkey;                /* Used to ack when packet sent*/
    unsigned short* base;               /* Base I/O address of controller*/
                                        /* (as it comes out of reset)*/
    int interrupt;                      /* Interrupt vector used by controller*/
    unsigned char enaddr[6];            /* Controller ESA*/
    /* Function to configure the ESA - may fetch ESA from EPROM or */
    /* RedBoot config option.  Use of the 'config_enaddr()' function*/
    /* is depreciated in favor of the 'provide_esa()' function and*/
    /* 'hardwired_esa' boolean*/
    void (*config_enaddr)(struct lan91cxx_priv_data* cpd);
    int hardwired_esa;
    int txpacket;
    int rxpacket;
    int within_send;
    int c111_reva;                      /* true if this is a revA LAN91C111*/
    struct smsc_lan91cxx_stats stats;
} lan91cxx_priv_data;

/* ------------------------------------------------------------------------*/

#ifdef LAN91CXX_32BIT_RX
typedef unsigned int rxd_t;
#else
typedef unsigned short rxd_t;
#endif

typedef struct _debug_regs_pair {
  int reg; char *name; struct _debug_regs_pair *bits;
} debug_regs_pair;

static debug_regs_pair debug_regs[] = {
  {LAN91CXX_TCR        , "LAN91CXX_TCR"       ,0},
  {LAN91CXX_EPH_STATUS , "LAN91CXX_EPH_STATUS",0},
  {LAN91CXX_RCR        , "LAN91CXX_RCR"       ,0},
  {LAN91CXX_COUNTER    , "LAN91CXX_COUNTER"   ,0},
  {LAN91CXX_MIR        , "LAN91CXX_MIR"       ,0},
  {LAN91CXX_MCR        , "LAN91CXX_MCR"       ,0},
  {LAN91CXX_RPCR       , "LAN91CXX_RPCR"      ,0},
  {LAN91CXX_RESERVED_0 , "LAN91CXX_RESERVED_0",0},
  {LAN91CXX_BS         , "LAN91CXX_BS"        ,0},
  {LAN91CXX_CONFIG     , "LAN91CXX_CONFIG"    ,0},
  {LAN91CXX_BASE_REG   , "LAN91CXX_BASE_REG"  ,0},
  {LAN91CXX_IA01       , "LAN91CXX_IA01"      ,0},
  {LAN91CXX_IA23       , "LAN91CXX_IA23"      ,0},
  {LAN91CXX_IA45       , "LAN91CXX_IA45"      ,0},
  {LAN91CXX_GENERAL    , "LAN91CXX_GENERAL"   ,0},
  {LAN91CXX_CONTROL    , "LAN91CXX_CONTROL"   ,0},
  {LAN91CXX_BS2        , "LAN91CXX_BS2"       ,0},
  {LAN91CXX_MMU_COMMAND, "LAN91CXX_MMU_COMMAND",0},
  {LAN91CXX_PNR        , "LAN91CXX_PNR"        ,0},
  {LAN91CXX_FIFO_PORTS , "LAN91CXX_FIFO_PORTS" ,0},
  {LAN91CXX_POINTER    , "LAN91CXX_POINTER"    ,0},
  {LAN91CXX_DATA_HIGH  , "LAN91CXX_DATA_HIGH"  ,0},
  {LAN91CXX_DATA       , "LAN91CXX_DATA"       ,0},
  {LAN91CXX_INTERRUPT  , "LAN91CXX_INTERRUPT"  ,0},
  {LAN91CXX_BS3        , "LAN91CXX_BS3"        ,0},
  {LAN91CXX_MT01       , "LAN91CXX_MT01"       ,0},
  {LAN91CXX_MT23       , "LAN91CXX_MT23"       ,0},
  {LAN91CXX_MT45       , "LAN91CXX_MT45"       ,0},
  {LAN91CXX_MT67       , "LAN91CXX_MT67"       ,0},
/*{LAN91CXX_MGMT       , "LAN91CXX_MGMT"       ,0},      */
  {LAN91CXX_REVISION   , "LAN91CXX_REVISION"   ,0},
  {LAN91CXX_ERCV       , "LAN91CXX_ERCV"       ,0},
  {LAN91CXX_BS4        , "LAN91CXX_BS4"        ,0},



  {-1,0}
};

static char *dbg_prefix = "";

#ifndef SMSC_PLATFORM_DEFINED_GET_REG
static __inline__ unsigned short
get_reg(struct lan91cxx_priv_data *cpd, int regno)
{
    unsigned short val; debug_regs_pair *dbg = debug_regs; int c;
    uint32_t              Irql;

    /*rtems_interrupt_disable(Irql);*/

    HAL_WRITE_UINT16(cpd->base+(LAN91CXX_BS), CYG_CPU_TO_LE16(regno>>3));
    HAL_READ_UINT16(cpd->base+((regno&0x7)), val);
    val = CYG_LE16_TO_CPU(val);

    /*rtems_interrupt_enable(Irql);*/

#if DEBUG & 32
    while ((c = dbg->reg) != -1) {
      if (c == regno) {
        db_printf("%sread  reg [%d:%x] -> 0x%04x (%-20s)\n", dbg_prefix, regno>>3,(regno&0x7)*2, val, dbg->name);
        break;
      }
      dbg++;
    }
#else
    db2_printf("%sread  reg %d:%x -> 0x%04x\n", dbg_prefix, regno>>3,(regno&0x7)*2, val);
#endif

    return val;
}
#endif /* SMSC_PLATFORM_DEFINED_GET_REG*/

#ifndef SMSC_PLATFORM_DEFINED_PUT_REG
static __inline__ void
put_reg(struct lan91cxx_priv_data *cpd, int regno, unsigned short val)
{
    debug_regs_pair *dbg = debug_regs; int c;
    uint32_t              Irql;

#if DEBUG & 32
    while ((c = dbg->reg) != -1) {
      if (c == regno) {
        db_printf("%swrite reg [%d:%x] <- 0x%04x (%-20s)\n", dbg_prefix, regno>>3, (regno&0x07)*2, val, dbg->name);
        break;
      }
      dbg++;
    }
#else
    db2_printf("%swrite reg %d:%x <- 0x%04x\n", dbg_prefix, regno>>3,(regno&0x7)*2, val);
#endif

    /*rtems_interrupt_disable(Irql);*/

    HAL_WRITE_UINT16(cpd->base+(LAN91CXX_BS), CYG_CPU_TO_LE16(regno>>3));
    HAL_WRITE_UINT16(cpd->base+((regno&0x7)), CYG_CPU_TO_LE16(val));

    /*rtems_interrupt_enable(Irql);*/

}
#endif /* SMSC_PLATFORM_DEFINED_PUT_REG*/

#ifndef SMSC_PLATFORM_DEFINED_PUT_DATA
/* ------------------------------------------------------------------------*/
/* Assumes bank2 has been selected*/
static __inline__ void
put_data(struct lan91cxx_priv_data *cpd, unsigned short val)
{
    db2_printf("%s[wdata] <- 0x%04x\n", dbg_prefix, val);

    HAL_WRITE_UINT16(cpd->base+((LAN91CXX_DATA & 0x7)), val);

}

/* Assumes bank2 has been selected*/
static __inline__ void
put_data8(struct lan91cxx_priv_data *cpd, unsigned char val)
{
    db2_printf("%s[bdata] <- 0x%02x\n", dbg_prefix, val);

    HAL_WRITE_UINT8(((unsigned char *)(cpd->base+((LAN91CXX_DATA & 0x7))))+1, val);

}

#endif /* SMSC_PLATFORM_DEFINED_PUT_DATA*/

#ifndef SMSC_PLATFORM_DEFINED_GET_DATA
/* Assumes bank2 has been selected*/
static __inline__ rxd_t
get_data(struct lan91cxx_priv_data *cpd)
{
    rxd_t val;

#ifdef LAN91CXX_32BIT_RX
    HAL_READ_UINT32(cpd->base+((LAN91CXX_DATA_HIGH & 0x7)), val);
#else
    HAL_READ_UINT16(cpd->base+((LAN91CXX_DATA & 0x7)), val);
#endif

    db2_printf("%s[rdata] -> 0x%08x\n", dbg_prefix, val);
    return val;
}
#endif /* SMSC_PLATFORM_DEFINED_GET_DATA*/

/* ------------------------------------------------------------------------*/
/* Read the bank register (this one is bank-independent)*/
#ifndef SMSC_PLATFORM_DEFINED_GET_BANKSEL
static __inline__ unsigned short
get_banksel(struct lan91cxx_priv_data *cpd)
{
    unsigned short val;

    HAL_READ_UINT16(cpd->base+(LAN91CXX_BS), val);
    val = CYG_LE16_TO_CPU(val);
    db2_printf("read bank sel val 0x%04x\n", val);
    return val;
}
#endif





#endif  /* _SMC_91111_H_ */