]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/mips/upd985xx/v2_0/src/if_upd985xx.c
Initial revision
[karo-tx-redboot.git] / packages / devs / eth / mips / upd985xx / v2_0 / src / if_upd985xx.c
1 //==========================================================================
2 //
3 //      if_upd985xx.c
4 //
5 //      Ethernet drivers
6 //      NEC UPD985XX device ethernet specific support
7 //
8 //==========================================================================
9 //####ECOSGPLCOPYRIGHTBEGIN####
10 // -------------------------------------------
11 // This file is part of eCos, the Embedded Configurable Operating System.
12 // Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
13 //
14 // eCos is free software; you can redistribute it and/or modify it under
15 // the terms of the GNU General Public License as published by the Free
16 // Software Foundation; either version 2 or (at your option) any later version.
17 //
18 // eCos is distributed in the hope that it will be useful, but WITHOUT ANY
19 // WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 // FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
21 // for more details.
22 //
23 // You should have received a copy of the GNU General Public License along
24 // with eCos; if not, write to the Free Software Foundation, Inc.,
25 // 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
26 //
27 // As a special exception, if other files instantiate templates or use macros
28 // or inline functions from this file, or you compile this file and link it
29 // with other works to produce a work based on this file, this file does not
30 // by itself cause the resulting work to be covered by the GNU General Public
31 // License. However the source code for this file must still be made available
32 // in accordance with section (3) of the GNU General Public License.
33 //
34 // This exception does not invalidate any other reasons why a work based on
35 // this file might be covered by the GNU General Public License.
36 //
37 // Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
38 // at http://sources.redhat.com/ecos/ecos-license/
39 // -------------------------------------------
40 //####ECOSGPLCOPYRIGHTEND####
41 //####BSDCOPYRIGHTBEGIN####
42 //
43 // -------------------------------------------
44 //
45 // Portions of this software may have been derived from OpenBSD or other sources,
46 // and are covered by the appropriate copyright disclaimers included herein.
47 //
48 // -------------------------------------------
49 //
50 //####BSDCOPYRIGHTEND####
51 //==========================================================================
52 //#####DESCRIPTIONBEGIN####
53 //
54 // Author(s):    hmt, gthomas
55 // Contributors:
56 // Date:         2001-06-28
57 // Purpose:      
58 // Description:  hardware driver for uPD985xx ethernet devices
59 //              
60 //
61 //####DESCRIPTIONEND####
62 //
63 //==========================================================================
64
65 #include <pkgconf/system.h>
66 #include <pkgconf/devs_eth_mips_upd985xx.h>
67 #include <pkgconf/io_eth_drivers.h>
68
69 #include <cyg/infra/cyg_type.h>
70 #include <cyg/infra/cyg_ass.h>
71 #include <cyg/hal/hal_arch.h>
72 #include <cyg/hal/hal_intr.h>
73 #include <cyg/hal/hal_cache.h>
74 #include <cyg/infra/diag.h>
75 #include <cyg/hal/drv_api.h>
76 #include <cyg/io/eth/netdev.h>
77 #include <cyg/io/eth/eth_drv.h>
78
79 #ifdef CYGPKG_NET
80 #include <pkgconf/net.h>
81 #include <net/if.h>  /* Needed for struct ifnet */
82 #else
83 #include <cyg/hal/hal_if.h>
84 #endif
85
86 #include <cyg/devs/eth/upd985xx_eth.h>
87
88 #include <cyg/io/eth/eth_drv_stats.h>
89
90 // ------------------------------------------------------------------------
91
92 #ifdef CYGDBG_DEVS_ETH_MIPS_UPD985XX_CHATTER
93 #define nDEBUG_TRAFFIC  // This one prints stuff as packets come and go
94 #define nDEBUG_IOCTL    // ioctl() call printing
95 #define DEBUG           // Startup printing mainly
96 #endif
97
98 #define os_printf diag_printf
99 #define db_printf diag_printf
100
101 #define STATIC static
102
103 // ------------------------------------------------------------------------
104 // I/O access macros as inlines for later changes to >1 device?
105 //
106 // (If we need to do this, then these macros would *assume* the
107 //  presence of a valid p_eth_upd985xx just like we always have)
108
109 static inline void OUTL( volatile cyg_uint32 *io_address, cyg_uint32 value )
110 {   *io_address = value;   }
111
112 static inline cyg_uint32 INL( volatile cyg_uint32 *io_address )
113 {   return *io_address;    }
114
115 // These map cachable addresses to uncachable ones and vice versa.
116 // This is all fixed on MIPS.  8-9xxxxxxx uncachable, A-Bxxxxxxx cachable.
117 #define VIRT_TO_BUS( _x_ ) virt_to_bus((cyg_uint32)(_x_))
118 static inline cyg_uint8 *virt_to_bus(cyg_uint32 p_memory)
119 {
120     return (cyg_uint8 *)(0xa0000000u + (p_memory  & ~0xe0000000u));
121 }
122 #define BUS_TO_VIRT( _x_ ) bus_to_virt((cyg_uint32)(_x_))
123 static inline cyg_uint8 *bus_to_virt(cyg_uint32 p_memory)
124 {
125     return (cyg_uint8 *)(0x80000000u + (p_memory  & ~0xe0000000u));
126 }
127
128
129 // ------------------------------------------------------------------------
130 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_S1
131 #define FLUSH_WRITES() CYG_MACRO_START          \
132     (void) INL( ETH_RXSR );                     \
133 CYG_MACRO_END
134 #else
135 #define FLUSH_WRITES() CYG_EMPTY_STATEMENT
136 #endif
137
138 // ------------------------------------------------------------------------
139 //
140 //                      DEVICES AND PACKET QUEUES
141 //
142 // ------------------------------------------------------------------------
143
144 // 128 bytes extra for VLAN packets should be enough; AFAICT usually the
145 // encapsulation is only 4 or 10 bytes extra.
146 #define MAX_ETHERNET_PACKET_SIZE  1536  // Ethernet Rx packet size
147 #define MAX_OVERSIZE_PACKET_SIZE  1664  // VLAN Rx packet size
148 #define MAX_RX_PACKET_SIZE        MAX_OVERSIZE_PACKET_SIZE
149
150 #define NUM_RXBUFS (8)
151
152 // This one is the hardware definition.
153 struct bufdesc {
154     volatile cyg_uint32 attr;
155     cyg_uint8 *ptr;
156 };
157
158 // Rx databuffer.
159 STATIC cyg_uint8 rx_databuf[ NUM_RXBUFS ] [ MAX_RX_PACKET_SIZE ];
160
161 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
162 // Tx databuffer
163 STATIC cyg_uint8 tx_databuf[ MAX_RX_PACKET_SIZE ];
164 #endif
165
166 struct eth_upd985xx {
167     cyg_uint8 active, index, tx_busy, mac_addr_ok;
168     cyg_uint8 vector; // interrupt numbers are small
169     cyg_uint8 phy_status; // from PHY_STATUS_ flags below
170     cyg_uint8 hardwired_esa;
171 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
172     cyg_uint8 promisc;
173 #endif
174     cyg_uint8 mac_address[6];
175
176     cyg_handle_t   interrupt_handle;
177     cyg_interrupt  interrupt_object;
178
179     struct cyg_netdevtab_entry *ndp;
180
181     // these shall hold uncached addresses of the structures following...
182     volatile struct bufdesc *txring;
183     volatile struct bufdesc *rxring_active;
184     volatile struct bufdesc *rxring_next;
185     int rxring_active_index;
186     int rxring_next_index;
187     cyg_uint32 intrs;
188     cyg_uint32 tx_keys[1];
189
190     // -----------------------------------------------------------------
191     // Statistics counters
192     cyg_uint32 count_rx_resource;
193     cyg_uint32 count_rx_restart;
194     cyg_uint32 count_interrupts;
195     cyg_uint32 count_bad_isr_restarts;
196     cyg_uint32 count_bad_tx_completion;
197
198     // -----------------------------------------------------------------
199     // DO NOT ACCESS THESE DIRECTLY - THE DEVICE HAS TO SEE THEM UNCACHED
200
201     // Initially, enough for one whole transmission to be described in one go,
202     // plus a null link on the end.
203     struct bufdesc tx_bufdesc[ MAX_ETH_DRV_SG + 2 ];
204
205     // Pending rx buffers, of full size.
206     struct bufdesc rx_bufdesc[ NUM_RXBUFS+1 ];
207
208     // -----------------------------------------------------------------
209 };
210
211 struct eth_upd985xx eth_upd985xx[CYGNUM_DEVS_ETH_MIPS_UPD985XX_DEV_COUNT] = {
212     {
213         index: 0,
214         vector: CYGNUM_HAL_INTERRUPT_ETHER, 
215 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
216         promisc: 0,
217 #endif
218 #ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_SET_ESA
219         hardwired_esa: 1,
220         mac_address: CYGDAT_DEVS_ETH_UPD985XX_ETH0_ESA,
221         mac_addr_ok: 1,
222 #else
223         hardwired_esa: 0,
224         mac_addr_ok: 0,
225 #endif
226     }
227 };
228
229 // eth0
230
231 ETH_DRV_SC(upd985xx_sc0,
232            &eth_upd985xx[0],            // Driver specific data
233            CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME, // name for this interface
234            eth_upd985xx_start,
235            eth_upd985xx_stop,
236            eth_upd985xx_ioctl,
237            eth_upd985xx_can_send,
238            eth_upd985xx_send,
239            eth_upd985xx_recv,
240            eth_upd985xx_deliver,
241            eth_upd985xx_poll,
242            eth_upd985xx_int_vector
243     );
244
245 NETDEVTAB_ENTRY(upd985xx_netdev0, 
246                 "upd985xx-" CYGDAT_DEVS_ETH_UPD985XX_ETH0_NAME,
247                 upd985xx_eth_upd985xx_init, 
248                 &upd985xx_sc0);
249
250
251 // This is in a macro so that if more devices arrive it can easily be changed
252 #define CHECK_NDP_SC_LINK() CYG_MACRO_START                              \
253     CYG_ASSERT( ((void *)ndp == (void *)&upd985xx_netdev0), "Bad ndp" ); \
254     CYG_ASSERT( ((void *)sc == (void *)&upd985xx_sc0), "Bad sc" );       \
255     CYG_ASSERT( (void *)p_eth_upd985xx == sc->driver_private,            \
256                 "sc pointer bad" );                                      \
257     CYG_ASSERT( (void *)p_eth_upd985xx == (void *)&eth_upd985xx[0],      \
258                 "bad p_eth_upd985x" );                                   \
259 CYG_MACRO_END
260
261 #define NUM_ELEMENTS( _x_ ) (sizeof( (_x_) ) / sizeof( (_x_[0]) ) )
262
263 // ------------------------------------------------------------------------
264 //
265 //                       FUNCTION PROTOTYPES
266 //
267 // ------------------------------------------------------------------------
268 STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx);
269 STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx);
270 STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx);
271 STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx);
272
273 #ifdef CYGPKG_NET
274 STATIC int eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx,
275                                   int promisc, int oversized);
276 #endif
277
278 STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx);
279 STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx);
280
281 #define PHY_STATUS_LINK    (1)
282 #define PHY_STATUS_FDX     (2)
283 #define PHY_STATUS_100MBPS (4)
284 STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx );
285 STATIC int eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data );
286
287 // ------------------------------------------------------------------------
288 //
289 //                       MII ACCESS TO PHY DEVICE
290 //
291 // ------------------------------------------------------------------------
292
293 STATIC cyg_bool mii_read( cyg_uint32 reg, cyg_uint32 *pvalue,
294                           struct eth_upd985xx *p_eth_upd985xx )
295 {
296     int i = 1000;
297     // wait a bit for it to be idle
298     while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
299                   & INL(ETH_MIND)) )
300         if ( --i < 0 )
301             return false;
302     // Tell it the register address and PHY address
303     OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg );
304     OUTL( ETH_MCMD, ETH_MCMD_RSTAT ); // "do a read"
305     // wait for the read to complete
306     while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
307                   & INL(ETH_MIND)) )
308         if ( --i < 0 )
309             return false;
310     // so get the data
311     *pvalue = INL( ETH_MRDD );
312     return true;
313 }
314
315 #if 0
316 STATIC cyg_bool mii_write( cyg_uint32 reg, cyg_uint32 value,
317                           struct eth_upd985xx *p_eth_upd985xx )
318 {
319     int i = 1000;
320     // wait a bit for it to be idle
321     while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
322                   & INL(ETH_MIND)) )
323         if ( --i < 0 )
324             return false;
325     // Tell it the register address and PHY address
326     OUTL( ETH_MADR, ETH_MADR_PHY_DEVICE_PHYS_ADDRESS | reg );
327     // And write the data:
328     OUTL( ETH_MWTD, value );
329     // wait a bit for it to be idle
330     while ( 0 != ((ETH_MIND_NVALID | ETH_MIND_SCANA | ETH_MIND_BUSY)
331                   & INL(ETH_MIND)) )
332         if ( --i < 0 )
333             return false;
334     return true;
335 }
336 #endif
337
338 // ------------------------------------------------------------------------
339 //
340 //                       INTERRUPT HANDLERS
341 //
342 // ------------------------------------------------------------------------
343
344 STATIC cyg_uint32 eth_isr(cyg_vector_t vector, cyg_addrword_t data)
345 {
346     cyg_drv_interrupt_mask( vector );
347
348     return CYG_ISR_CALL_DSR;        // schedule DSR
349 }
350
351 // ------------------------------------------------------------------------
352 // This is a callback from the higher level thread in consequence of the DSR
353 STATIC void
354 eth_upd985xx_deliver(struct eth_drv_sc *sc)
355 {
356     register int intrs;
357     struct eth_upd985xx *p_eth_upd985xx;
358     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
359
360     p_eth_upd985xx->count_interrupts++;
361
362     intrs = INL( ETH_ISR ); // Read-clear
363     // Acknowledge once at the start anyway to prevent an interrupt loop in
364     // case of a transient - interrupts latch in the interrupt controller
365     // as well as in the ethernet device.
366     cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
367
368 #ifdef DEBUG_TRAFFIC
369     os_printf("\n[[[[[[[ Deliver intrs = %x\n", intrs );
370 #endif
371
372     // Guard possible external entry points
373     if ( ! p_eth_upd985xx->active )
374         return; // without unmasking the interrupt
375
376     while ( intrs ) {
377         if ( 0xffff0000 & intrs ) {
378             // Then something very bad has happened
379             p_eth_upd985xx->count_bad_isr_restarts++;
380             CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" );
381             eth_upd985xx_stop( sc );
382             eth_upd985xx_start( sc, NULL, 0 );
383             intrs = INL( ETH_ISR ); // Read-clear
384         }
385         p_eth_upd985xx->intrs = intrs;
386         if ( ( ETH_ISR_XMTDN | ETH_ISR_TABR ) & intrs ) {
387             // Scan for completed Txen and inform the stack
388             TxDone(p_eth_upd985xx);
389         }
390         if ( ( ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU ) & intrs ) {
391             // Pass any rx data up the stack
392             PacketRxReady(p_eth_upd985xx);
393         }
394         // Now we have made the interrupt causes go away, acknowledge and
395         // *then* read the ISR again.  That way the race can result in a
396         // spurious interrupt rather than a lost interrupt.
397         cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
398         intrs = INL( ETH_ISR ); // Read-clear
399 #ifdef DEBUG_TRAFFIC
400         if ( intrs )
401             os_printf("------- Again intrs = %x\n", intrs );
402 #endif
403     }
404 #ifdef DEBUG_TRAFFIC
405     os_printf("]]]]]]]] Done intrs = %x\n\n", intrs );
406 #endif
407
408     cyg_drv_interrupt_unmask(p_eth_upd985xx->vector);
409 }
410
411 // ------------------------------------------------------------------------
412 // Device table entry to operate the chip in a polled mode.
413 // Only diddle the interface we were asked to!
414
415 STATIC void
416 eth_upd985xx_poll(struct eth_drv_sc *sc)
417 {
418     struct eth_upd985xx *p_eth_upd985xx;
419
420     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
421
422     // As it happens, this driver always requests the DSR to be called:
423     (void)eth_isr( p_eth_upd985xx->vector, (cyg_addrword_t)sc );
424     eth_upd985xx_deliver( sc );
425 }
426
427 // ------------------------------------------------------------------------
428 // Determine interrupt vector used by a device - for attaching GDB stubs
429 // packet handler.
430 STATIC int
431 eth_upd985xx_int_vector(struct eth_drv_sc *sc)
432 {
433     struct eth_upd985xx *p_eth_upd985xx;
434     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
435     return (p_eth_upd985xx->vector);
436 }
437
438 // ------------------------------------------------------------------------
439
440 STATIC int
441 eth_set_mac_address( struct eth_upd985xx *p_eth_upd985xx, void *data )
442 {
443     cyg_uint8 *p = (cyg_uint8 *)data;
444     cyg_uint8 *mac_address;
445
446     mac_address = &p_eth_upd985xx->mac_address[0];
447
448     mac_address[5] = p[5];
449     mac_address[4] = p[4];
450     mac_address[3] = p[3];
451     mac_address[2] = p[2];
452     mac_address[1] = p[1];
453     mac_address[0] = p[0];
454
455     p_eth_upd985xx->mac_addr_ok = 1;
456
457     // Set the ESA in the device regs
458     OUTL( ETH_LSA2,
459           (p_eth_upd985xx->mac_address[1]) |
460           (p_eth_upd985xx->mac_address[0] << 8 ) );
461     OUTL( ETH_LSA1,
462           (p_eth_upd985xx->mac_address[5]) |
463           (p_eth_upd985xx->mac_address[4] << 8 ) |
464           (p_eth_upd985xx->mac_address[3] << 16 ) |
465           (p_eth_upd985xx->mac_address[2] << 24) );
466
467     return 0; // OK
468 }
469
470 // ------------------------------------------------------------------------
471
472 STATIC void
473 eth_upd985xx_reset( struct eth_upd985xx *p_eth_upd985xx )
474 {
475     int i;
476
477     // Reset whole device: Software Reset (clears automatically)
478     OUTL( ETH_CCR, ETH_CCR_SRT );
479     for ( i = 0; i < 10000; i++ ) /* nothing */;
480     // Reset internal units
481     OUTL( ETH_MACC2, ETH_MACC2_MCRST | ETH_MACC2_RFRST | ETH_MACC2_TFRST );
482     for ( i = 0; i < 10000; i++ ) /* nothing */;
483     FLUSH_WRITES();
484     OUTL( ETH_MACC2, 0 ); // (and release reset)
485     // Enable CRC adding, padding
486     FLUSH_WRITES();
487     OUTL( ETH_MACC1,
488           ETH_MACC1_CRCEN | ETH_MACC1_PADEN |
489           ETH_MACC1_TXFC | ETH_MACC1_RXFC | ETH_MACC1_PARF );
490     FLUSH_WRITES();
491     OUTL( ETH_MACC2, ETH_MACC2_APD ); // Auto VLAN pad
492     FLUSH_WRITES();
493     OUTL( ETH_HT1, 0 );
494     FLUSH_WRITES();
495     OUTL( ETH_HT2, 0 );
496
497     // Enable rx of broadcasts, multicasts, but not promiscuous...
498     FLUSH_WRITES();
499 #if defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2 ) && \
500     !defined( CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY )
501     // Unless we are faking it.
502     OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM | ETH_AFR_PRO );
503 #else
504     OUTL( ETH_AFR, ETH_AFR_ABC | ETH_AFR_PRM );
505 #endif
506
507     FLUSH_WRITES();
508     OUTL( ETH_IPGT, 0x00000013 );
509     FLUSH_WRITES();
510     OUTL( ETH_IPGR, 0x00000e13 );
511     FLUSH_WRITES();
512     OUTL( ETH_CLRT, 0x0000380f );
513     FLUSH_WRITES();
514     OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE );
515
516     // Select a clock for the MII
517     FLUSH_WRITES();
518     OUTL( ETH_MIIC, ETH_MIIC_66 ); // Example code sets to 66.
519     // Set VLAN type reg
520     FLUSH_WRITES();
521     OUTL( ETH_VLTP, ETH_VLTP_VLTP );
522
523     // Set the ESA in the device regs
524     if ( p_eth_upd985xx->mac_addr_ok ) {
525         FLUSH_WRITES();
526         OUTL( ETH_LSA2,
527               (p_eth_upd985xx->mac_address[1]) |
528               (p_eth_upd985xx->mac_address[0] << 8 ) );
529         FLUSH_WRITES();
530         OUTL( ETH_LSA1,
531               (p_eth_upd985xx->mac_address[5]) |
532               (p_eth_upd985xx->mac_address[4] << 8 ) |
533               (p_eth_upd985xx->mac_address[3] << 16 ) |
534               (p_eth_upd985xx->mac_address[2] << 24) );
535     }
536
537     FLUSH_WRITES();
538     OUTL( ETH_RXFCR, ETH_RXFCR_UWM_DEFAULT |
539                      ETH_RXFCR_LWM_DEFAULT | ETH_RXFCR_DRTH16W ); 
540
541     FLUSH_WRITES();
542     // Fault E4 - use only 32 for FLTH, not the previously recommended 48 (words)
543     // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4
544     // but no config opt is provided.
545     OUTL( ETH_TXFCR, ETH_TXFCR_TPTV_DEFAULT |
546                      ETH_TXFCR_TX_DRTH_DEFAULT | (32 << ETH_TXFCR_TX_FLTH_SHIFT) );
547
548     // Transmit and receive config regs we hit when enabling those
549     // functions separately, and the wet string end of the receiver
550     // which is controlled by   MACC1 |= ETH_MACC1_SRXEN;
551
552     // Tx and Rx interrupts enabled internally; 
553     // Tx done/aborted, and rx OK.
554     FLUSH_WRITES();
555     OUTL( ETH_MSR, ETH_ISR_XMTDN | ETH_ISR_TABR | 
556                    ETH_ISR_RCVDN | ETH_ISR_RBDRS | ETH_ISR_RBDRU );
557     FLUSH_WRITES();
558 }
559
560 // ------------------------------------------------------------------------
561 //
562 //                NETWORK INTERFACE INITIALIZATION
563 //
564 // ------------------------------------------------------------------------
565 STATIC bool
566 upd985xx_eth_upd985xx_init(struct cyg_netdevtab_entry * ndp)
567 {
568     struct eth_drv_sc *sc;
569     cyg_uint8 *mac_address;
570     struct eth_upd985xx *p_eth_upd985xx;
571
572 #ifdef DEBUG
573     db_printf("upd985xx_eth_upd985xx_init\n");
574 #endif
575
576     sc = (struct eth_drv_sc *)(ndp->device_instance);
577     p_eth_upd985xx = (struct eth_upd985xx *)(sc->driver_private);
578
579     CHECK_NDP_SC_LINK();
580
581     p_eth_upd985xx->tx_busy = 0;
582
583     // record the net dev pointer
584     p_eth_upd985xx->ndp = (void *)ndp;
585
586     mac_address = &p_eth_upd985xx->mac_address[0];
587
588 #ifdef CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
589     if ( ! p_eth_upd985xx->hardwired_esa ) {
590         cyg_uint8 *p;
591         union macar {
592             struct {
593                 cyg_uint32 macar1, macar2, macar3;
594             } integers;
595             cyg_uint8 bytes[12];
596         } eeprom;
597
598         eeprom.integers.macar1 = INL( MACAR1 );  // MAC Address Register 1
599         eeprom.integers.macar2 = INL( MACAR2 );  // MAC Address Register 2
600         eeprom.integers.macar3 = INL( MACAR3 );  // MAC Address Register 3
601
602         if ( (0 != eeprom.integers.macar1 ||
603               0 != eeprom.integers.macar2 ||
604               0 != eeprom.integers.macar3 )
605              && 
606              (0xffffffff != eeprom.integers.macar1 ||
607               0xffffffff != eeprom.integers.macar2 ||
608               0xffffffff != eeprom.integers.macar3 ) ) {
609             // Then we have good data in the EEPROM
610 #ifdef DEBUG
611             os_printf( "EEPROM data %08x %08x %08x\n", 
612                        eeprom.integers.macar1,
613                        eeprom.integers.macar2,
614                        eeprom.integers.macar3 );
615 #endif
616             p = &eeprom.bytes[0]; // pick up either set of ESA info
617             if ( 1 == p_eth_upd985xx->index )
618                 p += 6;
619
620             mac_address[5] = p[5];
621             mac_address[4] = p[4];
622             mac_address[3] = p[3];
623             mac_address[2] = p[2];
624             mac_address[1] = p[1];
625             mac_address[0] = p[0];
626             p_eth_upd985xx->mac_addr_ok = 1;
627         }
628         else {
629             // Fake it so we can get RedBoot going on a board with no EEPROM
630             mac_address[0] = 0;
631             mac_address[1] = 0xBA;
632             mac_address[2] = 0xD0;
633             mac_address[3] = 0xEE;
634             mac_address[4] = 0x00;
635             mac_address[5] = p_eth_upd985xx->index;
636             p_eth_upd985xx->mac_addr_ok = 1;
637         }
638     }
639 #endif // CYGSEM_DEVS_ETH_UPD985XX_ETH0_GET_EEPROM_ESA
640     
641     // Init the underlying hardware and insert the ESA:
642     eth_upd985xx_reset(p_eth_upd985xx);
643
644 #ifdef DEBUG
645     os_printf("MAC Address %s, ESA = %02X %02X %02X %02X %02X %02X\n",
646               p_eth_upd985xx->mac_addr_ok ? "OK" : "**BAD**", 
647               mac_address[0], mac_address[1], mac_address[2], mac_address[3],
648               mac_address[4], mac_address[5]);
649 #endif
650
651     // Set up the pointers to data structures
652     InitTxRing(p_eth_upd985xx);
653
654     // Construct the interrupt handler
655     p_eth_upd985xx->active = 0;
656     cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
657     cyg_drv_interrupt_mask(p_eth_upd985xx->vector);
658     cyg_drv_interrupt_create(
659         p_eth_upd985xx->vector,
660         0,                              // Priority - unused
661         (CYG_ADDRWORD)sc,               // Data item passed to ISR & DSR
662         eth_isr,                        // ISR
663         eth_drv_dsr,                    // DSR (generic)
664         &p_eth_upd985xx->interrupt_handle, // handle to intr obj
665         &p_eth_upd985xx->interrupt_object ); // space for int obj
666
667     cyg_drv_interrupt_attach(p_eth_upd985xx->interrupt_handle);
668
669     // Initialize upper level driver
670     if ( p_eth_upd985xx->mac_addr_ok )
671         (sc->funs->eth_drv->init)(sc, &(p_eth_upd985xx->mac_address[0]) );
672     else
673         (sc->funs->eth_drv->init)(sc, 0 );
674     
675     return (1);
676 }
677
678 // ------------------------------------------------------------------------
679 //
680 //  Function : eth_upd985xx_start
681 //
682 // ------------------------------------------------------------------------
683 STATIC void
684 eth_upd985xx_start( struct eth_drv_sc *sc,
685                     unsigned char *enaddr, int flags )
686 {
687     struct eth_upd985xx *p_eth_upd985xx;
688     cyg_uint32 ss; 
689 #ifdef CYGPKG_NET
690     struct ifnet *ifp = &sc->sc_arpcom.ac_if;
691 #endif
692
693     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
694
695 #ifdef DEBUG
696     os_printf("eth_upd985xx_start %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx );
697 #endif
698
699     if ( p_eth_upd985xx->active )
700         eth_upd985xx_stop( sc );
701
702     p_eth_upd985xx->active = 1;
703     
704 #ifdef CYGPKG_NET
705     /* Enable promiscuous mode if requested, reception of oversized frames always.
706      * The latter is needed for VLAN support and shouldn't hurt even if we're not
707      * using VLANs.
708      */
709     eth_upd985xx_configure(p_eth_upd985xx, !!(ifp->if_flags & IFF_PROMISC), 1);
710 #endif
711
712     // renegotiate link status
713     p_eth_upd985xx->phy_status = eth_upd985xx_status( p_eth_upd985xx );
714
715     if ( p_eth_upd985xx->phy_status & PHY_STATUS_FDX ) {
716         cyg_uint32 ss;
717         // then enable full duplex in the MAC
718         ss = INL( ETH_MACC1 );
719         ss |= ETH_MACC1_FDX;
720         OUTL( ETH_MACC1, ss );
721     }
722
723 #ifdef DEBUG
724     {
725         int status = p_eth_upd985xx->phy_status;
726         os_printf("eth_upd985xx_start %d Link = %s, %s Mbps, %s Duplex\n",
727                   p_eth_upd985xx->index,
728                   status & PHY_STATUS_LINK ? "Up" : "Down",
729                   status & PHY_STATUS_100MBPS ?  "100" : "10",
730                   status & PHY_STATUS_FDX ? "Full" : "Half"
731             );
732     }
733 #endif
734
735
736     // Start the receive engine
737     p_eth_upd985xx->count_rx_restart++;
738     // Initialize all but one buffer: [B0,B1,B2,...Bx,NULL,LINK]
739     InitRxRing( p_eth_upd985xx );
740     // Point the hardware at the list of buffers
741     OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active );
742     // Tell it about the buffers via the rx descriptor count
743     OUTL( ETH_RXPDR, ETH_RXPDR_AL | (NUM_RXBUFS-1) );
744     // Ack any pending interrupts from the system
745     p_eth_upd985xx->intrs = INL( ETH_ISR ); // Read-clear
746     // Start the rx.
747     OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 );
748
749     // Enable the wet string end of the receiver
750     ss = INL( ETH_MACC1 );
751     ss |= ETH_MACC1_SRXEN;
752     OUTL( ETH_MACC1, ss );
753
754     // And unmask the interrupt
755     cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
756     cyg_drv_interrupt_unmask(p_eth_upd985xx->vector);
757 }
758
759 // ------------------------------------------------------------------------
760 //
761 //  Function : eth_upd985xx_status; 10/100 and Full/Half Duplex (FDX/HDX)
762 //
763 // ------------------------------------------------------------------------
764 STATIC int eth_upd985xx_status( struct eth_upd985xx *p_eth_upd985xx )
765 {
766     int status;
767     int i, j;
768     // Some of these bits latch and only reflect "the truth" on a 2nd reading.
769     // So read and discard.
770     mii_read( PHY_CONTROL_REG, &i, p_eth_upd985xx );
771     mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx );
772     // Use the "and" of the local and remote capabilities words to infer
773     // what is selected:
774     status = 0;
775     if ( mii_read( PHY_STATUS_REG, &i, p_eth_upd985xx ) ) {
776         if ( PHY_STATUS_LINK_OK & i )
777             status |= PHY_STATUS_LINK;
778     }
779     if ( mii_read( PHY_AUTONEG_ADVERT, &j, p_eth_upd985xx ) && 
780          mii_read( PHY_AUTONEG_REMOTE, &i, p_eth_upd985xx ) ) {
781 #if defined( DEBUG_TRAFFIC ) || defined( DEBUG_IOCTL )
782         os_printf( "MII: capabilities are %04x, %04x; common %04x\n",
783                    i, j, i & j );
784 #endif
785         j &= i; // select only common capabilities
786
787         if ( (PHY_AUTONEG_100BASET4 |
788               PHY_AUTONEG_100BASETX_FDX |
789               PHY_AUTONEG_100BASETX_HDX)  & j )
790             status |= PHY_STATUS_100MBPS;
791         if ( (PHY_AUTONEG_100BASETX_FDX | PHY_AUTONEG_10BASET_FDX) & j )
792             status |= PHY_STATUS_FDX;
793     }
794     return status;
795 }
796
797 // ------------------------------------------------------------------------
798 //
799 //  Function : eth_upd985xx_stop
800 //
801 // ------------------------------------------------------------------------
802
803 STATIC void eth_upd985xx_stop( struct eth_drv_sc *sc )
804 {
805     struct eth_upd985xx *p_eth_upd985xx;
806
807     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
808
809     // No more interrupts
810     cyg_drv_interrupt_acknowledge(p_eth_upd985xx->vector);
811     cyg_drv_interrupt_mask(p_eth_upd985xx->vector);
812
813 #ifdef DEBUG
814     os_printf("eth_upd985xx_stop %d flg %x\n", p_eth_upd985xx->index, *(int *)p_eth_upd985xx );
815 #endif
816
817     p_eth_upd985xx->active = 0;         // stop people tormenting it
818
819     if ( p_eth_upd985xx->tx_busy ) {
820         // Then it is finshed now, by force:
821         cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ];
822         // Turn off the transmitter (before the callback to the stack).
823         OUTL( ETH_TXCR, 0 );
824 #ifdef DEBUG_TRAFFIC
825         os_printf("Stop: tidying up TX, KEY %x\n", key );
826 #endif
827         // Leave tx_busy true so no recursion can occur here.
828         // Then tell the stack we are done:
829         if ( key ) {
830             (sc->funs->eth_drv->tx_done)( sc, key, 0 );
831         }
832     }
833     p_eth_upd985xx->tx_keys[ 0 ] = 0;
834     p_eth_upd985xx->tx_busy = p_eth_upd985xx->active = 0;
835
836     eth_upd985xx_reset(p_eth_upd985xx);
837
838     ResetTxRing( p_eth_upd985xx );
839 }
840
841
842 // ------------------------------------------------------------------------
843 //
844 //  Function : InitRxRing
845 //
846 // ------------------------------------------------------------------------
847 STATIC void InitRxRing(struct eth_upd985xx* p_eth_upd985xx)
848 {
849     int i;
850     struct bufdesc *bp;
851
852     // first just blat the various flags and addresses: the first N
853     // bufdescs point to data buffers, the last one is NULL.
854     bp = (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[0] );
855     // Record the initial active buffer:
856     p_eth_upd985xx->rxring_active = bp;
857     p_eth_upd985xx->rxring_active_index = 0;
858     for ( i = 0; i < NUM_RXBUFS - 1; i++, bp++ ) {
859         bp->ptr = VIRT_TO_BUS( &rx_databuf[i][0] );
860         bp->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU
861                      | (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) );
862     }
863     CYG_ASSERT( i == NUM_RXBUFS-1, "Penultimate rx buffer index mismatch" );
864     CYG_ASSERT( (cyg_uint8 *)bp == 
865                 VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS-1] ),
866                 "Penultimate rx buffer address mismatch" );
867
868     // NULL out the penultimate one
869     bp->ptr = NULL;
870     bp->attr = 0;
871     // And record it as next one to use
872     p_eth_upd985xx->rxring_next = bp;
873     p_eth_upd985xx->rxring_next_index = NUM_RXBUFS-1;
874
875     // Step on to the extra entry at the end which makes a ring:
876     bp++;
877     CYG_ASSERT( (cyg_uint8 *)bp == 
878                 VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[NUM_RXBUFS] ),
879                 "Ultimate rx buffer address mismatch" );
880
881     // Link the Ultimate back to the start
882     bp->ptr = (cyg_uint8 *)p_eth_upd985xx->rxring_active; // Zeroth entry
883     bp->attr = ETH_BUF_D_L_LINK;
884
885     // All done.
886 }
887
888
889 // ------------------------------------------------------------------------
890 //
891 //  Function : NextRxRing
892 //
893 // ------------------------------------------------------------------------
894
895 STATIC void NextRxRing(struct eth_upd985xx* p_eth_upd985xx )
896 {
897     volatile struct bufdesc *next, *dead;
898     int iactive;
899     int inext;
900
901     iactive = p_eth_upd985xx->rxring_active_index;
902     inext = p_eth_upd985xx->rxring_next_index;
903
904     // Preconditions:
905     CYG_ASSERT( 0 <=   inext && inext   < NUM_RXBUFS, "Bad inext" );
906     CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" );
907     CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] )
908                 == (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" );
909     CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] )
910                 == (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" );
911     CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" );
912     CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" );
913     CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" );
914     CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) ==
915                 p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" );
916     CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext),
917                 "Chasing pointers mismatch" );
918
919     // Select the new bufdesc to be active - ie. next to scan for reception:
920     if ( ++iactive >= NUM_RXBUFS )
921         iactive = 0;
922     dead = p_eth_upd985xx->rxring_active; // the one that just died
923     // Step ahead the new active buffer:
924     p_eth_upd985xx->rxring_active = (volatile struct bufdesc *)
925         VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] );
926     p_eth_upd985xx->rxring_active_index = iactive;
927
928     // Blow away the currently active entry; we have dealt with it already
929     // and it is needed for an end stop to the ring:
930     dead->ptr = NULL;
931     dead->attr = 0;
932    
933     // Select the next bufdesc to enliven
934     next = p_eth_upd985xx->rxring_next;
935     next->ptr = VIRT_TO_BUS( &rx_databuf[inext][0] );
936     next->attr = ( ETH_BUF_D_L_DATA | ETH_BUF_OWN_CPU
937                    | (ETH_BUF_SIZE & sizeof( rx_databuf[0] )) );
938
939     // And update the external info to reflect this:
940     if ( ++inext >= NUM_RXBUFS )
941         inext = 0;
942     next = (volatile struct bufdesc *)
943         VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] );
944
945     p_eth_upd985xx->rxring_next = next;
946     p_eth_upd985xx->rxring_next_index = inext;
947
948     // Postconditions:
949     CYG_ASSERT( 0 <=   inext && inext   < NUM_RXBUFS, "Bad inext" );
950     CYG_ASSERT( 0 <= iactive && iactive < NUM_RXBUFS, "Bad iactive" );
951     CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ inext ] )
952                 == (cyg_uint8 *)p_eth_upd985xx->rxring_next, "Next rx_bufdesc bad" );
953     CYG_ASSERT( VIRT_TO_BUS( &p_eth_upd985xx->rx_bufdesc[ iactive ] )
954                 == (cyg_uint8 *)p_eth_upd985xx->rxring_active, "Active rx_bufdesc bad" );
955     CYG_ASSERT( ETH_BUF_D_L_LINK == p_eth_upd985xx->rxring_next->attr, "Next not a link" );
956     CYG_ASSERT( ETH_BUF_D_L_DATA & p_eth_upd985xx->rxring_active->attr, "Active not data" );
957     CYG_ASSERT( NULL == p_eth_upd985xx->rxring_next->ptr, "Next not NULL" );
958     CYG_ASSERT( VIRT_TO_BUS( &rx_databuf[iactive][0] ) ==
959                 p_eth_upd985xx->rxring_active->ptr, "Active bad data pointer" );
960     CYG_ASSERT( (iactive - 1 == inext) || (0 == iactive && NUM_RXBUFS - 1 == inext),
961                 "Chasing pointers mismatch" );
962 }
963
964 // ------------------------------------------------------------------------
965 //
966 //  Function : PacketRxReady        (Called from delivery thread)
967 //
968 // ------------------------------------------------------------------------
969 STATIC void PacketRxReady(struct eth_upd985xx* p_eth_upd985xx)
970 {
971     struct cyg_netdevtab_entry *ndp;
972     struct eth_drv_sc *sc;
973     cyg_uint32 ss, length;
974     cyg_bool reset_required = 0;
975
976     ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp);
977     sc = (struct eth_drv_sc *)(ndp->device_instance);
978
979     CHECK_NDP_SC_LINK();
980
981 #ifdef DEBUG_TRAFFIC
982     ss = INL( ETH_RXSR );
983     os_printf("PacketRxReady: RXSR %x\n", ss );
984 #endif
985
986     if ( ETH_ISR_RBDRU & p_eth_upd985xx->intrs )
987         reset_required = 1; // Out of buffers
988     if ( ! ETH_ISR_RCVDN & p_eth_upd985xx->intrs )
989         reset_required = 1; // or if no reception completed, reset anyway
990
991     // For all ready rx blocks...
992     do {
993         volatile struct bufdesc *bp;
994
995         bp = p_eth_upd985xx->rxring_active; // Current rx candidate
996
997         ss = bp->attr;
998 #ifdef DEBUG_TRAFFIC
999         os_printf("PacketRxReady attr %x at %x\n", ss, bp );
1000 #endif
1001         if ( ETH_BUF_OWN_CPU == (ETH_BUF_OWN & ss) ) {
1002             // Then the packet is untouched...
1003             break;
1004         }
1005 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
1006         // Perform address recognition by hand, hardware is in promisc mode
1007         // (we have settable "software" promisc mode too of course)
1008         if ( ETH_BUF_OK & ss ) {
1009             cyg_uint8 *esa = (cyg_uint8 *)bp->ptr; // (this is a non-cachable address)
1010             int ok = 0;
1011             if ( p_eth_upd985xx->promisc )
1012                 ok = 1; // accept the packet
1013             else
1014             if ( p_eth_upd985xx->mac_address[0] == esa[0] &&
1015                  p_eth_upd985xx->mac_address[1] == esa[1] &&
1016                  p_eth_upd985xx->mac_address[2] == esa[2] &&
1017                  p_eth_upd985xx->mac_address[3] == esa[3] &&
1018                  p_eth_upd985xx->mac_address[4] == esa[4] &&
1019                  p_eth_upd985xx->mac_address[5] == esa[5] )
1020                 ok = 1; // Then they are equal - accept
1021             else
1022             if ( 0xff == esa[0] &&
1023                  0xff == esa[1] &&
1024                  0xff == esa[2] &&
1025                  0xff == esa[3] &&
1026                  0xff == esa[4] &&
1027                  0xff == esa[5] )
1028                 ok = 1; // Then they are equal - accept
1029
1030             if ( !ok )
1031                 ss = 0; // Easiest way...
1032         }
1033 #endif
1034         if ( ETH_BUF_OK & ss ) {
1035             length = ETH_BUF_SIZE & ss;
1036 #ifdef DEBUG_TRAFFIC
1037             os_printf("PacketRxReady found a packet size %d attr %x\n", length, ss );
1038 #endif
1039             // Asserts for the length in-range can fire, with good status
1040             // in the block, so be defensive here instead.  Belt and braces.
1041             if ( 63 < length && length <= MAX_RX_PACKET_SIZE ) {
1042                 CYG_ASSERT( ETH_BUF_D_L_DATA == (ETH_BUF_D_L & ss), "Not data buffer" );
1043                 CYG_ASSERT( length > 63, "Tiny packet" );
1044                 CYG_ASSERT( length <= MAX_RX_PACKET_SIZE, "Too big packet" );
1045                 CYG_ASSERT( ETH_BUF_LAST & ss, "Not last buffer" );
1046                 (sc->funs->eth_drv->recv)( sc, length );
1047             } // Else drop it on the floor.
1048         }
1049
1050         // Step along to the next buffer descriptor...
1051         NextRxRing( p_eth_upd985xx );
1052         if ( ! reset_required ) {
1053             // And tell the device it can have a biscuit:
1054             OUTL( ETH_RXPDR, ETH_RXPDR_AL | 1 );
1055
1056             // Now, before moving on to the next packet, find out if receptions
1057             // had caught up with us before adding that new buffer:
1058             ss = INL( ETH_RXPDR );
1059             ss &= ETH_RXPDR_RNOD;
1060             ss >>= ETH_RXPDR_RNOD_SHIFT;
1061             if ( 1 >= ss ) {
1062                 // Then it was zero before.  So the rx engine is stopped.
1063 #ifdef DEBUG_TRAFFIC
1064                 os_printf( "***ZERO rx buffers were left\n" );
1065 #endif
1066                 reset_required = 1;
1067             }
1068             // Otherwise we carry on as usual.
1069         }
1070     } while ( 1 );
1071
1072     if ( reset_required ) {
1073         p_eth_upd985xx->count_rx_resource++;
1074         // Disable the wet string end of the receiver
1075         ss = INL( ETH_MACC1 );
1076         ss &=~ETH_MACC1_SRXEN;
1077         OUTL( ETH_MACC1, ss );
1078         // Disable the DMA engine
1079         OUTL( ETH_RXCR, 0 );
1080         // Reset the RxRing from scratch
1081         InitRxRing( p_eth_upd985xx );
1082         // Point the hardware at the list of buffers
1083         OUTL( ETH_RXDPR, (cyg_uint32)p_eth_upd985xx->rxring_active );
1084         // Tell it about the buffers via the rx descriptor count:
1085         ss = INL( ETH_RXPDR );
1086         ss &= ETH_RXPDR_RNOD;
1087         ss >>= ETH_RXPDR_RNOD_SHIFT;
1088         // This awful register *increments* by what you write, even if the
1089         // machinery is halted.  Vile filthy evil rubbish.
1090         OUTL( ETH_RXPDR, ETH_RXPDR_AL | ((NUM_RXBUFS-1) - ss)  );
1091         ss = INL( ETH_RXPDR );
1092         CYG_ASSERT( (ETH_RXPDR_AL | (NUM_RXBUFS-1)) == ss, "RXPDR not right" );
1093         // Start the rx.
1094         OUTL( ETH_RXCR, ETH_RXCR_RXE | ETH_RXCR_DRBS_16 );
1095         // Enable the wet string end of the receiver
1096         ss = INL( ETH_MACC1 );
1097         ss |= ETH_MACC1_SRXEN;
1098         OUTL( ETH_MACC1, ss );
1099         // All done.
1100 #ifdef DEBUG_TRAFFIC
1101         os_printf( "***Rx Machine restarted\n" );
1102 #endif
1103     }
1104 }
1105
1106 // and the callback function
1107
1108 STATIC void
1109 eth_upd985xx_recv( struct eth_drv_sc *sc,
1110                    struct eth_drv_sg *sg_list, int sg_len )
1111 {
1112     struct eth_upd985xx *p_eth_upd985xx;
1113     int total_len;
1114     struct eth_drv_sg *last_sg;
1115     cyg_uint8 *from_p;
1116     volatile struct bufdesc *bp;
1117
1118     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1119     
1120     // Guard possible external entry points
1121     if ( ! p_eth_upd985xx->active )
1122         return;
1123
1124     bp = p_eth_upd985xx->rxring_active; // Current rx candidate
1125
1126 #ifdef DEBUG_TRAFFIC
1127     os_printf("Rx status %x\n", bp->attr );
1128 #endif
1129
1130     if ( 0 == (ETH_BUF_OK & bp->attr) )
1131         return;
1132         
1133     total_len = ETH_BUF_SIZE & bp->attr;
1134     
1135 #ifdef DEBUG_TRAFFIC
1136     os_printf("Rx %d %x (status %x): %d sg's, %d bytes\n",
1137               p_eth_upd985xx->index, (int)p_eth_upd985xx,
1138               bp->attr,
1139               sg_len, total_len);
1140 #endif
1141
1142     // Copy the data to the network stack
1143     from_p = bp->ptr; // (this is a non-cachable address)
1144
1145     // check we have memory to copy into; we would be called even if
1146     // caller was out of memory in order to maintain our state.
1147     if ( 0 == sg_len || 0 == sg_list )
1148         return; // caller was out of mbufs
1149
1150     CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
1151     CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
1152
1153     for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1154         cyg_uint8 *to_p;
1155         int l;
1156             
1157         to_p = (cyg_uint8 *)(sg_list->buf);
1158         l = sg_list->len;
1159
1160         CYG_ASSERT( 0 <= l, "sg length -ve" );
1161
1162         if ( 0 >= l || 0 == to_p )
1163             return; // caller was out of mbufs
1164
1165         if ( l > total_len )
1166             l = total_len;
1167
1168         memcpy( to_p, from_p, l );
1169         from_p += l;
1170         total_len -= l;
1171     }
1172
1173     CYG_ASSERT( 0 == total_len, "total_len mismatch in rx" );
1174     CYG_ASSERT( last_sg == sg_list, "sg count mismatch in rx" );
1175     CYG_ASSERT( bp->ptr < from_p, "from_p wild in rx" );
1176     CYG_ASSERT( bp->ptr + MAX_RX_PACKET_SIZE >= from_p,
1177                 "from_p overflow in rx" );
1178 }    
1179
1180
1181 // ------------------------------------------------------------------------
1182 //
1183 //  Function : InitTxRing
1184 //
1185 // ------------------------------------------------------------------------
1186 STATIC void InitTxRing(struct eth_upd985xx* p_eth_upd985xx)
1187 {
1188     int i;
1189     volatile struct bufdesc *bp;
1190     
1191     p_eth_upd985xx->txring =
1192         (struct bufdesc *)VIRT_TO_BUS( &p_eth_upd985xx->tx_bufdesc[0] );
1193
1194     bp = p_eth_upd985xx->txring;
1195
1196     for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ); i++, bp++ ) {
1197         bp->ptr = NULL;
1198         bp->attr = 0;
1199     }
1200     // Last one is a NULL link
1201     bp--;
1202     bp->ptr = NULL;
1203     bp->attr = ETH_BUF_D_L_LINK;
1204
1205     ResetTxRing(p_eth_upd985xx);
1206 }
1207
1208 // ------------------------------------------------------------------------
1209 //
1210 //  Function : ResetTxRing
1211 //
1212 // ------------------------------------------------------------------------
1213 STATIC void ResetTxRing(struct eth_upd985xx* p_eth_upd985xx)
1214 {
1215     int i;
1216     volatile struct bufdesc *bp;
1217     bp = p_eth_upd985xx->txring;
1218     for ( i = 0; i < NUM_ELEMENTS( p_eth_upd985xx->tx_bufdesc ) - 1; i++, bp++ ) {
1219         bp->attr =
1220             ETH_BUF_LAST |
1221             ETH_BUF_D_L_DATA |
1222             ETH_BUF_OWN_CPU |
1223             (ETH_BUF_SIZE & 0);
1224     }
1225 }
1226
1227 // ------------------------------------------------------------------------
1228 //
1229 //  Function : TxDone          (Called from delivery thread)
1230 //
1231 // This returns Tx's from the Tx Machine to the stack (ie. reports
1232 // completion) - allowing for missed interrupts, and so on.
1233 // ------------------------------------------------------------------------
1234
1235 STATIC void TxDone(struct eth_upd985xx* p_eth_upd985xx)
1236 {
1237     struct cyg_netdevtab_entry *ndp;
1238     struct eth_drv_sc *sc;
1239
1240     ndp = (struct cyg_netdevtab_entry *)(p_eth_upd985xx->ndp);
1241     sc = (struct eth_drv_sc *)(ndp->device_instance);
1242
1243     CHECK_NDP_SC_LINK();
1244
1245     if ( p_eth_upd985xx->tx_busy ) {
1246         cyg_uint32 ss;
1247
1248         ss = INL( ETH_TXSR ); // Get tx status
1249         if ( ss & (ETH_TXSR_CSE |
1250                    ETH_TXSR_TUDR |
1251                    ETH_TXSR_TGNT |
1252                    ETH_TXSR_LCOL |
1253                    ETH_TXSR_ECOL |
1254                    ETH_TXSR_TEDFR |
1255                    ETH_TXSR_TDFR |
1256                    ETH_TXSR_TBRO |
1257                    ETH_TXSR_TMUL |
1258                    ETH_TXSR_TDONE ) ) {
1259             // Then it finished; somehow...
1260             cyg_uint32 key = p_eth_upd985xx->tx_keys[ 0 ];
1261             
1262             // Turn off the transmitter (before the callback to the stack).
1263             OUTL( ETH_TXCR, 0 );
1264
1265 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E8
1266             // Must take action after certain types of tx failure:
1267             if ( ss & (ETH_TXSR_TUDR |
1268                        ETH_TXSR_LCOL |
1269                        ETH_TXSR_ECOL) ) {
1270                 p_eth_upd985xx->count_bad_tx_completion++;
1271                 CYG_ASSERT ( p_eth_upd985xx->active, "Device not active!" );
1272                 eth_upd985xx_stop( sc );
1273                 eth_upd985xx_start( sc, NULL, 0 );
1274                 key = 0; // Important!  Stop above already fed it back.
1275             }
1276 #endif
1277
1278 #ifdef DEBUG_TRAFFIC
1279             os_printf("TxDone %d %x: KEY %x\n",
1280                       p_eth_upd985xx->index, (int)p_eth_upd985xx, key );
1281 #endif
1282             // Finished, ready for the next one
1283             p_eth_upd985xx->tx_keys[ 0 ] = 0;
1284             p_eth_upd985xx->tx_busy = 0;
1285             // Then tell the stack we are done:
1286             if (key) {
1287                 (sc->funs->eth_drv->tx_done)( sc, key,
1288                        0 == (p_eth_upd985xx->intrs & ETH_ISR_TABR) );
1289             }
1290         }
1291     }
1292 }
1293
1294
1295 // ------------------------------------------------------------------------
1296 //
1297 //  Function : eth_upd985xx_can_send
1298 //
1299 // ------------------------------------------------------------------------
1300
1301 STATIC int 
1302 eth_upd985xx_can_send(struct eth_drv_sc *sc)
1303 {
1304     struct eth_upd985xx *p_eth_upd985xx;
1305
1306     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1307
1308     // Guard possible external entry points
1309     if ( ! p_eth_upd985xx->active )
1310         return 0;
1311
1312     return ! p_eth_upd985xx->tx_busy;
1313 }
1314
1315 // ------------------------------------------------------------------------
1316 //
1317 //  Function : eth_upd985xx_send
1318 //
1319 // ------------------------------------------------------------------------
1320
1321 STATIC void 
1322 eth_upd985xx_send(struct eth_drv_sc *sc,
1323             struct eth_drv_sg *sg_list, int sg_len, int total_len,
1324             unsigned long key)
1325 {
1326     struct eth_upd985xx *p_eth_upd985xx;
1327     struct eth_drv_sg *last_sg;
1328     volatile struct bufdesc *bp;
1329 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
1330     struct eth_drv_sg local_sg[2];
1331 #endif
1332
1333     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1334
1335 #ifdef DEBUG_TRAFFIC
1336     os_printf("Tx %d %x: %d sg's, %d bytes, KEY %x\n",
1337               p_eth_upd985xx->index, (int)p_eth_upd985xx, sg_len, total_len, key );
1338 #endif
1339
1340     if ( ! p_eth_upd985xx->active )
1341         return;                         // device inactive, no return
1342     
1343     CYG_ASSERT( ! p_eth_upd985xx->tx_busy, "Can't send when busy!" );
1344
1345     p_eth_upd985xx->tx_busy++;
1346
1347     p_eth_upd985xx->tx_keys[0] = key;
1348     bp = &p_eth_upd985xx->txring[0]; // Current free tx
1349     CYG_ASSERT( 0 < sg_len, "sg_len underflow" );
1350     CYG_ASSERT( MAX_ETH_DRV_SG >= sg_len, "sg_len overflow" );
1351
1352 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E3
1353     // We must copy any Tx that is more than two SGs into just one buffer.
1354     if ( sg_len > 2 ) {
1355         cyg_uint8 *from_p, *to_p;
1356         to_p = &tx_databuf[0]; // normal cached address
1357         if ( sizeof( tx_databuf ) < total_len )
1358             total_len = sizeof( tx_databuf );
1359         for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1360             int l;
1361
1362             from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
1363             l = sg_list->len;
1364            
1365             if ( l > total_len )
1366                 l = total_len;
1367
1368             memcpy( to_p, from_p, l ); // All in cached memory
1369             to_p += l;
1370             total_len -= l;
1371
1372             if ( 0 > total_len ) 
1373                 break; // Should exit via sg_last normally
1374         }
1375
1376         // Set up SGs describing the single tx buffer
1377         total_len = to_p - &tx_databuf[0];
1378         local_sg[0].buf = (CYG_ADDRESS)&tx_databuf[0];
1379         local_sg[0].len = (CYG_ADDRWORD)total_len;
1380         local_sg[1].buf = (CYG_ADDRESS)0;
1381         local_sg[1].len = (CYG_ADDRWORD)0;
1382
1383         // And make the subsequent code use it.
1384         sg_len = 1;
1385         sg_list = &local_sg[0];
1386     }
1387 #endif
1388
1389     for ( last_sg = &sg_list[sg_len]; sg_list < last_sg; sg_list++ ) {
1390         cyg_uint8 *from_p;
1391         int l;
1392             
1393         from_p = (cyg_uint8 *)(sg_list->buf); // normal cached address
1394         l = sg_list->len;
1395
1396         if ( l > total_len )
1397             l = total_len;
1398
1399         // Ensure the mbuf contents really is in RAM where DMA can see it.
1400         // (Must round to cache lines apparantly for 4120)
1401         HAL_DCACHE_STORE( ((CYG_ADDRESS)from_p) &~(HAL_DCACHE_LINE_SIZE-1),
1402                           l + HAL_DCACHE_LINE_SIZE );
1403         
1404         bp->ptr = VIRT_TO_BUS( from_p ); // uncached real RAM address
1405         bp->attr &=~(ETH_BUF_LAST | ETH_BUF_SIZE);
1406         bp->attr |= ETH_BUF_SIZE & l;
1407         bp->attr |= ETH_BUF_D_L_DATA;
1408
1409         total_len -= l;
1410         bp++;
1411
1412         if ( 0 > total_len ) 
1413             break; // Should exit via sg_last normally
1414     }
1415
1416     CYG_ASSERT( bp > &p_eth_upd985xx->txring[0], "bp underflow" );
1417     CYG_ASSERT( bp < &p_eth_upd985xx->txring[
1418         NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)
1419         ], "bp underflow" );
1420
1421     bp--;
1422     bp->attr |= ETH_BUF_LAST;
1423
1424     // Make the rest be null links
1425     for ( bp++; bp <
1426               &p_eth_upd985xx->txring[NUM_ELEMENTS(p_eth_upd985xx->tx_bufdesc)];
1427           bp++ ) {
1428         bp->attr = ETH_BUF_D_L_LINK;
1429         bp->ptr = NULL;
1430     }
1431
1432     CYG_ASSERT( 0 == total_len, "length mismatch in tx" );
1433     CYG_ASSERT( last_sg == sg_list, "sg count mismatch in tx" );
1434
1435     // And start off the tx system
1436
1437     // Point the hardware at the list of buffers
1438     OUTL( ETH_TXDPR, (cyg_uint32)p_eth_upd985xx->txring );
1439     // and start the tx.
1440
1441     // Fault E4 - use only 8 for DTBS, not the previously recommended 16.
1442     // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E4
1443     // but no config opt is provided.
1444
1445     // Fault E7: ETH_TXCR_AFCE must not be used.
1446     // Tag: CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E7
1447     // but no config opt is provided.
1448
1449     OUTL( ETH_TXCR, ETH_TXCR_TXE | ETH_TXCR_DTBS_8 /* | ETH_TXCR_AFCE */ );
1450 }
1451
1452 #ifdef CYGPKG_NET
1453 // ------------------------------------------------------------------------
1454 //
1455 //  Function : eth_upd985xx_configure
1456 //
1457 //  Return : 0 = It worked.
1458 //           non0 = It failed.
1459 // ------------------------------------------------------------------------
1460
1461 STATIC int
1462 eth_upd985xx_configure(struct eth_upd985xx* p_eth_upd985xx, int promisc, int oversized)
1463 {
1464     int ss;
1465
1466     // We implement permission of oversize packets by changing LMAX (rather
1467     // than enabling HUGEN in ETH_MACC1) because we rely on only one
1468     // reception per rx descriptor.  General oversize packets could eat
1469     // many rx descriptors and we would become ...confused.
1470
1471     // Sanity check the numbers we're about to use.
1472     CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_OVERSIZE_PACKET_SIZE,
1473                 "Oversize packet would overflow rx buffer" );
1474     CYG_ASSERT( sizeof( rx_databuf[0] ) >= MAX_ETHERNET_PACKET_SIZE,
1475                 "Ethernet packet would overflow rx buffer" );
1476     if ( oversized )
1477         OUTL( ETH_LMAX, MAX_OVERSIZE_PACKET_SIZE );
1478     else
1479         OUTL( ETH_LMAX, MAX_ETHERNET_PACKET_SIZE );
1480
1481 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2
1482     ss = promisc ? 1 : 0; // avoid unused var warning
1483     p_eth_upd985xx->promisc = ss;
1484 #ifdef CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY
1485     // Then we must also set the mode in the chip
1486     ss = INL( ETH_AFR );
1487     if ( promisc )
1488         ss |= ETH_AFR_PRO;
1489     else
1490         ss &=~ETH_AFR_PRO;
1491     OUTL( ETH_AFR, ss );
1492 #endif // CYGOPT_DEVS_ETH_MIPS_UPD985XX_HARDWARE_BUGS_E1E2_E2ONLY
1493 #else
1494     ss = INL( ETH_AFR );
1495     if ( promisc )
1496         ss |= ETH_AFR_PRO;
1497     else
1498         ss &=~ETH_AFR_PRO;
1499     OUTL( ETH_AFR, ss );
1500 #endif
1501     return 0; // OK
1502 }
1503 #endif
1504
1505 // ------------------------------------------------------------------------
1506 //
1507 //  Function : eth_upd985xx_ioctl
1508 //
1509 // ------------------------------------------------------------------------
1510 STATIC int 
1511 eth_upd985xx_ioctl(struct eth_drv_sc *sc, unsigned long key,
1512                    void *data, int data_length)
1513 {
1514     struct eth_upd985xx *p_eth_upd985xx;
1515
1516     p_eth_upd985xx = (struct eth_upd985xx *)sc->driver_private;
1517
1518 #ifdef DEBUG_IOCTL
1519     db_printf( "eth_upd985xx_ioctl: device eth%d at %x; key is 0x%x, data at %x[%d]\n",
1520                p_eth_upd985xx->index, p_eth_upd985xx, key, data, data_length );
1521 #endif
1522
1523     // DO NOT guard possible external entry points - want to be able eg. to
1524     // set a mac address of a down interface before bringing it up!
1525
1526     switch ( key ) {
1527
1528 #ifdef ETH_DRV_SET_MAC_ADDRESS
1529     case ETH_DRV_SET_MAC_ADDRESS:
1530         if ( 6 != data_length )
1531             return -2;
1532         return eth_set_mac_address( p_eth_upd985xx, data );
1533 #endif
1534
1535 #ifdef ETH_DRV_GET_IF_STATS_UD
1536     case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
1537 #endif
1538         // drop through
1539 #ifdef ETH_DRV_GET_IF_STATS
1540     case ETH_DRV_GET_IF_STATS:
1541 #endif
1542 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
1543     {
1544         struct ether_drv_stats *p = (struct ether_drv_stats *)data;
1545         int i;
1546
1547         // Chipset entry is no longer supported; RFC1573.
1548         for ( i = 0; i < SNMP_CHIPSET_LEN; i++ )
1549             p->snmp_chipset[i] = 0;
1550
1551         // This perhaps should be a config opt, so you can make up your own
1552         // description, or supply it from the instantiation.
1553         strcpy( p->description, "NEC uPD985xx on-chip ethernet (CANDY)" );
1554         // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
1555
1556         i = eth_upd985xx_status( p_eth_upd985xx );
1557
1558         if ( !( i & PHY_STATUS_LINK) ) {
1559             p->operational = 2;         // LINK DOWN
1560             p->duplex = 1;              // UNKNOWN
1561             p->speed = 0;
1562         }
1563         else {
1564             p->operational = 3;            // LINK UP
1565             p->duplex = (i & PHY_STATUS_FDX) ? 3 : 2; // 2 = SIMPLEX, 3 = DUPLEX
1566             p->speed = ((i & PHY_STATUS_100MBPS) ? 100 : 10) * 1000000;
1567         }
1568
1569         // Admit to it...
1570         p->supports_dot3        = true;
1571
1572         // Those commented out are not available on this chip.
1573         p->tx_good              = INL( ETH_TPCT   )   ;
1574         p->tx_max_collisions    = INL( ETH_TXCL   )   ;
1575         p->tx_late_collisions   = INL( ETH_TLCL   )   ;
1576         //p->tx_underrun          = INL(    )   ;
1577         p->tx_carrier_loss      = INL( ETH_TCSE   )   ;
1578         p->tx_deferred          = INL( ETH_TDFR   ) +
1579                                   INL( ETH_TXDF   )    ;
1580         //p->tx_sqetesterrors     = INL(    )   ;
1581         p->tx_single_collisions = INL( ETH_TSCL   )   ;
1582         p->tx_mult_collisions   = INL( ETH_TMCL   )   ;
1583         p->tx_total_collisions  = INL( ETH_TSCL   ) +
1584                                   INL( ETH_TMCL   ) +
1585                                   INL( ETH_TLCL   ) +
1586                                   INL( ETH_TXCL   )   ;
1587         p->rx_good              = INL( ETH_RPKT   )   ;
1588         p->rx_crc_errors        = INL( ETH_RFCS   )   ;
1589         p->rx_align_errors      = INL( ETH_RALN   )   ;
1590         p->rx_resource_errors   = p_eth_upd985xx->count_rx_resource;
1591         //p->rx_overrun_errors    = INL(    )   ;
1592         //p->rx_collisions        = INL(    )   ;
1593         p->rx_short_frames      = INL( ETH_RUND   )   ;
1594         p->rx_too_long_frames   = INL( ETH_ROVR   )   ;
1595         p->rx_symbol_errors     = INL( ETH_RXUO   )   ;
1596
1597         p->interrupts           = p_eth_upd985xx->count_interrupts;
1598         p->rx_count             = INL( ETH_RBYT   )   ;
1599         p->rx_deliver           = INL( ETH_RPKT   )   ;
1600         p->rx_resource          = p_eth_upd985xx->count_rx_resource;
1601         p->rx_restart           = p_eth_upd985xx->count_rx_resource +
1602                                   p_eth_upd985xx->count_rx_restart;
1603         p->tx_count             = INL( ETH_TBYT   )   ;
1604         p->tx_complete          = INL( ETH_TPCT   )   ;
1605         p->tx_dropped           = INL( ETH_TNCL   )   ;
1606         
1607         p->tx_queue_len = 1;
1608         
1609         return 0; // OK
1610     }
1611 #endif
1612
1613     default:
1614         break;
1615     }
1616     return -1;
1617 }
1618
1619 // ------------------------------------------------------------------------
1620
1621 // EOF if_upd985xx.c