]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/devs/eth/smsc/lan91c111/v2_0/src/if_lan91c111.c
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / packages / devs / eth / smsc / lan91c111 / v2_0 / src / if_lan91c111.c
1 //==========================================================================
2 //
3 //      dev/if_lan91c111.c
4 //
5 //      Ethernet device driver for SMSC LAN91C111 compatible controllers
6 //
7 //==========================================================================
8 //==========================================================================
9 //#####DESCRIPTIONBEGIN####
10 //
11 //
12 //      Original:       lan91cxyz.c
13 //
14 //
15
16 // Author(s):    hmt, based on lan900 (for LAN91C110) driver by jskov
17 //               jskov, based on CS8900 driver by Gary Thomas
18 // Contributors: gthomas, jskov, hmt, jco@ict.es
19
20 //      modified by usteinkohl, KaRo electronics GmbH, Germany
21
22 // last modification:   2002-05-14
23 // Purpose:      
24 // Description:  hardware driver for LAN91C111 "LAN9000" ethernet
25 // Notes:        Pointer register is not saved/restored on receive interrupts.
26 //               The pointer is shared by both receive/transmit code.
27 //               But the net stack manages atomicity for you here.
28 //
29 //               The controller has an autorelease mode that allows TX packets
30 //               to be freed automatically on successful transmission - but
31 //               that is not used since we're only sending one packet at a
32 //               time anyway.
33 //               We may want to pingpong in future for throughput reasons.
34 //
35 //               <jco@ict.es> Added support for PCMCIA mode and shifted
36 //               address buses.
37 //
38 //                               <us@karo-electronics.de> added support for LAN91C111 (reading writing phy-registers)
39
40 //
41 //####DESCRIPTIONEND####
42 //
43 //==========================================================================
44
45 // Based on LAN91C110 and LAN91C96
46
47 #include <pkgconf/system.h>
48 #include <pkgconf/devs_eth_smsc_lan91c111.h>
49 #include <cyg/infra/cyg_type.h>
50 #include <cyg/hal/hal_arch.h>
51 #include <cyg/hal/hal_intr.h>
52 #include <cyg/hal/hal_diag.h>
53 #include <cyg/infra/cyg_ass.h>
54 #include <cyg/infra/diag.h>
55 #include <cyg/hal/drv_api.h>
56 #include <cyg/io/eth/netdev.h>
57 #include <cyg/io/eth/eth_drv.h>
58 #ifdef CYGPKG_NET
59 #include <pkgconf/net.h>
60 #include <cyg/kernel/kapi.h>
61 #include <net/if.h>  /* Needed for struct ifnet */
62 #endif
63
64 #include "smsc_lan91c111.h"
65 #include CYGDAT_DEVS_ETH_SMSC_LAN91C111_INL
66
67 #ifdef CYGPKG_INFRA_DEBUG
68 // Then we log, OOI, the number of times we get a bad packet number
69 // from the tx done fifo.
70 int lan91c111_txfifo_good = 0;
71 int lan91c111_txfifo_bad = 0;
72 #endif
73
74 #if DEBUG_SMSC
75 #define DEBUG_FUNCTION() do { diag_printf("%s\n", __FUNCTION__); } while (0)
76 #else
77 #define DEBUG_FUNCTION() CYG_EMPTY_STATEMENT
78 #endif
79
80 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
81 #define KEEP_STATISTICS
82 #endif
83
84 #ifdef KEEP_STATISTICS
85 #define INCR_STAT(_x_)        (cpd->stats._x_++)
86 #else
87 #define INCR_STAT(_x_)        CYG_EMPTY_STATEMENT
88 #endif
89
90 static void lan91c111_poll(struct eth_drv_sc *sc);
91 static cyg_interrupt lan91c111_interrupt;
92 static cyg_handle_t  lan91c111_interrupt_handle;
93
94 // This ISR is called when the ethernet interrupt occurs
95 static int
96 lan91c111_isr(cyg_vector_t vector, cyg_addrword_t data
97              /* , HAL_SavedRegisters *regs */ )
98 {
99         struct eth_drv_sc *sc = (struct eth_drv_sc *)data;
100         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
101
102         DEBUG_FUNCTION();
103
104         INCR_STAT(interrupts);
105
106         cyg_drv_interrupt_mask(cpd->interrupt);
107         cyg_drv_interrupt_acknowledge(cpd->interrupt);
108         return CYG_ISR_HANDLED | CYG_ISR_CALL_DSR;  // Run the DSR
109 }
110
111 // The deliver function (ex-DSR)  handles the ethernet [logical] processing
112 static void
113 lan91c111_deliver(struct eth_drv_sc *sc)
114 {
115         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
116
117         DEBUG_FUNCTION();
118
119         // Service the interrupt:
120         lan91c111_poll(sc);
121         // Allow interrupts to happen again
122         cyg_drv_interrupt_unmask(cpd->interrupt);
123 }
124
125 static int
126 lan91c111_int_vector(struct eth_drv_sc *sc)
127 {
128     struct lan91c111_priv_data *cpd =
129         (struct lan91c111_priv_data *)sc->driver_private;
130
131     return cpd->interrupt;
132 }
133
134 /*
135  . Function: smc_enable
136  . Purpose: let the chip talk to the outside work
137  . Method:
138  .      1.  Enable the transmitter
139  .      2.  Enable the receiver
140  .      3.  Enable interrupts
141 */
142 static void smc_enable( struct eth_drv_sc *sc )
143 {
144         /* see the header file for options in TCR/RCR DEFAULT*/
145         put_reg(sc, LAN91C111_TCR, LAN91C111_TCR_TXENA  | LAN91C111_TCR_PAD_EN);
146         put_reg(sc, LAN91C111_RCR, LAN91C111_RCR_RXEN);
147
148         /* now, enable interrupts */
149 //      SMC_SELECT_BANK( 2 );
150 //      outb( SMC_INTERRUPT_MASK, ioaddr + IM_REG );
151 }
152
153 static void smc_reset(struct eth_drv_sc *sc )
154 {
155         /* This resets the registers mostly to defaults, but doesn't
156            affect EEPROM.  That seems unnecessary */
157         put_reg(sc, LAN91C111_RCR , LAN91C111_RCR_SOFT_RST);
158
159         /* Setup the Configuration Register */
160         /* This is necessary because the CONFIG_REG is not affected */
161         /* by a soft reset */
162
163         put_reg(sc, LAN91C111_CONFIG, 0xb0b1);
164
165         /* this should pause enough for the chip to be happy */
166         //mdelay(10);
167         CYGACC_CALL_IF_DELAY_US((cyg_int32)10000);
168
169         /* Disable transmit and receive functionality */
170         put_reg(sc, LAN91C111_RCR, 0);
171         put_reg(sc, LAN91C111_TCR, 0);
172
173         /* set the control register to automatically
174            release successfully transmitted packets, to make the best
175            use out of our limited memory */
176 //      put_reg(sc, LAN91C111_CONTROL, get_reg(sc, LAN91C111_CONTROL) | LAN91C111_CONTROL_AUTO_RELEASE);
177
178         /* Reset the MMU */
179         put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_reset_mmu);
180
181         /* Note:  It doesn't seem that waiting for the MMU busy is needed here,
182            but this is a place where future chipsets _COULD_ break.  Be wary
183            of issuing another MMU command right after this */
184
185         /* Disable all interrupts */
186         put_reg(sc, LAN91C111_INTERRUPT, 0);
187 }
188
189 /*------------------------------------------------------------
190  . Reads a register from the MII Management serial interface
191  .-------------------------------------------------------------*/
192 static unsigned short
193 smc_read_phy_register(struct eth_drv_sc *sc, unsigned char phyaddr, unsigned char phyreg)
194 {
195         int i;
196         unsigned char mask;
197         unsigned short mii_reg;
198         unsigned short bits[64];
199         int clk_idx = 0;
200         int input_idx;
201         unsigned short phydata;
202
203         // 32 consecutive ones on MDO to establish sync
204         for (i = 0; i < 32; ++i)
205                 bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
206
207         // Start code <01>
208         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
209         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
210
211         // Read command <10>
212         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
213         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
214
215         // Output the PHY address, msb first
216         mask = (unsigned char)0x10;
217         for (i = 0; i < 5; ++i) {
218                 if (phyaddr & mask)
219                         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
220                 else
221                         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
222
223                 // Shift to next lowest bit
224                 mask >>= 1;
225         }
226
227         // Output the phy register number, msb first
228         mask = (unsigned char)0x10;
229         for (i = 0; i < 5; ++i) {
230                 if (phyreg & mask)
231                         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
232                 else
233                         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
234
235                 // Shift to next lowest bit
236                 mask >>= 1;
237         }
238
239         // Tristate and turnaround (2 bit times)
240         bits[clk_idx++] = 0;
241         //bits[clk_idx++] = 0;
242
243         // Input starts at this bit time
244         input_idx = clk_idx;
245
246         // Will input 16 bits
247         for (i = 0; i < 16; ++i)
248                 bits[clk_idx++] = 0;
249
250         // Final clock bit
251         bits[clk_idx++] = 0;
252
253         // Save the current bank
254 //      oldBank = inw( ioaddr+BANK_SELECT );
255
256         // Select bank 3
257 //      SMC_SELECT_BANK( 3 );
258
259         // Get the current MII register value
260         mii_reg = get_reg(sc, LAN91C111_MGMT);
261         //diag_printf("\n\nMIIREG: %04X\n\n", mii_reg);
262
263         // Turn off all MII Interface bits
264         mii_reg &= ~(LAN91C111_MGMT__MDOE|LAN91C111_MGMT__MCLK|LAN91C111_MGMT__MDI|LAN91C111_MGMT__MDO);
265
266         // Clock all 64 cycles
267         for (i = 0; i < 64; ++i) {
268                 // Clock Low - output data
269                 put_reg(sc, LAN91C111_MGMT, mii_reg | bits[i]);
270                 CYGACC_CALL_IF_DELAY_US((cyg_int32)50);
271
272                 // Clock Hi - input data
273                 put_reg(sc, LAN91C111_MGMT, mii_reg | bits[i] | LAN91C111_MGMT__MCLK);
274                 CYGACC_CALL_IF_DELAY_US((cyg_int32)50);
275                 bits[i] |= get_reg(sc, LAN91C111_MGMT) & LAN91C111_MGMT__MDI;
276         }
277
278         // Return to idle state
279         // Set clock to low, data to low, and output tristated
280         put_reg(sc, LAN91C111_MGMT, mii_reg);
281         CYGACC_CALL_IF_DELAY_US((cyg_int32)50);
282
283         // Restore original bank select
284         //SMC_SELECT_BANK( oldBank );
285
286         // Recover input data
287         phydata = 0;
288         for (i = 0; i < 16; ++i) {
289                 phydata <<= 1;
290
291                 if (bits[input_idx++] & LAN91C111_MGMT__MDI)
292                         phydata |= 0x0001;
293         }
294         return phydata;
295 }
296
297 /*------------------------------------------------------------
298  . Finds and reports the PHY address
299  .-------------------------------------------------------------*/
300 static int smc_detect_phy(struct eth_drv_sc *sc)
301 {
302         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
303         unsigned short phy_id1;
304         unsigned short phy_id2;
305         int phyaddr;
306         int found = 0;
307
308         // Scan all 32 PHY addresses if necessary
309         for (phyaddr = 0; phyaddr < 32; ++phyaddr) {
310                 // Read the PHY identifiers
311                 phy_id1  = smc_read_phy_register(sc, phyaddr, PHY_ID1_REG);
312                 phy_id2  = smc_read_phy_register(sc, phyaddr, PHY_ID2_REG);
313
314 #if DEBUG_SMSC
315                 diag_printf("Phy_address %02X: phy_id1=%04x, phy_id2=%04x\n",
316                         phyaddr, phy_id1, phy_id2);
317 #endif
318                 // Make sure it is a valid identifier
319                 if ((phy_id2 > 0x0000) && (phy_id2 < 0xffff) &&
320                     (phy_id1 > 0x0000) && (phy_id1 < 0xffff)) {
321                         if ((phy_id1 != 0x8000) && (phy_id2 != 0x8000)) {
322                                 // Save the PHY's address
323                                 cpd->phyaddr = phyaddr;
324                                 found = 1;
325                                 break;
326                         }
327                 }
328         }
329
330         if (!found) {
331                 diag_printf("No PHY found\n");
332                 return 0;
333         }
334
335         // Set the PHY type
336         if ((phy_id1 == 0x0016) && ((phy_id2 & 0xFFF0) == 0xF840)) {
337                 cpd->phytype = PHY_LAN83C183;
338 #if DEBUG_SMSC
339                 diag_printf("PHY=LAN83C183 (LAN91C111 Internal)\n");
340 #endif
341         }
342
343         if ((phy_id1 == 0x0282) && ((phy_id2 & 0xFFF0) == 0x1C50)) {
344                 cpd->phytype = PHY_LAN83C180;
345 #if DEBUG_SMSC
346                 diag_printf("PHY=LAN83C180\n");
347 #endif
348         }
349         return 1;
350 }
351
352 /*------------------------------------------------------------
353  . Writes a register to the MII Management serial interface
354  .-------------------------------------------------------------*/
355 static void
356 smc_write_phy_register(struct eth_drv_sc *sc, unsigned char phyaddr, unsigned char phyreg, unsigned short phydata)
357 {
358         //int oldBank;
359         int i;
360         unsigned short mask;
361         unsigned short mii_reg;
362         unsigned char bits[65];
363         int clk_idx = 0;
364
365         // 32 consecutive ones on MDO to establish sync
366         for (i = 0; i < 32; ++i)
367                 bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
368
369         // Start code <01>
370         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
371         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
372
373         // Write command <01>
374         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
375         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
376
377         // Output the PHY address, msb first
378         mask = (unsigned short)0x10;
379         for (i = 0; i < 5; ++i) {
380                 if (phyaddr & mask)
381                         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
382                 else
383                         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
384
385                 // Shift to next lowest bit
386                 mask >>= 1;
387         }
388
389         // Output the phy register number, msb first
390         mask = (unsigned short)0x10;
391         for (i = 0; i < 5; ++i) {
392                 if (phyreg & mask)
393                         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
394                 else
395                         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
396
397                 // Shift to next lowest bit
398                 mask >>= 1;
399         }
400
401         // Tristate and turnaround (2 bit times)
402         bits[clk_idx++] = 0;
403         bits[clk_idx++] = 0;
404
405         // Write out 16 bits of data, msb first
406         mask = 0x8000;
407         for (i = 0; i < 16; ++i) {
408                 if (phydata & mask)
409                         bits[clk_idx++] = LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MDO;
410                 else
411                         bits[clk_idx++] = LAN91C111_MGMT__MDOE;
412
413                 // Shift to next lowest bit
414                 mask >>= 1;
415         }
416
417         // Final clock bit (tristate)
418         bits[clk_idx++] = 0;
419
420         // Save the current bank
421 //      oldBank = inw( ioaddr+BANK_SELECT );
422
423         // Select bank 3
424 //      SMC_SELECT_BANK( 3 );
425
426         // Get the current MII register value
427         mii_reg = get_reg(sc, LAN91C111_MGMT);
428
429         // Turn off all MII Interface bits
430         mii_reg &= ~(LAN91C111_MGMT__MDOE | LAN91C111_MGMT__MCLK | LAN91C111_MGMT__MDI | LAN91C111_MGMT__MDO);
431
432         // Clock all cycles
433         for (i = 0; i < sizeof bits; ++i) {
434                 // Clock Low - output data
435                 put_reg(sc, LAN91C111_MGMT, mii_reg | bits[i]);
436                 CYGACC_CALL_IF_DELAY_US((cyg_int32)50);
437
438                 // Clock Hi - input data
439                 put_reg(sc, LAN91C111_MGMT, mii_reg | bits[i] | LAN91C111_MGMT__MCLK );
440                 CYGACC_CALL_IF_DELAY_US((cyg_int32)50);
441                 bits[i] |= get_reg(sc, LAN91C111_MGMT) & LAN91C111_MGMT__MDI;
442         }
443
444         // Return to idle state
445         // Set clock to low, data to low, and output tristated
446         put_reg(sc, LAN91C111_MGMT, mii_reg);
447         CYGACC_CALL_IF_DELAY_US((cyg_int32)50);
448
449         // Restore original bank select
450         //SMC_SELECT_BANK(oldBank);
451 }
452
453 static bool
454 smsc_lan91c111_init(struct cyg_netdevtab_entry *tab)
455 {
456         struct eth_drv_sc *sc = (struct eth_drv_sc *)tab->device_instance;
457         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
458         unsigned short val;
459         int i, time_out;
460
461         DEBUG_FUNCTION();
462
463         cpd->txbusy = cpd->within_send = 0;
464
465 #ifdef CYGNUM_DEVS_ETH_SMSC_LAN91C111_SHIFT_ADDR
466         cpd->addrsh = CYGNUM_DEVS_ETH_SMSC_LAN91C111_SHIFT_ADDR;
467 #else
468         cpd->addrsh = 0;
469 #endif
470         // Initialize environment, setup interrupt handler
471         cyg_drv_interrupt_create(cpd->interrupt,
472                                  99, // Priority - what goes here?
473                                  (cyg_addrword_t)sc, //  Data item passed to interrupt handler
474                                  (cyg_ISR_t *)lan91c111_isr,
475                                  (cyg_DSR_t *)eth_drv_dsr, // The logical driver DSR
476                                  &lan91c111_interrupt_handle,
477                                  &lan91c111_interrupt);
478         cyg_drv_interrupt_attach(lan91c111_interrupt_handle);
479         cyg_drv_interrupt_acknowledge(cpd->interrupt);
480         cyg_drv_interrupt_unmask(cpd->interrupt);
481
482         // probe chip by reading the signature in BS register
483         val = get_banksel(sc);
484 #if DEBUG_SMSC
485         diag_printf("LAN91C111 base address is %08X\n", cpd->base);
486         diag_printf("%04X\n", LAN91C111_BS);
487         diag_printf("LAN91C111 - supposed BankReg at address  %x = %04x\n",
488                     cpd->base + LAN91C111_BS, val );
489 #endif
490         if (0x3300 != (0xff00 & val)) {
491                 diag_printf("no LAN91C111 chip found ...\n");
492                 return false;
493         }
494         CYG_ASSERT(0x3300 == (0xff00 & val), "No 91C111 signature");
495
496         val = get_reg(sc, LAN91C111_REVISION);
497 #if DEBUG_SMSC & 9
498         diag_printf("LAN91C111 - type: %01x, rev: %01x\n",
499                     (val >> 4) & 0xf, val & 0xf);
500 #endif
501         // The controller may provide a function used to set up the ESA
502         if (cpd->config_enaddr) {
503                 if (!cpd->config_enaddr(cpd)) {
504                         diag_printf("\nLAN91C111 - failed to get valid ESA!\n");
505                         return false;
506                 }
507         }
508         // Reset chip
509         put_reg(sc, LAN91C111_RCR, LAN91C111_RCR_SOFT_RST);
510         put_reg(sc, LAN91C111_RCR, 0);
511
512         val = get_reg(sc, LAN91C111_EPH_STATUS);
513 #if DEBUG_SMSC & 9
514         diag_printf("LAN91C111 - status: %04x\n", val);
515 #endif
516 #if 0 < CYGINT_DEVS_ETH_SMSC_LAN91C111_STATIC_ESA
517         // Use statically configured ESA from the private data
518 #if DEBUG_SMSC & 9
519         diag_printf("LAN91C111 - static ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
520                     cpd->enaddr[0],
521                     cpd->enaddr[1],
522                     cpd->enaddr[2],
523                     cpd->enaddr[3],
524                     cpd->enaddr[4],
525                     cpd->enaddr[5] );
526 #endif // DEBUG_SMSC
527         // Set up hardware address
528         for (i = 0; i < sizeof(cpd->enaddr); i += 2)
529                 put_reg(sc, LAN91C111_IA01+i/2,
530                         cpd->enaddr[i] | (cpd->enaddr[i+1] << 8));
531 #else // not CYGINT_DEVS_ETH_SMSC_LAN91C111_STATIC_ESA
532         // Use the address from the serial EEPROM
533
534         // Read out hardware address
535         for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
536                 unsigned short z = get_reg(sc, LAN91C111_IA01+i/2 );
537                 cpd->enaddr[i] =   (unsigned char)(0xff & z);
538                 cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
539         }
540 #if DEBUG_SMSC & 9
541         diag_printf("LAN91C111 - eeprom ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
542                     cpd->enaddr[0],
543                     cpd->enaddr[1],
544                     cpd->enaddr[2],
545                     cpd->enaddr[3],
546                     cpd->enaddr[4],
547                     cpd->enaddr[5] );
548 #endif // DEBUG_SMSC
549 #endif // !CYGINT_DEVS_ETH_SMSC_LAN91C111_STATIC_ESA
550         smc_reset(sc);
551         smc_enable(sc);
552         //      diag_printf("select external PHY .......\n");
553         //      put_reg(sc, LAN91C111_CONFIG, get_reg(sc, LAN91C111_CONFIG) | LAN91C111_CONFIG_EXT_PHY);
554 #if DEBUG_SMSC
555         diag_printf("revision_reg: %04X\n", get_reg(sc, LAN91C111_REVISION));
556
557         diag_printf("read receive_control_reg: %04X\n", get_reg(sc, LAN91C111_RCR));
558
559         diag_printf("read config_reg: %04X\n", get_reg(sc, LAN91C111_CONFIG));
560         diag_printf("searching for phy ..... \n");
561 #endif
562         smc_detect_phy(sc);
563         //CYGACC_CALL_IF_DELAY_US((cyg_int32)1000000);
564         smc_write_phy_register(sc, 0, 0, 0x3000);
565
566         // Init PHY
567         put_reg(sc, LAN91C111_RPCR, LAN91C111_RPCR_ANEG | 0x80);        // do auto-negotiation
568         //put_reg(sc, LAN91C111_RPCR, 0);                               // do 10 MBit
569 #if 0
570         diag_printf("phy_register0 is: %04X\n", smc_read_phy_register(sc, 0, 0));
571         diag_printf("phy_register1 is: %04X\n", smc_read_phy_register(sc, 0, 1));
572         diag_printf("phy_register2 is: %04X\n", smc_read_phy_register(sc, 0, 2));
573         diag_printf("phy_register3 is: %04X\n", smc_read_phy_register(sc, 0, 3));
574         diag_printf("phy_register4 is: %04X\n", smc_read_phy_register(sc, 0, 4));
575         diag_printf("phy_register5 is: %04X\n", smc_read_phy_register(sc, 0, 5));
576 #endif
577         time_out = 0;
578         val = smc_read_phy_register(sc, 0, 1);
579         while (!(smc_read_phy_register(sc, 0, 1) & PHY_STAT_LINK)) {
580                 time_out++;
581                 if (time_out == 50) {                                   /* 5 seconds */
582                         diag_printf("\n\nLAN91C111: cannot get valid link, check cabels, hubs ... \n\n");
583                         return false;
584                 }
585                 CYGACC_CALL_IF_DELAY_US((cyg_int32)100000);             /* wait 0,1 seconds */
586         }
587         // Initialize upper level driver
588         sc->funs->eth_drv->init(sc, cpd->enaddr);
589         return true;
590 }
591
592 static void
593 lan91c111_stop(struct eth_drv_sc *sc)
594 {
595         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
596         DEBUG_FUNCTION();
597
598         CYG_ASSERT(cpd->within_send < 10, "stop: Excess send recursions");
599         cpd->within_send++;
600         // Complete any outstanding activity:
601         if (cpd->txbusy) {
602                 cpd->txbusy = 0;
603 #if DEBUG_SMSC & 9
604                 diag_printf("LAN91C111 - Stopping, cleaning up pending TX\n");
605 #endif
606                 sc->funs->eth_drv->tx_done(sc, cpd->txkey, 0);
607         }
608         // Reset chip
609         put_reg(sc, LAN91C111_RCR, LAN91C111_RCR_SOFT_RST);
610         put_reg(sc, LAN91C111_RCR, 0);
611         cpd->txbusy = cpd->within_send = 0;
612 }
613
614 //
615 // This function is called to "start up" the interface.  It may be called
616 // multiple times, even when the hardware is already running.  It will be
617 // called whenever something "hardware oriented" changes and should leave
618 // the hardware ready to send/receive packets.
619 //
620 static void
621 lan91c111_start(struct eth_drv_sc *sc, unsigned char *enaddr, int flags)
622 {
623 #ifdef CYGPKG_NET
624         struct ifnet *ifp = &sc->sc_arpcom.ac_if;
625 #endif
626         DEBUG_FUNCTION();
627         put_reg(sc, LAN91C111_INTERRUPT, 0);    // disable interrupts
628         put_reg(sc, LAN91C111_INTERRUPT,        // ack old interrupts
629                 LAN91C111_INTERRUPT_TX_INT | LAN91C111_INTERRUPT_TX_EMPTY_INT |
630                 LAN91C111_INTERRUPT_RX_OVRN_INT | LAN91C111_INTERRUPT_ERCV_INT);
631         put_reg(sc, LAN91C111_RCR,
632 #ifdef RCR_HAS_ABORT_ENB // 91C96 does not - page 46.
633                 LAN91C111_RCR_ABORT_ENB |
634 #endif
635                 LAN91C111_RCR_STRIP_CRC |
636                 LAN91C111_RCR_RXEN);
637         put_reg(sc, LAN91C111_TCR, LAN91C111_TCR_TXENA | LAN91C111_TCR_PAD_EN);
638         put_reg(sc, LAN91C111_CONTROL, 0);
639         put_reg(sc, LAN91C111_INTERRUPT,       // enable interrupts
640                 LAN91C111_INTERRUPT_RCV_INT_M);
641 #ifdef CYGPKG_NET
642         if ((0
643 #ifdef ETH_DRV_FLAGS_PROMISC_MODE
644              != (flags & ETH_DRV_FLAGS_PROMISC_MODE)
645 #endif
646              ) || (ifp->if_flags & IFF_PROMISC)
647             ) {
648                 // Then we select promiscuous mode.
649                 unsigned short rcr;
650                 rcr = get_reg(sc, LAN91C111_RCR );
651                 rcr |= LAN91C111_RCR_PRMS;
652                 put_reg(sc, LAN91C111_RCR, rcr );
653         }
654 #endif
655 }
656
657 //
658 // This routine is called to perform special "control" operations
659 //
660 static int
661 lan91c111_control(struct eth_drv_sc *sc, unsigned long key,
662                void *data, int data_length)
663 {
664         unsigned char *esa = (unsigned char *)data;
665         int i;
666         unsigned short reg;
667         struct lan91c111_priv_data *cpd =
668                 (struct lan91c111_priv_data *)sc->driver_private;
669
670         DEBUG_FUNCTION();
671
672         switch (key) {
673         case ETH_DRV_SET_MAC_ADDRESS:
674 #if 9 & DEBUG_SMSC
675                 diag_printf("LAN91C111 - set ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
676                             esa[0],
677                             esa[1],
678                             esa[2],
679                             esa[3],
680                             esa[4],
681                             esa[5] );
682 #ifndef CYGSEM_DEVS_ETH_SMSC_LAN91C111_WRITE_EEPROM
683                 diag_printf("*** PERMANENT EEPROM WRITE NOT ENABLED ***\n");
684 #endif
685 #endif // DEBUG_SMSC
686
687 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_WRITE_EEPROM
688                 // Only now can we command the chip to perform EEPROM writes:
689
690                 // select arbitrary writing to the EEPROM
691                 reg = get_reg(sc, LAN91C111_CONTROL);
692                 reg |= LAN91C111_CONTROL_EEPROM_SELECT;
693                 put_reg(sc, LAN91C111_CONTROL, reg );
694
695                 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
696                         int j;
697                         // Set the address register
698                         put_reg(sc, LAN91C111_POINTER, LAN91C111_ESA_EEPROM_OFFSET + i/2);
699                         // Poke the data
700                         put_reg(sc, LAN91C111_GENERAL, esa[i] | (esa[i+1] << 8));
701                         // Command the store
702                         reg = get_reg(sc, LAN91C111_CONTROL);
703                         reg |= LAN91C111_CONTROL_STORE;
704                         put_reg(sc, LAN91C111_CONTROL, reg );
705                         // and poll for completion
706                         for ( j = 1024 * 1024; 0 < j ; j-- ) {
707                                 reg = get_reg(sc, LAN91C111_CONTROL);
708                                 if ( 0 == (reg & LAN91C111_CONTROL_EEPROM_BUSY) )
709                                         break;
710                         }
711                         CYG_ASSERT( 0 < j, "EEPROM write timout!" );
712                 }
713
714                 reg = get_reg(sc, LAN91C111_CONTROL);
715                 CYG_ASSERT( 0 == (reg & LAN91C111_CONTROL_EEPROM_BUSY),
716                             "EEPROM still busy!" );
717                 // Clear the EEPROM selection bit
718                 reg &=~LAN91C111_CONTROL_EEPROM_SELECT;
719                 put_reg(sc, LAN91C111_CONTROL, reg );
720                 // and check it "took"
721                 reg = get_reg(sc, LAN91C111_CONTROL);
722                 CYG_ASSERT(0 == (reg & LAN91C111_CONTROL_EEPROM_SELECT),
723                             "EEPROM still selected!");
724                 // and command a complete reload
725                 reg |= LAN91C111_CONTROL_RELOAD;
726                 put_reg(sc, LAN91C111_CONTROL, reg);
727                 for (i = 1024 * 1024; 0 < i ; i--) {
728                         reg = get_reg(sc, LAN91C111_CONTROL);
729                         if (0 == (reg & LAN91C111_CONTROL_EEPROM_BUSY))
730                                 break;
731                 }
732                 CYG_ASSERT( 0 < i, "EEPROM reload timout!" );
733                 // Now extract the MAC address that is in the chip, and tell the
734                 // system about it.
735                 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
736                         unsigned short z = get_reg(sc, LAN91C111_IA01+i/2 );
737                         cpd->enaddr[i] =   (unsigned char)(0xff & z);
738                         cpd->enaddr[i+1] = (unsigned char)(0xff & (z >> 8));
739                 }
740 #if DEBUG_SMSC & 9
741                 diag_printf("LAN91C111 - eeprom new ESA: %02x:%02x:%02x:%02x:%02x:%02x\n",
742                             cpd->enaddr[0],
743                             cpd->enaddr[1],
744                             cpd->enaddr[2],
745                             cpd->enaddr[3],
746                             cpd->enaddr[4],
747                             cpd->enaddr[5] );
748 #endif // DEBUG_SMSC
749                 for (i = 0; i < sizeof(cpd->enaddr); i++ ) {
750                         CYG_ASSERT( esa[i] == cpd->enaddr[i], "ESA not written correctly" );
751                         if ( esa[i] != cpd->enaddr[i] )
752                                 return 1; // the operation failed.
753                 }
754 #else // not CYGSEM_DEVS_ETH_SMSC_LAN91C111_WRITE_EEPROM
755                 // Whatever, we can write the MAC address into the interface info,
756                 // and the chip registers no problem.
757                 for ( i = 0; i < sizeof(cpd->enaddr); i++ )
758                         cpd->enaddr[i] = esa[i];
759                 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
760                         reg = cpd->enaddr[i] | (cpd->enaddr[i+1] << 8);
761                         put_reg(sc, LAN91C111_IA01+i/2, reg );
762                 }
763 #endif // !CYGSEM_DEVS_ETH_SMSC_LAN91C111_WRITE_EEPROM
764                 return 0;
765
766 #ifdef ETH_DRV_GET_MAC_ADDRESS
767         case ETH_DRV_GET_MAC_ADDRESS:
768                 // Extract the MAC address that is in the chip, and tell the
769                 // system about it.
770                 for (i = 0; i < sizeof(cpd->enaddr); i += 2) {
771                         unsigned short z = get_reg(sc, LAN91C111_IA01+i/2 );
772                         esa[i] =   (unsigned char)(0xff & z);
773                         esa[i+1] = (unsigned char)(0xff & (z >> 8));
774                 }
775                 return 0;
776 #endif
777
778 #ifdef ETH_DRV_GET_IF_STATS_UD
779         case ETH_DRV_GET_IF_STATS_UD: // UD == UPDATE
780 #endif
781                 // drop through
782 #ifdef ETH_DRV_GET_IF_STATS
783         case ETH_DRV_GET_IF_STATS:
784 #endif
785 #if defined(ETH_DRV_GET_IF_STATS) || defined (ETH_DRV_GET_IF_STATS_UD)
786                 {
787                         struct ether_drv_stats *p = (struct ether_drv_stats *)data;
788                         // Chipset entry is no longer supported; RFC1573.
789                         for (i = 0; i < SNMP_CHIPSET_LEN; i++)
790                                 p->snmp_chipset[i] = 0;
791
792                         // This perhaps should be a config opt, so you can make up your own
793                         // description, or supply it from the instantiation.
794                         strcpy( p->description, "SMSC LAN91C111" );
795                         // CYG_ASSERT( 48 > strlen(p->description), "Description too long" );
796
797                         reg = smc_read_phy_register(sc, 0, 1);
798
799                         if ((reg & PHY_STAT_LINK) == 0) {
800                                 p->operational = 2;     // LINK DOWN
801                                 p->duplex = 1;          // UNKNOWN
802                                 p->speed = 0;
803                         } else {
804                                 p->operational = 3;     // LINK UP
805                                 p->duplex = 2;          // 2 = SIMPLEX, 3 = DUPLEX
806                                 p->speed = 10 * 1000000;// it's only a 10Mbit device
807                         }
808 #ifdef KEEP_STATISTICS
809                         {
810                                 struct smsc_lan91c111_stats *ps = &cpd->stats;
811
812                                 // Admit to it...
813                                 p->supports_dot3        = true;
814
815                                 p->tx_good              = ps->tx_good             ;
816                                 p->tx_max_collisions    = ps->tx_max_collisions   ;
817                                 p->tx_late_collisions   = ps->tx_late_collisions  ;
818                                 p->tx_underrun          = ps->tx_underrun         ;
819                                 p->tx_carrier_loss      = ps->tx_carrier_loss     ;
820                                 p->tx_deferred          = ps->tx_deferred         ;
821                                 p->tx_sqetesterrors     = ps->tx_sqetesterrors    ;
822                                 p->tx_single_collisions = ps->tx_single_collisions;
823                                 p->tx_mult_collisions   = ps->tx_mult_collisions  ;
824                                 p->tx_total_collisions  = ps->tx_total_collisions ;
825                                 p->rx_good              = ps->rx_good             ;
826                                 p->rx_crc_errors        = ps->rx_crc_errors       ;
827                                 p->rx_align_errors      = ps->rx_align_errors     ;
828                                 p->rx_resource_errors   = ps->rx_resource_errors  ;
829                                 p->rx_overrun_errors    = ps->rx_overrun_errors   ;
830                                 p->rx_collisions        = ps->rx_collisions       ;
831                                 p->rx_short_frames      = ps->rx_short_frames     ;
832                                 p->rx_too_long_frames   = ps->rx_too_long_frames  ;
833                                 p->rx_symbol_errors     = ps->rx_symbol_errors    ;
834
835                                 p->interrupts           = ps->interrupts          ;
836                                 p->rx_count             = ps->rx_count            ;
837                                 p->rx_deliver           = ps->rx_deliver          ;
838                                 p->rx_resource          = ps->rx_resource         ;
839                                 p->rx_restart           = ps->rx_restart          ;
840                                 p->tx_count             = ps->tx_count            ;
841                                 p->tx_complete          = ps->tx_complete         ;
842                                 p->tx_dropped           = ps->tx_dropped          ;
843                         }
844 #endif // KEEP_STATISTICS
845                         p->tx_queue_len = 1;
846                         return 0; // OK
847                 }
848 #endif
849         }
850         return 1;
851 }
852
853 //
854 // This routine is called to see if it is possible to send another packet.
855 // It will return non-zero if a transmit is possible, zero otherwise.
856 //
857 static int lan91c111_can_send(struct eth_drv_sc *sc)
858 {
859         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
860 #ifdef CHECK_LINK_STAT
861         unsigned short stat;
862 #endif
863         int tcr;
864
865         DEBUG_FUNCTION();
866 #ifdef CHECK_LINK_STAT
867         // You don't want to do this normally on every packet
868         stat = smc_read_phy_register(sc, 0, 1);
869         if ((stat & PHY_STAT_LINK) == 0) {
870                 return false;  // Link not connected
871         }
872 #endif
873         CYG_ASSERT( cpd->within_send < 10, "can_send: Excess send recursions" );
874         cpd->within_send++;
875
876         tcr = get_reg(sc, LAN91C111_TCR);
877         if (0 == (LAN91C111_TCR_TXENA & tcr)) {
878 #if DEBUG_SMSC & 1
879                 diag_printf("%s: ENGINE RESTART: tcr %x\n", __FUNCTION__, tcr );
880 #endif
881                 // Complete any outstanding activity:
882                 if (cpd->txbusy) {
883                         cpd->txbusy = 0;
884 #if DEBUG_SMSC & 9
885                         diag_printf("LAN91C111 - can_send, cleaning up pending TX\n" );
886 #endif
887                         sc->funs->eth_drv->tx_done(sc, cpd->txkey, 0);
888                 }
889
890                 tcr |= LAN91C111_TCR_TXENA;
891                 put_reg(sc, LAN91C111_TCR, tcr);
892         }
893
894         // This helps unstick deadly embraces.
895         lan91c111_poll(sc); // Deal with any outstanding rx state
896         cpd->within_send--;
897
898         return (cpd->txbusy == 0) && (0 == cpd->within_send);
899 }
900
901 //
902 // This routine is called to send data to the hardware.
903 static void
904 lan91c111_send(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len,
905                int total_len, unsigned long key)
906 {
907         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
908         int i, len, plen, tcr;
909
910         unsigned short *sdata = NULL;
911         unsigned short ints, control;
912         cyg_uint16 packet, status;
913
914         DEBUG_FUNCTION();
915
916         INCR_STAT(tx_count);
917
918         // Worry about the TX engine stopping.
919         tcr = get_reg(sc, LAN91C111_TCR);
920         if (0 == (LAN91C111_TCR_TXENA & tcr)) {
921 #if DEBUG_SMSC & 1
922                 diag_printf("%s: ENGINE RESTART: tcr %x\n", __FUNCTION__, tcr );
923 #endif
924                 tcr |= LAN91C111_TCR_TXENA;
925                 put_reg(sc, LAN91C111_TCR, tcr);
926         }
927
928         // This helps unstick deadly embraces.
929         CYG_ASSERT(cpd->within_send < 10, "send: Excess send recursions" );
930         cpd->within_send++;
931         lan91c111_poll(sc); // Deal with any outstanding rx state
932         cpd->within_send--;
933
934         cpd->txbusy = 1;
935         cpd->txkey = key;
936
937         // Find packet length
938         plen = 0;
939         for (i = 0; i < sg_len; i++) {
940                 plen += sg_list[i].len;
941         }
942         CYG_ASSERT(plen == total_len, "sg data length mismatch");
943
944         // Alloc new TX packet
945         do {
946                 //put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_alloc_for_tx | ((plen >> 8) & 0x07));
947                 put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_alloc_for_tx);
948
949                 i = 1024 * 1024;
950                 do {
951                         status = get_reg(sc, LAN91C111_INTERRUPT);
952                 } while (0 == (status & LAN91C111_INTERRUPT_ALLOC_INT) && (--i > 0) );
953                 if (i) {
954                         packet = get_reg(sc, LAN91C111_PNR);
955                 } else {
956                         packet = 0xffff;
957                 }
958 #if DEBUG_SMSC & 1
959                 diag_printf("%s: allocated packet %04x\n", __FUNCTION__, packet);
960 #endif
961                 packet = packet >> 8;
962                 if (packet & 0x80) {
963                         // Hm.. Isn't this a dead end?
964 #if 0 //DEBUG_SMSC & 1
965                         diag_printf("%s: Allocation failed! Retrying...\n", __FUNCTION__ );
966 #endif
967                         // Not if we can make progress with what's filling memory.
968                         lan91c111_poll(sc); // Deal with any outstanding state
969                         continue;
970                 }
971         } while (0);
972
973 #if DEBUG_SMSC & 4
974         diag_printf("#####Tx packet allocated %x (previous %x)\n",
975                     packet, cpd->txpacket);
976 #endif
977         cpd->txpacket = packet;
978
979         put_reg(sc, LAN91C111_PNR, packet);
980         // Note: Check FIFO state here before continuing?
981         put_reg(sc, LAN91C111_POINTER, LAN91C111_POINTER_AUTO_INCR | 0x0000);
982         // Pointer is now set, and the proper bank is selected for
983         // data writes.
984
985         // Prepare header:
986         put_data(sc, 0);        // reserve space for status word
987         // packet length (includes status, byte-count and control shorts)
988         put_data(sc, 0x7FE & (plen + 6) ); // Always even, always < 15xx(dec)
989
990 #if DEBUG_SMSC & 16
991         diag_printf("writing packet data into Tx-FIFO ...\n");
992         diag_printf("interrupt status is: %04X\n", get_reg(sc, LAN91C111_INTERRUPT));
993         diag_printf("%02X %02X %02X %02X ", 0, 0, (0x7FE & (plen + 6)) & 0xff, (0x7FE & (plen + 6))>>8);
994         u=4;
995 #endif
996         // Put data into buffer
997         for (i = 0;  i < sg_len;  i++) {
998                 sdata = (unsigned short *)sg_list[i].buf;
999                 len = sg_list[i].len;
1000
1001                 CYG_ASSERT(0 == (len & 1) || (i == (sg_len-1)), "odd length");
1002                 CYG_ASSERT( sdata, "No sg data pointer here" );
1003                 while (len >= sizeof(*sdata)) {
1004                         put_data(sc, *sdata++);
1005 #if DEBUG_SMSC & 16 // dump packet written into FIFO
1006                         diag_printf("%02X ", *(sdata-1)&0xff);
1007                         diag_printf("%02X ", (*(sdata-1)>>8)&0xff);
1008                         u++;
1009                         u++;
1010                         if (u==16) {
1011                                 u=0;
1012                                 diag_printf("\n");
1013                         }
1014 #endif
1015                         len -= sizeof(*sdata);
1016                 }
1017         }
1018
1019         CYG_ASSERT( sdata, "No sg data pointer outside" );
1020
1021         // Lay down the control short unconditionally at the end.
1022         // (or it might use random memory contents)
1023         control = 0;
1024
1025         if (1 & plen) {
1026                 // Need to set ODD flag and insert the data
1027                 unsigned char onebyte = *(unsigned char*)sdata;
1028                 control = onebyte;
1029                 control |= LAN91C111_CONTROLBYTE_ODD;
1030         }
1031         control |= LAN91C111_CONTROLBYTE_CRC; // Just in case...
1032         put_data(sc, control);
1033 #if DEBUG_SMSC & 16
1034         diag_printf("%02X %02X\n", control & 0xff, (control>>8)&0xff);
1035 #endif
1036         // Enqueue the packet
1037         // put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_enq_packet);
1038
1039         // Ack TX empty int and unmask it.
1040         ints = get_reg(sc, LAN91C111_INTERRUPT);
1041
1042         ints |= LAN91C111_INTERRUPT_TX_SET_ACK;  // Do we really need the TX ack here ????
1043         put_reg(sc, LAN91C111_INTERRUPT, ints);
1044
1045         ints |= LAN91C111_INTERRUPT_TX_SET_M;
1046         put_reg(sc, LAN91C111_INTERRUPT, ints);
1047
1048         // Enqueue the packet
1049         put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_enq_packet);
1050
1051 #if DEBUG_SMSC & 1
1052         ints = get_reg(sc, LAN91C111_INTERRUPT);
1053         diag_printf("%s:END: ints at TX: %04x\n", __FUNCTION__, ints);
1054 #endif
1055 }
1056
1057 static void
1058 lan91c111_TxEvent(struct eth_drv_sc *sc, int stat)
1059 {
1060         unsigned short packet, ints, tcr;
1061         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
1062         int success = 1;
1063
1064         DEBUG_FUNCTION();
1065
1066         INCR_STAT(tx_complete);
1067
1068         // Ack and mask TX interrupt set
1069         ints = get_reg(sc, LAN91C111_INTERRUPT);
1070
1071         ints &=~LAN91C111_INTERRUPT_TX_FIFO_ACK; // Do NOT ACK this one here.
1072         ints |= LAN91C111_INTERRUPT_TX_SET_ACK; // Also ACKs other sources!
1073         ints &= ~LAN91C111_INTERRUPT_TX_SET_M;
1074         put_reg(sc, LAN91C111_INTERRUPT, ints);
1075
1076         // Get number of completed packet and read the status word
1077         packet = get_reg(sc, LAN91C111_FIFO_PORTS);
1078 #if DEBUG_SMSC & 1
1079         diag_printf("%s:START: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
1080 #endif
1081
1082 #ifdef KEEP_STATISTICS
1083         {
1084                 unsigned short reg;
1085
1086                 reg = get_reg( sc, LAN91C111_EPH_STATUS );
1087
1088                 // Covering each bit in turn...
1089                 if ( reg & LAN91C111_STATUS_TX_UNRN   ) INCR_STAT( tx_underrun );
1090                 //if ( reg & LAN91C111_STATUS_LINK_OK ) INCR_STAT(  );
1091                 //if ( reg & LAN91C111_STATUS_CTR_ROL ) INCR_STAT(  );
1092                 //if ( reg & LAN91C111_STATUS_EXC_DEF ) INCR_STAT(  );
1093                 if ( reg & LAN91C111_STATUS_LOST_CARR ) INCR_STAT( tx_carrier_loss );
1094                 if ( reg & LAN91C111_STATUS_LATCOL    ) INCR_STAT( tx_late_collisions );
1095                 //if ( reg & LAN91C111_STATUS_WAKEUP  ) INCR_STAT(  );
1096                 if ( reg & LAN91C111_STATUS_TX_DEFR   ) INCR_STAT( tx_deferred );
1097                 //if ( reg & LAN91C111_STATUS_LTX_BRD ) INCR_STAT(  );
1098                 if ( reg & LAN91C111_STATUS_SQET      ) INCR_STAT( tx_sqetesterrors );
1099                 if ( reg & LAN91C111_STATUS_16COL     ) INCR_STAT( tx_max_collisions );
1100                 //if ( reg & LAN91C111_STATUS_LTX_MULT) INCR_STAT(  );
1101                 if ( reg & LAN91C111_STATUS_MUL_COL   ) INCR_STAT( tx_mult_collisions );
1102                 if ( reg & LAN91C111_STATUS_SNGL_COL  ) INCR_STAT( tx_single_collisions );
1103                 if ( reg & LAN91C111_STATUS_TX_SUC    ) INCR_STAT( tx_good );
1104
1105                 cpd->stats.tx_total_collisions =
1106                         cpd->stats.tx_late_collisions +
1107                         cpd->stats.tx_max_collisions +
1108                         cpd->stats.tx_mult_collisions +
1109                         cpd->stats.tx_single_collisions;
1110
1111                 // We do not need to look in the Counter Register (LAN91C111_COUNTER)
1112                 // because it just mimics the info we already have above.
1113         }
1114 #endif // KEEP_STATISTICS
1115
1116 #if DEBUG_SMSC & 16
1117         diag_printf("transmit status is: %04X\n", get_reg(sc, LAN91C111_EPH_STATUS));
1118 #endif
1119         // We do not really care about Tx failure.  Ethernet is not a reliable
1120         // medium.  But we do care about the TX engine stopping.
1121         tcr = get_reg(sc, LAN91C111_TCR);
1122         if (0 == (LAN91C111_TCR_TXENA & tcr)) {
1123 #if DEBUG_SMSC & 1
1124                 diag_printf("%s: ENGINE RESTART: tcr %x ints %04x\n", __FUNCTION__, tcr, ints);
1125 #endif
1126                 tcr |= LAN91C111_TCR_TXENA;
1127                 put_reg(sc, LAN91C111_TCR, tcr);
1128                 success = 0; // And treat this as an error...
1129         }
1130
1131         packet &= 0xff;
1132
1133         // Ack the TX int which is supposed to clear the packet from the TX
1134         // completion queue.
1135         ints = get_reg(sc, LAN91C111_INTERRUPT);
1136         ints |= LAN91C111_INTERRUPT_TX_FIFO_ACK;
1137         put_reg(sc, LAN91C111_INTERRUPT, ints);
1138
1139         // It certainly appears that occasionally the tx fifo tells lies; we
1140         // get the wrong packet number.  Freeing the one we allocated seems to
1141         // give correct operation.
1142 #ifdef CYGPKG_INFRA_DEBUG
1143         // Then we log, OOI, the number of times we get a bad packet number
1144         // from the tx done fifo.
1145         if (cpd->txpacket != packet )
1146                 lan91c111_txfifo_bad++;
1147         else
1148                 lan91c111_txfifo_good++;
1149 #endif
1150 #if DEBUG_SMSC & 4
1151         diag_printf("#####Tx packet freed %x (expected %x)\n", packet, cpd->txpacket );
1152 #endif
1153         // and then free the packet
1154         put_reg(sc, LAN91C111_PNR, cpd->txpacket);
1155         put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_rel_packet);
1156
1157 #if DEBUG_SMSC & 1
1158         // Hm... The free doesn't seem to have the desired effect?!?
1159         ints = get_reg(sc, LAN91C111_INTERRUPT);
1160         packet = get_reg(sc, LAN91C111_FIFO_PORTS);
1161         diag_printf("%s:END: fifo %04x ints %04x\n", __FUNCTION__, packet, ints);
1162 #endif
1163         if (cpd->txbusy) {
1164                 cpd->txbusy = 0;
1165                 sc->funs->eth_drv->tx_done(sc, cpd->txkey, success);
1166         }
1167 }
1168
1169 //
1170 // This function is called when a packet has been received.  Its job is
1171 // to prepare to unload the packet from the hardware.  Once the length of
1172 // the packet is known, the upper layer of the driver can be told.  When
1173 // the upper layer is ready to unload the packet, the internal function
1174 // 'lan91c111_recv' will be called to actually fetch it from the hardware.
1175 //
1176 static void
1177 lan91c111_RxEvent(struct eth_drv_sc *sc)
1178 {
1179         struct lan91c111_priv_data *cpd = (struct lan91c111_priv_data *)sc->driver_private;
1180         unsigned short stat, len, controlbyte;
1181 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1182         unsigned long result;
1183 #endif
1184         DEBUG_FUNCTION();
1185
1186         stat = get_reg(sc, LAN91C111_FIFO_PORTS);
1187 #if DEBUG_SMSC & 1
1188         diag_printf("RxEvent - FIFOs: 0x%04x\n", stat);
1189 #endif
1190         if (0x8000 & stat)
1191                 // Then the Rx FIFO is empty
1192                 return;
1193
1194         INCR_STAT(rx_count);
1195
1196 #if DEBUG_SMSC & 4
1197         diag_printf("#####Rx packet allocated %x (previous %x)\n",
1198                     0xff & (stat >> 8), cpd->rxpacket );
1199 #endif
1200         // There is an Rx Packet ready
1201         cpd->rxpacket = 0xff & (stat >> 8);
1202
1203         // Read status and (word) length
1204         put_reg(sc, LAN91C111_POINTER, (LAN91C111_POINTER_RCV | LAN91C111_POINTER_READ |
1205                                         LAN91C111_POINTER_AUTO_INCR | 0x0000));
1206
1207 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1208         result = get_data32(sc);
1209         stat = (unsigned short)(result & 0xffff);
1210         len = (unsigned short)(result >> 16);
1211 #else
1212         stat = get_data(sc);
1213         len = get_data(sc);             // minus header/footer words
1214 #endif
1215         len &= 0x7ff;
1216         len = len - 6;             // minus header/footer words
1217 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1218         // Read control byte at end of packet to get last bit of length
1219         put_reg(sc, LAN91C111_POINTER, (LAN91C111_POINTER_RCV | LAN91C111_POINTER_READ |
1220                                         LAN91C111_POINTER_AUTO_INCR | (len + 4)));
1221         if (!(len % 4)) {
1222                 put_reg(sc, LAN91C111_POINTER, (LAN91C111_POINTER_RCV | LAN91C111_POINTER_READ |
1223                                                 LAN91C111_POINTER_AUTO_INCR | (len + 2)));
1224                 result = get_data32(sc);
1225                 controlbyte = (unsigned short)((result >> 16) & 0xffff);
1226         } else {
1227                 put_reg(sc, LAN91C111_POINTER, (LAN91C111_POINTER_RCV | LAN91C111_POINTER_READ |
1228                                                 LAN91C111_POINTER_AUTO_INCR | (len + 4)));
1229                 result = get_data32(sc);
1230                 controlbyte = (unsigned short)((result) & 0xffff);
1231         }
1232 #else
1233         // Read control byte at end of packet to get last bit of length
1234         put_reg(sc, LAN91C111_POINTER, (LAN91C111_POINTER_RCV | LAN91C111_POINTER_READ |
1235                                         LAN91C111_POINTER_AUTO_INCR | (len + 4)));
1236         controlbyte = get_data(sc);
1237 #endif
1238 #ifdef KEEP_STATISTICS
1239         if ( stat & LAN91C111_RX_STATUS_ALIGNERR ) INCR_STAT( rx_align_errors );
1240         //if ( stat & LAN91C111_RX_STATUS_BCAST    ) INCR_STAT(  );
1241         if ( stat & LAN91C111_RX_STATUS_BADCRC   ) INCR_STAT( rx_crc_errors );
1242         if ( stat & LAN91C111_RX_STATUS_TOOLONG  ) INCR_STAT( rx_too_long_frames );
1243         if ( stat & LAN91C111_RX_STATUS_TOOSHORT ) INCR_STAT( rx_short_frames );
1244         //if ( stat & LAN91C111_RX_STATUS_MCAST    ) INCR_STAT(  );
1245 #endif // KEEP_STATISTICS
1246         if (controlbyte & LAN91C111_CONTROLBYTE_RX) {
1247                 INCR_STAT( rx_good );
1248                 // Then it's OK
1249                 if (controlbyte & LAN91C111_CONTROLBYTE_ODD)
1250                         len++;
1251 #if DEBUG_SMSC & 32
1252                 diag_printf("RxEvent good rx - stat: 0x%04x, len: 0x%04x\n", stat, len);
1253 #endif
1254                 // Check for bogusly short packets; can happen in promisc mode:
1255                 // Asserted against and checked by upper layer driver.
1256 #ifdef CYGPKG_NET
1257                 if (len > sizeof(struct ether_header))
1258                         // then it is acceptable; offer the data to the network stack
1259 #endif
1260                         sc->funs->eth_drv->recv(sc, len);
1261                 return;
1262         }
1263         // Not OK for one reason or another...
1264 #if DEBUG_SMSC & 32
1265         diag_printf("RxEvent - No RX bit: stat: 0x%04x, len: %d, control'byte' 0x%04x\n",
1266                     stat, len, controlbyte);
1267 #endif
1268 #if DEBUG_SMSC & 4
1269         stat = get_reg(sc, LAN91C111_FIFO_PORTS);
1270         if ( 0x8000 & stat ) // Then the Rx FIFO is empty
1271                 diag_printf("#####Rx packet (bad controlbyte) NOT freed, stat is %x (expected %x)\n",
1272                             stat, cpd->rxpacket );
1273         else
1274                 diag_printf("#####Rx packet (bad controlbyte) freed %x (expected %x)\n",
1275                             0xff & (stat >> 8), cpd->rxpacket );
1276 #endif
1277         // Free packet
1278         put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_remrel_rx_frame);
1279 }
1280
1281 //
1282 // This function is called as a result of the "eth_drv_recv()" call above.
1283 // Its job is to actually fetch data for a packet from the hardware once
1284 // memory buffers have been allocated for the packet.  Note that the buffers
1285 // may come in pieces, using a scatter-gather list.  This allows for more
1286 // efficient processing in the upper layers of the stack.
1287 //
1288 static void
1289 lan91c111_recv(struct eth_drv_sc *sc, struct eth_drv_sg *sg_list, int sg_len)
1290 {
1291 #if (4 & DEBUG_SMSC) || defined(CYGPKG_INFRA_DEBUG) || defined(KEEP_STATISTICS)
1292         struct lan91c111_priv_data *cpd =
1293                 (struct lan91c111_priv_data *)sc->driver_private;
1294 #endif
1295         int i, mlen=0, plen;
1296         unsigned short *data = NULL, val;
1297         unsigned char *cp, cval;
1298         int u, wleft = 0;
1299         unsigned long result = 0;
1300         unsigned short stat;
1301         int dump_buf = 0;
1302
1303         DEBUG_FUNCTION();
1304 #if DEBUG_SMSC & 32
1305         diag_printf("\n\n\nreceiving package .... \n");
1306 #endif
1307         INCR_STAT(rx_deliver);
1308
1309         put_reg(sc, LAN91C111_POINTER, (LAN91C111_POINTER_RCV | LAN91C111_POINTER_READ |
1310                                         LAN91C111_POINTER_AUTO_INCR | 0x0000));
1311 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1312         result = get_data32(sc);
1313         stat = (unsigned short)(result & 0xffff);
1314         plen = (unsigned short)(result >> 16) -6;
1315 #else
1316         stat = get_data(sc);
1317         plen = get_data(sc) -6;         // minus header/footer words
1318 #endif
1319         if (!((stat & 0x4000) || (stat & 0x0001))) {
1320                 dump_buf=1;             // don't want to see BroadCast and Multicast
1321         }
1322         u = 0;
1323
1324         for (i = 0;  i < sg_len;  i++) {
1325                 data = (unsigned short *)sg_list[i].buf;
1326                 mlen = sg_list[i].len;
1327
1328                 CYG_ASSERT(0 == (mlen & 1) || (i == (sg_len-1)), "odd length");
1329 #if DEBUG_SMSC & 1
1330                 diag_printf("%s : mlen %x, plen %x\n", __FUNCTION__, mlen, plen);
1331 #endif
1332 #if (DEBUG_SMSC & 128)
1333                 if (dump_buf) {
1334                         diag_printf("\n\n\ndumping receive buffer:\n");
1335                         diag_printf("Status of packet is 0x%04X\n", stat);
1336                         diag_printf("Data length of packet is %d\n", plen);
1337                 }
1338 #endif
1339                 wleft = 0;
1340                 if (data) {
1341                         while (mlen >= sizeof(*data)) {
1342                                 if (!wleft) {
1343 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1344                                         result = get_data32(sc);
1345 #else
1346                                         result = get_data(sc) & 0xffff;
1347                                         result |= (get_data(sc)<<16);
1348 #endif
1349                                         wleft = 2;
1350                                 }
1351
1352                                 if (wleft == 2) {
1353                                         *data++ = (unsigned short)(result & 0xffff);
1354                                         wleft--;
1355                                 } else {
1356                                         *data++ = (unsigned short)((result>>16) & 0xffff);
1357                                         wleft--;
1358                                 }
1359
1360 #if (DEBUG_SMSC & 128)
1361                                 if (dump_buf) {
1362                                         diag_printf("%02X ", *(data-1)& 0xff);                  // low byte
1363                                         diag_printf("%02X ", (*(data-1)& 0xff00)>>8);   // high byte
1364
1365                                         u++;
1366                                         if (u==16) {
1367                                                 diag_printf("\n");
1368                                                 u=0;
1369                                         }
1370                                 }
1371
1372 #endif
1373
1374                                 mlen -= sizeof(*data);
1375                                 plen -= sizeof(*data);
1376                         }
1377                 } else { // must actively discard ie. read it from the chip anyway.
1378                         while (mlen >= sizeof(*data)) {
1379
1380                                 if (!wleft) {
1381 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1382                                         result = get_data32(sc);
1383 #else
1384                                         result = get_data(sc);
1385                                         result = get_data(sc);
1386 #endif
1387                                         wleft = 1;
1388                                 }
1389
1390                                 mlen -= sizeof(*data);
1391                                 plen -= sizeof(*data);
1392                         }
1393                 }
1394         }
1395         if (wleft == 1) {
1396                 val = (unsigned short)((result>>16) & 0xffff); // Read control word unconditionally
1397         } else {
1398 #ifdef CYGSEM_DEVS_ETH_SMSC_LAN91C111_USE_32BIT
1399                 val = (unsigned short)(get_data32(sc) & 0xffff);
1400 #else
1401                 val = get_data(sc);
1402 #endif
1403         }
1404
1405         CYG_ASSERT(val & LAN91C111_CONTROLBYTE_RX,
1406                    "Controlbyte is not for Rx");
1407         CYG_ASSERT( (1 == mlen) == (0 != (val & LAN91C111_CONTROLBYTE_ODD)),
1408                     "Controlbyte does not match");
1409         if (data && (1 == mlen) && (val & LAN91C111_CONTROLBYTE_ODD)) {
1410                 cval = val & 0x00ff;    // last byte contains data
1411                 cp = (unsigned char*)data;
1412                 *cp = cval;
1413
1414 #if (DEBUG_SMSC & 128)
1415                 if (dump_buf) {
1416                         diag_printf("\nlast byte written to buffer: %02X \n",cval);
1417                 }
1418 #endif
1419         }
1420
1421         val = get_reg(sc, LAN91C111_FIFO_PORTS);
1422 #if DEBUG_SMSC & 4
1423         if (0x8000 & val) { // Then the Rx FIFO is empty
1424                 diag_printf("#####Rx packet NOT freed, stat is %x (expected %x)\n",
1425                             val, cpd->rxpacket);
1426         } else {
1427                 diag_printf("#####Rx packet freed %x (expected %x)\n",
1428                             0xff & (val >> 8), cpd->rxpacket);
1429         }
1430 #endif
1431         CYG_ASSERT((0xff & (val >> 8)) == cpd->rxpacket, "Unexpected rx packet");
1432
1433         // Free packet
1434         put_reg(sc, LAN91C111_MMU_COMMAND, LAN91C111_MMU_remrel_rx_frame);
1435 }
1436
1437 static void
1438 lan91c111_poll(struct eth_drv_sc *sc)
1439 {
1440         unsigned short event;
1441
1442         DEBUG_FUNCTION();
1443
1444         while (1) {
1445                 // Get the (unmasked) requests
1446                 event = get_reg(sc, LAN91C111_INTERRUPT);
1447
1448                 //diag_printf("LAN91C111_INTERRUPT_REGISTER: %04X\n", event);
1449
1450                 event &= event >> 8;
1451                 //diag_printf("event: %04X\n", event);
1452
1453                 if (0 == event) {
1454                         break;
1455                 } else if (event & LAN91C111_INTERRUPT_ERCV_INT) {
1456                         // Early receive interrupt
1457                 } else if (event & LAN91C111_INTERRUPT_EPH_INT) {
1458                         // ethernet protocol handler failures
1459                 } else if (event & LAN91C111_INTERRUPT_RX_OVRN_INT) {
1460                         // receive overrun
1461                 } else if (event & LAN91C111_INTERRUPT_ALLOC_INT) {
1462                         // allocation interrupt
1463                 } else if (event & LAN91C111_INTERRUPT_TX_SET) {
1464                         lan91c111_TxEvent(sc, event);
1465                 } else if (event & LAN91C111_INTERRUPT_RCV_INT) {
1466                         lan91c111_RxEvent(sc);
1467                 } else {
1468                         diag_printf("%s: Unknown interrupt: 0x%04x\n",
1469                                     __FUNCTION__, event);
1470                 }
1471         }
1472 }