]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/amd/pcnet/v2_0/src/amd_pcnet.h
Initial revision
[karo-tx-redboot.git] / packages / devs / eth / amd / pcnet / v2_0 / src / amd_pcnet.h
1 #ifndef CYGONCE_DEVS_ETH_AMD_PCNET_H
2 #define CYGONCE_DEVS_ETH_AMD_PCNET_H
3 //==========================================================================
4 //
5 //      amd_pcnet.h
6 //
7 //      AMD PCNet 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):    jskov
56 // Contributors: jskov, hmt
57 // Date:         2001-04-02
58 // Purpose:      Hardware description of AMD PCnet series.
59 // Description:  
60 //
61 //####DESCRIPTIONEND####
62 //
63 //==========================================================================
64
65 #include <cyg/hal/hal_io.h>
66
67 //------------------------------------------------------------------------
68 // Get macros from platform header
69 #define __WANT_CONFIG
70 #include CYGDAT_DEVS_ETH_AMD_PCNET_INL
71 #undef  __WANT_CONFIG
72
73 //------------------------------------------------------------------------
74 // Set to perms of:
75 // 0 disables all debug output
76 // 1 for process debug output
77 // 2 for added data IO output: get_reg, put_reg
78 // 4 for packet allocation/free output
79 // 8 for only startup status, so we can tell we're installed OK
80 #define DEBUG 0x0
81
82 #if DEBUG & 1
83 #define DEBUG_FUNCTION() do { os_printf("%s\n", __FUNCTION__); } while (0)
84 #else
85 #define DEBUG_FUNCTION() do {} while(0)
86 #endif
87
88 // ------------------------------------------------------------------------
89 // Macros for keeping track of statistics
90 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
91 # define KEEP_STATISTICS
92 #endif
93
94 #ifdef KEEP_STATISTICS
95 # define INCR_STAT( _x_ )        (cpd->stats. _x_ ++)
96 #else
97 # define INCR_STAT( _x_ )        CYG_EMPTY_STATEMENT
98 #endif
99
100 //------------------------------------------------------------------------
101 // Cache translation
102 #ifndef CYGARC_UNCACHED_ADDRESS
103 # define CYGARC_UNCACHED_ADDRESS(x) (x)
104 #endif
105
106 //------------------------------------------------------------------------
107 // Address translation
108 #ifndef HAL_PCI_CPU_TO_BUS
109 # error "HAL PCI support must define translation macros"
110 #endif
111
112 // ------------------------------------------------------------------------
113 // Macros for accessing structure elements
114
115 #define _SU8( _base_, _offset_) \
116         *((cyg_uint8 *)((CYG_ADDRWORD)_base_+(_offset_)))
117 #define _SU16( _base_, _offset_) \
118         *((cyg_uint16 *)((CYG_ADDRWORD)_base_+(_offset_)))
119 #define _SU32( _base_, _offset_) \
120         *((cyg_uint32 *)((CYG_ADDRWORD)_base_+(_offset_)))
121
122 #define _SI8( _base_, _offset_) \
123         *((cyg_int8 *)((CYG_ADDRWORD)_base_+(_offset_)))
124 #define _SI16( _base_, _offset_) \
125         *((cyg_int16 *)((CYG_ADDRWORD)_base_+(_offset_)))
126 #define _SI32( _base_, _offset_) \
127         *((cyg_int32 *)((CYG_ADDRWORD)_base_+(_offset_)))
128
129 // ------------------------------------------------------------------------
130 // Macros for accessing controller registers
131 #ifndef HAL_PCI_IO_READ_UINT8
132 # define HAL_PCI_IO_READ_UINT8(addr, datum)   HAL_READ_UINT8(addr, datum)
133 # define HAL_PCI_IO_WRITE_UINT8(addr, datum)  HAL_WRITE_UINT8(addr, datum)
134 # define HAL_PCI_IO_READ_UINT16(addr, datum)  HAL_READ_UINT16(addr, datum)
135 # define HAL_PCI_IO_WRITE_UINT16(addr, datum) HAL_WRITE_UINT16(addr, datum)
136 # define HAL_PCI_IO_READ_UINT32(addr, datum)  HAL_READ_UINT32(addr, datum)
137 # define HAL_PCI_IO_WRITE_UINT32(addr, datum) HAL_WRITE_UINT32(addr, datum)
138 #endif
139
140 // ------------------------------------------------------------------------
141 // IO map registers
142 #define PCNET_IO_EEPROM   0x00
143 #define PCNET_IO_ID       0x0e
144 #define PCNET_IO_RDP      0x10
145 #define PCNET_IO_RAP      0x12
146 #define PCNET_IO_RESET    0x14
147 #define PCNET_IO_BDP      0x16
148
149 // The ID of the 79C790 is 0x5757 - that may be different in other
150 // (older) cards.
151 #define PCNET_IO_ID_KEY   0x5757
152
153 // ------------------------------------------------------------------------
154 // Controller registers come in three sets: CSR, BCR and ANR. Use
155 // high-bits do differentiate, make the put/get functions do the right
156 // thing depending the state of these bits.
157 #define PCNET_RAP_MASK    0x007f
158 //#define PCNET_CSR_FLAG  0x0000        // implied
159 #define PCNET_BCR_FLAG    0x0080
160 #define PCNET_ANR_FLAG    0x0100
161
162
163 // CSR registers
164 #define PCNET_CSR_CSCR    0
165 #define PCNET_CSR_IBA0    1
166 #define PCNET_CSR_IBA1    2
167 #define PCNET_CSR_IM      3
168 #define PCNET_CSR_TFC     4
169 #define PCNET_CSR_ECI     5
170 #define PCNET_CSR_LAR0    8
171 #define PCNET_CSR_LAR1    9
172 #define PCNET_CSR_LAR2    10
173 #define PCNET_CSR_LAR3    11
174 #define PCNET_CSR_PAR0    12
175 #define PCNET_CSR_PAR1    13
176 #define PCNET_CSR_PAR2    14
177 #define PCNET_CSR_MODE    15
178 #define PCNET_CSR_BARRL   24
179 #define PCNET_CSR_BARRU   25
180 #define PCNET_CSR_BATRL   30
181 #define PCNET_CSR_BATRU   31
182 #define PCNET_CSR_RRC     72
183 #define PCNET_CSR_TRC     74
184 #define PCNET_CSR_RRLEN   76
185 #define PCNET_CSR_TRLEN   78
186 #define PCNET_CSR_ID_LO   88
187 #define PCNET_CSR_ID_HI   89
188
189
190 #define PCNET_CSR_CSCR_ERR       0x8000
191 #define PCNET_CSR_CSCR_RES       0x4000
192 #define PCNET_CSR_CSCR_CERR      0x2000
193 #define PCNET_CSR_CSCR_MISS      0x1000
194 #define PCNET_CSR_CSCR_MERR      0x0800
195 #define PCNET_CSR_CSCR_RINT      0x0400
196 #define PCNET_CSR_CSCR_TINT      0x0200
197 #define PCNET_CSR_CSCR_IDON      0x0100
198 #define PCNET_CSR_CSCR_INTR      0x0080
199 #define PCNET_CSR_CSCR_IENA      0x0040
200 #define PCNET_CSR_CSCR_RXON      0x0020
201 #define PCNET_CSR_CSCR_TXON      0x0010
202 #define PCNET_CSR_CSCR_TDMD      0x0008
203 #define PCNET_CSR_CSCR_STOP      0x0004
204 #define PCNET_CSR_CSCR_STRT      0x0002
205 #define PCNET_CSR_CSCR_INIT      0x0001
206
207 #define PCNET_CSR_CSCR_EV_MASK   0x007f
208
209 #define PCNET_CSR_IM_MISSM       0x1000
210 #define PCNET_CSR_IM_MERRM       0x0800
211 #define PCNET_CSR_IM_RINTM       0x0400
212 #define PCNET_CSR_IM_TINTM       0x0200
213 #define PCNET_CSR_IM_IDONM       0x0100
214 #define PCNET_CSR_IM_DXSUFLO     0x0040
215 #define PCNET_CSR_IM_LAPPEN      0x0020
216 #define PCNET_CSR_IM_DXMT2PD     0x0010
217 #define PCNET_CSR_IM_EMBA        0x0008
218 #define PCNET_CSR_IM_BSWP        0x0004
219
220 #define PCNET_CSR_TFC_TXDPOLL    0x1000
221 #define PCNET_CSR_TFC_APAD_XMT   0x0800
222 #define PCNET_CSR_TFC_ASTRP_RCV  0x0400
223 #define PCNET_CSR_TFC_MFCO       0x0200
224 #define PCNET_CSR_TFC_MFCOM      0x0100
225 #define PCNET_CSR_TFC_UINTCMD    0x0080
226 #define PCNET_CSR_TFC_UINT       0x0040
227 #define PCNET_CSR_TFC_RCVCCO     0x0020
228 #define PCNET_CSR_TFC_RCVCCOM    0x0010
229 #define PCNET_CSR_TFC_TXSTRT     0x0008
230 #define PCNET_CSR_TFC_TXSTRTM    0x0004
231
232 #define PCNET_CSR_ECI_TOKINTD      0x8000
233 #define PCNET_CSR_ECI_LTINTEN      0x4000
234 #define PCNET_CSR_ECI_SINT         0x0800
235 #define PCNET_CSR_ECI_SINTE        0x0400
236 #define PCNET_CSR_ECI_EXDINT       0x0080
237 #define PCNET_CSR_ECI_EXDINTE      0x0040
238 #define PCNET_CSR_ECI_MPPLBA       0x0020
239 #define PCNET_CSR_ECI_MPINT        0x0010
240 #define PCNET_CSR_ECI_MPINTE       0x0008
241 #define PCNET_CSR_ECI_MPEN         0x0004
242 #define PCNET_CSR_ECI_MPMODE       0x0002
243 #define PCNET_CSR_ECI_SPND         0x0001
244
245 #define PCNET_CSR_MODE_PROM        0x8000
246 #define PCNET_CSR_MODE_DRCVBC      0x4000
247 #define PCNET_CSR_MODE_DRCVPA      0x2000
248 #define PCNET_CSR_MODE_PORTSEL     0x0180
249 #define PCNET_CSR_MODE_INTL        0x0040
250 #define PCNET_CSR_MODE_DRTY        0x0020
251 #define PCNET_CSR_MODE_FCOLL       0x0010
252 #define PCNET_CSR_MODE_DXMTFCS     0x0008
253 #define PCNET_CSR_MODE_LOOP        0x0004
254 #define PCNET_CSR_MODE_DTX         0x0002
255 #define PCNET_CSR_MODE_DRX         0x0001
256
257 // BCR registers
258 #define PCNET_BCR_SWSTYLE (20 |PCNET_BCR_FLAG)
259 #define PCNET_BCR_MIIADDR (33 |PCNET_BCR_FLAG)
260 #define PCNET_BCR_MIIDATA (34 |PCNET_BCR_FLAG)
261
262 #define PCNET_BCR_MIIADDR_PHYAD    0x03e0
263
264
265 // ANR registers
266 #define PCNET_ANR_PHYCTRL ( 0 |PCNET_ANR_FLAG)
267 #define PCNET_ANR_PHYSTAT ( 1 |PCNET_ANR_FLAG)
268 #define PCNET_ANR_AAR     ( 4 |PCNET_ANR_FLAG)
269
270 #define PCNET_ANR_PHYCTRL_100MBPS     0x2000
271 #define PCNET_ANR_PHYCTRL_RENEGOTIATE 0x0200
272 #define PCNET_ANR_PHYCTRL_DUPLEX      0x0100
273
274 #define PCNET_ANR_PHYSTAT_AUTONEG_COMP    0x0020
275 #define PCNET_ANR_PHYSTAT_LINK            0x0004
276
277 #define PCNET_ANR_AAR_100_FD      0x0100
278 #define PCNET_ANR_AAR_100_HD      0x0080
279 #define PCNET_ANR_AAR_100         0x0180
280 #define PCNET_ANR_AAR_10_FD       0x0040
281 #define PCNET_ANR_AAR_10_HD       0x0020
282 #define PCNET_ANR_AAR_10          0x0060
283
284 //----------------------------------------------------------------------------
285 // Receive buffer Descriptor
286 #if 1
287 #define PCNET_RD_PTR       0x00        // 32 bit
288 #define PCNET_RD_BLEN      0x04        // 16 bit (2's complement, negative)
289 #define PCNET_RD_MLEN      0x06        // 16 bit
290 #define PCNET_RD_SIZE      0x08
291
292 #define PCNET_RD_PTR_OWN       0x80000000
293 #define PCNET_RD_PTR_ERR       0x40000000
294 #define PCNET_RD_PTR_FRAM      0x20000000
295 #define PCNET_RD_PTR_OFLO      0x10000000
296 #define PCNET_RD_PTR_CRC       0x08000000
297 #define PCNET_RD_PTR_BUFF      0x04000000
298 #define PCNET_RD_PTR_STP       0x02000000
299 #define PCNET_RD_PTR_ENP       0x01000000
300 #define PCNET_RD_PTR_MASK      0x00ffffff
301 #else
302
303 #define PCNET_RD_PTR       0x00
304 #define PCNET_RD_BLEN      0x04
305 #define PCNET_RD_MLEN      0x08
306 #define PCNET_RD_USER      0x0c
307 #define PCNET_RD_SIZE      0x10
308
309 #define PCNET_RD_BLEN_OWN       0x80000000
310 #define PCNET_RD_BLEN_ERR       0x40000000
311 #define PCNET_RD_BLEN_FRAM      0x20000000
312 #define PCNET_RD_BLEN_OFLO      0x10000000
313 #define PCNET_RD_BLEN_CRC       0x08000000
314 #define PCNET_RD_BLEN_BUFF      0x04000000
315 #define PCNET_RD_BLEN_STP       0x02000000
316 #define PCNET_RD_BLEN_ENP       0x01000000
317 #define PCNET_RD_BLEN_BPE       0x00800000
318 #define PCNET_RD_BLEN_PAM       0x00400000
319 #define PCNET_RD_BLEN_LAFM      0x00200000
320 #define PCNET_RD_BLEN_BAM       0x00100000
321 #define PCNET_RD_BLEN_MASK      0x0000ffff
322 #endif
323
324 // Transmit buffer Descriptor
325 #if 1
326 #define PCNET_TD_PTR       0x00        // 32 bit
327 #define PCNET_TD_LEN       0x04        // 16 bit (2's complement, negative)
328 #define PCNET_TD_MISC      0x06        // 16 bit
329 #define PCNET_TD_SIZE      0x08
330
331 #define PCNET_TD_PTR_OWN       0x80000000
332 #define PCNET_TD_PTR_ERR       0x40000000
333 #define PCNET_TD_PTR_ADD_FCS   0x20000000
334 #define PCNET_TD_PTR_MORE      0x10000000
335 #define PCNET_TD_PTR_ONE       0x08000000
336 #define PCNET_TD_PTR_DEF       0x04000000
337 #define PCNET_TD_PTR_STP       0x02000000
338 #define PCNET_TD_PTR_ENP       0x01000000
339 #define PCNET_TD_PTR_MASK      0x00ffffff
340 #else
341 #define PCNET_TD_PTR       0x00
342 #define PCNET_TD_LEN       0x04
343 #define PCNET_TD_MISC      0x08
344 #define PCNET_TD_USER      0x0c
345 #define PCNET_TD_SIZE      0x10
346
347 #define PCNET_TD_LEN_OWN       0x80000000
348 #define PCNET_TD_LEN_ERR       0x40000000
349 #define PCNET_TD_LEN_ADD_FCS   0x20000000
350 #define PCNET_TD_LEN_MORE      0x10000000
351 #define PCNET_TD_LEN_ONE       0x08000000
352 #define PCNET_TD_LEN_DEF       0x04000000
353 #define PCNET_TD_LEN_STP       0x02000000
354 #define PCNET_TD_LEN_ENP       0x01000000
355 #define PCNET_TD_LEN_BPE       0x00800000
356 #define PCNET_TD_LEN_MASK      0x0000ffff
357
358 #define PCNET_TD_FLAGS_BUFF     0x80000000
359 #define PCNET_TD_FLAGS_UFLO     0x40000000
360 #define PCNET_TD_FLAGS_EX_DEF   0x20000000
361 #define PCNET_TD_FLAGS_LCOL     0x10000000
362 #define PCNET_TD_FLAGS_LCAR     0x08000000
363 #define PCNET_TD_FLAGS_RTRY     0x04000000
364 #define PCNET_TD_FLAGS_TRC_MASK 0x0000000f
365 #endif
366
367
368 #define PCNET_TD_MISC_BUFF     0x8000
369 #define PCNET_TD_MISC_UFLO     0x4000
370 #define PCNET_TD_MISC_EXDEF    0x2000
371 #define PCNET_TD_MISC_LCOL     0x1000
372 #define PCNET_TD_MISC_LCAR     0x0800
373 #define PCNET_TD_MISC_RTRY     0x0400
374 #define PCNET_TD_MISC_TDR      0x03ff
375
376 // Initialization Buffer
377 #define PCNET_IB_MODE            0
378 #define PCNET_IB_PADR0           2
379 #define PCNET_IB_PADR1           4
380 #define PCNET_IB_PADR2           6
381 #define PCNET_IB_LADRF0          8
382 #define PCNET_IB_LADRF1          10
383 #define PCNET_IB_LADRF2          12
384 #define PCNET_IB_LADRF3          14
385 #define PCNET_IB_RDRA            16
386 #define PCNET_IB_TDRA            20
387 #define PCNET_IB_SIZE            24
388
389 #define PCNET_IB_TDRA_CNT_shift  29
390 #define PCNET_IB_TDRA_PTR_mask   0x00ffffff
391 #define PCNET_IB_RDRA_CNT_shift  29
392 #define PCNET_IB_RDRA_PTR_mask   0x00ffffff
393
394 // ------------------------------------------------------------------------
395
396 #ifdef KEEP_STATISTICS
397 struct amd_pcnet_stats {
398     unsigned int tx_good             ;
399     unsigned int tx_max_collisions   ;
400     unsigned int tx_late_collisions  ;
401     unsigned int tx_underrun         ;
402     unsigned int tx_carrier_loss     ;
403     unsigned int tx_deferred         ;
404     unsigned int tx_sqetesterrors    ;
405     unsigned int tx_single_collisions;
406     unsigned int tx_mult_collisions  ;
407     unsigned int tx_total_collisions ;
408     unsigned int rx_good             ;
409     unsigned int rx_crc_errors       ;
410     unsigned int rx_align_errors     ;
411     unsigned int rx_resource_errors  ;
412     unsigned int rx_overrun_errors   ;
413     unsigned int rx_collisions       ;
414     unsigned int rx_short_frames     ;
415     unsigned int rx_too_long_frames  ;
416     unsigned int rx_symbol_errors    ;
417     unsigned int interrupts          ;
418     unsigned int rx_count            ;
419     unsigned int rx_deliver          ;
420     unsigned int rx_resource         ;
421     unsigned int rx_restart          ;
422     unsigned int tx_count            ;
423     unsigned int tx_complete         ;
424     unsigned int tx_dropped          ;
425 };
426 #endif
427
428 typedef struct pcnet_priv_data {
429     int index;
430     cyg_uint8                           // (split up for atomic byte access)
431         found:1,                        // was hardware discovered?
432         mac_addr_ok:1,                  // can we bring up?
433         active:1,                       // has this if been brung up?
434         hardwired_esa:1,                // set if ESA is hardwired via CDL
435         txbusy:1,                       // A packet has been sent
436         spare1:3; 
437
438     unsigned long txkey;                // Used to ack when packet sent
439     unsigned char* base;                // Base address of controller EPROM region
440     int interrupt;                      // Interrupt vector used by controller
441     unsigned char esa[6];            // Controller ESA
442     // Function to configure the ESA - may fetch ESA from EPROM or 
443     // RedBoot config option.
444     void (*config_esa)(struct pcnet_priv_data* cpd);
445     void *ndp;                          // Network Device Pointer
446
447     cyg_handle_t  interrupt_handle;
448     cyg_interrupt interrupt_object;
449     int devid;
450
451     cyg_uint8* rx_buffers;              // ptr to base of buffer mem
452     cyg_uint8* rx_ring;                 // ptr to base of rx ring memory
453     int rx_ring_cnt;                    // number of entries in ring
454     int rx_ring_log_cnt;                // log of above
455     int rx_ring_next;                   // index of next full ring entry
456
457     cyg_uint8* tx_buffers;
458     cyg_uint8* tx_ring;
459     int tx_ring_cnt;
460     int tx_ring_log_cnt;
461     int tx_ring_free;                   // index of next free ring entry
462     int tx_ring_alloc;                  // index of first controller owned ring
463     int tx_ring_owned;                  // number of controller owned ring entries
464
465     int rxpacket;
466 #ifdef KEEP_STATISTICS
467     struct amd_pcnet_stats stats;
468 #endif
469 #if DEBUG & 1
470     cyg_uint32 txd;
471 #endif
472 } pcnet_priv_data;
473
474 // ------------------------------------------------------------------------
475
476 static __inline__ cyg_uint16
477 get_reg(struct eth_drv_sc *sc, int regno)
478 {
479     struct pcnet_priv_data *cpd =
480         (struct pcnet_priv_data *)sc->driver_private;
481     cyg_uint16 val, addr;
482
483     if (regno & PCNET_ANR_FLAG) {
484         // We could do this with recursive calls to get/put reg
485         // functions, but might as well just do it directly.
486         // First set ANR address
487         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK);
488         HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr);
489         addr &= PCNET_BCR_MIIADDR_PHYAD;
490         addr |= (regno & PCNET_RAP_MASK);
491         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr);
492         // Then read ANR register data
493         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK);
494         HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val);
495     } else {
496         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK);
497         if (regno & PCNET_BCR_FLAG)
498             HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, val);
499         else
500             HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_RDP, val);
501     }
502 #if DEBUG & 2
503     os_printf("read %s reg %d val 0x%04x\n", 
504                 (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr", 
505                 regno & PCNET_RAP_MASK, val);
506 #endif
507     return val;
508 }
509
510 static __inline__ void
511 put_reg(struct eth_drv_sc *sc, int regno, cyg_uint16 val)
512 {
513     struct pcnet_priv_data *cpd =
514         (struct pcnet_priv_data *)sc->driver_private;
515     cyg_uint16 addr;
516
517     if (regno & PCNET_ANR_FLAG) {
518         // We could do this with recursive calls to get/put reg
519         // functions, but might as well just do it directly.
520         // First set ANR address
521         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIADDR & PCNET_RAP_MASK);
522         HAL_PCI_IO_READ_UINT16(cpd->base+PCNET_IO_BDP, addr);
523         addr &= PCNET_BCR_MIIADDR_PHYAD;
524         addr |= (regno & PCNET_RAP_MASK);
525         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, addr);
526         // Then write ANR register data
527         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, PCNET_BCR_MIIDATA & PCNET_RAP_MASK);
528         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val);
529     } else {
530         HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RAP, regno & PCNET_RAP_MASK);
531         if (regno & PCNET_BCR_FLAG)
532             HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_BDP, val);
533         else
534             HAL_PCI_IO_WRITE_UINT16(cpd->base+PCNET_IO_RDP, val);
535     }
536
537 #if DEBUG & 2
538     os_printf("write %s reg %d val 0x%04x\n", 
539                 (regno & PCNET_ANR_FLAG) ? "anr" : (regno & PCNET_BCR_FLAG) ? "bcr" : "csr", 
540                 regno & PCNET_RAP_MASK, val);
541 #endif
542 }
543
544 // ------------------------------------------------------------------------
545 #endif // CYGONCE_DEVS_ETH_AMD_PCNET_H
546 // EOF amd_pcnet.h