Main Page | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

sunhme.c

Go to the documentation of this file.
00001 /* sunhme.c: Sparc HME/BigMac 10/100baseT half/full duplex auto switching,
00002  *           auto carrier detecting ethernet driver.  Also known as the
00003  *           "Happy Meal Ethernet" found on SunSwift SBUS cards.
00004  *
00005  * Copyright (C) 1996, 1998 David S. Miller (davem@caipfs.rutgers.edu)
00006  */
00007 
00008 static char *version =
00009         "sunhme.c:v1.10 27/Jan/99 David S. Miller (davem@caipfs.rutgers.edu)\n";
00010 
00011 #include <linux/module.h>
00012 
00013 #include <linux/config.h>
00014 #include <linux/kernel.h>
00015 #include <linux/sched.h>
00016 #include <linux/types.h>
00017 #include <linux/fcntl.h>
00018 #include <linux/interrupt.h>
00019 #include <linux/ptrace.h>
00020 #include <linux/ioport.h>
00021 #include <linux/in.h>
00022 #include <linux/malloc.h>
00023 #include <linux/string.h>
00024 #include <linux/delay.h>
00025 #include <linux/init.h>
00026 #include <asm/system.h>
00027 #include <asm/bitops.h>
00028 #include <asm/io.h>
00029 #include <asm/dma.h>
00030 #include <linux/errno.h>
00031 #include <asm/byteorder.h>
00032 
00033 #include <asm/idprom.h>
00034 #include <asm/sbus.h>
00035 #include <asm/openprom.h>
00036 #include <asm/oplib.h>
00037 #include <asm/auxio.h>
00038 #include <asm/pgtable.h>
00039 #include <asm/irq.h>
00040 #ifndef __sparc_v9__
00041 #include <asm/io-unit.h>
00042 #endif
00043 #include <asm/ethtool.h>
00044 #include <asm/uaccess.h>
00045 
00046 #include <linux/netdevice.h>
00047 #include <linux/etherdevice.h>
00048 #include <linux/skbuff.h>
00049 
00050 #ifdef CONFIG_PCI
00051 #include <linux/pci.h>
00052 #include <asm/pbm.h>
00053 #endif
00054 
00055 #include "sunhme.h"
00056 
00057 #ifdef MODULE
00058 static struct happy_meal *root_happy_dev = NULL;
00059 #endif
00060 
00061 static struct quattro *qfe_sbus_list = NULL;
00062 #ifdef CONFIG_PCI
00063 static struct quattro *qfe_pci_list = NULL;
00064 #endif
00065 
00066 #undef HMEDEBUG
00067 #undef SXDEBUG
00068 #undef RXDEBUG
00069 #undef TXDEBUG
00070 #undef TXLOGGING
00071 
00072 #ifdef TXLOGGING
00073 struct hme_tx_logent {
00074         unsigned int tstamp;
00075         int tx_new, tx_old;
00076         unsigned int action;
00077 #define TXLOG_ACTION_IRQ        0x01
00078 #define TXLOG_ACTION_TXMIT      0x02
00079 #define TXLOG_ACTION_TBUSY      0x04
00080 #define TXLOG_ACTION_NBUFS      0x08
00081         unsigned int status;
00082 };
00083 #define TX_LOG_LEN      128
00084 static struct hme_tx_logent tx_log[TX_LOG_LEN];
00085 static int txlog_cur_entry = 0;
00086 static __inline__ void tx_add_log(struct happy_meal *hp, unsigned int a, unsigned int s)
00087 {
00088         struct hme_tx_logent *tlp;
00089         unsigned long flags;
00090 
00091         save_and_cli(flags);
00092         tlp = &tx_log[txlog_cur_entry];
00093         tlp->tstamp = (unsigned int)jiffies;
00094         tlp->tx_new = hp->tx_new;
00095         tlp->tx_old = hp->tx_old;
00096         tlp->action = a;
00097         tlp->status = s;
00098         txlog_cur_entry = (txlog_cur_entry + 1) & (TX_LOG_LEN - 1);
00099         restore_flags(flags);
00100 }
00101 static __inline__ void tx_dump_log(void)
00102 {
00103         int i, this;
00104 
00105         this = txlog_cur_entry;
00106         for(i = 0; i < TX_LOG_LEN; i++) {
00107                 printk("TXLOG[%d]: j[%08x] tx[N(%d)O(%d)] action[%08x] stat[%08x]\n", i,
00108                        tx_log[this].tstamp,
00109                        tx_log[this].tx_new, tx_log[this].tx_old,
00110                        tx_log[this].action, tx_log[this].status);
00111                 this = (this + 1) & (TX_LOG_LEN - 1);
00112         }
00113 }
00114 static __inline__ void tx_dump_ring(struct happy_meal *hp)
00115 {
00116         struct hmeal_init_block *hb = hp->happy_block;
00117         struct happy_meal_txd *tp = &hb->happy_meal_txd[0];
00118         int i;
00119 
00120         for(i = 0; i < TX_RING_SIZE; i+=4) {
00121                 printk("TXD[%d..%d]: [%08x:%08x] [%08x:%08x] [%08x:%08x] [%08x:%08x]\n",
00122                        i, i + 4,
00123                        le32_to_cpu(tp[i].tx_flags), le32_to_cpu(tp[i].tx_addr),
00124                        le32_to_cpu(tp[i + 1].tx_flags), le32_to_cpu(tp[i + 1].tx_addr),
00125                        le32_to_cpu(tp[i + 2].tx_flags), le32_to_cpu(tp[i + 2].tx_addr),
00126                        le32_to_cpu(tp[i + 3].tx_flags), le32_to_cpu(tp[i + 3].tx_addr));
00127         }
00128 }
00129 #else
00130 #define tx_add_log(hp, a, s)            do { } while(0)
00131 #define tx_dump_log()                   do { } while(0)
00132 #define tx_dump_ring(hp)                do { } while(0)
00133 #endif
00134 
00135 #ifdef HMEDEBUG
00136 #define HMD(x)  printk x
00137 #else
00138 #define HMD(x)
00139 #endif
00140 
00141 /* #define AUTO_SWITCH_DEBUG */
00142 
00143 #ifdef AUTO_SWITCH_DEBUG
00144 #define ASD(x)  printk x
00145 #else
00146 #define ASD(x)
00147 #endif
00148 
00149 #define DEFAULT_IPG0      16 /* For lance-mode only */
00150 #define DEFAULT_IPG1       8 /* For all modes */
00151 #define DEFAULT_IPG2       4 /* For all modes */
00152 #define DEFAULT_JAMSIZE    4 /* Toe jam */
00153 
00154 /* Oh yes, the MIF BitBang is mighty fun to program.  BitBucket is more like it. */
00155 #define BB_PUT_BIT(hp, tregs, bit)                                              \
00156 do {    hme_write32(hp, &(tregs)->bb_data, (bit));                              \
00157         hme_write32(hp, &(tregs)->bb_clock, 0);                                 \
00158         hme_write32(hp, &(tregs)->bb_clock, 1);                                 \
00159 } while(0)
00160 
00161 #define BB_GET_BIT(hp, tregs, internal)                                         \
00162 ({                                                                              \
00163         hme_write32(hp, &(tregs)->bb_clock, 0);                                 \
00164         hme_write32(hp, &(tregs)->bb_clock, 1);                                 \
00165         if(internal)                                                            \
00166                 hme_read32(hp, &(tregs)->cfg) & TCV_CFG_MDIO0;                  \
00167         else                                                                    \
00168                 hme_read32(hp, &(tregs)->cfg) & TCV_CFG_MDIO1;                  \
00169 })
00170 
00171 #define BB_GET_BIT2(hp, tregs, internal)                                        \
00172 ({                                                                              \
00173         int retval;                                                             \
00174         hme_write32(hp, &(tregs)->bb_clock, 0);                                 \
00175         udelay(1);                                                              \
00176         if(internal)                                                            \
00177                 retval = hme_read32(hp, &(tregs)->cfg) & TCV_CFG_MDIO0;         \
00178         else                                                                    \
00179                 retval = hme_read32(hp, &(tregs)->cfg) & TCV_CFG_MDIO1;         \
00180         hme_write32(hp, &(tregs)->bb_clock, 1);                                 \
00181         retval;                                                                 \
00182 })
00183 
00184 #define TCVR_FAILURE      0x80000000     /* Impossible MIF read value */
00185 
00186 static inline int happy_meal_bb_read(struct happy_meal *hp,
00187                                      struct hmeal_tcvregs *tregs, int reg)
00188 {
00189         volatile int unused;
00190         unsigned long tmp;
00191         int retval = 0;
00192         int i;
00193 
00194         ASD(("happy_meal_bb_read: reg=%d ", reg));
00195 
00196         /* Enable the MIF BitBang outputs. */
00197         hme_write32(hp, &tregs->bb_oenab, 1);
00198 
00199         /* Force BitBang into the idle state. */
00200         for(i = 0; i < 32; i++)
00201                 BB_PUT_BIT(hp, tregs, 1);
00202 
00203         /* Give it the read sequence. */
00204         BB_PUT_BIT(hp, tregs, 0);
00205         BB_PUT_BIT(hp, tregs, 1);
00206         BB_PUT_BIT(hp, tregs, 1);
00207         BB_PUT_BIT(hp, tregs, 0);
00208 
00209         /* Give it the PHY address. */
00210         tmp = hp->paddr & 0xff;
00211         for(i = 4; i >= 0; i--)
00212                 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
00213 
00214         /* Tell it what register we want to read. */
00215         tmp = (reg & 0xff);
00216         for(i = 4; i >= 0; i--)
00217                 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
00218 
00219         /* Close down the MIF BitBang outputs. */
00220         hme_write32(hp, &tregs->bb_oenab, 0);
00221 
00222         /* Now read in the value. */
00223         unused = BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
00224         for(i = 15; i >= 0; i--)
00225                 retval |= BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
00226         unused = BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
00227         unused = BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
00228         unused = BB_GET_BIT2(hp, tregs, (hp->tcvr_type == internal));
00229         ASD(("value=%x\n", retval));
00230         return retval;
00231 }
00232 
00233 static inline void happy_meal_bb_write(struct happy_meal *hp,
00234                                        struct hmeal_tcvregs *tregs, int reg,
00235                                        unsigned short value)
00236 {
00237         unsigned long tmp;
00238         int i;
00239 
00240         ASD(("happy_meal_bb_write: reg=%d value=%x\n", reg, value));
00241 
00242         /* Enable the MIF BitBang outputs. */
00243         hme_write32(hp, &tregs->bb_oenab, 1);
00244 
00245         /* Force BitBang into the idle state. */
00246         for(i = 0; i < 32; i++)
00247                 BB_PUT_BIT(hp, tregs, 1);
00248 
00249         /* Give it write sequence. */
00250         BB_PUT_BIT(hp, tregs, 0);
00251         BB_PUT_BIT(hp, tregs, 1);
00252         BB_PUT_BIT(hp, tregs, 0);
00253         BB_PUT_BIT(hp, tregs, 1);
00254 
00255         /* Give it the PHY address. */
00256         tmp = (hp->paddr & 0xff);
00257         for(i = 4; i >= 0; i--)
00258                 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
00259 
00260         /* Tell it what register we will be writing. */
00261         tmp = (reg & 0xff);
00262         for(i = 4; i >= 0; i--)
00263                 BB_PUT_BIT(hp, tregs, ((tmp >> i) & 1));
00264 
00265         /* Tell it to become ready for the bits. */
00266         BB_PUT_BIT(hp, tregs, 1);
00267         BB_PUT_BIT(hp, tregs, 0);
00268 
00269         for(i = 15; i >= 0; i--)
00270                 BB_PUT_BIT(hp, tregs, ((value >> i) & 1));
00271 
00272         /* Close down the MIF BitBang outputs. */
00273         hme_write32(hp, &tregs->bb_oenab, 0);
00274 }
00275 
00276 #define TCVR_READ_TRIES   16
00277 
00278 static inline int happy_meal_tcvr_read(struct happy_meal *hp,
00279                                        struct hmeal_tcvregs *tregs, int reg)
00280 {
00281         int tries = TCVR_READ_TRIES;
00282         int retval;
00283 
00284         ASD(("happy_meal_tcvr_read: reg=0x%02x ", reg));
00285         if(hp->tcvr_type == none) {
00286                 ASD(("no transceiver, value=TCVR_FAILURE\n"));
00287                 return TCVR_FAILURE;
00288         }
00289 
00290         if(!(hp->happy_flags & HFLAG_FENABLE)) {
00291                 ASD(("doing bit bang\n"));
00292                 return happy_meal_bb_read(hp, tregs, reg);
00293         }
00294 
00295         hme_write32(hp, &tregs->frame,
00296                     (FRAME_READ | (hp->paddr << 23) | ((reg & 0xff) << 18)));
00297         while(!(hme_read32(hp, &tregs->frame) & 0x10000) && --tries)
00298                 udelay(20);
00299         if(!tries) {
00300                 printk(KERN_ERR "happy meal: Aieee, transceiver MIF read bolixed\n");
00301                 return TCVR_FAILURE;
00302         }
00303         retval = hme_read32(hp, &tregs->frame) & 0xffff;
00304         ASD(("value=%04x\n", retval));
00305         return retval;
00306 }
00307 
00308 #define TCVR_WRITE_TRIES  16
00309 
00310 static inline void happy_meal_tcvr_write(struct happy_meal *hp,
00311                                          struct hmeal_tcvregs *tregs, int reg,
00312                                          unsigned short value)
00313 {
00314         int tries = TCVR_WRITE_TRIES;
00315         
00316         ASD(("happy_meal_tcvr_write: reg=0x%02x value=%04x\n", reg, value));
00317 
00318         /* Welcome to Sun Microsystems, can I take your order please? */
00319         if(!hp->happy_flags & HFLAG_FENABLE)
00320                 return happy_meal_bb_write(hp, tregs, reg, value);
00321 
00322         /* Would you like fries with that? */
00323         hme_write32(hp, &tregs->frame,
00324                     (FRAME_WRITE | (hp->paddr << 23) |
00325                      ((reg & 0xff) << 18) | (value & 0xffff)));
00326         while(!(hme_read32(hp, &tregs->frame) & 0x10000) && --tries)
00327                 udelay(20);
00328 
00329         /* Anything else? */
00330         if(!tries)
00331                 printk(KERN_ERR "happy meal: Aieee, transceiver MIF write bolixed\n");
00332 
00333         /* Fifty-two cents is your change, have a nice day. */
00334 }
00335 
00336 /* Auto negotiation.  The scheme is very simple.  We have a timer routine
00337  * that keeps watching the auto negotiation process as it progresses.
00338  * The DP83840 is first told to start doing it's thing, we set up the time
00339  * and place the timer state machine in it's initial state.
00340  *
00341  * Here the timer peeks at the DP83840 status registers at each click to see
00342  * if the auto negotiation has completed, we assume here that the DP83840 PHY
00343  * will time out at some point and just tell us what (didn't) happen.  For
00344  * complete coverage we only allow so many of the ticks at this level to run,
00345  * when this has expired we print a warning message and try another strategy.
00346  * This "other" strategy is to force the interface into various speed/duplex
00347  * configurations and we stop when we see a link-up condition before the
00348  * maximum number of "peek" ticks have occurred.
00349  *
00350  * Once a valid link status has been detected we configure the BigMAC and
00351  * the rest of the Happy Meal to speak the most efficient protocol we could
00352  * get a clean link for.  The priority for link configurations, highest first
00353  * is:
00354  *                 100 Base-T Full Duplex
00355  *                 100 Base-T Half Duplex
00356  *                 10 Base-T Full Duplex
00357  *                 10 Base-T Half Duplex
00358  *
00359  * We start a new timer now, after a successful auto negotiation status has
00360  * been detected.  This timer just waits for the link-up bit to get set in
00361  * the BMCR of the DP83840.  When this occurs we print a kernel log message
00362  * describing the link type in use and the fact that it is up.
00363  *
00364  * If a fatal error of some sort is signalled and detected in the interrupt
00365  * service routine, and the chip is reset, or the link is ifconfig'd down
00366  * and then back up, this entire process repeats itself all over again.
00367  */
00368 static int try_next_permutation(struct happy_meal *hp, struct hmeal_tcvregs *tregs)
00369 {
00370         hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00371 
00372         /* Downgrade from full to half duplex.  Only possible
00373          * via ethtool.
00374          */
00375         if(hp->sw_bmcr & BMCR_FULLDPLX) {
00376                 hp->sw_bmcr &= ~(BMCR_FULLDPLX);
00377                 happy_meal_tcvr_write(hp, tregs, DP83840_BMCR, hp->sw_bmcr);
00378                 return 0;
00379         }
00380 
00381         /* Downgrade from 100 to 10. */
00382         if(hp->sw_bmcr & BMCR_SPEED100) {
00383                 hp->sw_bmcr &= ~(BMCR_SPEED100);
00384                 happy_meal_tcvr_write(hp, tregs, DP83840_BMCR, hp->sw_bmcr);
00385                 return 0;
00386         }
00387 
00388         /* We've tried everything. */
00389         return -1;
00390 }
00391 
00392 static void display_link_mode(struct happy_meal *hp, struct hmeal_tcvregs *tregs)
00393 {
00394         printk(KERN_INFO "%s: Link is up using ", hp->dev->name);
00395         if(hp->tcvr_type == external)
00396                 printk("external ");
00397         else
00398                 printk("internal ");
00399         printk("transceiver at ");
00400         hp->sw_lpa = happy_meal_tcvr_read(hp, tregs, DP83840_LPA);
00401         if(hp->sw_lpa & (LPA_100HALF | LPA_100FULL)) {
00402                 if(hp->sw_lpa & LPA_100FULL)
00403                         printk("100Mb/s, Full Duplex.\n");
00404                 else
00405                         printk("100Mb/s, Half Duplex.\n");
00406         } else {
00407                 if(hp->sw_lpa & LPA_10FULL)
00408                         printk("10Mb/s, Full Duplex.\n");
00409                 else
00410                         printk("10Mb/s, Half Duplex.\n");
00411         }
00412 }
00413 
00414 static void display_forced_link_mode(struct happy_meal *hp, struct hmeal_tcvregs *tregs)
00415 {
00416         printk(KERN_INFO "%s: Link has been forced up using ", hp->dev->name);
00417         if(hp->tcvr_type == external)
00418                 printk("external ");
00419         else
00420                 printk("internal ");
00421         printk("transceiver at ");
00422         hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00423         if(hp->sw_bmcr & BMCR_SPEED100)
00424                 printk("100Mb/s, ");
00425         else
00426                 printk("10Mb/s, ");
00427         if(hp->sw_bmcr & BMCR_FULLDPLX)
00428                 printk("Full Duplex.\n");
00429         else
00430                 printk("Half Duplex.\n");
00431 }
00432 
00433 static int set_happy_link_modes(struct happy_meal *hp, struct hmeal_tcvregs *tregs)
00434 {
00435         int full;
00436 
00437         /* All we care about is making sure the bigmac tx_cfg has a
00438          * proper duplex setting.
00439          */
00440         if(hp->timer_state == arbwait) {
00441                 hp->sw_lpa = happy_meal_tcvr_read(hp, tregs, DP83840_LPA);
00442                 if(!(hp->sw_lpa & (LPA_10HALF | LPA_10FULL | LPA_100HALF | LPA_100FULL)))
00443                         goto no_response;
00444                 if(hp->sw_lpa & LPA_100FULL)
00445                         full = 1;
00446                 else if(hp->sw_lpa & LPA_100HALF)
00447                         full = 0;
00448                 else if(hp->sw_lpa & LPA_10FULL)
00449                         full = 1;
00450                 else
00451                         full = 0;
00452         } else {
00453                 /* Forcing a link mode. */
00454                 hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00455                 if(hp->sw_bmcr & BMCR_FULLDPLX)
00456                         full = 1;
00457                 else
00458                         full = 0;
00459         }
00460 
00461         /* Before changing other bits in the tx_cfg register, and in
00462          * general any of other the TX config registers too, you
00463          * must:
00464          * 1) Clear Enable
00465          * 2) Poll with reads until that bit reads back as zero
00466          * 3) Make TX configuration changes
00467          * 4) Set Enable once more
00468          */
00469         hme_write32(hp, &hp->bigmacregs->tx_cfg,
00470                     hme_read32(hp, &hp->bigmacregs->tx_cfg) &
00471                     ~(BIGMAC_TXCFG_ENABLE));
00472         while(hme_read32(hp, &hp->bigmacregs->tx_cfg) & BIGMAC_TXCFG_ENABLE)
00473                 barrier();
00474         if(full) {
00475                 hp->happy_flags |= HFLAG_FULL;
00476                 hme_write32(hp, &hp->bigmacregs->tx_cfg,
00477                             hme_read32(hp, &hp->bigmacregs->tx_cfg) |
00478                             BIGMAC_TXCFG_FULLDPLX);
00479         } else {
00480                 hp->happy_flags &= ~(HFLAG_FULL);
00481                 hme_write32(hp, &hp->bigmacregs->tx_cfg,
00482                             hme_read32(hp, &hp->bigmacregs->tx_cfg) &
00483                             ~(BIGMAC_TXCFG_FULLDPLX));
00484         }
00485         hme_write32(hp, &hp->bigmacregs->tx_cfg,
00486                     hme_read32(hp, &hp->bigmacregs->tx_cfg) |
00487                     BIGMAC_TXCFG_ENABLE);
00488         return 0;
00489 no_response:
00490         return 1;
00491 }
00492 
00493 static int happy_meal_init(struct happy_meal *hp, int from_irq);
00494 
00495 static int is_lucent_phy(struct happy_meal *hp)
00496 {
00497         struct hmeal_tcvregs *tregs = hp->tcvregs;
00498         unsigned short mr2, mr3;
00499         int ret = 0;
00500 
00501         mr2 = happy_meal_tcvr_read(hp, tregs, 2);
00502         mr3 = happy_meal_tcvr_read(hp, tregs, 3);
00503         if ((mr2 & 0xffff) == 0x0180 &&
00504             ((mr3 & 0xffff) >> 10) == 0x1d) {
00505 #if 0
00506                 printk("HMEDEBUG: Lucent PHY detected.\n");
00507 #endif
00508                 ret = 1;
00509         }
00510 
00511         return ret;
00512 }
00513 
00514 static void happy_meal_timer(unsigned long data)
00515 {
00516         struct happy_meal *hp = (struct happy_meal *) data;
00517         struct hmeal_tcvregs *tregs = hp->tcvregs;
00518         int restart_timer = 0;
00519 
00520         hp->timer_ticks++;
00521         switch(hp->timer_state) {
00522         case arbwait:
00523                 /* Only allow for 5 ticks, thats 10 seconds and much too
00524                  * long to wait for arbitration to complete.
00525                  */
00526                 if(hp->timer_ticks >= 10) {
00527                         /* Enter force mode. */
00528         do_force_mode:
00529                         hp->sw_bmcr = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00530                         printk(KERN_NOTICE "%s: Auto-Negotiation unsuccessful, trying force link mode\n",
00531                                hp->dev->name);
00532                         hp->sw_bmcr = BMCR_SPEED100;
00533                         happy_meal_tcvr_write(hp, tregs, DP83840_BMCR, hp->sw_bmcr);
00534 
00535                         if (!is_lucent_phy(hp)) {
00536                                 /* OK, seems we need do disable the transceiver for
00537                                  * the first tick to make sure we get an accurate
00538                                  * link state at the second tick.
00539                                  */
00540                                 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs,
00541                                                                        DP83840_CSCONFIG);
00542                                 hp->sw_csconfig &= ~(CSCONFIG_TCVDISAB);
00543                                 happy_meal_tcvr_write(hp, tregs, DP83840_CSCONFIG,
00544                                                       hp->sw_csconfig);
00545                         }
00546                         hp->timer_state = ltrywait;
00547                         hp->timer_ticks = 0;
00548                         restart_timer = 1;
00549                 } else {
00550                         /* Anything interesting happen? */
00551                         hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, DP83840_BMSR);
00552                         if(hp->sw_bmsr & BMSR_ANEGCOMPLETE) {
00553                                 int ret;
00554 
00555                                 /* Just what we've been waiting for... */
00556                                 ret = set_happy_link_modes(hp, tregs);
00557                                 if(ret) {
00558                                         /* Ooops, something bad happened, go to force
00559                                          * mode.
00560                                          *
00561                                          * XXX Broken hubs which don't support 802.3u
00562                                          * XXX auto-negotiation make this happen as well.
00563                                          */
00564                                         goto do_force_mode;
00565                                 }
00566 
00567                                 /* Success, at least so far, advance our state engine. */
00568                                 hp->timer_state = lupwait;
00569                                 restart_timer = 1;
00570                         } else {
00571                                 restart_timer = 1;
00572                         }
00573                 }
00574                 break;
00575 
00576         case lupwait:
00577                 /* Auto negotiation was successful and we are awaiting a
00578                  * link up status.  I have decided to let this timer run
00579                  * forever until some sort of error is signalled, reporting
00580                  * a message to the user at 10 second intervals.
00581                  */
00582                 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, DP83840_BMSR);
00583                 if(hp->sw_bmsr & BMSR_LSTATUS) {
00584                         /* Wheee, it's up, display the link mode in use and put
00585                          * the timer to sleep.
00586                          */
00587                         display_link_mode(hp, tregs);
00588                         hp->timer_state = asleep;
00589                         restart_timer = 0;
00590                 } else {
00591                         if(hp->timer_ticks >= 10) {
00592                                 printk(KERN_NOTICE "%s: Auto negotiation successful, link still "
00593                                        "not completely up.\n", hp->dev->name);
00594                                 hp->timer_ticks = 0;
00595                                 restart_timer = 1;
00596                         } else {
00597                                 restart_timer = 1;
00598                         }
00599                 }
00600                 break;
00601 
00602         case ltrywait:
00603                 /* Making the timeout here too long can make it take
00604                  * annoyingly long to attempt all of the link mode
00605                  * permutations, but then again this is essentially
00606                  * error recovery code for the most part.
00607                  */
00608                 hp->sw_bmsr = happy_meal_tcvr_read(hp, tregs, DP83840_BMSR);
00609                 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs, DP83840_CSCONFIG);
00610                 if(hp->timer_ticks == 1) {
00611                         /* Re-enable transceiver, we'll re-enable the transceiver next
00612                          * tick, then check link state on the following tick.
00613                          * XXX But dont do this on Lucent PHY -DaveM
00614                          */
00615                         if (!is_lucent_phy(hp)) {
00616                                 hp->sw_csconfig |= CSCONFIG_TCVDISAB;
00617                                 happy_meal_tcvr_write(hp, tregs,
00618                                                       DP83840_CSCONFIG, hp->sw_csconfig);
00619                         }
00620                         restart_timer = 1;
00621                         break;
00622                 }
00623                 if(hp->timer_ticks == 2) {
00624                         /* XXX See above about Lucent PHY -DaveM */
00625                         if (!is_lucent_phy(hp)) {
00626                                 hp->sw_csconfig &= ~(CSCONFIG_TCVDISAB);
00627                                 happy_meal_tcvr_write(hp, tregs,
00628                                                       DP83840_CSCONFIG, hp->sw_csconfig);
00629                         }
00630                         restart_timer = 1;
00631                         break;
00632                 }
00633                 if(hp->sw_bmsr & BMSR_LSTATUS) {
00634                         /* Force mode selection success. */
00635                         display_forced_link_mode(hp, tregs);
00636                         set_happy_link_modes(hp, tregs); /* XXX error? then what? */
00637                         hp->timer_state = asleep;
00638                         restart_timer = 0;
00639                 } else {
00640                         if(hp->timer_ticks >= 4) { /* 6 seconds or so... */
00641                                 int ret;
00642 
00643                                 ret = try_next_permutation(hp, tregs);
00644                                 if(ret == -1) {
00645                                         /* Aieee, tried them all, reset the
00646                                          * chip and try all over again.
00647                                          */
00648 
00649                                         /* Let the user know... */
00650                                         printk(KERN_NOTICE "%s: Link down, cable problem?\n",
00651                                                hp->dev->name);
00652 
00653                                         ret = happy_meal_init(hp, 0);
00654                                         if(ret) {
00655                                                 /* ho hum... */
00656                                                 printk(KERN_ERR "%s: Error, cannot re-init the "
00657                                                        "Happy Meal.\n", hp->dev->name);
00658                                         }
00659                                         return;
00660                                 }
00661                                 hp->sw_csconfig = happy_meal_tcvr_read(hp, tregs,
00662                                                                        DP83840_CSCONFIG);
00663                                 if (!is_lucent_phy(hp)) {
00664                                         hp->sw_csconfig |= CSCONFIG_TCVDISAB;
00665                                         happy_meal_tcvr_write(hp, tregs,
00666                                                               DP83840_CSCONFIG,
00667                                                               hp->sw_csconfig);
00668                                 }
00669                                 hp->timer_ticks = 0;
00670                                 restart_timer = 1;
00671                         } else {
00672                                 restart_timer = 1;
00673                         }
00674                 }
00675                 break;
00676 
00677         case asleep:
00678         default:
00679                 /* Can't happens.... */
00680                 printk(KERN_ERR "%s: Aieee, link timer is asleep but we got one anyways!\n",
00681                        hp->dev->name);
00682                 restart_timer = 0;
00683                 hp->timer_ticks = 0;
00684                 hp->timer_state = asleep; /* foo on you */
00685                 break;
00686         };
00687 
00688         if(restart_timer) {
00689                 hp->happy_timer.expires = jiffies + ((12 * HZ)/10); /* 1.2 sec. */
00690                 add_timer(&hp->happy_timer);
00691         }
00692 }
00693 
00694 #define TX_RESET_TRIES     32
00695 #define RX_RESET_TRIES     32
00696 
00697 static inline void happy_meal_tx_reset(struct happy_meal *hp,
00698                                        struct hmeal_bigmacregs *bregs)
00699 {
00700         int tries = TX_RESET_TRIES;
00701 
00702         HMD(("happy_meal_tx_reset: reset, "));
00703 
00704         /* Would you like to try our SMCC Delux? */
00705         hme_write32(hp, &bregs->tx_swreset, 0);
00706         while((hme_read32(hp, &bregs->tx_swreset) & 1) && --tries)
00707                 udelay(20);
00708 
00709         /* Lettuce, tomato, buggy hardware (no extra charge)? */
00710         if(!tries)
00711                 printk(KERN_ERR "happy meal: Transceiver BigMac ATTACK!");
00712 
00713         /* Take care. */
00714         HMD(("done\n"));
00715 }
00716 
00717 static inline void happy_meal_rx_reset(struct happy_meal *hp,
00718                                        struct hmeal_bigmacregs *bregs)
00719 {
00720         int tries = RX_RESET_TRIES;
00721 
00722         HMD(("happy_meal_rx_reset: reset, "));
00723 
00724         /* We have a special on GNU/Viking hardware bugs today. */
00725         hme_write32(hp, &bregs->rx_swreset, 0);
00726         while((hme_read32(hp, &bregs->rx_swreset) & 1) && --tries)
00727                 udelay(20);
00728 
00729         /* Will that be all? */
00730         if(!tries)
00731                 printk(KERN_ERR "happy meal: Receiver BigMac ATTACK!");
00732 
00733         /* Don't forget your vik_1137125_wa.  Have a nice day. */
00734         HMD(("done\n"));
00735 }
00736 
00737 #define STOP_TRIES         16
00738 
00739 static inline void happy_meal_stop(struct happy_meal *hp,
00740                                    struct hmeal_gregs *gregs)
00741 {
00742         int tries = STOP_TRIES;
00743 
00744         HMD(("happy_meal_stop: reset, "));
00745 
00746         /* We're consolidating our STB products, it's your lucky day. */
00747         hme_write32(hp, &gregs->sw_reset, GREG_RESET_ALL);
00748         while(hme_read32(hp, &gregs->sw_reset) && --tries)
00749                 udelay(20);
00750 
00751         /* Come back next week when we are "Sun Microelectronics". */
00752         if(!tries)
00753                 printk(KERN_ERR "happy meal: Fry guys.");
00754 
00755         /* Remember: "Different name, same old buggy as shit hardware." */
00756         HMD(("done\n"));
00757 }
00758 
00759 static void happy_meal_get_counters(struct happy_meal *hp,
00760                                     struct hmeal_bigmacregs *bregs)
00761 {
00762         struct net_device_stats *stats = &hp->net_stats;
00763 
00764         stats->rx_crc_errors += hme_read32(hp, &bregs->rcrce_ctr);
00765         hme_write32(hp, &bregs->rcrce_ctr, 0);
00766 
00767         stats->rx_frame_errors += hme_read32(hp, &bregs->unale_ctr);
00768         hme_write32(hp, &bregs->unale_ctr, 0);
00769 
00770         stats->rx_length_errors += hme_read32(hp, &bregs->gle_ctr);
00771         hme_write32(hp, &bregs->gle_ctr, 0);
00772 
00773         stats->tx_aborted_errors += hme_read32(hp, &bregs->ex_ctr);
00774 
00775         stats->collisions +=
00776                 (hme_read32(hp, &bregs->ex_ctr) +
00777                  hme_read32(hp, &bregs->lt_ctr));
00778         hme_write32(hp, &bregs->ex_ctr, 0);
00779         hme_write32(hp, &bregs->lt_ctr, 0);
00780 }
00781 
00782 static inline void happy_meal_poll_start(struct happy_meal *hp,
00783                                          struct hmeal_tcvregs *tregs)
00784 {
00785         unsigned long tmp;
00786         int speed;
00787 
00788         ASD(("happy_meal_poll_start: "));
00789         if(!(hp->happy_flags & HFLAG_POLLENABLE)) {
00790                 HMD(("polling disabled, return\n"));
00791                 return;
00792         }
00793 
00794         /* Start the MIF polling on the external transceiver. */
00795         ASD(("polling on, "));
00796         tmp = hme_read32(hp, &tregs->cfg);
00797         tmp &= ~(TCV_CFG_PDADDR | TCV_CFG_PREGADDR);
00798         tmp |= ((hp->paddr & 0x1f) << 10);
00799         tmp |= (TCV_PADDR_ETX << 3);
00800         tmp |= TCV_CFG_PENABLE;
00801         hme_write32(hp, &tregs->cfg, tmp);
00802 
00803         /* Let the bits set. */
00804         udelay(200);
00805 
00806         /* We are polling now. */
00807         ASD(("now polling, "));
00808         hp->happy_flags |= HFLAG_POLL;
00809 
00810         /* Clear the poll flags, get the basic status as of now. */
00811         hp->poll_flag = 0;
00812         hp->poll_data = tregs->status >> 16;
00813 
00814         if(hp->happy_flags & HFLAG_AUTO)
00815                 speed = hp->auto_speed;
00816         else
00817                 speed = hp->forced_speed;
00818 
00819         /* Listen only for the MIF interrupts we want to hear. */
00820         ASD(("mif ints on, "));
00821         if(speed == 100)
00822                 hme_write32(hp, &tregs->int_mask, 0xfffb);
00823         else
00824                 hme_write32(hp, &tregs->int_mask, 0xfff9);
00825         ASD(("done\n"));
00826 }
00827 
00828 static inline void happy_meal_poll_stop(struct happy_meal *hp,
00829                                         struct hmeal_tcvregs *tregs)
00830 {
00831         ASD(("happy_meal_poll_stop: "));
00832 
00833         /* If polling disabled or not polling already, nothing to do. */
00834         if((hp->happy_flags & (HFLAG_POLLENABLE | HFLAG_POLL)) !=
00835            (HFLAG_POLLENABLE | HFLAG_POLL)) {
00836                 HMD(("not polling, return\n"));
00837                 return;
00838         }
00839 
00840         /* Shut up the MIF. */
00841         ASD(("were polling, mif ints off, "));
00842         hme_write32(hp, &tregs->int_mask, 0xffff);
00843 
00844         /* Turn off polling. */
00845         ASD(("polling off, "));
00846         hme_write32(hp, &tregs->cfg,
00847                     hme_read32(hp, &tregs->cfg) & ~(TCV_CFG_PENABLE));
00848 
00849         /* We are no longer polling. */
00850         hp->happy_flags &= ~(HFLAG_POLL);
00851 
00852         /* Let the bits set. */
00853         udelay(200);
00854         ASD(("done\n"));
00855 }
00856 
00857 /* Only Sun can take such nice parts and fuck up the programming interface
00858  * like this.  Good job guys...
00859  */
00860 #define TCVR_RESET_TRIES       16 /* It should reset quickly        */
00861 #define TCVR_UNISOLATE_TRIES   32 /* Dis-isolation can take longer. */
00862 
00863 static int happy_meal_tcvr_reset(struct happy_meal *hp,
00864                                  struct hmeal_tcvregs *tregs)
00865 {
00866         unsigned long tconfig;
00867         int result, tries = TCVR_RESET_TRIES;
00868 
00869         tconfig = hme_read32(hp, &tregs->cfg);
00870         ASD(("happy_meal_tcvr_reset: tcfg<%08lx> ", tconfig));
00871         if(hp->tcvr_type == external) {
00872                 ASD(("external<"));
00873                 hme_write32(hp, &tregs->cfg, tconfig & ~(TCV_CFG_PSELECT));
00874                 hp->tcvr_type = internal;
00875                 hp->paddr = TCV_PADDR_ITX;
00876                 ASD(("ISOLATE,"));
00877                 happy_meal_tcvr_write(hp, tregs, DP83840_BMCR,
00878                                       (BMCR_LOOPBACK|BMCR_PDOWN|BMCR_ISOLATE));
00879                 result = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00880                 if(result == TCVR_FAILURE) {
00881                         ASD(("phyread_fail>\n"));
00882                         return -1;
00883                 }
00884                 ASD(("phyread_ok,PSELECT>"));
00885                 hme_write32(hp, &tregs->cfg, tconfig | TCV_CFG_PSELECT);
00886                 hp->tcvr_type = external;
00887                 hp->paddr = TCV_PADDR_ETX;
00888         } else {
00889                 if(tconfig & TCV_CFG_MDIO1) {
00890                         ASD(("internal<PSELECT,"));
00891                         hme_write32(hp, &tregs->cfg, (tconfig | TCV_CFG_PSELECT));
00892                         ASD(("ISOLATE,"));
00893                         happy_meal_tcvr_write(hp, tregs, DP83840_BMCR,
00894                                               (BMCR_LOOPBACK|BMCR_PDOWN|BMCR_ISOLATE));
00895                         result = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00896                         if(result == TCVR_FAILURE) {
00897                                 ASD(("phyread_fail>\n"));
00898                                 return -1;
00899                         }
00900                         ASD(("phyread_ok,~PSELECT>"));
00901                         hme_write32(hp, &tregs->cfg, (tconfig & ~(TCV_CFG_PSELECT)));
00902                         hp->tcvr_type = internal;
00903                         hp->paddr = TCV_PADDR_ITX;
00904                 }
00905         }
00906 
00907         ASD(("BMCR_RESET "));
00908         happy_meal_tcvr_write(hp, tregs, DP83840_BMCR, BMCR_RESET);
00909 
00910         while(--tries) {
00911                 result = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00912                 if(result == TCVR_FAILURE)
00913                         return -1;
00914                 hp->sw_bmcr = result;
00915                 if(!(result & BMCR_RESET))
00916                         break;
00917                 udelay(20);
00918         }
00919         if(!tries) {
00920                 ASD(("BMCR RESET FAILED!\n"));
00921                 return -1;
00922         }
00923         ASD(("RESET_OK\n"));
00924 
00925         /* Get fresh copies of the PHY registers. */
00926         hp->sw_bmsr      = happy_meal_tcvr_read(hp, tregs, DP83840_BMSR);
00927         hp->sw_physid1   = happy_meal_tcvr_read(hp, tregs, DP83840_PHYSID1);
00928         hp->sw_physid2   = happy_meal_tcvr_read(hp, tregs, DP83840_PHYSID2);
00929         hp->sw_advertise = happy_meal_tcvr_read(hp, tregs, DP83840_ADVERTISE);
00930 
00931         ASD(("UNISOLATE"));
00932         hp->sw_bmcr &= ~(BMCR_ISOLATE);
00933         happy_meal_tcvr_write(hp, tregs, DP83840_BMCR, hp->sw_bmcr);
00934 
00935         tries = TCVR_UNISOLATE_TRIES;
00936         while(--tries) {
00937                 result = happy_meal_tcvr_read(hp, tregs, DP83840_BMCR);
00938                 if(result == TCVR_FAILURE)
00939                         return -1;
00940                 if(!(result & BMCR_ISOLATE))
00941                         break;
00942                 udelay(20);
00943         }
00944         if(!tries) {
00945                 ASD((" FAILED!\n"));
00946                 return -1;
00947         }
00948         ASD((" SUCCESS and CSCONFIG_DFBYPASS\n"));
00949         if (!is_lucent_phy(hp)) {
00950                 result = happy_meal_tcvr_read(hp, tregs, DP83840_CSCONFIG);
00951                 happy_meal_tcvr_write(hp, tregs, DP83840_CSCONFIG,
00952                                       (result | CSCONFIG_DFBYPASS));
00953         }
00954         return 0;
00955 }
00956 
00957 /* Figure out whether we have an internal or external transceiver. */
00958 static void happy_meal_transceiver_check(struct happy_meal *hp,
00959                                          struct hmeal_tcvregs *tregs)
00960 {
00961         unsigned long tconfig = hme_read32(hp, &tregs->cfg);
00962 
00963         ASD(("happy_meal_transceiver_check: tcfg=%08lx ", tconfig));
00964         if(hp->happy_flags & HFLAG_POLL) {
00965                 /* If we are polling, we must stop to get the transceiver type. */
00966                 ASD(("<polling> "));
00967                 if(hp->tcvr_type == internal) {
00968                         if(tconfig & TCV_CFG_MDIO1) {
00969                                 ASD(("<internal> <poll stop> "));
00970                                 happy_meal_poll_stop(hp, tregs);
00971                                 hp->paddr = TCV_PADDR_ETX;
00972                                 hp->tcvr_type = external;
00973                                 ASD(("<external>\n"));
00974                                 tconfig &= ~(TCV_CFG_PENABLE);
00975                                 tconfig |= TCV_CFG_PSELECT;
00976                                 hme_write32(hp, &tregs->cfg, tconfig);
00977                         }
00978                 } else {
00979                         if(hp->tcvr_type == external) {
00980                                 ASD(("<external> "));
00981                                 if(!(hme_read32(hp, &tregs->status) >> 16)) {
00982                                         ASD(("<poll stop> "));
00983                                         happy_meal_poll_stop(hp, tregs);
00984                                         hp->paddr = TCV_PADDR_ITX;
00985                                         hp->tcvr_type = internal;
00986                                         ASD(("<internal>\n"));
00987                                         hme_write32(hp, &tregs->cfg,
00988                                                     hme_read32(hp, &tregs->cfg) &
00989                                                     ~(TCV_CFG_PSELECT));
00990                                 }
00991                                 ASD(("\n"));
00992                         } else {
00993                                 ASD(("<none>\n"));
00994                         }
00995                 }
00996         } else {
00997                 unsigned long reread = hme_read32(hp, &tregs->cfg);
00998 
00999                 /* Else we can just work off of the MDIO bits. */
01000                 ASD(("<not polling> "));
01001                 if(reread & TCV_CFG_MDIO1) {
01002                         hme_write32(hp, &tregs->cfg, tconfig | TCV_CFG_PSELECT);
01003                         hp->paddr = TCV_PADDR_ETX;
01004                         hp->tcvr_type = external;
01005                         ASD(("<external>\n"));
01006                 } else {
01007                         if(reread & TCV_CFG_MDIO0) {
01008                                 hme_write32(hp, &tregs->cfg,
01009                                             tconfig & ~(TCV_CFG_PSELECT));
01010                                 hp->paddr = TCV_PADDR_ITX;
01011                                 hp->tcvr_type = internal;
01012                                 ASD(("<internal>\n"));
01013                         } else {
01014                                 printk(KERN_ERR "happy meal: Transceiver and a coke please.");
01015                                 hp->tcvr_type = none; /* Grrr... */
01016                                 ASD(("<none>\n"));
01017                         }
01018                 }
01019         }
01020 }
01021 
01022 /* The receive ring buffers are a bit tricky to get right.  Here goes...
01023  *
01024  * The buffers we dma into must be 64 byte aligned.  So we use a special
01025  * alloc_skb() routine for the happy meal to allocate 64 bytes more than
01026  * we really need.
01027  *
01028  * We use skb_reserve() to align the data block we get in the skb.  We
01029  * also program the etxregs->cfg register to use an offset of 2.  This
01030  * imperical constant plus the ethernet header size will always leave
01031  * us with a nicely aligned ip header once we pass things up to the
01032  * protocol layers.
01033  *
01034  * The numbers work out to:
01035  *
01036  *         Max ethernet frame size         1518
01037  *         Ethernet header size              14
01038  *         Happy Meal base offset             2
01039  *
01040  * Say a skb data area is at 0xf001b010, and its size alloced is
01041  * (ETH_FRAME_LEN + 64 + 2) = (1514 + 64 + 2) = 1580 bytes.
01042  *
01043  * First our alloc_skb() routine aligns the data base to a 64 byte
01044  * boundry.  We now have 0xf001b040 as our skb data address.  We
01045  * plug this into the receive descriptor address.
01046  *
01047  * Next, we skb_reserve() 2 bytes to account for the Happy Meal offset.
01048  * So now the data we will end up looking at starts at 0xf001b042.  When
01049  * the packet arrives, we will check out the size received and subtract
01050  * this from the skb->length.  Then we just pass the packet up to the
01051  * protocols as is, and allocate a new skb to replace this slot we have
01052  * just received from.
01053  *
01054  * The ethernet layer will strip the ether header from the front of the
01055  * skb we just sent to it, this leaves us with the ip header sitting
01056  * nicely aligned at 0xf001b050.  Also, for tcp and udp packets the
01057  * Happy Meal has even checksummed the tcp/udp data for us.  The 16
01058  * bit checksum is obtained from the low bits of the receive descriptor
01059  * flags, thus:
01060  *
01061  *      skb->csum = rxd->rx_flags & 0xffff;
01062  *      skb->ip_summed = CHECKSUM_HW;
01063  *
01064  * before sending off the skb to the protocols, and we are good as gold.
01065  */
01066 static inline void happy_meal_clean_rings(struct happy_meal *hp)
01067 {
01068         int i;
01069 
01070         for(i = 0; i < RX_RING_SIZE; i++) {
01071                 if(hp->rx_skbs[i] != NULL) {
01072                         dev_kfree_skb(hp->rx_skbs[i]);
01073                         hp->rx_skbs[i] = NULL;
01074                 }
01075         }
01076 
01077         for(i = 0; i < TX_RING_SIZE; i++) {
01078                 if(hp->tx_skbs[i] != NULL) {
01079                         dev_kfree_skb(hp->tx_skbs[i]);
01080                         hp->tx_skbs[i] = NULL;
01081                 }
01082         }
01083 }
01084 
01085 static void happy_meal_init_rings(struct happy_meal *hp, int from_irq)
01086 {
01087         struct hmeal_init_block *hb = hp->happy_block;
01088         struct device *dev = hp->dev;
01089         int i, gfp_flags = GFP_KERNEL;
01090 
01091         if(from_irq || in_interrupt())
01092                 gfp_flags = GFP_ATOMIC;
01093 
01094         HMD(("happy_meal_init_rings: counters to zero, "));
01095         hp->rx_new = hp->rx_old = hp->tx_new = hp->tx_old = 0;
01096 
01097         /* Free any skippy bufs left around in the rings. */
01098         HMD(("clean, "));
01099         happy_meal_clean_rings(hp);
01100 
01101         /* Now get new skippy bufs for the receive ring. */
01102         HMD(("init rxring, "));
01103         for(i = 0; i < RX_RING_SIZE; i++) {
01104                 struct sk_buff *skb;
01105 
01106                 skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, gfp_flags | GFP_DMA);
01107                 if(!skb)
01108                         continue;
01109                 hp->rx_skbs[i] = skb;
01110                 skb->dev = dev;
01111 
01112                 /* Because we reserve afterwards. */
01113                 skb_put(skb, (ETH_FRAME_LEN + RX_OFFSET));
01114 
01115 #ifdef CONFIG_PCI
01116                 if(hp->happy_flags & HFLAG_PCI) {
01117                         pcihme_write_rxd(&hb->happy_meal_rxd[i],
01118                                          (RXFLAG_OWN |
01119                                           ((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
01120                                          (u32)virt_to_bus((volatile void *)skb->data));
01121                 } else
01122 #endif
01123 #ifndef __sparc_v9__
01124                 if (sparc_cpu_model == sun4d) {
01125                         __u32 va = (__u32)hp->sun4d_buffers + i * PAGE_SIZE;
01126 
01127                         hb->happy_meal_rxd[i].rx_addr =
01128                                 iounit_map_dma_page(va, skb->data, hp->happy_sbus_dev->my_bus);
01129                         hb->happy_meal_rxd[i].rx_flags =
01130                                 (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
01131                 } else
01132 #endif
01133                 {
01134                         hb->happy_meal_rxd[i].rx_addr = sbus_dvma_addr(skb->data);
01135                         hb->happy_meal_rxd[i].rx_flags =
01136                                 (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
01137                 }
01138                 skb_reserve(skb, RX_OFFSET);
01139         }
01140 
01141         HMD(("init txring, "));
01142         for(i = 0; i < TX_RING_SIZE; i++)
01143                 hb->happy_meal_txd[i].tx_flags = 0;
01144         HMD(("done\n"));
01145 }
01146 
01147 #ifndef __sparc_v9__
01148 static void sun4c_happy_meal_init_rings(struct happy_meal *hp)
01149 {
01150         struct hmeal_init_block *hb = hp->happy_block;
01151         __u32 hbufs = hp->s4c_buf_dvma;
01152         int i;
01153 
01154         HMD(("happy_meal_init_rings: counters to zero, "));
01155         hp->rx_new = hp->rx_old = hp->tx_new = hp->tx_old = 0;
01156 
01157         HMD(("init rxring, "));
01158         for(i = 0; i < RX_RING_SIZE; i++) {
01159                 hb->happy_meal_rxd[i].rx_addr = hbufs + hbuf_offset(rx_buf, i);
01160                 hb->happy_meal_rxd[i].rx_flags =
01161                         (RXFLAG_OWN | ((SUN4C_RX_BUFF_SIZE - RX_OFFSET) << 16));
01162         }
01163 
01164         HMD(("init txring, "));
01165         for(i = 0; i < TX_RING_SIZE; i++)
01166                 hb->happy_meal_txd[i].tx_flags = 0;
01167         HMD(("done\n"));
01168 }
01169 #endif
01170 
01171 static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
01172                                               struct hmeal_tcvregs *tregs,
01173                                               struct ethtool_cmd *ep)
01174 {
01175         int timeout;
01176 
01177         /* Read all of the registers we are interested in now. */
01178         hp->