summaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/3c505.c15
-rw-r--r--drivers/net/3c509.c93
-rw-r--r--drivers/net/3c515.c1499
-rw-r--r--drivers/net/3c523.c1916
-rw-r--r--drivers/net/3c59x.c13
-rw-r--r--drivers/net/82596.c4
-rw-r--r--drivers/net/8390.c3
-rw-r--r--drivers/net/8390.h9
-rw-r--r--drivers/net/Config.in45
-rw-r--r--drivers/net/Makefile73
-rw-r--r--drivers/net/Space.c36
-rw-r--r--drivers/net/a2065.c14
-rw-r--r--drivers/net/ac3200.c7
-rw-r--r--drivers/net/acenic.c1576
-rw-r--r--drivers/net/acenic.h612
-rw-r--r--drivers/net/acenic_firmware.h5517
-rw-r--r--drivers/net/apne.c4
-rw-r--r--drivers/net/arc-rimi.c5
-rw-r--r--drivers/net/arcnet.c7
-rw-r--r--drivers/net/ariadne.c11
-rw-r--r--drivers/net/ariadne2.c424
-rw-r--r--drivers/net/at1700.c421
-rw-r--r--drivers/net/atari_pamsnet.c3
-rw-r--r--drivers/net/atp.c2
-rw-r--r--drivers/net/bmac.c166
-rw-r--r--drivers/net/com20020.c5
-rw-r--r--drivers/net/com90io.c5
-rw-r--r--drivers/net/com90xx.c5
-rw-r--r--drivers/net/cops.c2
-rw-r--r--drivers/net/cs89x0.c3
-rw-r--r--drivers/net/daynaport.c162
-rw-r--r--drivers/net/de4x5.c108
-rw-r--r--drivers/net/depca.c3404
-rw-r--r--drivers/net/dummy.c2
-rw-r--r--drivers/net/eepro100.c989
-rw-r--r--drivers/net/eexpress.c13
-rw-r--r--drivers/net/eth16i.c1285
-rw-r--r--drivers/net/ethertap.c4
-rw-r--r--drivers/net/hamradio/6pack.c2
-rw-r--r--drivers/net/hamradio/baycom_epp.c14
-rw-r--r--drivers/net/hamradio/baycom_par.c12
-rw-r--r--drivers/net/hamradio/dmascc.c57
-rw-r--r--drivers/net/hamradio/hdlcdrv.c1
-rw-r--r--drivers/net/hamradio/mkiss.c1
-rw-r--r--drivers/net/hamradio/soundmodem/sm.c6
-rw-r--r--drivers/net/hamradio/z8530.h6
-rw-r--r--drivers/net/hostess_sv11.c122
-rw-r--r--drivers/net/hp100.c2
-rw-r--r--drivers/net/ibmtr.c59
-rw-r--r--drivers/net/ipddp.c6
-rw-r--r--drivers/net/lance.c12
-rw-r--r--drivers/net/lne390.c9
-rw-r--r--drivers/net/ltpc.c510
-rw-r--r--drivers/net/mace.c128
-rw-r--r--drivers/net/ne2.c697
-rw-r--r--drivers/net/ne3210.c432
-rw-r--r--drivers/net/net_init.c30
-rw-r--r--drivers/net/ni5010.c3
-rw-r--r--drivers/net/ni52.c3
-rw-r--r--drivers/net/ni65.c20
-rw-r--r--drivers/net/plip.c7
-rw-r--r--drivers/net/ppp.c56
-rw-r--r--drivers/net/rrunner.c1208
-rw-r--r--drivers/net/rrunner.h790
-rw-r--r--drivers/net/rtl8139.c1028
-rw-r--r--drivers/net/sdla_fr.c4
-rw-r--r--drivers/net/sdla_ppp.c4
-rw-r--r--drivers/net/sdla_x25.c6
-rw-r--r--drivers/net/sdladrv.c43
-rw-r--r--drivers/net/sdlamain.c8
-rw-r--r--drivers/net/shaper.c11
-rw-r--r--drivers/net/sktr.c15
-rw-r--r--drivers/net/strip.c297
-rw-r--r--drivers/net/sunhme.c277
-rw-r--r--drivers/net/sunhme.h23
-rw-r--r--drivers/net/syncppp.c18
-rw-r--r--drivers/net/syncppp.h3
-rw-r--r--drivers/net/tlan.c62
-rw-r--r--drivers/net/via-rhine.c1316
-rw-r--r--drivers/net/wavelan.c4
-rw-r--r--drivers/net/yellowfin.c1021
-rw-r--r--drivers/net/z85230.c240
-rw-r--r--drivers/net/z85230.h6
-rw-r--r--drivers/net/znet.c40
84 files changed, 21573 insertions, 5508 deletions
diff --git a/drivers/net/3c505.c b/drivers/net/3c505.c
index a1a822fa0..b8e9936f8 100644
--- a/drivers/net/3c505.c
+++ b/drivers/net/3c505.c
@@ -327,13 +327,17 @@ static inline void check_3c505_dma(struct device *dev)
{
elp_device *adapter = dev->priv;
if (adapter->dmaing && (jiffies > (adapter->current_dma.start_time + 10))) {
- unsigned long flags;
+ unsigned long flags, f;
printk("%s: DMA %s timed out, %d bytes left\n", dev->name, adapter->current_dma.direction ? "download" : "upload", get_dma_residue(dev->dma));
save_flags(flags);
cli();
adapter->dmaing = 0;
adapter->busy = 0;
+
+ f=claim_dma_lock();
disable_dma(dev->dma);
+ release_dma_lock(f);
+
if (adapter->rx_active)
adapter->rx_active--;
outb_control(adapter->hcr_val & ~(DMAE | TCEN | DIR), dev);
@@ -601,6 +605,7 @@ static void receive_packet(struct device *dev, int len)
elp_device *adapter = dev->priv;
void *target;
struct sk_buff *skb;
+ unsigned long flags;
rlen = (len + 1) & ~1;
skb = dev_alloc_skb(rlen + 2);
@@ -632,12 +637,14 @@ static void receive_packet(struct device *dev, int len)
outb_control(adapter->hcr_val | DIR | TCEN | DMAE, dev);
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
set_dma_mode(dev->dma, 0x04); /* dma read */
set_dma_addr(dev->dma, virt_to_bus(target));
set_dma_count(dev->dma, rlen);
enable_dma(dev->dma);
+ release_dma_lock(flags);
if (elp_debug >= 3) {
printk("%s: rx DMA transfer started\n", dev->name);
@@ -1019,6 +1026,7 @@ static int send_packet(struct device *dev, struct sk_buff *skb)
{
elp_device *adapter = dev->priv;
unsigned long target;
+ unsigned long flags;
/*
* make sure the length is even and no shorter than 60 bytes
@@ -1060,7 +1068,8 @@ static int send_packet(struct device *dev, struct sk_buff *skb)
target = virt_to_bus(adapter->dma_buffer);
}
adapter->current_dma.skb = skb;
- cli();
+
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
set_dma_mode(dev->dma, 0x48); /* dma memory -> io */
@@ -1068,6 +1077,8 @@ static int send_packet(struct device *dev, struct sk_buff *skb)
set_dma_count(dev->dma, nlen);
outb_control(adapter->hcr_val | DMAE | TCEN, dev);
enable_dma(dev->dma);
+ release_dma_lock(flags);
+
if (elp_debug >= 3)
printk("%s: DMA transfer started\n", dev->name);
diff --git a/drivers/net/3c509.c b/drivers/net/3c509.c
index ca8e80f8e..58a44182e 100644
--- a/drivers/net/3c509.c
+++ b/drivers/net/3c509.c
@@ -34,6 +34,7 @@
v1.10 4/21/97 Fixed module code so that multiple cards may be detected,
other cleanups. -djb
Andrea Arcangeli: Upgraded to Donald Becker's version 1.12.
+ Rick Payne: Fixed SMP race condition
*/
static char *version = "3c509.c:1.12 6/4/97 becker@cesdis.gsfc.nasa.gov\n";
@@ -59,6 +60,7 @@ static char *version = "3c509.c:1.12 6/4/97 becker@cesdis.gsfc.nasa.gov\n";
#include <linux/skbuff.h>
#include <linux/delay.h> /* for udelay() */
+#include <asm/spinlock.h>
#include <asm/bitops.h>
#include <asm/io.h>
@@ -122,6 +124,7 @@ enum RxFilter {
struct el3_private {
struct enet_statistics stats;
struct device *next_dev;
+ spinlock_t lock;
/* skb send-queue */
int head, size;
struct sk_buff *queue[SKB_QUEUE_SIZE];
@@ -178,28 +181,64 @@ int el3_probe(struct device *dev)
}
#ifdef CONFIG_MCA
-#warning "The MCA code in drivers/net/3c509.c does not compile"
-#warning "See http://glycerine.itsmm.uni.edu/mca/ for patches."
-#if 0
- if (MCA_bus) {
- mca_adaptor_select_mode(1);
- for (i = 0; i < 8; i++)
- if ((mca_adaptor_id(i) | 1) == 0x627c) {
- ioaddr = mca_pos_base_addr(i);
- irq = inw(ioaddr + WN0_IRQ) >> 12;
- if_port = inw(ioaddr + 6)>>14;
- for (i = 0; i < 3; i++)
- phys_addr[i] = htons(read_eeprom(ioaddr, i));
-
- mca_adaptor_select_mode(0);
- goto found;
+#define MCA_NUMBER_OF_SLOTS 8
+#define MCA_PORT_POS_SEL 0x096
+#define MCA_PORT_ID_REG_0 0x100
+#define MCA_PORT_ID_REG_1 0x101
+#define MCA_SELECT_BIT 0x08
+ if (MCA_bus)
+ {
+ u_int mca_id;
+ u_char posreg[4];
+ int mca_slot;
+
+ if (el3_debug > 2)
+ printk("3c529: probing...\n");
+ /* This should probably be done once early on and read into
+ * a structure somewhere... */
+ for (mca_slot = 0; mca_slot < MCA_NUMBER_OF_SLOTS; mca_slot++)
+ {
+ /* Select MCA slot i */
+ outb_p(mca_slot | MCA_SELECT_BIT, MCA_PORT_POS_SEL);
+ mca_id = ((inb_p(MCA_PORT_ID_REG_1)<<8)
+ + inb_p(MCA_PORT_ID_REG_0));
+ if (mca_id == 0x627C /* 10base2 */
+ || mca_id == 0x627D /* 10baseT */
+ || mca_id == 0x62DB /* Test mode */
+ || mca_id == 0x62F6 /* TP or coax */
+ || mca_id == 0x62F7) /* TP only */
+ {
+ if (el3_debug > 1)
+ printk("3c529: Found with id 0x%x at slot %d\n",
+ mca_id, mca_slot);
+ posreg[0] = inb_p(0x102); posreg[1] = inb_p(0x103);
+ posreg[2] = inb_p(0x104); posreg[3] = inb_p(0x105);
+ break;
}
- mca_adaptor_select_mode(0);
-
+ mca_id = 0xFFFF;
+ }
+ /* Read values from POS registers so now disable */
+ outb(0,MCA_PORT_POS_SEL);
+ if (mca_id != 0xFFFF && !(posreg[0]&0x01))
+ printk("3c529: Adapter found but disabled in slot %d\n", mca_slot);
+ else if (mca_id != 0xFFFF && posreg[0]&0x01)
+ {
+ /* Found and adapter is enabled */
+ if (el3_debug > 2)
+ printk("3c529: pos registers 0:0x%x 1:0x%x 2:0x%x 3:0x%x\n",
+ posreg[0], posreg[1], posreg[2], posreg[3]);
+ ioaddr = ((short)((posreg[2]&0xfc)|0x02)) << 8;
+ irq = posreg[3] & 0x0f;
+ if_port = posreg[2] & 0x03;
+ if (el3_debug > 2)
+ printk("3c529: irq %d ioaddr 0x%x ifport %d\n",
+ irq, ioaddr, if_port);
+ for (i = 0; i < 3; i++)
+ phys_addr[i] = htons(read_eeprom(ioaddr, i));
+ goto found;
+ }
}
#endif
-#endif
-
/* Reset the ISA PnP mechanism on 3c509b. */
outb(0x02, 0x279); /* Select PnP config control register. */
outb(0x02, 0xA79); /* Return to WaitForKey state. */
@@ -365,6 +404,9 @@ el3_open(struct device *dev)
outw(RxReset, ioaddr + EL3_CMD);
outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
+ /* Set the spinlock before grabbing IRQ! */
+ ((struct el3_private *)dev->priv)->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
+
if (request_irq(dev->irq, &el3_interrupt, 0, "3c509", dev)) {
return -EAGAIN;
}
@@ -484,6 +526,11 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
if (test_and_set_bit(0, (void*)&dev->tbusy) != 0)
printk("%s: Transmitter access conflict.\n", dev->name);
else {
+ unsigned long flags;
+
+ /* Spin on the lock, until we're clear of an IRQ */
+ spin_lock_irqsave(&lp->lock, flags);
+
/* Put out the doubleword header... */
outw(skb->len, ioaddr + TX_FIFO);
outw(0x00, ioaddr + TX_FIFO);
@@ -500,6 +547,8 @@ el3_start_xmit(struct sk_buff *skb, struct device *dev)
} else
/* Interrupt us when the FIFO has room for max-sized packet. */
outw(SetTxThreshold + 1536, ioaddr + EL3_CMD);
+
+ spin_unlock_irqrestore(&lp->lock, flags);
}
dev_kfree_skb (skb);
@@ -524,6 +573,7 @@ static void
el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_id;
+ struct el3_private *lp;
int ioaddr, status;
int i = INTR_WORK;
@@ -532,6 +582,9 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
return;
}
+ lp = (struct el3_private *)dev->priv;
+ spin_lock(&lp->lock);
+
if (dev->interrupt)
printk("%s: Re-entering the interrupt handler.\n", dev->name);
dev->interrupt = 1;
@@ -593,7 +646,7 @@ el3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
printk("%s: exiting interrupt, status %4.4x.\n", dev->name,
inw(ioaddr + EL3_STATUS));
}
-
+ spin_unlock(&lp->lock);
dev->interrupt = 0;
return;
}
diff --git a/drivers/net/3c515.c b/drivers/net/3c515.c
new file mode 100644
index 000000000..b74ca51e6
--- /dev/null
+++ b/drivers/net/3c515.c
@@ -0,0 +1,1499 @@
+/* 3c515.c: A 3Com ISA EtherLink XL "Corkscrew" ethernet driver for linux. */
+/*
+ Written 1997-1998 by Donald Becker.
+
+ This software may be used and distributed according to the terms
+ of the GNU Public License, incorporated herein by reference.
+
+ This driver is for the 3Com ISA EtherLink XL "Corkscrew" 3c515 ethercard.
+
+ The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
+ Center of Excellence in Space Data and Information Sciences
+ Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771
+*/
+
+static char *version = "3c515.c:v0.99 4/7/98 becker@cesdis.gsfc.nasa.gov\n";
+#define CORKSCREW 1
+
+/* "Knobs" that adjust features and parameters. */
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ Setting to > 1512 effectively disables this feature. */
+static const int rx_copybreak = 200;
+/* Allow setting MTU to a larger size, bypassing the normal ethernet setup. */
+static const int mtu = 1500;
+/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
+static int max_interrupt_work = 20;
+
+/* Enable the automatic media selection code -- usually set. */
+#define AUTOMEDIA 1
+
+/* Allow the use of fragment bus master transfers instead of only
+ programmed-I/O for Vortex cards. Full-bus-master transfers are always
+ enabled by default on Boomerang cards. If VORTEX_BUS_MASTER is defined,
+ the feature may be turned on using 'options'. */
+#define VORTEX_BUS_MASTER
+
+/* A few values that may be tweaked. */
+/* Keep the ring sizes a power of two for efficiency. */
+#define TX_RING_SIZE 16
+#define RX_RING_SIZE 16
+#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
+
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#include <linux/version.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/in.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/timer.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#if (LINUX_VERSION_CODE >= 0x10344)
+#define NEW_MULTICAST
+#include <linux/delay.h>
+#else
+#define udelay(microsec) do { int _i = 4*microsec; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
+#endif
+
+/* Kernel version compatibility functions. */
+#define RUN_AT(x) (jiffies + (x))
+#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
+
+#define FREE_IRQ(irqnum, dev) free_irq(irqnum, dev)
+#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n, instance)
+#define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs)
+
+#if (LINUX_VERSION_CODE < 0x20123)
+#define test_and_set_bit(val, addr) set_bit(val, addr)
+#elif defined(MODULE)
+MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
+MODULE_DESCRIPTION("3Com 3c515 Corkscrew driver");
+MODULE_PARM(debug, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(max_interrupt_work, "i");
+#endif
+
+/* "Knobs" for adjusting internal parameters. */
+/* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */
+#define DRIVER_DEBUG 1
+/* Some values here only for performance evaluation and path-coverage
+ debugging. */
+static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0;
+
+/* Number of times to check to see if the Tx FIFO has space, used in some
+ limited cases. */
+#define WAIT_TX_AVAIL 200
+
+/* Operational parameter that usually are not changed. */
+#define TX_TIMEOUT 40 /* Time in jiffies before concluding Tx hung */
+
+/* The size here is somewhat misleading: the Corkscrew also uses the ISA
+ aliased registers at <base>+0x400.
+ */
+#define CORKSCREW_TOTAL_SIZE 0x20
+
+#ifdef HAVE_DEVLIST
+struct netdev_entry tc515_drv =
+{"3c515", tc515_probe, CORKSCREW_TOTAL_SIZE, NULL};
+#endif
+
+#ifdef DRIVER_DEBUG
+int vortex_debug = DRIVER_DEBUG;
+#else
+int vortex_debug = 1;
+#endif
+
+#define CORKSCREW_ID 10
+
+/*
+ Theory of Operation
+
+I. Board Compatibility
+
+This device driver is designed for the 3Com 3c515 ISA Fast EtherLink XL,
+3Com's ISA bus adapter for Fast Ethernet. Due to the unique I/O port layout,
+it's not practical to integrate this driver with the other EtherLink drivers.
+
+II. Board-specific settings
+
+The Corkscrew has an EEPROM for configuration, but no special settings are
+needed for Linux.
+
+III. Driver operation
+
+The 3c515 series use an interface that's very similar to the 3c900 "Boomerang"
+PCI cards, with the bus master interface extensively modified to work with
+the ISA bus.
+
+The card is capable of full-bus-master transfers with separate
+lists of transmit and receive descriptors, similar to the AMD LANCE/PCnet,
+DEC Tulip and Intel Speedo3.
+
+This driver uses a "RX_COPYBREAK" scheme rather than a fixed intermediate
+receive buffer. This scheme allocates full-sized skbuffs as receive
+buffers. The value RX_COPYBREAK is used as the copying breakpoint: it is
+chosen to trade-off the memory wasted by passing the full-sized skbuff to
+the queue layer for all frames vs. the copying cost of copying a frame to a
+correctly-sized skbuff.
+
+
+IIIC. Synchronization
+The driver runs as two independent, single-threaded flows of control. One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag. The other thread is the interrupt handler, which is single
+threaded by the hardware and other software.
+
+IV. Notes
+
+Thanks to Terry Murphy of 3Com for providing documentation and a development
+board.
+
+The names "Vortex", "Boomerang" and "Corkscrew" are the internal 3Com
+project names. I use these names to eliminate confusion -- 3Com product
+numbers and names are very similar and often confused.
+
+The new chips support both ethernet (1.5K) and FDDI (4.5K) frame sizes!
+This driver only supports ethernet frames because of the recent MTU limit
+of 1.5K, but the changes to support 4.5K are minimal.
+*/
+
+/* Operational definitions.
+ These are not used by other compilation units and thus are not
+ exported in a ".h" file.
+
+ First the windows. There are eight register windows, with the command
+ and status registers available in each.
+ */
+#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
+#define EL3_CMD 0x0e
+#define EL3_STATUS 0x0e
+
+/* The top five bits written to EL3_CMD are a command, the lower
+ 11 bits are the parameter, if applicable.
+ Note that 11 parameters bits was fine for ethernet, but the new chips
+ can handle FDDI length frames (~4500 octets) and now parameters count
+ 32-bit 'Dwords' rather than octets. */
+
+enum vortex_cmd {
+ TotalReset = 0<<11, SelectWindow = 1<<11, StartCoax = 2<<11,
+ RxDisable = 3<<11, RxEnable = 4<<11, RxReset = 5<<11,
+ UpStall = 6<<11, UpUnstall = (6<<11)+1,
+ DownStall = (6<<11)+2, DownUnstall = (6<<11)+3,
+ RxDiscard = 8<<11, TxEnable = 9<<11, TxDisable = 10<<11, TxReset = 11<<11,
+ FakeIntr = 12<<11, AckIntr = 13<<11, SetIntrEnb = 14<<11,
+ SetStatusEnb = 15<<11, SetRxFilter = 16<<11, SetRxThreshold = 17<<11,
+ SetTxThreshold = 18<<11, SetTxStart = 19<<11,
+ StartDMAUp = 20<<11, StartDMADown = (20<<11)+1, StatsEnable = 21<<11,
+ StatsDisable = 22<<11, StopCoax = 23<<11,};
+
+/* The SetRxFilter command accepts the following classes: */
+enum RxFilter {
+ RxStation = 1, RxMulticast = 2, RxBroadcast = 4, RxProm = 8 };
+
+/* Bits in the general status register. */
+enum vortex_status {
+ IntLatch = 0x0001, AdapterFailure = 0x0002, TxComplete = 0x0004,
+ TxAvailable = 0x0008, RxComplete = 0x0010, RxEarly = 0x0020,
+ IntReq = 0x0040, StatsFull = 0x0080,
+ DMADone = 1<<8, DownComplete = 1<<9, UpComplete = 1<<10,
+ DMAInProgress = 1<<11, /* DMA controller is still busy.*/
+ CmdInProgress = 1<<12, /* EL3_CMD is still busy.*/
+};
+
+/* Register window 1 offsets, the window used in normal operation.
+ On the Corkscrew this window is always mapped at offsets 0x10-0x1f. */
+enum Window1 {
+ TX_FIFO = 0x10, RX_FIFO = 0x10, RxErrors = 0x14,
+ RxStatus = 0x18, Timer=0x1A, TxStatus = 0x1B,
+ TxFree = 0x1C, /* Remaining free bytes in Tx buffer. */
+};
+enum Window0 {
+ Wn0IRQ = 0x08,
+#if defined(CORKSCREW)
+ Wn0EepromCmd = 0x200A, /* Corkscrew EEPROM command register. */
+ Wn0EepromData = 0x200C, /* Corkscrew EEPROM results register. */
+#else
+ Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */
+ Wn0EepromData = 12, /* Window 0: EEPROM results register. */
+#endif
+};
+enum Win0_EEPROM_bits {
+ EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0,
+ EEPROM_EWENB = 0x30, /* Enable erasing/writing for 10 msec. */
+ EEPROM_EWDIS = 0x00, /* Disable EWENB before 10 msec timeout. */
+};
+/* EEPROM locations. */
+enum eeprom_offset {
+ PhysAddr01=0, PhysAddr23=1, PhysAddr45=2, ModelID=3,
+ EtherLink3ID=7, };
+
+enum Window3 { /* Window 3: MAC/config bits. */
+ Wn3_Config=0, Wn3_MAC_Ctrl=6, Wn3_Options=8,
+};
+union wn3_config {
+ int i;
+ struct w3_config_fields {
+ unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
+ int pad8:8;
+ unsigned int ram_split:2, pad18:2, xcvr:3, pad21:1, autoselect:1;
+ int pad24:7;
+ } u;
+};
+
+enum Window4 {
+ Wn4_NetDiag = 6, Wn4_Media = 10, /* Window 4: Xcvr/media bits. */
+};
+enum Win4_Media_bits {
+ Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */
+ Media_10TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */
+ Media_Lnk = 0x0080, /* Enable just link beat for 100TX/100FX. */
+ Media_LnkBeat = 0x0800,
+};
+enum Window7 { /* Window 7: Bus Master control. */
+ Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12,
+};
+/* Boomerang-style bus master control registers. Note ISA aliases! */
+enum MasterCtrl {
+ PktStatus = 0x400, DownListPtr = 0x404, FragAddr = 0x408, FragLen = 0x40c,
+ TxFreeThreshold = 0x40f, UpPktStatus = 0x410, UpListPtr = 0x418,
+};
+
+/* The Rx and Tx descriptor lists.
+ Caution Alpha hackers: these types are 32 bits! Note also the 8 byte
+ alignment contraint on tx_ring[] and rx_ring[]. */
+struct boom_rx_desc {
+ u32 next;
+ s32 status;
+ u32 addr;
+ s32 length;
+};
+/* Values for the Rx status entry. */
+enum rx_desc_status {
+ RxDComplete=0x00008000, RxDError=0x4000,
+ /* See boomerang_rx() for actual error bits */
+};
+
+struct boom_tx_desc {
+ u32 next;
+ s32 status;
+ u32 addr;
+ s32 length;
+};
+
+struct vortex_private {
+ char devname[8]; /* "ethN" string, also for kernel debug. */
+ const char *product_name;
+ struct device *next_module;
+ /* The Rx and Tx rings are here to keep them quad-word-aligned. */
+ struct boom_rx_desc rx_ring[RX_RING_SIZE];
+ struct boom_tx_desc tx_ring[TX_RING_SIZE];
+ /* The addresses of transmit- and receive-in-place skbuffs. */
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
+ struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ unsigned int cur_rx, cur_tx; /* The next free ring entry */
+ unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
+ struct enet_statistics stats;
+ struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */
+ struct timer_list timer; /* Media selection timer. */
+ int capabilities; /* Adapter capabilities word. */
+ int options; /* User-settable misc. driver options. */
+ int last_rx_packets; /* For media autoselection. */
+ unsigned int available_media:8, /* From Wn3_Options */
+ media_override:3, /* Passed-in media type. */
+ default_media:3, /* Read from the EEPROM. */
+ full_duplex:1, autoselect:1,
+ bus_master:1, /* Vortex can only do a fragment bus-m. */
+ full_bus_master_tx:1, full_bus_master_rx:1, /* Boomerang */
+ tx_full:1;
+};
+
+/* The action to take with a media selection timer tick.
+ Note that we deviate from the 3Com order by checking 10base2 before AUI.
+ */
+enum xcvr_types {
+ XCVR_10baseT=0, XCVR_AUI, XCVR_10baseTOnly, XCVR_10base2, XCVR_100baseTx,
+ XCVR_100baseFx, XCVR_MII=6, XCVR_Default=8,
+};
+
+static struct media_table {
+ char *name;
+ unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */
+ mask:8, /* The transceiver-present bit in Wn3_Config.*/
+ next:8; /* The media type to try next. */
+ short wait; /* Time before we check media status. */
+} media_tbl[] = {
+ { "10baseT", Media_10TP,0x08, XCVR_10base2, (14*HZ)/10},
+ { "10Mbs AUI", Media_SQE, 0x20, XCVR_Default, (1*HZ)/10},
+ { "undefined", 0, 0x80, XCVR_10baseT, 10000},
+ { "10base2", 0, 0x10, XCVR_AUI, (1*HZ)/10},
+ { "100baseTX", Media_Lnk, 0x02, XCVR_100baseFx, (14*HZ)/10},
+ { "100baseFX", Media_Lnk, 0x04, XCVR_MII, (14*HZ)/10},
+ { "MII", 0, 0x40, XCVR_10baseT, 3*HZ },
+ { "undefined", 0, 0x01, XCVR_10baseT, 10000},
+ { "Default", 0, 0xFF, XCVR_10baseT, 10000},
+};
+
+static int vortex_scan(struct device *dev);
+static struct device *vortex_found_device(struct device *dev, int ioaddr,
+ int irq, int product_index,
+ int options);
+static int vortex_probe1(struct device *dev);
+static int vortex_open(struct device *dev);
+static void vortex_timer(unsigned long arg);
+static int vortex_start_xmit(struct sk_buff *skb, struct device *dev);
+static int vortex_rx(struct device *dev);
+static int boomerang_rx(struct device *dev);
+static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs);
+static int vortex_close(struct device *dev);
+static void update_stats(int addr, struct device *dev);
+static struct enet_statistics *vortex_get_stats(struct device *dev);
+static void set_rx_mode(struct device *dev);
+
+
+/* Unlike the other PCI cards the 59x cards don't need a large contiguous
+ memory region, so making the driver a loadable module is feasible.
+
+ Unfortunately maximizing the shared code between the integrated and
+ module version of the driver results in a complicated set of initialization
+ procedures.
+ init_module() -- modules / tc59x_init() -- built-in
+ The wrappers for vortex_scan()
+ vortex_scan() The common routine that scans for PCI and EISA cards
+ vortex_found_device() Allocate a device structure when we find a card.
+ Different versions exist for modules and built-in.
+ vortex_probe1() Fill in the device structure -- this is separated
+ so that the modules code can put it in dev->init.
+*/
+/* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
+/* Note: this is the only limit on the number of cards supported!! */
+static int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,};
+
+#ifdef MODULE
+static int debug = -1;
+/* A list of all installed Vortex devices, for removing the driver module. */
+static struct device *root_vortex_dev = NULL;
+
+int
+init_module(void)
+{
+ int cards_found;
+
+ if (debug >= 0)
+ vortex_debug = debug;
+ if (vortex_debug)
+ printk(version);
+
+ root_vortex_dev = NULL;
+ cards_found = vortex_scan(0);
+ return cards_found ? 0 : -ENODEV;
+}
+
+#else
+int tc515_probe(struct device *dev)
+{
+ int cards_found = 0;
+
+ cards_found = vortex_scan(dev);
+
+ if (vortex_debug > 0 && cards_found)
+ printk(version);
+
+ return cards_found ? 0 : -ENODEV;
+}
+#endif /* not MODULE */
+
+static int vortex_scan(struct device *dev)
+{
+ int cards_found = 0;
+ static int ioaddr = 0x100;
+
+ /* Check all locations on the ISA bus -- evil! */
+ for (; ioaddr < 0x400; ioaddr += 0x20) {
+ int irq;
+ if (check_region(ioaddr, CORKSCREW_TOTAL_SIZE))
+ continue;
+ /* Check the resource configuration for a matching ioaddr. */
+ if ((inw(ioaddr + 0x2002) & 0x1f0) != (ioaddr & 0x1f0))
+ continue;
+ /* Verify by reading the device ID from the EEPROM. */
+ {
+ int timer;
+ outw(EEPROM_Read + 7, ioaddr + Wn0EepromCmd);
+ /* Pause for at least 162 us. for the read to take place. */
+ for (timer = 4; timer >= 0; timer--) {
+ udelay(162);
+ if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
+ break;
+ }
+ if (inw(ioaddr + Wn0EepromData) != 0x6d50)
+ continue;
+ }
+ printk("3c515 Resource configuraiton register %#4.4x, DCR %4.4x.\n",
+ inl(ioaddr + 0x2002), inw(ioaddr + 0x2000));
+ irq = inw(ioaddr + 0x2002) & 15;
+ vortex_found_device(dev, ioaddr, irq, CORKSCREW_ID, dev && dev->mem_start
+ ? dev->mem_start : options[cards_found]);
+ dev = 0;
+ cards_found++;
+ }
+
+ if (vortex_debug)
+ printk("%d 3c515 cards found.\n", cards_found);
+ return cards_found;
+}
+
+static struct device *vortex_found_device(struct device *dev, int ioaddr,
+ int irq, int product_index,
+ int options)
+{
+ struct vortex_private *vp;
+
+#ifdef MODULE
+ /* Allocate and fill new device structure. */
+ int dev_size = sizeof(struct device) +
+ sizeof(struct vortex_private) + 15; /* Pad for alignment */
+
+ dev = (struct device *) kmalloc(dev_size, GFP_KERNEL);
+ memset(dev, 0, dev_size);
+ /* Align the Rx and Tx ring entries. */
+ dev->priv = (void *)(((long)dev + sizeof(struct device) + 15) & ~15);
+ vp = (struct vortex_private *)dev->priv;
+ dev->name = vp->devname; /* An empty string. */
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
+ dev->init = vortex_probe1;
+ vp->product_name = "3c515";
+ vp->options = options;
+ if (options >= 0) {
+ vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
+ vp->full_duplex = (options & 8) ? 1 : 0;
+ vp->bus_master = (options & 16) ? 1 : 0;
+ } else {
+ vp->media_override = 7;
+ vp->full_duplex = 0;
+ vp->bus_master = 0;
+ }
+ ether_setup(dev);
+ vp->next_module = root_vortex_dev;
+ root_vortex_dev = dev;
+ if (register_netdev(dev) != 0)
+ return 0;
+#else /* not a MODULE */
+ if (dev) {
+ /* Caution: quad-word alignment required for rings! */
+ dev->priv = kmalloc(sizeof (struct vortex_private), GFP_KERNEL);
+ memset(dev->priv, 0, sizeof (struct vortex_private));
+ }
+ dev = init_etherdev(dev, sizeof(struct vortex_private));
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+ dev->dma = (product_index == CORKSCREW_ID ? inw(ioaddr + 0x2000) & 7 : 0);
+ vp = (struct vortex_private *)dev->priv;
+ vp->product_name = "3c515";
+ vp->options = options;
+ if (options >= 0) {
+ vp->media_override = ((options & 7) == 2) ? 0 : options & 7;
+ vp->full_duplex = (options & 8) ? 1 : 0;
+ vp->bus_master = (options & 16) ? 1 : 0;
+ } else {
+ vp->media_override = 7;
+ vp->full_duplex = 0;
+ vp->bus_master = 0;
+ }
+
+ vortex_probe1(dev);
+#endif /* MODULE */
+ return dev;
+}
+
+static int vortex_probe1(struct device *dev)
+{
+ int ioaddr = dev->base_addr;
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ unsigned int eeprom[0x40], checksum = 0; /* EEPROM contents */
+ int i;
+
+ printk("%s: 3Com %s at %#3x,", dev->name,
+ vp->product_name, ioaddr);
+
+ /* Read the station address from the EEPROM. */
+ EL3WINDOW(0);
+ for (i = 0; i < 0x18; i++) {
+ short *phys_addr = (short *)dev->dev_addr;
+ int timer;
+ outw(EEPROM_Read + i, ioaddr + Wn0EepromCmd);
+ /* Pause for at least 162 us. for the read to take place. */
+ for (timer = 4; timer >= 0; timer--) {
+ udelay(162);
+ if ((inw(ioaddr + Wn0EepromCmd) & 0x0200) == 0)
+ break;
+ }
+ eeprom[i] = inw(ioaddr + Wn0EepromData);
+ checksum ^= eeprom[i];
+ if (i < 3)
+ phys_addr[i] = htons(eeprom[i]);
+ }
+ checksum = (checksum ^ (checksum >> 8)) & 0xff;
+ if (checksum != 0x00)
+ printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
+ for (i = 0; i < 6; i++)
+ printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
+ if (eeprom[16] == 0x11c7) { /* Corkscrew */
+ if (request_dma(dev->dma, "3c515")) {
+ printk(", DMA %d allocation failed", dev->dma);
+ dev->dma = 0;
+ } else
+ printk(", DMA %d", dev->dma);
+ }
+ printk(", IRQ %d\n", dev->irq);
+ /* Tell them about an invalid IRQ. */
+ if (vortex_debug && (dev->irq <= 0 || dev->irq > 15))
+ printk(" *** Warning: this IRQ is unlikely to work! ***\n");
+
+ {
+ char *ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
+ union wn3_config config;
+ EL3WINDOW(3);
+ vp->available_media = inw(ioaddr + Wn3_Options);
+ config.i = inl(ioaddr + Wn3_Config);
+ if (vortex_debug > 1)
+ printk(" Internal config register is %4.4x, transceivers %#x.\n",
+ config.i, inw(ioaddr + Wn3_Options));
+ printk(" %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
+ 8 << config.u.ram_size,
+ config.u.ram_width ? "word" : "byte",
+ ram_split[config.u.ram_split],
+ config.u.autoselect ? "autoselect/" : "",
+ media_tbl[config.u.xcvr].name);
+ dev->if_port = config.u.xcvr;
+ vp->default_media = config.u.xcvr;
+ vp->autoselect = config.u.autoselect;
+ }
+ if (vp->media_override != 7) {
+ printk(" Media override to transceiver type %d (%s).\n",
+ vp->media_override, media_tbl[vp->media_override].name);
+ dev->if_port = vp->media_override;
+ }
+
+ vp->capabilities = eeprom[16];
+ vp->full_bus_master_tx = (vp->capabilities & 0x20) ? 1 : 0;
+ /* Rx is broken at 10mbps, so we always disable it. */
+ /* vp->full_bus_master_rx = 0;*/
+ vp->full_bus_master_rx = (vp->capabilities & 0x20) ? 1 : 0;
+
+ /* We do a request_region() to register /proc/ioports info. */
+ request_region(ioaddr, CORKSCREW_TOTAL_SIZE, vp->product_name);
+
+ /* The 3c59x-specific entries in the device structure. */
+ dev->open = &vortex_open;
+ dev->hard_start_xmit = &vortex_start_xmit;
+ dev->stop = &vortex_close;
+ dev->get_stats = &vortex_get_stats;
+ dev->set_multicast_list = &set_rx_mode;
+
+ return 0;
+}
+
+
+static int
+vortex_open(struct device *dev)
+{
+ int ioaddr = dev->base_addr;
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ union wn3_config config;
+ int i;
+
+ /* Before initializing select the active media port. */
+ EL3WINDOW(3);
+ if (vp->full_duplex)
+ outb(0x20, ioaddr + Wn3_MAC_Ctrl); /* Set the full-duplex bit. */
+ config.i = inl(ioaddr + Wn3_Config);
+
+ if (vp->media_override != 7) {
+ if (vortex_debug > 1)
+ printk("%s: Media override to transceiver %d (%s).\n",
+ dev->name, vp->media_override,
+ media_tbl[vp->media_override].name);
+ dev->if_port = vp->media_override;
+ } else if (vp->autoselect) {
+ /* Find first available media type, starting with 100baseTx. */
+ dev->if_port = 4;
+ while (! (vp->available_media & media_tbl[dev->if_port].mask))
+ dev->if_port = media_tbl[dev->if_port].next;
+
+ if (vortex_debug > 1)
+ printk("%s: Initial media type %s.\n",
+ dev->name, media_tbl[dev->if_port].name);
+
+ init_timer(&vp->timer);
+ vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
+ vp->timer.data = (unsigned long)dev;
+ vp->timer.function = &vortex_timer; /* timer handler */
+ add_timer(&vp->timer);
+ } else
+ dev->if_port = vp->default_media;
+
+ config.u.xcvr = dev->if_port;
+ outl(config.i, ioaddr + Wn3_Config);
+
+ if (vortex_debug > 1) {
+ printk("%s: vortex_open() InternalConfig %8.8x.\n",
+ dev->name, config.i);
+ }
+
+ outw(TxReset, ioaddr + EL3_CMD);
+ for (i = 20; i >= 0 ; i--)
+ if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ break;
+
+ outw(RxReset, ioaddr + EL3_CMD);
+ /* Wait a few ticks for the RxReset command to complete. */
+ for (i = 20; i >= 0 ; i--)
+ if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ break;
+
+ outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
+
+ /* Use the now-standard shared IRQ implementation. */
+ if (vp->capabilities == 0x11c7) {
+ /* Corkscrew: Cannot share ISA resources. */
+ if (dev->irq == 0
+ || dev->dma == 0
+ || request_irq(dev->irq, &vortex_interrupt, 0,
+ vp->product_name, dev))
+ return -EAGAIN;
+ enable_dma(dev->dma);
+ set_dma_mode(dev->dma, DMA_MODE_CASCADE);
+ } else if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ,
+ vp->product_name, dev)) {
+ return -EAGAIN;
+ }
+
+ if (vortex_debug > 1) {
+ EL3WINDOW(4);
+ printk("%s: vortex_open() irq %d media status %4.4x.\n",
+ dev->name, dev->irq, inw(ioaddr + Wn4_Media));
+ }
+
+ /* Set the station address and mask in window 2 each time opened. */
+ EL3WINDOW(2);
+ for (i = 0; i < 6; i++)
+ outb(dev->dev_addr[i], ioaddr + i);
+ for (; i < 12; i+=2)
+ outw(0, ioaddr + i);
+
+ if (dev->if_port == 3)
+ /* Start the thinnet transceiver. We should really wait 50ms...*/
+ outw(StartCoax, ioaddr + EL3_CMD);
+ EL3WINDOW(4);
+ outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
+ media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
+
+ /* Switch to the stats window, and clear all stats by reading. */
+ outw(StatsDisable, ioaddr + EL3_CMD);
+ EL3WINDOW(6);
+ for (i = 0; i < 10; i++)
+ inb(ioaddr + i);
+ inw(ioaddr + 10);
+ inw(ioaddr + 12);
+ /* New: On the Vortex we must also clear the BadSSD counter. */
+ EL3WINDOW(4);
+ inb(ioaddr + 12);
+ /* ..and on the Boomerang we enable the extra statistics bits. */
+ outw(0x0040, ioaddr + Wn4_NetDiag);
+
+ /* Switch to register set 7 for normal use. */
+ EL3WINDOW(7);
+
+ if (vp->full_bus_master_rx) { /* Boomerang bus master. */
+ vp->cur_rx = vp->dirty_rx = 0;
+ if (vortex_debug > 2)
+ printk("%s: Filling in the Rx ring.\n", dev->name);
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ struct sk_buff *skb;
+ if (i < (RX_RING_SIZE - 1))
+ vp->rx_ring[i].next = virt_to_bus(&vp->rx_ring[i+1]);
+ else
+ vp->rx_ring[i].next = 0;
+ vp->rx_ring[i].status = 0; /* Clear complete bit. */
+ vp->rx_ring[i].length = PKT_BUF_SZ | 0x80000000;
+ skb = dev_alloc_skb(PKT_BUF_SZ);
+ vp->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break; /* Bad news! */
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ vp->rx_ring[i].addr = virt_to_bus(skb->tail);
+ }
+ vp->rx_ring[i-1].next = virt_to_bus(&vp->rx_ring[0]); /* Wrap the ring. */
+ outl(virt_to_bus(&vp->rx_ring[0]), ioaddr + UpListPtr);
+ }
+ if (vp->full_bus_master_tx) { /* Boomerang bus master Tx. */
+ vp->cur_tx = vp->dirty_tx = 0;
+ outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
+ /* Clear the Tx ring. */
+ for (i = 0; i < TX_RING_SIZE; i++)
+ vp->tx_skbuff[i] = 0;
+ outl(0, ioaddr + DownListPtr);
+ }
+ /* Set reciever mode: presumably accept b-case and phys addr only. */
+ set_rx_mode(dev);
+ outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+ outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+ /* Allow status bits to be seen. */
+ outw(SetStatusEnb | AdapterFailure|IntReq|StatsFull |
+ (vp->full_bus_master_tx ? DownComplete : TxAvailable) |
+ (vp->full_bus_master_rx ? UpComplete : RxComplete) |
+ (vp->bus_master ? DMADone : 0),
+ ioaddr + EL3_CMD);
+ /* Ack all pending events, and set active indicator mask. */
+ outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+ ioaddr + EL3_CMD);
+ outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull
+ | (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete,
+ ioaddr + EL3_CMD);
+
+ MOD_INC_USE_COUNT;
+
+ return 0;
+}
+
+static void vortex_timer(unsigned long data)
+{
+#ifdef AUTOMEDIA
+ struct device *dev = (struct device *)data;
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ int ioaddr = dev->base_addr;
+ unsigned long flags;
+ int ok = 0;
+
+ if (vortex_debug > 1)
+ printk("%s: Media selection timer tick happened, %s.\n",
+ dev->name, media_tbl[dev->if_port].name);
+
+ save_flags(flags); cli(); {
+ int old_window = inw(ioaddr + EL3_CMD) >> 13;
+ int media_status;
+ EL3WINDOW(4);
+ media_status = inw(ioaddr + Wn4_Media);
+ switch (dev->if_port) {
+ case 0: case 4: case 5: /* 10baseT, 100baseTX, 100baseFX */
+ if (media_status & Media_LnkBeat) {
+ ok = 1;
+ if (vortex_debug > 1)
+ printk("%s: Media %s has link beat, %x.\n",
+ dev->name, media_tbl[dev->if_port].name, media_status);
+ } else if (vortex_debug > 1)
+ printk("%s: Media %s is has no link beat, %x.\n",
+ dev->name, media_tbl[dev->if_port].name, media_status);
+
+ break;
+ default: /* Other media types handled by Tx timeouts. */
+ if (vortex_debug > 1)
+ printk("%s: Media %s is has no indication, %x.\n",
+ dev->name, media_tbl[dev->if_port].name, media_status);
+ ok = 1;
+ }
+ if ( ! ok) {
+ union wn3_config config;
+
+ do {
+ dev->if_port = media_tbl[dev->if_port].next;
+ } while ( ! (vp->available_media & media_tbl[dev->if_port].mask));
+ if (dev->if_port == 8) { /* Go back to default. */
+ dev->if_port = vp->default_media;
+ if (vortex_debug > 1)
+ printk("%s: Media selection failing, using default %s port.\n",
+ dev->name, media_tbl[dev->if_port].name);
+ } else {
+ if (vortex_debug > 1)
+ printk("%s: Media selection failed, now trying %s port.\n",
+ dev->name, media_tbl[dev->if_port].name);
+ vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait);
+ add_timer(&vp->timer);
+ }
+ outw((media_status & ~(Media_10TP|Media_SQE)) |
+ media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
+
+ EL3WINDOW(3);
+ config.i = inl(ioaddr + Wn3_Config);
+ config.u.xcvr = dev->if_port;
+ outl(config.i, ioaddr + Wn3_Config);
+
+ outw(dev->if_port == 3 ? StartCoax : StopCoax, ioaddr + EL3_CMD);
+ }
+ EL3WINDOW(old_window);
+ } restore_flags(flags);
+ if (vortex_debug > 1)
+ printk("%s: Media selection timer finished, %s.\n",
+ dev->name, media_tbl[dev->if_port].name);
+
+#endif /* AUTOMEDIA*/
+ return;
+}
+
+static int
+vortex_start_xmit(struct sk_buff *skb, struct device *dev)
+{
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ int ioaddr = dev->base_addr;
+
+ if (dev->tbusy) {
+ int tickssofar = jiffies - dev->trans_start;
+ int i;
+
+ /* Min. wait before assuming a Tx failed == 400ms. */
+
+ if (tickssofar < 400*HZ/1000) /* We probably aren't empty. */
+ return 1;
+ printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
+ dev->name, inb(ioaddr + TxStatus),
+ inw(ioaddr + EL3_STATUS));
+ /* Slight code bloat to be user friendly. */
+ if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
+ printk("%s: Transmitter encountered 16 collisions -- network"
+ " network cable problem?\n", dev->name);
+#ifndef final_version
+ printk(" Flags; bus-master %d, full %d; dirty %d current %d.\n",
+ vp->full_bus_master_tx, vp->tx_full, vp->dirty_tx, vp->cur_tx);
+ printk(" Down list %8.8x vs. %p.\n", inl(ioaddr + DownListPtr),
+ &vp->tx_ring[0]);
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ printk(" %d: %p length %8.8x status %8.8x\n", i,
+ &vp->tx_ring[i],
+ vp->tx_ring[i].length,
+ vp->tx_ring[i].status);
+ }
+#endif
+ /* Issue TX_RESET and TX_START commands. */
+ outw(TxReset, ioaddr + EL3_CMD);
+ for (i = 20; i >= 0 ; i--)
+ if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ break;
+ outw(TxEnable, ioaddr + EL3_CMD);
+ dev->trans_start = jiffies;
+ /* dev->tbusy = 0;*/
+ vp->stats.tx_errors++;
+ vp->stats.tx_dropped++;
+ return 0; /* Yes, silently *drop* the packet! */
+ }
+
+ /* Block a timer-based transmit from overlapping. This could better be
+ done with atomic_swap(1, dev->tbusy), but set_bit() works as well.
+ If this ever occurs the queue layer is doing something evil! */
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+ printk("%s: Transmitter access conflict.\n", dev->name);
+ return 1;
+ }
+
+ if (vp->full_bus_master_tx) { /* BOOMERANG bus-master */
+ /* Calculate the next Tx descriptor entry. */
+ int entry = vp->cur_tx % TX_RING_SIZE;
+ struct boom_tx_desc *prev_entry;
+ unsigned long flags, i;
+
+ if (vp->tx_full) /* No room to transmit with */
+ return 1;
+ if (vp->cur_tx != 0)
+ prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
+ else
+ prev_entry = NULL;
+ if (vortex_debug > 3)
+ printk("%s: Trying to send a packet, Tx index %d.\n",
+ dev->name, vp->cur_tx);
+ /* vp->tx_full = 1; */
+ vp->tx_skbuff[entry] = skb;
+ vp->tx_ring[entry].next = 0;
+ vp->tx_ring[entry].addr = virt_to_bus(skb->data);
+ vp->tx_ring[entry].length = skb->len | 0x80000000;
+ vp->tx_ring[entry].status = skb->len | 0x80000000;
+
+ save_flags(flags);
+ cli();
+ outw(DownStall, ioaddr + EL3_CMD);
+ /* Wait for the stall to complete. */
+ for (i = 20; i >= 0 ; i--)
+ if ( (inw(ioaddr + EL3_STATUS) & CmdInProgress) == 0)
+ break;
+ if (prev_entry)
+ prev_entry->next = virt_to_bus(&vp->tx_ring[entry]);
+ if (inl(ioaddr + DownListPtr) == 0) {
+ outl(virt_to_bus(&vp->tx_ring[entry]), ioaddr + DownListPtr);
+ queued_packet++;
+ }
+ outw(DownUnstall, ioaddr + EL3_CMD);
+ restore_flags(flags);
+
+ vp->cur_tx++;
+ if (vp->cur_tx - vp->dirty_tx > TX_RING_SIZE - 1)
+ vp->tx_full = 1;
+ else { /* Clear previous interrupt enable. */
+ if (prev_entry)
+ prev_entry->status &= ~0x80000000;
+ dev->tbusy = 0;
+ }
+ dev->trans_start = jiffies;
+ return 0;
+ }
+ /* Put out the doubleword header... */
+ outl(skb->len, ioaddr + TX_FIFO);
+#ifdef VORTEX_BUS_MASTER
+ if (vp->bus_master) {
+ /* Set the bus-master controller to transfer the packet. */
+ outl((int)(skb->data), ioaddr + Wn7_MasterAddr);
+ outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
+ vp->tx_skb = skb;
+ outw(StartDMADown, ioaddr + EL3_CMD);
+ /* dev->tbusy will be cleared at the DMADone interrupt. */
+ } else {
+ /* ... and the packet rounded to a doubleword. */
+ outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+ dev_kfree_skb (skb);
+ if (inw(ioaddr + TxFree) > 1536) {
+ dev->tbusy = 0;
+ } else
+ /* Interrupt us when the FIFO has room for max-sized packet. */
+ outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+ }
+#else
+ /* ... and the packet rounded to a doubleword. */
+ outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+ dev_kfree_skb (skb);
+ if (inw(ioaddr + TxFree) > 1536) {
+ dev->tbusy = 0;
+ } else
+ /* Interrupt us when the FIFO has room for max-sized packet. */
+ outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+#endif /* bus master */
+
+ dev->trans_start = jiffies;
+
+ /* Clear the Tx status stack. */
+ {
+ short tx_status;
+ int i = 4;
+
+ while (--i > 0 && (tx_status = inb(ioaddr + TxStatus)) > 0) {
+ if (tx_status & 0x3C) { /* A Tx-disabling error occurred. */
+ if (vortex_debug > 2)
+ printk("%s: Tx error, status %2.2x.\n",
+ dev->name, tx_status);
+ if (tx_status & 0x04) vp->stats.tx_fifo_errors++;
+ if (tx_status & 0x38) vp->stats.tx_aborted_errors++;
+ if (tx_status & 0x30) {
+ int j;
+ outw(TxReset, ioaddr + EL3_CMD);
+ for (j = 20; j >= 0 ; j--)
+ if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ break;
+ }
+ outw(TxEnable, ioaddr + EL3_CMD);
+ }
+ outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
+ }
+ }
+ return 0;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+ after the Tx thread. */
+static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs)
+{
+ /* Use the now-standard shared IRQ implementation. */
+ struct device *dev = dev_id;
+ struct vortex_private *lp;
+ int ioaddr, status;
+ int latency;
+ int i = max_interrupt_work;
+
+ if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+ printk("%s: Re-entering the interrupt handler.\n", dev->name);
+ return;
+ }
+
+ ioaddr = dev->base_addr;
+ latency = inb(ioaddr + Timer);
+ lp = (struct vortex_private *)dev->priv;
+
+ status = inw(ioaddr + EL3_STATUS);
+
+ if (vortex_debug > 4)
+ printk("%s: interrupt, status %4.4x, timer %d.\n", dev->name,
+ status, latency);
+ if ((status & 0xE000) != 0xE000) {
+ static int donedidthis=0;
+ /* Some interrupt controllers store a bogus interrupt from boot-time.
+ Ignore a single early interrupt, but don't hang the machine for
+ other interrupt problems. */
+ if (donedidthis++ > 100) {
+ printk("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n",
+ dev->name, status, dev->start);
+ FREE_IRQ(dev->irq, dev);
+ }
+ }
+
+ do {
+ if (vortex_debug > 5)
+ printk("%s: In interrupt loop, status %4.4x.\n",
+ dev->name, status);
+ if (status & RxComplete)
+ vortex_rx(dev);
+
+ if (status & TxAvailable) {
+ if (vortex_debug > 5)
+ printk(" TX room bit was handled.\n");
+ /* There's room in the FIFO for a full-sized packet. */
+ outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+ if (status & DownComplete) {
+ unsigned int dirty_tx = lp->dirty_tx;
+
+ while (lp->cur_tx - dirty_tx > 0) {
+ int entry = dirty_tx % TX_RING_SIZE;
+ if (inl(ioaddr + DownListPtr) ==
+ virt_to_bus(&lp->tx_ring[entry]))
+ break; /* It still hasn't been processed. */
+ if (lp->tx_skbuff[entry]) {
+ dev_kfree_skb(lp->tx_skbuff[entry]);
+ lp->tx_skbuff[entry] = 0;
+ }
+ dirty_tx++;
+ }
+ lp->dirty_tx = dirty_tx;
+ outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
+ if (lp->tx_full && (lp->cur_tx - dirty_tx <= TX_RING_SIZE - 1)) {
+ lp->tx_full= 0;
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+ }
+#ifdef VORTEX_BUS_MASTER
+ if (status & DMADone) {
+ outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+ dev->tbusy = 0;
+ dev_kfree_skb (lp->tx_skb); /* Release the transfered buffer */
+ mark_bh(NET_BH);
+ }
+#endif
+ if (status & UpComplete) {
+ boomerang_rx(dev);
+ outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
+ }
+ if (status & (AdapterFailure | RxEarly | StatsFull)) {
+ /* Handle all uncommon interrupts at once. */
+ if (status & RxEarly) { /* Rx early is unused. */
+ vortex_rx(dev);
+ outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
+ }
+ if (status & StatsFull) { /* Empty statistics. */
+ static int DoneDidThat = 0;
+ if (vortex_debug > 4)
+ printk("%s: Updating stats.\n", dev->name);
+ update_stats(ioaddr, dev);
+ /* DEBUG HACK: Disable statistics as an interrupt source. */
+ /* This occurs when we have the wrong media type! */
+ if (DoneDidThat == 0 &&
+ inw(ioaddr + EL3_STATUS) & StatsFull) {
+ int win, reg;
+ printk("%s: Updating stats failed, disabling stats as an"
+ " interrupt source.\n", dev->name);
+ for (win = 0; win < 8; win++) {
+ EL3WINDOW(win);
+ printk("\n Vortex window %d:", win);
+ for (reg = 0; reg < 16; reg++)
+ printk(" %2.2x", inb(ioaddr+reg));
+ }
+ EL3WINDOW(7);
+ outw(SetIntrEnb | TxAvailable | RxComplete | AdapterFailure
+ | UpComplete | DownComplete | TxComplete,
+ ioaddr + EL3_CMD);
+ DoneDidThat++;
+ }
+ }
+ if (status & AdapterFailure) {
+ /* Adapter failure requires Rx reset and reinit. */
+ outw(RxReset, ioaddr + EL3_CMD);
+ /* Set the Rx filter to the current state. */
+ set_rx_mode(dev);
+ outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
+ outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD);
+ }
+ }
+
+ if (--i < 0) {
+ printk("%s: Too much work in interrupt, status %4.4x. "
+ "Disabling functions (%4.4x).\n",
+ dev->name, status, SetStatusEnb | ((~status) & 0x7FE));
+ /* Disable all pending interrupts. */
+ outw(SetStatusEnb | ((~status) & 0x7FE), ioaddr + EL3_CMD);
+ outw(AckIntr | 0x7FF, ioaddr + EL3_CMD);
+ break;
+ }
+ /* Acknowledge the IRQ. */
+ outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+
+ } while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+
+ if (vortex_debug > 4)
+ printk("%s: exiting interrupt, status %4.4x.\n", dev->name, status);
+
+ dev->interrupt = 0;
+ return;
+}
+
+static int
+vortex_rx(struct device *dev)
+{
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ int ioaddr = dev->base_addr;
+ int i;
+ short rx_status;
+
+ if (vortex_debug > 5)
+ printk(" In rx_packet(), status %4.4x, rx_status %4.4x.\n",
+ inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
+ while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
+ if (rx_status & 0x4000) { /* Error, update stats. */
+ unsigned char rx_error = inb(ioaddr + RxErrors);
+ if (vortex_debug > 2)
+ printk(" Rx error: status %2.2x.\n", rx_error);
+ vp->stats.rx_errors++;
+ if (rx_error & 0x01) vp->stats.rx_over_errors++;
+ if (rx_error & 0x02) vp->stats.rx_length_errors++;
+ if (rx_error & 0x04) vp->stats.rx_frame_errors++;
+ if (rx_error & 0x08) vp->stats.rx_crc_errors++;
+ if (rx_error & 0x10) vp->stats.rx_length_errors++;
+ } else {
+ /* The packet length: up to 4.5K!. */
+ short pkt_len = rx_status & 0x1fff;
+ struct sk_buff *skb;
+
+ skb = DEV_ALLOC_SKB(pkt_len + 5);
+ if (vortex_debug > 4)
+ printk("Receiving packet size %d status %4.4x.\n",
+ pkt_len, rx_status);
+ if (skb != NULL) {
+ skb->dev = dev;
+#if LINUX_VERSION_CODE >= 0x10300
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ /* 'skb_put()' points to the start of sk_buff data area. */
+ insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
+ (pkt_len + 3) >> 2);
+ outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+ skb->protocol = eth_type_trans(skb, dev);
+#else
+ skb->len = pkt_len;
+ /* 'skb->data' points to the start of sk_buff data area. */
+ insl(ioaddr + RX_FIFO, skb->data, (pkt_len + 3) >> 2);
+ outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+#endif /* KERNEL_1_3_0 */
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ vp->stats.rx_packets++;
+ /* Wait a limited time to go to next packet. */
+ for (i = 200; i >= 0; i--)
+ if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ break;
+ continue;
+ } else if (vortex_debug)
+ printk("%s: Couldn't allocate a sk_buff of size %d.\n",
+ dev->name, pkt_len);
+ }
+ outw(RxDiscard, ioaddr + EL3_CMD);
+ vp->stats.rx_dropped++;
+ /* Wait a limited time to skip this packet. */
+ for (i = 200; i >= 0; i--)
+ if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+ break;
+ }
+
+ return 0;
+}
+
+static int
+boomerang_rx(struct device *dev)
+{
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ int entry = vp->cur_rx % RX_RING_SIZE;
+ int ioaddr = dev->base_addr;
+ int rx_status;
+
+ if (vortex_debug > 5)
+ printk(" In boomerang_rx(), status %4.4x, rx_status %4.4x.\n",
+ inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
+ while ((rx_status = vp->rx_ring[entry].status) & RxDComplete) {
+ if (rx_status & RxDError) { /* Error, update stats. */
+ unsigned char rx_error = rx_status >> 16;
+ if (vortex_debug > 2)
+ printk(" Rx error: status %2.2x.\n", rx_error);
+ vp->stats.rx_errors++;
+ if (rx_error & 0x01) vp->stats.rx_over_errors++;
+ if (rx_error & 0x02) vp->stats.rx_length_errors++;
+ if (rx_error & 0x04) vp->stats.rx_frame_errors++;
+ if (rx_error & 0x08) vp->stats.rx_crc_errors++;
+ if (rx_error & 0x10) vp->stats.rx_length_errors++;
+ } else {
+ /* The packet length: up to 4.5K!. */
+ short pkt_len = rx_status & 0x1fff;
+ struct sk_buff *skb;
+
+ if (vortex_debug > 4)
+ printk("Receiving packet size %d status %4.4x.\n",
+ pkt_len, rx_status);
+
+ /* Check if the packet is long enough to just accept without
+ copying to a properly sized skbuff. */
+ if (pkt_len < rx_copybreak
+ && (skb = DEV_ALLOC_SKB(pkt_len + 2)) != 0) {
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ /* 'skb_put()' points to the start of sk_buff data area. */
+ memcpy(skb_put(skb, pkt_len),
+ bus_to_virt(vp->rx_ring[entry].addr),
+ pkt_len);
+ rx_copy++;
+ } else{
+ void *temp;
+ /* Pass up the skbuff already on the Rx ring. */
+ skb = vp->rx_skbuff[entry];
+ vp->rx_skbuff[entry] = NULL;
+ temp = skb_put(skb, pkt_len);
+ /* Remove this checking code for final release. */
+ if (bus_to_virt(vp->rx_ring[entry].addr) != temp)
+ printk("%s: Warning -- the skbuff addresses do not match"
+ " in boomerang_rx: %p vs. %p / %p.\n", dev->name,
+ bus_to_virt(vp->rx_ring[entry].addr),
+ skb->head, temp);
+ rx_nocopy++;
+ }
+#if LINUX_VERSION_CODE > 0x10300
+ skb->protocol = eth_type_trans(skb, dev);
+#else
+ skb->len = pkt_len;
+#endif
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ vp->stats.rx_packets++;
+ }
+ entry = (++vp->cur_rx) % RX_RING_SIZE;
+ }
+ /* Refill the Rx ring buffers. */
+ for (; vp->dirty_rx < vp->cur_rx; vp->dirty_rx++) {
+ struct sk_buff *skb;
+ entry = vp->dirty_rx % RX_RING_SIZE;
+ if (vp->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(PKT_BUF_SZ);
+ if (skb == NULL)
+ break; /* Bad news! */
+ skb->dev = dev; /* Mark as being used by this device. */
+#if LINUX_VERSION_CODE > 0x10300
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ vp->rx_ring[entry].addr = virt_to_bus(skb->tail);
+#else
+ vp->rx_ring[entry].addr = virt_to_bus(skb->data);
+#endif
+ vp->rx_skbuff[entry] = skb;
+ }
+ vp->rx_ring[entry].status = 0; /* Clear complete bit. */
+ }
+ return 0;
+}
+
+static int
+vortex_close(struct device *dev)
+{
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ int ioaddr = dev->base_addr;
+ int i;
+
+ dev->start = 0;
+ dev->tbusy = 1;
+
+ if (vortex_debug > 1) {
+ printk("%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
+ dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus));
+ printk("%s: vortex close stats: rx_nocopy %d rx_copy %d"
+ " tx_queued %d.\n",
+ dev->name, rx_nocopy, rx_copy, queued_packet);
+ }
+
+ del_timer(&vp->timer);
+
+ /* Turn off statistics ASAP. We update lp->stats below. */
+ outw(StatsDisable, ioaddr + EL3_CMD);
+
+ /* Disable the receiver and transmitter. */
+ outw(RxDisable, ioaddr + EL3_CMD);
+ outw(TxDisable, ioaddr + EL3_CMD);
+
+ if (dev->if_port == XCVR_10base2)
+ /* Turn off thinnet power. Green! */
+ outw(StopCoax, ioaddr + EL3_CMD);
+
+#ifdef SA_SHIRQ
+ free_irq(dev->irq, dev);
+#else
+ free_irq(dev->irq);
+ irq2dev_map[dev->irq] = 0;
+#endif
+
+ outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+
+ update_stats(ioaddr, dev);
+ if (vp->full_bus_master_rx) { /* Free Boomerang bus master Rx buffers. */
+ outl(0, ioaddr + UpListPtr);
+ for (i = 0; i < RX_RING_SIZE; i++)
+ if (vp->rx_skbuff[i]) {
+#if LINUX_VERSION_CODE < 0x20100
+ vp->rx_skbuff[i]->free = 1;
+#endif
+ dev_kfree_skb (vp->rx_skbuff[i]);
+ vp->rx_skbuff[i] = 0;
+ }
+ }
+ if (vp->full_bus_master_tx) { /* Free Boomerang bus master Tx buffers. */
+ outl(0, ioaddr + DownListPtr);
+ for (i = 0; i < TX_RING_SIZE; i++)
+ if (vp->tx_skbuff[i]) {
+ dev_kfree_skb(vp->tx_skbuff[i]);
+ vp->tx_skbuff[i] = 0;
+ }
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ return 0;
+}
+
+static struct enet_statistics *
+vortex_get_stats(struct device *dev)
+{
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+ unsigned long flags;
+
+ if (dev->start) {
+ save_flags(flags);
+ cli();
+ update_stats(dev->base_addr, dev);
+ restore_flags(flags);
+ }
+ return &vp->stats;
+}
+
+/* Update statistics.
+ Unlike with the EL3 we need not worry about interrupts changing
+ the window setting from underneath us, but we must still guard
+ against a race condition with a StatsUpdate interrupt updating the
+ table. This is done by checking that the ASM (!) code generated uses
+ atomic updates with '+='.
+ */
+static void update_stats(int ioaddr, struct device *dev)
+{
+ struct vortex_private *vp = (struct vortex_private *)dev->priv;
+
+ /* Unlike the 3c5x9 we need not turn off stats updates while reading. */
+ /* Switch to the stats window, and read everything. */
+ EL3WINDOW(6);
+ vp->stats.tx_carrier_errors += inb(ioaddr + 0);
+ vp->stats.tx_heartbeat_errors += inb(ioaddr + 1);
+ /* Multiple collisions. */ inb(ioaddr + 2);
+ vp->stats.collisions += inb(ioaddr + 3);
+ vp->stats.tx_window_errors += inb(ioaddr + 4);
+ vp->stats.rx_fifo_errors += inb(ioaddr + 5);
+ vp->stats.tx_packets += inb(ioaddr + 6);
+ vp->stats.tx_packets += (inb(ioaddr + 9)&0x30) << 4;
+ /* Rx packets */ inb(ioaddr + 7); /* Must read to clear */
+ /* Tx deferrals */ inb(ioaddr + 8);
+ /* Don't bother with register 9, an extension of registers 6&7.
+ If we do use the 6&7 values the atomic update assumption above
+ is invalid. */
+ inw(ioaddr + 10); /* Total Rx and Tx octets. */
+ inw(ioaddr + 12);
+ /* New: On the Vortex we must also clear the BadSSD counter. */
+ EL3WINDOW(4);
+ inb(ioaddr + 12);
+
+ /* We change back to window 7 (not 1) with the Vortex. */
+ EL3WINDOW(7);
+ return;
+}
+
+/* This new version of set_rx_mode() supports v1.4 kernels.
+ The Vortex chip has no documented multicast filter, so the only
+ multicast setting is to receive all multicast frames. At least
+ the chip has a very clean way to set the mode, unlike many others. */
+static void
+set_rx_mode(struct device *dev)
+{
+ int ioaddr = dev->base_addr;
+ short new_mode;
+
+ if (dev->flags & IFF_PROMISC) {
+ if (vortex_debug > 3)
+ printk("%s: Setting promiscuous mode.\n", dev->name);
+ new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm;
+ } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) {
+ new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast;
+ } else
+ new_mode = SetRxFilter | RxStation | RxBroadcast;
+
+ outw(new_mode, ioaddr + EL3_CMD);
+}
+
+#ifdef MODULE
+void
+cleanup_module(void)
+{
+ struct device *next_dev;
+
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+ while (root_vortex_dev) {
+ next_dev = ((struct vortex_private *)root_vortex_dev->priv)->next_module;
+ if (root_vortex_dev->dma)
+ free_dma(root_vortex_dev->dma);
+ unregister_netdev(root_vortex_dev);
+ outw(TotalReset, root_vortex_dev->base_addr + EL3_CMD);
+ release_region(root_vortex_dev->base_addr, CORKSCREW_TOTAL_SIZE);
+ kfree(root_vortex_dev);
+ root_vortex_dev = next_dev;
+ }
+}
+#endif /* MODULE */
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c 3c515.c"
+ * c-indent-level: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/drivers/net/3c523.c b/drivers/net/3c523.c
index 9a818d4d4..968168d01 100644
--- a/drivers/net/3c523.c
+++ b/drivers/net/3c523.c
@@ -1,84 +1,84 @@
/*
-net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
+ net-3-driver for the 3c523 Etherlink/MC card (i82586 Ethernet chip)
-This is an extension to the Linux operating system, and is covered by the
-same Gnu Public License that covers that work.
+ This is an extension to the Linux operating system, and is covered by the
+ same Gnu Public License that covers that work.
-Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
+ Copyright 1995, 1996 by Chris Beauregard (cpbeaure@undergrad.math.uwaterloo.ca)
-This is basically Michael Hipp's ni52 driver, with a new probing
-algorithm and some minor changes to the 82586 CA and reset routines.
-Thanks a lot Michael for a really clean i82586 implementation! Unless
-otherwise documented in ni52.c, any bugs are mine.
+ This is basically Michael Hipp's ni52 driver, with a new probing
+ algorithm and some minor changes to the 82586 CA and reset routines.
+ Thanks a lot Michael for a really clean i82586 implementation! Unless
+ otherwise documented in ni52.c, any bugs are mine.
-Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in
-any way. The ni52 is a lot easier to modify.
+ Contrary to the Ethernet-HOWTO, this isn't based on the 3c507 driver in
+ any way. The ni52 is a lot easier to modify.
-sources:
- ni52.c
+ sources:
+ ni52.c
- Crynwr packet driver collection was a great reference for my first
- attempt at this sucker. The 3c507 driver also helped, until I noticed
- that ni52.c was a lot nicer.
+ Crynwr packet driver collection was a great reference for my first
+ attempt at this sucker. The 3c507 driver also helped, until I noticed
+ that ni52.c was a lot nicer.
- EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference
- Manual, courtesy of 3Com CardFacts, documents the 3c523-specific
- stuff. Information on CardFacts is found in the Ethernet HOWTO.
- Also see <a href="http://www.3com.com/">
+ EtherLink/MC: Micro Channel Ethernet Adapter Technical Reference
+ Manual, courtesy of 3Com CardFacts, documents the 3c523-specific
+ stuff. Information on CardFacts is found in the Ethernet HOWTO.
+ Also see <a href="http://www.3com.com/">
- Microprocessor Communications Support Chips, T.J. Byers, ISBN
- 0-444-01224-9, has a section on the i82586. It tells you just enough
- to know that you really don't want to learn how to program the chip.
+ Microprocessor Communications Support Chips, T.J. Byers, ISBN
+ 0-444-01224-9, has a section on the i82586. It tells you just enough
+ to know that you really don't want to learn how to program the chip.
- The original device probe code was stolen from ps2esdi.c
+ The original device probe code was stolen from ps2esdi.c
-Known Problems:
- Since most of the code was stolen from ni52.c, you'll run across the
- same bugs in the 0.62 version of ni52.c, plus maybe a few because of
- the 3c523 idiosynchacies. The 3c523 has 16K of RAM though, so there
- shouldn't be the overrun problem that the 8K ni52 has.
+ Known Problems:
+ Since most of the code was stolen from ni52.c, you'll run across the
+ same bugs in the 0.62 version of ni52.c, plus maybe a few because of
+ the 3c523 idiosynchacies. The 3c523 has 16K of RAM though, so there
+ shouldn't be the overrun problem that the 8K ni52 has.
- This driver is for a 16K adapter. It should work fine on the 64K
- adapters, but it will only use one of the 4 banks of RAM. Modifying
- this for the 64K version would require a lot of heinous bank
- switching, which I'm sure not interested in doing. If you try to
- implement a bank switching version, you'll basically have to remember
- what bank is enabled and do a switch everytime you access a memory
- location that's not current. You'll also have to remap pointers on
- the driver side, because it only knows about 16K of the memory.
- Anyone desperate or masochistic enough to try?
+ This driver is for a 16K adapter. It should work fine on the 64K
+ adapters, but it will only use one of the 4 banks of RAM. Modifying
+ this for the 64K version would require a lot of heinous bank
+ switching, which I'm sure not interested in doing. If you try to
+ implement a bank switching version, you'll basically have to remember
+ what bank is enabled and do a switch everytime you access a memory
+ location that's not current. You'll also have to remap pointers on
+ the driver side, because it only knows about 16K of the memory.
+ Anyone desperate or masochistic enough to try?
- It seems to be stable now when multiple transmit buffers are used. I
- can't see any performance difference, but then I'm working on a 386SX.
+ It seems to be stable now when multiple transmit buffers are used. I
+ can't see any performance difference, but then I'm working on a 386SX.
- Multicast doesn't work. It doesn't even pretend to work. Don't use
- it. Don't compile your kernel with multicast support. I don't know
- why.
+ Multicast doesn't work. It doesn't even pretend to work. Don't use
+ it. Don't compile your kernel with multicast support. I don't know
+ why.
-Features:
- This driver is useable as a loadable module. If you try to specify an
- IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will
- search the MCA slots until it finds a 3c523 with the specified
- parameters.
+ Features:
+ This driver is useable as a loadable module. If you try to specify an
+ IRQ or a IO address (via insmod 3c523.o irq=xx io=0xyyy), it will
+ search the MCA slots until it finds a 3c523 with the specified
+ parameters.
- This driver should support multiple ethernet cards, but I can't test
- that. If someone would I'd greatly appreciate it.
+ This driver should support multiple ethernet cards, but I can't test
+ that. If someone would I'd greatly appreciate it.
- This has been tested with both BNC and TP versions, internal and
- external transceivers. Haven't tested with the 64K version (that I
- know of).
+ This has been tested with both BNC and TP versions, internal and
+ external transceivers. Haven't tested with the 64K version (that I
+ know of).
-History:
- Jan 1st, 1996
- first public release
- Feb 4th, 1996
- update to 1.3.59, incorporated multicast diffs from ni52.c
- Feb 15th, 1996
- added shared irq support
+ History:
+ Jan 1st, 1996
+ first public release
+ Feb 4th, 1996
+ update to 1.3.59, incorporated multicast diffs from ni52.c
+ Feb 15th, 1996
+ added shared irq support
- $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
-*/
+ $Header: /fsys2/home/chrisb/linux-1.3.59-MCA/drivers/net/RCS/3c523.c,v 1.1 1996/02/05 01:53:46 chrisb Exp chrisb $
+ */
#ifdef MODULE
#include <linux/module.h>
@@ -105,8 +105,8 @@ History:
#include "3c523.h"
/*************************************************************************/
-#define DEBUG /* debug on */
-#define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit*/
+#define DEBUG /* debug on */
+#define SYSBUSVAL 0 /* 1 = 8 Bit, 0 = 16 bit - 3c523 only does 16 bit */
#define make32(ptr16) (p->memtop + (short) (ptr16) )
#define make24(ptr32) ((char *) (ptr32) - p->base)
@@ -114,11 +114,19 @@ History:
/*************************************************************************/
/*
- Tables to which we can map values in the configuration registers.
-*/
-static int irq_table[] __initdata = {12, 7, 3, 9};
-static int csr_table[] __initdata = {0x300, 0x1300, 0x2300, 0x3300};
-static int shm_table[] __initdata = {0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000};
+ Tables to which we can map values in the configuration registers.
+ */
+static int irq_table[] __initdata = {
+ 12, 7, 3, 9
+};
+
+static int csr_table[] __initdata = {
+ 0x300, 0x1300, 0x2300, 0x3300
+};
+
+static int shm_table[] __initdata = {
+ 0x0c0000, 0x0c8000, 0x0d0000, 0x0d8000
+};
/******************* how to calculate the buffers *****************************
@@ -135,21 +143,21 @@ sizeof(nop_cmd) = 8;
* if you don't know the driver, better do not change this values: */
-#define RECV_BUFF_SIZE 1524 /* slightly oversized */
-#define XMIT_BUFF_SIZE 1524 /* slightly oversized */
-#define NUM_XMIT_BUFFS 4 /* config for both, 8K and 16K shmem */
-#define NUM_RECV_BUFFS_8 1 /* config for 8K shared mem */
-#define NUM_RECV_BUFFS_16 6 /* config for 16K shared mem */
+#define RECV_BUFF_SIZE 1524 /* slightly oversized */
+#define XMIT_BUFF_SIZE 1524 /* slightly oversized */
+#define NUM_XMIT_BUFFS 4 /* config for both, 8K and 16K shmem */
+#define NUM_RECV_BUFFS_8 1 /* config for 8K shared mem */
+#define NUM_RECV_BUFFS_16 6 /* config for 16K shared mem */
#if (NUM_XMIT_BUFFS == 1)
-#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
+#define NO_NOPCOMMANDS /* only possible with NUM_XMIT_BUFFS=1 */
#endif
/**************************************************************************/
#define DELAY(x) {int i=jiffies; \
if(loops_per_sec == 1) \
- while(i+(x)>jiffies); \
+ while(time_after(i+(x), jiffies)); \
else \
__delay((loops_per_sec>>5)*x); \
}
@@ -167,42 +175,41 @@ sizeof(nop_cmd) = 8;
dev->name,__LINE__); \
elmc_id_reset586(); } } }
-static void elmc_interrupt(int irq,void *dev_id,struct pt_regs *reg_ptr);
-static int elmc_open(struct device *dev);
-static int elmc_close(struct device *dev);
-static int elmc_send_packet(struct sk_buff *,struct device *);
-static struct net_device_stats *elmc_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
+static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr);
+static int elmc_open(struct device *dev);
+static int elmc_close(struct device *dev);
+static int elmc_send_packet(struct sk_buff *, struct device *);
+static struct net_device_stats *elmc_get_stats(struct device *dev);
+static void set_multicast_list(struct device *dev);
/* helper-functions */
-static int init586(struct device *dev);
-static int check586(struct device *dev,char *where,unsigned size);
-static void alloc586(struct device *dev);
-static void startrecv586(struct device *dev);
-static void *alloc_rfa(struct device *dev,void *ptr);
-static void elmc_rcv_int(struct device *dev);
-static void elmc_xmt_int(struct device *dev);
-static void elmc_rnr_int(struct device *dev);
-
-struct priv
-{
+static int init586(struct device *dev);
+static int check586(struct device *dev, char *where, unsigned size);
+static void alloc586(struct device *dev);
+static void startrecv586(struct device *dev);
+static void *alloc_rfa(struct device *dev, void *ptr);
+static void elmc_rcv_int(struct device *dev);
+static void elmc_xmt_int(struct device *dev);
+static void elmc_rnr_int(struct device *dev);
+
+struct priv {
struct net_device_stats stats;
unsigned long base;
char *memtop;
- volatile struct rfd_struct *rfd_last,*rfd_top,*rfd_first;
- volatile struct scp_struct *scp; /* volatile is important */
- volatile struct iscp_struct *iscp; /* volatile is important */
- volatile struct scb_struct *scb; /* volatile is important */
- volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
+ volatile struct rfd_struct *rfd_last, *rfd_top, *rfd_first;
+ volatile struct scp_struct *scp; /* volatile is important */
+ volatile struct iscp_struct *iscp; /* volatile is important */
+ volatile struct scb_struct *scb; /* volatile is important */
+ volatile struct tbd_struct *xmit_buffs[NUM_XMIT_BUFFS];
volatile struct transmit_cmd_struct *xmit_cmds[NUM_XMIT_BUFFS];
#if (NUM_XMIT_BUFFS == 1)
volatile struct nop_cmd_struct *nop_cmds[2];
#else
volatile struct nop_cmd_struct *nop_cmds[NUM_XMIT_BUFFS];
#endif
- volatile int nop_point,num_recv_buffs;
- volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
- volatile int xmit_count,xmit_last;
+ volatile int nop_point, num_recv_buffs;
+ volatile char *xmit_cbuffs[NUM_XMIT_BUFFS];
+ volatile int xmit_count, xmit_last;
volatile int slot;
};
@@ -210,379 +217,368 @@ struct priv
#define elmc_reset586() {elmc_do_reset586(dev->base_addr,ELMC_CTRL_INTE);}
/* with interrupts disabled - this will clear the interrupt bit in the
-3c523 control register, and won't put it back. This effectively
-disables interrupts on the card. */
+ 3c523 control register, and won't put it back. This effectively
+ disables interrupts on the card. */
#define elmc_id_attn586() {elmc_do_attn586(dev->base_addr,0);}
#define elmc_id_reset586() {elmc_do_reset586(dev->base_addr,0);}
/*************************************************************************/
/*
- Do a Channel Attention on the 3c523. This is extremely board dependent.
-*/
-static
-void
-elmc_do_attn586( int ioaddr, int ints ) {
- /* the 3c523 requires a minimum of 500 ns. The delays here might be
- a little too large, and hence they may cut the performance of the
- card slightly. If someone who knows a little more about Linux
- timing would care to play with these, I'd appreciate it. */
-
- /* this bit masking stuff is crap. I'd rather have separate
- registers with strobe triggers for each of these functions. <sigh>
- Ya take what ya got. */
-
- outb( ELMC_CTRL_RST|0x3|ELMC_CTRL_CA|ints, ioaddr + ELMC_CTRL);
- DELAY_16(); /* > 500 ns */
- outb( ELMC_CTRL_RST|0x3|ints, ioaddr + ELMC_CTRL);
+ Do a Channel Attention on the 3c523. This is extremely board dependent.
+ */
+static void elmc_do_attn586(int ioaddr, int ints)
+{
+ /* the 3c523 requires a minimum of 500 ns. The delays here might be
+ a little too large, and hence they may cut the performance of the
+ card slightly. If someone who knows a little more about Linux
+ timing would care to play with these, I'd appreciate it. */
+
+ /* this bit masking stuff is crap. I'd rather have separate
+ registers with strobe triggers for each of these functions. <sigh>
+ Ya take what ya got. */
+
+ outb(ELMC_CTRL_RST | 0x3 | ELMC_CTRL_CA | ints, ioaddr + ELMC_CTRL);
+ DELAY_16(); /* > 500 ns */
+ outb(ELMC_CTRL_RST | 0x3 | ints, ioaddr + ELMC_CTRL);
}
/*************************************************************************/
/*
- Reset the 82586 on the 3c523. Also very board dependent.
-*/
-static
-void
-elmc_do_reset586( int ioaddr, int ints ) {
- /* toggle the RST bit low then high */
- outb( 0x3|ELMC_CTRL_LBK, ioaddr + ELMC_CTRL );
- DELAY_16(); /* > 500 ns */
- outb( ELMC_CTRL_RST|ELMC_CTRL_LBK|0x3, ioaddr + ELMC_CTRL );
-
- elmc_do_attn586( ioaddr, ints );
+ Reset the 82586 on the 3c523. Also very board dependent.
+ */
+static void elmc_do_reset586(int ioaddr, int ints)
+{
+ /* toggle the RST bit low then high */
+ outb(0x3 | ELMC_CTRL_LBK, ioaddr + ELMC_CTRL);
+ DELAY_16(); /* > 500 ns */
+ outb(ELMC_CTRL_RST | ELMC_CTRL_LBK | 0x3, ioaddr + ELMC_CTRL);
+
+ elmc_do_attn586(ioaddr, ints);
}
/**********************************************
* close device
*/
-static
-int
-elmc_close(struct device *dev) {
- elmc_id_reset586(); /* the hard way to stop the receiver */
+static int elmc_close(struct device *dev)
+{
+ elmc_id_reset586(); /* the hard way to stop the receiver */
- free_irq(dev->irq, dev);
+ free_irq(dev->irq, dev);
- dev->start = 0;
- dev->tbusy = 0;
+ dev->start = 0;
+ dev->tbusy = 0;
#ifdef MODULE
MOD_DEC_USE_COUNT;
#endif
- return 0;
+ return 0;
}
/**********************************************
* open device
*/
-static
-int
-elmc_open(struct device *dev) {
-
- elmc_id_attn586(); /* disable interrupts */
+static int elmc_open(struct device *dev)
+{
- if(request_irq( dev->irq, &elmc_interrupt, SA_SHIRQ|SA_SAMPLE_RANDOM,
- "3c523", dev )
- ) {
- printk( "%s: couldn't get irq %d\n", dev->name, dev->irq );
- elmc_id_reset586();
- return -EAGAIN;
- }
+ elmc_id_attn586(); /* disable interrupts */
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
+ if (request_irq(dev->irq, &elmc_interrupt, SA_SHIRQ | SA_SAMPLE_RANDOM,
+ "3c523", dev)
+ ) {
+ printk("%s: couldn't get irq %d\n", dev->name, dev->irq);
+ elmc_id_reset586();
+ return -EAGAIN;
+ }
+ alloc586(dev);
+ init586(dev);
+ startrecv586(dev);
- dev->interrupt = 0;
- dev->tbusy = 0;
- dev->start = 1;
+ dev->interrupt = 0;
+ dev->tbusy = 0;
+ dev->start = 1;
#ifdef MODULE
MOD_INC_USE_COUNT;
#endif
- return 0; /* most done by init */
+ return 0; /* most done by init */
}
/**********************************************
* Check to see if there's an 82586 out there.
*/
-__initfunc(static
-int
-check586( struct device *dev, char *where, unsigned size)) {
- struct priv *p = (struct priv *) dev->priv;
- char *iscp_addrs[2];
- int i = 0;
-
- p->base = (unsigned long) where + size - 0x01000000;
- p->memtop = where + size;
- p->scp = (struct scp_struct *)(p->base + SCP_DEFAULT_ADDRESS);
- memset((char *)p->scp,0, sizeof(struct scp_struct));
- p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
+__initfunc(static int check586(struct device *dev, char *where, unsigned size))
+{
+ struct priv *p = (struct priv *) dev->priv;
+ char *iscp_addrs[2];
+ int i = 0;
- iscp_addrs[0] = where;
- iscp_addrs[1]= (char *) p->scp - sizeof(struct iscp_struct);
+ p->base = (unsigned long) where + size - 0x01000000;
+ p->memtop = where + size;
+ p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
+ memset((char *) p->scp, 0, sizeof(struct scp_struct));
+ p->scp->sysbus = SYSBUSVAL; /* 1 = 8Bit-Bus, 0 = 16 Bit */
- for( i = 0; i < 2; i ++ ) {
- p->iscp = (struct iscp_struct *) iscp_addrs[i];
- memset((char *)p->iscp,0, sizeof(struct iscp_struct));
+ iscp_addrs[0] = where;
+ iscp_addrs[1] = (char *) p->scp - sizeof(struct iscp_struct);
- p->scp->iscp = make24(p->iscp);
- p->iscp->busy = 1;
+ for (i = 0; i < 2; i++) {
+ p->iscp = (struct iscp_struct *) iscp_addrs[i];
+ memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
- elmc_id_reset586();
+ p->scp->iscp = make24(p->iscp);
+ p->iscp->busy = 1;
- /* reset586 does an implicit CA */
+ elmc_id_reset586();
- /* apparently, you sometimes have to kick the 82586 twice... */
- elmc_id_attn586();
+ /* reset586 does an implicit CA */
- if(p->iscp->busy) { /* i82586 clears 'busy' after successful init */
- return 0;
- }
- }
+ /* apparently, you sometimes have to kick the 82586 twice... */
+ elmc_id_attn586();
- return 1;
+ if (p->iscp->busy) { /* i82586 clears 'busy' after successful init */
+ return 0;
+ }
+ }
+ return 1;
}
/******************************************************************
* set iscp at the right place, called by elmc_probe and open586.
*/
-void
-alloc586( struct device *dev ) {
- struct priv *p = (struct priv *) dev->priv;
-
- elmc_id_reset586();
- DELAY(2);
+void alloc586(struct device *dev)
+{
+ struct priv *p = (struct priv *) dev->priv;
- p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
- p->scb = (struct scb_struct *) (dev->mem_start);
- p->iscp = (struct iscp_struct *) ((char *)p->scp - sizeof(struct iscp_struct));
+ elmc_id_reset586();
+ DELAY(2);
- memset((char *) p->iscp,0,sizeof(struct iscp_struct));
- memset((char *) p->scp ,0,sizeof(struct scp_struct));
+ p->scp = (struct scp_struct *) (p->base + SCP_DEFAULT_ADDRESS);
+ p->scb = (struct scb_struct *) (dev->mem_start);
+ p->iscp = (struct iscp_struct *) ((char *) p->scp - sizeof(struct iscp_struct));
- p->scp->iscp = make24(p->iscp);
- p->scp->sysbus = SYSBUSVAL;
- p->iscp->scb_offset = make16(p->scb);
+ memset((char *) p->iscp, 0, sizeof(struct iscp_struct));
+ memset((char *) p->scp, 0, sizeof(struct scp_struct));
- p->iscp->busy = 1;
- elmc_id_reset586();
- elmc_id_attn586();
+ p->scp->iscp = make24(p->iscp);
+ p->scp->sysbus = SYSBUSVAL;
+ p->iscp->scb_offset = make16(p->scb);
- DELAY(2);
+ p->iscp->busy = 1;
+ elmc_id_reset586();
+ elmc_id_attn586();
- if(p->iscp->busy) {
- printk("%s: Init-Problems (alloc).\n",dev->name);
- }
+ DELAY(2);
- memset((char *)p->scb,0,sizeof(struct scb_struct));
+ if (p->iscp->busy) {
+ printk("%s: Init-Problems (alloc).\n", dev->name);
+ }
+ memset((char *) p->scb, 0, sizeof(struct scb_struct));
}
/*****************************************************************/
-static int
-elmc_getinfo( char* buf, int slot, void* d ) {
+
+static int elmc_getinfo(char *buf, int slot, void *d)
+{
int len = 0;
- struct device* dev = (struct device*) d;
+ struct device *dev = (struct device *) d;
int i;
- if( dev == NULL ) return len;
-
- len += sprintf( buf+len, "Revision: 0x%x\n",
- inb( dev->base_addr + ELMC_REVISION ) & 0xf );
- len += sprintf( buf+len, "IRQ: %d\n", dev->irq );
- len += sprintf( buf+len, "IO Address: %#lx-%#lx\n", dev->base_addr,
- dev->base_addr+ELMC_IO_EXTENT );
- len += sprintf( buf+len, "Memory: %#lx-%#lx\n", dev->mem_start,
- dev->mem_end-1 );
- len += sprintf( buf+len, "Transceiver: %s\n", dev->if_port ?
- "External" : "Internal" );
- len += sprintf( buf+len, "Device: %s\n", dev->name );
- len += sprintf( buf+len, "Hardware Address:" );
- for (i = 0; i < 6; i ++ ) {
- len += sprintf( buf+len, " %02x", dev->dev_addr[i] );
+ if (dev == NULL)
+ return len;
+
+ len += sprintf(buf + len, "Revision: 0x%x\n",
+ inb(dev->base_addr + ELMC_REVISION) & 0xf);
+ len += sprintf(buf + len, "IRQ: %d\n", dev->irq);
+ len += sprintf(buf + len, "IO Address: %#lx-%#lx\n", dev->base_addr,
+ dev->base_addr + ELMC_IO_EXTENT);
+ len += sprintf(buf + len, "Memory: %#lx-%#lx\n", dev->mem_start,
+ dev->mem_end - 1);
+ len += sprintf(buf + len, "Transceiver: %s\n", dev->if_port ?
+ "External" : "Internal");
+ len += sprintf(buf + len, "Device: %s\n", dev->name);
+ len += sprintf(buf + len, "Hardware Address:");
+ for (i = 0; i < 6; i++) {
+ len += sprintf(buf + len, " %02x", dev->dev_addr[i]);
}
buf[len++] = '\n';
buf[len] = 0;
return len;
-} /* elmc_getinfo() */
+} /* elmc_getinfo() */
/*****************************************************************/
-__initfunc(int
-elmc_probe(struct device *dev)) {
- static int slot = 0;
- int base_addr = dev ? dev->base_addr : 0;
- int irq = dev ? dev->irq : 0;
- u_char status = 0;
- u_char revision = 0;
- int i = 0;
- unsigned int size = 0;
-
- if( MCA_bus == 0 ) {
- return ENODEV;
- }
+__initfunc(int elmc_probe(struct device *dev))
+{
+ static int slot = 0;
+ int base_addr = dev ? dev->base_addr : 0;
+ int irq = dev ? dev->irq : 0;
+ u_char status = 0;
+ u_char revision = 0;
+ int i = 0;
+ unsigned int size = 0;
+
+ if (MCA_bus == 0) {
+ return ENODEV;
+ }
/* search through the slots for the 3c523. */
- slot = mca_find_adapter( ELMC_MCA_ID, 0 );
- while( slot != -1 ) {
- status = mca_read_stored_pos( slot, 2 );
+ slot = mca_find_adapter(ELMC_MCA_ID, 0);
+ while (slot != -1) {
+ status = mca_read_stored_pos(slot, 2);
/*
- If we're trying to match a specified irq or IO address,
- we'll reject a match unless it's what we're looking for.
- */
- if( base_addr || irq ) {
+ If we're trying to match a specified irq or IO address,
+ we'll reject a match unless it's what we're looking for.
+ */
+ if (base_addr || irq) {
/* we're looking for a card at a particular place */
- if( irq &&
- irq != irq_table[ (status & ELMC_STATUS_IRQ_SELECT) >> 6]
- ) {
- slot = mca_find_adapter( ELMC_MCA_ID, slot + 1 );
+ if (irq && irq != irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6]) {
+ slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
-
- if( base_addr && base_addr !=
- csr_table[ (status & ELMC_STATUS_CSR_SELECT) >> 1]
- ) {
- slot = mca_find_adapter( ELMC_MCA_ID, slot + 1 );
+ if (base_addr && base_addr != csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1]) {
+ slot = mca_find_adapter(ELMC_MCA_ID, slot + 1);
continue;
}
}
-
/* found what we're looking for... */
break;
}
/* we didn't find any 3c523 in the slots we checked for */
- if( slot == MCA_NOTFOUND ) {
+ if (slot == MCA_NOTFOUND) {
return ((base_addr || irq) ? ENXIO : ENODEV);
}
+ mca_set_adapter_name(slot, "3Com 3c523 Etherlink/MC");
+ mca_set_adapter_procfn(slot, (MCA_ProcFn) elmc_getinfo, dev);
+
+ /* if we get this far, adapter has been found - carry on */
+ printk("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
+
+ /* Now we extract configuration info from the card.
+ The 3c523 provides information in two of the POS registers, but
+ the second one is only needed if we want to tell the card what IRQ
+ to use. I suspect that whoever sets the thing up initially would
+ prefer we don't screw with those things.
+
+ Note that we read the status info when we found the card...
+
+ See 3c523.h for more details.
+ */
+
+ /* revision is stored in the first 4 bits of the revision register */
+ revision = inb(dev->base_addr + ELMC_REVISION) & 0xf;
+
+ /* figure out our irq */
+ dev->irq = irq_table[(status & ELMC_STATUS_IRQ_SELECT) >> 6];
+
+ /* according to docs, we read the interrupt and write it back to
+ the IRQ select register, since the POST might not configure the IRQ
+ properly. */
+ switch (dev->irq) {
+ case 3:
+ mca_write_pos(slot, 3, 0x04);
+ break;
+ case 7:
+ mca_write_pos(slot, 3, 0x02);
+ break;
+ case 9:
+ mca_write_pos(slot, 3, 0x08);
+ break;
+ case 12:
+ mca_write_pos(slot, 3, 0x01);
+ break;
+ }
+
+ /* Our IO address? */
+ dev->base_addr = csr_table[(status & ELMC_STATUS_CSR_SELECT) >> 1];
+
+ request_region(dev->base_addr, ELMC_IO_EXTENT, "3c523");
+
+ dev->priv = (void *) kmalloc(sizeof(struct priv), GFP_KERNEL);
+ if (dev->priv == NULL) {
+ return -ENOMEM;
+ }
+ memset((char *) dev->priv, 0, sizeof(struct priv));
+
+ ((struct priv *) (dev->priv))->slot = slot;
+
+ printk("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
+ dev->base_addr);
+
+ /* Determine if we're using the on-board transceiver (i.e. coax) or
+ an external one. The information is pretty much useless, but I
+ guess it's worth brownie points. */
+ dev->if_port = (status & ELMC_STATUS_DISABLE_THIN);
+
+ /* The 3c523 has a 24K chunk of memory. The first 16K is the
+ shared memory, while the last 8K is for the EtherStart BIOS ROM.
+ Which we don't care much about here. We'll just tell Linux that
+ we're using 16K. MCA won't permit adress space conflicts caused
+ by not mapping the other 8K. */
+ dev->mem_start = phys_to_virt(shm_table[(status & ELMC_STATUS_MEMORY_SELECT) >> 3]);
+
+ /* We're using MCA, so it's a given that the information about memory
+ size is correct. The Crynwr drivers do something like this. */
+
+ elmc_id_reset586(); /* seems like a good idea before checking it... */
+
+ size = 0x4000; /* check for 16K mem */
+ if (!check586(dev, (char *) dev->mem_start, size)) {
+ printk("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
+ dev->mem_start);
+ release_region(dev->base_addr, ELMC_IO_EXTENT);
+ return ENODEV;
+ }
+ dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
+
+ ((struct priv *) (dev->priv))->base = dev->mem_start + size - 0x01000000;
+ alloc586(dev);
+
+ elmc_id_reset586(); /* make sure it doesn't generate spurious ints */
+
+ /* set number of receive-buffs according to memsize */
+ ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
+
+ /* dump all the assorted information */
+ printk("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
+ dev->irq, dev->if_port ? "ex" : "in",
+ virt_to_phys(dev->mem_start),
+ virt_to_phys(dev->mem_end - 1));
+
+ /* The hardware address for the 3c523 is stored in the first six
+ bytes of the IO address. */
+ printk("%s: hardware address ", dev->name);
+ for (i = 0; i < 6; i++) {
+ dev->dev_addr[i] = inb(dev->base_addr + i);
+ printk(" %02x", dev->dev_addr[i]);
+ }
+ printk("\n");
+
+ dev->open = &elmc_open;
+ dev->stop = &elmc_close;
+ dev->get_stats = &elmc_get_stats;
+ dev->hard_start_xmit = &elmc_send_packet;
+ dev->set_multicast_list = &set_multicast_list;
+
+ ether_setup(dev);
- mca_set_adapter_name( slot, "3Com 3c523 Etherlink/MC" );
- mca_set_adapter_procfn( slot, (MCA_ProcFn) elmc_getinfo, dev );
-
- /* if we get this far, adapter has been found - carry on */
- printk("%s: 3c523 adapter found in slot %d\n", dev->name, slot + 1);
-
- /* Now we extract configuration info from the card.
- The 3c523 provides information in two of the POS registers, but
- the second one is only needed if we want to tell the card what IRQ
- to use. I suspect that whoever sets the thing up initially would
- prefer we don't screw with those things.
-
- Note we we read the status info when we found the card...
-
- See 3c523.h for more details.
- */
-
- /* revision is stored in the first 4 bits of the revision register */
- revision = inb( dev->base_addr + ELMC_REVISION ) & 0xf;
-
- /* figure out our irq */
- dev->irq = irq_table[ (status & ELMC_STATUS_IRQ_SELECT) >> 6];
-
- /* according to docs, we read the interrupt and write it back to
- the IRQ select register, since the POST might not configure the IRQ
- properly. */
- switch( dev->irq ) {
- case 3:
- mca_write_pos( slot, 3, 0x04 );
- break;
- case 7:
- mca_write_pos( slot, 3, 0x02 );
- break;
- case 9:
- mca_write_pos( slot, 3, 0x08 );
- break;
- case 12:
- mca_write_pos( slot, 3, 0x01 );
- break;
- }
-
- /* Our IO address? */
- dev->base_addr = csr_table[ (status & ELMC_STATUS_CSR_SELECT) >> 1];
-
- request_region( dev->base_addr, ELMC_IO_EXTENT,"3c523");
-
- dev->priv = (void *) kmalloc(sizeof(struct priv),GFP_KERNEL);
- if (dev->priv == NULL) {
- return -ENOMEM;
- }
- memset((char *) dev->priv,0,sizeof(struct priv));
-
- ((struct priv *) (dev->priv))->slot = slot;
-
- printk("%s: 3Com 3c523 Rev 0x%x at %#lx\n", dev->name, (int) revision,
- dev->base_addr);
-
- /* Determine if we're using the on-board transceiver (i.e. coax) or
- an external one. The information is pretty much useless, but I
- guess it's worth brownie points. */
- dev->if_port = (status & ELMC_STATUS_DISABLE_THIN);
-
- /* The 3c523 has a 24K chunk of memory. The first 16K is the
- shared memory, while the last 8K is for the EtherStart BIOS ROM.
- Which we don't care much about here. We'll just tell Linux that
- we're using 16K. MCA won't permit adress space conflicts caused
- by not mapping the other 8K. */
- dev->mem_start = shm_table[ (status & ELMC_STATUS_MEMORY_SELECT) >> 3];
-
- /* We're using MCA, so it's a given that the information about memory
- size is correct. The Crynwr drivers do something like this. */
-
- elmc_id_reset586(); /* seems like a good idea before checking it... */
-
- size = 0x4000; /* check for 16K mem */
- if(!check586(dev,(char *) dev->mem_start,size)) {
- printk("%s: memprobe, Can't find memory at 0x%lx!\n", dev->name,
- dev->mem_start );
- release_region( dev->base_addr, ELMC_IO_EXTENT );
- return ENODEV;
- }
- dev->mem_end = dev->mem_start + size; /* set mem_end showed by 'ifconfig' */
-
- ((struct priv *) (dev->priv))->base = dev->mem_start + size - 0x01000000;
- alloc586(dev);
-
- elmc_id_reset586(); /* make sure it doesn't generate spurious ints */
-
- /* set number of receive-buffs according to memsize */
- ((struct priv *) dev->priv)->num_recv_buffs = NUM_RECV_BUFFS_16;
-
- /* dump all the assorted information */
- printk("%s: IRQ %d, %sternal xcvr, memory %#lx-%#lx.\n", dev->name,
- dev->irq, dev->if_port ? "ex" : "in", dev->mem_start, dev->mem_end-1);
-
- /* The hardware address for the 3c523 is stored in the first six
- bytes of the IO address. */
- printk( "%s: hardware address ", dev->name );
- for (i = 0; i < 6; i ++ ) {
- dev->dev_addr[i] = inb(dev->base_addr + i);
- printk(" %02x", dev->dev_addr[i]);
- }
- printk( "\n" );
-
- dev->open = &elmc_open;
- dev->stop = &elmc_close;
- dev->get_stats = &elmc_get_stats;
- dev->hard_start_xmit = &elmc_send_packet;
- dev->set_multicast_list = &set_multicast_list;
-
- ether_setup(dev);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 0;
-
- /* note that we haven't actually requested the IRQ from the kernel.
- That gets done in elmc_open(). I'm not sure that's such a good idea,
- but it works, so I'll go with it. */
-
- return 0;
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 0;
+
+ /* note that we haven't actually requested the IRQ from the kernel.
+ That gets done in elmc_open(). I'm not sure that's such a good idea,
+ but it works, so I'll go with it. */
+
+ return 0;
}
/**********************************************
@@ -590,241 +586,237 @@ elmc_probe(struct device *dev)) {
* needs a correct 'allocated' memory
*/
-static
-int
-init586(struct device *dev) {
- void *ptr;
- unsigned long s;
- int i,result=0;
- struct priv *p = (struct priv *) dev->priv;
- volatile struct configure_cmd_struct *cfg_cmd;
- volatile struct iasetup_cmd_struct *ias_cmd;
- volatile struct tdr_cmd_struct *tdr_cmd;
- volatile struct mcsetup_cmd_struct *mc_cmd;
- struct dev_mc_list *dmi=dev->mc_list;
- int num_addrs=dev->mc_count;
-
- ptr = (void *) ((char *)p->scb + sizeof(struct scb_struct));
-
- cfg_cmd = (struct configure_cmd_struct *)ptr; /* configure-command */
- cfg_cmd->cmd_status = 0;
- cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
- cfg_cmd->cmd_link = 0xffff;
-
- cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
- cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */
- cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
- cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
- cfg_cmd->priority = 0x00;
- cfg_cmd->ifs = 0x60;
- cfg_cmd->time_low = 0x00;
- cfg_cmd->time_high = 0xf2;
- cfg_cmd->promisc = 0;
- if(dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
- {
- cfg_cmd->promisc=1;
- dev->flags|=IFF_PROMISC;
- }
- cfg_cmd->carr_coll = 0x00;
-
- p->scb->cbl_offset = make16(cfg_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_id_attn586();
-
- s = jiffies; /* warning: only active with interrupts on !! */
- while(!(cfg_cmd->cmd_status & STAT_COMPL)) {
- if(jiffies-s > 30) break;
- }
-
- if((cfg_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_COMPL|STAT_OK)) {
- printk("%s (elmc): configure command failed: %x\n",dev->name,cfg_cmd->cmd_status);
- return 1;
- }
-
- /*
- * individual address setup
- */
- ias_cmd = (struct iasetup_cmd_struct *)ptr;
-
- ias_cmd->cmd_status = 0;
- ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
- ias_cmd->cmd_link = 0xffff;
-
- memcpy((char *)&ias_cmd->iaddr,(char *) dev->dev_addr,ETH_ALEN);
-
- p->scb->cbl_offset = make16(ias_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_id_attn586();
-
- s = jiffies;
- while(!(ias_cmd->cmd_status & STAT_COMPL)) {
- if(jiffies-s > 30) break;
- }
-
- if((ias_cmd->cmd_status & (STAT_OK|STAT_COMPL)) != (STAT_OK|STAT_COMPL)) {
- printk("%s (elmc): individual address setup command failed: %04x\n",dev->name,ias_cmd->cmd_status);
- return 1;
- }
-
- /*
- * TDR, wire check .. e.g. no resistor e.t.c
- */
- tdr_cmd = (struct tdr_cmd_struct *)ptr;
-
- tdr_cmd->cmd_status = 0;
- tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
- tdr_cmd->cmd_link = 0xffff;
- tdr_cmd->status = 0;
-
- p->scb->cbl_offset = make16(tdr_cmd);
-
- p->scb->cmd = CUC_START; /* cmd.-unit start */
- elmc_attn586();
-
- s = jiffies;
- while(!(tdr_cmd->cmd_status & STAT_COMPL)) {
- if(jiffies - s > 30) {
- printk("%s: %d Problems while running the TDR.\n",dev->name,__LINE__);
- result = 1;
- break;
- }
- }
-
- if(!result) {
- DELAY(2); /* wait for result */
- result = tdr_cmd->status;
-
- p->scb->cmd = p->scb->status & STAT_MASK;
- elmc_id_attn586(); /* ack the interrupts */
-
- if(result & TDR_LNK_OK) {
- /* empty */
- } else if(result & TDR_XCVR_PRB) {
- printk("%s: TDR: Transceiver problem!\n",dev->name);
- } else if(result & TDR_ET_OPN) {
- printk("%s: TDR: No correct termination %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
- } else if(result & TDR_ET_SRT) {
- if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
- printk("%s: TDR: Detected a short circuit %d clocks away.\n",dev->name,result & TDR_TIMEMASK);
- } else {
- printk("%s: TDR: Unknown status %04x\n",dev->name,result);
- }
- }
-
- /*
- * ack interrupts
- */
- p->scb->cmd = p->scb->status & STAT_MASK;
- elmc_id_attn586();
-
- /*
- * alloc nop/xmit-cmds
- */
+static int init586(struct device *dev)
+{
+ void *ptr;
+ unsigned long s;
+ int i, result = 0;
+ struct priv *p = (struct priv *) dev->priv;
+ volatile struct configure_cmd_struct *cfg_cmd;
+ volatile struct iasetup_cmd_struct *ias_cmd;
+ volatile struct tdr_cmd_struct *tdr_cmd;
+ volatile struct mcsetup_cmd_struct *mc_cmd;
+ struct dev_mc_list *dmi = dev->mc_list;
+ int num_addrs = dev->mc_count;
+
+ ptr = (void *) ((char *) p->scb + sizeof(struct scb_struct));
+
+ cfg_cmd = (struct configure_cmd_struct *) ptr; /* configure-command */
+ cfg_cmd->cmd_status = 0;
+ cfg_cmd->cmd_cmd = CMD_CONFIGURE | CMD_LAST;
+ cfg_cmd->cmd_link = 0xffff;
+
+ cfg_cmd->byte_cnt = 0x0a; /* number of cfg bytes */
+ cfg_cmd->fifo = 0x08; /* fifo-limit (8=tx:32/rx:64) */
+ cfg_cmd->sav_bf = 0x40; /* hold or discard bad recv frames (bit 7) */
+ cfg_cmd->adr_len = 0x2e; /* addr_len |!src_insert |pre-len |loopback */
+ cfg_cmd->priority = 0x00;
+ cfg_cmd->ifs = 0x60;
+ cfg_cmd->time_low = 0x00;
+ cfg_cmd->time_high = 0xf2;
+ cfg_cmd->promisc = 0;
+ if (dev->flags & (IFF_ALLMULTI | IFF_PROMISC)) {
+ cfg_cmd->promisc = 1;
+ dev->flags |= IFF_PROMISC;
+ }
+ cfg_cmd->carr_coll = 0x00;
+
+ p->scb->cbl_offset = make16(cfg_cmd);
+
+ p->scb->cmd = CUC_START; /* cmd.-unit start */
+ elmc_id_attn586();
+
+ s = jiffies; /* warning: only active with interrupts on !! */
+ while (!(cfg_cmd->cmd_status & STAT_COMPL)) {
+ if (jiffies - s > 30)
+ break;
+ }
+
+ if ((cfg_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_COMPL | STAT_OK)) {
+ printk("%s (elmc): configure command failed: %x\n", dev->name, cfg_cmd->cmd_status);
+ return 1;
+ }
+ /*
+ * individual address setup
+ */
+ ias_cmd = (struct iasetup_cmd_struct *) ptr;
+
+ ias_cmd->cmd_status = 0;
+ ias_cmd->cmd_cmd = CMD_IASETUP | CMD_LAST;
+ ias_cmd->cmd_link = 0xffff;
+
+ memcpy((char *) &ias_cmd->iaddr, (char *) dev->dev_addr, ETH_ALEN);
+
+ p->scb->cbl_offset = make16(ias_cmd);
+
+ p->scb->cmd = CUC_START; /* cmd.-unit start */
+ elmc_id_attn586();
+
+ s = jiffies;
+ while (!(ias_cmd->cmd_status & STAT_COMPL)) {
+ if (jiffies - s > 30)
+ break;
+ }
+
+ if ((ias_cmd->cmd_status & (STAT_OK | STAT_COMPL)) != (STAT_OK | STAT_COMPL)) {
+ printk("%s (elmc): individual address setup command failed: %04x\n", dev->name, ias_cmd->cmd_status);
+ return 1;
+ }
+ /*
+ * TDR, wire check .. e.g. no resistor e.t.c
+ */
+ tdr_cmd = (struct tdr_cmd_struct *) ptr;
+
+ tdr_cmd->cmd_status = 0;
+ tdr_cmd->cmd_cmd = CMD_TDR | CMD_LAST;
+ tdr_cmd->cmd_link = 0xffff;
+ tdr_cmd->status = 0;
+
+ p->scb->cbl_offset = make16(tdr_cmd);
+
+ p->scb->cmd = CUC_START; /* cmd.-unit start */
+ elmc_attn586();
+
+ s = jiffies;
+ while (!(tdr_cmd->cmd_status & STAT_COMPL)) {
+ if (jiffies - s > 30) {
+ printk("%s: %d Problems while running the TDR.\n", dev->name, __LINE__);
+ result = 1;
+ break;
+ }
+ }
+
+ if (!result) {
+ DELAY(2); /* wait for result */
+ result = tdr_cmd->status;
+
+ p->scb->cmd = p->scb->status & STAT_MASK;
+ elmc_id_attn586(); /* ack the interrupts */
+
+ if (result & TDR_LNK_OK) {
+ /* empty */
+ } else if (result & TDR_XCVR_PRB) {
+ printk("%s: TDR: Transceiver problem!\n", dev->name);
+ } else if (result & TDR_ET_OPN) {
+ printk("%s: TDR: No correct termination %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
+ } else if (result & TDR_ET_SRT) {
+ if (result & TDR_TIMEMASK) /* time == 0 -> strange :-) */
+ printk("%s: TDR: Detected a short circuit %d clocks away.\n", dev->name, result & TDR_TIMEMASK);
+ } else {
+ printk("%s: TDR: Unknown status %04x\n", dev->name, result);
+ }
+ }
+ /*
+ * ack interrupts
+ */
+ p->scb->cmd = p->scb->status & STAT_MASK;
+ elmc_id_attn586();
+
+ /*
+ * alloc nop/xmit-cmds
+ */
#if (NUM_XMIT_BUFFS == 1)
- for(i=0;i<2;i++) {
- p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- }
- p->xmit_cmds[0] = (struct transmit_cmd_struct *)ptr; /* transmit cmd/buff 0 */
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
+ for (i = 0; i < 2; i++) {
+ p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
+ p->nop_cmds[i]->cmd_cmd = CMD_NOP;
+ p->nop_cmds[i]->cmd_status = 0;
+ p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
+ ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
+ }
+ p->xmit_cmds[0] = (struct transmit_cmd_struct *) ptr; /* transmit cmd/buff 0 */
+ ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
#else
- for(i=0;i<NUM_XMIT_BUFFS;i++) {
- p->nop_cmds[i] = (struct nop_cmd_struct *)ptr;
- p->nop_cmds[i]->cmd_cmd = CMD_NOP;
- p->nop_cmds[i]->cmd_status = 0;
- p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
- ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
- p->xmit_cmds[i] = (struct transmit_cmd_struct *)ptr; /*transmit cmd/buff 0*/
- ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
- }
+ for (i = 0; i < NUM_XMIT_BUFFS; i++) {
+ p->nop_cmds[i] = (struct nop_cmd_struct *) ptr;
+ p->nop_cmds[i]->cmd_cmd = CMD_NOP;
+ p->nop_cmds[i]->cmd_status = 0;
+ p->nop_cmds[i]->cmd_link = make16((p->nop_cmds[i]));
+ ptr = (char *) ptr + sizeof(struct nop_cmd_struct);
+ p->xmit_cmds[i] = (struct transmit_cmd_struct *) ptr; /*transmit cmd/buff 0 */
+ ptr = (char *) ptr + sizeof(struct transmit_cmd_struct);
+ }
#endif
- ptr = alloc_rfa(dev,(void *)ptr); /* init receive-frame-area */
-
- /*
- * Multicast setup
- */
-
- if(dev->mc_count) {
- /* I don't understand this: do we really need memory after the init? */
- int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
- if(len <= 0) {
- printk("%s: Ooooops, no memory for MC-Setup!\n",dev->name);
- } else {
- if(len < num_addrs) {
- num_addrs = len;
- printk("%s: Sorry, can only apply %d MC-Address(es).\n",
- dev->name, num_addrs);
- }
- mc_cmd = (struct mcsetup_cmd_struct *) ptr;
- mc_cmd->cmd_status = 0;
- mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
- mc_cmd->cmd_link = 0xffff;
- mc_cmd->mc_cnt = num_addrs * 6;
- for(i=0;i<num_addrs;i++) {
- memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr,6);
- dmi=dmi->next;
- }
- p->scb->cbl_offset = make16(mc_cmd);
- p->scb->cmd = CUC_START;
- elmc_id_attn586();
- s = jiffies;
- while(!(mc_cmd->cmd_status & STAT_COMPL)) {
- if(jiffies - s > 30)
- break;
- }
- if(!(mc_cmd->cmd_status & STAT_COMPL)) {
- printk("%s: Can't apply multicast-address-list.\n",dev->name);
- }
- }
- }
-
- /*
- * alloc xmit-buffs / init xmit_cmds
- */
- for(i=0;i<NUM_XMIT_BUFFS;i++) {
- p->xmit_cbuffs[i] = (char *)ptr; /* char-buffs */
- ptr = (char *) ptr + XMIT_BUFF_SIZE;
- p->xmit_buffs[i] = (struct tbd_struct *)ptr; /* TBD */
- ptr = (char *) ptr + sizeof(struct tbd_struct);
- if((void *)ptr > (void *)p->iscp) {
- printk("%s: not enough shared-mem for your configuration!\n",dev->name);
- return 1;
- }
- memset((char *)(p->xmit_cmds[i]) ,0, sizeof(struct transmit_cmd_struct));
- memset((char *)(p->xmit_buffs[i]),0, sizeof(struct tbd_struct));
- p->xmit_cmds[i]->cmd_status = STAT_COMPL;
- p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
- p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
- p->xmit_buffs[i]->next = 0xffff;
- p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
- }
-
- p->xmit_count = 0;
- p->xmit_last = 0;
+ ptr = alloc_rfa(dev, (void *) ptr); /* init receive-frame-area */
+
+ /*
+ * Multicast setup
+ */
+
+ if (dev->mc_count) {
+ /* I don't understand this: do we really need memory after the init? */
+ int len = ((char *) p->iscp - (char *) ptr - 8) / 6;
+ if (len <= 0) {
+ printk("%s: Ooooops, no memory for MC-Setup!\n", dev->name);
+ } else {
+ if (len < num_addrs) {
+ num_addrs = len;
+ printk("%s: Sorry, can only apply %d MC-Address(es).\n",
+ dev->name, num_addrs);
+ }
+ mc_cmd = (struct mcsetup_cmd_struct *) ptr;
+ mc_cmd->cmd_status = 0;
+ mc_cmd->cmd_cmd = CMD_MCSETUP | CMD_LAST;
+ mc_cmd->cmd_link = 0xffff;
+ mc_cmd->mc_cnt = num_addrs * 6;
+ for (i = 0; i < num_addrs; i++) {
+ memcpy((char *) mc_cmd->mc_list[i], dmi->dmi_addr, 6);
+ dmi = dmi->next;
+ }
+ p->scb->cbl_offset = make16(mc_cmd);
+ p->scb->cmd = CUC_START;
+ elmc_id_attn586();
+ s = jiffies;
+ while (!(mc_cmd->cmd_status & STAT_COMPL)) {
+ if (jiffies - s > 30)
+ break;
+ }
+ if (!(mc_cmd->cmd_status & STAT_COMPL)) {
+ printk("%s: Can't apply multicast-address-list.\n", dev->name);
+ }
+ }
+ }
+ /*
+ * alloc xmit-buffs / init xmit_cmds
+ */
+ for (i = 0; i < NUM_XMIT_BUFFS; i++) {
+ p->xmit_cbuffs[i] = (char *) ptr; /* char-buffs */
+ ptr = (char *) ptr + XMIT_BUFF_SIZE;
+ p->xmit_buffs[i] = (struct tbd_struct *) ptr; /* TBD */
+ ptr = (char *) ptr + sizeof(struct tbd_struct);
+ if ((void *) ptr > (void *) p->iscp) {
+ printk("%s: not enough shared-mem for your configuration!\n", dev->name);
+ return 1;
+ }
+ memset((char *) (p->xmit_cmds[i]), 0, sizeof(struct transmit_cmd_struct));
+ memset((char *) (p->xmit_buffs[i]), 0, sizeof(struct tbd_struct));
+ p->xmit_cmds[i]->cmd_status = STAT_COMPL;
+ p->xmit_cmds[i]->cmd_cmd = CMD_XMIT | CMD_INT;
+ p->xmit_cmds[i]->tbd_offset = make16((p->xmit_buffs[i]));
+ p->xmit_buffs[i]->next = 0xffff;
+ p->xmit_buffs[i]->buffer = make24((p->xmit_cbuffs[i]));
+ }
+
+ p->xmit_count = 0;
+ p->xmit_last = 0;
#ifndef NO_NOPCOMMANDS
- p->nop_point = 0;
+ p->nop_point = 0;
#endif
- /*
- * 'start transmitter' (nop-loop)
- */
+ /*
+ * 'start transmitter' (nop-loop)
+ */
#ifndef NO_NOPCOMMANDS
- p->scb->cbl_offset = make16(p->nop_cmds[0]);
- p->scb->cmd = CUC_START;
- elmc_id_attn586();
- WAIT_4_SCB_CMD();
+ p->scb->cbl_offset = make16(p->nop_cmds[0]);
+ p->scb->cmd = CUC_START;
+ elmc_id_attn586();
+ WAIT_4_SCB_CMD();
#else
- p->xmit_cmds[0]->cmd_link = 0xffff;
- p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
+ p->xmit_cmds[0]->cmd_link = 0xffff;
+ p->xmit_cmds[0]->cmd_cmd = CMD_XMIT | CMD_LAST | CMD_INT;
#endif
- return 0;
+ return 0;
}
/******************************************************
@@ -832,44 +824,43 @@ init586(struct device *dev) {
* It sets up the Receive Frame Area (RFA).
*/
-static
-void*
-alloc_rfa(struct device *dev,void *ptr) {
- volatile struct rfd_struct *rfd = (struct rfd_struct *)ptr;
- volatile struct rbd_struct *rbd;
- int i;
- struct priv *p = (struct priv *) dev->priv;
+static void *alloc_rfa(struct device *dev, void *ptr)
+{
+ volatile struct rfd_struct *rfd = (struct rfd_struct *) ptr;
+ volatile struct rbd_struct *rbd;
+ int i;
+ struct priv *p = (struct priv *) dev->priv;
- memset((char *) rfd,0,sizeof(struct rfd_struct)*p->num_recv_buffs);
- p->rfd_first = rfd;
+ memset((char *) rfd, 0, sizeof(struct rfd_struct) * p->num_recv_buffs);
+ p->rfd_first = rfd;
- for(i = 0; i < p->num_recv_buffs; i++) {
- rfd[i].next = make16(rfd + (i+1) % p->num_recv_buffs);
- }
- rfd[p->num_recv_buffs-1].last = RFD_SUSP; /* RU suspend */
+ for (i = 0; i < p->num_recv_buffs; i++) {
+ rfd[i].next = make16(rfd + (i + 1) % p->num_recv_buffs);
+ }
+ rfd[p->num_recv_buffs - 1].last = RFD_SUSP; /* RU suspend */
- ptr = (void *) (rfd + p->num_recv_buffs);
+ ptr = (void *) (rfd + p->num_recv_buffs);
- rbd = (struct rbd_struct *) ptr;
- ptr = (void *) (rbd + p->num_recv_buffs);
+ rbd = (struct rbd_struct *) ptr;
+ ptr = (void *) (rbd + p->num_recv_buffs);
- /* clr descriptors */
- memset((char *) rbd,0,sizeof(struct rbd_struct)*p->num_recv_buffs);
+ /* clr descriptors */
+ memset((char *) rbd, 0, sizeof(struct rbd_struct) * p->num_recv_buffs);
- for(i=0;i<p->num_recv_buffs;i++) {
- rbd[i].next = make16((rbd + (i+1) % p->num_recv_buffs));
- rbd[i].size = RECV_BUFF_SIZE;
- rbd[i].buffer = make24(ptr);
- ptr = (char *) ptr + RECV_BUFF_SIZE;
- }
+ for (i = 0; i < p->num_recv_buffs; i++) {
+ rbd[i].next = make16((rbd + (i + 1) % p->num_recv_buffs));
+ rbd[i].size = RECV_BUFF_SIZE;
+ rbd[i].buffer = make24(ptr);
+ ptr = (char *) ptr + RECV_BUFF_SIZE;
+ }
- p->rfd_top = p->rfd_first;
- p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
+ p->rfd_top = p->rfd_first;
+ p->rfd_last = p->rfd_first + p->num_recv_buffs - 1;
- p->scb->rfa_offset = make16(p->rfd_first);
- p->rfd_first->rbd_offset = make16(rbd);
+ p->scb->rfa_offset = make16(p->rfd_first);
+ p->rfd_first->rbd_offset = make16(rbd);
- return ptr;
+ return ptr;
}
@@ -877,152 +868,145 @@ alloc_rfa(struct device *dev,void *ptr) {
* Interrupt Handler ...
*/
-static
-void
-elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr) {
- struct device *dev = (struct device *) dev_id;
- unsigned short stat;
- struct priv *p;
-
- if (dev == NULL) {
- printk ("elmc-interrupt: irq %d for unknown device.\n",(int) -(((struct pt_regs *)reg_ptr)->orig_eax+2));
- return;
- } else if( !dev->start ) {
- /* The 3c523 has this habit of generating interrupts during the
- reset. I'm not sure if the ni52 has this same problem, but it's
- really annoying if we haven't finished initializing it. I was
- hoping all the elmc_id_* commands would disable this, but I
- might have missed a few. */
-
- elmc_id_attn586(); /* ack inter. and disable any more */
- return;
- } else if( !(ELMC_CTRL_INT & inb( dev->base_addr+ELMC_CTRL )) ) {
- /* wasn't this device */
- return;
- }
-
- /* reading ELMC_CTRL also clears the INT bit. */
-
- p = (struct priv *) dev->priv;
-
- dev->interrupt = 1;
-
- while((stat=p->scb->status & STAT_MASK)) {
- p->scb->cmd = stat;
- elmc_attn586(); /* ack inter. */
-
- if(stat & STAT_CX) {
- /* command with I-bit set complete */
- elmc_xmt_int(dev);
- }
-
- if(stat & STAT_FR) {
- /* received a frame */
- elmc_rcv_int(dev);
- }
+static void elmc_interrupt(int irq, void *dev_id, struct pt_regs *reg_ptr)
+{
+ struct device *dev = (struct device *) dev_id;
+ unsigned short stat;
+ struct priv *p;
+
+ if (dev == NULL) {
+ printk("elmc-interrupt: irq %d for unknown device.\n", (int) -(((struct pt_regs *) reg_ptr)->orig_eax + 2));
+ return;
+ } else if (!dev->start) {
+ /* The 3c523 has this habit of generating interrupts during the
+ reset. I'm not sure if the ni52 has this same problem, but it's
+ really annoying if we haven't finished initializing it. I was
+ hoping all the elmc_id_* commands would disable this, but I
+ might have missed a few. */
+
+ elmc_id_attn586(); /* ack inter. and disable any more */
+ return;
+ } else if (!(ELMC_CTRL_INT & inb(dev->base_addr + ELMC_CTRL))) {
+ /* wasn't this device */
+ return;
+ }
+ /* reading ELMC_CTRL also clears the INT bit. */
+
+ p = (struct priv *) dev->priv;
+ dev->interrupt = 1;
+
+ while ((stat = p->scb->status & STAT_MASK))
+ {
+ p->scb->cmd = stat;
+ elmc_attn586(); /* ack inter. */
+
+ if (stat & STAT_CX) {
+ /* command with I-bit set complete */
+ elmc_xmt_int(dev);
+ }
+ if (stat & STAT_FR) {
+ /* received a frame */
+ elmc_rcv_int(dev);
+ }
#ifndef NO_NOPCOMMANDS
- if(stat & STAT_CNA) {
- /* CU went 'not ready' */
- if(dev->start) {
- printk("%s: oops! CU has left active state. stat: %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
- }
- }
+ if (stat & STAT_CNA) {
+ /* CU went 'not ready' */
+ if (dev->start) {
+ printk("%s: oops! CU has left active state. stat: %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
+ }
+ }
#endif
- if(stat & STAT_RNR) {
- /* RU went 'not ready' */
-
- if(p->scb->status & RU_SUSPEND) {
- /* special case: RU_SUSPEND */
-
- WAIT_4_SCB_CMD();
- p->scb->cmd = RUC_RESUME;
- elmc_attn586();
- } else {
- printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n",dev->name,(int) stat,(int) p->scb->status);
- elmc_rnr_int(dev);
- }
- }
- WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
- if(p->scb->cmd) { /* timed out? */
- break;
- }
- }
-
- dev->interrupt = 0;
+ if (stat & STAT_RNR) {
+ /* RU went 'not ready' */
+
+ if (p->scb->status & RU_SUSPEND) {
+ /* special case: RU_SUSPEND */
+
+ WAIT_4_SCB_CMD();
+ p->scb->cmd = RUC_RESUME;
+ elmc_attn586();
+ } else {
+ printk("%s: Receiver-Unit went 'NOT READY': %04x/%04x.\n", dev->name, (int) stat, (int) p->scb->status);
+ elmc_rnr_int(dev);
+ }
+ }
+ WAIT_4_SCB_CMD(); /* wait for ack. (elmc_xmt_int can be faster than ack!!) */
+ if (p->scb->cmd) { /* timed out? */
+ break;
+ }
+ }
+
+ dev->interrupt = 0;
}
/*******************************************************
* receive-interrupt
*/
-static
-void
-elmc_rcv_int(struct device *dev) {
- int status;
- unsigned short totlen;
- struct sk_buff *skb;
- struct rbd_struct *rbd;
- struct priv *p = (struct priv *) dev->priv;
-
- for(;(status = p->rfd_top->status) & STAT_COMPL;) {
- rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
-
- if(status & STAT_OK) /* frame received without error? */
- {
- if( (totlen = rbd->status) & RBD_LAST) /* the first and the last buffer? */
- {
- totlen &= RBD_MASK; /* length of this frame */
- rbd->status = 0;
- skb = (struct sk_buff *) dev_alloc_skb(totlen+2);
- if(skb != NULL) {
- skb->dev = dev;
- skb_reserve(skb,2); /* 16 byte alignment */
- memcpy(skb_put(skb,totlen),(char *) p->base+(unsigned long) rbd->buffer, totlen);
- skb->protocol=eth_type_trans(skb,dev);
- netif_rx(skb);
- p->stats.rx_packets++;
- p->stats.rx_bytes+=totlen;
- } else {
- p->stats.rx_dropped++;
- }
- } else {
- printk("%s: received oversized frame.\n",dev->name);
- p->stats.rx_dropped++;
- }
- } else /* frame !(ok), only with 'save-bad-frames' */ {
- printk("%s: oops! rfd-error-status: %04x\n",dev->name,status);
- p->stats.rx_errors++;
- }
- p->rfd_top->status = 0;
- p->rfd_top->last = RFD_SUSP;
- p->rfd_last->last = 0; /* delete RU_SUSP */
- p->rfd_last = p->rfd_top;
- p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
- }
+static void elmc_rcv_int(struct device *dev)
+{
+ int status;
+ unsigned short totlen;
+ struct sk_buff *skb;
+ struct rbd_struct *rbd;
+ struct priv *p = (struct priv *) dev->priv;
+
+ for (; (status = p->rfd_top->status) & STAT_COMPL;) {
+ rbd = (struct rbd_struct *) make32(p->rfd_top->rbd_offset);
+
+ if (status & STAT_OK) { /* frame received without error? */
+ if ((totlen = rbd->status) & RBD_LAST) { /* the first and the last buffer? */
+ totlen &= RBD_MASK; /* length of this frame */
+ rbd->status = 0;
+ skb = (struct sk_buff *) dev_alloc_skb(totlen + 2);
+ if (skb != NULL) {
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 byte alignment */
+ memcpy(skb_put(skb, totlen), (char *) p->base + (unsigned long) rbd->buffer, totlen);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ p->stats.rx_packets++;
+ p->stats.rx_bytes += totlen;
+ } else {
+ p->stats.rx_dropped++;
+ }
+ } else {
+ printk("%s: received oversized frame.\n", dev->name);
+ p->stats.rx_dropped++;
+ }
+ } else { /* frame !(ok), only with 'save-bad-frames' */
+ printk("%s: oops! rfd-error-status: %04x\n", dev->name, status);
+ p->stats.rx_errors++;
+ }
+ p->rfd_top->status = 0;
+ p->rfd_top->last = RFD_SUSP;
+ p->rfd_last->last = 0; /* delete RU_SUSP */
+ p->rfd_last = p->rfd_top;
+ p->rfd_top = (struct rfd_struct *) make32(p->rfd_top->next); /* step to next RFD */
+ }
}
/**********************************************************
* handle 'Receiver went not ready'.
*/
-static
-void
-elmc_rnr_int(struct device *dev) {
- struct priv *p = (struct priv *) dev->priv;
+static void elmc_rnr_int(struct device *dev)
+{
+ struct priv *p = (struct priv *) dev->priv;
- p->stats.rx_errors++;
+ p->stats.rx_errors++;
- WAIT_4_SCB_CMD(); /* wait for the last cmd */
- p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
- elmc_attn586();
- WAIT_4_SCB_CMD(); /* wait for accept cmd. */
+ WAIT_4_SCB_CMD(); /* wait for the last cmd */
+ p->scb->cmd = RUC_ABORT; /* usually the RU is in the 'no resource'-state .. abort it now. */
+ elmc_attn586();
+ WAIT_4_SCB_CMD(); /* wait for accept cmd. */
- alloc_rfa(dev,(char *)p->rfd_first);
- startrecv586(dev); /* restart RU */
+ alloc_rfa(dev, (char *) p->rfd_first);
+ startrecv586(dev); /* restart RU */
- printk("%s: Receive-Unit restarted. Status: %04x\n",dev->name,p->scb->status);
+ printk("%s: Receive-Unit restarted. Status: %04x\n", dev->name, p->scb->status);
}
@@ -1030,285 +1014,269 @@ elmc_rnr_int(struct device *dev) {
* handle xmit - interrupt
*/
-static
-void
-elmc_xmt_int(struct device *dev) {
- int status;
- struct priv *p = (struct priv *) dev->priv;
-
- status = p->xmit_cmds[p->xmit_last]->cmd_status;
- if(!(status & STAT_COMPL)) {
- printk("%s: strange .. xmit-int without a 'COMPLETE'\n",dev->name);
- }
-
- if(status & STAT_OK) {
- p->stats.tx_packets++;
- p->stats.collisions += (status & TCMD_MAXCOLLMASK);
- } else {
- p->stats.tx_errors++;
- if(status & TCMD_LATECOLL) {
- printk("%s: late collision detected.\n",dev->name);
- p->stats.collisions++;
- } else if(status & TCMD_NOCARRIER) {
- p->stats.tx_carrier_errors++;
- printk("%s: no carrier detected.\n",dev->name);
- } else if(status & TCMD_LOSTCTS) {
- printk("%s: loss of CTS detected.\n",dev->name);
- } else if(status & TCMD_UNDERRUN) {
- p->stats.tx_fifo_errors++;
- printk("%s: DMA underrun detected.\n",dev->name);
- } else if(status & TCMD_MAXCOLL) {
- printk("%s: Max. collisions exceeded.\n",dev->name);
- p->stats.collisions += 16;
- }
- }
+static void elmc_xmt_int(struct device *dev)
+{
+ int status;
+ struct priv *p = (struct priv *) dev->priv;
+
+ status = p->xmit_cmds[p->xmit_last]->cmd_status;
+ if (!(status & STAT_COMPL)) {
+ printk("%s: strange .. xmit-int without a 'COMPLETE'\n", dev->name);
+ }
+ if (status & STAT_OK) {
+ p->stats.tx_packets++;
+ p->stats.collisions += (status & TCMD_MAXCOLLMASK);
+ } else {
+ p->stats.tx_errors++;
+ if (status & TCMD_LATECOLL) {
+ printk("%s: late collision detected.\n", dev->name);
+ p->stats.collisions++;
+ } else if (status & TCMD_NOCARRIER) {
+ p->stats.tx_carrier_errors++;
+ printk("%s: no carrier detected.\n", dev->name);
+ } else if (status & TCMD_LOSTCTS) {
+ printk("%s: loss of CTS detected.\n", dev->name);
+ } else if (status & TCMD_UNDERRUN) {
+ p->stats.tx_fifo_errors++;
+ printk("%s: DMA underrun detected.\n", dev->name);
+ } else if (status & TCMD_MAXCOLL) {
+ printk("%s: Max. collisions exceeded.\n", dev->name);
+ p->stats.collisions += 16;
+ }
+ }
#if (NUM_XMIT_BUFFS != 1)
- if( (++p->xmit_last) == NUM_XMIT_BUFFS) {
- p->xmit_last = 0;
- }
+ if ((++p->xmit_last) == NUM_XMIT_BUFFS) {
+ p->xmit_last = 0;
+ }
#endif
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
}
/***********************************************************
* (re)start the receiver
*/
-static
-void
-startrecv586(struct device *dev)
+static void startrecv586(struct device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
+ struct priv *p = (struct priv *) dev->priv;
- p->scb->rfa_offset = make16(p->rfd_first);
- p->scb->cmd = RUC_START;
- elmc_attn586(); /* start cmd. */
- WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */
+ p->scb->rfa_offset = make16(p->rfd_first);
+ p->scb->cmd = RUC_START;
+ elmc_attn586(); /* start cmd. */
+ WAIT_4_SCB_CMD(); /* wait for accept cmd. (no timeout!!) */
}
/******************************************************
* send frame
*/
-static
-int
-elmc_send_packet(struct sk_buff *skb, struct device *dev)
+static int elmc_send_packet(struct sk_buff *skb, struct device *dev)
{
- int len;
+ int len;
#ifndef NO_NOPCOMMANDS
- int next_nop;
+ int next_nop;
#endif
- struct priv *p = (struct priv *) dev->priv;
-
- if(dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 5) {
- return 1;
- }
+ struct priv *p = (struct priv *) dev->priv;
- /* COMMAND-UNIT active? */
- if(p->scb->status & CU_ACTIVE) {
- dev->tbusy = 0;
+ if (dev->tbusy) {
+ int tickssofar = jiffies - dev->trans_start;
+ if (tickssofar < 5) {
+ return 1;
+ }
+ /* COMMAND-UNIT active? */
+ if (p->scb->status & CU_ACTIVE) {
+ dev->tbusy = 0;
#ifdef DEBUG
- printk("%s: strange ... timeout with CU active?!?\n",dev->name);
- printk("%s: X0: %04x N0: %04x N1: %04x %d\n",dev->name,(int)p->xmit_cmds[0]->cmd_status,(int)p->nop_cmds[0]->cmd_status,(int)p->nop_cmds[1]->cmd_status,(int)p->nop_point);
+ printk("%s: strange ... timeout with CU active?!?\n", dev->name);
+ printk("%s: X0: %04x N0: %04x N1: %04x %d\n", dev->name, (int) p->xmit_cmds[0]->cmd_status, (int) p->nop_cmds[0]->cmd_status, (int) p->nop_cmds[1]->cmd_status, (int) p->nop_point);
#endif
- p->scb->cmd = CUC_ABORT;
- elmc_attn586();
- WAIT_4_SCB_CMD();
- p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
- p->scb->cmd = CUC_START;
- elmc_attn586();
- WAIT_4_SCB_CMD();
- dev->trans_start = jiffies;
- return 0;
- } else {
+ p->scb->cmd = CUC_ABORT;
+ elmc_attn586();
+ WAIT_4_SCB_CMD();
+ p->scb->cbl_offset = make16(p->nop_cmds[p->nop_point]);
+ p->scb->cmd = CUC_START;
+ elmc_attn586();
+ WAIT_4_SCB_CMD();
+ dev->trans_start = jiffies;
+ return 0;
+ } else {
#ifdef DEBUG
- printk("%s: xmitter timed out, try to restart! stat: %04x\n",dev->name,p->scb->status);
- printk("%s: command-stats: %04x %04x\n",dev->name,p->xmit_cmds[0]->cmd_status,p->xmit_cmds[1]->cmd_status);
+ printk("%s: xmitter timed out, try to restart! stat: %04x\n", dev->name, p->scb->status);
+ printk("%s: command-stats: %04x %04x\n", dev->name, p->xmit_cmds[0]->cmd_status, p->xmit_cmds[1]->cmd_status);
#endif
- elmc_close(dev);
- elmc_open(dev);
- }
- dev->trans_start = jiffies;
- return 0;
- }
-
- if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- } else {
- memcpy((char *)p->xmit_cbuffs[p->xmit_count],(char *)(skb->data),skb->len);
- len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
+ elmc_close(dev);
+ elmc_open(dev);
+ }
+ dev->trans_start = jiffies;
+ return 0;
+ }
+ if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
+ printk("%s: Transmitter access conflict.\n", dev->name);
+ } else {
+ memcpy((char *) p->xmit_cbuffs[p->xmit_count], (char *) (skb->data), skb->len);
+ len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
#if (NUM_XMIT_BUFFS == 1)
-# ifdef NO_NOPCOMMANDS
- p->xmit_buffs[0]->size = TBD_LAST | len;
- for(i=0;i<16;i++) {
- p->scb->cbl_offset = make16(p->xmit_cmds[0]);
- p->scb->cmd = CUC_START;
- p->xmit_cmds[0]->cmd_status = 0;
-
- elmc_attn586();
- dev->trans_start = jiffies;
- if(!i) {
- dev_kfree_skb(skb);
- }
- WAIT_4_SCB_CMD();
- if( (p->scb->status & CU_ACTIVE)) /* test it, because CU sometimes doesn't start immediately */
- {
- break;
- }
- if(p->xmit_cmds[0]->cmd_status) {
- break;
- }
- if(i==15) {
- printk("%s: Can't start transmit-command.\n",dev->name);
- }
- }
-# else
- next_nop = (p->nop_point + 1) & 0x1;
- p->xmit_buffs[0]->size = TBD_LAST | len;
-
- p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
- dev->trans_start = jiffies;
- p->nop_point = next_nop;
- dev_kfree_skb(skb);
-# endif
+#ifdef NO_NOPCOMMANDS
+ p->xmit_buffs[0]->size = TBD_LAST | len;
+ for (i = 0; i < 16; i++) {
+ p->scb->cbl_offset = make16(p->xmit_cmds[0]);
+ p->scb->cmd = CUC_START;
+ p->xmit_cmds[0]->cmd_status = 0;
+
+ elmc_attn586();
+ dev->trans_start = jiffies;
+ if (!i) {
+ dev_kfree_skb(skb);
+ }
+ WAIT_4_SCB_CMD();
+ if ((p->scb->status & CU_ACTIVE)) { /* test it, because CU sometimes doesn't start immediately */
+ break;
+ }
+ if (p->xmit_cmds[0]->cmd_status) {
+ break;
+ }
+ if (i == 15) {
+ printk("%s: Can't start transmit-command.\n", dev->name);
+ }
+ }
#else
- p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
- if( (next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS ) {
- next_nop = 0;
- }
-
- p->xmit_cmds[p->xmit_count]->cmd_status = 0;
- p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
- = make16((p->nop_cmds[next_nop]));
- p->nop_cmds[next_nop]->cmd_status = 0;
-
- p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
- dev->trans_start = jiffies;
- p->xmit_count = next_nop;
-
- cli();
- if(p->xmit_count != p->xmit_last) {
- dev->tbusy = 0;
- }
- sti();
- dev_kfree_skb(skb);
+ next_nop = (p->nop_point + 1) & 0x1;
+ p->xmit_buffs[0]->size = TBD_LAST | len;
+
+ p->xmit_cmds[0]->cmd_link = p->nop_cmds[next_nop]->cmd_link
+ = make16((p->nop_cmds[next_nop]));
+ p->xmit_cmds[0]->cmd_status = p->nop_cmds[next_nop]->cmd_status = 0;
+
+ p->nop_cmds[p->nop_point]->cmd_link = make16((p->xmit_cmds[0]));
+ dev->trans_start = jiffies;
+ p->nop_point = next_nop;
+ dev_kfree_skb(skb);
#endif
- }
- return 0;
+#else
+ p->xmit_buffs[p->xmit_count]->size = TBD_LAST | len;
+ if ((next_nop = p->xmit_count + 1) == NUM_XMIT_BUFFS) {
+ next_nop = 0;
+ }
+ p->xmit_cmds[p->xmit_count]->cmd_status = 0;
+ p->xmit_cmds[p->xmit_count]->cmd_link = p->nop_cmds[next_nop]->cmd_link
+ = make16((p->nop_cmds[next_nop]));
+ p->nop_cmds[next_nop]->cmd_status = 0;
+
+ p->nop_cmds[p->xmit_count]->cmd_link = make16((p->xmit_cmds[p->xmit_count]));
+ dev->trans_start = jiffies;
+ p->xmit_count = next_nop;
+
+ cli();
+ if (p->xmit_count != p->xmit_last) {
+ dev->tbusy = 0;
+ }
+ sti();
+ dev_kfree_skb(skb);
+#endif
+ }
+ return 0;
}
/*******************************************
* Someone wanna have the statistics
*/
-static struct net_device_stats *elmc_get_stats( struct device *dev )
+static struct net_device_stats *elmc_get_stats(struct device *dev)
{
- struct priv *p = (struct priv *) dev->priv;
- unsigned short crc,aln,rsc,ovrn;
-
- crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
- p->scb->crc_errs -= crc;
- aln = p->scb->aln_errs;
- p->scb->aln_errs -= aln;
- rsc = p->scb->rsc_errs;
- p->scb->rsc_errs -= rsc;
- ovrn = p->scb->ovrn_errs;
- p->scb->ovrn_errs -= ovrn;
-
- p->stats.rx_crc_errors += crc;
- p->stats.rx_fifo_errors += ovrn;
- p->stats.rx_frame_errors += aln;
- p->stats.rx_dropped += rsc;
-
- return &p->stats;
+ struct priv *p = (struct priv *) dev->priv;
+ unsigned short crc, aln, rsc, ovrn;
+
+ crc = p->scb->crc_errs; /* get error-statistic from the ni82586 */
+ p->scb->crc_errs -= crc;
+ aln = p->scb->aln_errs;
+ p->scb->aln_errs -= aln;
+ rsc = p->scb->rsc_errs;
+ p->scb->rsc_errs -= rsc;
+ ovrn = p->scb->ovrn_errs;
+ p->scb->ovrn_errs -= ovrn;
+
+ p->stats.rx_crc_errors += crc;
+ p->stats.rx_fifo_errors += ovrn;
+ p->stats.rx_frame_errors += aln;
+ p->stats.rx_dropped += rsc;
+
+ return &p->stats;
}
/********************************************************
* Set MC list ..
*/
-static
-void
-set_multicast_list(struct device *dev) {
- if(!dev->start) {
- /* without a running interface, promiscuous doesn't work */
- return;
- }
-
- dev->start = 0;
- alloc586(dev);
- init586(dev);
- startrecv586(dev);
- dev->start = 1;
+static void set_multicast_list(struct device *dev)
+{
+ if (!dev->start) {
+ /* without a running interface, promiscuous doesn't work */
+ return;
+ }
+ dev->start = 0;
+ alloc586(dev);
+ init586(dev);
+ startrecv586(dev);
+ dev->start = 1;
}
/*************************************************************************/
#ifdef MODULE
-static struct device dev_elmc = {
- " " /*"3c523"*/, 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elmc_probe };
-static int irq=0;
-static int io=0;
+static char devicename[9] = {0,};
+
+static struct device dev_elmc =
+{
+ devicename /*"3c523" */ , 0, 0, 0, 0, 0, 0, 0, 0, 0, NULL, elmc_probe
+};
+
+static int irq = 0;
+static int io = 0;
MODULE_PARM(irq, "i");
MODULE_PARM(io, "i");
-int
-init_module(void) {
+int init_module(void)
+{
struct device *dev = &dev_elmc;
- dev->base_addr=io;
- dev->irq=irq;
+ dev->base_addr = io;
+ dev->irq = irq;
if (register_netdev(dev) != 0) {
return -EIO;
}
-
return 0;
}
-void
-cleanup_module(void) {
+void cleanup_module(void)
+{
struct device *dev = &dev_elmc;
- if (MOD_IN_USE) {
- printk("3c523: device busy, remove delayed\n");
- } else {
- /* shutdown interrupts on the card */
- elmc_id_reset586();
-
- if( dev->irq != 0 ) {
- /* this should be done by close, but if we failed to
- initialize properly something may have gotten hosed. */
- free_irq( dev->irq, dev );
- dev->irq = 0;
- }
-
-
-
- if( dev->base_addr != 0 ) {
- release_region( dev->base_addr, ELMC_IO_EXTENT );
- dev->base_addr = 0;
- }
- irq = 0;
- io = 0;
-
- unregister_netdev(dev);
+ /* shutdown interrupts on the card */
+ elmc_id_reset586();
+ if (dev->irq != 0) {
+ /* this should be done by close, but if we failed to
+ initialize properly something may have gotten hosed. */
+ free_irq(dev->irq, dev);
+ dev->irq = 0;
+ }
+ if (dev->base_addr != 0) {
+ release_region(dev->base_addr, ELMC_IO_EXTENT);
+ dev->base_addr = 0;
+ }
+ irq = 0;
+ io = 0;
+ unregister_netdev(dev);
- mca_set_adapter_procfn( ((struct priv *) (dev->priv))->slot,
- NULL, NULL );
+ mca_set_adapter_procfn(((struct priv *) (dev->priv))->slot,
+ NULL, NULL);
- kfree_s(dev->priv,sizeof(struct priv));
- dev->priv=NULL;
- }
+ kfree_s(dev->priv, sizeof(struct priv));
+ dev->priv = NULL;
}
-#endif /* MODULE */
+
+#endif /* MODULE */
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 889229892..547d0497c 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -77,8 +77,9 @@ static int rx_nocopy = 0, rx_copy = 0, queued_packet = 0, rx_csumhits;
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/bios32.h>
#include <linux/timer.h>
+
+#include <asm/byteorder.h>
#include <asm/irq.h> /* For NR_IRQS only. */
#include <asm/bitops.h>
#include <asm/io.h>
@@ -332,10 +333,20 @@ enum Window3 { /* Window 3: MAC/config bits. */
union wn3_config {
int i;
struct w3_config_fields {
+#if defined(__LITTLE_ENDIAN_BITFIELD)
unsigned int ram_size:3, ram_width:1, ram_speed:2, rom_size:2;
int pad8:8;
unsigned int ram_split:2, pad18:2, xcvr:4, autoselect:1;
int pad24:7;
+#elif defined(__BIG_ENDIAN_BITFIELD)
+ unsigned int rom_size:2, ram_speed:2, ram_width:1, ram_size:3;
+ int pad8:8;
+ unsigned int xcvr:4, pad18:2, ram_split:2;
+ int pad24:7;
+ unsigned int autoselect:1;
+#else
+#error "Bitfield endianness not defined! Check your byteorder.h"
+#endif
} u;
};
diff --git a/drivers/net/82596.c b/drivers/net/82596.c
index 43db9bc8d..6a9c0990c 100644
--- a/drivers/net/82596.c
+++ b/drivers/net/82596.c
@@ -1194,7 +1194,7 @@ static int i596_close(struct device *dev)
while (lp->scb.command)
if (--boguscnt == 0) {
- printk("%s: close1 timed timed out with status %4.4x, cmd %4.4x.\n",
+ printk("%s: close1 timed out with status %4.4x, cmd %4.4x.\n",
dev->name, lp->scb.status, lp->scb.command);
break;
}
@@ -1205,7 +1205,7 @@ static int i596_close(struct device *dev)
while (lp->scb.command)
if (--boguscnt == 0) {
- printk("%s: close2 timed timed out with status %4.4x, cmd %4.4x.\n",
+ printk("%s: close2 timed out with status %4.4x, cmd %4.4x.\n",
dev->name, lp->scb.status, lp->scb.command);
break;
}
diff --git a/drivers/net/8390.c b/drivers/net/8390.c
index e00094f45..cd638f3df 100644
--- a/drivers/net/8390.c
+++ b/drivers/net/8390.c
@@ -950,7 +950,8 @@ static void NS8390_trigger_send(struct device *dev, unsigned int length,
int start_page)
{
int e8390_base = dev->base_addr;
-
+ struct ei_device *ei_local = (struct ei_device *) dev->priv;
+
outb_p(E8390_NODMA+E8390_PAGE0, e8390_base+E8390_CMD);
if (inb_p(e8390_base) & E8390_TRANS)
diff --git a/drivers/net/8390.h b/drivers/net/8390.h
index 4418fb28d..52d4e9c9b 100644
--- a/drivers/net/8390.h
+++ b/drivers/net/8390.h
@@ -178,6 +178,7 @@ struct ei_device {
/* The new statistics table. */
struct net_device_stats stat;
unsigned char *reg_offset; /* Register mapping table */
+ unsigned long priv; /* Private field to store bus IDs etc. */
};
/* The maximum number of 8390 interrupt service routines called per IRQ. */
@@ -207,11 +208,11 @@ struct ei_device {
#define E8390_PAGE1 0x40 /* using the two high-order bits */
#define E8390_PAGE2 0x80 /* Page 3 is invalid. */
-
-#ifndef CONFIG_MAC
-#define EI_SHIFT(x) (x)
-#else
+#if defined(CONFIG_MAC) || defined(CONFIG_AMIGA_PCMCIA) || \
+ defined(CONFIG_ARIADNE2) || defined(CONFIG_ARIADNE2_MODULE)
#define EI_SHIFT(x) (ei_local->reg_offset[x])
+#else
+#define EI_SHIFT(x) (x)
#endif
#define E8390_CMD EI_SHIFT(0x00) /* The command register (for all pages) */
diff --git a/drivers/net/Config.in b/drivers/net/Config.in
index 81f703e6d..df7d7f60c 100644
--- a/drivers/net/Config.in
+++ b/drivers/net/Config.in
@@ -37,6 +37,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
fi
if [ "$CONFIG_ZORRO" = "y" ]; then
tristate 'Ariadne support' CONFIG_ARIADNE
+ tristate 'Ariadne II support' CONFIG_ARIADNE2
tristate 'A2065 support' CONFIG_A2065
tristate 'Hydra support' CONFIG_HYDRA
fi
@@ -55,6 +56,7 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
fi
fi
tristate '3c509/3c579 support' CONFIG_EL3
+ tristate '3c515 ISA Fast EtherLink' CONFIG_3C515
tristate '3c590/3c900 series (592/595/597) "Vortex/Boomerang" support' CONFIG_VORTEX
fi
bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE
@@ -79,11 +81,12 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'RealTek 8129/8139 (not 8019/8029!) support' CONFIG_RTL8139
tristate 'Packet Engines Yellowfin Gigabit-NIC support' CONFIG_YELLOWFIN
+ tristate 'Alteon AceNIC & 3Com 3C985 Gigabit support' CONFIG_ACENIC
fi
bool 'Other ISA cards' CONFIG_NET_ISA
if [ "$CONFIG_NET_ISA" = "y" ]; then
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- tristate 'AT1700 support (EXPERIMENTAL)' CONFIG_AT1700
+ tristate 'AT1700/1720 support (EXPERIMENTAL)' CONFIG_AT1700
fi
tristate 'Cabletron E21xx support' CONFIG_E2100
tristate 'DEPCA, DE10x, DE200, DE201, DE202, DE422 support' CONFIG_DEPCA
@@ -105,6 +108,9 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
fi
bool 'SK_G16 support' CONFIG_SK_G16
fi
+ if [ "$CONFIG_MCA" = "y" ]; then
+ tristate 'NE/2 (ne2000 MCA version) support' CONFIG_NE2_MCA
+ fi
bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA
if [ "$CONFIG_NET_EISA" = "y" ]; then
tristate 'AMD PCnet32 (VLB and PCI) support' CONFIG_PCNET32
@@ -124,9 +130,11 @@ if [ "$CONFIG_NET_ETHERNET" = "y" ]; then
tristate 'EtherExpressPro/100 support' CONFIG_EEXPRESS_PRO100
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Mylex EISA LNE390A/B support (EXPERIMENTAL)' CONFIG_LNE390
+ tristate 'Novell/Eagle/Microdyne NE3210 EISA support (EXPERIMENTAL)' CONFIG_NE3210
fi
tristate 'PCI NE2000 support' CONFIG_NE2K_PCI
tristate 'TI ThunderLAN support' CONFIG_TLAN
+ tristate 'VIA Rhine support' CONFIG_VIA_RHINE
if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
tristate 'Racal-Interlan EISA ES3210 support (EXPERIMENTAL)' CONFIG_ES3210
tristate 'SMC EtherPower II (EXPERIMENTAL)' CONFIG_EPIC100
@@ -146,6 +154,17 @@ if [ "$CONFIG_FDDI" = "y" ]; then
bool 'Digital DEFEA and DEFPA adapter support' CONFIG_DEFXX
fi
+if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
+ bool 'HIPPI driver support (EXPERIMENTAL)' CONFIG_HIPPI
+ if [ "$CONFIG_HIPPI" = "y" ]; then
+ bool 'CERN HIPPI PCI adapter support' CONFIG_CERN_HIPPI
+ bool 'Essential RoadRunner HIPPI PCI adapter support' CONFIG_ROADRUNNER
+ if [ "$CONFIG_ROADRUNNER" != "n" ]; then
+ bool ' Use large TX/RX rings' CONFIG_ROADRUNNER_LARGE_RINGS
+ fi
+ fi
+fi
+
tristate 'Frame relay DLCI support' CONFIG_DLCI
if [ "$CONFIG_DLCI" = "y" -o "$CONFIG_DLCI" = "m" ]; then
int ' Max open DLCI' CONFIG_DLCI_COUNT 24
@@ -156,19 +175,17 @@ fi
#
# AppleTalk
#
-if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
- if [ "$CONFIG_ATALK" != "n" ]; then
- tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC
- tristate 'COPS LocalTalk PC support' CONFIG_COPS
- if [ "$CONFIG_COPS" != "n" ]; then
- bool 'Dayna firmware support' CONFIG_COPS_DAYNA
- bool 'Tangent firmware support' CONFIG_COPS_TANGENT
- fi
- tristate 'Appletalk-IP driver support' CONFIG_IPDDP
- if [ "$CONFIG_IPDDP" != "n" ]; then
- bool 'IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP
- bool 'Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP
- fi
+if [ "$CONFIG_ATALK" != "n" ]; then
+ dep_tristate 'Apple/Farallon LocalTalk PC support' CONFIG_LTPC $CONFIG_ATALK
+ dep_tristate 'COPS LocalTalk PC support' CONFIG_COPS $CONFIG_ATALK
+ if [ "$CONFIG_COPS" != "n" ]; then
+ bool 'Dayna firmware support' CONFIG_COPS_DAYNA
+ bool 'Tangent firmware support' CONFIG_COPS_TANGENT
+ fi
+ dep_tristate 'Appletalk-IP driver support' CONFIG_IPDDP $CONFIG_ATALK
+ if [ "$CONFIG_IPDDP" != "n" ]; then
+ bool 'IP to Appletalk-IP Encapsulation support' CONFIG_IPDDP_ENCAP
+ bool 'Appletalk-IP to IP Decapsulation support' CONFIG_IPDDP_DECAP
fi
fi
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5009532be..2dc86b499 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -199,6 +199,16 @@ else
endif
endif
+ifeq ($(CONFIG_NE2_MCA),y)
+L_OBJS += ne2.o
+CONFIG_8390_BUILTIN = y
+else
+ ifeq ($(CONFIG_NE2_MCA),m)
+ CONFIG_8390_MODULE = y
+ M_OBJS += ne2.o
+ endif
+endif
+
ifeq ($(CONFIG_HPLAN),y)
L_OBJS += hp.o
CONFIG_8390_BUILTIN = y
@@ -279,6 +289,16 @@ else
endif
endif
+ifeq ($(CONFIG_NE3210),y)
+L_OBJS += ne3210.o
+CONFIG_8390_BUILTIN = y
+else
+ ifeq ($(CONFIG_NE3210),m)
+ CONFIG_8390_MODULE = y
+ M_OBJS += ne3210.o
+ endif
+endif
+
ifeq ($(CONFIG_PLIP),y)
L_OBJS += plip.o
else
@@ -462,6 +482,14 @@ else
endif
endif
+ifeq ($(CONFIG_3C515),y)
+L_OBJS += 3c515.o
+else
+ ifeq ($(CONFIG_3C515),m)
+ M_OBJS += 3c515.o
+ endif
+endif
+
ifeq ($(CONFIG_VORTEX),y)
L_OBJS += 3c59x.o
else
@@ -510,6 +538,14 @@ else
endif
endif
+ifeq ($(CONFIG_ACENIC),y)
+L_OBJS += acenic.o
+else
+ ifeq ($(CONFIG_ACENIC),m)
+ M_OBJS += acenic.o
+ endif
+endif
+
ifeq ($(CONFIG_WAVELAN),y)
L_OBJS += wavelan.o
else
@@ -526,6 +562,14 @@ else
endif
endif
+ifeq ($(CONFIG_VIA_RHINE),y)
+L_OBJS += via-rhine.o
+else
+ ifeq ($(CONFIG_VIA_RHINE),m)
+ M_OBJS += via-rhine.o
+ endif
+endif
+
ifeq ($(CONFIG_ZNET),y)
L_OBJS += znet.o
endif
@@ -752,6 +796,16 @@ else
endif
endif
+ifeq ($(CONFIG_ARIADNE2),y)
+L_OBJS += ariadne2.o
+CONFIG_8390_BUILTIN = y
+else
+ ifeq ($(CONFIG_ARIADNE2),m)
+ M_OBJS += ariadne2.o
+ CONFIG_8390_MODULE = y
+ endif
+endif
+
# If anything built-in uses the 8390, then build it into the kernel also.
# If not, but a module uses it, build as a module.
ifdef CONFIG_8390_BUILTIN
@@ -956,6 +1010,25 @@ else
endif
endif
+#
+# HIPPI adapters
+#
+ifeq ($(CONFIG_CERN_HIPPI),y)
+L_OBJS += cern_hippi.o
+else
+ ifeq ($(CONFIG_CERN_HIPPI),m)
+ M_OBJS += cern_hippi.o
+ endif
+endif
+
+ifeq ($(CONFIG_ROADRUNNER),y)
+L_OBJS += rrunner.o
+else
+ ifeq ($(CONFIG_ROADRUNNER),m)
+ M_OBJS += rrunner.o
+ endif
+endif
+
include $(TOPDIR)/Rules.make
clean:
diff --git a/drivers/net/Space.c b/drivers/net/Space.c
index 2fdfc177e..a3f8e68a9 100644
--- a/drivers/net/Space.c
+++ b/drivers/net/Space.c
@@ -39,6 +39,7 @@
ethernet adaptor have the name "eth[0123...]".
*/
+extern int ne2_probe(struct device *dev);
extern int tulip_probe(struct device *dev);
extern int hp100_probe(struct device *dev);
extern int ultra_probe(struct device *dev);
@@ -72,6 +73,7 @@ extern int elplus_probe(struct device *);
extern int ac3200_probe(struct device *);
extern int es_probe(struct device *);
extern int lne390_probe(struct device *);
+extern int ne3210_probe(struct device *);
extern int e2100_probe(struct device *);
extern int ni5010_probe(struct device *);
extern int ni52_probe(struct device *);
@@ -90,6 +92,7 @@ extern int sgiseeq_probe(struct device *);
extern int atarilance_probe(struct device *);
extern int a2065_probe(struct device *);
extern int ariadne_probe(struct device *);
+extern int ariadne2_probe(struct device *);
extern int hydra_probe(struct device *);
extern int apne_probe(struct device *);
extern int bionet_probe(struct device *);
@@ -106,9 +109,12 @@ extern int am79c961_probe(struct device *dev);
extern int epic100_probe(struct device *dev);
extern int rtl8139_probe(struct device *dev);
extern int hplance_probe(struct device *dev);
+extern int via_rhine_probe(struct device *dev);
+extern int tc515_probe(struct device *dev);
/* Gigabit Ethernet adapters */
extern int yellowfin_probe(struct device *dev);
+extern int acenic_probe(struct device *dev);
/* Detachable devices ("pocket adaptors") */
extern int atp_init(struct device *);
@@ -121,6 +127,7 @@ extern int apfddi_init(struct device *dev);
/* HIPPI boards */
extern int cern_hippi_probe(struct device *);
+extern int rr_hippi_probe(struct device *);
struct devprobe
{
@@ -195,6 +202,12 @@ struct devprobe pci_probes[] __initdata = {
#ifdef CONFIG_YELLOWFIN
{yellowfin_probe, 0},
#endif
+#ifdef CONFIG_ACENIC
+ {acenic_probe, 0},
+#endif
+#ifdef CONFIG_VIA_RHINE
+ {via_rhine_probe, 0},
+#endif
{NULL, 0},
};
@@ -217,6 +230,9 @@ struct devprobe eisa_probes[] __initdata = {
#ifdef CONFIG_LNE390
{lne390_probe, 0},
#endif
+#ifdef CONFIG_NE3210
+ {ne3210_probe, 0},
+#endif
{NULL, 0},
};
@@ -240,6 +256,9 @@ struct devprobe mca_probes[] __initdata = {
#ifdef CONFIG_ULTRAMCA
{ultramca_probe, 0},
#endif
+#ifdef CONFIG_NE2_MCA
+ {ne2_probe, 0},
+#endif
#ifdef CONFIG_ELMC /* 3c523 */
{elmc_probe, 0},
#endif
@@ -257,6 +276,9 @@ struct devprobe isa_probes[] __initdata = {
#ifdef CONFIG_HP100 /* ISA, EISA & PCI */
{hp100_probe, 0},
#endif
+#ifdef CONFIG_3C515
+ {tc515_probe, 0},
+#endif
#ifdef CONFIG_ULTRA
{ultra_probe, 0},
#endif
@@ -367,6 +389,9 @@ struct devprobe m68k_probes[] __initdata = {
#ifdef CONFIG_ARIADNE /* Village Tronic Ariadne Ethernet Board */
{ariadne_probe, 0},
#endif
+#ifdef CONFIG_ARIADNE2 /* Village Tronic Ariadne II Ethernet Board */
+ {ariadne2_probe, 0},
+#endif
#ifdef CONFIG_HYDRA /* Hydra Systems Amiganet Ethernet board */
{hydra_probe, 0},
#endif
@@ -514,6 +539,9 @@ static int hippi_probe(struct device *dev)
#ifdef CONFIG_CERN_HIPPI
&& cern_hippi_probe(dev)
#endif
+#ifdef CONFIG_ROADRUNNER
+ && rr_hippi_probe(dev)
+#endif
&& 1 ) {
return 1; /* -ENODEV or -EAGAIN would be more accurate. */
}
@@ -538,7 +566,7 @@ static int hippi_probe(struct device *dev)
#if defined(CONFIG_LTPC)
extern int ltpc_probe(struct device *);
static struct device dev_ltpc = {
- "ltalk0\0 ",
+ "lt0\0 ",
0, 0, 0, 0,
0x0, 0,
0, 0, 0, NEXT_DEV, ltpc_probe };
@@ -734,11 +762,11 @@ static struct device tr0_dev = {
#ifdef CONFIG_HIPPI
static struct device hip3_dev =
- {"hip3", 0, 0, 0, 0, -1, 0, 0, 0, 0, NEXT_DEV, hippi_probe};
+ {"hip3", 0, 0, 0, 0, 0, 0, 0, 0, 0, NEXT_DEV, hippi_probe};
static struct device hip2_dev =
- {"hip2", 0, 0, 0, 0, -1, 0, 0, 0, 0, &hip3_dev, hippi_probe};
+ {"hip2", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip3_dev, hippi_probe};
static struct device hip1_dev =
- {"hip1", 0, 0, 0, 0, -1, 0, 0, 0, 0, &hip2_dev, hippi_probe};
+ {"hip1", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip2_dev, hippi_probe};
static struct device hip0_dev =
{"hip0", 0, 0, 0, 0, 0, 0, 0, 0, 0, &hip1_dev, hippi_probe};
diff --git a/drivers/net/a2065.c b/drivers/net/a2065.c
index c9d2d5eca..898369fb3 100644
--- a/drivers/net/a2065.c
+++ b/drivers/net/a2065.c
@@ -570,6 +570,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev)
int entry, skblen, len;
int status = 0;
static int outs;
+ unsigned long flags;
/* Transmitter timeout, serious problems */
if (dev->tbusy) {
@@ -586,18 +587,20 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev)
}
/* Block a timer-based transmit from overlapping. */
-#ifdef OLD_METHOD
- dev->tbusy = 1;
-#else
if (test_and_set_bit (0, (void *) &dev->tbusy) != 0) {
printk ("Transmitter access conflict.\n");
return -1;
}
-#endif
+
skblen = skb->len;
- if (!TX_BUFFS_AVAIL)
+ save_flags(flags);
+ cli();
+
+ if (!TX_BUFFS_AVAIL){
+ restore_flags(flags);
return -1;
+ }
#ifdef DEBUG_DRIVER
/* dump the packet */
@@ -634,6 +637,7 @@ static int lance_start_xmit (struct sk_buff *skb, struct device *dev)
if (TX_BUFFS_AVAIL)
dev->tbusy = 0;
+ restore_flags(flags);
return status;
}
diff --git a/drivers/net/ac3200.c b/drivers/net/ac3200.c
index 0fa32d8ca..c6950ad28 100644
--- a/drivers/net/ac3200.c
+++ b/drivers/net/ac3200.c
@@ -205,10 +205,10 @@ __initfunc(static int ac_probe1(int ioaddr, struct device *dev))
* the card mem within the region covered by `normal' RAM !!!
*/
if (dev->mem_start > 1024*1024) { /* phys addr > 1MB */
- if (dev->mem_start < (unsigned long)high_memory) {
+ if (dev->mem_start < virt_to_bus(high_memory)) {
printk(KERN_CRIT "ac3200.c: Card RAM overlaps with normal memory!!!\n");
printk(KERN_CRIT "ac3200.c: Use EISA SCU to set card memory below 1MB,\n");
- printk(KERN_CRIT "ac3200.c: or to an address above %p.\n", high_memory);
+ printk(KERN_CRIT "ac3200.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
printk(KERN_CRIT "ac3200.c: Driver NOT installed.\n");
free_irq(dev->irq, dev);
kfree(dev->priv);
@@ -225,6 +225,7 @@ __initfunc(static int ac_probe1(int ioaddr, struct device *dev))
dev->priv = NULL;
return EAGAIN;
}
+ ei_status.reg0 = 1; /* Use as remap flag */
printk("ac3200.c: remapped %dkB card memory to virtual address %#lx\n",
AC_STOP_PG/4, dev->mem_start);
}
@@ -404,6 +405,8 @@ cleanup_module(void)
/* Someday free_irq may be in ac_close_card() */
free_irq(dev->irq, dev);
release_region(dev->base_addr, AC_IO_EXTENT);
+ if (ei_status.reg0)
+ iounmap((void *)dev->mem_start);
dev->priv = NULL;
unregister_netdev(dev);
kfree(priv);
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
new file mode 100644
index 000000000..7eef6b801
--- /dev/null
+++ b/drivers/net/acenic.c
@@ -0,0 +1,1576 @@
+/*
+ * acenic.c: Linux driver for the Alteon AceNIC Gigabit Ethernet card
+ * and other Tigon based cards.
+ *
+ * Copyright 1998 by Jes Sorensen, <Jes.Sorensen@cern.ch>.
+ *
+ * Thanks to Alteon and 3Com for providing hardware and documentation
+ * enabling me to write this driver.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define DEBUG 1
+#define RX_DMA_SKBUFF 1
+#define PKT_COPY_THRESHOLD 300
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <net/sock.h>
+#include <net/ip.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/byteorder.h>
+
+#include "acenic.h"
+
+/*
+ * These must be defined before the firmware is included.
+ */
+#define MAX_TEXT_LEN 96*1024
+#define MAX_RODATA_LEN 8*1024
+#define MAX_DATA_LEN 2*1024
+
+#include "acenic_firmware.h"
+
+
+/*
+ * This driver currently supports Tigon I and Tigon II based cards
+ * including the Alteon AceNIC and the 3Com 3C985.
+ *
+ * This card is really neat, it supports receive hardware checksumming
+ * and jumbo frames (up to 9000 bytes) and does a lot of work in the
+ * firmware. Also the programming interface is quite neat, except for
+ * the parts dealing with the i2c eeprom on the card ;-)
+ *
+ * A number of standard Ethernet receive skb's are now allocated at
+ * init time and not released before the driver is unloaded. This
+ * makes it possible to do ifconfig down/up.
+ *
+ * Using jumbo frames:
+ *
+ * To enable jumbo frames, simply specify an mtu between 1500 and 9000
+ * bytes to ifconfig. Jumbo frames can be enabled or disabled at any time
+ * by running `ifconfig eth<X> mtu <MTU>' with <X> being the Ethernet
+ * interface number and <MTU> being the MTU value.
+ *
+ * TODO:
+ *
+ * - Add multicast support.
+ * - Make all the tuning parameters and link speed negotiation, user
+ * settable at driver/module init time.
+ */
+
+static const char *version = "acenic.c: v0.13 11/25/98 Jes Sorensen (Jes.Sorensen@cern.ch)\n";
+
+static struct device *root_dev = NULL;
+
+static int ace_load_firmware(struct device *dev);
+
+__initfunc(int acenic_probe (struct device *dev))
+{
+ static int i = 0;
+ int boards_found = 0;
+ int version_disp;
+ u32 tmp;
+ struct ace_private *ap;
+ u16 vendor, device;
+ u8 pci_bus;
+ u8 pci_dev_fun;
+ u8 pci_latency;
+ u8 irq;
+
+ if (!pci_present()) /* is PCI support present? */
+ return -ENODEV;
+
+ version_disp = 0;
+
+ for (; i < 255; i++)
+ {
+ dev = NULL;
+
+ if (pcibios_find_class(PCI_CLASS_NETWORK_ETHERNET << 8,
+ i, &pci_bus, &pci_dev_fun) !=
+ PCIBIOS_SUCCESSFUL)
+ break;
+
+ pcibios_read_config_word(pci_bus, pci_dev_fun,
+ PCI_VENDOR_ID, &vendor);
+
+ pcibios_read_config_word(pci_bus, pci_dev_fun,
+ PCI_DEVICE_ID, &device);
+
+ if ((vendor != PCI_VENDOR_ID_ALTEON) &&
+ !((vendor == PCI_VENDOR_ID_3COM) &&
+ (device == PCI_DEVICE_ID_3COM_3C985)))
+ continue;
+
+ dev = init_etherdev(dev, sizeof(struct ace_private));
+
+ if (dev == NULL){
+ printk(KERN_ERR "Unable to allocate etherdev "
+ "structure!\n");
+ break;
+ }
+
+ if (!dev->priv)
+ dev->priv = kmalloc(sizeof(*ap), GFP_KERNEL);
+
+ ap = dev->priv;
+ ap->vendor = vendor;
+
+ /* Read register base address from
+ PCI Configuration Space */
+
+ pcibios_read_config_dword(pci_bus, pci_dev_fun,
+ PCI_BASE_ADDRESS_0, &tmp);
+
+ pcibios_read_config_byte(pci_bus, pci_dev_fun,
+ PCI_INTERRUPT_LINE, &irq);
+
+ pcibios_read_config_word(pci_bus, pci_dev_fun,
+ PCI_COMMAND, &ap->pci_command);
+
+ if (!(ap->pci_command & PCI_COMMAND_MASTER)){
+ ap->pci_command |= PCI_COMMAND_MASTER;
+ pcibios_write_config_word(pci_bus, pci_dev_fun,
+ PCI_COMMAND,
+ ap->pci_command);
+ }
+
+ if (!(ap->pci_command & PCI_COMMAND_MEMORY)){
+ printk(KERN_ERR "Shared mem not enabled - "
+ "unable to configure AceNIC\n");
+ break;
+ }
+
+ dev->irq = irq;
+ ap->pci_bus = pci_bus;
+ ap->pci_dev_fun = pci_dev_fun;
+#ifdef __SMP__
+ spin_lock_init(&ap->lock);
+#endif
+
+ dev->open = &ace_open;
+ dev->hard_start_xmit = &ace_start_xmit;
+ dev->stop = &ace_close;
+ dev->get_stats = &ace_get_stats;
+ dev->set_multicast_list = &ace_set_multicast_list;
+ dev->set_mac_address = &ace_set_mac_addr;
+ dev->change_mtu = &ace_change_mtu;
+
+ /*
+ * Dummy value.
+ */
+ dev->base_addr = 42;
+
+ /* display version info if adapter is found */
+ if (!version_disp)
+ {
+ /* set display flag to TRUE so that */
+ /* we only display this string ONCE */
+ version_disp = 1;
+ printk(version);
+ }
+
+ pcibios_read_config_byte(pci_bus, pci_dev_fun,
+ PCI_LATENCY_TIMER, &pci_latency);
+ if (pci_latency <= 0x40){
+ pci_latency = 0x40;
+ pcibios_write_config_byte(pci_bus, pci_dev_fun,
+ PCI_LATENCY_TIMER,
+ pci_latency);
+ }
+
+ switch(ap->vendor){
+ case PCI_VENDOR_ID_ALTEON:
+ sprintf(ap->name, "AceNIC Gigabit Ethernet");
+ printk(KERN_INFO "%s: Alteon AceNIC ", dev->name);
+ break;
+ case PCI_VENDOR_ID_3COM:
+ sprintf(ap->name, "3Com 3C985 Gigabit Ethernet");
+ printk(KERN_INFO "%s: 3Com 3C985 ", dev->name);
+ break;
+ default:
+ sprintf(ap->name, "Unknown AceNIC based Gigabit Ethernet");
+ printk(KERN_INFO "%s: Unknown AceNIC ", dev->name);
+ break;
+ }
+ printk("Gigabit Ethernet at 0x%08x, irq %i, PCI latency %i "
+ "clks\n", tmp, dev->irq, pci_latency);
+
+ /*
+ * Remap the regs into kernel space.
+ */
+
+ ap->regs = (struct ace_regs *)ioremap(tmp, 0x4000);
+ if (!ap->regs){
+ printk(KERN_ERR "%s: Unable to map I/O register, "
+ "AceNIC %i will be disabled.\n", dev->name, i);
+ break;
+ }
+
+ ace_init(dev);
+
+ boards_found++;
+
+ /*
+ * This is bollocks, but we need to tell the net-init
+ * code that it shall go for the next device.
+ */
+ dev->base_addr = 0;
+ }
+
+ /*
+ * If we're at this point we're going through ace_probe() for
+ * the first time. Return success (0) if we've initialized 1
+ * or more boards. Otherwise, return failure (-ENODEV).
+ */
+
+#ifdef MODULE
+ return boards_found;
+#else
+ if (boards_found > 0)
+ return 0;
+ else
+ return -ENODEV;
+#endif
+}
+
+
+#ifdef MODULE
+int init_module(void)
+{
+ int cards;
+
+ root_dev = NULL;
+
+ cards = acenic_probe(NULL);
+ return cards ? 0 : -ENODEV;
+}
+
+void cleanup_module(void)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct device *next;
+ short i;
+ unsigned long flags;
+
+ while (root_dev) {
+ next = ((struct ace_private *)root_dev->priv)->next;
+ ap = (struct ace_private *)root_dev->priv;
+
+ regs = ap->regs;
+ spin_lock_irqsave(&ap->lock, flags);
+
+ regs->CpuCtrl |= CPU_HALT;
+ if (ap->version == 2)
+ regs->CpuBCtrl |= CPU_HALT;
+ regs->Mb0Lo = 0;
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ /*
+ * Release the RX buffers.
+ */
+ for (i = 0; i < RX_STD_RING_ENTRIES; i++) {
+ if (ap->rx_std_skbuff[i]) {
+ ap->rx_std_ring[i].size = 0;
+ ap->rx_std_ring[i].addr = 0;
+ dev_kfree_skb(ap->rx_std_skbuff[i]);
+ }
+ }
+
+ iounmap(regs);
+ kfree(ap->info);
+ free_irq(root_dev->irq, root_dev);
+ unregister_netdev(root_dev);
+ kfree(root_dev);
+
+ root_dev = next;
+ }
+}
+#endif
+
+
+/*
+ * Commands are considered to be slow.
+ */
+static inline void ace_issue_cmd(struct ace_regs *regs, struct cmd *cmd)
+{
+ u32 idx;
+
+ idx = regs->CmdPrd;
+
+ regs->CmdRng[idx] = *(u32 *)(cmd);
+ idx = (idx + 1) % CMD_RING_ENTRIES;
+
+ regs->CmdPrd = idx;
+}
+
+
+__initfunc(static int ace_init(struct device *dev))
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct ace_info *info;
+ u32 tig_ver, mac1 = 0, mac2 = 0, tmp;
+ unsigned long tmp_ptr, myjif;
+ short i;
+
+ ap = dev->priv;
+ regs = ap->regs;
+
+#if 0
+ regs->HostCtrl |= 0x08;
+ regs->CpuCtrl = CPU_RESET;
+ regs->CpuBCtrl = CPU_RESET;
+
+ {
+ long myjif = jiffies + HZ;
+ while (myjif > jiffies);
+ }
+#endif
+
+ /*
+ * Don't access any other registes before this point!
+ */
+#ifdef __BIG_ENDIAN
+ regs->HostCtrl = ((BYTE_SWAP | WORD_SWAP | CLR_INT) |
+ ((BYTE_SWAP | WORD_SWAP | CLR_INT) << 24));
+#else
+ regs->HostCtrl = (CLR_INT | WORD_SWAP |
+ ((CLR_INT | WORD_SWAP) << 24));
+#endif
+
+#ifdef __LITTLE_ENDIAN
+ regs->ModeStat = ACE_BYTE_SWAP_DATA | ACE_WARN | ACE_FATAL
+ | ACE_WORD_SWAP;
+#else
+#error "this driver doesn't run on big-endian machines yet!"
+#endif
+
+ /*
+ * Stop the NIC CPU and clear pending interrupts
+ */
+ regs->CpuCtrl |= CPU_HALT;
+ regs->Mb0Lo = 0;
+
+ tig_ver = regs->HostCtrl >> 28;
+
+ switch(tig_ver){
+ case 4:
+ printk(KERN_INFO" Tigon I (Rev. 4), Firmware: %i.%i.%i, ",
+ tigonFwReleaseMajor, tigonFwReleaseMinor,
+ tigonFwReleaseFix);
+ regs->LocalCtrl = 0;
+ ap->version = 1;
+ break;
+ case 6:
+ printk(KERN_INFO" Tigon II (Rev. %i), Firmware: %i.%i.%i, ",
+ tig_ver, tigon2FwReleaseMajor, tigon2FwReleaseMinor,
+ tigon2FwReleaseFix);
+ regs->CpuBCtrl |= CPU_HALT;
+ regs->LocalCtrl = SRAM_BANK_512K;
+ regs->MiscCfg = SYNC_SRAM_TIMING;
+ ap->version = 2;
+ break;
+ default:
+ printk(KERN_INFO" Unsupported Tigon version detected (%i), ",
+ tig_ver);
+ return -ENODEV;
+ }
+
+ for(i = 0; i < 4; i++){
+ mac1 = mac1 << 8;
+ mac1 |= read_eeprom_byte(regs, 0x8c+i);
+ }
+ for(i = 4; i < 8; i++){
+ mac2 = mac2 << 8;
+ mac2 |= read_eeprom_byte(regs, 0x8c+i);
+ }
+
+ regs->MacAddrHi = mac1;
+ regs->MacAddrLo = mac2;
+
+ printk("MAC: %02x:%02x:%02x:%02x:%02x:%02x\n",
+ (mac1 >> 8) & 0xff, mac1 & 0xff, (mac2 >> 24) &0xff,
+ (mac2 >> 16) & 0xff, (mac2 >> 8) & 0xff, mac2 & 0xff);
+
+ dev->dev_addr[0] = (mac1 >> 8) & 0xff;
+ dev->dev_addr[1] = mac1 & 0xff;
+ dev->dev_addr[2] = (mac2 >> 24) & 0xff;
+ dev->dev_addr[3] = (mac2 >> 16) & 0xff;
+ dev->dev_addr[4] = (mac2 >> 8) & 0xff;
+ dev->dev_addr[5] = mac2 & 0xff;
+
+ /*
+ * Set the max DMA transfer size. Seems that for most systems
+ * the performance is better when no MAX parameter is
+ * set. However for systems enabling PCI write and invalidate,
+ * DMA writes must be set to the L1 cache line size to get
+ * optimal performance.
+ */
+ tmp = READ_CMD_MEM | WRITE_CMD_MEM;
+ if (ap->version == 2){
+ tmp |= DMA_WRITE_ALL_ALIGN;
+ if (ap->pci_command & PCI_COMMAND_INVALIDATE){
+ switch(L1_CACHE_BYTES){
+ case 16:
+ tmp |= DMA_WRITE_MAX_16;
+ break;
+ case 32:
+ tmp |= DMA_WRITE_MAX_32;
+ break;
+ case 64:
+ tmp |= DMA_WRITE_MAX_64;
+ break;
+ default:
+ printk(KERN_INFO " Cache line size %i not "
+ "supported, PCI write and invalidate "
+ "disabled\n", L1_CACHE_BYTES);
+ ap->pci_command &= ~PCI_COMMAND_INVALIDATE;
+ pcibios_write_config_word(ap->pci_bus,
+ ap->pci_dev_fun,
+ PCI_COMMAND,
+ ap->pci_command);
+ }
+ }
+ }
+ regs->PciState = tmp;
+
+ if (request_irq(dev->irq, ace_interrupt, SA_SHIRQ, ap->name, dev))
+ {
+ printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
+ dev->name, dev->irq);
+ return -EAGAIN;
+ }
+
+ /*
+ * Initialize the generic info block and the command+event rings
+ * and the control blocks for the transmit and receive rings
+ * as they need to be setup once and for all.
+ */
+ if (!(info = kmalloc(sizeof(struct ace_info), GFP_KERNEL | GFP_DMA))){
+ free_irq(dev->irq, dev);
+ return -EAGAIN;
+ }
+
+ ap->info = info;
+ memset(info, 0, sizeof(struct ace_info));
+
+ ace_load_firmware(dev);
+ ap->fw_running = 0;
+
+ tmp_ptr = virt_to_bus((void *)info);
+#if (BITS_PER_LONG == 64)
+ regs->InfoPtrHi = (tmp_ptr >> 32);
+#else
+ regs->InfoPtrHi = 0;
+#endif
+ regs->InfoPtrLo = ((tmp_ptr) & 0xffffffff);
+
+ memset(ap->evt_ring, 0, EVT_RING_ENTRIES * sizeof(struct event));
+
+ info->evt_ctrl.rngptr = virt_to_bus(ap->evt_ring);
+ info->evt_ctrl.flags = 0;
+
+ info->evt_prd_ptr = virt_to_bus(&ap->evt_prd);
+ ap->evt_prd = 0;
+ regs->EvtCsm = 0;
+
+ info->cmd_ctrl.flags = 0;
+ info->cmd_ctrl.rngptr = 0x100;
+ info->cmd_ctrl.max_len = 0;
+
+ for (i = 0; i < CMD_RING_ENTRIES; i++) {
+ regs->CmdRng[i] = 0;
+ }
+
+ regs->CmdPrd = 0;
+ regs->CmdCsm = 0;
+
+ info->stats2_ptr = virt_to_bus(&info->s.stats);
+
+ info->rx_std_ctrl.max_len = ACE_STD_MTU + ETH_HLEN + 4;
+ info->rx_std_ctrl.rngptr = virt_to_bus(ap->rx_std_ring);
+ info->rx_std_ctrl.flags = RX_TCP_UDP_SUM;
+
+ memset(ap->rx_std_ring, 0,
+ RX_STD_RING_ENTRIES * sizeof(struct rx_desc));
+
+ info->rx_jumbo_ctrl.max_len = 0;
+ info->rx_jumbo_ctrl.rngptr = virt_to_bus(ap->rx_jumbo_ring);
+ info->rx_jumbo_ctrl.flags = RX_TCP_UDP_SUM;
+
+ memset(ap->rx_jumbo_ring, 0,
+ RX_JUMBO_RING_ENTRIES * sizeof(struct rx_desc));
+
+ info->rx_return_ctrl.max_len = 0;
+ info->rx_return_ctrl.rngptr = virt_to_bus(ap->rx_return_ring);
+ info->rx_return_ctrl.flags = 0;
+
+ memset(ap->rx_return_ring, 0,
+ RX_RETURN_RING_ENTRIES * sizeof(struct rx_desc));
+
+ info->rx_ret_prd_ptr = virt_to_bus(&ap->rx_ret_prd);
+
+ regs->WinBase = TX_RING_BASE;
+ ap->tx_ring = (struct tx_desc *)regs->Window;
+ memset(ap->tx_ring, 0, TX_RING_ENTRIES * sizeof(struct tx_desc));
+
+ info->tx_ctrl.max_len = TX_RING_ENTRIES;
+ info->tx_ctrl.flags = 0;
+#if (BITS_PER_LONG == 64) && defined(__BIG_ENDIAN)
+ info->tx_ctrl.rngptr = TX_RING_BASE << 32;
+#else
+ info->tx_ctrl.rngptr = TX_RING_BASE;
+#endif
+
+ info->tx_csm_ptr = virt_to_bus(&ap->tx_csm);
+
+ regs->DmaReadCfg = DMA_THRESH_8W;
+ regs->DmaWriteCfg = DMA_THRESH_8W;
+
+ regs->MaskInt = 0;
+ regs->IfIdx = 1;
+
+#if 0
+{
+ u32 tmp;
+ tmp = regs->AssistState;
+ tmp &= ~2;
+ tmp |= 1;
+ regs->AssistState = tmp;
+
+ tmp = regs->MacRxState;
+ tmp &= ~4;
+ regs->MacRxState = tmp;
+}
+#endif
+ regs->TuneStatTicks = 2 * TICKS_PER_SEC;
+ regs->TuneTxCoalTicks = TICKS_PER_SEC / 500;
+ regs->TuneMaxTxDesc = 7;
+ regs->TuneRxCoalTicks = TICKS_PER_SEC / 10000;
+ regs->TuneMaxRxDesc = 2;
+ regs->TuneTrace = 0 /* 0x30001fff */;
+ tmp = LNK_ENABLE | LNK_FULL_DUPLEX | LNK_1000MB |
+ LNK_RX_FLOW_CTL_Y | LNK_NEG_FCTL | LNK_NEGOTIATE;
+ if(ap->version == 1)
+ regs->TuneLink = tmp;
+ else{
+ tmp |= LNK_TX_FLOW_CTL_Y;
+ regs->TuneLink = tmp;
+ regs->TuneFastLink = tmp;
+ }
+
+ if (ap->version == 1)
+ regs->Pc = tigonFwStartAddr;
+ else if (ap->version == 2)
+ regs->Pc = tigon2FwStartAddr;
+
+ regs->Mb0Lo = 0;
+
+ /*
+ * Start the NIC CPU
+ */
+
+ regs->CpuCtrl = (regs->CpuCtrl & ~(CPU_HALT | CPU_TRACE));
+
+ /*
+ * Wait for the firmware to spin up - max 2 seconds.
+ */
+ myjif = jiffies + 3 * HZ;
+ while ((myjif > jiffies) && !ap->fw_running);
+ if (!ap->fw_running){
+ printk(KERN_ERR "%s: firmware NOT running!\n", dev->name);
+ return -EBUSY;
+ }
+
+ ap->next = root_dev;
+ root_dev = dev;
+
+ /*
+ * We load the ring here as there seem to be no way to tell the
+ * firmware to wipe the ring without re-initializing it.
+ */
+ ace_load_std_rx_ring(dev);
+
+ return 0;
+}
+
+
+/*
+ * Monitor the card to detect hangs.
+ */
+
+static void ace_timer(unsigned long data)
+{
+ struct device *dev = (struct device *)data;
+ struct ace_private *ap = (struct ace_private *)dev->priv;
+ struct ace_regs *regs = ap->regs;
+
+ /*
+ * We haven't received a stats update event for more than 2.5
+ * seconds and there is data in the transmit queue, thus we
+ * asume the card is stuck.
+ */
+ if (ap->tx_csm != ap->tx_ret_csm){
+ printk(KERN_WARNING "%s: Transmitter is stuck, %08x\n",
+ dev->name, regs->HostCtrl);
+ }
+
+ ap->timer.expires = jiffies + (5/2*HZ);
+ add_timer(&ap->timer);
+}
+
+
+/*
+ * Load the standard rx ring.
+ */
+static int ace_load_std_rx_ring(struct device *dev)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct ace_info *info;
+ unsigned long flags;
+ struct cmd cmd;
+ short i;
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+ info = ap->info;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ /*
+ * Set tx_csm before we start receiving interrupts, otherwise
+ * the interrupt handler might think it is supposed to process
+ * tx ints before we are up and running, which may cause a null
+ * pointer access in the int handler.
+ */
+ ap->tx_full = 0;
+ ap->cur_rx = ap->dirty_rx = 0;
+ ap->tx_prd = ap->tx_csm = ap->tx_ret_csm = 0;
+ regs->RxRetCsm = 0;
+
+ for (i = 0; i < RX_RING_THRESH; i++) {
+ struct sk_buff *skb;
+
+ ap->rx_std_ring[i].flags = 0;
+ skb = alloc_skb(ACE_STD_MTU + ETH_HLEN + 6, GFP_ATOMIC);
+ ap->rx_std_skbuff[i] = skb;
+
+ /*
+ * Make sure the data contents end up on an aligned address
+ */
+ skb_reserve(skb, 2);
+
+ ap->rx_std_ring[i].addr = virt_to_bus(skb->data);
+ ap->rx_std_ring[i].size = ACE_STD_MTU + ETH_HLEN + 4;
+
+ ap->rx_std_ring[i].flags = 0;
+ ap->rx_std_ring[i].type = DESC_RX;
+
+ ap->rx_std_ring[i].idx = i;
+ }
+
+ ap->rx_std_skbprd = i;
+
+ /*
+ * The last descriptor needs to be marked as being special.
+ */
+ ap->rx_std_ring[i-1].type = DESC_END;
+
+ cmd.evt = C_SET_RX_PRD_IDX;
+ cmd.code = 0;
+ cmd.idx = ap->rx_std_skbprd;
+ ace_issue_cmd(regs, &cmd);
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ return 0;
+}
+
+
+/*
+ * Load the jumbo rx ring, this may happen at any time if the MTU
+ * is changed to a value > 1500.
+ */
+static int ace_load_jumbo_rx_ring(struct device *dev)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct cmd cmd;
+ unsigned long flags;
+ short i;
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ for (i = 0; i < RX_RING_THRESH; i++) {
+ struct sk_buff *skb;
+
+ ap->rx_jumbo_ring[i].flags = 0;
+ skb = alloc_skb(ACE_JUMBO_MTU + ETH_HLEN + 6, GFP_ATOMIC);
+ ap->rx_jumbo_skbuff[i] = skb;
+
+ /*
+ * Make sure the data contents end up on an aligned address
+ */
+ skb_reserve(skb, 2);
+
+ ap->rx_jumbo_ring[i].addr = virt_to_bus(skb->data);
+ ap->rx_jumbo_ring[i].size = ACE_JUMBO_MTU + ETH_HLEN + 4;
+
+ ap->rx_jumbo_ring[i].flags = JUMBO_FLAG;
+ ap->rx_jumbo_ring[i].type = DESC_RX;
+
+ ap->rx_jumbo_ring[i].idx = i;
+ }
+
+ ap->rx_jumbo_skbprd = i;
+
+ /*
+ * The last descriptor needs to be marked as being special.
+ */
+ ap->rx_jumbo_ring[i-1].type = DESC_END;
+
+ cmd.evt = C_SET_RX_JUMBO_PRD_IDX;
+ cmd.code = 0;
+ cmd.idx = ap->rx_jumbo_skbprd;
+ ace_issue_cmd(regs, &cmd);
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ return 0;
+}
+
+
+/*
+ * Tell the firmware not to accept jumbos and flush the jumbo ring.
+ * This function must be called with the spinlock held.
+ */
+static int ace_flush_jumbo_rx_ring(struct device *dev)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct cmd cmd;
+ short i;
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+
+ if (ap->jumbo){
+ cmd.evt = C_RESET_JUMBO_RNG;
+ cmd.code = 0;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ for (i = 0; i < RX_JUMBO_RING_ENTRIES; i++) {
+ if (ap->rx_jumbo_skbuff[i]) {
+ ap->rx_jumbo_ring[i].size = 0;
+ ap->rx_jumbo_ring[i].addr = 0;
+ dev_kfree_skb(ap->rx_jumbo_skbuff[i]);
+ }
+ }
+ }else
+ printk(KERN_ERR "%s: Trying to flush Jumbo ring without "
+ "Jumbo support enabled\n", dev->name);
+
+ return 0;
+}
+
+
+/*
+ * All events are considered to be slow (RX/TX ints do not generate
+ * events) and are handled here, outside the main interrupt handler,
+ * to reduce the size of the handler.
+ */
+static u32 ace_handle_event(struct device *dev, u32 evtcsm, u32 evtprd)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+
+ while (evtcsm != evtprd){
+ switch (ap->evt_ring[evtcsm].evt){
+ case E_FW_RUNNING:
+ printk(KERN_INFO "%s: Firmware up and running\n",
+ dev->name);
+ ap->fw_running = 1;
+ break;
+ case E_STATS_UPDATED:
+ mod_timer(&ap->timer, jiffies + (5/2*HZ));
+ break;
+ case E_LNK_STATE:
+ {
+ u16 code = ap->evt_ring[evtcsm].code;
+ if (code == E_C_LINK_UP){
+ printk("%s: Optical link UP\n", dev->name);
+ }
+ else if (code == E_C_LINK_DOWN)
+ printk(KERN_INFO "%s: Optical link DOWN\n",
+ dev->name);
+ else
+ printk(KERN_INFO "%s: Unknown optical link "
+ "state %02x\n", dev->name, code);
+ break;
+ }
+ case E_ERROR:
+ switch(ap->evt_ring[evtcsm].code){
+ case E_C_ERR_INVAL_CMD:
+ printk(KERN_ERR "%s: invalid command error\n",
+ dev->name);
+ break;
+ case E_C_ERR_UNIMP_CMD:
+ printk(KERN_ERR "%s: unimplemented command "
+ "error\n", dev->name);
+ break;
+ case E_C_ERR_BAD_CFG:
+ printk(KERN_ERR "%s: bad config error\n",
+ dev->name);
+ break;
+ default:
+ printk(KERN_ERR "%s: unknown error %02x\n",
+ dev->name, ap->evt_ring[evtcsm].code);
+ }
+ break;
+ case E_RESET_JUMBO_RNG:
+ break;
+ default:
+ printk(KERN_ERR "%s: Unhandled event 0x%02x\n",
+ dev->name, ap->evt_ring[evtcsm].evt);
+ }
+ evtcsm = (evtcsm + 1) % EVT_RING_ENTRIES;
+ }
+
+ return evtcsm;
+}
+
+
+static int rx_int(struct device *dev, u32 rxretprd, u32 rxretcsm)
+{
+ struct ace_private *ap = (struct ace_private *)dev->priv;
+ u32 idx, oldidx;
+ struct ace_regs *regs = ap->regs;
+
+ idx = rxretcsm;
+
+ while(idx != rxretprd){
+ struct sk_buff *skb, *newskb, *oldskb;
+ struct rx_desc *newrxdesc, *oldrxdesc;
+ u32 prdidx, size;
+ unsigned long addr;
+ u16 csum;
+ int jumbo;
+
+ oldidx = ap->rx_return_ring[idx].idx;
+ jumbo = ap->rx_return_ring[idx].flags & JUMBO_FLAG;
+
+ if (jumbo){
+ oldskb = ap->rx_jumbo_skbuff[oldidx];
+ prdidx = ap->rx_jumbo_skbprd;
+ newrxdesc = &ap->rx_jumbo_ring[prdidx];
+ oldrxdesc = &ap->rx_jumbo_ring[oldidx];
+ }else{
+ oldskb = ap->rx_std_skbuff[oldidx];
+ prdidx = ap->rx_std_skbprd;
+ newrxdesc = &ap->rx_std_ring[prdidx];
+ oldrxdesc = &ap->rx_std_ring[oldidx];
+ }
+
+ size = oldrxdesc->size;
+
+ if (size < PKT_COPY_THRESHOLD) {
+ skb = alloc_skb(size + 2, GFP_ATOMIC);
+ if (skb == NULL){
+ printk(KERN_ERR "%s: Out of memory\n",
+ dev->name);
+ goto error;
+ }
+ /*
+ * Make sure the real data is aligned
+ */
+
+ skb_reserve(skb, 2);
+ memcpy(skb_put(skb, size), oldskb->data, size);
+ addr = oldrxdesc->addr;
+ newskb = oldskb;
+ }else{
+ skb = oldskb;
+
+ skb_put(skb, size);
+
+ newskb = alloc_skb(size + 2, GFP_ATOMIC);
+ if (newskb == NULL){
+ printk(KERN_ERR "%s: Out of memory\n",
+ dev->name);
+ goto error;
+ }
+
+ /*
+ * Make sure we DMA directly into nicely
+ * aligned receive buffers
+ */
+ skb_reserve(newskb, 2);
+ addr = virt_to_bus(newskb->data);
+ }
+
+ newrxdesc->addr = addr;
+ newrxdesc->size = size;
+
+ newrxdesc->flags = oldrxdesc->flags;
+ newrxdesc->idx = prdidx;
+ newrxdesc->type = DESC_RX;
+#if (BITS_PER_LONG == 32)
+ newrxdesc->zero = 0;
+#endif
+
+ oldrxdesc->size = 0;
+ oldrxdesc->addr = 0;
+
+ if (jumbo){
+ ap->rx_jumbo_skbuff[oldidx] = NULL;
+ ap->rx_jumbo_skbuff[prdidx] = newskb;
+
+ prdidx = (prdidx + 1) % RX_JUMBO_RING_ENTRIES;
+ ap->rx_jumbo_skbprd = prdidx;
+ }else{
+ ap->rx_std_skbuff[oldidx] = NULL;
+ ap->rx_std_skbuff[prdidx] = newskb;
+
+ prdidx = (prdidx + 1) % RX_STD_RING_ENTRIES;
+ ap->rx_std_skbprd = prdidx;
+ }
+
+ /*
+ * Fly baby, fly!
+ */
+ csum = ap->rx_return_ring[idx].tcp_udp_csum;
+
+ skb->dev = dev;
+ skb->protocol = eth_type_trans(skb, dev);
+
+ /*
+ * If the checksum is correct and this is not a
+ * fragment, tell the stack that the data is correct.
+ */
+ if(!(csum ^ 0xffff) &&
+ (!(((struct iphdr *)skb->data)->frag_off &
+ __constant_htons(IP_MF|IP_OFFSET))))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ netif_rx(skb); /* send it up */
+
+ ap->stats.rx_packets++;
+ ap->stats.rx_bytes += skb->len;
+
+ if ((prdidx & 0x7) == 0){
+ struct cmd cmd;
+ if (jumbo)
+ cmd.evt = C_SET_RX_JUMBO_PRD_IDX;
+ else
+ cmd.evt = C_SET_RX_PRD_IDX;
+ cmd.code = 0;
+ cmd.idx = prdidx;
+ ace_issue_cmd(regs, &cmd);
+ }
+
+ idx = (idx + 1) % RX_RETURN_RING_ENTRIES;
+ }
+ out:
+ regs->RxRetCsm = idx;
+ ap->cur_rx = idx;
+
+ return idx;
+ error:
+ idx = rxretprd;
+ goto out;
+}
+
+
+static void ace_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct device *dev = (struct device *)dev_id;
+ u32 txcsm, rxretcsm, rxretprd;
+ u32 evtcsm, evtprd;
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+
+ spin_lock(&ap->lock);
+
+ /*
+ * In case of PCI shared interrupts or spurious interrupts,
+ * we want to make sure it is actually our interrupt before
+ * spending any time in here.
+ */
+ if (!(regs->HostCtrl & IN_INT)){
+ spin_unlock(&ap->lock);
+ return;
+ }
+
+#if 0
+ /*
+ * Since we are also using a spinlock, I wonder if this is
+ * actually worth it.
+ */
+ if (test_and_set_bit(0, (void*)&dev->interrupt) != 0) {
+ printk(KERN_WARNING "%s: Re-entering the interrupt handler.\n",
+ dev->name);
+ return;
+ }
+#endif
+
+ /*
+ * Tell the card not to generate interrupts while we are in here.
+ */
+ regs->Mb0Lo = 1;
+
+ txcsm = ap->tx_csm;
+ if (txcsm != ap->tx_ret_csm) {
+ u32 idx = ap->tx_ret_csm;
+
+ do {
+ ap->stats.tx_packets++;
+ ap->stats.tx_bytes += ap->tx_skbuff[idx]->len;
+ dev_kfree_skb(ap->tx_skbuff[idx]);
+
+ ap->tx_skbuff[idx] = NULL;
+
+ ap->tx_ring[idx].size = 0;
+ ap->tx_ring[idx].addr = 0;
+ ap->tx_ring[idx].flags = 0;
+
+ idx = (idx + 1) % TX_RING_ENTRIES;
+ } while (idx != txcsm);
+
+ if (ap->tx_full && dev->tbusy &&
+ (((ap->tx_prd + 1) % TX_RING_ENTRIES) != txcsm)){
+ ap->tx_full = 0;
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+
+ ap->tx_ret_csm = txcsm;
+ }
+
+ rxretprd = ap->rx_ret_prd;
+ rxretcsm = ap->cur_rx;
+
+ if (rxretprd != rxretcsm)
+ rxretprd = rx_int(dev, rxretprd, rxretcsm);
+
+ evtcsm = regs->EvtCsm;
+ evtprd = ap->evt_prd;
+
+ if (evtcsm != evtprd){
+ evtcsm = ace_handle_event(dev, evtcsm, evtprd);
+ }
+
+ regs->EvtCsm = evtcsm;
+ regs->Mb0Lo = 0;
+
+ spin_unlock(&ap->lock);
+#if 0
+ dev->interrupt = 0;
+#endif
+}
+
+
+static int ace_open(struct device *dev)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct cmd cmd;
+
+ ap = dev->priv;
+ regs = ap->regs;
+
+ if (!(ap->fw_running)){
+ printk(KERN_WARNING "%s: firmware not running!\n", dev->name);
+ return -EBUSY;
+ }
+
+ regs->IfMtu = dev->mtu + ETH_HLEN + 4;
+
+ cmd.evt = C_HOST_STATE;
+ cmd.code = C_C_STACK_UP;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ if (ap->jumbo)
+ ace_load_jumbo_rx_ring(dev);
+
+ if (dev->flags & IFF_PROMISC){
+ cmd.evt = C_SET_PROMISC_MODE;
+ cmd.code = C_C_PROMISC_ENABLE;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ ap->promisc = 1;
+ }else
+ ap->promisc = 0;
+
+#if 0
+ { long myjif = jiffies + HZ;
+ while (jiffies < myjif);
+ }
+
+ cmd.evt = C_LNK_NEGOTIATION;
+ cmd.code = 0;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+#endif
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ MOD_INC_USE_COUNT;
+
+ /*
+ * Setup the timer
+ */
+ init_timer(&ap->timer);
+ ap->timer.expires = jiffies + 5/2 * HZ;
+ ap->timer.data = (unsigned long)dev;
+ ap->timer.function = &ace_timer;
+ add_timer(&ap->timer);
+ return 0;
+}
+
+
+static int ace_close(struct device *dev)
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+ struct cmd cmd;
+ unsigned long flags;
+ short i;
+
+ dev->start = 0;
+ set_bit(0, (void*)&dev->tbusy);
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+
+ del_timer(&ap->timer);
+
+ if (ap->promisc){
+ cmd.evt = C_SET_PROMISC_MODE;
+ cmd.code = C_C_PROMISC_DISABLE;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+ ap->promisc = 0;
+ }
+
+ cmd.evt = C_HOST_STATE;
+ cmd.code = C_C_STACK_DOWN;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ for (i = 0; i < TX_RING_ENTRIES; i++) {
+ if (ap->tx_skbuff[i]) {
+ ap->tx_ring[i].size = 0;
+ ap->tx_ring[i].addr = 0;
+ dev_kfree_skb(ap->tx_skbuff[i]);
+ }
+ }
+
+ if (ap->jumbo)
+ ace_flush_jumbo_rx_ring(dev);
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+
+static int ace_start_xmit(struct sk_buff *skb, struct device *dev)
+{
+ struct ace_private *ap = (struct ace_private *)dev->priv;
+ struct ace_regs *regs = ap->regs;
+ unsigned long flags;
+ u32 idx;
+
+ spin_lock_irqsave(&ap->lock, flags);
+
+ idx = ap->tx_prd;
+
+ ap->tx_skbuff[idx] = skb;
+ ap->tx_ring[idx].addr = virt_to_bus(skb->data);
+ ap->tx_ring[idx].size = skb->len;
+ ap->tx_ring[idx].flags = DESC_END;
+ idx = (idx + 1) % TX_RING_ENTRIES;
+
+ ap->tx_prd = idx;
+ regs->TxPrd = idx;
+
+ if ((idx + 1) % TX_RING_ENTRIES == ap->tx_ret_csm){
+ ap->tx_full = 1;
+ set_bit(0, (void*)&dev->tbusy);
+ }
+
+ spin_unlock_irqrestore(&ap->lock, flags);
+
+ dev->trans_start = jiffies;
+ return 0;
+}
+
+
+static int ace_change_mtu(struct device *dev, int new_mtu)
+{
+ struct ace_private *ap = dev->priv;
+ struct ace_regs *regs = ap->regs;
+
+ if ((new_mtu < 68) || (new_mtu > ACE_JUMBO_MTU))
+ return -EINVAL;
+
+ regs->IfMtu = new_mtu + ETH_HLEN + 4;
+ dev->mtu = new_mtu;
+
+ if (new_mtu > ACE_STD_MTU){
+ if (!(ap->jumbo)){
+ printk(KERN_INFO "%s: Enabling Jumbo frame "
+ "support\n", dev->name);
+ ap->jumbo = 1;
+ ace_load_jumbo_rx_ring(dev);
+ }
+ ap->jumbo = 1;
+ }else{
+ if (ap->jumbo){
+ ace_flush_jumbo_rx_ring(dev);
+
+ printk(KERN_INFO "%s: Disabling Jumbo frame support\n",
+ dev->name);
+ }
+ ap->jumbo = 0;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Set the hardware MAC address.
+ */
+static int ace_set_mac_addr(struct device *dev, void *p)
+{
+ struct sockaddr *addr=p;
+ struct ace_regs *regs;
+ u16 *da;
+ struct cmd cmd;
+
+ if(dev->start)
+ return -EBUSY;
+ memcpy(dev->dev_addr, addr->sa_data,dev->addr_len);
+
+ da = (u16 *)dev->dev_addr;
+
+ regs = ((struct ace_private *)dev->priv)->regs;
+ regs->MacAddrHi = da[0];
+ regs->MacAddrLo = (da[1] << 16) | da[2];
+
+ cmd.evt = C_SET_MAC_ADDR;
+ cmd.code = 0;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ return 0;
+}
+
+
+static void ace_set_multicast_list(struct device *dev)
+{
+ struct ace_private *ap = dev->priv;
+ struct ace_regs *regs = ap->regs;
+ struct cmd cmd;
+
+ if ((dev->flags & IFF_PROMISC) && !(ap->promisc)) {
+ cmd.evt = C_SET_PROMISC_MODE;
+ cmd.code = C_C_PROMISC_ENABLE;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ ap->promisc = 1;
+ }else if (!(dev->flags & IFF_PROMISC) && (ap->promisc)){
+ cmd.evt = C_SET_PROMISC_MODE;
+ cmd.code = C_C_PROMISC_DISABLE;
+ cmd.idx = 0;
+ ace_issue_cmd(regs, &cmd);
+
+ ap->promisc = 0;
+ }
+}
+
+
+static struct net_device_stats *ace_get_stats(struct device *dev)
+{
+ struct ace_private *ap = dev->priv;
+
+ return(&ap->stats);
+}
+
+
+__initfunc(int ace_copy(struct ace_regs *regs, void *src, u32 dest, int size))
+{
+ int tsize;
+ u32 tdest;
+
+ while(size > 0){
+ tsize = min(((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
+ min(size, ACE_WINDOW_SIZE));
+ tdest = dest & (ACE_WINDOW_SIZE - 1);
+ regs->WinBase = dest & ~(ACE_WINDOW_SIZE - 1);
+#ifdef __BIG_ENDIAN
+#error "data must be swapped here"
+#else
+#if 0
+ printk("copying %04x from %08x to %06x (Window addr %08x), winbase %02x\n", tsize, (unsigned)src, dest, (unsigned) ((void *)regs->Window + tdest), regs->WinBase);
+#endif
+ memcpy((void *)((void *)regs->Window + tdest), src, tsize);
+#endif
+ dest += tsize;
+ src += tsize;
+ size -= tsize;
+ }
+
+ return 0;
+}
+
+
+__initfunc(int ace_clear(struct ace_regs *regs, u32 dest, int size))
+{
+ int tsize;
+ u32 tdest;
+
+ while(size > 0){
+ tsize = min(((~dest & (ACE_WINDOW_SIZE - 1)) + 1),
+ min(size, ACE_WINDOW_SIZE));
+ tdest = dest & (ACE_WINDOW_SIZE - 1);
+ regs->WinBase = dest & ~(ACE_WINDOW_SIZE - 1);
+
+ memset((void *)((void *)regs->Window + tdest), 0, tsize);
+
+ dest += tsize;
+ size -= tsize;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Download the firmware into the SRAM on the NIC
+ *
+ * This operation requires the NIC to be halted and is performed with
+ * interrupts disabled and with the spinlock hold.
+ */
+__initfunc(int ace_load_firmware(struct device *dev))
+{
+ struct ace_private *ap;
+ struct ace_regs *regs;
+
+ ap = (struct ace_private *)dev->priv;
+ regs = ap->regs;
+
+ if (!(regs->CpuCtrl & CPU_HALTED)){
+ printk(KERN_ERR "%s: trying to download firmware while the "
+ "CPU is running!\n", dev->name);
+ return -EFAULT;
+ }
+
+ ace_clear(regs, 0x2000, 0x100000-0x2000);
+ if (ap->version == 1){
+ ace_copy(regs, tigonFwText, tigonFwTextAddr, tigonFwTextLen);
+ ace_copy(regs, tigonFwData, tigonFwDataAddr, tigonFwDataLen);
+ ace_copy(regs, tigonFwRodata, tigonFwRodataAddr,
+ tigonFwRodataLen);
+ ace_clear(regs, tigonFwBssAddr, tigonFwBssLen);
+ ace_clear(regs, tigonFwSbssAddr, tigonFwSbssLen);
+ }else if (ap->version == 2){
+ ace_clear(regs, tigon2FwBssAddr, tigon2FwBssLen);
+ ace_clear(regs, tigon2FwSbssAddr, tigon2FwSbssLen);
+ ace_copy(regs, tigon2FwText, tigon2FwTextAddr,tigon2FwTextLen);
+ ace_copy(regs, tigon2FwRodata, tigon2FwRodataAddr,
+ tigon2FwRodataLen);
+ ace_copy(regs, tigon2FwData, tigon2FwDataAddr,tigon2FwDataLen);
+ }
+
+ return 0;
+}
+
+
+/*
+ * The eeprom on the AceNIC is an Atmel i2c EEPROM.
+ *
+ * Accessing the EEPROM is `interesting' to say the least - don't read
+ * this code right after dinner.
+ *
+ * This is all about black magic and bit-banging the device .... I
+ * wonder in what hospital they have put the guy who designed the i2c
+ * specs.
+ *
+ * Oh yes, this is only the beginning!
+ */
+static void eeprom_start(struct ace_regs *regs)
+{
+ udelay(1);
+ regs->LocalCtrl |= (EEPROM_DATA_OUT | EEPROM_WRITE_ENABLE);
+ udelay(1);
+ regs->LocalCtrl |= EEPROM_CLK_OUT;
+ udelay(1);
+ regs->LocalCtrl &= ~EEPROM_DATA_OUT;
+ udelay(1);
+ regs->LocalCtrl &= ~EEPROM_CLK_OUT;
+}
+
+
+static void eeprom_prep(struct ace_regs *regs, u8 magic)
+{
+ short i;
+
+ udelay(2);
+ regs->LocalCtrl &= ~EEPROM_DATA_OUT;
+ regs->LocalCtrl |= EEPROM_WRITE_ENABLE;
+
+ for (i = 0; i < 8; i++, magic <<= 1) {
+ udelay(2);
+ if (magic & 0x80)
+ regs->LocalCtrl |= EEPROM_DATA_OUT;
+ else
+ regs->LocalCtrl &= ~EEPROM_DATA_OUT;
+
+ udelay(1);
+ regs->LocalCtrl |= EEPROM_CLK_OUT;
+ udelay(1);
+ regs->LocalCtrl &= ~(EEPROM_CLK_OUT | EEPROM_DATA_OUT);
+ }
+}
+
+
+static int eeprom_check_ack(struct ace_regs *regs)
+{
+ int state;
+
+ regs->LocalCtrl &= ~EEPROM_WRITE_ENABLE;
+ udelay(2);
+ regs->LocalCtrl |= EEPROM_CLK_OUT;
+ udelay(1);
+ /* sample data in middle of high clk */
+ state = (regs->LocalCtrl & EEPROM_DATA_IN) != 0;
+ udelay(1);
+ regs->LocalCtrl &= ~EEPROM_CLK_OUT;
+
+ return state;
+}
+
+
+static void eeprom_stop(struct ace_regs *regs)
+{
+ regs->LocalCtrl |= EEPROM_WRITE_ENABLE;
+ udelay(1);
+ regs->LocalCtrl &= ~EEPROM_DATA_OUT;
+ udelay(1);
+ regs->LocalCtrl |= EEPROM_CLK_OUT;
+ udelay(1);
+ regs->LocalCtrl |= EEPROM_DATA_OUT;
+ udelay(2);
+ regs->LocalCtrl &= ~EEPROM_CLK_OUT;
+}
+
+
+/*
+ * Read a whole byte from the EEPROM.
+ */
+static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset)
+{
+ u32 i;
+ u8 result = 0;
+
+ if (!regs){
+ printk(KERN_ERR "No regs!\n");
+ return 0;
+ }
+
+ eeprom_start(regs);
+
+ eeprom_prep(regs, EEPROM_WRITE_SELECT);
+ if (eeprom_check_ack(regs)){
+ printk("Unable to sync eeprom\n");
+ return 0;
+ }
+
+ eeprom_prep(regs, (offset >> 8) & 0xff);
+ if (eeprom_check_ack(regs))
+ return 0;
+
+ eeprom_prep(regs, offset & 0xff);
+ if (eeprom_check_ack(regs))
+ return 0;
+
+ eeprom_start(regs);
+ eeprom_prep(regs, EEPROM_READ_SELECT);
+ if (eeprom_check_ack(regs))
+ return 0;
+
+ for (i = 0; i < 8; i++) {
+ regs->LocalCtrl &= ~EEPROM_WRITE_ENABLE;
+ udelay(2);
+ regs->LocalCtrl |= EEPROM_CLK_OUT;
+ udelay(1);
+ /* sample data mid high clk */
+ result = (result << 1) |
+ ((regs->LocalCtrl & EEPROM_DATA_IN) != 0);
+ udelay(1);
+ regs->LocalCtrl &= ~EEPROM_CLK_OUT;
+ if (i == 7)
+ regs->LocalCtrl |= EEPROM_WRITE_ENABLE;
+ }
+
+ regs->LocalCtrl |= EEPROM_DATA_OUT;
+ udelay(1);
+ regs->LocalCtrl |= EEPROM_CLK_OUT;
+ udelay(2);
+ regs->LocalCtrl &= ~EEPROM_CLK_OUT;
+ eeprom_stop(regs);
+
+ return result;
+}
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -D__KERNEL__ -D__SMP__ -I/data/home/jes/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=686 -DMODULE -DMODVERSIONS -include /data/home/jes/linux/include/linux/modversions.h -c -o acenic.o acenic.c"
+ * End:
+ */
diff --git a/drivers/net/acenic.h b/drivers/net/acenic.h
new file mode 100644
index 000000000..e84be5f7b
--- /dev/null
+++ b/drivers/net/acenic.h
@@ -0,0 +1,612 @@
+#ifndef _ACENIC_H_
+#define _ACENIC_H_
+
+#if ((BITS_PER_LONG != 32) && (BITS_PER_LONG != 64))
+#error "BITS_PER_LONG not defined or not valid"
+#endif
+
+
+struct ace_regs {
+
+ u32 pad0[16]; /* PCI control registers */
+
+ u32 HostCtrl; /* 0x40 */
+ u32 LocalCtrl;
+
+ u32 pad1[2];
+
+ u32 MiscCfg; /* 0x50 */
+
+ u32 pad2[2];
+
+ u32 PciState;
+
+ u32 pad3[2]; /* 0x60 */
+
+ u32 WinBase;
+ u32 WinData;
+
+ u32 pad4[12]; /* 0x70 */
+
+ u32 DmaWriteState; /* 0xa0 */
+ u32 pad5[3];
+ u32 DmaReadState; /* 0xb0 */
+
+ u32 pad6[26];
+
+ u32 AssistState;
+
+ u32 pad7[8]; /* 0x120 */
+
+ u32 CpuCtrl; /* 0x140 */
+ u32 Pc;
+
+ u32 pad8[3];
+
+ u32 SramAddr; /* 0x154 */
+ u32 SramData;
+
+ u32 pad9[49];
+
+ u32 MacRxState; /* 0x220 */
+
+ u32 pad10[7];
+
+ u32 CpuBCtrl; /* 0x240 */
+ u32 PcB;
+
+ u32 pad11[3];
+
+ u32 SramBAddr; /* 0x254 */
+ u32 SramBData;
+
+ u32 pad12[105];
+
+ u32 pad13[32]; /* 0x400 */
+ u32 Stats[32];
+
+ u32 Mb0Hi; /* 0x500 */
+ u32 Mb0Lo;
+ u32 Mb1Hi;
+ u32 CmdPrd;
+ u32 Mb2Hi;
+ u32 TxPrd;
+ u32 Mb3Hi;
+ u32 Mb3Lo;
+ u32 Mb4Hi;
+ u32 Mb4Lo;
+ u32 Mb5Hi;
+ u32 Mb5Lo;
+ u32 Mb6Hi;
+ u32 Mb6Lo;
+ u32 Mb7Hi;
+ u32 Mb7Lo;
+ u32 Mb8Hi;
+ u32 Mb8Lo;
+ u32 Mb9Hi;
+ u32 Mb9Lo;
+ u32 MbAHi;
+ u32 MbALo;
+ u32 MbBHi;
+ u32 MbBLo;
+ u32 MbCHi;
+ u32 MbCLo;
+ u32 MbDHi;
+ u32 MbDLo;
+ u32 MbEHi;
+ u32 MbELo;
+ u32 MbFHi;
+ u32 MbFLo;
+
+ u32 pad14[32];
+
+ u32 MacAddrHi; /* 0x600 */
+ u32 MacAddrLo;
+ u32 InfoPtrHi;
+ u32 InfoPtrLo;
+ u32 MultiCastHi; /* 0x610 */
+ u32 MultiCastLo;
+ u32 ModeStat;
+ u32 DmaReadCfg;
+ u32 DmaWriteCfg; /* 0x620 */
+ u32 pad15;
+ u32 EvtCsm;
+ u32 CmdCsm;
+ u32 TuneRxCoalTicks;/* 0x630 */
+ u32 TuneTxCoalTicks;
+ u32 TuneStatTicks;
+ u32 TuneMaxTxDesc;
+ u32 TuneMaxRxDesc; /* 0x640 */
+ u32 TuneTrace;
+ u32 TuneLink;
+ u32 TuneFastLink;
+ u32 TracePtr; /* 0x650 */
+ u32 TraceStrt;
+ u32 TraceLen;
+ u32 IfIdx;
+ u32 IfMtu; /* 0x660 */
+ u32 MaskInt;
+ u32 LnkState;
+ u32 FastLnkState;
+ u32 pad16[4]; /* 0x670 */
+ u32 RxRetCsm; /* 0x680 */
+
+ u32 pad17[31];
+
+ u32 CmdRng[64]; /* 0x700 */
+ u32 Window[0x200];
+};
+
+#define ACE_WINDOW_SIZE 0x800
+
+#define ACE_JUMBO_MTU 9000
+#define ACE_STD_MTU 1500
+
+/*
+ * Host control register bits.
+ */
+
+#define IN_INT 0x01
+#define CLR_INT 0x02
+#define BYTE_SWAP 0x10
+#define WORD_SWAP 0x20
+#define MASK_INTS 0x40
+
+/*
+ * Local control register bits.
+ */
+
+#define EEPROM_DATA_IN 0x800000
+#define EEPROM_DATA_OUT 0x400000
+#define EEPROM_WRITE_ENABLE 0x200000
+#define EEPROM_CLK_OUT 0x100000
+
+#define EEPROM_BASE 0xa0000000
+
+#define EEPROM_WRITE_SELECT 0xa0
+#define EEPROM_READ_SELECT 0xa1
+
+#define SRAM_BANK_512K 0x200
+
+
+/*
+ * Misc Config bits
+ */
+
+#define SYNC_SRAM_TIMING 0x100000
+
+
+/*
+ * CPU state bits.
+ */
+
+#define CPU_RESET 0x01
+#define CPU_TRACE 0x02
+#define CPU_PROM_FAILED 0x10
+#define CPU_HALT 0x00010000
+#define CPU_HALTED 0xffff0000
+
+
+/*
+ * PCI State bits.
+ */
+
+#define DMA_READ_MAX_4 0x04
+#define DMA_READ_MAX_16 0x08
+#define DMA_READ_MAX_32 0x0c
+#define DMA_READ_MAX_64 0x10
+#define DMA_READ_MAX_128 0x14
+#define DMA_READ_MAX_256 0x18
+#define DMA_READ_MAX_1K 0x1c
+#define DMA_WRITE_MAX_4 0x20
+#define DMA_WRITE_MAX_16 0x40
+#define DMA_WRITE_MAX_32 0x60
+#define DMA_WRITE_MAX_64 0x80
+#define DMA_WRITE_MAX_128 0xa0
+#define DMA_WRITE_MAX_256 0xc0
+#define DMA_WRITE_MAX_1K 0xe0
+#define DMA_WRITE_ALL_ALIGN 0x00800000
+#define READ_CMD_MEM 0x06000000
+#define WRITE_CMD_MEM 0x70000000
+
+
+/*
+ * Transmit status.
+ */
+
+#define ENA_XMIT 0x01
+#define PERM_CON 0x02
+
+
+/*
+ * Mode status
+ */
+
+#define ACE_BYTE_SWAP_DATA 0x10
+#define ACE_WARN 0x08
+#define ACE_WORD_SWAP 0x04
+#define ACE_FATAL 0x40000000
+
+
+/*
+ * DMA config
+ */
+
+#define DMA_THRESH_8W 0x80;
+
+
+/*
+ * Tuning parameters
+ */
+
+#define TICKS_PER_SEC 1000000
+
+
+/*
+ * Link bits
+ */
+
+#define LNK_PREF 0x00008000
+#define LNK_10MB 0x00010000
+#define LNK_100MB 0x00020000
+#define LNK_1000MB 0x00040000
+#define LNK_FULL_DUPLEX 0x00080000
+#define LNK_HALF_DUPLEX 0x00100000
+#define LNK_TX_FLOW_CTL_Y 0x00200000
+#define LNK_NEG_ADVANCED 0x00400000
+#define LNK_RX_FLOW_CTL_Y 0x00800000
+#define LNK_NIC 0x01000000
+#define LNK_JAM 0x02000000
+#define LNK_JUMBO 0x04000000
+#define LNK_ALTEON 0x08000000
+#define LNK_NEG_FCTL 0x10000000
+#define LNK_NEGOTIATE 0x20000000
+#define LNK_ENABLE 0x40000000
+#define LNK_UP 0x80000000
+
+
+/*
+ * Event definitions
+ */
+
+#define EVT_RING_ENTRIES 256
+#define EVT_RING_SIZE (EVT_RING_ENTRIES * sizeof(struct event))
+
+struct event {
+#ifdef __LITTLE_ENDIAN
+ u32 idx:12;
+ u32 code:12;
+ u32 evt:8;
+#else
+ u32 evt:8;
+ u32 code:12;
+ u32 idx:12;
+#endif
+ u32 pad;
+};
+
+
+/*
+ * Events
+ */
+
+#define E_FW_RUNNING 0x01
+#define E_STATS_UPDATED 0x04
+
+#define E_STATS_UPDATE 0x04
+
+#define E_LNK_STATE 0x06
+#define E_C_LINK_UP 0x01
+#define E_C_LINK_DOWN 0x02
+
+#define E_ERROR 0x07
+#define E_C_ERR_INVAL_CMD 0x01
+#define E_C_ERR_UNIMP_CMD 0x02
+#define E_C_ERR_BAD_CFG 0x03
+
+#define E_MCAST_LIST 0x08
+#define E_C_MCAST_ADDR_ADD 0x01
+#define E_C_MCAST_ADDR_DEL 0x02
+
+#define E_RESET_JUMBO_RNG 0x09
+
+
+/*
+ * Commands
+ */
+
+#define CMD_RING_ENTRIES 64
+
+struct cmd {
+#ifdef __LITTLE_ENDIAN
+ u32 idx:12;
+ u32 code:12;
+ u32 evt:8;
+#else
+ u32 evt:8;
+ u32 code:12;
+ u32 idx:12;
+#endif
+};
+
+
+#define C_HOST_STATE 0x01
+#define C_C_STACK_UP 0x01
+#define C_C_STACK_DOWN 0x02
+
+#define C_FDR_FILTERING 0x02
+#define C_C_FDR_FILT_ENABLE 0x01
+#define C_C_FDR_FILT_DISABLE 0x02
+
+#define C_SET_RX_PRD_IDX 0x03
+#define C_UPDATE_STATS 0x04
+#define C_RESET_JUMBO_RNG 0x05
+#define C_ADD_MULTICAST_ADDR 0x08
+#define C_DEL_MULTICAST_ADDR 0x09
+
+#define C_SET_PROMISC_MODE 0x0a
+#define C_C_PROMISC_ENABLE 0x01
+#define C_C_PROMISC_DISABLE 0x02
+
+#define C_LNK_NEGOTIATION 0x0b
+#define C_SET_MAC_ADDR 0x0c
+#define C_CLEAR_PROFILE 0x0d
+
+#define C_SET_MULTICAST_MODE 0x0e
+#define C_C_MCAST_ENABLE 0x01
+#define C_C_MCAST_DISABLE 0x02
+
+#define C_CLEAR_STATS 0x0f
+#define C_SET_RX_JUMBO_PRD_IDX 0x10
+#define C_REFRESH_STATS 0x11
+
+
+/*
+ * Descriptor types.
+ */
+
+#define DESC_TX 0x01
+#define DESC_RX 0x02
+#define DESC_END 0x04
+#define DESC_MORE 0x08
+
+/*
+ * RX control block flags
+ */
+
+#define RX_TCP_UDP_SUM 0x01
+#define RX_IP_SUM 0x02
+#define RX_SPLIT_HDRS 0x04
+#define RX_NO_PSEUDO_HDR_SUM 0x08
+
+/*
+ * Descriptor flags
+ */
+
+#define JUMBO_FLAG 0x10
+
+/*
+ * TX ring
+ */
+
+#define TX_RING_ENTRIES 128
+#define TX_RING_SIZE (TX_RING_ENTRIES * sizeof(struct tx_desc))
+#define TX_RING_BASE 0x3800
+
+struct tx_desc{
+#if (BITS_PER_LONG == 64)
+ u64 addr;
+#else
+ u32 zero;
+ u32 addr;
+#endif
+#if __LITTLE_ENDIAN
+ u16 flags;
+ u16 size;
+#else
+ u16 size;
+ u16 flags;
+#endif
+ u32 nic_addr;
+};
+
+
+#define RX_STD_RING_ENTRIES 512
+#define RX_STD_RING_SIZE (RX_STD_RING_ENTRIES * sizeof(struct rx_desc))
+
+#define RX_JUMBO_RING_ENTRIES 256
+#define RX_JUMBO_RING_SIZE (RX_JUMBO_RING_ENTRIES *sizeof(struct rx_desc))
+
+#define RX_RETURN_RING_ENTRIES (2 * RX_STD_RING_ENTRIES)
+#define RX_RETURN_RING_SIZE (RX_RETURN_RING_ENTRIES * \
+ sizeof(struct rx_desc))
+
+#define RX_RING_THRESH 32
+
+struct rx_desc{
+#if (BITS_PER_LONG == 64)
+ u64 addr;
+#else
+ u32 zero;
+ u32 addr;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u16 size;
+ u16 idx;
+#else
+ u16 idx;
+ u16 size;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u16 flags;
+ u16 type;
+#else
+ u16 type;
+ u16 flags;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u16 tcp_udp_csum;
+ u16 ip_csum;
+#else
+ u16 ip_csum;
+ u16 tcp_udp_csum;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u16 reserved;
+ u16 err_flags;
+#else
+ u16 err_flags;
+ u16 reserved;
+#endif
+ u32 nic_addr;
+ u32 pad[1];
+};
+
+
+/*
+ * This struct is shared with the NIC firmware.
+ */
+struct ring_ctrl {
+#if (BITS_PER_LONG == 64)
+ u64 rngptr;
+#else
+ u32 zero;
+ u32 rngptr;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u16 flags;
+ u16 max_len;
+#else
+ u16 max_len;
+ u16 flags;
+#endif
+ u32 pad;
+};
+
+
+struct ace_mac_stats {
+ u32 excess_colls;
+ u32 coll_1;
+ u32 coll_2;
+ u32 coll_3;
+ u32 coll_4;
+ u32 coll_5;
+ u32 coll_6;
+ u32 coll_7;
+ u32 coll_8;
+ u32 coll_9;
+ u32 coll_10;
+ u32 coll_11;
+ u32 coll_12;
+ u32 coll_13;
+ u32 coll_14;
+ u32 coll_15;
+ u32 late_coll;
+ u32 defers;
+ u32 crc_err;
+ u32 underrun;
+ u32 crs_err;
+ u32 pad[3];
+ u32 drop_ula;
+ u32 drop_mc;
+ u32 drop_fc;
+ u32 drop_space;
+ u32 coll;
+ u32 kept_bc;
+ u32 kept_mc;
+ u32 kept_uc;
+};
+
+
+struct ace_info {
+ union {
+ u32 stats[256];
+ } s;
+ struct ring_ctrl evt_ctrl;
+ struct ring_ctrl cmd_ctrl;
+ struct ring_ctrl tx_ctrl;
+ struct ring_ctrl rx_std_ctrl;
+ struct ring_ctrl rx_jumbo_ctrl;
+ struct ring_ctrl rx_return_ctrl;
+#if (BITS_PER_LONG == 64)
+ u64 evt_prd_ptr;
+ u64 rx_ret_prd_ptr;
+ u64 tx_csm_ptr;
+ u64 stats2_ptr;
+#else
+ u32 evt_prd_ptr_hi;
+ u32 evt_prd_ptr;
+ u32 rx_ret_prd_ptr_hi;
+ u32 rx_ret_prd_ptr;
+ u32 tx_csm_ptr_hi;
+ u32 tx_csm_ptr;
+ u32 stats2_ptr_hi;
+ u32 stats2_ptr;
+#endif
+};
+
+/*
+ * Struct private for the AceNIC.
+ */
+
+struct ace_private
+{
+ struct ace_regs *regs; /* register base */
+ volatile __u32 *sgt;
+ struct sk_buff *pkt_buf; /* Receive buffer */
+/*
+ * The send ring is located in the shared memory window
+ */
+ struct tx_desc *tx_ring;
+ struct rx_desc rx_std_ring[RX_STD_RING_ENTRIES];
+ struct rx_desc rx_jumbo_ring[RX_JUMBO_RING_ENTRIES];
+ struct rx_desc rx_return_ring[RX_RETURN_RING_ENTRIES];
+ struct event evt_ring[EVT_RING_ENTRIES];
+ struct ace_info *info;
+ struct sk_buff *tx_skbuff[TX_RING_ENTRIES];
+ struct sk_buff *rx_std_skbuff[RX_STD_RING_ENTRIES];
+ struct sk_buff *rx_jumbo_skbuff[RX_JUMBO_RING_ENTRIES];
+ spinlock_t lock;
+ struct timer_list timer;
+ u32 cur_rx, tx_prd;
+ u32 dirty_rx, tx_ret_csm, dirty_event;
+ u32 rx_std_skbprd, rx_jumbo_skbprd;
+ u32 tx_full;
+ volatile u32 evt_prd
+ __attribute__ ((aligned (L1_CACHE_BYTES)));
+ volatile u32 rx_ret_prd
+ __attribute__ ((aligned (L1_CACHE_BYTES)));
+ volatile u32 tx_csm
+ __attribute__ ((aligned (L1_CACHE_BYTES)));
+ struct device *next
+ __attribute__ ((aligned (L1_CACHE_BYTES)));
+ int fw_running, fw_up, jumbo, promisc;
+ int version;
+ int vendor;
+ u16 pci_command;
+ u8 pci_bus;
+ u8 pci_dev_fun;
+ char name[24];
+ struct net_device_stats stats;
+};
+
+/*
+ * Prototypes
+ */
+static int ace_init(struct device *dev);
+static int ace_load_std_rx_ring(struct device *dev);
+static int ace_load_jumbo_rx_ring(struct device *dev);
+static int ace_flush_jumbo_rx_ring(struct device *dev);
+static void ace_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static int ace_open(struct device *dev);
+static int ace_start_xmit(struct sk_buff *skb, struct device *dev);
+static int ace_close(struct device *dev);
+static void ace_timer(unsigned long data);
+static void ace_set_multicast_list(struct device *dev);
+static int ace_change_mtu(struct device *dev, int new_mtu);
+static int ace_set_mac_addr(struct device *dev, void *p);
+static struct net_device_stats *ace_get_stats(struct device *dev);
+static u8 read_eeprom_byte(struct ace_regs *regs, unsigned long offset);
+
+#endif /* _ACENIC_H_ */
diff --git a/drivers/net/acenic_firmware.h b/drivers/net/acenic_firmware.h
new file mode 100644
index 000000000..2c7d4f478
--- /dev/null
+++ b/drivers/net/acenic_firmware.h
@@ -0,0 +1,5517 @@
+/* Generated by genfw.c */
+int tigonFwReleaseMajor = 0xc;
+int tigonFwReleaseMinor = 0x1;
+int tigonFwReleaseFix = 0x4;
+u32 tigonFwStartAddr = 0x4000;
+u32 tigonFwTextAddr = 0x4000;
+int tigonFwTextLen = 0x10300;
+u32 tigonFwDataAddr = 0x14d40;
+int tigonFwDataLen = 0x140;
+u32 tigonFwRodataAddr = 0x14300;
+int tigonFwRodataLen = 0xa20;
+u32 tigonFwBssAddr = 0x14eb0;
+int tigonFwBssLen = 0x2080;
+u32 tigonFwSbssAddr = 0x14e80;
+int tigonFwSbssLen = 0x28;
+u32 tigonFwText[(MAX_TEXT_LEN/4) + 1] = {
+0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001, 0x8fbd4d74,
+0x3a0f021, 0x3c100000, 0x26104000, 0xc00100c, 0x0, 0xd,
+0x27bdffd8, 0x3c1cc000, 0x3c1b0013, 0x377bd800, 0xd021, 0x3c170013,
+0x36f75430, 0x2e02021, 0x340583d0, 0xafbf0024, 0xc00242c, 0xafb00020,
+0xc00238c, 0x0, 0x3c040001, 0x24844360, 0x24050001, 0x2e03021,
+0x3821, 0x3c100001, 0x26106f30, 0xafb00010, 0xc0023a7, 0xafbb0014,
+0x3c02000f, 0x3442ffff, 0x2021024, 0x362102b, 0x10400009, 0x24050003,
+0x3c040001, 0x2484436c, 0x2003021, 0x3603821, 0x3c020010, 0xafa20010,
+0xc0023a7, 0xafa00014, 0x2021, 0x3405c000, 0x3c010001, 0x370821,
+0xa02083a0, 0x3c010001, 0x370821, 0xa02083a2, 0x3c010001, 0x370821,
+0xa02083a3, 0x3c010001, 0x370821, 0xac2083a4, 0xa2e004c8, 0x418c0,
+0x24840001, 0x771021, 0xac40726c, 0x771021, 0xac407270, 0x2e31021,
+0xa445726c, 0x2c820020, 0x1440fff7, 0x418c0, 0x2021, 0x3405c000,
+0x418c0, 0x24840001, 0x771021, 0xac40736c, 0x771021, 0xac407370,
+0x2e31021, 0xa445736c, 0x2c820080, 0x5440fff7, 0x418c0, 0xaf800054,
+0xaf80011c, 0x8f820044, 0x34420040, 0xaf820044, 0x8f820044, 0x34420020,
+0xaf820044, 0x8f420218, 0x30420002, 0x10400009, 0x0, 0x8f420220,
+0x3c030002, 0x34630004, 0x431025, 0xaee204b4, 0x8f42021c, 0x8001074,
+0x34420004, 0x8f420220, 0x3c030002, 0x34630006, 0x431025, 0xaee204b4,
+0x8f42021c, 0x34420006, 0xaee204bc, 0x8f420218, 0x30420010, 0x1040000a,
+0x0, 0x8f42021c, 0x34420004, 0xaee204b8, 0x8f420220, 0x3c03000a,
+0x34630004, 0x431025, 0x800108a, 0xaee204b0, 0x8f420220, 0x3c03000a,
+0x34630006, 0x431025, 0xaee204b0, 0x8f42021c, 0x34420006, 0xaee204b8,
+0x8f420218, 0x30420200, 0x10400003, 0x24020001, 0x8001091, 0xa2e27238,
+0xa2e07238, 0x24020001, 0xaf8200a0, 0xaf8200b0, 0x8f830054, 0x8f820054,
+0x8001099, 0x24630064, 0x8f820054, 0x621023, 0x2c420065, 0x1440fffc,
+0x0, 0xaf800044, 0x8f420208, 0x8f43020c, 0xaee20010, 0xaee30014,
+0x8ee40010, 0x8ee50014, 0x26e20030, 0xaee20028, 0x24020480, 0xaee20018,
+0xaf840090, 0xaf850094, 0x8ee20028, 0xaf8200b4, 0x96e2001a, 0xaf82009c,
+0x8f8200b0, 0x8ee304bc, 0x431025, 0xaf8200b0, 0x8f8200b0, 0x30420004,
+0x1440fffd, 0x0, 0x8ee20450, 0x8ee30454, 0xaee304ec, 0x8ee204ec,
+0x2442e000, 0x2c422001, 0x1440000d, 0x26e40030, 0x8ee20450, 0x8ee30454,
+0x3c040001, 0x24844378, 0x3c050001, 0xafa00010, 0xafa00014, 0x8ee704ec,
+0x34a5f000, 0xc0023a7, 0x603021, 0x26e40030, 0xc00242c, 0x24050400,
+0x27440080, 0xc00242c, 0x24050080, 0x26e4776c, 0xc00242c, 0x24050400,
+0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260, 0x27450200, 0x24060008,
+0xaee20068, 0x24020006, 0xc00243e, 0xaee20064, 0x3c023b9a, 0x3442ca00,
+0x2021, 0x24030002, 0xaee30074, 0xaee30070, 0xaee2006c, 0x240203e8,
+0xaee20104, 0x24020001, 0xaee30100, 0xaee2010c, 0x3c030001, 0x641821,
+0x90634d40, 0x2e41021, 0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8,
+0x0, 0x8f820040, 0x2e41821, 0x24840001, 0x21702, 0x24420030,
+0xa062009c, 0x2e41021, 0xa040009c, 0x96e2046a, 0x30420003, 0x14400009,
+0x0, 0x96e2047a, 0x30420003, 0x5040012b, 0x3c030800, 0x96e2046a,
+0x30420003, 0x1040002a, 0x3c020700, 0x96e2047a, 0x30420003, 0x10400026,
+0x3c020700, 0x96e3047a, 0x96e2046a, 0x14620022, 0x3c020700, 0x8ee204b0,
+0x24030001, 0xa2e34e10, 0x34420e00, 0xaee204b0, 0x8f420218, 0x30420100,
+0x10400005, 0x0, 0x3c020001, 0x2442ded0, 0x800111d, 0x21100,
+0x3c020001, 0x2442d0d0, 0x21100, 0x21182, 0x3c030800, 0x431025,
+0x3c010001, 0xac220f38, 0x3c020001, 0x2442f3c8, 0x21100, 0x21182,
+0x3c030800, 0x431025, 0x3c010001, 0xac220f78, 0x8ee20000, 0x34424000,
+0x8001232, 0xaee20000, 0x34423000, 0xafa20018, 0x8ee205f8, 0x8f430228,
+0x24420001, 0x304900ff, 0x512300dc, 0xafa00010, 0x8ee205f8, 0x210c0,
+0x571021, 0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f870120,
+0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128,
+0x15020007, 0x1021, 0x8ee201a0, 0x3021, 0x24420001, 0xaee201a0,
+0x800119d, 0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430,
+0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000,
+0xace50004, 0x8ee305f8, 0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
+0xace9001c, 0x318c0, 0x246305fc, 0x2e31021, 0xace20008, 0x8ee204b4,
+0xace20010, 0xaf880120, 0x92e24e10, 0x14400037, 0x24060001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x8001187,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x800119d,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54c0000c,
+0xaee905f8, 0x3c040001, 0x24844384, 0xafa00010, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f000, 0x800121d, 0x0,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20007, 0x0, 0x8ee201a0, 0x3021, 0x24420001,
+0xaee201a0, 0x8001201, 0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490,
+0x8ee50494, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011,
+0xac620018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120,
+0x92e24e10, 0x14400037, 0x24060001, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x8c830000, 0x24020012, 0x1462001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007, 0x0, 0x8ee24e24,
+0x24420001, 0x10a20005, 0x0, 0x80011eb, 0x0, 0x14a00005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400013, 0xac800000, 0x8001201, 0x0, 0x8ee24e20,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x24020012,
+0xac820000, 0x24020001, 0xac820004, 0x14c0001b, 0x0, 0x3c040001,
+0x2484438c, 0xafa00010, 0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009,
+0xc0023a7, 0x34a5f001, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x800121d,
+0x8ee201ac, 0x3c040001, 0x24844398, 0xafa00014, 0x8ee605f8, 0x8f470228,
+0x3c050009, 0xc0023a7, 0x34a5f005, 0x8ee201a8, 0x24420001, 0xaee201a8,
+0x8ee201a8, 0x8ee2015c, 0x3c040001, 0x248443a4, 0x3405f001, 0x24420001,
+0xaee2015c, 0x8ee2015c, 0x3021, 0x3821, 0xafa00010, 0xc0023a7,
+0xafa00014, 0x8001232, 0x0, 0x3c020001, 0x2442f2f0, 0x21100,
+0x21182, 0x431025, 0x3c010001, 0xac220f78, 0x96e2045a, 0x30420003,
+0x10400025, 0x3c050fff, 0x8ee204b8, 0x34a5ffff, 0x34420a00, 0xaee204b8,
+0x8ee304b8, 0x3c040001, 0x248443b0, 0x24020001, 0xa2e204dc, 0xa2e204dd,
+0x3c020002, 0x621825, 0x3c020001, 0x2442a1c0, 0x451024, 0x21082,
+0xaee304b8, 0x3c030800, 0x431025, 0x3c010001, 0xac220f20, 0x3c020001,
+0x2442abb4, 0x451024, 0x21082, 0x431025, 0x3c010001, 0xac220f80,
+0x96e6045a, 0x3821, 0x24050011, 0xafa00010, 0xc0023a7, 0xafa00014,
+0x8001262, 0x0, 0x3c020001, 0x2442a7e0, 0x21100, 0x21182,
+0x3c030800, 0x431025, 0x3c010001, 0xac220f80, 0x96e2046a, 0x30420010,
+0x14400009, 0x0, 0x96e2047a, 0x30420010, 0x1040010c, 0x0,
+0x96e2046a, 0x30420010, 0x10400005, 0x3c020700, 0x96e2047a, 0x30420010,
+0x144000fc, 0x3c020700, 0x34423000, 0xafa20018, 0x8ee205f8, 0x8f430228,
+0x24420001, 0x304900ff, 0x512300dc, 0xafa00010, 0x8ee205f8, 0x210c0,
+0x571021, 0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f870120,
+0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128,
+0x15020007, 0x1021, 0x8ee201a0, 0x3021, 0x24420001, 0xaee201a0,
+0x80012e1, 0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430,
+0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000,
+0xace50004, 0x8ee305f8, 0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
+0xace9001c, 0x318c0, 0x246305fc, 0x2e31021, 0xace20008, 0x8ee204b4,
+0xace20010, 0xaf880120, 0x92e24e10, 0x14400037, 0x24060001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x80012cb,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x80012e1,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54c0000c,
+0xaee905f8, 0x3c040001, 0x24844384, 0xafa00010, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f000, 0x8001361, 0x0,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20007, 0x0, 0x8ee201a0, 0x3021, 0x24420001,
+0xaee201a0, 0x8001345, 0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490,
+0x8ee50494, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011,
+0xac620018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120,
+0x92e24e10, 0x14400037, 0x24060001, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x8c830000, 0x24020012, 0x1462001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007, 0x0, 0x8ee24e24,
+0x24420001, 0x10a20005, 0x0, 0x800132f, 0x0, 0x14a00005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400013, 0xac800000, 0x8001345, 0x0, 0x8ee24e20,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x24020012,
+0xac820000, 0x24020001, 0xac820004, 0x14c0001b, 0x0, 0x3c040001,
+0x2484438c, 0xafa00010, 0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009,
+0xc0023a7, 0x34a5f001, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8001361,
+0x8ee201ac, 0x3c040001, 0x24844398, 0xafa00014, 0x8ee605f8, 0x8f470228,
+0x3c050009, 0xc0023a7, 0x34a5f005, 0x8ee201a8, 0x24420001, 0xaee201a8,
+0x8ee201a8, 0x8ee2015c, 0x3c040001, 0x248443a4, 0x3405f002, 0x24420001,
+0xaee2015c, 0x8ee2015c, 0x3021, 0x3821, 0xafa00010, 0xc0023a7,
+0xafa00014, 0x96e6047a, 0x96e7046a, 0x3c040001, 0x248443bc, 0x24050012,
+0xafa00010, 0xc0023a7, 0xafa00014, 0xc004440, 0x0, 0xc0022b8,
+0x0, 0x3c060001, 0x34c63800, 0xaee005f8, 0xaf400228, 0xaf40022c,
+0x96e30458, 0x8ee40000, 0x3c0512d8, 0x34a5c358, 0x27623800, 0xaee27248,
+0x27623800, 0xaee27250, 0x27623800, 0xaee27254, 0x3661021, 0xaee27260,
+0x2402ffff, 0xaee004c4, 0xaee004d0, 0xaee004d4, 0xaee004e0, 0xa2e004e4,
+0xaee00dfc, 0xaee00e08, 0xaee00e00, 0xaee00e04, 0xaee00e0c, 0xaee0723c,
+0xaee05234, 0xaee05230, 0xaee0522c, 0xaee07240, 0xaee07244, 0xaee0724c,
+0xaee07258, 0xaee004c0, 0x2463ffff, 0x852025, 0xaee304e8, 0xaee40000,
+0xaf800060, 0xaf820064, 0x3c020100, 0xafa20018, 0x8ee205f8, 0x8f430228,
+0x24420001, 0x304900ff, 0x512300dc, 0xafa00010, 0x8ee205f8, 0x210c0,
+0x571021, 0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f870120,
+0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128,
+0x15020007, 0x1021, 0x8ee201a0, 0x3021, 0x24420001, 0xaee201a0,
+0x8001413, 0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430,
+0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000,
+0xace50004, 0x8ee305f8, 0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
+0xace9001c, 0x318c0, 0x246305fc, 0x2e31021, 0xace20008, 0x8ee204b4,
+0xace20010, 0xaf880120, 0x92e24e10, 0x14400037, 0x24060001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x80013fd,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x8001413,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54c0000c,
+0xaee905f8, 0x3c040001, 0x24844384, 0xafa00010, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f000, 0x8001493, 0x0,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20007, 0x0, 0x8ee201a0, 0x3021, 0x24420001,
+0xaee201a0, 0x8001477, 0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490,
+0x8ee50494, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011,
+0xac620018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120,
+0x92e24e10, 0x14400037, 0x24060001, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x8c830000, 0x24020012, 0x1462001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007, 0x0, 0x8ee24e24,
+0x24420001, 0x10a20005, 0x0, 0x8001461, 0x0, 0x14a00005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400013, 0xac800000, 0x8001477, 0x0, 0x8ee24e20,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x24020012,
+0xac820000, 0x24020001, 0xac820004, 0x14c0001b, 0x0, 0x3c040001,
+0x2484438c, 0xafa00010, 0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009,
+0xc0023a7, 0x34a5f001, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x8001493,
+0x8ee201ac, 0x3c040001, 0x24844398, 0xafa00014, 0x8ee605f8, 0x8f470228,
+0x3c050009, 0xc0023a7, 0x34a5f005, 0x8ee201a8, 0x24420001, 0xaee201a8,
+0x8ee201a8, 0x8ee20150, 0x24420001, 0xaee20150, 0xc0014c8, 0x8ee20150,
+0x8f8200a0, 0x30420004, 0x1440fffd, 0x0, 0x8f820040, 0x30420001,
+0x14400008, 0x0, 0x8f430104, 0x24020001, 0x10620004, 0x0,
+0x8f420264, 0x10400006, 0x0, 0x8ee20178, 0x24420001, 0xaee20178,
+0x80014b3, 0x8ee20178, 0x8f820044, 0x34420004, 0xaf820044, 0x8ee20174,
+0x24420001, 0xaee20174, 0x8ee20174, 0x8f8200d8, 0x8f8300d4, 0x431023,
+0xaee2725c, 0x8ee2725c, 0x1c400003, 0x3c030001, 0x431021, 0xaee2725c,
+0xc003fb0, 0x0, 0xc004380, 0xaf800228, 0x8fbf0024, 0x8fb00020,
+0x3e00008, 0x27bd0028, 0x3e00008, 0x0, 0x3e00008, 0x0,
+0x2402002c, 0xaf820050, 0xaee07264, 0x8f420238, 0xaee27268, 0x8f820054,
+0x24420067, 0xaf820058, 0xaee07b78, 0xaee07b7c, 0xaee07b74, 0x3c010001,
+0x370821, 0xac2083ac, 0x3c010001, 0x370821, 0x3e00008, 0xa02083a9,
+0x27bdffd8, 0xafbf0024, 0xafb00020, 0x8f820054, 0x3c030001, 0x8c634dfc,
+0x24420067, 0x1060000d, 0xaf820058, 0x3c020001, 0x571021, 0x904283a8,
+0x10400005, 0x3c030200, 0x3c010001, 0x370821, 0x80014ef, 0xa02083a8,
+0x8ee20000, 0x431025, 0xaee20000, 0x8f420218, 0x30420100, 0x104000c3,
+0x0, 0x8f8200b0, 0x30420004, 0x104000bf, 0x0, 0x3c030001,
+0x771821, 0x8c6383c0, 0x8f820104, 0x146200b1, 0x0, 0x3c030001,
+0x771821, 0x8c6383c4, 0x8f8200b4, 0x146200ab, 0x0, 0x8f8200b0,
+0x3c030080, 0x431024, 0x1040000d, 0x0, 0x8f82011c, 0x34420002,
+0xaf82011c, 0x8f8200b0, 0x2403fffb, 0x431024, 0xaf8200b0, 0x8f82011c,
+0x2403fffd, 0x431024, 0x80015b5, 0xaf82011c, 0x3c030001, 0x771821,
+0x8c6383c0, 0x8f820104, 0x1462007f, 0x0, 0x3c030001, 0x771821,
+0x8c6383c4, 0x8f8200b4, 0x14620079, 0x0, 0x3c070001, 0xf73821,
+0x8ce783c0, 0x8f8200b0, 0x3c040001, 0x24844430, 0xafa00014, 0xafa20010,
+0x8f8600b0, 0x3c050005, 0xc0023a7, 0x34a50900, 0x8f82011c, 0x34420002,
+0xaf82011c, 0x8f830104, 0x8f8200b0, 0x34420001, 0xaf8200b0, 0xaf830104,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20006, 0x0, 0x8ee201a0, 0x24420001, 0xaee201a0,
+0x8001589, 0x8ee201a0, 0x8f440208, 0x8f45020c, 0x26e20030, 0xac620008,
+0x24020400, 0xa462000e, 0x2402000f, 0xac620018, 0xac60001c, 0xac640000,
+0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400037,
+0x0, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000,
+0x24020007, 0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20,
+0x24420001, 0x10430007, 0x0, 0x8ee24e24, 0x24420001, 0x10a20005,
+0x0, 0x8001573, 0x0, 0x14a00005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x8001589, 0x0, 0x8ee24e20, 0x24030040, 0x24420001,
+0x50430003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x24020007, 0xac820000, 0x24020001,
+0xac820004, 0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201d4,
+0x3c070001, 0xf73821, 0x8ce783c0, 0x24420001, 0xaee201d4, 0x8ee201d4,
+0x3c040001, 0x2484443c, 0x80015a6, 0xafa00010, 0x8f820104, 0x3c010001,
+0x370821, 0xac2283c0, 0x8f8200b4, 0x3c070001, 0xf73821, 0x8ce783c0,
+0x3c040001, 0x24844444, 0x3c010001, 0x370821, 0xac2283c4, 0xafa00010,
+0xafa00014, 0x8f8600b0, 0x3c050005, 0xc0023a7, 0x34a50900, 0x80015b5,
+0x0, 0x8f820104, 0x3c010001, 0x370821, 0xac2283c0, 0x8f8200b4,
+0x3c010001, 0x370821, 0xac2283c4, 0x8ee27264, 0x92e304e4, 0x24420067,
+0x14600006, 0xaee27264, 0x8ee27264, 0x8f430234, 0x43102b, 0x14400078,
+0x0, 0x8ee304d4, 0x8ee204e8, 0x14620004, 0x0, 0x92e204e4,
+0x50400071, 0xa2e004e4, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
+0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0, 0x8ee201a0,
+0x8021, 0x24420001, 0xaee201a0, 0x800161d, 0x8ee201a0, 0x8ee204d4,
+0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008, 0x24020008,
+0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004, 0x8ee204b4,
+0xac620010, 0xaf860120, 0x92e24e10, 0x14400037, 0x24100001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020012, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x8001607,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x800161d,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x5600000b,
+0x24100001, 0x8ee204d4, 0x3c040001, 0x2484444c, 0xafa00014, 0xafa20010,
+0x8ee605f8, 0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f006, 0x16000003,
+0x24020001, 0x8001636, 0xa2e204e4, 0x8ee2016c, 0x24420001, 0xaee2016c,
+0x8ee2016c, 0x8ee204d4, 0xa2e004e4, 0xaee004e0, 0xaee07264, 0xaee204e8,
+0x8ee20e0c, 0x1040006a, 0x0, 0x8f830120, 0x27623800, 0x24660020,
+0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0,
+0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8001690, 0x8ee201a0,
+0x8ee2723c, 0xac62001c, 0x8ee40498, 0x8ee5049c, 0x2462001c, 0xac620008,
+0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004,
+0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400037, 0x24100001,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020012,
+0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001,
+0x10430007, 0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0,
+0x800167a, 0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
+0x8001690, 0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004,
+0x5600000b, 0x24100001, 0x8ee2723c, 0x3c040001, 0x24844458, 0xafa00014,
+0xafa20010, 0x8ee6723c, 0x8f470280, 0x3c050009, 0xc0023a7, 0x34a5f008,
+0x56000001, 0xaee00e0c, 0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170,
+0x8ee24e14, 0x10400019, 0x0, 0xaee04e14, 0x8f820040, 0x30420001,
+0x14400008, 0x0, 0x8f430104, 0x24020001, 0x10620004, 0x0,
+0x8f420264, 0x10400006, 0x0, 0x8ee20178, 0x24420001, 0xaee20178,
+0x80016bd, 0x8ee20178, 0x8f820044, 0x34420004, 0xaf820044, 0x8ee20174,
+0x24420001, 0xaee20174, 0x8ee20174, 0x8ee27268, 0x2442ff99, 0xaee27268,
+0x8ee27268, 0x1c400299, 0x0, 0x8f420238, 0x10400296, 0x0,
+0x8f420080, 0xaee2004c, 0x8f4200c0, 0xaee20048, 0x8f420084, 0xaee20038,
+0x8f420084, 0xaee20234, 0x8f420088, 0xaee20238, 0x8f42008c, 0xaee2023c,
+0x8f420090, 0xaee20240, 0x8f420094, 0xaee20244, 0x8f420098, 0xaee20248,
+0x8f42009c, 0xaee2024c, 0x8f4200a0, 0xaee20250, 0x8f4200a4, 0xaee20254,
+0x8f4200a8, 0xaee20258, 0x8f4200ac, 0xaee2025c, 0x8f4200b0, 0xaee20260,
+0x8f4200b4, 0xaee20264, 0x8f4200b8, 0xaee20268, 0x8f4200bc, 0x24040001,
+0xaee2026c, 0xaee0003c, 0x41080, 0x571021, 0x8ee3003c, 0x8c420234,
+0x24840001, 0x621821, 0x2c82000f, 0xaee3003c, 0x1440fff8, 0x41080,
+0x8f4200cc, 0xaee20050, 0x8f4200d0, 0xaee20054, 0x8f830120, 0x27623800,
+0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007,
+0x0, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8001750,
+0x8ee201a0, 0x8f440208, 0x8f45020c, 0x26e20030, 0xac620008, 0x24020400,
+0xa462000e, 0x2402000f, 0xac620018, 0xac60001c, 0xac640000, 0xac650004,
+0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400037, 0x24100001,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007,
+0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001,
+0x10430007, 0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0,
+0x800173a, 0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
+0x8001750, 0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004,
+0x12000206, 0x3c020400, 0xafa20018, 0x3c020001, 0x571021, 0x904283a0,
+0x10400105, 0x0, 0x8ee205f8, 0x8f430228, 0x24420001, 0x304a00ff,
+0x514300f7, 0xafa00010, 0x8ee205f8, 0x210c0, 0x571021, 0x8fa30018,
+0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f830054, 0x8f820054, 0x24690032,
+0x1221023, 0x2c420033, 0x10400067, 0x5821, 0x24180008, 0x240f000d,
+0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120, 0x27623800, 0x24e80020,
+0x102102b, 0x50400001, 0x27683000, 0x8f820128, 0x15020007, 0x1021,
+0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x80017cb, 0x8ee201a0,
+0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, 0xa32821,
+0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004, 0x8ee205f8,
+0xa4f8000e, 0xacef0018, 0xacea001c, 0x210c0, 0x244205fc, 0x2e21021,
+0xace20008, 0x8ee204b4, 0xace20010, 0xaf880120, 0x92e24e10, 0x14400033,
+0x24100001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c820000,
+0x144d001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001,
+0x104c0007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005, 0x0,
+0x80017b8, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
+0x80017cb, 0x0, 0x8ee24e20, 0x24420001, 0x504c0003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0xac8d0000, 0xac8e0004, 0x56000006, 0x240b0001, 0x8f820054,
+0x1221023, 0x2c420033, 0x1440ffa0, 0x0, 0x316300ff, 0x24020001,
+0x14620074, 0x3c050009, 0xaeea05f8, 0x8f830054, 0x8f820054, 0x24690032,
+0x1221023, 0x2c420033, 0x1040005e, 0x5821, 0x240d0008, 0x240c0011,
+0x24080012, 0x24070040, 0x240a0001, 0x8f830120, 0x27623800, 0x24660020,
+0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0,
+0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8001834, 0x8ee201a0,
+0x8ee205f8, 0xac62001c, 0x8ee40490, 0x8ee50494, 0x2462001c, 0xac620008,
+0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010,
+0xaf860120, 0x92e24e10, 0x14400033, 0x24100001, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x8c820000, 0x1448001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee34e20, 0x24420001, 0x10470007, 0x0, 0x8ee24e24,
+0x24420001, 0x10620005, 0x0, 0x8001821, 0x0, 0x14600005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400010, 0xac800000, 0x8001834, 0x0, 0x8ee24e20,
+0x24420001, 0x50470003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0xac880000, 0xac8a0004,
+0x56000006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa9,
+0x0, 0x316300ff, 0x24020001, 0x14620003, 0x3c050009, 0x800194b,
+0x24100001, 0x3c040001, 0x24844464, 0xafa00010, 0xafa00014, 0x8f860120,
+0x8f870124, 0x8001850, 0x34a5f011, 0x3c040001, 0x24844470, 0xafa00010,
+0xafa00014, 0x8f860120, 0x8f870124, 0x34a5f010, 0xc0023a7, 0x8021,
+0x800194b, 0x0, 0x3c040001, 0x2484447c, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0x8001944, 0x34a5f00f, 0x8ee205f8, 0x8f430228,
+0x24420001, 0x304900ff, 0x512300dc, 0xafa00010, 0x8ee205f8, 0x210c0,
+0x571021, 0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f870120,
+0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128,
+0x15020007, 0x1021, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0,
+0x80018c9, 0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430,
+0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000,
+0xace50004, 0x8ee305f8, 0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
+0xace9001c, 0x318c0, 0x246305fc, 0x2e31021, 0xace20008, 0x8ee204b4,
+0xace20010, 0xaf880120, 0x92e24e10, 0x14400037, 0x24100001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x80018b3,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x80018c9,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x5600000c,
+0xaee905f8, 0x3c040001, 0x24844488, 0xafa00010, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f000, 0x800194b, 0x0,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20007, 0x0, 0x8ee201a0, 0x8021, 0x24420001,
+0xaee201a0, 0x800192d, 0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490,
+0x8ee50494, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011,
+0xac620018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120,
+0x92e24e10, 0x14400037, 0x24100001, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x8c830000, 0x24020012, 0x1462001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007, 0x0, 0x8ee24e24,
+0x24420001, 0x10a20005, 0x0, 0x8001917, 0x0, 0x14a00005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400013, 0xac800000, 0x800192d, 0x0, 0x8ee24e20,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x24020012,
+0xac820000, 0x24020001, 0xac820004, 0x5600001d, 0x24100001, 0x3c040001,
+0x24844490, 0xafa00010, 0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009,
+0xc0023a7, 0x34a5f001, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x800194b,
+0x8ee201ac, 0x3c040001, 0x2484449c, 0xafa00014, 0x8ee605f8, 0x8f470228,
+0x3c050009, 0x34a5f005, 0xc0023a7, 0x0, 0x8ee201a8, 0x8021,
+0x24420001, 0xaee201a8, 0x8ee201a8, 0x1200000c, 0x24020001, 0x3c010001,
+0x370821, 0xa02083a0, 0x8f420238, 0x8ee30154, 0x24630001, 0xaee30154,
+0x8ee30154, 0x800195b, 0xaee27268, 0x24020001, 0x3c010001, 0x370821,
+0xa02283a0, 0x3c020001, 0x8c424dfc, 0x10400181, 0x0, 0x8ee27b74,
+0x24430001, 0x284200c9, 0x1440019e, 0xaee37b74, 0x8ee204c4, 0x30420002,
+0x14400113, 0xaee07b74, 0x8ee204c4, 0x3c030600, 0x34631000, 0x34420002,
+0xaee204c4, 0xafa30018, 0x8ee205f8, 0x8f430228, 0x24420001, 0x304a00ff,
+0x514300f7, 0xafa00010, 0x8ee205f8, 0x210c0, 0x571021, 0x8fa30018,
+0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f830054, 0x8f820054, 0x24690032,
+0x1221023, 0x2c420033, 0x10400067, 0x5821, 0x24180008, 0x240f000d,
+0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120, 0x27623800, 0x24e80020,
+0x102102b, 0x50400001, 0x27683000, 0x8f820128, 0x15020007, 0x1021,
+0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x80019e1, 0x8ee201a0,
+0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, 0xa32821,
+0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004, 0x8ee205f8,
+0xa4f8000e, 0xacef0018, 0xacea001c, 0x210c0, 0x244205fc, 0x2e21021,
+0xace20008, 0x8ee204b4, 0xace20010, 0xaf880120, 0x92e24e10, 0x14400033,
+0x24100001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c820000,
+0x144d001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001,
+0x104c0007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005, 0x0,
+0x80019ce, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
+0x80019e1, 0x0, 0x8ee24e20, 0x24420001, 0x504c0003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0xac8d0000, 0xac8e0004, 0x56000006, 0x240b0001, 0x8f820054,
+0x1221023, 0x2c420033, 0x1440ffa0, 0x0, 0x316300ff, 0x24020001,
+0x54620075, 0xafa00010, 0xaeea05f8, 0x8f830054, 0x8f820054, 0x24690032,
+0x1221023, 0x2c420033, 0x1040005e, 0x5821, 0x240d0008, 0x240c0011,
+0x24080012, 0x24070040, 0x240a0001, 0x8f830120, 0x27623800, 0x24660020,
+0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0,
+0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8001a4a, 0x8ee201a0,
+0x8ee205f8, 0xac62001c, 0x8ee40490, 0x8ee50494, 0x2462001c, 0xac620008,
+0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010,
+0xaf860120, 0x92e24e10, 0x14400033, 0x24100001, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x8c820000, 0x1448001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee34e20, 0x24420001, 0x10470007, 0x0, 0x8ee24e24,
+0x24420001, 0x10620005, 0x0, 0x8001a37, 0x0, 0x14600005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400010, 0xac800000, 0x8001a4a, 0x0, 0x8ee24e20,
+0x24420001, 0x50470003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0xac880000, 0xac8a0004,
+0x56000006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa9,
+0x0, 0x316300ff, 0x24020001, 0x10620022, 0x0, 0x3c040001,
+0x24844464, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
+0xc0023a7, 0x34a5f011, 0x8001a76, 0x0, 0x3c040001, 0x24844470,
+0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0xc0023a7, 0x34a5f010,
+0x8001a76, 0x0, 0x3c040001, 0x2484447c, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f00f, 0x8ee201a8, 0x24420001,
+0xaee201a8, 0x8ee201a8, 0x8ee20158, 0x24420001, 0xaee20158, 0x8ee20158,
+0x8ee204c4, 0x30420001, 0x10400055, 0x0, 0x8f420218, 0x30420080,
+0x10400029, 0x0, 0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b6c,
+0x402821, 0x8ee200c0, 0x8ee300c4, 0x24060000, 0x2407ffff, 0x2021,
+0x461024, 0x1444000d, 0x671824, 0x1465000b, 0x0, 0x8ee27b70,
+0x402821, 0x8ee200e0, 0x8ee300e4, 0x2021, 0x461024, 0x14440003,
+0x671824, 0x1065000b, 0x0, 0x8ee200c0, 0x8ee300c4, 0x8ee400e0,
+0x8ee500e4, 0xaee37b6c, 0xaee57b70, 0x8f820044, 0x38420020, 0x8001b01,
+0xaf820044, 0x8f820044, 0x2403ffdf, 0x431024, 0x8001b01, 0xaf820044,
+0x8f820044, 0x2403ffdf, 0x431024, 0xaf820044, 0x8ee27b6c, 0x402821,
+0x8ee200c0, 0x8ee300c4, 0x24060000, 0x2407ffff, 0x2021, 0x461024,
+0x1444000d, 0x671824, 0x1465000b, 0x0, 0x8ee27b70, 0x402821,
+0x8ee200e0, 0x8ee300e4, 0x2021, 0x461024, 0x14440003, 0x671824,
+0x1065000b, 0x0, 0x8ee200c0, 0x8ee300c4, 0x8ee400e0, 0x8ee500e4,
+0xaee37b6c, 0xaee57b70, 0x8f820044, 0x38420040, 0x8001b01, 0xaf820044,
+0x8f820044, 0x34420040, 0x8001b01, 0xaf820044, 0x8f820044, 0x34420040,
+0xaf820044, 0x8ee27b7c, 0x24430001, 0x28420015, 0x14400028, 0xaee37b7c,
+0x8f820044, 0x38420020, 0xaf820044, 0x8001b01, 0xaee07b7c, 0x8ee204c4,
+0x30420001, 0x10400011, 0x0, 0x8f420218, 0x30420080, 0x10400009,
+0x0, 0x8f820044, 0x34420020, 0xaf820044, 0x8f820044, 0x2403ffbf,
+0x431024, 0x8001aff, 0xaf820044, 0x8f820044, 0x34420060, 0x8001aff,
+0xaf820044, 0x8f820044, 0x34420040, 0xaf820044, 0x8ee27b78, 0x24430001,
+0x28421389, 0x14400005, 0xaee37b78, 0x8f820044, 0x38420020, 0xaf820044,
+0xaee07b78, 0xc0044fc, 0x0, 0x8fbf0024, 0x8fb00020, 0x3e00008,
+0x27bd0028, 0x0, 0x0, 0x0, 0x27bdffb8, 0xafbf0044,
+0xafb60040, 0xafb5003c, 0xafb40038, 0xafb30034, 0xafb20030, 0xafb1002c,
+0xafb00028, 0x8f960064, 0x32c20004, 0x1040000c, 0x24020004, 0xaf820064,
+0x8f420114, 0xaee204d0, 0x8f820060, 0x34420008, 0xaf820060, 0x8ee20168,
+0x24420001, 0xaee20168, 0x8002293, 0x8ee20168, 0x32c20001, 0x10400004,
+0x24020001, 0xaf820064, 0x8002293, 0x0, 0x32c20002, 0x1040076b,
+0x0, 0x8f43022c, 0x8f42010c, 0x5062000c, 0xafa00010, 0x8f42022c,
+0x21080, 0x5a1021, 0x8c420300, 0xafa20020, 0x8f42022c, 0x24070001,
+0x24420001, 0x3042003f, 0x8001b41, 0xaf42022c, 0x3c040001, 0x24844510,
+0xafa00014, 0x8f46022c, 0x8f47010c, 0x3c050003, 0xc0023a7, 0x34a5f01f,
+0x3821, 0x14e00003, 0x0, 0x800228c, 0xaf960064, 0x93a20020,
+0x2443ffff, 0x2c620011, 0x1040063c, 0x31080, 0x3c010001, 0x220821,
+0x8c2245c8, 0x400008, 0x0, 0x8fa20020, 0x30420fff, 0xaee20dfc,
+0x8f820060, 0x34420200, 0xaf820060, 0x8ee20118, 0x24420001, 0xaee20118,
+0x8002287, 0x8ee20118, 0x8fa20020, 0x24030001, 0x3c010001, 0x370821,
+0xa02383a1, 0x30420fff, 0xaee25228, 0x8f820060, 0x34420100, 0xaf820060,
+0x8ee20144, 0x24420001, 0xaee20144, 0x8002287, 0x8ee20144, 0x8fa20020,
+0x21200, 0x22502, 0x24020001, 0x10820005, 0x24020002, 0x10820009,
+0x2402fffe, 0x8001b8a, 0xafa00010, 0x8ee204c4, 0xaee40070, 0xaee40074,
+0x34420001, 0x8001b7e, 0xaee204c4, 0x8ee304c4, 0xaee40070, 0xaee40074,
+0x621824, 0xaee304c4, 0x8f840054, 0x41442, 0x41c82, 0x431021,
+0x41cc2, 0x431023, 0x41d02, 0x431021, 0x41d42, 0x431023,
+0x8001b91, 0xaee20078, 0x3c040001, 0x2484451c, 0xafa00014, 0x8fa60020,
+0x3c050003, 0xc0023a7, 0x34a50004, 0x8ee20110, 0x24420001, 0xaee20110,
+0x8002287, 0x8ee20110, 0x27440212, 0xc00229d, 0x24050006, 0x3049001f,
+0x920c0, 0x2e41021, 0x9442726c, 0x30424000, 0x1040000a, 0x971021,
+0x97430212, 0xa443726e, 0x8f430214, 0x971021, 0xac437270, 0x2e41821,
+0x34028000, 0x8001c38, 0xa462726c, 0x9443726e, 0x97420212, 0x14620006,
+0x2e41021, 0x971021, 0x8c437270, 0x8f420214, 0x1062009d, 0x2e41021,
+0x9442726c, 0x30428000, 0x10400028, 0x2406ffff, 0x2021, 0x410c0,
+0x2e21021, 0x9442736c, 0x30424000, 0x54400005, 0x803021, 0x24840001,
+0x2c820080, 0x1440fff8, 0x410c0, 0x4c10010, 0x620c0, 0x610c0,
+0x571821, 0x8c63736c, 0x571021, 0xafa30010, 0x8c427370, 0x3c040001,
+0x24844528, 0xafa20014, 0x8f470214, 0x3c050003, 0xc0023a7, 0x34a50013,
+0x8001c4f, 0x3c020800, 0x97430212, 0x971021, 0xa443736e, 0x8f430214,
+0x971021, 0xac437370, 0x910c0, 0x2e21021, 0x2e41821, 0x8001c36,
+0xa446726c, 0x2e41021, 0x9445726c, 0x8001bed, 0x510c0, 0x9443736e,
+0x97420212, 0x14620006, 0x510c0, 0x971021, 0x8c437370, 0x8f420214,
+0x10620065, 0x510c0, 0x2e21021, 0x9445736c, 0x510c0, 0x2e21021,
+0x9442736c, 0x30428000, 0x1040fff0, 0x971021, 0x520c0, 0x971021,
+0x9443736e, 0x97420212, 0x14620006, 0x2406ffff, 0x971021, 0x8c437370,
+0x8f420214, 0x10620053, 0x3c020800, 0x2021, 0x410c0, 0x2e21021,
+0x9442736c, 0x30424000, 0x54400005, 0x803021, 0x24840001, 0x2c820080,
+0x1440fff8, 0x410c0, 0x4c10023, 0x620c0, 0x910c0, 0x571821,
+0x8c63726c, 0x571021, 0xafa30010, 0x8c427270, 0x3c040001, 0x24844534,
+0xafa20014, 0x8f470214, 0x3c050003, 0xc0023a7, 0x34a5f017, 0x8001c4f,
+0x3c020800, 0x8f430210, 0xb71021, 0xac43776c, 0x8f430214, 0xb71021,
+0xac437770, 0x3c020001, 0x571021, 0x8c4283a4, 0x24420001, 0x3c010001,
+0x370821, 0xac2283a4, 0x3c030001, 0x771821, 0x8c6383a4, 0x2e51021,
+0x8001c41, 0xa443776c, 0x97430212, 0x971021, 0xa443736e, 0x8f430214,
+0x971021, 0xac437370, 0x510c0, 0x2e21021, 0x2e41821, 0xa446736c,
+0x34028000, 0xa462736c, 0x2021, 0x428c0, 0x2e51021, 0x9442776c,
+0x1040ffdc, 0x24840001, 0x2c820080, 0x5440fffa, 0x428c0, 0x92e204c8,
+0x10400006, 0x24020001, 0x8ee304cc, 0x1221004, 0x621825, 0x8001c4e,
+0xaee304cc, 0x8f830228, 0x24020001, 0x1221004, 0x621825, 0xaf830228,
+0x3c020800, 0x34421000, 0xafa20018, 0x8ee205f8, 0x8f430228, 0x24420001,
+0x304a00ff, 0x514300f7, 0xafa00010, 0x8ee205f8, 0x210c0, 0x571021,
+0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f830054, 0x8f820054,
+0x24690032, 0x1221023, 0x2c420033, 0x10400067, 0x5821, 0x24100008,
+0x240f000d, 0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120, 0x27623800,
+0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128, 0x15020007,
+0x1021, 0x8ee201a0, 0x3821, 0x24420001, 0xaee201a0, 0x8001cc4,
+0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430, 0x8ee50434,
+0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004,
+0x8ee205f8, 0xa4f0000e, 0xacef0018, 0xacea001c, 0x210c0, 0x244205fc,
+0x2e21021, 0xace20008, 0x8ee204b4, 0xace20010, 0xaf880120, 0x92e24e10,
+0x14400033, 0x24070001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x144d001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x104c0007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8001cb1, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
+0xac800000, 0x8001cc4, 0x0, 0x8ee24e20, 0x24420001, 0x504c0003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0xac8d0000, 0xac8e0004, 0x54e00006, 0x240b0001,
+0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa0, 0x0, 0x316300ff,
+0x24020001, 0x54620075, 0xafa00010, 0xaeea05f8, 0x8f830054, 0x8f820054,
+0x24690032, 0x1221023, 0x2c420033, 0x1040005e, 0x5821, 0x240e0008,
+0x240d0011, 0x240a0012, 0x24080040, 0x240c0001, 0x8f830120, 0x27623800,
+0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007,
+0x0, 0x8ee201a0, 0x3821, 0x24420001, 0xaee201a0, 0x8001d2d,
+0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490, 0x8ee50494, 0x2462001c,
+0xac620008, 0xa46e000e, 0xac6d0018, 0xac640000, 0xac650004, 0x8ee204b4,
+0xac620010, 0xaf860120, 0x92e24e10, 0x14400033, 0x24070001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c820000, 0x144a001f, 0x0,
+0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0, 0x8c820004, 0x24420001,
+0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001, 0x10480007, 0x0,
+0x8ee24e24, 0x24420001, 0x10620005, 0x0, 0x8001d1a, 0x0,
+0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
+0x8c820004, 0x2c420011, 0x50400010, 0xac800000, 0x8001d2d, 0x0,
+0x8ee24e20, 0x24420001, 0x50480003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0xac8a0000,
+0xac8c0004, 0x54e00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
+0x1440ffa9, 0x0, 0x316300ff, 0x24020001, 0x10620022, 0x0,
+0x3c040001, 0x24844540, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
+0x3c050009, 0xc0023a7, 0x34a5f011, 0x8001d59, 0x0, 0x3c040001,
+0x2484454c, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0xc0023a7,
+0x34a5f010, 0x8001d59, 0x0, 0x3c040001, 0x24844558, 0xafa00014,
+0x8ee605f8, 0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f00f, 0x8ee201a8,
+0x24420001, 0xaee201a8, 0x8ee201a8, 0x8ee20124, 0x24420001, 0xaee20124,
+0x8001f47, 0x8ee20124, 0x27440212, 0xc00229d, 0x24050006, 0x3049001f,
+0x928c0, 0x2e51021, 0x9442726c, 0x30428000, 0x1040002d, 0xb71021,
+0x9443726e, 0x97420212, 0x1462001a, 0xb71021, 0x8c437270, 0x8f420214,
+0x54620018, 0xafa20010, 0x92e204c8, 0x10400007, 0x24020001, 0x8ee304cc,
+0x1221004, 0x21027, 0x621824, 0x8001d7e, 0xaee304cc, 0x8f830228,
+0x1221004, 0x21027, 0x621824, 0xaf830228, 0x918c0, 0x2e31021,
+0x9442726c, 0x2e31821, 0x34424000, 0x8001e04, 0xa462726c, 0x8f420214,
+0xafa20010, 0x910c0, 0x571021, 0x8c42726c, 0x3c040001, 0x24844564,
+0x3c050003, 0xafa20014, 0x8f470210, 0x34a5f01c, 0xc0023a7, 0x1203021,
+0x8001e39, 0x3c020800, 0x9443726e, 0x97420212, 0x14620019, 0x918c0,
+0xb71021, 0x8c437270, 0x8f420214, 0x14620014, 0x918c0, 0x2e51021,
+0x9447726c, 0x720c0, 0x971021, 0x9443736e, 0xb71021, 0xa443726e,
+0x971021, 0x8c437370, 0xb71021, 0xac437270, 0x2e41021, 0x9443736c,
+0x2e51021, 0xa443726c, 0x2e41821, 0x24024000, 0x8001e04, 0xa462736c,
+0x2e31021, 0x9447726c, 0x3021, 0x720c0, 0x2e41021, 0x9442736c,
+0x4021, 0x30428000, 0x14400025, 0xe02821, 0x605021, 0x240b4000,
+0x971021, 0x9443736e, 0x97420212, 0x54620015, 0xe02821, 0x971021,
+0x8c437370, 0x8f420214, 0x54620010, 0xe02821, 0x11000006, 0x2e41021,
+0x9443736c, 0x510c0, 0x2e21021, 0x8001dd0, 0xa443736c, 0x9443736c,
+0x2ea1021, 0xa443726c, 0x710c0, 0x2e21021, 0xa44b736c, 0x8001dde,
+0x24060001, 0x510c0, 0x2e21021, 0x9447736c, 0x720c0, 0x2e41021,
+0x9442736c, 0x30428000, 0x1040ffdf, 0x25080001, 0x30c200ff, 0x14400025,
+0x2021, 0x720c0, 0x971021, 0x9443736e, 0x97420212, 0x1462000f,
+0x910c0, 0x971021, 0x8c437370, 0x8f420214, 0x1462000a, 0x910c0,
+0x2e41821, 0x24024000, 0x15000015, 0xa462736c, 0x910c0, 0x2e21821,
+0x34028000, 0x8001e04, 0xa462726c, 0x571021, 0x8c42726c, 0x3c040001,
+0x24844570, 0x3c050003, 0xafa20010, 0x710c0, 0x571021, 0x8c42736c,
+0x34a5001e, 0x1203021, 0xc0023a7, 0xafa20014, 0x8001e39, 0x3c020800,
+0x2021, 0x428c0, 0xb71021, 0x9443776e, 0x97420212, 0x5462002b,
+0x24840001, 0xb71021, 0x8c437770, 0x8f420214, 0x54620026, 0x24840001,
+0x3c020001, 0x571021, 0x8c4283a4, 0x2442ffff, 0x3c010001, 0x370821,
+0xac2283a4, 0x3c020001, 0x571021, 0x8c4283a4, 0x809021, 0x242102b,
+0x1040000e, 0x24b1776c, 0x24b07774, 0x2f02021, 0x2f12821, 0xc002434,
+0x24060008, 0x26310008, 0x3c020001, 0x571021, 0x8c4283a4, 0x26520001,
+0x242102b, 0x1440fff5, 0x26100008, 0x3c040001, 0x972021, 0x8c8483a4,
+0x24050008, 0x420c0, 0x2484776c, 0xc00242c, 0x2e42021, 0x8001e39,
+0x3c020800, 0x2c820080, 0x1440ffcf, 0x428c0, 0x3c020800, 0x34422000,
+0xafa20018, 0x8ee205f8, 0x8f430228, 0x24420001, 0x304a00ff, 0x514300f7,
+0xafa00010, 0x8ee205f8, 0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c,
+0xac4305fc, 0xac440600, 0x8f830054, 0x8f820054, 0x24690032, 0x1221023,
+0x2c420033, 0x10400067, 0x5821, 0x24100008, 0x240f000d, 0x240d0007,
+0x240c0040, 0x240e0001, 0x8f870120, 0x27623800, 0x24e80020, 0x102102b,
+0x50400001, 0x27683000, 0x8f820128, 0x15020007, 0x1021, 0x8ee201a0,
+0x3821, 0x24420001, 0xaee201a0, 0x8001eae, 0x8ee201a0, 0x8ee405f8,
+0x420c0, 0x801821, 0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b,
+0x822021, 0x862021, 0xace40000, 0xace50004, 0x8ee205f8, 0xa4f0000e,
+0xacef0018, 0xacea001c, 0x210c0, 0x244205fc, 0x2e21021, 0xace20008,
+0x8ee204b4, 0xace20010, 0xaf880120, 0x92e24e10, 0x14400033, 0x24070001,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c820000, 0x144d001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001, 0x104c0007,
+0x0, 0x8ee24e24, 0x24420001, 0x10620005, 0x0, 0x8001e9b,
+0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, 0xac800000, 0x8001eae,
+0x0, 0x8ee24e20, 0x24420001, 0x504c0003, 0x1021, 0x8ee24e20,
+0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0xac8d0000, 0xac8e0004, 0x54e00006, 0x240b0001, 0x8f820054, 0x1221023,
+0x2c420033, 0x1440ffa0, 0x0, 0x316300ff, 0x24020001, 0x54620075,
+0xafa00010, 0xaeea05f8, 0x8f830054, 0x8f820054, 0x24690032, 0x1221023,
+0x2c420033, 0x1040005e, 0x5821, 0x240e0008, 0x240d0011, 0x240a0012,
+0x24080040, 0x240c0001, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
+0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0, 0x8ee201a0,
+0x3821, 0x24420001, 0xaee201a0, 0x8001f17, 0x8ee201a0, 0x8ee205f8,
+0xac62001c, 0x8ee40490, 0x8ee50494, 0x2462001c, 0xac620008, 0xa46e000e,
+0xac6d0018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120,
+0x92e24e10, 0x14400033, 0x24070001, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x8c820000, 0x144a001f, 0x0, 0x8ee34e20, 0x8ee24e24,
+0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24,
+0x8ee34e20, 0x24420001, 0x10480007, 0x0, 0x8ee24e24, 0x24420001,
+0x10620005, 0x0, 0x8001f04, 0x0, 0x14600005, 0x0,
+0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011,
+0x50400010, 0xac800000, 0x8001f17, 0x0, 0x8ee24e20, 0x24420001,
+0x50480003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006,
+0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa9, 0x0,
+0x316300ff, 0x24020001, 0x10620022, 0x0, 0x3c040001, 0x24844540,
+0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0xc0023a7,
+0x34a5f011, 0x8001f43, 0x0, 0x3c040001, 0x2484454c, 0xafa00014,
+0x8f860120, 0x8f870124, 0x3c050009, 0xc0023a7, 0x34a5f010, 0x8001f43,
+0x0, 0x3c040001, 0x24844558, 0xafa00014, 0x8ee605f8, 0x8f470228,
+0x3c050009, 0xc0023a7, 0x34a5f00f, 0x8ee201a8, 0x24420001, 0xaee201a8,
+0x8ee201a8, 0x8ee20128, 0x24420001, 0xaee20128, 0x8ee20128, 0x8ee20160,
+0x24420001, 0xaee20160, 0x8002287, 0x8ee20160, 0x8fa20020, 0x21200,
+0x21d02, 0x24020001, 0x10620005, 0x24020002, 0x1062000d, 0x0,
+0x8001f67, 0xafa00010, 0x92e204c8, 0x14400006, 0x24020001, 0x8f820228,
+0xaee204cc, 0x2402ffff, 0xaf820228, 0x24020001, 0x8001f6e, 0xa2e204c8,
+0x92e204c8, 0x5040000c, 0xa2e004c8, 0x8ee204cc, 0xaf820228, 0x8001f6e,
+0xa2e004c8, 0x3c040001, 0x24844578, 0xafa00014, 0x8fa60020, 0x3c050003,
+0xc0023a7, 0x34a5f009, 0x8ee2013c, 0x24420001, 0xaee2013c, 0x8002287,
+0x8ee2013c, 0x8fa20020, 0x21200, 0x22502, 0x24020001, 0x10820005,
+0x24020002, 0x1082000f, 0x0, 0x8001f93, 0xafa00010, 0x8f820220,
+0x3c0308ff, 0x3463ffff, 0x431024, 0x34420008, 0xaf820220, 0x24020001,
+0x3c010001, 0x370821, 0xa02283a2, 0x8001f9a, 0xaee40108, 0x8f820220,
+0x3c0308ff, 0x3463fff7, 0x431024, 0xaf820220, 0x3c010001, 0x370821,
+0xa02083a2, 0x8001f9a, 0xaee40108, 0x3c040001, 0x24844584, 0xafa00014,
+0x8fa60020, 0x3c050003, 0xc0023a7, 0x34a5f00a, 0x8ee2012c, 0x24420001,
+0xaee2012c, 0x8002287, 0x8ee2012c, 0x8fa20020, 0x21200, 0x21d02,
+0x24020001, 0x10620005, 0x24020002, 0x1062000e, 0x0, 0x8001fc1,
+0xafa00010, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420008,
+0xaf820220, 0x24020001, 0x3c010001, 0x370821, 0x8001fc8, 0xa02283a3,
+0x3c020001, 0x571021, 0x904283a2, 0x3c010001, 0x370821, 0x1440000e,
+0xa02083a3, 0x8f820220, 0x3c0308ff, 0x3463fff7, 0x431024, 0x8001fc8,
+0xaf820220, 0x3c040001, 0x24844590, 0xafa00014, 0x8fa60020, 0x3c050003,
+0xc0023a7, 0x34a5f00b, 0x8ee20114, 0x24420001, 0xaee20114, 0x8002287,
+0x8ee20114, 0x27840208, 0x27450200, 0xc00243e, 0x24060008, 0x26e40094,
+0x27450200, 0xc00243e, 0x24060008, 0x8ee20134, 0x24420001, 0xaee20134,
+0x8002287, 0x8ee20134, 0x8f460248, 0x24040001, 0xc004e2c, 0x24050004,
+0x8ee20130, 0x24420001, 0xaee20130, 0x8002287, 0x8ee20130, 0x8ef301c4,
+0x8ef401c8, 0x8ef501cc, 0x8ee20140, 0x26e40030, 0x24420001, 0xaee20140,
+0x8ef00140, 0x8ef10074, 0x8ef20070, 0xc00242c, 0x24050400, 0xaef301c4,
+0xaef401c8, 0xaef501cc, 0xaef00140, 0xaef10074, 0xaef20070, 0x8f42025c,
+0x26e40094, 0xaee20060, 0x8f420260, 0x27450200, 0x24060008, 0xaee20068,
+0x24020006, 0xc00243e, 0xaee20064, 0x3c023b9a, 0x3442ca00, 0xaee2006c,
+0x240203e8, 0x24040002, 0x24030001, 0xaee20104, 0xaee40100, 0xaee3010c,
+0x8f820220, 0x30420008, 0x10400004, 0x0, 0xaee30108, 0x8002011,
+0x2021, 0xaee40108, 0x2021, 0x3c030001, 0x641821, 0x90634d50,
+0x2e41021, 0x24840001, 0xa043009c, 0x2c82000f, 0x1440fff8, 0x0,
+0x8f820040, 0x2e41821, 0x24840001, 0x21702, 0x24420030, 0xa062009c,
+0x2e41021, 0x8002287, 0xa040009c, 0x240a0400, 0x24090040, 0x24080001,
+0x8f830100, 0x27623000, 0x24660020, 0xc2102b, 0x50400001, 0x27662800,
+0x8f820108, 0x14c20007, 0x26e20030, 0x8ee201a4, 0x3821, 0x24420001,
+0xaee201a4, 0x8002050, 0x8ee201a4, 0x8ee404a8, 0x8ee504ac, 0xac620008,
+0xa46a000e, 0xac600018, 0xac60001c, 0xac640000, 0xac650004, 0x8ee204bc,
+0xac620010, 0xaf860100, 0x92e204dc, 0x1440000e, 0x24070001, 0x8ee24e18,
+0x24420001, 0x50490003, 0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18,
+0x8ee24e18, 0x210c0, 0x24424e28, 0x2e21021, 0xac400000, 0xac480004,
+0x10e0ffd5, 0x0, 0x8ee20148, 0x24420001, 0xaee20148, 0x8002287,
+0x8ee20148, 0x3c020900, 0xaee05228, 0xaee0522c, 0xaee05230, 0xaee05234,
+0xaee001c8, 0x3c010001, 0x370821, 0xa02083a1, 0xafa20018, 0x8ee205f8,
+0x8f430228, 0x24420001, 0x304a00ff, 0x514300f7, 0xafa00010, 0x8ee205f8,
+0x210c0, 0x571021, 0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600,
+0x8f830054, 0x8f820054, 0x24690032, 0x1221023, 0x2c420033, 0x10400067,
+0x5821, 0x24100008, 0x240f000d, 0x240d0007, 0x240c0040, 0x240e0001,
+0x8f870120, 0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000,
+0x8f820128, 0x15020007, 0x1021, 0x8ee201a0, 0x3821, 0x24420001,
+0xaee201a0, 0x80020d4, 0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821,
+0x8ee40430, 0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xace40000, 0xace50004, 0x8ee205f8, 0xa4f0000e, 0xacef0018, 0xacea001c,
+0x210c0, 0x244205fc, 0x2e21021, 0xace20008, 0x8ee204b4, 0xace20010,
+0xaf880120, 0x92e24e10, 0x14400033, 0x24070001, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x8c820000, 0x144d001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x0, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee34e20, 0x24420001, 0x104c0007, 0x0, 0x8ee24e24,
+0x24420001, 0x10620005, 0x0, 0x80020c1, 0x0, 0x14600005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400010, 0xac800000, 0x80020d4, 0x0, 0x8ee24e20,
+0x24420001, 0x504c0003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0xac8d0000, 0xac8e0004,
+0x54e00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa0,
+0x0, 0x316300ff, 0x24020001, 0x54620075, 0xafa00010, 0xaeea05f8,
+0x8f830054, 0x8f820054, 0x24690032, 0x1221023, 0x2c420033, 0x1040005e,
+0x5821, 0x240e0008, 0x240d0011, 0x240a0012, 0x24080040, 0x240c0001,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20007, 0x0, 0x8ee201a0, 0x3821, 0x24420001,
+0xaee201a0, 0x800213d, 0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490,
+0x8ee50494, 0x2462001c, 0xac620008, 0xa46e000e, 0xac6d0018, 0xac640000,
+0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400033,
+0x24070001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c820000,
+0x144a001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001,
+0x10480007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005, 0x0,
+0x800212a, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, 0xac800000,
+0x800213d, 0x0, 0x8ee24e20, 0x24420001, 0x50480003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0xac8a0000, 0xac8c0004, 0x54e00006, 0x240b0001, 0x8f820054,
+0x1221023, 0x2c420033, 0x1440ffa9, 0x0, 0x316300ff, 0x24020001,
+0x10620022, 0x0, 0x3c040001, 0x24844540, 0xafa00010, 0xafa00014,
+0x8f860120, 0x8f870124, 0x3c050009, 0xc0023a7, 0x34a5f011, 0x8002169,
+0x0, 0x3c040001, 0x2484454c, 0xafa00014, 0x8f860120, 0x8f870124,
+0x3c050009, 0xc0023a7, 0x34a5f010, 0x8002169, 0x0, 0x3c040001,
+0x24844558, 0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009, 0xc0023a7,
+0x34a5f00f, 0x8ee201a8, 0x24420001, 0xaee201a8, 0x8ee201a8, 0x8ee20120,
+0x24420001, 0xaee20120, 0x8ee20120, 0x8ee20164, 0x24420001, 0xaee20164,
+0x8002287, 0x8ee20164, 0x8f42025c, 0x26e40094, 0xaee20060, 0x8f420260,
+0x27450200, 0x24060008, 0xc00243e, 0xaee20068, 0x8f820220, 0x30420008,
+0x14400002, 0x24020001, 0x24020002, 0xaee20108, 0x8ee2011c, 0x24420001,
+0xaee2011c, 0x8002287, 0x8ee2011c, 0x3c040001, 0x2484459c, 0xafa00010,
+0xafa00014, 0x8fa60020, 0x3c050003, 0xc0023a7, 0x34a5f00f, 0x93a20020,
+0x3c030700, 0x34631000, 0x431025, 0xafa20018, 0x8ee205f8, 0x8f430228,
+0x24420001, 0x304900ff, 0x512300dc, 0xafa00010, 0x8ee205f8, 0x210c0,
+0x571021, 0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f870120,
+0x27623800, 0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128,
+0x15020007, 0x1021, 0x8ee201a0, 0x3821, 0x24420001, 0xaee201a0,
+0x80021ff, 0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430,
+0x8ee50434, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000,
+0xace50004, 0x8ee305f8, 0x24020008, 0xa4e2000e, 0x2402000d, 0xace20018,
+0xace9001c, 0x318c0, 0x246305fc, 0x2e31021, 0xace20008, 0x8ee204b4,
+0xace20010, 0xaf880120, 0x92e24e10, 0x14400037, 0x24070001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x80021e9,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x80021ff,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004, 0x54e0000c,
+0xaee905f8, 0x3c040001, 0x248445a4, 0xafa00010, 0xafa00014, 0x8ee605f8,
+0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f000, 0x800227f, 0x0,
+0x8f830120, 0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000,
+0x8f820128, 0x14c20007, 0x0, 0x8ee201a0, 0x3821, 0x24420001,
+0xaee201a0, 0x8002263, 0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490,
+0x8ee50494, 0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011,
+0xac620018, 0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120,
+0x92e24e10, 0x14400037, 0x24070001, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x8c830000, 0x24020012, 0x1462001f, 0x0, 0x8ee34e20,
+0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007, 0x0, 0x8ee24e24,
+0x24420001, 0x10a20005, 0x0, 0x800224d, 0x0, 0x14a00005,
+0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128, 0x8c820004,
+0x2c420011, 0x50400013, 0xac800000, 0x8002263, 0x0, 0x8ee24e20,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x24020012,
+0xac820000, 0x24020001, 0xac820004, 0x14e0001b, 0x0, 0x3c040001,
+0x248445ac, 0xafa00010, 0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009,
+0xc0023a7, 0x34a5f001, 0x8ee201ac, 0x24420001, 0xaee201ac, 0x800227f,
+0x8ee201ac, 0x3c040001, 0x248445b8, 0xafa00014, 0x8ee605f8, 0x8f470228,
+0x3c050009, 0xc0023a7, 0x34a5f005, 0x8ee201a8, 0x24420001, 0xaee201a8,
+0x8ee201a8, 0x8ee2014c, 0x24420001, 0xaee2014c, 0x8ee2014c, 0x8ee2015c,
+0x24420001, 0xaee2015c, 0x8ee2015c, 0x8f43022c, 0x8f42010c, 0x14620009,
+0x24020002, 0xaf820064, 0x8f820064, 0x14400005, 0x0, 0x8f43022c,
+0x8f42010c, 0x1462f897, 0x0, 0x8fbf0044, 0x8fb60040, 0x8fb5003c,
+0x8fb40038, 0x8fb30034, 0x8fb20030, 0x8fb1002c, 0x8fb00028, 0x3e00008,
+0x27bd0048, 0x27bdfff8, 0x2408ffff, 0x10a00014, 0x4821, 0x3c0aedb8,
+0x354a8320, 0x90870000, 0x24840001, 0x3021, 0x1071026, 0x30420001,
+0x10400002, 0x81842, 0x6a1826, 0x604021, 0x24c60001, 0x2cc20008,
+0x1440fff7, 0x73842, 0x25290001, 0x125102b, 0x1440fff0, 0x0,
+0x1001021, 0x3e00008, 0x27bd0008, 0x0, 0x27bdffe8, 0x27642800,
+0xafbf0010, 0xc00242c, 0x24051000, 0x24020021, 0xaf800100, 0xaf800104,
+0xaf800108, 0xaf800110, 0xaf800114, 0xaf800118, 0xaf800120, 0xaf800124,
+0xaf800128, 0xaf800130, 0xaf800134, 0xaf800138, 0xaee04e18, 0xaee04e1c,
+0xaee04e20, 0xaee04e24, 0xaf82011c, 0x8f420218, 0x30420040, 0x10400004,
+0x0, 0x8f82011c, 0x34420004, 0xaf82011c, 0x8fbf0010, 0x3e00008,
+0x27bd0018, 0x27bdffe0, 0xafbf0018, 0x8f820104, 0xafa20010, 0x8f820100,
+0x3c050002, 0xafa20014, 0x8f8600b0, 0x8f87011c, 0x3c040001, 0x2484466c,
+0xc0023a7, 0x34a5f000, 0x8f8300b0, 0x3c027f00, 0x621824, 0x3c020400,
+0x1062002b, 0x43102b, 0x14400008, 0x3c022000, 0x3c020100, 0x10620026,
+0x3c020200, 0x10620013, 0x0, 0x8002316, 0x0, 0x1062000a,
+0x43102b, 0x1040001e, 0x3c024000, 0x1462001c, 0x0, 0x8ee2018c,
+0x24420001, 0xaee2018c, 0x8002316, 0x8ee2018c, 0x8ee20188, 0x24420001,
+0xaee20188, 0x8002316, 0x8ee20188, 0x8f82011c, 0x34420002, 0xaf82011c,
+0x8f830104, 0x8f8200b0, 0x34420001, 0xaf8200b0, 0xaf830104, 0x8f82011c,
+0x2403fffd, 0x431024, 0xaf82011c, 0x8ee2019c, 0x24420001, 0xaee2019c,
+0x8002319, 0x8ee2019c, 0x8f8200b0, 0x34420001, 0xaf8200b0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x27bdffe0, 0xafbf001c, 0xafb00018, 0x8f820120,
+0xafa20010, 0x8f820124, 0x3c050001, 0xafa20014, 0x8f8600a0, 0x8f87011c,
+0x3c040001, 0x24844678, 0xc0023a7, 0x34a5f000, 0x8f8300a0, 0x3c027f00,
+0x621824, 0x3c020400, 0x10620055, 0x8021, 0x43102b, 0x14400008,
+0x3c042000, 0x3c020100, 0x1062004f, 0x3c020200, 0x1062003c, 0x0,
+0x8002384, 0x0, 0x10640005, 0x83102b, 0x10400047, 0x3c024000,
+0x14620045, 0x0, 0x8f8200a0, 0x441024, 0x10400006, 0x0,
+0x8ee20190, 0x24420001, 0xaee20190, 0x800234d, 0x8ee20190, 0x8ee20194,
+0x24420001, 0xaee20194, 0x8ee20194, 0x8f82011c, 0x34420002, 0xaf82011c,
+0x8f82011c, 0x30420200, 0x1040001b, 0x0, 0x8f8300a0, 0x8f840124,
+0x8f8200ac, 0x14400007, 0x24020001, 0x3c020001, 0x3442f000, 0x621024,
+0x50400001, 0x24100001, 0x24020001, 0x1200000d, 0xaf8200a0, 0x8f820124,
+0x2442ffe0, 0xaf820124, 0x8f820124, 0x8f820124, 0x27633000, 0x43102b,
+0x10400005, 0x276237e0, 0xaf820124, 0x800236e, 0x0, 0xaf840124,
+0x8f82011c, 0x2403fffd, 0x431024, 0x8002387, 0xaf82011c, 0x8f82011c,
+0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0, 0x34420001, 0xaf8200a0,
+0xaf830124, 0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, 0x8ee20198,
+0x24420001, 0xaee20198, 0x8002387, 0x8ee20198, 0x8f8200a0, 0x34420001,
+0xaf8200a0, 0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, 0x0,
+0x3c020001, 0x8c424d78, 0x27bdffe8, 0xafbf0014, 0x14400012, 0xafb00010,
+0x3c100001, 0x26104eb0, 0x2002021, 0xc00242c, 0x24052000, 0x26021fe0,
+0x3c010001, 0xac224e84, 0x3c010001, 0xac224e80, 0xaf420250, 0x24022000,
+0xaf500254, 0xaf420258, 0x24020001, 0x3c010001, 0xac224d78, 0x8fbf0014,
+0x8fb00010, 0x3e00008, 0x27bd0018, 0x3c030001, 0x8c634e84, 0x8c820000,
+0x8fa80010, 0x8fa90014, 0xac620000, 0x3c020001, 0x8c424e84, 0x8c830004,
+0xac430004, 0xac450008, 0x8f840054, 0x2443ffe0, 0xac460010, 0xac470014,
+0xac480018, 0xac49001c, 0x3c010001, 0xac234e84, 0xac44000c, 0x3c020001,
+0x24424eb0, 0x62182b, 0x10600005, 0x0, 0x3c020001, 0x8c424e80,
+0x3c010001, 0xac224e84, 0x3c030001, 0x8c634e84, 0x3c020001, 0x8c424d60,
+0xac620000, 0x3c030001, 0x8c634e84, 0x3c020001, 0x8c424d60, 0xac620004,
+0x3e00008, 0xaf430250, 0x3c030001, 0x8c634e84, 0x3c020001, 0x8c424d60,
+0x27bdffd0, 0xafb40020, 0x8fb40040, 0xafb00010, 0x808021, 0xafb50024,
+0x8fb50044, 0x8fa40048, 0xafb10014, 0xa08821, 0xafbf0028, 0xafb3001c,
+0xafb20018, 0xac620000, 0x3c050001, 0x8ca54e84, 0x3c020001, 0x8c424d60,
+0xc09021, 0xe09821, 0x10800006, 0xaca20004, 0x24a50008, 0xc002434,
+0x24060018, 0x80023f2, 0x0, 0x24a40008, 0xc00242c, 0x24050018,
+0x3c020001, 0x8c424e84, 0x3c050001, 0x24a54eb0, 0x2442ffe0, 0x3c010001,
+0xac224e84, 0x45102b, 0x10400005, 0x0, 0x3c020001, 0x8c424e80,
+0x3c010001, 0xac224e84, 0x3c030001, 0x8c634e84, 0x8e020000, 0xac620000,
+0x3c030001, 0x8c634e84, 0x8e020004, 0xac620004, 0xac710008, 0x8f840054,
+0x2462ffe0, 0x3c010001, 0xac224e84, 0x45102b, 0xac720010, 0xac730014,
+0xac740018, 0xac75001c, 0x10400005, 0xac64000c, 0x3c020001, 0x8c424e80,
+0x3c010001, 0xac224e84, 0x3c030001, 0x8c634e84, 0x3c020001, 0x8c424d60,
+0xac620000, 0x3c030001, 0x8c634e84, 0x3c020001, 0x8c424d60, 0xac620004,
+0xaf430250, 0x8fbf0028, 0x8fb50024, 0x8fb40020, 0x8fb3001c, 0x8fb20018,
+0x8fb10014, 0x8fb00010, 0x3e00008, 0x27bd0030, 0x10a00005, 0x0,
+0xac800000, 0x24a5fffc, 0x14a0fffd, 0x24840004, 0x3e00008, 0x0,
+0x10c00007, 0x0, 0x8c820000, 0x24840004, 0x24c6fffc, 0xaca20000,
+0x14c0fffb, 0x24a50004, 0x3e00008, 0x0, 0x10c00007, 0x0,
+0x8ca20000, 0x24a50004, 0x24c6fffc, 0xac820000, 0x14c0fffb, 0x24840004,
+0x3e00008, 0x0, 0x3e00008, 0x0, 0x27bdffd8, 0xafbf0020,
+0x8ee304d4, 0x8ee204d0, 0x1062041e, 0x0, 0x8ee204d4, 0x8ee304ec,
+0x21100, 0x626021, 0x95870008, 0x8d8a0000, 0x8d8b0004, 0x958d000a,
+0x8ee2724c, 0x8ee3725c, 0x30e4ffff, 0x441021, 0x62182b, 0x10600015,
+0x31a20004, 0x8f8200d8, 0x8ee37248, 0x431023, 0xaee2725c, 0x8ee2725c,
+0x1c400003, 0x3c030001, 0x431021, 0xaee2725c, 0x8ee2724c, 0x8ee3725c,
+0x441021, 0x62182b, 0x10600006, 0x31a20004, 0x8ee201b4, 0x24420001,
+0xaee201b4, 0x800286d, 0x8ee201b4, 0x10400234, 0x31a20200, 0x10400144,
+0x4821, 0x96e2045a, 0x30420010, 0x10400140, 0x0, 0x8f840100,
+0x27623000, 0x24850020, 0xa2102b, 0x50400001, 0x27652800, 0x8f820108,
+0x14a20006, 0x2402000c, 0x8ee201a4, 0x24420001, 0xaee201a4, 0x80024cd,
+0x8ee201a4, 0xac8a0000, 0xac8b0004, 0x8ee37254, 0x24060005, 0xa482000e,
+0xac860018, 0xac830008, 0x8ee204d4, 0xac82001c, 0x8ee204b8, 0xac820010,
+0xaf850100, 0x92e204dc, 0x14400036, 0x24090001, 0x8ee24e18, 0x210c0,
+0x24424e28, 0x2e22021, 0x8c820000, 0x1446001f, 0x0, 0x8ee34e18,
+0x8ee24e1c, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004,
+0x8ee24e1c, 0x8ee54e18, 0x24420001, 0x10430007, 0x0, 0x8ee24e1c,
+0x24420001, 0x10a20005, 0x0, 0x80024b7, 0x0, 0x14a00005,
+0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004,
+0x2c420011, 0x50400013, 0xac800000, 0x80024cd, 0x0, 0x8ee24e18,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e18, 0x24420001,
+0xaee24e18, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x24020005,
+0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x3c040001, 0xafab0010,
+0x8ee27254, 0x3c040001, 0x248448e0, 0x3c050004, 0xafa20014, 0x8ee604d4,
+0x800284a, 0x34a5f114, 0x8ee27254, 0x34843800, 0x3641821, 0x24420010,
+0x43102b, 0x14400070, 0x0, 0x8ee27254, 0x24480010, 0x3641021,
+0x102102b, 0x14400002, 0x3c02ffff, 0x1024021, 0x8f850100, 0x27623000,
+0x24a60020, 0xc2102b, 0x50400001, 0x27662800, 0x8f820108, 0x14c20007,
+0x2563000c, 0x8ee201a4, 0x4821, 0x24420001, 0xaee201a4, 0x800253e,
+0x8ee201a4, 0x2c64000c, 0x1441021, 0xaca20000, 0xaca30004, 0x24e2fff4,
+0xa4a2000e, 0x24020006, 0xaca80008, 0xaca20018, 0x8ee204d4, 0xaca2001c,
+0x8ee204b8, 0x3c030002, 0x431025, 0xaca20010, 0xaf860100, 0x92e204dc,
+0x14400037, 0x24090001, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021,
+0x8c830000, 0x24020005, 0x1462001f, 0x0, 0x8ee34e18, 0x8ee24e1c,
+0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c,
+0x8ee54e18, 0x24420001, 0x10430007, 0x0, 0x8ee24e1c, 0x24420001,
+0x10a20005, 0x0, 0x8002528, 0x0, 0x14a00005, 0x0,
+0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011,
+0x50400013, 0xac800000, 0x800253e, 0x0, 0x8ee24e18, 0x24030040,
+0x24420001, 0x50430003, 0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18,
+0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x24020005, 0xac820000,
+0x24020001, 0xac820004, 0x1520000a, 0x2508fffc, 0xafab0010, 0x8ee27254,
+0x3c040001, 0x248448e0, 0x3c050004, 0xafa20014, 0x8ee604d4, 0x800284a,
+0x34a5f125, 0x34028100, 0xa5020000, 0x9582000e, 0x80025b8, 0xa5020002,
+0x8f850100, 0x27623000, 0x24a60020, 0xc2102b, 0x50400001, 0x27662800,
+0x8f820108, 0x14c20007, 0x2563000c, 0x8ee201a4, 0x4821, 0x24420001,
+0xaee201a4, 0x80025a8, 0x8ee201a4, 0x2c64000c, 0x1441021, 0xaca20000,
+0xaca30004, 0x8ee37254, 0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca20018,
+0x24630010, 0xaca30008, 0x8ee204d4, 0xaca2001c, 0x8ee204b8, 0x3c030002,
+0x431025, 0xaca20010, 0xaf860100, 0x92e204dc, 0x14400037, 0x24090001,
+0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x8c830000, 0x24020005,
+0x1462001f, 0x0, 0x8ee34e18, 0x8ee24e1c, 0x1062001b, 0x24030040,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c, 0x8ee54e18, 0x24420001,
+0x10430007, 0x0, 0x8ee24e1c, 0x24420001, 0x10a20005, 0x0,
+0x8002592, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020,
+0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
+0x80025a8, 0x0, 0x8ee24e18, 0x24030040, 0x24420001, 0x50430003,
+0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18, 0x210c0,
+0x24424e28, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004,
+0x1520000a, 0x34028100, 0xafab0010, 0x8ee27254, 0x3c040001, 0x248448e0,
+0x3c050004, 0xafa20014, 0x8ee604d4, 0x800284a, 0x34a5f015, 0x8ee37254,
+0xa462000c, 0x8ee37254, 0x9582000e, 0xa462000e, 0x8002619, 0x24e70004,
+0x8f840100, 0x27623000, 0x24850020, 0xa2102b, 0x50400001, 0x27652800,
+0x8f820108, 0x14a20007, 0x24020006, 0x8ee201a4, 0x4821, 0x24420001,
+0xaee201a4, 0x800260f, 0x8ee201a4, 0xac8a0000, 0xac8b0004, 0x8ee37254,
+0xa487000e, 0xac820018, 0xac830008, 0x8ee204d4, 0xac82001c, 0x8ee204b8,
+0x3c030002, 0x431025, 0xac820010, 0xaf850100, 0x92e204dc, 0x14400037,
+0x24090001, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x8c830000,
+0x24020005, 0x1462001f, 0x0, 0x8ee34e18, 0x8ee24e1c, 0x1062001b,
+0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c, 0x8ee54e18,
+0x24420001, 0x10430007, 0x0, 0x8ee24e1c, 0x24420001, 0x10a20005,
+0x0, 0x80025f9, 0x0, 0x14a00005, 0x0, 0x8f820108,
+0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x800260f, 0x0, 0x8ee24e18, 0x24030040, 0x24420001,
+0x50430003, 0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18,
+0x210c0, 0x24424e28, 0x2e22021, 0x24020005, 0xac820000, 0x24020001,
+0xac820004, 0x15200009, 0x3c050004, 0xafab0010, 0x8ee27254, 0x3c040001,
+0x248448e0, 0xafa20014, 0x8ee604d4, 0x800284a, 0x34a5f004, 0x8ee2724c,
+0x30e7ffff, 0x471021, 0xaee2724c, 0x8ee204d4, 0x8ee304ec, 0x8ee47248,
+0x21100, 0x431021, 0xac44000c, 0x8ee27248, 0xafa20018, 0x8ee3724c,
+0xafa3001c, 0x8ee2724c, 0x2c42003c, 0x10400004, 0x24620001, 0x2403fffe,
+0x431024, 0xafa2001c, 0x8ee27254, 0x3c060001, 0x34c63800, 0x8ee3724c,
+0x2405fff8, 0x471021, 0x24420007, 0x451024, 0x24630007, 0xaee27248,
+0x8ee2725c, 0x8ee47248, 0x651824, 0x431023, 0xaee2725c, 0x3661021,
+0x82202b, 0x14800004, 0x3c03ffff, 0x8ee27248, 0x431021, 0xaee27248,
+0x8ee27248, 0xaee27254, 0x8f8200f0, 0x24470008, 0x27621800, 0xe2102b,
+0x50400001, 0x27671000, 0x8f8200f4, 0x14e20007, 0x0, 0x8ee201b0,
+0x4821, 0x24420001, 0xaee201b0, 0x800265c, 0x8ee201b0, 0x8f8200f0,
+0x24090001, 0x8fa30018, 0x8fa4001c, 0xac430000, 0xac440004, 0xaf8700f0,
+0x15200012, 0xd1142, 0x8f8200f0, 0xafa20010, 0x8f8200f4, 0x3c040001,
+0x248448ec, 0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050004, 0xc0023a7,
+0x34a5f005, 0x8ee20088, 0x24420001, 0xaee20088, 0x8ee20088, 0x800285f,
+0xaee0724c, 0x30430003, 0x24020002, 0x10620016, 0x28620003, 0x10400005,
+0x24020001, 0x10620008, 0x0, 0x800269b, 0x0, 0x24020003,
+0x10620017, 0x0, 0x800269b, 0x0, 0x8ee200e8, 0x8ee300ec,
+0x24630001, 0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, 0x8ee200e8,
+0x800269b, 0x8ee300ec, 0x8ee200f0, 0x8ee300f4, 0x24630001, 0x2c640001,
+0x441021, 0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x800269b, 0x8ee300f4,
+0x8ee200f8, 0x8ee300fc, 0x24630001, 0x2c640001, 0x441021, 0xaee200f8,
+0xaee300fc, 0x8ee200f8, 0x8ee300fc, 0x8ee2724c, 0x8ee400e0, 0x8ee500e4,
+0x401821, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xaee400e0, 0xaee500e4, 0x800285f, 0xaee0724c, 0x30e2ffff, 0x104001b5,
+0x31a20200, 0x10400144, 0x4821, 0x96e2045a, 0x30420010, 0x10400140,
+0x0, 0x8f840100, 0x27623000, 0x24850020, 0xa2102b, 0x50400001,
+0x27652800, 0x8f820108, 0x14a20006, 0x2402000c, 0x8ee201a4, 0x24420001,
+0xaee201a4, 0x8002703, 0x8ee201a4, 0xac8a0000, 0xac8b0004, 0x8ee37254,
+0x24060005, 0xa482000e, 0xac860018, 0xac830008, 0x8ee204d4, 0xac82001c,
+0x8ee204b8, 0xac820010, 0xaf850100, 0x92e204dc, 0x14400036, 0x24090001,
+0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x8c820000, 0x1446001f,
+0x0, 0x8ee34e18, 0x8ee24e1c, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e1c, 0x8ee54e18, 0x24420001, 0x10430007,
+0x0, 0x8ee24e1c, 0x24420001, 0x10a20005, 0x0, 0x80026ed,
+0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108,
+0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x8002703,
+0x0, 0x8ee24e18, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18, 0x210c0, 0x24424e28,
+0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a,
+0x3c040001, 0xafab0010, 0x8ee27254, 0x3c040001, 0x248448e0, 0x3c050004,
+0xafa20014, 0x8ee604d4, 0x800284a, 0x34a5f014, 0x8ee27254, 0x34843800,
+0x3641821, 0x24420010, 0x43102b, 0x14400070, 0x0, 0x8ee27254,
+0x24480010, 0x3641021, 0x102102b, 0x14400002, 0x3c02ffff, 0x1024021,
+0x8f850100, 0x27623000, 0x24a60020, 0xc2102b, 0x50400001, 0x27662800,
+0x8f820108, 0x14c20007, 0x2563000c, 0x8ee201a4, 0x4821, 0x24420001,
+0xaee201a4, 0x8002774, 0x8ee201a4, 0x2c64000c, 0x1441021, 0xaca20000,
+0xaca30004, 0x24e2fff4, 0xa4a2000e, 0x24020006, 0xaca80008, 0xaca20018,
+0x8ee204d4, 0xaca2001c, 0x8ee204b8, 0x3c030002, 0x431025, 0xaca20010,
+0xaf860100, 0x92e204dc, 0x14400037, 0x24090001, 0x8ee24e18, 0x210c0,
+0x24424e28, 0x2e22021, 0x8c830000, 0x24020005, 0x1462001f, 0x0,
+0x8ee34e18, 0x8ee24e1c, 0x1062001b, 0x24030040, 0x8c820004, 0x24420001,
+0xac820004, 0x8ee24e1c, 0x8ee54e18, 0x24420001, 0x10430007, 0x0,
+0x8ee24e1c, 0x24420001, 0x10a20005, 0x0, 0x800275e, 0x0,
+0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108,
+0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x8002774, 0x0,
+0x8ee24e18, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e18,
+0x24420001, 0xaee24e18, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021,
+0x24020005, 0xac820000, 0x24020001, 0xac820004, 0x1520000a, 0x2508fffc,
+0xafab0010, 0x8ee27254, 0x3c040001, 0x248448e0, 0x3c050004, 0xafa20014,
+0x8ee604d4, 0x800284a, 0x34a5f015, 0x34028100, 0xa5020000, 0x9582000e,
+0x80027ee, 0xa5020002, 0x8f850100, 0x27623000, 0x24a60020, 0xc2102b,
+0x50400001, 0x27662800, 0x8f820108, 0x14c20007, 0x2563000c, 0x8ee201a4,
+0x4821, 0x24420001, 0xaee201a4, 0x80027de, 0x8ee201a4, 0x2c64000c,
+0x1441021, 0xaca20000, 0xaca30004, 0x8ee37254, 0x24e2fff4, 0xa4a2000e,
+0x24020006, 0xaca20018, 0x24630010, 0xaca30008, 0x8ee204d4, 0xaca2001c,
+0x8ee204b8, 0x3c030002, 0x431025, 0xaca20010, 0xaf860100, 0x92e204dc,
+0x14400037, 0x24090001, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021,
+0x8c830000, 0x24020005, 0x1462001f, 0x0, 0x8ee34e18, 0x8ee24e1c,
+0x1062001b, 0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c,
+0x8ee54e18, 0x24420001, 0x10430007, 0x0, 0x8ee24e1c, 0x24420001,
+0x10a20005, 0x0, 0x80027c8, 0x0, 0x14a00005, 0x0,
+0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011,
+0x50400013, 0xac800000, 0x80027de, 0x0, 0x8ee24e18, 0x24030040,
+0x24420001, 0x50430003, 0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18,
+0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x24020005, 0xac820000,
+0x24020001, 0xac820004, 0x1520000a, 0x34028100, 0xafab0010, 0x8ee27254,
+0x3c040001, 0x248448e0, 0x3c050004, 0xafa20014, 0x8ee604d4, 0x800284a,
+0x34a5f016, 0x8ee37254, 0xa462000c, 0x8ee37254, 0x9582000e, 0xa462000e,
+0x800284e, 0x24e70004, 0x8f830100, 0x27623000, 0x24640020, 0x82102b,
+0x50400001, 0x27642800, 0x8f820108, 0x14820007, 0x24050005, 0x8ee201a4,
+0x4821, 0x24420001, 0xaee201a4, 0x8002842, 0x8ee201a4, 0xac6a0000,
+0xac6b0004, 0x8ee27254, 0xa467000e, 0xac650018, 0xac620008, 0x8ee204d4,
+0xac62001c, 0x8ee204b8, 0xac620010, 0xaf840100, 0x92e204dc, 0x14400036,
+0x24090001, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x8c820000,
+0x1445001f, 0x0, 0x8ee34e18, 0x8ee24e1c, 0x1062001b, 0x24030040,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c, 0x8ee54e18, 0x24420001,
+0x10430007, 0x0, 0x8ee24e1c, 0x24420001, 0x10a20005, 0x0,
+0x800282c, 0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020,
+0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
+0x8002842, 0x0, 0x8ee24e18, 0x24030040, 0x24420001, 0x50430003,
+0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18, 0x210c0,
+0x24424e28, 0x2e22021, 0x24020005, 0xac820000, 0x24020001, 0xac820004,
+0x1520000b, 0x3c050004, 0x3c040001, 0x248448f8, 0xafab0010, 0xafa00014,
+0x8ee604d4, 0x34a5f017, 0xc0023a7, 0x30e7ffff, 0x800286d, 0x0,
+0x8ee27254, 0x3c050001, 0x30e4ffff, 0x441021, 0xaee27254, 0x8ee2724c,
+0x8ee37254, 0x34a53800, 0x441021, 0xaee2724c, 0x3651021, 0x62182b,
+0x14600004, 0x3c03ffff, 0x8ee27254, 0x431021, 0xaee27254, 0x8ee304d4,
+0x96e20458, 0x24630001, 0x2442ffff, 0x621824, 0xaee304d4, 0x8ee304d4,
+0x8ee204d0, 0x14620005, 0x0, 0x8f820060, 0x2403fff7, 0x431024,
+0xaf820060, 0x8fbf0020, 0x3e00008, 0x27bd0028, 0x27bdffe0, 0xafbf0018,
+0x8ee304d8, 0x8ee204d0, 0x10620180, 0x0, 0x8ee204d8, 0x8ee304ec,
+0x21100, 0x621821, 0x94670008, 0x92e204dd, 0x8c680000, 0x8c690004,
+0x10400023, 0x946a000a, 0x8ee204b8, 0x34460400, 0x31420200, 0x1040001f,
+0x0, 0x96e2045a, 0x30420010, 0x1040001b, 0x3c028000, 0x3c010001,
+0x370821, 0xac2283c8, 0x8ee27254, 0x9464000e, 0x3c050001, 0x34a53800,
+0x24420004, 0xaee27254, 0x8ee37254, 0x42400, 0x3651021, 0x3c010001,
+0x370821, 0xac2483cc, 0x62182b, 0x14600005, 0x24e70004, 0x8ee27254,
+0x3c03ffff, 0x431021, 0xaee27254, 0x8ee27254, 0x80028a3, 0xaee27248,
+0x8ee604b8, 0x8ee2725c, 0x30e4ffff, 0x44102a, 0x10400015, 0x0,
+0x8f8200d8, 0x8ee37248, 0x431023, 0xaee2725c, 0x8ee2725c, 0x1c400007,
+0x44102a, 0x8ee2725c, 0x3c030001, 0x431021, 0xaee2725c, 0x8ee2725c,
+0x44102a, 0x10400006, 0x0, 0x8ee201b4, 0x24420001, 0xaee201b4,
+0x80029f5, 0x8ee201b4, 0x3c020001, 0x571021, 0x8c4283c8, 0x54400001,
+0x24e7fffc, 0x31420004, 0x104000b3, 0x30e2ffff, 0x3c020001, 0x571021,
+0x8c4283c8, 0x1040002c, 0x5021, 0x8f840100, 0x27623000, 0x24850020,
+0xa2102b, 0x50400001, 0x27652800, 0x8f820108, 0x10a2002c, 0x24020015,
+0xac880000, 0xac890004, 0x8ee37254, 0xa487000e, 0xac820018, 0xac830008,
+0x8ee204d8, 0x3c030001, 0x771821, 0x8c6383cc, 0xac860010, 0x431025,
+0xac82001c, 0xaf850100, 0x92e204dc, 0x14400063, 0x240a0001, 0x8ee24e18,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e18, 0x24420001,
+0xaee24e18, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e21821, 0x24020015,
+0xac620000, 0x24020001, 0x8002945, 0xac620004, 0x8f840100, 0x27623000,
+0x24850020, 0xa2102b, 0x50400001, 0x27652800, 0x8f820108, 0x14a20006,
+0x24020006, 0x8ee201a4, 0x24420001, 0xaee201a4, 0x8002945, 0x8ee201a4,
+0xac880000, 0xac890004, 0x8ee37254, 0xa487000e, 0xac820018, 0xac830008,
+0x8ee204d8, 0xac860010, 0xac82001c, 0xaf850100, 0x92e204dc, 0x14400037,
+0x240a0001, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021, 0x8c830000,
+0x24020005, 0x1462001f, 0x0, 0x8ee34e18, 0x8ee24e1c, 0x1062001b,
+0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c, 0x8ee54e18,
+0x24420001, 0x10430007, 0x0, 0x8ee24e1c, 0x24420001, 0x10a20005,
+0x0, 0x800292f, 0x0, 0x14a00005, 0x0, 0x8f820108,
+0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x8002945, 0x0, 0x8ee24e18, 0x24030040, 0x24420001,
+0x50430003, 0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18,
+0x210c0, 0x24424e28, 0x2e22021, 0x24020005, 0xac820000, 0x24020001,
+0xac820004, 0x1540000a, 0x24020001, 0xafa90010, 0x8ee27254, 0x3c040001,
+0x248448e0, 0x3c050004, 0xafa20014, 0x8ee604d4, 0x80029d2, 0x34a5f204,
+0xa2e204dd, 0x8ee204d8, 0x8ee304ec, 0x8ee47248, 0x3c060001, 0x34c63800,
+0x3c010001, 0x370821, 0xac2083c8, 0x3c010001, 0x370821, 0xac2083cc,
+0x21100, 0x431021, 0xac44000c, 0x8ee27254, 0x2405fff8, 0x30e3ffff,
+0x431021, 0x24420007, 0x451024, 0x24630007, 0xaee27248, 0x8ee2725c,
+0x8ee47248, 0x651824, 0x431023, 0xaee2725c, 0x3661021, 0x82202b,
+0x14800004, 0x3c03ffff, 0x8ee27248, 0x431021, 0xaee27248, 0x8ee27248,
+0x80029e7, 0xaee27254, 0x10400070, 0x0, 0x8f830100, 0x27623000,
+0x24640020, 0x82102b, 0x14400002, 0x5021, 0x27642800, 0x8f820108,
+0x14820006, 0x24050005, 0x8ee201a4, 0x24420001, 0xaee201a4, 0x80029c9,
+0x8ee201a4, 0xac680000, 0xac690004, 0x8ee27254, 0xa467000e, 0xac650018,
+0xac620008, 0x8ee204d8, 0xac660010, 0xac62001c, 0xaf840100, 0x92e204dc,
+0x14400036, 0x240a0001, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e22021,
+0x8c820000, 0x1445001f, 0x0, 0x8ee34e18, 0x8ee24e1c, 0x1062001b,
+0x24030040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e1c, 0x8ee54e18,
+0x24420001, 0x10430007, 0x0, 0x8ee24e1c, 0x24420001, 0x10a20005,
+0x0, 0x80029b3, 0x0, 0x14a00005, 0x0, 0x8f820108,
+0x24420020, 0xaf820108, 0x8f820108, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x80029c9, 0x0, 0x8ee24e18, 0x24030040, 0x24420001,
+0x50430003, 0x1021, 0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18,
+0x210c0, 0x24424e28, 0x2e22021, 0x24020005, 0xac820000, 0x24020001,
+0xac820004, 0x1540000c, 0x30e5ffff, 0x3c040001, 0x248448f8, 0x3c050004,
+0xafa90010, 0xafa00014, 0x8ee604d4, 0x34a5f237, 0xc0023a7, 0x30e7ffff,
+0x80029f5, 0x0, 0x8ee27254, 0x451021, 0xaee27254, 0x8ee2725c,
+0x8ee37254, 0x3c040001, 0x34843800, 0xa2e004dd, 0x451023, 0xaee2725c,
+0x3641021, 0x62182b, 0x14600004, 0x3c03ffff, 0x8ee27254, 0x431021,
+0xaee27254, 0x8ee304d8, 0x96e20458, 0x24630001, 0x2442ffff, 0x621824,
+0xaee304d8, 0x8ee304d8, 0x8ee204d0, 0x14620005, 0x0, 0x8f820060,
+0x2403fff7, 0x431024, 0xaf820060, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x27bdffe0, 0xafbf001c, 0xafb00018, 0x8f820100, 0x8ee34e1c, 0x8f820104,
+0x8f850108, 0x24020040, 0x24630001, 0x50620003, 0x1021, 0x8ee24e1c,
+0x24420001, 0xaee24e1c, 0x8ee24e1c, 0x8ee34e1c, 0x210c0, 0x24424e28,
+0x2e22021, 0x8ee24e18, 0x8c870004, 0x14620007, 0xa03021, 0x8f820108,
+0x24420020, 0xaf820108, 0x8f820108, 0x8002a25, 0xac800000, 0x8ee24e1c,
+0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e1c, 0x24420001,
+0x210c0, 0x24424e28, 0x2e22021, 0x8c820004, 0x8f830108, 0x21140,
+0x621821, 0xaf830108, 0xac800000, 0x8cc30018, 0x2c620002, 0x144000b7,
+0x2c620004, 0x5440008a, 0x24030040, 0x2c620007, 0x104000b2, 0x2c620005,
+0x144000b0, 0x0, 0x8ee204e0, 0x471021, 0xaee204e0, 0x8ee204e0,
+0x8f43023c, 0x43102b, 0x144000b2, 0x0, 0x8ee304d4, 0x8ee204e8,
+0x506200ae, 0xa2e004e4, 0x8f830120, 0x27623800, 0x24660020, 0xc2102b,
+0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0, 0x8ee201a0,
+0x8021, 0x24420001, 0xaee201a0, 0x8002a93, 0x8ee201a0, 0x8ee204d4,
+0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c, 0xac620008, 0x24020008,
+0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004, 0x8ee204b4,
+0xac620010, 0xaf860120, 0x92e24e10, 0x14400037, 0x24100001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020012, 0x1462001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee54e20, 0x24420001, 0x10430007,
+0x0, 0x8ee24e24, 0x24420001, 0x10a20005, 0x0, 0x8002a7d,
+0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000, 0x8002a93,
+0x0, 0x8ee24e20, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020012, 0xac820000, 0x24020001, 0xac820004, 0x5600000b,
+0x24100001, 0x8ee204d4, 0x3c040001, 0x24844904, 0xafa00014, 0xafa20010,
+0x8ee605f8, 0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f006, 0x16000003,
+0x24020001, 0x8002ae9, 0xa2e204e4, 0x8ee2016c, 0x24420001, 0xaee2016c,
+0x8ee2016c, 0x8ee204d4, 0xa2e004e4, 0xaee004e0, 0xaee204e8, 0x8f42023c,
+0x5040003c, 0xaee07264, 0x8ee20180, 0x24420001, 0xaee20180, 0x8ee20180,
+0x8002ae9, 0xaee07264, 0x8ee204f4, 0x24420001, 0x50430003, 0x1021,
+0x8ee204f4, 0x24420001, 0xaee204f4, 0x8ee204f4, 0x8cc30018, 0x21080,
+0x571021, 0x8c4404f8, 0x24020003, 0x1462000f, 0x0, 0x3c020001,
+0x571021, 0x904283a1, 0x10400014, 0x0, 0x8ee201c8, 0x8ee35230,
+0x441021, 0xaee201c8, 0x8ee201cc, 0x641821, 0x306300ff, 0x8002ad9,
+0xaee35230, 0x8ee201c4, 0x8ee30e00, 0x441021, 0xaee201c4, 0x8ee201cc,
+0x641821, 0x306301ff, 0xaee30e00, 0x441021, 0xaee201cc, 0x8ee20000,
+0x34420040, 0x8002ae9, 0xaee20000, 0x94c7000e, 0x8cc2001c, 0x3c040001,
+0x24844910, 0xafa60014, 0xafa20010, 0x8cc60018, 0x3c050008, 0xc0023a7,
+0x34a50910, 0x8fbf001c, 0x8fb00018, 0x3e00008, 0x27bd0020, 0x27bdff98,
+0xafbf0060, 0xafbe005c, 0xafb60058, 0xafb50054, 0xafb40050, 0xafb3004c,
+0xafb20048, 0xafb10044, 0xafb00040, 0x8f830108, 0x8f820104, 0xafa00024,
+0x106203d9, 0xafa0002c, 0x3c1e0001, 0x37de3800, 0x3c0bffff, 0x8f930108,
+0x8e620018, 0x8f830104, 0x2443fffe, 0x2c620014, 0x104003c1, 0x31080,
+0x3c010001, 0x220821, 0x8c224920, 0x400008, 0x0, 0x9663000e,
+0x8ee2724c, 0x8ee404e0, 0x431021, 0xaee2724c, 0x8e63001c, 0x96e20458,
+0x24840001, 0xaee404e0, 0x24630001, 0x2442ffff, 0x621824, 0xaee304d4,
+0x8f42023c, 0x82202b, 0x148003ab, 0x0, 0x8f830120, 0x27623800,
+0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007,
+0x0, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8002b73,
+0x8ee201a0, 0x8ee204d4, 0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c,
+0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000,
+0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400037,
+0x24100001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000,
+0x24020012, 0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x240c0040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x104c0007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8002b5d, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x8002b73, 0x0, 0x8ee24e20, 0x240c0040, 0x24420001,
+0x504c0003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x24020012, 0x240c0001, 0xac820000,
+0xac8c0004, 0x5600000d, 0x24100001, 0x8ee204d4, 0x3c040001, 0x24844904,
+0xafa00014, 0xafa20010, 0x8ee605f8, 0x8f470228, 0x3c050009, 0x34a5f006,
+0xc0023a7, 0xafab0038, 0x8fab0038, 0x12000307, 0x240c0001, 0x8002e8b,
+0x0, 0x966c001c, 0xafac002c, 0x9662001e, 0x3c0c8000, 0xafac0024,
+0xae62001c, 0x8e75001c, 0x8ee204ec, 0x8ee404ec, 0x151900, 0x621021,
+0x8c52000c, 0x92e27b88, 0x641821, 0x9476000a, 0x14400003, 0x32c20002,
+0xaef27b94, 0xaef57b8c, 0x1040004b, 0x8021, 0x96e2045a, 0x30420002,
+0x10400047, 0x0, 0x8e63001c, 0x8ee204ec, 0x32100, 0x821021,
+0x8c42000c, 0x37e1821, 0x24420022, 0x43102b, 0x1440000a, 0x24050014,
+0x8ee204ec, 0x821021, 0x8c44000c, 0xafab0038, 0xc002edf, 0x2484000e,
+0x8fab0038, 0x8002bc7, 0x3050ffff, 0x8ee204ec, 0x821021, 0x8c42000c,
+0x9450000e, 0x94430010, 0x94440012, 0x94450014, 0x2038021, 0x2048021,
+0x2058021, 0x94430016, 0x94440018, 0x9445001a, 0x2038021, 0x2048021,
+0x2058021, 0x9443001c, 0x9444001e, 0x94420020, 0x2038021, 0x2048021,
+0x2028021, 0x101c02, 0x3202ffff, 0x628021, 0x8e63001c, 0x8ee204ec,
+0x102402, 0x32900, 0xa21021, 0x8c43000c, 0x3202ffff, 0x828021,
+0x37e1021, 0x24630018, 0x62182b, 0x14600009, 0x0, 0x8ee204ec,
+0xa21021, 0x8c43000c, 0x101027, 0x3c01ffff, 0x230821, 0x8002be4,
+0xa4220018, 0x8ee204ec, 0xa21021, 0x8c43000c, 0x101027, 0xa4620018,
+0x96e2045a, 0x8821, 0x30420008, 0x14400063, 0xa021, 0x8e63001c,
+0x8ee204ec, 0x33100, 0xc21021, 0x8c42000c, 0x37e1821, 0x24420022,
+0x43102b, 0x14400035, 0x0, 0x8ee204ec, 0xc21021, 0x8c42000c,
+0x24470010, 0x37e1021, 0xe2102b, 0x50400001, 0xeb3821, 0x8ee204ec,
+0x94f10000, 0xc21021, 0x8c42000c, 0x24470016, 0x37e1021, 0xe2102b,
+0x14400002, 0x2634ffec, 0xeb3821, 0x8ee204ec, 0x90e30001, 0xc21021,
+0x8c42000c, 0x2447001a, 0x37e1021, 0xe2102b, 0x14400002, 0x2838821,
+0xeb3821, 0x94e20000, 0x24e70002, 0x2228821, 0x37e1021, 0xe2102b,
+0x50400001, 0xeb3821, 0x94e20000, 0x24e70002, 0x2228821, 0x37e1021,
+0xe2102b, 0x50400001, 0xeb3821, 0x94e20000, 0x24e70002, 0x2228821,
+0x37e1021, 0xe2102b, 0x50400001, 0xeb3821, 0x94e20000, 0x8002c45,
+0x2228821, 0x8ee204ec, 0xc21021, 0x8c43000c, 0x8ee204ec, 0x94710010,
+0x8ee304ec, 0xc21021, 0x8c44000c, 0xc31821, 0x8c62000c, 0x2634ffec,
+0x90840017, 0x8ee304ec, 0x9442001a, 0x2848821, 0xc31821, 0x8c65000c,
+0x8ee304ec, 0x2228821, 0x8ee204ec, 0xc31821, 0xc21021, 0x8c44000c,
+0x8c62000c, 0x94a3001c, 0x9484001e, 0x94420020, 0x2238821, 0x2248821,
+0x2228821, 0x111c02, 0x3222ffff, 0x628821, 0x111c02, 0x3222ffff,
+0x628821, 0x32c20001, 0x104000b2, 0x0, 0x96e2045a, 0x30420001,
+0x104000ae, 0x32c20080, 0x10400008, 0x0, 0x92e27b88, 0x14400005,
+0x0, 0x240c0001, 0xa2ec7b88, 0xaef57b8c, 0xaef27b94, 0x8ee304ec,
+0x151100, 0x431021, 0x8c47000c, 0x37e1821, 0x24e2000e, 0x43102b,
+0x14400008, 0xe02021, 0x2405000e, 0xc002edf, 0xafab0038, 0x3042ffff,
+0x8fab0038, 0x8002c7e, 0x2028021, 0x94e60000, 0x24e70002, 0x94e50000,
+0x24e70002, 0x94e30000, 0x24e70002, 0x94e20000, 0x24e70002, 0x94e40000,
+0x24e70002, 0x2068021, 0x2058021, 0x2038021, 0x2028021, 0x94e20000,
+0x94e30002, 0x2048021, 0x2028021, 0x2038021, 0x101c02, 0x3202ffff,
+0x628021, 0x101c02, 0x3202ffff, 0x8ee47b8c, 0x628021, 0x14950004,
+0x3205ffff, 0x96620016, 0x8002c8c, 0x512021, 0x96620016, 0x542021,
+0x41402, 0x3083ffff, 0x432021, 0x852023, 0x41402, 0x822021,
+0x3084ffff, 0x50800001, 0x3404ffff, 0x8ee27b94, 0x24430017, 0x37e1021,
+0x62102b, 0x50400001, 0x6b1821, 0x90630000, 0x24020011, 0x14620031,
+0x24020006, 0x8ee27b94, 0x37e1821, 0x24420028, 0x43102b, 0x14400018,
+0x0, 0x8ee27b8c, 0x12a2000a, 0x32c20100, 0x8ee27b94, 0x3c01ffff,
+0x220821, 0x94220028, 0x822021, 0x41c02, 0x3082ffff, 0x622021,
+0x32c20100, 0x14400004, 0x41027, 0x92e27b88, 0x14400002, 0x41027,
+0x3044ffff, 0x8ee27b94, 0x3c01ffff, 0x220821, 0x8002cff, 0xa4240028,
+0x8ee27b8c, 0x12a20008, 0x32c20100, 0x8ee27b94, 0x94420028, 0x822021,
+0x41c02, 0x3082ffff, 0x622021, 0x32c20100, 0x14400004, 0x41027,
+0x92e27b88, 0x14400002, 0x41027, 0x3044ffff, 0x8ee27b94, 0x8002cff,
+0xa4440028, 0x1462002f, 0x37e1821, 0x8ee27b94, 0x24420032, 0x43102b,
+0x14400018, 0x0, 0x8ee27b8c, 0x12a2000a, 0x32c20100, 0x8ee27b94,
+0x3c01ffff, 0x220821, 0x94220032, 0x822021, 0x41c02, 0x3082ffff,
+0x622021, 0x32c20100, 0x14400004, 0x41027, 0x92e27b88, 0x14400002,
+0x41027, 0x3044ffff, 0x8ee27b94, 0x3c01ffff, 0x220821, 0x8002cff,
+0xa4240032, 0x8ee27b8c, 0x12a20008, 0x32c20100, 0x8ee27b94, 0x94420032,
+0x822021, 0x41c02, 0x3082ffff, 0x622021, 0x32c20100, 0x14400004,
+0x41027, 0x92e27b88, 0x14400002, 0x41027, 0x3044ffff, 0x8ee27b94,
+0xa4440032, 0x8fac0024, 0x1180002c, 0x37e1821, 0x8e420000, 0xae42fffc,
+0x2642000a, 0x43102b, 0x1440001b, 0x34038100, 0x26430004, 0x37e1021,
+0x62102b, 0x14400003, 0x602021, 0x6b1821, 0x602021, 0x8c620000,
+0x24630004, 0xae420000, 0x37e1021, 0x62102b, 0x50400001, 0x6b1821,
+0x8c620000, 0xac820000, 0x34028100, 0xa4620000, 0x24630002, 0x37e1021,
+0x62102b, 0x50400001, 0x6b1821, 0x97ac002e, 0x8002d29, 0xa46c0000,
+0x8e420004, 0x8e440008, 0xa6430008, 0x97ac002e, 0xa64c000a, 0xae420000,
+0xae440004, 0x9662000e, 0x2652fffc, 0x24420004, 0xa662000e, 0x9662000e,
+0x8ee3724c, 0x621821, 0xaee3724c, 0xafb20018, 0x8ee3724c, 0xafa3001c,
+0x8ee2724c, 0x2c42003c, 0x10400004, 0x24620001, 0x2403fffe, 0x431024,
+0xafa2001c, 0x32c20080, 0x1040000c, 0x32c20100, 0x8ee27b98, 0x24430001,
+0x210c0, 0x571021, 0xaee37b98, 0x8fa30018, 0x8fa4001c, 0xac437b9c,
+0xac447ba0, 0x8002e15, 0xaee0724c, 0x10400072, 0x0, 0x8ee27b98,
+0x24430001, 0x210c0, 0x571021, 0xaee37b98, 0x8fa30018, 0x8fa4001c,
+0xac437b9c, 0xac447ba0, 0x8ee27b98, 0x10400063, 0x4821, 0x5021,
+0x8f8200f0, 0x24480008, 0x27621800, 0x102102b, 0x50400001, 0x27681000,
+0x8f8200f4, 0x15020007, 0x0, 0x8ee201b0, 0x8021, 0x24420001,
+0xaee201b0, 0x8002d6f, 0x8ee201b0, 0x8f8300f0, 0x24100001, 0x1571021,
+0x8c447b9c, 0x8c457ba0, 0xac640000, 0xac650004, 0xaf8800f0, 0x16000006,
+0x2ea1021, 0x8ee20088, 0x24420001, 0xaee20088, 0x8002db4, 0x8ee20088,
+0x8c427ba0, 0x8ee400e0, 0x8ee500e4, 0x8ee67b8c, 0x401821, 0x1021,
+0xa32821, 0xa3382b, 0x822021, 0x872021, 0x8ee204ec, 0xc93021,
+0x63100, 0xaee400e0, 0xaee500e4, 0xc23021, 0x94c2000a, 0x240c0002,
+0x21142, 0x30430003, 0x106c0016, 0x28620003, 0x10400005, 0x240c0001,
+0x106c0008, 0x0, 0x8002db4, 0x0, 0x240c0003, 0x106c0017,
+0x0, 0x8002db4, 0x0, 0x8ee200e8, 0x8ee300ec, 0x24630001,
+0x2c640001, 0x441021, 0xaee200e8, 0xaee300ec, 0x8ee200e8, 0x8002db4,
+0x8ee300ec, 0x8ee200f0, 0x8ee300f4, 0x24630001, 0x2c640001, 0x441021,
+0xaee200f0, 0xaee300f4, 0x8ee200f0, 0x8002db4, 0x8ee300f4, 0x8ee200f8,
+0x8ee300fc, 0x24630001, 0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc,
+0x8ee200f8, 0x8ee300fc, 0x8ee27b98, 0x25290001, 0x122102b, 0x1440ffa0,
+0x254a0008, 0xa2e07b88, 0x8002e14, 0xaee07b98, 0x8f8200f0, 0x24470008,
+0x27621800, 0xe2102b, 0x50400001, 0x27671000, 0x8f8200f4, 0x14e20007,
+0x0, 0x8ee201b0, 0x8021, 0x24420001, 0xaee201b0, 0x8002dd2,
+0x8ee201b0, 0x8f8200f0, 0x24100001, 0x8fa30018, 0x8fa4001c, 0xac430000,
+0xac440004, 0xaf8700f0, 0x16000007, 0x0, 0x8ee20088, 0x24420001,
+0xaee20088, 0x8ee20088, 0x8002e15, 0xaee0724c, 0x8ee2724c, 0x8ee400e0,
+0x8ee500e4, 0x240c0002, 0x401821, 0x1021, 0xa32821, 0xa3302b,
+0x822021, 0x862021, 0x161142, 0x30430003, 0xaee400e0, 0xaee500e4,
+0x106c0017, 0x2c620003, 0x10400005, 0x240c0001, 0x106c0008, 0x0,
+0x8002e15, 0xaee0724c, 0x240c0003, 0x106c0019, 0x0, 0x8002e15,
+0xaee0724c, 0x8ee200e8, 0x8ee300ec, 0x24630001, 0x2c640001, 0x441021,
+0xaee200e8, 0xaee300ec, 0x8ee200e8, 0x8ee300ec, 0x8002e15, 0xaee0724c,
+0x8ee200f0, 0x8ee300f4, 0x24630001, 0x2c640001, 0x441021, 0xaee200f0,
+0xaee300f4, 0x8ee200f0, 0x8ee300f4, 0x8002e15, 0xaee0724c, 0x8ee200f8,
+0x8ee300fc, 0x24630001, 0x2c640001, 0x441021, 0xaee200f8, 0xaee300fc,
+0x8ee200f8, 0x8ee300fc, 0xaee0724c, 0x8e62001c, 0x96e30458, 0x8ee404e0,
+0x24420001, 0x2463ffff, 0x431024, 0x24840001, 0xaee204d4, 0xaee404e0,
+0x8f42023c, 0x82202b, 0x148000a5, 0x0, 0x8f830120, 0x27623800,
+0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007,
+0x0, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8002e79,
+0x8ee201a0, 0x8ee204d4, 0xac62001c, 0x8ee404a0, 0x8ee504a4, 0x2462001c,
+0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000,
+0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400037,
+0x24100001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000,
+0x24020012, 0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x240c0040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x104c0007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8002e63, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x8002e79, 0x0, 0x8ee24e20, 0x240c0040, 0x24420001,
+0x504c0003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x24020012, 0x240c0001, 0xac820000,
+0xac8c0004, 0x5600000d, 0x24100001, 0x8ee204d4, 0x3c040001, 0x24844904,
+0xafa00014, 0xafa20010, 0x8ee605f8, 0x8f470228, 0x3c050009, 0x34a5f006,
+0xc0023a7, 0xafab0038, 0x8fab0038, 0x16000003, 0x240c0001, 0x8002ec6,
+0xa2ec04e4, 0x8ee2016c, 0x24420001, 0xaee2016c, 0x8ee2016c, 0x8ee204d4,
+0xa2e004e4, 0xaee004e0, 0xaee07264, 0xaee204e8, 0x8f42023c, 0x10400030,
+0x0, 0x8ee20180, 0x24420001, 0xaee20180, 0x8002ec6, 0x8ee20180,
+0x8ee204f4, 0x240c0040, 0x24420001, 0x504c0003, 0x1021, 0x8ee204f4,
+0x24420001, 0xaee204f4, 0x8ee204f4, 0x8e630018, 0x240c0003, 0x21080,
+0x571021, 0x146c000f, 0x8c4404f8, 0x3c020001, 0x571021, 0x904283a1,
+0x10400014, 0x0, 0x8ee201c8, 0x8ee35230, 0x441021, 0xaee201c8,
+0x8ee201cc, 0x641821, 0x306300ff, 0x8002ec1, 0xaee35230, 0x8ee201c4,
+0x8ee30e00, 0x441021, 0xaee201c4, 0x8ee201cc, 0x641821, 0x306301ff,
+0xaee30e00, 0x441021, 0xaee201cc, 0x8ee20000, 0x34420040, 0xaee20000,
+0x8f820108, 0x24420020, 0xaf820108, 0x8f820108, 0x8f820108, 0x27633000,
+0x43102b, 0x14400002, 0x27622800, 0xaf820108, 0x8f830108, 0x8f820104,
+0x1462fc2c, 0x0, 0x8fbf0060, 0x8fbe005c, 0x8fb60058, 0x8fb50054,
+0x8fb40050, 0x8fb3004c, 0x8fb20048, 0x8fb10044, 0x8fb00040, 0x3e00008,
+0x27bd0068, 0x52843, 0x10a0000d, 0x3021, 0x3c030001, 0x34633800,
+0x3c07ffff, 0x3631021, 0x82102b, 0x50400001, 0x872021, 0x94820000,
+0x24840002, 0x24a5ffff, 0x14a0fff8, 0xc23021, 0x61c02, 0x30c2ffff,
+0x623021, 0x61c02, 0x30c2ffff, 0x623021, 0x3e00008, 0x30c2ffff,
+0x0, 0x0, 0x27bdff88, 0x240f0001, 0xafbf0070, 0xafbe006c,
+0xafb60068, 0xafb50064, 0xafb40060, 0xafb3005c, 0xafb20058, 0xafb10054,
+0xafb00050, 0xa3a00027, 0xafaf002c, 0x8ee204c4, 0x8021, 0x30420001,
+0x1440002a, 0xa3a00037, 0x8f8700e0, 0x8f8800c4, 0x8f8200e8, 0xe22023,
+0x2c821000, 0x50400001, 0x24841000, 0x420c2, 0x801821, 0x8ee400c8,
+0x8ee500cc, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xaee400c8, 0xaee500cc, 0x8f8300c8, 0x3c02000a, 0x3442efff, 0x1032023,
+0x44102b, 0x10400003, 0x3c02000a, 0x3442f000, 0x822021, 0x801821,
+0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021,
+0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, 0xaf8700e4, 0x8003429,
+0xaf8700e8, 0x3c020001, 0x571021, 0x904283b0, 0x1040000b, 0x0,
+0x3c140001, 0x297a021, 0x8e9483b4, 0x3c130001, 0x2779821, 0x8e7383b8,
+0x3c120001, 0x2579021, 0x80030ff, 0x8e5283bc, 0x8f8300e0, 0x8f8200e4,
+0x10430007, 0x8821, 0x8f8200e4, 0x24110001, 0x8c430000, 0x8c440004,
+0xafa30018, 0xafa4001c, 0x1620000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010,
+0x8f8200c8, 0x3c040001, 0x248449d0, 0xafa20014, 0x8f8600e0, 0x8f8700e4,
+0x3c050006, 0xc0023a7, 0x34a5f000, 0x8003429, 0x0, 0x8fa3001c,
+0x8fb20018, 0x3074ffff, 0x2694fffc, 0x621024, 0x10400058, 0x2409821,
+0x3c020080, 0x621024, 0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001,
+0xaee2007c, 0x8ee2007c, 0x8ee201ec, 0x24420001, 0xaee201ec, 0x8003423,
+0x8ee201ec, 0x3c060004, 0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008,
+0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, 0xaee20080, 0x8ee20080,
+0x8fa2001c, 0x441824, 0x10660021, 0xc3102b, 0x14400007, 0x0,
+0x106b0011, 0x0, 0x106a0015, 0x0, 0x8002fb5, 0x42042,
+0x10650023, 0xa3102b, 0x14400005, 0x0, 0x10690019, 0x0,
+0x8002fb5, 0x42042, 0x10680021, 0x0, 0x8002fb5, 0x42042,
+0x8ee20034, 0x24420001, 0xaee20034, 0x8ee20034, 0x8002fb5, 0x42042,
+0x8ee201dc, 0x24420001, 0xaee201dc, 0x8ee201dc, 0x8002fb5, 0x42042,
+0x8ee201e0, 0x24420001, 0xaee201e0, 0x8ee201e0, 0x8002fb5, 0x42042,
+0x8ee201e4, 0x24420001, 0xaee201e4, 0x8ee201e4, 0x8002fb5, 0x42042,
+0x8ee20030, 0x24420001, 0xaee20030, 0x8ee20030, 0x8002fb5, 0x42042,
+0x8ee201e8, 0x24420001, 0xaee201e8, 0x8ee201e8, 0x42042, 0x1087046d,
+0x0, 0x8002f7a, 0x0, 0x3c020001, 0x571021, 0x904283a2,
+0x14400084, 0x24020001, 0x3c030001, 0x771821, 0x906383a3, 0x1462007f,
+0x3c020100, 0x8e430000, 0x621024, 0x1040006f, 0x2402ffff, 0x14620005,
+0x24100001, 0x96430004, 0x3402ffff, 0x10620075, 0x0, 0x92e204c8,
+0x14400072, 0x0, 0x3c020001, 0x571021, 0x8c4283a4, 0x28420005,
+0x10400020, 0x3821, 0x3c020001, 0x571021, 0x8c4283a4, 0x18400016,
+0x2821, 0x96660000, 0x520c0, 0x971021, 0x9442776e, 0x14460009,
+0x971021, 0x94437770, 0x96620002, 0x14620005, 0x971021, 0x94437772,
+0x96620004, 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283a4,
+0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff, 0x10400431,
+0x0, 0x8003041, 0x0, 0x2402021, 0xc00229d, 0x24050006,
+0x3044001f, 0x428c0, 0x2e51021, 0x9442726c, 0x30424000, 0x14400425,
+0xb71021, 0x9443726e, 0x96620000, 0x1462000b, 0x418c0, 0xb71021,
+0x94437270, 0x96620002, 0x14620006, 0x418c0, 0xb71021, 0x94437272,
+0x96620004, 0x10620035, 0x418c0, 0x2e31021, 0x9442726c, 0x30428000,
+0x14400412, 0x2e31021, 0x944b726c, 0x96670000, 0xb28c0, 0xb71021,
+0x9442736e, 0x8003023, 0x3021, 0x420c0, 0x2e41021, 0x9443736c,
+0x2e41021, 0x944b736c, 0x30638000, 0x14600010, 0xb28c0, 0xb71021,
+0x9442736e, 0x1447fff5, 0x1602021, 0xb71021, 0x94437370, 0x96620002,
+0x5462fff1, 0x420c0, 0xb71021, 0x94437372, 0x96620004, 0x5462ffec,
+0x420c0, 0x24060001, 0x30c200ff, 0x104003f1, 0x0, 0x8003041,
+0x0, 0x97430202, 0x96420000, 0x146203eb, 0x0, 0x97430204,
+0x96420002, 0x146203e7, 0x0, 0x97430206, 0x96420004, 0x146203e3,
+0x0, 0x92420000, 0x3a030001, 0x30420001, 0x431024, 0x10400074,
+0x2402ffff, 0x8e630000, 0x14620004, 0x3402ffff, 0x96630004, 0x1062006f,
+0x240f0002, 0x3c020001, 0x571021, 0x904283a2, 0x1440006a, 0x240f0003,
+0x92e204c8, 0x54400068, 0xafaf002c, 0x3c020001, 0x571021, 0x8c4283a4,
+0x28420005, 0x10400020, 0x3821, 0x3c020001, 0x571021, 0x8c4283a4,
+0x18400016, 0x2821, 0x96660000, 0x520c0, 0x971021, 0x9442776e,
+0x14460009, 0x971021, 0x94437770, 0x96620002, 0x14620005, 0x971021,
+0x94437772, 0x96620004, 0x50620008, 0x24070001, 0x3c020001, 0x571021,
+0x8c4283a4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff,
+0x14400044, 0x240f0003, 0x8003423, 0x0, 0x2402021, 0xc00229d,
+0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442726c, 0x30424000,
+0x144003a0, 0xb71021, 0x9443726e, 0x96620000, 0x1462000b, 0x418c0,
+0xb71021, 0x94437270, 0x96620002, 0x14620006, 0x418c0, 0xb71021,
+0x94437272, 0x96620004, 0x10620027, 0x418c0, 0x2e31021, 0x9442726c,
+0x30428000, 0x1440038d, 0x2e31021, 0x944b726c, 0x96670000, 0xb28c0,
+0xb71021, 0x9442736e, 0x80030a8, 0x3021, 0x420c0, 0x2e41021,
+0x9443736c, 0x2e41021, 0x944b736c, 0x30638000, 0x14600010, 0xb28c0,
+0xb71021, 0x9442736e, 0x1447fff5, 0x1602021, 0xb71021, 0x94437370,
+0x96620002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437372, 0x96620004,
+0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff, 0x1040036c, 0x0,
+0x80030bb, 0x240f0003, 0x240f0001, 0xafaf002c, 0x8f420260, 0x54102b,
+0x1040003a, 0x0, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008,
+0xaf8300e4, 0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2801821, 0x1021,
+0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4,
+0x8ee20058, 0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, 0x24420001,
+0xaee2007c, 0x8ee2007c, 0x8f8200e0, 0xafa20010, 0x8f8200e4, 0x3c040001,
+0x248449d8, 0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, 0xc0023a7,
+0x34a5f003, 0x8003429, 0x0, 0x8ee25230, 0xafa20010, 0x8ee25234,
+0x3c040001, 0x248449e4, 0xafa20014, 0x8ee60e00, 0x8ee70e08, 0x3c050006,
+0xc0023a7, 0x34a5f002, 0x8ee201bc, 0x24420001, 0xaee201bc, 0x8ee20000,
+0x8ee301bc, 0x2403ffbf, 0x431024, 0x80033cd, 0xaee20000, 0x96e20468,
+0x54102b, 0x10400003, 0x0, 0x240f0001, 0xa3af0027, 0x128002f2,
+0x24160007, 0x24150040, 0x241e0001, 0x240e0012, 0x8ee2723c, 0x8f430280,
+0x24420001, 0x304203ff, 0x106202c4, 0x0, 0x93a20027, 0x10400014,
+0x0, 0x8ee35230, 0x8ee25234, 0x10620009, 0x26ed5234, 0x8ee65234,
+0x8ee35234, 0x21140, 0x24425238, 0x2e28021, 0x24630001, 0x800312b,
+0x306b00ff, 0x92e27238, 0x1440ffca, 0x0, 0x8ee201d0, 0x24420001,
+0xaee201d0, 0x8ee201d0, 0x8ee30e00, 0x8ee20e08, 0x1062ffc2, 0x26ed0e08,
+0x8ee60e08, 0x8ee30e08, 0x21140, 0x24420e10, 0x2e28021, 0x24630001,
+0x306b01ff, 0x96e2046a, 0x30420010, 0x10400019, 0x0, 0x9642000c,
+0x340f8100, 0x144f0015, 0x0, 0x3c020001, 0x571021, 0x904283b0,
+0x14400010, 0x0, 0x9642000e, 0xa6020016, 0x8e420008, 0x8e430004,
+0x8e440000, 0x2694fffc, 0xae42000c, 0xae430008, 0xae440004, 0x9602000e,
+0x26730004, 0x240f0001, 0xa3af0037, 0x34420200, 0xa602000e, 0x8e020000,
+0x8e030004, 0x3c040001, 0x34843800, 0x306a0007, 0x26a9823, 0x3641021,
+0x262102b, 0x10400005, 0x28aa021, 0x2641023, 0x3621823, 0x3c020020,
+0x439823, 0x26820007, 0x2404fff8, 0x9603000a, 0x446024, 0x6a1821,
+0x6c102b, 0x10400002, 0x1803821, 0x603821, 0xae130018, 0x8f880120,
+0x24e20007, 0x443824, 0x27623800, 0x25090020, 0x122102b, 0x50400001,
+0x27693000, 0x8f820128, 0x15220007, 0x1401821, 0x8ee201a0, 0x8821,
+0x24420001, 0xaee201a0, 0x80031b5, 0x8ee201a0, 0x8e040000, 0x8e050004,
+0x1021, 0xad130008, 0xa507000e, 0xad160018, 0xad06001c, 0xa3302b,
+0xa32823, 0x822023, 0x862023, 0xad040000, 0xad050004, 0x8ee204b0,
+0xad020010, 0xaf890120, 0x92e24e10, 0x14400033, 0x24110001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c820000, 0x1456001f, 0x0,
+0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0, 0x8c820004, 0x24420001,
+0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001, 0x10550007, 0x0,
+0x8ee24e24, 0x24420001, 0x10620005, 0x0, 0x80031a2, 0x0,
+0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
+0x8c820004, 0x2c420011, 0x50400010, 0xac800000, 0x80031b5, 0x0,
+0x8ee24e20, 0x24420001, 0x50550003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0xac960000,
+0xac9e0004, 0x16200018, 0x3c050006, 0x8e020018, 0x3c040001, 0x248449f0,
+0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009, 0x2003021, 0xc0023a7,
+0xafa30014, 0x93a20037, 0x1040020a, 0x340f8100, 0x8e420004, 0x8e430008,
+0x8e44000c, 0xa64f000c, 0xae420000, 0xae430004, 0xae440008, 0x96020016,
+0x80033cd, 0xa642000e, 0x14ec015f, 0x28a1823, 0x960c000a, 0x9603000e,
+0x28a1023, 0xa602000a, 0x34620004, 0xa602000e, 0x8f880120, 0x27623800,
+0x25090020, 0x122102b, 0x14400002, 0x306affff, 0x27693000, 0x8f820128,
+0x15220007, 0x24040020, 0x8ee201a0, 0x8821, 0x24420001, 0xaee201a0,
+0x8003230, 0x8ee201a0, 0x8ee5723c, 0x8ee60480, 0x8ee70484, 0xa504000e,
+0x24040004, 0xad100008, 0xad040018, 0x52940, 0xa01821, 0x1021,
+0xe33821, 0xe3202b, 0xc23021, 0xc43021, 0xad060000, 0xad070004,
+0x8ee2723c, 0xad02001c, 0x8ee204b4, 0xad020010, 0xaf890120, 0x92e24e10,
+0x14400033, 0x24110001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x1456001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x10550007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x800321d, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
+0xac800000, 0x8003230, 0x0, 0x8ee24e20, 0x24420001, 0x50550003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0xac960000, 0xac9e0004, 0x1620000d, 0x0,
+0xa60c000a, 0xa60a000e, 0x8f820100, 0xafa20010, 0x8f820104, 0x3c040001,
+0x248449fc, 0x3c050006, 0xafa20014, 0x8ee6723c, 0x8003398, 0x34a5f00b,
+0x3c010001, 0x370821, 0xa02083b0, 0xadab0000, 0x8ee201cc, 0x8ee3723c,
+0x2442ffff, 0xaee201cc, 0x8ee201cc, 0x24630001, 0x306303ff, 0x26e25234,
+0x15a20006, 0xaee3723c, 0x8ee201c8, 0x2442ffff, 0xaee201c8, 0x8003255,
+0x8ee201c8, 0x8ee201c4, 0x2442ffff, 0xaee201c4, 0x8ee201c4, 0x8f420240,
+0x10400070, 0x0, 0x8ee20e0c, 0x24420001, 0xaee20e0c, 0x8f430240,
+0x43102b, 0x1440016d, 0xa021, 0x8f830120, 0x27623800, 0x24660020,
+0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007, 0x0,
+0x8ee201a0, 0x8821, 0x24420001, 0xaee201a0, 0x80032b2, 0x8ee201a0,
+0x8ee2723c, 0xac62001c, 0x8ee40498, 0x8ee5049c, 0x2462001c, 0xac620008,
+0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000, 0xac650004,
+0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400033, 0x24110001,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c820000, 0x144e001f,
+0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0, 0x8c820004,
+0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001, 0x10550007,
+0x0, 0x8ee24e24, 0x24420001, 0x10620005, 0x0, 0x800329f,
+0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x8c820004, 0x2c420011, 0x50400010, 0xac800000, 0x80032b2,
+0x0, 0x8ee24e20, 0x24420001, 0x50550003, 0x1021, 0x8ee24e20,
+0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0xac8e0000, 0xac9e0004, 0x5620000d, 0x24110001, 0x8ee2723c, 0x3c040001,
+0x24844a08, 0xafa00014, 0xafa20010, 0x8ee6723c, 0x8f470280, 0x3c050009,
+0x34a5f008, 0xc0023a7, 0xafae0048, 0x8fae0048, 0x56200001, 0xaee00e0c,
+0x8ee20184, 0x24420001, 0xaee20184, 0x8003328, 0x8ee20184, 0x8f830120,
+0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128,
+0x14c20007, 0x0, 0x8ee201a0, 0x8821, 0x24420001, 0xaee201a0,
+0x800331a, 0x8ee201a0, 0x8ee2723c, 0xac62001c, 0x8ee40498, 0x8ee5049c,
+0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018,
+0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10,
+0x14400033, 0x24110001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x144e001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x10550007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8003307, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
+0xac800000, 0x800331a, 0x0, 0x8ee24e20, 0x24420001, 0x50550003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0xac8e0000, 0xac9e0004, 0x1620000d, 0x0,
+0x8ee2723c, 0x3c040001, 0x24844a08, 0xafa00014, 0xafa20010, 0x8ee6723c,
+0x8f470280, 0x3c050009, 0x34a5f008, 0xc0023a7, 0xafae0048, 0x8fae0048,
+0x8ee20170, 0x24420001, 0xaee20170, 0x8ee20170, 0x80033cb, 0xa021,
+0x960c000a, 0x183102b, 0x54400001, 0x1801821, 0xa603000a, 0x8f880120,
+0x27623800, 0x25090020, 0x122102b, 0x50400001, 0x27693000, 0x8f820128,
+0x15220007, 0x24040020, 0x8ee201a0, 0x8821, 0x24420001, 0xaee201a0,
+0x800338c, 0x8ee201a0, 0x8ee5723c, 0x8ee60480, 0x8ee70484, 0xa504000e,
+0x24040004, 0xad100008, 0xad040018, 0x52940, 0xa01821, 0x1021,
+0xe33821, 0xe3202b, 0xc23021, 0xc43021, 0xad060000, 0xad070004,
+0x8ee2723c, 0xad02001c, 0x8ee204b4, 0xad020010, 0xaf890120, 0x92e24e10,
+0x14400033, 0x24110001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x1456001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x10550007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8003379, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
+0xac800000, 0x800338c, 0x0, 0x8ee24e20, 0x24420001, 0x50550003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0xac960000, 0xac9e0004, 0x1620001d, 0x0,
+0xa60c000a, 0x8f820100, 0xafa20010, 0x8f820104, 0x3c040001, 0x248449fc,
+0x3c050006, 0xafa20014, 0x8ee6723c, 0x34a5f00d, 0xc0023a7, 0x2003821,
+0x93a20037, 0x10400031, 0x340f8100, 0x8e420004, 0x8e430008, 0x8e44000c,
+0xa64f000c, 0xae420000, 0xae430004, 0xae440008, 0x96020016, 0xa642000e,
+0x9602000e, 0x3042fdff, 0x80033cd, 0xa602000e, 0x8ee201cc, 0x2442ffff,
+0xaee201cc, 0x8ee201cc, 0x8ee201c4, 0x3c04001f, 0x3c010001, 0x370821,
+0xa03e83b0, 0x2442ffff, 0xaee201c4, 0x9603000a, 0x3484ffff, 0x8ee201c4,
+0x6a1821, 0x2639821, 0x93202b, 0x10800003, 0x3c02fff5, 0x34421000,
+0x2629821, 0xadab0000, 0x8ee2723c, 0x24420001, 0x304203ff, 0xaee2723c,
+0x8f420240, 0x10400004, 0x283a023, 0x8ee20e0c, 0x24420001, 0xaee20e0c,
+0xa3a00027, 0x1680fd38, 0x0, 0x12800024, 0x0, 0x3c010001,
+0x370821, 0xac3483b4, 0x3c010001, 0x370821, 0xac3383b8, 0x3c010001,
+0x370821, 0xac3283bc, 0x93a20037, 0x10400008, 0x0, 0x3c020001,
+0x571021, 0x8c4283bc, 0x24420004, 0x3c010001, 0x370821, 0xac2283bc,
+0x8ee2723c, 0x8f430280, 0x24420001, 0x304203ff, 0x14620006, 0x0,
+0x8ee201c0, 0x24420001, 0xaee201c0, 0x8003429, 0x8ee201c0, 0x8ee201b8,
+0x24420001, 0xaee201b8, 0x8003429, 0x8ee201b8, 0x97a4001e, 0x2484fffc,
+0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b,
+0x822021, 0x862021, 0xaee400c0, 0xaee500c4, 0x8faf002c, 0x24020002,
+0x11e2000f, 0x29e20003, 0x14400017, 0x24020003, 0x15e20015, 0x0,
+0x8ee200d0, 0x8ee300d4, 0x24630001, 0x2c640001, 0x441021, 0xaee200d0,
+0xaee300d4, 0x8ee200d0, 0x8003423, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc,
+0x24630001, 0x2c640001, 0x441021, 0xaee200d8, 0xaee300dc, 0x8ee200d8,
+0x8003423, 0x8ee300dc, 0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001,
+0x441021, 0xaee200c8, 0xaee300cc, 0x8ee200c8, 0x8ee300cc, 0x8f8300e4,
+0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8fbf0070,
+0x8fbe006c, 0x8fb60068, 0x8fb50064, 0x8fb40060, 0x8fb3005c, 0x8fb20058,
+0x8fb10054, 0x8fb00050, 0x3e00008, 0x27bd0078, 0x27bdffb0, 0xafb50044,
+0xa821, 0xafb00030, 0x8021, 0xafbf004c, 0xafb60048, 0xafb40040,
+0xafb3003c, 0xafb20038, 0xafb10034, 0x8ee204c4, 0x24140001, 0x30420001,
+0x1440002a, 0xb021, 0x8f8700e0, 0x8f8800c4, 0x8f8200e8, 0xe22023,
+0x2c821000, 0x50400001, 0x24841000, 0x420c2, 0x801821, 0x8ee400c8,
+0x8ee500cc, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xaee400c8, 0xaee500cc, 0x8f8300c8, 0x3c02000a, 0x3442efff, 0x1032023,
+0x44102b, 0x10400003, 0x3c02000a, 0x3442f000, 0x822021, 0x801821,
+0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021,
+0x862021, 0xaee400c0, 0xaee500c4, 0xaf8800c8, 0xaf8700e4, 0x80037aa,
+0xaf8700e8, 0x3c020001, 0x571021, 0x904283b0, 0x1040000b, 0x0,
+0x3c130001, 0x2779821, 0x8e7383b4, 0x3c110001, 0x2378821, 0x8e3183b8,
+0x3c120001, 0x2579021, 0x8003645, 0x8e5283bc, 0x8f8300e0, 0x8f8200e4,
+0x10430007, 0x4821, 0x8f8200e4, 0x24090001, 0x8c430000, 0x8c440004,
+0xafa30018, 0xafa4001c, 0x1520000e, 0x3c02ffff, 0x8f8200c4, 0xafa20010,
+0x8f8200c8, 0x3c040001, 0x248449d0, 0xafa20014, 0x8f8600e0, 0x8f8700e4,
+0x3c050006, 0xc0023a7, 0x34a5f000, 0x80037aa, 0x0, 0x8fa3001c,
+0x8fb20018, 0x3073ffff, 0x2673fffc, 0x621024, 0x10400058, 0x2408821,
+0x3c020080, 0x621024, 0x1040000a, 0x3c040040, 0x8ee2007c, 0x24420001,
+0xaee2007c, 0x8ee2007c, 0x8ee201ec, 0x24420001, 0xaee201ec, 0x80037a4,
+0x8ee201ec, 0x3c060004, 0x3c0b0001, 0x3c0a0002, 0x3c050010, 0x3c090008,
+0x8ee20080, 0x3c080020, 0x34078000, 0x24420001, 0xaee20080, 0x8ee20080,
+0x8fa2001c, 0x441824, 0x10660021, 0xc3102b, 0x14400007, 0x0,
+0x106b0011, 0x0, 0x106a0015, 0x0, 0x80034ef, 0x42042,
+0x10650023, 0xa3102b, 0x14400005, 0x0, 0x10690019, 0x0,
+0x80034ef, 0x42042, 0x10680021, 0x0, 0x80034ef, 0x42042,
+0x8ee20034, 0x24420001, 0xaee20034, 0x8ee20034, 0x80034ef, 0x42042,
+0x8ee201dc, 0x24420001, 0xaee201dc, 0x8ee201dc, 0x80034ef, 0x42042,
+0x8ee201e0, 0x24420001, 0xaee201e0, 0x8ee201e0, 0x80034ef, 0x42042,
+0x8ee201e4, 0x24420001, 0xaee201e4, 0x8ee201e4, 0x80034ef, 0x42042,
+0x8ee20030, 0x24420001, 0xaee20030, 0x8ee20030, 0x80034ef, 0x42042,
+0x8ee201e8, 0x24420001, 0xaee201e8, 0x8ee201e8, 0x42042, 0x108702b4,
+0x0, 0x80034b4, 0x0, 0x3c020001, 0x571021, 0x904283a2,
+0x14400084, 0x24020001, 0x3c030001, 0x771821, 0x906383a3, 0x1462007f,
+0x3c020100, 0x8e430000, 0x621024, 0x1040006f, 0x2402ffff, 0x14620005,
+0x24100001, 0x96430004, 0x3402ffff, 0x10620075, 0x0, 0x92e204c8,
+0x14400072, 0x0, 0x3c020001, 0x571021, 0x8c4283a4, 0x28420005,
+0x10400020, 0x3821, 0x3c020001, 0x571021, 0x8c4283a4, 0x18400016,
+0x2821, 0x96260000, 0x520c0, 0x971021, 0x9442776e, 0x14460009,
+0x971021, 0x94437770, 0x96220002, 0x14620005, 0x971021, 0x94437772,
+0x96220004, 0x50620008, 0x24070001, 0x3c020001, 0x571021, 0x8c4283a4,
+0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff, 0x10400278,
+0x0, 0x800357b, 0x0, 0x2402021, 0xc00229d, 0x24050006,
+0x3044001f, 0x428c0, 0x2e51021, 0x9442726c, 0x30424000, 0x1440026c,
+0xb71021, 0x9443726e, 0x96220000, 0x1462000b, 0x418c0, 0xb71021,
+0x94437270, 0x96220002, 0x14620006, 0x418c0, 0xb71021, 0x94437272,
+0x96220004, 0x10620035, 0x418c0, 0x2e31021, 0x9442726c, 0x30428000,
+0x14400259, 0x2e31021, 0x9448726c, 0x96270000, 0x828c0, 0xb71021,
+0x9442736e, 0x800355d, 0x3021, 0x420c0, 0x2e41021, 0x9443736c,
+0x2e41021, 0x9448736c, 0x30638000, 0x14600010, 0x828c0, 0xb71021,
+0x9442736e, 0x1447fff5, 0x1002021, 0xb71021, 0x94437370, 0x96220002,
+0x5462fff1, 0x420c0, 0xb71021, 0x94437372, 0x96220004, 0x5462ffec,
+0x420c0, 0x24060001, 0x30c200ff, 0x10400238, 0x0, 0x800357b,
+0x0, 0x97430202, 0x96420000, 0x14620232, 0x0, 0x97430204,
+0x96420002, 0x1462022e, 0x0, 0x97430206, 0x96420004, 0x1462022a,
+0x0, 0x92420000, 0x3a030001, 0x30420001, 0x431024, 0x10400074,
+0x2402ffff, 0x8e230000, 0x14620004, 0x3402ffff, 0x96230004, 0x1062006f,
+0x24140002, 0x3c020001, 0x571021, 0x904283a2, 0x1440006a, 0x24140003,
+0x92e204c8, 0x14400067, 0x0, 0x3c020001, 0x571021, 0x8c4283a4,
+0x28420005, 0x10400020, 0x3821, 0x3c020001, 0x571021, 0x8c4283a4,
+0x18400016, 0x2821, 0x96260000, 0x520c0, 0x971021, 0x9442776e,
+0x14460009, 0x971021, 0x94437770, 0x96220002, 0x14620005, 0x971021,
+0x94437772, 0x96220004, 0x50620008, 0x24070001, 0x3c020001, 0x571021,
+0x8c4283a4, 0x24a50001, 0xa2102a, 0x5440ffee, 0x520c0, 0x30e200ff,
+0x14400044, 0x24140003, 0x80037a4, 0x0, 0x2402021, 0xc00229d,
+0x24050006, 0x3044001f, 0x428c0, 0x2e51021, 0x9442726c, 0x30424000,
+0x144001e7, 0xb71021, 0x9443726e, 0x96220000, 0x1462000b, 0x418c0,
+0xb71021, 0x94437270, 0x96220002, 0x14620006, 0x418c0, 0xb71021,
+0x94437272, 0x96220004, 0x10620027, 0x418c0, 0x2e31021, 0x9442726c,
+0x30428000, 0x144001d4, 0x2e31021, 0x9448726c, 0x96270000, 0x828c0,
+0xb71021, 0x9442736e, 0x80035e2, 0x3021, 0x420c0, 0x2e41021,
+0x9443736c, 0x2e41021, 0x9448736c, 0x30638000, 0x14600010, 0x828c0,
+0xb71021, 0x9442736e, 0x1447fff5, 0x1002021, 0xb71021, 0x94437370,
+0x96220002, 0x5462fff1, 0x420c0, 0xb71021, 0x94437372, 0x96220004,
+0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff, 0x104001b3, 0x0,
+0x80035f5, 0x24140003, 0x24140001, 0x8f420260, 0x53102b, 0x10400049,
+0x0, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008, 0xaf8300e4,
+0xaf8300e8, 0x8ee400c0, 0x8ee500c4, 0x2601821, 0x1021, 0xa32821,
+0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4, 0x8ee20058,
+0x24420001, 0xaee20058, 0x8ee20058, 0x8ee2007c, 0x24420001, 0xaee2007c,
+0x8ee2007c, 0x8f8200e0, 0xafa20010, 0x8f8200e4, 0x3c040001, 0x248449d8,
+0xafa20014, 0x8fa60018, 0x8fa7001c, 0x3c050006, 0xc0023a7, 0x34a5f003,
+0x80037aa, 0x0, 0x8ee25230, 0xafa20010, 0x8ee25234, 0x3c040001,
+0x248449e4, 0xafa20014, 0x8ee60e00, 0x8ee70e08, 0xc0023a7, 0x34a5f002,
+0x8ee201bc, 0x24420001, 0xaee201bc, 0x8ee20000, 0x8ee301bc, 0x2403ffbf,
+0x431024, 0x8003752, 0xaee20000, 0x8ee25230, 0xafa20010, 0x8ee25234,
+0x3c040001, 0x248449e4, 0xafa20014, 0x8ee60e00, 0x8ee70e08, 0x3c050006,
+0xc0023a7, 0x34a5f002, 0x8ee201bc, 0x24420001, 0xaee201bc, 0x8003752,
+0x8ee201bc, 0x96e20468, 0x53102b, 0x54400001, 0x3c158000, 0x1260012e,
+0x3c0c001f, 0x358cffff, 0x8ee2723c, 0x8f430280, 0x24420001, 0x304203ff,
+0x10620105, 0x0, 0x12a00014, 0x0, 0x8ee35230, 0x8ee25234,
+0x10620009, 0x26ee5234, 0x8eeb5234, 0x8ee35234, 0x21140, 0x24425238,
+0x2e28021, 0x24630001, 0x800366f, 0x306800ff, 0x92e27238, 0x1440ffc0,
+0x3c050006, 0x8ee201d0, 0x24420001, 0xaee201d0, 0x8ee201d0, 0x8ee30e00,
+0x8ee20e08, 0x1062ffcb, 0x26ee0e08, 0x8eeb0e08, 0xa821, 0x8ee30e08,
+0x21140, 0x24420e10, 0x2e28021, 0x24630001, 0x306801ff, 0x96e2046a,
+0x30420010, 0x10400017, 0x34028100, 0x9643000c, 0x14620014, 0x0,
+0x3c020001, 0x571021, 0x904283b0, 0x1440000f, 0x0, 0x9642000e,
+0xa6020016, 0x8e420008, 0x8e430004, 0x8e440000, 0x2673fffc, 0xae42000c,
+0xae430008, 0xae440004, 0x9602000e, 0x26310004, 0x24160001, 0x34420200,
+0xa602000e, 0x9603000a, 0x2605021, 0x73102b, 0x10400002, 0x2606821,
+0x605021, 0x2d42003d, 0x1040002a, 0x3821, 0x9623000c, 0x24020800,
+0x54620027, 0xae110018, 0x3c020001, 0x571021, 0x904283b0, 0x54400022,
+0xae110018, 0x26220017, 0x182102b, 0x10400013, 0x0, 0x3c02fff5,
+0x511021, 0x90421017, 0x38430006, 0x2c630001, 0x38420011, 0x2c420001,
+0x621825, 0x10600013, 0x26220010, 0x182102b, 0x1040000e, 0x0,
+0x3c07fff5, 0xf13821, 0x94e71010, 0x80036bb, 0x24e7000e, 0x92220017,
+0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x50600004,
+0xae110018, 0x96270010, 0x24e7000e, 0xae110018, 0x3c020001, 0x571021,
+0x904283b0, 0x2102b, 0x14e00002, 0x24ec0, 0x1403821, 0x8f830120,
+0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128,
+0x14c20007, 0x2402000b, 0x8ee201a0, 0x4821, 0x24420001, 0xaee201a0,
+0x8003719, 0x8ee201a0, 0x8e040000, 0x8e050004, 0xac620018, 0x1751025,
+0x491025, 0xac710008, 0xa467000e, 0xac62001c, 0xac640000, 0xac650004,
+0x8ee204b0, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400038, 0x24090001,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000, 0x24020007,
+0x14620020, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001c, 0x0,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee34e24, 0x8ee54e20, 0x24020040,
+0x24630001, 0x10620007, 0x0, 0x8ee24e24, 0x24420001, 0x10a20005,
+0x0, 0x8003703, 0x0, 0x14a00005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x8003719, 0x0, 0x8ee24e20, 0x24030040, 0x24420001,
+0x50430003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x24020007, 0xac820000, 0x24020001,
+0xac820004, 0x15200018, 0x3c050006, 0x8e020018, 0x3c040001, 0x248449f0,
+0xafa20010, 0x8e020000, 0x8e030004, 0x34a5f009, 0x2003021, 0xc0023a7,
+0xafa30014, 0x32c200ff, 0x1040002b, 0x34028100, 0x8e430004, 0x8e440008,
+0x8e45000c, 0xa642000c, 0xae430000, 0xae440004, 0xae450008, 0x96020016,
+0x8003752, 0xa642000e, 0x154d000a, 0x0, 0x9602000e, 0xa613000a,
+0x34420004, 0xa602000e, 0x3c010001, 0x370821, 0xa02083b0, 0x8003750,
+0x9821, 0x9604000a, 0x93102b, 0x10400002, 0x2601821, 0x801821,
+0x24020001, 0xa603000a, 0x3c010001, 0x370821, 0xa02283b0, 0x9604000a,
+0x2248821, 0x191102b, 0x10400003, 0x3c02fff5, 0x34421000, 0x2228821,
+0x2649823, 0xa821, 0x1660fef7, 0xadc80000, 0x12600021, 0x32c200ff,
+0x3c010001, 0x370821, 0xac3383b4, 0x3c010001, 0x370821, 0xac3183b8,
+0x3c010001, 0x370821, 0x10400008, 0xac3283bc, 0x3c020001, 0x571021,
+0x8c4283bc, 0x24420004, 0x3c010001, 0x370821, 0xac2283bc, 0x8ee2723c,
+0x8f430280, 0x24420001, 0x14620006, 0x0, 0x8ee201c0, 0x24420001,
+0xaee201c0, 0x80037aa, 0x8ee201c0, 0x8ee201b8, 0x24420001, 0xaee201b8,
+0x80037aa, 0x8ee201b8, 0x97a4001e, 0x2484fffc, 0x801821, 0x8ee400c0,
+0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0x24020002, 0xaee400c0, 0xaee500c4, 0x1282000f, 0x2a820003, 0x14400017,
+0x24020003, 0x16820015, 0x0, 0x8ee200d0, 0x8ee300d4, 0x24630001,
+0x2c640001, 0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0, 0x80037a4,
+0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001, 0x2c640001, 0x441021,
+0xaee200d8, 0xaee300dc, 0x8ee200d8, 0x80037a4, 0x8ee300dc, 0x8ee200c8,
+0x8ee300cc, 0x24630001, 0x2c640001, 0x441021, 0xaee200c8, 0xaee300cc,
+0x8ee200c8, 0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003, 0x24630008,
+0xaf8300e4, 0xaf8300e8, 0x8fbf004c, 0x8fb60048, 0x8fb50044, 0x8fb40040,
+0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030, 0x3e00008, 0x27bd0050,
+0x27bdff90, 0xafbe0064, 0xf021, 0xafbf0068, 0xafb60060, 0xafb5005c,
+0xafb40058, 0xafb30054, 0xafb20050, 0xafb1004c, 0xafb00048, 0x8ee204c4,
+0x8821, 0x24160001, 0x30420001, 0x1440002a, 0xa3a0002f, 0x8f8700e0,
+0x8f8800c4, 0x8f8200e8, 0xe22023, 0x2c821000, 0x50400001, 0x24841000,
+0x420c2, 0x801821, 0x8ee400c8, 0x8ee500cc, 0x1021, 0xa32821,
+0xa3302b, 0x822021, 0x862021, 0xaee400c8, 0xaee500cc, 0x8f8300c8,
+0x3c02000a, 0x3442efff, 0x1032023, 0x44102b, 0x10400003, 0x3c02000a,
+0x3442f000, 0x822021, 0x801821, 0x8ee400c0, 0x8ee500c4, 0x1021,
+0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaee400c0, 0xaee500c4,
+0xaf8800c8, 0xaf8700e4, 0x8003bb3, 0xaf8700e8, 0x3c020001, 0x571021,
+0x904283b0, 0x1040000b, 0x0, 0x3c130001, 0x2779821, 0x8e7383b4,
+0x3c100001, 0x2178021, 0x8e1083b8, 0x3c120001, 0x2579021, 0x80039b3,
+0x8e5283bc, 0x8f8300e0, 0x8f8200e4, 0x10430007, 0x3821, 0x8f8200e4,
+0x24070001, 0x8c430000, 0x8c440004, 0xafa30018, 0xafa4001c, 0x14e0000e,
+0x3c02ffff, 0x8f8200c4, 0xafa20010, 0x8f8200c8, 0x3c040001, 0x24844a14,
+0xafa20014, 0x8f8600e0, 0x8f8700e4, 0x3c050006, 0xc0023a7, 0x34a5f200,
+0x8003bb3, 0x0, 0x8fa3001c, 0x8fb20018, 0x3073ffff, 0x2673fffc,
+0x621024, 0x10400058, 0x2408021, 0x3c020080, 0x621024, 0x1040000a,
+0x3c040040, 0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8ee201ec,
+0x24420001, 0xaee201ec, 0x8003bad, 0x8ee201ec, 0x3c060004, 0x3c0b0001,
+0x3c0a0002, 0x3c050010, 0x3c090008, 0x8ee20080, 0x3c080020, 0x34078000,
+0x24420001, 0xaee20080, 0x8ee20080, 0x8fa2001c, 0x441824, 0x10660021,
+0xc3102b, 0x14400007, 0x0, 0x106b0011, 0x0, 0x106a0015,
+0x0, 0x8003870, 0x42042, 0x10650023, 0xa3102b, 0x14400005,
+0x0, 0x10690019, 0x0, 0x8003870, 0x42042, 0x10680021,
+0x0, 0x8003870, 0x42042, 0x8ee20034, 0x24420001, 0xaee20034,
+0x8ee20034, 0x8003870, 0x42042, 0x8ee201dc, 0x24420001, 0xaee201dc,
+0x8ee201dc, 0x8003870, 0x42042, 0x8ee201e0, 0x24420001, 0xaee201e0,
+0x8ee201e0, 0x8003870, 0x42042, 0x8ee201e4, 0x24420001, 0xaee201e4,
+0x8ee201e4, 0x8003870, 0x42042, 0x8ee20030, 0x24420001, 0xaee20030,
+0x8ee20030, 0x8003870, 0x42042, 0x8ee201e8, 0x24420001, 0xaee201e8,
+0x8ee201e8, 0x42042, 0x1087033c, 0x0, 0x8003835, 0x0,
+0x3c020001, 0x571021, 0x904283a2, 0x14400084, 0x24020001, 0x3c030001,
+0x771821, 0x906383a3, 0x1462007f, 0x3c020100, 0x8e430000, 0x621024,
+0x1040006f, 0x2402ffff, 0x14620005, 0x24110001, 0x96430004, 0x3402ffff,
+0x10620075, 0x0, 0x92e204c8, 0x14400072, 0x0, 0x3c020001,
+0x571021, 0x8c4283a4, 0x28420005, 0x10400020, 0x3821, 0x3c020001,
+0x571021, 0x8c4283a4, 0x18400016, 0x2821, 0x96060000, 0x520c0,
+0x971021, 0x9442776e, 0x14460009, 0x971021, 0x94437770, 0x96020002,
+0x14620005, 0x971021, 0x94437772, 0x96020004, 0x50620008, 0x24070001,
+0x3c020001, 0x571021, 0x8c4283a4, 0x24a50001, 0xa2102a, 0x5440ffee,
+0x520c0, 0x30e200ff, 0x10400300, 0x0, 0x80038fc, 0x0,
+0x2402021, 0xc00229d, 0x24050006, 0x3044001f, 0x428c0, 0x2e51021,
+0x9442726c, 0x30424000, 0x144002f4, 0xb71021, 0x9443726e, 0x96020000,
+0x1462000b, 0x418c0, 0xb71021, 0x94437270, 0x96020002, 0x14620006,
+0x418c0, 0xb71021, 0x94437272, 0x96020004, 0x10620035, 0x418c0,
+0x2e31021, 0x9442726c, 0x30428000, 0x144002e1, 0x2e31021, 0x944e726c,
+0x96070000, 0xe28c0, 0xb71021, 0x9442736e, 0x80038de, 0x3021,
+0x420c0, 0x2e41021, 0x9443736c, 0x2e41021, 0x944e736c, 0x30638000,
+0x14600010, 0xe28c0, 0xb71021, 0x9442736e, 0x1447fff5, 0x1c02021,
+0xb71021, 0x94437370, 0x96020002, 0x5462fff1, 0x420c0, 0xb71021,
+0x94437372, 0x96020004, 0x5462ffec, 0x420c0, 0x24060001, 0x30c200ff,
+0x104002c0, 0x0, 0x80038fc, 0x0, 0x97430202, 0x96420000,
+0x146202ba, 0x0, 0x97430204, 0x96420002, 0x146202b6, 0x0,
+0x97430206, 0x96420004, 0x146202b2, 0x0, 0x92420000, 0x3a230001,
+0x30420001, 0x431024, 0x10400074, 0x2402ffff, 0x8e030000, 0x14620004,
+0x3402ffff, 0x96030004, 0x1062006f, 0x24160002, 0x3c020001, 0x571021,
+0x904283a2, 0x1440006a, 0x24160003, 0x92e204c8, 0x14400067, 0x0,
+0x3c020001, 0x571021, 0x8c4283a4, 0x28420005, 0x10400020, 0x3821,
+0x3c020001, 0x571021, 0x8c4283a4, 0x18400016, 0x2821, 0x96060000,
+0x520c0, 0x971021, 0x9442776e, 0x14460009, 0x971021, 0x94437770,
+0x96020002, 0x14620005, 0x971021, 0x94437772, 0x96020004, 0x50620008,
+0x24070001, 0x3c020001, 0x571021, 0x8c4283a4, 0x24a50001, 0xa2102a,
+0x5440ffee, 0x520c0, 0x30e200ff, 0x14400044, 0x24160003, 0x8003bad,
+0x0, 0x2402021, 0xc00229d, 0x24050006, 0x3044001f, 0x428c0,
+0x2e51021, 0x9442726c, 0x30424000, 0x1440026f, 0xb71021, 0x9443726e,
+0x96020000, 0x1462000b, 0x418c0, 0xb71021, 0x94437270, 0x96020002,
+0x14620006, 0x418c0, 0xb71021, 0x94437272, 0x96020004, 0x10620027,
+0x418c0, 0x2e31021, 0x9442726c, 0x30428000, 0x1440025c, 0x2e31021,
+0x944e726c, 0x96070000, 0xe28c0, 0xb71021, 0x9442736e, 0x8003963,
+0x3021, 0x420c0, 0x2e41021, 0x9443736c, 0x2e41021, 0x944e736c,
+0x30638000, 0x14600010, 0xe28c0, 0xb71021, 0x9442736e, 0x1447fff5,
+0x1c02021, 0xb71021, 0x94437370, 0x96020002, 0x5462fff1, 0x420c0,
+0xb71021, 0x94437372, 0x96020004, 0x5462ffec, 0x420c0, 0x24060001,
+0x30c200ff, 0x1040023b, 0x0, 0x8003976, 0x24160003, 0x24160001,
+0x8f420260, 0x53102b, 0x10400036, 0x0, 0x8f8300e4, 0x8f8200e0,
+0x10620003, 0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8ee400c0, 0x8ee500c4,
+0x2601821, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xaee400c0, 0xaee500c4, 0x8ee20058, 0x24420001, 0xaee20058, 0x8ee20058,
+0x8ee2007c, 0x24420001, 0xaee2007c, 0x8ee2007c, 0x8f8200e0, 0xafa20010,
+0x8f8200e4, 0x3c040001, 0x24844a20, 0xafa20014, 0x8fa60018, 0x8fa7001c,
+0x3c050006, 0xc0023a7, 0x34a5f203, 0x8003bb3, 0x0, 0x8ee25230,
+0xafa20010, 0x8ee25234, 0x3c040001, 0x24844a2c, 0xafa20014, 0x8ee60e00,
+0x8ee70e08, 0x3c050006, 0xc0023a7, 0x34a5f202, 0x8ee201bc, 0x24420001,
+0xaee201bc, 0x8003b5a, 0x8ee201bc, 0x96e20468, 0x53102b, 0x54400001,
+0x3c1e8000, 0x126001c9, 0x3c0f001f, 0x35efffff, 0x3c18fff5, 0x37181000,
+0x8ee2723c, 0x8f430280, 0x24420001, 0x304203ff, 0x1062019d, 0x0,
+0x13c00012, 0x0, 0x8ee35230, 0x8ee25234, 0x1062000a, 0x26f95234,
+0x8ef55234, 0xafb90024, 0x8ee35234, 0x21140, 0x24425238, 0x2e28821,
+0x24630001, 0x80039de, 0x306e00ff, 0x8ee201d0, 0x24420001, 0xaee201d0,
+0x8ee201d0, 0x8ee30e00, 0x8ee20e08, 0x1062ffcb, 0x26f90e08, 0x8ef50e08,
+0xf021, 0xafb90024, 0x8ee30e08, 0x21140, 0x24420e10, 0x2e28821,
+0x24630001, 0x306e01ff, 0x96e2046a, 0x30420010, 0x10400018, 0x34028100,
+0x9643000c, 0x14620015, 0x0, 0x3c020001, 0x571021, 0x904283b0,
+0x14400010, 0x0, 0x9642000e, 0xa6220016, 0x8e420008, 0x8e430004,
+0x8e440000, 0x2673fffc, 0xae42000c, 0xae430008, 0xae440004, 0x9622000e,
+0x26100004, 0x24190001, 0xa3b9002f, 0x34420200, 0xa622000e, 0x8e220000,
+0x8e230004, 0x3c040001, 0x34843800, 0x2003021, 0x306b0007, 0x20b8023,
+0x3641021, 0x202102b, 0x10400005, 0x26b9821, 0x2041023, 0x3621823,
+0x3c020020, 0x438023, 0x26620007, 0x9623000a, 0x2419fff8, 0x59a024,
+0x6b1821, 0x74102b, 0x10400002, 0x2806821, 0x606821, 0x1a01821,
+0x24620007, 0x2419fff8, 0x596824, 0x26d102b, 0x14400004, 0x1b32823,
+0x1a32823, 0x8003a1c, 0xc31021, 0xd31021, 0x4b2023, 0x1e4102b,
+0x54400001, 0x982021, 0x25620040, 0x4d102b, 0x14400035, 0x6021,
+0x94c3000c, 0x24020800, 0x54620032, 0xae260018, 0x3c020001, 0x571021,
+0x904283b0, 0x5440002d, 0xae260018, 0x24c20017, 0x1e2102b, 0x10400013,
+0x0, 0x3c02fff5, 0x461021, 0x90421017, 0x38430006, 0x2c630001,
+0x38420011, 0x2c420001, 0x621825, 0x10600014, 0x24c20010, 0x1e2102b,
+0x1040000e, 0x0, 0x3c0cfff5, 0x1866021, 0x958c1010, 0x8003a4d,
+0x2582000e, 0x90c20017, 0x38430006, 0x2c630001, 0x38420011, 0x2c420001,
+0x621825, 0x10600005, 0x1801821, 0x94cc0010, 0x2582000e, 0x4b6021,
+0x1801821, 0x24620007, 0x2419fff8, 0x596024, 0xc31021, 0x4b2023,
+0x1e4102b, 0x10400002, 0x1832823, 0x982021, 0xae260018, 0x3c020001,
+0x571021, 0x904283b0, 0x2102b, 0x216c0, 0x15800002, 0xafa20044,
+0x1a06021, 0x30820001, 0x10400007, 0x4021, 0x90880000, 0x24840001,
+0x1e4102b, 0x10400002, 0x24a5ffff, 0x982021, 0x50a00012, 0x81c02,
+0x2ca20002, 0x54400009, 0x24a5ffff, 0x94820000, 0x24840002, 0x1024021,
+0x1e4102b, 0x10400006, 0x24a5fffe, 0x8003a7a, 0x982021, 0x90820000,
+0x21200, 0x1024021, 0x14a0fff2, 0x2ca20002, 0x81c02, 0x3102ffff,
+0x624021, 0x3108ffff, 0x1602821, 0x11600011, 0x2002021, 0x2ca20002,
+0x54400009, 0x24a5ffff, 0x94820000, 0x24840002, 0x1024021, 0x1e4102b,
+0x10400006, 0x24a5fffe, 0x8003a91, 0x982021, 0x90820000, 0x21200,
+0x1024021, 0x14a0fff2, 0x2ca20002, 0x81c02, 0x3102ffff, 0x624021,
+0x81c02, 0x3102ffff, 0x8f890120, 0x624021, 0x27623800, 0x252a0020,
+0x142102b, 0x14400002, 0x3108ffff, 0x276a3000, 0x8f820128, 0x15420007,
+0x1602821, 0x8ee201a0, 0x3821, 0x24420001, 0xaee201a0, 0x8003b21,
+0x8ee201a0, 0x8e260000, 0x8e270004, 0x81400, 0x3443000b, 0xad300008,
+0xa52c000e, 0xad230018, 0x8fb90044, 0x2021, 0x2be1025, 0x591025,
+0xad22001c, 0xe5102b, 0xe53823, 0xc43023, 0xc23023, 0xad260000,
+0xad270004, 0x8ee204b0, 0xad220010, 0xaf8a0120, 0x92e24e10, 0x14400061,
+0x24070001, 0x2462ffee, 0x2c420002, 0x14400003, 0x24020011, 0x14620025,
+0x0, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000,
+0x24020012, 0x1462000f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062000b,
+0x24190040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x1059002b, 0x0, 0x8003aff, 0x0, 0x8ee24e20,
+0x24190040, 0x24420001, 0x50590003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8003b1e,
+0x24020012, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000,
+0x24020007, 0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x24190040, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x10590007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8003b0b, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013,
+0xac800000, 0x8003b21, 0x0, 0x8ee24e20, 0x24190040, 0x24420001,
+0x50590003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x24020007, 0xac820000, 0x24020001,
+0xac820004, 0x14e00019, 0x3c050006, 0x3c040001, 0x248449f0, 0x8e220018,
+0x34a5f209, 0xafa20010, 0x8e220000, 0x8e230004, 0x2203021, 0x1803821,
+0xc0023a7, 0xafa30014, 0x93a2002f, 0x1040002a, 0x34028100, 0x8e430004,
+0x8e440008, 0x8e45000c, 0xa642000c, 0xae430000, 0xae440004, 0xae450008,
+0x96220016, 0x8003b5a, 0xa642000e, 0x15b4000a, 0x26b1823, 0x9622000e,
+0xa623000a, 0x34420004, 0xa622000e, 0x3c010001, 0x370821, 0xa02083b0,
+0x8003b57, 0x9821, 0x9624000a, 0x83102b, 0x54400001, 0x801821,
+0x24020001, 0xa623000a, 0x3c010001, 0x370821, 0xa02283b0, 0x9622000a,
+0x4b1821, 0x2038021, 0x1f0102b, 0x54400001, 0x2188021, 0x2639823,
+0xf021, 0x8fb90024, 0x1660fe5f, 0xaf2e0000, 0x12600022, 0x0,
+0x3c010001, 0x370821, 0xac3383b4, 0x3c010001, 0x370821, 0xac3083b8,
+0x3c010001, 0x370821, 0xac3283bc, 0x93a2002f, 0x10400008, 0x0,
+0x3c020001, 0x571021, 0x8c4283bc, 0x24420004, 0x3c010001, 0x370821,
+0xac2283bc, 0x8f430280, 0x8ee2723c, 0x14620006, 0x0, 0x8ee201c0,
+0x24420001, 0xaee201c0, 0x8003bb3, 0x8ee201c0, 0x8ee201b8, 0x24420001,
+0xaee201b8, 0x8003bb3, 0x8ee201b8, 0x97a4001e, 0x2484fffc, 0x801821,
+0x8ee400c0, 0x8ee500c4, 0x1021, 0xa32821, 0xa3302b, 0x822021,
+0x862021, 0x24020002, 0xaee400c0, 0xaee500c4, 0x12c2000f, 0x2ac20003,
+0x14400017, 0x24020003, 0x16c20015, 0x0, 0x8ee200d0, 0x8ee300d4,
+0x24630001, 0x2c640001, 0x441021, 0xaee200d0, 0xaee300d4, 0x8ee200d0,
+0x8003bad, 0x8ee300d4, 0x8ee200d8, 0x8ee300dc, 0x24630001, 0x2c640001,
+0x441021, 0xaee200d8, 0xaee300dc, 0x8ee200d8, 0x8003bad, 0x8ee300dc,
+0x8ee200c8, 0x8ee300cc, 0x24630001, 0x2c640001, 0x441021, 0xaee200c8,
+0xaee300cc, 0x8ee200c8, 0x8ee300cc, 0x8f8300e4, 0x8f8200e0, 0x10620003,
+0x24630008, 0xaf8300e4, 0xaf8300e8, 0x8fbf0068, 0x8fbe0064, 0x8fb60060,
+0x8fb5005c, 0x8fb40058, 0x8fb30054, 0x8fb20050, 0x8fb1004c, 0x8fb00048,
+0x3e00008, 0x27bd0070, 0x27bdffe0, 0xafbf0018, 0x8ee30e04, 0x8ee20dfc,
+0x10620071, 0x0, 0x8ee30dfc, 0x8ee20e04, 0x622023, 0x4820001,
+0x24840200, 0x8ee30e08, 0x8ee20e04, 0x43102b, 0x14400004, 0x24020200,
+0x8ee30e04, 0x8003bd5, 0x431823, 0x8ee20e08, 0x8ee30e04, 0x431023,
+0x2443ffff, 0x804821, 0x69102a, 0x54400001, 0x604821, 0x8f870100,
+0x27623000, 0x24e80020, 0x102102b, 0x50400001, 0x27682800, 0x8f820108,
+0x15020007, 0x1021, 0x8ee201a4, 0x2021, 0x24420001, 0xaee201a4,
+0x8003c14, 0x8ee201a4, 0x8ee40e04, 0x42140, 0x801821, 0x8ee40460,
+0x8ee50464, 0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000,
+0xace50004, 0x8ee30e04, 0x91140, 0xa4e2000e, 0x24020002, 0xace20018,
+0x31940, 0x24630e10, 0x2e31021, 0xace20008, 0x8ee20e04, 0xace2001c,
+0x8ee204bc, 0xace20010, 0xaf880100, 0x92e204dc, 0x14400011, 0x24040001,
+0x8ee24e18, 0x24030040, 0x24420001, 0x50430003, 0x1021, 0x8ee24e18,
+0x24420001, 0xaee24e18, 0x8ee24e18, 0x210c0, 0x24424e28, 0x2e21821,
+0x24020002, 0xac620000, 0x24020001, 0xac620004, 0x1480000e, 0x24030040,
+0x8ee20e04, 0xafa20010, 0x8ee20e08, 0x3c050007, 0xafa20014, 0x8ee60dfc,
+0x8ee70e00, 0x3c040001, 0x24844a34, 0xc0023a7, 0x34a5f001, 0x8003c32,
+0x0, 0x8ee204f0, 0x24420001, 0x50430003, 0x1021, 0x8ee204f0,
+0x24420001, 0xaee204f0, 0x8ee204f0, 0x21080, 0x571021, 0xac4904f8,
+0x8ee20e04, 0x491021, 0x304201ff, 0xaee20e04, 0x8ee30e04, 0x8ee20dfc,
+0x14620005, 0x0, 0x8f820060, 0x2403fdff, 0x431024, 0xaf820060,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x27bdffe0, 0xafbf0018, 0x8ee3522c,
+0x8ee25228, 0x10620071, 0x0, 0x8ee35228, 0x8ee2522c, 0x622023,
+0x4820001, 0x24840100, 0x8ee35234, 0x8ee2522c, 0x43102b, 0x14400004,
+0x24020100, 0x8ee3522c, 0x8003c54, 0x431823, 0x8ee25234, 0x8ee3522c,
+0x431023, 0x2443ffff, 0x804821, 0x69102a, 0x54400001, 0x604821,
+0x8f870100, 0x27623000, 0x24e80020, 0x102102b, 0x50400001, 0x27682800,
+0x8f820108, 0x15020007, 0x1021, 0x8ee201a4, 0x2021, 0x24420001,
+0xaee201a4, 0x8003c93, 0x8ee201a4, 0x8ee4522c, 0x42140, 0x801821,
+0x8ee40470, 0x8ee50474, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xace40000, 0xace50004, 0x8ee3522c, 0x91140, 0xa4e2000e, 0x24020003,
+0xace20018, 0x31940, 0x24635238, 0x2e31021, 0xace20008, 0x8ee2522c,
+0xace2001c, 0x8ee204bc, 0xace20010, 0xaf880100, 0x92e204dc, 0x14400011,
+0x24040001, 0x8ee24e18, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ee24e18, 0x24420001, 0xaee24e18, 0x8ee24e18, 0x210c0, 0x24424e28,
+0x2e21821, 0x24020003, 0xac620000, 0x24020001, 0xac620004, 0x1480000e,
+0x24030040, 0x8ee2522c, 0xafa20010, 0x8ee25234, 0x3c050007, 0xafa20014,
+0x8ee65228, 0x8ee75230, 0x3c040001, 0x24844a40, 0xc0023a7, 0x34a5f010,
+0x8003cb1, 0x0, 0x8ee204f0, 0x24420001, 0x50430003, 0x1021,
+0x8ee204f0, 0x24420001, 0xaee204f0, 0x8ee204f0, 0x21080, 0x571021,
+0xac4904f8, 0x8ee2522c, 0x491021, 0x304200ff, 0xaee2522c, 0x8ee3522c,
+0x8ee25228, 0x14620005, 0x0, 0x8f820060, 0x2403feff, 0x431024,
+0xaf820060, 0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f820120, 0x8ee34e24,
+0x8f820124, 0x8f860128, 0x24020040, 0x24630001, 0x50620003, 0x1021,
+0x8ee24e24, 0x24420001, 0xaee24e24, 0x8ee24e24, 0x8ee44e24, 0x8ee34e20,
+0x210c0, 0x24425028, 0x14830007, 0x2e22821, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8003ce4, 0xaca00000, 0x8ee24e24, 0x24030040,
+0x24420001, 0x50430003, 0x1021, 0x8ee24e24, 0x24420001, 0x210c0,
+0x24425028, 0x2e22821, 0x8ca20004, 0x8f830128, 0x21140, 0x621821,
+0xaf830128, 0xaca00000, 0x8cc20018, 0x2443fffe, 0x2c620012, 0x10400008,
+0x31080, 0x3c010001, 0x220821, 0x8c224a50, 0x400008, 0x0,
+0x24020001, 0xaee24e14, 0x3e00008, 0x0, 0x27bdffc8, 0xafbf0030,
+0xafb5002c, 0xafb40028, 0xafb30024, 0xafb20020, 0xafb1001c, 0xafb00018,
+0x8f830128, 0x8f820124, 0x106202a7, 0xa021, 0x3c11001f, 0x3631ffff,
+0x3c12fff5, 0x36521000, 0x24150012, 0x24130040, 0x8f8c0128, 0x8f820128,
+0x24420020, 0xaf820128, 0x9182001b, 0x8f830128, 0x2443fffe, 0x2c620012,
+0x10400293, 0x31080, 0x3c010001, 0x220821, 0x8c224aa8, 0x400008,
+0x0, 0x8f420218, 0x30420100, 0x10400007, 0x0, 0x95830016,
+0x95820018, 0x621823, 0x31402, 0x431021, 0xa5820016, 0x8d82001c,
+0x3c038000, 0x3044ffff, 0x436824, 0x3c030800, 0x431824, 0x11a00004,
+0xad84001c, 0x41140, 0x8003d2a, 0x24425238, 0x41140, 0x24420e10,
+0x2e25821, 0x9562000e, 0x3042fffc, 0x10600004, 0xa562000e, 0x95840016,
+0x8003e12, 0x0, 0x8d690018, 0x4021, 0x952a0000, 0x25290002,
+0x95270000, 0x25290002, 0x95260000, 0x25290002, 0x95250000, 0x25290002,
+0x95240000, 0x25290002, 0x95230000, 0x25290002, 0x95220000, 0x25290002,
+0x1475021, 0x1465021, 0x1455021, 0x1445021, 0x1435021, 0x1425021,
+0xa1c02, 0x3142ffff, 0x625021, 0xa1c02, 0x3142ffff, 0x625021,
+0x96e2046a, 0x314effff, 0x30420002, 0x10400044, 0x5021, 0x25220014,
+0x222102b, 0x10400014, 0x1201821, 0x2405000a, 0x2021, 0x223102b,
+0x54400001, 0x721821, 0x94620000, 0x24630002, 0x24a5ffff, 0x14a0fff9,
+0x822021, 0x41c02, 0x3082ffff, 0x622021, 0x41402, 0x3083ffff,
+0x431021, 0x3042ffff, 0x8003d85, 0x1425021, 0x952a0000, 0x25290002,
+0x95280000, 0x25290002, 0x95270000, 0x25290002, 0x95260000, 0x25290002,
+0x95250000, 0x25290002, 0x95230000, 0x25290002, 0x95220000, 0x25290002,
+0x95240000, 0x25290002, 0x1485021, 0x1475021, 0x1465021, 0x1455021,
+0x1435021, 0x1425021, 0x95220000, 0x95230002, 0x1445021, 0x1425021,
+0x1435021, 0xa1c02, 0x3142ffff, 0x625021, 0xa1c02, 0x3142ffff,
+0x625021, 0x3148ffff, 0x51000001, 0x3408ffff, 0x8d620018, 0x9443000c,
+0x24020800, 0x54620005, 0xa5680010, 0x9562000e, 0x34420002, 0xa562000e,
+0xa5680010, 0x96e2046a, 0x2821, 0x30420008, 0x14400056, 0x3021,
+0x8d630018, 0x24620024, 0x222102b, 0x10400034, 0x24690010, 0x229102b,
+0x54400001, 0x1324821, 0x95250000, 0x24690014, 0x229102b, 0x10400002,
+0x24a5ffec, 0x1324821, 0x95220000, 0x30420fff, 0x14400003, 0x25290002,
+0x8003db2, 0x24140001, 0xa021, 0xa03021, 0x229102b, 0x54400001,
+0x1324821, 0x91220001, 0x25290002, 0xa22821, 0x229102b, 0x54400001,
+0x1324821, 0x25290002, 0x229102b, 0x54400001, 0x1324821, 0x95220000,
+0x25290002, 0xa22821, 0x229102b, 0x54400001, 0x1324821, 0x95220000,
+0x25290002, 0xa22821, 0x229102b, 0x54400001, 0x1324821, 0x95220000,
+0x25290002, 0xa22821, 0x229102b, 0x54400001, 0x1324821, 0x95220000,
+0x8003deb, 0xa22821, 0x94650010, 0x94620014, 0x24690016, 0x30420fff,
+0x14400003, 0x24a5ffec, 0x8003dde, 0x24140001, 0xa021, 0xa03021,
+0x91230001, 0x25290004, 0x95220000, 0x25290002, 0x95240000, 0x25290002,
+0xa32821, 0xa22821, 0x95220000, 0x95230002, 0xa42821, 0xa22821,
+0xa32821, 0x51c02, 0x30a2ffff, 0x622821, 0x51c02, 0x30a2ffff,
+0x622821, 0x96e2046a, 0x30420001, 0x1040001e, 0x2021, 0x95820016,
+0x4e2023, 0x41402, 0x822021, 0x328200ff, 0x50400002, 0x862021,
+0x852021, 0x41402, 0x822021, 0x3084ffff, 0x50800001, 0x3404ffff,
+0x8d620018, 0x24430017, 0x223102b, 0x54400001, 0x721821, 0x90620000,
+0x38430011, 0x2c630001, 0x38420006, 0x2c420001, 0x621825, 0x10600004,
+0x0, 0x9562000e, 0x34420001, 0xa562000e, 0x9562000e, 0x240a0002,
+0x30420004, 0x10400002, 0xa5640012, 0x240a0004, 0x8f880120, 0x27623800,
+0x25090020, 0x122102b, 0x50400001, 0x27693000, 0x8f820128, 0x15220007,
+0x24040020, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8003e9e,
+0x8ee201a0, 0x8ee5723c, 0x8ee60480, 0x8ee70484, 0xad0b0008, 0xa504000e,
+0xad0a0018, 0x52940, 0xa01821, 0x1021, 0xe33821, 0xe3202b,
+0xc23021, 0xc43021, 0xad060000, 0xad070004, 0x8ee2723c, 0x4d1025,
+0xad02001c, 0x8ee204b4, 0xad020010, 0xaf890120, 0x92e24e10, 0x14400060,
+0x24100001, 0x2543ffee, 0x2c630002, 0x39420011, 0x2c420001, 0x621825,
+0x10600024, 0x0, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x1455000f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062000b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x1053002b, 0x0, 0x8003e7d, 0x0, 0x8ee24e20,
+0x24420001, 0x50530003, 0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20,
+0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x24020001, 0x8003e9d,
+0xac950000, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c830000,
+0x24020007, 0x1462001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x10530007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8003e89, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400012,
+0xac800000, 0x8003e9e, 0x0, 0x8ee24e20, 0x24420001, 0x50530003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004,
+0x1600000d, 0x0, 0x8f820120, 0x3c040001, 0x24844a98, 0xafa00014,
+0xafa20010, 0x8d86001c, 0x8f870124, 0x3c050008, 0xc0023a7, 0x34a50001,
+0x8003fa0, 0x0, 0x8ee2723c, 0x24420001, 0x304203ff, 0x11a00006,
+0xaee2723c, 0x8ee201c8, 0x2442ffff, 0xaee201c8, 0x8003eba, 0x8ee201c8,
+0x8ee201c4, 0x2442ffff, 0xaee201c4, 0x8ee201c4, 0x8ee201cc, 0x2442ffff,
+0xaee201cc, 0x8003fa0, 0x8ee201cc, 0x8f420240, 0x104000df, 0x0,
+0x8ee20e0c, 0x24420001, 0x8003fa0, 0xaee20e0c, 0x9582001e, 0xad82001c,
+0x8f420240, 0x1040006f, 0x0, 0x8ee20e0c, 0x24420001, 0xaee20e0c,
+0x8f430240, 0x43102b, 0x144000cf, 0x0, 0x8f830120, 0x27623800,
+0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007,
+0x0, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0, 0x8003f26,
+0x8ee201a0, 0x8ee2723c, 0xac62001c, 0x8ee40498, 0x8ee5049c, 0x2462001c,
+0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018, 0xac640000,
+0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10, 0x14400034,
+0x24100001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0x8c820000,
+0x1455001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0,
+0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001,
+0x10530007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005, 0x0,
+0x8003f12, 0x0, 0x14600005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400011, 0xac800000,
+0x8003f26, 0x0, 0x8ee24e20, 0x24420001, 0x50530003, 0x1021,
+0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028,
+0x2e22021, 0x24020001, 0xac950000, 0xac820004, 0x5600000b, 0x24100001,
+0x8ee2723c, 0x3c040001, 0x24844a08, 0xafa00014, 0xafa20010, 0x8ee6723c,
+0x8f470280, 0x3c050009, 0xc0023a7, 0x34a5f008, 0x56000001, 0xaee00e0c,
+0x8ee20184, 0x24420001, 0xaee20184, 0x8003f99, 0x8ee20184, 0x8f830120,
+0x27623800, 0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128,
+0x14c20007, 0x0, 0x8ee201a0, 0x8021, 0x24420001, 0xaee201a0,
+0x8003f8d, 0x8ee201a0, 0x8ee2723c, 0xac62001c, 0x8ee40498, 0x8ee5049c,
+0x2462001c, 0xac620008, 0x24020008, 0xa462000e, 0x24020011, 0xac620018,
+0xac640000, 0xac650004, 0x8ee204b4, 0xac620010, 0xaf860120, 0x92e24e10,
+0x14400034, 0x24100001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x1455001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x10530007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8003f79, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400011,
+0xac800000, 0x8003f8d, 0x0, 0x8ee24e20, 0x24420001, 0x50530003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0x24020001, 0xac950000, 0xac820004, 0x1600000b,
+0x0, 0x8ee2723c, 0x3c040001, 0x24844a08, 0xafa00014, 0xafa20010,
+0x8ee6723c, 0x8f470280, 0x3c050009, 0xc0023a7, 0x34a5f008, 0x8ee20170,
+0x24420001, 0xaee20170, 0x8003fa0, 0x8ee20170, 0x24020001, 0xaee24e14,
+0x8f830128, 0x8f820124, 0x1462fd61, 0x0, 0x8fbf0030, 0x8fb5002c,
+0x8fb40028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018, 0x3e00008,
+0x27bd0038, 0x0, 0x0, 0x0, 0x27bdffe8, 0x27840208,
+0x27450200, 0x24060008, 0xafbf0014, 0xc00243e, 0xafb00010, 0x24040001,
+0x24100001, 0x2402241f, 0xaf900210, 0xaf900200, 0xaf800204, 0xaf820214,
+0x8f460248, 0x24030004, 0x3c020040, 0x3c010001, 0xac234de8, 0x3c010001,
+0xac234dec, 0x3c010001, 0xac204e8c, 0x3c010001, 0xac224de4, 0x3c010001,
+0xac234dec, 0xc004e2c, 0x24050004, 0xc0046b4, 0x0, 0x8ee20000,
+0x3c03feff, 0x3463fffd, 0x431024, 0xaee20000, 0x3c023c00, 0xaf82021c,
+0x3c010001, 0x370821, 0xac30839c, 0x8fbf0014, 0x8fb00010, 0x3e00008,
+0x27bd0018, 0x27bdffe0, 0x3c050008, 0x34a50400, 0xafbf0018, 0xafa00010,
+0xafa00014, 0x8f860200, 0x3c040001, 0x24844b50, 0xc0023a7, 0x3821,
+0x8ee20270, 0x24420001, 0xaee20270, 0x8ee20270, 0x8f830200, 0x3c023f00,
+0x621824, 0x8fbf0018, 0x3c020400, 0x3e00008, 0x27bd0020, 0x27bdffd8,
+0xafbf0020, 0xafb1001c, 0xafb00018, 0x8f900220, 0x8ee20204, 0x3821,
+0x24420001, 0xaee20204, 0x8ee20204, 0x3c020300, 0x2021024, 0x10400027,
+0x3c110400, 0xc0041e7, 0x0, 0x3c020100, 0x2021024, 0x10400007,
+0x0, 0x8ee20208, 0x24420001, 0xaee20208, 0x8ee20208, 0x8004012,
+0x3c03fdff, 0x8ee2020c, 0x24420001, 0xaee2020c, 0x8ee2020c, 0x3c03fdff,
+0x3463ffff, 0x3c0808ff, 0x3508ffff, 0x8ee20000, 0x3c040001, 0x24844b5c,
+0x3c050008, 0x2003021, 0x431024, 0xaee20000, 0x8f820220, 0x3821,
+0x3c030300, 0x481024, 0x431025, 0xaf820220, 0xafa00010, 0xc0023a7,
+0xafa00014, 0x80041e2, 0x0, 0x2111024, 0x1040001f, 0x3c024000,
+0x8f830224, 0x24021402, 0x1462000b, 0x3c03fdff, 0x3c040001, 0x24844b68,
+0x3c050008, 0xafa00010, 0xafa00014, 0x8f860224, 0x34a5ffff, 0xc0023a7,
+0x3821, 0x3c03fdff, 0x8ee20000, 0x3463ffff, 0x2002021, 0x431024,
+0xc004b88, 0xaee20000, 0x8ee20210, 0x24420001, 0xaee20210, 0x8ee20210,
+0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x80041e1, 0x511025,
+0x2021024, 0x10400142, 0x0, 0x8ee2021c, 0x24420001, 0xaee2021c,
+0x8ee2021c, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420004,
+0xaf820220, 0x8f830054, 0x8f820054, 0x800405a, 0x24630002, 0x8f820054,
+0x621023, 0x2c420003, 0x1440fffc, 0x0, 0x8f8600e0, 0x8f8400e4,
+0x30c20007, 0x10400012, 0x0, 0x8f8300e4, 0x2402fff8, 0xc21024,
+0x1043000d, 0x0, 0x8f820054, 0x8f8300e0, 0x14c30009, 0x24440050,
+0x8f820054, 0x821023, 0x2c420051, 0x10400004, 0x0, 0x8f8200e0,
+0x10c2fff9, 0x0, 0x8f820220, 0x3c0308ff, 0x3463fffd, 0x431024,
+0xaf820220, 0x8f8600e0, 0x30c20007, 0x10400003, 0x2402fff8, 0xc23024,
+0xaf8600e0, 0x8f8300c4, 0x3c02001f, 0x3442ffff, 0x24680008, 0x48102b,
+0x10400003, 0x3c02fff5, 0x34421000, 0x1024021, 0x8f8b00c8, 0x8f850120,
+0x8f840124, 0x8004091, 0x6021, 0x27623800, 0x82102b, 0x50400001,
+0x27643000, 0x10a40010, 0x318200ff, 0x8c820018, 0x38430007, 0x2c630001,
+0x3842000b, 0x2c420001, 0x621825, 0x5060fff3, 0x24840020, 0x8ee20230,
+0x240c0001, 0x24420001, 0xaee20230, 0x8ee20230, 0x8c8b0008, 0x318200ff,
+0x14400065, 0x0, 0x3c020001, 0x571021, 0x904283b0, 0x14400060,
+0x0, 0x8f8400e4, 0xc41023, 0x218c3, 0x4620001, 0x24630200,
+0x8f8900c4, 0x10600005, 0x24020001, 0x10620009, 0x0, 0x80040d3,
+0x0, 0x8ee20220, 0x1205821, 0x24420001, 0xaee20220, 0x8004108,
+0x8ee20220, 0x8ee20224, 0x3c05000a, 0x24420001, 0xaee20224, 0x8c8b0000,
+0x34a5f000, 0x8ee20224, 0x12b1823, 0xa3102b, 0x54400001, 0x651821,
+0x2c62233f, 0x14400040, 0x0, 0x8f8200e8, 0x24420008, 0xaf8200e8,
+0x8f8200e8, 0x8f8200e4, 0x1205821, 0x24420008, 0xaf8200e4, 0x8004108,
+0x8f8200e4, 0x8ee20228, 0x3c03000a, 0x24420001, 0xaee20228, 0x8c840000,
+0x3463f000, 0x8ee20228, 0x883823, 0x67102b, 0x54400001, 0xe33821,
+0x3c020003, 0x34420d40, 0x47102b, 0x10400003, 0x0, 0x8004108,
+0x805821, 0x8f8200e4, 0x24440008, 0xaf8400e4, 0x8f8400e4, 0x10860018,
+0x3c05000a, 0x34a5f000, 0x3c0a0003, 0x354a0d40, 0x8ee2007c, 0x24420001,
+0xaee2007c, 0x8c830000, 0x8ee2007c, 0x683823, 0xa7102b, 0x54400001,
+0xe53821, 0x147102b, 0x54400007, 0x605821, 0x8f8200e4, 0x24440008,
+0xaf8400e4, 0x8f8400e4, 0x1486ffef, 0x0, 0x14860005, 0x0,
+0x1205821, 0xaf8600e4, 0x8004108, 0xaf8600e8, 0xaf8400e4, 0xaf8400e8,
+0x8f8200c8, 0x3c03000a, 0x3463f000, 0x483823, 0x67102b, 0x54400001,
+0xe33821, 0x3c020003, 0x34420d3f, 0x47102b, 0x54400007, 0x6021,
+0x1683823, 0x67102b, 0x54400003, 0xe33821, 0x800411b, 0x3c020003,
+0x3c020003, 0x34420d3f, 0x47102b, 0x14400016, 0x318200ff, 0x14400006,
+0x0, 0x3c020001, 0x571021, 0x904283b0, 0x1040000f, 0x0,
+0x8ee2022c, 0x3c04fdff, 0x8ee30000, 0x3484ffff, 0x24420001, 0xaee2022c,
+0x8ee2022c, 0x24020001, 0x641824, 0x3c010001, 0x370821, 0xa02283a8,
+0x8004178, 0xaee30000, 0xaf8b00c8, 0x8f8300c8, 0x8f8200c4, 0x3c04000a,
+0x3484f000, 0x623823, 0x87102b, 0x54400001, 0xe43821, 0x3c020003,
+0x34420d40, 0x47102b, 0x2ce30001, 0x431025, 0x10400008, 0x0,
+0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x3c034000, 0x431025,
+0xaf820220, 0x8f8600e0, 0x8f8400e4, 0x10c4002a, 0x0, 0x8ee2007c,
+0x24420001, 0xaee2007c, 0x8ee2007c, 0x24c2fff8, 0xaf8200e0, 0x3c020001,
+0x8c426f30, 0x3c030008, 0x8f8600e0, 0x431024, 0x1040001d, 0x0,
+0x10c4001b, 0x240dfff8, 0x3c0a000a, 0x354af000, 0x3c0c0080, 0x24850008,
+0x27622800, 0x50a20001, 0x27651800, 0x8c880004, 0x8c820000, 0x8ca90000,
+0x3103ffff, 0x431021, 0x4d1024, 0x24430010, 0x6b102b, 0x54400001,
+0x6a1821, 0x12b102b, 0x54400001, 0x12a4821, 0x10690002, 0x10c1025,
+0xac820004, 0xa02021, 0x14c4ffeb, 0x24850008, 0x8f820220, 0x3c0308ff,
+0x3463ffff, 0x431024, 0x34420002, 0xaf820220, 0x8f830054, 0x8f820054,
+0x8004183, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
+0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, 0xaf820220,
+0x6010055, 0x0, 0x8ee20218, 0x24420001, 0xaee20218, 0x8ee20218,
+0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420004, 0xaf820220,
+0x8f830054, 0x8f820054, 0x800419d, 0x24630002, 0x8f820054, 0x621023,
+0x2c420003, 0x1440fffc, 0x0, 0x8f8600e0, 0x30c20007, 0x10400012,
+0x0, 0x8f8300e4, 0x2402fff8, 0xc21024, 0x1043000d, 0x0,
+0x8f820054, 0x8f8300e0, 0x14c30009, 0x24440032, 0x8f820054, 0x821023,
+0x2c420033, 0x10400004, 0x0, 0x8f8200e0, 0x10c2fff9, 0x0,
+0x8f820220, 0x3c0308ff, 0x3463fffd, 0x431024, 0xaf820220, 0x8f8600e0,
+0x30c20007, 0x10400003, 0x2402fff8, 0xc23024, 0xaf8600e0, 0x240301f5,
+0x8f8200e8, 0x673823, 0x718c0, 0x431021, 0xaf8200e8, 0x8f8200e8,
+0xaf8200e4, 0x8ee2007c, 0x3c0408ff, 0x3484ffff, 0x471021, 0xaee2007c,
+0x8f820220, 0x3c038000, 0x34630002, 0x441024, 0x431025, 0xaf820220,
+0x8f830054, 0x8f820054, 0x80041d9, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb,
+0x431024, 0xaf820220, 0x8fbf0020, 0x8fb1001c, 0x8fb00018, 0x3e00008,
+0x27bd0028, 0x3c020001, 0x8c424dfc, 0x27bdffd8, 0x10400012, 0xafbf0020,
+0x3c040001, 0x24844b74, 0x3c050008, 0x24020001, 0x3c010001, 0x370821,
+0xac22839c, 0xafa00010, 0xafa00014, 0x8f860220, 0x34a50498, 0x3c010001,
+0xac204dfc, 0x3c010001, 0xac224df0, 0xc0023a7, 0x3821, 0x8f420268,
+0x3c037fff, 0x3463ffff, 0x431024, 0xaf420268, 0x8ee204c0, 0x8ee404c4,
+0x2403fffe, 0x431024, 0x30840002, 0x10800118, 0xaee204c0, 0x8ee204c4,
+0x2403fffd, 0x431024, 0xaee204c4, 0x8f820044, 0x3c030600, 0x34632000,
+0x34420020, 0xaf820044, 0xafa30018, 0x8ee205f8, 0x8f430228, 0x24420001,
+0x304a00ff, 0x514300f8, 0xafa00010, 0x8ee205f8, 0x210c0, 0x571021,
+0x8fa30018, 0x8fa4001c, 0xac4305fc, 0xac440600, 0x8f830054, 0x8f820054,
+0x24690032, 0x1221023, 0x2c420033, 0x10400067, 0x5821, 0x24180008,
+0x240f000d, 0x240d0007, 0x240c0040, 0x240e0001, 0x8f870120, 0x27623800,
+0x24e80020, 0x102102b, 0x50400001, 0x27683000, 0x8f820128, 0x15020007,
+0x1021, 0x8ee201a0, 0x2821, 0x24420001, 0xaee201a0, 0x8004286,
+0x8ee201a0, 0x8ee405f8, 0x420c0, 0x801821, 0x8ee40430, 0x8ee50434,
+0xa32821, 0xa3302b, 0x822021, 0x862021, 0xace40000, 0xace50004,
+0x8ee205f8, 0xa4f8000e, 0xacef0018, 0xacea001c, 0x210c0, 0x244205fc,
+0x2e21021, 0xace20008, 0x8ee204b4, 0xace20010, 0xaf880120, 0x92e24e10,
+0x14400033, 0x24050001, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021,
+0x8c820000, 0x144d001f, 0x0, 0x8ee34e20, 0x8ee24e24, 0x1062001b,
+0x0, 0x8c820004, 0x24420001, 0xac820004, 0x8ee24e24, 0x8ee34e20,
+0x24420001, 0x104c0007, 0x0, 0x8ee24e24, 0x24420001, 0x10620005,
+0x0, 0x8004273, 0x0, 0x14600005, 0x0, 0x8f820128,
+0x24420020, 0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400010,
+0xac800000, 0x8004286, 0x0, 0x8ee24e20, 0x24420001, 0x504c0003,
+0x1021, 0x8ee24e20, 0x24420001, 0xaee24e20, 0x8ee24e20, 0x210c0,
+0x24425028, 0x2e22021, 0xac8d0000, 0xac8e0004, 0x54a00006, 0x240b0001,
+0x8f820054, 0x1221023, 0x2c420033, 0x1440ffa0, 0x0, 0x316300ff,
+0x24020001, 0x54620076, 0xafa00010, 0xaeea05f8, 0x8f830054, 0x8f820054,
+0x24690032, 0x1221023, 0x2c420033, 0x1040005e, 0x5821, 0x240d0008,
+0x240c0011, 0x24080012, 0x24070040, 0x240a0001, 0x8f830120, 0x27623800,
+0x24660020, 0xc2102b, 0x50400001, 0x27663000, 0x8f820128, 0x14c20007,
+0x0, 0x8ee201a0, 0x2821, 0x24420001, 0xaee201a0, 0x80042ef,
+0x8ee201a0, 0x8ee205f8, 0xac62001c, 0x8ee40490, 0x8ee50494, 0x2462001c,
+0xac620008, 0xa46d000e, 0xac6c0018, 0xac640000, 0xac650004, 0x8ee204b4,
+0xac620010, 0xaf860120, 0x92e24e10, 0x14400033, 0x24050001, 0x8ee24e20,
+0x210c0, 0x24425028, 0x2e22021, 0x8c820000, 0x1448001f, 0x0,
+0x8ee34e20, 0x8ee24e24, 0x1062001b, 0x0, 0x8c820004, 0x24420001,
+0xac820004, 0x8ee24e24, 0x8ee34e20, 0x24420001, 0x10470007, 0x0,
+0x8ee24e24, 0x24420001, 0x10620005, 0x0, 0x80042dc, 0x0,
+0x14600005, 0x0, 0x8f820128, 0x24420020, 0xaf820128, 0x8f820128,
+0x8c820004, 0x2c420011, 0x50400010, 0xac800000, 0x80042ef, 0x0,
+0x8ee24e20, 0x24420001, 0x50470003, 0x1021, 0x8ee24e20, 0x24420001,
+0xaee24e20, 0x8ee24e20, 0x210c0, 0x24425028, 0x2e22021, 0xac880000,
+0xac8a0004, 0x54a00006, 0x240b0001, 0x8f820054, 0x1221023, 0x2c420033,
+0x1440ffa9, 0x0, 0x316300ff, 0x24020001, 0x54620003, 0xafa00010,
+0x800431c, 0x0, 0x3c040001, 0x24844b80, 0xafa00014, 0x8f860120,
+0x8f870124, 0x3c050009, 0xc0023a7, 0x34a5f011, 0x800431c, 0x0,
+0x3c040001, 0x24844b8c, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
+0xc0023a7, 0x34a5f010, 0x800431c, 0x0, 0x3c040001, 0x24844b98,
+0xafa00014, 0x8ee605f8, 0x8f470228, 0x3c050009, 0xc0023a7, 0x34a5f00f,
+0x8ee201a8, 0x24420001, 0xaee201a8, 0x8ee201a8, 0x8ee20158, 0x24420001,
+0xaee20158, 0x8ee20158, 0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3c020001,
+0x8c424dfc, 0x27bdffe0, 0x1440000d, 0xafbf0018, 0x3c040001, 0x24844ba4,
+0x3c050008, 0xafa00010, 0xafa00014, 0x8f860220, 0x34a50499, 0x24020001,
+0x3c010001, 0xac224dfc, 0xc0023a7, 0x3821, 0x8ee204c0, 0x3c030001,
+0x771821, 0x946383a2, 0x34420001, 0x10600007, 0xaee204c0, 0x8f820220,
+0x3c0308ff, 0x3463ffff, 0x431024, 0x34420008, 0xaf820220, 0x24040001,
+0xc004f33, 0x24050004, 0xaf420268, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x3c120001, 0x26520f00, 0x3c140001, 0x8e944d70,
+0x3c100001, 0x26100e20, 0x3c15c000, 0x36b50060, 0x8e8a0000, 0x8eb30000,
+0x26a400b, 0x248000a, 0x200f821, 0x0, 0xd, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x80014c4, 0x0, 0x80014c6, 0x3c0a0001, 0x80014c6, 0x3c0a0002,
+0x80014c6, 0x0, 0x800244a, 0x0, 0x80014c6, 0x3c0a0003,
+0x80014c6, 0x3c0a0004, 0x8002ef8, 0x0, 0x80014c6, 0x3c0a0005,
+0x8003c3d, 0x0, 0x8003bbe, 0x0, 0x80014c6, 0x3c0a0006,
+0x80014c6, 0x3c0a0007, 0x80014c6, 0x0, 0x80014c6, 0x0,
+0x80014c6, 0x0, 0x80029f8, 0x0, 0x80014c6, 0x3c0a000b,
+0x80014c6, 0x3c0a000c, 0x80014c6, 0x3c0a000d, 0x800231c, 0x0,
+0x80022d9, 0x0, 0x80014c6, 0x3c0a000e, 0x8001b08, 0x0,
+0x8002448, 0x0, 0x80014c6, 0x3c0a000f, 0x8003ff3, 0x0,
+0x8003fdd, 0x0, 0x80014c6, 0x3c0a0010, 0x80014da, 0x0,
+0x80014c6, 0x3c0a0011, 0x80014c6, 0x3c0a0012, 0x80014c6, 0x3c0a0013,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x3c030001, 0x34633800, 0x24050080, 0x2404001f,
+0x2406ffff, 0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220, 0x3631021,
+0xaf8200c0, 0x3631021, 0xaf8200c4, 0x3631021, 0xaf8200c8, 0x27623800,
+0xaf8200d0, 0x27623800, 0xaf8200d4, 0x27623800, 0xaf8200d8, 0x27621800,
+0xaf8200e0, 0x27621800, 0xaf8200e4, 0x27621800, 0xaf8200e8, 0x27621000,
+0xaf8200f0, 0x27621000, 0xaf8200f4, 0x27621000, 0xaf8200f8, 0xaca00000,
+0x2484ffff, 0x1486fffd, 0x24a50004, 0x8f830040, 0x3c02f000, 0x621824,
+0x3c025000, 0x1062000c, 0x43102b, 0x14400006, 0x3c026000, 0x3c024000,
+0x10620008, 0x24020800, 0x8004479, 0x0, 0x10620004, 0x24020800,
+0x8004479, 0x0, 0x24020700, 0x3c010001, 0xac224e00, 0x3e00008,
+0x0, 0x27bdffd0, 0xafbf0028, 0x3c010001, 0xc004b65, 0xac204de8,
+0x24040001, 0x2821, 0x27a60020, 0x34028000, 0xc004782, 0xa7a20020,
+0x8f830054, 0x8f820054, 0x800448b, 0x24630064, 0x8f820054, 0x621023,
+0x2c420065, 0x1440fffc, 0x24040001, 0x24050001, 0xc004740, 0x27a60020,
+0x8f830054, 0x8f820054, 0x8004497, 0x24630064, 0x8f820054, 0x621023,
+0x2c420065, 0x1440fffc, 0x24040001, 0x24050001, 0xc004740, 0x27a60020,
+0x8f830054, 0x8f820054, 0x80044a3, 0x24630064, 0x8f820054, 0x621023,
+0x2c420065, 0x1440fffc, 0x24040001, 0x24050002, 0xc004740, 0x27a60018,
+0x8f830054, 0x8f820054, 0x80044af, 0x24630064, 0x8f820054, 0x621023,
+0x2c420065, 0x1440fffc, 0x24040001, 0x24050003, 0xc004740, 0x27a6001a,
+0x97a20020, 0x10400022, 0x24030001, 0x3c020001, 0x8c424de8, 0x97a30018,
+0x34420001, 0x3c010001, 0xac224de8, 0x24020015, 0x14620008, 0x3402f423,
+0x97a3001a, 0x14620005, 0x24020003, 0x3c010001, 0xac224e9c, 0x80044e2,
+0x3c08fff0, 0x97a30018, 0x24027810, 0x1462000a, 0x24020002, 0x97a3001a,
+0x24020001, 0x14620006, 0x24020002, 0x24020004, 0x3c010001, 0xac224e9c,
+0x80044e2, 0x3c08fff0, 0x3c010001, 0xac224e9c, 0x80044e2, 0x3c08fff0,
+0x3c020001, 0x8c424de8, 0x3c010001, 0xac234e9c, 0x34420004, 0x3c010001,
+0xac224de8, 0x3c08fff0, 0x3508bdc0, 0x8f830054, 0x97a60018, 0x3c070001,
+0x8ce74e9c, 0x3c040001, 0x24844c10, 0x24020001, 0x3c010001, 0xac224df0,
+0xafa60010, 0x3c060001, 0x8cc64de8, 0x97a2001a, 0x3c05000d, 0x34a50100,
+0x3c010001, 0xac204dec, 0x681821, 0x3c010001, 0xac234e94, 0xc0023a7,
+0xafa20014, 0x8fbf0028, 0x3e00008, 0x27bd0030, 0x27bdffe8, 0x24070004,
+0x3c040001, 0x8c844dec, 0x3021, 0x24020001, 0x1482000a, 0xafbf0010,
+0x3c020001, 0x8c426f3c, 0x3c050004, 0x30428000, 0x1040000c, 0x34a593e0,
+0x3c05000f, 0x8004515, 0x34a54240, 0x3c020001, 0x8c426f3c, 0x3c05000f,
+0x30428000, 0x10400003, 0x34a54240, 0x3c05001e, 0x34a58480, 0x3c020001,
+0x8c424e94, 0x8f830054, 0x451021, 0x431023, 0x45102b, 0x1440002e,
+0x0, 0x3c020001, 0x8c424df4, 0x1440002a, 0x2cc20001, 0x7182b,
+0x431024, 0x1040001d, 0x0, 0x3c090001, 0x8d294de8, 0x240b0001,
+0x3c054000, 0x3c080001, 0x25086f3c, 0x250afffc, 0x42042, 0x14800002,
+0x24e7ffff, 0x24040008, 0x891024, 0x5040000b, 0x2cc20001, 0x148b0004,
+0x0, 0x8d020000, 0x800453a, 0x451024, 0x8d420000, 0x451024,
+0x54400001, 0x24060001, 0x2cc20001, 0x7182b, 0x431024, 0x5440ffed,
+0x42042, 0x3c010001, 0x10c00024, 0xac244dec, 0x8f830054, 0x24020001,
+0x3c010001, 0xac224df0, 0x3c010001, 0xac234e94, 0x3c020001, 0x8c424df0,
+0x10400006, 0x24020001, 0x3c010001, 0xac204df0, 0x3c010001, 0x370821,
+0xac22839c, 0x3c030001, 0x771821, 0x8c63839c, 0x24020008, 0x10620005,
+0x24020001, 0xc00456a, 0x0, 0x8004567, 0x0, 0x3c030001,
+0x8c634dec, 0x10620007, 0x2402000e, 0x3c030001, 0x8c636eb0, 0x10620003,
+0x0, 0xc004b88, 0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018,
+0x27bdffe0, 0x3c02fdff, 0xafbf0018, 0x8ee30000, 0x3c050001, 0x8ca54dec,
+0x3c040001, 0x8c844e04, 0x3442ffff, 0x621824, 0x14a40008, 0xaee30000,
+0x3c030001, 0x771821, 0x8c63839c, 0x3c020001, 0x8c424e08, 0x10620008,
+0x0, 0x3c020001, 0x571021, 0x8c42839c, 0x3c010001, 0xac254e04,
+0x3c010001, 0xac224e08, 0x3c030001, 0x8c634dec, 0x24020002, 0x10620126,
+0x2c620003, 0x10400005, 0x24020001, 0x10620008, 0x0, 0x80046ae,
+0x0, 0x24020004, 0x1062007c, 0x24020001, 0x80046af, 0x0,
+0x3c020001, 0x571021, 0x8c42839c, 0x2443ffff, 0x2c620008, 0x10400117,
+0x31080, 0x3c010001, 0x220821, 0x8c224c28, 0x400008, 0x0,
+0xc0046b4, 0x0, 0x3c020001, 0x8c424df8, 0x3c010001, 0xac204d80,
+0x104000c5, 0x24020002, 0x3c010001, 0x370821, 0xac22839c, 0x3c010001,
+0x80046b1, 0xac204df8, 0xc0047c3, 0x0, 0x3c030001, 0x8c634e10,
+0x24020011, 0x146200fd, 0x24020003, 0x8004631, 0x0, 0x3c050001,
+0x8ca54dec, 0x3c060001, 0x8cc66f3c, 0xc004e2c, 0x24040001, 0x24020005,
+0x3c010001, 0xac204df8, 0x3c010001, 0x370821, 0x80046b1, 0xac22839c,
+0x3c040001, 0x24844c1c, 0x3c05000f, 0x34a50100, 0x3021, 0x3821,
+0xafa00010, 0xc0023a7, 0xafa00014, 0x80046b1, 0x0, 0x8f820220,
+0x3c03f700, 0x431025, 0x8004658, 0xaf820220, 0x8f820220, 0x3c030004,
+0x431024, 0x14400095, 0x24020007, 0x8f830054, 0x3c020001, 0x8c424e90,
+0x2463d8f0, 0x431023, 0x2c422710, 0x144000d1, 0x24020001, 0x80046af,
+0x0, 0x3c050001, 0x8ca54dec, 0xc004f33, 0x24040001, 0xc004ff8,
+0x24040001, 0x3c030001, 0x8c636f34, 0x46100c3, 0x24020001, 0x3c020008,
+0x621024, 0x10400006, 0x0, 0x8f820214, 0x3c03ffff, 0x431024,
+0x80045fa, 0x3442251f, 0x8f820214, 0x3c03ffff, 0x431024, 0x3442241f,
+0xaf820214, 0x8ee20000, 0x3c030200, 0x431025, 0xaee20000, 0x8f820220,
+0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, 0x34420002, 0xaf820220,
+0x24020008, 0x3c010001, 0x370821, 0xc004323, 0xac22839c, 0x80046b1,
+0x0, 0x3c020001, 0x571021, 0x8c42839c, 0x2443ffff, 0x2c620008,
+0x1040009e, 0x31080, 0x3c010001, 0x220821, 0x8c224c48, 0x400008,
+0x0, 0xc0041e7, 0x0, 0x3c010001, 0xac204df0, 0xaf800204,
+0x3c010001, 0xc0046b4, 0xac206f00, 0x8f820044, 0x34428080, 0xaf820044,
+0x8f830054, 0x3c010001, 0xac204d80, 0x800465a, 0x24020002, 0x8f830054,
+0x3c020001, 0x8c424e90, 0x2463d8f0, 0x431023, 0x2c422710, 0x14400081,
+0x24020003, 0x3c010001, 0x370821, 0x80046b1, 0xac22839c, 0x3c020001,
+0x8c426f38, 0x30424000, 0x10400005, 0x0, 0x8f820044, 0x3c03ffff,
+0x8004640, 0x34637fff, 0x8f820044, 0x2403ff7f, 0x431024, 0xaf820044,
+0x8f830054, 0x800465a, 0x24020004, 0x8f830054, 0x3c020001, 0x8c424e90,
+0x2463d8f0, 0x431023, 0x2c422710, 0x14400065, 0x24020005, 0x3c010001,
+0x370821, 0x80046b1, 0xac22839c, 0x8f820220, 0x3c03f700, 0x431025,
+0xaf820220, 0xaf800204, 0x3c010001, 0xac206f00, 0x8f830054, 0x24020006,
+0x3c010001, 0x370821, 0xac22839c, 0x3c010001, 0x80046b1, 0xac234e90,
+0x3c05fffe, 0x34a57960, 0x3c040001, 0x8f820054, 0x3c030001, 0x8c634e90,
+0x3484869f, 0x451021, 0x621823, 0x83202b, 0x10800046, 0x0,
+0x24020007, 0x3c010001, 0x370821, 0x80046b1, 0xac22839c, 0x8f820220,
+0x3c04f700, 0x441025, 0xaf820220, 0x8f820220, 0x3c030300, 0x431024,
+0x14400005, 0x1821, 0x8f820220, 0x24030001, 0x441025, 0xaf820220,
+0x10600030, 0x24020001, 0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c844e88,
+0x431024, 0x3442251f, 0xaf820214, 0x24020008, 0x3c010001, 0x370821,
+0xac22839c, 0x10800007, 0x24020001, 0x3c010001, 0xac226eb0, 0xc004b88,
+0x8f840220, 0x80046b1, 0x0, 0x8f820220, 0x3c030008, 0x431024,
+0x1440001a, 0x2402000e, 0x3c010001, 0xac226eb0, 0x8ee20000, 0x24040001,
+0x3c030200, 0x431025, 0xc004ff8, 0xaee20000, 0x8f820220, 0x2403fffb,
+0x431024, 0xaf820220, 0x8f820220, 0x34420002, 0xc004323, 0xaf820220,
+0x3c050001, 0x8ca54dec, 0xc004f33, 0x24040001, 0x80046b1, 0x0,
+0x24020001, 0x3c010001, 0xac224df0, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x8f820200, 0x8f820220, 0x8f820220, 0x34420004, 0xaf820220, 0x8f820200,
+0x3c060001, 0x8cc64dec, 0x34420004, 0xaf820200, 0x24020002, 0x10c20048,
+0x2cc20003, 0x10400005, 0x24020001, 0x10c20008, 0x0, 0x8004708,
+0x0, 0x24020004, 0x10c20013, 0x24020001, 0x8004708, 0x0,
+0x3c030001, 0x8c634dd8, 0x3c020001, 0x8c424de4, 0x3c040001, 0x8c844e00,
+0x3c050001, 0x8ca54ddc, 0xaf860200, 0xaf860220, 0x34630022, 0x441025,
+0x451025, 0x34420002, 0x8004707, 0xaf830200, 0xaf820200, 0xaf820220,
+0x8f820044, 0x3c030001, 0x8c634e88, 0x34428080, 0xaf820044, 0x10600005,
+0x3c033f00, 0x3c020001, 0x8c424dd0, 0x80046fb, 0x346300e0, 0x8f8400f0,
+0x276217f8, 0x14820002, 0x24850008, 0x27651000, 0x8f8200f4, 0x10a20007,
+0x3c038000, 0x34630040, 0x3c020001, 0x24424d90, 0xac820000, 0xac830004,
+0xaf8500f0, 0x3c020001, 0x8c424dd0, 0x3c033f00, 0x346300e2, 0x431025,
+0xaf820200, 0x3c030001, 0x8c634dd4, 0x3c04f700, 0x3c020001, 0x8c424de4,
+0x3c050001, 0x8ca54e00, 0x641825, 0x431025, 0x451025, 0xaf820220,
+0x3e00008, 0x0, 0x8f820220, 0x3c030001, 0x8c634dec, 0x34420004,
+0xaf820220, 0x24020001, 0x1062000f, 0x0, 0x8f830054, 0x8f820054,
+0x24630002, 0x621023, 0x2c420003, 0x10400011, 0x0, 0x8f820054,
+0x621023, 0x2c420003, 0x1040000c, 0x0, 0x8004719, 0x0,
+0x8f830054, 0x8f820054, 0x8004725, 0x24630007, 0x8f820054, 0x621023,
+0x2c420008, 0x1440fffc, 0x0, 0x8f8400e0, 0x30820007, 0x1040000d,
+0x0, 0x8f820054, 0x8f8300e0, 0x14830009, 0x24450032, 0x8f820054,
+0xa21023, 0x2c420033, 0x10400004, 0x0, 0x8f8200e0, 0x1082fff9,
+0x0, 0x8f820220, 0x2403fffd, 0x431024, 0xaf820220, 0x3e00008,
+0x0, 0x0, 0x27bdffd8, 0xafb20018, 0x809021, 0xafb3001c,
+0xa09821, 0xafb10014, 0xc08821, 0xafb00010, 0x8021, 0xafbf0020,
+0xa6200000, 0xc004b3f, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x2021, 0x24100010, 0x2501024, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x2501024,
+0x24100010, 0x2701024, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fffa, 0x2701024, 0xc004b65, 0x34108000, 0xc004b65,
+0x0, 0xc004b1f, 0x0, 0x50400005, 0x108042, 0x96220000,
+0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, 0xc004b65,
+0x0, 0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010,
+0x3e00008, 0x27bd0028, 0x27bdffd8, 0xafb10014, 0x808821, 0xafb20018,
+0xa09021, 0xafb3001c, 0xc09821, 0xafb00010, 0x8021, 0xafbf0020,
+0xc004b3f, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0,
+0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021,
+0xc004b3f, 0x24040001, 0x24100010, 0x2301024, 0x10400002, 0x2021,
+0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x2301024, 0x24100010,
+0x2501024, 0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042,
+0x1600fffa, 0x2501024, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021,
+0x34108000, 0x96620000, 0x501024, 0x10400002, 0x2021, 0x24040001,
+0xc004b3f, 0x108042, 0x1600fff8, 0x0, 0xc004b65, 0x0,
+0x8fbf0020, 0x8fb3001c, 0x8fb20018, 0x8fb10014, 0x8fb00010, 0x3e00008,
+0x27bd0028, 0x3c030001, 0x8c634e10, 0x3c020001, 0x8c424e54, 0x27bdffd8,
+0xafbf0020, 0xafb1001c, 0x10620003, 0xafb00018, 0x3c010001, 0xac234e54,
+0x2463ffff, 0x2c620013, 0x10400349, 0x31080, 0x3c010001, 0x220821,
+0x8c224c70, 0x400008, 0x0, 0xc004b65, 0x8021, 0x34028000,
+0xa7a20010, 0x27b10010, 0xc004b3f, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001,
+0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa,
+0x32020001, 0x24100010, 0xc004b3f, 0x2021, 0x108042, 0x1600fffc,
+0x0, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0x34108000,
+0x96220000, 0x501024, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fff8, 0x0, 0xc004b65, 0x0, 0x8004b18,
+0x24020002, 0x27b10010, 0xa7a00010, 0x8021, 0xc004b3f, 0x24040001,
+0x26100001, 0x2e020020, 0x1440fffb, 0x0, 0xc004b3f, 0x2021,
+0xc004b3f, 0x24040001, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021,
+0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0xc004b3f, 0x2021,
+0x108042, 0x1600fffc, 0x0, 0xc004b65, 0x34108000, 0xc004b65,
+0x0, 0xc004b1f, 0x0, 0x50400005, 0x108042, 0x96220000,
+0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, 0xc004b65,
+0x0, 0x97a20010, 0x30428000, 0x144002dc, 0x24020003, 0x8004b18,
+0x0, 0x24021200, 0xa7a20010, 0x27b10010, 0x8021, 0xc004b3f,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0, 0xc004b3f,
+0x2021, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0xc004b3f,
+0x24040001, 0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001,
+0xc004b3f, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0xc004b3f,
+0x2021, 0x108042, 0x1600fffc, 0x0, 0xc004b3f, 0x24040001,
+0xc004b3f, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fff8, 0x0,
+0xc004b65, 0x0, 0x8f830054, 0x8004b0a, 0x24020004, 0x8f830054,
+0x3c020001, 0x8c424e98, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440029e,
+0x24020002, 0x3c030001, 0x8c634e9c, 0x10620297, 0x2c620003, 0x14400296,
+0x24020011, 0x24020003, 0x10620005, 0x24020004, 0x10620291, 0x2402000f,
+0x8004b18, 0x24020011, 0x8004b18, 0x24020005, 0x24020014, 0xa7a20010,
+0x27b10010, 0x8021, 0xc004b3f, 0x24040001, 0x26100001, 0x2e020020,
+0x1440fffb, 0x0, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001,
+0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0x24100010, 0x32020001,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa,
+0x32020001, 0x24100010, 0x32020012, 0x10400002, 0x2021, 0x24040001,
+0xc004b3f, 0x108042, 0x1600fffa, 0x32020012, 0xc004b3f, 0x24040001,
+0xc004b3f, 0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fff8, 0x0,
+0xc004b65, 0x0, 0x8f830054, 0x8004b0a, 0x24020006, 0x8f830054,
+0x3c020001, 0x8c424e98, 0x2463ff9c, 0x431023, 0x2c420064, 0x14400250,
+0x24020007, 0x8004b18, 0x0, 0x24020006, 0xa7a20010, 0x27b10010,
+0x8021, 0xc004b3f, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x2021, 0xc004b3f, 0x24040001, 0x24100010, 0x32020001, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020001,
+0x24100010, 0x32020013, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fffa, 0x32020013, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, 0x2021,
+0x24040001, 0xc004b3f, 0x108042, 0x1600fff8, 0x0, 0xc004b65,
+0x0, 0x8f830054, 0x8004b0a, 0x24020008, 0x8f830054, 0x3c020001,
+0x8c424e98, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440020f, 0x24020009,
+0x8004b18, 0x0, 0x27b10010, 0xa7a00010, 0x8021, 0xc004b3f,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0, 0xc004b3f,
+0x2021, 0xc004b3f, 0x24040001, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x2021, 0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001,
+0xc004b3f, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa,
+0x32020018, 0xc004b65, 0x34108000, 0xc004b65, 0x0, 0xc004b1f,
+0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000,
+0x108042, 0x1600fff7, 0x0, 0xc004b65, 0x8021, 0x97a20010,
+0x27b10010, 0x34420001, 0xa7a20010, 0xc004b3f, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004b3f, 0x2021, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0x24100010,
+0x32020001, 0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021,
+0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020018, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x2021, 0x34108000, 0x96220000, 0x501024,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fff8,
+0x0, 0xc004b65, 0x0, 0x8f830054, 0x8004b0a, 0x2402000a,
+0x8f830054, 0x3c020001, 0x8c424e98, 0x2463ff9c, 0x431023, 0x2c420064,
+0x1440019b, 0x2402000b, 0x8004b18, 0x0, 0x27b10010, 0xa7a00010,
+0x8021, 0xc004b3f, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x2021, 0x24100010, 0x32020001, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020001,
+0x24100010, 0x32020017, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fffa, 0x32020017, 0xc004b65, 0x34108000, 0xc004b65,
+0x0, 0xc004b1f, 0x0, 0x50400005, 0x108042, 0x96220000,
+0x501025, 0xa6220000, 0x108042, 0x1600fff7, 0x0, 0xc004b65,
+0x8021, 0x97a20010, 0x27b10010, 0x34420700, 0xa7a20010, 0xc004b3f,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0, 0xc004b3f,
+0x2021, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0xc004b3f,
+0x24040001, 0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001,
+0xc004b3f, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020017,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa,
+0x32020017, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0x34108000,
+0x96220000, 0x501024, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fff8, 0x0, 0xc004b65, 0x0, 0x8f830054,
+0x8004b0a, 0x2402000c, 0x8f830054, 0x3c020001, 0x8c424e98, 0x2463ff9c,
+0x431023, 0x2c420064, 0x14400127, 0x24020012, 0x8004b18, 0x0,
+0x27b10010, 0xa7a00010, 0x8021, 0xc004b3f, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004b3f, 0x2021, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0x24100010,
+0x32020001, 0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0x32020014, 0x10400002, 0x2021,
+0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020014, 0xc004b65,
+0x34108000, 0xc004b65, 0x0, 0xc004b1f, 0x0, 0x50400005,
+0x108042, 0x96220000, 0x501025, 0xa6220000, 0x108042, 0x1600fff7,
+0x0, 0xc004b65, 0x8021, 0x97a20010, 0x27b10010, 0x34420010,
+0xa7a20010, 0xc004b3f, 0x24040001, 0x26100001, 0x2e020020, 0x1440fffb,
+0x0, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x2021, 0xc004b3f, 0x24040001, 0x24100010, 0x32020001, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020001,
+0x24100010, 0x32020014, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fffa, 0x32020014, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x2021, 0x34108000, 0x96220000, 0x501024, 0x10400002, 0x2021,
+0x24040001, 0xc004b3f, 0x108042, 0x1600fff8, 0x0, 0xc004b65,
+0x0, 0x8f830054, 0x8004b0a, 0x24020013, 0x8f830054, 0x3c020001,
+0x8c424e98, 0x2463ff9c, 0x431023, 0x2c420064, 0x144000b3, 0x2402000d,
+0x8004b18, 0x0, 0x27b10010, 0xa7a00010, 0x8021, 0xc004b3f,
+0x24040001, 0x26100001, 0x2e020020, 0x1440fffb, 0x0, 0xc004b3f,
+0x2021, 0xc004b3f, 0x24040001, 0xc004b3f, 0x24040001, 0xc004b3f,
+0x2021, 0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001,
+0xc004b3f, 0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020018,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa,
+0x32020018, 0xc004b65, 0x34108000, 0xc004b65, 0x0, 0xc004b1f,
+0x0, 0x50400005, 0x108042, 0x96220000, 0x501025, 0xa6220000,
+0x108042, 0x1600fff7, 0x0, 0xc004b65, 0x8021, 0x97a20010,
+0x27b10010, 0x3042fffe, 0xa7a20010, 0xc004b3f, 0x24040001, 0x26100001,
+0x2e020020, 0x1440fffb, 0x0, 0xc004b3f, 0x2021, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001, 0x24100010,
+0x32020001, 0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042,
+0x1600fffa, 0x32020001, 0x24100010, 0x32020018, 0x10400002, 0x2021,
+0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020018, 0xc004b3f,
+0x24040001, 0xc004b3f, 0x2021, 0x34108000, 0x96220000, 0x501024,
+0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fff8,
+0x0, 0xc004b65, 0x0, 0x8f830054, 0x8004b0a, 0x2402000e,
+0x24020840, 0xa7a20010, 0x27b10010, 0x8021, 0xc004b3f, 0x24040001,
+0x26100001, 0x2e020020, 0x1440fffb, 0x0, 0xc004b3f, 0x2021,
+0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0xc004b3f, 0x24040001,
+0x24100010, 0x32020001, 0x10400002, 0x2021, 0x24040001, 0xc004b3f,
+0x108042, 0x1600fffa, 0x32020001, 0x24100010, 0x32020013, 0x10400002,
+0x2021, 0x24040001, 0xc004b3f, 0x108042, 0x1600fffa, 0x32020013,
+0xc004b3f, 0x24040001, 0xc004b3f, 0x2021, 0x34108000, 0x96220000,
+0x501024, 0x10400002, 0x2021, 0x24040001, 0xc004b3f, 0x108042,
+0x1600fff8, 0x0, 0xc004b65, 0x0, 0x8f830054, 0x24020010,
+0x3c010001, 0xac224e10, 0x3c010001, 0x8004b1a, 0xac234e98, 0x8f830054,
+0x3c020001, 0x8c424e98, 0x2463ff9c, 0x431023, 0x2c420064, 0x14400004,
+0x0, 0x24020011, 0x3c010001, 0xac224e10, 0x8fbf0020, 0x8fb1001c,
+0x8fb00018, 0x3e00008, 0x27bd0028, 0x8f850044, 0x8f820044, 0x3c030001,
+0x431025, 0x3c030008, 0xaf820044, 0x8f840054, 0x8f820054, 0xa32824,
+0x8004b2b, 0x24840001, 0x8f820054, 0x821023, 0x2c420002, 0x1440fffc,
+0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
+0x8f830054, 0x8f820054, 0x8004b39, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0xa01021, 0x8f830044,
+0x3c02fff0, 0x3442ffff, 0x42480, 0x621824, 0x3c020002, 0x822025,
+0x641825, 0xaf830044, 0x8f820044, 0x3c030001, 0x431025, 0xaf820044,
+0x8f830054, 0x8f820054, 0x8004b51, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff,
+0x431024, 0xaf820044, 0x8f830054, 0x8f820054, 0x8004b5f, 0x24630001,
+0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x3e00008,
+0x0, 0x8f820044, 0x3c03fff0, 0x3463ffff, 0x431024, 0xaf820044,
+0x8f820044, 0x3c030001, 0x431025, 0xaf820044, 0x8f830054, 0x8f820054,
+0x8004b73, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
+0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
+0x8f830054, 0x8f820054, 0x8004b81, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0x0, 0x0,
+0x27bdffe8, 0xafbf0010, 0x3c030001, 0x771821, 0x8c63839c, 0x24020008,
+0x1462021c, 0x803021, 0x3c020001, 0x8c424e88, 0x14400033, 0x0,
+0x8f850224, 0x38a30020, 0x2c630001, 0x38a20010, 0x2c420001, 0x621825,
+0x1460000d, 0x38a30030, 0x2c630001, 0x38a20400, 0x2c420001, 0x621825,
+0x14600007, 0x38a30402, 0x2c630001, 0x38a20404, 0x2c420001, 0x621825,
+0x10600005, 0x0, 0xc0041e7, 0x0, 0x8004bc1, 0x2402000e,
+0xc004323, 0x0, 0x3c050001, 0x8ca54dec, 0xc004f33, 0x24040001,
+0x3c030001, 0x8c634dec, 0x24020004, 0x14620005, 0x2403fffb, 0x3c020001,
+0x8c424de8, 0x8004bbd, 0x2403fff7, 0x3c020001, 0x8c424de8, 0x431024,
+0x3c010001, 0xac224de8, 0x2402000e, 0x3c010001, 0xc0041e7, 0xac226eb0,
+0x8004dab, 0x0, 0x8f820220, 0x3c030400, 0x431024, 0x10400027,
+0x2403ffbf, 0x8f850224, 0x3c020001, 0x8c426ebc, 0xa32024, 0x431024,
+0x1482000c, 0x0, 0x3c020001, 0x8c426ec0, 0x24420001, 0x3c010001,
+0xac226ec0, 0x2c420002, 0x14400008, 0x24020001, 0x3c010001, 0x8004be1,
+0xac226ee0, 0x3c010001, 0xac206ec0, 0x3c010001, 0xac206ee0, 0x3c020001,
+0x8c426ee0, 0x10400006, 0x30a20040, 0x10400004, 0x24020001, 0x3c010001,
+0x8004bec, 0xac226ee4, 0x3c010001, 0xac206ee4, 0x3c010001, 0xac256ebc,
+0x3c010001, 0x8004bfc, 0xac206ef0, 0x24020001, 0x3c010001, 0xac226ef0,
+0x3c010001, 0xac206ee0, 0x3c010001, 0xac206ec0, 0x3c010001, 0xac206ee4,
+0x3c010001, 0xac206ebc, 0x3c030001, 0x8c636eb0, 0x3c020001, 0x8c426eb4,
+0x10620003, 0x3c020200, 0x3c010001, 0xac236eb4, 0xc21024, 0x10400007,
+0x2463ffff, 0x8f820220, 0x24030001, 0x3c010001, 0xac234df0, 0x8004da9,
+0x3c03f700, 0x2c62000e, 0x10400198, 0x31080, 0x3c010001, 0x220821,
+0x8c224cc0, 0x400008, 0x0, 0x8ee20000, 0x3c03fdff, 0x3463ffff,
+0x431024, 0xaee20000, 0x3c010001, 0xac206ee0, 0x3c010001, 0xac206ec0,
+0x3c010001, 0xac206ef0, 0x3c010001, 0xac206ebc, 0x3c010001, 0xac206ee4,
+0x3c010001, 0xac206ed8, 0x3c010001, 0xac206ed0, 0xc00470a, 0xaf800224,
+0x24020002, 0x3c010001, 0xac226eb0, 0xc0041e7, 0x0, 0xaf800204,
+0x8f820200, 0x2403fffd, 0x431024, 0xaf820200, 0x3c010001, 0xac206f00,
+0x8f830054, 0x3c020001, 0x8c426ed8, 0x24040001, 0x3c010001, 0xac246eec,
+0x24420001, 0x3c010001, 0xac226ed8, 0x2c420004, 0x3c010001, 0xac236ed4,
+0x14400006, 0x24020003, 0x3c010001, 0xac244df0, 0x3c010001, 0x8004da7,
+0xac206ed8, 0x3c010001, 0x8004da7, 0xac226eb0, 0x8f830054, 0x3c020001,
+0x8c426ed4, 0x2463d8f0, 0x431023, 0x2c422710, 0x14400154, 0x24020004,
+0x3c010001, 0x8004da7, 0xac226eb0, 0x3c040001, 0x8c844e8c, 0x3c010001,
+0xc004dae, 0xac206ec8, 0x3c020001, 0x8c426efc, 0xaf820204, 0x8f820204,
+0x30420030, 0x1440013c, 0x24020002, 0x3c030001, 0x8c636efc, 0x24020005,
+0x3c010001, 0xac226eb0, 0x3c010001, 0x8004da7, 0xac236f00, 0x3c020001,
+0x8c426ee0, 0x10400139, 0x0, 0x3c020001, 0x8c426ebc, 0x10400135,
+0x0, 0x3c010001, 0xac226ee8, 0x24020003, 0x3c010001, 0xac226ec0,
+0x8004d3a, 0x24020006, 0x3c010001, 0xac206ec8, 0x8f820204, 0x34420040,
+0xaf820204, 0x3c020001, 0x8c426f00, 0x24030007, 0x3c010001, 0xac236eb0,
+0x34420040, 0x3c010001, 0xac226f00, 0x3c020001, 0x8c426ee0, 0x10400005,
+0x0, 0x3c020001, 0x8c426ebc, 0x10400110, 0x24020002, 0x3c050001,
+0x24a56ec0, 0x8ca20000, 0x2c424e21, 0x1040010a, 0x24020002, 0x3c020001,
+0x8c426ee4, 0x1040010f, 0x2404ffbf, 0x3c020001, 0x8c426ebc, 0x3c030001,
+0x8c636ee8, 0x441024, 0x641824, 0x14430007, 0x24020001, 0x24020003,
+0xaca20000, 0x24020008, 0x3c010001, 0x8004da7, 0xac226eb0, 0x3c010001,
+0x8004da7, 0xac226eb0, 0x3c020001, 0x8c426eec, 0x1040000c, 0x24020001,
+0x3c040001, 0xc004dbb, 0x8c846ebc, 0x3c020001, 0x8c426f08, 0x14400005,
+0x24020001, 0x3c020001, 0x8c426f04, 0x10400006, 0x24020001, 0x3c010001,
+0xac224df0, 0x3c010001, 0x8004da7, 0xac206ed8, 0x8f820204, 0x34420040,
+0xaf820204, 0x3c020001, 0x8c426f00, 0x3c030001, 0x8c636ed0, 0x34420040,
+0x3c010001, 0xac226f00, 0x3c020001, 0x8c426ebc, 0x2c630001, 0x318c0,
+0x3c010001, 0xac236ed0, 0x30420008, 0x3c010001, 0xac226ecc, 0x8f830054,
+0x24020009, 0x3c010001, 0xac226eb0, 0x3c010001, 0x8004da7, 0xac236ed4,
+0x8f830054, 0x3c020001, 0x8c426ed4, 0x2463d8f0, 0x431023, 0x2c422710,
+0x144000b6, 0x0, 0x3c020001, 0x8c426ee0, 0x10400005, 0x0,
+0x3c020001, 0x8c426ebc, 0x104000b7, 0x24020002, 0x3c030001, 0x24636ec0,
+0x8c620000, 0x2c424e21, 0x104000b1, 0x24020002, 0x3c020001, 0x8c426eec,
+0x1040000e, 0x0, 0x3c020001, 0x8c426ebc, 0x3c010001, 0xac206eec,
+0x30420080, 0x1040002f, 0x2402000c, 0x8f820204, 0x30420080, 0x1440000c,
+0x24020003, 0x8004d27, 0x2402000c, 0x3c020001, 0x8c426ebc, 0x30420080,
+0x14400005, 0x24020003, 0x8f820204, 0x30420080, 0x1040001f, 0x24020003,
+0xac620000, 0x2402000a, 0x3c010001, 0xac226eb0, 0x3c040001, 0x24846ef8,
+0x8c820000, 0x3c030001, 0x8c636ed0, 0x431025, 0xaf820204, 0x8c830000,
+0x3c040001, 0x8c846ed0, 0x2402000b, 0x3c010001, 0xac226eb0, 0x641825,
+0x3c010001, 0xac236f00, 0x3c050001, 0x24a56ec0, 0x8ca20000, 0x2c424e21,
+0x1040007d, 0x24020002, 0x3c020001, 0x8c426ef0, 0x10400005, 0x0,
+0x2402000c, 0x3c010001, 0x8004da7, 0xac226eb0, 0x3c020001, 0x8c426ee0,
+0x1040007a, 0x0, 0x3c040001, 0x8c846ebc, 0x1080006c, 0x30820008,
+0x3c030001, 0x8c636ecc, 0x10620072, 0x24020003, 0x3c010001, 0xac246ee8,
+0xaca20000, 0x24020006, 0x3c010001, 0x8004da7, 0xac226eb0, 0x8f8400f0,
+0x276217f8, 0x14820002, 0x24850008, 0x27651000, 0x8f8200f4, 0x10a20007,
+0x3c038000, 0x34630040, 0x3c020001, 0x24424d90, 0xac820000, 0xac830004,
+0xaf8500f0, 0x8f820200, 0x34420002, 0xaf820200, 0x8f830054, 0x2402000d,
+0x3c010001, 0xac226eb0, 0x3c010001, 0xac236ed4, 0x8f830054, 0x3c020001,
+0x8c426ed4, 0x2463d8f0, 0x431023, 0x2c422710, 0x1440003a, 0x0,
+0x3c020001, 0x8c426ef0, 0x10400029, 0x2402000e, 0x3c030001, 0x8c636f04,
+0x3c010001, 0x14600015, 0xac226eb0, 0xc004323, 0x0, 0x3c050001,
+0x8ca54dec, 0xc004f33, 0x24040001, 0x3c030001, 0x8c634dec, 0x24020004,
+0x14620005, 0x2403fffb, 0x3c020001, 0x8c424de8, 0x8004d76, 0x2403fff7,
+0x3c020001, 0x8c424de8, 0x431024, 0x3c010001, 0xac224de8, 0x8ee20000,
+0x3c030200, 0x431025, 0xaee20000, 0x8f820224, 0x3c010001, 0xac226f0c,
+0x8f820220, 0x2403fffb, 0x431024, 0xaf820220, 0x8f820220, 0x34420002,
+0x8004da7, 0xaf820220, 0x3c020001, 0x8c426ee0, 0x10400005, 0x0,
+0x3c020001, 0x8c426ebc, 0x1040000f, 0x24020002, 0x3c020001, 0x8c426ec0,
+0x2c424e21, 0x1040000a, 0x24020002, 0x3c020001, 0x8c426ee0, 0x1040000f,
+0x0, 0x3c020001, 0x8c426ebc, 0x1440000b, 0x0, 0x24020002,
+0x3c010001, 0x8004da7, 0xac226eb0, 0x3c020001, 0x8c426ee0, 0x10400003,
+0x0, 0xc0041e7, 0x0, 0x8f820220, 0x3c03f700, 0x431025,
+0xaf820220, 0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3c030001, 0x24636f08,
+0x8c620000, 0x10400005, 0x34422000, 0x3c010001, 0xac226efc, 0x8004db9,
+0xac600000, 0x3c010001, 0xac246efc, 0x3e00008, 0x0, 0x27bdffe0,
+0x30820030, 0xafbf0018, 0x3c010001, 0xac226f04, 0x14400067, 0x3c02ffff,
+0x34421f0e, 0x821024, 0x14400061, 0x24020030, 0x30822000, 0x1040005d,
+0x30838000, 0x31a02, 0x30820001, 0x21200, 0x3c040001, 0x8c844e8c,
+0x621825, 0x331c2, 0x3c030001, 0x24634e6c, 0x30828000, 0x21202,
+0x30840001, 0x42200, 0x441025, 0x239c2, 0x61080, 0x431021,
+0x471021, 0x90430000, 0x24020001, 0x10620025, 0x0, 0x10600007,
+0x24020002, 0x10620013, 0x24020003, 0x1062002c, 0x3c05000f, 0x8004e1d,
+0x0, 0x8f820200, 0x2403feff, 0x431024, 0xaf820200, 0x8f820220,
+0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, 0x3c010001, 0xac206f44,
+0x3c010001, 0x8004e28, 0xac206f4c, 0x8f820200, 0x34420100, 0xaf820200,
+0x8f820220, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820220, 0x24020100,
+0x3c010001, 0xac226f44, 0x3c010001, 0x8004e28, 0xac206f4c, 0x8f820200,
+0x2403feff, 0x431024, 0xaf820200, 0x8f820220, 0x3c030001, 0x431025,
+0xaf820220, 0x3c010001, 0xac206f44, 0x3c010001, 0x8004e28, 0xac236f4c,
+0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, 0x3c030001, 0x431025,
+0xaf820220, 0x24020100, 0x3c010001, 0xac226f44, 0x3c010001, 0x8004e28,
+0xac236f4c, 0x34a5ffff, 0x3c040001, 0x24844cf8, 0xafa30010, 0xc0023a7,
+0xafa00014, 0x8004e28, 0x0, 0x24020030, 0x3c010001, 0xac226f08,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x0, 0x27bdffc8, 0xafb10024,
+0x808821, 0xafb3002c, 0xa09821, 0xafb00020, 0xc08021, 0x3c040001,
+0x24844d10, 0x3c050009, 0x3c020001, 0x8c424dec, 0x34a59001, 0x2203021,
+0x2603821, 0xafbf0030, 0xafb20028, 0xa7a0001a, 0xafb00014, 0xc0023a7,
+0xafa20010, 0x24020002, 0x126200e9, 0x2e620003, 0x10400005, 0x24020001,
+0x1262000a, 0x3c02fffb, 0x8004f2c, 0x0, 0x24020004, 0x1262006d,
+0x24020008, 0x1262006c, 0x3c02ffec, 0x8004f2c, 0x0, 0x3442ffff,
+0x2028024, 0x119140, 0x3c010001, 0x320821, 0xac306f1c, 0x3c024000,
+0x2021024, 0x10400046, 0x1023c2, 0x30840030, 0x101382, 0x3042000c,
+0x3c030001, 0x24634e14, 0x431021, 0x823821, 0x3c020020, 0x2021024,
+0x10400006, 0x24020100, 0x3c010001, 0x320821, 0xac226f20, 0x8004e6f,
+0x3c020080, 0x3c010001, 0x320821, 0xac206f20, 0x3c020080, 0x2021024,
+0x10400006, 0x111940, 0x3c020001, 0x3c010001, 0x230821, 0x8004e7b,
+0xac226f28, 0x111140, 0x3c010001, 0x220821, 0xac206f28, 0x94e30000,
+0x32024000, 0x10400003, 0xa7a30018, 0x34624000, 0xa7a20018, 0x24040001,
+0x94e20002, 0x24050004, 0x24e60002, 0x34420001, 0xc004782, 0xa4e20002,
+0x24040001, 0x2821, 0xc004782, 0x27a60018, 0x3c020001, 0x8c424dec,
+0x24110001, 0x3c010001, 0xac314df8, 0x14530004, 0x32028000, 0xc0041e7,
+0x0, 0x32028000, 0x10400095, 0x0, 0xc0041e7, 0x0,
+0x24020002, 0x3c010001, 0xac314df0, 0x3c010001, 0x8004f2c, 0xac224dec,
+0x24040001, 0x24050004, 0x27b0001a, 0xc004782, 0x2003021, 0x24040001,
+0x2821, 0xc004782, 0x2003021, 0x3c020001, 0x521021, 0x8c426f14,
+0x3c040001, 0x8c844dec, 0x3c03bfff, 0x3463ffff, 0x3c010001, 0xac334df8,
+0x431024, 0x3c010001, 0x320821, 0x10930074, 0xac226f14, 0x8004f2c,
+0x0, 0x3c02ffec, 0x3442ffff, 0x2028024, 0x3c020008, 0x2028025,
+0x111140, 0x3c010001, 0x220821, 0xac306f18, 0x3c022000, 0x2021024,
+0x10400005, 0x24020001, 0x3c010001, 0xac224e88, 0x8004ecd, 0x3c024000,
+0x3c010001, 0xac204e88, 0x3c024000, 0x2021024, 0x1440001c, 0x0,
+0x3c020001, 0x8c424e88, 0x10400007, 0x24022020, 0x3c010001, 0xac224e8c,
+0x24020001, 0x3c010001, 0x370821, 0xac22839c, 0x3c04bfff, 0x111940,
+0x3c020001, 0x431021, 0x8c426f10, 0x3c050001, 0x8ca54dec, 0x3484ffff,
+0x441024, 0x3c010001, 0x230821, 0xac226f10, 0x24020001, 0x10a20044,
+0x0, 0x8004f2a, 0x0, 0x3c020001, 0x8c424e88, 0x1040001c,
+0x24022000, 0x3c010001, 0xac224e8c, 0x3c0300a0, 0x2031024, 0x14430005,
+0x111140, 0x3402a000, 0x3c010001, 0x8004f25, 0xac224e8c, 0x3c030001,
+0x621821, 0x8c636f18, 0x3c020020, 0x621024, 0x10400004, 0x24022001,
+0x3c010001, 0x8004f25, 0xac224e8c, 0x3c020080, 0x621024, 0x1040001f,
+0x3402a001, 0x3c010001, 0x8004f25, 0xac224e8c, 0x3c020020, 0x2021024,
+0x10400007, 0x111940, 0x24020100, 0x3c010001, 0x230821, 0xac226f24,
+0x8004f19, 0x3c020080, 0x111140, 0x3c010001, 0x220821, 0xac206f24,
+0x3c020080, 0x2021024, 0x10400006, 0x111940, 0x3c020001, 0x3c010001,
+0x230821, 0x8004f25, 0xac226f2c, 0x111140, 0x3c010001, 0x220821,
+0xac206f2c, 0x3c030001, 0x8c634dec, 0x24020001, 0x10620003, 0x0,
+0xc0041e7, 0x0, 0x8fbf0030, 0x8fb3002c, 0x8fb20028, 0x8fb10024,
+0x8fb00020, 0x3e00008, 0x27bd0038, 0x27bdffd0, 0xafb40028, 0x80a021,
+0xafb20020, 0x9021, 0xafb30024, 0x9821, 0xafb1001c, 0x8821,
+0x24020002, 0xafbf002c, 0xafb00018, 0xa7a00012, 0x10a20068, 0xa7a00010,
+0x2ca20003, 0x10400005, 0x24020001, 0x10a2000a, 0x148140, 0x8004ff0,
+0x2201021, 0x24020004, 0x10a2005e, 0x24020008, 0x10a2005d, 0x142140,
+0x8004ff0, 0x2201021, 0x3c030001, 0x701821, 0x8c636f1c, 0x3c024000,
+0x621024, 0x14400009, 0x24040001, 0x3c027fff, 0x3442ffff, 0x628824,
+0x3c010001, 0x300821, 0xac316f14, 0x8004ff0, 0x2201021, 0x24050001,
+0xc004740, 0x27a60010, 0x24040001, 0x24050001, 0xc004740, 0x27a60010,
+0x97a20010, 0x30420004, 0x10400034, 0x3c114000, 0x3c030001, 0x8c634e9c,
+0x24020003, 0x10620008, 0x2c620004, 0x14400029, 0x3c028000, 0x24020004,
+0x10620014, 0x24040001, 0x8004f99, 0x3c028000, 0x24040001, 0x24050011,
+0x27b00012, 0xc004740, 0x2003021, 0x24040001, 0x24050011, 0xc004740,
+0x2003021, 0x97a30012, 0x30624000, 0x10400002, 0x3c130010, 0x3c130008,
+0x3c120001, 0x8004f96, 0x30628000, 0x24050014, 0x27b00012, 0xc004740,
+0x2003021, 0x24040001, 0x24050014, 0xc004740, 0x2003021, 0x97a30012,
+0x30621000, 0x10400002, 0x3c130010, 0x3c130008, 0x3c120001, 0x30620800,
+0x54400001, 0x3c120002, 0x3c028000, 0x2221025, 0x2531825, 0x8004fa3,
+0x438825, 0x3c110001, 0x2308821, 0x8e316f1c, 0x3c027fff, 0x3442ffff,
+0x2228824, 0x141140, 0x3c010001, 0x220821, 0xac316f14, 0x8004ff0,
+0x2201021, 0x142140, 0x3c030001, 0x641821, 0x8c636f18, 0x3c024000,
+0x621024, 0x14400008, 0x3c027fff, 0x3442ffff, 0x628824, 0x3c010001,
+0x240821, 0xac316f10, 0x8004ff0, 0x2201021, 0x3c020001, 0x8c424dfc,
+0x1040002d, 0x3c11c00c, 0x3c020001, 0x8c424e88, 0x3c03e00c, 0x3c010001,
+0x240821, 0x8c246f24, 0x2102b, 0x21023, 0x431024, 0x10800004,
+0x518825, 0x3c020020, 0x8004fcd, 0x2228825, 0x3c02ffdf, 0x3442ffff,
+0x2228824, 0x141140, 0x3c010001, 0x220821, 0x8c226f2c, 0x10400003,
+0x3c020080, 0x8004fd8, 0x2228825, 0x3c02ff7f, 0x3442ffff, 0x2228824,
+0x3c020001, 0x8c424e60, 0x10400002, 0x3c020800, 0x2228825, 0x3c020001,
+0x8c424e64, 0x10400002, 0x3c020400, 0x2228825, 0x3c020001, 0x8c424e68,
+0x10400006, 0x3c020100, 0x8004feb, 0x2228825, 0x3c027fff, 0x3442ffff,
+0x628824, 0x141140, 0x3c010001, 0x220821, 0xac316f10, 0x2201021,
+0x8fbf002c, 0x8fb40028, 0x8fb30024, 0x8fb20020, 0x8fb1001c, 0x8fb00018,
+0x3e00008, 0x27bd0030, 0x27bdffd8, 0xafb40020, 0x80a021, 0xafbf0024,
+0xafb3001c, 0xafb20018, 0xafb10014, 0xafb00010, 0x8f900200, 0x3c030001,
+0x8c634dec, 0x8f930220, 0x24020002, 0x106200b1, 0x2c620003, 0x10400005,
+0x24020001, 0x1062000a, 0x141940, 0x80050b7, 0x0, 0x24020004,
+0x1062005a, 0x24020008, 0x10620059, 0x149140, 0x80050b7, 0x0,
+0x3c040001, 0x832021, 0x8c846f1c, 0x3c110001, 0x2238821, 0x8e316f14,
+0x3c024000, 0x821024, 0x1040003e, 0x3c020008, 0x2221024, 0x10400020,
+0x36100002, 0x3c020001, 0x431021, 0x8c426f20, 0x10400005, 0x36100020,
+0x36100100, 0x3c020020, 0x800502f, 0x2228825, 0x2402feff, 0x2028024,
+0x3c02ffdf, 0x3442ffff, 0x2228824, 0x141140, 0x3c010001, 0x220821,
+0x8c226f28, 0x10400005, 0x3c020001, 0x2629825, 0x3c020080, 0x800504e,
+0x2228825, 0x3c02fffe, 0x3442ffff, 0x2629824, 0x3c02ff7f, 0x3442ffff,
+0x800504e, 0x2228824, 0x2402fedf, 0x2028024, 0x3c02fffe, 0x3442ffff,
+0x2629824, 0x3c02ff5f, 0x3442ffff, 0x2228824, 0x3c010001, 0x230821,
+0xac206f20, 0x3c010001, 0x230821, 0xac206f28, 0xc00470a, 0x0,
+0xaf900200, 0xaf930220, 0x8f820220, 0x2403fffb, 0x431024, 0xaf820220,
+0x8f820220, 0x34420002, 0xaf820220, 0x8005065, 0x141140, 0x8f820200,
+0x2403fffd, 0x431024, 0xc00470a, 0xaf820200, 0x3c02bfff, 0x3442ffff,
+0xc0041e7, 0x2228824, 0x141140, 0x3c010001, 0x220821, 0x80050b7,
+0xac316f14, 0x149140, 0x3c040001, 0x922021, 0x8c846f18, 0x3c110001,
+0x2328821, 0x8e316f10, 0x3c024000, 0x821024, 0x14400011, 0x0,
+0x3c020001, 0x8c424e88, 0x14400006, 0x3c02bfff, 0x8f820200, 0x34420002,
+0xc00470a, 0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc0041e7, 0x2228824,
+0x3c010001, 0x320821, 0x80050b7, 0xac316f10, 0x3c020001, 0x8c424e88,
+0x1440002d, 0x141140, 0x3c020020, 0x821024, 0x10400007, 0x36100020,
+0x24020100, 0x3c010001, 0x320821, 0xac226f24, 0x8005097, 0x36100100,
+0x3c010001, 0x320821, 0xac206f24, 0x2402feff, 0x2028024, 0x3c020080,
+0x821024, 0x10400007, 0x141940, 0x3c020001, 0x3c010001, 0x230821,
+0xac226f2c, 0x80050a8, 0x2629825, 0x141140, 0x3c010001, 0x220821,
+0xac206f2c, 0x3c02fffe, 0x3442ffff, 0x2629824, 0xc00470a, 0x0,
+0xaf900200, 0xaf930220, 0x8f820220, 0x2403fffb, 0x431024, 0xaf820220,
+0x8f820220, 0x34420002, 0xaf820220, 0x141140, 0x3c010001, 0x220821,
+0xac316f10, 0x8fbf0024, 0x8fb40020, 0x8fb3001c, 0x8fb20018, 0x8fb10014,
+0x8fb00010, 0x3e00008, 0x27bd0028, 0x0, 0x0 };
+u32 tigonFwData[(MAX_DATA_LEN/4) + 1] = {
+0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x416c7465, 0x6f6e2041,
+0x63654e49, 0x43205600, 0x42424242, 0x0, 0x0, 0x0,
+0x135430, 0x13e7fc, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x60cf00, 0x60, 0xcf000000, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x3, 0x0, 0x1, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x1, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x1000000, 0x21000000,
+0x12000140, 0x0, 0x0, 0x20000000, 0x120000a0, 0x0,
+0x12000060, 0x12000180, 0x120001e0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x30001, 0x1,
+0x30201, 0x0, 0x0 };
+u32 tigonFwRodata[(MAX_RODATA_LEN/4) + 1] = {
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f66, 0x776d6169,
+0x6e2e632c, 0x7620312e, 0x312e322e, 0x31312031, 0x3939382f, 0x30342f32,
+0x37203232, 0x3a31333a, 0x34322073, 0x6875616e, 0x67204578, 0x70202400,
+0x7468655f, 0x4441574e, 0x0, 0x53544143, 0x4b5f3120, 0x0,
+0x42616453, 0x6e64526e, 0x67000000, 0x3f456e71, 0x45767400, 0x3f6e6f51,
+0x64457650, 0x0, 0x6576526e, 0x6746756c, 0x6c000000, 0x496c6c43,
+0x6f6e6652, 0x78000000, 0x53656e64, 0x436b5375, 0x6d000000, 0x52656376,
+0x566c616e, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f74, 0x696d6572, 0x2e632c76, 0x20312e31,
+0x2e322e37, 0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, 0x333a3439,
+0x20736875, 0x616e6720, 0x45787020, 0x24000000, 0x542d446d, 0x61526431,
+0x0, 0x542d446d, 0x61424200, 0x542d446d, 0x61320000, 0x3f6e6f51,
+0x64547845, 0x0, 0x3f6e6f51, 0x64527845, 0x0, 0x656e714d,
+0x45765046, 0x61696c00, 0x656e714d, 0x45764661, 0x696c0000, 0x6661696c,
+0x456e454d, 0x0, 0x3f456e71, 0x45767400, 0x3f6e6f51, 0x64457650,
+0x0, 0x6576526e, 0x6746756c, 0x6c000000, 0x0, 0x0,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f63, 0x6f6d6d61,
+0x6e642e63, 0x2c762031, 0x2e312e32, 0x2e382031, 0x3939382f, 0x30342f32,
+0x37203232, 0x3a31333a, 0x33392073, 0x6875616e, 0x67204578, 0x70202400,
+0x4e4f636f, 0x6d616e64, 0x0, 0x68737465, 0x5f455252, 0x0,
+0x412d4572, 0x72427563, 0x0, 0x4552524f, 0x522d4164, 0x64000000,
+0x656e714d, 0x45765046, 0x61696c00, 0x656e714d, 0x45764661, 0x696c0000,
+0x6661696c, 0x456e454d, 0x0, 0x442d4572, 0x724c6173, 0x74000000,
+0x442d4572, 0x72320000, 0x6d437374, 0x4d644552, 0x52000000, 0x70726f6d,
+0x4d644552, 0x52000000, 0x46696c74, 0x4d644552, 0x52000000, 0x636d645f,
+0x45525200, 0x3f456e71, 0x45767400, 0x3f6e6f51, 0x64457650, 0x0,
+0x6576526e, 0x6746756c, 0x6c000000, 0x0, 0x6da4, 0x7e7c,
+0x6d3c, 0x85c8, 0x815c, 0x8614, 0x8614, 0x6e58,
+0x7578, 0x7dcc, 0x7f68, 0x7f34, 0x8614, 0x7d30,
+0x7f8c, 0x6d68, 0x808c, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f64, 0x6d612e63, 0x2c762031, 0x2e312e32,
+0x2e332031, 0x3939382f, 0x30342f32, 0x37203232, 0x3a31333a, 0x34312073,
+0x6875616e, 0x67204578, 0x70202400, 0x646d6172, 0x6441544e, 0x0,
+0x646d6177, 0x7241544e, 0x0, 0x0, 0x0, 0x0,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f74, 0x72616365,
+0x2e632c76, 0x20312e31, 0x2e322e32, 0x20313939, 0x382f3034, 0x2f323720,
+0x32323a31, 0x333a3530, 0x20736875, 0x616e6720, 0x45787020, 0x24000000,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f66772f, 0x636f6d6d, 0x6f6e2f64, 0x6174612e,
+0x632c7620, 0x312e312e, 0x322e3220, 0x31393938, 0x2f30342f, 0x32372032,
+0x323a3133, 0x3a343020, 0x73687561, 0x6e672045, 0x78702024, 0x0,
+0x46575f56, 0x45525349, 0x4f4e3a20, 0x23312046, 0x7269204f, 0x63742031,
+0x36203130, 0x3a31333a, 0x30352050, 0x44542031, 0x39393800, 0x46575f43,
+0x4f4d5049, 0x4c455f54, 0x494d453a, 0x2031303a, 0x31333a30, 0x35000000,
+0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263, 0x73000000,
+0x46575f43, 0x4f4d5049, 0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465,
+0x0, 0x46575f43, 0x4f4d5049, 0x4c455f44, 0x4f4d4149, 0x4e3a2065,
+0x6e672e61, 0x6374656f, 0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049,
+0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e, 0x20322e37, 0x2e320000,
+0x0, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f6d, 0x656d2e63, 0x2c762031, 0x2e312e32,
+0x2e322031, 0x3939382f, 0x30342f32, 0x37203232, 0x3a31333a, 0x34342073,
+0x6875616e, 0x67204578, 0x70202400, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f73, 0x656e642e, 0x632c7620, 0x312e312e,
+0x322e3820, 0x31393938, 0x2f30342f, 0x32372032, 0x323a3133, 0x3a343820,
+0x73687561, 0x6e672045, 0x78702024, 0x0, 0x736e6464, 0x654e6f51,
+0x20000000, 0x6e6f454e, 0x515f5458, 0x0, 0x736e6464, 0x744e6f51,
+0x20000000, 0x3f6e6f51, 0x64547845, 0x0, 0x756e6b72, 0x64747970,
+0x65000000, 0x0, 0xba70, 0xba70, 0xbb18, 0xac2c,
+0xae2c, 0xbb18, 0xbb18, 0xbb18, 0xbb18, 0xbb18,
+0xbb18, 0xbb18, 0xbb18, 0xbb18, 0xbb18, 0xbb18,
+0xbb18, 0xbb18, 0xbb18, 0xae14, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f72, 0x6563762e, 0x632c7620, 0x312e312e,
+0x322e3139, 0x20313939, 0x382f3037, 0x2f323420, 0x32313a33, 0x303a3035,
+0x20736875, 0x616e6720, 0x45787020, 0x24000000, 0x706b5278, 0x45525200,
+0x66726d32, 0x4c617267, 0x65000000, 0x72784e6f, 0x52784264, 0x0,
+0x72785144, 0x6d614446, 0x0, 0x72785144, 0x6d614246, 0x0,
+0x3f6e6f51, 0x64527845, 0x0, 0x706b5278, 0x45525273, 0x0,
+0x66726d32, 0x4c726753, 0x0, 0x72784e6f, 0x42645300, 0x3f724264,
+0x446d6146, 0x0, 0x3f724a42, 0x64446d46, 0x0, 0x0,
+0xf3c0, 0xf3c0, 0xf3c0, 0xf3c0, 0xf3c0, 0xf3c0,
+0xf3c0, 0xf3c0, 0xf3c0, 0xf3c0, 0xf3c0, 0xf3c0,
+0xf3c0, 0xf3c0, 0xf3c0, 0xf3b8, 0xf3b8, 0xf3b8,
+0x572d444d, 0x41456e46, 0x0, 0x0, 0xfafc, 0xfe80,
+0xfb18, 0xfe80, 0xfe80, 0xfe80, 0xfe80, 0xfe80,
+0xfe80, 0xf44c, 0xfe80, 0xfe80, 0xfe80, 0xfe80,
+0xfe80, 0xfe78, 0xfe78, 0xfe78, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f6d, 0x61632e63, 0x2c762031, 0x2e312e32,
+0x2e313220, 0x31393938, 0x2f30342f, 0x32372032, 0x323a3133, 0x3a343220,
+0x73687561, 0x6e672045, 0x78702024, 0x0, 0x6d616374, 0x7841544e,
+0x0, 0x4e745379, 0x6e264c6b, 0x0, 0x72656d61, 0x73737274,
+0x0, 0x6c696e6b, 0x444f574e, 0x0, 0x656e714d, 0x45765046,
+0x61696c00, 0x656e714d, 0x45764661, 0x696c0000, 0x6661696c, 0x456e454d,
+0x0, 0x6c696e6b, 0x55500000, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f66772f, 0x636f6d6d, 0x6f6e2f63, 0x6b73756d, 0x2e632c76, 0x20312e31,
+0x2e322e32, 0x20313939, 0x382f3034, 0x2f323720, 0x32323a31, 0x333a3339,
+0x20736875, 0x616e6720, 0x45787020, 0x24000000, 0x50726f62, 0x65506879,
+0x0, 0x6c6e6b41, 0x53535254, 0x0, 0x11680, 0x116b8,
+0x116dc, 0x11710, 0x1173c, 0x11750, 0x1178c, 0x11ac4,
+0x11864, 0x118a4, 0x118d4, 0x11914, 0x11944, 0x11980,
+0x119c4, 0x11ac4, 0x0, 0x0, 0x11f5c, 0x1202c,
+0x12104, 0x121d4, 0x12230, 0x1230c, 0x12334, 0x12410,
+0x12438, 0x125e0, 0x12608, 0x127b0, 0x129a8, 0x12c3c,
+0x12b50, 0x12c3c, 0x12c68, 0x127d8, 0x12980, 0x0,
+0x13054, 0x130b4, 0x13130, 0x1315c, 0x131ac, 0x131e8,
+0x1321c, 0x132a8, 0x13360, 0x13430, 0x13470, 0x134f4,
+0x13550, 0x13684, 0x646f4261, 0x73655067, 0x0, 0x0,
+0x0, 0x0, 0x73746d61, 0x634c4e4b, 0x0, 0x0,
+0x0 };
+/* Generated by genfw.c */
+int tigon2FwReleaseMajor = 0xc;
+int tigon2FwReleaseMinor = 0x1;
+int tigon2FwReleaseFix = 0x4;
+u32 tigon2FwStartAddr = 0x4000;
+u32 tigon2FwTextAddr = 0x4000;
+int tigon2FwTextLen = 0xe480;
+u32 tigon2FwDataAddr = 0x131d0;
+int tigon2FwDataLen = 0x170;
+u32 tigon2FwRodataAddr = 0x12480;
+int tigon2FwRodataLen = 0xd30;
+u32 tigon2FwBssAddr = 0x133f0;
+int tigon2FwBssLen = 0x20c0;
+u32 tigon2FwSbssAddr = 0x13340;
+int tigon2FwSbssLen = 0xa8;
+u32 tigon2FwText[(MAX_TEXT_LEN/4) + 1] = {
+0x0, 0x10000003, 0x0, 0xd, 0xd, 0x3c1d0001,
+0x8fbd3220, 0x3a0f021, 0x3c100000, 0x26104000, 0xc0010c0, 0x0,
+0xd, 0x3c1d0001, 0x8fbd3224, 0x3a0f021, 0x3c100000, 0x26104000,
+0xc0016fe, 0x0, 0xd, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x2000008, 0x0,
+0x8001671, 0x3c0a0001, 0x8001671, 0x3c0a0002, 0x8001671, 0x0,
+0x8002994, 0x0, 0x8001671, 0x3c0a0003, 0x8001671, 0x3c0a0004,
+0x8003110, 0x0, 0x80019ba, 0x0, 0x8003608, 0x0,
+0x8003597, 0x0, 0x8001671, 0x3c0a0006, 0x8001671, 0x3c0a0007,
+0x8001671, 0x3c0a0008, 0x8001671, 0x3c0a0009, 0x8003679, 0x0,
+0x8002bd5, 0x0, 0x8001671, 0x3c0a000b, 0x8001671, 0x3c0a000c,
+0x8001671, 0x3c0a000d, 0x80026e0, 0x0, 0x80026b3, 0x0,
+0x8001671, 0x3c0a000e, 0x8001f40, 0x0, 0x80018c9, 0x0,
+0x800196b, 0x0, 0x80038f7, 0x0, 0x80038e1, 0x0,
+0x8001671, 0x0, 0x800184d, 0x0, 0x8001893, 0x0,
+0x8001671, 0x3c0a0013, 0x8001671, 0x3c0a0014, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x27bdffe0, 0x3c1cc000, 0xafbf0018, 0xc0028d0, 0xd021, 0x8f820040,
+0x3c03f000, 0x431824, 0x3c025000, 0x10620005, 0x3c026000, 0x1062001a,
+0x24020003, 0x10000030, 0x0, 0x8f820050, 0x3c030010, 0x431024,
+0x50400013, 0x24020003, 0x3c030001, 0x2463c2d0, 0x3c020001, 0x2442c354,
+0x431023, 0x3c010001, 0xac2333b8, 0x8f830140, 0x3c040001, 0x2484c35c,
+0x3c010001, 0xac2233a4, 0x3c020001, 0x2442c3c4, 0x3c010001, 0xac2031d8,
+0x10000013, 0x441023, 0x3c030001, 0x2463c3cc, 0xaf8200ec, 0x3c020001,
+0x2442c408, 0x431023, 0x3c010001, 0xac2333b8, 0x8f830140, 0x3c040001,
+0x2484c410, 0x3c010001, 0xac2233a4, 0x3c020001, 0x2442c438, 0x441023,
+0x3c0100c0, 0xac203ffc, 0x3c010001, 0xac2433b0, 0x3c010001, 0xac2233ac,
+0x34630004, 0xaf830140, 0xc00169c, 0x0, 0x402821, 0x3c010001,
+0xac253350, 0x3c020008, 0x10a2002c, 0x45102b, 0x14400006, 0x3c020010,
+0x3c020004, 0x10a20007, 0x3c02ffff, 0x1000005b, 0x0, 0x10a20045,
+0x3c030003, 0x10000057, 0x0, 0x34422e10, 0x3c030001, 0x246354b0,
+0x3c040001, 0x8c8431d4, 0xa31823, 0x14800002, 0x622821, 0x24a5faa8,
+0x2403f000, 0xa32824, 0x51082, 0x431024, 0x3c010001, 0xac223340,
+0xa21023, 0x3c010001, 0xac223348, 0x3402a000, 0x3c010001, 0xac223358,
+0x24020008, 0x3c010001, 0xac223360, 0x2402001f, 0x3c010001, 0xac223368,
+0x24020016, 0x3c010001, 0xac22334c, 0x10000041, 0x3c08ffff, 0x3c02ffff,
+0x34422e10, 0x3c030001, 0x246354b0, 0x3c040001, 0x8c8431d4, 0xa31823,
+0x14800002, 0x622821, 0x24a5faa8, 0x2403f000, 0xa32824, 0x3c040003,
+0x34842000, 0x510c2, 0x431024, 0x3c010001, 0xac223340, 0xa21023,
+0x3c010001, 0xac223348, 0x24020008, 0x3c010001, 0xac223360, 0x2402001f,
+0x3c010001, 0xac223368, 0x24020016, 0x3c010001, 0xac243358, 0x3c010001,
+0xac22334c, 0x1000001f, 0x3c08ffff, 0x34632000, 0x3c020001, 0x3c010001,
+0xac223340, 0x3c020007, 0x3c010001, 0xac223348, 0x24020008, 0x3c010001,
+0xac223360, 0x2402001f, 0x3c010001, 0xac223368, 0x24020016, 0x3c010001,
+0xac233358, 0x3c010001, 0xac22334c, 0x1000000b, 0x3c08ffff, 0x3c040001,
+0x24842540, 0x3c050001, 0x8ca53350, 0x3021, 0x3821, 0xafa00010,
+0xc0028eb, 0xafa00014, 0x3c08ffff, 0x35087e10, 0x3c0500bf, 0x34a5f000,
+0x3c0600bf, 0x34c6e000, 0x3c070001, 0x8ce73340, 0x3c040001, 0x8c843348,
+0x3c030020, 0x3c090001, 0x8d2931d0, 0x671023, 0x441023, 0x245bb000,
+0x641823, 0x3c010001, 0xac233354, 0x671823, 0x27620ffc, 0x3c010001,
+0xac223220, 0x27621ffc, 0xbb2823, 0xdb3023, 0x3c010001, 0xac233344,
+0x3c010001, 0xac223224, 0xaf850150, 0xaf860250, 0x1120001b, 0x368b821,
+0x33620fff, 0x10400008, 0x24050019, 0x3c040001, 0x2484254c, 0x3603021,
+0x3821, 0xafa00010, 0xc0028eb, 0xafa00014, 0x3c1d0001, 0x8fbd31dc,
+0x3a0f021, 0xc001684, 0x0, 0x3c020001, 0x8c4231e0, 0x3c030001,
+0x8c6331e4, 0x2442fe00, 0x24630200, 0x3c010001, 0xac2231e0, 0x3c010001,
+0x10000004, 0xac2331e4, 0x3c1d0001, 0x8fbd3220, 0x3a0f021, 0x3c020001,
+0x8c4231d4, 0x1040000d, 0x26f6faa8, 0x3c020001, 0x8c4231e0, 0x3c030001,
+0x8c6331e4, 0x3c160001, 0x8ed631e4, 0x2442faa8, 0x24630558, 0x3c010001,
+0xac2231e0, 0x3c010001, 0xac2331e4, 0x3c020001, 0x8c4231d8, 0x14400003,
+0x0, 0x3c010001, 0xac2031e0, 0xc0011ca, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x27bdff98, 0xafbf0060, 0xafbe005c, 0xafb50058,
+0xafb30054, 0xafb10050, 0x8f820240, 0x3c030001, 0x431025, 0xaf820240,
+0x3c020001, 0x8c4231e0, 0x3c030001, 0x8c6331e4, 0xaf800048, 0x8f840048,
+0x3c120000, 0x26524100, 0xa3a00047, 0xafa20034, 0x14800005, 0xafa30030,
+0xaf800048, 0x8f820048, 0x10400004, 0x0, 0xaf800048, 0x10000003,
+0x2e02021, 0xaf80004c, 0x2e02021, 0xc00296c, 0x340581f0, 0x2c02021,
+0xc00296c, 0x24050558, 0x3c020001, 0x8c423344, 0x3c030001, 0x8c633340,
+0x3c040001, 0x8c843348, 0x3c050001, 0x8ca53358, 0x3c060001, 0x8cc63360,
+0x3c070001, 0x8ce73368, 0x3c080001, 0x8d08334c, 0xaec20534, 0x3c020001,
+0x8c423354, 0x8ec90534, 0xaec50544, 0x3c050001, 0x8ca53350, 0xaec00000,
+0xaec3053c, 0xaec40540, 0xaec60548, 0xaec7054c, 0xaec80550, 0xaec20538,
+0xafa90010, 0x8ec20538, 0xafa20014, 0x8ec6053c, 0x8ec70540, 0x3c040001,
+0xc0028eb, 0x24842558, 0xafb70010, 0xafb60014, 0x8ec60544, 0x8ec70548,
+0x3c040001, 0x24842560, 0xc0028eb, 0x24050001, 0x3c040001, 0x24842568,
+0x24050001, 0x24060001, 0x24070001, 0xafa00010, 0xc0028eb, 0xafa00014,
+0x3c020001, 0x8c423350, 0x3603821, 0x3c060001, 0x24c654b0, 0x2448ffff,
+0x1061824, 0xe81024, 0x43102b, 0x10400006, 0x24050002, 0x3c040001,
+0x24842570, 0xafa80010, 0xc0028eb, 0xafa00014, 0x24020001, 0xa2c20529,
+0xaf800054, 0xaf80011c, 0x8f420218, 0x30420002, 0x10400009, 0x0,
+0x8f420220, 0x3c030002, 0x34630004, 0x431025, 0xaec20008, 0x8f42021c,
+0x10000008, 0x34420004, 0x8f420220, 0x3c030002, 0x34630006, 0x431025,
+0xaec20008, 0x8f42021c, 0x34420006, 0xaec20010, 0x8f420218, 0x30420010,
+0x1040000a, 0x0, 0x8f42021c, 0x34420004, 0xaec2000c, 0x8f420220,
+0x3c03000a, 0x34630004, 0x431025, 0x10000009, 0xaec20004, 0x8f420220,
+0x3c03000a, 0x34630006, 0x431025, 0xaec20004, 0x8f42021c, 0x34420006,
+0xaec2000c, 0x8f420218, 0x30420200, 0x10400003, 0x24020001, 0x10000002,
+0xa2c20064, 0xa2c00064, 0x24020001, 0xaf8200a0, 0xaf8200b0, 0x8f830054,
+0x8f820054, 0x10000002, 0x24630064, 0x8f820054, 0x621023, 0x2c420065,
+0x1440fffc, 0x0, 0x8f440208, 0x8f45020c, 0x26e20028, 0xaee20020,
+0x24020480, 0xaee20010, 0xaee40008, 0xaee5000c, 0x26e40008, 0x8c820000,
+0x8c830004, 0x3802821, 0xaf820090, 0xaf830094, 0x8c820018, 0xaca200b4,
+0x9482000a, 0xaca2009c, 0x8ca200b0, 0x8ec30010, 0x431025, 0xaca200b0,
+0x8f8200b0, 0x30420004, 0x1440fffd, 0x0, 0x8ee20448, 0x8ee3044c,
+0xaee304bc, 0x8ee204bc, 0x2442e000, 0x2c422001, 0x1440000d, 0x26c40128,
+0x8ee20448, 0x8ee3044c, 0x3c040001, 0x2484257c, 0x3c050001, 0xafa00010,
+0xafa00014, 0x8ee704bc, 0x34a5f000, 0xc0028eb, 0x603021, 0x26c40128,
+0xc00296c, 0x24050400, 0x27440080, 0xc00296c, 0x24050080, 0x8f42025c,
+0x26c4018c, 0xaec20158, 0x8f420260, 0x27450200, 0x24060008, 0xc00297e,
+0xaec20160, 0x3c043b9a, 0x3484ca00, 0x2821, 0x24020006, 0x24030002,
+0xaec2015c, 0x240203e8, 0xaec3016c, 0xaec30168, 0xaec40164, 0xaec201fc,
+0x24020001, 0xaec301f8, 0xaec20204, 0x3c030001, 0x651821, 0x906331e8,
+0x2c51021, 0x24a50001, 0xa0430194, 0x2ca2000f, 0x1440fff8, 0x2c51821,
+0x8f820040, 0x24a50001, 0x21702, 0x24420030, 0xa0620194, 0x2c51021,
+0xa0400194, 0xafa00010, 0x8fa20034, 0x3c040001, 0x24842588, 0xafa20014,
+0x8fa60030, 0x3821, 0xc0028eb, 0x2821, 0x3c040000, 0x24845990,
+0x24050010, 0x27b30030, 0x2603021, 0x27b10034, 0xc0016be, 0x2203821,
+0x3c030001, 0x8c6331d8, 0x3c15f000, 0x1060000a, 0xafa2003c, 0x8fa30030,
+0x2405ff00, 0x8fa20034, 0x246400ff, 0x852024, 0x831823, 0x431023,
+0xafa20034, 0xafa40030, 0x3c040000, 0x24844100, 0x24050108, 0x2603021,
+0xc0016be, 0x2203821, 0x96e30452, 0x30630003, 0x1060005f, 0x409021,
+0x8f820050, 0x3c030010, 0x431024, 0x10400021, 0x0, 0x8f820040,
+0x3c035000, 0x551024, 0x14430009, 0x0, 0x96e60452, 0x8f820050,
+0xafa00014, 0xafa20010, 0x8f870040, 0x3c040001, 0x1000000d, 0x24842594,
+0x8f420218, 0x30420040, 0x1040000d, 0x24020001, 0x8f820050, 0x96e60452,
+0xafa20010, 0x8f420218, 0xafa20014, 0x8f870040, 0x3c040001, 0x2484259c,
+0xc0028eb, 0x2821, 0x10000004, 0x0, 0x3c010001, 0x370821,
+0xa02281ec, 0x3c040001, 0x24849a48, 0x3c050001, 0x24a59ac4, 0xa42823,
+0x27b30030, 0x2603021, 0x8ec3000c, 0x27b10034, 0x2203821, 0x24020001,
+0xa2c20020, 0xa2c20021, 0x34630a00, 0xc0016be, 0xaec3000c, 0x3c040001,
+0x2484ab64, 0x3c050001, 0x24a5af4c, 0xa42823, 0x2603021, 0x2203821,
+0xc0016be, 0xaec200a4, 0x3c040001, 0x2484b418, 0x3c050001, 0x24a5c2c8,
+0xa42823, 0x2603021, 0x3c010001, 0xac22339c, 0xc0016be, 0x2203821,
+0x3c040001, 0x2484dacc, 0x3c050001, 0x24a5e290, 0xa42823, 0x2603021,
+0x3c010001, 0xac2233a0, 0xc0016be, 0x2203821, 0x3c040001, 0x248425a4,
+0x96e60452, 0x24050011, 0x3821, 0x3c010001, 0xac2233bc, 0xafa00010,
+0xc0028eb, 0xafa00014, 0x10000028, 0x0, 0x3c040001, 0x2484989c,
+0x3c050001, 0x24a59a40, 0xa42823, 0x2603021, 0xc0016be, 0x2203821,
+0x3c040001, 0x2484a650, 0x3c050001, 0x24a5ab5c, 0xa42823, 0x2603021,
+0x2203821, 0xc0016be, 0xaec200a4, 0x3c040001, 0x2484af54, 0x3c050001,
+0x24a5b410, 0xa42823, 0x2603021, 0x3c010001, 0xac22339c, 0xc0016be,
+0x2203821, 0x3c040001, 0x2484d9e4, 0x3c050001, 0x24a5dac4, 0xa42823,
+0x2603021, 0x3c010001, 0xac2233a0, 0xc0016be, 0x2203821, 0x3c010001,
+0xac2233bc, 0x3c020001, 0x8c42339c, 0x3c050fff, 0x34a5ffff, 0x3c030001,
+0x8c6333a0, 0x3c040800, 0x451024, 0x21082, 0x441025, 0x651824,
+0xae420020, 0x3c020001, 0x8c4233bc, 0x31882, 0x641825, 0xae430080,
+0x451024, 0x21082, 0x441025, 0xae420078, 0x96e20462, 0x30420003,
+0x14400009, 0x0, 0x96e20472, 0x30420003, 0x1040007f, 0x27b30030,
+0x96e20462, 0x30420003, 0x1040006d, 0x3c020700, 0x96e20472, 0x30420003,
+0x10400069, 0x3c020700, 0x96e30472, 0x96e20462, 0x14620065, 0x3c020700,
+0x8f82005c, 0x3c030080, 0x431024, 0x1040000b, 0x0, 0x8f820050,
+0x96e60462, 0xafa20010, 0x8f82005c, 0xafa20014, 0x8f870040, 0x3c040001,
+0x248425b0, 0xc0028eb, 0x24051977, 0x8f820050, 0x3c030010, 0x431024,
+0x10400022, 0x0, 0x8f820040, 0x3c03f000, 0x431024, 0x3c035000,
+0x14430009, 0x0, 0x96e60462, 0x8f820050, 0xafa00014, 0xafa20010,
+0x8f870040, 0x3c040001, 0x1000000d, 0x24842594, 0x8f420218, 0x30420040,
+0x1040000d, 0x24020001, 0x8f820050, 0x96e60462, 0xafa20010, 0x8f420218,
+0xafa20014, 0x8f870040, 0x3c040001, 0x2484259c, 0xc0028eb, 0x24050001,
+0x10000004, 0x0, 0x3c010001, 0x370821, 0xa02281ec, 0x3c040001,
+0x2484981c, 0x3c050001, 0x24a59894, 0xa42823, 0x27b30030, 0x2603021,
+0x8ec30004, 0x27b10034, 0x2203821, 0x24020001, 0xa2c2004c, 0x34630e00,
+0xc0016be, 0xaec30004, 0x3c040001, 0x2484cf2c, 0x3c050001, 0x24a5d654,
+0xa42823, 0x2603021, 0x2203821, 0xc0016be, 0xaec200a8, 0x3c040001,
+0x2484dacc, 0x3c050001, 0x24a5e290, 0xa42823, 0x2603021, 0x3c010001,
+0xac2233b4, 0xc0016be, 0x2203821, 0x3c040001, 0x248425bc, 0x21900,
+0x31982, 0x3c050800, 0x651825, 0xae430078, 0x96e60462, 0x24050012,
+0x3c010001, 0xac2233bc, 0x1000000a, 0x3821, 0x34423000, 0x240a0001,
+0x3c040001, 0x248425c8, 0x3405f001, 0x3021, 0x3821, 0xa3aa0047,
+0xafa20020, 0xafa00010, 0xc0028eb, 0xafa00014, 0x10000015, 0x0,
+0x3c040001, 0x2484960c, 0x3c050001, 0x24a59814, 0xa42823, 0x2603021,
+0x27b10034, 0xc0016be, 0x2203821, 0x3c040001, 0x2484c4ec, 0x3c050001,
+0x24a5cf24, 0xa42823, 0x2603021, 0x2203821, 0xc0016be, 0xaec200a8,
+0x3c010001, 0xac2233b4, 0x3c020001, 0x8c4233b4, 0x3c030800, 0x21100,
+0x21182, 0x431025, 0xae420038, 0x8f420218, 0x30420040, 0x14400004,
+0x24020001, 0x3c010001, 0x370821, 0xa02281ec, 0x96e20462, 0x30420010,
+0x14400009, 0x0, 0x96e20472, 0x30420010, 0x10400021, 0x0,
+0x96e20462, 0x30420010, 0x10400005, 0x3c020700, 0x96e20472, 0x30420010,
+0x14400011, 0x3c020700, 0x34423000, 0x240a0001, 0xa3aa0047, 0xafa20020,
+0x8ee20154, 0x96e60462, 0x96e70472, 0x24420001, 0xaee20154, 0x8ee20154,
+0x3c040001, 0x248425d4, 0x3405f002, 0xafa00010, 0xc0028eb, 0xafa00014,
+0x96e60472, 0x96e70462, 0x3c040001, 0x248425dc, 0x24050012, 0xafa00010,
+0xc0028eb, 0xafa00014, 0x3c040001, 0x2484d65c, 0x3c050001, 0x24a5d818,
+0xa42823, 0x27b30030, 0x2603021, 0x27b10034, 0xc0016be, 0x2203821,
+0x3c1e0fff, 0x37deffff, 0x3c040001, 0x2484d820, 0x3c050001, 0x24a5d9dc,
+0xa42823, 0x2603021, 0x2203821, 0x3c010001, 0xac2233a8, 0x5e1024,
+0x21082, 0x3c150800, 0x551025, 0xc0016be, 0xae420050, 0x3c040000,
+0x24847d00, 0x3c050000, 0x24a57f50, 0xa42823, 0x2603021, 0x2203821,
+0x3c010001, 0xac2233c0, 0x5e1024, 0x21082, 0x551025, 0xc0016be,
+0xae420048, 0x3c040000, 0x24846134, 0x3c050000, 0x24a56244, 0xa42823,
+0x2603021, 0x2203821, 0x3c010001, 0xac223388, 0x5e1024, 0x21082,
+0x551025, 0xc0016be, 0xae4200b8, 0x3c040000, 0x2484624c, 0x3c050000,
+0x24a5631c, 0xa42823, 0x2603021, 0x2203821, 0x3c010001, 0xac22337c,
+0x5e1024, 0x21082, 0x551025, 0xc0016be, 0xae4200e8, 0x3c040000,
+0x24846324, 0x3c050000, 0x24a565a4, 0xa42823, 0x2603021, 0x2203821,
+0x3c010001, 0xac22336c, 0x5e1024, 0x21082, 0x551025, 0xc0016be,
+0xae4200f0, 0x3c040000, 0x248465ac, 0x3c050000, 0x24a566e0, 0xa42823,
+0x2603021, 0x2203821, 0x3c010001, 0xac223374, 0x5e1024, 0x21082,
+0x551025, 0xc0016be, 0xae4200c0, 0x3c040001, 0x2484e3dc, 0x3c050001,
+0x24a5e98c, 0xa42823, 0x2603021, 0x2203821, 0x3c010001, 0xac223380,
+0x5e1024, 0x21082, 0x551025, 0xc0016be, 0xae4200c8, 0x3c040001,
+0x2484ed00, 0x3c050001, 0x24a5edd8, 0xa42823, 0x2603021, 0x2203821,
+0x3c010001, 0xac2233c4, 0x5e1024, 0x21082, 0x551025, 0xc0016be,
+0xae4200d0, 0x3c040001, 0x8c8433b8, 0x3c050001, 0x8ca533a4, 0x2603021,
+0x2203821, 0xc0016be, 0xaec200ac, 0x3c040001, 0x8c8433b0, 0x3c050001,
+0x8ca533ac, 0x2603021, 0x3c010001, 0xac2233b8, 0xc0016be, 0x2203821,
+0x3c010001, 0xac2233b0, 0x3c070001, 0xf73821, 0x90e781ec, 0xafa00010,
+0x8fa20034, 0xafa20014, 0x8fa60030, 0x3c040001, 0x248425e8, 0xc0028eb,
+0x2821, 0x8faa003c, 0xc003beb, 0x1408021, 0xc0038a8, 0x0,
+0xc002548, 0x0, 0xaec0002c, 0xaf400228, 0xaf40022c, 0xaee004a8,
+0xaec00014, 0xaec00018, 0xaec00024, 0x96e20450, 0x2442ffff, 0xaec20028,
+0x3c010001, 0x370821, 0xac2081d4, 0xaec00038, 0xaec00044, 0xaec0003c,
+0xaec00040, 0xaec00048, 0x96e20480, 0x2442ffff, 0xaec2006c, 0x3c010001,
+0x370821, 0xac2081e0, 0x8ec20534, 0x8ec30534, 0x8ec40534, 0x8ec50538,
+0xaec00068, 0xaec00060, 0xaec0005c, 0xaec00058, 0xa2c000ed, 0xaec00078,
+0xaec00084, 0xaec20074, 0xaec3007c, 0xaec40080, 0xaec5008c, 0xc002298,
+0xa2c00115, 0x3c1433d8, 0x3694c348, 0x3c020800, 0x34420080, 0x3c040000,
+0x248459dc, 0x3c050000, 0x24a55a08, 0xa42823, 0x2603021, 0x2203821,
+0xaf820060, 0x2402ffff, 0xaec00030, 0xaec00034, 0xc0016be, 0xaf820064,
+0x3c010001, 0xac223364, 0x5e1024, 0x21082, 0x551025, 0xc00181c,
+0xae420000, 0x8f820240, 0x3c030001, 0x431025, 0xaf820240, 0x3c020000,
+0x24424034, 0xaf820244, 0xaf800240, 0x8f820060, 0x551024, 0x14400005,
+0x3c030800, 0x8f820060, 0x431024, 0x1040fffd, 0x0, 0xc0038b5,
+0x0, 0x3c020100, 0xafa20028, 0x8ec3002c, 0x240200ff, 0x10620003,
+0x8821, 0x8ec2002c, 0x24510001, 0x8f420228, 0x1622000f, 0x24070008,
+0x3c040001, 0x248424fc, 0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228,
+0x3c050009, 0xc0028eb, 0x34a5f005, 0x8ec202a0, 0x24420001, 0xaec202a0,
+0x10000046, 0x8ec202a0, 0x8ec2002c, 0x210c0, 0x571021, 0x8fa30028,
+0x8fa4002c, 0xac4304c0, 0xac4404c4, 0x8ec3002c, 0x8ee40428, 0x8ee5042c,
+0x8ec6002c, 0x2402000d, 0xafa20010, 0xafb10014, 0x8ec20008, 0x318c0,
+0x604821, 0x4021, 0xa92821, 0xa9182b, 0x882021, 0x832021,
+0x630c0, 0xafa20018, 0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021,
+0x5440000c, 0xaed1002c, 0x3c040001, 0x24842508, 0xafa00010, 0xafa00014,
+0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f000, 0x1000001d,
+0x0, 0x8ee40488, 0x8ee5048c, 0x8ec3002c, 0x8ec80008, 0x8f860120,
+0x24020011, 0xafa20010, 0xafa30014, 0xafa80018, 0x8ec200a8, 0x24070008,
+0x40f809, 0x24c6001c, 0x1440000e, 0x0, 0x3c040001, 0x24842510,
+0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb,
+0x34a5f001, 0x8ec202a4, 0x24420001, 0xaec202a4, 0x8ec202a4, 0x8ec20248,
+0x24420001, 0xaec20248, 0x8ec20248, 0x93a20047, 0x10400070, 0x240200ff,
+0x8ec3002c, 0x10620004, 0x27a70020, 0x8ec2002c, 0x10000002, 0x24510001,
+0x8821, 0x8f420228, 0x1622000f, 0x4021, 0x3c040001, 0x248424fc,
+0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb,
+0x34a5f005, 0x8ec202a0, 0x24420001, 0xaec202a0, 0x10000046, 0x8ec202a0,
+0x8ec2002c, 0x210c0, 0x571021, 0x8ce30000, 0x8ce40004, 0xac4304c0,
+0xac4404c4, 0x8ec3002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c, 0x24070008,
+0x2402000d, 0xafa20010, 0xafb10014, 0x8ec20008, 0x318c0, 0x604821,
+0xa92821, 0xa9182b, 0x882021, 0x832021, 0x630c0, 0xafa20018,
+0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021, 0x5440000c, 0xaed1002c,
+0x3c040001, 0x24842508, 0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228,
+0x3c050009, 0xc0028eb, 0x34a5f000, 0x1000001d, 0x0, 0x8ee40488,
+0x8ee5048c, 0x8ec3002c, 0x8ec80008, 0x8f860120, 0x24020011, 0xafa20010,
+0xafa30014, 0xafa80018, 0x8ec200a8, 0x24070008, 0x40f809, 0x24c6001c,
+0x1440000e, 0x0, 0x3c040001, 0x24842510, 0xafa00010, 0xafa00014,
+0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f001, 0x8ec202a4,
+0x24420001, 0xaec202a4, 0x8ec202a4, 0x3c040001, 0x248425f4, 0x8ec20254,
+0x3c050009, 0x34a59999, 0x24420001, 0xaec20254, 0x8ec20254, 0x3021,
+0x3821, 0xafa00010, 0xc0028eb, 0xafa00014, 0x10000004, 0x0,
+0x8f420264, 0x10400005, 0x0, 0x8f8200a0, 0x30420004, 0x1440fffa,
+0x0, 0x8f820044, 0x34420004, 0xaf820044, 0x8ec2026c, 0x24420001,
+0xaec2026c, 0x8ec2026c, 0x8f8200d8, 0x8f8300d4, 0x431023, 0x2442fff8,
+0xaec20088, 0x8ec20088, 0x4410006, 0x24020001, 0x8ec20088, 0x8ec3053c,
+0x431021, 0xaec20088, 0x24020001, 0xaec20070, 0x96e20452, 0x30420010,
+0x10400005, 0x0, 0x8f820214, 0x3c038100, 0x431025, 0xaf820214,
+0x3c020001, 0x8c4232a8, 0x30420001, 0x10400007, 0x0, 0x3c040000,
+0x24846bb4, 0x3c050000, 0x24a570e8, 0x10000006, 0xa42823, 0x3c040000,
+0x248466e8, 0x3c050000, 0x24a56bac, 0xa42823, 0x27a60030, 0xc0016be,
+0x27a70034, 0x3c010001, 0xac223378, 0x3c020001, 0x8c423378, 0x3c030800,
+0x21100, 0x21182, 0x431025, 0xae420040, 0x8f830060, 0x74100b,
+0x242000a, 0x200f821, 0x0, 0xd, 0x8fbf0060, 0x8fbe005c,
+0x8fb50058, 0x8fb30054, 0x8fb10050, 0x3e00008, 0x27bd0068, 0x3e00008,
+0x0, 0x3e00008, 0x0, 0x3e00008, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x3e00008, 0x0, 0x3e00008, 0x0,
+0x27bdfde0, 0x27a70018, 0x3c02dead, 0x3442beef, 0xafbf0218, 0x8f830150,
+0x3c04001f, 0x3484ffff, 0xafa20018, 0xe33823, 0xe43824, 0x8ce30000,
+0x10620008, 0x0, 0xafa30010, 0xafa00014, 0x8f860150, 0x3c040001,
+0x24842600, 0xc0028eb, 0x24050020, 0x8fbf0218, 0x3e00008, 0x27bd0220,
+0x27bdffe0, 0x3c06abba, 0x34c6babe, 0xafb10018, 0x3c110004, 0x3c07007f,
+0x34e7ffff, 0xafbf001c, 0x112840, 0x8e240000, 0x8ca30000, 0xaca00000,
+0xae260000, 0x8ca20000, 0xaca30000, 0x10460005, 0xae240000, 0xa08821,
+0xf1102b, 0x1040fff5, 0x112840, 0x3c040001, 0x2484260c, 0x2202821,
+0x3021, 0x3821, 0xafa00010, 0xc0028eb, 0xafa00014, 0x2201021,
+0x8fbf001c, 0x8fb10018, 0x3e00008, 0x27bd0020, 0x27bdffc8, 0xafb30024,
+0x809821, 0xafbe002c, 0xafb50028, 0xe0a821, 0x24a50003, 0xafbf0030,
+0xafb10020, 0x8ea20000, 0x2403fffc, 0xa38824, 0x51102b, 0x14400020,
+0xc0f021, 0x8fc80000, 0xafa00010, 0xafa8001c, 0x8ea20000, 0x3c040001,
+0x24842618, 0xafa20014, 0x8fc60000, 0x2602821, 0xc0028eb, 0x2203821,
+0x8fc60000, 0x111882, 0x2463ffff, 0x2402ffff, 0x10620008, 0x2602021,
+0x2405ffff, 0x8c820000, 0x24840004, 0x2463ffff, 0xacc20000, 0x1465fffb,
+0x24c60004, 0x8ea20000, 0x511023, 0xaea20000, 0x8fc20000, 0x511021,
+0x1000000b, 0xafc20000, 0xafa00010, 0x8ea20000, 0x3c040001, 0x24842620,
+0xafa20014, 0x8fc60000, 0x2602821, 0x2203821, 0xc0028eb, 0xafa5001c,
+0x8fa2001c, 0x8fbf0030, 0x8fbe002c, 0x8fb50028, 0x8fb30024, 0x8fb10020,
+0x3e00008, 0x27bd0038, 0x27bdffe8, 0x3c1cc000, 0xd021, 0x3c05ffff,
+0x3c030001, 0x8c633340, 0x3c040001, 0x8c843348, 0x34a57e10, 0x24021ffc,
+0x3c010001, 0xac2231e0, 0x3c0200c0, 0x3c010001, 0xac2231e4, 0x3c020020,
+0xafbf0010, 0x3c0100c0, 0xac201ffc, 0x431023, 0x441023, 0x245bb000,
+0x365b821, 0x3c1d0001, 0x8fbd31dc, 0x3a0f021, 0x3c0400c0, 0x34840200,
+0x3c1600c0, 0x3c0300c0, 0x34630758, 0x24021dfc, 0x3c010001, 0xac2231e0,
+0x240218a4, 0x3c010001, 0xac2431e4, 0x3c010001, 0xac2231e0, 0x3c010001,
+0xac2331e4, 0xc00172c, 0x36d60200, 0x8fbf0010, 0x3e00008, 0x27bd0018,
+0x27bdffc8, 0x3c040001, 0x24842628, 0x2821, 0x3c020001, 0x8c4231e0,
+0x3c030001, 0x8c6331e4, 0x3021, 0x3603821, 0xafbf0030, 0xafbe002c,
+0xafb50028, 0xafb30024, 0xafb10020, 0xafa2001c, 0xafa30018, 0xafb70010,
+0xc0028eb, 0xafb60014, 0xc001849, 0x0, 0x8f820240, 0x34420004,
+0xaf820240, 0x24020001, 0xaec20000, 0x3c020001, 0x571021, 0x904281ec,
+0x10400090, 0x2402fffc, 0x3c110001, 0x2631a33b, 0x3c150001, 0x26b59ee8,
+0x2351823, 0x8fa6001c, 0x628824, 0xd1102b, 0x1440001e, 0x27be0018,
+0x8fb30018, 0x3c040001, 0x24842618, 0x2a02821, 0x2203821, 0xafa00010,
+0xafa60014, 0xc0028eb, 0x2603021, 0x8fa40018, 0x111882, 0x2463ffff,
+0x2402ffff, 0x10620008, 0x2a02821, 0x2406ffff, 0x8ca20000, 0x24a50004,
+0x2463ffff, 0xac820000, 0x1466fffb, 0x24840004, 0x8fa2001c, 0x511023,
+0xafa2001c, 0x8fc20000, 0x511021, 0x1000000a, 0xafc20000, 0x3c040001,
+0x24842620, 0x2a02821, 0xafa00010, 0xafa60014, 0x8fa60018, 0x2203821,
+0xc0028eb, 0xa09821, 0x8fa3001c, 0x24150020, 0x3c010001, 0xac33335c,
+0x2c620020, 0x1440001d, 0x27b30018, 0x8fb10018, 0x3c040001, 0x24842618,
+0x3c050001, 0x24a533f0, 0x24070020, 0xafa00010, 0xafa30014, 0xc0028eb,
+0x2203021, 0x3c050001, 0x24a533f0, 0x8fa40018, 0x24030007, 0x2406ffff,
+0x8ca20000, 0x24a50004, 0x2463ffff, 0xac820000, 0x1466fffb, 0x24840004,
+0x8fa2001c, 0x551023, 0xafa2001c, 0x8e620000, 0x551021, 0x1000000c,
+0xae620000, 0x3c040001, 0x24842620, 0x3c050001, 0x24a533f0, 0xafa00010,
+0xafa30014, 0x8fa60018, 0x3c110001, 0x263133f0, 0xc0028eb, 0x24070020,
+0x8fa3001c, 0x24150020, 0x3c010001, 0xac313390, 0x2c620020, 0x1440001d,
+0x27b30018, 0x8fb10018, 0x3c040001, 0x24842618, 0x3c050001, 0x24a53410,
+0x24070020, 0xafa00010, 0xafa30014, 0xc0028eb, 0x2203021, 0x3c050001,
+0x24a53410, 0x8fa40018, 0x24030007, 0x2406ffff, 0x8ca20000, 0x24a50004,
+0x2463ffff, 0xac820000, 0x1466fffb, 0x24840004, 0x8fa2001c, 0x551023,
+0xafa2001c, 0x8e620000, 0x551021, 0x1000000c, 0xae620000, 0x3c040001,
+0x24842620, 0x3c050001, 0x24a53410, 0xafa00010, 0xafa30014, 0x8fa60018,
+0x3c110001, 0x26313410, 0xc0028eb, 0x24070020, 0x3c010001, 0x10000033,
+0xac31338c, 0x3c110000, 0x26317cef, 0x3c150000, 0x26b57b3c, 0x2351823,
+0x8fa6001c, 0x628824, 0xd1102b, 0x1440001e, 0x27be0018, 0x8fb30018,
+0x3c040001, 0x24842618, 0x2a02821, 0x2203821, 0xafa00010, 0xafa60014,
+0xc0028eb, 0x2603021, 0x8fa40018, 0x111882, 0x2463ffff, 0x2402ffff,
+0x10620008, 0x2a02821, 0x2406ffff, 0x8ca20000, 0x24a50004, 0x2463ffff,
+0xac820000, 0x1466fffb, 0x24840004, 0x8fa2001c, 0x511023, 0xafa2001c,
+0x8fc20000, 0x511021, 0x1000000a, 0xafc20000, 0x3c040001, 0x24842620,
+0x2a02821, 0xafa00010, 0xafa60014, 0x8fa60018, 0x2203821, 0xc0028eb,
+0xa09821, 0x3c010001, 0xac33335c, 0x3c030001, 0x8c63335c, 0x24020400,
+0x60f809, 0xaf820070, 0x8fbf0030, 0x8fbe002c, 0x8fb50028, 0x8fb30024,
+0x8fb10020, 0x3e00008, 0x27bd0038, 0x0, 0x0, 0x0,
+0x8f820040, 0x3c03f000, 0x431824, 0x3c025000, 0x10620005, 0x3c026000,
+0x10620012, 0x0, 0x10000015, 0x0, 0x8f820050, 0x3c030010,
+0x431024, 0x10400006, 0x0, 0x8f820050, 0x2403ff80, 0x431024,
+0x1000000a, 0x34420063, 0x8f820050, 0x2403ff80, 0x431024, 0x10000005,
+0x3442004f, 0x8f820050, 0x2403ff80, 0x431024, 0x34420055, 0xaf820050,
+0x8f820054, 0x244203e8, 0xaf820058, 0x240201f4, 0xaec200c8, 0x24020004,
+0xaec200d0, 0x24020002, 0xaec000a0, 0xaec000cc, 0xaec200c4, 0xaec000c0,
+0xaec000bc, 0x3e00008, 0xaec000b8, 0x8f820054, 0x24420005, 0x3e00008,
+0xaf820078, 0x27bdffe8, 0xafbf0010, 0x8f820054, 0x3c030001, 0x8c6332bc,
+0x244203e8, 0x1060001d, 0xaf820058, 0x3c020001, 0x8c4232a8, 0x30420001,
+0x1440000c, 0x0, 0x3c020001, 0x8c4233c8, 0x10400008, 0x0,
+0x8f830224, 0x3c020001, 0x8c42548c, 0x10620003, 0x0, 0xc003a65,
+0x0, 0x92c200ec, 0x10400003, 0x3c0208ff, 0x1000000a, 0xa2c000ec,
+0x3442fffb, 0x8f830220, 0x3c040200, 0x284a025, 0x621824, 0x10000003,
+0xaf830220, 0xc003d6d, 0x0, 0x8f420238, 0x1040000a, 0x0,
+0x8ec200a0, 0x244203e8, 0xaec200a0, 0x8f430238, 0x43102b, 0x14400003,
+0x0, 0xc001c3c, 0x0, 0x8f420218, 0x30420100, 0x10400003,
+0x0, 0xc001e07, 0x0, 0x8ec200c0, 0x8ec300c4, 0x24420001,
+0xaec200c0, 0x43102b, 0x14400003, 0x0, 0xaec000c0, 0x36940080,
+0x8fbf0010, 0x3e00008, 0x27bd0018, 0x3e00008, 0x0, 0x8f820040,
+0x30420001, 0x14400008, 0x2021, 0x8f430104, 0x24020001, 0x50620005,
+0x24040001, 0x8f420264, 0x10400003, 0x801021, 0x24040001, 0x801021,
+0x10400006, 0x0, 0x8ec20270, 0x24420001, 0xaec20270, 0x10000008,
+0x8ec20270, 0x8f820044, 0x34420004, 0xaf820044, 0x8ec2026c, 0x24420001,
+0xaec2026c, 0x8ec2026c, 0x8ec20000, 0x3c03dfff, 0x10400007, 0x3463ffff,
+0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, 0x10000005, 0x0,
+0xaf800048, 0x8f820048, 0x1040fffd, 0x0, 0x8f820060, 0x431024,
+0xaf820060, 0x8ec20000, 0x10400003, 0x0, 0x10000002, 0xaf80004c,
+0xaf800048, 0x3e00008, 0x0, 0x3e00008, 0x0, 0x27bdffd8,
+0xafbf0024, 0xafb10020, 0x8ec30018, 0x8ec20028, 0x10620056, 0x0,
+0x3c020001, 0x571021, 0x8c4281d4, 0x10400023, 0x24070008, 0x8ed10018,
+0x8ee40498, 0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020012, 0xafa20010,
+0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b,
+0x24020001, 0x3c040001, 0x24842690, 0xafb10010, 0xafa00014, 0x8ec6002c,
+0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021, 0x14400005,
+0x24020001, 0x3c010001, 0x370821, 0x1000005c, 0xac2281d4, 0x3c010001,
+0x370821, 0x10000022, 0xac2081d0, 0x8ed10018, 0x8ee40498, 0x8ee5049c,
+0x8ec30008, 0x8f860120, 0x24020019, 0xafa20010, 0xafb10014, 0xafa30018,
+0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b, 0x24020001, 0x3c040001,
+0x24842690, 0xafb10010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009,
+0xc0028eb, 0x34a5f006, 0x1021, 0x14400005, 0x24020001, 0x3c010001,
+0x370821, 0x1000003a, 0xac2281d8, 0x3c010001, 0x370821, 0xac2281d0,
+0x3c010001, 0x370821, 0xac2081d8, 0x3c010001, 0x370821, 0xac2081d4,
+0x8ec20264, 0xaec00024, 0xaed10028, 0x24420001, 0xaec20264, 0x1000002a,
+0x8ec20264, 0x3c020001, 0x571021, 0x8c4281d0, 0x1040001f, 0x0,
+0x8f820040, 0x30420001, 0x14400008, 0x2021, 0x8f430104, 0x24020001,
+0x50620005, 0x24040001, 0x8f420264, 0x10400003, 0x801021, 0x24040001,
+0x801021, 0x10400006, 0x0, 0x8ec20270, 0x24420001, 0xaec20270,
+0x10000008, 0x8ec20270, 0x8f820044, 0x34420004, 0xaf820044, 0x8ec2026c,
+0x24420001, 0xaec2026c, 0x8ec2026c, 0x3c010001, 0x370821, 0xac2081d0,
+0x3c010001, 0x370821, 0xac2081d4, 0x3c010001, 0x370821, 0xac2081d8,
+0x8ec20000, 0x3c03ff7f, 0x10400007, 0x3463ffff, 0xaf80004c, 0x8f82004c,
+0x1040fffd, 0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048,
+0x1040fffd, 0x0, 0x8f820060, 0x431024, 0xaf820060, 0x8ec20000,
+0x10400003, 0x0, 0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0024,
+0x8fb10020, 0x3e00008, 0x27bd0028, 0x3e00008, 0x0, 0x27bdffd8,
+0xafbf0024, 0xafb10020, 0x8ec30068, 0x8ec2006c, 0x10620029, 0x24070008,
+0x8ed10068, 0x8ee40490, 0x8ee50494, 0x8ec30008, 0x8f860120, 0x24020013,
+0xafa20010, 0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c,
+0x1440000b, 0x24020001, 0x3c040001, 0x2484269c, 0xafb10010, 0xafa00014,
+0x8ec60068, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f008, 0x1021,
+0x14400005, 0x24020001, 0x3c010001, 0x370821, 0x1000000e, 0xac2281e0,
+0x3c010001, 0x370821, 0xac2081e0, 0x8ec20268, 0xaec00048, 0xaed1006c,
+0x24420001, 0xaec20268, 0x10000004, 0x8ec20268, 0x3c010001, 0x370821,
+0xac2081e0, 0x8ec20000, 0x3c03feff, 0x10400007, 0x3463ffff, 0xaf80004c,
+0x8f82004c, 0x1040fffd, 0x0, 0x10000005, 0x0, 0xaf800048,
+0x8f820048, 0x1040fffd, 0x0, 0x8f820060, 0x431024, 0xaf820060,
+0x8ec20000, 0x10400003, 0x0, 0x10000002, 0xaf80004c, 0xaf800048,
+0x8fbf0024, 0x8fb10020, 0x3e00008, 0x27bd0028, 0x3e00008, 0x0,
+0x3c020001, 0x8c4232bc, 0x27bdffc0, 0xafbf0038, 0xafbe0034, 0xafb50030,
+0xafb3002c, 0x104000fe, 0xafb10028, 0x8ec200b8, 0x24430001, 0x2842000b,
+0x1440011b, 0xaec300b8, 0xaec000b8, 0x8ee204a8, 0x30420002, 0x14400096,
+0x0, 0x8ee204a8, 0x3c030001, 0x8c6332ac, 0x34420002, 0xaee204a8,
+0x24020001, 0x14620003, 0x3c020600, 0x10000002, 0x34423000, 0x34421000,
+0xafa20020, 0x8ec3002c, 0x240200ff, 0x10620004, 0x27a70020, 0x8ec2002c,
+0x10000002, 0x24530001, 0x9821, 0x8f420228, 0x1662000f, 0x0,
+0x3c040001, 0x248426c8, 0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228,
+0x3c050009, 0xc0028eb, 0x34a5f00f, 0x8ec202a0, 0x24420001, 0xaec202a0,
+0x1000006d, 0x8ec202a0, 0x8ec2002c, 0x210c0, 0x571021, 0x8ce30000,
+0x8ce40004, 0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, 0x247103e8,
+0x2221023, 0x2c4203e9, 0x1040001e, 0xa821, 0x241e000c, 0x8ec8002c,
+0x8ee40428, 0x8ee5042c, 0x8ec6002c, 0x24070008, 0xafbe0010, 0xafb30014,
+0x840c0, 0x1001821, 0x1021, 0x8ec80008, 0xa32821, 0xa3482b,
+0x822021, 0x892021, 0x630c0, 0xafa80018, 0x8ec200a8, 0x24c604c0,
+0x40f809, 0x2e63021, 0x54400006, 0x24150001, 0x8f820054, 0x2221023,
+0x2c4203e9, 0x1440ffe5, 0x0, 0x32a200ff, 0x54400011, 0xaed3002c,
+0x3c040001, 0x248426d4, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
+0x3c050009, 0x10000030, 0x34a5f010, 0x8ec2026c, 0x24150001, 0x24420001,
+0xaec2026c, 0x8ec2026c, 0x1000001f, 0x32a200ff, 0x8f830054, 0x8f820054,
+0x247103e8, 0x2221023, 0x2c4203e9, 0x10400017, 0xa821, 0x3c1e0020,
+0x24130011, 0x8ec20008, 0x8ee40488, 0x8ee5048c, 0x8ec3002c, 0x8f860120,
+0xafb30010, 0x5e1025, 0xafa30014, 0xafa20018, 0x8ec200a8, 0x24070008,
+0x40f809, 0x24c6001c, 0x1440ffe2, 0x0, 0x8f820054, 0x2221023,
+0x2c4203e9, 0x1440ffed, 0x0, 0x32a200ff, 0x1440000f, 0x0,
+0x3c040001, 0x248426e0, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
+0x3c050009, 0x34a5f011, 0xc0028eb, 0x0, 0x8ec202d0, 0x24420001,
+0xaec202d0, 0x8ec202d0, 0x8ec20250, 0x24420001, 0xaec20250, 0x8ec20250,
+0x8ee204a8, 0x30420001, 0x10400054, 0x0, 0x8f420218, 0x30420080,
+0x1040002b, 0x0, 0x8f820044, 0x34420040, 0xaf820044, 0x8ec200b0,
+0x402821, 0x8ec201b8, 0x8ec301bc, 0x24060000, 0x2407ffff, 0x2021,
+0x461024, 0x1444000d, 0x671824, 0x1465000b, 0x0, 0x8ec200b4,
+0x402821, 0x8ec201d8, 0x8ec301dc, 0x2021, 0x461024, 0x14440003,
+0x671824, 0x1065000c, 0x0, 0x8ec201b8, 0x8ec301bc, 0x8ec401d8,
+0x8ec501dc, 0xaec300b0, 0xaec500b4, 0x8f820044, 0x38420020, 0xaf820044,
+0x10000056, 0x2402ff7f, 0x8f820044, 0x2403ffdf, 0x431024, 0xaf820044,
+0x10000050, 0x2402ff7f, 0x8f820044, 0x2403ffdf, 0x431024, 0xaf820044,
+0x8ec200b0, 0x402821, 0x8ec201b8, 0x8ec301bc, 0x24060000, 0x2407ffff,
+0x2021, 0x461024, 0x1444000d, 0x671824, 0x1465000b, 0x0,
+0x8ec200b4, 0x402821, 0x8ec201d8, 0x8ec301dc, 0x2021, 0x461024,
+0x14440003, 0x671824, 0x1065001f, 0x0, 0x8ec201b8, 0x8ec301bc,
+0x8ec401d8, 0x8ec501dc, 0xaec300b0, 0xaec500b4, 0x8f820044, 0x38420040,
+0xaf820044, 0x1000002b, 0x2402ff7f, 0x8f820044, 0x34420040, 0xaf820044,
+0x8ec200bc, 0x24430001, 0x1000001d, 0x28420033, 0x8ee204a8, 0x30420001,
+0x10400013, 0x0, 0x8f420218, 0x30420080, 0x1040000a, 0x0,
+0x8f820044, 0x2403ffdf, 0x431024, 0xaf820044, 0x8f820044, 0x34420040,
+0xaf820044, 0x10000013, 0x2402ff7f, 0x8f820044, 0x34420060, 0xaf820044,
+0x1000000e, 0x2402ff7f, 0x8f820044, 0x34420040, 0xaf820044, 0x8ec200bc,
+0x24430001, 0x284201f5, 0x14400005, 0xaec300bc, 0x8f820044, 0x38420020,
+0xaf820044, 0xaec000bc, 0x2402ff7f, 0x282a024, 0x8fbf0038, 0x8fbe0034,
+0x8fb50030, 0x8fb3002c, 0x8fb10028, 0x3e00008, 0x27bd0040, 0x3e00008,
+0x0, 0x3c020001, 0x8c4232bc, 0x27bdffc0, 0xafbf0038, 0xafbe0034,
+0xafb50030, 0xafb3002c, 0x10400100, 0xafb10028, 0x8ec200b8, 0x3c040001,
+0x8c8432ac, 0x24430001, 0x2842000b, 0xaec400d0, 0x14400127, 0xaec300b8,
+0xaec000b8, 0x8ee204a8, 0x30420002, 0x14400094, 0x0, 0x8ee204a8,
+0x34420002, 0xaee204a8, 0x24020001, 0x14820003, 0x3c020600, 0x10000002,
+0x34423000, 0x34421000, 0xafa20020, 0x8ec3002c, 0x240200ff, 0x10620004,
+0x27a70020, 0x8ec2002c, 0x10000002, 0x24530001, 0x9821, 0x8f420228,
+0x1662000f, 0x0, 0x3c040001, 0x248426c8, 0xafa00010, 0xafa00014,
+0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f00f, 0x8ec202a0,
+0x24420001, 0xaec202a0, 0x1000006d, 0x8ec202a0, 0x8ec2002c, 0x210c0,
+0x571021, 0x8ce30000, 0x8ce40004, 0xac4304c0, 0xac4404c4, 0x8f830054,
+0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, 0x1040001e, 0xa821,
+0x241e000c, 0x8ec8002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c, 0x24070008,
+0xafbe0010, 0xafb30014, 0x840c0, 0x1001821, 0x1021, 0x8ec80008,
+0xa32821, 0xa3482b, 0x822021, 0x892021, 0x630c0, 0xafa80018,
+0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021, 0x54400006, 0x24150001,
+0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffe5, 0x0, 0x32a200ff,
+0x54400011, 0xaed3002c, 0x3c040001, 0x248426d4, 0xafa00010, 0xafa00014,
+0x8f860120, 0x8f870124, 0x3c050009, 0x10000030, 0x34a5f010, 0x8ec2026c,
+0x24150001, 0x24420001, 0xaec2026c, 0x8ec2026c, 0x1000001f, 0x32a200ff,
+0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, 0x10400017,
+0xa821, 0x3c1e0020, 0x24130011, 0x8ec20008, 0x8ee40488, 0x8ee5048c,
+0x8ec3002c, 0x8f860120, 0xafb30010, 0x5e1025, 0xafa30014, 0xafa20018,
+0x8ec200a8, 0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe2, 0x0,
+0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffed, 0x0, 0x32a200ff,
+0x1440000f, 0x0, 0x3c040001, 0x248426e0, 0xafa00010, 0xafa00014,
+0x8f860120, 0x8f870124, 0x3c050009, 0x34a5f011, 0xc0028eb, 0x0,
+0x8ec202d0, 0x24420001, 0xaec202d0, 0x8ec202d0, 0x8ec20250, 0x24420001,
+0xaec20250, 0x8ec20250, 0x8ee204a8, 0x30420001, 0x10400055, 0x0,
+0x8f420218, 0x30420080, 0x10400027, 0x0, 0x8ec200b0, 0x3c040001,
+0x90843370, 0x24080000, 0x2409ffff, 0x403821, 0x8ec201b8, 0x8ec301bc,
+0x3021, 0x34840020, 0x3c010001, 0xa0243370, 0x481024, 0x1446000d,
+0x691824, 0x1467000b, 0x0, 0x8ec200b4, 0x403821, 0x8ec201d8,
+0x8ec301dc, 0x3021, 0x481024, 0x14460003, 0x691824, 0x10670009,
+0x308200bf, 0x8ec201b8, 0x8ec301bc, 0x3c040001, 0x90843370, 0x8ec601d8,
+0x8ec701dc, 0x10000026, 0x38840040, 0x3c010001, 0x10000061, 0xa0223370,
+0x8ec200b0, 0x3c040001, 0x90843370, 0x24080000, 0x2409ffff, 0x403821,
+0x8ec201b8, 0x8ec301bc, 0x3021, 0x308400bf, 0x3c010001, 0xa0243370,
+0x481024, 0x1446000d, 0x691824, 0x1467000b, 0x0, 0x8ec200b4,
+0x403821, 0x8ec201d8, 0x8ec301dc, 0x3021, 0x481024, 0x14460003,
+0x691824, 0x1067000d, 0x34820020, 0x8ec201b8, 0x8ec301bc, 0x3c040001,
+0x90843370, 0x8ec601d8, 0x8ec701dc, 0x38840020, 0xaec300b0, 0xaec700b4,
+0x3c010001, 0x1000003a, 0xa0243370, 0x3c010001, 0x10000037, 0xa0223370,
+0x3c020001, 0x90423370, 0x8ec300bc, 0x34440020, 0x24620001, 0x10000028,
+0x28630033, 0x8ec200cc, 0x8ec300c8, 0x24420001, 0xaec200cc, 0x43102a,
+0x14400006, 0x24030001, 0x8ec200d0, 0x14430002, 0xaec000cc, 0x24030004,
+0xaec300d0, 0x8ee204a8, 0x30420001, 0x10400012, 0x0, 0x8f420218,
+0x30420080, 0x10400008, 0x0, 0x3c020001, 0x90423370, 0x34420040,
+0x304200df, 0x3c010001, 0x10000015, 0xa0223370, 0x3c020001, 0x90423370,
+0x34420060, 0x3c010001, 0x1000000f, 0xa0223370, 0x3c020001, 0x90423370,
+0x8ec300bc, 0x34440020, 0x24620001, 0x286300fb, 0x3c010001, 0xa0243370,
+0x14600005, 0xaec200bc, 0x38820040, 0x3c010001, 0xa0223370, 0xaec000bc,
+0x3c020001, 0x90423370, 0x8ec300d0, 0x3044007f, 0x24020001, 0x3c010001,
+0xa0243370, 0x54620003, 0x3484000f, 0x42102, 0x348400f0, 0xc004904,
+0x0, 0x2402ff7f, 0x282a024, 0x8fbf0038, 0x8fbe0034, 0x8fb50030,
+0x8fb3002c, 0x8fb10028, 0x3e00008, 0x27bd0040, 0x3e00008, 0x0,
+0x27bdffc0, 0xafbf0038, 0xafbe0034, 0xafb50030, 0xafb3002c, 0xafb10028,
+0x92c20528, 0x144001bc, 0x26c50128, 0x26e40028, 0x240300ff, 0x2406ffff,
+0x8ca20000, 0x24a50004, 0x2463ffff, 0xac820000, 0x1466fffb, 0x24840004,
+0x8f420080, 0xaee20044, 0x8f4200c0, 0xaee20040, 0x8f420084, 0xaee20030,
+0x8f420084, 0xaee2022c, 0x8f420088, 0xaee20230, 0x8f42008c, 0xaee20234,
+0x8f420090, 0xaee20238, 0x8f420094, 0xaee2023c, 0x8f420098, 0xaee20240,
+0x8f42009c, 0xaee20244, 0x8f4200a0, 0xaee20248, 0x8f4200a4, 0xaee2024c,
+0x8f4200a8, 0xaee20250, 0x8f4200ac, 0xaee20254, 0x8f4200b0, 0xaee20258,
+0x8f4200b4, 0xaee2025c, 0x8f4200b8, 0xaee20260, 0x8f4200bc, 0x24040001,
+0xaee20264, 0xaee00034, 0x41080, 0x571021, 0x8ee30034, 0x8c42022c,
+0x24840001, 0x621821, 0x2c82000f, 0xaee30034, 0x1440fff8, 0x41080,
+0x8f4200cc, 0xaee20048, 0x8f4200d0, 0xaee2004c, 0x8f4200e0, 0xaee201e8,
+0x8f4200e4, 0xaee201ec, 0x8f4200e8, 0xaee201f0, 0x8f4200ec, 0xaee201f4,
+0x8f4200f0, 0xaee201f8, 0x8f4200fc, 0x402821, 0x8ee200c0, 0x2021,
+0x82102b, 0x1440000a, 0x0, 0x8ee200c0, 0x14440011, 0x0,
+0x8ee200c4, 0xa2102b, 0x14400003, 0x0, 0x1000000b, 0x8ee200c4,
+0x8ee200c0, 0x8ee300c4, 0x24040001, 0x24050000, 0x651821, 0x65302b,
+0x441021, 0x461021, 0xaee200c0, 0xaee300c4, 0x8f4200fc, 0x8ee400c0,
+0x8ee500c4, 0x2406ffff, 0x24070000, 0x401821, 0x1021, 0x862024,
+0xa72824, 0x822025, 0xa32825, 0xaee400c0, 0xaee500c4, 0x8f4200f4,
+0x402821, 0x8ee200d0, 0x2021, 0x82102b, 0x1440000a, 0x0,
+0x8ee200d0, 0x14440011, 0x0, 0x8ee200d4, 0xa2102b, 0x14400003,
+0x0, 0x1000000b, 0x8ee200d4, 0x8ee200d0, 0x8ee300d4, 0x24040001,
+0x24050000, 0x651821, 0x65302b, 0x441021, 0x461021, 0xaee200d0,
+0xaee300d4, 0x8f4200f4, 0x8ee400d0, 0x8ee500d4, 0x2406ffff, 0x24070000,
+0x401821, 0x1021, 0x862024, 0xa72824, 0x822025, 0xa32825,
+0xaee400d0, 0xaee500d4, 0x8f4200f8, 0x402821, 0x8ee200c8, 0x2021,
+0x82102b, 0x1440000a, 0x0, 0x8ee200c8, 0x14440011, 0x0,
+0x8ee200cc, 0xa2102b, 0x14400003, 0x0, 0x1000000b, 0x8ee200cc,
+0x8ee200c8, 0x8ee300cc, 0x24040001, 0x24050000, 0x651821, 0x65302b,
+0x441021, 0x461021, 0xaee200c8, 0xaee300cc, 0x8f4200f8, 0x8ee400c8,
+0x8ee500cc, 0x2406ffff, 0x24070000, 0x401821, 0x1021, 0x862024,
+0xa72824, 0x822025, 0xa32825, 0xaee400c8, 0xaee500cc, 0x8f440208,
+0x8f45020c, 0x2402000f, 0xafa20010, 0xafa00014, 0x8ec20008, 0xafa20018,
+0x8ec200a8, 0x26e60028, 0x40f809, 0x24070400, 0x104000f1, 0x3c020400,
+0xafa20020, 0x92c20115, 0x10400080, 0x240200ff, 0x8ec3002c, 0x10620004,
+0x27a70020, 0x8ec2002c, 0x10000002, 0x24530001, 0x9821, 0x8f420228,
+0x1662000a, 0x0, 0x3c040001, 0x248426c8, 0xafa00010, 0xafa00014,
+0x8ec6002c, 0x8f470228, 0x3c050009, 0x1000007f, 0x34a5f00f, 0x8ec2002c,
+0x210c0, 0x571021, 0x8ce30000, 0x8ce40004, 0xac4304c0, 0xac4404c4,
+0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, 0x1040001e,
+0xa821, 0x241e000d, 0x8ec8002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c,
+0x24070008, 0xafbe0010, 0xafb30014, 0x840c0, 0x1001821, 0x1021,
+0x8ec80008, 0xa32821, 0xa3482b, 0x822021, 0x892021, 0x630c0,
+0xafa80018, 0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021, 0x54400006,
+0x24150001, 0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffe5, 0x0,
+0x32a200ff, 0x54400018, 0xaed3002c, 0x3c040001, 0x248426d4, 0xafa00010,
+0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0x34a5f010, 0xc0028eb,
+0x0, 0x8ec202d0, 0x1821, 0x24420001, 0xaec202d0, 0x1000008f,
+0x8ec202d0, 0x8ec2026c, 0x24150001, 0x24420001, 0xaec2026c, 0x8ec2026c,
+0x1000001d, 0x32a200ff, 0x8f830054, 0x8f820054, 0x247103e8, 0x2221023,
+0x2c4203e9, 0x10400015, 0xa821, 0x24130011, 0x8ec30008, 0x8ee40488,
+0x8ee5048c, 0x8ec2002c, 0x8f860120, 0xafb30010, 0xafa20014, 0xafa30018,
+0x8ec200a8, 0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe4, 0x0,
+0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffee, 0x0, 0x32a200ff,
+0x1440006a, 0x24030001, 0x3c040001, 0x248426e0, 0xafa00010, 0xafa00014,
+0x8f860120, 0x8f870124, 0x3c050009, 0x1000ffcb, 0x34a5f011, 0x8ec3002c,
+0x10620004, 0x27a70020, 0x8ec2002c, 0x10000002, 0x24510001, 0x8821,
+0x8f420228, 0x16220011, 0x4021, 0x3c040001, 0x248426a8, 0xafa00010,
+0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0x34a5f005, 0xc0028eb,
+0x0, 0x8ec202a0, 0x1821, 0x24420001, 0xaec202a0, 0x10000047,
+0x8ec202a0, 0x8ec2002c, 0x210c0, 0x571021, 0x8ce30000, 0x8ce40004,
+0xac4304c0, 0xac4404c4, 0x8ec3002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c,
+0x24070008, 0x2402000d, 0xafa20010, 0xafb10014, 0x8ec20008, 0x318c0,
+0x604821, 0xa92821, 0xa9182b, 0x882021, 0x832021, 0x630c0,
+0xafa20018, 0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021, 0x5440000c,
+0xaed1002c, 0x3c040001, 0x248426b4, 0xafa00010, 0xafa00014, 0x8ec6002c,
+0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f000, 0x1000001e, 0x1821,
+0x8ee40488, 0x8ee5048c, 0x8ec3002c, 0x8ec80008, 0x8f860120, 0x24020011,
+0xafa20010, 0xafa30014, 0xafa80018, 0x8ec200a8, 0x24070008, 0x40f809,
+0x24c6001c, 0x1440000f, 0x24030001, 0x3c040001, 0x248426bc, 0xafa00010,
+0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f001,
+0x8ec202a4, 0x1821, 0x24420001, 0xaec202a4, 0x8ec202a4, 0x1060000d,
+0x24020001, 0x8ec2024c, 0xa2c00115, 0xaec000a0, 0x24420001, 0xaec2024c,
+0x8ec2024c, 0x8ee2014c, 0x24420001, 0xaee2014c, 0x10000003, 0x8ee2014c,
+0x24020001, 0xa2c20115, 0x8fbf0038, 0x8fbe0034, 0x8fb50030, 0x8fb3002c,
+0x8fb10028, 0x3e00008, 0x27bd0040, 0x27bdffd8, 0xafbf0020, 0x8f8200b0,
+0x30420004, 0x1040005e, 0x0, 0x8ec30104, 0x8f820104, 0x14620005,
+0x0, 0x8ec3010c, 0x8f8200b4, 0x10620006, 0x0, 0x8f820104,
+0xaec20104, 0x8f8200b4, 0x10000051, 0xaec2010c, 0x8f8200b0, 0x3c030080,
+0x431024, 0x1040000d, 0x0, 0x8f82011c, 0x34420002, 0xaf82011c,
+0x8f8200b0, 0x2403fffb, 0x431024, 0xaf8200b0, 0x8f82011c, 0x2403fffd,
+0x431024, 0x10000040, 0xaf82011c, 0x8ec30104, 0x8f820104, 0x14620005,
+0x0, 0x8ec3010c, 0x8f8200b4, 0x5062000a, 0x3c050005, 0x8f820104,
+0xaec20104, 0x8f8200b4, 0xaec2010c, 0x8ec2010c, 0x3c040001, 0x248426ec,
+0x10000029, 0xafa00014, 0x8ec2010c, 0x3c040001, 0x248426f8, 0xafa00014,
+0xafa20010, 0x8f8600b0, 0x8ec70104, 0xc0028eb, 0x34a50900, 0x8f82011c,
+0x34420002, 0xaf82011c, 0x8f830104, 0x8f8200b0, 0x34420001, 0xaf8200b0,
+0xaf830104, 0x8f440208, 0x8f45020c, 0x2402000f, 0xafa20010, 0xafa00014,
+0x8ec20008, 0xafa20018, 0x8ec200a8, 0x26e60028, 0x40f809, 0x24070400,
+0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, 0x8ee201cc, 0x24420001,
+0xaee201cc, 0x8ee201cc, 0x8ec2010c, 0x3c040001, 0x24842704, 0xafa00014,
+0xafa20010, 0x8f8600b0, 0x8ec70104, 0x3c050005, 0xc0028eb, 0x34a50900,
+0x8f8200a0, 0x30420004, 0x1040005f, 0x0, 0x8ec30108, 0x8f820124,
+0x14620005, 0x0, 0x8ec30110, 0x8f8200a4, 0x10620006, 0x0,
+0x8f820124, 0xaec20108, 0x8f8200a4, 0x10000052, 0xaec20110, 0x8f8200a0,
+0x3c030080, 0x431024, 0x1040000d, 0x0, 0x8f82011c, 0x34420002,
+0xaf82011c, 0x8f8200a0, 0x2403fffb, 0x431024, 0xaf8200a0, 0x8f82011c,
+0x2403fffd, 0x431024, 0x10000041, 0xaf82011c, 0x8ec30108, 0x8f820124,
+0x14620005, 0x0, 0x8ec30110, 0x8f8200a4, 0x5062000a, 0x3c050005,
+0x8f820124, 0xaec20108, 0x8f8200a4, 0xaec20110, 0x8ec20110, 0x3c040001,
+0x24842710, 0x1000002a, 0xafa00014, 0x8ec20110, 0x3c040001, 0x2484271c,
+0xafa00014, 0xafa20010, 0x8f8600a0, 0x8ec70108, 0xc0028eb, 0x34a50900,
+0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830124, 0x8f8200a0, 0x34420001,
+0xaf8200a0, 0xaf830124, 0x8f440208, 0x8f45020c, 0x24020010, 0xafa20010,
+0xafa00014, 0x8ec20010, 0xafa20018, 0x8ec200a4, 0x3c060001, 0x24c63384,
+0x40f809, 0x24070004, 0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c,
+0x8ee201cc, 0x24420001, 0xaee201cc, 0x8ee201cc, 0x8ec20110, 0x3c040001,
+0x24842728, 0xafa00014, 0xafa20010, 0x8f8600a0, 0x8ec70108, 0x3c050005,
+0xc0028eb, 0x34a50900, 0x8fbf0020, 0x3e00008, 0x27bd0028, 0x3c091000,
+0x24080001, 0x3c070080, 0x3c050100, 0x3c062000, 0x8f820070, 0x491024,
+0x1040fffd, 0x0, 0x8f820054, 0x24420005, 0xaf820078, 0x8f420234,
+0x10400017, 0x2021, 0x3c020001, 0x571021, 0x8c4281dc, 0x24420005,
+0x3c010001, 0x370821, 0xac2281dc, 0x3c020001, 0x571021, 0x8c4281dc,
+0x8f430234, 0x43102b, 0x14400009, 0x0, 0x3c040080, 0x3c010001,
+0x370821, 0xac2881d4, 0x3c010001, 0x370821, 0x1000000b, 0xac2081dc,
+0x3c020001, 0x571021, 0x8c4281d4, 0x54400006, 0x872025, 0x3c020001,
+0x571021, 0x8c4281d8, 0x54400001, 0x872025, 0x8f420230, 0x10400014,
+0x0, 0x3c020001, 0x571021, 0x8c4281e4, 0x24420005, 0x3c010001,
+0x370821, 0xac2281e4, 0x3c020001, 0x571021, 0x8c4281e4, 0x8f430230,
+0x43102b, 0x14400006, 0x0, 0x3c010001, 0x370821, 0xac2081e4,
+0x10000006, 0x852025, 0x3c020001, 0x571021, 0x8c4281e0, 0x54400001,
+0x852025, 0x3c020001, 0x571021, 0x8c4281e8, 0x10400005, 0x0,
+0x862025, 0x3c010001, 0x370821, 0xac2081e8, 0x1080ffb1, 0x0,
+0x8ec20000, 0x10400007, 0x0, 0xaf80004c, 0x8f82004c, 0x1040fffd,
+0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
+0x0, 0x8f820060, 0x441025, 0xaf820060, 0x8ec20000, 0x10400003,
+0x0, 0x1000ff9c, 0xaf80004c, 0x1000ff9a, 0xaf800048, 0x3e00008,
+0x0, 0x0, 0x0, 0x0, 0x27bdffe0, 0xafbf0018,
+0x8f860064, 0x30c20004, 0x1040001e, 0x24020004, 0xaf820064, 0x8f420114,
+0x8ec30000, 0x10600007, 0xaec20014, 0xaf80004c, 0x8f82004c, 0x1040fffd,
+0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
+0x0, 0x8f820060, 0x34420008, 0xaf820060, 0x8ec20000, 0x10400003,
+0x0, 0x10000002, 0xaf80004c, 0xaf800048, 0x8ec20260, 0x24420001,
+0xaec20260, 0x1000006f, 0x8ec20260, 0x30c20001, 0x10400004, 0x24020001,
+0xaf820064, 0x10000069, 0x0, 0x30c20002, 0x1440000b, 0x3c050003,
+0x3c040001, 0x24842800, 0x34a50001, 0x3821, 0xafa00010, 0xc0028eb,
+0xafa00014, 0x2402fff8, 0x1000005c, 0xaf820064, 0x8f43022c, 0x8f42010c,
+0x1062004c, 0x0, 0x8f42022c, 0x21080, 0x5a1021, 0x8c440300,
+0x8f42022c, 0x24420001, 0x3042003f, 0x41e02, 0xaf42022c, 0x24020003,
+0x10620005, 0x24020010, 0x1062001f, 0x30830fff, 0x1000003a, 0x0,
+0x8ec30000, 0x30820fff, 0x10600007, 0xaec20038, 0xaf80004c, 0x8f82004c,
+0x1040fffd, 0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048,
+0x1040fffd, 0x0, 0x8f820060, 0x34420200, 0xaf820060, 0x8ec20000,
+0x10400003, 0x0, 0x10000002, 0xaf80004c, 0xaf800048, 0x8ec20210,
+0x24420001, 0xaec20210, 0x10000020, 0x8ec20210, 0x8ec20000, 0xaec30054,
+0x24030001, 0x10400007, 0xa2c30065, 0xaf80004c, 0x8f82004c, 0x1040fffd,
+0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
+0x0, 0x8f820060, 0x34420100, 0xaf820060, 0x8ec20000, 0x10400003,
+0x0, 0x10000002, 0xaf80004c, 0xaf800048, 0x8ec2023c, 0x24420001,
+0xaec2023c, 0x10000003, 0x8ec2023c, 0xc001fd6, 0x0, 0x8f43022c,
+0x8f42010c, 0x14620002, 0x24020002, 0xaf820064, 0x8f820064, 0x14400005,
+0x0, 0x8f43022c, 0x8f42010c, 0x1462ffa6, 0x0, 0x8fbf0018,
+0x3e00008, 0x27bd0020, 0x3e00008, 0x0, 0x27bdffc0, 0xafb10028,
+0x808821, 0x111602, 0x2442ffff, 0x304300ff, 0x2c620011, 0xafbf0038,
+0xafbe0034, 0xafb50030, 0x104001ab, 0xafb3002c, 0x31080, 0x3c010001,
+0x220821, 0x8c222848, 0x400008, 0x0, 0x111302, 0x30440fff,
+0x24020001, 0x10820006, 0x3c030800, 0x24020002, 0x1082000c, 0x3c050003,
+0x10000022, 0x0, 0x3c020001, 0x8c4233b4, 0x21100, 0x21182,
+0x431025, 0xae420038, 0x8ee204a8, 0x1000000a, 0x34420001, 0x3c020001,
+0x2442c440, 0x21100, 0x21182, 0x431025, 0xae420038, 0x8ee204a8,
+0x2403fffe, 0x431024, 0xaee204a8, 0xaec40168, 0xaec4016c, 0x8f840054,
+0x41442, 0x41c82, 0x431021, 0x41cc2, 0x431023, 0x41d02,
+0x431021, 0x41d42, 0x431023, 0x10000009, 0xaec20170, 0x3c040001,
+0x2484280c, 0x34a50004, 0x2203021, 0x3821, 0xafa00010, 0xc0028eb,
+0xafa00014, 0x8ec20208, 0x24420001, 0xaec20208, 0x100001e1, 0x8ec20208,
+0xc0022fe, 0x0, 0x100001dd, 0x0, 0xc002419, 0x0,
+0x100001d9, 0x0, 0x111302, 0x30430fff, 0x24020001, 0x10620005,
+0x24020002, 0x10620016, 0x3c050003, 0x10000021, 0x0, 0x92c2011c,
+0x1440000f, 0x24020001, 0x8f820228, 0xaee204ac, 0x8f82022c, 0xaee204b0,
+0x8f820230, 0xaee204b4, 0x8f820234, 0xaee204b8, 0x2402ffff, 0xaf820228,
+0xaf82022c, 0xaf820230, 0xaf820234, 0x24020001, 0x10000016, 0xa2c2011c,
+0x92c2011c, 0x50400013, 0xa2c0011c, 0x8ee204ac, 0xaf820228, 0x8ee204b0,
+0xaf82022c, 0x8ee204b4, 0xaf820230, 0x8ee204b8, 0xaf820234, 0x10000009,
+0xa2c0011c, 0x3c040001, 0x24842818, 0x34a5f009, 0x2203021, 0x3821,
+0xafa00010, 0xc0028eb, 0xafa00014, 0x8ec20234, 0x24420001, 0xaec20234,
+0x100001a3, 0x8ec20234, 0x111302, 0x30440fff, 0x24020001, 0x10820005,
+0x24020002, 0x1082000d, 0x3c050003, 0x10000013, 0x0, 0x8f820220,
+0x3c0308ff, 0x3463ffff, 0x431024, 0x34420008, 0xaf820220, 0x24020001,
+0xa2c2011d, 0x10000011, 0xaec40200, 0x8f820220, 0x3c0308ff, 0x3463fff7,
+0x431024, 0xaf820220, 0xa2c0011d, 0x10000009, 0xaec40200, 0x3c040001,
+0x24842824, 0x34a5f00a, 0x2203021, 0x3821, 0xafa00010, 0xc0028eb,
+0xafa00014, 0x8ec20224, 0x24420001, 0xaec20224, 0x1000017b, 0x8ec20224,
+0x27840208, 0x27450200, 0xc00297e, 0x24060008, 0x26c4018c, 0x27450200,
+0xc00297e, 0x24060008, 0x8ec2022c, 0x24420001, 0xaec2022c, 0x1000016e,
+0x8ec2022c, 0x111302, 0x30430fff, 0x24020001, 0x10620011, 0x28620002,
+0x50400005, 0x24020002, 0x10600007, 0x0, 0x10000017, 0x0,
+0x1062000f, 0x0, 0x10000013, 0x0, 0x8f460248, 0x24040001,
+0xc004680, 0x24050004, 0x10000007, 0x0, 0x8f460248, 0x24040001,
+0xc004680, 0x24050004, 0x10000010, 0x0, 0x8f46024c, 0x24040001,
+0xc004680, 0x24050001, 0x1000000a, 0x0, 0x3c040001, 0x24842830,
+0x3c050003, 0x34a50005, 0x2203021, 0x3821, 0xafa00010, 0xc0028eb,
+0xafa00014, 0x8ec20228, 0x24420001, 0xaec20228, 0x1000013f, 0x8ec20228,
+0xc002221, 0x0, 0x1000013b, 0x0, 0x24020001, 0xa2c20528,
+0x24110014, 0x8ee404a0, 0x8ee504a4, 0xafb10010, 0xafa00014, 0x8ec20010,
+0xafa20018, 0x8ec200a4, 0x26e60028, 0x40f809, 0x24070400, 0x1040fff5,
+0x0, 0x1000012a, 0x0, 0x3c020900, 0xaec00054, 0xaec00058,
+0xaec0005c, 0xaec00060, 0xaec002c0, 0xa2c00065, 0xafa20020, 0x8ec3002c,
+0x240200ff, 0x10620004, 0x27a70020, 0x8ec2002c, 0x10000002, 0x24530001,
+0x9821, 0x8f420228, 0x1662000f, 0x0, 0x3c040001, 0x248427dc,
+0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb,
+0x34a5f00f, 0x8ec202a0, 0x24420001, 0xaec202a0, 0x1000006b, 0x8ec202a0,
+0x8ec2002c, 0x210c0, 0x571021, 0x8ce30000, 0x8ce40004, 0xac4304c0,
+0xac4404c4, 0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9,
+0x1040001e, 0xa821, 0x241e000d, 0x8ec8002c, 0x8ee40428, 0x8ee5042c,
+0x8ec6002c, 0x24070008, 0xafbe0010, 0xafb30014, 0x840c0, 0x1001821,
+0x1021, 0x8ec80008, 0xa32821, 0xa3482b, 0x822021, 0x892021,
+0x630c0, 0xafa80018, 0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021,
+0x54400006, 0x24150001, 0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffe5,
+0x0, 0x32a200ff, 0x54400011, 0xaed3002c, 0x3c040001, 0x248427e8,
+0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0x1000002e,
+0x34a5f010, 0x8ec2026c, 0x24150001, 0x24420001, 0xaec2026c, 0x8ec2026c,
+0x1000001d, 0x32a200ff, 0x8f830054, 0x8f820054, 0x247103e8, 0x2221023,
+0x2c4203e9, 0x10400015, 0xa821, 0x24130011, 0x8ec30008, 0x8ee40488,
+0x8ee5048c, 0x8ec2002c, 0x8f860120, 0xafb30010, 0xafa20014, 0xafa30018,
+0x8ec200a8, 0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe4, 0x0,
+0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffee, 0x0, 0x32a200ff,
+0x1440000f, 0x0, 0x3c040001, 0x248427f4, 0xafa00010, 0xafa00014,
+0x8f860120, 0x8f870124, 0x3c050009, 0x34a5f011, 0xc0028eb, 0x0,
+0x8ec202d0, 0x24420001, 0xaec202d0, 0x8ec202d0, 0x8ec20218, 0x24420001,
+0xaec20218, 0x8ec20218, 0x8ec2025c, 0x24420001, 0xaec2025c, 0x10000096,
+0x8ec2025c, 0x8f42025c, 0x26c4018c, 0xaec20158, 0x8f420260, 0x27450200,
+0x24060008, 0xc00297e, 0xaec20160, 0x8f820220, 0x30420008, 0x14400002,
+0x24020001, 0x24020002, 0xaec20200, 0x8ec20214, 0x24420001, 0xaec20214,
+0x10000083, 0x8ec20214, 0x3c0200ff, 0x96e30462, 0x3442ffff, 0x2222024,
+0x3402fffb, 0x44102b, 0x38420001, 0x30630003, 0x2c630001, 0x621824,
+0x10600003, 0x0, 0x10000075, 0xaec40050, 0x3c040001, 0x2484283c,
+0x3c050003, 0x34a5f00f, 0x2203021, 0x3821, 0xafa00010, 0xc0028eb,
+0xafa00014, 0x3c030700, 0x34631000, 0x111602, 0x431025, 0xafa20020,
+0x8ec3002c, 0x240200ff, 0x10620004, 0x27a70020, 0x8ec2002c, 0x10000002,
+0x24510001, 0x8821, 0x8f420228, 0x1622000f, 0x4021, 0x3c040001,
+0x248427bc, 0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009,
+0xc0028eb, 0x34a5f005, 0x8ec202a0, 0x24420001, 0xaec202a0, 0x10000046,
+0x8ec202a0, 0x8ec2002c, 0x210c0, 0x571021, 0x8ce30000, 0x8ce40004,
+0xac4304c0, 0xac4404c4, 0x8ec3002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c,
+0x24070008, 0x2402000d, 0xafa20010, 0xafb10014, 0x8ec20008, 0x318c0,
+0x604821, 0xa92821, 0xa9182b, 0x882021, 0x832021, 0x630c0,
+0xafa20018, 0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021, 0x5440000c,
+0xaed1002c, 0x3c040001, 0x248427c8, 0xafa00010, 0xafa00014, 0x8ec6002c,
+0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f000, 0x1000001d, 0x0,
+0x8ee40488, 0x8ee5048c, 0x8ec3002c, 0x8ec80008, 0x8f860120, 0x24020011,
+0xafa20010, 0xafa30014, 0xafa80018, 0x8ec200a8, 0x24070008, 0x40f809,
+0x24c6001c, 0x1440000e, 0x0, 0x3c040001, 0x248427d0, 0xafa00010,
+0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f001,
+0x8ec202a4, 0x24420001, 0xaec202a4, 0x8ec202a4, 0x8ec20244, 0x24420001,
+0xaec20244, 0x8ec20244, 0x8ec20254, 0x24420001, 0xaec20254, 0x8ec20254,
+0x8fbf0038, 0x8fbe0034, 0x8fb50030, 0x8fb3002c, 0x8fb10028, 0x3e00008,
+0x27bd0040, 0x27bdfff8, 0x2408ffff, 0x10a00014, 0x4821, 0x3c0aedb8,
+0x354a8320, 0x90870000, 0x24840001, 0x3021, 0x1071026, 0x30420001,
+0x10400002, 0x81842, 0x6a1826, 0x604021, 0x24c60001, 0x2cc20008,
+0x1440fff7, 0x73842, 0x25290001, 0x125102b, 0x1440fff0, 0x0,
+0x1001021, 0x3e00008, 0x27bd0008, 0x27bdffb8, 0xafbf0040, 0xafbe003c,
+0xafb50038, 0xafb30034, 0xafb10030, 0x8f870220, 0xafa70024, 0x8f870200,
+0xafa7002c, 0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420004,
+0xaf820220, 0x8f820200, 0x3c03c0ff, 0x3463ffff, 0x431024, 0x34420004,
+0xaf820200, 0x8ede02bc, 0x8ec702c0, 0xafa70014, 0x8ec702c4, 0xafa7001c,
+0x8ec20238, 0x26c40128, 0x24420001, 0xaec20238, 0x8ed10238, 0x8ed3016c,
+0x8ed50168, 0xc00296c, 0x24050400, 0xaede02bc, 0x8fa70014, 0xaec702c0,
+0x8fa7001c, 0xaec702c4, 0xaed10238, 0xaed3016c, 0xaed50168, 0x8f42025c,
+0x26c4018c, 0xaec20158, 0x8f420260, 0x27450200, 0x24060008, 0xaec20160,
+0x24020006, 0xc00297e, 0xaec2015c, 0x3c023b9a, 0x3442ca00, 0xaec20164,
+0x240203e8, 0x24040002, 0x24030001, 0xaec201fc, 0xaec401f8, 0xaec30204,
+0x8f820220, 0x30420008, 0x10400004, 0x0, 0xaec30200, 0x10000003,
+0x3021, 0xaec40200, 0x3021, 0x3c030001, 0x661821, 0x90633200,
+0x2c61021, 0x24c60001, 0xa0430194, 0x2cc2000f, 0x1440fff8, 0x2c61821,
+0x24c60001, 0x8f820040, 0x27440080, 0x24050080, 0x21702, 0x24420030,
+0xa0620194, 0x2c61021, 0xc00296c, 0xa0400194, 0x8fa70024, 0x30e20004,
+0x14400006, 0x0, 0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024,
+0xaf820220, 0x8fa7002c, 0x30e20004, 0x14400006, 0x0, 0x8f820200,
+0x3c03c0ff, 0x3463fffb, 0x431024, 0xaf820200, 0x8fbf0040, 0x8fbe003c,
+0x8fb50038, 0x8fb30034, 0x8fb10030, 0x3e00008, 0x27bd0048, 0x0,
+0x0, 0x0, 0x24040001, 0xa2c0011d, 0xa2c0011c, 0xaec00120,
+0x410c0, 0x2e21821, 0x24820001, 0xa46275c0, 0x402021, 0x2c820080,
+0x1440fffa, 0x410c0, 0x24020001, 0xa6e079c0, 0xaec20124, 0xaf800228,
+0xaf80022c, 0xaf800230, 0xaf800234, 0x3e00008, 0x0, 0x27bdffe0,
+0xafbf001c, 0xafb10018, 0x8ec20120, 0x28420005, 0x10400021, 0x808821,
+0x8ec20120, 0x3021, 0x18400015, 0x26e371c0, 0x96270000, 0x24640006,
+0x9482fffc, 0x14470009, 0x2821, 0x9483fffe, 0x96220002, 0x14620006,
+0xa01021, 0x94820000, 0x96230004, 0x431026, 0x2c450001, 0xa01021,
+0x1440000b, 0x24c60001, 0x8ec20120, 0xc2102a, 0x1440ffef, 0x24840008,
+0x1021, 0x304200ff, 0x14400029, 0x24020001, 0x10000027, 0x1021,
+0x1000fffa, 0x24020001, 0x2202021, 0xc002207, 0x24050006, 0x3042007f,
+0x218c0, 0x2e31021, 0x944271c0, 0x1040fff4, 0x2e31021, 0x944671c0,
+0x10c00019, 0x1021, 0x96270000, 0x610c0, 0x572021, 0x248475c2,
+0x94820000, 0x14470009, 0x2821, 0x94830002, 0x96220002, 0x14620006,
+0xa01021, 0x94820004, 0x96230004, 0x431026, 0x2c450001, 0xa01021,
+0x14400005, 0x610c0, 0x2e21021, 0x944675c0, 0x14c0ffed, 0x610c0,
+0x10c0ffd9, 0x24020001, 0x8fbf001c, 0x8fb10018, 0x3e00008, 0x27bd0020,
+0x3e00008, 0x0, 0x27bdffc0, 0x27440212, 0x24050006, 0xafbf0038,
+0xafbe0034, 0xafb50030, 0xafb3002c, 0xc002207, 0xafb10028, 0x3048007f,
+0x810c0, 0x2e21021, 0x944571c0, 0x10a00017, 0x27470212, 0x94e90000,
+0x510c0, 0x572021, 0x248475c2, 0x94820000, 0x14490009, 0x3021,
+0x94830002, 0x94e20002, 0x14620006, 0xc01021, 0x94820004, 0x94e30004,
+0x431026, 0x2c460001, 0xc01021, 0x14400005, 0x510c0, 0x2e21021,
+0x944575c0, 0x14a0ffed, 0x510c0, 0xa03021, 0x10c00010, 0x610c0,
+0x571821, 0x8c6375c0, 0x571021, 0xafa30010, 0x8c4275c4, 0x3c040001,
+0x2484294c, 0xafa20014, 0x8f460210, 0x8f470214, 0x3c050003, 0xc0028eb,
+0x34a5f012, 0x10000051, 0x3c020800, 0x8ec50124, 0x10a00004, 0x510c0,
+0x2e21021, 0x944275c0, 0xaec20124, 0xa03021, 0x14c0000f, 0x27440212,
+0x810c0, 0x2e21021, 0xafa80010, 0x944271c0, 0x3c040001, 0x24842958,
+0xafa20014, 0x8f460210, 0x8f470214, 0x3c050003, 0xc0028eb, 0x34a5f013,
+0x1000003a, 0x3c020800, 0x628c0, 0x94830000, 0xb71021, 0x244275c2,
+0xa4430000, 0x8c830002, 0x820c0, 0xac430002, 0x2e41021, 0x944371c0,
+0x2e51021, 0xa44375c0, 0x2e41021, 0xa44671c0, 0x8ec20120, 0x24420001,
+0x28420080, 0x1040000c, 0x27440212, 0x8ec20120, 0x94830000, 0x210c0,
+0x571021, 0x244271c2, 0xa4430000, 0x8c830002, 0xac430002, 0x8ec20120,
+0x24420001, 0xaec20120, 0x92c2011c, 0x1040000d, 0x81942, 0x24020003,
+0x431023, 0x21080, 0x572821, 0x571021, 0x3104001f, 0x8c4304ac,
+0x24020001, 0x821004, 0x621825, 0x1000000c, 0xaca304ac, 0x24020003,
+0x431023, 0x21080, 0x5c2821, 0x5c1021, 0x3104001f, 0x8c430228,
+0x24020001, 0x821004, 0x621825, 0xaca30228, 0x3c020800, 0x34421000,
+0xafa20020, 0x8ec3002c, 0x240200ff, 0x10620004, 0x27a70020, 0x8ec2002c,
+0x10000002, 0x24530001, 0x9821, 0x8f420228, 0x1662000f, 0x0,
+0x3c040001, 0x24842928, 0xafa00010, 0xafa00014, 0x8ec6002c, 0x8f470228,
+0x3c050009, 0xc0028eb, 0x34a5f00f, 0x8ec202a0, 0x24420001, 0xaec202a0,
+0x1000006b, 0x8ec202a0, 0x8ec2002c, 0x210c0, 0x571021, 0x8ce30000,
+0x8ce40004, 0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054, 0x247103e8,
+0x2221023, 0x2c4203e9, 0x1040001e, 0xa821, 0x241e000d, 0x8ec8002c,
+0x8ee40428, 0x8ee5042c, 0x8ec6002c, 0x24070008, 0xafbe0010, 0xafb30014,
+0x840c0, 0x1001821, 0x1021, 0x8ec80008, 0xa32821, 0xa3482b,
+0x822021, 0x892021, 0x630c0, 0xafa80018, 0x8ec200a8, 0x24c604c0,
+0x40f809, 0x2e63021, 0x54400006, 0x24150001, 0x8f820054, 0x2221023,
+0x2c4203e9, 0x1440ffe5, 0x0, 0x32a200ff, 0x54400011, 0xaed3002c,
+0x3c040001, 0x24842934, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124,
+0x3c050009, 0x1000002e, 0x34a5f010, 0x8ec2026c, 0x24150001, 0x24420001,
+0xaec2026c, 0x8ec2026c, 0x1000001d, 0x32a200ff, 0x8f830054, 0x8f820054,
+0x247103e8, 0x2221023, 0x2c4203e9, 0x10400015, 0xa821, 0x24130011,
+0x8ec30008, 0x8ee40488, 0x8ee5048c, 0x8ec2002c, 0x8f860120, 0xafb30010,
+0xafa20014, 0xafa30018, 0x8ec200a8, 0x24070008, 0x40f809, 0x24c6001c,
+0x1440ffe4, 0x0, 0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffee,
+0x0, 0x32a200ff, 0x1440000f, 0x0, 0x3c040001, 0x24842940,
+0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0x34a5f011,
+0xc0028eb, 0x0, 0x8ec202d0, 0x24420001, 0xaec202d0, 0x8ec202d0,
+0x8ec2021c, 0x24420001, 0xaec2021c, 0x8ec2021c, 0x8ec20258, 0x24420001,
+0xaec20258, 0x8ec20258, 0x8fbf0038, 0x8fbe0034, 0x8fb50030, 0x8fb3002c,
+0x8fb10028, 0x3e00008, 0x27bd0040, 0x27bdffb0, 0x27440212, 0x24050006,
+0xafbf0048, 0xafbe0044, 0xafb50040, 0xafb3003c, 0xc002207, 0xafb10038,
+0x3044007f, 0x410c0, 0x2e21021, 0x944771c0, 0x4021, 0x10e00018,
+0x27490212, 0x952a0000, 0x710c0, 0x572821, 0x24a575c2, 0x94a20000,
+0x144a0009, 0x3021, 0x94a30002, 0x95220002, 0x14620006, 0xc01021,
+0x94a20004, 0x95230004, 0x431026, 0x2c460001, 0xc01021, 0x14400006,
+0x710c0, 0xe04021, 0x2e21021, 0x944775c0, 0x14e0ffec, 0x710c0,
+0xe02821, 0x14a0000f, 0xafa80028, 0x410c0, 0x2e21021, 0xafa40010,
+0x944271c0, 0x3c040001, 0x24842964, 0xafa20014, 0x8f460210, 0x8f470214,
+0x3c050003, 0xc0028eb, 0x34a5f01c, 0x10000062, 0x3c020800, 0x11000007,
+0x510c0, 0x2e21021, 0x944375c0, 0x810c0, 0x2e21021, 0x10000006,
+0xa44375c0, 0x2e21021, 0x944375c0, 0x410c0, 0x2e21021, 0xa44371c0,
+0x8ec30124, 0x510c0, 0x2e21021, 0x26e871c0, 0xa44375c0, 0x8ec20120,
+0x3021, 0x27490212, 0x18400029, 0xaec50124, 0x25070006, 0x94e3fffc,
+0x95220000, 0x14620009, 0x2821, 0x94e3fffe, 0x95220002, 0x14620006,
+0xa01021, 0x94e20000, 0x95230004, 0x431026, 0x2c450001, 0xa01021,
+0x50400014, 0x24c60001, 0x8ec20120, 0x2442ffff, 0xc2102a, 0x1040000b,
+0x25050004, 0x94a20006, 0x8ca30008, 0xa4a2fffe, 0xaca30000, 0x8ec20120,
+0x24c60001, 0x2442ffff, 0xc2102a, 0x1440fff7, 0x24a50008, 0x8ec20120,
+0x2442ffff, 0x10000006, 0xaec20120, 0x8ec20120, 0x24e70008, 0xc2102a,
+0x1440ffda, 0x25080008, 0x410c0, 0x2e21021, 0x944271c0, 0x1440001e,
+0x3c020800, 0x92c2011c, 0x1040000e, 0x41942, 0x24020003, 0x431023,
+0x21080, 0x572821, 0x571021, 0x3084001f, 0x24030001, 0x8c4204ac,
+0x831804, 0x31827, 0x431024, 0x1000000d, 0xaca204ac, 0x24020003,
+0x431023, 0x21080, 0x5c2821, 0x5c1021, 0x3084001f, 0x24030001,
+0x8c420228, 0x831804, 0x31827, 0x431024, 0xaca20228, 0x3c020800,
+0x34422000, 0xafa20020, 0x8ec3002c, 0x240200ff, 0x10620004, 0x27a70020,
+0x8ec2002c, 0x10000002, 0x24530001, 0x9821, 0x8f420228, 0x1662000f,
+0x0, 0x3c040001, 0x24842928, 0xafa00010, 0xafa00014, 0x8ec6002c,
+0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f00f, 0x8ec202a0, 0x24420001,
+0xaec202a0, 0x1000006b, 0x8ec202a0, 0x8ec2002c, 0x210c0, 0x571021,
+0x8ce30000, 0x8ce40004, 0xac4304c0, 0xac4404c4, 0x8f830054, 0x8f820054,
+0x247103e8, 0x2221023, 0x2c4203e9, 0x1040001e, 0xa821, 0x241e000d,
+0x8ec8002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c, 0x24070008, 0xafbe0010,
+0xafb30014, 0x840c0, 0x1001821, 0x1021, 0x8ec80008, 0xa32821,
+0xa3482b, 0x822021, 0x892021, 0x630c0, 0xafa80018, 0x8ec200a8,
+0x24c604c0, 0x40f809, 0x2e63021, 0x54400006, 0x24150001, 0x8f820054,
+0x2221023, 0x2c4203e9, 0x1440ffe5, 0x0, 0x32a200ff, 0x54400011,
+0xaed3002c, 0x3c040001, 0x24842934, 0xafa00010, 0xafa00014, 0x8f860120,
+0x8f870124, 0x3c050009, 0x1000002e, 0x34a5f010, 0x8ec2026c, 0x24150001,
+0x24420001, 0xaec2026c, 0x8ec2026c, 0x1000001d, 0x32a200ff, 0x8f830054,
+0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, 0x10400015, 0xa821,
+0x24130011, 0x8ec30008, 0x8ee40488, 0x8ee5048c, 0x8ec2002c, 0x8f860120,
+0xafb30010, 0xafa20014, 0xafa30018, 0x8ec200a8, 0x24070008, 0x40f809,
+0x24c6001c, 0x1440ffe4, 0x0, 0x8f820054, 0x2221023, 0x2c4203e9,
+0x1440ffee, 0x0, 0x32a200ff, 0x1440000f, 0x0, 0x3c040001,
+0x24842940, 0xafa00010, 0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009,
+0x34a5f011, 0xc0028eb, 0x0, 0x8ec202d0, 0x24420001, 0xaec202d0,
+0x8ec202d0, 0x8ec20220, 0x24420001, 0xaec20220, 0x8ec20220, 0x8ec20258,
+0x24420001, 0xaec20258, 0x8ec20258, 0x8fbf0048, 0x8fbe0044, 0x8fb50040,
+0x8fb3003c, 0x8fb10038, 0x3e00008, 0x27bd0050, 0x0, 0x0,
+0x27bdffe8, 0x27644000, 0xafbf0010, 0xc00296c, 0x24051000, 0x24020020,
+0xaf82011c, 0xaf800100, 0xaf800104, 0xaf800108, 0xaf800110, 0xaf800114,
+0xaf800118, 0xaf800120, 0xaf800124, 0xaf800128, 0xaf800130, 0xaf800134,
+0xaf800138, 0xaec000dc, 0xaec000e0, 0xaec000e4, 0xaec000e8, 0x3c020001,
+0x571021, 0x904281ec, 0x1440001d, 0x0, 0x8f82011c, 0x34420001,
+0xaf82011c, 0x8f830040, 0x3c02f000, 0x621824, 0x3c025000, 0x10620005,
+0x3c026000, 0x1062000b, 0x0, 0x10000010, 0x0, 0x8f420218,
+0x30420040, 0x14400009, 0x0, 0x8f820050, 0x3c030010, 0x10000003,
+0x431024, 0x8f420218, 0x30420040, 0x10400004, 0x0, 0x8f82011c,
+0x34420004, 0xaf82011c, 0x8fbf0010, 0x3e00008, 0x27bd0018, 0x8faa0010,
+0x8f83012c, 0x8fab0014, 0x1060000c, 0x8fac0018, 0x8ec20534, 0x8f890128,
+0x24680020, 0x51020005, 0x27624800, 0x11280005, 0x24620020, 0x10000009,
+0x0, 0x15220007, 0x24620020, 0x8ec30298, 0x1021, 0x24630001,
+0xaec30298, 0x1000006b, 0x8ec30298, 0xac640000, 0xac650004, 0xac660008,
+0xa467000e, 0xac6a0018, 0xac6b001c, 0xac6c0010, 0x2543ffee, 0x2c630002,
+0xaf820120, 0x39420011, 0x2c420001, 0x621825, 0x10600025, 0x0,
+0x8ec200e4, 0x210c0, 0x24426fc0, 0x2e22021, 0x8c830000, 0x24020012,
+0x1462000f, 0x0, 0x8ec300e4, 0x8ec200e8, 0x1062000b, 0x24030040,
+0x8c820004, 0x24420001, 0xac820004, 0x8ec200e8, 0x8ec500e4, 0x24420001,
+0x1043002b, 0x0, 0x10000023, 0x0, 0x8ec200e4, 0x24030040,
+0x24420001, 0x50430003, 0x1021, 0x8ec200e4, 0x24420001, 0xaec200e4,
+0x8ec200e4, 0x210c0, 0x24426fc0, 0x2e22021, 0x10000034, 0x24020012,
+0x8ec200e4, 0x210c0, 0x24426fc0, 0x2e22021, 0x8c830000, 0x24020007,
+0x1462001f, 0x0, 0x8ec300e4, 0x8ec200e8, 0x1062001b, 0x24030040,
+0x8c820004, 0x24420001, 0xac820004, 0x8ec200e8, 0x8ec500e4, 0x24420001,
+0x10430007, 0x0, 0x8ec200e8, 0x24420001, 0x10a20005, 0x0,
+0x10000007, 0x0, 0x14a00005, 0x0, 0x8f820128, 0x24420020,
+0xaf820128, 0x8f820128, 0x8c820004, 0x2c420011, 0x50400013, 0xac800000,
+0x10000012, 0x24020001, 0x8ec200e4, 0x24030040, 0x24420001, 0x50430003,
+0x1021, 0x8ec200e4, 0x24420001, 0xaec200e4, 0x8ec200e4, 0x210c0,
+0x24426fc0, 0x2e22021, 0x24020007, 0xac820000, 0x24020001, 0xac820004,
+0x24020001, 0x3e00008, 0x0, 0x3e00008, 0x0, 0x8faa0010,
+0x8fab0014, 0x8f880120, 0x8ec20534, 0x8fac0018, 0x25030020, 0x14620002,
+0x604821, 0x27694800, 0x8f820128, 0x1122000c, 0x25030016, 0xad040000,
+0xad050004, 0xad060008, 0xa507000e, 0xad0a0018, 0xad0b001c, 0xad030014,
+0xad0c0010, 0xaf890120, 0x10000006, 0x24020001, 0x8ec30298, 0x1021,
+0x24630001, 0xaec30298, 0x8ec30298, 0x3e00008, 0x0, 0x3e00008,
+0x0, 0x8faa0010, 0x8f83010c, 0x8fab0014, 0x1060000c, 0x8fac0018,
+0x8f890108, 0x24680020, 0x27624800, 0x51020005, 0x27624000, 0x11280005,
+0x24620020, 0x10000009, 0x0, 0x15220007, 0x24620020, 0x8ec3029c,
+0x1021, 0x24630001, 0xaec3029c, 0x10000052, 0x8ec3029c, 0xac640000,
+0xac650004, 0xac660008, 0xa467000e, 0xac6a0018, 0xac6b001c, 0xac6c0010,
+0xaf820100, 0x2542fffb, 0x2c420002, 0x10400037, 0x24030040, 0x8ec200dc,
+0x210c0, 0x24426dc0, 0x2e22021, 0x8c830000, 0x24020005, 0x1462001f,
+0x0, 0x8ec300dc, 0x8ec200e0, 0x1062001b, 0x24030040, 0x8c820004,
+0x24420001, 0xac820004, 0x8ec200e0, 0x8ec500dc, 0x24420001, 0x10430007,
+0x0, 0x8ec200e0, 0x24420001, 0x10a20005, 0x0, 0x10000007,
+0x0, 0x14a00005, 0x0, 0x8f820108, 0x24420020, 0xaf820108,
+0x8f820108, 0x8c820004, 0x2c420011, 0x50400021, 0xac800000, 0x10000020,
+0x24020001, 0x8ec200dc, 0x24030040, 0x24420001, 0x50430003, 0x1021,
+0x8ec200dc, 0x24420001, 0xaec200dc, 0x8ec200dc, 0x210c0, 0x24426dc0,
+0x2e22021, 0x24020005, 0xac820000, 0x1000000e, 0x24020001, 0x8ec200dc,
+0x24420001, 0x50430003, 0x1021, 0x8ec200dc, 0x24420001, 0xaec200dc,
+0x8ec200dc, 0x210c0, 0x24426dc0, 0x2e22021, 0x24020001, 0xac8a0000,
+0xac820004, 0x24020001, 0x3e00008, 0x0, 0x3e00008, 0x0,
+0x8f880100, 0x8fa30010, 0x8faa0014, 0x8fab0018, 0x27624800, 0x25090020,
+0x122102b, 0x50400001, 0x27694000, 0x8f820108, 0x1122000d, 0x0,
+0xad030018, 0x25030016, 0xad040000, 0xad050004, 0xad060008, 0xa507000e,
+0xad0a001c, 0xad030014, 0xad0b0010, 0xaf890100, 0x10000006, 0x24020001,
+0x8ec3029c, 0x1021, 0x24630001, 0xaec3029c, 0x8ec3029c, 0x3e00008,
+0x0, 0x3e00008, 0x0, 0x27bdffe0, 0xafbf0018, 0x8f820104,
+0xafa20010, 0x8f820100, 0x3c050002, 0xafa20014, 0x8f8600b0, 0x8f87011c,
+0x3c040001, 0x24842a2c, 0xc0028eb, 0x34a5f000, 0x8f420218, 0x30420100,
+0x10400017, 0x0, 0x8f8200b0, 0x3c030200, 0x431024, 0x10400012,
+0x0, 0x8f82011c, 0x34420002, 0xaf82011c, 0x8f830104, 0x8f8200b0,
+0x34420001, 0xaf8200b0, 0xaf830104, 0x8f82011c, 0x2403fffd, 0x431024,
+0xaf82011c, 0x8ec20294, 0x24420001, 0xaec20294, 0x10000004, 0x8ec20294,
+0x8f8200b0, 0x34420001, 0xaf8200b0, 0x8fbf0018, 0x3e00008, 0x27bd0020,
+0x27bdffe0, 0xafbf0018, 0x8f820120, 0xafa20010, 0x8f820124, 0x3c050001,
+0xafa20014, 0x8f8600a0, 0x8f87011c, 0x3c040001, 0x24842a38, 0xc0028eb,
+0x34a5f000, 0x8f420218, 0x30420100, 0x10400017, 0x0, 0x8f8200a0,
+0x3c030200, 0x431024, 0x10400012, 0x0, 0x8f82011c, 0x34420002,
+0xaf82011c, 0x8f830124, 0x8f8200a0, 0x34420001, 0xaf8200a0, 0xaf830124,
+0x8f82011c, 0x2403fffd, 0x431024, 0xaf82011c, 0x8ec20290, 0x24420001,
+0xaec20290, 0x10000004, 0x8ec20290, 0x8f8200a0, 0x34420001, 0xaf8200a0,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x6021, 0x5021, 0x3021,
+0x2821, 0x6821, 0x4821, 0x7821, 0x7021, 0x8f880124,
+0x8f870104, 0x1580002e, 0x8f8b011c, 0x11a00014, 0x31620800, 0x8f820120,
+0x10460029, 0x0, 0x3c040001, 0x8c843390, 0x8cc20000, 0x8cc30004,
+0xac820000, 0xac830004, 0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e,
+0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014, 0x10000012, 0x24c60020,
+0x10400017, 0x0, 0x3c040001, 0x8c843390, 0x8d020000, 0x8d030004,
+0xac820000, 0xac830004, 0x8d020008, 0xac820008, 0x9502000e, 0xa482000e,
+0x8d020010, 0x25060020, 0xac820010, 0x8d020014, 0x240c0001, 0xc01821,
+0xac820014, 0x27624fe0, 0x43102b, 0x54400001, 0x27634800, 0x603021,
+0x1540002f, 0x31620100, 0x11200014, 0x31628000, 0x8f820100, 0x1045002a,
+0x31620100, 0x3c040001, 0x8c84338c, 0x8ca20000, 0x8ca30004, 0xac820000,
+0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010,
+0x240a0001, 0xac820010, 0x8ca20014, 0x10000012, 0x24a50020, 0x10400018,
+0x31620100, 0x3c040001, 0x8c84338c, 0x8ce20000, 0x8ce30004, 0xac820000,
+0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010,
+0x24e50020, 0xac820010, 0x8ce20014, 0x240a0001, 0xa01821, 0xac820014,
+0x276247e0, 0x43102b, 0x54400001, 0x27634000, 0x602821, 0x31620100,
+0x5440001d, 0x31621000, 0x11a00009, 0x31a20800, 0x10400004, 0x25020020,
+0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124, 0x8f880124, 0x6821,
+0x11800011, 0x31621000, 0x3c040001, 0x8c843390, 0x8c820000, 0x8c830004,
+0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac,
+0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31621000,
+0x1440ff82, 0x0, 0x1120000f, 0x31220800, 0x10400004, 0x3c020002,
+0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1221024, 0x10400004, 0x24e20020,
+0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104, 0x8f870104, 0x4821,
+0x1140ff70, 0x0, 0x3c040001, 0x8c84338c, 0x8c820000, 0x8c830004,
+0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c,
+0x8c820010, 0x5021, 0xaf8200b0, 0x8c890010, 0x1000ff60, 0x8c8e0014,
+0x3e00008, 0x0, 0x6021, 0x5821, 0x3021, 0x2821,
+0x6821, 0x5021, 0x7821, 0x7021, 0x8f880124, 0x8f870104,
+0x3c180100, 0x1580002e, 0x8f89011c, 0x11a00014, 0x31220800, 0x8f820120,
+0x10460029, 0x0, 0x3c040001, 0x8c843390, 0x8cc20000, 0x8cc30004,
+0xac820000, 0xac830004, 0x8cc20008, 0xac820008, 0x94c2000e, 0xa482000e,
+0x8cc20010, 0x240c0001, 0xac820010, 0x8cc20014, 0x10000012, 0x24c60020,
+0x10400017, 0x0, 0x3c040001, 0x8c843390, 0x8d020000, 0x8d030004,
+0xac820000, 0xac830004, 0x8d020008, 0xac820008, 0x9502000e, 0xa482000e,
+0x8d020010, 0x25060020, 0xac820010, 0x8d020014, 0x240c0001, 0xc01821,
+0xac820014, 0x27624fe0, 0x43102b, 0x54400001, 0x27634800, 0x603021,
+0x1560002f, 0x31220100, 0x11400014, 0x31228000, 0x8f820100, 0x1045002a,
+0x31220100, 0x3c040001, 0x8c84338c, 0x8ca20000, 0x8ca30004, 0xac820000,
+0xac830004, 0x8ca20008, 0xac820008, 0x94a2000e, 0xa482000e, 0x8ca20010,
+0x240b0001, 0xac820010, 0x8ca20014, 0x10000012, 0x24a50020, 0x10400018,
+0x31220100, 0x3c040001, 0x8c84338c, 0x8ce20000, 0x8ce30004, 0xac820000,
+0xac830004, 0x8ce20008, 0xac820008, 0x94e2000e, 0xa482000e, 0x8ce20010,
+0x24e50020, 0xac820010, 0x8ce20014, 0x240b0001, 0xa01821, 0xac820014,
+0x276247e0, 0x43102b, 0x54400001, 0x27634000, 0x602821, 0x31220100,
+0x5440001d, 0x31221000, 0x11a00009, 0x31a20800, 0x10400004, 0x25020020,
+0x8f8200a8, 0xa5e20000, 0x25020020, 0xaf820124, 0x8f880124, 0x6821,
+0x11800011, 0x31221000, 0x3c040001, 0x8c843390, 0x8c820000, 0x8c830004,
+0xaf820080, 0xaf830084, 0x8c820008, 0xaf8200a4, 0x9482000e, 0xaf8200ac,
+0x8c820010, 0x6021, 0xaf8200a0, 0x8c8d0010, 0x8c8f0014, 0x31221000,
+0x14400022, 0x0, 0x1140000f, 0x31420800, 0x10400004, 0x3c020002,
+0x8f8200b8, 0xa5c20000, 0x3c020002, 0x1421024, 0x10400004, 0x24e20020,
+0x8f8200b4, 0xaf8200d4, 0x24e20020, 0xaf820104, 0x8f870104, 0x5021,
+0x11600010, 0x0, 0x3c040001, 0x8c84338c, 0x8c820000, 0x8c830004,
+0xaf820090, 0xaf830094, 0x8c820008, 0xaf8200b4, 0x9482000e, 0xaf82009c,
+0x8c820010, 0x5821, 0xaf8200b0, 0x8c8a0010, 0x8c8e0014, 0x8f820070,
+0x3c031000, 0x431024, 0x1040ff5c, 0x0, 0x8f820054, 0x24420005,
+0xaf820078, 0x8f420234, 0x10400017, 0x2021, 0x3c020001, 0x571021,
+0x8c4281dc, 0x24420005, 0x3c010001, 0x370821, 0xac2281dc, 0x3c020001,
+0x571021, 0x8c4281dc, 0x8f430234, 0x43102b, 0x14400009, 0x24020001,
+0x3c040080, 0x3c010001, 0x370821, 0xac2281d4, 0x3c010001, 0x370821,
+0x1000000c, 0xac2081dc, 0x3c020001, 0x571021, 0x8c4281d4, 0x14400006,
+0x3c020080, 0x3c020001, 0x571021, 0x8c4281d8, 0x10400002, 0x3c020080,
+0x822025, 0x8f420230, 0x10400014, 0x0, 0x3c020001, 0x571021,
+0x8c4281e4, 0x24420005, 0x3c010001, 0x370821, 0xac2281e4, 0x3c020001,
+0x571021, 0x8c4281e4, 0x8f430230, 0x43102b, 0x14400006, 0x0,
+0x3c010001, 0x370821, 0xac2081e4, 0x10000006, 0x982025, 0x3c020001,
+0x571021, 0x8c4281e0, 0x54400001, 0x982025, 0x3c020001, 0x571021,
+0x8c4281e8, 0x10400005, 0x3c022000, 0x822025, 0x3c010001, 0x370821,
+0xac2081e8, 0x1080ff0f, 0x0, 0x8ec20000, 0x10400007, 0x0,
+0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, 0x10000005, 0x0,
+0xaf800048, 0x8f820048, 0x1040fffd, 0x0, 0x8f820060, 0x441025,
+0xaf820060, 0x8ec20000, 0x10400003, 0x0, 0x1000fefa, 0xaf80004c,
+0x1000fef8, 0xaf800048, 0x3e00008, 0x0, 0x3c020001, 0x8c423228,
+0x27bdffe8, 0xafbf0014, 0x14400012, 0xafb10010, 0x3c110001, 0x26313430,
+0x2202021, 0xc00296c, 0x24052000, 0x26221fe0, 0x3c010001, 0xac223398,
+0x3c010001, 0xac223394, 0xaf420250, 0x24022000, 0xaf510254, 0xaf420258,
+0x24020001, 0x3c010001, 0xac223228, 0x8fbf0014, 0x8fb10010, 0x3e00008,
+0x27bd0018, 0x3c030001, 0x8c633398, 0x8c820000, 0x8fa80010, 0x8fa90014,
+0xac620000, 0x3c020001, 0x8c423398, 0x8c830004, 0xac430004, 0xac450008,
+0x8f840054, 0x2443ffe0, 0xac460010, 0xac470014, 0xac480018, 0xac49001c,
+0x3c010001, 0xac233398, 0xac44000c, 0x3c020001, 0x24423430, 0x62182b,
+0x10600005, 0x0, 0x3c020001, 0x8c423394, 0x3c010001, 0xac223398,
+0x3c030001, 0x8c633398, 0x3c020001, 0x8c423210, 0xac620000, 0x3c030001,
+0x8c633398, 0x3c020001, 0x8c423210, 0xac620004, 0x3e00008, 0xaf430250,
+0x27bdffd8, 0xafb10010, 0x808821, 0x3c030001, 0x8c633398, 0x3c020001,
+0x8c423210, 0x8fa40040, 0xafb30014, 0xa09821, 0xafbf0020, 0xafbe001c,
+0xafb50018, 0xac620000, 0x3c050001, 0x8ca53398, 0x3c020001, 0x8c423210,
+0xc0a821, 0xe0f021, 0x10800006, 0xaca20004, 0x24a50008, 0xc002974,
+0x24060018, 0x10000004, 0x0, 0x24a40008, 0xc00296c, 0x24050018,
+0x3c020001, 0x8c423398, 0x3c050001, 0x24a53430, 0x2442ffe0, 0x3c010001,
+0xac223398, 0x45102b, 0x10400005, 0x0, 0x3c020001, 0x8c423394,
+0x3c010001, 0xac223398, 0x3c030001, 0x8c633398, 0x8e220000, 0xac620000,
+0x3c030001, 0x8c633398, 0x8e220004, 0xac620004, 0xac730008, 0x8f840054,
+0xac750010, 0xac7e0014, 0x8fa80038, 0xac680018, 0x8fa8003c, 0x2462ffe0,
+0x3c010001, 0xac223398, 0x45102b, 0xac68001c, 0x10400005, 0xac64000c,
+0x3c020001, 0x8c423394, 0x3c010001, 0xac223398, 0x3c030001, 0x8c633398,
+0x3c020001, 0x8c423210, 0xac620000, 0x3c030001, 0x8c633398, 0x3c020001,
+0x8c423210, 0xac620004, 0xaf430250, 0x8fbf0020, 0x8fbe001c, 0x8fb50018,
+0x8fb30014, 0x8fb10010, 0x3e00008, 0x27bd0028, 0x10a00005, 0x0,
+0xac800000, 0x24a5fffc, 0x14a0fffd, 0x24840004, 0x3e00008, 0x0,
+0x10c00007, 0x0, 0x8c820000, 0x24840004, 0x24c6fffc, 0xaca20000,
+0x14c0fffb, 0x24a50004, 0x3e00008, 0x0, 0x10c00007, 0x0,
+0x8ca20000, 0x24a50004, 0x24c6fffc, 0xac820000, 0x14c0fffb, 0x24840004,
+0x3e00008, 0x0, 0x63080, 0x861821, 0x83102b, 0x10400006,
+0x0, 0xac850000, 0x24840004, 0x83102b, 0x5440fffd, 0xac850000,
+0x3e00008, 0x0, 0x27bdffc0, 0xafbf0038, 0xafb30034, 0xafb10030,
+0x8ec3001c, 0x8ec20014, 0x10620137, 0x0, 0x8ec2001c, 0x8ee304bc,
+0x21100, 0x622021, 0x9493000a, 0x8c880000, 0x8c890004, 0x1312c2,
+0x30460001, 0xafa80028, 0xafa9002c, 0x94910008, 0x8ec20078, 0x8ec30088,
+0x3225ffff, 0x451021, 0x62182b, 0x10600017, 0x0, 0x8f8200d8,
+0x8ec30074, 0x431023, 0x2442fff8, 0xaec20088, 0x8ec20088, 0x4410004,
+0x0, 0x8ec3053c, 0x431021, 0xaec20088, 0x8ec20078, 0x8ec30088,
+0x451021, 0x62182b, 0x10600006, 0x0, 0x8ec202ac, 0x24420001,
+0xaec202ac, 0x1000010e, 0x8ec202ac, 0x8f8200fc, 0x14400006, 0x0,
+0x8ec202a8, 0x24420001, 0xaec202a8, 0x10000106, 0x8ec202a8, 0x92c20529,
+0x1040000b, 0x32620200, 0x1040000a, 0x32620004, 0x96e20452, 0x30420010,
+0x10400005, 0x3c028000, 0xaec2052c, 0x9482000e, 0x21400, 0xaec20530,
+0x32620004, 0x104000a8, 0x30c200ff, 0x10400003, 0x3227ffff, 0x10000002,
+0x24020017, 0x24020006, 0xafa20010, 0x8ec2001c, 0xafa20014, 0x8ec2000c,
+0x8fa40028, 0x8fa5002c, 0x3c030002, 0x431025, 0xafa20018, 0x8ec60080,
+0x8ec200a4, 0x40f809, 0x0, 0x5440000b, 0x3225ffff, 0x8fa9002c,
+0xafa90010, 0x8ec20080, 0x3c040001, 0x24842cfc, 0x3c050004, 0xafa20014,
+0x8ec6001c, 0x100000a5, 0x34a5f004, 0x8ec20078, 0x451021, 0xaec20078,
+0x8ec2001c, 0x8ee304bc, 0x8ec40074, 0x21100, 0x431021, 0xac44000c,
+0x8ec30074, 0xafa30020, 0x8ec40078, 0xafa40024, 0x8ec2052c, 0x10400006,
+0x3c024000, 0x621025, 0xafa20020, 0x8ec20530, 0x821025, 0xafa20024,
+0x8ec20080, 0x8ec30078, 0x2406fff8, 0x451021, 0x24420007, 0x461024,
+0x24630007, 0xaec20074, 0x8ec20088, 0x8ec40074, 0x8ec50538, 0x661824,
+0x431023, 0x85202b, 0x14800005, 0xaec20088, 0x8ec20074, 0x8ec3053c,
+0x431023, 0xaec20074, 0x8ec20074, 0xaec20080, 0x8f8600fc, 0x14c00007,
+0x0, 0x8ec202a8, 0x1821, 0x24420001, 0xaec202a8, 0x10000008,
+0x8ec202a8, 0x8fa20020, 0x8fa30024, 0xacc20000, 0xacc30004, 0x24c20008,
+0xaf8200f0, 0x24030001, 0x14600012, 0x131142, 0x8f8200f0, 0xafa20010,
+0x8f8200f4, 0x3c040001, 0x24842d08, 0xafa20014, 0x8fa60020, 0x8fa70024,
+0x3c050004, 0xc0028eb, 0x34a5f005, 0x8ec20180, 0x24420001, 0xaec20180,
+0x8ec20180, 0x10000039, 0x24020001, 0x30430003, 0x24020002, 0x10620016,
+0x28620003, 0x10400005, 0x24020001, 0x10620008, 0x0, 0x10000023,
+0x0, 0x24020003, 0x10620017, 0x0, 0x1000001e, 0x0,
+0x8ec201e0, 0x8ec301e4, 0x24630001, 0x2c640001, 0x441021, 0xaec201e0,
+0xaec301e4, 0x8ec201e0, 0x10000014, 0x8ec301e4, 0x8ec201e8, 0x8ec301ec,
+0x24630001, 0x2c640001, 0x441021, 0xaec201e8, 0xaec301ec, 0x8ec201e8,
+0x1000000a, 0x8ec301ec, 0x8ec201f0, 0x8ec301f4, 0x24630001, 0x2c640001,
+0x441021, 0xaec201f0, 0xaec301f4, 0x8ec201f0, 0x8ec301f4, 0x8ec20078,
+0x8ec401d8, 0x8ec501dc, 0x401821, 0x1021, 0xa32821, 0xa3302b,
+0x822021, 0x862021, 0xaec401d8, 0xaec501dc, 0x24020001, 0xaec00078,
+0x1000002f, 0xa2c20529, 0x3227ffff, 0x10e0002c, 0x0, 0x14400002,
+0x24020016, 0x24020005, 0xafa20010, 0x8ec2001c, 0x8fa40028, 0x8fa5002c,
+0xafa20014, 0x8ec2000c, 0xafa20018, 0x8ec60080, 0x8ec200a4, 0x40f809,
+0x0, 0x1440000d, 0x3225ffff, 0x3c040001, 0x24842d14, 0x8fa8002c,
+0x3c050004, 0xafa00014, 0xafa80010, 0x8ec6001c, 0x34a5f007, 0xc0028eb,
+0x2203821, 0x10000030, 0x0, 0x8ec20080, 0x8ec40538, 0x451021,
+0xaec20080, 0x8ec20078, 0x8ec30080, 0x451021, 0x64182b, 0x14600005,
+0xaec20078, 0x8ec20080, 0x8ec3053c, 0x431023, 0xaec20080, 0xa2c00529,
+0x8ec3001c, 0x96e20450, 0x24630001, 0x2442ffff, 0x621824, 0xaec3001c,
+0x8ec3001c, 0x8ec20014, 0x14620017, 0x0, 0x8ec20000, 0x10400007,
+0x2403fff7, 0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0, 0x10000005,
+0x0, 0xaf800048, 0x8f820048, 0x1040fffd, 0x0, 0x8f820060,
+0x431024, 0xaf820060, 0x8ec20000, 0x10400003, 0x0, 0x10000002,
+0xaf80004c, 0xaf800048, 0x8fbf0038, 0x8fb30034, 0x8fb10030, 0x3e00008,
+0x27bd0040, 0x3e00008, 0x0, 0x27bdffd0, 0xafbf002c, 0xafb10028,
+0x8ec3001c, 0x8ec20014, 0x106200f0, 0x0, 0x8ec2001c, 0x8ee304bc,
+0x21100, 0x622821, 0x8caa0000, 0x8cab0004, 0x94a7000a, 0xafaa0020,
+0xafab0024, 0x94b10008, 0x71ac2, 0x8ec20088, 0x3224ffff, 0x44102a,
+0x10400017, 0x30680001, 0x8f8200d8, 0x8ec30080, 0x431023, 0x2442fff8,
+0xaec20088, 0x8ec20088, 0x2842fff9, 0x10400005, 0x0, 0x8ec20088,
+0x8ec3053c, 0x431021, 0xaec20088, 0x8ec20088, 0x44102a, 0x10400006,
+0x0, 0x8ec202ac, 0x24420001, 0xaec202ac, 0x100000ca, 0x8ec202ac,
+0x8f8400fc, 0x1080000c, 0x0, 0x8f8200f4, 0x2403fff8, 0x431024,
+0x441023, 0x218c3, 0x50600001, 0x24030100, 0x8ec20070, 0x43102b,
+0x14400006, 0x0, 0x8ec202a8, 0x24420001, 0xaec202a8, 0x100000b7,
+0x8ec202a8, 0x92c20021, 0x1040000f, 0x0, 0x8ec2000c, 0x34460400,
+0x30e20200, 0x1040000b, 0x0, 0x96e20452, 0x30420010, 0x10400007,
+0x3c028000, 0xaec2052c, 0x94a2000e, 0x21400, 0x10000002, 0xaec20530,
+0x8ec6000c, 0x8ec2001c, 0x8ee304bc, 0x8ec40074, 0x21100, 0x431021,
+0xac44000c, 0x30e20004, 0x50400050, 0x3227ffff, 0x8ec2052c, 0x10400013,
+0x0, 0x11000003, 0x3227ffff, 0x10000002, 0x24020018, 0x24020015,
+0xafa20010, 0x8ec3001c, 0x8ec40530, 0x3c020002, 0xc21025, 0xafa20018,
+0x641825, 0xafa30014, 0x8ec60080, 0x8ec200a4, 0x8fa40020, 0x10000010,
+0x8fa50024, 0x11000003, 0x3227ffff, 0x10000002, 0x24020017, 0x24020006,
+0xafa20010, 0x8ec2001c, 0x8fa40020, 0x8fa50024, 0x3c030002, 0xc31825,
+0xafa30018, 0xafa20014, 0x8ec60080, 0x8ec200a4, 0x40f809, 0x0,
+0x1440000b, 0x24030001, 0x8fab0024, 0xafab0010, 0x8ec20080, 0x3c040001,
+0x24842cfc, 0x3c050004, 0xafa20014, 0x8ec60018, 0x10000037, 0x34a5f004,
+0x8ec40070, 0x8ec20080, 0x8ec50538, 0x2406fff8, 0xa2c30021, 0xaec0052c,
+0xaec00530, 0x24840001, 0xaec40070, 0x3224ffff, 0x441021, 0x24420007,
+0x461024, 0x24840007, 0xaec20074, 0x8ec20088, 0x8ec30074, 0x862024,
+0x441023, 0x65182b, 0x14600005, 0xaec20088, 0x8ec20074, 0x8ec3053c,
+0x431023, 0xaec20074, 0x8ec20074, 0x1000002d, 0xaec20080, 0x10e0002b,
+0x0, 0x15000002, 0x24020016, 0x24020005, 0xafa20010, 0x8ec2001c,
+0x8fa40020, 0x8fa50024, 0xafa60018, 0xafa20014, 0x8ec60080, 0x8ec200a4,
+0x40f809, 0x0, 0x1440000d, 0x3225ffff, 0x3c040001, 0x24842d14,
+0x8faa0024, 0x3c050004, 0xafa00014, 0xafaa0010, 0x8ec60018, 0x34a5f007,
+0xc0028eb, 0x2203821, 0x10000030, 0x0, 0x8ec20080, 0x8ec40538,
+0x451021, 0xaec20080, 0x8ec20088, 0x8ec30080, 0xa2c00021, 0x451023,
+0x64182b, 0x14600005, 0xaec20088, 0x8ec20080, 0x8ec3053c, 0x431023,
+0xaec20080, 0x8ec3001c, 0x96e20450, 0x24630001, 0x2442ffff, 0x621824,
+0xaec3001c, 0x8ec3001c, 0x8ec20014, 0x14620017, 0x0, 0x8ec20000,
+0x10400007, 0x2403fff7, 0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
+0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
+0x8f820060, 0x431024, 0xaf820060, 0x8ec20000, 0x10400003, 0x0,
+0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf002c, 0x8fb10028, 0x3e00008,
+0x27bd0030, 0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024, 0xafb10020,
+0x8f820100, 0x8ec300e0, 0x8f820104, 0x8f850108, 0x24020040, 0x24630001,
+0x50620003, 0x1021, 0x8ec200e0, 0x24420001, 0xaec200e0, 0x8ec200e0,
+0x8ec300e0, 0x210c0, 0x24426dc0, 0x2e22021, 0x8ec200dc, 0x8c870004,
+0x14620007, 0xa03021, 0x8f820108, 0x24420020, 0xaf820108, 0x8f820108,
+0x10000011, 0xac800000, 0x8ec200e0, 0x24030040, 0x24420001, 0x50430003,
+0x1021, 0x8ec200e0, 0x24420001, 0x210c0, 0x24426dc0, 0x2e22021,
+0x8c820004, 0x8f830108, 0x21140, 0x621821, 0xaf830108, 0xac800000,
+0x8cc50018, 0x24a2fffb, 0x2c420002, 0x1040004c, 0x24a2ffea, 0x8cc2001c,
+0x96e30450, 0x8ec40024, 0x24420001, 0x2463ffff, 0x431024, 0x872021,
+0xaec20018, 0xaec40024, 0x8ec20024, 0x8f43023c, 0x43102b, 0x144000ec,
+0x0, 0x96e20452, 0x8ed10018, 0x30420020, 0x1040001e, 0x24070008,
+0x8ee40498, 0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020019, 0xafa20010,
+0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b,
+0x24020001, 0x3c040001, 0x24842ca0, 0xafb10010, 0xafa00014, 0x8ec6002c,
+0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021, 0x1040004a,
+0x24020001, 0x3c010001, 0x370821, 0x1000006f, 0xac2281d0, 0x8ee40498,
+0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020012, 0xafa20010, 0xafb10014,
+0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b, 0x24020001,
+0x3c040001, 0x24842ca0, 0xafb10010, 0xafa00014, 0x8ec6002c, 0x8f470228,
+0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021, 0x1040004f, 0x24020001,
+0x10000051, 0x0, 0x2c420002, 0x10400062, 0x24a2fffe, 0x8cc2001c,
+0x96e30450, 0x8ec40024, 0x24420001, 0x2463ffff, 0x431024, 0x872021,
+0xaec20018, 0xaec40024, 0x96e20452, 0x8ed10018, 0x30420020, 0x10400023,
+0x24070008, 0x8ee40498, 0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020019,
+0xafa20010, 0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c,
+0x1440000b, 0x24020001, 0x3c040001, 0x24842ca0, 0xafb10010, 0xafa00014,
+0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021,
+0x14400006, 0x24020001, 0x24020001, 0x3c010001, 0x370821, 0x10000031,
+0xac2281d8, 0x3c010001, 0x370821, 0x10000021, 0xac2281d0, 0x8ee40498,
+0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020012, 0xafa20010, 0xafb10014,
+0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b, 0x24020001,
+0x3c040001, 0x24842ca0, 0xafb10010, 0xafa00014, 0x8ec6002c, 0x8f470228,
+0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021, 0x14400005, 0x24020001,
+0x3c010001, 0x370821, 0x10000010, 0xac2281d4, 0x3c010001, 0x370821,
+0xac2081d0, 0x3c010001, 0x370821, 0xac2081d8, 0x3c010001, 0x370821,
+0xac2081d4, 0x8ec20264, 0xaec00024, 0xaed10028, 0x24420001, 0xaec20264,
+0x8ec20264, 0x8ec20278, 0x24420001, 0xaec20278, 0x1000004b, 0x8ec20278,
+0x2c420002, 0x10400027, 0x24030040, 0x8ec20034, 0x24420001, 0x50430003,
+0x1021, 0x8ec20034, 0x24420001, 0xaec20034, 0x8ec20034, 0x21080,
+0x571021, 0x8c440cc0, 0x24020003, 0x14a2000d, 0x0, 0x92c20065,
+0x50400037, 0x36940040, 0x8ec202c0, 0x8ec3005c, 0x441021, 0xaec202c0,
+0x8ec202c4, 0x641821, 0x306300ff, 0x10000009, 0xaec3005c, 0x8ec202bc,
+0x8ec3003c, 0x441021, 0xaec202bc, 0x8ec202c4, 0x641821, 0x306301ff,
+0xaec3003c, 0x441021, 0xaec202c4, 0x10000022, 0x36940040, 0x24020014,
+0x14a20014, 0x24020010, 0x3c020001, 0x8c4231d4, 0x1040000a, 0x26e50028,
+0x26c40128, 0x240300ff, 0x2406ffff, 0x8ca20000, 0x24a50004, 0x2463ffff,
+0xac820000, 0x1466fffb, 0x24840004, 0x8ec20240, 0xa2c00528, 0x24420001,
+0xaec20240, 0x1000000c, 0x8ec20240, 0x10a2000a, 0x3c050008, 0x94c7000e,
+0x8cc2001c, 0x3c040001, 0x24842d20, 0xafa60014, 0xafa20010, 0x8cc60018,
+0xc0028eb, 0x34a50910, 0x8fbf0024, 0x8fb10020, 0x3e00008, 0x27bd0028,
+0x3e00008, 0x0, 0x27bdff80, 0xafbf0078, 0xafbe0074, 0xafb50070,
+0xafb3006c, 0xafb10068, 0x8f820104, 0x8f950108, 0xafa00034, 0x12a2039b,
+0xafa0003c, 0x8f820108, 0x24420020, 0xaf820108, 0x8ead0018, 0xafad0044,
+0x8f820108, 0x39a30015, 0x2c630001, 0x39a20018, 0x2c420001, 0x621825,
+0x10600009, 0x3c0d8000, 0x8ea2001c, 0x3c03ffff, 0xafad0034, 0x431824,
+0x3042ffff, 0xafa3003c, 0x10000009, 0xaea2001c, 0x8fad0044, 0x39a30006,
+0x2c630001, 0x39a20017, 0x2c420001, 0x621825, 0x1060028d, 0x24020005,
+0x96a20016, 0x8ead001c, 0xaea20014, 0xafad0054, 0x8ee204bc, 0xd1900,
+0x8ee404bc, 0x621021, 0x9442000a, 0xafa2004c, 0x92c20090, 0x641821,
+0x14400003, 0x8c71000c, 0xaed1009c, 0xaecd0094, 0x8ec20538, 0x2625000c,
+0xa2102b, 0x14400003, 0x0, 0x8ec2053c, 0xa22823, 0x94a30000,
+0x24020800, 0x1462014c, 0x0, 0x8fad004c, 0x31a20002, 0x10400045,
+0x9821, 0x96e20452, 0x30420002, 0x10400041, 0x2629000e, 0x8ec60538,
+0x8ec7053c, 0x126102b, 0x50400001, 0x1274823, 0x25220014, 0x46102b,
+0x10400027, 0x24030005, 0x91220000, 0x3042000f, 0x14430024, 0x1202021,
+0x952a0000, 0x25290002, 0x95280000, 0x25290002, 0x95270000, 0x25290002,
+0x95260000, 0x25290002, 0x95250000, 0x25290002, 0x95230000, 0x25290002,
+0x95220000, 0x25290002, 0x95240000, 0x25290002, 0x1485021, 0x1475021,
+0x1465021, 0x1455021, 0x1435021, 0x1425021, 0x95220000, 0x95230002,
+0x1445021, 0x1425021, 0x1435021, 0xa1c02, 0x3142ffff, 0x625021,
+0xa1c02, 0x3142ffff, 0x10000008, 0x625021, 0x1202021, 0x90850000,
+0x8ec200ac, 0x30a5000f, 0x40f809, 0x52840, 0x304affff, 0x8ec20538,
+0x26250018, 0xa2102b, 0x14400003, 0x3153ffff, 0x8ec2053c, 0xa22823,
+0x131027, 0xa4a20000, 0x8fad004c, 0x31a20001, 0x10400101, 0x0,
+0x96e20452, 0x30420001, 0x104000fd, 0x31a20080, 0x10400008, 0x0,
+0x92c20090, 0x14400005, 0x24020001, 0xa2c20090, 0x8fad0054, 0xaed1009c,
+0xaecd0094, 0x8ec3009c, 0x8ec20538, 0x24650017, 0xa2102b, 0x14400003,
+0x0, 0x8ec2053c, 0xa22823, 0x90a50000, 0xa3a5005f, 0x93a6005f,
+0x38c30006, 0x3182b, 0x38c20011, 0x2102b, 0x621824, 0x1060000c,
+0x3c050008, 0x8fad0054, 0xafad0010, 0x8ec2009c, 0x3c040001, 0x24842d2c,
+0xafa20014, 0x8ec70094, 0xc0028eb, 0x34a5f055, 0x100000d7, 0x0,
+0x96e20452, 0x30420008, 0x1040000c, 0x2625000e, 0x8ec20538, 0xa2102b,
+0x14400003, 0xf021, 0x8ec2053c, 0xa22823, 0x90a20000, 0x3042000f,
+0x21080, 0x10000068, 0xafa20028, 0x8ec20094, 0x8fad0054, 0x11a20013,
+0x26240010, 0x8ec30538, 0x8ec5053c, 0x83102b, 0x14400002, 0x2626000e,
+0x852023, 0x94870000, 0xc02021, 0x83102b, 0x50400001, 0x852023,
+0x90820000, 0x3042000f, 0x21080, 0xe21823, 0x307effff, 0x10000052,
+0xafa20028, 0x8ec30538, 0x2625000e, 0x8ec4053c, 0xa3102b, 0x50400001,
+0xa42823, 0x24a20014, 0x43102b, 0x10400015, 0xa03821, 0x90a20000,
+0x94a30002, 0x3042000f, 0x21080, 0x623023, 0xafa20028, 0x90a30009,
+0x24a5000c, 0x94a20000, 0x24a50002, 0x94a40000, 0x24a50002, 0xc33021,
+0xc23021, 0x94a20000, 0x94a30002, 0xc43021, 0xc23021, 0x1000002d,
+0xc33021, 0x24a50002, 0xa3102b, 0x50400001, 0xa42823, 0x94a60000,
+0xe02821, 0xa3102b, 0x50400001, 0xa42823, 0x90a20000, 0x24e50009,
+0x3042000f, 0x21080, 0xc23023, 0xafa20028, 0xa3102b, 0x50400001,
+0xa42823, 0x90a20000, 0x24e5000c, 0xc23021, 0xa3102b, 0x50400001,
+0xa42823, 0x94a20000, 0x24a50002, 0xc23021, 0xa3102b, 0x50400001,
+0xa42823, 0x94a20000, 0x24a50002, 0xc23021, 0xa3102b, 0x50400001,
+0xa42823, 0x94a20000, 0x24a50002, 0xc23021, 0xa3102b, 0x50400001,
+0xa42823, 0x94a20000, 0xc23021, 0x61c02, 0x30c2ffff, 0x623021,
+0x61402, 0x30c3ffff, 0x431021, 0x305effff, 0x8ec60538, 0x8ec7053c,
+0x226102b, 0x14400002, 0x2204021, 0x2274023, 0x2502000e, 0x46102b,
+0x1040001a, 0x1002021, 0x95060000, 0x25080002, 0x95050000, 0x25080002,
+0x95030000, 0x25080002, 0x95020000, 0x25080002, 0x95040000, 0x25080002,
+0xc53021, 0xc33021, 0xc23021, 0x95020000, 0x95030002, 0xc43021,
+0xc23021, 0xc33021, 0x61c02, 0x30c2ffff, 0x623021, 0x61c02,
+0x30c2ffff, 0x10000005, 0x623021, 0x8ec200ac, 0x40f809, 0x24050007,
+0x3046ffff, 0x30c2ffff, 0x2629821, 0x131c02, 0x3262ffff, 0x629821,
+0x131c02, 0x8ea40014, 0x3262ffff, 0x629821, 0x9e2021, 0x41c02,
+0x3082ffff, 0x622021, 0x932023, 0x41402, 0x822021, 0x3084ffff,
+0x50800001, 0x3404ffff, 0x93a3005f, 0x24020006, 0x14620006, 0x0,
+0x8fa20028, 0x8ec3009c, 0x431021, 0x10000005, 0x2445001e, 0x8fa20028,
+0x8ec3009c, 0x431021, 0x24450014, 0x8ec20538, 0xa2102b, 0x14400003,
+0x0, 0x8ec2053c, 0xa22823, 0x8ec20094, 0x8fad0054, 0x11a20006,
+0x0, 0x94a20000, 0x822021, 0x41c02, 0x3082ffff, 0x622021,
+0x8fad004c, 0x31a20100, 0x14400005, 0x41027, 0x92c20090, 0x54400004,
+0xa4a40000, 0x41027, 0x3044ffff, 0xa4a40000, 0x96a3000e, 0x8ec20078,
+0x431021, 0xaec20078, 0xafb10020, 0x8ec30078, 0x8fad0034, 0x11a00007,
+0xafa30024, 0x8fad003c, 0x3c024000, 0x2221025, 0xafa20020, 0x6d1025,
+0xafa20024, 0x8fad004c, 0x31a20080, 0x1040000c, 0x31a20100, 0x8ee279cc,
+0x24430001, 0x210c0, 0x571021, 0xaee379cc, 0x8fa30020, 0x8fa40024,
+0xac4379d0, 0xac4479d4, 0x100000ba, 0xaec00078, 0x1040006b, 0x0,
+0x8ee279cc, 0x24430001, 0x210c0, 0x571021, 0xaee379cc, 0x8fa30020,
+0x8fa40024, 0xac4379d0, 0xac4479d4, 0x8ee279cc, 0x10400058, 0x4821,
+0x3c0a001f, 0x354affff, 0x240cffff, 0x340bffff, 0x4021, 0x8f8700fc,
+0x1173021, 0x14e00007, 0x24c679d0, 0x8ec202a8, 0x1821, 0x24420001,
+0xaec202a8, 0x10000008, 0x8ec202a8, 0x8cc20000, 0x8cc30004, 0xace20000,
+0xace30004, 0x24e20008, 0xaf8200f0, 0x24030001, 0x14600006, 0x2e81021,
+0x8ec20180, 0x24420001, 0xaec20180, 0x10000036, 0x8ec20180, 0x944279d6,
+0x8ec401d8, 0x8ec501dc, 0x401821, 0x1021, 0xa32821, 0xa3302b,
+0x822021, 0x862021, 0x2e81021, 0xaec401d8, 0xaec501dc, 0x8c4279d0,
+0x4a1824, 0x90620000, 0x30420001, 0x1040001b, 0x0, 0x8c620000,
+0x144c000e, 0x0, 0x94620004, 0x144b000b, 0x0, 0x8ec201f0,
+0x8ec301f4, 0x24630001, 0x2c640001, 0x441021, 0xaec201f0, 0xaec301f4,
+0x8ec201f0, 0x10000014, 0x8ec301f4, 0x8ec201e8, 0x8ec301ec, 0x24630001,
+0x2c640001, 0x441021, 0xaec201e8, 0xaec301ec, 0x8ec201e8, 0x1000000a,
+0x8ec301ec, 0x8ec201e0, 0x8ec301e4, 0x24630001, 0x2c640001, 0x441021,
+0xaec201e0, 0xaec301e4, 0x8ec201e0, 0x8ec301e4, 0x8ee279cc, 0x25290001,
+0x122102b, 0x1440ffaf, 0x25080008, 0x8ec20070, 0xa2c00090, 0x8ee379cc,
+0x431023, 0xaec20070, 0x1000004d, 0xaee079cc, 0x8f8600fc, 0x14c00007,
+0x0, 0x8ec202a8, 0x1821, 0x24420001, 0xaec202a8, 0x10000008,
+0x8ec202a8, 0x8fa20020, 0x8fa30024, 0xacc20000, 0xacc30004, 0x24c20008,
+0xaf8200f0, 0x24030001, 0x14600006, 0x0, 0x8ec20180, 0x24420001,
+0xaec20180, 0x10000033, 0x8ec20180, 0x8ec20078, 0x8ec401d8, 0x8ec501dc,
+0x401821, 0x1021, 0xa32821, 0xa3302b, 0x822021, 0x862021,
+0xaec401d8, 0xaec501dc, 0x92220000, 0x30420001, 0x1040001b, 0x2402ffff,
+0x8e230000, 0x1462000e, 0x3402ffff, 0x96230004, 0x1462000b, 0x0,
+0x8ec201f0, 0x8ec301f4, 0x24630001, 0x2c640001, 0x441021, 0xaec201f0,
+0xaec301f4, 0x8ec201f0, 0x10000014, 0x8ec301f4, 0x8ec201e8, 0x8ec301ec,
+0x24630001, 0x2c640001, 0x441021, 0xaec201e8, 0xaec301ec, 0x8ec201e8,
+0x1000000a, 0x8ec301ec, 0x8ec201e0, 0x8ec301e4, 0x24630001, 0x2c640001,
+0x441021, 0xaec201e0, 0xaec301e4, 0x8ec201e0, 0x8ec301e4, 0x8ec20070,
+0x2442ffff, 0xaec20070, 0xaec00078, 0x8ea2001c, 0x96e30450, 0x8ec40024,
+0x24420001, 0x2463ffff, 0x431024, 0x24840001, 0xaec20018, 0xaec40024,
+0x8f42023c, 0x82202b, 0x10800006, 0x0, 0x8fad0044, 0x25a2ffe9,
+0x2c420002, 0x1040012f, 0x0, 0x96e20452, 0x8ed10018, 0x30420020,
+0x1040001e, 0x24070008, 0x8ee40498, 0x8ee5049c, 0x8ec30008, 0x8f860120,
+0x24020019, 0xafa20010, 0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809,
+0x24c6001c, 0x1440000b, 0x24020001, 0x3c040001, 0x24842ca0, 0xafb10010,
+0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f006,
+0x1021, 0x1040008f, 0x24020001, 0x3c010001, 0x370821, 0x100000b4,
+0xac2281d0, 0x8ee40498, 0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020012,
+0xafa20010, 0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c,
+0x1440000b, 0x24020001, 0x3c040001, 0x24842ca0, 0xafb10010, 0xafa00014,
+0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021,
+0x10400094, 0x24020001, 0x10000096, 0x0, 0x15a20043, 0x24020016,
+0x96a3000e, 0x8ec20078, 0x8ec40024, 0x431021, 0xaec20078, 0x8ea3001c,
+0x96e20450, 0x24840001, 0xaec40024, 0x24630001, 0x2442ffff, 0x621824,
+0xaec30018, 0x8f42023c, 0x82202b, 0x148000df, 0x0, 0x96e20452,
+0x8ed10018, 0x30420020, 0x1040001e, 0x24070008, 0x8ee40498, 0x8ee5049c,
+0x8ec30008, 0x8f860120, 0x24020019, 0xafa20010, 0xafb10014, 0xafa30018,
+0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b, 0x24020001, 0x3c040001,
+0x24842ca0, 0xafb10010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009,
+0xc0028eb, 0x34a5f006, 0x1021, 0x1040003f, 0x24020001, 0x3c010001,
+0x370821, 0x10000064, 0xac2281d0, 0x8ee40498, 0x8ee5049c, 0x8ec30008,
+0x8f860120, 0x24020012, 0xafa20010, 0xafb10014, 0xafa30018, 0x8ec200a8,
+0x40f809, 0x24c6001c, 0x1040ffb1, 0x0, 0x1000ffb9, 0x24020001,
+0x8fad0044, 0x15a20063, 0x25a2fffe, 0x96a3000e, 0x8ec20078, 0x431021,
+0xaec20078, 0x8ea3001c, 0x96e20450, 0x24630001, 0x2442ffff, 0x621824,
+0xaec30018, 0x96e20452, 0x8ed10018, 0x30420020, 0x10400023, 0x24070008,
+0x8ee40498, 0x8ee5049c, 0x8ec30008, 0x8f860120, 0x24020019, 0xafa20010,
+0xafb10014, 0xafa30018, 0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b,
+0x24020001, 0x3c040001, 0x24842ca0, 0xafb10010, 0xafa00014, 0x8ec6002c,
+0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f006, 0x1021, 0x14400006,
+0x24020001, 0x24020001, 0x3c010001, 0x370821, 0x10000031, 0xac2281d8,
+0x3c010001, 0x370821, 0x10000021, 0xac2281d0, 0x8ee40498, 0x8ee5049c,
+0x8ec30008, 0x8f860120, 0x24020012, 0xafa20010, 0xafb10014, 0xafa30018,
+0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b, 0x24020001, 0x3c040001,
+0x24842ca0, 0xafb10010, 0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009,
+0xc0028eb, 0x34a5f006, 0x1021, 0x14400005, 0x24020001, 0x3c010001,
+0x370821, 0x10000010, 0xac2281d4, 0x3c010001, 0x370821, 0xac2081d0,
+0x3c010001, 0x370821, 0xac2081d8, 0x3c010001, 0x370821, 0xac2081d4,
+0x8ec20264, 0xaec00024, 0xaed10028, 0x24420001, 0xaec20264, 0x8ec20264,
+0x8ec20278, 0x24420001, 0xaec20278, 0x10000049, 0x8ec20278, 0x2c420002,
+0x10400028, 0x24030040, 0x8ec20034, 0x24420001, 0x50430003, 0x1021,
+0x8ec20034, 0x24420001, 0xaec20034, 0x8ec20034, 0x8ea30018, 0x21080,
+0x571021, 0x8c440cc0, 0x24020003, 0x1462000d, 0x0, 0x92c20065,
+0x50400034, 0x36940040, 0x8ec202c0, 0x8ec3005c, 0x441021, 0xaec202c0,
+0x8ec202c4, 0x641821, 0x306300ff, 0x10000009, 0xaec3005c, 0x8ec202bc,
+0x8ec3003c, 0x441021, 0xaec202bc, 0x8ec202c4, 0x641821, 0x306301ff,
+0xaec3003c, 0x441021, 0xaec202c4, 0x1000001f, 0x36940040, 0x8fad0044,
+0x24020014, 0x15a20010, 0x24020010, 0x3c020001, 0x8c4231d4, 0x10400017,
+0x26e50028, 0x26c40128, 0x240300ff, 0x2406ffff, 0x8ca20000, 0x24a50004,
+0x2463ffff, 0xac820000, 0x1466fffb, 0x24840004, 0x1000000c, 0x0,
+0x11a2000a, 0x3c050008, 0x96a7000e, 0x8ea2001c, 0x3c040001, 0x24842d20,
+0xafb50014, 0xafa20010, 0x8ea60018, 0xc0028eb, 0x34a50910, 0x8fbf0078,
+0x8fbe0074, 0x8fb50070, 0x8fb3006c, 0x8fb10068, 0x3e00008, 0x27bd0080,
+0x3e00008, 0x0, 0x803821, 0x8f8600e4, 0x8f8400e0, 0x2402fff8,
+0x8cc30004, 0x822024, 0x10c4000d, 0x3c020100, 0x3c050100, 0x651024,
+0x1040000c, 0x27623ff8, 0x14c20002, 0x24c20008, 0x27623000, 0x403021,
+0x8cc30004, 0x14c4fff8, 0x651024, 0x3c020100, 0x621024, 0x14400007,
+0x0, 0x8cc20000, 0x8cc30004, 0xace20000, 0xace30004, 0x10000003,
+0x24020001, 0xaf8600e8, 0x1021, 0x3e00008, 0x0, 0x3e00008,
+0x0, 0x8f8300e4, 0x8f8500e0, 0x2402fff8, 0x8c640004, 0xa22824,
+0x1065000d, 0x3c020100, 0x3c060100, 0x861024, 0x10400008, 0x27623ff8,
+0x14620002, 0x24620008, 0x27623000, 0x401821, 0x8c640004, 0x1465fff8,
+0x861024, 0x3c020100, 0xac620004, 0xaf8300e8, 0x54650001, 0x24630008,
+0xaf8300e4, 0x3e00008, 0x0, 0x3e00008, 0x0, 0x8f8600e4,
+0x8f8200e0, 0x2403fff8, 0x431024, 0x14c20003, 0x803821, 0x10000006,
+0x1021, 0x8cc20000, 0x8cc30004, 0xace20000, 0xace30004, 0x24020001,
+0x3e00008, 0x0, 0x3e00008, 0x0, 0x8f8300e4, 0x27623ff8,
+0x14620002, 0x24620008, 0x27623000, 0x401821, 0xaf8300e8, 0xaf8300e4,
+0x3e00008, 0x0, 0x3e00008, 0x0, 0x8f8400e0, 0x8f8800c4,
+0x8f8300e8, 0x2402fff8, 0x823824, 0xe32023, 0x2c821000, 0x50400001,
+0x24841000, 0x420c2, 0x801821, 0x8ec401c0, 0x8ec501c4, 0x1021,
+0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaec401c0, 0xaec501c4,
+0x8f8300c8, 0x8ec20540, 0x1032023, 0x82102b, 0x14400004, 0x801821,
+0x8ec20540, 0x822021, 0x801821, 0x8ec401b8, 0x8ec501bc, 0x1021,
+0xa32821, 0xa3302b, 0x822021, 0x862021, 0xaec401b8, 0xaec501bc,
+0xaf8800c8, 0xaf8700e4, 0xaf8700e8, 0x3e00008, 0x0, 0x27bdff70,
+0xafbf0088, 0xafbe0084, 0xafb50080, 0xafb3007c, 0xafb10078, 0x92c200ed,
+0xa3a0004f, 0x1040000b, 0xa3a00067, 0x8ecd00f0, 0xafad0034, 0x8ece00f4,
+0xafae002c, 0x8ecd00fc, 0x8ed500f8, 0xafad006c, 0x8ece0100, 0x100000d9,
+0xafae003c, 0x3c020001, 0x8c4233b8, 0x40f809, 0x27a40020, 0x1040026e,
+0x0, 0x8fa30024, 0x8fb50020, 0x306dffff, 0x25adfffc, 0xafad0034,
+0x92a20000, 0xafb5002c, 0x30420001, 0x10400017, 0xafa3006c, 0x8ec2011c,
+0x3c03ffff, 0x431024, 0x14400012, 0x2402ffff, 0x8ea30000, 0x14620004,
+0x3402ffff, 0x96a30004, 0x1062000c, 0x0, 0xc0022ad, 0x2a02021,
+0x304200ff, 0x14400007, 0x0, 0x3c020001, 0x8c4233b0, 0x40f809,
+0x0, 0x1000024e, 0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
+0x431024, 0x3c03ffff, 0x432824, 0x14a00003, 0xafa20024, 0x10000053,
+0x1821, 0x3c020080, 0xa21024, 0x50400007, 0x3c040040, 0x8ec202e4,
+0x24420001, 0xaec202e4, 0x8ec202e4, 0x10000049, 0x24030001, 0x3c070004,
+0x3c0c0001, 0x3c0b0002, 0x3c060010, 0x3c0a0008, 0x8ec20178, 0x3c090020,
+0x34088000, 0x24420001, 0xaec20178, 0x8ec20178, 0x851824, 0x10670021,
+0xe3102b, 0x14400007, 0x0, 0x106c0011, 0x0, 0x106b0015,
+0x0, 0x10000030, 0x42042, 0x10660023, 0xc3102b, 0x14400005,
+0x0, 0x106a0019, 0x0, 0x10000028, 0x42042, 0x10690021,
+0x0, 0x10000024, 0x42042, 0x8ec2012c, 0x24420001, 0xaec2012c,
+0x8ec2012c, 0x1000001e, 0x42042, 0x8ec202d4, 0x24420001, 0xaec202d4,
+0x8ec202d4, 0x10000018, 0x42042, 0x8ec202d8, 0x24420001, 0xaec202d8,
+0x8ec202d8, 0x10000012, 0x42042, 0x8ec202dc, 0x24420001, 0xaec202dc,
+0x8ec202dc, 0x1000000c, 0x42042, 0x8ec20128, 0x24420001, 0xaec20128,
+0x8ec20128, 0x10000006, 0x42042, 0x8ec202e0, 0x24420001, 0xaec202e0,
+0x8ec202e0, 0x42042, 0x1488ffc6, 0x851824, 0x24030001, 0x8f420260,
+0x8fae0034, 0x4e102b, 0x10400015, 0x306400ff, 0x8f8200e0, 0xafa20010,
+0x8f8200e4, 0x3c040001, 0x24842dfc, 0xafa20014, 0x8fa60020, 0x8fa70024,
+0x3c050006, 0xc0028eb, 0x34a5f003, 0x8ec30150, 0x8fad006c, 0x3c020100,
+0x24040001, 0x1a26825, 0x24630001, 0xafad006c, 0xaec30150, 0x8ec20150,
+0x1080000f, 0x0, 0x8f420218, 0x30420800, 0x1440000b, 0x3c020180,
+0x8fae006c, 0x1c21024, 0x10400005, 0x0, 0x8ec20174, 0x24420001,
+0xaec20174, 0x8ec20174, 0x100001bd, 0x8fa30034, 0x8f420218, 0x30420400,
+0x10400004, 0x0, 0x8fad0034, 0x25ad0004, 0xafad0034, 0x8ec20050,
+0x5040001d, 0xafa0003c, 0x8fae0034, 0x4e102b, 0x50400019, 0xafa0003c,
+0x8ec20050, 0x1c21023, 0xafa2003c, 0x8ecd0050, 0x10000013, 0xafad0034,
+0x8ec2005c, 0xafa20010, 0x8ec20060, 0x3c040001, 0x24842e08, 0xafa20014,
+0x8ec6003c, 0x8ec70044, 0x3c050006, 0xc0028eb, 0x34a5f002, 0x8ec202b4,
+0x2403ffbf, 0x283a024, 0x24420001, 0xaec202b4, 0x10000172, 0x8ec202b4,
+0x96e20460, 0x8fae0034, 0x4e102b, 0x10400004, 0x0, 0x240d0001,
+0xa3ad004f, 0x8fae0034, 0x11c00189, 0x3c02ffff, 0x8fad006c, 0x1a21024,
+0xafa20074, 0x8ec20068, 0x8f430280, 0x24420001, 0x304203ff, 0x1062015f,
+0x0, 0x93a2004f, 0x10400015, 0x0, 0x8ec3005c, 0x8ec20060,
+0x1062000a, 0x26ce0060, 0x8ec60060, 0xafae0054, 0x8ec30060, 0x21140,
+0x24424dc0, 0x2e28821, 0x24630001, 0x10000014, 0x306300ff, 0x92c20064,
+0x1440ffc9, 0x0, 0x8ec202c8, 0x24420001, 0xaec202c8, 0x8ec202c8,
+0x8ec3003c, 0x8ec20044, 0x1062ffc1, 0x26cd0044, 0x8ec60044, 0xafad0054,
+0x8ec30044, 0x21140, 0x24420dc0, 0x2e28821, 0x24630001, 0x306301ff,
+0xafa3005c, 0x96e20462, 0x30420010, 0x1040001a, 0x340e8100, 0x96a2000c,
+0x144e0017, 0x0, 0x92c200ed, 0x14400014, 0x0, 0x96a2000e,
+0xa6220016, 0x8ea20008, 0x8ea30004, 0x8fad0034, 0x8ea40000, 0x25adfffc,
+0xafad0034, 0xaea2000c, 0xaea30008, 0xaea40004, 0x9622000e, 0x8fae002c,
+0x240d0001, 0xa3ad0067, 0x25ce0004, 0x34420200, 0xafae002c, 0xa622000e,
+0x9627000a, 0x8fae0034, 0xee102b, 0x14400002, 0x30f3fff8, 0x8fb30034,
+0x8e240000, 0x8e250004, 0x8fad002c, 0x24020007, 0xae2d0018, 0xafa20010,
+0xafa60014, 0x8ec20004, 0x8fa6002c, 0xafa20018, 0x8ec200a8, 0x40f809,
+0x2603821, 0x1440001a, 0x3c050006, 0x3c040001, 0x24842e14, 0x8e220018,
+0x34a5f009, 0xafa20010, 0x8e220000, 0x8e230004, 0x2203021, 0x2603821,
+0xc0028eb, 0xafa30014, 0x93a20067, 0x104000fb, 0x0, 0x8ea20004,
+0x8ea30008, 0x8ea4000c, 0x340e8100, 0xa6ae000c, 0xaea20000, 0xaea30004,
+0xaea40008, 0x96220016, 0x100000f0, 0xa6a2000e, 0x8fad0034, 0x166d0089,
+0x0, 0x962e000a, 0xafae0044, 0x8fae003c, 0x9623000e, 0x1ae1021,
+0xa622000a, 0x34620004, 0xa622000e, 0x8fad0074, 0x11a00006, 0x307effff,
+0x34620404, 0xa622000e, 0x8fae006c, 0xe1402, 0xa6220014, 0x8ec30068,
+0x8ee40478, 0x8ee5047c, 0x24020004, 0xafa20010, 0x8ec20068, 0x2203021,
+0x24070020, 0xafa20014, 0x8ec20008, 0x31940, 0x604821, 0xafa20018,
+0x8ec200a8, 0x4021, 0xa92821, 0xa9182b, 0x882021, 0x40f809,
+0x832021, 0x54400018, 0xa2c000ed, 0x97ad0046, 0xa63e000e, 0xa62d000a,
+0x8f820100, 0xafa20010, 0x8f820104, 0x3c040001, 0x24842e20, 0x3c050006,
+0xafa20014, 0x8ec60068, 0x34a5f00b, 0xc0028eb, 0x2203821, 0x93a20067,
+0x104000b6, 0x0, 0x8ea20004, 0x8ea30008, 0x8ea4000c, 0x340e8100,
+0x10000083, 0xa6ae000c, 0x8fae005c, 0x8fad0054, 0xadae0000, 0x8ec202c4,
+0x8ec30068, 0x2442ffff, 0xaec202c4, 0x8ec202c4, 0x24630001, 0x306303ff,
+0x26c20060, 0x15a20006, 0xaec30068, 0x8ec202c0, 0x2442ffff, 0xaec202c0,
+0x10000005, 0x8ec202c0, 0x8ec202bc, 0x2442ffff, 0xaec202bc, 0x8ec202bc,
+0x8ec20048, 0x24420001, 0xaec20048, 0x8f430240, 0x43102b, 0x54400090,
+0xafa00034, 0x8ed10068, 0x8ee40490, 0x8ee50494, 0x8ec30008, 0x8f860120,
+0x24020013, 0xafa20010, 0xafb10014, 0xafa30018, 0x8ec200a8, 0x24070008,
+0x40f809, 0x24c6001c, 0x1440000b, 0x24020001, 0x3c040001, 0x24842dac,
+0xafb10010, 0xafa00014, 0x8ec60068, 0x8f470228, 0x3c050009, 0xc0028eb,
+0x34a5f008, 0x1021, 0x14400005, 0x24020001, 0x3c010001, 0x370821,
+0x1000000a, 0xac2281e0, 0x3c010001, 0x370821, 0xac2081e0, 0x8ec20268,
+0xaec00048, 0xaed1006c, 0x24420001, 0xaec20268, 0x8ec20268, 0x8ec2027c,
+0x24420001, 0xaec2027c, 0x8ec2027c, 0x10000062, 0xafa00034, 0x962d000a,
+0xafad0044, 0x9622000e, 0xa633000a, 0x8fae0074, 0x11c00006, 0x305effff,
+0x34420400, 0xa622000e, 0x8fad006c, 0xd1402, 0xa6220014, 0x8ec30068,
+0x8ee40478, 0x8ee5047c, 0x24020004, 0xafa20010, 0x8ec20068, 0x2203021,
+0x24070020, 0xafa20014, 0x8ec20008, 0x31940, 0x604821, 0xafa20018,
+0x8ec200a8, 0x4021, 0xa92821, 0xa9182b, 0x882021, 0x40f809,
+0x832021, 0x1440001f, 0x3c04001f, 0x97ae0046, 0xa63e000e, 0xa62e000a,
+0x8f820100, 0xafa20010, 0x8f820104, 0x3c040001, 0x24842e20, 0x3c050006,
+0xafa20014, 0x8ec60068, 0x34a5f00d, 0xc0028eb, 0x2203821, 0x93a20067,
+0x10400032, 0x340d8100, 0x8ea20004, 0x8ea30008, 0x8ea4000c, 0xa6ad000c,
+0xaea20000, 0xaea30004, 0xaea40008, 0x96220016, 0xa6a2000e, 0x9622000e,
+0x3042fdff, 0x10000025, 0xa622000e, 0x8ec202c4, 0x8fae002c, 0x3484ffff,
+0x1d37021, 0x2442ffff, 0xafae002c, 0xaec202c4, 0x8ec202c4, 0x8ec302bc,
+0x24020001, 0x8e202b, 0xa2c200ed, 0x2463ffff, 0xaec302bc, 0x10800004,
+0x8ec202bc, 0x8ec20540, 0x1c27023, 0xafae002c, 0x8fad0034, 0x8fae0054,
+0x1b36823, 0xafad0034, 0x8fad005c, 0xadcd0000, 0x8ec20068, 0xa3a0004f,
+0x8ec30048, 0x24420001, 0x304203ff, 0x24630001, 0xaec20068, 0xaec30048,
+0x8fae0034, 0x15c0fe9d, 0x0, 0x8fad0034, 0x11a0001f, 0x0,
+0xaecd00f0, 0x8fae002c, 0xaece00f4, 0xaed500f8, 0x93a20067, 0x10400004,
+0x0, 0x8ec200f8, 0x24420004, 0xaec200f8, 0x8fad006c, 0x8ec20068,
+0xaecd00fc, 0x8fae003c, 0xaece0100, 0x8f430280, 0x24420001, 0x304203ff,
+0x14620006, 0x0, 0x8ec202b8, 0x24420001, 0xaec202b8, 0x10000016,
+0x8ec202b8, 0x8ec202b0, 0x24420001, 0xaec202b0, 0x10000011, 0x8ec202b0,
+0x8fad006c, 0x31a4ffff, 0x2484fffc, 0x801821, 0x8ec401b8, 0x8ec501bc,
+0x3c060001, 0x8cc633b0, 0x1021, 0xa32821, 0xa3382b, 0x822021,
+0x872021, 0xaec401b8, 0xc0f809, 0xaec501bc, 0x8fbf0088, 0x8fbe0084,
+0x8fb50080, 0x8fb3007c, 0x8fb10078, 0x3e00008, 0x27bd0090, 0x3e00008,
+0x0, 0x27bdff90, 0xafbf0068, 0xafbe0064, 0xafb50060, 0xafb3005c,
+0xafb10058, 0x92c200ed, 0xafa0002c, 0x10400007, 0xa3a00037, 0x8ecf00fc,
+0x8ec800f0, 0x8ec900f4, 0x8ed500f8, 0x100000d1, 0xafaf003c, 0x3c020001,
+0x8c4233b8, 0x40f809, 0x27a40020, 0x104001ae, 0x0, 0x8fa30024,
+0x8fb50020, 0x3068ffff, 0x92a20000, 0x2508fffc, 0x2a04821, 0x30420001,
+0x1040001a, 0xafa3003c, 0x8ec2011c, 0x3c03ffff, 0x431024, 0x14400015,
+0x2402ffff, 0x8ea30000, 0x14620005, 0x2a02021, 0x96a30004, 0x3402ffff,
+0x1062000e, 0x0, 0xafa80048, 0xc0022ad, 0xafa9004c, 0x304200ff,
+0x8fa80048, 0x14400007, 0x8fa9004c, 0x3c020001, 0x8c4233b0, 0x40f809,
+0x0, 0x1000018c, 0x0, 0x8fa20024, 0x3c03ffbf, 0x3463ffff,
+0x431024, 0x3c03ffff, 0x432824, 0x14a00003, 0xafa20024, 0x10000053,
+0x1821, 0x3c020080, 0xa21024, 0x50400007, 0x3c040040, 0x8ec202e4,
+0x24420001, 0xaec202e4, 0x8ec202e4, 0x10000049, 0x24030001, 0x3c070004,
+0x3c0e0001, 0x3c0d0002, 0x3c060010, 0x3c0c0008, 0x8ec20178, 0x3c0b0020,
+0x340a8000, 0x24420001, 0xaec20178, 0x8ec20178, 0x851824, 0x10670021,
+0xe3102b, 0x14400007, 0x0, 0x106e0011, 0x0, 0x106d0015,
+0x0, 0x10000030, 0x42042, 0x10660023, 0xc3102b, 0x14400005,
+0x0, 0x106c0019, 0x0, 0x10000028, 0x42042, 0x106b0021,
+0x0, 0x10000024, 0x42042, 0x8ec2012c, 0x24420001, 0xaec2012c,
+0x8ec2012c, 0x1000001e, 0x42042, 0x8ec202d4, 0x24420001, 0xaec202d4,
+0x8ec202d4, 0x10000018, 0x42042, 0x8ec202d8, 0x24420001, 0xaec202d8,
+0x8ec202d8, 0x10000012, 0x42042, 0x8ec202dc, 0x24420001, 0xaec202dc,
+0x8ec202dc, 0x1000000c, 0x42042, 0x8ec20128, 0x24420001, 0xaec20128,
+0x8ec20128, 0x10000006, 0x42042, 0x8ec202e0, 0x24420001, 0xaec202e0,
+0x8ec202e0, 0x42042, 0x148affc6, 0x851824, 0x24030001, 0x8f420260,
+0x48102b, 0x10400019, 0x306400ff, 0x8f8200e0, 0xafa20010, 0x8f8200e4,
+0x3c040001, 0x24842dfc, 0xafa20014, 0x8fa60020, 0x8fa70024, 0x3c050006,
+0x34a5f003, 0xafa80048, 0xc0028eb, 0xafa9004c, 0x8ec30150, 0x8faf003c,
+0x3c020100, 0x24040001, 0x1e27825, 0x24630001, 0xafaf003c, 0xaec30150,
+0x8ec20150, 0x8fa9004c, 0x8fa80048, 0x10800025, 0x0, 0x8f420218,
+0x30420800, 0x14400021, 0x3c020180, 0x8faf003c, 0x1e21024, 0x104000fe,
+0x1001821, 0x8ec20174, 0x24420001, 0xaec20174, 0x8ec20174, 0x100000f8,
+0x1001821, 0x8ec2005c, 0xafa20010, 0x8ec20060, 0x3c040001, 0x24842e08,
+0xafa20014, 0x8ec6003c, 0x8ec70044, 0x3c050006, 0x34a5f002, 0xafa80048,
+0xc0028eb, 0xafa9004c, 0x8ec202b4, 0x2403ffbf, 0x283a024, 0x24420001,
+0xaec202b4, 0x8ec202b4, 0x8fa80048, 0x100000c2, 0x8fa9004c, 0x8f420218,
+0x30420400, 0x54400001, 0x25080004, 0x96e20460, 0x48102b, 0x10400003,
+0x0, 0x3c0f8000, 0xafaf002c, 0x110000d2, 0x3c02ffff, 0x8faf003c,
+0x1e21024, 0xafa20044, 0x8ec20068, 0x8f430280, 0x24420001, 0x304203ff,
+0x106200ad, 0x0, 0x8faf002c, 0x11e00014, 0x0, 0x8ec3005c,
+0x8ec20060, 0x10620009, 0x26cb0060, 0x8ec60060, 0x8ec30060, 0x21140,
+0x24424dc0, 0x2e28821, 0x24630001, 0x10000014, 0x306a00ff, 0x92c20064,
+0x1440ffc4, 0x0, 0x8ec202c8, 0x24420001, 0xaec202c8, 0x8ec202c8,
+0x8ec3003c, 0x8ec20044, 0x1062ffbc, 0x26cb0044, 0x8ec60044, 0xafa0002c,
+0x8ec30044, 0x21140, 0x24420dc0, 0x2e28821, 0x24630001, 0x306a01ff,
+0x96e20462, 0x30420010, 0x10400017, 0x0, 0x96a2000c, 0x340f8100,
+0x144f0013, 0x0, 0x92c200ed, 0x14400010, 0x0, 0x96a2000e,
+0xa6220016, 0x8ea20008, 0x8ea30004, 0x8ea40000, 0x2508fffc, 0xaea2000c,
+0xaea30008, 0xaea40004, 0x9622000e, 0x25290004, 0x240f0001, 0xa3af0037,
+0x34420200, 0xa622000e, 0x9623000a, 0x68102b, 0x14400002, 0x3073fff8,
+0x1009821, 0x92c300ed, 0x2e62003d, 0x2c630001, 0x621824, 0x1060000f,
+0x260f021, 0x9523000c, 0x24020800, 0x5462000c, 0xae290018, 0x91220017,
+0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x50600004,
+0xae290018, 0x95220010, 0x245e000e, 0xae290018, 0x92c300ed, 0x8e240000,
+0x8e250004, 0x8faf002c, 0x2402000b, 0xafa20010, 0x3182b, 0x31ec0,
+0xcf1025, 0x431025, 0xafa20014, 0x8ec20004, 0xafa20018, 0x8ec200a8,
+0x3c03821, 0x1203021, 0xafa80048, 0xafa9004c, 0xafaa0050, 0x40f809,
+0xafab0054, 0x8fa80048, 0x8fa9004c, 0x8faa0050, 0x8fab0054, 0x1440001d,
+0x3c050006, 0x3c040001, 0x24842e14, 0x8e220018, 0x34a5f009, 0xafa20010,
+0x8e220000, 0x8e230004, 0x2203021, 0x3c03821, 0xafa80048, 0xafa9004c,
+0xc0028eb, 0xafa30014, 0x93a20037, 0x8fa80048, 0x8fa9004c, 0x1040002a,
+0x340f8100, 0x8ea20004, 0x8ea30008, 0x8ea4000c, 0xa6af000c, 0xaea20000,
+0xaea30004, 0xaea40008, 0x96220016, 0x10000020, 0xa6a2000e, 0x8faf0044,
+0x11e00007, 0x0, 0x8faf003c, 0x9623000e, 0xf1402, 0x34630400,
+0xa6220014, 0xa623000e, 0x56680008, 0x1334821, 0x9622000e, 0xa628000a,
+0x4021, 0x34420004, 0xa622000e, 0x1000000c, 0xa2c000ed, 0x3c03001f,
+0x3463ffff, 0x24020001, 0x69182b, 0xa633000a, 0x10600003, 0xa2c200ed,
+0x8ec20540, 0x1224823, 0x1134023, 0xafa0002c, 0x1500ff4f, 0xad6a0000,
+0x1100001b, 0x0, 0xaec800f0, 0xaec900f4, 0xaed500f8, 0x93a20037,
+0x10400004, 0x0, 0x8ec200f8, 0x24420004, 0xaec200f8, 0x8faf003c,
+0x8ec20068, 0xaecf00fc, 0x8f430280, 0x24420001, 0x14620006, 0x0,
+0x8ec202b8, 0x24420001, 0xaec202b8, 0x10000016, 0x8ec202b8, 0x8ec202b0,
+0x24420001, 0xaec202b0, 0x10000011, 0x8ec202b0, 0x8faf003c, 0x31e4ffff,
+0x2484fffc, 0x801821, 0x8ec401b8, 0x8ec501bc, 0x3c060001, 0x8cc633b0,
+0x1021, 0xa32821, 0xa3382b, 0x822021, 0x872021, 0xaec401b8,
+0xc0f809, 0xaec501bc, 0x8fbf0068, 0x8fbe0064, 0x8fb50060, 0x8fb3005c,
+0x8fb10058, 0x3e00008, 0x27bd0070, 0x3e00008, 0x0, 0x27bdffd8,
+0xafbf0024, 0xafb10020, 0x8ec30040, 0x8ec20038, 0x1062004d, 0x0,
+0x8ec30038, 0x8ec20040, 0x623823, 0x4e20001, 0x24e70200, 0x8ec30044,
+0x8ec20040, 0x43102b, 0x14400004, 0x24020200, 0x8ec30040, 0x10000005,
+0x431823, 0x8ec20044, 0x8ec30040, 0x431023, 0x2443ffff, 0xe08821,
+0x71102a, 0x54400001, 0x608821, 0x8ec90040, 0x8ee40458, 0x8ee5045c,
+0x8ec60040, 0x113940, 0x24080002, 0xafa80010, 0x8ec80040, 0x94940,
+0x1201821, 0x1021, 0xafa80014, 0x8ec80010, 0xa32821, 0xa3482b,
+0x822021, 0x892021, 0x63140, 0xafa80018, 0x8ec200a4, 0x24c60dc0,
+0x40f809, 0x2e63021, 0x1440000e, 0x24030040, 0x8ec20040, 0xafa20010,
+0x8ec20044, 0x3c040001, 0x24842e2c, 0xafa20014, 0x8ec60038, 0x8ec7003c,
+0x3c050007, 0xc0028eb, 0x34a5f001, 0x10000010, 0x0, 0x8ec20030,
+0x24420001, 0x50430003, 0x1021, 0x8ec20030, 0x24420001, 0xaec20030,
+0x8ec20030, 0x21080, 0x571021, 0xac510cc0, 0x8ec20040, 0x511021,
+0x304201ff, 0xaec20040, 0x8ec30040, 0x8ec20038, 0x14620017, 0x0,
+0x8ec20000, 0x10400007, 0x2403fdff, 0xaf80004c, 0x8f82004c, 0x1040fffd,
+0x0, 0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd,
+0x0, 0x8f820060, 0x431024, 0xaf820060, 0x8ec20000, 0x10400003,
+0x0, 0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0024, 0x8fb10020,
+0x3e00008, 0x27bd0028, 0x3e00008, 0x0, 0x27bdffd8, 0xafbf0024,
+0xafb10020, 0x8ec30058, 0x8ec20054, 0x1062004d, 0x0, 0x8ec30054,
+0x8ec20058, 0x623823, 0x4e20001, 0x24e70100, 0x8ec30060, 0x8ec20058,
+0x43102b, 0x14400004, 0x24020100, 0x8ec30058, 0x10000005, 0x431823,
+0x8ec20060, 0x8ec30058, 0x431023, 0x2443ffff, 0xe08821, 0x71102a,
+0x54400001, 0x608821, 0x8ec90058, 0x8ee40468, 0x8ee5046c, 0x8ec60058,
+0x113940, 0x24080003, 0xafa80010, 0x8ec80058, 0x94940, 0x1201821,
+0x1021, 0xafa80014, 0x8ec80010, 0xa32821, 0xa3482b, 0x822021,
+0x892021, 0x63140, 0xafa80018, 0x8ec200a4, 0x24c64dc0, 0x40f809,
+0x2e63021, 0x1440000e, 0x24030040, 0x8ec20058, 0xafa20010, 0x8ec20060,
+0x3c040001, 0x24842e38, 0xafa20014, 0x8ec60054, 0x8ec7005c, 0x3c050007,
+0xc0028eb, 0x34a5f010, 0x10000010, 0x0, 0x8ec20030, 0x24420001,
+0x50430003, 0x1021, 0x8ec20030, 0x24420001, 0xaec20030, 0x8ec20030,
+0x21080, 0x571021, 0xac510cc0, 0x8ec20058, 0x511021, 0x304200ff,
+0xaec20058, 0x8ec30058, 0x8ec20054, 0x14620017, 0x0, 0x8ec20000,
+0x10400007, 0x2403feff, 0xaf80004c, 0x8f82004c, 0x1040fffd, 0x0,
+0x10000005, 0x0, 0xaf800048, 0x8f820048, 0x1040fffd, 0x0,
+0x8f820060, 0x431024, 0xaf820060, 0x8ec20000, 0x10400003, 0x0,
+0x10000002, 0xaf80004c, 0xaf800048, 0x8fbf0024, 0x8fb10020, 0x3e00008,
+0x27bd0028, 0x3e00008, 0x0, 0x8f820120, 0x8ec300e8, 0x8f820124,
+0x8f860128, 0x24020040, 0x24630001, 0x50620003, 0x1021, 0x8ec200e8,
+0x24420001, 0xaec200e8, 0x8ec200e8, 0x8ec400e8, 0x8ec300e4, 0x210c0,
+0x24426fc0, 0x14830007, 0x2e22821, 0x8f820128, 0x24420020, 0xaf820128,
+0x8f820128, 0x10000011, 0xaca00000, 0x8ec200e8, 0x24030040, 0x24420001,
+0x50430003, 0x1021, 0x8ec200e8, 0x24420001, 0x220c0, 0x2e41021,
+0x8c426fc4, 0x8f830128, 0x21140, 0x621821, 0x2e41021, 0xaf830128,
+0xac406fc0, 0x8cc20018, 0x2443fffe, 0x2c620018, 0x1040000a, 0x31080,
+0x3c010001, 0x220821, 0x8c222e48, 0x400008, 0x0, 0x24020001,
+0x3c010001, 0x370821, 0xac2281e8, 0x3e00008, 0x0, 0x3e00008,
+0x0, 0x27bdffa8, 0xafbf0050, 0xafbe004c, 0xafb50048, 0xafb30044,
+0xafb10040, 0x8f830128, 0x8f820124, 0x106201e1, 0x0, 0x8f9e0128,
+0x8f820128, 0x24420020, 0xaf820128, 0x8fc40018, 0x8f820128, 0x2402000b,
+0x1482018f, 0x24020002, 0x8fc3001c, 0x97c20016, 0x3064ffff, 0xafc20014,
+0x3c028000, 0x621024, 0xafc4001c, 0xafa2002c, 0x8fab002c, 0x3c020800,
+0x11600004, 0x622824, 0x41140, 0x10000003, 0x24424dc0, 0x41140,
+0x24420dc0, 0x2e2a821, 0x96a2000e, 0x3043fffc, 0x30420400, 0x10400003,
+0xa6a3000e, 0x10000137, 0x8821, 0x10a00004, 0x8821, 0x97d10016,
+0x10000132, 0x0, 0x8eab0018, 0xafab0034, 0x9563000c, 0x96eb0462,
+0x24020800, 0x1462012b, 0xafab003c, 0x8fab0034, 0x2573000e, 0x8fab003c,
+0x31620002, 0x1040003f, 0x3c030020, 0x8ec70540, 0x263102b, 0x14400002,
+0x2604821, 0x2674823, 0x25220014, 0x43102b, 0x10400027, 0x24030005,
+0x91220000, 0x3042000f, 0x14430024, 0x1202021, 0x952a0000, 0x25290002,
+0x95280000, 0x25290002, 0x95270000, 0x25290002, 0x95260000, 0x25290002,
+0x95250000, 0x25290002, 0x95230000, 0x25290002, 0x95220000, 0x25290002,
+0x95240000, 0x25290002, 0x1485021, 0x1475021, 0x1465021, 0x1455021,
+0x1435021, 0x1425021, 0x95220000, 0x95230002, 0x1445021, 0x1425021,
+0x1435021, 0xa1c02, 0x3142ffff, 0x625021, 0xa1c02, 0x3142ffff,
+0x10000009, 0x625021, 0x1202021, 0x90850000, 0x3c060020, 0x8ec200ac,
+0x30a5000f, 0x40f809, 0x52840, 0x304affff, 0x3143ffff, 0x50600001,
+0x3403ffff, 0x96a2000e, 0x34420002, 0x10000002, 0xa6a2000e, 0x1821,
+0xa6a30010, 0x8fab003c, 0x31620001, 0x104000e1, 0x0, 0x92620009,
+0x38430006, 0x2c630001, 0x38420011, 0x2c420001, 0x621825, 0x106000d9,
+0x3c030020, 0x8fa60034, 0x8ec70540, 0xc3102b, 0x50400001, 0xc73023,
+0x24c2000e, 0x43102b, 0x1040001a, 0xc02021, 0x94c70000, 0x24c60002,
+0x94c50000, 0x24c60002, 0x94c30000, 0x24c60002, 0x94c20000, 0x24c60002,
+0x94c40000, 0x24c60002, 0xe53821, 0xe33821, 0xe23821, 0x94c20000,
+0x94c30002, 0xe43821, 0xe23821, 0xe33821, 0x71c02, 0x30e2ffff,
+0x623821, 0x71c02, 0x30e2ffff, 0x10000006, 0x623821, 0x8ec200ac,
+0x24050007, 0x40f809, 0x3c060020, 0x3047ffff, 0x8fab003c, 0x31620008,
+0x10400003, 0x30e8ffff, 0x1000005b, 0x4821, 0x96620006, 0x30421fff,
+0x10400007, 0x2602821, 0x92620000, 0x96630002, 0x3042000f, 0x21080,
+0x10000051, 0x624823, 0x3c070020, 0x8ec30540, 0xa7102b, 0x50400001,
+0xa32823, 0x24a20014, 0x47102b, 0x10400015, 0xa02021, 0x90a20000,
+0x94a30002, 0x3042000f, 0x21080, 0x623023, 0xafa20020, 0x90a30009,
+0x24a5000c, 0x94a20000, 0x24a50002, 0x94a40000, 0x24a50002, 0xc33021,
+0xc23021, 0x94a20000, 0x94a30002, 0xc43021, 0xc23021, 0x1000002d,
+0xc33021, 0x24a50002, 0xa7102b, 0x50400001, 0xa32823, 0x94a60000,
+0x802821, 0xa7102b, 0x50400001, 0xa32823, 0x90a20000, 0x24850009,
+0x3042000f, 0x21080, 0xc23023, 0xafa20020, 0xa7102b, 0x50400001,
+0xa32823, 0x90a20000, 0x2485000c, 0xc23021, 0xa7102b, 0x50400001,
+0xa32823, 0x94a20000, 0x24a50002, 0xc23021, 0xa7102b, 0x50400001,
+0xa32823, 0x94a20000, 0x24a50002, 0xc23021, 0xa7102b, 0x50400001,
+0xa32823, 0x94a20000, 0x24a50002, 0xc23021, 0xa7102b, 0x50400001,
+0xa32823, 0x94a20000, 0xc23021, 0x61c02, 0x30c2ffff, 0x623021,
+0x61402, 0x30c3ffff, 0x431021, 0x3049ffff, 0x96a2000e, 0x30420004,
+0x10400041, 0x0, 0x8f420218, 0x30420400, 0x1040003d, 0x3c070020,
+0x97c2000e, 0x8fc30008, 0x8ec60540, 0x621821, 0x2463fffc, 0x67102b,
+0x50400001, 0x661823, 0x602821, 0x24a20004, 0x47102b, 0x5040000a,
+0xa7102b, 0x90a20000, 0x90a40001, 0x90a30002, 0x21200, 0x441021,
+0x90a40003, 0x31a00, 0x10000017, 0x431021, 0x50400001, 0xa62823,
+0x90a20000, 0x24a50001, 0x22200, 0xa7102b, 0x50400001, 0xa62823,
+0x90a20000, 0x24a50001, 0x822021, 0xa7102b, 0x50400001, 0xa62823,
+0x90a20000, 0x24a50001, 0x21200, 0x822021, 0xa7102b, 0x50400001,
+0xa62823, 0x90a20000, 0x822021, 0x41c02, 0x3082ffff, 0x622021,
+0x41402, 0x3083ffff, 0x431021, 0x3042ffff, 0x1024021, 0x81c02,
+0x3102ffff, 0x624021, 0x81c02, 0x3102ffff, 0x624021, 0x3108ffff,
+0x8fc20014, 0x488823, 0x111402, 0x2228821, 0x2298821, 0x111402,
+0x2228821, 0x3231ffff, 0x52200001, 0x3411ffff, 0x96a2000e, 0x34420001,
+0xa6a2000e, 0x96a2000e, 0x24080002, 0x30420004, 0x10400002, 0xa6b10012,
+0x24080004, 0x8ec90068, 0x8ee40478, 0x8ee5047c, 0xafa80010, 0x8ec80068,
+0x8fab002c, 0x2a03021, 0x24070020, 0x10b4025, 0xafa80014, 0x8ec80008,
+0x94940, 0x1201821, 0xafa80018, 0x8ec800a8, 0x1021, 0xa32821,
+0xa3482b, 0x822021, 0x100f809, 0x892021, 0x1440000e, 0x0,
+0x8f820120, 0xafa20010, 0x8f820128, 0x3c040001, 0x24842ea8, 0xafa20014,
+0x8fc6001c, 0x8f870124, 0x3c050008, 0xc0028eb, 0x34a50001, 0x1000005f,
+0x0, 0x8ec20068, 0x24420001, 0x304203ff, 0xaec20068, 0x8fab002c,
+0x11600006, 0x0, 0x8ec202c0, 0x2442ffff, 0xaec202c0, 0x10000005,
+0x8ec202c0, 0x8ec202bc, 0x2442ffff, 0xaec202bc, 0x8ec202bc, 0x8ec202c4,
+0x2442ffff, 0xaec202c4, 0x1000004a, 0x8ec202c4, 0x14820005, 0x24020004,
+0x8ec20048, 0x24420001, 0x10000044, 0xaec20048, 0x14820036, 0x38830011,
+0x97c2001e, 0xafc2001c, 0x8ec20048, 0x24420001, 0xaec20048, 0x8f430240,
+0x43102b, 0x14400039, 0x24070008, 0x8ed10068, 0x8ee40490, 0x8ee50494,
+0x8ec30008, 0x8f860120, 0x24020013, 0xafa20010, 0xafb10014, 0xafa30018,
+0x8ec200a8, 0x40f809, 0x24c6001c, 0x1440000b, 0x24020001, 0x3c040001,
+0x24842dac, 0xafb10010, 0xafa00014, 0x8ec60068, 0x8f470228, 0x3c050009,
+0xc0028eb, 0x34a5f008, 0x1021, 0x14400005, 0x24020001, 0x3c010001,
+0x370821, 0x1000000a, 0xac2281e0, 0x3c010001, 0x370821, 0xac2081e0,
+0x8ec20268, 0xaec00048, 0xaed1006c, 0x24420001, 0xaec20268, 0x8ec20268,
+0x8ec2027c, 0x24420001, 0xaec2027c, 0x1000000d, 0x8ec2027c, 0x2c630001,
+0x38820013, 0x2c420001, 0x621825, 0x14600004, 0x24020001, 0x24020012,
+0x14820004, 0x24020001, 0x3c010001, 0x370821, 0xac2281e8, 0x8fbf0050,
+0x8fbe004c, 0x8fb50048, 0x8fb30044, 0x8fb10040, 0x3e00008, 0x27bd0058,
+0x3e00008, 0x0, 0x0, 0x0, 0x8ec20538, 0xaf8200c0,
+0x8ec20538, 0xaf8200c4, 0x8ec20538, 0xaf8200c8, 0x8ec20534, 0xaf8200d0,
+0x8ec20534, 0xaf8200d4, 0x8ec20534, 0x3e00008, 0xaf8200d8, 0x27bdffe8,
+0x27840208, 0x27450200, 0xafbf0010, 0xc00297e, 0x24060008, 0x8f420204,
+0xc003c3a, 0xaf820210, 0x24040001, 0x8f460248, 0x24020004, 0x3c010001,
+0xac2232ac, 0xc004680, 0x24050004, 0x3c020001, 0x8c4232a8, 0x30420001,
+0x10400007, 0x24020001, 0x3c010001, 0xac2232ac, 0x24040001, 0x24050001,
+0xc004680, 0x3c06601b, 0x8ec20548, 0x8ec4054c, 0x8ec30550, 0x3c010001,
+0xac2032a4, 0x3c010001, 0xac2032bc, 0x21640, 0x42140, 0x34840403,
+0x441025, 0x31bc0, 0x431025, 0xaf82021c, 0x8fbf0010, 0x3e00008,
+0x27bd0018, 0x27bdffe0, 0x3c050008, 0x34a50400, 0xafbf0018, 0xafa00010,
+0xafa00014, 0x8f860200, 0x3c040001, 0x24842f7c, 0xc0028eb, 0x3821,
+0x8ec20368, 0x24420001, 0xaec20368, 0x8ec20368, 0x8f830200, 0x3c023f00,
+0x621824, 0x8fbf0018, 0x3c020400, 0x3e00008, 0x27bd0020, 0x27bdffd8,
+0xafbf0020, 0xafb3001c, 0xafb10018, 0x8f910220, 0x8ec202fc, 0x24420001,
+0xaec202fc, 0x8ec202fc, 0x8ec30310, 0x3c020001, 0x8c4232bc, 0x3c040001,
+0x24842f88, 0xafa20014, 0xafa30010, 0x8ec70314, 0x3c050008, 0xc0028eb,
+0x2203021, 0x3c024000, 0x2221024, 0x104000e5, 0x3c040100, 0x8ec20314,
+0x24420001, 0xaec20314, 0x8ec20314, 0x8f820220, 0x3c0308ff, 0x3463ffff,
+0x431024, 0x34420004, 0xaf820220, 0x8f8200e0, 0x8f8300c4, 0x3c02001f,
+0x3442ffff, 0x24690008, 0x49102b, 0x10400003, 0x0, 0x8ec20540,
+0x1224823, 0x8f8700c8, 0x8f850120, 0x8f840124, 0x10000005, 0x5821,
+0x8ec20534, 0x82102b, 0x50400001, 0x27644800, 0x10a40010, 0x316200ff,
+0x8c820018, 0x38430007, 0x2c630001, 0x3842000b, 0x2c420001, 0x621825,
+0x5060fff3, 0x24840020, 0x8ec20328, 0x240b0001, 0x24420001, 0xaec20328,
+0x8ec20328, 0x8c870008, 0x316200ff, 0x14400078, 0x0, 0x92c200ed,
+0x14400075, 0x0, 0x8f8500e4, 0x8f8200e0, 0x2403fff8, 0x433024,
+0xc51023, 0x218c3, 0x4620001, 0x24630100, 0x8f8a00c4, 0x10600005,
+0x24020001, 0x10620009, 0x0, 0x10000021, 0x0, 0x8ec20318,
+0x1403821, 0x24420001, 0xaec20318, 0x10000060, 0x8ec20318, 0x8ec2031c,
+0x24420001, 0xaec2031c, 0x8ca70000, 0x8ec20540, 0x8ec3031c, 0x1471823,
+0x43102b, 0x10400004, 0x2c62233f, 0x8ec20540, 0x621821, 0x2c62233f,
+0x14400051, 0x3c020100, 0xaca20004, 0x8f8200e8, 0x24420008, 0xaf8200e8,
+0x8f8200e8, 0x8f8200e4, 0x1403821, 0x24420008, 0xaf8200e4, 0x10000046,
+0x8f8200e4, 0x8ec20320, 0x24420001, 0xaec20320, 0x8ca80000, 0x8ec20540,
+0x8ec30320, 0x1092023, 0x44102b, 0x10400003, 0x0, 0x8ec20540,
+0x822021, 0x8ec20544, 0x44102b, 0x10400003, 0x3c030100, 0x10000034,
+0x1003821, 0x8ca20004, 0x431025, 0xaca20004, 0x8f8200e4, 0x24450008,
+0xaf8500e4, 0x8f8500e4, 0x10a60025, 0x3c080100, 0x8ec20174, 0x24420001,
+0xaec20174, 0x8ca20004, 0x8ec30174, 0x481024, 0x1440000e, 0x0,
+0x8ca30000, 0x8ec20540, 0x692023, 0x44102b, 0x10400003, 0x0,
+0x8ec20540, 0x822021, 0x8ec20544, 0x44102b, 0x10400006, 0x0,
+0x603821, 0x8ec20544, 0x44102b, 0x1440000a, 0x0, 0x8ca20004,
+0x481025, 0xaca20004, 0x8f8200e4, 0x24450008, 0xaf8500e4, 0x8f8500e4,
+0x14a6ffdf, 0x0, 0x14a60005, 0x0, 0x1403821, 0xaf8600e4,
+0x10000003, 0xaf8600e8, 0xaf8500e4, 0xaf8500e8, 0x8f8300c8, 0x8ec20540,
+0x692023, 0x44102b, 0x10400003, 0x0, 0x8ec20540, 0x822021,
+0x8ec20544, 0x82102b, 0x50400008, 0x5821, 0x8ec20540, 0xe92023,
+0x44102b, 0x10400003, 0x0, 0x8ec20540, 0x822021, 0x8ec20544,
+0x82102b, 0x10400006, 0x316200ff, 0x1440001c, 0x3c02fdff, 0x92c200ed,
+0x14400019, 0x3c02fdff, 0xaf8700c8, 0x8f8400c8, 0x8f8300c4, 0x8ec20540,
+0x832023, 0x44102b, 0x10400003, 0x0, 0x8ec20540, 0x822021,
+0x8ec20544, 0x2c830001, 0x44102b, 0x431025, 0x10400009, 0x3c02fdff,
+0x8f820220, 0x3c0308ff, 0x3463fffb, 0x431024, 0x3c034000, 0x431025,
+0x10000075, 0xaf820220, 0x3442ffff, 0x8ec30324, 0x282a024, 0x24020001,
+0xa2c200ec, 0x24630001, 0xaec30324, 0x1000006c, 0x8ec20324, 0x2241024,
+0x10400013, 0x3c130200, 0x8ec20300, 0x24420001, 0xaec20300, 0x8ec20300,
+0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x441025, 0xaf820220,
+0x3c020004, 0x2221024, 0x14400005, 0x3c130200, 0xc003a65, 0x0,
+0x10000057, 0x0, 0x2331024, 0x50400008, 0x3c130400, 0x8ec20304,
+0x24420001, 0xaec20304, 0xc003a65, 0x8ec20304, 0x10000019, 0x0,
+0x2331024, 0x1040001d, 0x3c020800, 0x8f830224, 0x24021402, 0x14620009,
+0x3c050008, 0x3c040001, 0x24842f94, 0xafa00010, 0xafa00014, 0x8f860224,
+0x34a5ffff, 0xc0028eb, 0x3821, 0x8ec20308, 0x24420001, 0xaec20308,
+0x8ec20308, 0x8f820220, 0x2202021, 0x34420002, 0xc004430, 0xaf820220,
+0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x531025, 0x1000002e,
+0xaf820220, 0x2221024, 0x10400009, 0x3c050008, 0x3c040001, 0x24842f7c,
+0xafa00010, 0xafa00014, 0x8f860220, 0x34a50403, 0xc0028eb, 0x3821,
+0x3c021000, 0x2221024, 0x10400009, 0x3c050008, 0x3c040001, 0x24842f7c,
+0xafa00010, 0xafa00014, 0x8f860220, 0x34a50401, 0xc0028eb, 0x3821,
+0x3c022000, 0x2221024, 0x10400009, 0x3c050008, 0x3c040001, 0x24842f7c,
+0xafa00010, 0xafa00014, 0x8f860220, 0x34a50402, 0xc0028eb, 0x3821,
+0x6210009, 0x3c050008, 0x3c040001, 0x24842f7c, 0xafa00010, 0xafa00014,
+0x8f860220, 0x34a50404, 0xc0028eb, 0x3821, 0x8fbf0020, 0x8fb3001c,
+0x8fb10018, 0x3e00008, 0x27bd0028, 0x3e00008, 0x0, 0x3c020001,
+0x8c4232bc, 0x27bdffc0, 0xafbf0038, 0xafbe0034, 0xafb50030, 0xafb3002c,
+0x1040000f, 0xafb10028, 0x3c040001, 0x24842fa0, 0x3c050008, 0xafa00010,
+0xafa00014, 0x8f860220, 0x34a50498, 0x24020001, 0x3c010001, 0xac2032bc,
+0x3c010001, 0xac2232b0, 0xc0028eb, 0x3821, 0x3c037fff, 0x8f420268,
+0x3463ffff, 0x3c04fdff, 0x431024, 0xaf420268, 0x8ee204a8, 0x3484ffff,
+0x30420002, 0x10400091, 0x284a024, 0x3c040600, 0x8ee204a8, 0x34842000,
+0x2403fffd, 0x431024, 0xaee204a8, 0xafa40020, 0x8ec3002c, 0x240200ff,
+0x10620004, 0x27a70020, 0x8ec2002c, 0x10000002, 0x24530001, 0x9821,
+0x8f420228, 0x1662000f, 0x0, 0x3c040001, 0x24842f58, 0xafa00010,
+0xafa00014, 0x8ec6002c, 0x8f470228, 0x3c050009, 0xc0028eb, 0x34a5f00f,
+0x8ec202a0, 0x24420001, 0xaec202a0, 0x1000006d, 0x8ec202a0, 0x8ec2002c,
+0x210c0, 0x571021, 0x8ce30000, 0x8ce40004, 0xac4304c0, 0xac4404c4,
+0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9, 0x1040001e,
+0xa821, 0x241e000c, 0x8ec8002c, 0x8ee40428, 0x8ee5042c, 0x8ec6002c,
+0x24070008, 0xafbe0010, 0xafb30014, 0x840c0, 0x1001821, 0x1021,
+0x8ec80008, 0xa32821, 0xa3482b, 0x822021, 0x892021, 0x630c0,
+0xafa80018, 0x8ec200a8, 0x24c604c0, 0x40f809, 0x2e63021, 0x54400006,
+0x24150001, 0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffe5, 0x0,
+0x32a200ff, 0x54400011, 0xaed3002c, 0x3c040001, 0x24842f64, 0xafa00010,
+0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0x10000030, 0x34a5f010,
+0x8ec2026c, 0x24150001, 0x24420001, 0xaec2026c, 0x8ec2026c, 0x1000001f,
+0x32a200ff, 0x8f830054, 0x8f820054, 0x247103e8, 0x2221023, 0x2c4203e9,
+0x10400017, 0xa821, 0x3c1e0020, 0x24130011, 0x8ec20008, 0x8ee40488,
+0x8ee5048c, 0x8ec3002c, 0x8f860120, 0xafb30010, 0x5e1025, 0xafa30014,
+0xafa20018, 0x8ec200a8, 0x24070008, 0x40f809, 0x24c6001c, 0x1440ffe2,
+0x0, 0x8f820054, 0x2221023, 0x2c4203e9, 0x1440ffed, 0x0,
+0x32a200ff, 0x1440000f, 0x0, 0x3c040001, 0x24842f70, 0xafa00010,
+0xafa00014, 0x8f860120, 0x8f870124, 0x3c050009, 0x34a5f011, 0xc0028eb,
+0x0, 0x8ec202d0, 0x24420001, 0xaec202d0, 0x8ec202d0, 0x8ec20250,
+0x24420001, 0xaec20250, 0x8ec20250, 0x8fbf0038, 0x8fbe0034, 0x8fb50030,
+0x8fb3002c, 0x8fb10028, 0x3e00008, 0x27bd0040, 0x3c020001, 0x8c4232bc,
+0x27bdffe0, 0x1440000d, 0xafbf0018, 0x3c040001, 0x24842fac, 0x3c050008,
+0xafa00010, 0xafa00014, 0x8f860220, 0x34a50499, 0x24020001, 0x3c010001,
+0xac2232bc, 0xc0028eb, 0x3821, 0x92c2011d, 0x10400008, 0x24040001,
+0x8f820220, 0x3c0308ff, 0x3463ffff, 0x431024, 0x34420008, 0xaf820220,
+0x24040001, 0xc004785, 0x24050004, 0xaf420268, 0x8fbf0018, 0x3e00008,
+0x27bd0020, 0x0, 0x86102b, 0x50400001, 0x872023, 0xc41023,
+0x24843, 0x125102b, 0x1040001b, 0x91040, 0x824021, 0x88102b,
+0x10400007, 0x1821, 0x94820000, 0x24840002, 0x621821, 0x88102b,
+0x1440fffb, 0x0, 0x602021, 0xc73023, 0xa91023, 0x21040,
+0xc22821, 0xc5102b, 0x10400007, 0x1821, 0x94c20000, 0x24c60002,
+0x621821, 0xc5102b, 0x1440fffb, 0x0, 0x1000000d, 0x832021,
+0x51040, 0x822821, 0x85102b, 0x10400007, 0x1821, 0x94820000,
+0x24840002, 0x621821, 0x85102b, 0x1440fffb, 0x0, 0x602021,
+0x41c02, 0x3082ffff, 0x622021, 0x41c02, 0x3082ffff, 0x622021,
+0x3e00008, 0x3082ffff, 0x3e00008, 0x0, 0x8f820220, 0x34420002,
+0xaf820220, 0x3c020001, 0x8c4254b8, 0x30424000, 0x10400054, 0x24040001,
+0x8f820200, 0x24067fff, 0x8f830200, 0x30450002, 0x2402fffd, 0x621824,
+0xaf830200, 0xaf840204, 0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
+0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820224,
+0x1444004d, 0x42040, 0xc4102b, 0x1040fff1, 0x0, 0x8f820200,
+0x451025, 0xaf820200, 0x8f820220, 0x34428000, 0xaf820220, 0x8f830054,
+0x8f820054, 0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002,
+0x1440fffc, 0x0, 0x8f820220, 0x3c030004, 0x431024, 0x1440000f,
+0x0, 0x8f820220, 0x3c03ffff, 0x34637fff, 0x431024, 0xaf820220,
+0x8f830054, 0x8f820054, 0x10000002, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820220, 0x3c030004, 0x431024,
+0x1440000d, 0x0, 0x8f820220, 0x34428000, 0xaf820220, 0x8f830054,
+0x8f820054, 0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002,
+0x1440fffc, 0x0, 0x8f820220, 0x3c030004, 0x431024, 0x1040001b,
+0x1021, 0x8f830220, 0x24020001, 0x10000015, 0x3c04f700, 0x8f820220,
+0x3c04f700, 0x441025, 0xaf820220, 0x8f820220, 0x2403fffd, 0x431024,
+0xaf820220, 0x8f820220, 0x3c030300, 0x431024, 0x14400003, 0x0,
+0x10000008, 0x1021, 0x8f820220, 0x34420002, 0xaf820220, 0x8f830220,
+0x24020001, 0x641825, 0xaf830220, 0x3e00008, 0x0, 0x2021,
+0x3c050100, 0x24020001, 0xaf80021c, 0xaf820200, 0xaf820220, 0x27625000,
+0xaf8200c0, 0x27625000, 0xaf8200c4, 0x27625000, 0xaf8200c8, 0x27625000,
+0xaf8200d0, 0x27625000, 0xaf8200d4, 0x27625000, 0xaf8200d8, 0x27623000,
+0xaf8200e0, 0x27623000, 0xaf8200e4, 0x27623000, 0xaf8200e8, 0x27622800,
+0xaf8200f0, 0x27622800, 0xaf8200f4, 0x27622800, 0xaf8200f8, 0x418c0,
+0x24840001, 0x3631021, 0xac453004, 0x3631021, 0xac403000, 0x28820200,
+0x1440fff9, 0x418c0, 0x2021, 0x418c0, 0x24840001, 0x3631021,
+0xac402804, 0x3631021, 0xac402800, 0x28820100, 0x1440fff9, 0x418c0,
+0xaf80023c, 0x24030080, 0x24040100, 0xac600000, 0x24630004, 0x64102b,
+0x5440fffd, 0xac600000, 0x8f830040, 0x3c02f000, 0x621824, 0x3c025000,
+0x1062000c, 0x43102b, 0x14400006, 0x3c026000, 0x3c024000, 0x10620008,
+0x24020800, 0x10000008, 0x0, 0x10620004, 0x24020800, 0x10000004,
+0x0, 0x24020700, 0x3c010001, 0xac2232c0, 0x3e00008, 0x0,
+0x27bdffc8, 0xafbf0034, 0xafb50030, 0xafb3002c, 0xafb10028, 0x3c010001,
+0xc00440d, 0xac2032a8, 0x24040001, 0x2821, 0x27a60020, 0x34028000,
+0xc00402a, 0xa7a20020, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, 0x24050001,
+0xc003fe8, 0x27a60020, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, 0x24050001,
+0xc003fe8, 0x27a60020, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, 0x24050002,
+0xc003fe8, 0x27a60018, 0x8f830054, 0x8f820054, 0x10000002, 0x24630064,
+0x8f820054, 0x621023, 0x2c420065, 0x1440fffc, 0x24040001, 0x24050003,
+0xc003fe8, 0x27a6001a, 0x97a20020, 0x10400024, 0x24020001, 0x3c020001,
+0x8c4232a8, 0x97a30018, 0x34420001, 0x3c010001, 0xac2232a8, 0x24020015,
+0x14620004, 0x3402f423, 0x97a3001a, 0x10620018, 0x24020003, 0x97a30018,
+0x24027810, 0x14620014, 0x24020002, 0x97a3001a, 0x24020001, 0x14620010,
+0x24020002, 0x1000000e, 0x24020004, 0x3c020001, 0x8c4232a8, 0x34420008,
+0x3c010001, 0xac2232a8, 0x10000058, 0x24020004, 0x3c020001, 0x8c4232a8,
+0x34420004, 0x3c010001, 0x100000a8, 0xac2232a8, 0x3c010001, 0xac2233dc,
+0x24020e00, 0xaf820238, 0x8f840054, 0x8f820054, 0x24030008, 0x3c010001,
+0xac2332ac, 0x10000002, 0x248401f4, 0x8f820054, 0x821023, 0x2c4201f5,
+0x1440fffc, 0x3c0200c8, 0x344201fb, 0xaf820238, 0x8f830054, 0x8f820054,
+0x10000002, 0x246301f4, 0x8f820054, 0x621023, 0x2c4201f5, 0x1440fffc,
+0x8821, 0x3c1300c8, 0x367301f6, 0x2415fffd, 0xc003f2b, 0x0,
+0x8f830054, 0x8f820054, 0x10000002, 0x246301f4, 0x8f820054, 0x621023,
+0x2c4201f5, 0x1440fffc, 0x0, 0xaf930238, 0x8f830054, 0x8f820054,
+0x10000002, 0x2463000a, 0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc,
+0x0, 0x8f820220, 0x34420002, 0xaf820220, 0x8f820200, 0x24040001,
+0x24057fff, 0x551024, 0xaf820200, 0xaf840204, 0x8f830054, 0x8f820054,
+0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
+0x0, 0x8f820224, 0x14440005, 0x34028000, 0x42040, 0xa4102b,
+0x1040fff0, 0x34028000, 0x1082ffa6, 0x26310001, 0x2e220014, 0x1440ffce,
+0x24020004, 0x3c010001, 0xac2232ac, 0x8821, 0x3c13ffff, 0x36733f7f,
+0xc003f2b, 0x0, 0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
+0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820044,
+0x531024, 0x34425080, 0xaf820044, 0x8f830054, 0x8f820054, 0x10000002,
+0x2463000a, 0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc, 0x0,
+0x8f820044, 0x531024, 0x3442f080, 0xaf820044, 0x8f830054, 0x8f820054,
+0x10000002, 0x2463000a, 0x8f820054, 0x621023, 0x2c42000b, 0x1440fffc,
+0x0, 0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, 0x8f830054,
+0x8f820054, 0x10000002, 0x24630064, 0x8f820054, 0x621023, 0x2c420065,
+0x1440fffc, 0x0, 0x8f820220, 0x24040001, 0x34420002, 0xaf820220,
+0x8f830200, 0x24057fff, 0x2402fffd, 0x621824, 0xaf830200, 0xaf840204,
+0x8f830054, 0x8f820054, 0x10000002, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x8f820224, 0x14440005, 0x34028000,
+0x42040, 0xa4102b, 0x1040fff0, 0x34028000, 0x1082ff57, 0x26310001,
+0x2e220064, 0x1440ffb0, 0x0, 0x3c020001, 0x8c4232a8, 0x30420004,
+0x14400007, 0x3c08fff0, 0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024,
+0xaf820044, 0x3c08fff0, 0x3508bdc0, 0x8f830054, 0x97a60018, 0x3c070001,
+0x8ce733dc, 0x3c040001, 0x24843080, 0x24020001, 0x3c010001, 0xac2232b0,
+0xafa60010, 0x3c060001, 0x8cc632a8, 0x97a2001a, 0x3c05000d, 0x34a50100,
+0x3c010001, 0xac2032ac, 0x681821, 0x3c010001, 0xac2333d4, 0xc0028eb,
+0xafa20014, 0x8fbf0034, 0x8fb50030, 0x8fb3002c, 0x8fb10028, 0x3e00008,
+0x27bd0038, 0x27bdffe8, 0x24070004, 0x3c040001, 0x8c8432ac, 0x3021,
+0x24020001, 0x1482000a, 0xafbf0010, 0x3c020001, 0x8c4254bc, 0x3c050004,
+0x30428000, 0x1040000c, 0x34a593e0, 0x3c05000f, 0x10000009, 0x34a54240,
+0x3c020001, 0x8c4254bc, 0x3c05000f, 0x30428000, 0x10400003, 0x34a54240,
+0x3c05001e, 0x34a58480, 0x3c020001, 0x8c4233d4, 0x8f830054, 0x451021,
+0x431023, 0x45102b, 0x1440002e, 0x0, 0x3c020001, 0x8c4232b4,
+0x1440002a, 0x2cc20001, 0x7182b, 0x431024, 0x1040001d, 0x0,
+0x3c090001, 0x8d2932a8, 0x240b0001, 0x3c054000, 0x3c080001, 0x250854bc,
+0x250afffc, 0x42042, 0x14800002, 0x24e7ffff, 0x24040008, 0x891024,
+0x5040000b, 0x2cc20001, 0x148b0004, 0x0, 0x8d020000, 0x10000003,
+0x451024, 0x8d420000, 0x451024, 0x54400001, 0x24060001, 0x2cc20001,
+0x7182b, 0x431024, 0x5440ffed, 0x42042, 0x3c010001, 0x10c00020,
+0xac2432ac, 0x8f830054, 0x24020001, 0x3c010001, 0xac2232b0, 0x3c010001,
+0xac2333d4, 0x3c020001, 0x8c4232b0, 0x10400004, 0x24020001, 0x3c010001,
+0xac2032b0, 0xaee279c8, 0x8ee379c8, 0x24020008, 0x10620005, 0x24020001,
+0xc003dd7, 0x0, 0x1000000b, 0x0, 0x3c030001, 0x8c6332ac,
+0x10620007, 0x2402000e, 0x3c030001, 0x8c635430, 0x10620003, 0x0,
+0xc004430, 0x8f840220, 0x8fbf0010, 0x3e00008, 0x27bd0018, 0x27bdffe0,
+0x3c03fdff, 0x3c040001, 0x8c8432ac, 0x3c020001, 0x8c4232c4, 0x3463ffff,
+0x283a024, 0x14820006, 0xafbf0018, 0x8ee379c8, 0x3c020001, 0x8c4232c8,
+0x10620006, 0x0, 0x8ee279c8, 0x3c010001, 0xac2432c4, 0x3c010001,
+0xac2232c8, 0x3c030001, 0x8c6332ac, 0x24020002, 0x10620139, 0x2c620003,
+0x10400005, 0x24020001, 0x1062000a, 0x0, 0x10000131, 0x0,
+0x24020004, 0x10620070, 0x24020008, 0x106200ac, 0x24020001, 0x1000012a,
+0x0, 0x8ee279c8, 0x2443ffff, 0x2c620008, 0x10400127, 0x31080,
+0x3c010001, 0x220821, 0x8c223098, 0x400008, 0x0, 0xc003f2b,
+0x0, 0x3c020001, 0x8c4232b8, 0x3c010001, 0xac203240, 0x104000e8,
+0x24020002, 0xaee279c8, 0x3c010001, 0x10000116, 0xac2032b8, 0xc00406b,
+0x0, 0x3c030001, 0x8c6332d0, 0x24020011, 0x1462010f, 0x24020003,
+0x100000aa, 0x0, 0x3c050001, 0x8ca532ac, 0x3c060001, 0x8cc654bc,
+0xc004680, 0x24040001, 0x24020005, 0x3c010001, 0xac2032b8, 0x10000102,
+0xaee279c8, 0x3c040001, 0x2484308c, 0x3c05000f, 0x34a50100, 0x3021,
+0x3821, 0xafa00010, 0xc0028eb, 0xafa00014, 0x100000f7, 0x0,
+0x8f820220, 0x3c03f700, 0x431025, 0x100000ae, 0xaf820220, 0x8f820220,
+0x3c030004, 0x431024, 0x144000bc, 0x24020007, 0x8f830054, 0x3c020001,
+0x8c4233d0, 0x2463d8f0, 0x431023, 0x2c422710, 0x144000e5, 0x24020001,
+0x100000e1, 0x0, 0x3c050001, 0x8ca532ac, 0xc004785, 0x24040001,
+0xc00484d, 0x24040001, 0x3c030001, 0x8c6354b4, 0x46100d7, 0x24020001,
+0x3c020008, 0x621024, 0x10400006, 0x0, 0x8f820214, 0x3c03ffff,
+0x431024, 0x10000005, 0x3442251f, 0x8f820214, 0x3c03ffff, 0x431024,
+0x3442241f, 0xaf820214, 0x8f820220, 0x3c030200, 0x283a025, 0x34420002,
+0xaf820220, 0x24020008, 0xc003b1e, 0xaee279c8, 0x100000c1, 0x0,
+0x8ee279c8, 0x2443ffff, 0x2c620008, 0x104000bc, 0x31080, 0x3c010001,
+0x220821, 0x8c2230b8, 0x400008, 0x0, 0xc003a65, 0x0,
+0x3c010001, 0xac2032b0, 0xaf800204, 0x3c010001, 0xc003f2b, 0xac205480,
+0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024, 0x34425080, 0xaf820044,
+0x8f830054, 0x3c010001, 0xac203240, 0x10000062, 0x24020002, 0x3c020001,
+0x8c4254b8, 0x30424000, 0x10400004, 0x0, 0x8f820044, 0x10000006,
+0x3442f080, 0x8f820044, 0x3c03ffff, 0x34633f7f, 0x431024, 0x3442a080,
+0xaf820044, 0x8f830054, 0x10000051, 0x24020004, 0xc003b78, 0x0,
+0x1040008d, 0x24020001, 0x8f820214, 0x3c03ffff, 0x3c040001, 0x8c8433c8,
+0x431024, 0x3442251f, 0xaf820214, 0x24020008, 0x14800067, 0xaee279c8,
+0x1000006c, 0x0, 0x8ee279c8, 0x2443ffff, 0x2c620007, 0x1040007e,
+0x31080, 0x3c010001, 0x220821, 0x8c2230d8, 0x400008, 0x0,
+0xc003a65, 0x0, 0x3c010001, 0xac2032b0, 0xaf800204, 0x3c010001,
+0xc003f2b, 0xac205480, 0x8f830054, 0x3c010001, 0xac203240, 0x1000002a,
+0x24020002, 0x8f830054, 0x3c020001, 0x8c4233d0, 0x2463d8f0, 0x431023,
+0x2c422710, 0x14400064, 0x24020003, 0x10000062, 0xaee279c8, 0x3c020001,
+0x8c4254b8, 0x30424000, 0x10400003, 0x3c0200c8, 0x10000002, 0x344201f6,
+0x344201fe, 0xaf820238, 0x8f830054, 0x10000014, 0x24020004, 0x8f830054,
+0x3c020001, 0x8c4233d0, 0x2463d8f0, 0x431023, 0x2c422710, 0x1440004e,
+0x24020005, 0x1000004c, 0xaee279c8, 0x8f820220, 0x3c03f700, 0x431025,
+0xaf820220, 0xaf800204, 0x3c010001, 0xac205480, 0x8f830054, 0x24020006,
+0xaee279c8, 0x3c010001, 0x1000003f, 0xac2333d0, 0x3c05fffe, 0x34a57960,
+0x3c040001, 0x8f820054, 0x3c030001, 0x8c6333d0, 0x3484869f, 0x451021,
+0x621823, 0x83202b, 0x10800033, 0x0, 0x24020007, 0x10000030,
+0xaee279c8, 0xc003b78, 0x0, 0x1040002a, 0x24020001, 0x8f820214,
+0x3c03ffff, 0x3c040001, 0x8c8433c8, 0x431024, 0x3442251f, 0xaf820214,
+0x24020008, 0x1080000b, 0xaee279c8, 0x8f820220, 0x34420002, 0xaf820220,
+0x24020001, 0x3c010001, 0xac225430, 0xc004430, 0x8f840220, 0x10000018,
+0x0, 0x8f820220, 0x3c030008, 0x431024, 0x14400013, 0x3c020200,
+0x282a025, 0x2402000e, 0x3c010001, 0xac225430, 0xc00484d, 0x24040001,
+0x8f820220, 0x34420002, 0xc003b1e, 0xaf820220, 0x3c050001, 0x8ca532ac,
+0xc004785, 0x24040001, 0x10000003, 0x0, 0x3c010001, 0xac2232b0,
+0x8fbf0018, 0x3e00008, 0x27bd0020, 0x8f820200, 0x8f820220, 0x8f820220,
+0x34420004, 0xaf820220, 0x8f820200, 0x3c040001, 0x8c8432ac, 0x34420004,
+0xaf820200, 0x24020002, 0x1082003a, 0x2c820003, 0x10400005, 0x24020001,
+0x1082000a, 0x3c03f0ff, 0x100000a8, 0x0, 0x24020004, 0x10820055,
+0x24020008, 0x10820074, 0x3c02f0ff, 0x100000a1, 0x0, 0x8f820050,
+0x3463ffff, 0x3c05ffff, 0x34a53f7f, 0x431024, 0x3c030700, 0x431025,
+0xaf820050, 0x24020e00, 0xaf840200, 0xaf840220, 0xaf820238, 0x8f820044,
+0x3c030001, 0x8c633298, 0x3c040001, 0x8c8433dc, 0x451024, 0x34630022,
+0xaf820044, 0x24020004, 0x1082000c, 0xaf830200, 0x3c020001, 0x8c4232c0,
+0x3c030001, 0x8c6332a4, 0x3c040001, 0x8c84329c, 0x34428000, 0x621825,
+0x641825, 0x1000007e, 0x34620002, 0x3c020001, 0x8c4232a4, 0x3c030001,
+0x8c6332c0, 0x3c040001, 0x8c84329c, 0x431025, 0x441025, 0x10000074,
+0x34420002, 0x8f830050, 0x3c02f0ff, 0x3442ffff, 0x3c040001, 0x8c8433c8,
+0x621824, 0x3c020d00, 0x621825, 0x24020001, 0xaf830050, 0xaf820200,
+0xaf820220, 0x24020e00, 0xaf820238, 0x10800005, 0x3c033f00, 0x3c020001,
+0x8c423290, 0x10000004, 0x34630070, 0x3c020001, 0x8c423290, 0x34630072,
+0x431025, 0xaf820200, 0x3c030001, 0x8c633294, 0x3c04f700, 0x3c020001,
+0x8c4232a4, 0x3c050001, 0x8ca532c0, 0x641825, 0x431025, 0x10000050,
+0x451025, 0x3c03f0ff, 0x8f820050, 0x3463ffff, 0x3c04ffff, 0x431024,
+0x3c030a00, 0x431025, 0xaf820050, 0x24020001, 0xaf820200, 0xaf820220,
+0x24020e01, 0xaf820238, 0x8f820044, 0x34843f7f, 0x3c030001, 0x8c6333c8,
+0x441024, 0x34420080, 0xaf820044, 0x10600005, 0x3c033f00, 0x3c020001,
+0x8c423290, 0x10000004, 0x346300e0, 0x3c020001, 0x8c423290, 0x346300e2,
+0x431025, 0xaf820200, 0x10000025, 0x3c05f700, 0x8f830050, 0x3c040001,
+0x8c8433c8, 0x3442ffff, 0x621824, 0xaf830050, 0x10800013, 0x3c0500c8,
+0x34a501fb, 0x3c063f00, 0x3c030001, 0x8c6332a0, 0x3c040001, 0x8c843290,
+0x34c600e0, 0x24020001, 0xaf820200, 0xaf820220, 0xaf850238, 0x24630001,
+0x862025, 0x3c010001, 0xac2332a0, 0xaf840200, 0x1000000b, 0x3c05f700,
+0x3c0200c8, 0x344201fb, 0x3c030001, 0x8c633290, 0x3c043f00, 0x348400e2,
+0xaf820238, 0x641825, 0xaf830200, 0x3c05f700, 0x34a58000, 0x3c030001,
+0x8c633294, 0x3c020001, 0x8c4232a4, 0x3c040001, 0x8c8432c0, 0x651825,
+0x431025, 0x441025, 0xaf820220, 0x3e00008, 0x0, 0x0,
+0x27bdffd8, 0xafb50018, 0x80a821, 0xafbe001c, 0xa0f021, 0xafb30014,
+0xc09821, 0xafb10010, 0x8821, 0xafbf0020, 0xa6600000, 0xc0043e7,
+0x24040001, 0x26310001, 0x2e220020, 0x1440fffb, 0x0, 0xc0043e7,
+0x2021, 0xc0043e7, 0x24040001, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x2021, 0x24110010, 0x2b11024, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fffa, 0x2b11024, 0x24110010, 0x3d11024,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa,
+0x3d11024, 0xc00440d, 0x34118000, 0xc00440d, 0x0, 0xc0043c7,
+0x0, 0x50400005, 0x118842, 0x96620000, 0x511025, 0xa6620000,
+0x118842, 0x1620fff7, 0x0, 0xc00440d, 0x0, 0x8fbf0020,
+0x8fbe001c, 0x8fb50018, 0x8fb30014, 0x8fb10010, 0x3e00008, 0x27bd0028,
+0x27bdffd8, 0xafb30014, 0x809821, 0xafb50018, 0xa0a821, 0xafbe001c,
+0xc0f021, 0xafb10010, 0x8821, 0xafbf0020, 0xc0043e7, 0x24040001,
+0x26310001, 0x2e220020, 0x1440fffb, 0x0, 0xc0043e7, 0x2021,
+0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001,
+0x24110010, 0x2711024, 0x10400002, 0x2021, 0x24040001, 0xc0043e7,
+0x118842, 0x1620fffa, 0x2711024, 0x24110010, 0x2b11024, 0x10400002,
+0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x2b11024,
+0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0x34118000, 0x97c20000,
+0x511024, 0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842,
+0x1620fff8, 0x0, 0xc00440d, 0x0, 0x8fbf0020, 0x8fbe001c,
+0x8fb50018, 0x8fb30014, 0x8fb10010, 0x3e00008, 0x27bd0028, 0x3c030001,
+0x8c6332d0, 0x3c020001, 0x8c423314, 0x27bdffd8, 0xafbf0020, 0xafb3001c,
+0x10620003, 0xafb10018, 0x3c010001, 0xac233314, 0x2463ffff, 0x2c620013,
+0x10400349, 0x31080, 0x3c010001, 0x220821, 0x8c223100, 0x400008,
+0x0, 0xc00440d, 0x8821, 0x34028000, 0xa7a20010, 0x27b30010,
+0xc0043e7, 0x24040001, 0x26310001, 0x2e220020, 0x1440fffb, 0x0,
+0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021,
+0xc0043e7, 0x24040001, 0x24110010, 0x32220001, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220001, 0x24110010,
+0xc0043e7, 0x2021, 0x118842, 0x1620fffc, 0x0, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x2021, 0x34118000, 0x96620000, 0x511024,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fff8,
+0x0, 0xc00440d, 0x0, 0x1000030e, 0x24020002, 0x27b30010,
+0xa7a00010, 0x8821, 0xc0043e7, 0x24040001, 0x26310001, 0x2e220020,
+0x1440fffb, 0x0, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001,
+0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0x24110010, 0x32220001,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa,
+0x32220001, 0x24110010, 0xc0043e7, 0x2021, 0x118842, 0x1620fffc,
+0x0, 0xc00440d, 0x34118000, 0xc00440d, 0x0, 0xc0043c7,
+0x0, 0x50400005, 0x118842, 0x96620000, 0x511025, 0xa6620000,
+0x118842, 0x1620fff7, 0x0, 0xc00440d, 0x0, 0x97a20010,
+0x30428000, 0x144002dc, 0x24020003, 0x100002d8, 0x0, 0x24021200,
+0xa7a20010, 0x27b30010, 0x8821, 0xc0043e7, 0x24040001, 0x26310001,
+0x2e220020, 0x1440fffb, 0x0, 0xc0043e7, 0x2021, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0x24110010,
+0x32220001, 0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842,
+0x1620fffa, 0x32220001, 0x24110010, 0xc0043e7, 0x2021, 0x118842,
+0x1620fffc, 0x0, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021,
+0x34118000, 0x96620000, 0x511024, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fff8, 0x0, 0xc00440d, 0x0,
+0x8f830054, 0x10000296, 0x24020004, 0x8f830054, 0x3c020001, 0x8c4233d8,
+0x2463ff9c, 0x431023, 0x2c420064, 0x1440029e, 0x24020002, 0x3c030001,
+0x8c6333dc, 0x10620297, 0x2c620003, 0x14400296, 0x24020011, 0x24020003,
+0x10620005, 0x24020004, 0x10620291, 0x2402000f, 0x1000028f, 0x24020011,
+0x1000028d, 0x24020005, 0x24020014, 0xa7a20010, 0x27b30010, 0x8821,
+0xc0043e7, 0x24040001, 0x26310001, 0x2e220020, 0x1440fffb, 0x0,
+0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021,
+0xc0043e7, 0x24040001, 0x24110010, 0x32220001, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220001, 0x24110010,
+0x32220012, 0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842,
+0x1620fffa, 0x32220012, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021,
+0x34118000, 0x96620000, 0x511024, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fff8, 0x0, 0xc00440d, 0x0,
+0x8f830054, 0x10000248, 0x24020006, 0x8f830054, 0x3c020001, 0x8c4233d8,
+0x2463ff9c, 0x431023, 0x2c420064, 0x14400250, 0x24020007, 0x1000024c,
+0x0, 0x24020006, 0xa7a20010, 0x27b30010, 0x8821, 0xc0043e7,
+0x24040001, 0x26310001, 0x2e220020, 0x1440fffb, 0x0, 0xc0043e7,
+0x2021, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0xc0043e7,
+0x24040001, 0x24110010, 0x32220001, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fffa, 0x32220001, 0x24110010, 0x32220013,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa,
+0x32220013, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0x34118000,
+0x96620000, 0x511024, 0x10400002, 0x2021, 0x24040001, 0xc0043e7,
+0x118842, 0x1620fff8, 0x0, 0xc00440d, 0x0, 0x8f830054,
+0x10000207, 0x24020008, 0x8f830054, 0x3c020001, 0x8c4233d8, 0x2463ff9c,
+0x431023, 0x2c420064, 0x1440020f, 0x24020009, 0x1000020b, 0x0,
+0x27b30010, 0xa7a00010, 0x8821, 0xc0043e7, 0x24040001, 0x26310001,
+0x2e220020, 0x1440fffb, 0x0, 0xc0043e7, 0x2021, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0x24110010,
+0x32220001, 0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842,
+0x1620fffa, 0x32220001, 0x24110010, 0x32220018, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220018, 0xc00440d,
+0x34118000, 0xc00440d, 0x0, 0xc0043c7, 0x0, 0x50400005,
+0x118842, 0x96620000, 0x511025, 0xa6620000, 0x118842, 0x1620fff7,
+0x0, 0xc00440d, 0x8821, 0x97a20010, 0x27b30010, 0x34420001,
+0xa7a20010, 0xc0043e7, 0x24040001, 0x26310001, 0x2e220020, 0x1440fffb,
+0x0, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x2021, 0xc0043e7, 0x24040001, 0x24110010, 0x32220001, 0x10400002,
+0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220001,
+0x24110010, 0x32220018, 0x10400002, 0x2021, 0x24040001, 0xc0043e7,
+0x118842, 0x1620fffa, 0x32220018, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x2021, 0x34118000, 0x96620000, 0x511024, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fff8, 0x0, 0xc00440d,
+0x0, 0x8f830054, 0x10000193, 0x2402000a, 0x8f830054, 0x3c020001,
+0x8c4233d8, 0x2463ff9c, 0x431023, 0x2c420064, 0x1440019b, 0x2402000b,
+0x10000197, 0x0, 0x27b30010, 0xa7a00010, 0x8821, 0xc0043e7,
+0x24040001, 0x26310001, 0x2e220020, 0x1440fffb, 0x0, 0xc0043e7,
+0x2021, 0xc0043e7, 0x24040001, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x2021, 0x24110010, 0x32220001, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fffa, 0x32220001, 0x24110010, 0x32220017,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa,
+0x32220017, 0xc00440d, 0x34118000, 0xc00440d, 0x0, 0xc0043c7,
+0x0, 0x50400005, 0x118842, 0x96620000, 0x511025, 0xa6620000,
+0x118842, 0x1620fff7, 0x0, 0xc00440d, 0x8821, 0x97a20010,
+0x27b30010, 0x34420700, 0xa7a20010, 0xc0043e7, 0x24040001, 0x26310001,
+0x2e220020, 0x1440fffb, 0x0, 0xc0043e7, 0x2021, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0x24110010,
+0x32220001, 0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842,
+0x1620fffa, 0x32220001, 0x24110010, 0x32220017, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220017, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x2021, 0x34118000, 0x96620000, 0x511024,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fff8,
+0x0, 0xc00440d, 0x0, 0x8f830054, 0x1000011f, 0x2402000c,
+0x8f830054, 0x3c020001, 0x8c4233d8, 0x2463ff9c, 0x431023, 0x2c420064,
+0x14400127, 0x24020012, 0x10000123, 0x0, 0x27b30010, 0xa7a00010,
+0x8821, 0xc0043e7, 0x24040001, 0x26310001, 0x2e220020, 0x1440fffb,
+0x0, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x2021, 0x24110010, 0x32220001, 0x10400002,
+0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220001,
+0x24110010, 0x32220014, 0x10400002, 0x2021, 0x24040001, 0xc0043e7,
+0x118842, 0x1620fffa, 0x32220014, 0xc00440d, 0x34118000, 0xc00440d,
+0x0, 0xc0043c7, 0x0, 0x50400005, 0x118842, 0x96620000,
+0x511025, 0xa6620000, 0x118842, 0x1620fff7, 0x0, 0xc00440d,
+0x8821, 0x97a20010, 0x27b30010, 0x34420010, 0xa7a20010, 0xc0043e7,
+0x24040001, 0x26310001, 0x2e220020, 0x1440fffb, 0x0, 0xc0043e7,
+0x2021, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0xc0043e7,
+0x24040001, 0x24110010, 0x32220001, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fffa, 0x32220001, 0x24110010, 0x32220014,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa,
+0x32220014, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0x34118000,
+0x96620000, 0x511024, 0x10400002, 0x2021, 0x24040001, 0xc0043e7,
+0x118842, 0x1620fff8, 0x0, 0xc00440d, 0x0, 0x8f830054,
+0x100000ab, 0x24020013, 0x8f830054, 0x3c020001, 0x8c4233d8, 0x2463ff9c,
+0x431023, 0x2c420064, 0x144000b3, 0x2402000d, 0x100000af, 0x0,
+0x27b30010, 0xa7a00010, 0x8821, 0xc0043e7, 0x24040001, 0x26310001,
+0x2e220020, 0x1440fffb, 0x0, 0xc0043e7, 0x2021, 0xc0043e7,
+0x24040001, 0xc0043e7, 0x24040001, 0xc0043e7, 0x2021, 0x24110010,
+0x32220001, 0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842,
+0x1620fffa, 0x32220001, 0x24110010, 0x32220018, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220018, 0xc00440d,
+0x34118000, 0xc00440d, 0x0, 0xc0043c7, 0x0, 0x50400005,
+0x118842, 0x96620000, 0x511025, 0xa6620000, 0x118842, 0x1620fff7,
+0x0, 0xc00440d, 0x8821, 0x97a20010, 0x27b30010, 0x3042fffe,
+0xa7a20010, 0xc0043e7, 0x24040001, 0x26310001, 0x2e220020, 0x1440fffb,
+0x0, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x2021, 0xc0043e7, 0x24040001, 0x24110010, 0x32220001, 0x10400002,
+0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa, 0x32220001,
+0x24110010, 0x32220018, 0x10400002, 0x2021, 0x24040001, 0xc0043e7,
+0x118842, 0x1620fffa, 0x32220018, 0xc0043e7, 0x24040001, 0xc0043e7,
+0x2021, 0x34118000, 0x96620000, 0x511024, 0x10400002, 0x2021,
+0x24040001, 0xc0043e7, 0x118842, 0x1620fff8, 0x0, 0xc00440d,
+0x0, 0x8f830054, 0x10000037, 0x2402000e, 0x24020840, 0xa7a20010,
+0x27b30010, 0x8821, 0xc0043e7, 0x24040001, 0x26310001, 0x2e220020,
+0x1440fffb, 0x0, 0xc0043e7, 0x2021, 0xc0043e7, 0x24040001,
+0xc0043e7, 0x2021, 0xc0043e7, 0x24040001, 0x24110010, 0x32220001,
+0x10400002, 0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fffa,
+0x32220001, 0x24110010, 0x32220013, 0x10400002, 0x2021, 0x24040001,
+0xc0043e7, 0x118842, 0x1620fffa, 0x32220013, 0xc0043e7, 0x24040001,
+0xc0043e7, 0x2021, 0x34118000, 0x96620000, 0x511024, 0x10400002,
+0x2021, 0x24040001, 0xc0043e7, 0x118842, 0x1620fff8, 0x0,
+0xc00440d, 0x0, 0x8f830054, 0x24020010, 0x3c010001, 0xac2232d0,
+0x3c010001, 0x1000000c, 0xac2333d8, 0x8f830054, 0x3c020001, 0x8c4233d8,
+0x2463ff9c, 0x431023, 0x2c420064, 0x14400004, 0x0, 0x24020011,
+0x3c010001, 0xac2232d0, 0x8fbf0020, 0x8fb3001c, 0x8fb10018, 0x3e00008,
+0x27bd0028, 0x8f850044, 0x8f820044, 0x3c030001, 0x431025, 0x3c030008,
+0xaf820044, 0x8f840054, 0x8f820054, 0xa32824, 0x10000002, 0x24840001,
+0x8f820054, 0x821023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820044,
+0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, 0x8f820054,
+0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
+0x0, 0x3e00008, 0xa01021, 0x8f830044, 0x3c02fff0, 0x3442ffff,
+0x42480, 0x621824, 0x3c020002, 0x822025, 0x641825, 0xaf830044,
+0x8f820044, 0x3c030001, 0x431025, 0xaf820044, 0x8f830054, 0x8f820054,
+0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
+0x0, 0x8f820044, 0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044,
+0x8f830054, 0x8f820054, 0x10000002, 0x24630001, 0x8f820054, 0x621023,
+0x2c420002, 0x1440fffc, 0x0, 0x3e00008, 0x0, 0x8f820044,
+0x3c03fff0, 0x3463ffff, 0x431024, 0xaf820044, 0x8f820044, 0x3c030001,
+0x431025, 0xaf820044, 0x8f830054, 0x8f820054, 0x10000002, 0x24630001,
+0x8f820054, 0x621023, 0x2c420002, 0x1440fffc, 0x0, 0x8f820044,
+0x3c03fffe, 0x3463ffff, 0x431024, 0xaf820044, 0x8f830054, 0x8f820054,
+0x10000002, 0x24630001, 0x8f820054, 0x621023, 0x2c420002, 0x1440fffc,
+0x0, 0x3e00008, 0x0, 0x0, 0x27bdffe8, 0xafbf0010,
+0x8ee379c8, 0x24020008, 0x146201ca, 0x0, 0x3c020001, 0x8c4233c8,
+0x14400005, 0x0, 0xc003a65, 0x8f840224, 0x100001c2, 0x0,
+0x8f820220, 0x3c030008, 0x431024, 0x10400026, 0x24020001, 0x8f840224,
+0x8f820220, 0x3c030400, 0x431024, 0x10400006, 0x0, 0x3c010001,
+0xac205440, 0x3c010001, 0x1000000b, 0xac205460, 0x3c030001, 0x24635440,
+0x8c620000, 0x24420001, 0xac620000, 0x2c420002, 0x14400003, 0x24020001,
+0x3c010001, 0xac225460, 0x3c020001, 0x8c425460, 0x10400006, 0x30820040,
+0x10400004, 0x24020001, 0x3c010001, 0x10000003, 0xac225464, 0x3c010001,
+0xac205464, 0x3c010001, 0xac24543c, 0x3c010001, 0x1000000b, 0xac205470,
+0x3c010001, 0xac225470, 0x3c010001, 0xac205460, 0x3c010001, 0xac205440,
+0x3c010001, 0xac205464, 0x3c010001, 0xac20543c, 0x3c030001, 0x8c635430,
+0x3c020001, 0x8c425434, 0x50620004, 0x2463ffff, 0x3c010001, 0xac235434,
+0x2463ffff, 0x2c62000e, 0x1040017e, 0x31080, 0x3c010001, 0x220821,
+0x8c223150, 0x400008, 0x0, 0x3c02fdff, 0x3442ffff, 0x282a024,
+0x24020002, 0x3c010001, 0xac205460, 0x3c010001, 0xac205440, 0x3c010001,
+0xac205470, 0x3c010001, 0xac20543c, 0x3c010001, 0xac205464, 0x3c010001,
+0xac205458, 0x3c010001, 0xac205450, 0xaf800224, 0x3c010001, 0xac225430,
+0xc003a65, 0x0, 0xaf800204, 0x8f820200, 0x2403fffd, 0x431024,
+0xaf820200, 0x3c010001, 0xac205480, 0x8f830054, 0x3c020001, 0x8c425458,
+0x24040001, 0x3c010001, 0xac24546c, 0x24420001, 0x3c010001, 0xac225458,
+0x2c420004, 0x3c010001, 0xac235454, 0x14400006, 0x24020003, 0x3c010001,
+0xac2432b0, 0x3c010001, 0x10000148, 0xac205458, 0x3c010001, 0x10000145,
+0xac225430, 0x8f830054, 0x3c020001, 0x8c425454, 0x2463d8f0, 0x431023,
+0x2c422710, 0x1440013d, 0x24020004, 0x3c010001, 0x1000013a, 0xac225430,
+0x3c040001, 0x8c8433cc, 0x3c010001, 0xc004602, 0xac205448, 0x3c020001,
+0x8c42547c, 0xaf820204, 0x8f820204, 0x30420030, 0x14400125, 0x24020002,
+0x3c030001, 0x8c63547c, 0x24020005, 0x3c010001, 0xac225430, 0x3c010001,
+0x10000126, 0xac235480, 0x3c020001, 0x8c425460, 0x10400122, 0x0,
+0x3c020001, 0x8c42543c, 0x1040011e, 0x0, 0x3c010001, 0xac225468,
+0x24020003, 0x3c010001, 0xac225440, 0x100000c1, 0x24020006, 0x3c010001,
+0xac205448, 0x8f820204, 0x34420040, 0xaf820204, 0x3c020001, 0x8c425480,
+0x24030007, 0x3c010001, 0xac235430, 0x34420040, 0x3c010001, 0xac225480,
+0x3c020001, 0x8c425460, 0x10400005, 0x0, 0x3c020001, 0x8c42543c,
+0x104000f9, 0x24020002, 0x3c050001, 0x24a55440, 0x8ca20000, 0x2c424e21,
+0x104000f3, 0x24020002, 0x3c020001, 0x8c425464, 0x104000f8, 0x2404ffbf,
+0x3c020001, 0x8c42543c, 0x3c030001, 0x8c635468, 0x441024, 0x641824,
+0x14430007, 0x24020001, 0x24020003, 0xaca20000, 0x24020008, 0x3c010001,
+0x100000ea, 0xac225430, 0x3c010001, 0x100000e7, 0xac225430, 0x3c020001,
+0x8c42546c, 0x1040000c, 0x24020001, 0x3c040001, 0xc00460f, 0x8c84543c,
+0x3c020001, 0x8c425488, 0x14400005, 0x24020001, 0x3c020001, 0x8c425484,
+0x10400006, 0x24020001, 0x3c010001, 0xac2232b0, 0x3c010001, 0x100000d3,
+0xac205458, 0x8f820204, 0x34420040, 0xaf820204, 0x3c020001, 0x8c425480,
+0x3c030001, 0x8c635450, 0x34420040, 0x3c010001, 0xac225480, 0x3c020001,
+0x8c42543c, 0x2c630001, 0x318c0, 0x3c010001, 0xac235450, 0x30420008,
+0x3c010001, 0xac22544c, 0x8f830054, 0x24020009, 0x3c010001, 0xac225430,
+0x3c010001, 0x100000b9, 0xac235454, 0x8f830054, 0x3c020001, 0x8c425454,
+0x2463d8f0, 0x431023, 0x2c422710, 0x1440009f, 0x0, 0x3c020001,
+0x8c425460, 0x10400005, 0x0, 0x3c020001, 0x8c42543c, 0x104000a0,
+0x24020002, 0x3c030001, 0x24635440, 0x8c620000, 0x2c424e21, 0x1040009a,
+0x24020002, 0x3c020001, 0x8c42546c, 0x1040000e, 0x0, 0x3c020001,
+0x8c42543c, 0x3c010001, 0xac20546c, 0x30420080, 0x1040002f, 0x2402000c,
+0x8f820204, 0x30420080, 0x1440000c, 0x24020003, 0x10000029, 0x2402000c,
+0x3c020001, 0x8c42543c, 0x30420080, 0x14400005, 0x24020003, 0x8f820204,
+0x30420080, 0x1040001f, 0x24020003, 0xac620000, 0x2402000a, 0x3c010001,
+0xac225430, 0x3c040001, 0x24845478, 0x8c820000, 0x3c030001, 0x8c635450,
+0x431025, 0xaf820204, 0x8c830000, 0x3c040001, 0x8c845450, 0x2402000b,
+0x3c010001, 0xac225430, 0x641825, 0x3c010001, 0xac235480, 0x3c050001,
+0x24a55440, 0x8ca20000, 0x2c424e21, 0x10400066, 0x24020002, 0x3c020001,
+0x8c425470, 0x10400005, 0x0, 0x2402000c, 0x3c010001, 0x10000067,
+0xac225430, 0x3c020001, 0x8c425460, 0x10400063, 0x0, 0x3c040001,
+0x8c84543c, 0x10800055, 0x30820008, 0x3c030001, 0x8c63544c, 0x1062005b,
+0x24020003, 0x3c010001, 0xac245468, 0xaca20000, 0x24020006, 0x3c010001,
+0x10000054, 0xac225430, 0x8f820200, 0x34420002, 0xaf820200, 0x8f830054,
+0x2402000d, 0x3c010001, 0xac225430, 0x3c010001, 0xac235454, 0x8f830054,
+0x3c020001, 0x8c425454, 0x2463d8f0, 0x431023, 0x2c422710, 0x14400031,
+0x0, 0x3c020001, 0x8c425470, 0x10400020, 0x2402000e, 0x3c030001,
+0x8c635484, 0x3c010001, 0x14600015, 0xac225430, 0xc003b1e, 0x0,
+0x3c050001, 0x8ca532ac, 0xc004785, 0x24040001, 0x3c030001, 0x8c6332ac,
+0x24020004, 0x14620005, 0x2403fffb, 0x3c020001, 0x8c4232a8, 0x10000003,
+0x2403fff7, 0x3c020001, 0x8c4232a8, 0x431024, 0x3c010001, 0xac2232a8,
+0x8f830224, 0x3c020200, 0x3c010001, 0xac23548c, 0x10000020, 0x282a025,
+0x3c020001, 0x8c425460, 0x10400005, 0x0, 0x3c020001, 0x8c42543c,
+0x1040000f, 0x24020002, 0x3c020001, 0x8c425440, 0x2c424e21, 0x1040000a,
+0x24020002, 0x3c020001, 0x8c425460, 0x1040000f, 0x0, 0x3c020001,
+0x8c42543c, 0x1440000b, 0x0, 0x24020002, 0x3c010001, 0x10000007,
+0xac225430, 0x3c020001, 0x8c425460, 0x10400003, 0x0, 0xc003a65,
+0x0, 0x8f820220, 0x3c03f700, 0x431025, 0xaf820220, 0x8fbf0010,
+0x3e00008, 0x27bd0018, 0x3c030001, 0x24635488, 0x8c620000, 0x10400005,
+0x34422000, 0x3c010001, 0xac22547c, 0x10000003, 0xac600000, 0x3c010001,
+0xac24547c, 0x3e00008, 0x0, 0x27bdffe0, 0x30820030, 0xafbf0018,
+0x3c010001, 0xac225484, 0x14400067, 0x3c02ffff, 0x34421f0e, 0x821024,
+0x14400061, 0x24020030, 0x30822000, 0x1040005d, 0x30838000, 0x31a02,
+0x30820001, 0x21200, 0x3c040001, 0x8c8433cc, 0x621825, 0x331c2,
+0x3c030001, 0x2463332c, 0x30828000, 0x21202, 0x30840001, 0x42200,
+0x441025, 0x239c2, 0x61080, 0x431021, 0x471021, 0x90430000,
+0x24020001, 0x10620025, 0x0, 0x10600007, 0x24020002, 0x10620013,
+0x24020003, 0x1062002c, 0x3c05000f, 0x10000037, 0x0, 0x8f820200,
+0x2403feff, 0x431024, 0xaf820200, 0x8f820220, 0x3c03fffe, 0x3463ffff,
+0x431024, 0xaf820220, 0x3c010001, 0xac2054c4, 0x3c010001, 0x10000034,
+0xac2054cc, 0x8f820200, 0x34420100, 0xaf820200, 0x8f820220, 0x3c03fffe,
+0x3463ffff, 0x431024, 0xaf820220, 0x24020100, 0x3c010001, 0xac2254c4,
+0x3c010001, 0x10000026, 0xac2054cc, 0x8f820200, 0x2403feff, 0x431024,
+0xaf820200, 0x8f820220, 0x3c030001, 0x431025, 0xaf820220, 0x3c010001,
+0xac2054c4, 0x3c010001, 0x10000019, 0xac2354cc, 0x8f820200, 0x34420100,
+0xaf820200, 0x8f820220, 0x3c030001, 0x431025, 0xaf820220, 0x24020100,
+0x3c010001, 0xac2254c4, 0x3c010001, 0x1000000c, 0xac2354cc, 0x34a5ffff,
+0x3c040001, 0x24843188, 0xafa30010, 0xc0028eb, 0xafa00014, 0x10000004,
+0x0, 0x24020030, 0x3c010001, 0xac225488, 0x8fbf0018, 0x3e00008,
+0x27bd0020, 0x0, 0x27bdffc8, 0xafb30024, 0x809821, 0xafbe002c,
+0xa0f021, 0xafb10020, 0xc08821, 0x3c040001, 0x248431a0, 0x3c050009,
+0x3c020001, 0x8c4232ac, 0x34a59001, 0x2603021, 0x3c03821, 0xafbf0030,
+0xafb50028, 0xa7a0001a, 0xafb10014, 0xc0028eb, 0xafa20010, 0x24020002,
+0x13c200e7, 0x2fc20003, 0x10400005, 0x24020001, 0x13c2000a, 0x3c02fffb,
+0x100000e1, 0x0, 0x24020004, 0x13c2006d, 0x24020008, 0x13c2006c,
+0x3c02ffec, 0x100000da, 0x0, 0x3442ffff, 0x2228824, 0x13a940,
+0x3c010001, 0x350821, 0xac31549c, 0x3c024000, 0x2221024, 0x10400046,
+0x1123c2, 0x30840030, 0x111382, 0x3042000c, 0x3c030001, 0x246332d4,
+0x431021, 0x823821, 0x3c020020, 0x2221024, 0x10400006, 0x24020100,
+0x3c010001, 0x350821, 0xac2254a0, 0x10000005, 0x3c020080, 0x3c010001,
+0x350821, 0xac2054a0, 0x3c020080, 0x2221024, 0x10400006, 0x131940,
+0x3c020001, 0x3c010001, 0x230821, 0x10000005, 0xac2254a8, 0x131140,
+0x3c010001, 0x220821, 0xac2054a8, 0x94e30000, 0x32224000, 0x10400003,
+0xa7a30018, 0x34624000, 0xa7a20018, 0x24040001, 0x94e20002, 0x24050004,
+0x24e60002, 0x34420001, 0xc00402a, 0xa4e20002, 0x24040001, 0x2821,
+0xc00402a, 0x27a60018, 0x3c020001, 0x8c4232ac, 0x24130001, 0x3c010001,
+0xac3332b8, 0x145e0004, 0x32228000, 0xc003a65, 0x0, 0x32228000,
+0x10400093, 0x0, 0xc003a65, 0x0, 0x24020002, 0x3c010001,
+0xac3332b0, 0x3c010001, 0x1000008b, 0xac2232ac, 0x24040001, 0x24050004,
+0x27b1001a, 0xc00402a, 0x2203021, 0x24040001, 0x2821, 0xc00402a,
+0x2203021, 0x3c020001, 0x551021, 0x8c425494, 0x3c040001, 0x8c8432ac,
+0x3c03bfff, 0x3463ffff, 0x3c010001, 0xac3e32b8, 0x431024, 0x3c010001,
+0x350821, 0x109e0072, 0xac225494, 0x10000072, 0x0, 0x3c02ffec,
+0x3442ffff, 0x2228824, 0x3c020008, 0x2228825, 0x131140, 0x3c010001,
+0x220821, 0xac315498, 0x3c022000, 0x2221024, 0x10400005, 0x24020001,
+0x3c010001, 0xac2233c8, 0x10000004, 0x3c024000, 0x3c010001, 0xac2033c8,
+0x3c024000, 0x2221024, 0x1440001a, 0x0, 0x3c020001, 0x8c4233c8,
+0x10400005, 0x24022020, 0x3c010001, 0xac2233cc, 0x24020001, 0xaee279c8,
+0x3c04bfff, 0x131940, 0x3c020001, 0x431021, 0x8c425490, 0x3c050001,
+0x8ca532ac, 0x3484ffff, 0x441024, 0x3c010001, 0x230821, 0xac225490,
+0x24020001, 0x10a20044, 0x0, 0x10000040, 0x0, 0x3c020001,
+0x8c4233c8, 0x1040001c, 0x24022000, 0x3c010001, 0xac2233cc, 0x3c0300a0,
+0x2231024, 0x14430005, 0x131140, 0x3402a000, 0x3c010001, 0x1000002d,
+0xac2233cc, 0x3c030001, 0x621821, 0x8c635498, 0x3c020020, 0x621024,
+0x10400004, 0x24022001, 0x3c010001, 0x10000023, 0xac2233cc, 0x3c020080,
+0x621024, 0x1040001f, 0x3402a001, 0x3c010001, 0x1000001c, 0xac2233cc,
+0x3c020020, 0x2221024, 0x10400007, 0x131940, 0x24020100, 0x3c010001,
+0x230821, 0xac2254a4, 0x10000006, 0x3c020080, 0x131140, 0x3c010001,
+0x220821, 0xac2054a4, 0x3c020080, 0x2221024, 0x10400006, 0x131940,
+0x3c020001, 0x3c010001, 0x230821, 0x10000005, 0xac2254ac, 0x131140,
+0x3c010001, 0x220821, 0xac2054ac, 0x3c030001, 0x8c6332ac, 0x24020001,
+0x10620003, 0x0, 0xc003a65, 0x0, 0x8fbf0030, 0x8fbe002c,
+0x8fb50028, 0x8fb30024, 0x8fb10020, 0x3e00008, 0x27bd0038, 0x27bdffc8,
+0xafb50028, 0xa821, 0xafbe002c, 0xf021, 0xafb30024, 0x9821,
+0x24020002, 0xafbf0030, 0xafb10020, 0xafa4001c, 0xa7a00012, 0x10a2006a,
+0xa7a00010, 0x2ca20003, 0x10400005, 0x24020001, 0x10a2000a, 0x3c024000,
+0x100000ad, 0x2601021, 0x24020004, 0x10a20060, 0x24020008, 0x10a2005e,
+0x2601021, 0x100000a6, 0x0, 0x8fa7001c, 0x78940, 0x3c030001,
+0x711821, 0x8c63549c, 0x621024, 0x14400009, 0x24040001, 0x3c027fff,
+0x3442ffff, 0x629824, 0x3c010001, 0x310821, 0xac335494, 0x10000096,
+0x2601021, 0x24050001, 0xc003fe8, 0x27a60010, 0x24040001, 0x24050001,
+0xc003fe8, 0x27a60010, 0x97a20010, 0x30420004, 0x10400034, 0x3c134000,
+0x3c030001, 0x8c6333dc, 0x24020003, 0x10620008, 0x2c620004, 0x14400029,
+0x3c028000, 0x24020004, 0x10620014, 0x24040001, 0x10000024, 0x3c028000,
+0x24040001, 0x24050011, 0x27b10012, 0xc003fe8, 0x2203021, 0x24040001,
+0x24050011, 0xc003fe8, 0x2203021, 0x97a30012, 0x30624000, 0x10400002,
+0x3c1e0010, 0x3c1e0008, 0x3c150001, 0x10000010, 0x30628000, 0x24050014,
+0x27b10012, 0xc003fe8, 0x2203021, 0x24040001, 0x24050014, 0xc003fe8,
+0x2203021, 0x97a30012, 0x30621000, 0x10400002, 0x3c1e0010, 0x3c1e0008,
+0x3c150001, 0x30620800, 0x54400001, 0x3c150002, 0x3c028000, 0x2621025,
+0x2be1825, 0x10000007, 0x439825, 0x3c130001, 0x2719821, 0x8e73549c,
+0x3c027fff, 0x3442ffff, 0x2629824, 0x8fa7001c, 0x71140, 0x3c010001,
+0x220821, 0xac335494, 0x1000004b, 0x2601021, 0x8fa7001c, 0x72140,
+0x3c030001, 0x641821, 0x8c635498, 0x3c024000, 0x621024, 0x14400008,
+0x3c027fff, 0x3442ffff, 0x629824, 0x3c010001, 0x240821, 0xac335490,
+0x1000003b, 0x2601021, 0x3c020001, 0x8c4232bc, 0x1040002e, 0x3c13c00c,
+0x3c020001, 0x8c4233c8, 0x3c03e00c, 0x3c010001, 0x240821, 0x8c2454a4,
+0x2102b, 0x21023, 0x431024, 0x10800004, 0x539825, 0x3c020020,
+0x10000004, 0x2629825, 0x3c02ffdf, 0x3442ffff, 0x2629824, 0x8fa7001c,
+0x71140, 0x3c010001, 0x220821, 0x8c2254ac, 0x10400003, 0x3c020080,
+0x10000004, 0x2629825, 0x3c02ff7f, 0x3442ffff, 0x2629824, 0x3c020001,
+0x8c423320, 0x10400002, 0x3c020800, 0x2629825, 0x3c020001, 0x8c423324,
+0x10400002, 0x3c020400, 0x2629825, 0x3c020001, 0x8c423328, 0x10400006,
+0x3c020100, 0x10000004, 0x2629825, 0x3c027fff, 0x3442ffff, 0x629824,
+0x8fa7001c, 0x71140, 0x3c010001, 0x220821, 0xac335490, 0x2601021,
+0x8fbf0030, 0x8fbe002c, 0x8fb50028, 0x8fb30024, 0x8fb10020, 0x3e00008,
+0x27bd0038, 0x27bdffe0, 0xafb50018, 0x80a821, 0xafbf001c, 0xafb30014,
+0xafb10010, 0x8f840200, 0x3c030001, 0x8c6332ac, 0x8f860220, 0x24020002,
+0x106200a3, 0x2c620003, 0x10400005, 0x24020001, 0x1062000a, 0x151940,
+0x1000009d, 0x0, 0x24020004, 0x10620053, 0x24020008, 0x10620052,
+0x159940, 0x10000096, 0x0, 0x3c050001, 0xa32821, 0x8ca5549c,
+0x3c110001, 0x2238821, 0x8e315494, 0x3c024000, 0xa21024, 0x10400038,
+0x3c020008, 0x2221024, 0x10400020, 0x34840002, 0x3c020001, 0x431021,
+0x8c4254a0, 0x10400005, 0x34840020, 0x34840100, 0x3c020020, 0x10000006,
+0x2228825, 0x2402feff, 0x822024, 0x3c02ffdf, 0x3442ffff, 0x2228824,
+0x151140, 0x3c010001, 0x220821, 0x8c2254a8, 0x10400005, 0x3c020001,
+0xc23025, 0x3c020080, 0x10000016, 0x2228825, 0x3c02fffe, 0x3442ffff,
+0xc23024, 0x3c02ff7f, 0x3442ffff, 0x1000000f, 0x2228824, 0x2402fedf,
+0x822024, 0x3c02fffe, 0x3442ffff, 0xc23024, 0x3c02ff5f, 0x3442ffff,
+0x2228824, 0x3c010001, 0x230821, 0xac2054a0, 0x3c010001, 0x230821,
+0xac2054a8, 0xaf840200, 0xaf860220, 0x8f820220, 0x34420002, 0xaf820220,
+0x1000000a, 0x151140, 0x3c02bfff, 0x3442ffff, 0x8f830200, 0x2228824,
+0x2402fffd, 0x621824, 0xc003a65, 0xaf830200, 0x151140, 0x3c010001,
+0x220821, 0x10000048, 0xac315494, 0x159940, 0x3c050001, 0xb32821,
+0x8ca55498, 0x3c110001, 0x2338821, 0x8e315490, 0x3c024000, 0xa21024,
+0x14400010, 0x0, 0x3c020001, 0x8c4233c8, 0x14400005, 0x3c02bfff,
+0x8f820200, 0x34420002, 0xaf820200, 0x3c02bfff, 0x3442ffff, 0xc003a65,
+0x2228824, 0x3c010001, 0x330821, 0x1000002e, 0xac315490, 0x3c020001,
+0x8c4233c8, 0x14400027, 0x151140, 0x3c020020, 0xa21024, 0x10400007,
+0x34840020, 0x24020100, 0x3c010001, 0x330821, 0xac2254a4, 0x10000006,
+0x34840100, 0x3c010001, 0x330821, 0xac2054a4, 0x2402feff, 0x822024,
+0x3c020080, 0xa21024, 0x10400007, 0x151940, 0x3c020001, 0x3c010001,
+0x230821, 0xac2254ac, 0x10000008, 0xc23025, 0x151140, 0x3c010001,
+0x220821, 0xac2054ac, 0x3c02fffe, 0x3442ffff, 0xc23024, 0xaf840200,
+0xaf860220, 0x8f820220, 0x34420002, 0xaf820220, 0x151140, 0x3c010001,
+0x220821, 0xac315490, 0x8fbf001c, 0x8fb50018, 0x8fb30014, 0x8fb10010,
+0x3e00008, 0x27bd0020, 0x0, 0x0, 0x1821, 0x308400ff,
+0x2405ffdf, 0x2406ffbf, 0x641007, 0x30420001, 0x10400004, 0x0,
+0x8f820044, 0x10000003, 0x34420040, 0x8f820044, 0x461024, 0xaf820044,
+0x8f820044, 0x34420020, 0xaf820044, 0x8f820044, 0x451024, 0xaf820044,
+0x24630001, 0x28620008, 0x5440ffee, 0x641007, 0x3e00008, 0x0,
+0x0, 0x0, 0x0 };
+u32 tigon2FwData[(MAX_DATA_LEN/4) + 1] = {
+0x1, 0x1, 0x1, 0xc001fc, 0x3ffc, 0xc00000,
+0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x0, 0x0,
+0x416c7465, 0x6f6e2041, 0x63654e49, 0x43205600, 0x42424242, 0x0,
+0x0, 0x0, 0x1ffffc, 0x1fff7c, 0x0, 0x0,
+0x1, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x60cf00, 0x60, 0xcf000000, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x3, 0x0, 0x1, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x1, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x1000000, 0x21000000,
+0x12000140, 0x0, 0x0, 0x20000000, 0x120000a0, 0x0,
+0x12000060, 0x12000180, 0x120001e0, 0x0, 0x0, 0x0,
+0x0, 0x0, 0x0, 0x0, 0x30001, 0x1,
+0x30201, 0x0, 0x0 };
+u32 tigon2FwRodata[(MAX_RODATA_LEN/4) + 1] = {
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x66776d61,
+0x696e2e63, 0x2c762031, 0x2e312e34, 0x372e3420, 0x31393938, 0x2f31302f,
+0x31342031, 0x393a3330, 0x3a323920, 0x73687561, 0x6e672045, 0x78702024,
+0x0, 0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51, 0x64527845,
+0x0, 0x6576526e, 0x6746756c, 0x6c000000, 0x3f456e71, 0x45767400,
+0x3f6e6f51, 0x64457650, 0x0, 0x6661696c, 0x456e454d, 0x0,
+0x656e714d, 0x45764661, 0x696c0000, 0x656e714d, 0x45765046, 0x61696c00,
+0x3f6d656d, 0x53697a65, 0x0, 0x65787453, 0x746b5067, 0x0,
+0x4441574e, 0x2d310000, 0x4441574e, 0x2d320000, 0x4441574e, 0x2d330000,
+0x5245445a, 0x4f4e4531, 0x0, 0x42616453, 0x6e64526e, 0x67000000,
+0x496e666f, 0x2d336d42, 0x0, 0x76357373, 0x72616d00, 0x3f737731,
+0x646d6100, 0x536e6443, 0x6b53756d, 0x0, 0x646d6141, 0x6c69676e,
+0x0, 0x52637643, 0x6b53756d, 0x0, 0x496c6c43, 0x6f6e6652,
+0x78000000, 0x766c616e, 0x52434200, 0x52656376, 0x566c616e, 0x0,
+0x496e666f, 0x2d336d45, 0x0, 0x66774f50, 0x6661696c, 0x0,
+0x696e7453, 0x746b4572, 0x0, 0x70726f62, 0x654d656d, 0x0,
+0x436f7079, 0x0, 0x4e6f7443, 0x6f707900, 0x4441574e, 0x2d420000,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x74696d65,
+0x722e632c, 0x7620312e, 0x312e3139, 0x2e332031, 0x3939382f, 0x31302f30,
+0x37203233, 0x3a34333a, 0x30302066, 0x6877616e, 0x67204578, 0x70202400,
+0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51, 0x64527845, 0x0,
+0x6576526e, 0x6746756c, 0x6c000000, 0x3f456e71, 0x45767400, 0x3f6e6f51,
+0x64457650, 0x0, 0x6661696c, 0x456e454d, 0x0, 0x656e714d,
+0x45764661, 0x696c0000, 0x656e714d, 0x45765046, 0x61696c00, 0x542d446d,
+0x61526432, 0x0, 0x542d446d, 0x61526431, 0x0, 0x542d446d,
+0x61526442, 0x0, 0x542d446d, 0x61577232, 0x0, 0x542d446d,
+0x61577231, 0x0, 0x542d446d, 0x61577242, 0x0, 0x0,
+0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563,
+0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d,
+0x6d6f6e2f, 0x636f6d6d, 0x616e642e, 0x632c7620, 0x312e312e, 0x322e3232,
+0x20313939, 0x382f3037, 0x2f323920, 0x32323a33, 0x313a3030, 0x20736875,
+0x616e6720, 0x45787020, 0x24000000, 0x3f6e6f51, 0x64547845, 0x0,
+0x3f6e6f51, 0x64527845, 0x0, 0x6576526e, 0x6746756c, 0x6c000000,
+0x3f456e71, 0x45767400, 0x3f6e6f51, 0x64457650, 0x0, 0x6661696c,
+0x456e454d, 0x0, 0x656e714d, 0x45764661, 0x696c0000, 0x656e714d,
+0x45765046, 0x61696c00, 0x3f4d626f, 0x78457674, 0x0, 0x68737465,
+0x5f455252, 0x0, 0x6d437374, 0x4d644552, 0x52000000, 0x70726f6d,
+0x4d644552, 0x52000000, 0x6c6e6b43, 0x6d644572, 0x72000000, 0x636d645f,
+0x45525200, 0x0, 0x7fa0, 0x8630, 0x8630, 0x85ac,
+0x835c, 0x85f8, 0x8630, 0x8080, 0x8090, 0x8178,
+0x824c, 0x8218, 0x8630, 0x80a0, 0x8308, 0x8630,
+0x8318, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563,
+0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d,
+0x6d6f6e2f, 0x6d636173, 0x742e632c, 0x7620312e, 0x312e322e, 0x35203139,
+0x39382f30, 0x342f3234, 0x2030303a, 0x30303a33, 0x39206861, 0x79657320,
+0x45787020, 0x24000000, 0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51,
+0x64527845, 0x0, 0x6576526e, 0x6746756c, 0x6c000000, 0x3f456e71,
+0x45767400, 0x3f6e6f51, 0x64457650, 0x0, 0x6661696c, 0x456e454d,
+0x0, 0x656e714d, 0x45764661, 0x696c0000, 0x656e714d, 0x45765046,
+0x61696c00, 0x4d634164, 0x64447570, 0x0, 0x4d634164, 0x6446756c,
+0x0, 0x4d634465, 0x6c4e6f45, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x646d612e, 0x632c7620, 0x312e312e,
+0x31322e31, 0x20313939, 0x382f3038, 0x2f303420, 0x32313a35, 0x343a3339,
+0x20736875, 0x616e6720, 0x45787020, 0x24000000, 0x3f6e6f51, 0x64547845,
+0x0, 0x3f6e6f51, 0x64527845, 0x0, 0x6576526e, 0x6746756c,
+0x6c000000, 0x3f456e71, 0x45767400, 0x3f6e6f51, 0x64457650, 0x0,
+0x6661696c, 0x456e454d, 0x0, 0x656e714d, 0x45764661, 0x696c0000,
+0x656e714d, 0x45765046, 0x61696c00, 0x646d6172, 0x6441544e, 0x0,
+0x646d6177, 0x7241544e, 0x0, 0x0, 0x0, 0x0,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x74726163,
+0x652e632c, 0x7620312e, 0x312e322e, 0x34203139, 0x39382f30, 0x342f3234,
+0x2030303a, 0x30303a34, 0x35206861, 0x79657320, 0x45787020, 0x24000000,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x64617461,
+0x2e632c76, 0x20312e31, 0x2e322e34, 0x20313939, 0x382f3036, 0x2f323320,
+0x30313a32, 0x393a3330, 0x20736875, 0x616e6720, 0x45787020, 0x24000000,
+0x46575f56, 0x45525349, 0x4f4e3a20, 0x23312046, 0x7269204f, 0x63742031,
+0x36203130, 0x3a31353a, 0x30362050, 0x44542031, 0x39393800, 0x46575f43,
+0x4f4d5049, 0x4c455f54, 0x494d453a, 0x2031303a, 0x31353a30, 0x36000000,
+0x46575f43, 0x4f4d5049, 0x4c455f42, 0x593a2064, 0x65767263, 0x73000000,
+0x46575f43, 0x4f4d5049, 0x4c455f48, 0x4f53543a, 0x20636f6d, 0x70757465,
+0x0, 0x46575f43, 0x4f4d5049, 0x4c455f44, 0x4f4d4149, 0x4e3a2065,
+0x6e672e61, 0x6374656f, 0x6e2e636f, 0x6d000000, 0x46575f43, 0x4f4d5049,
+0x4c45523a, 0x20676363, 0x20766572, 0x73696f6e, 0x20322e37, 0x2e320000,
+0x0, 0x0, 0x0, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x6d656d2e, 0x632c7620, 0x312e312e,
+0x322e3420, 0x31393938, 0x2f30342f, 0x32342030, 0x303a3030, 0x3a343020,
+0x68617965, 0x73204578, 0x70202400, 0x0, 0x24486561, 0x6465723a,
+0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963,
+0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x73656e64, 0x2e632c76, 0x20312e31,
+0x2e32322e, 0x33203139, 0x39382f30, 0x392f3137, 0x2032313a, 0x32343a33,
+0x38207368, 0x75616e67, 0x20457870, 0x20240000, 0x3f6e6f51, 0x64547845,
+0x0, 0x3f6e6f51, 0x64527845, 0x0, 0x6576526e, 0x6746756c,
+0x6c000000, 0x3f456e71, 0x45767400, 0x3f6e6f51, 0x64457650, 0x0,
+0x6661696c, 0x456e454d, 0x0, 0x656e714d, 0x45764661, 0x696c0000,
+0x656e714d, 0x45765046, 0x61696c00, 0x736e6464, 0x654e6f51, 0x20000000,
+0x6e6f454e, 0x515f5458, 0x0, 0x736e6464, 0x744e6f51, 0x20000000,
+0x756e6b72, 0x64747970, 0x65000000, 0x3f546370, 0x436b7375, 0x6d000000,
+0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563,
+0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d,
+0x6d6f6e2f, 0x72656376, 0x2e632c76, 0x20312e31, 0x2e322e33, 0x35203139,
+0x39382f30, 0x372f3239, 0x2030303a, 0x30373a32, 0x37207368, 0x75616e67,
+0x20457870, 0x20240000, 0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51,
+0x64527845, 0x0, 0x6576526e, 0x6746756c, 0x6c000000, 0x3f456e71,
+0x45767400, 0x3f6e6f51, 0x64457650, 0x0, 0x6661696c, 0x456e454d,
+0x0, 0x656e714d, 0x45764661, 0x696c0000, 0x656e714d, 0x45765046,
+0x61696c00, 0x66726d32, 0x4c617267, 0x65000000, 0x72784e6f, 0x52784264,
+0x0, 0x72785144, 0x6d614446, 0x0, 0x72785144, 0x6d614246,
+0x0, 0x3f724264, 0x446d6146, 0x0, 0x3f724a42, 0x64446d46,
+0x0, 0x0, 0xdabc, 0xdabc, 0xdabc, 0xdabc,
+0xdabc, 0xdabc, 0xdabc, 0xdabc, 0xdabc, 0xdabc,
+0xdabc, 0xdabc, 0xdabc, 0xdabc, 0xdabc, 0xdaac,
+0xdaac, 0xdaac, 0xdabc, 0xdabc, 0xdabc, 0xdabc,
+0xdabc, 0xdabc, 0x572d444d, 0x41456e46, 0x0, 0x0,
+0x0, 0x0, 0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563,
+0x74732f72, 0x63732f73, 0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d,
+0x6d6f6e2f, 0x6d61632e, 0x632c7620, 0x312e312e, 0x31372e31, 0x20313939,
+0x382f3038, 0x2f323720, 0x32323a31, 0x333a3230, 0x20736875, 0x616e6720,
+0x45787020, 0x24000000, 0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51,
+0x64527845, 0x0, 0x6576526e, 0x6746756c, 0x6c000000, 0x3f456e71,
+0x45767400, 0x3f6e6f51, 0x64457650, 0x0, 0x6661696c, 0x456e454d,
+0x0, 0x656e714d, 0x45764661, 0x696c0000, 0x656e714d, 0x45765046,
+0x61696c00, 0x6d616374, 0x7841544e, 0x0, 0x684d6352, 0x7841746e,
+0x0, 0x72656d61, 0x73737274, 0x0, 0x6c696e6b, 0x444f574e,
+0x0, 0x6c696e6b, 0x55500000, 0x0, 0x0, 0x0,
+0x24486561, 0x6465723a, 0x202f7072, 0x6f6a6563, 0x74732f72, 0x63732f73,
+0x772f6765, 0x2f6e6963, 0x2f667732, 0x2f636f6d, 0x6d6f6e2f, 0x636b7375,
+0x6d2e632c, 0x7620312e, 0x312e322e, 0x36203139, 0x39382f30, 0x362f3233,
+0x2030313a, 0x32393a32, 0x37207368, 0x75616e67, 0x20457870, 0x20240000,
+0x3f6e6f51, 0x64547845, 0x0, 0x3f6e6f51, 0x64527845, 0x0,
+0x6576526e, 0x6746756c, 0x6c000000, 0x3f456e71, 0x45767400, 0x3f6e6f51,
+0x64457650, 0x0, 0x6661696c, 0x456e454d, 0x0, 0x656e714d,
+0x45764661, 0x696c0000, 0x656e714d, 0x45765046, 0x61696c00, 0x0,
+0x50726f62, 0x65506879, 0x0, 0x6c6e6b41, 0x53535254, 0x0,
+0xf81c, 0xf84c, 0xf870, 0xf89c, 0xf8c8, 0xf8dc,
+0xf918, 0xfca0, 0xf9c8, 0xfaf4, 0xfa14, 0xfb4c,
+0xfb74, 0xfba8, 0xfa58, 0xfca0, 0xfac0, 0xfaf4,
+0xfb1c, 0xfb4c, 0xfb74, 0xfba8, 0xfbe4, 0x0,
+0x0, 0x0, 0x101fc, 0x102cc, 0x103a4, 0x10474,
+0x104d0, 0x105ac, 0x105d4, 0x106b0, 0x106d8, 0x10880,
+0x108a8, 0x10a50, 0x10c48, 0x10edc, 0x10df0, 0x10edc,
+0x10f08, 0x10a78, 0x10c20, 0x0, 0x1120c, 0x11260,
+0x112dc, 0x11308, 0x11358, 0x11394, 0x113c8, 0x11454,
+0x1150c, 0x115dc, 0x1161c, 0x116a0, 0x116c4, 0x117d4,
+0x646f4261, 0x73655067, 0x0, 0x0, 0x0, 0x0,
+0x73746d61, 0x634c4e4b, 0x0, 0x0, 0x0 };
diff --git a/drivers/net/apne.c b/drivers/net/apne.c
index 005cc3195..d3578f5da 100644
--- a/drivers/net/apne.c
+++ b/drivers/net/apne.c
@@ -577,14 +577,14 @@ int init_module(void)
void cleanup_module(void)
{
- unregister_netdev(&apne_dev);
-
pcmcia_disable_irq();
free_irq(IRQ_AMIGA_PORTS, &apne_dev);
pcmcia_reset();
+ unregister_netdev(&apne_dev);
+
unlock_8390_module();
}
diff --git a/drivers/net/arc-rimi.c b/drivers/net/arc-rimi.c
index e260d0e58..d27fbee7c 100644
--- a/drivers/net/arc-rimi.c
+++ b/drivers/net/arc-rimi.c
@@ -4,9 +4,6 @@
Written 1994-1996 by Avery Pennarun,
which was in turn derived from skeleton.c by Donald Becker.
- Contact Avery at: apenwarr@bond.net or
- RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-
**********************
The original copyright of skeleton.c was as follows:
@@ -130,7 +127,7 @@ extern int arcnet_num_devs;
#define SETCONF writeb(lp->config,_CONFIG)
static const char *version =
-"arc-rimi.c: v3.00 97/11/09 Avery Pennarun <apenwarr@bond.net> et al.\n";
+"arc-rimi.c: v3.00 97/11/09 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
/****************************************************************************
* *
diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c
index 8926902a5..1111e19c7 100644
--- a/drivers/net/arcnet.c
+++ b/drivers/net/arcnet.c
@@ -3,9 +3,6 @@
Written 1994-1996 by Avery Pennarun,
derived from skeleton.c by Donald Becker.
- Contact Avery at: apenwarr@bond.net or
- RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-
**********************
The original copyright was as follows:
@@ -88,7 +85,7 @@
The following has been SUMMARIZED. The complete ChangeLog is
available in the full Linux-ARCnet package at
- http://www.foxnet.net/~apenwarr/arcnet
+ http://www.worldvisions.ca/~apenwarr/arcnet
v2.50 (96/02/24)
- Massively improved autoprobe routines; they now work even as a
@@ -181,7 +178,7 @@
*/
static const char *version =
- "arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@bond.net> et al.\n";
+ "arcnet.c: v3.02 98/06/07 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
#include <linux/module.h>
#include <linux/config.h>
diff --git a/drivers/net/ariadne.c b/drivers/net/ariadne.c
index 232b714a8..baaa59692 100644
--- a/drivers/net/ariadne.c
+++ b/drivers/net/ariadne.c
@@ -545,6 +545,7 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev)
struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
struct AriadneBoard *board = priv->board;
int entry;
+ unsigned long flags;
/* Transmitter timeout, serious problems. */
if (dev->tbusy) {
@@ -625,6 +626,9 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev)
printk(" data 0x%08x len %d\n", (int)skb->data, (int)skb->len);
#endif
+ save_flags(flags);
+ cli();
+
entry = priv->cur_tx % TX_RING_SIZE;
/* Caution: the write order is important here, set the base address with
@@ -675,13 +679,12 @@ static int ariadne_start_xmit(struct sk_buff *skb, struct device *dev)
dev->trans_start = jiffies;
- cli();
priv->lock = 0;
if (lowb(priv->tx_ring[(entry+1) % TX_RING_SIZE]->TMD1) == 0)
dev->tbusy = 0;
else
priv->tx_full = 1;
- sti();
+ restore_flags(flags);
return(0);
}
@@ -780,13 +783,15 @@ static struct net_device_stats *ariadne_get_stats(struct device *dev)
struct ariadne_private *priv = (struct ariadne_private *)dev->priv;
struct AriadneBoard *board = priv->board;
short saved_addr;
+ unsigned long flags;
+ save_flags(flags);
cli();
saved_addr = board->Lance.RAP;
board->Lance.RAP = CSR112; /* Missed Frame Count */
priv->stats.rx_missed_errors = swapw(board->Lance.RDP);
board->Lance.RAP = saved_addr;
- sti();
+ restore_flags(flags);
return(&priv->stats);
}
diff --git a/drivers/net/ariadne2.c b/drivers/net/ariadne2.c
new file mode 100644
index 000000000..0b71b5987
--- /dev/null
+++ b/drivers/net/ariadne2.c
@@ -0,0 +1,424 @@
+/*
+ * Amiga Linux/m68k Ariadne II Ethernet Driver
+ *
+ * (C) Copyright 1998 by some Elitist 680x0 Users(TM)
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This program is based on all the other NE2000 drivers for Linux
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * This file is subject to the terms and conditions of the GNU General Public
+ * License. See the file COPYING in the main directory of the Linux
+ * distribution for more details.
+ *
+ * ---------------------------------------------------------------------------
+ *
+ * The Ariadne II is a Zorro-II board made by Village Tronic. It contains a
+ * Realtek RTL8019AS Ethernet Controller.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/zorro.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/amigaints.h>
+
+#include "8390.h"
+
+
+#define ARIADNE2_BASE 0x0300
+#define ARIADNE2_BOOTROM 0xc000
+
+
+#define NE_BASE (dev->base_addr)
+#define NE_CMD (0x00*2)
+#define NE_DATAPORT (0x10*2) /* NatSemi-defined port window offset. */
+#define NE_RESET (0x1f*2) /* Issue a read to reset, a write to clear. */
+#define NE_IO_EXTENT (0x20*2)
+
+#define NE_EN0_ISR (0x07*2)
+#define NE_EN0_DCFG (0x0e*2)
+
+#define NE_EN0_RSARLO (0x08*2)
+#define NE_EN0_RSARHI (0x09*2)
+#define NE_EN0_RCNTLO (0x0a*2)
+#define NE_EN0_RXCR (0x0c*2)
+#define NE_EN0_TXCR (0x0d*2)
+#define NE_EN0_RCNTHI (0x0b*2)
+#define NE_EN0_IMR (0x0f*2)
+
+#define NESM_START_PG 0x40 /* First page of TX buffer */
+#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
+
+
+#define WORDSWAP(a) ((((a)>>8)&0xff) | ((a)<<8))
+
+int ariadne2_probe(struct device *dev);
+static int ariadne2_init(struct device *dev, unsigned int key,
+ unsigned long board);
+
+static int ariadne2_open(struct device *dev);
+static int ariadne2_close(struct device *dev);
+
+static void ariadne2_reset_8390(struct device *dev);
+static void ariadne2_get_8390_hdr(struct device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page);
+static void ariadne2_block_input(struct device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
+static void ariadne2_block_output(struct device *dev, const int count,
+ const unsigned char *buf,
+ const int start_page);
+
+
+__initfunc(int ariadne2_probe(struct device *dev))
+{
+ unsigned int key;
+ const struct ConfigDev *cd;
+ u_long board;
+ int err;
+
+ if ((key = zorro_find(ZORRO_PROD_VILLAGE_TRONIC_ARIADNE2, 0, 0))) {
+ cd = zorro_get_board(key);
+ if ((board = (u_long)cd->cd_BoardAddr)) {
+ if ((err = ariadne2_init(dev, key, ZTWO_VADDR(board))))
+ return err;
+ zorro_config_board(key, 0);
+ return 0;
+ }
+ }
+ return -ENODEV;
+}
+
+__initfunc(static int ariadne2_init(struct device *dev, unsigned int key,
+ unsigned long board))
+{
+ int i;
+ unsigned char SA_prom[32];
+ const char *name = NULL;
+ int start_page, stop_page;
+ static int ariadne2_offsets[16] = {
+ 0x00, 0x02, 0x04, 0x06, 0x08, 0x0a, 0x0c, 0x0e,
+ 0x10, 0x12, 0x14, 0x16, 0x18, 0x1a, 0x1c, 0x1e,
+ };
+ int ioaddr = board+ARIADNE2_BASE*2;
+
+ if (load_8390_module("ariadne2.c"))
+ return -ENOSYS;
+
+ /* We should have a "dev" from Space.c or the static module table. */
+ if (dev == NULL) {
+ printk(KERN_ERR "ariadne2.c: Passed a NULL device.\n");
+ dev = init_etherdev(0, 0);
+ }
+
+ /* Reset card. Who knows what dain-bramaged state it was left in. */
+ {
+ unsigned long reset_start_time = jiffies;
+
+ writeb(readb(ioaddr + NE_RESET), ioaddr + NE_RESET);
+
+ while ((readb(ioaddr + NE_EN0_ISR) & ENISR_RESET) == 0)
+ if (jiffies - reset_start_time > 2*HZ/100) {
+ printk(" not found (no reset ack).\n");
+ return -ENODEV;
+ }
+
+ writeb(0xff, ioaddr + NE_EN0_ISR); /* Ack all intr. */
+ }
+
+ /* Read the 16 bytes of station address PROM.
+ We must first initialize registers, similar to NS8390_init(eifdev, 0).
+ We can't reliably read the SAPROM address without this.
+ (I learned the hard way!). */
+ {
+ struct {
+ u32 value;
+ u32 offset;
+ } program_seq[] = {
+ {E8390_NODMA+E8390_PAGE0+E8390_STOP, NE_CMD}, /* Select page 0*/
+ {0x48, NE_EN0_DCFG}, /* Set byte-wide (0x48) access. */
+ {0x00, NE_EN0_RCNTLO}, /* Clear the count regs. */
+ {0x00, NE_EN0_RCNTHI},
+ {0x00, NE_EN0_IMR}, /* Mask completion irq. */
+ {0xFF, NE_EN0_ISR},
+ {E8390_RXOFF, NE_EN0_RXCR}, /* 0x20 Set to monitor */
+ {E8390_TXOFF, NE_EN0_TXCR}, /* 0x02 and loopback mode. */
+ {32, NE_EN0_RCNTLO},
+ {0x00, NE_EN0_RCNTHI},
+ {0x00, NE_EN0_RSARLO}, /* DMA starting at 0x0000. */
+ {0x00, NE_EN0_RSARHI},
+ {E8390_RREAD+E8390_START, NE_CMD},
+ };
+ for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++) {
+ writeb(program_seq[i].value, ioaddr + program_seq[i].offset);
+ }
+ }
+ for (i = 0; i < 16; i++) {
+ SA_prom[i] = readb(ioaddr + NE_DATAPORT);
+ (void)readb(ioaddr + NE_DATAPORT);
+ }
+
+ /* We must set the 8390 for word mode. */
+ writeb(0x49, ioaddr + NE_EN0_DCFG);
+ start_page = NESM_START_PG;
+ stop_page = NESM_STOP_PG;
+
+ name = "NE2000";
+
+ dev->base_addr = ioaddr;
+
+ /* Install the Interrupt handler */
+ if (request_irq(IRQ_AMIGA_PORTS, ei_interrupt, 0, "AriadNE2 Ethernet",
+ dev))
+ return -EAGAIN;
+
+ /* Allocate dev->priv and fill in 8390 specific dev fields. */
+ if (ethdev_init(dev)) {
+ printk("Unable to get memory for dev->priv.\n");
+ return -ENOMEM;
+ }
+ ((struct ei_device *)dev->priv)->priv = key;
+
+ for(i = 0; i < ETHER_ADDR_LEN; i++) {
+ printk(" %2.2x", SA_prom[i]);
+ dev->dev_addr[i] = SA_prom[i];
+ }
+
+ printk("%s: AriadNE2 at 0x%08lx, Ethernet Address "
+ "%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name, board,
+ dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
+ dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
+
+ ei_status.name = name;
+ ei_status.tx_start_page = start_page;
+ ei_status.stop_page = stop_page;
+ ei_status.word16 = 1;
+
+ ei_status.rx_start_page = start_page + TX_PAGES;
+
+ ei_status.reset_8390 = &ariadne2_reset_8390;
+ ei_status.block_input = &ariadne2_block_input;
+ ei_status.block_output = &ariadne2_block_output;
+ ei_status.get_8390_hdr = &ariadne2_get_8390_hdr;
+ ei_status.reg_offset = ariadne2_offsets;
+ dev->open = &ariadne2_open;
+ dev->stop = &ariadne2_close;
+ NS8390_init(dev, 0);
+ return 0;
+}
+
+static int ariadne2_open(struct device *dev)
+{
+ ei_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int ariadne2_close(struct device *dev)
+{
+ if (ei_debug > 1)
+ printk("%s: Shutting down ethercard.\n", dev->name);
+ ei_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+/* Hard reset the card. This used to pause for the same period that a
+ 8390 reset command required, but that shouldn't be necessary. */
+static void ariadne2_reset_8390(struct device *dev)
+{
+ unsigned long reset_start_time = jiffies;
+
+ if (ei_debug > 1)
+ printk("resetting the 8390 t=%ld...", jiffies);
+
+ writeb(readb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+
+ ei_status.txing = 0;
+ ei_status.dmaing = 0;
+
+ /* This check _should_not_ be necessary, omit eventually. */
+ while ((readb(NE_BASE+NE_EN0_ISR) & ENISR_RESET) == 0)
+ if (jiffies - reset_start_time > 2*HZ/100) {
+ printk("%s: ne_reset_8390() did not complete.\n", dev->name);
+ break;
+ }
+ writeb(ENISR_RESET, NE_BASE + NE_EN0_ISR); /* Ack intr. */
+}
+
+/* Grab the 8390 specific header. Similar to the block_input routine, but
+ we don't need to be concerned with ring wrap as the header will be at
+ the start of a page, so we optimize accordingly. */
+
+static void ariadne2_get_8390_hdr(struct device *dev,
+ struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ int nic_base = dev->base_addr;
+ int cnt;
+ short *ptrs;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_get_8390_hdr "
+ "[DMAstat:%d][irqlock:%d][intr:%ld].\n", dev->name, ei_status.dmaing,
+ ei_status.irqlock, dev->interrupt);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+ writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+ writeb(sizeof(struct e8390_pkt_hdr), nic_base + NE_EN0_RCNTLO);
+ writeb(0, nic_base + NE_EN0_RCNTHI);
+ writeb(0, nic_base + NE_EN0_RSARLO); /* On page boundary */
+ writeb(ring_page, nic_base + NE_EN0_RSARHI);
+ writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ ptrs = (short*)hdr;
+ for (cnt = 0; cnt < (sizeof(struct e8390_pkt_hdr)>>1); cnt++)
+ *ptrs++ = readw(NE_BASE + NE_DATAPORT);
+
+ writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
+
+ hdr->count = WORDSWAP(hdr->count);
+
+ ei_status.dmaing &= ~0x01;
+}
+
+/* Block input and output, similar to the Crynwr packet driver. If you
+ are porting to a new ethercard, look at the packet driver source for hints.
+ The NEx000 doesn't share the on-board packet memory -- you have to put
+ the packet out through the "remote DMA" dataport using writeb. */
+
+static void ariadne2_block_input(struct device *dev, int count,
+ struct sk_buff *skb, int ring_offset)
+{
+ int nic_base = dev->base_addr;
+ char *buf = skb->data;
+ short *ptrs;
+ int cnt;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_block_input "
+ "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
+ return;
+ }
+ ei_status.dmaing |= 0x01;
+ writeb(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+ writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+ writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
+ writeb(ring_offset & 0xff, nic_base + NE_EN0_RSARLO);
+ writeb(ring_offset >> 8, nic_base + NE_EN0_RSARHI);
+ writeb(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+ ptrs = (short*)buf;
+ for (cnt = 0; cnt < (count>>1); cnt++)
+ *ptrs++ = readw(NE_BASE + NE_DATAPORT);
+ if (count & 0x01)
+ buf[count-1] = readb(NE_BASE + NE_DATAPORT);
+
+ writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+}
+
+static void ariadne2_block_output(struct device *dev, int count,
+ const unsigned char *buf,
+ const int start_page)
+{
+ int nic_base = NE_BASE;
+ unsigned long dma_start;
+ short *ptrs;
+ int cnt;
+
+ /* Round the count up for word writes. Do we need to do this?
+ What effect will an odd byte count have on the 8390?
+ I should check someday. */
+ if (count & 0x01)
+ count++;
+
+ /* This *shouldn't* happen. If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_block_output."
+ "[DMAstat:%d][irqlock:%d][intr:%ld]\n", dev->name, ei_status.dmaing,
+ ei_status.irqlock, dev->interrupt);
+ return;
+ }
+ ei_status.dmaing |= 0x01;
+ /* We should already be in page 0, but to be safe... */
+ writeb(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+ writeb(ENISR_RDC, nic_base + NE_EN0_ISR);
+
+ /* Now the normal output. */
+ writeb(count & 0xff, nic_base + NE_EN0_RCNTLO);
+ writeb(count >> 8, nic_base + NE_EN0_RCNTHI);
+ writeb(0x00, nic_base + NE_EN0_RSARLO);
+ writeb(start_page, nic_base + NE_EN0_RSARHI);
+
+ writeb(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+ ptrs = (short*)buf;
+ for (cnt = 0; cnt < count>>1; cnt++)
+ writew(*ptrs++, NE_BASE+NE_DATAPORT);
+
+ dma_start = jiffies;
+
+ while ((readb(NE_BASE + NE_EN0_ISR) & ENISR_RDC) == 0)
+ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
+ printk("%s: timeout waiting for Tx RDC.\n", dev->name);
+ ariadne2_reset_8390(dev);
+ NS8390_init(dev,1);
+ break;
+ }
+
+ writeb(ENISR_RDC, nic_base + NE_EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+ return;
+}
+
+#ifdef MODULE
+static char devicename[9] = { 0, };
+
+static struct device ariadne2_dev =
+{
+ devicename,
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, ariadne2_probe,
+};
+
+int init_module(void)
+{
+ int err;
+ if ((err = register_netdev(&ariadne2_dev))) {
+ if (err == -EIO)
+ printk("No AriadNE2 ethernet card found.\n");
+ return err;
+ }
+ lock_8390_module();
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ unsigned int key = ((struct ei_device *)ariadne2_dev.priv)->priv;
+ free_irq(IRQ_AMIGA_PORTS, &ariadne2_dev);
+ unregister_netdev(&ariadne2_dev);
+ zorro_config_board(key, 0);
+ unlock_8390_module();
+}
+
+#endif /* MODULE */
diff --git a/drivers/net/at1700.c b/drivers/net/at1700.c
index 3751b4336..77641a0f4 100644
--- a/drivers/net/at1700.c
+++ b/drivers/net/at1700.c
@@ -1,6 +1,6 @@
/* at1700.c: A network device driver for the Allied Telesis AT1700.
- Written 1993-94 by Donald Becker.
+ Written 1993-98 by Donald Becker.
Copyright 1993 United States Government as represented by the
Director, National Security Agency.
@@ -22,6 +22,8 @@
ATI provided their EEPROM configuration code header file.
Thanks to NIIBE Yutaka <gniibe@mri.co.jp> for bug fixes.
+ MCA bus (AT1720) support by Rene Schmit <rene@bss.lu>
+
Bugs:
The MB86965 has a design flaw that makes all probes unreliable. Not
only is it difficult to detect, it also moves around in I/O space in
@@ -29,8 +31,9 @@
*/
static const char *version =
- "at1700.c:v1.12 1/18/95 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+ "at1700.c:v1.15 4/7/98 Donald Becker (becker@cesdis.gsfc.nasa.gov)\n";
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -43,20 +46,54 @@ static const char *version =
#include <linux/in.h>
#include <linux/malloc.h>
#include <linux/string.h>
+#include <linux/init.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <linux/errno.h>
-#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-/* This unusual address order is used to verify the CONFIG register. */
-static int at1700_probe_list[] __initdata =
-{0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0};
+#include <linux/mca.h>
+
+/* Tunable parameters. */
+
+/* When to switch from the 64-entry multicast filter to Rx-all-multicast. */
+#define MC_FILTERBREAK 64
+
+/* These unusual address orders are used to verify the CONFIG register. */
+
+static int fmv18x_probe_list[] = {
+ 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x300, 0x340, 0
+};
+
+/*
+ * ISA
+ */
+
+static int at1700_probe_list[] = {
+ 0x260, 0x280, 0x2a0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
+};
+
+/*
+ * MCA
+ */
+
+static int at1700_ioaddr_pattern[] = {
+ 0x00, 0x04, 0x01, 0x05, 0x02, 0x06, 0x03, 0x07
+};
+
+static int at1700_mca_probe_list[] = {
+ 0x400, 0x1400, 0x2400, 0x3400, 0x4400, 0x5400, 0x6400, 0x7400, 0
+};
+
+static int at1700_irq_pattern[] = {
+ 0x00, 0x00, 0x00, 0x30, 0x70, 0xb0, 0x00, 0x00,
+ 0x00, 0xf0, 0x34, 0x74, 0xb4, 0x00, 0x00, 0xf4, 0x00
+};
/* use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG
@@ -68,10 +105,14 @@ typedef unsigned char uchar;
/* Information that need to be kept for each board. */
struct net_local {
- struct net_device_stats stats;
- uint tx_started:1; /* Number of packet on the Tx queue. */
+ struct enet_statistics stats;
+ unsigned char mc_filter[8];
+ uint jumpered:1; /* Set iff the board has jumper config. */
+ uint tx_started:1; /* Packets are on the Tx queue. */
+ uint invalid_irq:1;
uchar tx_queue; /* Number of packet on the Tx queue. */
- ushort tx_queue_len; /* Current length of the Tx queue. */
+ char mca_slot; /* -1 means ISA */
+ ushort tx_queue_len; /* Current length of the Tx queue. */
};
@@ -89,56 +130,59 @@ struct net_local {
#define DATAPORT 8 /* Word-wide DMA or programmed-I/O dataport. */
#define TX_START 10
#define MODE13 13
+/* Configuration registers only on the '865A/B chips. */
#define EEPROM_Ctrl 16
#define EEPROM_Data 17
-#define IOCONFIG 19
+#define IOCONFIG 18 /* Either read the jumper, or move the I/O. */
+#define IOCONFIG1 19
+#define SAPROM 20 /* The station address PROM, if no EEPROM. */
#define RESET 31 /* Write to reset some parts of the chip. */
#define AT1700_IO_EXTENT 32
-
-/* EEPROM_Ctrl bits. */
-#define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
-#define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
-#define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
-#define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
-
-/* Delay between EEPROM clock transitions. */
-#define eeprom_delay() do { int _i = 40; while (--_i > 0) { inb(0x80); }} while (0)
-
-/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD (5 << 6)
-#define EE_READ_CMD (6 << 6)
-#define EE_ERASE_CMD (7 << 6)
-
-
/* Index to functions, as function prototypes. */
extern int at1700_probe(struct device *dev);
-static int at1700_probe1(struct device *dev, short ioaddr);
+static int at1700_probe1(struct device *dev, int ioaddr);
static int read_eeprom(int ioaddr, int location);
static int net_open(struct device *dev);
static int net_send_packet(struct sk_buff *skb, struct device *dev);
static void net_interrupt(int irq, void *dev_id, struct pt_regs *regs);
static void net_rx(struct device *dev);
static int net_close(struct device *dev);
-static struct net_device_stats *net_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
+static struct enet_statistics *net_get_stats(struct device *dev);
+static void set_rx_mode(struct device *dev);
+#ifdef CONFIG_MCA
+struct at1720_mca_adapters_struct {
+ char* name;
+ int id;
+};
+/* rEnE : maybe there are others I don't know off... */
+
+struct at1720_mca_adapters_struct at1720_mca_adapters[] = {
+ { "Allied Telesys AT1720AT", 0x6410 },
+ { "Allied Telesys AT1720BT", 0x6413 },
+ { "Allied Telesys AT1720T", 0x6416 },
+ { NULL, 0 },
+};
+#endif
+
/* Check for a network adaptor of this type, and return '0' iff one exists.
If dev->base_addr == 0, probe all likely locations.
If dev->base_addr == 1, always return failure.
If dev->base_addr == 2, allocate space for the device and return success
(detachable devices only).
*/
+
#ifdef HAVE_DEVLIST
-/* Support for an alternate probe manager, which will eliminate the
+/* Support for a alternate probe manager, which will eliminate the
boilerplate below. */
struct netdev_entry at1700_drv =
{"at1700", at1700_probe1, AT1700_IO_EXTENT, at1700_probe_list};
#else
-__initfunc(int
-at1700_probe(struct device *dev))
+
+int at1700_probe(struct device *dev)
{
int i;
int base_addr = dev ? dev->base_addr : 0;
@@ -155,7 +199,6 @@ at1700_probe(struct device *dev))
if (at1700_probe1(dev, ioaddr) == 0)
return 0;
}
-
return ENODEV;
}
#endif
@@ -168,12 +211,15 @@ at1700_probe(struct device *dev))
that can be done is checking a few bits and then diving right into an
EEPROM read. */
-__initfunc(int at1700_probe1(struct device *dev, short ioaddr))
+int at1700_probe1(struct device *dev, int ioaddr)
{
- char irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
- unsigned int i, irq;
-
- /* Resetting the chip doesn't reset the ISA interface, so don't bother.
+ char fmv_irqmap[4] = {3, 7, 10, 15};
+ char at1700_irqmap[8] = {3, 4, 5, 9, 10, 11, 14, 15};
+ unsigned int i, irq, is_fmv18x = 0, is_at1700 = 0;
+ int l_i;
+ int slot;
+
+ /* Resetting the chip doesn't reset the ISA interface, so don't bother.
That means we have to be careful with the register values we probe for.
*/
#ifdef notdef
@@ -181,31 +227,98 @@ __initfunc(int at1700_probe1(struct device *dev, short ioaddr))
ioaddr, read_eeprom(ioaddr, 4), read_eeprom(ioaddr, 5),
read_eeprom(ioaddr, 6), inw(ioaddr + EEPROM_Ctrl));
#endif
- if (at1700_probe_list[inb(ioaddr + IOCONFIG) & 0x07] != ioaddr
- || read_eeprom(ioaddr, 4) != 0x0000
- || (read_eeprom(ioaddr, 5) & 0xff00) != 0xF400)
+
+#ifdef CONFIG_MCA
+ /* rEnE (rene@bss.lu): got this from 3c509 driver source , adapted for AT1720 */
+
+ /* Based on Erik Nygren's (nygren@mit.edu) 3c529 patch, heavily
+ modified by Chris Beauregard (cpbeaure@csclub.uwaterloo.ca)
+ to support standard MCA probing. */
+
+ /* redone for multi-card detection by ZP Gu (zpg@castle.net) */
+ /* now works as a module */
+
+ if( MCA_bus ) {
+ int j;
+ u_char pos3, pos4;
+
+ for( j = 0; at1720_mca_adapters[j].name != NULL; j ++ ) {
+ slot = 0;
+ while( slot != MCA_NOTFOUND ) {
+
+ slot = mca_find_unused_adapter( at1720_mca_adapters[j].id, slot );
+ if( slot == MCA_NOTFOUND ) break;
+
+ /* if we get this far, an adapter has been detected and is
+ enabled */
+
+ pos3 = mca_read_stored_pos( slot, 3 );
+ pos4 = mca_read_stored_pos( slot, 4 );
+
+ for (l_i = 0; l_i < 0x09; l_i++)
+ if (( pos3 & 0x07) == at1700_ioaddr_pattern[l_i])
+ break;
+ ioaddr = at1700_mca_probe_list[l_i];
+
+ for (irq = 0; irq < 0x10; irq++)
+ if (((((pos4>>4) & 0x0f) | (pos3 & 0xf0)) & 0xff) == at1700_irq_pattern[irq])
+ break;
+
+ /* probing for a card at a particular IO/IRQ */
+ if (dev &&
+ ((dev->irq && dev->irq != irq) ||
+ (dev->base_addr && dev->base_addr != ioaddr))) {
+ slot++; /* probing next slot */
+ continue;
+ }
+
+ if (dev)
+ dev->irq = irq;
+
+ /* claim the slot */
+ mca_set_adapter_name( slot, at1720_mca_adapters[j].name );
+ mca_mark_as_used(slot);
+
+ goto found;
+ }
+ }
+ /* if we get here, we didn't find an MCA adapter - try ISA */
+ }
+#endif
+ slot = -1;
+ /* We must check for the EEPROM-config boards first, else accessing
+ IOCONFIG0 will move the board! */
+ if (at1700_probe_list[inb(ioaddr + IOCONFIG1) & 0x07] == ioaddr
+ && read_eeprom(ioaddr, 4) == 0x0000
+ && (read_eeprom(ioaddr, 5) & 0xff00) == 0xF400)
+ is_at1700 = 1;
+ else if (fmv18x_probe_list[inb(ioaddr + IOCONFIG) & 0x07] == ioaddr
+ && inb(ioaddr + SAPROM ) == 0x00
+ && inb(ioaddr + SAPROM + 1) == 0x00
+ && inb(ioaddr + SAPROM + 2) == 0x0e)
+ is_fmv18x = 1;
+ else
return -ENODEV;
+
+found:
- /* Reset the internal state machines. */
+ /* Reset the internal state machines. */
outb(0, ioaddr + RESET);
- irq = irqmap[(read_eeprom(ioaddr, 12)&0x04)
- | (read_eeprom(ioaddr, 0)>>14)];
-
- /* Snarf the interrupt vector now. */
- if (request_irq(irq, &net_interrupt, 0, "at1700", dev)) {
- printk ("AT1700 found at %#3x, but it's unusable due to a conflict on"
- "IRQ %d.\n", ioaddr, irq);
- return EAGAIN;
- }
-
/* Allocate a new 'dev' if needed. */
if (dev == NULL)
dev = init_etherdev(0, sizeof(struct net_local));
+ if (is_at1700)
+ irq = at1700_irqmap[(read_eeprom(ioaddr, 12)&0x04)
+ | (read_eeprom(ioaddr, 0)>>14)];
+ else
+ if (is_fmv18x)
+ irq = fmv_irqmap[(inb(ioaddr + IOCONFIG)>>6) & 0x03];
+
/* Grab the region so that we can find another board if the IRQ request
fails. */
- request_region(ioaddr, AT1700_IO_EXTENT, "at1700");
+ request_region(ioaddr, AT1700_IO_EXTENT, dev->name);
printk("%s: AT1700 found at %#3x, IRQ %d, address ", dev->name,
ioaddr, irq);
@@ -234,12 +347,12 @@ __initfunc(int at1700_probe1(struct device *dev, short ioaddr))
}
/* Set the station address in bank zero. */
- outb(0xe0, ioaddr + 7);
+ outb(0xe0, ioaddr + CONFIG_1);
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + 8 + i);
/* Switch to bank 1 and set the multicast table to accept none. */
- outb(0xe4, ioaddr + 7);
+ outb(0xe4, ioaddr + CONFIG_1);
for (i = 0; i < 8; i++)
outb(0x00, ioaddr + 8 + i);
@@ -248,7 +361,7 @@ __initfunc(int at1700_probe1(struct device *dev, short ioaddr))
outb(0xda, ioaddr + CONFIG_0);
/* Switch to bank 2 and lock our I/O address. */
- outb(0xe8, ioaddr + 7);
+ outb(0xe8, ioaddr + CONFIG_1);
outb(dev->if_port, MODE13);
/* Power-down the chip. Aren't we green! */
@@ -265,52 +378,75 @@ __initfunc(int at1700_probe1(struct device *dev, short ioaddr))
dev->open = net_open;
dev->stop = net_close;
- dev->hard_start_xmit = net_send_packet;
- dev->get_stats = net_get_stats;
- dev->set_multicast_list = &set_multicast_list;
+ dev->hard_start_xmit = net_send_packet;
+ dev->get_stats = net_get_stats;
+ dev->set_multicast_list = &set_rx_mode;
/* Fill in the fields of 'dev' with ethernet-generic values. */
-
ether_setup(dev);
+
+ {
+ struct net_local *lp = (struct net_local *)dev->priv;
+ lp->jumpered = is_fmv18x;
+ lp->mca_slot = slot;
+ /* Snarf the interrupt vector now. */
+ if (request_irq(irq, &net_interrupt, 0, dev->name, dev)) {
+ printk (" AT1700 at %#3x is unusable due to a conflict on"
+ "IRQ %d.\n", ioaddr, irq);
+ lp->invalid_irq = 1;
+ return 0;
+ }
+ }
+
return 0;
}
-__initfunc(static int read_eeprom(int ioaddr, int location))
+
+/* EEPROM_Ctrl bits. */
+#define EE_SHIFT_CLK 0x40 /* EEPROM shift clock, in reg. 16. */
+#define EE_CS 0x20 /* EEPROM chip select, in reg. 16. */
+#define EE_DATA_WRITE 0x80 /* EEPROM chip data in, in reg. 17. */
+#define EE_DATA_READ 0x80 /* EEPROM chip data out, in reg. 17. */
+
+/* Delay between EEPROM clock transitions. */
+#define eeprom_delay() do {} while (0);
+
+/* The EEPROM commands include the alway-set leading bit. */
+#define EE_WRITE_CMD (5 << 6)
+#define EE_READ_CMD (6 << 6)
+#define EE_ERASE_CMD (7 << 6)
+
+static int read_eeprom(int ioaddr, int location)
{
int i;
unsigned short retval = 0;
- short ee_addr = ioaddr + EEPROM_Ctrl;
- short ee_daddr = ioaddr + EEPROM_Data;
+ int ee_addr = ioaddr + EEPROM_Ctrl;
+ int ee_daddr = ioaddr + EEPROM_Data;
int read_cmd = location | EE_READ_CMD;
- short ctrl_val = EE_CS;
-
- outb(ctrl_val, ee_addr);
/* Shift the read command bits out. */
for (i = 9; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ outb(EE_CS, ee_addr);
outb(dataval, ee_daddr);
- outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
eeprom_delay();
- outb(EE_CS, ee_addr); /* Finish EEPROM a clock tick. */
+ outb(EE_CS | EE_SHIFT_CLK, ee_addr); /* EEPROM clock tick. */
eeprom_delay();
}
- outb(EE_CS, ee_addr);
-
+ outb(EE_DATA_WRITE, ee_daddr);
for (i = 16; i > 0; i--) {
+ outb(EE_CS, ee_addr);
+ eeprom_delay();
outb(EE_CS | EE_SHIFT_CLK, ee_addr);
eeprom_delay();
retval = (retval << 1) | ((inb(ee_daddr) & EE_DATA_READ) ? 1 : 0);
- outb(EE_CS, ee_addr);
- eeprom_delay();
}
/* Terminate the EEPROM access. */
- ctrl_val &= ~EE_CS;
- outb(ctrl_val | EE_SHIFT_CLK, ee_addr);
- eeprom_delay();
- outb(ctrl_val, ee_addr);
+ outb(EE_CS, ee_addr);
eeprom_delay();
+ outb(EE_SHIFT_CLK, ee_addr);
+ outb(0, ee_addr);
return retval;
}
@@ -330,7 +466,7 @@ static int net_open(struct device *dev)
outb(dev->dev_addr[i], ioaddr + 8 + i);
/* Switch to bank 1 and set the multicast table to accept none. */
- outb(0xe4, ioaddr + 7);
+ outb(0xe4, ioaddr + CONFIG_1);
for (i = 0; i < 8; i++)
outb(0x00, ioaddr + 8 + i);
@@ -338,10 +474,8 @@ static int net_open(struct device *dev)
bus access, and two 4K Tx queues. */
outb(0xda, ioaddr + CONFIG_0);
- /* Same config 0, except enable the Rx and Tx. */
- outb(0x5a, ioaddr + CONFIG_0);
- /* Switch to register bank 2 for the run-time registers. */
- outb(0xe8, ioaddr + CONFIG_1);
+ /* Switch to register bank 2, enable the Rx and Tx. */
+ outw(0xe85a, ioaddr + CONFIG_0);
lp->tx_started = 0;
lp->tx_queue = 0;
@@ -564,6 +698,7 @@ net_rx(struct device *dev)
/* The inverse routine to net_open(). */
static int net_close(struct device *dev)
{
+/* struct net_local *lp = (struct net_local *)dev->priv;*/
int ioaddr = dev->base_addr;
dev->tbusy = 1;
@@ -572,7 +707,15 @@ static int net_close(struct device *dev)
/* Set configuration register 0 to disable Tx and Rx. */
outb(0xda, ioaddr + CONFIG_0);
- /* Update the statistics -- ToDo. */
+ /* No statistic counters on the chip to update. */
+
+#if 0
+ /* Disable the IRQ on boards where it is feasible. */
+ if (lp->jumpered) {
+ outb(0x00, ioaddr + IOCONFIG1);
+ free_irq(dev->irq, dev);
+ }
+#endif
/* Power-down the chip. Green, green, green! */
outb(0x00, ioaddr + CONFIG_1);
@@ -582,44 +725,90 @@ static int net_close(struct device *dev)
return 0;
}
-/* Get the current statistics. This may be called with the card open or
- closed. */
-
-static struct net_device_stats *net_get_stats(struct device *dev)
+/* Get the current statistics.
+ This may be called with the card open or closed.
+ There are no on-chip counters, so this function is trivial.
+*/
+static struct enet_statistics *
+net_get_stats(struct device *dev)
{
struct net_local *lp = (struct net_local *)dev->priv;
+ return &lp->stats;
+}
- cli();
- /* ToDo: Update the statistics from the device registers. */
- sti();
+/*
+ Set the multicast/promiscuous mode for this adaptor.
+*/
- return &lp->stats;
+/* The little-endian AUTODIN II ethernet CRC calculation.
+ N.B. Do not use for bulk data, use a table-based routine instead.
+ This is common code and should be moved to net/core/crc.c */
+static unsigned const ethernet_polynomial_le = 0xedb88320U;
+static inline unsigned ether_crc_le(int length, unsigned char *data)
+{
+ unsigned int crc = 0xffffffff; /* Initial value. */
+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;
+ for (bit = 8; --bit >= 0; current_octet >>= 1) {
+ if ((crc ^ current_octet) & 1) {
+ crc >>= 1;
+ crc ^= ethernet_polynomial_le;
+ } else
+ crc >>= 1;
+ }
+ }
+ return crc;
}
-/* Set or clear the multicast filter for this adaptor.
- num_addrs == -1 Promiscuous mode, receive all packets
- num_addrs == 0 Normal mode, clear multicast list
- num_addrs > 0 Multicast mode, receive normal and MC packets, and do
- best-effort filtering.
- */
static void
-set_multicast_list(struct device *dev)
+set_rx_mode(struct device *dev)
{
- short ioaddr = dev->base_addr;
- if (dev->mc_count || dev->flags&(IFF_PROMISC|IFF_ALLMULTI))
- {
- /*
- * We must make the kernel realise we had to move
- * into promisc mode or we start all out war on
- * the cable. - AC
- */
- dev->flags|=IFF_PROMISC;
+ int ioaddr = dev->base_addr;
+ struct net_local *lp = (struct net_local *)dev->priv;
+ unsigned char mc_filter[8]; /* Multicast hash filter */
+ long flags;
+ int i;
+ if (dev->flags & IFF_PROMISC) {
+ /* Unconditionally log net taps. */
+ printk("%s: Promiscuous mode enabled.\n", dev->name);
+ memset(mc_filter, 0xff, sizeof(mc_filter));
outb(3, ioaddr + RX_MODE); /* Enable promiscuous mode */
+ } else if (dev->mc_count > MC_FILTERBREAK
+ || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to filter perfectly -- accept all multicasts. */
+ memset(mc_filter, 0xff, sizeof(mc_filter));
+ outb(2, ioaddr + RX_MODE); /* Use normal mode. */
+ } else if (dev->mc_count == 0) {
+ memset(mc_filter, 0x00, sizeof(mc_filter));
+ outb(1, ioaddr + RX_MODE); /* Ignore almost all multicasts. */
+ } else {
+ struct dev_mc_list *mclist;
+ int i;
+
+ memset(mc_filter, 0, sizeof(mc_filter));
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next)
+ set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) >> 26,
+ mc_filter);
}
- else
- outb(2, ioaddr + RX_MODE); /* Disable promiscuous, use normal mode */
+
+ save_flags(flags);
+ cli();
+ if (memcmp(mc_filter, lp->mc_filter, sizeof(mc_filter))) {
+ int saved_bank = inw(ioaddr + CONFIG_0);
+ /* Switch to bank 1 and set the multicast table. */
+ outw((saved_bank & ~0x0C00) | 0x0480, ioaddr + CONFIG_0);
+ for (i = 0; i < 8; i++)
+ outb(mc_filter[i], ioaddr + 8 + i);
+ memcpy(lp->mc_filter, mc_filter, sizeof(mc_filter));
+ outw(saved_bank, ioaddr + CONFIG_0);
+ }
+ restore_flags(flags);
+ return;
}
+
#ifdef MODULE
static char devicename[9] = { 0, };
static struct device dev_at1700 = {
@@ -630,8 +819,6 @@ static struct device dev_at1700 = {
static int io = 0x260;
static int irq = 0;
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
int init_module(void)
{
@@ -649,22 +836,28 @@ int init_module(void)
void
cleanup_module(void)
{
+ struct net_local *lp = dev_at1700.priv;
unregister_netdev(&dev_at1700);
+ if(lp->mca_slot)
+ {
+ mca_mark_as_unused(lp->mca_slot);
+ }
kfree(dev_at1700.priv);
dev_at1700.priv = NULL;
/* If we don't do this, we can't re-insmod it later. */
- free_irq(dev_at1700.irq, &dev_at1700);
+ free_irq(dev_at1700.irq, NULL);
release_region(dev_at1700.base_addr, AT1700_IO_EXTENT);
}
#endif /* MODULE */
/*
* Local variables:
- * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c at1700.c"
- * version-control: t
- * kept-new-versions: 5
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
+ * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c at1700.c"
* tab-width: 4
+ * c-basic-offset: 4
* c-indent-level: 4
* End:
*/
+
diff --git a/drivers/net/atari_pamsnet.c b/drivers/net/atari_pamsnet.c
index 794b4e4d5..269b7de15 100644
--- a/drivers/net/atari_pamsnet.c
+++ b/drivers/net/atari_pamsnet.c
@@ -864,9 +864,10 @@ static struct net_device_stats *net_get_stats(struct device *dev)
#ifdef MODULE
+static char devicename[9] = { 0, };
static struct device pam_dev =
{
- " ", /* filled in by register_netdev() */
+ devicename, /* filled in by register_netdev() */
0, 0, 0, 0, /* memory */
0, 0, /* base, irq */
0, 0, 0, NULL, pamsnet_probe,
diff --git a/drivers/net/atp.c b/drivers/net/atp.c
index 0e5b92b7f..658c894b9 100644
--- a/drivers/net/atp.c
+++ b/drivers/net/atp.c
@@ -556,7 +556,7 @@ net_interrupt(int irq, void *dev_id, struct pt_regs * regs)
}
num_tx_since_rx++;
} else if (num_tx_since_rx > 8
- && jiffies > dev->last_rx + 100) {
+ && jiffies - dev->last_rx > 100) {
if (net_debug > 2)
printk("%s: Missed packet? No Rx after %d Tx and %ld jiffies"
" status %02x CMR1 %02x.\n", dev->name,
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index aef810322..c2e26819b 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -17,6 +17,7 @@
#include <asm/io.h>
#include <asm/page.h>
#include <asm/pgtable.h>
+#include <asm/feature.h>
#include "bmac.h"
#define trunc_page(x) ((void *)(((unsigned long)(x)) & ~((unsigned long)(PAGE_SIZE - 1))))
@@ -30,15 +31,6 @@
/* switch to use multicast code lifted from sunhme driver */
#define SUNHME_MULTICAST
-/* a bunch of constants for the "Heathrow" interrupt controller.
- These really should be in an include file somewhere */
-#define IoBaseHeathrow ((unsigned *)0xf3000000)
-#define HeathrowFCR 0x0038 /* FCR offset from Heathrow Base Address */
-#define fcrEnetEnabledBits 0x60000000 /* mask to enable Enet Xcvr/Controller */
-#define fcrResetEnetCell 0x80000000 /* mask used to reset Enet cell */
-#define fcrClearResetEnetCell 0x7fffffff /* mask used to clear reset Enet cell */
-#define fcrDisableEnet 0x1fffffff /* mask to disable Enet Xcvr/Controller */
-
#define N_RX_RING 64
#define N_TX_RING 32
#define MAX_TX_ACTIVE 1
@@ -62,6 +54,7 @@ struct bmac_data {
int rx_dma_intr;
volatile struct dbdma_cmd *tx_cmds; /* xmit dma command list */
volatile struct dbdma_cmd *rx_cmds; /* recv dma command list */
+ struct device_node *node;
struct sk_buff *rx_bufs[N_RX_RING];
int rx_fill;
int rx_empty;
@@ -122,6 +115,7 @@ bmac_reg_entry_t reg_entries[N_REG_ENTRIES] = {
};
struct device *bmac_devs = NULL;
+static int is_bmac_plus;
#if 0
/*
@@ -157,8 +151,6 @@ static void bmac_txdma_intr(int irq, void *dev_id, struct pt_regs *regs);
static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs);
static void bmac_set_timeout(struct device *dev);
static void bmac_tx_timeout(unsigned long data);
-static void bmac_reset_chip(struct device *dev);
-static void bmac_init_registers(struct device *dev);
static int bmac_proc_info ( char *buffer, char **start, off_t offset, int length, int dummy);
static int bmac_output(struct sk_buff *skb, struct device *dev);
static void bmac_start(struct device *dev);
@@ -240,34 +232,86 @@ bmac_reset_chip(struct device *dev)
struct bmac_data *bp = (struct bmac_data *) dev->priv;
volatile struct dbdma_regs *rd = bp->rx_dma;
volatile struct dbdma_regs *td = bp->tx_dma;
- volatile unsigned *heathrowFCR;
- unsigned int fcrValue;
dbdma_reset(rd);
dbdma_reset(td);
- heathrowFCR = (unsigned *)((unsigned char *)IoBaseHeathrow + HeathrowFCR);
+ feature_set(bp->node, FEATURE_BMac_IO_enable);
+ udelay(10000);
+ feature_set(bp->node, FEATURE_BMac_reset);
+ udelay(10000);
+ feature_clear(bp->node, FEATURE_BMac_reset);
+ udelay(10000);
+}
- fcrValue = in_le32(heathrowFCR);
+#define MIFDELAY udelay(500)
- fcrValue &= fcrDisableEnet; /* clear out Xvr and Controller Bit */
- out_le32(heathrowFCR, fcrValue);
- udelay(50000);
+static unsigned int
+bmac_mif_readbits(struct device *dev, int nb)
+{
+ unsigned int val = 0;
+
+ while (--nb >= 0) {
+ bmwrite(dev, MIFCSR, 0);
+ MIFDELAY;
+ if (bmread(dev, MIFCSR) & 8)
+ val |= 1 << nb;
+ bmwrite(dev, MIFCSR, 1);
+ MIFDELAY;
+ }
+ bmwrite(dev, MIFCSR, 0);
+ MIFDELAY;
+ bmwrite(dev, MIFCSR, 1);
+ MIFDELAY;
+ return val;
+}
- fcrValue |= fcrResetEnetCell; /* set bit to reset them */
- out_le32(heathrowFCR, fcrValue);
- udelay(50000);
-
- fcrValue &= fcrDisableEnet;
- out_le32(heathrowFCR, fcrValue);
- udelay(50000);
+static void
+bmac_mif_writebits(struct device *dev, unsigned int val, int nb)
+{
+ int b;
+
+ while (--nb >= 0) {
+ b = (val & (1 << nb))? 6: 4;
+ bmwrite(dev, MIFCSR, b);
+ MIFDELAY;
+ bmwrite(dev, MIFCSR, b|1);
+ MIFDELAY;
+ }
+}
- fcrValue |= fcrEnetEnabledBits;
- out_le32(heathrowFCR, fcrValue);
- udelay(50000);
-
- out_le32(heathrowFCR, fcrValue);
- udelay(50000);
+static unsigned int
+bmac_mif_read(struct device *dev, unsigned int addr)
+{
+ unsigned int val;
+
+ bmwrite(dev, MIFCSR, 4);
+ MIFDELAY;
+ bmac_mif_writebits(dev, ~0U, 32);
+ bmac_mif_writebits(dev, 6, 4);
+ bmac_mif_writebits(dev, addr, 10);
+ bmwrite(dev, MIFCSR, 2);
+ MIFDELAY;
+ bmwrite(dev, MIFCSR, 1);
+ MIFDELAY;
+ val = bmac_mif_readbits(dev, 17);
+ bmwrite(dev, MIFCSR, 4);
+ MIFDELAY;
+ printk(KERN_DEBUG "bmac_mif_read(%x) -> %x\n", addr, val);
+ return val;
+}
+
+static void
+bmac_mif_write(struct device *dev, unsigned int addr, unsigned int val)
+{
+ bmwrite(dev, MIFCSR, 4);
+ MIFDELAY;
+ bmac_mif_writebits(dev, ~0U, 32);
+ bmac_mif_writebits(dev, 5, 4);
+ bmac_mif_writebits(dev, addr, 10);
+ bmac_mif_writebits(dev, 2, 2);
+ bmac_mif_writebits(dev, val, 16);
+ bmac_mif_writebits(dev, 3, 2);
}
static void
@@ -280,14 +324,23 @@ bmac_init_registers(struct device *dev)
/* XXDEBUG(("bmac: enter init_registers\n")); */
+ bmwrite(dev, RXRST, RxResetValue);
bmwrite(dev, TXRST, TxResetBit);
+ i = 100;
do {
+ --i;
+ udelay(10000);
regValue = bmread(dev, TXRST); /* wait for reset to clear..acknowledge */
- } while (regValue & TxResetBit);
+ } while ((regValue & TxResetBit) && i > 0);
+
+ if (!is_bmac_plus) {
+ regValue = bmread(dev, XCVRIF);
+ regValue |= ClkBit | SerialMode | COLActiveLow;
+ bmwrite(dev, XCVRIF, regValue);
+ udelay(10000);
+ }
- bmwrite(dev, RXRST, RxResetValue);
- bmwrite(dev, XCVRIF, ClkBit | SerialMode | COLActiveLow);
bmwrite(dev, RSEED, (unsigned short)0x1968);
regValue = bmread(dev, XIFC);
@@ -322,8 +375,6 @@ bmac_init_registers(struct device *dev)
//bmwrite(dev, TXCFG, TxMACEnable); /* TxNeverGiveUp maybe later */
bmread(dev, STATUS); /* read it just to clear it */
- bmwrite(dev, INTDISABLE, EnableNormal);
-
/* zero out the chip Hash Filter registers */
for (i=0; i<4; i++) bp->hash_table_mask[i] = 0;
bmwrite(dev, BHASH3, bp->hash_table_mask[0]); /* bits 15 - 0 */
@@ -335,10 +386,11 @@ bmac_init_registers(struct device *dev)
bmwrite(dev, MADD0, *pWord16++);
bmwrite(dev, MADD1, *pWord16++);
bmwrite(dev, MADD2, *pWord16);
-
bmwrite(dev, RXCFG, RxCRCNoStrip | RxHashFilterEnable | RxRejectOwnPackets);
-
+
+ bmwrite(dev, INTDISABLE, EnableNormal);
+
return;
}
@@ -366,18 +418,30 @@ bmac_start_chip(struct device *dev)
/* enable rx dma channel */
dbdma_continue(rd);
+
+ oldConfig = bmread(dev, TXCFG);
+ bmwrite(dev, TXCFG, oldConfig | TxMACEnable );
/* turn on rx plus any other bits already on (promiscuous possibly) */
oldConfig = bmread(dev, RXCFG);
bmwrite(dev, RXCFG, oldConfig | RxMACEnable );
-
- oldConfig = bmread(dev, TXCFG);
- bmwrite(dev, TXCFG, oldConfig | TxMACEnable );
+ udelay(20000);
}
static int
bmac_init_chip(struct device *dev)
{
+ if (is_bmac_plus && bmac_mif_read(dev, 2) == 0x7810) {
+ if (bmac_mif_read(dev, 4) == 0xa1) {
+ bmac_mif_write(dev, 0, 0x1000);
+ } else {
+ bmac_mif_write(dev, 4, 0xa1);
+ bmac_mif_write(dev, 0, 0x1200);
+ }
+ /* XXX debugging */
+ bmac_mif_read(dev, 0);
+ bmac_mif_read(dev, 4);
+ }
bmac_init_registers(dev);
return 1;
}
@@ -556,6 +620,8 @@ static int bmac_transmit_packet(struct sk_buff *skb, struct device *dev)
bp->tx_bufs[bp->tx_fill] = skb;
bp->tx_fill = i;
+ bp->stats.tx_bytes += skb->len;
+
dbdma_continue(td);
return 0;
@@ -605,6 +671,7 @@ static void bmac_rxdma_intr(int irq, void *dev_id, struct pt_regs *regs)
skb_reserve(bp->rx_bufs[i], 2);
bmac_construct_rxbuff(bp->rx_bufs[i]->data, &bp->rx_cmds[i]);
++bp->stats.rx_packets;
+ bp->stats.rx_bytes += nb;
} else {
++bp->stats.rx_dropped;
}
@@ -1144,8 +1211,16 @@ bmac_probe(struct device *dev)
unsigned char *addr;
static struct device_node *all_bmacs = NULL, *next_bmac;
- if (all_bmacs == NULL)
- all_bmacs = next_bmac = find_devices("bmac");
+ if (all_bmacs == NULL) {
+ all_bmacs = find_devices("bmac");
+ is_bmac_plus = 0;
+ if (all_bmacs == NULL) {
+ all_bmacs = find_compatible_devices("network", "bmac+");
+ if (all_bmacs)
+ is_bmac_plus = 1;
+ }
+ next_bmac = all_bmacs;
+ }
bmacs = next_bmac;
if (bmacs == NULL) return -ENODEV;
next_bmac = bmacs->next;
@@ -1157,7 +1232,7 @@ bmac_probe(struct device *dev)
bmacs->full_name);
return -EINVAL;
}
-
+
if (dev == NULL) {
dev = init_etherdev(NULL, PRIV_BYTES);
bmac_devs = dev; /*KLUDGE!!*/
@@ -1169,7 +1244,7 @@ bmac_probe(struct device *dev)
dev->base_addr = bmacs->addrs[0].address;
dev->irq = bmacs->intrs[0].line;
-
+
bmwrite(dev, INTDISABLE, DisableAll);
addr = get_property(bmacs, "mac-address", NULL);
@@ -1216,6 +1291,7 @@ bmac_probe(struct device *dev)
bp->queue = (struct sk_buff_head *)(bp->rx_cmds + N_RX_RING + 1);
skb_queue_head_init(bp->queue);
+ bp->node = bmacs;
memset(&bp->stats, 0, sizeof(bp->stats));
memset((char *) bp->tx_cmds, 0,
(N_TX_RING + N_RX_RING + 2) * sizeof(struct dbdma_cmd));
diff --git a/drivers/net/com20020.c b/drivers/net/com20020.c
index 5c9ac32ab..093a5acf0 100644
--- a/drivers/net/com20020.c
+++ b/drivers/net/com20020.c
@@ -6,9 +6,6 @@
Written 1994-1996 by Avery Pennarun,
which was in turn derived from skeleton.c by Donald Becker.
- Contact Avery at: apenwarr@bond.net or
- RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-
**********************
The original copyright of skeleton.c was as follows:
@@ -214,7 +211,7 @@ void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, cha
static const char *version =
- "com20020.c: v3.00 97/11/09 Avery Pennarun <apenwarr@bond.net> et al.\n";
+ "com20020.c: v3.00 97/11/09 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
/****************************************************************************
* *
diff --git a/drivers/net/com90io.c b/drivers/net/com90io.c
index 46f5d6f2e..309654460 100644
--- a/drivers/net/com90io.c
+++ b/drivers/net/com90io.c
@@ -6,9 +6,6 @@
Written 1994-1996 by Avery Pennarun,
which was in turn derived from skeleton.c by Donald Becker.
- Contact Avery at: apenwarr@bond.net or
- RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-
**********************
The original copyright of skeleton.c was as follows:
@@ -183,7 +180,7 @@ void put_whole_buffer (struct device *dev, unsigned offset, unsigned length, cha
static const char *version =
- "com90io.c: v3.00 97/11/09 Avery Pennarun <apenwarr@bond.net> et al.\n";
+ "com90io.c: v3.00 97/11/09 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
/****************************************************************************
diff --git a/drivers/net/com90xx.c b/drivers/net/com90xx.c
index f605ce20b..3ca5a5ef8 100644
--- a/drivers/net/com90xx.c
+++ b/drivers/net/com90xx.c
@@ -4,9 +4,6 @@
Written 1994-1996 by Avery Pennarun,
which was in turn derived from skeleton.c by Donald Becker.
- Contact Avery at: apenwarr@bond.net or
- RR #5 Pole Line Road, Thunder Bay, ON, Canada P7C 5M9
-
**********************
The original copyright of skeleton.c was as follows:
@@ -153,7 +150,7 @@ extern int arcnet_num_devs;
#define ARCRESET inb(_RESET)
static const char *version =
-"com90xx.c: v3.00 97/11/09 Avery Pennarun <apenwarr@bond.net> et al.\n";
+"com90xx.c: v3.00 97/11/09 Avery Pennarun <apenwarr@worldvisions.ca> et al.\n";
/****************************************************************************
diff --git a/drivers/net/cops.c b/drivers/net/cops.c
index 1c0635c62..e920debeb 100644
--- a/drivers/net/cops.c
+++ b/drivers/net/cops.c
@@ -140,7 +140,7 @@ static int irq = 0; /* Default IRQ */
* N.B.
*
* The Daystar Digital LT200 boards do not support interrupt-driven
- * IO. You must specify 'io=0xff' as a module parameter to invoke
+ * IO. You must specify 'irq=0xff' as a module parameter to invoke
* polled mode. I also believe that the port probing logic is quite
* dangerous at best and certainly hopeless for a polled card. Best to
* specify both. - Steve H.
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index e83c8faf9..a5e0c68b2 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -403,8 +403,7 @@ reset_chip(struct device *dev))
/* wait 30 ms */
current->state = TASK_INTERRUPTIBLE;
- current->timeout = jiffies + 3;
- schedule();
+ schedule_timeout(30*HZ/1000);
if (lp->chip_type != CS8900) {
/* Hardware problem requires PNP registers to be reconfigured after a reset */
diff --git a/drivers/net/daynaport.c b/drivers/net/daynaport.c
index 0b550fd57..00c0ed9b6 100644
--- a/drivers/net/daynaport.c
+++ b/drivers/net/daynaport.c
@@ -30,6 +30,8 @@ static const char *version =
#include <linux/nubus.h>
#include <asm/io.h>
#include <asm/system.h>
+#include <asm/hwtest.h>
+#include <linux/delay.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -48,14 +50,21 @@ static void dayna_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
static void dayna_block_input(struct device *dev, int count,
struct sk_buff *skb, int ring_offset);
static void dayna_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
+ const unsigned char *buf, const int start_page);
static void sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
int ring_page);
static void sane_block_input(struct device *dev, int count,
struct sk_buff *skb, int ring_offset);
static void sane_block_output(struct device *dev, int count,
- const unsigned char *buf, const start_page);
+ const unsigned char *buf, const int start_page);
+
+static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
+ int ring_page);
+static void slow_sane_block_input(struct device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
+static void slow_sane_block_output(struct device *dev, int count,
+ const unsigned char *buf, const int start_page);
#define WD_START_PG 0x00 /* First page of TX buffer */
@@ -81,11 +90,11 @@ static int test_8390(volatile char *ptr, int scale)
int regd;
int v;
- if(nubus_hwreg_present(&ptr[0x00])==0)
+ if(hwreg_present(&ptr[0x00])==0)
return -EIO;
- if(nubus_hwreg_present(&ptr[0x0D<<scale])==0)
+ if(hwreg_present(&ptr[0x0D<<scale])==0)
return -EIO;
- if(nubus_hwreg_present(&ptr[0x0D<<scale])==0)
+ if(hwreg_present(&ptr[0x0D<<scale])==0)
return -EIO;
ptr[0x00]=E8390_NODMA+E8390_PAGE1+E8390_STOP;
regd=ptr[0x0D<<scale];
@@ -136,6 +145,51 @@ int ns8390_ident(struct nubus_type *nb)
}
/*
+ * Memory probe for 8390 cards
+ */
+
+int apple_8390_mem_probe(volatile unsigned short *p)
+{
+ int i, j;
+ /*
+ * Algorithm.
+ * 1. Check each block size of memory doesn't fault
+ * 2. Write a value to it
+ * 3. Check all previous blocks are unaffected
+ */
+
+ for(i=0;i<2;i++)
+ {
+ volatile unsigned short *m=p+4096*i;
+ /* Unwriteable - we have a fully decoded card and the
+ RAM end located */
+
+ if(hwreg_present(m)==0)
+ return 8192*i;
+
+ *m=0xA5A0|i;
+
+ for(j=0;j<i;j++)
+ {
+ /* Partial decode and wrap ? */
+ if(p[4096*j]!=(0xA5A0|j))
+ {
+ /* This is the first misdecode, so it had
+ one less page than we tried */
+ return 8192*i;
+ }
+ j++;
+ }
+ /* Ok it still decodes.. move on 8K */
+ }
+ /*
+ * We don't look past 16K. That should cover most cards
+ * and above 16K there isnt really any gain.
+ */
+ return 16384;
+ }
+
+/*
* Probe for 8390 cards.
* The ns8390_probe1() routine initializes the card and fills the
* station address field. On entry base_addr is set, irq is set
@@ -216,16 +270,21 @@ int ns8390_probe(struct nubus_device_specifier *d, int slot, struct nubus_type *
/* Apple, Farallon, Asante */
if(id==NS8390_APPLE|| id==NS8390_FARALLON || id==NS8390_ASANTE)
{
+ int memsize;
+
dev->base_addr=(int)(nubus_slot_addr(slot)+APPLE_8390_BASE);
dev->mem_start=(int)(nubus_slot_addr(slot)+APPLE_8390_MEM);
- dev->mem_end=dev->mem_start+APPLE_MEMSIZE; /* 8K it seems */
+
+ memsize = apple_8390_mem_probe((void *)dev->mem_start);
+
+ dev->mem_end=dev->mem_start+memsize;
dev->irq=slot;
printk("apple/clone: testing board: ");
- printk("memory - ");
+ printk("%dK memory - ", memsize>>10);
i=(void *)dev->mem_start;
- memset((void *)i,0xAA, DAYNA_MEMSIZE);
+ memset((void *)i,0xAA, memsize);
while(i<(volatile unsigned short *)dev->mem_end)
{
if(*i!=0xAAAA)
@@ -366,8 +425,15 @@ int ns8390_probe1(struct device *dev, int word16, char *model_name, int type, in
ei_status.get_8390_hdr = &dayna_get_8390_hdr;
ei_status.reg_offset = fwrd4_offsets;
break;
- case NS8390_APPLE: /* Apple/Asante/Farallon */
case NS8390_FARALLON:
+ case NS8390_APPLE: /* Apple/Asante/Farallon */
+ /* 16 bit card, register map is reversed */
+ ei_status.reset_8390 = &ns8390_no_reset;
+ ei_status.block_input = &slow_sane_block_input;
+ ei_status.block_output = &slow_sane_block_output;
+ ei_status.get_8390_hdr = &slow_sane_get_8390_hdr;
+ ei_status.reg_offset = back4_offsets;
+ break;
case NS8390_ASANTE:
/* 16 bit card, register map is reversed */
ei_status.reset_8390 = &ns8390_no_reset;
@@ -442,7 +508,7 @@ static void interlan_reset(struct device *dev)
{
unsigned char *target=nubus_slot_addr(dev->irq);
if (ei_debug > 1)
- printk("Need to reset the NS8390 t=%lu...", jiffies);
+ printk("Need to reset the NS8390 t=%lu...", jiffies);
ei_status.txing = 0;
/* This write resets the card */
target[0xC0000]=0;
@@ -585,6 +651,7 @@ static void sane_block_input(struct device *dev, int count, struct sk_buff *skb,
}
}
+
static void sane_block_output(struct device *dev, int count, const unsigned char *buf,
int start_page)
{
@@ -593,6 +660,81 @@ static void sane_block_output(struct device *dev, int count, const unsigned char
memcpy((char *)dev->mem_start+shmem, buf, count);
}
+static void word_memcpy_tocard(void *tp, const void *fp, int count)
+{
+ volatile unsigned short *to = tp;
+ const unsigned short *from = fp;
+
+ count++;
+ count/=2;
+
+ while(count--)
+ *to++=*from++;
+}
+
+static void word_memcpy_fromcard(void *tp, const void *fp, int count)
+{
+ unsigned short *to = tp;
+ const volatile unsigned short *from = fp;
+
+ count++;
+ count/=2;
+
+ while(count--)
+ *to++=*from++;
+}
+
+static void slow_sane_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ unsigned long hdr_start = (ring_page - WD_START_PG)<<8;
+ word_memcpy_fromcard((void *)hdr, (char *)dev->mem_start+hdr_start, 4);
+ /* Register endianism - fix here rather than 8390.c */
+ hdr->count=(hdr->count&0xFF)<<8|(hdr->count>>8);
+}
+
+static void slow_sane_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset)
+{
+ unsigned long xfer_base = ring_offset - (WD_START_PG<<8);
+ unsigned long xfer_start = xfer_base+dev->mem_start;
+
+ if (xfer_start + count > dev->rmem_end)
+ {
+ /* We must wrap the input move. */
+ int semi_count = dev->rmem_end - xfer_start;
+ word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, semi_count);
+ count -= semi_count;
+ word_memcpy_fromcard(skb->data + semi_count,
+ (char *)dev->rmem_start, count);
+ }
+ else
+ {
+ word_memcpy_fromcard(skb->data, (char *)dev->mem_start+xfer_base, count);
+ }
+}
+
+static void slow_sane_block_output(struct device *dev, int count, const unsigned char *buf,
+ int start_page)
+{
+ long shmem = (start_page - WD_START_PG)<<8;
+
+ word_memcpy_tocard((char *)dev->mem_start+shmem, buf, count);
+#if 0
+ long shmem = (start_page - WD_START_PG)<<8;
+ volatile unsigned short *to=(unsigned short *)(dev->mem_start+shmem);
+ volatile int p;
+ unsigned short *bp=(unsigned short *)buf;
+
+ count=(count+1)/2;
+
+ while(count--)
+ {
+ *to++=*bp++;
+ for(p=0;p<10;p++)
+ p++;
+ }
+#endif
+}
+
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c daynaport.c"
diff --git a/drivers/net/de4x5.c b/drivers/net/de4x5.c
index 57502ecc7..bbc86f2a2 100644
--- a/drivers/net/de4x5.c
+++ b/drivers/net/de4x5.c
@@ -409,11 +409,17 @@
Fix lastPCI to correctly work with compiled in
kernels and modules from bug report by
<Zlatko.Calusic@CARNet.hr> et al.
+ 0.542 15-Sep-98 Fix dc2114x_autoconf() to stop multiple messages
+ when media is unconnected.
+ Change dev->interrupt to lp->interrupt to ensure
+ alignment for Alpha's and avoid their unaligned
+ access traps. This flag is merely for log messages:
+ should do something more definitive though...
=========================================================================
*/
-static const char *version = "de4x5.c:V0.541 1998/8/24 davies@maniac.ultranet.com\n";
+static const char *version = "de4x5.c:V0.542 1998/9/15 davies@maniac.ultranet.com\n";
#include <linux/config.h>
#include <linux/module.h>
@@ -744,6 +750,7 @@ struct de4x5_desc {
struct de4x5_private {
char adapter_name[80]; /* Adapter name */
+ u_long interrupt; /* Aligned ISR flag */
struct de4x5_desc rx_ring[NUM_RX_DESC]; /* RX descriptor ring */
struct de4x5_desc tx_ring[NUM_TX_DESC]; /* TX descriptor ring */
struct sk_buff *tx_skb[NUM_TX_DESC]; /* TX skb for freeing when sent */
@@ -965,7 +972,7 @@ static int get_hw_addr(struct device *dev);
static void srom_repair(struct device *dev, int card);
static int test_bad_enet(struct device *dev, int status);
static int an_exception(struct bus_type *lp);
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
static void eisa_probe(struct device *dev, u_long iobase);
#endif
static void pci_probe(struct device *dev, u_long iobase);
@@ -1014,7 +1021,7 @@ static int loading_module = 0;
#endif /* MODULE */
static char name[DE4X5_NAME_LENGTH + 1];
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
static u_char de4x5_irq[] = EISA_ALLOWED_IRQ_LIST;
static int lastEISA = 0;
#else
@@ -1088,7 +1095,7 @@ de4x5_probe(struct device *dev))
{
u_long iobase = dev->base_addr;
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
eisa_probe(dev, iobase);
#endif
if (lastEISA == MAX_EISA_SLOTS) {
@@ -1362,7 +1369,7 @@ de4x5_open(struct device *dev)
dev->tbusy = 0;
dev->start = 1;
- dev->interrupt = UNMASK_INTERRUPTS;
+ lp->interrupt = UNMASK_INTERRUPTS;
dev->trans_start = jiffies;
START_DE4X5;
@@ -1506,12 +1513,12 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev)
sti();
/* Test if cache is already locked - requeue skb if so */
- if (test_and_set_bit(0, (void *)&lp->cache.lock) && !dev->interrupt)
+ if (test_and_set_bit(0, (void *)&lp->cache.lock) && !lp->interrupt)
return -1;
/* Transmit descriptor ring full or stale skb */
if (dev->tbusy || lp->tx_skb[lp->tx_new]) {
- if (dev->interrupt) {
+ if (lp->interrupt) {
de4x5_putb_cache(dev, skb); /* Requeue the buffer */
} else {
de4x5_put_cache(dev, skb);
@@ -1521,7 +1528,7 @@ de4x5_queue_pkt(struct sk_buff *skb, struct device *dev)
}
} else if (skb->len > 0) {
/* If we already have stuff queued locally, use that first */
- if (lp->cache.skb && !dev->interrupt) {
+ if (lp->cache.skb && !lp->interrupt) {
de4x5_put_cache(dev, skb);
skb = de4x5_get_cache(dev);
}
@@ -1576,10 +1583,11 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
lp = (struct de4x5_private *)dev->priv;
iobase = dev->base_addr;
- if (test_and_set_bit(MASK_INTERRUPTS, (void*) &dev->interrupt))
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
-
DISABLE_IRQs; /* Ensure non re-entrancy */
+
+ if (test_and_set_bit(MASK_INTERRUPTS, (void*) &lp->interrupt))
+ printk("%s: Re-entering the interrupt handler.\n", dev->name);
+
synchronize_irq();
for (limit=0; limit<8; limit++) {
@@ -1618,7 +1626,7 @@ de4x5_interrupt(int irq, void *dev_id, struct pt_regs *regs)
lp->cache.lock = 0;
}
- dev->interrupt = UNMASK_INTERRUPTS;
+ lp->interrupt = UNMASK_INTERRUPTS;
ENABLE_IRQs;
return;
@@ -1748,7 +1756,7 @@ de4x5_tx(struct device *dev)
if (TX_BUFFS_AVAIL && dev->tbusy) { /* Any resources available? */
dev->tbusy = 0; /* Clear TX busy flag */
- if (dev->interrupt) mark_bh(NET_BH);
+ if (lp->interrupt) mark_bh(NET_BH);
}
return 0;
@@ -2020,7 +2028,7 @@ SetMulticastFilter(struct device *dev)
return;
}
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
/*
** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
** the motherboard. Upto 15 EISA devices are supported.
@@ -2088,7 +2096,7 @@ eisa_probe(struct device *dev, u_long ioaddr))
return;
}
-#endif /* !(__sparc_v9__) && !(__powerpc__) */
+#endif /* !(__sparc_v9__) && !(__powerpc__) && !defined(__alpha__) */
/*
** PCI bus I/O device probe
@@ -2351,7 +2359,7 @@ dc21040_autoconf(struct device *dev)
s32 imr;
switch (lp->media) {
- case INIT:
+ case INIT:
DISABLE_IRQs;
lp->tx_enable = NO;
lp->timeout = -1;
@@ -2369,36 +2377,36 @@ dc21040_autoconf(struct device *dev)
next_tick = dc21040_autoconf(dev);
break;
- case TP:
+ case TP:
next_tick = dc21040_state(dev, 0x8f01, 0xffff, 0x0000, 3000, BNC_AUI,
TP_SUSPECT, test_tp);
break;
- case TP_SUSPECT:
+ case TP_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21040_autoconf);
break;
- case BNC:
- case AUI:
- case BNC_AUI:
+ case BNC:
+ case AUI:
+ case BNC_AUI:
next_tick = dc21040_state(dev, 0x8f09, 0x0705, 0x0006, 3000, EXT_SIA,
BNC_AUI_SUSPECT, ping_media);
break;
- case BNC_AUI_SUSPECT:
+ case BNC_AUI_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, BNC_AUI, ping_media, dc21040_autoconf);
break;
- case EXT_SIA:
+ case EXT_SIA:
next_tick = dc21040_state(dev, 0x3041, 0x0000, 0x0006, 3000,
NC, EXT_SIA_SUSPECT, ping_media);
break;
- case EXT_SIA_SUSPECT:
+ case EXT_SIA_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, EXT_SIA, ping_media, dc21040_autoconf);
break;
- case NC:
+ case NC:
/* default to TP for all */
reset_init_sia(dev, 0x8f01, 0xffff, 0x0000);
if (lp->media != lp->c_media) {
@@ -2423,13 +2431,13 @@ dc21040_state(struct device *dev, int csr13, int csr14, int csr15, int timeout,
int linkBad;
switch (lp->local_state) {
- case 0:
+ case 0:
reset_init_sia(dev, csr13, csr14, csr15);
lp->local_state++;
next_tick = 500;
break;
- case 1:
+ case 1:
if (!lp->tx_enable) {
linkBad = fn(dev, timeout);
if (linkBad < 0) {
@@ -2462,7 +2470,7 @@ de4x5_suspect_state(struct device *dev, int timeout, int prev_state,
int linkBad;
switch (lp->local_state) {
- case 1:
+ case 1:
if (lp->linkOK) {
lp->media = prev_state;
} else {
@@ -2471,7 +2479,7 @@ de4x5_suspect_state(struct device *dev, int timeout, int prev_state,
}
break;
- case 2:
+ case 2:
linkBad = fn(dev, timeout);
if (linkBad < 0) {
next_tick = linkBad & ~TIMER_CB;
@@ -2505,7 +2513,7 @@ dc21041_autoconf(struct device *dev)
int next_tick = DE4X5_AUTOSENSE_MS;
switch (lp->media) {
- case INIT:
+ case INIT:
DISABLE_IRQs;
lp->tx_enable = NO;
lp->timeout = -1;
@@ -2525,7 +2533,7 @@ dc21041_autoconf(struct device *dev)
next_tick = dc21041_autoconf(dev);
break;
- case TP_NW:
+ case TP_NW:
if (lp->timeout < 0) {
omr = inl(DE4X5_OMR);/* Set up full duplex for the autonegotiate */
outl(omr | OMR_FDX, DE4X5_OMR);
@@ -2545,7 +2553,7 @@ dc21041_autoconf(struct device *dev)
}
break;
- case ANS:
+ case ANS:
if (!lp->tx_enable) {
irqs = STS_LNP;
irq_mask = IMR_LPM;
@@ -2567,11 +2575,11 @@ dc21041_autoconf(struct device *dev)
}
break;
- case ANS_SUSPECT:
+ case ANS_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, ANS, test_tp, dc21041_autoconf);
break;
- case TP:
+ case TP:
if (!lp->tx_enable) {
if (lp->timeout < 0) {
omr = inl(DE4X5_OMR); /* Set up half duplex for TP */
@@ -2601,11 +2609,11 @@ dc21041_autoconf(struct device *dev)
}
break;
- case TP_SUSPECT:
+ case TP_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, TP, test_tp, dc21041_autoconf);
break;
- case AUI:
+ case AUI:
if (!lp->tx_enable) {
if (lp->timeout < 0) {
omr = inl(DE4X5_OMR); /* Set up half duplex for AUI */
@@ -2631,13 +2639,13 @@ dc21041_autoconf(struct device *dev)
}
break;
- case AUI_SUSPECT:
+ case AUI_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, AUI, ping_media, dc21041_autoconf);
break;
- case BNC:
+ case BNC:
switch (lp->local_state) {
- case 0:
+ case 0:
if (lp->timeout < 0) {
omr = inl(DE4X5_OMR); /* Set up half duplex for BNC */
outl(omr & ~OMR_FDX, DE4X5_OMR);
@@ -2653,7 +2661,7 @@ dc21041_autoconf(struct device *dev)
}
break;
- case 1:
+ case 1:
if (!lp->tx_enable) {
if ((sts = ping_media(dev, 3000)) < 0) {
next_tick = sts & ~TIMER_CB;
@@ -2673,11 +2681,11 @@ dc21041_autoconf(struct device *dev)
}
break;
- case BNC_SUSPECT:
+ case BNC_SUSPECT:
next_tick = de4x5_suspect_state(dev, 1000, BNC, ping_media, dc21041_autoconf);
break;
- case NC:
+ case NC:
omr = inl(DE4X5_OMR); /* Set up full duplex for the autonegotiate */
outl(omr | OMR_FDX, DE4X5_OMR);
reset_init_sia(dev, 0xef01, 0xffff, 0x0008);/* Initialise the SIA */
@@ -3081,9 +3089,9 @@ dc2114x_autoconf(struct device *dev)
}
next_tick = dc2114x_autoconf(dev);
} else if (((lp->media == _100Mb) && is_100_up(dev)) ||
- ((lp->media == _10Mb) && is_10_up(dev)) ||
- (lp->media == TP) ||
- (lp->media == BNC) || (lp->media == AUI)) {
+ (((lp->media == _10Mb) || (lp->media == TP) ||
+ (lp->media == BNC) || (lp->media == AUI)) &&
+ is_10_up(dev))) {
next_tick = dc2114x_autoconf(dev);
} else {
lp->tcount++;
@@ -4049,7 +4057,7 @@ enet_addr_rst(u_long aprom_addr)
if (data == dev.Sig[0]) { /* rare case.... */
j=1;
} else {
- j=0;
+ j=0;
}
}
}
@@ -4121,8 +4129,10 @@ get_hw_addr(struct device *dev)
srom_repair(dev, broken);
#ifdef CONFIG_PMAC
- /* If the address starts with 00 a0, we have to bit-reverse
- each byte of the address. */
+ /*
+ ** If the address starts with 00 a0, we have to bit-reverse
+ ** each byte of the address.
+ */
if (dev->dev_addr[0] == 0 && dev->dev_addr[1] == 0xa0) {
for (i = 0; i < ETH_ALEN; ++i) {
int x = dev->dev_addr[i];
@@ -5816,7 +5826,7 @@ count_adapters(void)
u_int class = DE4X5_CLASS_CODE;
u_int device;
-#if !defined(__sparc_v9__) && !defined(__powerpc__)
+#if !defined(__sparc_v9__) && !defined(__powerpc__) && !defined(__alpha__)
char name[DE4X5_STRLEN];
u_long iobase = 0x1000;
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 0320cc322..c3701e230 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1,213 +1,233 @@
/* depca.c: A DIGITAL DEPCA & EtherWORKS ethernet driver for linux.
- Written 1994, 1995 by David C. Davies.
-
-
- Copyright 1994 David C. Davies
- and
- United States Government
- (as represented by the Director, National Security Agency).
-
- Copyright 1995 Digital Equipment Corporation.
-
-
- This software may be used and distributed according to the terms of
- the GNU Public License, incorporated herein by reference.
-
- This driver is written for the Digital Equipment Corporation series
- of DEPCA and EtherWORKS ethernet cards:
-
- DEPCA (the original)
- DE100
- DE101
- DE200 Turbo
- DE201 Turbo
- DE202 Turbo (TP BNC)
- DE210
- DE422 (EISA)
-
- The driver has been tested on DE100, DE200 and DE202 cards in a
- relatively busy network. The DE422 has been tested a little.
-
- This driver will NOT work for the DE203, DE204 and DE205 series of
- cards, since they have a new custom ASIC in place of the AMD LANCE
- chip. See the 'ewrk3.c' driver in the Linux source tree for running
- those cards.
-
- I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
- a DECstation 5000/200.
-
- The author may be reached at davies@maniac.ultranet.com
-
- =========================================================================
-
- The driver was originally based on the 'lance.c' driver from Donald
- Becker which is included with the standard driver distribution for
- linux. V0.4 is a complete re-write with only the kernel interface
- remaining from the original code.
-
- 1) Lance.c code in /linux/drivers/net/
- 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
- AMD, 1992 [(800) 222-9323].
- 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
- AMD, Pub. #17881, May 1993.
- 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
- AMD, Pub. #16907, May 1992
- 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
- 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
- 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
- Digital Equipment Corporation, 1989
- 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
- Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
-
-
- Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
- driver.
-
- The original DEPCA card requires that the ethernet ROM address counter
- be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
- only done when a 0x08 is read as the first address octet (to minimise
- the chances of writing over some other hardware's I/O register). The
- NICSR accesses have been changed to byte accesses for all the cards
- supported by this driver, since there is only one useful bit in the MSB
- (remote boot timeout) and it is not used. Also, there is a maximum of
- only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
- help debugging all this (and holding my feet to the fire until I got it
- right).
-
- The DE200 series boards have on-board 64kB RAM for use as a shared
- memory network buffer. Only the DE100 cards make use of a 2kB buffer
- mode which has not been implemented in this driver (only the 32kB and
- 64kB modes are supported [16kB/48kB for the original DEPCA]).
-
- At the most only 2 DEPCA cards can be supported on the ISA bus because
- there is only provision for two I/O base addresses on each card (0x300
- and 0x200). The I/O address is detected by searching for a byte sequence
- in the Ethernet station address PROM at the expected I/O address for the
- Ethernet PROM. The shared memory base address is 'autoprobed' by
- looking for the self test PROM and detecting the card name. When a
- second DEPCA is detected, information is placed in the base_addr
- variable of the next device structure (which is created if necessary),
- thus enabling ethif_probe initialization for the device. More than 2
- EISA cards can be supported, but care will be needed assigning the
- shared memory to ensure that each slot has the correct IRQ, I/O address
- and shared memory address assigned.
-
- ************************************************************************
-
- NOTE: If you are using two ISA DEPCAs, it is important that you assign
- the base memory addresses correctly. The driver autoprobes I/O 0x300
- then 0x200. The base memory address for the first device must be less
- than that of the second so that the auto probe will correctly assign the
- I/O and memory addresses on the same card. I can't think of a way to do
- this unambiguously at the moment, since there is nothing on the cards to
- tie I/O and memory information together.
-
- I am unable to test 2 cards together for now, so this code is
- unchecked. All reports, good or bad, are welcome.
-
- ************************************************************************
-
- The board IRQ setting must be at an unused IRQ which is auto-probed
- using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
- {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
- really IRQ9 in machines with 16 IRQ lines.
-
- No 16MB memory limitation should exist with this driver as DMA is not
- used and the common memory area is in low memory on the network card (my
- current system has 20MB and I've not had problems yet).
-
- The ability to load this driver as a loadable module has been added. To
- utilise this ability, you have to do <8 things:
-
- 0) have a copy of the loadable modules code installed on your system.
- 1) copy depca.c from the /linux/drivers/net directory to your favourite
- temporary directory.
- 2) if you wish, edit the source code near line 1530 to reflect the I/O
- address and IRQ you're using (see also 5).
- 3) compile depca.c, but include -DMODULE in the command line to ensure
- that the correct bits are compiled (see end of source code).
- 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
- kernel with the depca configuration turned off and reboot.
- 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
- [Alan Cox: Changed the code to allow command line irq/io assignments]
- [Dave Davies: Changed the code to allow command line mem/name
- assignments]
- 6) run the net startup bits for your eth?? interface manually
- (usually /etc/rc.inet[12] at boot time).
- 7) enjoy!
-
- Note that autoprobing is not allowed in loadable modules - the system is
- already up and running and you're messing with interrupts.
-
- To unload a module, turn off the associated interface
- 'ifconfig eth?? down' then 'rmmod depca'.
-
- To assign a base memory address for the shared memory when running as a
- loadable module, see 5 above. To include the adapter name (if you have
- no PROM but know the card name) also see 5 above. Note that this last
- option will not work with kernel built-in depca's.
-
- The shared memory assignment for a loadable module makes sense to avoid
- the 'memory autoprobe' picking the wrong shared memory (for the case of
- 2 depca's in a PC).
-
-
- TO DO:
- ------
-
-
- Revision History
- ----------------
-
- Version Date Description
-
- 0.1 25-jan-94 Initial writing.
- 0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
- 0.3 1-feb-94 Added multiple DEPCA support.
- 0.31 4-feb-94 Added DE202 recognition.
- 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
- 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
- Add jabber packet fix from murf@perftech.com
- and becker@super.org
- 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
- 0.35 8-mar-94 Added DE201 recognition. Tidied up.
- 0.351 30-apr-94 Added EISA support. Added DE422 recognition.
- 0.36 16-may-94 DE422 fix released.
- 0.37 22-jul-94 Added MODULE support
- 0.38 15-aug-94 Added DBR ROM switch in depca_close().
- Multi DEPCA bug fix.
- 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
- 0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
- 0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
- 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
- <stromain@alf.dec.com>
- 0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
- 0.385 3-apr-95 Fix a recognition bug reported by
- <ryan.niemi@lastfrontier.com>
- 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
- 0.40 25-May-95 Rewrite for portability & updated.
- ALPHA support from <jestabro@amt.tay1.dec.com>
- 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
- suggestion by <heiko@colossus.escape.de>
- 0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
- modules.
- Add 'adapter_name' for loadable modules when no PROM.
- Both above from a suggestion by
- <pchen@woodruffs121.residence.gatech.edu>.
- Add new multicasting code.
- 0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
- 0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
- 0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
- 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
-
- =========================================================================
- */
-
-static const char *version = "depca.c:v0.43 96/8/16 davies@maniac.ultranet.com\n";
-
+ Written 1994, 1995 by David C. Davies.
+
+
+ Copyright 1994 David C. Davies
+ and
+ United States Government
+ (as represented by the Director, National Security Agency).
+
+ Copyright 1995 Digital Equipment Corporation.
+
+
+ This software may be used and distributed according to the terms of
+ the GNU Public License, incorporated herein by reference.
+
+ This driver is written for the Digital Equipment Corporation series
+ of DEPCA and EtherWORKS ethernet cards:
+
+ DEPCA (the original)
+ DE100
+ DE101
+ DE200 Turbo
+ DE201 Turbo
+ DE202 Turbo (TP BNC)
+ DE210
+ DE422 (EISA)
+
+ The driver has been tested on DE100, DE200 and DE202 cards in a
+ relatively busy network. The DE422 has been tested a little.
+
+ This driver will NOT work for the DE203, DE204 and DE205 series of
+ cards, since they have a new custom ASIC in place of the AMD LANCE
+ chip. See the 'ewrk3.c' driver in the Linux source tree for running
+ those cards.
+
+ I have benchmarked the driver with a DE100 at 595kB/s to (542kB/s from)
+ a DECstation 5000/200.
+
+ The author may be reached at davies@maniac.ultranet.com
+
+ =========================================================================
+
+ The driver was originally based on the 'lance.c' driver from Donald
+ Becker which is included with the standard driver distribution for
+ linux. V0.4 is a complete re-write with only the kernel interface
+ remaining from the original code.
+
+ 1) Lance.c code in /linux/drivers/net/
+ 2) "Ethernet/IEEE 802.3 Family. 1992 World Network Data Book/Handbook",
+ AMD, 1992 [(800) 222-9323].
+ 3) "Am79C90 CMOS Local Area Network Controller for Ethernet (C-LANCE)",
+ AMD, Pub. #17881, May 1993.
+ 4) "Am79C960 PCnet-ISA(tm), Single-Chip Ethernet Controller for ISA",
+ AMD, Pub. #16907, May 1992
+ 5) "DEC EtherWORKS LC Ethernet Controller Owners Manual",
+ Digital Equipment corporation, 1990, Pub. #EK-DE100-OM.003
+ 6) "DEC EtherWORKS Turbo Ethernet Controller Owners Manual",
+ Digital Equipment corporation, 1990, Pub. #EK-DE200-OM.003
+ 7) "DEPCA Hardware Reference Manual", Pub. #EK-DEPCA-PR
+ Digital Equipment Corporation, 1989
+ 8) "DEC EtherWORKS Turbo_(TP BNC) Ethernet Controller Owners Manual",
+ Digital Equipment corporation, 1991, Pub. #EK-DE202-OM.001
+
+
+ Peter Bauer's depca.c (V0.5) was referred to when debugging V0.1 of this
+ driver.
+
+ The original DEPCA card requires that the ethernet ROM address counter
+ be enabled to count and has an 8 bit NICSR. The ROM counter enabling is
+ only done when a 0x08 is read as the first address octet (to minimise
+ the chances of writing over some other hardware's I/O register). The
+ NICSR accesses have been changed to byte accesses for all the cards
+ supported by this driver, since there is only one useful bit in the MSB
+ (remote boot timeout) and it is not used. Also, there is a maximum of
+ only 48kB network RAM for this card. My thanks to Torbjorn Lindh for
+ help debugging all this (and holding my feet to the fire until I got it
+ right).
+
+ The DE200 series boards have on-board 64kB RAM for use as a shared
+ memory network buffer. Only the DE100 cards make use of a 2kB buffer
+ mode which has not been implemented in this driver (only the 32kB and
+ 64kB modes are supported [16kB/48kB for the original DEPCA]).
+
+ At the most only 2 DEPCA cards can be supported on the ISA bus because
+ there is only provision for two I/O base addresses on each card (0x300
+ and 0x200). The I/O address is detected by searching for a byte sequence
+ in the Ethernet station address PROM at the expected I/O address for the
+ Ethernet PROM. The shared memory base address is 'autoprobed' by
+ looking for the self test PROM and detecting the card name. When a
+ second DEPCA is detected, information is placed in the base_addr
+ variable of the next device structure (which is created if necessary),
+ thus enabling ethif_probe initialization for the device. More than 2
+ EISA cards can be supported, but care will be needed assigning the
+ shared memory to ensure that each slot has the correct IRQ, I/O address
+ and shared memory address assigned.
+
+ ************************************************************************
+
+ NOTE: If you are using two ISA DEPCAs, it is important that you assign
+ the base memory addresses correctly. The driver autoprobes I/O 0x300
+ then 0x200. The base memory address for the first device must be less
+ than that of the second so that the auto probe will correctly assign the
+ I/O and memory addresses on the same card. I can't think of a way to do
+ this unambiguously at the moment, since there is nothing on the cards to
+ tie I/O and memory information together.
+
+ I am unable to test 2 cards together for now, so this code is
+ unchecked. All reports, good or bad, are welcome.
+
+ ************************************************************************
+
+ The board IRQ setting must be at an unused IRQ which is auto-probed
+ using Donald Becker's autoprobe routines. DEPCA and DE100 board IRQs are
+ {2,3,4,5,7}, whereas the DE200 is at {5,9,10,11,15}. Note that IRQ2 is
+ really IRQ9 in machines with 16 IRQ lines.
+
+ No 16MB memory limitation should exist with this driver as DMA is not
+ used and the common memory area is in low memory on the network card (my
+ current system has 20MB and I've not had problems yet).
+
+ The ability to load this driver as a loadable module has been added. To
+ utilise this ability, you have to do <8 things:
+
+ 0) have a copy of the loadable modules code installed on your system.
+ 1) copy depca.c from the /linux/drivers/net directory to your favourite
+ temporary directory.
+ 2) if you wish, edit the source code near line 1530 to reflect the I/O
+ address and IRQ you're using (see also 5).
+ 3) compile depca.c, but include -DMODULE in the command line to ensure
+ that the correct bits are compiled (see end of source code).
+ 4) if you are wanting to add a new card, goto 5. Otherwise, recompile a
+ kernel with the depca configuration turned off and reboot.
+ 5) insmod depca.o [irq=7] [io=0x200] [mem=0xd0000] [adapter_name=DE100]
+ [Alan Cox: Changed the code to allow command line irq/io assignments]
+ [Dave Davies: Changed the code to allow command line mem/name
+ assignments]
+ 6) run the net startup bits for your eth?? interface manually
+ (usually /etc/rc.inet[12] at boot time).
+ 7) enjoy!
+
+ Note that autoprobing is not allowed in loadable modules - the system is
+ already up and running and you're messing with interrupts.
+
+ To unload a module, turn off the associated interface
+ 'ifconfig eth?? down' then 'rmmod depca'.
+
+ To assign a base memory address for the shared memory when running as a
+ loadable module, see 5 above. To include the adapter name (if you have
+ no PROM but know the card name) also see 5 above. Note that this last
+ option will not work with kernel built-in depca's.
+
+ The shared memory assignment for a loadable module makes sense to avoid
+ the 'memory autoprobe' picking the wrong shared memory (for the case of
+ 2 depca's in a PC).
+
+ ************************************************************************
+ Support for MCA EtherWORKS cards added 11-3-98.
+ Verified to work with up to 2 DE212 cards in a system (although not
+ fully stress-tested).
+
+ Currently known bugs/limitations:
+
+ Note: with the MCA stuff as a module, it trusts the MCA configuration,
+ not the command line for IRQ and memory address. You can
+ specify them if you want, but it will throw your values out.
+ You still have to pass the IO address it was configured as
+ though.
+
+ ************************************************************************
+ TO DO:
+ ------
+
+
+ Revision History
+ ----------------
+
+ Version Date Description
+
+ 0.1 25-jan-94 Initial writing.
+ 0.2 27-jan-94 Added LANCE TX hardware buffer chaining.
+ 0.3 1-feb-94 Added multiple DEPCA support.
+ 0.31 4-feb-94 Added DE202 recognition.
+ 0.32 19-feb-94 Tidy up. Improve multi-DEPCA support.
+ 0.33 25-feb-94 Fix DEPCA ethernet ROM counter enable.
+ Add jabber packet fix from murf@perftech.com
+ and becker@super.org
+ 0.34 7-mar-94 Fix DEPCA max network memory RAM & NICSR access.
+ 0.35 8-mar-94 Added DE201 recognition. Tidied up.
+ 0.351 30-apr-94 Added EISA support. Added DE422 recognition.
+ 0.36 16-may-94 DE422 fix released.
+ 0.37 22-jul-94 Added MODULE support
+ 0.38 15-aug-94 Added DBR ROM switch in depca_close().
+ Multi DEPCA bug fix.
+ 0.38axp 15-sep-94 Special version for Alpha AXP Linux V1.0.
+ 0.381 12-dec-94 Added DE101 recognition, fix multicast bug.
+ 0.382 9-feb-95 Fix recognition bug reported by <bkm@star.rl.ac.uk>.
+ 0.383 22-feb-95 Fix for conflict with VESA SCSI reported by
+ <stromain@alf.dec.com>
+ 0.384 17-mar-95 Fix a ring full bug reported by <bkm@star.rl.ac.uk>
+ 0.385 3-apr-95 Fix a recognition bug reported by
+ <ryan.niemi@lastfrontier.com>
+ 0.386 21-apr-95 Fix the last fix...sorry, must be galloping senility
+ 0.40 25-May-95 Rewrite for portability & updated.
+ ALPHA support from <jestabro@amt.tay1.dec.com>
+ 0.41 26-Jun-95 Added verify_area() calls in depca_ioctl() from
+ suggestion by <heiko@colossus.escape.de>
+ 0.42 27-Dec-95 Add 'mem' shared memory assignment for loadable
+ modules.
+ Add 'adapter_name' for loadable modules when no PROM.
+ Both above from a suggestion by
+ <pchen@woodruffs121.residence.gatech.edu>.
+ Add new multicasting code.
+ 0.421 22-Apr-96 Fix alloc_device() bug <jari@markkus2.fimr.fi>
+ 0.422 29-Apr-96 Fix depca_hw_init() bug <jari@markkus2.fimr.fi>
+ 0.423 7-Jun-96 Fix module load bug <kmg@barco.be>
+ 0.43 16-Aug-96 Update alloc_device() to conform to de4x5.c
+ 0.44 1-Sep-97 Fix *_probe() to test check_region() first - bug
+ reported by <mmogilvi@elbert.uccs.edu>
+ 0.45 3-Nov-98 Added support for MCA EtherWORKS (DE210/DE212) cards
+ by <tymm@computer.org>
+ 0.451 5-Nov-98 Fixed mca stuff cuz I'm a dummy. <tymm@computer.org>
+ 0.5 14-Nov-98 Re-spin for 2.1.x kernels.
+
+ =========================================================================
+*/
+
+static const char *version = "depca.c:v0.5 1998/11/14 davies@maniac.ultranet.com\n";
+
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
@@ -234,6 +254,10 @@ static const char *version = "depca.c:v0.43 96/8/16 davies@maniac.ultranet.com\n
#include <linux/unistd.h>
#include <linux/ctype.h>
+#ifdef CONFIG_MCA
+#include <linux/mca.h>
+#endif
+
#include "depca.h"
#ifdef DEPCA_DEBUG
@@ -242,1650 +266,1800 @@ static int depca_debug = DEPCA_DEBUG;
static int depca_debug = 1;
#endif
-#define DEPCA_NDA 0xffe0 /* No Device Address */
+#define DEPCA_NDA 0xffe0 /* No Device Address */
/*
- ** Ethernet PROM defines
- */
+** Ethernet PROM defines
+*/
#define PROBE_LENGTH 32
#define ETH_PROM_SIG 0xAA5500FFUL
/*
- ** Set the number of Tx and Rx buffers. Ensure that the memory requested
- ** here is <= to the amount of shared memory set up by the board switches.
- ** The number of descriptors MUST BE A POWER OF 2.
- **
- ** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
- */
-#define NUM_RX_DESC 8 /* Number of RX descriptors */
-#define NUM_TX_DESC 8 /* Number of TX descriptors */
-#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
-#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
-
-#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
-#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
+** Set the number of Tx and Rx buffers. Ensure that the memory requested
+** here is <= to the amount of shared memory set up by the board switches.
+** The number of descriptors MUST BE A POWER OF 2.
+**
+** total_memory = NUM_RX_DESC*(8+RX_BUFF_SZ) + NUM_TX_DESC*(8+TX_BUFF_SZ)
+*/
+#define NUM_RX_DESC 8 /* Number of RX descriptors */
+#define NUM_TX_DESC 8 /* Number of TX descriptors */
+#define RX_BUFF_SZ 1536 /* Buffer size for each Rx buffer */
+#define TX_BUFF_SZ 1536 /* Buffer size for each Tx buffer */
+
+#define CRC_POLYNOMIAL_BE 0x04c11db7UL /* Ethernet CRC, big endian */
+#define CRC_POLYNOMIAL_LE 0xedb88320UL /* Ethernet CRC, little endian */
/*
- ** EISA bus defines
- */
-#define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
+** EISA bus defines
+*/
+#define DEPCA_EISA_IO_PORTS 0x0c00 /* I/O port base address, slot 0 */
#define MAX_EISA_SLOTS 16
#define EISA_SLOT_INC 0x1000
/*
- ** ISA Bus defines
- */
+** ISA Bus defines
+*/
#define DEPCA_RAM_BASE_ADDRESSES {0xc0000,0xd0000,0xe0000,0x00000}
#define DEPCA_IO_PORTS {0x300, 0x200, 0}
#define DEPCA_TOTAL_SIZE 0x10
static short mem_chkd = 0;
/*
- ** Name <-> Adapter mapping
- */
+** Adapter ID for the MCA EtherWORKS DE210/212 adapter
+*/
+#define DE212_ID 0x6def
+
+/*
+** Name <-> Adapter mapping
+*/
#define DEPCA_SIGNATURE {"DEPCA",\
"DE100","DE101",\
"DE200","DE201","DE202",\
- "DE210",\
+ "DE210","DE212",\
"DE422",\
""}
static enum {
- DEPCA, de100, de101, de200, de201, de202, de210, de422, unknown
+ DEPCA, de100, de101, de200, de201, de202, de210, de212, de422, unknown
} adapter;
/*
- ** Miscellaneous info...
- */
+** Miscellaneous info...
+*/
#define DEPCA_STRLEN 16
#define MAX_NUM_DEPCAS 2
/*
- ** Memory Alignment. Each descriptor is 4 longwords long. To force a
- ** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
- ** DESC_ALIGN. ALIGN aligns the start address of the private memory area
- ** and hence the RX descriptor ring's first entry.
- */
-#define ALIGN4 ((u_long)4 - 1) /* 1 longword align */
-#define ALIGN8 ((u_long)8 - 1) /* 2 longword (quadword) align */
-#define ALIGN ALIGN8 /* Keep the LANCE happy... */
+** Memory Alignment. Each descriptor is 4 longwords long. To force a
+** particular alignment on the TX descriptor, adjust DESC_SKIP_LEN and
+** DESC_ALIGN. ALIGN aligns the start address of the private memory area
+** and hence the RX descriptor ring's first entry.
+*/
+#define ALIGN4 ((u_long)4 - 1) /* 1 longword align */
+#define ALIGN8 ((u_long)8 - 1) /* 2 longword (quadword) align */
+#define ALIGN ALIGN8 /* Keep the LANCE happy... */
/*
- ** The DEPCA Rx and Tx ring descriptors.
- */
+** The DEPCA Rx and Tx ring descriptors.
+*/
struct depca_rx_desc {
- volatile s32 base;
- s16 buf_length; /* This length is negative 2's complement! */
- s16 msg_length; /* This length is "normal". */
+ volatile s32 base;
+ s16 buf_length; /* This length is negative 2's complement! */
+ s16 msg_length; /* This length is "normal". */
};
struct depca_tx_desc {
- volatile s32 base;
- s16 length; /* This length is negative 2's complement! */
- s16 misc; /* Errors and TDR info */
+ volatile s32 base;
+ s16 length; /* This length is negative 2's complement! */
+ s16 misc; /* Errors and TDR info */
};
-#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
+#define LA_MASK 0x0000ffff /* LANCE address mask for mapping network RAM
to LANCE memory address space */
/*
- ** The Lance initialization block, described in databook, in common memory.
- */
+** The Lance initialization block, described in databook, in common memory.
+*/
struct depca_init {
- u16 mode; /* Mode register */
- u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
- u8 mcast_table[8]; /* Multicast Hash Table. */
- u32 rx_ring; /* Rx ring base pointer & ring length */
- u32 tx_ring; /* Tx ring base pointer & ring length */
+ u16 mode; /* Mode register */
+ u8 phys_addr[ETH_ALEN]; /* Physical ethernet address */
+ u8 mcast_table[8]; /* Multicast Hash Table. */
+ u32 rx_ring; /* Rx ring base pointer & ring length */
+ u32 tx_ring; /* Tx ring base pointer & ring length */
};
#define DEPCA_PKT_STAT_SZ 16
-#define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
- increase DEPCA_PKT_STAT_SZ */
+#define DEPCA_PKT_BIN_SZ 128 /* Should be >=100 unless you
+ increase DEPCA_PKT_STAT_SZ */
struct depca_private {
- char devname[DEPCA_STRLEN]; /* Device Product String */
- char adapter_name[DEPCA_STRLEN]; /* /proc/ioports string */
- char adapter; /* Adapter type */
- struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */
- struct depca_tx_desc *tx_ring; /* Pointer to start of TX descriptor ring */
- struct depca_init init_block; /* Shadow Initialization block */
- char *rx_memcpy[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */
- char *tx_memcpy[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */
- u_long bus_offset; /* (E)ISA bus address offset vs LANCE */
- u_long sh_mem; /* Physical start addr of shared mem area */
- u_long dma_buffs; /* LANCE Rx and Tx buffers start address. */
- int rx_new, tx_new; /* The next free ring entry */
- int rx_old, tx_old; /* The ring entries to be free()ed. */
- struct net_device_stats stats;
- struct { /* Private stats counters */
- u32 bins[DEPCA_PKT_STAT_SZ];
- u32 unicast;
- u32 multicast;
- u32 broadcast;
- u32 excessive_collisions;
- u32 tx_underruns;
- u32 excessive_underruns;
- } pktStats;
- int txRingMask; /* TX ring mask */
- int rxRingMask; /* RX ring mask */
- s32 rx_rlen; /* log2(rxRingMask+1) for the descriptors */
- s32 tx_rlen; /* log2(txRingMask+1) for the descriptors */
+ char devname[DEPCA_STRLEN]; /* Device Product String */
+ char adapter_name[DEPCA_STRLEN];/* /proc/ioports string */
+ char adapter; /* Adapter type */
+ char mca_slot; /* MCA slot, if MCA else -1 */ struct depca_rx_desc *rx_ring; /* Pointer to start of RX descriptor ring */
+ struct depca_tx_desc *tx_ring; /* Pointer to start of TX descriptor ring */
+ struct depca_init init_block;/* Shadow Initialization block */
+ char *rx_memcpy[NUM_RX_DESC]; /* CPU virt address of sh'd memory buffs */
+ char *tx_memcpy[NUM_TX_DESC]; /* CPU virt address of sh'd memory buffs */
+ u_long bus_offset; /* (E)ISA bus address offset vs LANCE */
+ u_long sh_mem; /* Physical start addr of shared mem area */
+ u_long dma_buffs; /* LANCE Rx and Tx buffers start address. */
+ int rx_new, tx_new; /* The next free ring entry */
+ int rx_old, tx_old; /* The ring entries to be free()ed. */
+ struct net_device_stats stats;
+ struct { /* Private stats counters */
+ u32 bins[DEPCA_PKT_STAT_SZ];
+ u32 unicast;
+ u32 multicast;
+ u32 broadcast;
+ u32 excessive_collisions;
+ u32 tx_underruns;
+ u32 excessive_underruns;
+ } pktStats;
+ int txRingMask; /* TX ring mask */
+ int rxRingMask; /* RX ring mask */
+ s32 rx_rlen; /* log2(rxRingMask+1) for the descriptors */
+ s32 tx_rlen; /* log2(txRingMask+1) for the descriptors */
};
/*
- ** The transmit ring full condition is described by the tx_old and tx_new
- ** pointers by:
- ** tx_old = tx_new Empty ring
- ** tx_old = tx_new+1 Full ring
- ** tx_old+txRingMask = tx_new Full ring (wrapped condition)
- */
+** The transmit ring full condition is described by the tx_old and tx_new
+** pointers by:
+** tx_old = tx_new Empty ring
+** tx_old = tx_new+1 Full ring
+** tx_old+txRingMask = tx_new Full ring (wrapped condition)
+*/
#define TX_BUFFS_AVAIL ((lp->tx_old<=lp->tx_new)?\
lp->tx_old+lp->txRingMask-lp->tx_new:\
lp->tx_old -lp->tx_new-1)
/*
- ** Public Functions
- */
-static int depca_open(struct device *dev);
-static int depca_start_xmit(struct sk_buff *skb, struct device *dev);
-static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static int depca_close(struct device *dev);
-static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd);
+** Public Functions
+*/
+static int depca_open(struct device *dev);
+static int depca_start_xmit(struct sk_buff *skb, struct device *dev);
+static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static int depca_close(struct device *dev);
+static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd);
static struct net_device_stats *depca_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev);
+static void set_multicast_list(struct device *dev);
/*
- ** Private functions
- */
-static int depca_hw_init(struct device *dev, u_long ioaddr);
-static void depca_init_ring(struct device *dev);
-static int depca_rx(struct device *dev);
-static int depca_tx(struct device *dev);
-
-static void LoadCSRs(struct device *dev);
-static int InitRestartDepca(struct device *dev);
-static void DepcaSignature(char *name, u_long paddr);
-static int DevicePresent(u_long ioaddr);
-static int get_hw_addr(struct device *dev);
-static int EISA_signature(char *name, s32 eisa_id);
-static void SetMulticastFilter(struct device *dev);
-static void isa_probe(struct device *dev, u_long iobase);
-static void eisa_probe(struct device *dev, u_long iobase);
+** Private functions
+*/
+static int depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot);
+static void depca_init_ring(struct device *dev);
+static int depca_rx(struct device *dev);
+static int depca_tx(struct device *dev);
+
+static void LoadCSRs(struct device *dev);
+static int InitRestartDepca(struct device *dev);
+static void DepcaSignature(char *name, u_long paddr);
+static int DevicePresent(u_long ioaddr);
+static int get_hw_addr(struct device *dev);
+static int EISA_signature(char *name, s32 eisa_id);
+static void SetMulticastFilter(struct device *dev);
+static void isa_probe(struct device *dev, u_long iobase);
+static void eisa_probe(struct device *dev, u_long iobase);
+#ifdef CONFIG_MCA
+static void mca_probe(struct device *dev, u_long iobase);
+#endif
static struct device *alloc_device(struct device *dev, u_long iobase);
-static int depca_dev_index(char *s);
-static struct device *insert_device(struct device *dev, u_long iobase, int (*init) (struct device *));
-static int load_packet(struct device *dev, struct sk_buff *skb);
-static void depca_dbg_open(struct device *dev);
+static int depca_dev_index(char *s);
+static struct device *insert_device(struct device *dev, u_long iobase, int (*init)(struct device *));
+static int load_packet(struct device *dev, struct sk_buff *skb);
+static void depca_dbg_open(struct device *dev);
#ifdef MODULE
-int init_module(void);
-void cleanup_module(void);
-static int autoprobed = 1, loading_module = 1;
-#else
-static u_char de1xx_irq[] __initdata =
-{2, 3, 4, 5, 7, 9, 0};
-static u_char de2xx_irq[] __initdata =
-{5, 9, 10, 11, 15, 0};
-static u_char de422_irq[] __initdata =
-{5, 9, 10, 11, 0};
+int init_module(void);
+void cleanup_module(void);
+static int autoprobed = 1, loading_module = 1;
+# else
+static u_char de1xx_irq[] __initdata = {2,3,4,5,7,9,0};
+static u_char de2xx_irq[] __initdata = {5,9,10,11,15,0};
+static u_char de422_irq[] __initdata = {5,9,10,11,0};
static u_char *depca_irq;
-static int autoprobed = 0, loading_module = 0;
-#endif /* MODULE */
-
-static char name[DEPCA_STRLEN];
-static int num_depcas = 0, num_eth = 0;
-static int mem = 0; /* For loadable module assignment
- use insmod mem=0x????? .... */
-static char *adapter_name = '\0'; /* If no PROM when loadable module
- use insmod adapter_name=DE??? ...
- */
+static int autoprobed = 0, loading_module = 0;
+#endif /* MODULE */
+
+static char name[DEPCA_STRLEN];
+static int num_depcas = 0, num_eth = 0;
+static int mem=0; /* For loadable module assignment
+ use insmod mem=0x????? .... */
+static char *adapter_name = '\0'; /* If no PROM when loadable module
+ use insmod adapter_name=DE??? ...
+ */
/*
- ** Miscellaneous defines...
- */
+** Miscellaneous defines...
+*/
#define STOP_DEPCA \
outw(CSR0, DEPCA_ADDR);\
outw(STOP, DEPCA_DATA)
-
+
-__initfunc(int depca_probe(struct device *dev))
+__initfunc(int
+depca_probe(struct device *dev))
{
- int tmp = num_depcas, status = -ENODEV;
- u_long iobase = dev->base_addr;
+ int tmp = num_depcas, status = -ENODEV;
+ u_long iobase = dev->base_addr;
+
+ if ((iobase == 0) && loading_module){
+ printk("Autoprobing is not supported when loading a module based driver.\n");
+ status = -EIO;
+ } else {
+#ifdef CONFIG_MCA
+ mca_probe(dev, iobase);
+#endif
+ isa_probe(dev, iobase);
+ eisa_probe(dev, iobase);
- if ((iobase == 0) && loading_module) {
- printk("Autoprobing is not supported when loading a module based driver.\n");
- status = -EIO;
- } else {
- isa_probe(dev, iobase);
- eisa_probe(dev, iobase);
+ if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
+ printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name,
+ iobase);
+ }
- if ((tmp == num_depcas) && (iobase != 0) && loading_module) {
- printk("%s: depca_probe() cannot find device at 0x%04lx.\n", dev->name,
- iobase);
- }
- /*
- ** Walk the device list to check that at least one device
- ** initialised OK
- */
- for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
-
- if (dev->priv)
- status = 0;
- if (iobase == 0)
- autoprobed = 1;
- }
+ /*
+ ** Walk the device list to check that at least one device
+ ** initialised OK
+ */
+ for (; (dev->priv == NULL) && (dev->next != NULL); dev = dev->next);
- return status;
+ if (dev->priv) status = 0;
+ if (iobase == 0) autoprobed = 1;
+ }
+
+ return status;
}
__initfunc(static int
- depca_hw_init(struct device *dev, u_long ioaddr))
+depca_hw_init(struct device *dev, u_long ioaddr, int mca_slot))
{
- struct depca_private *lp;
- int i, j, offset, netRAM, mem_len, status = 0;
- s16 nicsr;
- u_long mem_start = 0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
-
- STOP_DEPCA;
-
- nicsr = inb(DEPCA_NICSR);
- nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
- outb(nicsr, DEPCA_NICSR);
-
- if (inw(DEPCA_DATA) == STOP) {
- do {
- strcpy(name, (adapter_name ? adapter_name : ""));
- mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);
- DepcaSignature(name, mem_start);
- } while (!mem && mem_base[mem_chkd] && (adapter == unknown));
-
- if ((adapter != unknown) && mem_start) { /* found a DEPCA device */
- dev->base_addr = ioaddr;
-
- if ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS) { /* EISA slot address */
- printk("%s: %s at 0x%04lx (EISA slot %d)",
- dev->name, name, ioaddr, (int) ((ioaddr >> 12) & 0x0f));
- } else { /* ISA port address */
- printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
- }
-
- printk(", h/w address ");
- status = get_hw_addr(dev);
- for (i = 0; i < ETH_ALEN - 1; i++) { /* get the ethernet address */
- printk("%2.2x:", dev->dev_addr[i]);
- }
- printk("%2.2x", dev->dev_addr[i]);
-
- if (status == 0) {
- /* Set up the maximum amount of network RAM(kB) */
- netRAM = ((adapter != DEPCA) ? 64 : 48);
- if ((nicsr & _128KB) && (adapter == de422))
- netRAM = 128;
- offset = 0x0000;
-
- /* Shared Memory Base Address */
- if (nicsr & BUF) {
- offset = 0x8000; /* 32kbyte RAM offset */
- nicsr &= ~BS; /* DEPCA RAM in top 32k */
- netRAM -= 32;
- }
- mem_start += offset; /* (E)ISA start address */
- if ((mem_len = (NUM_RX_DESC * (sizeof(struct depca_rx_desc) + RX_BUFF_SZ) +
- NUM_TX_DESC * (sizeof(struct depca_tx_desc) + TX_BUFF_SZ) +
- sizeof(struct depca_init))) <=
- (netRAM << 10)) {
- printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start);
-
- /* Enable the shadow RAM. */
- if (adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
- /* Define the device private memory */
- dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
- if (dev->priv == NULL)
- return -ENOMEM;
- lp = (struct depca_private *) dev->priv;
- memset((char *) dev->priv, 0, sizeof(struct depca_private));
- lp->adapter = adapter;
- sprintf(lp->adapter_name, "%s (%s)", name, dev->name);
- request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name);
-
- /* Initialisation Block */
- lp->sh_mem = mem_start;
- mem_start += sizeof(struct depca_init);
-
- /* Tx & Rx descriptors (aligned to a quadword boundary) */
- mem_start = (mem_start + ALIGN) & ~ALIGN;
- lp->rx_ring = (struct depca_rx_desc *) mem_start;
-
- mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
- lp->tx_ring = (struct depca_tx_desc *) mem_start;
-
- mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
- lp->bus_offset = mem_start & 0x00ff0000;
- mem_start &= LA_MASK; /* LANCE re-mapped start address */
-
- lp->dma_buffs = mem_start;
-
- /* Finish initialising the ring information. */
- lp->rxRingMask = NUM_RX_DESC - 1;
- lp->txRingMask = NUM_TX_DESC - 1;
-
- /* Calculate Tx/Rx RLEN size for the descriptors. */
- for (i = 0, j = lp->rxRingMask; j > 0; i++) {
- j >>= 1;
- }
- lp->rx_rlen = (s32) (i << 29);
- for (i = 0, j = lp->txRingMask; j > 0; i++) {
- j >>= 1;
- }
- lp->tx_rlen = (s32) (i << 29);
-
- /* Load the initialisation block */
- depca_init_ring(dev);
-
- /* Initialise the control and status registers */
- LoadCSRs(dev);
-
- /* Enable DEPCA board interrupts for autoprobing */
- nicsr = ((nicsr & ~IM) | IEN);
- outb(nicsr, DEPCA_NICSR);
-
- /* To auto-IRQ we enable the initialization-done and DMA err,
- interrupts. For now we will always get a DMA error. */
- if (dev->irq < 2) {
+ struct depca_private *lp;
+ int i, j, offset, netRAM, mem_len, status=0;
+ s16 nicsr;
+ u_long mem_start=0, mem_base[] = DEPCA_RAM_BASE_ADDRESSES;
+
+ STOP_DEPCA;
+
+ nicsr = inb(DEPCA_NICSR);
+ nicsr = ((nicsr & ~SHE & ~RBE & ~IEN) | IM);
+ outb(nicsr, DEPCA_NICSR);
+
+ if (inw(DEPCA_DATA) == STOP) {
+ do {
+ strcpy(name, (adapter_name ? adapter_name : ""));
+ mem_start = (mem ? mem & 0xf0000 : mem_base[mem_chkd++]);
+ DepcaSignature(name, mem_start);
+ } while (!mem && mem_base[mem_chkd] && (adapter == unknown));
+
+ if ((adapter != unknown) && mem_start) { /* found a DEPCA device */
+ dev->base_addr = ioaddr;
+
+ if (mca_slot != -1) {
+ printk("%s: %s at 0x%04lx (MCA slot %d)", dev->name, name,
+ ioaddr, mca_slot);
+ } else if ((ioaddr & 0x0fff) == DEPCA_EISA_IO_PORTS) { /* EISA slot address */
+ printk("%s: %s at 0x%04lx (EISA slot %d)",
+ dev->name, name, ioaddr, (int)((ioaddr>>12)&0x0f));
+ } else { /* ISA port address */
+ printk("%s: %s at 0x%04lx", dev->name, name, ioaddr);
+ }
+
+ printk(", h/w address ");
+ status = get_hw_addr(dev);
+ for (i=0; i<ETH_ALEN - 1; i++) { /* get the ethernet address */
+ printk("%2.2x:", dev->dev_addr[i]);
+ }
+ printk("%2.2x", dev->dev_addr[i]);
+
+ if (status == 0) {
+ /* Set up the maximum amount of network RAM(kB) */
+ netRAM = ((adapter != DEPCA) ? 64 : 48);
+ if ((nicsr & _128KB) && (adapter == de422)) netRAM = 128;
+ offset = 0x0000;
+
+ /* Shared Memory Base Address */
+ if (nicsr & BUF) {
+ offset = 0x8000; /* 32kbyte RAM offset*/
+ nicsr &= ~BS; /* DEPCA RAM in top 32k */
+ netRAM -= 32;
+ }
+ mem_start += offset; /* (E)ISA start address */
+ if ((mem_len = (NUM_RX_DESC*(sizeof(struct depca_rx_desc)+RX_BUFF_SZ) +
+ NUM_TX_DESC*(sizeof(struct depca_tx_desc)+TX_BUFF_SZ) +
+ sizeof(struct depca_init))) <=
+ (netRAM<<10)) {
+ printk(",\n has %dkB RAM at 0x%.5lx", netRAM, mem_start);
+
+ /* Enable the shadow RAM. */
+ if (adapter != DEPCA) {
+ nicsr |= SHE;
+ outb(nicsr, DEPCA_NICSR);
+ }
+
+ /* Define the device private memory */
+ dev->priv = (void *) kmalloc(sizeof(struct depca_private), GFP_KERNEL);
+ if (dev->priv == NULL)
+ return -ENOMEM;
+ lp = (struct depca_private *)dev->priv;
+ memset((char *)dev->priv, 0, sizeof(struct depca_private));
+ lp->adapter = adapter;
+ lp->mca_slot = mca_slot;
+ sprintf(lp->adapter_name,"%s (%s)", name, dev->name);
+ request_region(ioaddr, DEPCA_TOTAL_SIZE, lp->adapter_name);
+
+ /* Initialisation Block */
+ lp->sh_mem = mem_start;
+ mem_start += sizeof(struct depca_init);
+
+ /* Tx & Rx descriptors (aligned to a quadword boundary) */
+ mem_start = (mem_start + ALIGN) & ~ALIGN;
+ lp->rx_ring = (struct depca_rx_desc *)mem_start;
+
+ mem_start += (sizeof(struct depca_rx_desc) * NUM_RX_DESC);
+ lp->tx_ring = (struct depca_tx_desc *)mem_start;
+
+ mem_start += (sizeof(struct depca_tx_desc) * NUM_TX_DESC);
+ lp->bus_offset = mem_start & 0x00ff0000;
+ mem_start &= LA_MASK; /* LANCE re-mapped start address */
+
+ lp->dma_buffs = mem_start;
+
+ /* Finish initialising the ring information. */
+ lp->rxRingMask = NUM_RX_DESC - 1;
+ lp->txRingMask = NUM_TX_DESC - 1;
+
+ /* Calculate Tx/Rx RLEN size for the descriptors. */
+ for (i=0, j = lp->rxRingMask; j>0; i++) {
+ j >>= 1;
+ }
+ lp->rx_rlen = (s32)(i << 29);
+ for (i=0, j = lp->txRingMask; j>0; i++) {
+ j >>= 1;
+ }
+ lp->tx_rlen = (s32)(i << 29);
+
+ /* Load the initialisation block */
+ depca_init_ring(dev);
+
+ /* Initialise the control and status registers */
+ LoadCSRs(dev);
+
+ /* Enable DEPCA board interrupts for autoprobing */
+ nicsr = ((nicsr & ~IM)|IEN);
+ outb(nicsr, DEPCA_NICSR);
+
+ /* To auto-IRQ we enable the initialization-done and DMA err,
+ interrupts. For now we will always get a DMA error. */
+ if (dev->irq < 2) {
#ifndef MODULE
- unsigned char irqnum;
- autoirq_setup(0);
-
- /* Assign the correct irq list */
- switch (lp->adapter) {
- case DEPCA:
- case de100:
- case de101:
- depca_irq = de1xx_irq;
- break;
- case de200:
- case de201:
- case de202:
- case de210:
- depca_irq = de2xx_irq;
- break;
- case de422:
- depca_irq = de422_irq;
- break;
- }
-
- /* Trigger an initialization just for the interrupt. */
- outw(INEA | INIT, DEPCA_DATA);
-
- irqnum = autoirq_report(1);
- if (!irqnum) {
- printk(" and failed to detect IRQ line.\n");
- status = -ENXIO;
- } else {
- for (dev->irq = 0, i = 0; (depca_irq[i]) && (!dev->irq); i++) {
- if (irqnum == depca_irq[i]) {
- dev->irq = irqnum;
- printk(" and uses IRQ%d.\n", dev->irq);
- }
- }
-
- if (!dev->irq) {
- printk(" but incorrect IRQ line detected.\n");
- status = -ENXIO;
- }
- }
-#endif /* MODULE */
- } else {
- printk(" and assigned IRQ%d.\n", dev->irq);
- }
- if (status)
- release_region(ioaddr, DEPCA_TOTAL_SIZE);
- } else {
- printk(",\n requests %dkB RAM: only %dkB is available!\n",
- (mem_len >> 10), netRAM);
- status = -ENXIO;
- }
- } else {
- printk(" which has an Ethernet PROM CRC error.\n");
- status = -ENXIO;
- }
- } else {
- status = -ENXIO;
+ unsigned char irqnum;
+ autoirq_setup(0);
+
+ /* Assign the correct irq list */
+ switch (lp->adapter) {
+ case DEPCA:
+ case de100:
+ case de101:
+ depca_irq = de1xx_irq;
+ break;
+ case de200:
+ case de201:
+ case de202:
+ case de210:
+ case de212:
+ depca_irq = de2xx_irq;
+ break;
+ case de422:
+ depca_irq = de422_irq;
+ break;
+ }
+
+ /* Trigger an initialization just for the interrupt. */
+ outw(INEA | INIT, DEPCA_DATA);
+
+ irqnum = autoirq_report(1);
+ if (!irqnum) {
+ printk(" and failed to detect IRQ line.\n");
+ status = -ENXIO;
+ } else {
+ for (dev->irq=0,i=0; (depca_irq[i]) && (!dev->irq); i++) {
+ if (irqnum == depca_irq[i]) {
+ dev->irq = irqnum;
+ printk(" and uses IRQ%d.\n", dev->irq);
}
- if (!status) {
- if (depca_debug > 1) {
- printk(version);
- }
- /* The DEPCA-specific entries in the device structure. */
- dev->open = &depca_open;
- dev->hard_start_xmit = &depca_start_xmit;
- dev->stop = &depca_close;
- dev->get_stats = &depca_get_stats;
- dev->set_multicast_list = &set_multicast_list;
- dev->do_ioctl = &depca_ioctl;
-
- dev->mem_start = 0;
-
- /* Fill in the generic field of the device structure. */
- ether_setup(dev);
- } else { /* Incorrectly initialised hardware */
- if (dev->priv) {
- kfree_s(dev->priv, sizeof(struct depca_private));
- dev->priv = NULL;
- }
- }
- } else {
+ }
+
+ if (!dev->irq) {
+ printk(" but incorrect IRQ line detected.\n");
status = -ENXIO;
+ }
+ }
+#endif /* MODULE */
+ } else {
+ printk(" and assigned IRQ%d.\n", dev->irq);
+ }
+ if (status) release_region(ioaddr, DEPCA_TOTAL_SIZE);
+ } else {
+ printk(",\n requests %dkB RAM: only %dkB is available!\n",
+ (mem_len>>10), netRAM);
+ status = -ENXIO;
}
-
- return status;
+ } else {
+ printk(" which has an Ethernet PROM CRC error.\n");
+ status = -ENXIO;
+ }
+ } else {
+ status = -ENXIO;
+ }
+ if (!status) {
+ if (depca_debug > 1) {
+ printk(version);
+ }
+
+ /* The DEPCA-specific entries in the device structure. */
+ dev->open = &depca_open;
+ dev->hard_start_xmit = &depca_start_xmit;
+ dev->stop = &depca_close;
+ dev->get_stats = &depca_get_stats;
+ dev->set_multicast_list = &set_multicast_list;
+ dev->do_ioctl = &depca_ioctl;
+
+ dev->mem_start = 0;
+
+ /* Fill in the generic field of the device structure. */
+ ether_setup(dev);
+ } else { /* Incorrectly initialised hardware */
+ if (dev->priv) {
+ kfree_s(dev->priv, sizeof(struct depca_private));
+ dev->priv = NULL;
+ }
+ }
+ } else {
+ status = -ENXIO;
+ }
+
+ return status;
}
-
-static int depca_open(struct device *dev)
+
+static int
+depca_open(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- s16 nicsr;
- int status = 0;
-
- STOP_DEPCA;
- nicsr = inb(DEPCA_NICSR);
-
- /* Make sure the shadow RAM is enabled */
- if (adapter != DEPCA) {
- nicsr |= SHE;
- outb(nicsr, DEPCA_NICSR);
- }
- /* Re-initialize the DEPCA... */
- depca_init_ring(dev);
- LoadCSRs(dev);
-
- depca_dbg_open(dev);
-
- if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, dev)) {
- printk("depca_open(): Requested IRQ%d is busy\n", dev->irq);
- status = -EAGAIN;
- } else {
-
- /* Enable DEPCA board interrupts and turn off LED */
- nicsr = ((nicsr & ~IM & ~LED) | IEN);
- outb(nicsr, DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR);
-
- dev->tbusy = 0;
- dev->interrupt = 0;
- dev->start = 1;
-
- status = InitRestartDepca(dev);
-
- if (depca_debug > 1) {
- printk("CSR0: 0x%4.4x\n", inw(DEPCA_DATA));
- printk("nicsr: 0x%02x\n", inb(DEPCA_NICSR));
- }
- }
-
- MOD_INC_USE_COUNT;
-
- return status;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_long ioaddr = dev->base_addr;
+ s16 nicsr;
+ int status = 0;
+
+ STOP_DEPCA;
+ nicsr = inb(DEPCA_NICSR);
+
+ /* Make sure the shadow RAM is enabled */
+ if (adapter != DEPCA) {
+ nicsr |= SHE;
+ outb(nicsr, DEPCA_NICSR);
+ }
+
+ /* Re-initialize the DEPCA... */
+ depca_init_ring(dev);
+ LoadCSRs(dev);
+
+ depca_dbg_open(dev);
+
+ if (request_irq(dev->irq, &depca_interrupt, 0, lp->adapter_name, dev)) {
+ printk("depca_open(): Requested IRQ%d is busy\n",dev->irq);
+ status = -EAGAIN;
+ } else {
+
+ /* Enable DEPCA board interrupts and turn off LED */
+ nicsr = ((nicsr & ~IM & ~LED)|IEN);
+ outb(nicsr, DEPCA_NICSR);
+ outw(CSR0,DEPCA_ADDR);
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ status = InitRestartDepca(dev);
+
+ if (depca_debug > 1){
+ printk("CSR0: 0x%4.4x\n",inw(DEPCA_DATA));
+ printk("nicsr: 0x%02x\n",inb(DEPCA_NICSR));
+ }
+ }
+
+ MOD_INC_USE_COUNT;
+
+ return status;
}
/* Initialize the lance Rx and Tx descriptor rings. */
-static void depca_init_ring(struct device *dev)
+static void
+depca_init_ring(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_int i;
- u_long p;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_int i;
+ u_long p;
- /* Lock out other processes whilst setting up the hardware */
- set_bit(0, (void *) &dev->tbusy);
+ /* Lock out other processes whilst setting up the hardware */
+ test_and_set_bit(0, (void *)&dev->tbusy);
- lp->rx_new = lp->tx_new = 0;
- lp->rx_old = lp->tx_old = 0;
+ lp->rx_new = lp->tx_new = 0;
+ lp->rx_old = lp->tx_old = 0;
- /* Initialize the base addresses and length of each buffer in the ring */
- for (i = 0; i <= lp->rxRingMask; i++) {
- writel((p = lp->dma_buffs + i * RX_BUFF_SZ) | R_OWN, &lp->rx_ring[i].base);
- writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length);
- lp->rx_memcpy[i] = (char *) (p + lp->bus_offset);
- }
- for (i = 0; i <= lp->txRingMask; i++) {
- writel((p = lp->dma_buffs + (i + lp->txRingMask + 1) * TX_BUFF_SZ) & 0x00ffffff,
- &lp->tx_ring[i].base);
- lp->tx_memcpy[i] = (char *) (p + lp->bus_offset);
- }
+ /* Initialize the base addresses and length of each buffer in the ring */
+ for (i = 0; i <= lp->rxRingMask; i++) {
+ writel((p=lp->dma_buffs+i*RX_BUFF_SZ) | R_OWN, &lp->rx_ring[i].base);
+ writew(-RX_BUFF_SZ, &lp->rx_ring[i].buf_length);
+ lp->rx_memcpy[i]=(char *)(p+lp->bus_offset);
+ }
+ for (i = 0; i <= lp->txRingMask; i++) {
+ writel((p=lp->dma_buffs+(i+lp->txRingMask+1)*TX_BUFF_SZ) & 0x00ffffff,
+ &lp->tx_ring[i].base);
+ lp->tx_memcpy[i]=(char *)(p+lp->bus_offset);
+ }
- /* Set up the initialization block */
- lp->init_block.rx_ring = ((u32) ((u_long) lp->rx_ring) & LA_MASK) | lp->rx_rlen;
- lp->init_block.tx_ring = ((u32) ((u_long) lp->tx_ring) & LA_MASK) | lp->tx_rlen;
+ /* Set up the initialization block */
+ lp->init_block.rx_ring = ((u32)((u_long)lp->rx_ring)&LA_MASK) | lp->rx_rlen;
+ lp->init_block.tx_ring = ((u32)((u_long)lp->tx_ring)&LA_MASK) | lp->tx_rlen;
- SetMulticastFilter(dev);
+ SetMulticastFilter(dev);
- for (i = 0; i < ETH_ALEN; i++) {
- lp->init_block.phys_addr[i] = dev->dev_addr[i];
- }
+ for (i = 0; i < ETH_ALEN; i++) {
+ lp->init_block.phys_addr[i] = dev->dev_addr[i];
+ }
- lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */
+ lp->init_block.mode = 0x0000; /* Enable the Tx and Rx */
- return;
+ return;
}
-/*
- ** Writes a socket buffer to TX descriptor ring and starts transmission
- */
-static int depca_start_xmit(struct sk_buff *skb, struct device *dev)
+/*
+** Writes a socket buffer to TX descriptor ring and starts transmission
+*/
+static int
+depca_start_xmit(struct sk_buff *skb, struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- int status = 0;
-
- /* Transmitter timeout, serious problems. */
- if (dev->tbusy) {
- int tickssofar = jiffies - dev->trans_start;
- if (tickssofar < 1 * HZ) {
- status = -1;
- } else {
- printk("%s: transmit timed out, status %04x, resetting.\n",
- dev->name, inw(DEPCA_DATA));
-
- STOP_DEPCA;
- depca_init_ring(dev);
- LoadCSRs(dev);
- dev->interrupt = UNMASK_INTERRUPTS;
- dev->start = 1;
- dev->tbusy = 0;
- dev->trans_start = jiffies;
- InitRestartDepca(dev);
- }
- return status;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_long ioaddr = dev->base_addr;
+ int status = 0;
+
+ /* Transmitter timeout, serious problems. */
+ if (dev->tbusy) {
+ int tickssofar = jiffies - dev->trans_start;
+ if (tickssofar < 1*HZ) {
+ status = -1;
+ } else {
+ printk("%s: transmit timed out, status %04x, resetting.\n",
+ dev->name, inw(DEPCA_DATA));
+
+ STOP_DEPCA;
+ depca_init_ring(dev);
+ LoadCSRs(dev);
+ dev->interrupt = UNMASK_INTERRUPTS;
+ dev->start = 1;
+ dev->tbusy=0;
+ dev->trans_start = jiffies;
+ InitRestartDepca(dev);
+ }
+ return status;
+ } else if (skb->len > 0) {
+ /* Enforce 1 process per h/w access */
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+ printk("%s: Transmitter access conflict.\n", dev->name);
+ status = -1;
+ } else {
+ if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */
+ status = load_packet(dev, skb);
+
+ if (!status) {
+ /* Trigger an immediate send demand. */
+ outw(CSR0, DEPCA_ADDR);
+ outw(INEA | TDMD, DEPCA_DATA);
+
+ dev->trans_start = jiffies;
+ dev_kfree_skb(skb);
}
- else if (skb->len > 0)
- {
- /* Enforce 1 process per h/w access */
- if (test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
- printk("%s: Transmitter access conflict.\n", dev->name);
- status = -1;
- } else {
- if (TX_BUFFS_AVAIL) { /* Fill in a Tx ring entry */
- status = load_packet(dev, skb);
-
- if (!status) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
-
- dev->trans_start = jiffies;
- dev_kfree_skb(skb);
- }
- if (TX_BUFFS_AVAIL) {
- dev->tbusy = 0;
- }
- } else {
- status = -1;
- }
- }
- }
- return status;
+ if (TX_BUFFS_AVAIL) {
+ dev->tbusy=0;
+ }
+ } else {
+ status = -1;
+ }
+ }
+ }
+
+ return status;
}
/*
- ** The DEPCA interrupt handler.
- */
-static void depca_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+** The DEPCA interrupt handler.
+*/
+static void
+depca_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
- struct device *dev = dev_id;
- struct depca_private *lp;
- s16 csr0, nicsr;
- u_long ioaddr;
+ struct device *dev = dev_id;
+ struct depca_private *lp;
+ s16 csr0, nicsr;
+ u_long ioaddr;
- if (dev == NULL) {
- printk("depca_interrupt(): irq %d for unknown device.\n", irq);
- } else {
- lp = (struct depca_private *) dev->priv;
- ioaddr = dev->base_addr;
+ if (dev == NULL) {
+ printk ("depca_interrupt(): irq %d for unknown device.\n", irq);
+ } else {
+ lp = (struct depca_private *)dev->priv;
+ ioaddr = dev->base_addr;
+
+ if (dev->interrupt)
+ printk("%s: Re-entering the interrupt handler.\n", dev->name);
- if (dev->interrupt)
- printk("%s: Re-entering the interrupt handler.\n", dev->name);
+ dev->interrupt = MASK_INTERRUPTS;
- dev->interrupt = MASK_INTERRUPTS;
+ /* mask the DEPCA board interrupts and turn on the LED */
+ nicsr = inb(DEPCA_NICSR);
+ nicsr |= (IM|LED);
+ outb(nicsr, DEPCA_NICSR);
- /* mask the DEPCA board interrupts and turn on the LED */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= (IM | LED);
- outb(nicsr, DEPCA_NICSR);
+ outw(CSR0, DEPCA_ADDR);
+ csr0 = inw(DEPCA_DATA);
- outw(CSR0, DEPCA_ADDR);
- csr0 = inw(DEPCA_DATA);
+ /* Acknowledge all of the current interrupt sources ASAP. */
+ outw(csr0 & INTE, DEPCA_DATA);
- /* Acknowledge all of the current interrupt sources ASAP. */
- outw(csr0 & INTE, DEPCA_DATA);
+ if (csr0 & RINT) /* Rx interrupt (packet arrived) */
+ depca_rx(dev);
- if (csr0 & RINT) /* Rx interrupt (packet arrived) */
- depca_rx(dev);
+ if (csr0 & TINT) /* Tx interrupt (packet sent) */
+ depca_tx(dev);
- if (csr0 & TINT) /* Tx interrupt (packet sent) */
- depca_tx(dev);
+ if ((TX_BUFFS_AVAIL >= 0) && dev->tbusy) { /* any resources available? */
+ dev->tbusy = 0; /* clear TX busy flag */
+ mark_bh(NET_BH);
+ }
- if ((TX_BUFFS_AVAIL >= 0) && dev->tbusy) { /* any resources available? */
- dev->tbusy = 0; /* clear TX busy flag */
- mark_bh(NET_BH);
- }
- /* Unmask the DEPCA board interrupts and turn off the LED */
- nicsr = (nicsr & ~IM & ~LED);
- outb(nicsr, DEPCA_NICSR);
+ /* Unmask the DEPCA board interrupts and turn off the LED */
+ nicsr = (nicsr & ~IM & ~LED);
+ outb(nicsr, DEPCA_NICSR);
- dev->interrupt = UNMASK_INTERRUPTS;
- }
+ dev->interrupt = UNMASK_INTERRUPTS;
+ }
- return;
+ return;
}
-static int depca_rx(struct device *dev)
+static int
+depca_rx(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- int i, entry;
- s32 status;
-
- for (entry = lp->rx_new;
- !(readl(&lp->rx_ring[entry].base) & R_OWN);
- entry = lp->rx_new) {
- status = readl(&lp->rx_ring[entry].base) >> 16;
- if (status & R_STP) { /* Remember start of frame */
- lp->rx_old = entry;
- }
- if (status & R_ENP) { /* Valid frame status */
- if (status & R_ERR) { /* There was an error. */
- lp->stats.rx_errors++; /* Update the error stats. */
- if (status & R_FRAM)
- lp->stats.rx_frame_errors++;
- if (status & R_OFLO)
- lp->stats.rx_over_errors++;
- if (status & R_CRC)
- lp->stats.rx_crc_errors++;
- if (status & R_BUFF)
- lp->stats.rx_fifo_errors++;
- } else {
- short len, pkt_len = readw(&lp->rx_ring[entry].msg_length);
- struct sk_buff *skb;
-
- skb = dev_alloc_skb(pkt_len + 2);
- if (skb != NULL) {
- unsigned char *buf;
- skb_reserve(skb, 2); /* 16 byte align the IP header */
- buf = skb_put(skb, pkt_len);
- skb->dev = dev;
- if (entry < lp->rx_old) { /* Wrapped buffer */
- len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ;
- memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], len);
- memcpy_fromio(buf + len, lp->rx_memcpy[0], pkt_len - len);
- } else { /* Linear buffer */
- memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len);
- }
-
- /*
- ** Notify the upper protocol layers that there is another
- ** packet to handle
- */
- skb->protocol = eth_type_trans(skb, dev);
- netif_rx(skb);
-
- /*
- ** Update stats
- */
- lp->stats.rx_packets++;
- for (i = 1; i < DEPCA_PKT_STAT_SZ - 1; i++) {
- if (pkt_len < (i * DEPCA_PKT_BIN_SZ)) {
- lp->pktStats.bins[i]++;
- i = DEPCA_PKT_STAT_SZ;
- }
- }
- if (buf[0] & 0x01) { /* Multicast/Broadcast */
- if ((*(s16 *) & buf[0] == -1) &&
- (*(s16 *) & buf[2] == -1) &&
- (*(s16 *) & buf[4] == -1)) {
- lp->pktStats.broadcast++;
- } else {
- lp->pktStats.multicast++;
- }
- } else if ((*(s16 *) & buf[0] == *(s16 *) & dev->dev_addr[0]) &&
- (*(s16 *) & buf[2] == *(s16 *) & dev->dev_addr[2]) &&
- (*(s16 *) & buf[4] == *(s16 *) & dev->dev_addr[4])) {
- lp->pktStats.unicast++;
- }
- lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
- if (lp->pktStats.bins[0] == 0) { /* Reset counters */
- memset((char *) &lp->pktStats, 0, sizeof(lp->pktStats));
- }
- } else {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- lp->stats.rx_dropped++; /* Really, deferred. */
- break;
- }
- }
- /* Change buffer ownership for this last frame, back to the adapter */
- for (; lp->rx_old != entry; lp->rx_old = (++lp->rx_old) & lp->rxRingMask) {
- writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN,
- &lp->rx_ring[lp->rx_old].base);
- }
- writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
- }
- /*
- ** Update entry information
- */
- lp->rx_new = (++lp->rx_new) & lp->rxRingMask;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ int i, entry;
+ s32 status;
+
+ for (entry=lp->rx_new;
+ !(readl(&lp->rx_ring[entry].base) & R_OWN);
+ entry=lp->rx_new){
+ status = readl(&lp->rx_ring[entry].base) >> 16 ;
+ if (status & R_STP) { /* Remember start of frame */
+ lp->rx_old = entry;
+ }
+ if (status & R_ENP) { /* Valid frame status */
+ if (status & R_ERR) { /* There was an error. */
+ lp->stats.rx_errors++; /* Update the error stats. */
+ if (status & R_FRAM) lp->stats.rx_frame_errors++;
+ if (status & R_OFLO) lp->stats.rx_over_errors++;
+ if (status & R_CRC) lp->stats.rx_crc_errors++;
+ if (status & R_BUFF) lp->stats.rx_fifo_errors++;
+ } else {
+ short len, pkt_len = readw(&lp->rx_ring[entry].msg_length);
+ struct sk_buff *skb;
+
+ skb = dev_alloc_skb(pkt_len+2);
+ if (skb != NULL) {
+ unsigned char *buf;
+ skb_reserve(skb,2); /* 16 byte align the IP header */
+ buf = skb_put(skb,pkt_len);
+ skb->dev = dev;
+ if (entry < lp->rx_old) { /* Wrapped buffer */
+ len = (lp->rxRingMask - lp->rx_old + 1) * RX_BUFF_SZ;
+ memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], len);
+ memcpy_fromio(buf + len, lp->rx_memcpy[0], pkt_len-len);
+ } else { /* Linear buffer */
+ memcpy_fromio(buf, lp->rx_memcpy[lp->rx_old], pkt_len);
+ }
+
+ /*
+ ** Notify the upper protocol layers that there is another
+ ** packet to handle
+ */
+ skb->protocol=eth_type_trans(skb,dev);
+ netif_rx(skb);
+
+ /*
+ ** Update stats
+ */
+ lp->stats.rx_packets++;
+ for (i=1; i<DEPCA_PKT_STAT_SZ-1; i++) {
+ if (pkt_len < (i*DEPCA_PKT_BIN_SZ)) {
+ lp->pktStats.bins[i]++;
+ i = DEPCA_PKT_STAT_SZ;
+ }
+ }
+ if (buf[0] & 0x01) { /* Multicast/Broadcast */
+ if ((*(s16 *)&buf[0] == -1) &&
+ (*(s16 *)&buf[2] == -1) &&
+ (*(s16 *)&buf[4] == -1)) {
+ lp->pktStats.broadcast++;
+ } else {
+ lp->pktStats.multicast++;
+ }
+ } else if ((*(s16 *)&buf[0] == *(s16 *)&dev->dev_addr[0]) &&
+ (*(s16 *)&buf[2] == *(s16 *)&dev->dev_addr[2]) &&
+ (*(s16 *)&buf[4] == *(s16 *)&dev->dev_addr[4])) {
+ lp->pktStats.unicast++;
+ }
+
+ lp->pktStats.bins[0]++; /* Duplicates stats.rx_packets */
+ if (lp->pktStats.bins[0] == 0) { /* Reset counters */
+ memset((char *)&lp->pktStats, 0, sizeof(lp->pktStats));
+ }
+ } else {
+ printk("%s: Memory squeeze, deferring packet.\n", dev->name);
+ lp->stats.rx_dropped++; /* Really, deferred. */
+ break;
}
-
- return 0;
+ }
+ /* Change buffer ownership for this last frame, back to the adapter */
+ for (; lp->rx_old!=entry; lp->rx_old=(++lp->rx_old)&lp->rxRingMask) {
+ writel(readl(&lp->rx_ring[lp->rx_old].base) | R_OWN,
+ &lp->rx_ring[lp->rx_old].base);
+ }
+ writel(readl(&lp->rx_ring[entry].base) | R_OWN, &lp->rx_ring[entry].base);
+ }
+
+ /*
+ ** Update entry information
+ */
+ lp->rx_new = (++lp->rx_new) & lp->rxRingMask;
+ }
+
+ return 0;
}
/*
- ** Buffer sent - check for buffer errors.
- */
-static int depca_tx(struct device *dev)
+** Buffer sent - check for buffer errors.
+*/
+static int
+depca_tx(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- int entry;
- s32 status;
- u_long ioaddr = dev->base_addr;
-
- for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
- status = readl(&lp->tx_ring[entry].base) >> 16;
-
- if (status < 0) { /* Packet not yet sent! */
- break;
- } else if (status & T_ERR) { /* An error occurred. */
- status = readl(&lp->tx_ring[entry].misc);
- lp->stats.tx_errors++;
- if (status & TMD3_RTRY)
- lp->stats.tx_aborted_errors++;
- if (status & TMD3_LCAR)
- lp->stats.tx_carrier_errors++;
- if (status & TMD3_LCOL)
- lp->stats.tx_window_errors++;
- if (status & TMD3_UFLO)
- lp->stats.tx_fifo_errors++;
- if (status & (TMD3_BUFF | TMD3_UFLO)) {
- /* Trigger an immediate send demand. */
- outw(CSR0, DEPCA_ADDR);
- outw(INEA | TDMD, DEPCA_DATA);
- }
- } else if (status & (T_MORE | T_ONE)) {
- lp->stats.collisions++;
- } else {
- lp->stats.tx_packets++;
- }
-
- /* Update all the pointers */
- lp->tx_old = (++lp->tx_old) & lp->txRingMask;
- }
-
- return 0;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ int entry;
+ s32 status;
+ u_long ioaddr = dev->base_addr;
+
+ for (entry = lp->tx_old; entry != lp->tx_new; entry = lp->tx_old) {
+ status = readl(&lp->tx_ring[entry].base) >> 16 ;
+
+ if (status < 0) { /* Packet not yet sent! */
+ break;
+ } else if (status & T_ERR) { /* An error occurred. */
+ status = readl(&lp->tx_ring[entry].misc);
+ lp->stats.tx_errors++;
+ if (status & TMD3_RTRY) lp->stats.tx_aborted_errors++;
+ if (status & TMD3_LCAR) lp->stats.tx_carrier_errors++;
+ if (status & TMD3_LCOL) lp->stats.tx_window_errors++;
+ if (status & TMD3_UFLO) lp->stats.tx_fifo_errors++;
+ if (status & (TMD3_BUFF | TMD3_UFLO)) {
+ /* Trigger an immediate send demand. */
+ outw(CSR0, DEPCA_ADDR);
+ outw(INEA | TDMD, DEPCA_DATA);
+ }
+ } else if (status & (T_MORE | T_ONE)) {
+ lp->stats.collisions++;
+ } else {
+ lp->stats.tx_packets++;
+ }
+
+ /* Update all the pointers */
+ lp->tx_old = (++lp->tx_old) & lp->txRingMask;
+ }
+
+ return 0;
}
-static int depca_close(struct device *dev)
+static int
+depca_close(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- s16 nicsr;
- u_long ioaddr = dev->base_addr;
-
- dev->start = 0;
- dev->tbusy = 1;
-
- outw(CSR0, DEPCA_ADDR);
-
- if (depca_debug > 1) {
- printk("%s: Shutting down ethercard, status was %2.2x.\n",
- dev->name, inw(DEPCA_DATA));
- }
- /*
- ** We stop the DEPCA here -- it occasionally polls
- ** memory if we don't.
- */
- outw(STOP, DEPCA_DATA);
-
- /*
- ** Give back the ROM in case the user wants to go to DOS
- */
- if (lp->adapter != DEPCA) {
- nicsr = inb(DEPCA_NICSR);
- nicsr &= ~SHE;
- outb(nicsr, DEPCA_NICSR);
- }
- /*
- ** Free the associated irq
- */
- free_irq(dev->irq, dev);
-
- MOD_DEC_USE_COUNT;
-
- return 0;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ s16 nicsr;
+ u_long ioaddr = dev->base_addr;
+
+ dev->start = 0;
+ dev->tbusy = 1;
+
+ outw(CSR0, DEPCA_ADDR);
+
+ if (depca_debug > 1) {
+ printk("%s: Shutting down ethercard, status was %2.2x.\n",
+ dev->name, inw(DEPCA_DATA));
+ }
+
+ /*
+ ** We stop the DEPCA here -- it occasionally polls
+ ** memory if we don't.
+ */
+ outw(STOP, DEPCA_DATA);
+
+ /*
+ ** Give back the ROM in case the user wants to go to DOS
+ */
+ if (lp->adapter != DEPCA) {
+ nicsr = inb(DEPCA_NICSR);
+ nicsr &= ~SHE;
+ outb(nicsr, DEPCA_NICSR);
+ }
+
+ /*
+ ** Free the associated irq
+ */
+ free_irq(dev->irq, dev);
+
+ MOD_DEC_USE_COUNT;
+
+ return 0;
}
static void LoadCSRs(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_long ioaddr = dev->base_addr;
- outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
- outw((u16) (lp->sh_mem & LA_MASK), DEPCA_DATA);
- outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
- outw((u16) ((lp->sh_mem & LA_MASK) >> 16), DEPCA_DATA);
- outw(CSR3, DEPCA_ADDR); /* ALE control */
- outw(ACON, DEPCA_DATA);
+ outw(CSR1, DEPCA_ADDR); /* initialisation block address LSW */
+ outw((u16)(lp->sh_mem & LA_MASK), DEPCA_DATA);
+ outw(CSR2, DEPCA_ADDR); /* initialisation block address MSW */
+ outw((u16)((lp->sh_mem & LA_MASK) >> 16), DEPCA_DATA);
+ outw(CSR3, DEPCA_ADDR); /* ALE control */
+ outw(ACON, DEPCA_DATA);
- outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
+ outw(CSR0, DEPCA_ADDR); /* Point back to CSR0 */
- return;
+ return;
}
static int InitRestartDepca(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- int i, status = 0;
-
- /* Copy the shadow init_block to shared memory */
- memcpy_toio((char *) lp->sh_mem, &lp->init_block, sizeof(struct depca_init));
-
- outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
- outw(INIT, DEPCA_DATA); /* initialize DEPCA */
-
- /* wait for lance to complete initialisation */
- for (i = 0; (i < 100) && !(inw(DEPCA_DATA) & IDON); i++);
-
- if (i != 100) {
- /* clear IDON by writing a "1", enable interrupts and start lance */
- outw(IDON | INEA | STRT, DEPCA_DATA);
- if (depca_debug > 2) {
- printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n",
- dev->name, i, lp->sh_mem, inw(DEPCA_DATA));
- }
- } else {
- printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n",
- dev->name, i, lp->sh_mem, inw(DEPCA_DATA));
- status = -1;
- }
-
- return status;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_long ioaddr = dev->base_addr;
+ int i, status=0;
+
+ /* Copy the shadow init_block to shared memory */
+ memcpy_toio((char *)lp->sh_mem, &lp->init_block, sizeof(struct depca_init));
+
+ outw(CSR0, DEPCA_ADDR); /* point back to CSR0 */
+ outw(INIT, DEPCA_DATA); /* initialize DEPCA */
+
+ /* wait for lance to complete initialisation */
+ for (i=0;(i<100) && !(inw(DEPCA_DATA) & IDON); i++);
+
+ if (i!=100) {
+ /* clear IDON by writing a "1", enable interrupts and start lance */
+ outw(IDON | INEA | STRT, DEPCA_DATA);
+ if (depca_debug > 2) {
+ printk("%s: DEPCA open after %d ticks, init block 0x%08lx csr0 %4.4x.\n",
+ dev->name, i, lp->sh_mem, inw(DEPCA_DATA));
+ }
+ } else {
+ printk("%s: DEPCA unopen after %d ticks, init block 0x%08lx csr0 %4.4x.\n",
+ dev->name, i, lp->sh_mem, inw(DEPCA_DATA));
+ status = -1;
+ }
+
+ return status;
}
static struct net_device_stats *
- depca_get_stats(struct device *dev)
+depca_get_stats(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
- /* Null body since there is no framing error counter */
+ /* Null body since there is no framing error counter */
- return &lp->stats;
+ return &lp->stats;
}
/*
- ** Set or clear the multicast filter for this adaptor.
- */
-static void set_multicast_list(struct device *dev)
+** Set or clear the multicast filter for this adaptor.
+*/
+static void
+set_multicast_list(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
-
- while (dev->tbusy); /* Stop ring access */
- set_bit(0, (void *) &dev->tbusy);
- while (lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_long ioaddr = dev->base_addr;
+
+ if (dev) {
+ while(dev->tbusy) barrier(); /* Stop ring access */
+ set_bit(0, (void*)&dev->tbusy);
+ while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
+
+ STOP_DEPCA; /* Temporarily stop the depca. */
+ depca_init_ring(dev); /* Initialize the descriptor rings */
+
+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous mode */
+ lp->init_block.mode |= PROM;
+ } else {
+ SetMulticastFilter(dev);
+ lp->init_block.mode &= ~PROM; /* Unset promiscuous mode */
+ }
+
+ LoadCSRs(dev); /* Reload CSR3 */
+ InitRestartDepca(dev); /* Resume normal operation. */
+ dev->tbusy = 0; /* Unlock the TX ring */
+ }
+}
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous mode */
- lp->init_block.mode |= PROM;
- } else {
- SetMulticastFilter(dev);
- lp->init_block.mode &= ~PROM; /* Unset promiscuous mode */
+/*
+** Calculate the hash code and update the logical address filter
+** from a list of ethernet multicast addresses.
+** Big endian crc one liner is mine, all mine, ha ha ha ha!
+** LANCE calculates its hash codes big endian.
+*/
+static void SetMulticastFilter(struct device *dev)
+{
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ struct dev_mc_list *dmi=dev->mc_list;
+ char *addrs;
+ int i, j, bit, byte;
+ u16 hashcode;
+ s32 crc, poly = CRC_POLYNOMIAL_BE;
+
+ if (dev->flags & IFF_ALLMULTI) { /* Set all multicast bits */
+ for (i=0; i<(HASH_TABLE_LEN>>3); i++) {
+ lp->init_block.mcast_table[i] = (char)0xff;
+ }
+ } else {
+ for (i=0; i<(HASH_TABLE_LEN>>3); i++){ /* Clear the multicast table */
+ lp->init_block.mcast_table[i]=0;
+ }
+ /* Add multicast addresses */
+ for (i=0;i<dev->mc_count;i++) { /* for each address in the list */
+ addrs=dmi->dmi_addr;
+ dmi=dmi->next;
+ if ((*addrs & 0x01) == 1) { /* multicast address? */
+ crc = 0xffffffff; /* init CRC for each address */
+ for (byte=0;byte<ETH_ALEN;byte++) {/* for each address byte */
+ /* process each address bit */
+ for (bit = *addrs++,j=0;j<8;j++, bit>>=1) {
+ crc = (crc << 1) ^ ((((crc<0?1:0) ^ bit) & 0x01) ? poly : 0);
+ }
}
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
+ hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */
+ for (j=0;j<5;j++) { /* ... in reverse order. */
+ hashcode = (hashcode << 1) | ((crc>>=1) & 1);
+ }
+
+
+ byte = hashcode >> 3; /* bit[3-5] -> byte in filter */
+ bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
+ lp->init_block.mcast_table[byte] |= bit;
+ }
+ }
+ }
+
+ return;
}
+#ifdef CONFIG_MCA
/*
- ** Calculate the hash code and update the logical address filter
- ** from a list of ethernet multicast addresses.
- ** Big endian crc one liner is mine, all mine, ha ha ha ha!
- ** LANCE calculates its hash codes big endian.
- */
-static void SetMulticastFilter(struct device *dev)
+** Microchannel bus I/O device probe
+*/
+__initfunc(static void
+mca_probe(struct device *dev, u_long ioaddr))
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- struct dev_mc_list *dmi = dev->mc_list;
- char *addrs;
- int i, j, bit, byte;
- u16 hashcode;
- s32 crc, poly = CRC_POLYNOMIAL_BE;
-
- if (dev->flags & IFF_ALLMULTI) { /* Set all multicast bits */
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) {
- lp->init_block.mcast_table[i] = (char) 0xff;
- }
- } else {
- for (i = 0; i < (HASH_TABLE_LEN >> 3); i++) { /* Clear the multicast table */
- lp->init_block.mcast_table[i] = 0;
- }
- /* Add multicast addresses */
- for (i = 0; i < dev->mc_count; i++) { /* for each address in the list */
- addrs = dmi->dmi_addr;
- dmi = dmi->next;
- if ((*addrs & 0x01) == 1) { /* multicast address? */
- crc = 0xffffffff; /* init CRC for each address */
- for (byte = 0; byte < ETH_ALEN; byte++) { /* for each address byte */
- /* process each address bit */
- for (bit = *addrs++, j = 0; j < 8; j++, bit >>= 1) {
- crc = (crc << 1) ^ ((((crc < 0 ? 1 : 0) ^ bit) & 0x01) ? poly : 0);
- }
- }
- hashcode = (crc & 1); /* hashcode is 6 LSb of CRC ... */
- for (j = 0; j < 5; j++) { /* ... in reverse order. */
- hashcode = (hashcode << 1) | ((crc >>= 1) & 1);
- }
-
-
- byte = hashcode >> 3; /* bit[3-5] -> byte in filter */
- bit = 1 << (hashcode & 0x07); /* bit[0-2] -> bit in byte */
- lp->init_block.mcast_table[byte] |= bit;
- }
+ unsigned char pos[2];
+ unsigned char where;
+ unsigned long iobase;
+ int irq;
+ int slot = 0;
+
+ /*
+ ** See if we've been here before.
+ */
+ if ((!ioaddr && autoprobed) || (ioaddr && !loading_module)) return;
+
+ if (MCA_bus) {
+ /*
+ ** Search for the adapter. If an address has been given, search
+ ** specifically for the card at that address. Otherwise find the
+ ** first card in the system.
+ */
+ while ((dev!=NULL) &&
+ ((slot=mca_find_adapter(DE212_ID, slot)) != MCA_NOTFOUND)) {
+ pos[0] = mca_read_stored_pos(slot, 2);
+ pos[1] = mca_read_stored_pos(slot, 3);
+
+ /*
+ ** IO of card is handled by bits 1 and 2 of pos0.
+ **
+ ** bit2 bit1 IO
+ ** 0 0 0x2c00
+ ** 0 1 0x2c10
+ ** 1 0 0x2c20
+ ** 1 1 0x2c30
+ */
+ where = (pos[0] & 6) >> 1;
+ iobase = 0x2c00 + (0x10 * where);
+
+ if ((ioaddr) && (ioaddr != iobase)) {
+ /*
+ ** Card was found, but not at the right IO location. Continue
+ ** scanning from the next MCA slot up for another card.
+ */
+ slot++;
+ continue;
+ }
+
+ /*
+ ** Found the adapter we were looking for. Now start setting it up.
+ **
+ ** First work on decoding the IRQ. It's stored in the lower 4 bits
+ ** of pos1. Bits are as follows (from the ADF file):
+ **
+ ** Bits
+ ** 3 2 1 0 IRQ
+ ** --------------------
+ ** 0 0 1 0 5
+ ** 0 0 0 1 9
+ ** 0 1 0 0 10
+ ** 1 0 0 0 11
+ **/
+ where = pos[1] & 0x0f;
+ switch(where) {
+ case 1:
+ irq = 9;
+ break;
+ case 2:
+ irq = 5;
+ break;
+ case 4:
+ irq = 10;
+ break;
+ case 8:
+ irq = 11;
+ break;
+ default:
+ printk("%s: mca_probe IRQ error. You should never get here (%d).\n", dev->name, where);
+ return;
+ }
+
+ /*
+ ** Shared memory address of adapter is stored in bits 3-5 of pos0.
+ ** They are mapped as follows:
+ **
+ ** Bit
+ ** 5 4 3 Memory Addresses
+ ** 0 0 0 C0000-CFFFF (64K)
+ ** 1 0 0 C8000-CFFFF (32K)
+ ** 0 0 1 D0000-DFFFF (64K)
+ ** 1 0 1 D8000-DFFFF (32K)
+ ** 0 1 0 E0000-EFFFF (64K)
+ ** 1 1 0 E8000-EFFFF (32K)
+ */
+ where = (pos[0] & 0x18) >> 3;
+ mem = 0xc0000 + (where * 0x10000);
+ if (pos[0] & 0x20) {
+ mem += 0x8000;
+ }
+
+ /*
+ ** Get everything allocated and initialized... (almost just
+ ** like the ISA and EISA probes)
+ */
+ if (DevicePresent(iobase) != 0) {
+ /*
+ ** If the MCA configuration says the card should be here,
+ ** it really should be here.
+ */
+ printk(KERN_ERR "%s: MCA reports card at 0x%lx but it is not
+responding.\n", dev->name, iobase);
+ }
+
+ if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) {
+ if ((dev = alloc_device(dev, iobase)) != NULL) {
+ dev->irq = irq;
+ if (depca_hw_init(dev, iobase, slot) == 0) {
+ /*
+ ** Adapter initialized correctly: Name it in
+ ** /proc/mca.
+ */
+ mca_set_adapter_name(slot, "DE210/212 Ethernet Adapter");
+ mca_mark_as_used(slot);
+ num_depcas++;
+ }
+ num_eth++;
}
+ } else if (autoprobed) {
+ printk(KERN_WARNING "%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
+ }
+
+ /*
+ ** If this is a probe by a module, return after setting up the
+ ** given card.
+ */
+ if (ioaddr) return;
+
+ /*
+ ** Set up to check the next slot and loop.
+ */
+ slot++;
}
+ }
- return;
+ return;
}
+#endif
/*
- ** ISA bus I/O device probe
- */
-__initfunc(static void isa_probe(struct device *dev, u_long ioaddr))
+** ISA bus I/O device probe
+*/
+__initfunc(static void
+isa_probe(struct device *dev, u_long ioaddr))
{
- int i = num_depcas, maxSlots;
- s32 ports[] = DEPCA_IO_PORTS;
-
- if (!ioaddr && autoprobed)
- return; /* Been here before ! */
- if (ioaddr > 0x400)
- return; /* EISA Address */
- if (i >= MAX_NUM_DEPCAS)
- return; /* Too many ISA adapters */
-
- if (ioaddr == 0) { /* Autoprobing */
- maxSlots = MAX_NUM_DEPCAS;
- } else { /* Probe a specific location */
- ports[i] = ioaddr;
- maxSlots = i + 1;
- }
-
- for (; (i < maxSlots) && (dev != NULL) && ports[i]; i++) {
- if (DevicePresent(ports[i]) == 0) {
- if (check_region(ports[i], DEPCA_TOTAL_SIZE) == 0) {
- if ((dev = alloc_device(dev, ports[i])) != NULL) {
- if (depca_hw_init(dev, ports[i]) == 0) {
- num_depcas++;
- }
- num_eth++;
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04x.\n", dev->name, ports[i]);
- }
- }
+ int i = num_depcas, maxSlots;
+ s32 ports[] = DEPCA_IO_PORTS;
+
+ if (!ioaddr && autoprobed) return ; /* Been here before ! */
+ if (ioaddr > 0x400) return; /* EISA Address */
+ if (i >= MAX_NUM_DEPCAS) return; /* Too many ISA adapters */
+
+ if (ioaddr == 0) { /* Autoprobing */
+ maxSlots = MAX_NUM_DEPCAS;
+ } else { /* Probe a specific location */
+ ports[i] = ioaddr;
+ maxSlots = i + 1;
+ }
+
+ for (; (i<maxSlots) && (dev!=NULL) && ports[i]; i++) {
+ if (check_region(ports[i], DEPCA_TOTAL_SIZE) == 0) {
+ if (DevicePresent(ports[i]) == 0) {
+ if ((dev = alloc_device(dev, ports[i])) != NULL) {
+ if (depca_hw_init(dev, ports[i], -1) == 0) {
+ num_depcas++;
+ }
+ num_eth++;
}
+ }
+ } else if (autoprobed) {
+ printk("%s: region already allocated at 0x%04x.\n", dev->name, ports[i]);
+ }
+ }
- return;
+ return;
}
/*
- ** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
- ** the motherboard. Upto 15 EISA devices are supported.
- */
-__initfunc(static void eisa_probe(struct device *dev, u_long ioaddr))
+** EISA bus I/O device probe. Probe from slot 1 since slot 0 is usually
+** the motherboard. Upto 15 EISA devices are supported.
+*/
+__initfunc(static void
+eisa_probe(struct device *dev, u_long ioaddr))
{
- int i, maxSlots;
- u_long iobase;
- char name[DEPCA_STRLEN];
-
- if (!ioaddr && autoprobed)
- return; /* Been here before ! */
- if ((ioaddr < 0x400) && (ioaddr > 0))
- return; /* ISA Address */
-
- if (ioaddr == 0) { /* Autoprobing */
- iobase = EISA_SLOT_INC; /* Get the first slot address */
- i = 1;
- maxSlots = MAX_EISA_SLOTS;
- } else { /* Probe a specific location */
- iobase = ioaddr;
- i = (ioaddr >> 12);
- maxSlots = i + 1;
- }
- if ((iobase & 0x0fff) == 0)
- iobase += DEPCA_EISA_IO_PORTS;
-
- for (; (i < maxSlots) && (dev != NULL); i++, iobase += EISA_SLOT_INC) {
- if (EISA_signature(name, EISA_ID)) {
- if (DevicePresent(iobase) == 0) {
- if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) {
- if ((dev = alloc_device(dev, iobase)) != NULL) {
- if (depca_hw_init(dev, iobase) == 0) {
- num_depcas++;
- }
- num_eth++;
- }
- } else if (autoprobed) {
- printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
- }
- }
- }
+ int i, maxSlots;
+ u_long iobase;
+ char name[DEPCA_STRLEN];
+
+ if (!ioaddr && autoprobed) return ; /* Been here before ! */
+ if ((ioaddr < 0x400) && (ioaddr > 0)) return; /* ISA Address */
+
+ if (ioaddr == 0) { /* Autoprobing */
+ iobase = EISA_SLOT_INC; /* Get the first slot address */
+ i = 1;
+ maxSlots = MAX_EISA_SLOTS;
+ } else { /* Probe a specific location */
+ iobase = ioaddr;
+ i = (ioaddr >> 12);
+ maxSlots = i + 1;
+ }
+ if ((iobase & 0x0fff) == 0) iobase += DEPCA_EISA_IO_PORTS;
+
+ for (; (i<maxSlots) && (dev!=NULL); i++, iobase+=EISA_SLOT_INC) {
+ if (check_region(iobase, DEPCA_TOTAL_SIZE) == 0) {
+ if (EISA_signature(name, EISA_ID)) {
+ if (DevicePresent(iobase) == 0) {
+ if ((dev = alloc_device(dev, iobase)) != NULL) {
+ if (depca_hw_init(dev, iobase, -1) == 0) {
+ num_depcas++;
+ }
+ num_eth++;
+ }
}
+ }
+ } else if (autoprobed) {
+ printk("%s: region already allocated at 0x%04lx.\n", dev->name, iobase);
+ }
+ }
- return;
+ return;
}
/*
- ** Search the entire 'eth' device list for a fixed probe. If a match isn't
- ** found then check for an autoprobe or unused device location. If they
- ** are not available then insert a new device structure at the end of
- ** the current list.
- */
+** Search the entire 'eth' device list for a fixed probe. If a match isn't
+** found then check for an autoprobe or unused device location. If they
+** are not available then insert a new device structure at the end of
+** the current list.
+*/
__initfunc(static struct device *
- alloc_device(struct device *dev, u_long iobase))
+alloc_device(struct device *dev, u_long iobase))
{
- struct device *adev = NULL;
- int fixed = 0, new_dev = 0;
-
- num_eth = depca_dev_index(dev->name);
- if (loading_module)
- return dev;
-
- while (1) {
- if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr == 0)) && !adev) {
- adev = dev;
- } else if ((dev->priv == NULL) && (dev->base_addr == iobase)) {
- fixed = 1;
- } else {
- if (dev->next == NULL) {
- new_dev = 1;
- } else if (strncmp(dev->next->name, "eth", 3) != 0) {
- new_dev = 1;
- }
- }
- if ((dev->next == NULL) || new_dev || fixed)
- break;
- dev = dev->next;
- num_eth++;
- }
- if (adev && !fixed) {
- dev = adev;
- num_eth = depca_dev_index(dev->name);
- new_dev = 0;
- }
- if (((dev->next == NULL) &&
- ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) ||
- new_dev) {
- num_eth++; /* New device */
- dev = insert_device(dev, iobase, depca_probe);
+ struct device *adev = NULL;
+ int fixed = 0, new_dev = 0;
+
+ num_eth = depca_dev_index(dev->name);
+ if (loading_module) return dev;
+
+ while (1) {
+ if (((dev->base_addr == DEPCA_NDA) || (dev->base_addr==0)) && !adev) {
+ adev=dev;
+ } else if ((dev->priv == NULL) && (dev->base_addr==iobase)) {
+ fixed = 1;
+ } else {
+ if (dev->next == NULL) {
+ new_dev = 1;
+ } else if (strncmp(dev->next->name, "eth", 3) != 0) {
+ new_dev = 1;
+ }
}
- return dev;
+ if ((dev->next == NULL) || new_dev || fixed) break;
+ dev = dev->next;
+ num_eth++;
+ }
+ if (adev && !fixed) {
+ dev = adev;
+ num_eth = depca_dev_index(dev->name);
+ new_dev = 0;
+ }
+
+ if (((dev->next == NULL) &&
+ ((dev->base_addr != DEPCA_NDA) && (dev->base_addr != 0)) && !fixed) ||
+ new_dev) {
+ num_eth++; /* New device */
+ dev = insert_device(dev, iobase, depca_probe);
+ }
+
+ return dev;
}
/*
- ** If at end of eth device list and can't use current entry, malloc
- ** one up. If memory could not be allocated, print an error message.
- */
+** If at end of eth device list and can't use current entry, malloc
+** one up. If memory could not be allocated, print an error message.
+*/
__initfunc(static struct device *
- insert_device(struct device *dev, u_long iobase, int (*init) (struct device *)))
+insert_device(struct device *dev, u_long iobase, int (*init)(struct device *)))
{
- struct device *new;
-
- new = (struct device *) kmalloc(sizeof(struct device) + 8, GFP_KERNEL);
- if (new == NULL) {
- printk("eth%d: Device not initialised, insufficient memory\n", num_eth);
- return NULL;
+ struct device *new;
+
+ new = (struct device *)kmalloc(sizeof(struct device)+8, GFP_KERNEL);
+ if (new == NULL) {
+ printk("eth%d: Device not initialised, insufficient memory\n",num_eth);
+ return NULL;
+ } else {
+ new->next = dev->next;
+ dev->next = new;
+ dev = dev->next; /* point to the new device */
+ dev->name = (char *)(dev + 1);
+ if (num_eth > 9999) {
+ sprintf(dev->name,"eth????");/* New device name */
} else {
- new->next = dev->next;
- dev->next = new;
- dev = dev->next; /* point to the new device */
- dev->name = (char *) (dev + 1);
- if (num_eth > 9999) {
- sprintf(dev->name, "eth????"); /* New device name */
- } else {
- sprintf(dev->name, "eth%d", num_eth); /* New device name */
- }
- dev->base_addr = iobase; /* assign the io address */
- dev->init = init; /* initialisation routine */
+ sprintf(dev->name,"eth%d", num_eth);/* New device name */
}
+ dev->base_addr = iobase; /* assign the io address */
+ dev->init = init; /* initialisation routine */
+ }
- return dev;
+ return dev;
}
__initfunc(static int
- depca_dev_index(char *s))
+depca_dev_index(char *s))
{
- int i = 0, j = 0;
-
- for (; *s; s++) {
- if (isdigit(*s)) {
- j = 1;
- i = (i * 10) + (*s - '0');
- } else if (j)
- break;
- }
+ int i=0, j=0;
- return i;
+ for (;*s; s++) {
+ if (isdigit(*s)) {
+ j=1;
+ i = (i * 10) + (*s - '0');
+ } else if (j) break;
+ }
+
+ return i;
}
/*
- ** Look for a particular board name in the on-board Remote Diagnostics
- ** and Boot (readb) ROM. This will also give us a clue to the network RAM
- ** base address.
- */
-__initfunc(static void DepcaSignature(char *name, u_long paddr))
+** Look for a particular board name in the on-board Remote Diagnostics
+** and Boot (readb) ROM. This will also give us a clue to the network RAM
+** base address.
+*/
+__initfunc(static void
+DepcaSignature(char *name, u_long paddr))
{
- u_int i, j, k;
- const char *signatures[] = DEPCA_SIGNATURE;
- char tmpstr[16];
-
- /* Copy the first 16 bytes of ROM */
- for (i = 0; i < 16; i++) {
- tmpstr[i] = readb(paddr + 0xc000 + i);
- }
-
- /* Check if PROM contains a valid string */
- for (i = 0; *signatures[i] != '\0'; i++) {
- for (j = 0, k = 0; j < 16 && k < strlen(signatures[i]); j++) {
- if (signatures[i][k] == tmpstr[j]) { /* track signature */
- k++;
- } else { /* lost signature; begin search again */
- k = 0;
- }
- }
- if (k == strlen(signatures[i]))
- break;
- }
-
- /* Check if name string is valid, provided there's no PROM */
- if (*name && (i == unknown)) {
- for (i = 0; *signatures[i] != '\0'; i++) {
- if (strcmp(name, signatures[i]) == 0)
- break;
- }
- }
- /* Update search results */
- strcpy(name, signatures[i]);
- adapter = i;
-
- return;
+ u_int i,j,k;
+ const char *signatures[] = DEPCA_SIGNATURE;
+ char tmpstr[16];
+
+ /* Copy the first 16 bytes of ROM */
+ for (i=0;i<16;i++) {
+ tmpstr[i] = readb(paddr+0xc000+i);
+ }
+
+ /* Check if PROM contains a valid string */
+ for (i=0;*signatures[i]!='\0';i++) {
+ for (j=0,k=0;j<16 && k<strlen(signatures[i]);j++) {
+ if (signatures[i][k] == tmpstr[j]) { /* track signature */
+ k++;
+ } else { /* lost signature; begin search again */
+ k=0;
+ }
+ }
+ if (k == strlen(signatures[i])) break;
+ }
+
+ /* Check if name string is valid, provided there's no PROM */
+ if (*name && (i == unknown)) {
+ for (i=0;*signatures[i]!='\0';i++) {
+ if (strcmp(name,signatures[i]) == 0) break;
+ }
+ }
+
+ /* Update search results */
+ strcpy(name,signatures[i]);
+ adapter = i;
+
+ return;
}
/*
- ** Look for a special sequence in the Ethernet station address PROM that
- ** is common across all DEPCA products. Note that the original DEPCA needs
- ** its ROM address counter to be initialized and enabled. Only enable
- ** if the first address octet is a 0x08 - this minimises the chances of
- ** messing around with some other hardware, but it assumes that this DEPCA
- ** card initialized itself correctly.
- **
- ** Search the Ethernet address ROM for the signature. Since the ROM address
- ** counter can start at an arbitrary point, the search must include the entire
- ** probe sequence length plus the (length_of_the_signature - 1).
- ** Stop the search IMMEDIATELY after the signature is found so that the
- ** PROM address counter is correctly positioned at the start of the
- ** ethernet address for later read out.
- */
-__initfunc(static int DevicePresent(u_long ioaddr))
+** Look for a special sequence in the Ethernet station address PROM that
+** is common across all DEPCA products. Note that the original DEPCA needs
+** its ROM address counter to be initialized and enabled. Only enable
+** if the first address octet is a 0x08 - this minimises the chances of
+** messing around with some other hardware, but it assumes that this DEPCA
+** card initialized itself correctly.
+**
+** Search the Ethernet address ROM for the signature. Since the ROM address
+** counter can start at an arbitrary point, the search must include the entire
+** probe sequence length plus the (length_of_the_signature - 1).
+** Stop the search IMMEDIATELY after the signature is found so that the
+** PROM address counter is correctly positioned at the start of the
+** ethernet address for later read out.
+*/
+__initfunc(static int
+DevicePresent(u_long ioaddr))
{
- union {
- struct {
- u32 a;
- u32 b;
- } llsig;
- char Sig[sizeof(u32) << 1];
- }
- dev;
- short sigLength = 0;
- s8 data;
- s16 nicsr;
- int i, j, status = 0;
-
- data = inb(DEPCA_PROM); /* clear counter on DEPCA */
- data = inb(DEPCA_PROM); /* read data */
-
- if (data == 0x08) { /* Enable counter on DEPCA */
- nicsr = inb(DEPCA_NICSR);
- nicsr |= AAC;
- outb(nicsr, DEPCA_NICSR);
- }
- dev.llsig.a = ETH_PROM_SIG;
- dev.llsig.b = ETH_PROM_SIG;
- sigLength = sizeof(u32) << 1;
-
- for (i = 0, j = 0; j < sigLength && i < PROBE_LENGTH + sigLength - 1; i++) {
- data = inb(DEPCA_PROM);
- if (dev.Sig[j] == data) { /* track signature */
- j++;
- } else { /* lost signature; begin search again */
- if (data == dev.Sig[0]) { /* rare case.... */
- j = 1;
- } else {
- j = 0;
- }
- }
- }
-
- if (j != sigLength) {
- status = -ENODEV; /* search failed */
- }
- return status;
+ union {
+ struct {
+ u32 a;
+ u32 b;
+ } llsig;
+ char Sig[sizeof(u32) << 1];
+ } dev;
+ short sigLength=0;
+ s8 data;
+ s16 nicsr;
+ int i, j, status = 0;
+
+ data = inb(DEPCA_PROM); /* clear counter on DEPCA */
+ data = inb(DEPCA_PROM); /* read data */
+
+ if (data == 0x08) { /* Enable counter on DEPCA */
+ nicsr = inb(DEPCA_NICSR);
+ nicsr |= AAC;
+ outb(nicsr, DEPCA_NICSR);
+ }
+
+ dev.llsig.a = ETH_PROM_SIG;
+ dev.llsig.b = ETH_PROM_SIG;
+ sigLength = sizeof(u32) << 1;
+
+ for (i=0,j=0;j<sigLength && i<PROBE_LENGTH+sigLength-1;i++) {
+ data = inb(DEPCA_PROM);
+ if (dev.Sig[j] == data) { /* track signature */
+ j++;
+ } else { /* lost signature; begin search again */
+ if (data == dev.Sig[0]) { /* rare case.... */
+ j=1;
+ } else {
+ j=0;
+ }
+ }
+ }
+
+ if (j!=sigLength) {
+ status = -ENODEV; /* search failed */
+ }
+
+ return status;
}
/*
- ** The DE100 and DE101 PROM accesses were made non-standard for some bizarre
- ** reason: access the upper half of the PROM with x=0; access the lower half
- ** with x=1.
- */
-__initfunc(static int get_hw_addr(struct device *dev))
+** The DE100 and DE101 PROM accesses were made non-standard for some bizarre
+** reason: access the upper half of the PROM with x=0; access the lower half
+** with x=1.
+*/
+__initfunc(static int
+get_hw_addr(struct device *dev))
{
- u_long ioaddr = dev->base_addr;
- int i, k, tmp, status = 0;
- u_short j, x, chksum;
+ u_long ioaddr = dev->base_addr;
+ int i, k, tmp, status = 0;
+ u_short j, x, chksum;
- x = (((adapter == de100) || (adapter == de101)) ? 1 : 0);
+ x = (((adapter == de100) || (adapter == de101)) ? 1 : 0);
- for (i = 0, k = 0, j = 0; j < 3; j++) {
- k <<= 1;
- if (k > 0xffff)
- k -= 0xffff;
+ for (i=0,k=0,j=0;j<3;j++) {
+ k <<= 1 ;
+ if (k > 0xffff) k-=0xffff;
- k += (u_char) (tmp = inb(DEPCA_PROM + x));
- dev->dev_addr[i++] = (u_char) tmp;
- k += (u_short) ((tmp = inb(DEPCA_PROM + x)) << 8);
- dev->dev_addr[i++] = (u_char) tmp;
+ k += (u_char) (tmp = inb(DEPCA_PROM + x));
+ dev->dev_addr[i++] = (u_char) tmp;
+ k += (u_short) ((tmp = inb(DEPCA_PROM + x)) << 8);
+ dev->dev_addr[i++] = (u_char) tmp;
- if (k > 0xffff)
- k -= 0xffff;
- }
- if (k == 0xffff)
- k = 0;
+ if (k > 0xffff) k-=0xffff;
+ }
+ if (k == 0xffff) k=0;
- chksum = (u_char) inb(DEPCA_PROM + x);
- chksum |= (u_short) (inb(DEPCA_PROM + x) << 8);
- if (k != chksum)
- status = -1;
+ chksum = (u_char) inb(DEPCA_PROM + x);
+ chksum |= (u_short) (inb(DEPCA_PROM + x) << 8);
+ if (k != chksum) status = -1;
- return status;
+ return status;
}
/*
- ** Load a packet into the shared memory
- */
+** Load a packet into the shared memory
+*/
static int load_packet(struct device *dev, struct sk_buff *skb)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- int i, entry, end, len, status = 0;
-
- entry = lp->tx_new; /* Ring around buffer number. */
- end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
- if (!(readl(&lp->tx_ring[end].base) & T_OWN)) { /* Enough room? */
- /*
- ** Caution: the write order is important here... don't set up the
- ** ownership rights until all the other information is in place.
- */
- if (end < entry) { /* wrapped buffer */
- len = (lp->txRingMask - entry + 1) * TX_BUFF_SZ;
- memcpy_toio(lp->tx_memcpy[entry], skb->data, len);
- memcpy_toio(lp->tx_memcpy[0], skb->data + len, skb->len - len);
- } else { /* linear buffer */
- memcpy_toio(lp->tx_memcpy[entry], skb->data, skb->len);
- }
-
- /* set up the buffer descriptors */
- len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
- for (i = entry; i != end; i = (++i) & lp->txRingMask) {
- /* clean out flags */
- writel(readl(&lp->tx_ring[i].base) & ~T_FLAGS, &lp->tx_ring[i].base);
- writew(0x0000, &lp->tx_ring[i].misc); /* clears other error flags */
- writew(-TX_BUFF_SZ, &lp->tx_ring[i].length); /* packet length in buffer */
- len -= TX_BUFF_SZ;
- }
- /* clean out flags */
- writel(readl(&lp->tx_ring[end].base) & ~T_FLAGS, &lp->tx_ring[end].base);
- writew(0x0000, &lp->tx_ring[end].misc); /* clears other error flags */
- writew(-len, &lp->tx_ring[end].length); /* packet length in last buff */
-
- /* start of packet */
- writel(readl(&lp->tx_ring[entry].base) | T_STP, &lp->tx_ring[entry].base);
- /* end of packet */
- writel(readl(&lp->tx_ring[end].base) | T_ENP, &lp->tx_ring[end].base);
-
- for (i = end; i != entry; --i) {
- /* ownership of packet */
- writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
- if (i == 0)
- i = lp->txRingMask + 1;
- }
- writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
-
- lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
- } else {
- status = -1;
- }
-
- return status;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ int i, entry, end, len, status = 0;
+
+ entry = lp->tx_new; /* Ring around buffer number. */
+ end = (entry + (skb->len - 1) / TX_BUFF_SZ) & lp->txRingMask;
+ if (!(readl(&lp->tx_ring[end].base) & T_OWN)) {/* Enough room? */
+ /*
+ ** Caution: the write order is important here... don't set up the
+ ** ownership rights until all the other information is in place.
+ */
+ if (end < entry) { /* wrapped buffer */
+ len = (lp->txRingMask - entry + 1) * TX_BUFF_SZ;
+ memcpy_toio(lp->tx_memcpy[entry], skb->data, len);
+ memcpy_toio(lp->tx_memcpy[0], skb->data + len, skb->len - len);
+ } else { /* linear buffer */
+ memcpy_toio(lp->tx_memcpy[entry], skb->data, skb->len);
+ }
+
+ /* set up the buffer descriptors */
+ len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;
+ for (i = entry; i != end; i = (++i) & lp->txRingMask) {
+ /* clean out flags */
+ writel(readl(&lp->tx_ring[i].base) & ~T_FLAGS, &lp->tx_ring[i].base);
+ writew(0x0000, &lp->tx_ring[i].misc); /* clears other error flags */
+ writew(-TX_BUFF_SZ, &lp->tx_ring[i].length);/* packet length in buffer */
+ len -= TX_BUFF_SZ;
+ }
+ /* clean out flags */
+ writel(readl(&lp->tx_ring[end].base) & ~T_FLAGS, &lp->tx_ring[end].base);
+ writew(0x0000, &lp->tx_ring[end].misc); /* clears other error flags */
+ writew(-len, &lp->tx_ring[end].length); /* packet length in last buff */
+
+ /* start of packet */
+ writel(readl(&lp->tx_ring[entry].base) | T_STP, &lp->tx_ring[entry].base);
+ /* end of packet */
+ writel(readl(&lp->tx_ring[end].base) | T_ENP, &lp->tx_ring[end].base);
+
+ for (i=end; i!=entry; --i) {
+ /* ownership of packet */
+ writel(readl(&lp->tx_ring[i].base) | T_OWN, &lp->tx_ring[i].base);
+ if (i == 0) i=lp->txRingMask+1;
+ }
+ writel(readl(&lp->tx_ring[entry].base) | T_OWN, &lp->tx_ring[entry].base);
+
+ lp->tx_new = (++end) & lp->txRingMask; /* update current pointers */
+ } else {
+ status = -1;
+ }
+
+ return status;
}
/*
- ** Look for a particular board name in the EISA configuration space
- */
-__initfunc(static int EISA_signature(char *name, s32 eisa_id))
+** Look for a particular board name in the EISA configuration space
+*/
+__initfunc(static int
+EISA_signature(char *name, s32 eisa_id))
{
- u_int i;
- const char *signatures[] = DEPCA_SIGNATURE;
- char ManCode[DEPCA_STRLEN];
- union {
- s32 ID;
- char Id[4];
- } Eisa;
- int status = 0;
-
- *name = '\0';
- Eisa.ID = inl(eisa_id);
-
- ManCode[0] = (((Eisa.Id[0] >> 2) & 0x1f) + 0x40);
- ManCode[1] = (((Eisa.Id[1] & 0xe0) >> 5) + ((Eisa.Id[0] & 0x03) << 3) + 0x40);
- ManCode[2] = (((Eisa.Id[2] >> 4) & 0x0f) + 0x30);
- ManCode[3] = ((Eisa.Id[2] & 0x0f) + 0x30);
- ManCode[4] = (((Eisa.Id[3] >> 4) & 0x0f) + 0x30);
- ManCode[5] = '\0';
-
- for (i = 0; (*signatures[i] != '\0') && (*name == '\0'); i++) {
- if (strstr(ManCode, signatures[i]) != NULL) {
- strcpy(name, ManCode);
- status = 1;
- }
- }
-
- return status;
+ u_int i;
+ const char *signatures[] = DEPCA_SIGNATURE;
+ char ManCode[DEPCA_STRLEN];
+ union {
+ s32 ID;
+ char Id[4];
+ } Eisa;
+ int status = 0;
+
+ *name = '\0';
+ Eisa.ID = inl(eisa_id);
+
+ ManCode[0]=(((Eisa.Id[0]>>2)&0x1f)+0x40);
+ ManCode[1]=(((Eisa.Id[1]&0xe0)>>5)+((Eisa.Id[0]&0x03)<<3)+0x40);
+ ManCode[2]=(((Eisa.Id[2]>>4)&0x0f)+0x30);
+ ManCode[3]=(( Eisa.Id[2]&0x0f)+0x30);
+ ManCode[4]=(((Eisa.Id[3]>>4)&0x0f)+0x30);
+ ManCode[5]='\0';
+
+ for (i=0;(*signatures[i] != '\0') && (*name == '\0');i++) {
+ if (strstr(ManCode, signatures[i]) != NULL) {
+ strcpy(name,ManCode);
+ status = 1;
+ }
+ }
+
+ return status;
}
static void depca_dbg_open(struct device *dev)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- u_long ioaddr = dev->base_addr;
- struct depca_init *p = (struct depca_init *) lp->sh_mem;
- int i;
-
- if (depca_debug > 1) {
- /* Copy the shadow init_block to shared memory */
- memcpy_toio((char *) lp->sh_mem, &lp->init_block, sizeof(struct depca_init));
-
- printk("%s: depca open with irq %d\n", dev->name, dev->irq);
- printk("Descriptor head addresses:\n");
- printk("\t0x%lx 0x%lx\n", (u_long) lp->rx_ring, (u_long) lp->tx_ring);
- printk("Descriptor addresses:\nRX: ");
- for (i = 0; i < lp->rxRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8lx ", (long) &lp->rx_ring[i].base);
- }
- }
- printk("...0x%8.8lx\n", (long) &lp->rx_ring[i].base);
- printk("TX: ");
- for (i = 0; i < lp->txRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8lx ", (long) &lp->tx_ring[i].base);
- }
- }
- printk("...0x%8.8lx\n", (long) &lp->tx_ring[i].base);
- printk("\nDescriptor buffers:\nRX: ");
- for (i = 0; i < lp->rxRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8x ", readl(&lp->rx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", readl(&lp->rx_ring[i].base));
- printk("TX: ");
- for (i = 0; i < lp->txRingMask; i++) {
- if (i < 3) {
- printk("0x%8.8x ", readl(&lp->tx_ring[i].base));
- }
- }
- printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
- printk("Initialisation block at 0x%8.8lx\n", lp->sh_mem);
- printk("\tmode: 0x%4.4x\n", readw(&p->mode));
- printk("\tphysical address: ");
- for (i = 0; i < ETH_ALEN - 1; i++) {
- printk("%2.2x:", (u_char) readb(&p->phys_addr[i]));
- }
- printk("%2.2x\n", (u_char) readb(&p->phys_addr[i]));
- printk("\tmulticast hash table: ");
- for (i = 0; i < (HASH_TABLE_LEN >> 3) - 1; i++) {
- printk("%2.2x:", (u_char) readb(&p->mcast_table[i]));
- }
- printk("%2.2x\n", (u_char) readb(&p->mcast_table[i]));
- printk("\trx_ring at: 0x%8.8x\n", readl(&p->rx_ring));
- printk("\ttx_ring at: 0x%8.8x\n", readl(&p->tx_ring));
- printk("dma_buffs: 0x%8.8lx\n", lp->dma_buffs);
- printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n",
- (int) lp->rxRingMask + 1,
- lp->rx_rlen);
- printk("TX: %d Log2(txRingMask): 0x%8.8x\n",
- (int) lp->txRingMask + 1,
- lp->tx_rlen);
- outw(CSR2, DEPCA_ADDR);
- printk("CSR2&1: 0x%4.4x", inw(DEPCA_DATA));
- outw(CSR1, DEPCA_ADDR);
- printk("%4.4x\n", inw(DEPCA_DATA));
- outw(CSR3, DEPCA_ADDR);
- printk("CSR3: 0x%4.4x\n", inw(DEPCA_DATA));
- }
- return;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ u_long ioaddr = dev->base_addr;
+ struct depca_init *p = (struct depca_init *)lp->sh_mem;
+ int i;
+
+ if (depca_debug > 1){
+ /* Copy the shadow init_block to shared memory */
+ memcpy_toio((char *)lp->sh_mem,&lp->init_block,sizeof(struct depca_init));
+
+ printk("%s: depca open with irq %d\n",dev->name,dev->irq);
+ printk("Descriptor head addresses:\n");
+ printk("\t0x%lx 0x%lx\n",(u_long)lp->rx_ring, (u_long)lp->tx_ring);
+ printk("Descriptor addresses:\nRX: ");
+ for (i=0;i<lp->rxRingMask;i++){
+ if (i < 3) {
+ printk("0x%8.8lx ", (long) &lp->rx_ring[i].base);
+ }
+ }
+ printk("...0x%8.8lx\n", (long) &lp->rx_ring[i].base);
+ printk("TX: ");
+ for (i=0;i<lp->txRingMask;i++){
+ if (i < 3) {
+ printk("0x%8.8lx ", (long) &lp->tx_ring[i].base);
+ }
+ }
+ printk("...0x%8.8lx\n", (long) &lp->tx_ring[i].base);
+ printk("\nDescriptor buffers:\nRX: ");
+ for (i=0;i<lp->rxRingMask;i++){
+ if (i < 3) {
+ printk("0x%8.8x ", readl(&lp->rx_ring[i].base));
+ }
+ }
+ printk("...0x%8.8x\n", readl(&lp->rx_ring[i].base));
+ printk("TX: ");
+ for (i=0;i<lp->txRingMask;i++){
+ if (i < 3) {
+ printk("0x%8.8x ", readl(&lp->tx_ring[i].base));
+ }
+ }
+ printk("...0x%8.8x\n", readl(&lp->tx_ring[i].base));
+ printk("Initialisation block at 0x%8.8lx\n",lp->sh_mem);
+ printk("\tmode: 0x%4.4x\n",readw(&p->mode));
+ printk("\tphysical address: ");
+ for (i=0;i<ETH_ALEN-1;i++){
+ printk("%2.2x:",(u_char)readb(&p->phys_addr[i]));
+ }
+ printk("%2.2x\n",(u_char)readb(&p->phys_addr[i]));
+ printk("\tmulticast hash table: ");
+ for (i=0;i<(HASH_TABLE_LEN >> 3)-1;i++){
+ printk("%2.2x:",(u_char)readb(&p->mcast_table[i]));
+ }
+ printk("%2.2x\n",(u_char)readb(&p->mcast_table[i]));
+ printk("\trx_ring at: 0x%8.8x\n",readl(&p->rx_ring));
+ printk("\ttx_ring at: 0x%8.8x\n",readl(&p->tx_ring));
+ printk("dma_buffs: 0x%8.8lx\n",lp->dma_buffs);
+ printk("Ring size:\nRX: %d Log2(rxRingMask): 0x%8.8x\n",
+ (int)lp->rxRingMask + 1,
+ lp->rx_rlen);
+ printk("TX: %d Log2(txRingMask): 0x%8.8x\n",
+ (int)lp->txRingMask + 1,
+ lp->tx_rlen);
+ outw(CSR2,DEPCA_ADDR);
+ printk("CSR2&1: 0x%4.4x",inw(DEPCA_DATA));
+ outw(CSR1,DEPCA_ADDR);
+ printk("%4.4x\n",inw(DEPCA_DATA));
+ outw(CSR3,DEPCA_ADDR);
+ printk("CSR3: 0x%4.4x\n",inw(DEPCA_DATA));
+ }
+
+ return;
}
/*
- ** Perform IOCTL call functions here. Some are privileged operations and the
- ** effective uid is checked in those cases.
- ** All MCA IOCTLs will not work here and are for testing purposes only.
- */
+** Perform IOCTL call functions here. Some are privileged operations and the
+** effective uid is checked in those cases.
+** All multicast IOCTLs will not work here and are for testing purposes only.
+*/
static int depca_ioctl(struct device *dev, struct ifreq *rq, int cmd)
{
- struct depca_private *lp = (struct depca_private *) dev->priv;
- struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data;
- int i, status = 0;
- u_long ioaddr = dev->base_addr;
- union {
- u8 addr[(HASH_TABLE_LEN * ETH_ALEN)];
- u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
- u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
- } tmp;
-
- switch (ioc->cmd) {
- case DEPCA_GET_HWADDR: /* Get the hardware address */
- for (i = 0; i < ETH_ALEN; i++) {
- tmp.addr[i] = dev->dev_addr[i];
- }
- ioc->len = ETH_ALEN;
- if (!(status = verify_area(VERIFY_WRITE, (void *) ioc->data, ioc->len))) {
- copy_to_user(ioc->data, tmp.addr, ioc->len);
- }
- break;
- case DEPCA_SET_HWADDR: /* Set the hardware address */
- if (capable(CAP_NET_ADMIN)) {
- if (!(status = verify_area(VERIFY_READ, (void *) ioc->data, ETH_ALEN))) {
- copy_from_user(tmp.addr, ioc->data, ETH_ALEN);
- for (i = 0; i < ETH_ALEN; i++) {
- dev->dev_addr[i] = tmp.addr[i];
- }
- while (dev->tbusy); /* Stop ring access */
- set_bit(0, (void *) &dev->tbusy);
- while (lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_SET_PROM: /* Set Promiscuous Mode */
- if (capable(CAP_NET_ADMIN)) {
- while (dev->tbusy); /* Stop ring access */
- set_bit(0, (void *) &dev->tbusy);
- while (lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode |= PROM; /* Set promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_CLR_PROM: /* Clear Promiscuous Mode */
- if (capable(CAP_NET_ADMIN)) {
- while (dev->tbusy); /* Stop ring access */
- set_bit(0, (void *) &dev->tbusy);
- while (lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
-
- STOP_DEPCA; /* Temporarily stop the depca. */
- depca_init_ring(dev); /* Initialize the descriptor rings */
- lp->init_block.mode &= ~PROM; /* Clear promiscuous mode */
-
- LoadCSRs(dev); /* Reload CSR3 */
- InitRestartDepca(dev); /* Resume normal operation. */
- dev->tbusy = 0; /* Unlock the TX ring */
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_SAY_BOO: /* Say "Boo!" to the kernel log file */
- printk("%s: Boo!\n", dev->name);
-
- break;
- case DEPCA_GET_MCA: /* Get the multicast address table */
- ioc->len = (HASH_TABLE_LEN >> 3);
- if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len);
- }
- break;
- case DEPCA_SET_MCA: /* Set a multicast address */
- if (capable(CAP_NET_ADMIN)) {
- if (!(status = verify_area(VERIFY_READ, ioc->data, ETH_ALEN * ioc->len))) {
- copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
- set_multicast_list(dev);
- }
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_CLR_MCA: /* Clear all multicast addresses */
- if (capable(CAP_NET_ADMIN)) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_MCA_EN: /* Enable pass all multicast addressing */
- if (capable(CAP_NET_ADMIN)) {
- set_multicast_list(dev);
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_GET_STATS: /* Get the driver statistics */
- cli();
- ioc->len = sizeof(lp->pktStats);
- if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- copy_to_user(ioc->data, &lp->pktStats, ioc->len);
- }
- sti();
-
- break;
- case DEPCA_CLR_STATS: /* Zero out the driver statistics */
- if (capable(CAP_NET_ADMIN)) {
- cli();
- memset(&lp->pktStats, 0, sizeof(lp->pktStats));
- sti();
- } else {
- status = -EPERM;
- }
-
- break;
- case DEPCA_GET_REG: /* Get the DEPCA Registers */
- i = 0;
- tmp.sval[i++] = inw(DEPCA_NICSR);
- outw(CSR0, DEPCA_ADDR); /* status register */
- tmp.sval[i++] = inw(DEPCA_DATA);
- memcpy(&tmp.sval[i], &lp->init_block, sizeof(struct depca_init));
- ioc->len = i + sizeof(struct depca_init);
- if (!(status = verify_area(VERIFY_WRITE, ioc->data, ioc->len))) {
- copy_to_user(ioc->data, tmp.addr, ioc->len);
- }
- break;
- default:
- status = -EOPNOTSUPP;
- }
-
- return status;
+ struct depca_private *lp = (struct depca_private *)dev->priv;
+ struct depca_ioctl *ioc = (struct depca_ioctl *) &rq->ifr_data;
+ int i, status = 0;
+ u_long ioaddr = dev->base_addr;
+ union {
+ u8 addr[(HASH_TABLE_LEN * ETH_ALEN)];
+ u16 sval[(HASH_TABLE_LEN * ETH_ALEN) >> 1];
+ u32 lval[(HASH_TABLE_LEN * ETH_ALEN) >> 2];
+ } tmp;
+
+ switch(ioc->cmd) {
+ case DEPCA_GET_HWADDR: /* Get the hardware address */
+ for (i=0; i<ETH_ALEN; i++) {
+ tmp.addr[i] = dev->dev_addr[i];
+ }
+ ioc->len = ETH_ALEN;
+ if (verify_area(VERIFY_WRITE, (void *)ioc->data, ioc->len)) return -EFAULT;
+ copy_to_user(ioc->data, tmp.addr, ioc->len);
+ break;
+
+ case DEPCA_SET_HWADDR: /* Set the hardware address */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ if (verify_area(VERIFY_READ, (void *)ioc->data, ETH_ALEN)) return -EFAULT;
+ copy_from_user(tmp.addr,ioc->data,ETH_ALEN);
+ for (i=0; i<ETH_ALEN; i++) {
+ dev->dev_addr[i] = tmp.addr[i];
+ }
+ while(dev->tbusy) barrier(); /* Stop ring access */
+ test_and_set_bit(0, (void*)&dev->tbusy);
+ while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
+
+ STOP_DEPCA; /* Temporarily stop the depca. */
+ depca_init_ring(dev); /* Initialize the descriptor rings */
+ LoadCSRs(dev); /* Reload CSR3 */
+ InitRestartDepca(dev); /* Resume normal operation. */
+ dev->tbusy = 0; /* Unlock the TX ring */
+ break;
+
+ case DEPCA_SET_PROM: /* Set Promiscuous Mode */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ while(dev->tbusy) barrier(); /* Stop ring access */
+ test_and_set_bit(0, (void*)&dev->tbusy);
+ while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
+
+ STOP_DEPCA; /* Temporarily stop the depca. */
+ depca_init_ring(dev); /* Initialize the descriptor rings */
+ lp->init_block.mode |= PROM; /* Set promiscuous mode */
+
+ LoadCSRs(dev); /* Reload CSR3 */
+ InitRestartDepca(dev); /* Resume normal operation. */
+ dev->tbusy = 0; /* Unlock the TX ring */
+ break;
+
+ case DEPCA_CLR_PROM: /* Clear Promiscuous Mode */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ while(dev->tbusy) barrier(); /* Stop ring access */
+ test_and_set_bit(0, (void*)&dev->tbusy);
+ while(lp->tx_old != lp->tx_new); /* Wait for the ring to empty */
+
+ STOP_DEPCA; /* Temporarily stop the depca. */
+ depca_init_ring(dev); /* Initialize the descriptor rings */
+ lp->init_block.mode &= ~PROM; /* Clear promiscuous mode */
+
+ LoadCSRs(dev); /* Reload CSR3 */
+ InitRestartDepca(dev); /* Resume normal operation. */
+ dev->tbusy = 0; /* Unlock the TX ring */
+ break;
+
+ case DEPCA_SAY_BOO: /* Say "Boo!" to the kernel log file */
+ printk("%s: Boo!\n", dev->name);
+ break;
+
+ case DEPCA_GET_MCA: /* Get the multicast address table */
+ ioc->len = (HASH_TABLE_LEN >> 3);
+ if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) return -EFAULT;
+ copy_to_user(ioc->data, lp->init_block.mcast_table, ioc->len);
+ break;
+
+ case DEPCA_SET_MCA: /* Set a multicast address */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ if (verify_area(VERIFY_READ, ioc->data, ETH_ALEN*ioc->len)) return -EFAULT;
+ copy_from_user(tmp.addr, ioc->data, ETH_ALEN * ioc->len);
+ set_multicast_list(dev);
+ break;
+
+ case DEPCA_CLR_MCA: /* Clear all multicast addresses */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ set_multicast_list(dev);
+ break;
+
+ case DEPCA_MCA_EN: /* Enable pass all multicast addressing */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ set_multicast_list(dev);
+ break;
+
+ case DEPCA_GET_STATS: /* Get the driver statistics */
+ cli();
+ ioc->len = sizeof(lp->pktStats);
+ if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) {
+ status = -EFAULT;
+ } else {
+ copy_to_user(ioc->data, &lp->pktStats, ioc->len);
+ }
+ sti();
+ break;
+
+ case DEPCA_CLR_STATS: /* Zero out the driver statistics */
+ if (!capable(CAP_NET_ADMIN)) return -EPERM;
+ cli();
+ memset(&lp->pktStats, 0, sizeof(lp->pktStats));
+ sti();
+ break;
+
+ case DEPCA_GET_REG: /* Get the DEPCA Registers */
+ i=0;
+ tmp.sval[i++] = inw(DEPCA_NICSR);
+ outw(CSR0, DEPCA_ADDR); /* status register */
+ tmp.sval[i++] = inw(DEPCA_DATA);
+ memcpy(&tmp.sval[i], &lp->init_block, sizeof(struct depca_init));
+ ioc->len = i+sizeof(struct depca_init);
+ if (verify_area(VERIFY_WRITE, ioc->data, ioc->len)) return -EFAULT;
+ copy_to_user(ioc->data, tmp.addr, ioc->len);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return status;
}
#ifdef MODULE
-static char devicename[9] =
-{0,};
-static struct device thisDepca =
-{
- devicename, /* device name is inserted by /linux/drivers/net/net_init.c */
- 0, 0, 0, 0,
- 0x200, 7, /* I/O address, IRQ */
- 0, 0, 0, NULL, depca_probe};
+static char devicename[9] = {0,};
+static struct device thisDepca = {
+ devicename, /* device name is inserted by /linux/drivers/net/net_init.c */
+ 0, 0, 0, 0,
+ 0x200, 7, /* I/O address, IRQ */
+ 0, 0, 0, NULL, depca_probe
+};
-static int irq = 7; /* EDIT THESE LINE FOR YOUR CONFIGURATION */
-static int io = 0x200; /* Or use the irq= io= options to insmod */
+static int irq=7; /* EDIT THESE LINE FOR YOUR CONFIGURATION */
+static int io=0x200; /* Or use the irq= io= options to insmod */
MODULE_PARM(irq, "i");
MODULE_PARM(io, "i");
-/* See depca_probe() for autoprobe messages when a module */
-int init_module(void)
+/* See depca_probe() for autoprobe messages when a module */
+int
+init_module(void)
{
- thisDepca.irq = irq;
- thisDepca.base_addr = io;
+ thisDepca.irq=irq;
+ thisDepca.base_addr=io;
- if (register_netdev(&thisDepca) != 0)
- return -EIO;
+ if (register_netdev(&thisDepca) != 0)
+ return -EIO;
- return 0;
+ return 0;
}
-void cleanup_module(void)
+void
+cleanup_module(void)
{
- if (thisDepca.priv) {
- kfree(thisDepca.priv);
- thisDepca.priv = NULL;
- }
- thisDepca.irq = 0;
-
- unregister_netdev(&thisDepca);
- release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
+ struct depca_private *lp = thisDepca.priv;
+ if (lp) {
+#ifdef CONFIG_MCA
+ if(lp->mca_slot != -1)
+ mca_mark_as_unused(lp->mca_slot);
+#endif
+ kfree(lp);
+ thisDepca.priv = NULL;
+ }
+ thisDepca.irq=0;
+
+ unregister_netdev(&thisDepca);
+ release_region(thisDepca.base_addr, DEPCA_TOTAL_SIZE);
}
-#endif /* MODULE */
-
+#endif /* MODULE */
+
/*
* Local variables:
* compile-command: "gcc -D__KERNEL__ -I/linux/include -Wall -Wstrict-prototypes -fomit-frame-pointer -fno-strength-reduce -malign-loops=2 -malign-jumps=2 -malign-functions=2 -O2 -m486 -c depca.c"
diff --git a/drivers/net/dummy.c b/drivers/net/dummy.c
index 4367f476f..8d4ea3b05 100644
--- a/drivers/net/dummy.c
+++ b/drivers/net/dummy.c
@@ -99,7 +99,7 @@ __initfunc(int dummy_init(struct device *dev))
ether_setup(dev);
dev->tx_queue_len = 0;
dev->flags |= IFF_NOARP;
- dev->flags &= ~(IFF_BROADCAST|IFF_MULTICAST);
+ dev->flags &= ~IFF_MULTICAST;
#ifdef CONFIG_NET_FASTROUTE
dev->accept_fastpath = dummy_accept_fastpath;
#endif
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index 37d4df7f9..14354fd1a 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -1,13 +1,13 @@
/* drivers/net/eepro100.c: An Intel i82557 Ethernet driver for Linux. */
/*
NOTICE: this version tested with kernels 1.3.72 and later only!
- Written 1996-1997 by Donald Becker.
+ Written 1996-1998 by Donald Becker.
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
This driver is for the Intel EtherExpress Pro 100B boards.
- It should work with other i82557 boards (if any others exist).
+ It should work with other i82557 and i82558 boards.
To use a built-in driver, install as drivers/net/eepro100.c.
To use as a module, use the compile-command at the end of the file.
@@ -15,11 +15,13 @@
Center of Excellence in Space Data and Information Sciences
Code 930.5, NASA Goddard Space Flight Center, Greenbelt MD 20771
For updates see
- <base href="http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html">
+ http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html
+ There is also a mailing list based at
+ linux-eepro100@cesdis.gsfc.nasa.gov
*/
static const char *version =
-"eepro100.c:v0.36 10/20/97 Donald Becker linux-eepro100@cesdis.gsfc.nasa.gov\n";
+"eepro100.c:v1.06 10/16/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n";
/* A few user-configurable values that apply to all boards.
First set are undocumented and spelled per Intel recommendations. */
@@ -33,125 +35,60 @@ static int rxdmacount = 0;
/* Set the copy breakpoint for the copy-only-tiny-buffer Rx method.
Lower values use more memory, but are faster. */
-/*
- * NOTE! The value of 2000 means that this optimization never gets
- * used. Rationale: it seems to be broken when in low-memory situations,
- * apparently when alloc_skb() can return NULL the clever list of
- * copy-buffers can get buggered.
- *
- * My personal suspicion is that the allocation failure will cause
- * us to not remove the skb from the list of available buffers, but
- * we'd already have done a "skb_push()" with the data we got, so
- * the buffer stays on the list but the available memory in it
- * shrinks until we panic.
- *
- * Donald, when you fix this you can shrink this value again.
- *
- * Linus
- */
-static int rx_copybreak = 2000;
+static int rx_copybreak = 200;
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
static int max_interrupt_work = 200;
-#ifdef MODULE
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast) */
+static int multicast_filter_limit = 64;
+
#include <linux/module.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
#include <linux/version.h>
#include <linux/kernel.h>
-#include <linux/sched.h>
#include <linux/string.h>
#include <linux/timer.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <linux/delay.h>
-#include <asm/processor.h> /* Processor type for cache alignment. */
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-
-/* A nominally proper method to handle version dependencies is to use
- LINUX_VERSION_CODE in version.h, but that triggers recompiles w/'make'. */
-#define VERSION(v,p,s) (((v)<<16)+(p<<8)+s)
-#ifdef MODULE
-#if (LINUX_VERSION_CODE < VERSION(1,3,0))
-#define KERNEL_1_2
-#else /* 1.3.0 */
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
-#define NEW_MULTICAST
-#define LINUX_1_4
-#else
-#warning "This driver is tested for 1.3.44 and later development kernels only."
-#endif /* 1.3.44 */
-#endif
-#else
-
-#if (LINUX_VERSION_CODE >= 0x10344)
-#define NEW_MULTICAST
#include <linux/delay.h>
-#endif
-#ifdef HAVE_HEADER_CACHE
-#define LINUX_1_4
-#define NEW_MULTICAST
-#else
-#ifdef ETH_P_DDCMP /* Warning: Bogus! This means IS_LINUX_1_3. */
-#define KERNEL_1_3
-#else
-#define KERNEL_1_2
-#endif
-#endif
+#include <asm/spinlock.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+/*
+ * Module documentation
+ */
+MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
+MODULE_DESCRIPTION("Intel i82557/i82558 PCI EtherExpressPro driver");
+MODULE_PARM(debug, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(congenb, "i");
+MODULE_PARM(txfifo, "i");
+MODULE_PARM(rxfifo, "i");
+MODULE_PARM(txdmacount, "i");
+MODULE_PARM(rxdmacount, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(multicast_filter_limit, "i");
-#endif
-/* This should be in a header file. */
-#if (LINUX_VERSION_CODE < VERSION(1,3,44))
-struct device *init_etherdev(struct device *dev, int sizeof_priv,
- unsigned long *mem_startp);
-#endif
-#if LINUX_VERSION_CODE < 0x10300
-#define RUN_AT(x) (x) /* What to put in timer->expires. */
-#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC)
-#define virt_to_bus(addr) ((unsigned long)addr)
-#define bus_to_virt(addr) ((void*)addr)
-#else /* 1.3.0 and later */
#define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
-#endif
-#if (LINUX_VERSION_CODE < 0x20123)
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#include <linux/bios32.h>
-#endif
+#define dev_free_skb(skb) dev_kfree_skb(skb);
-/* The total I/O port extent of the board. Nominally 0x18, but rounded up
- for PCI allocation. */
+/* The total I/O port extent of the board.
+ The registers beyond 0x18 only exist on the i82558. */
#define SPEEDO3_TOTAL_SIZE 0x20
-#ifdef HAVE_DEVLIST
-struct netdev_entry eepro100_drv =
-{"EEPro-100", eepro100_init, SPEEDO3_TOTAL_SIZE, NULL};
-#endif
-
-#ifdef SPEEDO3_DEBUG
-int speedo_debug = SPEEDO3_DEBUG;
-#else
-int speedo_debug = 3;
-#endif
+int speedo_debug = 0;
/*
Theory of Operation
@@ -183,7 +120,7 @@ single buffer descriptor with each frame descriptor.
Despite the extra space overhead in each receive skbuff, the driver must use
the simplified Rx buffer mode to assure that only a single data buffer is
associated with each RxFD. The driver implements this by reserving space
-for the Rx descriptor at the head of each Rx skbuff
+for the Rx descriptor at the head of each Rx skbuff.
The Speedo-3 has receive and command unit base addresses that are added to
almost all descriptor pointers. The driver sets these to zero, so that all
@@ -198,10 +135,13 @@ IIIB. Transmit structure
The driver must use the complex Tx command+descriptor mode in order to
have a indirect pointer to the skbuff data section. Each Tx command block
-(TxCB) is associated with a single, immediately appended Tx buffer descriptor
+(TxCB) is associated with two immediately appended Tx Buffer Descriptor
(TxBD). A fixed ring of these TxCB+TxBD pairs are kept as part of the
speedo_private data structure for each adapter instance.
+The newer i82558 explicitly supports this structure, and can read the two
+TxBDs in the same PCI burst as the TxCB.
+
This ring structure is used for all normal transmit packets, but the
transmit packet descriptors aren't long enough for most non-Tx commands such
as CmdConfigure. This is complicated by the possibility that the chip has
@@ -290,26 +230,19 @@ having to sign an Intel NDA when I'm helping Intel sell their own product!
#define PKT_BUF_SZ 1536
/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT ((400*HZ)/1000)
+#define TX_TIMEOUT ((800*HZ)/1000)
/* How to wait for the command unit to accept a command.
Typically this takes 0 ticks. */
-static inline void wait_for_cmd_done(int cmd_ioaddr)
+static inline void wait_for_cmd_done(long cmd_ioaddr)
{
- short wait = 100;
- do ;
- while(inb(cmd_ioaddr) && --wait >= 0);
+ int wait = 100;
+ do ;
+ while(inb(cmd_ioaddr) && --wait >= 0);
}
/* Operational parameter that usually are not changed. */
-#ifndef PCI_VENDOR_ID_INTEL /* Now defined in linux/pci.h */
-#define PCI_VENDOR_ID_INTEL 0x8086 /* Hmmmm, how did they pick that? */
-#endif
-#ifndef PCI_DEVICE_ID_INTEL_82557
-#define PCI_DEVICE_ID_INTEL_82557 0x1229
-#endif
-
/* The rest of these values should never change. */
/* Offsets to the various registers.
@@ -364,17 +297,24 @@ struct RxFD { /* Receive frame descriptor. */
u16 size;
};
-/* Elements of the RxFD.status word. */
-#define RX_COMPLETE 0x8000
+/* Selected elements of the Tx/RxFD.status word. */
+enum RxFD_bits {
+ RxComplete=0x8000, RxOK=0x2000,
+ RxErrCRC=0x0800, RxErrAlign=0x0400, RxErrTooBig=0x0200, RxErrSymbol=0x0010,
+ RxEth2Type=0x0020, RxNoMatch=0x0004, RxNoIAMatch=0x0002,
+ StatusComplete=0x8000,
+};
struct TxFD { /* Transmit frame descriptor set. */
s32 status;
u32 link; /* void * */
u32 tx_desc_addr; /* Always points to the tx_buf_addr element. */
s32 count; /* # of TBD (=1), Tx start thresh., etc. */
- /* This constitutes a single "TBD" entry -- we only use one. */
- u32 tx_buf_addr; /* void *, frame to be transmitted. */
- s32 tx_buf_size; /* Length of Tx frame. */
+ /* This constitutes two "TBD" entries -- we only use one. */
+ u32 tx_buf_addr0; /* void *, frame to be transmitted. */
+ s32 tx_buf_size0; /* Length of Tx frame. */
+ u32 tx_buf_addr1; /* void *, frame to be transmitted. */
+ s32 tx_buf_size1; /* Length of Tx frame. */
};
/* Elements of the dump_statistics block. This block must be lword aligned. */
@@ -402,6 +342,7 @@ struct speedo_private {
char devname[8]; /* Used only for kernel debugging. */
const char *product_name;
struct device *next_module;
+ spinlock_t lock;
struct TxFD tx_ring[TX_RING_SIZE]; /* Commands (usually CmdTxPacket). */
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[TX_RING_SIZE];
@@ -409,9 +350,6 @@ struct speedo_private {
/* Rx descriptor ring & addresses of receive-in-place skbuffs. */
struct RxFD *rx_ringp[RX_RING_SIZE];
struct sk_buff* rx_skbuff[RX_RING_SIZE];
-#if (LINUX_VERSION_CODE < 0x10300) /* Kernel v1.2.*. */
- struct RxFD saved_skhead[RX_RING_SIZE]; /* Saved skbuff header chunk. */
-#endif
struct RxFD *last_rxf; /* Last command sent. */
struct enet_statistics stats;
struct speedo_stats lstats;
@@ -419,10 +357,9 @@ struct speedo_private {
long last_rx_time; /* Last Rx, in jiffies, to handle Rx hang. */
unsigned int cur_rx, cur_tx; /* The next free ring entry */
unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
- struct descriptor config_cmd; /* A configure command, with header... */
- u8 config_cmd_data[22]; /* .. and setup parameters. */
int mc_setup_frm_len; /* The length of an allocated.. */
struct descriptor *mc_setup_frm; /* ..multicast setup frame. */
+ int mc_setup_busy; /* Avoid double-use of setup frame. */
char rx_mode; /* Current PROMISC/ALLMULTI setting. */
unsigned int tx_full:1; /* The Tx queue is full. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
@@ -436,11 +373,16 @@ struct speedo_private {
/* The parameters for a CmdConfigure operation.
There are so many options that it would be difficult to document each bit.
We mostly use the default or recommended settings. */
-const char basic_config_cmd[22] = {
+const char i82557_config_cmd[22] = {
22, 0x08, 0, 0, 0, 0x80, 0x32, 0x03, 1, /* 1=Use MII 0=Use AUI */
0, 0x2E, 0, 0x60, 0,
0xf2, 0x48, 0, 0x40, 0xf2, 0x80, /* 0x40=Force full-duplex */
0x3f, 0x05, };
+const char i82558_config_cmd[22] = {
+ 22, 0x08, 0, 1, 0, 0x80, 0x22, 0x03, 1, /* 1=Use MII 0=Use AUI */
+ 0, 0x2E, 0, 0x60, 0x08, 0x88,
+ 0x68, 0, 0x40, 0xf2, 0xBD, /* 0xBD->0xFD=Force full-duplex */
+ 0x31, 0x05, };
/* PHY media interface chips. */
static const char *phys[] = {
@@ -452,12 +394,12 @@ enum phy_chips { NonSuchPhy=0, I82553AB, I82553C, I82503, DP83840, S80C240,
S80C24, I82555, DP83840A=10, };
static const char is_mii[] = { 0, 1, 1, 0, 1, 1, 0, 1 };
-static void speedo_found1(struct device *dev, int ioaddr, int irq,
- int options, int card_idx);
+static void speedo_found1(struct device *dev, long ioaddr, int irq,
+ int card_idx);
-static int read_eeprom(int ioaddr, int location);
-static int mdio_read(int ioaddr, int phy_id, int location);
-static int mdio_write(int ioaddr, int phy_id, int location, int value);
+static int read_eeprom(long ioaddr, int location, int addr_len);
+static int mdio_read(long ioaddr, int phy_id, int location);
+static int mdio_write(long ioaddr, int phy_id, int location, int value);
static int speedo_open(struct device *dev);
static void speedo_timer(unsigned long data);
static void speedo_init_rx_ring(struct device *dev);
@@ -466,9 +408,7 @@ static int speedo_rx(struct device *dev);
static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static int speedo_close(struct device *dev);
static struct enet_statistics *speedo_get_stats(struct device *dev);
-#ifdef HAVE_PRIVATE_IOCTL
static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd);
-#endif
static void set_rx_mode(struct device *dev);
@@ -477,109 +417,101 @@ static void set_rx_mode(struct device *dev);
/* 'options' is used to pass a transceiver override or full-duplex flag
e.g. "options=16" for FD, "options=32" for 100mbps-only. */
static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-#ifdef MODULE
static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
+#ifdef MODULE
static int debug = -1; /* The debug level */
#endif
+#ifdef honor_default_port
+/* Optional driver feature to allow forcing the transceiver setting.
+ Not recommended. */
+static int mii_ctrl[8] = { 0x3300, 0x3100, 0x0000, 0x0100,
+ 0x2000, 0x2100, 0x0400, 0x3100};
+#endif
+
/* A list of all installed Speedo devices, for removing the driver module. */
static struct device *root_speedo_dev = NULL;
int eepro100_init(struct device *dev)
{
int cards_found = 0;
+ static int pci_index = 0;
- if (pci_present()) {
- static int pci_index = 0;
+ if (! pcibios_present())
+ return cards_found;
- for (; pci_index < 8; pci_index++) {
- unsigned char pci_bus, pci_device_fn, pci_latency;
-#if (LINUX_VERSION_CODE >= VERSION(2,1,85))
- unsigned int pci_irq_line;
- struct pci_dev *pdev;
-#else
- unsigned char pci_irq_line;
-#endif
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
- int pci_ioaddr;
-#else
- long pci_ioaddr;
-#endif
- unsigned short pci_command;
-
- if (pcibios_find_device(PCI_VENDOR_ID_INTEL,
- PCI_DEVICE_ID_INTEL_82557,
- pci_index, &pci_bus,
- &pci_device_fn))
- break;
-#if (LINUX_VERSION_CODE >= VERSION(2,1,85))
- pdev = pci_find_slot(pci_bus, pci_device_fn);
- pci_irq_line = pdev->irq;
- pci_ioaddr = pdev->base_address[1];
-#else
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_INTERRUPT_LINE, &pci_irq_line);
- /* Note: BASE_ADDRESS_0 is for memory-mapping the registers. */
- pcibios_read_config_dword(pci_bus, pci_device_fn,
- PCI_BASE_ADDRESS_1, &pci_ioaddr);
-#endif
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
- if (speedo_debug > 2)
- printk("Found Intel i82557 PCI Speedo at I/O %#x, IRQ %d.\n",
- (int)pci_ioaddr, pci_irq_line);
-
- /* Get and check the bus-master and latency values. */
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
- if ( ! (pci_command & PCI_COMMAND_MASTER)) {
- printk(" PCI Master Bit has not been set! Setting...\n");
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, pci_command);
- }
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, &pci_latency);
- if (pci_latency < 10) {
- printk(" PCI latency timer (CFLT) is unreasonably low at %d."
- " Setting to 255 clocks.\n", pci_latency);
- pcibios_write_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, 255);
- } else if (speedo_debug > 1)
- printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency);
+ for (; pci_index < 8; pci_index++) {
+ unsigned char pci_bus, pci_device_fn, pci_latency;
+ long ioaddr;
+ int irq;
-#ifdef MODULE
- speedo_found1(dev, pci_ioaddr, pci_irq_line, options[cards_found],
- cards_found);
-#else
- speedo_found1(dev, pci_ioaddr, pci_irq_line,
- dev ? dev->mem_start : 0, -1);
-#endif
- dev = NULL;
- cards_found++;
+ u16 pci_command, new_command;
+
+ if (pcibios_find_device(PCI_VENDOR_ID_INTEL,
+ PCI_DEVICE_ID_INTEL_82557,
+ pci_index, &pci_bus,
+ &pci_device_fn))
+ break;
+ {
+ struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
+ ioaddr = pdev->base_address[1]; /* Use [0] to mem-map */
+ irq = pdev->irq;
+ }
+ /* Remove I/O space marker in bit 0. */
+ ioaddr &= ~3;
+ if (speedo_debug > 2)
+ printk("Found Intel i82557 PCI Speedo at I/O %#lx, IRQ %d.\n",
+ ioaddr, irq);
+
+ /* Get and check the bus-master and latency values. */
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, &pci_command);
+ new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+ if (pci_command != new_command) {
+ printk(KERN_INFO " The PCI BIOS has not enabled this"
+ " device! Updating PCI command %4.4x->%4.4x.\n",
+ pci_command, new_command);
+ pcibios_write_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, new_command);
}
+ pcibios_read_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, &pci_latency);
+ if (pci_latency < 32) {
+ printk(" PCI latency timer (CFLT) is unreasonably low at %d."
+ " Setting to 32 clocks.\n", pci_latency);
+ pcibios_write_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, 32);
+ } else if (speedo_debug > 1)
+ printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency);
+
+ speedo_found1(dev, ioaddr, irq, cards_found);
+ dev = NULL;
+ cards_found++;
}
return cards_found;
}
-static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
+static void speedo_found1(struct device *dev, long ioaddr, int irq,
int card_idx)
{
static int did_version = 0; /* Already printed version info. */
struct speedo_private *sp;
char *product;
- int i;
+ int i, option;
u16 eeprom[0x40];
if (speedo_debug > 0 && did_version++ == 0)
printk(version);
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
dev = init_etherdev(dev, sizeof(struct speedo_private));
-#else
- dev = init_etherdev(dev, sizeof(struct speedo_private), 0);
-#endif
+
+ if (dev->mem_start > 0)
+ option = dev->mem_start;
+ else if (card_idx >= 0 && options[card_idx] >= 0)
+ option = options[card_idx];
+ else
+ option = 0;
/* Read the station address EEPROM before doing the reset.
Perhaps this should even be done before accepting the device,
@@ -587,8 +519,10 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
{
u16 sum = 0;
int j;
+ int addr_len = read_eeprom(ioaddr, 0, 6) == 0xffff ? 8 : 6;
+
for (j = 0, i = 0; i < 0x40; i++) {
- u16 value = read_eeprom(ioaddr, i);
+ u16 value = read_eeprom(ioaddr, i, addr_len);
eeprom[i] = value;
sum += value;
if (i < 3) {
@@ -614,7 +548,7 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
else
product = "Intel EtherExpress Pro 10/100";
- printk(KERN_INFO "%s: %s at %#3x, ", dev->name, product, ioaddr);
+ printk(KERN_INFO "%s: %s at %#3lx, ", dev->name, product, ioaddr);
for (i = 0; i < 5; i++)
printk("%2.2X:", dev->dev_addr[i]);
@@ -643,17 +577,6 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
if (eeprom[7] & 0x0700)
printk(KERN_INFO " Secondary interface chip %s.\n",
phys[(eeprom[7]>>8)&7]);
-#if defined(notdef)
- /* ToDo: Read and set PHY registers through MDIO port. */
- for (i = 0; i < 2; i++)
- printk(KERN_INFO" MDIO register %d is %4.4x.\n",
- i, mdio_read(ioaddr, eeprom[6] & 0x1f, i));
- for (i = 5; i < 7; i++)
- printk(KERN_INFO" MDIO register %d is %4.4x.\n",
- i, mdio_read(ioaddr, eeprom[6] & 0x1f, i));
- printk(KERN_INFO" MDIO register %d is %4.4x.\n",
- 25, mdio_read(ioaddr, eeprom[6] & 0x1f, 25));
-#endif
if (((eeprom[6]>>8) & 0x3f) == DP83840
|| ((eeprom[6]>>8) & 0x3f) == DP83840A) {
int mdi_reg23 = mdio_read(ioaddr, eeprom[6] & 0x1f, 23) | 0x0422;
@@ -663,13 +586,13 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
mdi_reg23);
mdio_write(ioaddr, eeprom[6] & 0x1f, 23, mdi_reg23);
}
- if ((options >= 0) && (options & 0x60)) {
+ if ((option >= 0) && (option & 0x70)) {
printk(KERN_INFO " Forcing %dMbs %s-duplex operation.\n",
- (options & 0x20 ? 100 : 10),
- (options & 0x10 ? "full" : "half"));
+ (option & 0x20 ? 100 : 10),
+ (option & 0x10 ? "full" : "half"));
mdio_write(ioaddr, eeprom[6] & 0x1f, 0,
- ((options & 0x20) ? 0x2000 : 0) | /* 100mbps? */
- ((options & 0x10) ? 0x0100 : 0)); /* Full duplex? */
+ ((option & 0x20) ? 0x2000 : 0) | /* 100mbps? */
+ ((option & 0x10) ? 0x0100 : 0)); /* Full duplex? */
}
/* Perform a system self-test. */
@@ -678,11 +601,7 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
self_test_results[1] = -1;
outl(virt_to_bus(self_test_results) | 1, ioaddr + SCBPort);
do {
-#ifdef _LINUX_DELAY_H
udelay(10);
-#else
- SLOW_DOWN_IO;
-#endif
} while (self_test_results[1] == -1 && --boguscnt >= 0);
if (boguscnt < 0) { /* Test optimized out. */
@@ -704,8 +623,6 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
}
#endif /* kernel_bloat */
- outl(0, ioaddr + SCBPort);
-
/* We do a request_region() only to register /proc/ioports info. */
request_region(ioaddr, SPEEDO3_TOTAL_SIZE, "Intel Speedo3 Ethernet");
@@ -719,12 +636,12 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
sp->next_module = root_speedo_dev;
root_speedo_dev = dev;
+ sp->full_duplex = option >= 0 && (option & 0x10) ? 1 : 0;
if (card_idx >= 0) {
if (full_duplex[card_idx] >= 0)
sp->full_duplex = full_duplex[card_idx];
- } else
- sp->full_duplex = options >= 0 && (options & 0x10) ? 1 : 0;
- sp->default_port = options >= 0 ? (options & 0x0f) : 0;
+ }
+ sp->default_port = option >= 0 ? (option & 0x0f) : 0;
sp->phy[0] = eeprom[6];
sp->phy[1] = eeprom[7];
@@ -738,12 +655,8 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
dev->hard_start_xmit = &speedo_start_xmit;
dev->stop = &speedo_close;
dev->get_stats = &speedo_get_stats;
-#ifdef NEW_MULTICAST
dev->set_multicast_list = &set_rx_mode;
-#endif
-#ifdef HAVE_PRIVATE_IOCTL
dev->do_ioctl = &speedo_ioctl;
-#endif
return;
}
@@ -760,38 +673,31 @@ static void speedo_found1(struct device *dev, int ioaddr, int irq, int options,
#define EE_ENB (0x4800 | EE_CS)
/* Delay between EEPROM clock transitions.
- This is a "nasty" timing loop, but PC compatible machines are defined
- to delay an ISA compatible period for the SLOW_DOWN_IO macro. */
-#ifdef _LINUX_DELAY_H
+ This will actually work with no delay on 33Mhz PCI. */
#define eeprom_delay(nanosec) udelay(1);
-#else
-#define eeprom_delay(nanosec) do { int _i = 3; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
-#endif
/* The EEPROM commands include the alway-set leading bit. */
-#define EE_WRITE_CMD (5 << 6)
-#define EE_READ_CMD (6 << 6)
-#define EE_ERASE_CMD (7 << 6)
+#define EE_WRITE_CMD (5 << addr_len)
+#define EE_READ_CMD (6 << addr_len)
+#define EE_ERASE_CMD (7 << addr_len)
-static int read_eeprom(int ioaddr, int location)
+static int read_eeprom(long ioaddr, int location, int addr_len)
{
- int i;
unsigned short retval = 0;
int ee_addr = ioaddr + SCBeeprom;
int read_cmd = location | EE_READ_CMD;
+ int i;
outw(EE_ENB & ~EE_CS, ee_addr);
outw(EE_ENB, ee_addr);
/* Shift the read command bits out. */
- for (i = 10; i >= 0; i--) {
+ for (i = 12; i >= 0; i--) {
short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
outw(EE_ENB | dataval, ee_addr);
eeprom_delay(100);
outw(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
eeprom_delay(150);
- outw(EE_ENB | dataval, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay(250);
}
outw(EE_ENB, ee_addr);
@@ -808,16 +714,11 @@ static int read_eeprom(int ioaddr, int location)
return retval;
}
-static int mdio_read(int ioaddr, int phy_id, int location)
+static int mdio_read(long ioaddr, int phy_id, int location)
{
- int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
+ int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */
outl(0x08000000 | (location<<16) | (phy_id<<21), ioaddr + SCBCtrlMDI);
do {
-#ifdef _LINUX_DELAY_H
- udelay(16);
-#else
- SLOW_DOWN_IO;
-#endif
val = inl(ioaddr + SCBCtrlMDI);
if (--boguscnt < 0) {
printk(KERN_ERR " mdio_read() timed out with val = %8.8x.\n", val);
@@ -826,17 +727,12 @@ static int mdio_read(int ioaddr, int phy_id, int location)
return val & 0xffff;
}
-static int mdio_write(int ioaddr, int phy_id, int location, int value)
+static int mdio_write(long ioaddr, int phy_id, int location, int value)
{
- int val, boguscnt = 64*4; /* <64 usec. to complete, typ 27 ticks */
+ int val, boguscnt = 64*10; /* <64 usec. to complete, typ 27 ticks */
outl(0x04000000 | (location<<16) | (phy_id<<21) | value,
ioaddr + SCBCtrlMDI);
do {
-#ifdef _LINUX_DELAY_H
- udelay(16);
-#else
- SLOW_DOWN_IO;
-#endif
val = inl(ioaddr + SCBCtrlMDI);
if (--boguscnt < 0) {
printk(KERN_ERR" mdio_write() timed out with val = %8.8x.\n", val);
@@ -850,24 +746,38 @@ static int
speedo_open(struct device *dev)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
#ifdef notdef
/* We could reset the chip, but should not need to. */
+ /* In fact we MUST NOT, unless we also re-do the init */
outl(0, ioaddr + SCBPort);
- for (i = 40; i >= 0; i--)
- SLOW_DOWN_IO; /* At least 250ns */
+ udelay(10);
#endif
- if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ,
- "Intel EtherExpress Pro 10/100 Ethernet", dev)) {
- return -EAGAIN;
- }
+ /* This had better be initialized before we initialize the interrupt! */
+ sp->lock = (spinlock_t) SPIN_LOCK_UNLOCKED;
if (speedo_debug > 1)
printk(KERN_DEBUG "%s: speedo_open() irq %d.\n", dev->name, dev->irq);
- MOD_INC_USE_COUNT;
+#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us
+ /* Retrigger negotiation to reset previous errors. */
+ if ((sp->phy[0] & 0x8000) == 0) {
+ int phy_addr = sp->phy[0] & 0x1f ;
+ /* Use 0x3300 for restarting NWay, other values to force xcvr:
+ 0x0000 10-HD
+ 0x0100 10-FD
+ 0x2000 100-HD
+ 0x2100 100-FD
+ */
+#ifdef honor_default_port
+ mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]);
+#else
+ mdio_write(ioaddr, phy_addr, 0, 0x3300);
+#endif
+ }
+#endif
/* Load the statistics block address. */
wait_for_cmd_done(ioaddr + SCBCmd);
@@ -921,6 +831,7 @@ speedo_open(struct device *dev)
/* Setup the chip and configure the multicast list. */
sp->mc_setup_frm = NULL;
sp->mc_setup_frm_len = 0;
+ sp->mc_setup_busy = 0;
sp->rx_mode = -1; /* Invalid -> always reset the mode. */
set_rx_mode(dev);
@@ -928,6 +839,24 @@ speedo_open(struct device *dev)
printk(KERN_DEBUG "%s: Done speedo_open(), status %8.8x.\n",
dev->name, inw(ioaddr + SCBStatus));
}
+
+ wait_for_cmd_done(ioaddr + SCBCmd);
+ outw(CU_DUMPSTATS, ioaddr + SCBCmd);
+ /* No need to wait for the command unit to accept here. */
+ if ((sp->phy[0] & 0x8000) == 0)
+ mdio_read(ioaddr, sp->phy[0] & 0x1f, 0);
+
+ /*
+ * Request the IRQ last, after we have set up all data structures.
+ * It would be bad to get an interrupt before we're ready.
+ */
+ if (request_irq(dev->irq, &speedo_interrupt, SA_SHIRQ,
+ "Intel EtherExpress Pro 10/100 Ethernet", dev)) {
+ return -EAGAIN;
+ }
+
+ MOD_INC_USE_COUNT;
+
/* Set the timer. The timer serves a dual purpose:
1) to monitor the media interface (e.g. link beat) and perhaps switch
to an alternate media type
@@ -939,8 +868,6 @@ speedo_open(struct device *dev)
sp->timer.function = &speedo_timer; /* timer handler */
add_timer(&sp->timer);
- wait_for_cmd_done(ioaddr + SCBCmd);
- outw(CU_DUMPSTATS, ioaddr + SCBCmd);
return 0;
}
@@ -949,24 +876,22 @@ static void speedo_timer(unsigned long data)
{
struct device *dev = (struct device *)data;
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int tickssofar = jiffies - sp->last_rx_time;
if (speedo_debug > 3) {
- int ioaddr = dev->base_addr;
- printk(KERN_DEBUG "%s: Media selection tick, status %4.4x.\n",
+ long ioaddr = dev->base_addr;
+ printk(KERN_DEBUG "%s: Media control tick, status %4.4x.\n",
dev->name, inw(ioaddr + SCBStatus));
}
- if (sp->rx_bug) {
- if (tickssofar > 2*HZ || sp->rx_mode < 0) {
- /* We haven't received a packet in a Long Time. We might have been
- bitten by the receiver hang bug. This can be cleared by sending
- a set multicast list command. */
- set_rx_mode(dev);
- }
- /* We must continue to monitor the media. */
- sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */
- add_timer(&sp->timer);
+ if (sp->rx_mode < 0 ||
+ (sp->rx_bug && jiffies - sp->last_rx_time > 2*HZ)) {
+ /* We haven't received a packet in a Long Time. We might have been
+ bitten by the receiver hang bug. This can be cleared by sending
+ a set multicast list command. */
+ set_rx_mode(dev);
}
+ /* We must continue to monitor the media. */
+ sp->timer.expires = RUN_AT(2*HZ); /* 2.0 sec. */
+ add_timer(&sp->timer);
}
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
@@ -978,43 +903,32 @@ speedo_init_rx_ring(struct device *dev)
int i;
sp->cur_rx = 0;
- sp->dirty_rx = RX_RING_SIZE - 1;
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
-#ifndef KERNEL_1_2
skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
-#else
- skb = alloc_skb(PKT_BUF_SZ, GFP_ATOMIC);
-#endif
sp->rx_skbuff[i] = skb;
if (skb == NULL)
- break; /* Bad news! */
+ break; /* OK. Just initially short of Rx bufs. */
skb->dev = dev; /* Mark as being used by this device. */
-
-#if LINUX_VERSION_CODE >= 0x10300
rxf = (struct RxFD *)skb->tail;
- skb_reserve(skb, sizeof(struct RxFD));
-#else
- /* Save the data in the header region -- it's restored later. */
- rxf = (struct RxFD *)(skb->data - sizeof(struct RxFD));
- memcpy(&sp->saved_skhead[i], rxf, sizeof(struct RxFD));
-#endif
sp->rx_ringp[i] = rxf;
+ skb_reserve(skb, sizeof(struct RxFD));
if (last_rxf)
last_rxf->link = virt_to_bus(rxf);
last_rxf = rxf;
rxf->status = 0x00000001; /* '1' is flag value only. */
rxf->link = 0; /* None yet. */
-#if LINUX_VERSION_CODE < 0x10300
/* This field unused by i82557, we use it as a consistency check. */
- rxf->rx_buf_addr = virt_to_bus(skb->data);
+#ifdef final_version
+ rxf->rx_buf_addr = 0xffffffff;
#else
rxf->rx_buf_addr = virt_to_bus(skb->tail);
#endif
rxf->count = 0;
rxf->size = PKT_BUF_SZ;
}
+ sp->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
/* Mark the last entry as end-of-list. */
last_rxf->status = 0xC0000002; /* '2' is flag value only. */
sp->last_rxf = last_rxf;
@@ -1023,40 +937,35 @@ speedo_init_rx_ring(struct device *dev)
static void speedo_tx_timeout(struct device *dev)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
+ long ioaddr = dev->base_addr;
printk(KERN_WARNING "%s: Transmit timed out: status %4.4x "
- "command %4.4x.\n",
- dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd));
-#ifndef final_version
- printk(KERN_WARNING "%s: Tx timeout fill index %d scavenge index %d.\n",
- dev->name, sp->cur_tx, sp->dirty_tx);
- printk(KERN_WARNING " Tx queue ");
- for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %8.8x", (int)sp->tx_ring[i].status);
- printk(".\n" KERN_WARNING " Rx ring ");
- for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", (int)sp->rx_ringp[i]->status);
- printk(".\n");
-
-#else
- dev->if_port ^= 1;
- printk(KERN_WARNING " (Media type switching not yet implemented.)\n");
- /* Do not do 'dev->tbusy = 0;' there -- it is incorrect. */
-#endif
+ " %4.4x at %d/%d command %8.8x.\n",
+ dev->name, inw(ioaddr + SCBStatus), inw(ioaddr + SCBCmd),
+ sp->dirty_tx, sp->cur_tx,
+ sp->tx_ring[sp->dirty_tx % TX_RING_SIZE].status);
if ((inw(ioaddr + SCBStatus) & 0x00C0) != 0x0080) {
- printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
- dev->name);
- outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]),
- ioaddr + SCBPointer);
- outw(CU_START, ioaddr + SCBCmd);
+ printk(KERN_WARNING "%s: Trying to restart the transmitter...\n",
+ dev->name);
+ outl(virt_to_bus(&sp->tx_ring[sp->dirty_tx % TX_RING_SIZE]),
+ ioaddr + SCBPointer);
+ outw(CU_START, ioaddr + SCBCmd);
} else {
- outw(DRVR_INT, ioaddr + SCBCmd);
+ outw(DRVR_INT, ioaddr + SCBCmd);
}
- /* Reset the MII transceiver. */
- if ((sp->phy[0] & 0x8000) == 0)
- mdio_write(ioaddr, sp->phy[0] & 0x1f, 0, 0x8000);
+#ifdef oh_no_you_dont_unless_you_honour_the_options_passed_in_to_us
+ /* Reset the MII transceiver, suggested by Fred Young @ scalable.com. */
+ if ((sp->phy[0] & 0x8000) == 0) {
+ int phy_addr = sp->phy[0] & 0x1f;
+ mdio_write(ioaddr, phy_addr, 0, 0x0400);
+ mdio_write(ioaddr, phy_addr, 1, 0x0000);
+ mdio_write(ioaddr, phy_addr, 4, 0x0000);
+ mdio_write(ioaddr, phy_addr, 0, 0x8000);
+#ifdef honor_default_port
+ mdio_write(ioaddr, phy_addr, 0, mii_ctrl[dev->default_port & 7]);
+#endif
+ }
+#endif
sp->stats.tx_errors++;
dev->trans_start = jiffies;
return;
@@ -1066,7 +975,7 @@ static int
speedo_start_xmit(struct sk_buff *skb, struct device *dev)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
int entry;
/* Block a timer-based transmit from overlapping. This could better be
@@ -1082,7 +991,7 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev)
return 1;
}
speedo_tx_timeout(dev);
- return 0;
+ return 1;
}
/* Caution: the write order is important here, set the base address
@@ -1091,8 +1000,8 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev)
{ /* Prevent interrupts from changing the Tx ring from underneath us. */
unsigned long flags;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sp->lock, flags);
+
/* Calculate the Tx descriptor entry. */
entry = sp->cur_tx++ % TX_RING_SIZE;
@@ -1103,29 +1012,31 @@ speedo_start_xmit(struct sk_buff *skb, struct device *dev)
sp->tx_ring[entry].link =
virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]);
sp->tx_ring[entry].tx_desc_addr =
- virt_to_bus(&sp->tx_ring[entry].tx_buf_addr);
+ virt_to_bus(&sp->tx_ring[entry].tx_buf_addr0);
/* The data region is always in one buffer descriptor, Tx FIFO
threshold of 256. */
sp->tx_ring[entry].count = 0x01208000;
- sp->tx_ring[entry].tx_buf_addr = virt_to_bus(skb->data);
- sp->tx_ring[entry].tx_buf_size = skb->len;
+ sp->tx_ring[entry].tx_buf_addr0 = virt_to_bus(skb->data);
+ sp->tx_ring[entry].tx_buf_size0 = skb->len;
/* Todo: perhaps leave the interrupt bit set if the Tx queue is more
than half full. Argument against: we should be receiving packets
and scavenging the queue. Argument for: if so, it shouldn't
matter. */
sp->last_cmd->command &= ~(CmdSuspend | CmdIntr);
sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
/* Trigger the command unit resume. */
wait_for_cmd_done(ioaddr + SCBCmd);
outw(CU_RESUME, ioaddr + SCBCmd);
- restore_flags(flags);
+
+ spin_unlock_irqrestore(&sp->lock, flags);
}
/* Leave room for set_rx_mode() to fill two entries. */
if (sp->cur_tx - sp->dirty_tx > TX_RING_SIZE - 3)
sp->tx_full = 1;
else
- dev->tbusy = 0;
+ clear_bit(0, (void*)&dev->tbusy);
dev->trans_start = jiffies;
@@ -1138,7 +1049,7 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
struct device *dev = (struct device *)dev_instance;
struct speedo_private *sp;
- int ioaddr, boguscnt = max_interrupt_work;
+ long ioaddr, boguscnt = max_interrupt_work;
unsigned short status;
#ifndef final_version
@@ -1150,11 +1061,9 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
ioaddr = dev->base_addr;
sp = (struct speedo_private *)dev->priv;
+ spin_lock(&sp->lock);
+
#ifndef final_version
- if (dev->interrupt) {
- printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
- return;
- }
dev->interrupt = 1;
#endif
@@ -1174,19 +1083,6 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
speedo_rx(dev);
if (status & 0x1000) {
-#ifdef notdef
- int i;
- printk(KERN_WARNING"%s: The EEPro100 receiver left the ready"
- " state -- %4.4x! Index %d (%d).\n", dev->name, status,
- sp->cur_rx, sp->cur_rx % RX_RING_SIZE);
- printk(KERN_WARNING " Rx ring:\n ");
- for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %d %8.8x %8.8x %8.8x %d %d.\n",
- i, sp->rx_ringp[i]->status, sp->rx_ringp[i]->link,
- sp->rx_ringp[i]->rx_buf_addr, sp->rx_ringp[i]->count,
- sp->rx_ringp[i]->size);
-#endif
-
if ((status & 0x003c) == 0x0028) /* No more Rx buffers. */
outw(RX_RESUMENR, ioaddr + SCBCmd);
else if ((status & 0x003c) == 0x0008) { /* No resources (why?!) */
@@ -1209,14 +1105,15 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
if (speedo_debug > 5)
printk(KERN_DEBUG " scavenge candidate %d status %4.4x.\n",
entry, status);
- if ((status & 0x8000) == 0)
+ if ((status & StatusComplete) == 0)
break; /* It still hasn't been processed. */
/* Free the original skb. */
if (sp->tx_skbuff[entry]) {
sp->stats.tx_packets++; /* Count only user packets. */
- dev_kfree_skb(sp->tx_skbuff[entry]);
+ dev_free_skb(sp->tx_skbuff[entry]);
sp->tx_skbuff[entry] = 0;
- }
+ } else if ((sp->tx_ring[entry].status&0x70000) == CmdNOp << 16)
+ sp->mc_setup_busy = 0;
dirty_tx++;
}
@@ -1233,7 +1130,7 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
&& dirty_tx > sp->cur_tx - TX_RING_SIZE + 2) {
/* The ring is no longer full, clear tbusy. */
sp->tx_full = 0;
- dev->tbusy = 0;
+ clear_bit(0, (void*)&dev->tbusy);
mark_bh(NET_BH);
}
@@ -1253,19 +1150,8 @@ static void speedo_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
dev->name, inw(ioaddr + SCBStatus));
-#ifndef final_version
- /* Special code for testing *only*. */
- {
- static int stopit = 100;
- if (dev->start == 0 && --stopit < 0) {
- printk(KERN_ALERT "%s: Emergency stop, interrupt is stuck.\n",
- dev->name);
- free_irq(irq, dev);
- }
- }
-#endif
-
dev->interrupt = 0;
+ spin_unlock(&sp->lock);
return;
}
@@ -1275,150 +1161,104 @@ speedo_rx(struct device *dev)
struct speedo_private *sp = (struct speedo_private *)dev->priv;
int entry = sp->cur_rx % RX_RING_SIZE;
int status;
+ int rx_work_limit = sp->dirty_rx + RX_RING_SIZE - sp->cur_rx;
if (speedo_debug > 4)
printk(KERN_DEBUG " In speedo_rx().\n");
/* If we own the next entry, it's a new packet. Send it up. */
- while ((status = sp->rx_ringp[entry]->status) & RX_COMPLETE) {
+ while (sp->rx_ringp[entry] != NULL &&
+ (status = sp->rx_ringp[entry]->status) & RxComplete) {
+ if (--rx_work_limit < 0)
+ break;
if (speedo_debug > 4)
printk(KERN_DEBUG " speedo_rx() status %8.8x len %d.\n", status,
sp->rx_ringp[entry]->count & 0x3fff);
- if (status & 0x0200) {
- printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, "
- "status %8.8x!\n", dev->name, status);
- } else if ( ! (status & 0x2000)) {
- /* There was a fatal error. This *should* be impossible. */
- sp->stats.rx_errors++;
- printk(KERN_ERR "%s: Anomalous event in speedo_rx(), status %8.8x.\n",
- dev->name, status);
+ if ((status & (RxErrTooBig|RxOK)) != RxOK) {
+ if (status & RxErrTooBig)
+ printk(KERN_ERR "%s: Ethernet frame overran the Rx buffer, "
+ "status %8.8x!\n", dev->name, status);
+ else if ( ! (status & 0x2000)) {
+ /* There was a fatal error. This *should* be impossible. */
+ sp->stats.rx_errors++;
+ printk(KERN_ERR "%s: Anomalous event in speedo_rx(), "
+ "status %8.8x.\n",
+ dev->name, status);
+ }
} else {
- /* Malloc up new buffer, compatible with net-2e. */
int pkt_len = sp->rx_ringp[entry]->count & 0x3fff;
struct sk_buff *skb;
- int rx_in_place = 0;
/* Check if the packet is long enough to just accept without
copying to a properly sized skbuff. */
- if (pkt_len > rx_copybreak) {
- struct sk_buff *newskb;
- char *temp;
-
- /* Pass up the skb already on the Rx ring. */
- skb = sp->rx_skbuff[entry];
-#ifdef KERNEL_1_2
- temp = skb->data;
- if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp)
- printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match"
- " in speedo_rx: %p vs. %p / %p.\n", dev->name,
- bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
- temp, skb->data);
- /* Get a fresh skbuff to replace the filled one. */
- newskb = alloc_skb(PKT_BUF_SZ, GFP_ATOMIC);
-#else
- temp = skb_put(skb, pkt_len);
- if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp)
- printk(KERN_ERR "%s: Warning -- the skbuff addresses do not match"
- " in speedo_rx: %8.8x vs. %p / %p.\n", dev->name,
- sp->rx_ringp[entry]->rx_buf_addr, skb->head, temp);
- /* Get a fresh skbuff to replace the filled one. */
- newskb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
-#endif
- if (newskb) {
- struct RxFD *rxf;
- rx_in_place = 1;
- sp->rx_skbuff[entry] = newskb;
- newskb->dev = dev;
-#ifdef KERNEL_1_2
- /* Restore the data in the old header region. */
- memcpy(skb->data - sizeof(struct RxFD),
- &sp->saved_skhead[entry], sizeof(struct RxFD));
- /* Save the data in this header region. */
- rxf = (struct RxFD *)(newskb->data - sizeof(struct RxFD));
- sp->rx_ringp[entry] = rxf;
- memcpy(&sp->saved_skhead[entry], rxf, sizeof(struct RxFD));
- rxf->rx_buf_addr = virt_to_bus(newskb->data);
-#else
- rxf = sp->rx_ringp[entry] = (struct RxFD *)newskb->tail;
- skb_reserve(newskb, sizeof(struct RxFD));
- /* Unused by i82557, consistency check only. */
- rxf->rx_buf_addr = virt_to_bus(newskb->tail);
-#endif
- rxf->status = 0x00000001;
- } else /* No memory, drop the packet. */
- skb = 0;
- } else
-#ifdef KERNEL_1_2
- skb = alloc_skb(pkt_len, GFP_ATOMIC);
-#else
- skb = dev_alloc_skb(pkt_len + 2);
-#endif
- if (skb == NULL) {
- int i;
- printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n", dev->name);
- /* Check that at least two ring entries are free.
- If not, free one and mark stats->rx_dropped++. */
- /* ToDo: This is not correct!!!! We should count the number
- of linked-in Rx buffer to very that we have at least two
- remaining. */
- for (i = 0; i < RX_RING_SIZE; i++)
- if (! ((sp->rx_ringp[(entry+i) % RX_RING_SIZE]->status)
- & RX_COMPLETE))
- break;
-
- if (i > RX_RING_SIZE -2) {
- sp->stats.rx_dropped++;
- sp->rx_ringp[entry]->status = 0;
- sp->cur_rx++;
- }
- break;
- }
- skb->dev = dev;
-#if (LINUX_VERSION_CODE >= VERSION(1,3,44))
- if (! rx_in_place) {
- skb_reserve(skb, 2); /* 16 byte align the data fields */
-#if defined(__i386__) && notyet
+ if (pkt_len < rx_copybreak
+ && (skb = dev_alloc_skb(pkt_len + 2)) != 0) {
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ /* 'skb_put()' points to the start of sk_buff data area. */
+#if 1 || USE_IP_CSUM
/* Packet is in one chunk -- we can copy + cksum. */
- eth_io_copy_and_sum(skb, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
- pkt_len, 0);
+ eth_copy_and_sum(skb,
+ bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
+ pkt_len, 0);
+ skb_put(skb, pkt_len);
#else
memcpy(skb_put(skb, pkt_len),
bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len);
#endif
+ } else {
+ void *temp;
+ /* Pass up the already-filled skbuff. */
+ skb = sp->rx_skbuff[entry];
+ if (skb == NULL) {
+ printk(KERN_ERR "%s: Inconsistent Rx descriptor chain.\n",
+ dev->name);
+ break;
+ }
+ sp->rx_skbuff[entry] = NULL;
+ temp = skb_put(skb, pkt_len);
+ if (bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr) != temp)
+ printk(KERN_ERR "%s: Rx consistency error -- the skbuff "
+ "addresses do not match in speedo_rx: %p vs. %p "
+ "/ %p.\n", dev->name,
+ bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
+ skb->head, temp);
+ sp->rx_ringp[entry] = NULL;
}
skb->protocol = eth_type_trans(skb, dev);
-#else
-#ifdef KERNEL_1_3
-#warning This code has only been tested with later 1.3.* kernels.
- skb->len = pkt_len;
- memcpy(skb->data, bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr),
- pkt_len);
- /* Needed for 1.3.*. */
- skb->protocol = eth_type_trans(skb, dev);
-#else /* KERNEL_1_2 */
- skb->len = pkt_len;
- if (! rx_in_place) {
- memcpy(skb->data,
- bus_to_virt(sp->rx_ringp[entry]->rx_buf_addr), pkt_len);
- }
-#endif
-#endif
netif_rx(skb);
sp->stats.rx_packets++;
}
+ entry = (++sp->cur_rx) % RX_RING_SIZE;
+ }
- /* ToDo: This is better than before, but should be checked. */
- {
- struct RxFD *rxf = sp->rx_ringp[entry];
- rxf->status = 0xC0000003; /* '3' for verification only */
- rxf->link = 0; /* None yet. */
- rxf->count = 0;
- rxf->size = PKT_BUF_SZ;
- sp->last_rxf->link = virt_to_bus(rxf);
- sp->last_rxf->status &= ~0xC0000000;
- sp->last_rxf = rxf;
- entry = (++sp->cur_rx) % RX_RING_SIZE;
+ /* Refill the Rx ring buffers. */
+ for (; sp->dirty_rx < sp->cur_rx; sp->dirty_rx++) {
+ struct RxFD *rxf;
+ entry = sp->dirty_rx % RX_RING_SIZE;
+ if (sp->rx_skbuff[entry] == NULL) {
+ struct sk_buff *skb;
+ /* Get a fresh skbuff to replace the consumed one. */
+ skb = dev_alloc_skb(PKT_BUF_SZ + sizeof(struct RxFD));
+ sp->rx_skbuff[entry] = skb;
+ if (skb == NULL) {
+ sp->rx_ringp[entry] = NULL;
+ break; /* Better luck next time! */
+ }
+ rxf = sp->rx_ringp[entry] = (struct RxFD *)skb->tail;
+ skb->dev = dev;
+ skb_reserve(skb, sizeof(struct RxFD));
+ rxf->rx_buf_addr = virt_to_bus(skb->tail);
+ } else {
+ rxf = sp->rx_ringp[entry];
}
+ rxf->status = 0xC0000001; /* '1' for driver use only. */
+ rxf->link = 0; /* None yet. */
+ rxf->count = 0;
+ rxf->size = PKT_BUF_SZ;
+ sp->last_rxf->link = virt_to_bus(rxf);
+ sp->last_rxf->status &= ~0xC0000000;
+ sp->last_rxf = rxf;
}
sp->last_rx_time = jiffies;
@@ -1428,7 +1268,7 @@ speedo_rx(struct device *dev)
static int
speedo_close(struct device *dev)
{
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
struct speedo_private *sp = (struct speedo_private *)dev->priv;
int i;
@@ -1454,7 +1294,7 @@ speedo_close(struct device *dev)
sp->rx_skbuff[i] = 0;
/* Clear the Rx descriptors. */
if (skb)
- dev_kfree_skb(skb);
+ dev_free_skb(skb);
}
for (i = 0; i < TX_RING_SIZE; i++) {
@@ -1462,7 +1302,7 @@ speedo_close(struct device *dev)
sp->tx_skbuff[i] = 0;
/* Clear the Tx descriptors. */
if (skb)
- dev_kfree_skb(skb);
+ dev_free_skb(skb);
}
if (sp->mc_setup_frm) {
kfree(sp->mc_setup_frm);
@@ -1507,7 +1347,7 @@ static struct enet_statistics *
speedo_get_stats(struct device *dev)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
if (sp->lstats.done_marker == 0xA007) { /* Previous dump finished */
sp->stats.tx_aborted_errors += sp->lstats.tx_coll16_errs;
@@ -1530,11 +1370,10 @@ speedo_get_stats(struct device *dev)
return &sp->stats;
}
-#ifdef HAVE_PRIVATE_IOCTL
static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
u16 *data = (u16 *)&rq->ifr_data;
int phy = sp->phy[0] & 0x1f;
@@ -1553,7 +1392,6 @@ static int speedo_ioctl(struct device *dev, struct ifreq *rq, int cmd)
return -EOPNOTSUPP;
}
}
-#endif /* HAVE_PRIVATE_IOCTL */
/* Set or clear the multicast filter for this adaptor.
This is very ugly with Intel chips -- we usually have to execute an
@@ -1568,14 +1406,16 @@ static void
set_rx_mode(struct device *dev)
{
struct speedo_private *sp = (struct speedo_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
+ struct descriptor *last_cmd;
char new_rx_mode;
unsigned long flags;
int entry, i;
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
new_rx_mode = 3;
- } else if (dev->flags & IFF_ALLMULTI) {
+ } else if ((dev->flags & IFF_ALLMULTI) ||
+ dev->mc_count > multicast_filter_limit) {
new_rx_mode = 1;
} else
new_rx_mode = 0;
@@ -1588,57 +1428,54 @@ set_rx_mode(struct device *dev)
}
if (new_rx_mode != sp->rx_mode) {
- /* We must change the configuration. Construct a CmdConfig frame. */
- memcpy(sp->config_cmd_data, basic_config_cmd,sizeof(basic_config_cmd));
- sp->config_cmd_data[1] = (txfifo << 4) | rxfifo;
- sp->config_cmd_data[4] = rxdmacount;
- sp->config_cmd_data[5] = txdmacount + 0x80;
- sp->config_cmd_data[15] = (new_rx_mode & 2) ? 0x49 : 0x48;
- sp->config_cmd_data[19] = sp->full_duplex ? 0xC0 : 0x80;
- sp->config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05;
+ u8 *config_cmd_data;
+
+ spin_lock_irqsave(&sp->lock, flags);
+ entry = sp->cur_tx++ % TX_RING_SIZE;
+ last_cmd = sp->last_cmd;
+ sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
+ sp->tx_skbuff[entry] = 0; /* Redundant. */
+ sp->tx_ring[entry].status = (CmdSuspend | CmdConfigure) << 16;
+ sp->tx_ring[entry].link =
+ virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]);
+ config_cmd_data = (void *)&sp->tx_ring[entry].tx_desc_addr;
+ /* Construct a full CmdConfig frame. */
+ memcpy(config_cmd_data, i82558_config_cmd, sizeof(i82558_config_cmd));
+ config_cmd_data[1] = (txfifo << 4) | rxfifo;
+ config_cmd_data[4] = rxdmacount;
+ config_cmd_data[5] = txdmacount + 0x80;
+ config_cmd_data[15] |= (new_rx_mode & 2) ? 1 : 0;
+ config_cmd_data[19] |= sp->full_duplex ? 0x40 : 0;
+ config_cmd_data[21] = (new_rx_mode & 1) ? 0x0D : 0x05;
if (sp->phy[0] & 0x8000) { /* Use the AUI port instead. */
- sp->config_cmd_data[15] |= 0x80;
- sp->config_cmd_data[8] = 0;
+ config_cmd_data[15] |= 0x80;
+ config_cmd_data[8] = 0;
}
- save_flags(flags);
- cli();
- /* Fill the "real" tx_ring frame with a no-op and point it to us. */
- entry = sp->cur_tx++ % TX_RING_SIZE;
- sp->tx_skbuff[entry] = 0; /* Nothing to free. */
- sp->tx_ring[entry].status = CmdNOp << 16;
- sp->tx_ring[entry].link = virt_to_bus(&sp->config_cmd);
- sp->config_cmd.status = 0;
- sp->config_cmd.command = CmdSuspend | CmdConfigure;
- sp->config_cmd.link =
- virt_to_bus(&(sp->tx_ring[sp->cur_tx % TX_RING_SIZE]));
- sp->last_cmd->command &= ~CmdSuspend;
- /* Immediately trigger the command unit resume. */
+ /* Trigger the command unit resume. */
+ last_cmd->command &= ~CmdSuspend;
+
wait_for_cmd_done(ioaddr + SCBCmd);
outw(CU_RESUME, ioaddr + SCBCmd);
- sp->last_cmd = &sp->config_cmd;
- restore_flags(flags);
- if (speedo_debug > 5) {
- int i;
- printk(KERN_DEBUG " CmdConfig frame in entry %d.\n", entry);
- for(i = 0; i < 32; i++)
- printk(" %2.2x", ((unsigned char *)&sp->config_cmd)[i]);
- printk(".\n");
- }
+
+ spin_unlock_irqrestore(&sp->lock, flags);
}
- if (new_rx_mode == 0 && dev->mc_count < 3) {
- /* The simple case of 0-2 multicast list entries occurs often, and
+ if (new_rx_mode == 0 && dev->mc_count < 4) {
+ /* The simple case of 0-3 multicast list entries occurs often, and
fits within one tx_ring[] entry. */
- u16 *setup_params, *eaddrs;
struct dev_mc_list *mclist;
+ u16 *setup_params, *eaddrs;
- save_flags(flags);
- cli();
+ spin_lock_irqsave(&sp->lock, flags);
entry = sp->cur_tx++ % TX_RING_SIZE;
+ last_cmd = sp->last_cmd;
+ sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
+
sp->tx_skbuff[entry] = 0;
sp->tx_ring[entry].status = (CmdSuspend | CmdMulticastList) << 16;
sp->tx_ring[entry].link =
- virt_to_bus(&sp->tx_ring[sp->cur_tx % TX_RING_SIZE]);
+ virt_to_bus(&sp->tx_ring[(entry + 1) % TX_RING_SIZE]);
sp->tx_ring[entry].tx_desc_addr = 0; /* Really MC list count. */
setup_params = (u16 *)&sp->tx_ring[entry].tx_desc_addr;
*setup_params++ = dev->mc_count*6;
@@ -1651,36 +1488,42 @@ set_rx_mode(struct device *dev)
*setup_params++ = *eaddrs++;
}
- sp->last_cmd->command &= ~CmdSuspend;
+ last_cmd->command &= ~CmdSuspend;
+
/* Immediately trigger the command unit resume. */
wait_for_cmd_done(ioaddr + SCBCmd);
outw(CU_RESUME, ioaddr + SCBCmd);
- sp->last_cmd = (struct descriptor *)&sp->tx_ring[entry];
- restore_flags(flags);
+
+ spin_unlock_irqrestore(&sp->lock, flags);
} else if (new_rx_mode == 0) {
- /* This does not work correctly, but why not? */
struct dev_mc_list *mclist;
- u16 *eaddrs;
+ u16 *setup_params, *eaddrs;
struct descriptor *mc_setup_frm = sp->mc_setup_frm;
- u16 *setup_params = (u16 *)mc_setup_frm->params;
int i;
if (sp->mc_setup_frm_len < 10 + dev->mc_count*6
|| sp->mc_setup_frm == NULL) {
- /* Allocate a new frame, 10bytes + addrs, with a few
- extra entries for growth. */
+ /* Allocate a full setup frame, 10bytes + <max addrs>. */
if (sp->mc_setup_frm)
kfree(sp->mc_setup_frm);
- sp->mc_setup_frm_len = 10 + dev->mc_count*6 + 24;
+ sp->mc_setup_busy = 0;
+ sp->mc_setup_frm_len = 10 + multicast_filter_limit*6;
sp->mc_setup_frm = kmalloc(sp->mc_setup_frm_len, GFP_ATOMIC);
if (sp->mc_setup_frm == NULL) {
- printk(KERN_ERR "%s: Failed to allocate a setup frame.\n", dev->name);
+ printk(KERN_ERR "%s: Failed to allocate a setup frame.\n",
+ dev->name);
sp->rx_mode = -1; /* We failed, try again. */
return;
}
}
+ /* If we are busy, someone might be quickly adding to the MC list.
+ Try again later when the list changes stop. */
+ if (sp->mc_setup_busy) {
+ sp->rx_mode = -1;
+ return;
+ }
mc_setup_frm = sp->mc_setup_frm;
- /* Construct the new setup frame. */
+ /* Fill the setup frame. */
if (speedo_debug > 1)
printk(KERN_DEBUG "%s: Constructing a setup frame at %p, "
"%d bytes.\n",
@@ -1688,7 +1531,7 @@ set_rx_mode(struct device *dev)
mc_setup_frm->status = 0;
mc_setup_frm->command = CmdSuspend | CmdIntr | CmdMulticastList;
/* Link set below. */
- setup_params = (u16 *)mc_setup_frm->params;
+ setup_params = (u16 *)&mc_setup_frm->params;
*setup_params++ = dev->mc_count*6;
/* Fill in the multicast addresses. */
for (i = 0, mclist = dev->mc_list; i < dev->mc_count;
@@ -1700,13 +1543,12 @@ set_rx_mode(struct device *dev)
}
/* Disable interrupts while playing with the Tx Cmd list. */
- save_flags(flags);
- cli();
- entry = sp->cur_tx++ % TX_RING_SIZE;
+ spin_lock_irqsave(&sp->lock, flags);
- if (speedo_debug > 5)
- printk(" CmdMCSetup frame length %d in entry %d.\n",
- dev->mc_count, entry);
+ entry = sp->cur_tx++ % TX_RING_SIZE;
+ last_cmd = sp->last_cmd;
+ sp->last_cmd = mc_setup_frm;
+ sp->mc_setup_busy++;
/* Change the command to a NoOp, pointing to the CmdMulti command. */
sp->tx_skbuff[entry] = 0;
@@ -1715,41 +1557,25 @@ set_rx_mode(struct device *dev)
/* Set the link in the setup frame. */
mc_setup_frm->link =
- virt_to_bus(&(sp->tx_ring[sp->cur_tx % TX_RING_SIZE]));
+ virt_to_bus(&(sp->tx_ring[(entry+1) % TX_RING_SIZE]));
+
+ last_cmd->command &= ~CmdSuspend;
- sp->last_cmd->command &= ~CmdSuspend;
/* Immediately trigger the command unit resume. */
wait_for_cmd_done(ioaddr + SCBCmd);
outw(CU_RESUME, ioaddr + SCBCmd);
- sp->last_cmd = mc_setup_frm;
- restore_flags(flags);
- if (speedo_debug > 1)
- printk(KERN_DEBUG "%s: Last command at %p is %4.4x.\n",
- dev->name, sp->last_cmd, sp->last_cmd->command);
+
+ spin_unlock_irqrestore(&sp->lock, flags);
+
+ if (speedo_debug > 5)
+ printk(" CmdMCSetup frame length %d in entry %d.\n",
+ dev->mc_count, entry);
}
sp->rx_mode = new_rx_mode;
}
#ifdef MODULE
-#if (LINUX_VERSION_CODE < VERSION(1,3,38)) /* 1.3.38 and later */
-char kernel_version[] = UTS_RELEASE;
-#endif
-
-#if LINUX_VERSION_CODE > 0x20118
-MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
-MODULE_DESCRIPTION("Intel i82557/i82558 EtherExpressPro driver");
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(congenb, "i");
-MODULE_PARM(txfifo, "i");
-MODULE_PARM(rxfifo, "i");
-MODULE_PARM(txdmacount, "i");
-MODULE_PARM(rxdmacount, "i");
-MODULE_PARM(rx_copybreak, "i");
-MODULE_PARM(max_interrupt_work, "i");
-#endif
int
init_module(void)
@@ -1796,7 +1622,8 @@ int eepro100_probe(struct device *dev)
/*
* Local variables:
- * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c"
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
+ * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c eepro100.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
diff --git a/drivers/net/eexpress.c b/drivers/net/eexpress.c
index 38c2b80b8..057fe5b86 100644
--- a/drivers/net/eexpress.c
+++ b/drivers/net/eexpress.c
@@ -8,6 +8,11 @@
*
* Many modifications, and currently maintained, by
* Philip Blundell <Philip.Blundell@pobox.com>
+ * Added the Compaq LTE Alan Cox <alan@redhat.com>
+ *
+ * Note - this driver is experimental still - it has problems on faster
+ * machines. Someone needs to sit down and go through it line by line with
+ * a databook...
*/
/* The EtherExpress 16 is a fairly simple card, based on a shared-memory
@@ -326,7 +331,7 @@ __initfunc(int express_probe(struct device *dev))
if (sum==0xbaba && !eexp_hw_probe(dev,*port))
return 0;
}
- return ENODEV;
+ return -ENODEV;
}
/*
@@ -931,11 +936,13 @@ __initfunc(static int eexp_hw_probe(struct device *dev, unsigned short ioaddr))
hw_addr[1] = eexp_hw_readeeprom(ioaddr,3);
hw_addr[2] = eexp_hw_readeeprom(ioaddr,4);
- if (hw_addr[2]!=0x00aa || ((hw_addr[1] & 0xff00)!=0x0000))
+ /* Standard Address or Compaq LTE Address */
+ if (!((hw_addr[2]==0x00aa && ((hw_addr[1] & 0xff00)==0x0000)) ||
+ (hw_addr[2]==0x0080 && ((hw_addr[1] & 0xff00)==0x5F00))))
{
printk(" rejected: invalid address %04x%04x%04x\n",
hw_addr[2],hw_addr[1],hw_addr[0]);
- return ENODEV;
+ return -ENODEV;
}
/* Calculate the EEPROM checksum. Carry on anyway if it's bad,
diff --git a/drivers/net/eth16i.c b/drivers/net/eth16i.c
index e68c0d64d..59921bfc2 100644
--- a/drivers/net/eth16i.c
+++ b/drivers/net/eth16i.c
@@ -1,122 +1,207 @@
/* eth16i.c An ICL EtherTeam 16i and 32 EISA ethernet driver for Linux
-
- Written 1994-95 by Mika Kuoppala
-
- Copyright (C) 1994, 1995 by Mika Kuoppala
- Based on skeleton.c and at1700.c by Donald Becker
+
+ Written 1994-1998 by Mika Kuoppala
+
+ Copyright (C) 1994-1998 by Mika Kuoppala
+ Based on skeleton.c and heavily on at1700.c by Donald Becker
This software may be used and distributed according to the terms
of the GNU Public Licence, incorporated herein by reference.
- The author may be reached as miku@elt.icl.fi
+ The author may be reached as miku@iki.fi
This driver supports following cards :
- ICL EtherTeam 16i
- - ICL EtherTeam 32 EISA
+ - ICL EtherTeam 32 EISA
+ (Uses true 32 bit transfers rather than 16i compability mode)
+
+ Example Module usage:
+ insmod eth16i.o ioaddr=0x2a0 mediatype=bnc
+
+ mediatype can be one of the following: bnc,tp,dix,auto,eprom
+ 'auto' will try to autoprobe mediatype.
+ 'eprom' will use whatever type defined in eprom.
+
+ I have benchmarked driver with PII/300Mhz as a ftp client
+ and 486/33Mhz as a ftp server. Top speed was 1128.37 kilobytes/sec.
+
Sources:
- skeleton.c a sample network driver core for linux,
written by Donald Becker <becker@CESDIS.gsfc.nasa.gov>
- - at1700.c a driver for Allied Telesis AT1700, written
+ - at1700.c a driver for Allied Telesis AT1700, written
by Donald Becker.
- e16iSRV.asm a Netware 3.X Server Driver for ICL EtherTeam16i
written by Markku Viima
- The Fujitsu MB86965 databook.
-
- Valuable assistance from:
- Markku Viima (ICL)
- Ari Valve (ICL)
+
+ Author thanks following persons due to their valueble assistance:
+ Markku Viima (ICL)
+ Ari Valve (ICL)
+ Donald Becker
+ Kurt Huwig <kurt@huwig.de>
Revision history:
Version Date Description
-
- 0.01 15.12-94 Initial version (card detection)
+
+ 0.01 15.12-94 Initial version (card detection)
0.02 23.01-95 Interrupt is now hooked correctly
0.03 01.02-95 Rewrote initialization part
0.04 07.02-95 Base skeleton done...
- Made a few changes to signature checking
- to make it a bit reliable.
- - fixed bug in tx_buf mapping
- - fixed bug in initialization (DLC_EN
- wasn't enabled when initialization
- was done.)
- 0.05 08.02-95 If there were more than one packet to send,
- transmit was jammed due to invalid
- register write...now fixed
- 0.06 19.02-95 Rewrote interrupt handling
+ Made a few changes to signature checking
+ to make it a bit reliable.
+ - fixed bug in tx_buf mapping
+ - fixed bug in initialization (DLC_EN
+ wasn't enabled when initialization
+ was done.)
+ 0.05 08.02-95 If there were more than one packet to send,
+ transmit was jammed due to invalid
+ register write...now fixed
+ 0.06 19.02-95 Rewrote interrupt handling
0.07 13.04-95 Wrote EEPROM read routines
Card configuration now set according to
- data read from EEPROM
+ data read from EEPROM
0.08 23.06-95 Wrote part that tries to probe used interface
port if AUTO is selected
- 0.09 01.09-95 Added module support
-
- 0.10 04.09-95 Fixed receive packet allocation to work
- with kernels > 1.3.x
+ 0.09 01.09-95 Added module support
+
+ 0.10 04.09-95 Fixed receive packet allocation to work
+ with kernels > 1.3.x
+
+ 0.20 20.09-95 Added support for EtherTeam32 EISA
- 0.20 20.09-95 Added support for EtherTeam32 EISA
-
- 0.21 17.10-95 Removed the unnecessary extern
+ 0.21 17.10-95 Removed the unnecessary extern
init_etherdev() declaration. Some
other cleanups.
+
+ 0.22 22.02-96 Receive buffer was not flushed
+ correctly when faulty packet was
+ received. Now fixed.
+
+ 0.23 26.02-96 Made resetting the adapter
+ more reliable.
+
+ 0.24 27.02-96 Rewrote faulty packet handling in eth16i_rx
+
+ 0.25 22.05-96 kfree() was missing from cleanup_module.
+
+ 0.26 11.06-96 Sometimes card was not found by
+ check_signature(). Now made more reliable.
+
+ 0.27 23.06-96 Oops. 16 consecutive collisions halted
+ adapter. Now will try to retransmit
+ MAX_COL_16 times before finally giving up.
+
+ 0.28 28.10-97 Added dev_id parameter (NULL) for free_irq
+
+ 0.29 29.10-97 Multiple card support for module users
+
+ 0.30 30.10-97 Fixed irq allocation bug.
+ (request_irq moved from probe to open)
+
+ 0.30a 21.08-98 Card detection made more relaxed. Driver
+ had problems with some TCP/IP-PROM boots
+ to find the card. Suggested by
+ Kurt Huwig <kurt@huwig.de>
+
+ 0.31 28.08-98 Media interface port can now be selected
+ with module parameters or kernel
+ boot parameters.
+
+ 0.32 31.08-98 IRQ was never freed if open/close
+ pair wasn't called. Now fixed.
+
+ 0.33 10.09-98 When eth16i_open() was called after
+ eth16i_close() chip never recovered.
+ Now more shallow reset is made on
+ close.
+
Bugs:
- In some cases the interface autoprobing code doesn't find
- the correct interface type. In this case you can
- manually choose the interface type in DOS with E16IC.EXE which is
+ In some cases the media interface autoprobing code doesn't find
+ the correct interface type. In this case you can
+ manually choose the interface type in DOS with E16IC.EXE which is
configuration software for EtherTeam16i and EtherTeam32 cards.
+ This is also true for IRQ setting. You cannot use module
+ parameter to configure IRQ of the card (yet).
To do:
- Real multicast support
+ - Rewrite the media interface autoprobing code. Its _horrible_ !
+ - Possibly merge all the MB86965 specific code to external
+ module for use by eth16.c and Donald's at1700.c
+ - IRQ configuration with module parameter. I will do
+ this when i will get enough info about setting
+ irq without configuration utility.
*/
-static char *version =
- "eth16i.c: v0.21 17-10-95 Mika Kuoppala (miku@elt.icl.fi)\n";
+static char *version =
+ "eth16i.c: v0.33 10-09-98 Mika Kuoppala (miku@iki.fi)\n";
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/fcntl.h>
-#include <linux/interrupt.h>
-#include <linux/ptrace.h>
-#include <linux/ioport.h>
-#include <linux/in.h>
-#include <linux/malloc.h>
-#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
#include <linux/errno.h>
-#include <linux/init.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-#include <asm/system.h>
-#include <asm/bitops.h>
-#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
#include <asm/dma.h>
-#include <asm/delay.h>
+
+#ifndef LINUX_VERSION_CODE
+#include <linux/version.h>
+#endif
+
+#if LINUX_VERSION_CODE >= 0x20123
+#include <linux/init.h>
+#else
+#define __init
+#define __initdata
+#define __initfunc(x) x
+#endif
+
+#if LINUX_VERSION_CODE < 0x20138
+#define test_and_set_bit(val,addr) set_bit(val,addr)
+#endif
+
+#if LINUX_VERSION_CODE < 0x020100
+typedef struct enet_statistics eth16i_stats_type;
+#else
+typedef struct net_device_stats eth16i_stats_type;
+#endif
/* Few macros */
-#define BIT(a) ( (1 << (a)) )
-#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
+#define BIT(a) ( (1 << (a)) )
+#define BITSET(ioaddr, bnum) ((outb(((inb(ioaddr)) | (bnum)), ioaddr)))
#define BITCLR(ioaddr, bnum) ((outb(((inb(ioaddr)) & (~(bnum))), ioaddr)))
/* This is the I/O address space for Etherteam 16i adapter. */
-#define ETH16I_IO_EXTENT 32
+#define ETH16I_IO_EXTENT 32
/* Ticks before deciding that transmit has timed out */
-#define TIMEOUT_TICKS 30
+#define TX_TIMEOUT (400*HZ/1000)
/* Maximum loop count when receiving packets */
-#define MAX_RX_LOOP 40
+#define MAX_RX_LOOP 20
/* Some interrupt masks */
-#define ETH16I_INTR_ON 0x8f82
+#define ETH16I_INTR_ON 0xef8a /* Higher is receive mask */
#define ETH16I_INTR_OFF 0x0000
-
+
/* Buffers header status byte meanings */
#define PKT_GOOD BIT(5)
#define PKT_GOOD_RMT BIT(4)
@@ -131,6 +216,7 @@ static char *version =
#define NET_BUSY BIT(6)
#define TX_PKT_RCD BIT(5)
#define CR_LOST BIT(4)
+#define TX_JABBER_ERR BIT(3)
#define COLLISION BIT(2)
#define COLLISIONS_16 BIT(1)
@@ -142,7 +228,7 @@ static char *version =
#define ALIGN_ERR BIT(2)
#define CRC_ERR BIT(1)
#define RX_BUF_OVERFLOW BIT(0)
-
+
/* Transmit Interrupt Enable Register (DLCR2) */
#define TX_INTR_REG 2
#define TX_INTR_DONE BIT(7)
@@ -181,18 +267,18 @@ static char *version =
#define SRAM_CYCLE_TIME_100NS BIT(6)
#define SYSTEM_BUS_WIDTH_8 BIT(5) /* 1 = 8bit, 0 = 16bit */
#define BUFFER_WIDTH_8 BIT(4) /* 1 = 8bit, 0 = 16bit */
-#define TBS1 BIT(3)
+#define TBS1 BIT(3)
#define TBS0 BIT(2)
-#define MBS1 BIT(1) /* 00=8kb, 01=16kb */
-#define MBS0 BIT(0) /* 10=32kb, 11=64kb */
+#define SRAM_BS1 BIT(1) /* 00=8kb, 01=16kb */
+#define SRAM_BS0 BIT(0) /* 10=32kb, 11=64kb */
-#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
-#define ETH16I_TX_BUF_SIZE 2 /* 2 = 8kb, 3 = 16kb */
-#endif
-#define TX_BUF_1x2048 0
-#define TX_BUF_2x2048 1
-#define TX_BUF_2x4098 2
-#define TX_BUF_2x8192 3
+#ifndef ETH16I_TX_BUF_SIZE /* 0 = 2kb, 1 = 4kb */
+#define ETH16I_TX_BUF_SIZE 3 /* 2 = 8kb, 3 = 16kb */
+#endif
+#define TX_BUF_1x2048 0
+#define TX_BUF_2x2048 1
+#define TX_BUF_2x4098 2
+#define TX_BUF_2x8192 3
/* Configuration Register 1 (DLCR7) */
#define CONFIG_REG_1 7
@@ -212,18 +298,21 @@ static char *version =
#define HASH_TABLE_RB 1
/* Buffer memory ports */
-#define BUFFER_MEM_PORT_LB 8
-#define DATAPORT BUFFER_MEM_PORT_LB
-#define BUFFER_MEM_PORT_HB 9
+#define BUFFER_MEM_PORT_LB 8
+#define DATAPORT BUFFER_MEM_PORT_LB
+#define BUFFER_MEM_PORT_HB 9
/* 16 Collision control register (BMPR11) */
#define COL_16_REG 11
#define HALT_ON_16 0x00
#define RETRANS_AND_HALT_ON_16 0x02
+/* Maximum number of attempts to send after 16 concecutive collisions */
+#define MAX_COL_16 10
+
/* DMA Burst and Transceiver Mode Register (BMPR13) */
#define TRANSCEIVER_MODE_REG 13
-#define TRANSCEIVER_MODE_RB 2
+#define TRANSCEIVER_MODE_RB 2
#define IO_BASE_UNLOCK BIT(7)
#define LOWER_SQUELCH_TRESH BIT(6)
#define LINK_TEST_DISABLE BIT(5)
@@ -232,9 +321,8 @@ static char *version =
/* Filter Self Receive Register (BMPR14) */
#define FILTER_SELF_RX_REG 14
-#define SKIP_RECEIVE_PACKET BIT(2)
+#define SKIP_RX_PACKET BIT(2)
#define FILTER_SELF_RECEIVE BIT(0)
-#define RX_BUF_SKIP_PACKET SKIP_RECEIVE_PACKET | FILTER_SELF_RECEIVE
/* EEPROM Control Register (BMPR 16) */
#define EEPROM_CTRL_REG 16
@@ -254,19 +342,20 @@ static char *version =
#define EEPROM_READ 0x80
/* NMC93CSx6 EEPROM Addresses */
-#define E_NODEID_0 0x02
-#define E_NODEID_1 0x03
-#define E_NODEID_2 0x04
-#define E_PORT_SELECT 0x14
- #define E_PORT_BNC 0
- #define E_PORT_DIX 1
- #define E_PORT_TP 2
- #define E_PORT_AUTO 3
-#define E_PRODUCT_CFG 0x30
-
+#define E_NODEID_0 0x02
+#define E_NODEID_1 0x03
+#define E_NODEID_2 0x04
+#define E_PORT_SELECT 0x14
+ #define E_PORT_BNC 0x00
+ #define E_PORT_DIX 0x01
+ #define E_PORT_TP 0x02
+ #define E_PORT_AUTO 0x03
+ #define E_PORT_FROM_EPROM 0x04
+#define E_PRODUCT_CFG 0x30
+
/* Macro to slow down io between EEPROM clock transitions */
-#define eeprom_slow_io() udelay(100) /* FIXME: smaller but right value here */
+#define eeprom_slow_io() do { int _i = 40; while(--_i > 0) { inb(0x80); }}while(0)
/* Jumperless Configuration Register (BMPR19) */
#define JUMPERLESS_CONFIG 19
@@ -277,31 +366,24 @@ static char *version =
#define RESET ID_ROM_0
/* This is the I/O address list to be probed when seeking the card */
-static unsigned int eth16i_portlist[] __initdata = {
- 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0
-};
+static unsigned int eth16i_portlist[] =
+ { 0x260, 0x280, 0x2A0, 0x240, 0x340, 0x320, 0x380, 0x300, 0 };
-static unsigned int eth32i_portlist[] __initdata = {
- 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
- 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0
-};
+static unsigned int eth32i_portlist[] =
+ { 0x1000, 0x2000, 0x3000, 0x4000, 0x5000, 0x6000, 0x7000, 0x8000,
+ 0x9000, 0xA000, 0xB000, 0xC000, 0xD000, 0xE000, 0xF000, 0 };
/* This is the Interrupt lookup table for Eth16i card */
-static unsigned int eth16i_irqmap[] __initdata = {
- 9, 10, 5, 15
-};
+static unsigned int eth16i_irqmap[] = { 9, 10, 5, 15, 0 };
+#define NUM_OF_ISA_IRQS 4
/* This is the Interrupt lookup table for Eth32i card */
-static unsigned int eth32i_irqmap[] __initdata = {
- 3, 5, 7, 9, 10, 11, 12, 15
-};
-
+static unsigned int eth32i_irqmap[] = { 3, 5, 7, 9, 10, 11, 12, 15, 0 };
#define EISA_IRQ_REG 0xc89
+#define NUM_OF_EISA_IRQS 8
-static unsigned int eth16i_tx_buf_map[] = {
- 2048, 2048, 4096, 8192
-};
-unsigned int boot = 1;
+static unsigned int eth16i_tx_buf_map[] = { 2048, 2048, 4096, 8192 };
+static unsigned int boot = 1;
/* Use 0 for production, 1 for verification, >2 for debug */
#ifndef ETH16I_DEBUG
@@ -310,60 +392,76 @@ unsigned int boot = 1;
static unsigned int eth16i_debug = ETH16I_DEBUG;
/* Information for each board */
-struct eth16i_local
-{
- struct net_device_stats stats;
- unsigned int tx_started:1;
- unsigned char tx_queue; /* Number of packets in transmit buffer */
- unsigned short tx_queue_len;
- unsigned int tx_buf_size;
- unsigned long open_time;
+
+struct eth16i_local {
+ eth16i_stats_type stats;
+ unsigned char tx_started;
+ unsigned char tx_buf_busy;
+ unsigned short tx_queue; /* Number of packets in transmit buffer */
+ unsigned short tx_queue_len;
+ unsigned int tx_buf_size;
+ unsigned long open_time;
+ unsigned long tx_buffered_packets;
+ unsigned long col_16;
};
/* Function prototypes */
-extern int eth16i_probe(struct device *dev);
-
-static int eth16i_probe1(struct device *dev, short ioaddr);
-static int eth16i_check_signature(short ioaddr);
-static int eth16i_probe_port(short ioaddr);
-static void eth16i_set_port(short ioaddr, int porttype);
-static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l);
-static int eth16i_receive_probe_packet(short ioaddr);
-static int eth16i_get_irq(short ioaddr);
-static int eth16i_read_eeprom(int ioaddr, int offset);
-static int eth16i_read_eeprom_word(int ioaddr);
-static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
-static int eth16i_open(struct device *dev);
-static int eth16i_close(struct device *dev);
-static int eth16i_tx(struct sk_buff *skb, struct device *dev);
-static void eth16i_rx(struct device *dev);
-static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
-static void eth16i_multicast(struct device *dev);
-static void eth16i_select_regbank(unsigned char regbank, short ioaddr);
-static void eth16i_initialize(struct device *dev);
-static struct net_device_stats *eth16i_get_stats(struct device *dev);
+extern int eth16i_probe(struct device *dev);
+
+static int eth16i_probe1(struct device *dev, int ioaddr);
+static int eth16i_check_signature(int ioaddr);
+static int eth16i_probe_port(int ioaddr);
+static void eth16i_set_port(int ioaddr, int porttype);
+static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l);
+static int eth16i_receive_probe_packet(int ioaddr);
+static int eth16i_get_irq(int ioaddr);
+static int eth16i_read_eeprom(int ioaddr, int offset);
+static int eth16i_read_eeprom_word(int ioaddr);
+static void eth16i_eeprom_cmd(int ioaddr, unsigned char command);
+static int eth16i_open(struct device *dev);
+static int eth16i_close(struct device *dev);
+static int eth16i_tx(struct sk_buff *skb, struct device *dev);
+static void eth16i_rx(struct device *dev);
+static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static void eth16i_reset(struct device *dev);
+static void eth16i_skip_packet(struct device *dev);
+static void eth16i_multicast(struct device *dev);
+static void eth16i_select_regbank(unsigned char regbank, int ioaddr);
+static void eth16i_initialize(struct device *dev);
+
+#if 0
+static int eth16i_set_irq(struct device *dev);
+#endif
+
+#ifdef MODULE
+static ushort eth16i_parse_mediatype(const char* s);
+#endif
+
+static struct enet_statistics *eth16i_get_stats(struct device *dev);
static char *cardname = "ICL EtherTeam 16i/32";
-#ifdef HAVE_DEVLIST
+#ifdef HAVE_DEVLIST
+
/* Support for alternate probe manager */
-/struct netdev_entry eth16i_drv =
- {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list};
+/struct netdev_entry eth16i_drv =
+ {"eth16i", eth16i_probe1, ETH16I_IO_EXTENT, eth16i_probe_list};
#else /* Not HAVE_DEVLIST */
+
__initfunc(int eth16i_probe(struct device *dev))
{
int i;
int ioaddr;
int base_addr = dev ? dev->base_addr : 0;
+
+ if(eth16i_debug > 4)
+ printk(KERN_DEBUG "Probing started for %s\n", cardname);
- if(eth16i_debug > 4)
- printk("Probing started for %s\n", cardname);
-
- if(base_addr > 0x1ff) /* Check only single location */
+ if(base_addr > 0x1ff) /* Check only single location */
return eth16i_probe1(dev, base_addr);
- else if(base_addr != 0) /* Don't probe at all */
+ else if(base_addr != 0) /* Don't probe at all */
return ENXIO;
/* Seek card from the ISA io address space */
@@ -377,88 +475,107 @@ __initfunc(int eth16i_probe(struct device *dev))
/* Seek card from the EISA io address space */
for(i = 0; (ioaddr = eth32i_portlist[i]) ; i++) {
if(check_region(ioaddr, ETH16I_IO_EXTENT))
- continue;
+ continue;
if(eth16i_probe1(dev, ioaddr) == 0)
- return 0;
- }
+ return 0;
+ }
return ENODEV;
}
-#endif /* Not HAVE_DEVLIST */
+#endif /* Not HAVE_DEVLIST */
-__initfunc(static int eth16i_probe1(struct device *dev, short ioaddr))
+__initfunc(static int eth16i_probe1(struct device *dev, int ioaddr))
{
static unsigned version_printed = 0;
- unsigned int irq = 0;
- boot = 1; /* To inform initialization that we are in boot probe */
+ boot = 1; /* To inform initilization that we are in boot probe */
/*
- The MB86985 chip has on register which holds information in which
- io address the chip lies. First read this register and compare
- it to our current io address and if match then this could
- be our chip.
- */
+ The MB86985 chip has on register which holds information in which
+ io address the chip lies. First read this register and compare
+ it to our current io address and if match then this could
+ be our chip.
+ */
if(ioaddr < 0x1000) {
- if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)] != ioaddr)
+
+ if(eth16i_portlist[(inb(ioaddr + JUMPERLESS_CONFIG) & 0x07)]
+ != ioaddr)
return -ENODEV;
}
/* Now we will go a bit deeper and try to find the chip's signature */
- if(eth16i_check_signature(ioaddr) != 0) /* Can we find the signature here */
+ if(eth16i_check_signature(ioaddr) != 0)
return -ENODEV;
- /*
- Now it seems that we have found an ethernet chip in this particular
- ioaddr. The MB86985 chip has this feature, that when you read a
- certain register it will increase its io base address to next
- configurable slot. Now when we have found the chip, first thing is
- to make sure that the chip's ioaddr will hold still here.
- */
+ /*
+ Now it seems that we have found a ethernet chip in this particular
+ ioaddr. The MB86985 chip has this feature, that when you read a
+ certain register it will increase it's io base address to next
+ configurable slot. Now when we have found the chip, first thing is
+ to make sure that the chip's ioaddr will hold still here.
+ */
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
outb(0x00, ioaddr + TRANSCEIVER_MODE_REG);
- outb(0x00, ioaddr + RESET); /* Will reset some parts of chip */
- BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* This will disable the data link */
+ outb(0x00, ioaddr + RESET); /* Reset some parts of chip */
+ BITSET(ioaddr + CONFIG_REG_0, BIT(7)); /* Disable the data link */
if(dev == NULL)
- dev = init_etherdev(0, sizeof(struct eth16i_local));
+ dev = init_etherdev(0, 0);
if( (eth16i_debug & version_printed++) == 0)
- printk(version);
+ printk(KERN_INFO "%s", version);
dev->base_addr = ioaddr;
+
+#if 0
+ if(dev->irq) {
+ if(eth16i_set_irq(dev)) {
+ dev->irq = eth16i_get_irq(ioaddr);
+ }
+
+ }
+ else {
+#endif
- irq = eth16i_get_irq(ioaddr);
- dev->irq = irq;
+ dev->irq = eth16i_get_irq(ioaddr);
/* Try to obtain interrupt vector */
- if(request_irq(dev->irq, &eth16i_interrupt, 0, "eth16i", dev)) {
- printk("%s: %s at %#3x, but is unusable due
- conflict on IRQ %d.\n", dev->name, cardname, ioaddr, irq);
- return EAGAIN;
+
+ if (request_irq(dev->irq, (void *)&eth16i_interrupt, 0, "eth16i", dev)) {
+ printk(KERN_WARNING "%s: %s at %#3x, but is unusable due conflicting IRQ %d.\n",
+ dev->name, cardname, ioaddr, dev->irq);
+ return -EAGAIN;
}
- printk("%s: %s at %#3x, IRQ %d, ",
- dev->name, cardname, ioaddr, dev->irq);
+#if 0
+ irq2dev_map[dev->irq] = dev;
+#endif
+
+ printk(KERN_INFO "%s: %s at %#3x, IRQ %d, ",
+ dev->name, cardname, ioaddr, dev->irq);
/* Let's grab the region */
request_region(ioaddr, ETH16I_IO_EXTENT, "eth16i");
/* Now we will have to lock the chip's io address */
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
- outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
+ outb(0x38, ioaddr + TRANSCEIVER_MODE_REG);
- eth16i_initialize(dev); /* Initialize rest of the chip's registers */
+ eth16i_initialize(dev); /* Initialize rest of the chip's registers */
/* Now let's same some energy by shutting down the chip ;) */
BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
/* Initialize the device structure */
- if(dev->priv == NULL)
+ if(dev->priv == NULL) {
dev->priv = kmalloc(sizeof(struct eth16i_local), GFP_KERNEL);
+ if(dev->priv == NULL)
+ return -ENOMEM;
+ }
+
memset(dev->priv, 0, sizeof(struct eth16i_local));
dev->open = eth16i_open;
@@ -478,7 +595,7 @@ __initfunc(static int eth16i_probe1(struct device *dev, short ioaddr))
static void eth16i_initialize(struct device *dev)
{
- short ioaddr = dev->base_addr;
+ int ioaddr = dev->base_addr;
int i, node_w = 0;
unsigned char node_byte = 0;
@@ -489,11 +606,9 @@ static void eth16i_initialize(struct device *dev)
((unsigned short *)dev->dev_addr)[i] = ntohs(node_val);
}
- for(i = 0; i < 6; i++)
- {
+ for(i = 0; i < 6; i++) {
outb( ((unsigned char *)dev->dev_addr)[i], ioaddr + NODE_ID_0 + i);
- if(boot)
- {
+ if(boot) {
printk("%02x", inb(ioaddr + NODE_ID_0 + i));
if(i != 5)
printk(":");
@@ -502,14 +617,14 @@ static void eth16i_initialize(struct device *dev)
/* Now we will set multicast addresses to accept none */
eth16i_select_regbank(HASH_TABLE_RB, ioaddr);
- for(i = 0; i < 8; i++)
+ for(i = 0; i < 8; i++)
outb(0x00, ioaddr + HASH_TABLE_0 + i);
/*
- Now let's disable the transmitter and receiver, set the buffer ram
- cycle time, bus width and buffer data path width. Also we shall
- set transmit buffer size and total buffer size.
- */
+ Now let's disable the transmitter and receiver, set the buffer ram
+ cycle time, bus width and buffer data path width. Also we shall
+ set transmit buffer size and total buffer size.
+ */
eth16i_select_regbank(2, ioaddr);
@@ -519,38 +634,56 @@ static void eth16i_initialize(struct device *dev)
if( (node_w & 0xFF00) == 0x0800)
node_byte |= BUFFER_WIDTH_8;
- node_byte |= MBS1;
+ node_byte |= SRAM_BS1;
if( (node_w & 0x00FF) == 64)
- node_byte |= MBS0;
+ node_byte |= SRAM_BS0;
node_byte |= DLC_EN | SRAM_CYCLE_TIME_100NS | (ETH16I_TX_BUF_SIZE << 2);
outb(node_byte, ioaddr + CONFIG_REG_0);
/* We shall halt the transmitting, if 16 collisions are detected */
- outb(RETRANS_AND_HALT_ON_16, ioaddr + COL_16_REG);
+ outb(HALT_ON_16, ioaddr + COL_16_REG);
- if(boot) /* Now set port type */
- {
- char *porttype[] = {"BNC", "DIX", "TP", "AUTO"};
+#ifdef MODULE
+ /* if_port already set by init_module() */
+#else
+ dev->if_port = (dev->mem_start < E_PORT_FROM_EPROM) ?
+ dev->mem_start : E_PORT_FROM_EPROM;
+#endif
- ushort ptype = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
- dev->if_port = (ptype & 0x00FF);
+ /* Set interface port type */
+ if(boot) {
+ char *porttype[] = {"BNC", "DIX", "TP", "AUTO", "FROM_EPROM" };
- printk(" %s interface.\n", porttype[dev->if_port]);
+ switch(dev->if_port)
+ {
+
+ case E_PORT_FROM_EPROM:
+ dev->if_port = eth16i_read_eeprom(ioaddr, E_PORT_SELECT);
+ break;
+
+ case E_PORT_AUTO:
+ dev->if_port = eth16i_probe_port(ioaddr);
+ break;
+
+ case E_PORT_BNC:
+ case E_PORT_TP:
+ case E_PORT_DIX:
+ break;
+ }
- if(ptype == E_PORT_AUTO)
- ptype = eth16i_probe_port(ioaddr);
+ printk(" %s interface.\n", porttype[dev->if_port]);
- eth16i_set_port(ioaddr, ptype);
+ eth16i_set_port(ioaddr, dev->if_port);
}
/* Set Receive Mode to normal operation */
outb(MODE_2, ioaddr + RECEIVE_MODE_REG);
}
-static int eth16i_probe_port(short ioaddr)
+static int eth16i_probe_port(int ioaddr)
{
int i;
int retcode;
@@ -579,136 +712,163 @@ static int eth16i_probe_port(short ioaddr)
eth16i_set_port(ioaddr, i);
if(eth16i_debug > 1)
- printk("Set port number %d\n", i);
+ printk(KERN_DEBUG "Set port number %d\n", i);
retcode = eth16i_send_probe_packet(ioaddr, dummy_packet, 64);
- if(retcode == 0)
- {
+ if(retcode == 0) {
retcode = eth16i_receive_probe_packet(ioaddr);
- if(retcode != -1)
- {
+ if(retcode != -1) {
if(eth16i_debug > 1)
- printk("Eth16i interface port found at %d\n", i);
+ printk(KERN_DEBUG "Eth16i interface port found at %d\n", i);
return i;
}
}
else {
if(eth16i_debug > 1)
- printk("TRANSMIT_DONE timeout\n");
+ printk(KERN_DEBUG "TRANSMIT_DONE timeout when probing interface port\n");
}
}
if( eth16i_debug > 1)
- printk("Using default port\n");
+ printk(KERN_DEBUG "Using default port\n");
return E_PORT_BNC;
}
-static void eth16i_set_port(short ioaddr, int porttype)
-{
+static void eth16i_set_port(int ioaddr, int porttype)
+{
unsigned short temp = 0;
eth16i_select_regbank(TRANSCEIVER_MODE_RB, ioaddr);
outb(LOOPBACK_CONTROL, ioaddr + TRANSMIT_MODE_REG);
temp |= DIS_AUTO_PORT_SEL;
- switch(porttype)
- {
- case E_PORT_BNC :
- temp |= AUI_SELECT;
- break;
+ switch(porttype) {
- case E_PORT_TP :
- break;
+ case E_PORT_BNC :
+ temp |= AUI_SELECT;
+ break;
+
+ case E_PORT_TP :
+ break;
+
+ case E_PORT_DIX :
+ temp |= AUI_SELECT;
+ BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
+ break;
+ }
- case E_PORT_DIX :
- temp |= AUI_SELECT;
- BITSET(ioaddr + TRANSMIT_MODE_REG, CONTROL_OUTPUT);
- break;
- }
outb(temp, ioaddr + TRANSCEIVER_MODE_REG);
if(eth16i_debug > 1) {
- printk("TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
- printk("TRANSCEIVER_MODE_REG = %x\n", inb(ioaddr+TRANSCEIVER_MODE_REG));
+ printk(KERN_DEBUG "TRANSMIT_MODE_REG = %x\n", inb(ioaddr + TRANSMIT_MODE_REG));
+ printk(KERN_DEBUG "TRANSCEIVER_MODE_REG = %x\n",
+ inb(ioaddr+TRANSCEIVER_MODE_REG));
}
}
-static int eth16i_send_probe_packet(short ioaddr, unsigned char *b, int l)
+static int eth16i_send_probe_packet(int ioaddr, unsigned char *b, int l)
{
int starttime;
outb(0xff, ioaddr + TX_STATUS_REG);
outw(l, ioaddr + DATAPORT);
- outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
+ outsw(ioaddr + DATAPORT, (unsigned short *)b, (l + 1) >> 1);
starttime = jiffies;
- outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
+ outb(TX_START | 1, ioaddr + TRANSMIT_START_REG);
- while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0)
- if( (jiffies - starttime) > TIMEOUT_TICKS)
- break;
- return(0);
+ while( (inb(ioaddr + TX_STATUS_REG) & 0x80) == 0) {
+ if( (jiffies - starttime) > TX_TIMEOUT) {
+ return -1;
+ }
+ }
+
+ return 0;
}
-static int eth16i_receive_probe_packet(short ioaddr)
+static int eth16i_receive_probe_packet(int ioaddr)
{
int starttime;
starttime = jiffies;
- while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0)
- {
- if( (jiffies - starttime) > TIMEOUT_TICKS)
- {
+ while((inb(ioaddr + TX_STATUS_REG) & 0x20) == 0) {
+ if( (jiffies - starttime) > TX_TIMEOUT) {
+
if(eth16i_debug > 1)
- printk("Timeout occurred waiting transmit packet received\n");
+ printk(KERN_DEBUG "Timeout occured waiting transmit packet received\n");
starttime = jiffies;
- while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0)
- {
- if( (jiffies - starttime) > TIMEOUT_TICKS)
- {
+ while((inb(ioaddr + RX_STATUS_REG) & 0x80) == 0) {
+ if( (jiffies - starttime) > TX_TIMEOUT) {
if(eth16i_debug > 1)
- printk("Timeout occurred waiting receive packet\n");
+ printk(KERN_DEBUG "Timeout occured waiting receive packet\n");
return -1;
}
}
if(eth16i_debug > 1)
- printk("RECEIVE_PACKET\n");
+ printk(KERN_DEBUG "RECEIVE_PACKET\n");
return(0); /* Found receive packet */
}
}
if(eth16i_debug > 1) {
- printk("TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
- printk("RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
+ printk(KERN_DEBUG "TRANSMIT_PACKET_RECEIVED %x\n", inb(ioaddr + TX_STATUS_REG));
+ printk(KERN_DEBUG "RX_STATUS_REG = %x\n", inb(ioaddr + RX_STATUS_REG));
}
return(0); /* Return success */
}
-static int eth16i_get_irq(short ioaddr)
+#if 0
+static int eth16i_set_irq(struct device* dev)
+{
+ const int ioaddr = dev->base_addr;
+ const int irq = dev->irq;
+ int i = 0;
+
+ if(ioaddr < 0x1000) {
+ while(eth16i_irqmap[i] && eth16i_irqmap[i] != irq)
+ i++;
+
+ if(i < NUM_OF_ISA_IRQS) {
+ u8 cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
+ cbyte = (cbyte & 0x3F) | (i << 6);
+ outb(cbyte, ioaddr + JUMPERLESS_CONFIG);
+ return 0;
+ }
+ }
+ else {
+ printk(KERN_NOTICE "%s: EISA Interrupt cannot be set. Use EISA Configuration utility.\n", dev->name);
+ }
+
+ return -1;
+
+}
+#endif
+
+static int eth16i_get_irq(int ioaddr)
{
unsigned char cbyte;
if( ioaddr < 0x1000) {
cbyte = inb(ioaddr + JUMPERLESS_CONFIG);
- return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
- } else { /* Oh..the card is EISA so method getting IRQ different */
- unsigned short index = 0;
- cbyte = inb(ioaddr + EISA_IRQ_REG);
- while( (cbyte & 0x01) == 0) {
- cbyte = cbyte >> 1;
- index++;
- }
- return( eth32i_irqmap[ index ] );
+ return( eth16i_irqmap[ ((cbyte & 0xC0) >> 6) ] );
+ } else { /* Oh..the card is EISA so method getting IRQ different */
+ unsigned short index = 0;
+ cbyte = inb(ioaddr + EISA_IRQ_REG);
+ while( (cbyte & 0x01) == 0) {
+ cbyte = cbyte >> 1;
+ index++;
+ }
+ return( eth32i_irqmap[ index ] );
}
}
-static int eth16i_check_signature(short ioaddr)
+static int eth16i_check_signature(int ioaddr)
{
int i;
unsigned char creg[4] = { 0 };
@@ -718,36 +878,37 @@ static int eth16i_check_signature(short ioaddr)
creg[i] = inb(ioaddr + TRANSMIT_MODE_REG + i);
if(eth16i_debug > 1)
- printk("eth16i: read signature byte %x at %x\n", creg[i],
- ioaddr + TRANSMIT_MODE_REG + i);
+ printk("eth16i: read signature byte %x at %x\n",
+ creg[i],
+ ioaddr + TRANSMIT_MODE_REG + i);
}
creg[0] &= 0x0F; /* Mask collision cnr */
creg[2] &= 0x7F; /* Mask DCLEN bit */
-#if 0
-/*
- This was removed because the card was sometimes left to state
- from which it couldn't be find anymore. If there is need
- to have a more strict check still this have to be fixed.
-*/
- if( !( (creg[0] == 0x06) && (creg[1] == 0x41)) ) {
+#ifdef 0
+ /*
+ This was removed because the card was sometimes left to state
+ from which it couldn't be find anymore. If there is need
+ to more strict check still this have to be fixed.
+ */
+ if( ! ((creg[0] == 0x06) && (creg[1] == 0x41)) ) {
if(creg[1] != 0x42)
return -1;
}
#endif
- if( !( (creg[2] == 0x36) && (creg[3] == 0xE0)) )
- {
- creg[2] &= 0x42;
+ if( !((creg[2] == 0x36) && (creg[3] == 0xE0)) ) {
+ creg[2] &= 0x40;
creg[3] &= 0x03;
-
- if( !( (creg[2] == 0x42) && (creg[3] == 0x00)) )
+
+ if( !((creg[2] == 0x40) && (creg[3] == 0x00)) )
return -1;
}
-
+
if(eth16i_read_eeprom(ioaddr, E_NODEID_0) != 0)
return -1;
+
if((eth16i_read_eeprom(ioaddr, E_NODEID_1) & 0xFF00) != 0x4B00)
return -1;
@@ -763,20 +924,22 @@ static int eth16i_read_eeprom(int ioaddr, int offset)
data = eth16i_read_eeprom_word(ioaddr);
outb(CS_0 | SK_0, ioaddr + EEPROM_CTRL_REG);
- return(data);
+ return(data);
}
static int eth16i_read_eeprom_word(int ioaddr)
{
int i;
int data = 0;
-
+
for(i = 16; i > 0; i--) {
outb(CS_1 | SK_0, ioaddr + EEPROM_CTRL_REG);
eeprom_slow_io();
outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
eeprom_slow_io();
- data = (data << 1) | ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
+ data = (data << 1) |
+ ((inb(ioaddr + EEPROM_DATA_REG) & DI_1) ? 1 : 0);
+
eeprom_slow_io();
}
@@ -800,25 +963,26 @@ static void eth16i_eeprom_cmd(int ioaddr, unsigned char command)
eeprom_slow_io();
outb(CS_1 | SK_1, ioaddr + EEPROM_CTRL_REG);
eeprom_slow_io();
- }
+ }
}
static int eth16i_open(struct device *dev)
{
struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
int ioaddr = dev->base_addr;
-
+
/* Powerup the chip */
outb(0xc0 | POWERUP, ioaddr + CONFIG_REG_1);
/* Initialize the chip */
- eth16i_initialize(dev);
+ eth16i_initialize(dev);
/* Set the transmit buffer size */
lp->tx_buf_size = eth16i_tx_buf_map[ETH16I_TX_BUF_SIZE & 0x03];
- if(eth16i_debug > 3)
- printk("%s: transmit buffer size %d\n", dev->name, lp->tx_buf_size);
+ if(eth16i_debug > 0)
+ printk(KERN_DEBUG "%s: transmit buffer size %d\n",
+ dev->name, lp->tx_buf_size);
/* Now enable Transmitter and Receiver sections */
BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
@@ -832,15 +996,13 @@ static int eth16i_open(struct device *dev)
lp->tx_queue_len = 0;
/* Turn on interrupts*/
- outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
+ outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
dev->tbusy = 0;
dev->interrupt = 0;
dev->start = 1;
-#ifdef MODULE
MOD_INC_USE_COUNT;
-#endif
return 0;
}
@@ -850,23 +1012,26 @@ static int eth16i_close(struct device *dev)
struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
int ioaddr = dev->base_addr;
- lp->open_time = 0;
+ eth16i_reset(dev);
+
+ /* Turn off interrupts*/
+ outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
- dev->tbusy = 1;
dev->start = 0;
+ dev->tbusy = 1;
+
+ lp->open_time = 0;
/* Disable transmit and receive */
BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
/* Reset the chip */
- outb(0xff, ioaddr + RESET);
-
- /* Save some energy by switching off power */
- BITCLR(ioaddr + CONFIG_REG_1, POWERUP);
+ /* outb(0xff, ioaddr + RESET); */
+ /* outw(0xffff, ioaddr + TX_STATUS_REG); */
+
+ outb(0x00, ioaddr + CONFIG_REG_1);
-#ifdef MODULE
MOD_DEC_USE_COUNT;
-#endif
return 0;
}
@@ -875,88 +1040,120 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev)
{
struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
int ioaddr = dev->base_addr;
+ int status = 0;
if(dev->tbusy) {
- /*
- If we get here, some higher level has decided that we are broken.
- There should really be a "kick me" function call instead.
- */
+
+ /*
+ If we get here, some higher level has decided that
+ we are broken. There should really be a "kick me"
+ function call instead.
+ */
int tickssofar = jiffies - dev->trans_start;
- if(tickssofar < TIMEOUT_TICKS) /* Let's not rush with our timeout, */
- return 1; /* wait a couple of ticks first */
+ if(tickssofar < TX_TIMEOUT)
+ return 1;
- printk("%s: transmit timed out with status %04x, %s ?\n", dev->name,
- inw(ioaddr + TX_STATUS_REG),
- (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
- "IRQ conflict" : "network cable problem");
+ outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
- /* Let's dump all registers */
- if(eth16i_debug > 0) {
- printk("%s: timeout regs: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
- dev->name, inb(ioaddr + 0), inb(ioaddr + 1), inb(ioaddr + 2),
- inb(ioaddr + 3), inb(ioaddr + 4), inb(ioaddr + 5),
- inb(ioaddr + 6), inb(ioaddr + 7));
+ printk(KERN_WARNING "%s: transmit timed out with status %04x, %s ?\n",
+ dev->name,
+ inw(ioaddr + TX_STATUS_REG),
+ (inb(ioaddr + TX_STATUS_REG) & TX_DONE) ?
+ "IRQ conflict" : "network cable problem");
+ dev->trans_start = jiffies;
- printk("lp->tx_queue = %d\n", lp->tx_queue);
- printk("lp->tx_queue_len = %d\n", lp->tx_queue_len);
- printk("lp->tx_started = %d\n", lp->tx_started);
+ /* Let's dump all registers */
+ if(eth16i_debug > 0) {
+ printk(KERN_DEBUG "%s: timeout: %02x %02x %02x %02x %02x %02x %02x %02x.\n",
+ dev->name, inb(ioaddr + 0),
+ inb(ioaddr + 1), inb(ioaddr + 2),
+ inb(ioaddr + 3), inb(ioaddr + 4),
+ inb(ioaddr + 5),
+ inb(ioaddr + 6), inb(ioaddr + 7));
+
+ printk(KERN_DEBUG "%s: transmit start reg: %02x. collision reg %02x\n",
+ dev->name, inb(ioaddr + TRANSMIT_START_REG),
+ inb(ioaddr + COL_16_REG));
+
+ printk(KERN_DEBUG "lp->tx_queue = %d\n", lp->tx_queue);
+ printk(KERN_DEBUG "lp->tx_queue_len = %d\n", lp->tx_queue_len);
+ printk(KERN_DEBUG "lp->tx_started = %d\n", lp->tx_started);
}
lp->stats.tx_errors++;
- /* Now let's try to restart the adaptor */
-
- BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
- outw(0xffff, ioaddr + RESET);
- eth16i_initialize(dev);
- outw(0xffff, ioaddr + TX_STATUS_REG);
- BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
+ eth16i_reset(dev);
- lp->tx_started = 0;
- lp->tx_queue = 0;
- lp->tx_queue_len = 0;
+ dev->trans_start = jiffies;
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
- dev->tbusy = 0;
- dev->trans_start = jiffies;
}
- /* Block a timer based transmitter from overlapping. This could better be
- done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+ /*
+ If some higher layer thinks we've missed an tx-done interrupt
+ we are passed NULL. Caution: dev_tint() handles the cli()/sti()
+ itself
+ */
+
+ if(skb == NULL) {
+#if LINUX_VERSION_CODE < 0x020100
+ dev_tint(dev);
+#endif
+ if(eth16i_debug > 0)
+ printk(KERN_WARNING "%s: Missed tx-done interrupt.\n", dev->name);
+ return 0;
+ }
+
+ /* Block a timer based transmitter from overlapping.
+ This could better be done with atomic_swap(1, dev->tbusy),
+ but set_bit() works as well. */
+ set_bit(0, (void *)&lp->tx_buf_busy);
+
/* Turn off TX interrupts */
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
- if(test_and_set_bit(0, (void *)&dev->tbusy) != 0)
- printk("%s: Transmitter access conflict.\n", dev->name);
+ if(test_and_set_bit(0, (void *)&dev->tbusy) != 0) {
+ printk(KERN_WARNING "%s: Transmitter access conflict.\n", dev->name);
+ status = -1;
+ }
else {
- short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
+ ushort length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
unsigned char *buf = skb->data;
- outw(length, ioaddr + DATAPORT);
+ if( (length + 2) > (lp->tx_buf_size - lp->tx_queue_len)) {
+ if(eth16i_debug > 0)
+ printk(KERN_WARNING "%s: Transmit buffer full.\n", dev->name);
+ }
+ else {
+ outw(length, ioaddr + DATAPORT);
- if( ioaddr < 0x1000 )
- outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
- else
- {
- unsigned char frag = length % 4;
+ if( ioaddr < 0x1000 )
+ outsw(ioaddr + DATAPORT, buf, (length + 1) >> 1);
+ else {
+ unsigned char frag = length % 4;
- outsl(ioaddr + DATAPORT, buf, length >> 2);
+ outsl(ioaddr + DATAPORT, buf, length >> 2);
- if( frag != 0 )
- {
- outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
- if( frag == 3 )
- outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC) + 2), 1);
+ if( frag != 0 ) {
+ outsw(ioaddr + DATAPORT, (buf + (length & 0xFFFC)), 1);
+ if( frag == 3 )
+ outsw(ioaddr + DATAPORT,
+ (buf + (length & 0xFFFC) + 2), 1);
+ }
}
- }
- lp->tx_queue++;
- lp->tx_queue_len += length + 2;
+ lp->tx_buffered_packets++;
+ lp->tx_queue++;
+ lp->tx_queue_len += length + 2;
+
+ }
+
+ lp->tx_buf_busy = 0;
if(lp->tx_started == 0) {
/* If the transmitter is idle..always trigger a transmit */
@@ -971,15 +1168,21 @@ static int eth16i_tx(struct sk_buff *skb, struct device *dev)
/* There is still more room for one more packet in tx buffer */
dev->tbusy = 0;
}
-
+
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
+
/* Turn TX interrupts back on */
/* outb(TX_INTR_DONE | TX_INTR_16_COL, ioaddr + TX_INTR_REG); */
- }
+ status = 0;
+ }
+
+#if LINUX_VERSION_CODE >= 0x020100
dev_kfree_skb(skb);
+#else
+ dev_kfree_skb(skb, FREE_WRITE);
+#endif
- return 0;
+ return status;
}
static void eth16i_rx(struct device *dev)
@@ -989,71 +1192,63 @@ static void eth16i_rx(struct device *dev)
int boguscount = MAX_RX_LOOP;
/* Loop until all packets have been read */
- while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0)
- {
- /* Read status byte from receive buffer */
+ while( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) {
+
+ /* Read status byte from receive buffer */
ushort status = inw(ioaddr + DATAPORT);
- if(eth16i_debug > 4)
- printk("%s: Receiving packet mode %02x status %04x.\n",
- dev->name, inb(ioaddr + RECEIVE_MODE_REG), status);
+ /* Get the size of the packet from receive buffer */
+ ushort pkt_len = inw(ioaddr + DATAPORT);
- if( !(status & PKT_GOOD) )
- {
- /* Hmm..something went wrong. Let's check what error occurred */
+ if(eth16i_debug > 4)
+ printk(KERN_DEBUG "%s: Receiving packet mode %02x status %04x.\n",
+ dev->name,
+ inb(ioaddr + RECEIVE_MODE_REG), status);
+
+ if( !(status & PKT_GOOD) ) {
lp->stats.rx_errors++;
- if( status & PKT_SHORT)
+
+ if( (pkt_len < ETH_ZLEN) || (pkt_len > ETH_FRAME_LEN) ) {
lp->stats.rx_length_errors++;
- if( status & PKT_ALIGN_ERR )
- lp->stats.rx_frame_errors++;
- if( status & PKT_CRC_ERR )
- lp->stats.rx_crc_errors++;
- if( status & PKT_RX_BUF_OVERFLOW)
- lp->stats.rx_over_errors++;
+ eth16i_reset(dev);
+ return;
+ }
+ else {
+ eth16i_skip_packet(dev);
+ lp->stats.rx_dropped++;
+ }
}
- else
- { /* Ok so now we should have a good packet */
+ else { /* Ok so now we should have a good packet */
struct sk_buff *skb;
- /* Get the size of the packet from receive buffer */
- ushort pkt_len = inw(ioaddr + DATAPORT);
-
- if(pkt_len > ETH_FRAME_LEN)
- {
- printk("%s: %s claimed a very large packet, size of %d bytes.\n",
- dev->name, cardname, pkt_len);
- outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
- lp->stats.rx_dropped++;
- break;
- }
skb = dev_alloc_skb(pkt_len + 3);
- if( skb == NULL )
- {
- printk("%s: Couldn't allocate memory for packet (len %d)\n",
- dev->name, pkt_len);
- outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
+ if( skb == NULL ) {
+ printk(KERN_WARNING "%s: Could'n allocate memory for packet (len %d)\n",
+ dev->name, pkt_len);
+ eth16i_skip_packet(dev);
lp->stats.rx_dropped++;
break;
}
+
skb->dev = dev;
skb_reserve(skb,2);
- /*
- Now let's get the packet out of buffer.
- size is (pkt_len + 1) >> 1, cause we are now reading words
- and it has to be even aligned.
- */
-
- if( ioaddr < 0x1000)
- insw(ioaddr + DATAPORT, skb_put(skb, pkt_len), (pkt_len + 1) >> 1);
- else
- {
+
+ /*
+ Now let's get the packet out of buffer.
+ size is (pkt_len + 1) >> 1, cause we are now reading words
+ and it have to be even aligned.
+ */
+
+ if(ioaddr < 0x1000)
+ insw(ioaddr + DATAPORT, skb_put(skb, pkt_len),
+ (pkt_len + 1) >> 1);
+ else {
unsigned char *buf = skb_put(skb, pkt_len);
unsigned char frag = pkt_len % 4;
insl(ioaddr + DATAPORT, buf, pkt_len >> 2);
- if(frag != 0)
- {
+ if(frag != 0) {
unsigned short rest[2];
rest[0] = inw( ioaddr + DATAPORT );
if(frag == 3)
@@ -1067,13 +1262,13 @@ static void eth16i_rx(struct device *dev)
netif_rx(skb);
lp->stats.rx_packets++;
- if( eth16i_debug > 5 )
- {
+ if( eth16i_debug > 5 ) {
int i;
- printk("%s: Received packet of length %d.\n", dev->name, pkt_len);
- for(i = 0; i < 14; i++)
- printk(" %02x", skb->data[i]);
- printk(".\n");
+ printk(KERN_DEBUG "%s: Received packet of length %d.\n",
+ dev->name, pkt_len);
+ for(i = 0; i < 14; i++)
+ printk(KERN_DEBUG " %02x", skb->data[i]);
+ printk(KERN_DEBUG ".\n");
}
} /* else */
@@ -1087,16 +1282,16 @@ static void eth16i_rx(struct device *dev)
{
int i;
- for(i = 0; i < 20; i++)
- {
- if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == RX_BUFFER_EMPTY)
+ for(i = 0; i < 20; i++) {
+ if( (inb(ioaddr+RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) ==
+ RX_BUFFER_EMPTY)
break;
inw(ioaddr + DATAPORT);
- outb(RX_BUF_SKIP_PACKET, ioaddr + FILTER_SELF_RX_REG);
+ outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
}
if(eth16i_debug > 1)
- printk("%s: Flushed receive buffer.\n", dev->name);
+ printk(KERN_DEBUG "%s: Flushed receive buffer.\n", dev->name);
}
#endif
@@ -1108,126 +1303,302 @@ static void eth16i_interrupt(int irq, void *dev_id, struct pt_regs *regs)
struct device *dev = dev_id;
struct eth16i_local *lp;
int ioaddr = 0,
- status;
+ status;
if(dev == NULL) {
- printk("eth16i_interrupt(): irq %d for unknown device. \n", irq);
+ printk(KERN_WARNING "eth16i_interrupt(): irq %d for unknown device. \n", irq);
return;
}
/* Turn off all interrupts from adapter */
outw(ETH16I_INTR_OFF, ioaddr + TX_INTR_REG);
+ set_bit(0, (void *)&dev->tbusy); /* Set the device busy so that */
+ /* eth16i_tx wont be called */
+
+ if(dev->interrupt)
+ printk(KERN_WARNING "%s: Re-entering the interrupt handler.\n", dev->name);
dev->interrupt = 1;
ioaddr = dev->base_addr;
lp = (struct eth16i_local *)dev->priv;
- status = inw(ioaddr + TX_STATUS_REG); /* Get the status */
- outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */
+ status = inw(ioaddr + TX_STATUS_REG); /* Get the status */
+ outw(status, ioaddr + TX_STATUS_REG); /* Clear status bits */
if(eth16i_debug > 3)
- printk("%s: Interrupt with status %04x.\n", dev->name, status);
-
- if( status & 0x00ff ) { /* Let's check the transmit status reg */
- if(status & TX_DONE)
- { /* The transmit has been done */
- lp->stats.tx_packets++;
- if(lp->tx_queue)
- { /* Are there still packets ? */
+ printk(KERN_DEBUG "%s: Interrupt with status %04x.\n", dev->name, status);
+
+ if( status & 0x7f00 ) {
+
+ lp->stats.rx_errors++;
+
+ if(status & (BUS_RD_ERR << 8) )
+ printk(KERN_WARNING "%s: Bus read error.\n",dev->name);
+ if(status & (SHORT_PKT_ERR << 8) ) lp->stats.rx_length_errors++;
+ if(status & (ALIGN_ERR << 8) ) lp->stats.rx_frame_errors++;
+ if(status & (CRC_ERR << 8) ) lp->stats.rx_crc_errors++;
+ if(status & (RX_BUF_OVERFLOW << 8) ) lp->stats.rx_over_errors++;
+ }
+ if( status & 0x001a) {
+
+ lp->stats.tx_errors++;
+
+ if(status & CR_LOST) lp->stats.tx_carrier_errors++;
+ if(status & TX_JABBER_ERR) lp->stats.tx_window_errors++;
+
+#if 0
+ if(status & COLLISION) {
+ lp->stats.collisions +=
+ ((inb(ioaddr+TRANSMIT_MODE_REG) & 0xF0) >> 4);
+ }
+#endif
+ if(status & COLLISIONS_16) {
+ if(lp->col_16 < MAX_COL_16) {
+ lp->col_16++;
+ lp->stats.collisions++;
+ /* Resume transmitting, skip failed packet */
+ outb(0x02, ioaddr + COL_16_REG);
+ }
+ else {
+ printk(KERN_WARNING "%s: bailing out due to many consecutive 16-in-a-row collisions. Network cable problem?\n", dev->name);
+ }
+ }
+ }
+
+ if( status & 0x00ff ) { /* Let's check the transmit status reg */
+
+ if(status & TX_DONE) { /* The transmit has been done */
+ lp->stats.tx_packets = lp->tx_buffered_packets;
+ lp->col_16 = 0;
+
+ if(lp->tx_queue) { /* Is there still packets ? */
/* There was packet(s) so start transmitting and write also
- how many packets there is to be sent */
+ how many packets there is to be sended */
outb(TX_START | lp->tx_queue, ioaddr + TRANSMIT_START_REG);
lp->tx_queue = 0;
lp->tx_queue_len = 0;
+ lp->tx_started = 1;
dev->trans_start = jiffies;
- dev->tbusy = 0;
- mark_bh(NET_BH);
+ mark_bh(NET_BH);
}
- else
- {
+ else {
lp->tx_started = 0;
- dev->tbusy = 0;
mark_bh(NET_BH);
}
}
}
- if( ( status & 0xff00 ) ||
- ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
- eth16i_rx(dev); /* We have packet in receive buffer */
- }
-
+ if( ( status & 0x8000 ) ||
+ ( (inb(ioaddr + RECEIVE_MODE_REG) & RX_BUFFER_EMPTY) == 0) ) {
+ eth16i_rx(dev); /* We have packet in receive buffer */
+ }
+
dev->interrupt = 0;
-
+
/* Turn interrupts back on */
outw(ETH16I_INTR_ON, ioaddr + TX_INTR_REG);
-
+
+ if(lp->tx_queue_len < lp->tx_buf_size - (ETH_FRAME_LEN + 2)) {
+ /* There is still more room for one more packet in tx buffer */
+ dev->tbusy = 0;
+ }
+
return;
}
-static void eth16i_multicast(struct device *dev)
+static void eth16i_skip_packet(struct device *dev)
+{
+ int ioaddr = dev->base_addr;
+
+ inw(ioaddr + DATAPORT);
+ inw(ioaddr + DATAPORT);
+ inw(ioaddr + DATAPORT);
+
+ outb(SKIP_RX_PACKET, ioaddr + FILTER_SELF_RX_REG);
+ while( inb( ioaddr + FILTER_SELF_RX_REG ) != 0);
+}
+
+static void eth16i_reset(struct device *dev)
{
- short ioaddr = dev->base_addr;
+ struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
+ int ioaddr = dev->base_addr;
+
+ if(eth16i_debug > 1)
+ printk(KERN_DEBUG "%s: Resetting device.\n", dev->name);
+
+ BITSET(ioaddr + CONFIG_REG_0, DLC_EN);
+ outw(0xffff, ioaddr + TX_STATUS_REG);
+ eth16i_select_regbank(2, ioaddr);
+
+ lp->tx_started = 0;
+ lp->tx_buf_busy = 0;
+ lp->tx_queue = 0;
+ lp->tx_queue_len = 0;
+
+ dev->interrupt = 0;
+ dev->start = 1;
+ dev->tbusy = 0;
+ BITCLR(ioaddr + CONFIG_REG_0, DLC_EN);
+}
- if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
+static void eth16i_multicast(struct device *dev)
+{
+ int ioaddr = dev->base_addr;
+
+ if(dev->mc_count || dev->flags&(IFF_ALLMULTI|IFF_PROMISC))
{
dev->flags|=IFF_PROMISC; /* Must do this */
- outb(3, ioaddr + RECEIVE_MODE_REG);
+ outb(3, ioaddr + RECEIVE_MODE_REG);
} else {
outb(2, ioaddr + RECEIVE_MODE_REG);
}
}
-static struct net_device_stats *eth16i_get_stats(struct device *dev)
+static struct enet_statistics *eth16i_get_stats(struct device *dev)
{
struct eth16i_local *lp = (struct eth16i_local *)dev->priv;
return &lp->stats;
}
-static void eth16i_select_regbank(unsigned char banknbr, short ioaddr)
+static void eth16i_select_regbank(unsigned char banknbr, int ioaddr)
{
unsigned char data;
data = inb(ioaddr + CONFIG_REG_1);
- outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
+ outb( ((data & 0xF3) | ( (banknbr & 0x03) << 2)), ioaddr + CONFIG_REG_1);
}
#ifdef MODULE
-static char devicename[9] = { 0, };
-static struct device dev_eth16i = {
- devicename,
- 0, 0, 0, 0,
- 0, 0,
- 0, 0, 0, NULL, eth16i_probe
+
+static ushort eth16i_parse_mediatype(const char* s)
+{
+ if(!s)
+ return E_PORT_FROM_EPROM;
+
+ if (!strncmp(s, "bnc", 3))
+ return E_PORT_BNC;
+ else if (!strncmp(s, "tp", 2))
+ return E_PORT_TP;
+ else if (!strncmp(s, "dix", 3))
+ return E_PORT_DIX;
+ else if (!strncmp(s, "auto", 4))
+ return E_PORT_AUTO;
+ else
+ return E_PORT_FROM_EPROM;
+}
+
+#define MAX_ETH16I_CARDS 4 /* Max number of Eth16i cards per module */
+#define NAMELEN 8 /* number of chars for storing dev->name */
+
+static char namelist[NAMELEN * MAX_ETH16I_CARDS] = { 0, };
+static struct device dev_eth16i[MAX_ETH16I_CARDS] = {
+ {
+ NULL,
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, NULL
+ },
};
-int io = 0x2a0;
-int irq = 0;
+static int ioaddr[MAX_ETH16I_CARDS] = { 0, };
+#if 0
+static int irq[MAX_ETH16I_CARDS] = { 0, };
+#endif
+static char* mediatype[MAX_ETH16I_CARDS] = { 0, };
+static int debug = -1;
-MODULE_PARM(io, "i");
-MODULE_PARM(irq, "i");
+#if (LINUX_VERSION_CODE >= 0x20115)
+MODULE_AUTHOR("Mika Kuoppala <miku@iki.fi>");
+MODULE_DESCRIPTION("ICL EtherTeam 16i/32 driver");
+
+MODULE_PARM(ioaddr, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
+MODULE_PARM_DESC(ioaddr, "eth16i io base address");
+
+#if 0
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "i");
+MODULE_PARM_DESC(irq, "eth16i interrupt request number");
+#endif
+
+MODULE_PARM(mediatype, "1-" __MODULE_STRING(MAX_ETH16I_CARDS) "s");
+MODULE_PARM_DESC(mediatype, "eth16i interfaceport mediatype");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "eth16i debug level (0-4)");
+#endif
int init_module(void)
{
- if(io == 0)
- printk("eth16i: You should not use auto-probing with insmod!\n");
-
- dev_eth16i.base_addr = io;
- dev_eth16i.irq = irq;
- if( register_netdev( &dev_eth16i ) != 0 ) {
- printk("eth16i: register_netdev() returned non-zero.\n");
- return -EIO;
- }
+ int this_dev, found = 0;
+
+ for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
+ {
+ struct device *dev = &dev_eth16i[this_dev];
+
+ dev->name = namelist + (NAMELEN*this_dev);
+ dev->irq = 0; /* irq[this_dev]; */
+ dev->base_addr = ioaddr[this_dev];
+ dev->init = eth16i_probe;
+
+ if(debug != -1)
+ eth16i_debug = debug;
+
+ if(eth16i_debug > 1)
+ printk(KERN_NOTICE "eth16i(%d): interface type %s\n", this_dev, mediatype[this_dev] ? mediatype[this_dev] : "none" );
+
+ dev->if_port = eth16i_parse_mediatype(mediatype[this_dev]);
+
+ if(ioaddr[this_dev] == 0)
+ {
+ if(this_dev != 0) break; /* Only autoprobe 1st one */
+ printk(KERN_NOTICE "eth16i.c: Presently autoprobing (not recommended) for a single card.\n");
+ }
+
+ if(register_netdev(dev) != 0)
+ {
+ printk(KERN_WARNING "eth16i.c No Eth16i card found (i/o = 0x%x).\n",
+ ioaddr[this_dev]);
+
+ if(found != 0) return 0;
+ return -ENXIO;
+ }
+
+ found++;
+ }
return 0;
}
-
+
void cleanup_module(void)
{
- unregister_netdev( &dev_eth16i );
- free_irq( dev_eth16i.irq, &dev_eth16i );
- release_region( dev_eth16i.base_addr, ETH16I_IO_EXTENT );
-}
+ int this_dev;
+ for(this_dev = 0; this_dev < MAX_ETH16I_CARDS; this_dev++)
+ {
+ struct device* dev = &dev_eth16i[this_dev];
+
+ if(dev->priv != NULL)
+ {
+ unregister_netdev(dev);
+ kfree(dev->priv);
+ dev->priv = NULL;
+
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, ETH16I_IO_EXTENT);
+
+ }
+ }
+}
#endif /* MODULE */
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c eth16i.c"
+ * alt-compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict -prototypes -O6 -c eth16i.c"
+ * tab-width: 8
+ * c-basic-offset: 8
+ * c-indent-level: 8
+ * End:
+ */
+
+/* End of file eth16i.c */
diff --git a/drivers/net/ethertap.c b/drivers/net/ethertap.c
index 49e84fd06..46b7babd4 100644
--- a/drivers/net/ethertap.c
+++ b/drivers/net/ethertap.c
@@ -7,7 +7,7 @@
* on it will attempt to ARP the user space and reply to ARPS from the
* user space.
*
- * As this is an ethernet device you cau use it for appletalk, IPX etc
+ * As this is an ethernet device you can use it for appletalk, IPX etc
* even for building bridging tunnels.
*/
@@ -329,7 +329,7 @@ static struct net_device_stats *ethertap_get_stats(struct device *dev)
#ifdef MODULE
-int unit;
+static int unit;
MODULE_PARM(unit,"i");
static char devicename[9] = { 0, };
diff --git a/drivers/net/hamradio/6pack.c b/drivers/net/hamradio/6pack.c
index 198ba1633..99bd59e9a 100644
--- a/drivers/net/hamradio/6pack.c
+++ b/drivers/net/hamradio/6pack.c
@@ -726,7 +726,7 @@ static int sp_open_dev(struct device *dev)
#ifdef MODULE
static int sixpack_init_ctrl_dev(void)
#else /* !MODULE */
-__initfunc sixpack_init_ctrl_dev(struct device *dummy)
+__initfunc(int sixpack_init_ctrl_dev(struct device *dummy))
#endif /* !MODULE */
{
int status;
diff --git a/drivers/net/hamradio/baycom_epp.c b/drivers/net/hamradio/baycom_epp.c
index 2a2f4e909..f7b3156fc 100644
--- a/drivers/net/hamradio/baycom_epp.c
+++ b/drivers/net/hamradio/baycom_epp.c
@@ -1010,14 +1010,6 @@ static struct net_device_stats *baycom_get_stats(struct device *dev)
/* --------------------------------------------------------------------- */
-static int epp_preempt(void *handle)
-{
- /* we cannot relinquish the port in the middle of an operation */
- return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
static void epp_wakeup(void *handle)
{
struct device *dev = (struct device *)handle;
@@ -1070,8 +1062,8 @@ static int epp_open(struct device *dev)
}
#endif
memset(&bc->modem, 0, sizeof(bc->modem));
- if (!(bc->pdev = parport_register_device(pp, dev->name, epp_preempt, epp_wakeup,
- epp_interrupt, PARPORT_DEV_LURK, dev))) {
+ if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, epp_wakeup,
+ epp_interrupt, PARPORT_DEV_EXCL, dev))) {
printk(KERN_ERR "%s: cannot register parport at 0x%lx\n", bc_drvname, pp->base);
return -ENXIO;
}
@@ -1548,7 +1540,7 @@ __initfunc(void baycom_epp_setup(char *str, int *ints))
return;
}
baycom_ports[i].mode = str;
- baycom_ports[i].irq = ints[1];
+ baycom_ports[i].iobase = ints[1];
if (i < NR_PORTS-1)
baycom_ports[i+1].mode = NULL;
}
diff --git a/drivers/net/hamradio/baycom_par.c b/drivers/net/hamradio/baycom_par.c
index e79a00ef6..bbc29e4c1 100644
--- a/drivers/net/hamradio/baycom_par.c
+++ b/drivers/net/hamradio/baycom_par.c
@@ -357,14 +357,6 @@ static void par96_interrupt(int irq, void *dev_id, struct pt_regs *regs)
/* --------------------------------------------------------------------- */
-static int par96_preempt(void *handle)
-{
- /* we cannot relinquish the port in the middle of an operation */
- return 1;
-}
-
-/* --------------------------------------------------------------------- */
-
static void par96_wakeup(void *handle)
{
struct device *dev = (struct device *)handle;
@@ -396,8 +388,8 @@ static int par96_open(struct device *dev)
}
memset(&bc->modem, 0, sizeof(bc->modem));
bc->hdrv.par.bitrate = 9600;
- if (!(bc->pdev = parport_register_device(pp, dev->name, par96_preempt, par96_wakeup,
- par96_interrupt, PARPORT_DEV_LURK, dev))) {
+ if (!(bc->pdev = parport_register_device(pp, dev->name, NULL, par96_wakeup,
+ par96_interrupt, PARPORT_DEV_EXCL, dev))) {
printk(KERN_ERR "baycom_par: cannot register parport at 0x%lx\n", pp->base);
return -ENXIO;
}
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index bf453dc53..ac474d0b9 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -1,5 +1,5 @@
/*
- * $Id: dmascc.c,v 1.2.1.4 1998/06/10 02:24:11 kudielka Exp $
+ * $Id: dmascc.c,v 1.3 1998/09/07 04:41:56 kudielka Exp $
*
* Driver for high-speed SCC boards (those with DMA support)
* Copyright (C) 1997 Klaus Kudielka
@@ -62,6 +62,14 @@
#define test_and_set_bit(x,y) set_bit(x,y)
#define register_netdevice(x) register_netdev(x)
#define unregister_netdevice(x) unregister_netdev(x)
+#define dev_kfree_skb(x) dev_kfree_skb(x,FREE_WRITE)
+#define SET_DEV_INIT(x) (x=dmascc_dev_init)
+
+#define SHDLCE 0x01 /* WR15 */
+
+#define AUTOEOM 0x02 /* WR7' */
+#define RXFIFOH 0x08
+#define TXFIFOE 0x20
static int dmascc_dev_init(struct device *dev)
{
@@ -83,7 +91,7 @@ static void dev_init_buffers(struct device *dev)
#include <linux/init.h>
#include <asm/uaccess.h>
-#define dmascc_dev_init NULL
+#define SET_DEV_INIT(x)
#endif
@@ -286,7 +294,7 @@ static unsigned long rand;
#ifdef MODULE
-MODULE_AUTHOR("Klaus Kudielka <oe1kib@oe1xtu.ampr.org>");
+MODULE_AUTHOR("Klaus Kudielka");
MODULE_DESCRIPTION("Driver for high-speed SCC boards");
MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NUM_DEVS) "i");
@@ -462,8 +470,8 @@ __initfunc(int setup_adapter(int io, int h, int n))
/* Reset 8530 */
write_scc(cmd, R9, FHWRES | MIE | NV);
- /* Determine type of chip */
- write_scc(cmd, R15, 1);
+ /* Determine type of chip by enabling SDLC/HDLC enhancements */
+ write_scc(cmd, R15, SHDLCE);
if (!read_scc(cmd, R15)) {
/* WR7' not present. This is an ordinary Z8530 SCC. */
chip = Z8530;
@@ -575,7 +583,7 @@ __initfunc(int setup_adapter(int io, int h, int n))
dev->hard_header = ax25_encapsulate;
dev->rebuild_header = ax25_rebuild_header;
dev->set_mac_address = scc_set_mac_address;
- dev->init = dmascc_dev_init;
+ SET_DEV_INIT(dev->init);
dev->type = ARPHRD_AX25;
dev->hard_header_len = 73;
dev->mtu = 1500;
@@ -662,17 +670,17 @@ static int scc_open(struct device *dev)
switch (info->chip) {
case Z85C30:
/* Select WR7' */
- write_scc(cmd, R15, 1);
+ write_scc(cmd, R15, SHDLCE);
/* Auto EOM reset */
- write_scc(cmd, R7, 0x02);
+ write_scc(cmd, R7, AUTOEOM);
write_scc(cmd, R15, 0);
break;
case Z85230:
/* Select WR7' */
- write_scc(cmd, R15, 1);
+ write_scc(cmd, R15, SHDLCE);
/* RX FIFO half full (interrupt only), Auto EOM reset,
TX FIFO empty (DMA only) */
- write_scc(cmd, R7, dev->dma ? 0x22 : 0x0a);
+ write_scc(cmd, R7, AUTOEOM | (dev->dma ? TXFIFOE : RXFIFOH));
write_scc(cmd, R15, 0);
break;
}
@@ -958,6 +966,7 @@ static void special_condition(struct device *dev, int rc)
{
struct scc_priv *priv = dev->priv;
int cb, cmd = priv->cmd;
+ unsigned long flags;
/* See Figure 2-15. Only overrun and EOF need to be checked. */
@@ -968,9 +977,12 @@ static void special_condition(struct device *dev, int rc)
} else if (rc & END_FR) {
/* End of frame. Get byte count */
if (dev->dma) {
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
cb = BUF_SIZE - get_dma_residue(dev->dma) - 2;
+ release_dma_lock(flags);
+
} else {
cb = priv->rx_ptr - 2;
}
@@ -1005,9 +1017,13 @@ static void special_condition(struct device *dev, int rc)
}
/* Get ready for new frame */
if (dev->dma) {
+
+ flags=claim_dma_lock();
set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]);
set_dma_count(dev->dma, BUF_SIZE);
enable_dma(dev->dma);
+ release_dma_lock(flags);
+
} else {
priv->rx_ptr = 0;
}
@@ -1094,6 +1110,7 @@ static void es_isr(struct device *dev)
struct scc_info *info = priv->info;
int i, cmd = priv->cmd;
int st, dst, res;
+ unsigned long flags;
/* Read status and reset interrupt bit */
st = read_scc(cmd, R0);
@@ -1110,9 +1127,11 @@ static void es_isr(struct device *dev)
/* Get remaining bytes */
i = priv->tx_tail;
if (dev->dma) {
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
res = get_dma_residue(dev->dma);
+ release_dma_lock(flags);
} else {
res = priv->tx_len[i] - priv->tx_ptr;
if (res) write_scc(cmd, R0, RES_Tx_P);
@@ -1125,9 +1144,11 @@ static void es_isr(struct device *dev)
/* Check if another frame is available and we are allowed to transmit */
if (priv->tx_count && (jiffies - priv->tx_start) < priv->param.txtime) {
if (dev->dma) {
+ flags=claim_dma_lock();
set_dma_addr(dev->dma, (int) priv->tx_buf[priv->tx_tail]);
set_dma_count(dev->dma, priv->tx_len[priv->tx_tail]);
enable_dma(dev->dma);
+ release_dma_lock(flags);
} else {
/* If we have an ESCC, we are allowed to write data bytes
immediately. Otherwise we have to wait for the next
@@ -1162,12 +1183,14 @@ static void es_isr(struct device *dev)
if (st & DCD) {
if (dev->dma) {
/* Program DMA controller */
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
set_dma_mode(dev->dma, DMA_MODE_READ);
set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]);
set_dma_count(dev->dma, BUF_SIZE);
enable_dma(dev->dma);
+ release_dma_lock(flags);
/* Configure PackeTwin DMA */
if (info->type == TYPE_TWIN) {
outb_p((dev->dma == 1) ? TWIN_DMA_HDX_R1 : TWIN_DMA_HDX_R3,
@@ -1187,7 +1210,12 @@ static void es_isr(struct device *dev)
}
} else {
/* Disable DMA */
- if (dev->dma) disable_dma(dev->dma);
+ if (dev->dma)
+ {
+ flags=claim_dma_lock();
+ disable_dma(dev->dma);
+ release_dma_lock(flags);
+ }
/* Disable receiver */
write_scc(cmd, R3, Rx8);
/* DMA disable, RX int disable, Ext int enable */
@@ -1220,11 +1248,13 @@ static void es_isr(struct device *dev)
while (read_scc(cmd, R0) & Rx_CH_AV) read_scc(cmd, R8);
priv->rx_over = 0;
if (dev->dma) {
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
set_dma_addr(dev->dma, (int) priv->rx_buf[priv->rx_head]);
set_dma_count(dev->dma, BUF_SIZE);
enable_dma(dev->dma);
+ release_dma_lock(flags);
} else {
priv->rx_ptr = 0;
}
@@ -1237,6 +1267,7 @@ static void tm_isr(struct device *dev)
struct scc_priv *priv = dev->priv;
struct scc_info *info = priv->info;
int cmd = priv->cmd;
+ unsigned long flags;
switch (priv->tx_state) {
case TX_OFF:
@@ -1258,12 +1289,16 @@ static void tm_isr(struct device *dev)
priv->tx_state = TX_ACTIVE;
if (dev->dma) {
/* Program DMA controller */
+
+ flags=claim_dma_lock();
disable_dma(dev->dma);
clear_dma_ff(dev->dma);
set_dma_mode(dev->dma, DMA_MODE_WRITE);
set_dma_addr(dev->dma, (int) priv->tx_buf[priv->tx_tail]);
set_dma_count(dev->dma, priv->tx_len[priv->tx_tail]);
enable_dma(dev->dma);
+ release_dma_lock(flags);
+
/* Configure PackeTwin DMA */
if (info->type == TYPE_TWIN) {
outb_p((dev->dma == 1) ? TWIN_DMA_HDX_T1 : TWIN_DMA_HDX_T3,
diff --git a/drivers/net/hamradio/hdlcdrv.c b/drivers/net/hamradio/hdlcdrv.c
index 1b2ee9eac..258c5c58c 100644
--- a/drivers/net/hamradio/hdlcdrv.c
+++ b/drivers/net/hamradio/hdlcdrv.c
@@ -42,6 +42,7 @@
#include <linux/config.h>
#include <linux/module.h>
+#include <linux/version.h>
#include <linux/types.h>
#include <linux/net.h>
#include <linux/in.h>
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 4d7b96c40..ab1ecab6a 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -894,7 +894,6 @@ static int ax_set_dev_mac_address(struct device *dev, void *addr)
static int ax25_disp_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
{
struct ax_disp *ax = (struct ax_disp *)tty->disc_data;
- int err;
unsigned int tmp;
/* First make sure we're connected. */
diff --git a/drivers/net/hamradio/soundmodem/sm.c b/drivers/net/hamradio/soundmodem/sm.c
index fbfbb7e36..d1760af4b 100644
--- a/drivers/net/hamradio/soundmodem/sm.c
+++ b/drivers/net/hamradio/soundmodem/sm.c
@@ -554,17 +554,17 @@ static int sm_ioctl(struct device *dev, struct ifreq *ifr,
cp = hi->data.modename;
while (*hwp) {
if ((*hwp)->hw_name)
- cp += sprintf("%s:,", (*hwp)->hw_name);
+ cp += sprintf(cp, "%s:,", (*hwp)->hw_name);
hwp++;
}
while (*mtp) {
if ((*mtp)->name)
- cp += sprintf(">%s,", (*mtp)->name);
+ cp += sprintf(cp, ">%s,", (*mtp)->name);
mtp++;
}
while (*mrp) {
if ((*mrp)->name)
- cp += sprintf("<%s,", (*mrp)->name);
+ cp += sprintf(cp, "<%s,", (*mrp)->name);
mrp++;
}
cp[-1] = '\0';
diff --git a/drivers/net/hamradio/z8530.h b/drivers/net/hamradio/z8530.h
index 3d4a918d7..8bef54857 100644
--- a/drivers/net/hamradio/z8530.h
+++ b/drivers/net/hamradio/z8530.h
@@ -219,15 +219,17 @@
/* Read Register 15 (value of WR 15) */
-/* 8580/85180/85280 Enhanced SCC register definitions */
+/* Z85C30/Z85230 Enhanced SCC register definitions */
/* Write Register 7' (SDLC/HDLC Programmable Enhancements) */
#define AUTOTXF 0x01 /* Auto Tx Flag */
#define AUTOEOM 0x02 /* Auto EOM Latch Reset */
#define AUTORTS 0x04 /* Auto RTS */
#define TXDNRZI 0x08 /* TxD Pulled High in SDLC NRZI mode */
+#define RXFIFOH 0x08 /* Z85230: Int on RX FIFO half full */
#define FASTDTR 0x10 /* Fast DTR/REQ Mode */
#define CRCCBCR 0x20 /* CRC Check Bytes Completely Received */
+#define TXFIFOE 0x20 /* Z85230: Int on TX FIFO completely empty */
#define EXTRDEN 0x40 /* Extended Read Enabled */
/* Write Register 15 (external/status interrupt control) */
@@ -240,4 +242,4 @@
/* Read Register 7 (frame status FIFO) */
#define BCMSB 0x3f /* MSB of 14 bits count */
#define FDA 0x40 /* FIFO Data Available Status */
-#define FOY 0x80 /* FIFO Overflow Status */
+#define FOS 0x80 /* FIFO Overflow Status */
diff --git a/drivers/net/hostess_sv11.c b/drivers/net/hostess_sv11.c
index 3ca2477b5..8317d37e0 100644
--- a/drivers/net/hostess_sv11.c
+++ b/drivers/net/hostess_sv11.c
@@ -1,3 +1,5 @@
+#define LINUX_21
+
/*
* Comtrol SV11 card driver
*
@@ -7,7 +9,7 @@
* Its a genuine Z85230
*
* It supports DMA using two DMA channels in SYNC mode. The driver doesn't
- * use these facilities (yet).
+ * use these facilities
*
* The control port is at io+1, the data at io+3 and turning off the DMA
* is done by writing 0 to io+4
@@ -50,7 +52,7 @@ struct sv11_device
/*
* Frame receive. Simple for our card as we do sync ppp and there
- * is no funny garbage involved. This is very timing sensitive.
+ * is no funny garbage involved
*/
static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
@@ -58,13 +60,12 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
/* Drop the CRC - its not a good idea to try and negotiate it ;) */
skb_trim(skb, skb->len-2);
skb->protocol=htons(ETH_P_WAN_PPP);
+ skb->mac.raw=skb->data;
skb->dev=c->netdevice;
/*
* Send it to the PPP layer. We dont have time to process
* it right now.
*/
- skb->mac.raw = skb->data;
-
netif_rx(skb);
}
@@ -75,15 +76,24 @@ static void hostess_input(struct z8530_channel *c, struct sk_buff *skb)
static int hostess_open(struct device *d)
{
struct sv11_device *sv11=d->priv;
- int err;
+ int err = -1;
/*
* Link layer up
*/
- if(dma)
- err=z8530_sync_dma_open(d, &sv11->sync.chanA);
- else
- err=z8530_sync_open(d, &sv11->sync.chanA);
+ switch(dma)
+ {
+ case 0:
+ err=z8530_sync_open(d, &sv11->sync.chanA);
+ break;
+ case 1:
+ err=z8530_sync_dma_open(d, &sv11->sync.chanA);
+ break;
+ case 2:
+ err=z8530_sync_txdma_open(d, &sv11->sync.chanA);
+ break;
+ }
+
if(err)
return err;
/*
@@ -92,10 +102,18 @@ static int hostess_open(struct device *d)
err=sppp_open(d);
if(err)
{
- if(dma)
- z8530_sync_dma_close(d, &sv11->sync.chanA);
- else
- z8530_sync_close(d, &sv11->sync.chanA);
+ switch(dma)
+ {
+ case 0:
+ z8530_sync_close(d, &sv11->sync.chanA);
+ break;
+ case 1:
+ z8530_sync_dma_close(d, &sv11->sync.chanA);
+ break;
+ case 2:
+ z8530_sync_txdma_close(d, &sv11->sync.chanA);
+ break;
+ }
return err;
}
sv11->sync.chanA.rx_function=hostess_input;
@@ -123,22 +141,31 @@ static int hostess_close(struct device *d)
* Link layer down
*/
d->tbusy=1;
- if(dma)
- z8530_sync_dma_close(d, &sv11->sync.chanA);
- else
- z8530_sync_close(d, &sv11->sync.chanA);
+
+ switch(dma)
+ {
+ case 0:
+ z8530_sync_close(d, &sv11->sync.chanA);
+ break;
+ case 1:
+ z8530_sync_dma_close(d, &sv11->sync.chanA);
+ break;
+ case 2:
+ z8530_sync_txdma_close(d, &sv11->sync.chanA);
+ break;
+ }
MOD_DEC_USE_COUNT;
return 0;
}
static int hostess_ioctl(struct device *d, struct ifreq *ifr, int cmd)
{
- struct sv11_device *sv11=d->priv;
- /* z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
- return sppp_do_ioctl(d, ifr, cmd);
+ /* struct sv11_device *sv11=d->priv;
+ z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */
+ return sppp_do_ioctl(d, ifr,cmd);
}
-static struct net_device_stats *hostess_get_stats(struct device *d)
+static struct enet_statistics *hostess_get_stats(struct device *d)
{
struct sv11_device *sv11=d->priv;
if(sv11)
@@ -157,6 +184,7 @@ static int hostess_queue_xmit(struct sk_buff *skb, struct device *d)
return z8530_queue_xmit(&sv11->sync.chanA, skb);
}
+#ifdef LINUX_21
static int hostess_neigh_setup(struct neighbour *n)
{
if (n->nud_state == NUD_NONE) {
@@ -176,6 +204,15 @@ static int hostess_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
return 0;
}
+#else
+
+static int return_0(struct device *d)
+{
+ return 0;
+}
+
+#endif
+
/*
* Description block for a Comtrol Hostess SV11 card
*/
@@ -243,13 +280,17 @@ static struct sv11_device *sv11_init(int iobase, int irq)
* You can have DMA off or 1 and 3 thats the lot
* on the Comtrol.
*/
- dev->chanA.txdma=1;
- dev->chanA.rxdma=3;
- outb(14, iobase+4); /* DMA on */
+ dev->chanA.txdma=3;
+ dev->chanA.rxdma=1;
+ outb(0x03|0x08, iobase+4); /* DMA on */
if(request_dma(dev->chanA.txdma, "Hostess SV/11 (TX)")!=0)
goto fail;
- if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0)
- goto dmafail;
+
+ if(dma==1)
+ {
+ if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0)
+ goto dmafail;
+ }
}
save_flags(flags);
cli();
@@ -259,7 +300,10 @@ static struct sv11_device *sv11_init(int iobase, int irq)
*/
if(z8530_init(dev)!=0)
+ {
+ printk(KERN_ERR "Z8530 series device not found.\n");
goto dmafail2;
+ }
z8530_channel_load(&dev->chanB, z8530_dead_port);
if(dev->type==Z85C30)
z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream);
@@ -269,8 +313,6 @@ static struct sv11_device *sv11_init(int iobase, int irq)
restore_flags(flags);
- printk(KERN_INFO "begin loading hdlc\n");
-
/*
* Now we can take the IRQ
*/
@@ -291,7 +333,6 @@ static struct sv11_device *sv11_init(int iobase, int irq)
* Local fields
*/
sprintf(sv->name,"hdlc%d", i);
- printk("Filling in device '%s' at %p\n", sv->name, d);
d->name = sv->name;
d->base_addr = iobase;
@@ -305,8 +346,12 @@ static struct sv11_device *sv11_init(int iobase, int irq)
d->get_stats = hostess_get_stats;
d->set_multicast_list = NULL;
d->do_ioctl = hostess_ioctl;
+#ifdef LINUX_21
d->neigh_setup = hostess_neigh_setup_dev;
dev_init_buffers(d);
+#else
+ d->init = return_0;
+#endif
d->set_mac_address = NULL;
if(register_netdev(d)==-1)
@@ -322,11 +367,11 @@ static struct sv11_device *sv11_init(int iobase, int irq)
}
}
dmafail2:
- if(!dma)
- goto fail;
- free_dma(dev->chanA.rxdma);
+ if(dma==1)
+ free_dma(dev->chanA.rxdma);
dmafail:
- free_dma(dev->chanA.txdma);
+ if(dma)
+ free_dma(dev->chanA.txdma);
fail:
free_irq(irq, dev);
fail2:
@@ -342,8 +387,11 @@ static void sv11_shutdown(struct sv11_device *dev)
z8530_shutdown(&dev->sync);
unregister_netdev(&dev->netdev.dev);
free_irq(dev->sync.irq, dev);
- free_dma(dev->sync.chanA.rxdma);
- free_dma(dev->sync.chanA.txdma);
+ if(dma)
+ {
+ free_dma(dev->sync.chanA.rxdma);
+ free_dma(dev->sync.chanA.txdma);
+ }
release_region(dev->sync.chanA.ctrlio-1, 8);
}
@@ -352,6 +400,7 @@ static void sv11_shutdown(struct sv11_device *dev)
static int io=0x200;
static int irq=9;
+#ifdef LINUX_21
MODULE_PARM(io,"i");
MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card");
MODULE_PARM(dma,"i");
@@ -361,12 +410,13 @@ MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 c
MODULE_AUTHOR("Bulding Number Three Ltd");
MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11");
+#endif
static struct sv11_device *sv11_unit;
int init_module(void)
{
- printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n");
+ printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.01.\n");
printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n");
if(dma)
printk(KERN_WARNING "DMA mode probably wont work right now.\n");
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index d39e02ee8..4b415d6cc 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -1144,7 +1144,7 @@ static void hp100_mmuinit( struct device *dev )
/*
* Each pdl is 508 bytes long. (63 frags * 4 bytes for address and
- * 4 bytes for for header). We will leave NUM_RXPDLS * 508 (rounded
+ * 4 bytes for header). We will leave NUM_RXPDLS * 508 (rounded
* to the next higher 1k boundary) bytes for the rx-pdl's
* Note: For non-etr chips the transmit stop register must be
* programmed on a 1k boundary, i.e. bits 9:0 must be zero.
diff --git a/drivers/net/ibmtr.c b/drivers/net/ibmtr.c
index 527cd0443..f781abbf3 100644
--- a/drivers/net/ibmtr.c
+++ b/drivers/net/ibmtr.c
@@ -59,12 +59,13 @@
* Changes by Christopher Turcksin <wabbit@rtfc.demon.co.uk>
* + Now compiles ok as a module again.
*
- * Changes by Paul Norton (p.norton@computer.org) :
+ * Changes by Paul Norton (pnorton@ieee.org) :
* + moved the header manipulation code in tr_tx and tr_rx to
* net/802/tr.c. (July 12 1997)
* + add retry and timeout on open if cable disconnected. (May 5 1998)
* + lifted 2000 byte mtu limit. now depends on shared-RAM size.
* May 25 1998)
+ * + can't allocate 2k recv buff at 8k shared-RAM. (20 October 1998)
*/
#ifdef PCMCIA
@@ -93,8 +94,8 @@
/* version and credits */
static char *version =
-"ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
-" v2.1.106 6/22/98 Paul Norton <p.norton@computer.org>\n";
+"ibmtr.c: v1.3.57 8/ 7/94 Peter De Schrijver and Mark Swanson\n"
+" v2.1.125 10/20/98 Paul Norton <pnorton@ieee.org>\n";
static char pcchannelid[] = {
0x05, 0x00, 0x04, 0x09,
@@ -416,7 +417,7 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
timeout = jiffies + TR_SPIN_INTERVAL;
while(!readb(ti->mmio + ACA_OFFSET + ACA_RW + RRR_EVEN))
- if (jiffies > timeout) {
+ if (time_after(jiffies, timeout)) {
DPRINTK("Hardware timeout during initialization.\n");
kfree_s(ti, sizeof(struct tok_info));
return -ENODEV;
@@ -634,56 +635,56 @@ __initfunc(static int ibmtr_probe1(struct device *dev, int PIOaddr))
switch (ti->mapped_ram_size) {
case 16 : /* 8KB shared RAM */
ti->dhb_size4mb = MIN(ti->dhb_size4mb, 2048);
- ti->rbuf_len4 = 2048;
- ti->rbuf_cnt4 = 1;
+ ti->rbuf_len4 = 1032;
+ ti->rbuf_cnt4 = 2;
ti->dhb_size16mb = MIN(ti->dhb_size16mb, 2048);
- ti->rbuf_len16 = 2048;
- ti->rbuf_cnt16 = 1;
+ ti->rbuf_len16 = 1032;
+ ti->rbuf_cnt16 = 2;
break;
case 32 : /* 16KB shared RAM */
ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
- ti->rbuf_len4 = 512;
+ ti->rbuf_len4 = 520;
ti->rbuf_cnt4 = 9;
ti->dhb_size16mb = MIN(ti->dhb_size16mb, 4096);
- ti->rbuf_len16 = 2048;
- ti->rbuf_cnt16 = 2;
+ ti->rbuf_len16 = 1032; /* 1024 usable */
+ ti->rbuf_cnt16 = 4;
break;
case 64 : /* 32KB shared RAM */
ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
- ti->rbuf_len4 = 2048;
- ti->rbuf_cnt4 = 3;
+ ti->rbuf_len4 = 1032;
+ ti->rbuf_cnt4 = 6;
ti->dhb_size16mb = MIN(ti->dhb_size16mb, 10240);
- ti->rbuf_len16 = 2048;
- ti->rbuf_cnt16 = 5;
+ ti->rbuf_len16 = 1032;
+ ti->rbuf_cnt16 = 10;
break;
case 127 : /* 63KB shared RAM */
ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
- ti->rbuf_len4 = 2048;
- ti->rbuf_cnt4 = 3;
+ ti->rbuf_len4 = 1032;
+ ti->rbuf_cnt4 = 6;
ti->dhb_size16mb = MIN(ti->dhb_size16mb, 16384);
- ti->rbuf_len16 = 2048;
- ti->rbuf_cnt16 = 8;
+ ti->rbuf_len16 = 1032;
+ ti->rbuf_cnt16 = 16;
break;
case 128 : /* 64KB shared RAM */
ti->dhb_size4mb = MIN(ti->dhb_size4mb, 4464);
- ti->rbuf_len4 = 2048;
- ti->rbuf_cnt4 = 3;
+ ti->rbuf_len4 = 1032;
+ ti->rbuf_cnt4 = 6;
ti->dhb_size16mb = MIN(ti->dhb_size16mb, 17960);
- ti->rbuf_len16 = 2048;
- ti->rbuf_cnt16 = 9;
+ ti->rbuf_len16 = 1032;
+ ti->rbuf_cnt16 = 18;
break;
default :
ti->dhb_size4mb = 2048;
- ti->rbuf_len4 = 2048;
- ti->rbuf_cnt4 = 1;
+ ti->rbuf_len4 = 1032;
+ ti->rbuf_cnt4 = 2;
ti->dhb_size16mb = 2048;
- ti->rbuf_len16 = 2048;
- ti->rbuf_cnt16 = 1;
+ ti->rbuf_len16 = 1032;
+ ti->rbuf_cnt16 = 2;
break;
}
- ti->maxmtu16 = ti->dhb_size16mb-((ti->rbuf_cnt16)<<3)-TR_HLEN;
- ti->maxmtu4 = ti->dhb_size4mb-((ti->rbuf_cnt4)<<3)-TR_HLEN;
+ ti->maxmtu16 = (ti->rbuf_len16*ti->rbuf_cnt16)-((ti->rbuf_cnt16)<<3)-TR_HLEN;
+ ti->maxmtu4 = (ti->rbuf_len4*ti->rbuf_cnt4)-((ti->rbuf_cnt4)<<3)-TR_HLEN;
DPRINTK("Maximum MTU 16Mbps: %d, 4Mbps: %d\n",
ti->maxmtu16, ti->maxmtu4);
diff --git a/drivers/net/ipddp.c b/drivers/net/ipddp.c
index df22a0ee7..ac0d6b27e 100644
--- a/drivers/net/ipddp.c
+++ b/drivers/net/ipddp.c
@@ -62,12 +62,6 @@ static const char *version =
static struct ipddp_route *ipddp_route_list = NULL;
-/*
- * The name of the card. Is used for messages and in the requests for
- * io regions, irqs and dma channels
- */
-static const char *cardname = "ipddp";
-
#ifdef CONFIG_IPDDP_ENCAP
static int ipddp_mode = IPDDP_ENCAP;
#else
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 5a7d1fee5..15f7f9ad7 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -377,6 +377,7 @@ __initfunc(void lance_probe1(int ioaddr))
unsigned char hpJ2405A = 0; /* HP ISA adaptor */
int hp_builtin = 0; /* HP on-board ethernet. */
static int did_version = 0; /* Already printed version info. */
+ unsigned long flags;
/* First we look for special cases.
Check for HP's on-board ethernet by looking for 'HP' in the BIOS.
@@ -563,8 +564,11 @@ __initfunc(void lance_probe1(int ioaddr))
outw(0x7f04, ioaddr+LANCE_DATA); /* Clear the memory error bits. */
if (request_dma(dma, chipname))
continue;
+
+ flags=claim_dma_lock();
set_dma_mode(dma, DMA_MODE_CASCADE);
enable_dma(dma);
+ release_dma_lock(flags);
/* Trigger an initialization. */
outw(0x0001, ioaddr+LANCE_DATA);
@@ -576,7 +580,9 @@ __initfunc(void lance_probe1(int ioaddr))
printk(", DMA %d.\n", dev->dma);
break;
} else {
+ flags=claim_dma_lock();
disable_dma(dma);
+ release_dma_lock(flags);
free_dma(dma);
}
}
@@ -649,8 +655,10 @@ lance_open(struct device *dev)
/* The DMA controller is used as a no-operation slave, "cascade mode". */
if (dev->dma != 4) {
+ unsigned long flags=claim_dma_lock();
enable_dma(dev->dma);
set_dma_mode(dev->dma, DMA_MODE_CASCADE);
+ release_dma_lock(flags);
}
/* Un-Reset the LANCE, needed only for the NE2100. */
@@ -1121,7 +1129,11 @@ lance_close(struct device *dev)
outw(0x0004, ioaddr+LANCE_DATA);
if (dev->dma != 4)
+ {
+ unsigned long flags=claim_dma_lock();
disable_dma(dev->dma);
+ release_dma_lock(flags);
+ }
free_irq(dev->irq, dev);
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index df14d510c..1d3b02a86 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -194,7 +194,7 @@ __initfunc(int lne390_probe1(struct device *dev, int ioaddr))
}
printk(" IRQ %d,", dev->irq);
- if (request_irq(dev->irq, ei_interrupt, 0, "lne390", NULL)) {
+ if (request_irq(dev->irq, ei_interrupt, 0, "lne390", dev)) {
printk (" unable to get IRQ %d.\n", dev->irq);
kfree(dev->priv);
dev->priv = NULL;
@@ -223,10 +223,10 @@ __initfunc(int lne390_probe1(struct device *dev, int ioaddr))
the card mem within the region covered by `normal' RAM !!!
*/
if (dev->mem_start > 1024*1024) { /* phys addr > 1MB */
- if (dev->mem_start < (unsigned long)high_memory) {
+ if (dev->mem_start < virt_to_bus(high_memory)) {
printk(KERN_CRIT "lne390.c: Card RAM overlaps with normal memory!!!\n");
printk(KERN_CRIT "lne390.c: Use EISA SCU to set card memory below 1MB,\n");
- printk(KERN_CRIT "lne390.c: or to an address above %p.\n", high_memory);
+ printk(KERN_CRIT "lne390.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
printk(KERN_CRIT "lne390.c: Driver NOT installed.\n");
free_irq(dev->irq, dev);
kfree(dev->priv);
@@ -243,6 +243,7 @@ __initfunc(int lne390_probe1(struct device *dev, int ioaddr))
dev->priv = NULL;
return EAGAIN;
}
+ ei_status.reg0 = 1; /* Use as remap flag */
printk("lne390.c: remapped %dkB card memory to virtual address %#lx\n",
LNE390_STOP_PG/4, dev->mem_start);
}
@@ -427,6 +428,8 @@ void cleanup_module(void)
void *priv = dev->priv;
free_irq(dev->irq, dev);
release_region(dev->base_addr, LNE390_IO_EXTENT);
+ if (ei_status.reg0)
+ iounmap((void *)dev->mem_start);
dev->priv = NULL;
unregister_netdev(dev);
kfree(priv);
diff --git a/drivers/net/ltpc.c b/drivers/net/ltpc.c
index 205ec6ac2..c90f05945 100644
--- a/drivers/net/ltpc.c
+++ b/drivers/net/ltpc.c
@@ -67,6 +67,25 @@
* Hacked about a bit to clean things up - Alan Cox
* Probably broken it from the origina 1.8
*
+
+ * 1998/11/09: David Huggins-Daines <dhd@debian.org>
+ * Cleaned up the initialization code to use the standard autoirq methods,
+ and to probe for things in the standard order of i/o, irq, dma. This
+ removes the "reset the reset" hack, because I couldn't figure out an
+ easy way to get the card to trigger an interrupt after it.
+ * Added support for passing configuration parameters on the kernel command
+ line and through insmod
+ * Changed the device name from "ltalk0" to "lt0", both to conform with the
+ other localtalk driver, and to clear up the inconsistency between the
+ module and the non-module versions of the driver :-)
+ * Added a bunch of comments (I was going to make some enums for the state
+ codes and the register offsets, but I'm still not sure exactly what their
+ semantics are)
+ * Don't poll anymore in interrupt-driven mode
+ * It seems to work as a module now (as of 2.1.127), but I don't think
+ I'm responsible for that...
+
+ *
* Revision 1.7 1996/12/12 03:42:33 bradford
* DMA alloc cribbed from 3c505.c.
*
@@ -180,6 +199,9 @@ static int debug=0;
#define DEBUG_UPPER 2
#define DEBUG_LOWER 4
+static int io=0;
+static int irq=0;
+static int dma=0;
#ifdef MODULE
#include <linux/module.h>
@@ -245,25 +267,34 @@ static unsigned long dma_mem_alloc(int size)
return __get_dma_pages(GFP_KERNEL, order);
}
+/* DMA data buffer, DMA command buffer */
static unsigned char *ltdmabuf;
static unsigned char *ltdmacbuf;
+/* private struct, holds our appletalk address */
+
struct ltpc_private
{
struct net_device_stats stats;
struct at_addr my_addr;
};
+/* transmit queue element struct */
+
struct xmitQel {
struct xmitQel *next;
+ /* command buffer */
unsigned char *cbuf;
short cbuflen;
+ /* data buffer */
unsigned char *dbuf;
short dbuflen;
unsigned char QWrite; /* read or write data */
unsigned char mailbox;
};
+/* the transmit queue itself */
+
static struct xmitQel *xmQhd=NULL,*xmQtl=NULL;
static void enQ(struct xmitQel *qel)
@@ -310,8 +341,10 @@ static struct xmitQel *deQ(void)
return qel;
}
+/* and... the queue elements we'll be using */
static struct xmitQel qels[16];
+/* and their corresponding mailboxes */
static unsigned char mailbox[16];
static unsigned char mboxinuse[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
@@ -331,6 +364,8 @@ static int wait_timeout(struct device *dev, int c)
return 1; /* timed out */
}
+/* get the first free mailbox */
+
static int getmbox(void)
{
unsigned long flags;
@@ -347,18 +382,23 @@ static int getmbox(void)
return 0;
}
+/* read a command from the card */
static void handlefc(struct device *dev)
{
/* called *only* from idle, non-reentrant */
int dma = dev->dma;
int base = dev->base_addr;
+ unsigned long flags;
+
+ flags=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma,DMA_MODE_READ);
set_dma_addr(dma,virt_to_bus(ltdmacbuf));
set_dma_count(dma,50);
enable_dma(dma);
+ release_dma_lock(flags);
inb_p(base+3);
inb_p(base+2);
@@ -366,17 +406,21 @@ static void handlefc(struct device *dev)
if ( wait_timeout(dev,0xfc) ) printk("timed out in handlefc\n");
}
+/* read data from the card */
static void handlefd(struct device *dev)
{
int dma = dev->dma;
int base = dev->base_addr;
+ unsigned long flags;
+ flags=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma,DMA_MODE_READ);
set_dma_addr(dma,virt_to_bus(ltdmabuf));
set_dma_count(dma,800);
enable_dma(dma);
+ release_dma_lock(flags);
inb_p(base+3);
inb_p(base+2);
@@ -391,21 +435,25 @@ static void handlewrite(struct device *dev)
/* on entry, 0xfb and ltdmabuf holds data */
int dma = dev->dma;
int base = dev->base_addr;
-
-
+ unsigned long flags;
+
+ flags=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma,DMA_MODE_WRITE);
set_dma_addr(dma,virt_to_bus(ltdmabuf));
set_dma_count(dma,800);
enable_dma(dma);
-
+ release_dma_lock(flags);
+
inb_p(base+3);
inb_p(base+2);
if ( wait_timeout(dev,0xfb) ) {
+ flags=claim_dma_lock();
printk("timed out in handlewrite, dma res %d\n",
get_dma_residue(dev->dma) );
+ release_dma_lock(flags);
}
}
@@ -415,15 +463,17 @@ static void handleread(struct device *dev)
/* on exit, ltdmabuf holds data */
int dma = dev->dma;
int base = dev->base_addr;
+ unsigned long flags;
-
-
+
+ flags=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma,DMA_MODE_READ);
set_dma_addr(dma,virt_to_bus(ltdmabuf));
set_dma_count(dma,800);
enable_dma(dma);
+ release_dma_lock(flags);
inb_p(base+3);
inb_p(base+2);
@@ -435,20 +485,23 @@ static void handlecommand(struct device *dev)
/* on entry, 0xfa and ltdmacbuf holds command */
int dma = dev->dma;
int base = dev->base_addr;
+ unsigned long flags;
+ flags=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma,DMA_MODE_WRITE);
set_dma_addr(dma,virt_to_bus(ltdmacbuf));
set_dma_count(dma,50);
enable_dma(dma);
-
+ release_dma_lock(flags);
inb_p(base+3);
inb_p(base+2);
if ( wait_timeout(dev,0xfa) ) printk("timed out in handlecommand\n");
}
-static unsigned char rescbuf[2] = {0,0};
+/* ready made command for getting the result from the card */
+static unsigned char rescbuf[2] = {LT_GETRESULT,0};
static unsigned char resdbuf[2];
static int QInIdle=0;
@@ -467,7 +520,7 @@ static void idle(struct device *dev)
struct xmitQel *q=0;
int oops;
int i;
- int statusPort = dev->base_addr+6;
+ int base = dev->base_addr;
save_flags(flags);
cli();
@@ -480,8 +533,8 @@ static void idle(struct device *dev)
restore_flags(flags);
-
- (void) inb_p(statusPort); /* this tri-states the IRQ line */
+ /* this tri-states the IRQ line */
+ (void) inb_p(base+6);
oops = 100;
@@ -491,19 +544,22 @@ loop:
goto done;
}
- state = inb_p(statusPort);
- if (state != inb_p(statusPort)) goto loop;
+ state = inb_p(base+6);
+ if (state != inb_p(base+6)) goto loop;
switch(state) {
- case 0xfc:
+ case 0xfc:
+ /* incoming command */
if (debug&DEBUG_LOWER) printk("idle: fc\n");
handlefc(dev);
break;
- case 0xfd:
+ case 0xfd:
+ /* incoming data */
if(debug&DEBUG_LOWER) printk("idle: fd\n");
handlefd(dev);
break;
- case 0xf9:
+ case 0xf9:
+ /* result ready */
if (debug&DEBUG_LOWER) printk("idle: f9\n");
if(!mboxinuse[0]) {
mboxinuse[0] = 1;
@@ -521,6 +577,7 @@ loop:
printk("timed out idle f9\n");
break;
case 0xf8:
+ /* ?? */
if (xmQhd) {
inb_p(dev->base_addr+1);
inb_p(dev->base_addr+0);
@@ -530,7 +587,8 @@ loop:
goto done;
}
break;
- case 0xfa:
+ case 0xfa:
+ /* waiting for command */
if(debug&DEBUG_LOWER) printk("idle: fa\n");
if (xmQhd) {
q=deQ();
@@ -546,7 +604,7 @@ loop:
printk("\n");
}
handlecommand(dev);
- if(0xfa==inb_p(statusPort)) {
+ if(0xfa==inb_p(base+6)) {
/* we timed out, so return */
goto done;
}
@@ -567,13 +625,17 @@ loop:
}
}
break;
- case 0xfb:
+ case 0Xfb:
+ /* data transfer ready */
if(debug&DEBUG_LOWER) printk("idle: fb\n");
if(q->QWrite) {
memcpy(ltdmabuf,q->dbuf,q->dbuflen);
handlewrite(dev);
} else {
handleread(dev);
+ /* non-zero mailbox numbers are for
+ commmands, 0 is for GETRESULT
+ requests */
if(q->mailbox) {
memcpy(q->dbuf,ltdmabuf,q->dbuflen);
} else {
@@ -590,13 +652,14 @@ done:
QInIdle=0;
/* now set the interrupts back as appropriate */
- /* the first 7 takes it out of tri-state (but still high) */
+ /* the first read takes it out of tri-state (but still high) */
/* the second resets it */
- /* note that after this point, any read of 6 will trigger an interrupt */
+ /* note that after this point, any read of base+6 will
+ trigger an interrupt */
if (dev->irq) {
- inb_p(dev->base_addr+7);
- inb_p(dev->base_addr+7);
+ inb_p(base+7);
+ inb_p(base+7);
}
return;
}
@@ -688,6 +751,8 @@ static int set_30 (struct device *dev,int x)
return do_write(dev, &c, sizeof(c.setflags),&c,0);
}
+/* LLAP to DDP translation */
+
static int sendup_buffer (struct device *dev)
{
/* on entry, command is in ltdmacbuf, data in ltdmabuf */
@@ -897,23 +962,14 @@ static void ltpc_poll(unsigned long l)
if (!dev)
return; /* we've been downed */
- if (dev->irq)
- {
- /* we're set up for interrupts */
- if (0xf8 != inb_p(dev->base_addr+7)) {
- /* trigger an interrupt */
- (void) inb_p(dev->base_addr+6);
- }
- ltpc_timer.expires = jiffies+100;
- } else {
- /* we're strictly polling mode */
- idle(dev);
- ltpc_timer.expires = jiffies+5;
- }
-
+ idle(dev);
+ ltpc_timer.expires = jiffies+5;
+
add_timer(&ltpc_timer);
}
+/* DDP to LLAP translation */
+
static int ltpc_xmit(struct sk_buff *skb, struct device *dev)
{
/* in kernel 1.3.xx, on entry skb->data points to ddp header,
@@ -960,106 +1016,133 @@ static struct net_device_stats *ltpc_get_stats(struct device *dev)
return stats;
}
-static unsigned short irqhitmask;
-
-__initfunc(static void lt_probe_handler(int irq, void *dev_id, struct pt_regs *reg_ptr))
-{
- irqhitmask |= 1<<irq;
-}
-
-__initfunc(int ltpc_probe(struct device *dev))
+/* initialization stuff */
+
+__initfunc(int ltpc_probe_dma(int base))
{
- int err;
- unsigned char dma=0;
- short base=0;
- unsigned char irq=0;
- int x=0,y=0;
- int timeout;
- int probe3, probe4, probe9;
- unsigned short straymask;
- unsigned long flags;
-
- err = ltpc_init(dev);
- if (err) return err;
+ int dma = 0;
+ int timeout;
+ unsigned long f;
+
+ if (!request_dma(1,"ltpc")) {
+ f=claim_dma_lock();
+ disable_dma(1);
+ clear_dma_ff(1);
+ set_dma_mode(1,DMA_MODE_WRITE);
+ set_dma_addr(1,virt_to_bus(ltdmabuf));
+ set_dma_count(1,sizeof(struct lt_mem));
+ enable_dma(1);
+ release_dma_lock(f);
+ dma|=1;
+ }
+ if (!request_dma(3,"ltpc")) {
+ f=claim_dma_lock();
+ disable_dma(3);
+ clear_dma_ff(3);
+ set_dma_mode(3,DMA_MODE_WRITE);
+ set_dma_addr(3,virt_to_bus(ltdmabuf));
+ set_dma_count(3,sizeof(struct lt_mem));
+ enable_dma(3);
+ release_dma_lock(f);
+ dma|=2;
+ }
- /* occasionally the card comes up with reset latched, so we need
- * to "reset the reset" first of all -- check the irq first also
- */
+ /* set up request */
- save_flags(flags);
- cli();
+ /* FIXME -- do timings better! */
- probe3 = request_irq( 3, &lt_probe_handler, 0, "ltpc_probe",dev);
- probe4 = request_irq( 4, &lt_probe_handler, 0, "ltpc_probe",dev);
- probe9 = request_irq( 9, &lt_probe_handler, 0, "ltpc_probe",dev);
+ ltdmabuf[0] = LT_READMEM;
+ ltdmabuf[1] = 1; /* mailbox */
+ ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */
+ ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */
+ ltdmabuf[6] = 0; /* dunno if this is necessary */
- irqhitmask = 0;
+ inb_p(io+1);
+ inb_p(io+0);
+ timeout = jiffies+100;
+ while(timeout>jiffies) {
+ if ( 0xfa == inb_p(io+6) ) break;
+ }
- sti();
+ inb_p(io+3);
+ inb_p(io+2);
+ while(timeout>jiffies) {
+ if ( 0xfb == inb_p(io+6) ) break;
+ }
- timeout = jiffies+2;
- while(timeout>jiffies) ; /* wait for strays */
+ /* release the other dma channel (if we opened both of them) */
- straymask = irqhitmask; /* pick up any strays */
-
- /* if someone already owns this address, don't probe */
- if (!check_region(0x220,8)) {
- inb_p(0x227);
- inb_p(0x227);
- x=inb_p(0x226);
- timeout = jiffies+2;
- while(timeout>jiffies) ;
- if(straymask != irqhitmask) base = 0x220;
+ if ( (dma&0x2) && (get_dma_residue(3)==sizeof(struct lt_mem)) ){
+ dma&=1;
+ free_dma(3);
}
- if (!check_region(0x240,8)) {
- inb_p(0x247);
- inb_p(0x247);
- y=inb_p(0x246);
- timeout = jiffies+2;
- while(timeout>jiffies) ;
- if(straymask != irqhitmask) base = 0x240;
+
+ if ( (dma&0x1) && (get_dma_residue(1)==sizeof(struct lt_mem)) ){
+ dma&=0x2;
+ free_dma(1);
}
- /* at this point, either we have an irq and the base addr, or
- * there isn't any irq and we don't know the base address, but
- * in either event the card is no longer latched in reset and
- * the irq request line is tri-stated.
- */
+ /* fix up dma number */
+ dma|=1;
- cli();
-
- if (!probe3) free_irq(3,dev);
- if (!probe4) free_irq(4,dev);
- if (!probe9) free_irq(9,dev);
+ return dma;
+}
- sti();
-
- irqhitmask &= ~straymask;
+__initfunc(int ltpc_probe(struct device *dev))
+{
+ int err;
+ int x=0,y=0;
+ int timeout;
+ int autoirq;
+ unsigned long flags;
+ unsigned long f;
- irq = ffz(~irqhitmask);
- if (irqhitmask != 1<<irq)
- printk("ltpc card raised more than one interrupt!\n");
+ save_flags(flags);
- if (!base) {
- if (!check_region(0x220,8)) {
- x = inb_p(0x220+6);
- if ( (x!=0xff) && (x>=0xf0) ) base = 0x220;
- }
-
- if (!check_region(0x240,8)) {
- y = inb_p(0x240+6);
- if ( (y!=0xff) && (y>=0xf0) ) base = 0x240;
- }
+ /* probe for the I/O port address */
+ if (io != 0x240 && !check_region(0x220,8)) {
+ x = inb_p(0x220+6);
+ if ( (x!=0xff) && (x>=0xf0) ) io = 0x220;
}
+
+ if (io != 0x220 && !check_region(0x240,8)) {
+ y = inb_p(0x240+6);
+ if ( (y!=0xff) && (y>=0xf0) ) io = 0x240;
+ }
- if(base) {
- request_region(base,8,"ltpc");
+ if(io) {
+ /* found it, now grab it */
+ request_region(io,8,"ltpc");
} else {
- printk("LocalTalk card not found; 220 = %02x, 240 = %02x.\n",x,y);
+ /* give up in despair */
+ printk ("LocalTalk card not found; 220 = %02x, 240 = %02x.\n",
+ x,y);
restore_flags(flags);
return -1;
}
+ /* probe for the IRQ line */
+ if (irq < 2) {
+ autoirq_setup(2);
+
+ /* reset the interrupt line */
+ inb_p(io+7);
+ inb_p(io+7);
+ /* trigger an interrupt (I hope) */
+ inb_p(io+6);
+
+ autoirq = autoirq_report(1);
+
+ if (autoirq == 0) {
+ printk("ltpc: probe at %#x failed to detect IRQ line.\n",
+ io);
+ }
+ else {
+ irq = autoirq;
+ }
+ }
+
+ /* allocate a DMA buffer */
ltdmabuf = (unsigned char *) dma_mem_alloc(1000);
if (ltdmabuf) ltdmacbuf = &ltdmabuf[800];
@@ -1076,147 +1159,124 @@ __initfunc(int ltpc_probe(struct device *dev))
/* reset the card */
- inb_p(base+1);
- inb_p(base+3);
+ inb_p(io+1);
+ inb_p(io+3);
timeout = jiffies+2;
while(timeout>jiffies) ; /* hold it in reset for a coupla jiffies */
- inb_p(base+0);
- inb_p(base+2);
- inb_p(base+7); /* clear reset */
- inb_p(base+4);
- inb_p(base+5);
- inb_p(base+5); /* enable dma */
- inb_p(base+6); /* tri-state interrupt line */
+ inb_p(io+0);
+ inb_p(io+2);
+ inb_p(io+7); /* clear reset */
+ inb_p(io+4);
+ inb_p(io+5);
+ inb_p(io+5); /* enable dma */
+ inb_p(io+6); /* tri-state interrupt line */
timeout = jiffies+100;
+
while(timeout>jiffies) {
/* wait for the card to complete initialization */
}
- /* now, figure out which dma channel we're using */
-
- /* set up both dma 1 and 3 for read call */
-
- if (!request_dma(1,"ltpc")) {
- disable_dma(1);
- clear_dma_ff(1);
- set_dma_mode(1,DMA_MODE_WRITE);
- set_dma_addr(1,virt_to_bus(ltdmabuf));
- set_dma_count(1,sizeof(struct lt_mem));
- enable_dma(1);
- dma|=1;
- }
- if (!request_dma(3,"ltpc")) {
- disable_dma(3);
- clear_dma_ff(3);
- set_dma_mode(3,DMA_MODE_WRITE);
- set_dma_addr(3,virt_to_bus(ltdmabuf));
- set_dma_count(3,sizeof(struct lt_mem));
- enable_dma(3);
- dma|=2;
- }
-
- /* set up request */
-
- /* FIXME -- do timings better! */
-
- ltdmabuf[0] = 2; /* read request */
- ltdmabuf[1] = 1; /* mailbox */
- ltdmabuf[2] = 0; ltdmabuf[3] = 0; /* address */
- ltdmabuf[4] = 0; ltdmabuf[5] = 1; /* read 0x0100 bytes */
- ltdmabuf[6] = 0; /* dunno if this is necessary */
-
- inb_p(base+1);
- inb_p(base+0);
- timeout = jiffies+100;
- while(timeout>jiffies) {
- if ( 0xfa == inb_p(base+6) ) break;
- }
-
- inb_p(base+3);
- inb_p(base+2);
- while(timeout>jiffies) {
- if ( 0xfb == inb_p(base+6) ) break;
- }
-
- /* release the other dma channel */
-
- if ( (dma&0x2) && (get_dma_residue(3)==sizeof(struct lt_mem)) ){
- dma&=1;
- free_dma(3);
- }
-
- if ( (dma&0x1) && (get_dma_residue(1)==sizeof(struct lt_mem)) ){
- dma&=0x2;
- free_dma(1);
+ /* now, figure out which dma channel we're using, unless it's
+ already been specified */
+ /* well, 0 is a legal DMA channel, but the LTPC card doesn't
+ use it... */
+ if (dma == 0) {
+ dma = ltpc_probe_dma(io);
+ if (!dma) { /* no dma channel */
+ printk("No DMA channel found on ltpc card.\n");
+ restore_flags(flags);
+ return -1;
+ }
}
-
- if (!dma) { /* no dma channel */
- printk("No DMA channel found on ltpc card.\n");
- restore_flags(flags);
- return -1;
- }
-
- /* fix up dma number */
- dma|=1;
- /* set up read */
+ /* print out friendly message */
if(irq)
- printk("LocalTalk card found at %03x, IR%d, DMA%d.\n",base,irq,dma);
+ printk("Apple/Farallon LocalTalk-PC card at %03x, IR%d, DMA%d.\n",io,irq,dma);
else
- printk("LocalTalk card found at %03x, DMA%d. Using polled mode.\n",base,dma);
-
- dev->base_addr = base;
+ printk("Apple/Farallon LocalTalk-PC card at %03x, DMA%d. Using polled mode.\n",io,dma);
+
+ /* seems more logical to do this *after* probing the card... */
+ err = ltpc_init(dev);
+ if (err) return err;
+
+ dev->base_addr = io;
dev->irq = irq;
dev->dma = dma;
- if(debug&DEBUG_VERBOSE) {
- printk("finishing up transfer\n");
- }
+ /* the card will want to send a result at this point */
+ /* (I think... leaving out this part makes the kernel crash,
+ so I put it back in...) */
+ f=claim_dma_lock();
disable_dma(dma);
clear_dma_ff(dma);
set_dma_mode(dma,DMA_MODE_READ);
set_dma_addr(dma,virt_to_bus(ltdmabuf));
set_dma_count(dma,0x100);
enable_dma(dma);
+ release_dma_lock(f);
- (void) inb_p(base+3);
- (void) inb_p(base+2);
+ (void) inb_p(io+3);
+ (void) inb_p(io+2);
timeout = jiffies+100;
while(timeout>jiffies) {
- if( 0xf9 == inb_p(base+6)) break;
+ if( 0xf9 == inb_p(io+6)) break;
}
if(debug&DEBUG_VERBOSE) {
printk("setting up timer and irq\n");
}
- init_timer(&ltpc_timer);
- ltpc_timer.function=ltpc_poll;
- ltpc_timer.data = (unsigned long) dev;
-
if (irq) {
+ /* grab it and don't let go :-) */
(void) request_irq( irq, &ltpc_interrupt, 0, "ltpc", dev);
- (void) inb_p(base+7); /* enable interrupts from board */
- (void) inb_p(base+7); /* and reset irq line */
- ltpc_timer.expires = 100;
- /* poll it once per second just in case */
+ (void) inb_p(io+7); /* enable interrupts from board */
+ (void) inb_p(io+7); /* and reset irq line */
} else {
- ltpc_timer.expires = 5;
- /* polled mode -- 20 times per second */
- }
-
- ltpc_timer.expires += jiffies; /* 1.2 to 1.3 change... */
-
- add_timer(&ltpc_timer);
+ /* polled mode -- 20 times per second */
+ /* this is really, really slow... should it poll more often? */
+ init_timer(&ltpc_timer);
+ ltpc_timer.function=ltpc_poll;
+ ltpc_timer.data = (unsigned long) dev;
- restore_flags(flags);
+ ltpc_timer.expires = jiffies + 5;
+ add_timer(&ltpc_timer);
+ restore_flags(flags);
+ }
return 0;
}
+/* handles "ltpc=io,irq,dma" kernel command lines */
+__initfunc(void ltpc_setup(char *str, int *ints))
+{
+ if (ints[0] == 0) {
+ if (str && !strncmp(str, "auto", 4)) {
+ /* do nothing :-) */
+ }
+ else {
+ /* usage message */
+ printk (KERN_ERR
+ "ltpc: usage: ltpc=auto|iobase[,irq[,dma]]\n");
+ }
+ return;
+ } else {
+ io = ints[1];
+ if (ints[0] > 1) {
+ irq = ints[2];
+ return;
+ }
+ if (ints[0] > 2) {
+ dma = ints[3];
+ return;
+ }
+ /* ignore any other paramters */
+ }
+ return;
+}
+
#ifdef MODULE
static char dev_name[8];
@@ -1227,17 +1287,28 @@ static struct device dev_ltpc = {
0x0, 0,
0, 0, 0, NULL, ltpc_probe };
+MODULE_PARM(debug, "i");
+MODULE_PARM(io, "i");
+MODULE_PARM(irq, "i");
+MODULE_PARM(dma, "i");
+
int init_module(void)
{
+ int err, result;
+
+ if(io == 0)
+ printk(KERN_NOTICE
+ "ltpc: Autoprobing is not recommended for modules\n");
+
/* Find a name for this unit */
- int err=dev_alloc_name(&dev_ltpc,"lt%d");
+ err=dev_alloc_name(&dev_ltpc,"lt%d");
if(err<0)
return err;
- if (register_netdev(&dev_ltpc) != 0) {
- if(debug&DEBUG_VERBOSE) printk("EIO from register_netdev\n");
- return -EIO;
+ if ((result = register_netdev(&dev_ltpc)) != 0) {
+ printk(KERN_DEBUG "could not register Localtalk-PC device\n");
+ return result;
} else {
if(debug&DEBUG_VERBOSE) printk("0 from register_netdev\n");
return 0;
@@ -1298,3 +1369,4 @@ void cleanup_module(void)
if(debug&DEBUG_VERBOSE) printk("returning from cleanup_module\n");
}
#endif /* MODULE */
+
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 392354f5a..ed653ce16 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -120,6 +120,7 @@ mace_probe(struct device *dev)
if (dev->priv == 0)
return -ENOMEM;
}
+ memset(dev->priv, 0, PRIV_BYTES);
mp = (struct mace_data *) dev->priv;
dev->base_addr = mace->addrs[0].address;
@@ -127,21 +128,6 @@ mace_probe(struct device *dev)
ioremap(mace->addrs[0].address, 0x1000);
dev->irq = mace->intrs[0].line;
- if (request_irq(dev->irq, mace_interrupt, 0, "MACE", dev)) {
- printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
- return -EAGAIN;
- }
- if (request_irq(mace->intrs[1].line, mace_txdma_intr, 0, "MACE-txdma",
- dev)) {
- printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line);
- return -EAGAIN;
- }
- if (request_irq(mace->intrs[2].line, mace_rxdma_intr, 0, "MACE-rxdma",
- dev)) {
- printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line);
- return -EAGAIN;
- }
-
addr = get_property(mace, "mac-address", NULL);
if (addr == NULL) {
addr = get_property(mace, "local-mac-address", NULL);
@@ -187,6 +173,23 @@ mace_probe(struct device *dev)
ether_setup(dev);
+ mace_reset(dev);
+
+ if (request_irq(dev->irq, mace_interrupt, 0, "MACE", dev)) {
+ printk(KERN_ERR "MACE: can't get irq %d\n", dev->irq);
+ return -EAGAIN;
+ }
+ if (request_irq(mace->intrs[1].line, mace_txdma_intr, 0, "MACE-txdma",
+ dev)) {
+ printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[1].line);
+ return -EAGAIN;
+ }
+ if (request_irq(mace->intrs[2].line, mace_rxdma_intr, 0, "MACE-rxdma",
+ dev)) {
+ printk(KERN_ERR "MACE: can't get irq %d\n", mace->intrs[2].line);
+ return -EAGAIN;
+ }
+
return 0;
}
@@ -197,36 +200,49 @@ static void mace_reset(struct device *dev)
int i;
/* soft-reset the chip */
- mb->biucc = SWRST; eieio();
- udelay(100);
+ i = 200;
+ while (--i) {
+ out_8(&mb->biucc, SWRST);
+ if (mb->biucc & SWRST) {
+ udelay(20);
+ continue;
+ }
+ break;
+ }
+ if (!i) {
+ printk("mace: cannot reset chip!\n");
+ return;
+ }
+
+ out_8(&mb->imr, 0xff); /* disable all intrs for now */
+ i = in_8(&mb->ir);
+ out_8(&mb->maccc, 0); /* turn off tx, rx */
mb->biucc = XMTSP_64;
- mb->imr = 0xff; /* disable all intrs for now */
- i = mb->ir;
- mb->maccc = 0; /* turn off tx, rx */
mb->utr = RTRD;
- mb->fifocc = RCVFW_64;
+ mb->fifocc = RCVFW_32 | XMTFW_16 | XMTFWU | RCVFWU | XMTBRST;
mb->xmtfc = AUTO_PAD_XMIT; /* auto-pad short frames */
+ mb->rcvfc = 0;
/* load up the hardware address */
- mb->iac = ADDRCHG | PHYADDR; eieio();
- while ((mb->iac & ADDRCHG) != 0)
- eieio();
+ out_8(&mb->iac, ADDRCHG | PHYADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
for (i = 0; i < 6; ++i) {
- mb->padr = dev->dev_addr[i];
- eieio();
+ out_8(&mb->padr, dev->dev_addr[i]);
}
/* clear the multicast filter */
- mb->iac = ADDRCHG | LOGADDR; eieio();
- while ((mb->iac & ADDRCHG) != 0)
- eieio();
+ out_8(&mb->iac, ADDRCHG | LOGADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
for (i = 0; i < 8; ++i) {
- mb->ladrf = 0;
- eieio();
+ out_8(&mb->ladrf, 0);
}
+ /* done changing address */
+ out_8(&mb->iac, 0);
- mb->plscc = PORTSEL_GPSI + ENPLSIO;
+ out_8(&mb->plscc, PORTSEL_GPSI + ENPLSIO);
}
static int mace_set_address(struct device *dev, void *addr)
@@ -240,15 +256,15 @@ static int mace_set_address(struct device *dev, void *addr)
save_flags(flags); cli();
/* load up the hardware address */
- mb->iac = ADDRCHG | PHYADDR; eieio();
- while ((mb->iac & ADDRCHG) != 0)
- eieio();
+ out_8(&mb->iac, ADDRCHG | PHYADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
for (i = 0; i < 6; ++i) {
- mb->padr = dev->dev_addr[i] = p[i];
- eieio();
+ out_8(&mb->padr, dev->dev_addr[i] = p[i]);
}
+ out_8(&mb->iac, 0);
/* note: setting ADDRCHG clears ENRCV */
- mb->maccc = mp->maccc; eieio();
+ out_8(&mb->maccc, mp->maccc);
restore_flags(flags);
return 0;
@@ -316,9 +332,9 @@ static int mace_open(struct device *dev)
mp->tx_bad_runt = 0;
/* turn it on! */
- mb->maccc = mp->maccc; eieio();
+ out_8(&mb->maccc, mp->maccc);
/* enable all interrupts except receive interrupts */
- mb->imr = RCVINT; eieio();
+ out_8(&mb->imr, RCVINT);
return 0;
}
@@ -389,7 +405,7 @@ static int mace_xmit_start(struct sk_buff *skb, struct device *dev)
dev->tbusy = 1;
mp->tx_fullup = 1;
restore_flags(flags);
- return -1; /* can't take it at the moment */
+ return 1; /* can't take it at the moment */
}
restore_flags(flags);
@@ -483,16 +499,15 @@ static void mace_set_multicast(struct device *dev)
printk("\n");
#endif
- mb->iac = ADDRCHG | LOGADDR; eieio();
- while ((mb->iac & ADDRCHG) != 0)
- eieio();
+ out_8(&mb->iac, ADDRCHG | LOGADDR);
+ while ((in_8(&mb->iac) & ADDRCHG) != 0)
+ ;
for (i = 0; i < 8; ++i) {
- mb->ladrf = multicast_filter[i];
- eieio();
+ out_8(&mb->ladrf, multicast_filter[i]);
}
}
/* reset maccc */
- mb->maccc = mp->maccc; eieio();
+ out_8(&mb->maccc, mp->maccc);
}
static void mace_handle_misc_intrs(struct mace_data *mp, int intr)
@@ -525,9 +540,10 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
volatile struct dbdma_cmd *cp;
int intr, fs, i, stat, x;
int xcount, dstat;
- static int mace_last_fs, mace_last_xcount;
+ /* static int mace_last_fs, mace_last_xcount; */
- intr = mb->ir; /* read interrupt register */
+ intr = in_8(&mb->ir); /* read interrupt register */
+ in_8(&mb->xmtrc); /* get retries */
mace_handle_misc_intrs(mp, intr);
i = mp->tx_empty;
@@ -543,10 +559,9 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
if (intr != 0)
mace_handle_misc_intrs(mp, intr);
if (mp->tx_bad_runt) {
- fs = mb->xmtfs;
- eieio();
+ fs = in_8(&mb->xmtfs);
mp->tx_bad_runt = 0;
- mb->xmtfc = AUTO_PAD_XMIT;
+ mb->xmtfc = AUTO_PAD_XMIT;
continue;
}
dstat = ld_le32(&td->status);
@@ -569,8 +584,7 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
* so the two bytes will only be a runt packet which should
* be ignored by other stations.
*/
- mb->xmtfc = DXMTFCS;
- eieio();
+ out_8(&mb->xmtfc, DXMTFCS);
}
fs = mb->xmtfs;
if ((fs & XMTSV) == 0) {
@@ -618,14 +632,16 @@ static void mace_interrupt(int irq, void *dev_id, struct pt_regs *regs)
++mp->stats.tx_carrier_errors;
if (fs & (UFLO|LCOL|RTRY))
++mp->stats.tx_aborted_errors;
- } else
+ } else
++mp->stats.tx_packets;
dev_kfree_skb(mp->tx_bufs[i]);
--mp->tx_active;
if (++i >= N_TX_RING)
i = 0;
+#if 0
mace_last_fs = fs;
mace_last_xcount = xcount;
+#endif
}
if (i != mp->tx_empty) {
@@ -675,7 +691,7 @@ static void mace_tx_timeout(unsigned long data)
cp = mp->tx_cmds + NCMDS_TX * mp->tx_empty;
/* turn off both tx and rx and reset the chip */
- mb->maccc = 0;
+ out_8(&mb->maccc, 0);
out_le32(&td->control, (RUN|PAUSE|FLUSH|WAKE) << 16);
printk(KERN_ERR "mace: transmit timeout - resetting\n");
mace_reset(dev);
diff --git a/drivers/net/ne2.c b/drivers/net/ne2.c
new file mode 100644
index 000000000..429699c34
--- /dev/null
+++ b/drivers/net/ne2.c
@@ -0,0 +1,697 @@
+/* ne2.c: A NE/2 Ethernet Driver for Linux. */
+/*
+ Based on the NE2000 driver written by Donald Becker (1992-94).
+ modified by Wim Dumon (Apr 1996)
+
+ This software may be used and distributed according to the terms
+ of the GNU Public License, incorporated herein by reference.
+
+ The author may be reached as wimpie@linux.cc.kuleuven.ac.be
+
+ Currently supported: NE/2
+ This patch was never tested on other MCA-ethernet adapters, but it
+ might work. Just give it a try and let me know if you have problems.
+ Also mail me if it really works, please!
+
+ Changelog:
+ Mon Feb 3 16:26:02 MET 1997
+ - adapted the driver to work with the 2.1.25 kernel
+ - multiple ne2 support (untested)
+ - module support (untested)
+
+ Fri Aug 28 00:18:36 CET 1998 (David Weinehall)
+ - fixed a few minor typos
+ - made the MODULE_PARM conditional (it only works with the v2.1.x kernels)
+ - fixed the module support (Now it's working...)
+
+ Mon Sep 7 19:01:44 CET 1998 (David Weinehall)
+ - added support for Arco Electronics AE/2-card (experimental)
+
+ Mon Sep 14 09:53:42 CET 1998 (David Weinehall)
+ - added support for Compex ENET-16MC/P (experimental)
+
+ Tue Sep 15 16:21:12 CET 1998 (David Weinehall, Magnus Jonsson, Tomas Ogren)
+ - Miscellaneous bugfixes
+
+ Tue Sep 19 16:21:12 CET 1998 (Magnus Jonsson)
+ - Cleanup
+
+ Wed Sep 23 14:33:34 CET 1998 (David Weinehall)
+ - Restructuring and rewriting for v2.1.x compliance
+
+ Wed Oct 14 17:19:21 CET 1998 (David Weinehall)
+ - Added code that unregisters irq and proc-info
+ - Version# bump
+
+ * WARNING
+ -------
+ This is alpha-test software. It is not guaranteed to work. As a
+ matter of fact, I'm quite sure there are *LOTS* of bugs in here. I
+ would like to hear from you if you use this driver, even if it works.
+ If it doesn't work, be sure to send me a mail with the problems !
+*/
+
+static const char *version =
+"ne2.c:v0.90 Oct 14 1998 David Weinehall <tao@acc.umu.se>\n";
+
+#include <linux/module.h>
+#include <linux/version.h>
+
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/types.h>
+#include <linux/fcntl.h>
+#include <linux/interrupt.h>
+#include <linux/ptrace.h>
+#include <linux/ioport.h>
+#include <linux/in.h>
+#include <linux/malloc.h>
+#include <linux/string.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
+#include <asm/io.h>
+#include <asm/dma.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/ioport.h>
+#include <linux/mca.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include "8390.h"
+
+
+
+/* Some defines that people can play with if so inclined. */
+
+/* Do we perform extra sanity checks on stuff ? */
+/* #define NE_SANITY_CHECK */
+
+/* Do we implement the read before write bugfix ? */
+/* #define NE_RW_BUGFIX */
+
+/* Do we have a non std. amount of memory? (in units of 256 byte pages) */
+/* #define PACKETBUF_MEMSIZE 0x40 */
+
+
+/* ---- No user-serviceable parts below ---- */
+
+#define NE_BASE (dev->base_addr)
+#define NE_CMD 0x00
+#define NE_DATAPORT 0x10 /* NatSemi-defined port window offset. */
+#define NE_RESET 0x20 /* Issue a read to reset, a write to clear. */
+#define NE_IO_EXTENT 0x30
+
+#define NE1SM_START_PG 0x20 /* First page of TX buffer */
+#define NE1SM_STOP_PG 0x40 /* Last page +1 of RX ring */
+#define NESM_START_PG 0x40 /* First page of TX buffer */
+#define NESM_STOP_PG 0x80 /* Last page +1 of RX ring */
+
+/* From the .ADF file: */
+static unsigned int addresses[7]=
+ {0x1000, 0x2020, 0x8020, 0xa0a0, 0xb0b0, 0xc0c0, 0xc3d0};
+static int irqs[4] = {3, 4, 5, 9};
+
+struct ne2_adapters_t {
+ unsigned int id;
+ char *name;
+};
+
+const struct ne2_adapters_t ne2_adapters[] = {
+ { 0x6354, "Arco Ethernet Adapter AE/2" },
+ { 0x70DE, "Compex ENET-16 MC/P" },
+ { 0x7154, "Novell Ethernet Adapter NE/2" },
+ { 0x0000, NULL }
+};
+
+extern int netcard_probe(struct device *dev);
+
+static int ne2_probe1(struct device *dev, int slot);
+
+static int ne_open(struct device *dev);
+static int ne_close(struct device *dev);
+
+static void ne_reset_8390(struct device *dev);
+static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
+ int ring_page);
+static void ne_block_input(struct device *dev, int count,
+ struct sk_buff *skb, int ring_offset);
+static void ne_block_output(struct device *dev, const int count,
+ const unsigned char *buf, const int start_page);
+
+
+/*
+ * Note that at boot, this probe only picks up one card at a time.
+ */
+
+__initfunc (int ne2_probe(struct device *dev))
+{
+ static int current_mca_slot = -1;
+ int i;
+ int adapter_found = 0;
+
+ /* Do not check any supplied i/o locations.
+ POS registers usually don't fail :) */
+
+ /* MCA cards have POS registers.
+ Autodetecting MCA cards is extremely simple.
+ Just search for the card. */
+
+ for(i = 0; (ne2_adapters[i].name != NULL) && !adapter_found; i++) {
+ current_mca_slot =
+ mca_find_unused_adapter(ne2_adapters[i].id, 0);
+
+ if((current_mca_slot != MCA_NOTFOUND) && !adapter_found) {
+ mca_set_adapter_name(current_mca_slot,
+ ne2_adapters[i].name);
+ mca_mark_as_used(current_mca_slot);
+
+ return ne2_probe1(dev, current_mca_slot);
+ }
+ }
+ return ENODEV;
+}
+
+
+static int ne2_procinfo(char *buf, int slot, struct device *dev)
+{
+ int len=0;
+
+ len += sprintf(buf+len, "The NE/2 Ethernet Adapter\n" );
+ len += sprintf(buf+len, "Driver written by Wim Dumon ");
+ len += sprintf(buf+len, "<wimpie@kotnet.org>\n");
+ len += sprintf(buf+len, "Modified by ");
+ len += sprintf(buf+len, "David Weinehall <tao@acc.umu.se>\n");
+ len += sprintf(buf+len, "and by Magnus Jonsson <bigfoot@acc.umu.se>\n");
+ len += sprintf(buf+len, "Based on the original NE2000 drivers\n" );
+ len += sprintf(buf+len, "Base IO: %#x\n", (unsigned int)dev->base_addr);
+ len += sprintf(buf+len, "IRQ : %d\n", dev->irq);
+
+#define HW_ADDR(i) dev->dev_addr[i]
+ len += sprintf(buf+len, "HW addr : %x:%x:%x:%x:%x:%x\n",
+ HW_ADDR(0), HW_ADDR(1), HW_ADDR(2),
+ HW_ADDR(3), HW_ADDR(4), HW_ADDR(5) );
+#undef HW_ADDR
+
+ return len;
+}
+
+
+__initfunc (static int ne2_probe1(struct device *dev, int slot))
+{
+ int i, base_addr, irq;
+ unsigned char POS;
+ unsigned char SA_prom[32];
+ const char *name = "NE/2";
+ int start_page, stop_page;
+ static unsigned version_printed = 0;
+
+ /* We should have a "dev" from Space.c or the static module table. */
+ if (dev == NULL) {
+ printk(KERN_ERR "ne2.c: Passed a NULL device.\n");
+ dev = init_etherdev(0, 0);
+ }
+
+ if (ei_debug && version_printed++ == 0)
+ printk(version);
+
+ printk("NE/2 ethercard found in slot %d:", slot);
+
+ /* Read base IO and IRQ from the POS-registers */
+ POS = mca_read_stored_pos(slot, 2);
+ if(!(POS % 2)) {
+ printk(" disabled.\n");
+ return ENODEV;
+ }
+
+ i = (POS & 0xE)>>1;
+ /* printk("Halleluja sdog, als er na de pijl een 1 staat is 1 - 1 == 0"
+ " en zou het moeten werken -> %d\n", i);
+ The above line was for remote testing, thanx to sdog ... */
+ base_addr = addresses[i - 1];
+ irq = irqs[(POS & 0x60)>>5];
+
+#ifdef DEBUG
+ printk("POS info : pos 2 = %#x ; base = %#x ; irq = %ld\n", POS,
+ base_addr, irq);
+#endif
+
+#ifndef CRYNWR_WAY
+ /* Reset the card the way they do it in the Crynwr packet driver */
+ for (i=0; i<8; i++)
+ outb(0x0, base_addr + NE_RESET);
+ inb(base_addr + NE_RESET);
+ outb(0x21, base_addr + NE_CMD);
+ if (inb(base_addr + NE_CMD) != 0x21) {
+ printk("NE/2 adapter not responding\n");
+ return ENODEV;
+ }
+
+ /* In the crynwr sources they do a RAM-test here. I skip it. I suppose
+ my RAM is okay. Suppose your memory is broken. Then this test
+ should fail and you won't be able to use your card. But if I do not
+ test, you won't be able to use your card, neither. So this test
+ won't help you. */
+
+#else /* _I_ never tested it this way .. Go ahead and try ...*/
+ /* Reset card. Who knows what dain-bramaged state it was left in. */
+ {
+ unsigned long reset_start_time = jiffies;
+
+ /* DON'T change these to inb_p/outb_p or reset will fail on
+ clones.. */
+ outb(inb(base_addr + NE_RESET), base_addr + NE_RESET);
+
+ while ((inb_p(base_addr + EN0_ISR) & ENISR_RESET) == 0)
+ if (jiffies - reset_start_time > 2*HZ/100) {
+ printk(" not found (no reset ack).\n");
+ return ENODEV;
+ }
+
+ outb_p(0xff, base_addr + EN0_ISR); /* Ack all intr. */
+ }
+#endif
+
+
+ /* Read the 16 bytes of station address PROM.
+ We must first initialize registers, similar to
+ NS8390_init(eifdev, 0).
+ We can't reliably read the SAPROM address without this.
+ (I learned the hard way!). */
+ {
+ struct {
+ unsigned char value, offset;
+ } program_seq[] = {
+ /* Select page 0 */
+ {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD},
+ {0x49, EN0_DCFG}, /* Set WORD-wide (0x49) access. */
+ {0x00, EN0_RCNTLO}, /* Clear the count regs. */
+ {0x00, EN0_RCNTHI},
+ {0x00, EN0_IMR}, /* Mask completion irq. */
+ {0xFF, EN0_ISR},
+ {E8390_RXOFF, EN0_RXCR}, /* 0x20 Set to monitor */
+ {E8390_TXOFF, EN0_TXCR}, /* 0x02 and loopback mode. */
+ {32, EN0_RCNTLO},
+ {0x00, EN0_RCNTHI},
+ {0x00, EN0_RSARLO}, /* DMA starting at 0x0000. */
+ {0x00, EN0_RSARHI},
+ {E8390_RREAD+E8390_START, E8390_CMD},
+ };
+
+ for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
+ outb_p(program_seq[i].value, base_addr +
+ program_seq[i].offset);
+
+ }
+ for(i = 0; i < 6 /*sizeof(SA_prom)*/; i+=1) {
+ SA_prom[i] = inb(base_addr + NE_DATAPORT);
+ }
+
+ start_page = NESM_START_PG;
+ stop_page = NESM_STOP_PG;
+
+ dev->irq=irq;
+
+ /* Snarf the interrupt now. There's no point in waiting since we cannot
+ share and the board will usually be enabled. */
+ {
+ int irqval = request_irq(dev->irq, ei_interrupt,
+ 0, name, NULL);
+ if (irqval) {
+ printk (" unable to get IRQ %d (irqval=%d).\n",
+ dev->irq, +irqval);
+ return EAGAIN;
+ }
+ }
+
+ dev->base_addr = base_addr;
+
+ /* Allocate dev->priv and fill in 8390 specific dev fields. */
+ if (ethdev_init(dev)) {
+ printk (" unable to get memory for dev->priv.\n");
+ free_irq(dev->irq, NULL);
+ return -ENOMEM;
+ }
+
+ request_region(base_addr, NE_IO_EXTENT, name);
+
+ for(i = 0; i < ETHER_ADDR_LEN; i++) {
+ printk(" %2.2x", SA_prom[i]);
+ dev->dev_addr[i] = SA_prom[i];
+ }
+
+ printk("\n%s: %s found at %#x, using IRQ %d.\n",
+ dev->name, name, base_addr, dev->irq);
+
+ mca_set_adapter_procfn(slot, (MCA_ProcFn) ne2_procinfo, dev);
+
+ ei_status.name = name;
+ ei_status.tx_start_page = start_page;
+ ei_status.stop_page = stop_page;
+ ei_status.word16 = (2 == 2);
+
+ ei_status.rx_start_page = start_page + TX_PAGES;
+#ifdef PACKETBUF_MEMSIZE
+ /* Allow the packet buffer size to be overridden by know-it-alls. */
+ ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
+#endif
+
+ ei_status.reset_8390 = &ne_reset_8390;
+ ei_status.block_input = &ne_block_input;
+ ei_status.block_output = &ne_block_output;
+ ei_status.get_8390_hdr = &ne_get_8390_hdr;
+
+ ei_status.priv = slot;
+
+ dev->open = &ne_open;
+ dev->stop = &ne_close;
+ NS8390_init(dev, 0);
+ return 0;
+}
+
+static int ne_open(struct device *dev)
+{
+ ei_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int ne_close(struct device *dev)
+{
+ if (ei_debug > 1)
+ printk("%s: Shutting down ethercard.\n", dev->name);
+ ei_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+/* Hard reset the card. This used to pause for the same period that a
+ 8390 reset command required, but that shouldn't be necessary. */
+static void ne_reset_8390(struct device *dev)
+{
+ unsigned long reset_start_time = jiffies;
+
+ if (ei_debug > 1)
+ printk("resetting the 8390 t=%ld...", jiffies);
+
+ /* DON'T change these to inb_p/outb_p or reset will fail on clones. */
+ outb(inb(NE_BASE + NE_RESET), NE_BASE + NE_RESET);
+
+ ei_status.txing = 0;
+ ei_status.dmaing = 0;
+
+ /* This check _should_not_ be necessary, omit eventually. */
+ while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
+ if (jiffies - reset_start_time > 2*HZ/100) {
+ printk("%s: ne_reset_8390() did not complete.\n",
+ dev->name);
+ break;
+ }
+ outb_p(ENISR_RESET, NE_BASE + EN0_ISR); /* Ack intr. */
+}
+
+/* Grab the 8390 specific header. Similar to the block_input routine, but
+ we don't need to be concerned with ring wrap as the header will be at
+ the start of a page, so we optimize accordingly. */
+
+static void ne_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr,
+ int ring_page)
+{
+
+ int nic_base = dev->base_addr;
+
+ /* This *shouldn't* happen.
+ If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_get_8390_hdr "
+ "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
+ return;
+ }
+
+ ei_status.dmaing |= 0x01;
+ outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ outb_p(sizeof(struct e8390_pkt_hdr), nic_base + EN0_RCNTLO);
+ outb_p(0, nic_base + EN0_RCNTHI);
+ outb_p(0, nic_base + EN0_RSARLO); /* On page boundary */
+ outb_p(ring_page, nic_base + EN0_RSARHI);
+ outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+
+ if (ei_status.word16)
+ insw(NE_BASE + NE_DATAPORT, hdr,
+ sizeof(struct e8390_pkt_hdr)>>1);
+ else
+ insb(NE_BASE + NE_DATAPORT, hdr,
+ sizeof(struct e8390_pkt_hdr));
+
+ outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+}
+
+/* Block input and output, similar to the Crynwr packet driver. If you
+ are porting to a new ethercard, look at the packet driver source for
+ hints. The NEx000 doesn't share the on-board packet memory -- you have
+ to put the packet out through the "remote DMA" dataport using outb. */
+
+static void ne_block_input(struct device *dev, int count, struct sk_buff *skb,
+ int ring_offset)
+{
+#ifdef NE_SANITY_CHECK
+ int xfer_count = count;
+#endif
+ int nic_base = dev->base_addr;
+ char *buf = skb->data;
+
+ /* This *shouldn't* happen.
+ If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_block_input "
+ "[DMAstat:%d][irqlock:%d][intr:%ld].\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
+ return;
+ }
+ ei_status.dmaing |= 0x01;
+ outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
+ outb_p(count & 0xff, nic_base + EN0_RCNTLO);
+ outb_p(count >> 8, nic_base + EN0_RCNTHI);
+ outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
+ outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
+ outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+ if (ei_status.word16) {
+ insw(NE_BASE + NE_DATAPORT,buf,count>>1);
+ if (count & 0x01) {
+ buf[count-1] = inb(NE_BASE + NE_DATAPORT);
+#ifdef NE_SANITY_CHECK
+ xfer_count++;
+#endif
+ }
+ } else {
+ insb(NE_BASE + NE_DATAPORT, buf, count);
+ }
+
+#ifdef NE_SANITY_CHECK
+ /* This was for the ALPHA version only, but enough people have
+ been encountering problems so it is still here. If you see
+ this message you either 1) have a slightly incompatible clone
+ or 2) have noise/speed problems with your bus. */
+ if (ei_debug > 1) { /* DMA termination address check... */
+ int addr, tries = 20;
+ do {
+ /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
+ -- it's broken for Rx on some cards! */
+ int high = inb_p(nic_base + EN0_RSARHI);
+ int low = inb_p(nic_base + EN0_RSARLO);
+ addr = (high << 8) + low;
+ if (((ring_offset + xfer_count) & 0xff) == low)
+ break;
+ } while (--tries > 0);
+ if (tries <= 0)
+ printk("%s: RX transfer address mismatch,"
+ "%#4.4x (expected) vs. %#4.4x (actual).\n",
+ dev->name, ring_offset + xfer_count, addr);
+ }
+#endif
+ outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+}
+
+static void ne_block_output(struct device *dev, int count,
+ const unsigned char *buf, const int start_page)
+{
+ int nic_base = NE_BASE;
+ unsigned long dma_start;
+#ifdef NE_SANITY_CHECK
+ int retries = 0;
+#endif
+
+ /* Round the count up for word writes. Do we need to do this?
+ What effect will an odd byte count have on the 8390?
+ I should check someday. */
+ if (ei_status.word16 && (count & 0x01))
+ count++;
+
+ /* This *shouldn't* happen.
+ If it does, it's the last thing you'll see */
+ if (ei_status.dmaing) {
+ printk("%s: DMAing conflict in ne_block_output."
+ "[DMAstat:%d][irqlock:%d][intr:%ld]\n",
+ dev->name, ei_status.dmaing, ei_status.irqlock,
+ dev->interrupt);
+ return;
+ }
+ ei_status.dmaing |= 0x01;
+ /* We should already be in page 0, but to be safe... */
+ outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);
+
+#ifdef NE_SANITY_CHECK
+retry:
+#endif
+
+#ifdef NE8390_RW_BUGFIX
+ /* Handle the read-before-write bug the same way as the
+ Crynwr packet driver -- the NatSemi method doesn't work.
+ Actually this doesn't always work either, but if you have
+ problems with your NEx000 this is better than nothing! */
+ outb_p(0x42, nic_base + EN0_RCNTLO);
+ outb_p(0x00, nic_base + EN0_RCNTHI);
+ outb_p(0x42, nic_base + EN0_RSARLO);
+ outb_p(0x00, nic_base + EN0_RSARHI);
+ outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
+ /* Make certain that the dummy read has occurred. */
+ SLOW_DOWN_IO;
+ SLOW_DOWN_IO;
+ SLOW_DOWN_IO;
+#endif
+
+ outb_p(ENISR_RDC, nic_base + EN0_ISR);
+
+ /* Now the normal output. */
+ outb_p(count & 0xff, nic_base + EN0_RCNTLO);
+ outb_p(count >> 8, nic_base + EN0_RCNTHI);
+ outb_p(0x00, nic_base + EN0_RSARLO);
+ outb_p(start_page, nic_base + EN0_RSARHI);
+
+ outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
+ if (ei_status.word16) {
+ outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
+ } else {
+ outsb(NE_BASE + NE_DATAPORT, buf, count);
+ }
+
+ dma_start = jiffies;
+
+#ifdef NE_SANITY_CHECK
+ /* This was for the ALPHA version only, but enough people have
+ been encountering problems so it is still here. */
+
+ if (ei_debug > 1) { /* DMA termination address check... */
+ int addr, tries = 20;
+ do {
+ int high = inb_p(nic_base + EN0_RSARHI);
+ int low = inb_p(nic_base + EN0_RSARLO);
+ addr = (high << 8) + low;
+ if ((start_page << 8) + count == addr)
+ break;
+ } while (--tries > 0);
+ if (tries <= 0) {
+ printk("%s: Tx packet transfer address mismatch,"
+ "%#4.4x (expected) vs. %#4.4x (actual).\n",
+ dev->name, (start_page << 8) + count, addr);
+ if (retries++ == 0)
+ goto retry;
+ }
+ }
+#endif
+
+ while ((inb_p(nic_base + EN0_ISR) & ENISR_RDC) == 0)
+ if (jiffies - dma_start > 2*HZ/100) { /* 20ms */
+ printk("%s: timeout waiting for Tx RDC.\n", dev->name);
+ ne_reset_8390(dev);
+ NS8390_init(dev,1);
+ break;
+ }
+
+ outb_p(ENISR_RDC, nic_base + EN0_ISR); /* Ack intr. */
+ ei_status.dmaing &= ~0x01;
+ return;
+}
+
+
+#ifdef MODULE
+#define MAX_NE_CARDS 4 /* Max number of NE cards per module */
+#define NAMELEN 8 /* # of chars for storing dev->name */
+static char namelist[NAMELEN * MAX_NE_CARDS] = { 0, };
+static struct device dev_ne[MAX_NE_CARDS] = {
+ {
+ NULL, /* assign a chunk of namelist[] below */
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, NULL
+ },
+};
+
+static int io[MAX_NE_CARDS] = { 0, };
+static int irq[MAX_NE_CARDS] = { 0, };
+static int bad[MAX_NE_CARDS] = { 0, }; /* 0xbad = bad sig or no reset ack */
+
+#ifdef MODULE_PARM
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+MODULE_PARM(bad, "1-" __MODULE_STRING(MAX_NE_CARDS) "i");
+#endif
+
+/* Module code fixed by David Weinehall */
+
+int init_module(void)
+{
+ int this_dev, found = 0;
+
+ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+ struct device *dev = &dev_ne[this_dev];
+ dev->name = namelist+(NAMELEN*this_dev);
+ dev->irq = irq[this_dev];
+ dev->mem_end = bad[this_dev];
+ dev->base_addr = io[this_dev];
+ dev->init = ne2_probe;
+ if (register_netdev(dev) != 0) {
+ if (found != 0) return 0; /* Got at least one. */
+
+ printk(KERN_WARNING "ne2.c: No NE/2 card found.\n");
+ return -ENXIO;
+ }
+ found++;
+ }
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ int this_dev;
+
+ for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) {
+ struct device *dev = &dev_ne[this_dev];
+ if (dev->priv != NULL) {
+ mca_mark_as_unused(ei_status.priv);
+ mca_set_adapter_procfn( ei_status.priv, NULL, NULL);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ free_irq(dev->irq, dev);
+ /* removed (temporary) fot */
+ /* irq2dev_map[dev->irq] = NULL; */
+ release_region(dev->base_addr, NE_IO_EXTENT);
+ unregister_netdev(dev);
+ }
+ }
+}
+#endif /* MODULE */
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne2.c"
+ * version-control: t
+ * kept-new-versions: 5
+ * End:
+ */
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
new file mode 100644
index 000000000..d5764928a
--- /dev/null
+++ b/drivers/net/ne3210.c
@@ -0,0 +1,432 @@
+/*
+ ne3210.c
+
+ Linux driver for Novell NE3210 EISA Network Adapter
+
+ Copyright (C) 1998, Paul Gortmaker.
+
+ This software may be used and distributed according to the terms
+ of the GNU Public License, incorporated herein by reference.
+
+ Information and Code Sources:
+
+ 1) Based upon my other EISA 8390 drivers (lne390, es3210, smc-ultra32)
+ 2) The existing myriad of other Linux 8390 drivers by Donald Becker.
+ 3) Info for getting IRQ and sh-mem gleaned from the EISA cfg file
+
+ The NE3210 is an EISA shared memory NS8390 implementation. Shared
+ memory address > 1MB should work with this driver.
+
+ Note that the .cfg file (3/11/93, v1.0) has AUI and BNC switched
+ around (or perhaps there are some defective/backwards cards ???)
+
+ This driver WILL NOT WORK FOR THE NE3200 - it is completely different
+ and does not use an 8390 at all.
+
+*/
+
+static const char *version =
+ "ne3210.c: Driver revision v0.03, 30/09/98\n";
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+
+#include <asm/io.h>
+#include <asm/system.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include "8390.h"
+
+int ne3210_probe(struct device *dev);
+int ne3210_probe1(struct device *dev, int ioaddr);
+
+static int ne3210_open(struct device *dev);
+static int ne3210_close(struct device *dev);
+
+static void ne3210_reset_8390(struct device *dev);
+
+static void ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page);
+static void ne3210_block_input(struct device *dev, int count, struct sk_buff *skb, int ring_offset);
+static void ne3210_block_output(struct device *dev, int count, const unsigned char *buf, const int start_page);
+
+#define NE3210_START_PG 0x00 /* First page of TX buffer */
+#define NE3210_STOP_PG 0x80 /* Last page +1 of RX ring */
+
+#define NE3210_ID_PORT 0xc80 /* Same for all EISA cards */
+#define NE3210_IO_EXTENT 0x20
+#define NE3210_SA_PROM 0x16 /* Start of e'net addr. */
+#define NE3210_RESET_PORT 0xc84
+#define NE3210_NIC_OFFSET 0x00 /* Hello, the 8390 is *here* */
+
+#define NE3210_ADDR0 0x00 /* 3 byte vendor prefix */
+#define NE3210_ADDR1 0x00
+#define NE3210_ADDR2 0x1b
+
+#define NE3210_ID 0x0118cc3a /* 0x3acc = 1110 10110 01100 = nvl */
+
+#define NE3210_CFG1 0xc84 /* NB: 0xc84 is also "reset" port. */
+#define NE3210_CFG2 0xc90
+
+/*
+ * You can OR any of the following bits together and assign it
+ * to NE3210_DEBUG to get verbose driver info during operation.
+ * Currently only the probe one is implemented.
+ */
+
+#define NE3210_D_PROBE 0x01
+#define NE3210_D_RX_PKT 0x02
+#define NE3210_D_TX_PKT 0x04
+#define NE3210_D_IRQ 0x08
+
+#define NE3210_DEBUG 0x0
+
+static unsigned char irq_map[] __initdata = {15, 12, 11, 10, 9, 7, 5, 3};
+static unsigned int shmem_map[] __initdata = {0xff0, 0xfe0, 0xfff0, 0xd8, 0xffe0, 0xffc0, 0xd0, 0x0};
+
+/*
+ * Probe for the card. The best way is to read the EISA ID if it
+ * is known. Then we can check the prefix of the station address
+ * PROM for a match against the value assigned to Novell.
+ */
+
+__initfunc(int ne3210_probe(struct device *dev))
+{
+ unsigned short ioaddr = dev->base_addr;
+
+ if (ioaddr > 0x1ff) /* Check a single specified location. */
+ return ne3210_probe1(dev, ioaddr);
+ else if (ioaddr > 0) /* Don't probe at all. */
+ return ENXIO;
+
+ if (!EISA_bus) {
+#if NE3210_DEBUG & NE3210_D_PROBE
+ printk("ne3210-debug: Not an EISA bus. Not probing high ports.\n");
+#endif
+ return ENXIO;
+ }
+
+ /* EISA spec allows for up to 16 slots, but 8 is typical. */
+ for (ioaddr = 0x1000; ioaddr < 0x9000; ioaddr += 0x1000) {
+ if (check_region(ioaddr , NE3210_IO_EXTENT))
+ continue;
+ if (ne3210_probe1(dev, ioaddr) == 0)
+ return 0;
+ }
+
+ return ENODEV;
+}
+
+__initfunc(int ne3210_probe1(struct device *dev, int ioaddr))
+{
+ int i;
+ unsigned long eisa_id;
+ const char *ifmap[] = {"UTP", "?", "BNC", "AUI"};
+
+ if (inb_p(ioaddr + NE3210_ID_PORT) == 0xff) return -ENODEV;
+
+#if NE3210_DEBUG & NE3210_D_PROBE
+ printk("ne3210-debug: probe at %#x, ID %#8x\n", ioaddr, inl(ioaddr + NE3210_ID_PORT));
+ printk("ne3210-debug: config regs: %#x %#x\n",
+ inb(ioaddr + NE3210_CFG1), inb(ioaddr + NE3210_CFG2));
+#endif
+
+
+/* Check the EISA ID of the card. */
+ eisa_id = inl(ioaddr + NE3210_ID_PORT);
+ if (eisa_id != NE3210_ID) {
+ return ENODEV;
+ }
+
+
+#if 0
+/* Check the vendor ID as well. Not really required. */
+ if (inb(ioaddr + NE3210_SA_PROM + 0) != NE3210_ADDR0
+ || inb(ioaddr + NE3210_SA_PROM + 1) != NE3210_ADDR1
+ || inb(ioaddr + NE3210_SA_PROM + 2) != NE3210_ADDR2 ) {
+ printk("ne3210.c: card not found");
+ for(i = 0; i < ETHER_ADDR_LEN; i++)
+ printk(" %02x", inb(ioaddr + NE3210_SA_PROM + i));
+ printk(" (invalid prefix).\n");
+ return ENODEV;
+ }
+#endif
+
+ if (load_8390_module("ne3210.c"))
+ return -ENOSYS;
+
+ /* We should have a "dev" from Space.c or the static module table. */
+ if (dev == NULL) {
+ printk("ne3210.c: Passed a NULL device.\n");
+ dev = init_etherdev(0, 0);
+ }
+
+ /* Allocate dev->priv and fill in 8390 specific dev fields. */
+ if (ethdev_init(dev)) {
+ printk ("ne3210.c: unable to allocate memory for dev->priv!\n");
+ return -ENOMEM;
+ }
+
+ printk("ne3210.c: NE3210 in EISA slot %d, media: %s, addr:",
+ ioaddr/0x1000, ifmap[inb(ioaddr + NE3210_CFG2) >> 6]);
+ for(i = 0; i < ETHER_ADDR_LEN; i++)
+ printk(" %02x", (dev->dev_addr[i] = inb(ioaddr + NE3210_SA_PROM + i)));
+ printk(".\nne3210.c: ");
+
+ /* Snarf the interrupt now. CFG file has them all listed as `edge' with share=NO */
+ if (dev->irq == 0) {
+ unsigned char irq_reg = inb(ioaddr + NE3210_CFG2) >> 3;
+ dev->irq = irq_map[irq_reg & 0x07];
+ printk("using");
+ } else {
+ /* This is useless unless we reprogram the card here too */
+ if (dev->irq == 2) dev->irq = 9; /* Doh! */
+ printk("assigning");
+ }
+ printk(" IRQ %d,", dev->irq);
+
+ if (request_irq(dev->irq, ei_interrupt, 0, "ne3210", dev)) {
+ printk (" unable to get IRQ %d.\n", dev->irq);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return EAGAIN;
+ }
+
+ if (dev->mem_start == 0) {
+ unsigned char mem_reg = inb(ioaddr + NE3210_CFG2) & 0x07;
+ dev->mem_start = shmem_map[mem_reg] * 0x1000;
+ printk(" using ");
+ } else {
+ /* Should check for value in shmem_map and reprogram the card to use it */
+ dev->mem_start &= 0xfff8000;
+ printk(" assigning ");
+ }
+
+ printk("%dkB memory at physical address %#lx\n",
+ NE3210_STOP_PG/4, dev->mem_start);
+
+ /*
+ BEWARE!! Some dain-bramaged EISA SCUs will allow you to put
+ the card mem within the region covered by `normal' RAM !!!
+ */
+ if (dev->mem_start > 1024*1024) { /* phys addr > 1MB */
+ if (dev->mem_start < virt_to_bus(high_memory)) {
+ printk(KERN_CRIT "ne3210.c: Card RAM overlaps with normal memory!!!\n");
+ printk(KERN_CRIT "ne3210.c: Use EISA SCU to set card memory below 1MB,\n");
+ printk(KERN_CRIT "ne3210.c: or to an address above 0x%lx.\n", virt_to_bus(high_memory));
+ printk(KERN_CRIT "ne3210.c: Driver NOT installed.\n");
+ free_irq(dev->irq, dev);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return EINVAL;
+ }
+ dev->mem_start = (unsigned long)ioremap(dev->mem_start, NE3210_STOP_PG*0x100);
+ if (dev->mem_start == 0) {
+ printk(KERN_ERR "ne3210.c: Unable to remap card memory above 1MB !!\n");
+ printk(KERN_ERR "ne3210.c: Try using EISA SCU to set memory below 1MB.\n");
+ printk(KERN_ERR "ne3210.c: Driver NOT installed.\n");
+ free_irq(dev->irq, dev);
+ kfree(dev->priv);
+ dev->priv = NULL;
+ return EAGAIN;
+ }
+ ei_status.reg0 = 1; /* Use as remap flag */
+ printk("ne3210.c: remapped %dkB card memory to virtual address %#lx\n",
+ NE3210_STOP_PG/4, dev->mem_start);
+ }
+
+ dev->mem_end = dev->rmem_end = dev->mem_start
+ + (NE3210_STOP_PG - NE3210_START_PG)*256;
+ dev->rmem_start = dev->mem_start + TX_PAGES*256;
+
+ /* The 8390 offset is zero for the NE3210 */
+ dev->base_addr = ioaddr;
+ request_region(dev->base_addr, NE3210_IO_EXTENT, "ne3210");
+
+ ei_status.name = "NE3210";
+ ei_status.tx_start_page = NE3210_START_PG;
+ ei_status.rx_start_page = NE3210_START_PG + TX_PAGES;
+ ei_status.stop_page = NE3210_STOP_PG;
+ ei_status.word16 = 1;
+
+ if (ei_debug > 0)
+ printk(version);
+
+ ei_status.reset_8390 = &ne3210_reset_8390;
+ ei_status.block_input = &ne3210_block_input;
+ ei_status.block_output = &ne3210_block_output;
+ ei_status.get_8390_hdr = &ne3210_get_8390_hdr;
+
+ dev->open = &ne3210_open;
+ dev->stop = &ne3210_close;
+ NS8390_init(dev, 0);
+ return 0;
+}
+
+/*
+ * Reset by toggling the "Board Enable" bits (bit 2 and 0).
+ */
+
+static void ne3210_reset_8390(struct device *dev)
+{
+ unsigned short ioaddr = dev->base_addr;
+
+ outb(0x04, ioaddr + NE3210_RESET_PORT);
+ if (ei_debug > 1) printk("%s: resetting the NE3210...", dev->name);
+
+ mdelay(2);
+
+ ei_status.txing = 0;
+ outb(0x01, ioaddr + NE3210_RESET_PORT);
+ if (ei_debug > 1) printk("reset done\n");
+
+ return;
+}
+
+/*
+ * Note: In the following three functions is the implicit assumption
+ * that the associated memcpy will only use "rep; movsl" as long as
+ * we keep the counts as some multiple of doublewords. This is a
+ * requirement of the hardware, and also prevents us from using
+ * eth_io_copy_and_sum() since we can't guarantee it will limit
+ * itself to doubleword access.
+ */
+
+/*
+ * Grab the 8390 specific header. Similar to the block_input routine, but
+ * we don't need to be concerned with ring wrap as the header will be at
+ * the start of a page, so we optimize accordingly. (A single doubleword.)
+ */
+
+static void
+ne3210_get_8390_hdr(struct device *dev, struct e8390_pkt_hdr *hdr, int ring_page)
+{
+ unsigned long hdr_start = dev->mem_start + ((ring_page - NE3210_START_PG)<<8);
+ memcpy_fromio(hdr, hdr_start, sizeof(struct e8390_pkt_hdr));
+ hdr->count = (hdr->count + 3) & ~3; /* Round up allocation. */
+}
+
+/*
+ * Block input and output are easy on shared memory ethercards, the only
+ * complication is when the ring buffer wraps. The count will already
+ * be rounded up to a doubleword value via ne3210_get_8390_hdr() above.
+ */
+
+static void ne3210_block_input(struct device *dev, int count, struct sk_buff *skb,
+ int ring_offset)
+{
+ unsigned long xfer_start = dev->mem_start + ring_offset - (NE3210_START_PG<<8);
+
+ if (xfer_start + count > dev->rmem_end) {
+ /* Packet wraps over end of ring buffer. */
+ int semi_count = dev->rmem_end - xfer_start;
+ memcpy_fromio(skb->data, xfer_start, semi_count);
+ count -= semi_count;
+ memcpy_fromio(skb->data + semi_count, dev->rmem_start, count);
+ } else {
+ /* Packet is in one chunk. */
+ memcpy_fromio(skb->data, xfer_start, count);
+ }
+}
+
+static void ne3210_block_output(struct device *dev, int count,
+ const unsigned char *buf, int start_page)
+{
+ unsigned long shmem = dev->mem_start + ((start_page - NE3210_START_PG)<<8);
+
+ count = (count + 3) & ~3; /* Round up to doubleword */
+ memcpy_toio(shmem, buf, count);
+}
+
+static int ne3210_open(struct device *dev)
+{
+ ei_open(dev);
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+static int ne3210_close(struct device *dev)
+{
+
+ if (ei_debug > 1)
+ printk("%s: Shutting down ethercard.\n", dev->name);
+
+ ei_close(dev);
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+#ifdef MODULE
+#define MAX_NE3210_CARDS 4 /* Max number of NE3210 cards per module */
+#define NAMELEN 8 /* # of chars for storing dev->name */
+static char namelist[NAMELEN * MAX_NE3210_CARDS] = { 0, };
+static struct device dev_ne3210[MAX_NE3210_CARDS] = {
+ {
+ NULL, /* assign a chunk of namelist[] below */
+ 0, 0, 0, 0,
+ 0, 0,
+ 0, 0, 0, NULL, NULL
+ },
+};
+
+static int io[MAX_NE3210_CARDS] = { 0, };
+static int irq[MAX_NE3210_CARDS] = { 0, };
+static int mem[MAX_NE3210_CARDS] = { 0, };
+
+MODULE_PARM(io, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+MODULE_PARM(mem, "1-" __MODULE_STRING(MAX_NE3210_CARDS) "i");
+
+int init_module(void)
+{
+ int this_dev, found = 0;
+
+ for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
+ struct device *dev = &dev_ne3210[this_dev];
+ dev->name = namelist+(NAMELEN*this_dev);
+ dev->irq = irq[this_dev];
+ dev->base_addr = io[this_dev];
+ dev->mem_start = mem[this_dev];
+ dev->init = ne3210_probe;
+ /* Default is to only install one card. */
+ if (io[this_dev] == 0 && this_dev != 0) break;
+ if (register_netdev(dev) != 0) {
+ printk(KERN_WARNING "ne3210.c: No NE3210 card found (i/o = 0x%x).\n", io[this_dev]);
+ if (found != 0) { /* Got at least one. */
+ lock_8390_module();
+ return 0;
+ }
+ return -ENXIO;
+ }
+ found++;
+ }
+ lock_8390_module();
+ return 0;
+}
+
+void cleanup_module(void)
+{
+ int this_dev;
+
+ for (this_dev = 0; this_dev < MAX_NE3210_CARDS; this_dev++) {
+ struct device *dev = &dev_ne3210[this_dev];
+ if (dev->priv != NULL) {
+ void *priv = dev->priv;
+ free_irq(dev->irq, dev);
+ release_region(dev->base_addr, NE3210_IO_EXTENT);
+ if (ei_status.reg0)
+ iounmap((void *)dev->mem_start);
+ dev->priv = NULL;
+ unregister_netdev(dev);
+ kfree(priv);
+ }
+ }
+ unlock_8390_module();
+}
+#endif /* MODULE */
+
diff --git a/drivers/net/net_init.c b/drivers/net/net_init.c
index 360f62166..5e381d985 100644
--- a/drivers/net/net_init.c
+++ b/drivers/net/net_init.c
@@ -41,6 +41,7 @@
#include <linux/if_arp.h>
#include <linux/if_ltalk.h>
#include <linux/rtnetlink.h>
+#include <net/neighbour.h>
/* The network devices currently exist only in the socket namespace, so these
entries are unused. The only ones that make sense are
@@ -219,6 +220,21 @@ struct device *init_hippi_dev(struct device *dev, int sizeof_priv)
hippi_setup(tmp_dev);
return tmp_dev;
}
+
+static int hippi_neigh_setup_dev(struct device *dev, struct neigh_parms *p)
+{
+ /* Never send broadcast/multicast ARP messages */
+ p->mcast_probes = 0;
+
+ /* In IPv6 unicast probes are valid even on NBMA,
+ * because they are encapsulated in normal IPv6 protocol.
+ * Should be a generic flag.
+ */
+ if (p->tbl->family != AF_INET6)
+ p->ucast_probes = 0;
+ return 0;
+}
+
#endif
void ether_setup(struct device *dev)
@@ -304,6 +320,7 @@ void hippi_setup(struct device *dev)
dev->hard_header_parse = NULL;
dev->hard_header_cache = NULL;
dev->header_cache_update = NULL;
+ dev->neigh_setup = hippi_neigh_setup_dev;
/*
* We don't support HIPPI `ARP' for the time being, and probably
@@ -317,12 +334,13 @@ void hippi_setup(struct device *dev)
dev->tx_queue_len = 25 /* 5 */;
memset(dev->broadcast, 0xFF, HIPPI_ALEN);
- /* New-style flags. */
- dev->flags = IFF_NODYNARP; /*
- * HIPPI doesn't support
- * broadcast+multicast and we only
- * use static ARP tables.
- */
+
+ /*
+ * HIPPI doesn't support broadcast+multicast and we only use
+ * static ARP tables. ARP is disabled by hippi_neigh_setup_dev.
+ */
+ dev->flags = 0;
+
dev_init_buffers(dev);
}
#endif
diff --git a/drivers/net/ni5010.c b/drivers/net/ni5010.c
index 9eea1b7ac..b5e959ddd 100644
--- a/drivers/net/ni5010.c
+++ b/drivers/net/ni5010.c
@@ -771,8 +771,9 @@ static void show_registers(struct device *dev)
}
#ifdef MODULE
+static char devicename[9] = { 0, };
static struct device dev_ni5010 = {
- " ",
+ devicename,
0, 0, 0, 0,
0, 0,
0, 0, 0, NULL, ni5010_probe };
diff --git a/drivers/net/ni52.c b/drivers/net/ni52.c
index 7c3e60bb3..9f47c66e8 100644
--- a/drivers/net/ni52.c
+++ b/drivers/net/ni52.c
@@ -1303,8 +1303,9 @@ static void set_multicast_list(struct device *dev)
}
#ifdef MODULE
+static char devicename[9] = { 0, };
static struct device dev_ni52 = {
- " ", /* "ni5210": device name inserted by net_init.c */
+ devicename, /* "ni5210": device name inserted by net_init.c */
0, 0, 0, 0,
0x300, 9, /* I/O address, IRQ */
0, 0, 0, NULL, ni52_probe };
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index c778255cb..8fd432aa9 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -351,6 +351,7 @@ __initfunc(static int ni65_probe1(struct device *dev,int ioaddr))
{
int i,j;
struct priv *p;
+ unsigned long flags;
for(i=0;i<NUM_CARDS;i++) {
if(check_region(ioaddr, cards[i].total_size))
@@ -417,12 +418,20 @@ __initfunc(static int ni65_probe1(struct device *dev,int ioaddr))
int dma = dmatab[i];
if(test_bit(dma,&dma_channels) || request_dma(dma,"ni6510"))
continue;
+
+ flags=claim_dma_lock();
disable_dma(dma);
set_dma_mode(dma,DMA_MODE_CASCADE);
enable_dma(dma);
+ release_dma_lock(flags);
+
ni65_init_lance(p,dev->dev_addr,0,0); /* trigger memory access */
+
+ flags=claim_dma_lock();
disable_dma(dma);
free_dma(dma);
+ release_dma_lock(flags);
+
if(readreg(CSR0) & CSR0_IDON)
break;
}
@@ -718,20 +727,25 @@ static int ni65_lance_reinit(struct device *dev)
{
int i;
struct priv *p = (struct priv *) dev->priv;
+ unsigned long flags;
p->lock = 0;
p->xmit_queued = 0;
+ flags=claim_dma_lock();
disable_dma(dev->dma); /* I've never worked with dma, but we do it like the packetdriver */
set_dma_mode(dev->dma,DMA_MODE_CASCADE);
enable_dma(dev->dma);
+ release_dma_lock(flags);
outw(inw(PORT+L_RESET),PORT+L_RESET); /* first: reset the card */
if( (i=readreg(CSR0) ) != 0x4)
{
printk(KERN_ERR "%s: can't RESET %s card: %04x\n",dev->name,
cards[p->cardno].cardname,(int) i);
+ flags=claim_dma_lock();
disable_dma(dev->dma);
+ release_dma_lock(flags);
return 0;
}
@@ -782,7 +796,9 @@ static int ni65_lance_reinit(struct device *dev)
return 1; /* ->OK */
}
printk(KERN_ERR "%s: can't init lance, status: %04x\n",dev->name,(int) inw(PORT+L_DATAREG));
+ flags=claim_dma_lock();
disable_dma(dev->dma);
+ release_dma_lock(flags);
return 0; /* ->Error */
}
@@ -1167,8 +1183,10 @@ static void set_multicast_list(struct device *dev)
}
#ifdef MODULE
+static char devicename[9] = { 0, };
+
static struct device dev_ni65 = {
- " ", /* "ni6510": device name inserted by net_init.c */
+ devicename, /* "ni6510": device name inserted by net_init.c */
0, 0, 0, 0,
0x360, 9, /* I/O address, IRQ */
0, 0, 0, NULL, ni65_probe };
diff --git a/drivers/net/plip.c b/drivers/net/plip.c
index 5dd8d1d54..91666827e 100644
--- a/drivers/net/plip.c
+++ b/drivers/net/plip.c
@@ -242,7 +242,10 @@ plip_init_dev(struct device *dev, struct parport *pb))
pardev = parport_register_device(pb, dev->name, plip_preempt,
plip_wakeup, plip_interrupt,
- PARPORT_DEV_LURK, dev);
+ 0, dev);
+
+ if (!pardev)
+ return -ENODEV;
printk(KERN_INFO "%s", version);
printk(KERN_INFO "%s: Parallel port at %#3lx, using IRQ %d\n", dev->name,
@@ -1175,7 +1178,7 @@ void plip_setup(char *str, int *ints)
timid = 1;
} else {
if (ints[0] == 0 || ints[1] == 0) {
- /* disable driver on "parport=" or "parport=0" */
+ /* disable driver on "plip=" or "plip=0" */
parport[0] = -2;
} else {
printk(KERN_WARNING "warning: 'plip=0x%x' ignored\n",
diff --git a/drivers/net/ppp.c b/drivers/net/ppp.c
index 590a0df97..c578ba87d 100644
--- a/drivers/net/ppp.c
+++ b/drivers/net/ppp.c
@@ -4,7 +4,7 @@
* Al Longyear <longyear@netcom.com>
* Extensively rewritten by Paul Mackerras <paulus@cs.anu.edu.au>
*
- * ==FILEVERSION 980704==
+ * ==FILEVERSION 981004==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
@@ -115,6 +115,7 @@ static void ppp_receive_error(struct ppp *ppp);
static void ppp_output_wakeup(struct ppp *ppp);
static void ppp_send_ctrl(struct ppp *ppp, struct sk_buff *skb);
static void ppp_send_frame(struct ppp *ppp, struct sk_buff *skb);
+static void ppp_send_frames(struct ppp *ppp);
static struct sk_buff *ppp_vj_compress(struct ppp *ppp, struct sk_buff *skb);
static struct ppp *ppp_find (int pid_value);
@@ -439,6 +440,8 @@ ppp_tty_close (struct tty_struct *tty)
return;
if (ppp->backup_tty) {
ppp->tty = ppp->backup_tty;
+ if (ppp_tty_push(ppp))
+ ppp_output_wakeup(ppp);
} else {
ppp->tty = 0;
ppp->sc_xfer = 0;
@@ -448,7 +451,6 @@ ppp_tty_close (struct tty_struct *tty)
ppp_async_release(ppp);
ppp_release(ppp);
- ppp->inuse = 0;
MOD_DEC_USE_COUNT;
}
}
@@ -505,7 +507,6 @@ ppp_tty_read(struct tty_struct *tty, struct file *file, __u8 * buf,
if (file->f_flags & O_NONBLOCK)
break;
- current->timeout = 0;
interruptible_sleep_on(&ppp->read_wait);
err = -EINTR;
if (signal_pending(current))
@@ -1289,6 +1290,9 @@ ppp_dev_close (struct device *dev)
CHECK_PPP_MAGIC(ppp);
+ /* ppp_dev_close may be called with tbusy==1 so we must set it to 0 */
+ dev->tbusy=0;
+
MOD_DEC_USE_COUNT;
return 0;
@@ -1386,6 +1390,7 @@ ppp_ioctl(struct ppp *ppp, unsigned int param2, unsigned long param3)
break;
if (temp_i < PPP_MRU)
temp_i = PPP_MRU;
+ ppp->mru = temp_i;
if (ppp->flags & SC_DEBUG)
printk(KERN_INFO
"ppp_ioctl: set mru to %x\n", temp_i);
@@ -2112,8 +2117,8 @@ extern inline __u8 * store_long (register __u8 *p, register int value) {
/*
* Compress and send an frame to the peer.
- * Should be called with dev->tbusy == 1, having been set by the caller.
- * That is, we use dev->tbusy as a lock to prevent reentry of this
+ * Should be called with xmit_busy == 1, having been set by the caller.
+ * That is, we use xmit_busy as a lock to prevent reentry of this
* procedure.
*/
static void
@@ -2185,7 +2190,7 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
if (new_skb == NULL) {
printk(KERN_ERR "ppp_send_frame: no memory\n");
kfree_skb(skb);
- ppp->dev.tbusy = 0;
+ ppp->xmit_busy = 0;
return;
}
@@ -2214,9 +2219,9 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
ret = ppp_async_send(ppp, skb);
if (ret > 0) {
/* we can release the lock */
- ppp->dev.tbusy = 0;
+ ppp->xmit_busy = 0;
} else if (ret < 0) {
- /* this can't happen, since the caller got the tbusy lock */
+ /* can't happen, since the caller got the xmit_busy lock */
printk(KERN_ERR "ppp: ppp_async_send didn't accept pkt\n");
}
}
@@ -2275,15 +2280,18 @@ ppp_send_frames(struct ppp *ppp)
{
struct sk_buff *skb;
- while (!test_and_set_bit(0, &ppp->dev.tbusy)) {
+ while (!test_and_set_bit(0, &ppp->xmit_busy)) {
skb = skb_dequeue(&ppp->xmt_q);
if (skb == NULL) {
- ppp->dev.tbusy = 0;
- mark_bh(NET_BH);
+ ppp->xmit_busy = 0;
break;
}
ppp_send_frame(ppp, skb);
}
+ if (!ppp->xmit_busy && ppp->dev.tbusy) {
+ ppp->dev.tbusy = 0;
+ mark_bh(NET_BH);
+ }
}
/*
@@ -2295,11 +2303,11 @@ ppp_output_wakeup(struct ppp *ppp)
{
CHECK_PPP_VOID();
- if (!ppp->dev.tbusy) {
- printk(KERN_ERR "ppp_output_wakeup called but tbusy==0\n");
+ if (!ppp->xmit_busy) {
+ printk(KERN_ERR "ppp_output_wakeup called but xmit_busy==0\n");
return;
}
- ppp->dev.tbusy = 0;
+ ppp->xmit_busy = 0;
ppp_send_frames(ppp);
}
@@ -2424,9 +2432,15 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev)
* The dev->tbusy field acts as a lock to allow only
* one packet to be processed at a time. If we can't
* get the lock, try again later.
+ * We deliberately queue as little as possible inside
+ * the ppp driver in order to minimize the latency
+ * for high-priority packets.
*/
- if (test_and_set_bit(0, &dev->tbusy))
+ if (test_and_set_bit(0, &ppp->xmit_busy)) {
+ dev->tbusy = 1; /* can't take it now */
return 1;
+ }
+ dev->tbusy = 0;
/*
* Put the 4-byte PPP header on the packet.
@@ -2440,7 +2454,8 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev)
printk(KERN_ERR "%s: skb hdr alloc failed\n",
ppp->name);
dev_kfree_skb(skb);
- dev->tbusy = 0;
+ ppp->xmit_busy = 0;
+ ppp_send_frames(ppp);
return 0;
}
skb_reserve(new_skb, PPP_HDRLEN);
@@ -2456,6 +2471,8 @@ ppp_dev_xmit(struct sk_buff *skb, struct device *dev)
hdr[3] = proto;
ppp_send_frame(ppp, skb);
+ if (!ppp->xmit_busy)
+ ppp_send_frames(ppp);
return 0;
}
@@ -2599,6 +2616,7 @@ ppp_generic_init(struct ppp *ppp)
ppp->last_xmit = jiffies;
ppp->last_recv = jiffies;
+ ppp->xmit_busy = 0;
/* clear statistics */
memset(&ppp->stats, 0, sizeof (struct pppstat));
@@ -2639,6 +2657,12 @@ ppp_release(struct ppp *ppp)
kfree_skb(skb);
while ((skb = skb_dequeue(&ppp->xmt_q)) != NULL)
kfree_skb(skb);
+
+ ppp->inuse = 0;
+ if (ppp->dev.tbusy) {
+ ppp->dev.tbusy = 0;
+ mark_bh(NET_BH);
+ }
}
/*
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
new file mode 100644
index 000000000..8d053abf6
--- /dev/null
+++ b/drivers/net/rrunner.c
@@ -0,0 +1,1208 @@
+/*
+ * rrunner.c: Linux driver for the Essential RoadRunner HIPPI board.
+ *
+ * Written 1998 by Jes Sorensen, <Jes.Sorensen@cern.ch>.
+ *
+ * Thanks to Essential Communication for providing us with hardware
+ * and very comprehensive documentation without which I would not have
+ * been able to write this driver. A special thank you to John Gibbon
+ * for sorting out the legal issues, with the NDA, allowing the code to
+ * be released under the GPL.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#define DEBUG 1
+#define RX_DMA_SKBUFF 1
+#define PKT_COPY_THRESHOLD 512
+
+#include <linux/module.h>
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/pci.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/hippidevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/delay.h>
+#include <linux/mm.h>
+#include <net/sock.h>
+
+#include <asm/system.h>
+#include <asm/cache.h>
+#include <asm/byteorder.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+
+#include "rrunner.h"
+
+/*
+ * Implementation notes:
+ *
+ * The DMA engine only allows for DMA within physical 64KB chunks of
+ * memory. The current approach of the driver (and stack) is to use
+ * linear blocks of memory for the skbuffs. However, as the data block
+ * is always the first part of the skb and skbs are 2^n aligned so we
+ * are guarantted to get the whole block within one 64KB align 64KB
+ * chunk.
+ *
+ * On the long term, relying on being able to allocate 64KB linear
+ * chunks of memory is not feasible and the skb handling code and the
+ * stack will need to know about I/O vectors or something similar.
+ */
+
+static const char *version = "rrunner.c: v0.06 09/02/98 Jes Sorensen (Jes.Sorensen@cern.ch)\n";
+
+static unsigned int read_eeprom(struct rr_private *rrpriv,
+ unsigned long offset,
+ unsigned char *buf,
+ unsigned long length);
+static u32 read_eeprom_word(struct rr_private *rrpriv,
+ void * offset);
+static int rr_load_firmware(struct device *dev);
+
+
+__initfunc(int rr_hippi_probe (struct device *dev))
+{
+ static int i = 0;
+ int boards_found = 0;
+ int version_disp; /* was version info already displayed? */
+ u8 pci_bus; /* PCI bus number (0-255) */
+ u8 pci_dev_fun; /* PCI device and function numbers (0-255) */
+ u8 pci_latency;
+ u16 command; /* PCI Configuration space Command register */
+ unsigned int tmp;
+ u8 irq;
+ struct rr_private *rrpriv;
+
+ if (!pci_present()) /* is PCI BIOS even present? */
+ return -ENODEV;
+
+ version_disp = 0;
+
+ for (; i < 255; i++)
+ {
+ if (pcibios_find_device(PCI_VENDOR_ID_ESSENTIAL,
+ PCI_DEVICE_ID_ESSENTIAL_ROADRUNNER,
+ i, &pci_bus, &pci_dev_fun) != 0)
+ break;
+
+ pcibios_read_config_word(pci_bus, pci_dev_fun,
+ PCI_COMMAND, &command);
+
+ /* Enable mastering */
+
+ command |= PCI_COMMAND_MASTER;
+ pcibios_write_config_word(pci_bus, pci_dev_fun,
+ PCI_COMMAND, command);
+
+ if (!(command & PCI_COMMAND_MEMORY)){
+ printk("shared mem not enabled - unable to configure RoadRunner\n");
+ break;
+ }
+
+ /*
+ * So we found our HIPPI ... time to tell the system.
+ */
+
+ dev = init_hippi_dev(dev, sizeof(struct rr_private));
+
+ if (dev == NULL)
+ break;
+
+ rrpriv = (struct rr_private *)dev->priv;
+
+ /* Read register base address from
+ PCI Configuration Space */
+
+ pcibios_read_config_dword(pci_bus, pci_dev_fun,
+ PCI_BASE_ADDRESS_0, &tmp);
+
+ pcibios_read_config_byte(pci_bus, pci_dev_fun,
+ PCI_INTERRUPT_LINE, &irq);
+
+ dev->irq = irq;
+ rrpriv->pci_bus = pci_bus;
+ rrpriv->pci_dev_fun = pci_dev_fun;
+ sprintf(rrpriv->name, "RoadRunner serial HIPPI");
+#ifdef __SMP__
+ spin_lock_init(&rrpriv->lock);
+#endif
+
+ dev->open = &rr_open;
+ dev->hard_start_xmit = &rr_start_xmit;
+ dev->stop = &rr_close;
+ dev->get_stats = &rr_get_stats;
+ dev->do_ioctl = &rr_ioctl;
+
+ /*
+ * Dummy value.
+ */
+ dev->base_addr = 42;
+
+ /* display version info if adapter is found */
+ if (!version_disp)
+ {
+ /* set display flag to TRUE so that */
+ /* we only display this string ONCE */
+ version_disp = 1;
+ printk(version);
+ }
+
+ printk(KERN_INFO "%s: Essential RoadRunner serial HIPPI at 0x%08x, irq %i\n",
+ dev->name, tmp, dev->irq);
+
+ pcibios_read_config_byte(pci_bus, pci_dev_fun,
+ PCI_LATENCY_TIMER, &pci_latency);
+#if 0
+ if (pci_latency <= 48){
+ printk(" PCI latency counter too low (%i), setting to 48 clocks\n", pci_latency);
+ pcibios_write_config_byte(pci_bus, pci_dev_fun,
+ PCI_LATENCY_TIMER, 48);
+ }
+#else
+ if (pci_latency <= 0x58)
+ pcibios_write_config_byte(pci_bus, pci_dev_fun,
+ PCI_LATENCY_TIMER, 0x58);
+#endif
+ /*
+ * Remap the regs into kernel space.
+ */
+
+ rrpriv->regs = (struct rr_regs *)ioremap(tmp, 0x1000);
+ if (!rrpriv->regs){
+ printk(KERN_ERR "%s: Unable to map I/O register, RoadRunner %i will be disabled.\n", dev->name, i);
+ break;
+ }
+
+ /*
+ * Don't access any registes before this point!
+ */
+#ifdef __BIG_ENDIAN
+ regs->HostCtrl |= NO_SWAP;
+#endif
+ /*
+ * Need to add a case for little-endian 64-bit hosts here.
+ */
+
+ rr_init(dev);
+
+ boards_found++;
+
+ /*
+ * This is bollocks, but we need to tell the net-init
+ * code that it shall go for the next device.
+ */
+ dev->base_addr = 0;
+ }
+
+ /*
+ * If we're at this point we're going through rr_hippi_probe()
+ * for the first time. Return success (0) if we've initialized
+ * 1 or more boards. Otherwise, return failure (-ENODEV).
+ */
+
+ if (boards_found > 0)
+ return 0;
+ else
+ return -ENODEV;
+}
+
+
+/*
+ * Commands are considered to be slow, thus there is no reason to
+ * inline this.
+ */
+static void rr_issue_cmd(struct rr_private *rrpriv, struct cmd *cmd)
+{
+ struct rr_regs *regs;
+ u32 idx;
+
+ regs = rrpriv->regs;
+ /*
+ * This is temporary - it will go away in the final version.
+ * We probably also want to make this function inline.
+ */
+ if (regs->HostCtrl & NIC_HALTED){
+ printk("issuing command for halted NIC, code 0x%x, HostCtrl %08x\n", cmd->code, regs->HostCtrl);
+ if (regs->Mode & FATAL_ERR)
+ printk("error code %02x\n", regs->Fail1);
+ }
+
+ idx = rrpriv->info->cmd_ctrl.pi;
+
+ regs->CmdRing[idx] = *(u32*)(cmd);
+
+ idx = (idx - 1) % CMD_RING_ENTRIES;
+ rrpriv->info->cmd_ctrl.pi = idx;
+
+ if (regs->Mode & FATAL_ERR)
+ printk("error code %02x\n", regs->Fail1);
+}
+
+
+/*
+ * Reset the board in a sensible manner. The NIC is already halted
+ * when we get here and a spin-lock is held.
+ */
+static int rr_reset(struct device *dev)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ struct eeprom *hw = NULL;
+ u32 start_pc;
+ int i;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ rr_load_firmware(dev);
+
+ regs->TX_state = 0x01000000;
+ regs->RX_state = 0xff800000;
+ regs->AssistState = 0;
+ regs->LocalCtrl = CLEAR_INTA;
+ regs->BrkPt = 0x01;
+ regs->Timer = 0;
+ regs->TimerRef = 0;
+ regs->DmaReadState = RESET_DMA;
+ regs->DmaWriteState = RESET_DMA;
+ regs->DmaWriteHostHi = 0;
+ regs->DmaWriteHostLo = 0;
+ regs->DmaReadHostHi = 0;
+ regs->DmaReadHostLo = 0;
+ regs->DmaReadLen = 0;
+ regs->DmaWriteLen = 0;
+ regs->DmaWriteLcl = 0;
+ regs->DmaWriteIPchecksum = 0;
+ regs->DmaReadLcl = 0;
+ regs->DmaReadIPchecksum = 0;
+ regs->PciState = 0; /* 0x90 for GE? */
+ regs->Mode = SWAP_DATA;
+
+#if 0
+ /*
+ * Don't worry, this is just black magic.
+ */
+ regs->RxBase = 0xdf000;
+ regs->RxPrd = 0xdf000;
+ regs->RxCon = 0xdf000;
+ regs->TxBase = 0xce000;
+ regs->TxPrd = 0xce000;
+ regs->TxCon = 0xce000;
+ regs->RxIndPro = 0;
+ regs->RxIndCon = 0;
+ regs->RxIndRef = 0;
+ regs->TxIndPro = 0;
+ regs->TxIndCon = 0;
+ regs->TxIndRef = 0;
+ regs->pad10[0] = 0xcc000;
+ regs->DrCmndPro = 0;
+ regs->DrCmndCon = 0;
+ regs->DwCmndPro = 0;
+ regs->DwCmndCon = 0;
+ regs->DwCmndRef = 0;
+ regs->DrDataPro = 0;
+ regs->DrDataCon = 0;
+ regs->DrDataRef = 0;
+ regs->DwDataPro = 0;
+ regs->DwDataCon = 0;
+ regs->DwDataRef = 0;
+#endif
+
+ regs->MbEvent = 0xffffffff;
+ regs->Event = 0;
+
+ regs->TxPi = 0;
+ regs->IpRxPi = 0;
+
+ regs->EvtCon = 0;
+ regs->EvtPrd = 0;
+
+ rrpriv->info->evt_ctrl.pi = 0;
+
+ for (i = 0; i < CMD_RING_ENTRIES; i++)
+ regs->CmdRing[i] = 0;
+
+ regs->PciState = 0;
+
+ start_pc = read_eeprom_word(rrpriv, &hw->rncd_info.FwStart);
+
+#if (DEBUG > 1)
+ printk("%s: Executing firmware at address 0x%06x\n",
+ dev->name, start_pc);
+#endif
+
+ regs->Pc = start_pc + 0x800;
+ udelay(5);
+
+ regs->Pc = start_pc;
+
+ return 0;
+}
+
+/*
+ * Read a string from the EEPROM.
+ */
+static unsigned int read_eeprom(struct rr_private *rrpriv,
+ unsigned long offset,
+ unsigned char *buf,
+ unsigned long length)
+{
+ struct rr_regs *regs = rrpriv->regs;
+ u32 misc, io, i;
+
+ io = regs->ExtIo;
+ regs->ExtIo = 0;
+ misc = regs->LocalCtrl;
+ regs->LocalCtrl = 0;
+
+ for (i = 0; i < length; i++){
+ regs->WinBase = (EEPROM_BASE + ((offset+i) << 3));
+ buf[i] = (regs->WinData >> 24) & 0xff;
+ }
+
+ regs->LocalCtrl = misc;
+ regs->ExtIo = io;
+
+ return i;
+}
+
+
+/*
+ * Shortcut to read one word (4 bytes) out of the EEPROM and convert
+ * it to our CPU byte-order.
+ */
+static u32 read_eeprom_word(struct rr_private *rrpriv,
+ void * offset)
+{
+ u32 word;
+
+ if ((read_eeprom(rrpriv, (unsigned long)offset,
+ (char *)&word, 4) == 4))
+ return be32_to_cpu(word);
+ return 0;
+}
+
+
+__initfunc(static int rr_init(struct device *dev))
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ u32 sram_size, rev;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ rev = regs->FwRev;
+ if (rev > 0x00020024)
+ printk(" Firmware revision: %i.%i.%i\n", (rev >> 16),
+ ((rev >> 8) & 0xff), (rev & 0xff));
+ else{
+ printk(" Firmware revision too old: %i.%i.%i, please upgrade to 2.0.37 or later.\n",
+ (rev >> 16), ((rev >> 8) & 0xff), (rev & 0xff));
+ return -EFAULT;
+
+ }
+
+ printk(" Maximum receive rings %i\n", regs->MaxRxRng);
+
+ sram_size = read_eeprom_word(rrpriv, (void *)8);
+ printk(" SRAM size 0x%06x\n", sram_size);
+
+ return 0;
+}
+
+
+static int rr_init1(struct device *dev)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ u32 hostctrl;
+ unsigned long myjif, flags, tmp_ptr;
+ struct cmd cmd;
+ short i;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ spin_lock_irqsave(&rrpriv->lock, flags);
+
+ hostctrl = regs->HostCtrl;
+ regs->HostCtrl |= HALT_NIC;
+
+ if (hostctrl & PARITY_ERR){
+ printk("%s: Parity error halting NIC - this is serious!\n",
+ dev->name);
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
+ return -EFAULT;
+ }
+
+
+ memset(rrpriv->rx_ctrl, 0, 256 * sizeof(struct ring_ctrl));
+ memset(rrpriv->info, 0, sizeof(struct rr_info));
+
+ tmp_ptr = virt_to_bus((void *)rrpriv->rx_ctrl);
+#if (BITS_PER_LONG == 64)
+ regs->RxRingHi = (tmp_ptr >> 32);
+#else
+ regs->RxRingHi = 0;
+#endif
+ regs->RxRingLo = ((tmp_ptr) & 0xffffffff);
+
+ tmp_ptr = virt_to_bus((void *)rrpriv->info);
+#if (BITS_PER_LONG == 64)
+ regs->InfoPtrHi = (tmp_ptr >> 32);
+#else
+ regs->InfoPtrHi = 0;
+#endif
+ regs->InfoPtrLo = ((tmp_ptr) & 0xffffffff);
+
+ rrpriv->info->evt_ctrl.entry_size = sizeof(struct event);
+ rrpriv->info->evt_ctrl.entries = EVT_RING_ENTRIES;
+ rrpriv->info->evt_ctrl.mode = 0;
+ rrpriv->info->evt_ctrl.pi = 0;
+ rrpriv->info->evt_ctrl.rngptr = virt_to_bus(rrpriv->evt_ring);
+
+ rrpriv->info->cmd_ctrl.entry_size = sizeof(struct cmd);
+ rrpriv->info->cmd_ctrl.entries = CMD_RING_ENTRIES;
+ rrpriv->info->cmd_ctrl.mode = 0;
+ rrpriv->info->cmd_ctrl.pi = 15;
+
+ for (i = 0; i < CMD_RING_ENTRIES; i++) {
+ regs->CmdRing[i] = 0;
+ }
+
+ for (i = 0; i < TX_RING_ENTRIES; i++) {
+ rrpriv->tx_ring[i].size = 0;
+ rrpriv->tx_ring[i].addr = 0;
+ rrpriv->tx_skbuff[i] = 0;
+ }
+
+ rrpriv->info->tx_ctrl.entry_size = sizeof(struct tx_desc);
+ rrpriv->info->tx_ctrl.entries = TX_RING_ENTRIES;
+ rrpriv->info->tx_ctrl.mode = 0;
+ rrpriv->info->tx_ctrl.pi = 0;
+ rrpriv->info->tx_ctrl.rngptr = virt_to_bus(rrpriv->tx_ring);
+
+ /*
+ * Set dirty_tx before we start receiving interrupts, otherwise
+ * the interrupt handler might think it is supposed to process
+ * tx ints before we are up and running, which may cause a null
+ * pointer access in the int handler.
+ */
+ rrpriv->tx_full = 0;
+ rrpriv->cur_rx = 0;
+ rrpriv->dirty_rx = rrpriv->dirty_tx = 0;
+
+ rr_reset(dev);
+
+ regs->IntrTmr = 0x60;
+ regs->WriteDmaThresh = 0x80 | 0x1f;
+ regs->ReadDmaThresh = 0x80 | 0x1f;
+
+ rrpriv->fw_running = 0;
+
+ hostctrl &= ~(HALT_NIC | INVALID_INST_B | PARITY_ERR);
+ regs->HostCtrl = hostctrl;
+
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
+
+ udelay(1000);
+
+ /*
+ * Now start the FirmWare.
+ */
+ cmd.code = C_START_FW;
+ cmd.ring = 0;
+ cmd.index = 0;
+
+ rr_issue_cmd(rrpriv, &cmd);
+
+ /*
+ * Give the FirmWare time to chew on the `get running' command.
+ */
+ myjif = jiffies + 5 * HZ;
+ while ((jiffies < myjif) && !rrpriv->fw_running);
+
+ for (i = 0; i < RX_RING_ENTRIES; i++) {
+ struct sk_buff *skb;
+
+ rrpriv->rx_ring[i].mode = 0;
+ skb = alloc_skb(dev->mtu + HIPPI_HLEN, GFP_ATOMIC);
+ rrpriv->rx_skbuff[i] = skb;
+ /*
+ * Sanity test to see if we conflict with the DMA
+ * limitations of the Roadrunner.
+ */
+ if ((((unsigned long)skb->data) & 0xfff) > ~65320)
+ printk("skb alloc error\n");
+
+#if (BITS_PER_LONG == 32)
+ rrpriv->rx_ring[i].zero = 0;
+#endif
+ rrpriv->rx_ring[i].addr = virt_to_bus(skb->data);
+ rrpriv->rx_ring[i].size = dev->mtu + HIPPI_HLEN;
+ }
+
+ rrpriv->rx_ctrl[4].entry_size = sizeof(struct rx_desc);
+ rrpriv->rx_ctrl[4].entries = RX_RING_ENTRIES;
+ rrpriv->rx_ctrl[4].mode = 8;
+ rrpriv->rx_ctrl[4].pi = 0;
+ rrpriv->rx_ctrl[4].rngptr = virt_to_bus(rrpriv->rx_ring);
+
+ cmd.code = C_NEW_RNG;
+ cmd.ring = 4;
+ cmd.index = 0;
+ rr_issue_cmd(rrpriv, &cmd);
+
+#if 0
+{
+ u32 tmp;
+ tmp = regs->ExtIo;
+ regs->ExtIo = 0x80;
+
+ i = jiffies + 1 * HZ;
+ while (jiffies < i);
+ regs->ExtIo = tmp;
+}
+#endif
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+ return 0;
+}
+
+
+/*
+ * All events are considered to be slow (RX/TX ints do not generate
+ * events) and are handled here, outside the main interrupt handler,
+ * to reduce the size of the handler.
+ */
+static u32 rr_handle_event(struct device *dev, u32 prodidx)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ u32 tmp, eidx;
+#if 0
+ short i;
+#endif
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+ eidx = rrpriv->info->evt_ctrl.pi;
+
+ while (prodidx != eidx){
+ switch (rrpriv->evt_ring[eidx].code){
+ case E_NIC_UP:
+ tmp = regs->FwRev;
+ printk("%s: Firmware revision %i.%i.%i up and running\n",
+ dev->name, (tmp >> 16), ((tmp >> 8) & 0xff),
+ (tmp & 0xff));
+ rrpriv->fw_running = 1;
+ break;
+ case E_LINK_ON:
+ printk("%s: Optical link ON\n", dev->name);
+ break;
+ case E_LINK_OFF:
+ printk("%s: Optical link OFF\n", dev->name);
+ break;
+ case E_RX_IDLE:
+ printk("%s: RX data not moving\n", dev->name);
+ break;
+ case E_WATCHDOG:
+ printk("%s: The watchdog is here to see us\n",
+ dev->name);
+ break;
+ /*
+ * TX events.
+ */
+ case E_CON_REJ:
+ printk("%s: Connection rejected\n", dev->name);
+ rrpriv->stats.tx_aborted_errors++;
+ break;
+ case E_CON_TMOUT:
+ printk("%s: Connection timeout\n", dev->name);
+ break;
+ case E_DISC_ERR:
+ printk("%s: HIPPI disconnect error\n", dev->name);
+ rrpriv->stats.tx_aborted_errors++;
+ break;
+ case E_TX_IDLE:
+ printk("%s: Transmitter idle\n", dev->name);
+ break;
+ case E_TX_LINK_DROP:
+ printk("%s: Link lost during transmit\n", dev->name);
+ rrpriv->stats.tx_aborted_errors++;
+ break;
+ /*
+ * RX events.
+ */
+ case E_VAL_RNG: /* Should be ignored */
+#if (DEBUG > 2)
+ printk("%s: RX ring valid event\n", dev->name);
+#endif
+ regs->IpRxPi = RX_RING_ENTRIES - 1;
+ break;
+ case E_INV_RNG:
+ printk("%s: RX ring invalid event\n", dev->name);
+ break;
+ case E_RX_RNG_OUT:
+ printk("%s: Receive ring full\n", dev->name);
+ break;
+
+ case E_RX_PAR_ERR:
+ printk("%s: Receive parity error.\n", dev->name);
+ break;
+ case E_RX_LLRC_ERR:
+ printk("%s: Receive LLRC error.\n", dev->name);
+ break;
+ case E_PKT_LN_ERR:
+ printk("%s: Receive packet length error.\n",
+ dev->name);
+ break;
+ default:
+ printk("%s: Unhandled event 0x%02x\n",
+ dev->name, rrpriv->evt_ring[eidx].code);
+ }
+ eidx = (eidx + 1) % EVT_RING_ENTRIES;
+ }
+
+ rrpriv->info->evt_ctrl.pi = eidx;
+ return eidx;
+}
+
+
+static int rx_int(struct device *dev, u32 rxlimit)
+{
+ struct rr_private *rrpriv = (struct rr_private *)dev->priv;
+ u32 index, pkt_len;
+ struct rr_regs *regs = rrpriv->regs;
+
+ index = rrpriv->cur_rx;
+
+ while(index != rxlimit){
+ pkt_len = rrpriv->rx_ring[index].size;
+#if (DEBUG > 2)
+ printk("index %i, rxlimit %i\n", index, rxlimit);
+ printk("len %x, mode %x\n", pkt_len,
+ rrpriv->rx_ring[index].mode);
+#endif
+#if 0
+/*
+ * I have never seen this occur
+ */
+ if(!(rrpriv->rx_skbuff[index])){
+ printk("Trying to receive in empty skbuff\n");
+ goto out;
+ }
+#endif
+
+ if (pkt_len > 0){
+ struct sk_buff *skb;
+
+ if (pkt_len < PKT_COPY_THRESHOLD) {
+ skb = alloc_skb(pkt_len, GFP_ATOMIC);
+ if (skb == NULL){
+ printk("%s: Out of memory deferring packet\n", dev->name);
+ rrpriv->stats.rx_dropped++;
+ goto defer;
+ }else
+ memcpy(skb_put(skb, pkt_len),
+ rrpriv->rx_skbuff[index]->data,
+ pkt_len);
+ }else{
+ struct sk_buff *newskb;
+
+ newskb = alloc_skb(dev->mtu + HIPPI_HLEN, GFP_ATOMIC);
+ if (newskb){
+ skb = rrpriv->rx_skbuff[index];
+ skb_put(skb, pkt_len);
+ rrpriv->rx_skbuff[index] = newskb;
+ rrpriv->rx_ring[index].addr = virt_to_bus(newskb->data);
+ }else{
+ printk("%s: Out of memory, deferring packet\n", dev->name);
+ rrpriv->stats.rx_dropped++;
+ goto defer;
+ }
+ }
+ skb->dev = dev;
+ skb->protocol = hippi_type_trans(skb, dev);
+
+ netif_rx(skb); /* send it up */
+
+ rrpriv->stats.rx_packets++;
+ rrpriv->stats.rx_bytes += skb->len;
+ }
+ defer:
+ rrpriv->rx_ring[index].mode = 0;
+ rrpriv->rx_ring[index].size = dev->mtu + HIPPI_HLEN;
+
+ if ((index & 7) == 7)
+ regs->IpRxPi = index;
+
+ index = (index + 1) % RX_RING_ENTRIES;
+ }
+
+ rrpriv->cur_rx = index;
+ return index;
+}
+
+
+static void rr_interrupt(int irq, void *dev_id, struct pt_regs *ptregs)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ struct device *dev = (struct device *)dev_id;
+ u32 prodidx, eidx, txcsmr, rxlimit, txcon;
+ unsigned long flags;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ if (!(regs->HostCtrl & RR_INT)){
+#if 0
+ /* These are harmless */
+ printk("%s: spurious interrupt detected\n", dev->name);
+#endif
+ return;
+ }
+
+ if (test_and_set_bit(0, (void*)&dev->interrupt) != 0) {
+ printk("%s: Re-entering the interrupt handler.\n", dev->name);
+ return;
+ }
+
+ spin_lock_irqsave(&rrpriv->lock, flags);
+
+ prodidx = regs->EvtPrd;
+ txcsmr = (prodidx >> 8) & 0xff;
+ rxlimit = (prodidx >> 16) & 0xff;
+ prodidx &= 0xff;
+
+#if (DEBUG > 2)
+ printk("%s: interrupt, prodidx = %i, eidx = %i\n", dev->name,
+ prodidx, rrpriv->info->evt_ctrl.pi);
+#endif
+
+ txcon = rrpriv->dirty_tx;
+ if (txcsmr != txcon) {
+ do {
+ rrpriv->stats.tx_packets++;
+ rrpriv->stats.tx_bytes +=rrpriv->tx_skbuff[txcon]->len;
+ dev_kfree_skb(rrpriv->tx_skbuff[txcon]);
+
+ rrpriv->tx_skbuff[txcon] = NULL;
+ rrpriv->tx_ring[txcon].size = 0;
+ rrpriv->tx_ring[txcon].addr = 0;
+ rrpriv->tx_ring[txcon].mode = 0;
+
+ txcon = (txcon + 1) % TX_RING_ENTRIES;
+ } while (txcsmr != txcon);
+
+ rrpriv->dirty_tx = txcon;
+ if (rrpriv->tx_full && dev->tbusy &&
+ (((rrpriv->info->tx_ctrl.pi + 1) % TX_RING_ENTRIES)
+ != rrpriv->dirty_tx)){
+ rrpriv->tx_full = 0;
+ dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+ }
+
+ rx_int(dev, rxlimit);
+
+ eidx = rrpriv->info->evt_ctrl.pi;
+
+ if (prodidx != eidx)
+ eidx = rr_handle_event(dev, prodidx);
+
+ eidx |= ((txcsmr << 8) | (rxlimit << 16));
+ regs->EvtCon = eidx;
+
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
+
+ dev->interrupt = 0;
+}
+
+
+static int rr_open(struct device *dev)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+#if 0
+ regs->HostCtrl |= (HALT_NIC | RR_CLEAR_INT);
+#endif
+
+ if (request_irq(dev->irq, rr_interrupt, 0, rrpriv->name, dev))
+ {
+ printk(KERN_WARNING "%s: Requested IRQ %d is busy\n",
+ dev->name, dev->irq);
+ return -EAGAIN;
+ }
+
+ rrpriv->rx_ctrl = kmalloc(256*sizeof(struct ring_ctrl),
+ GFP_KERNEL | GFP_DMA);
+ rrpriv->info = kmalloc(sizeof(struct rr_info), GFP_KERNEL | GFP_DMA);
+
+ rr_init1(dev);
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ dev->start = 1;
+
+ MOD_INC_USE_COUNT;
+ return 0;
+}
+
+
+static void rr_dump(struct device *dev)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ u32 index, cons;
+ short i;
+ int len;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ printk("%s: dumping NIC TX rings\n", dev->name);
+
+ printk("RxPrd %08x, TxPrd %02x, EvtPrd %08x, TxPi %02x, TxCtrlPi %02x\n",
+ regs->RxPrd, regs->TxPrd, regs->EvtPrd, regs->TxPi,
+ rrpriv->info->tx_ctrl.pi);
+
+ printk("Error code 0x%x\n", regs->Fail1);
+
+ index = (((regs->EvtPrd >> 8) & 0xff ) - 1) % EVT_RING_ENTRIES;
+ cons = rrpriv->dirty_tx;
+ printk("TX ring index %i, TX consumer %i\n",
+ index, cons);
+
+ if (rrpriv->tx_skbuff[index]){
+ len = min(0x80, rrpriv->tx_skbuff[index]->len);
+ printk("skbuff for index %i is valid - dumping data (0x%x bytes - DMA len 0x%x)\n", index, len, rrpriv->tx_ring[index].size);
+ for (i = 0; i < len; i++){
+ if (!(i & 7))
+ printk("\n");
+ printk("%02x ", (unsigned char) rrpriv->tx_skbuff[index]->data[i]);
+ }
+ printk("\n");
+ }
+
+ if (rrpriv->tx_skbuff[cons]){
+ len = min(0x80, rrpriv->tx_skbuff[cons]->len);
+ printk("skbuff for cons %i is valid - dumping data (0x%x bytes - skbuff len 0x%x)\n", cons, len, rrpriv->tx_skbuff[cons]->len);
+ printk("mode 0x%x, size 0x%x,\n phys %08x (virt %08x), skbuff-addr %08x, truesize 0x%x\n",
+ rrpriv->tx_ring[cons].mode,
+ rrpriv->tx_ring[cons].size,
+ rrpriv->tx_ring[cons].addr,
+ (unsigned int)bus_to_virt(rrpriv->tx_ring[cons].addr),
+ (unsigned int)rrpriv->tx_skbuff[cons]->data,
+ (unsigned int)rrpriv->tx_skbuff[cons]->truesize);
+ for (i = 0; i < len; i++){
+ if (!(i & 7))
+ printk("\n");
+ printk("%02x ", (unsigned char)rrpriv->tx_ring[cons].size);
+ }
+ printk("\n");
+ }
+
+ printk("dumping TX ring info:\n");
+ for (i = 0; i < TX_RING_ENTRIES; i++)
+ printk("mode 0x%x, size 0x%x, phys-addr %08x\n",
+ rrpriv->tx_ring[i].mode,
+ rrpriv->tx_ring[i].size,
+ rrpriv->tx_ring[i].addr);
+
+}
+
+
+static int rr_close(struct device *dev)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+ u32 tmp;
+ short i;
+
+ dev->start = 0;
+ set_bit(0, (void*)&dev->tbusy);
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ tmp = regs->HostCtrl;
+ if (tmp & NIC_HALTED){
+ printk("%s: NIC already halted\n", dev->name);
+ rr_dump(dev);
+ }else
+ tmp |= HALT_NIC;
+ regs->HostCtrl = tmp;
+
+ /*
+ * Lock to make sure we are not cleaning up while another CPU
+ * handling interrupts.
+ */
+ spin_lock(&rrpriv->lock);
+
+ regs->TxPi = 0;
+ regs->IpRxPi = 0;
+
+ regs->EvtCon = 0;
+ regs->EvtPrd = 0;
+
+ for (i = 0; i < CMD_RING_ENTRIES; i++)
+ regs->CmdRing[i] = 0;
+
+ rrpriv->info->tx_ctrl.entries = 0;
+ rrpriv->info->cmd_ctrl.pi = 0;
+ rrpriv->info->evt_ctrl.pi = 0;
+ rrpriv->rx_ctrl[4].entries = 0;
+
+ for (i = 0; i < TX_RING_ENTRIES; i++) {
+ if (rrpriv->tx_skbuff[i]) {
+ rrpriv->tx_ring[i].size = 0;
+ rrpriv->tx_ring[i].addr = 0;
+ dev_kfree_skb(rrpriv->tx_skbuff[i]);
+ }
+ }
+
+ for (i = 0; i < RX_RING_ENTRIES; i++) {
+ if (rrpriv->rx_skbuff[i]) {
+ rrpriv->rx_ring[i].size = 0;
+ rrpriv->rx_ring[i].addr = 0;
+ dev_kfree_skb(rrpriv->rx_skbuff[i]);
+ }
+ }
+
+ kfree(rrpriv->rx_ctrl);
+ kfree(rrpriv->info);
+
+ free_irq(dev->irq, dev);
+ spin_unlock(&rrpriv->lock);
+
+ MOD_DEC_USE_COUNT;
+ return 0;
+}
+
+
+static int rr_start_xmit(struct sk_buff *skb, struct device *dev)
+{
+ struct rr_private *rrpriv = (struct rr_private *)dev->priv;
+ struct rr_regs *regs = rrpriv->regs;
+ struct ring_ctrl *txctrl;
+ unsigned long flags;
+ u32 index, len = skb->len;
+ u32 *ifield;
+ struct sk_buff *new_skb;
+
+ /*
+ * We probably need to deal with tbusy here to prevent overruns.
+ */
+
+ if (skb_headroom(skb) < 8){
+ printk("incoming skb too small - reallocating\n");
+ if (!(new_skb = dev_alloc_skb(len + 8))) {
+ dev_kfree_skb(skb);
+ dev->tbusy = 0;
+ return -EBUSY;
+ }
+ skb_reserve(new_skb, 8);
+ skb_put(new_skb, len);
+ memcpy(new_skb->data, skb->data, len);
+ dev_kfree_skb(skb);
+ skb = new_skb;
+ }
+
+ ifield = (u32 *)skb_push(skb, 8);
+
+ ifield[0] = 0;
+ ifield[1] = skb->private.ifield;
+
+ /*
+ * We don't need the lock before we are actually going to start
+ * fiddling with the control blocks.
+ */
+ spin_lock_irqsave(&rrpriv->lock, flags);
+
+ txctrl = &rrpriv->info->tx_ctrl;
+
+ index = txctrl->pi;
+
+ rrpriv->tx_skbuff[index] = skb;
+ rrpriv->tx_ring[index].addr = virt_to_bus(skb->data);
+ rrpriv->tx_ring[index].size = len + 8; /* include IFIELD */
+ rrpriv->tx_ring[index].mode = PACKET_START | PACKET_END;
+ txctrl->pi = (index + 1) % TX_RING_ENTRIES;
+ regs->TxPi = txctrl->pi;
+
+ if (txctrl->pi == rrpriv->dirty_tx){
+ rrpriv->tx_full = 1;
+ set_bit(0, (void*)&dev->tbusy);
+ }
+
+ spin_unlock_irqrestore(&rrpriv->lock, flags);
+
+ dev->trans_start = jiffies;
+ return 0;
+}
+
+
+static struct net_device_stats *rr_get_stats(struct device *dev)
+{
+ struct rr_private *rrpriv;
+
+ rrpriv = (struct rr_private *)dev->priv;
+
+ return(&rrpriv->stats);
+}
+
+
+/*
+ * Read the firmware out of the EEPROM and put it into the SRAM
+ * (or from user space - later)
+ *
+ * This operation requires the NIC to be halted and is performed with
+ * interrupts disabled and with the spinlock hold.
+ */
+static int rr_load_firmware(struct device *dev)
+{
+ struct rr_private *rrpriv;
+ struct rr_regs *regs;
+#if 0
+ unsigned long flags;
+#endif
+ int i, j;
+ u32 localctrl, eptr, sptr, segptr, len, tmp;
+ u32 p2len, p2size, nr_seg, revision, io, sram_size;
+ struct eeprom *hw = NULL;
+
+ rrpriv = (struct rr_private *)dev->priv;
+ regs = rrpriv->regs;
+
+ if (dev->flags & IFF_UP)
+ return -EBUSY;
+
+ if (!(regs->HostCtrl & NIC_HALTED)){
+ printk("%s: Trying to load firmware to a running NIC.\n",
+ dev->name);
+ return -EBUSY;
+ }
+
+ localctrl = regs->LocalCtrl;
+ regs->LocalCtrl = 0;
+
+ regs->EvtPrd = 0;
+ regs->RxPrd = 0;
+ regs->TxPrd = 0;
+
+ /*
+ * First wipe the entire SRAM, otherwise we might run into all
+ * kinds of trouble ... sigh, this took almost all afternoon
+ * to track down ;-(
+ */
+ io = regs->ExtIo;
+ regs->ExtIo = 0;
+ sram_size = read_eeprom_word(rrpriv, (void *)8);
+
+ for (i = 200; i < sram_size / 4; i++){
+ regs->WinBase = i * 4;
+ regs->WinData = 0;
+ }
+ regs->ExtIo = io;
+
+ eptr = read_eeprom_word(rrpriv, &hw->rncd_info.AddrRunCodeSegs);
+ eptr = ((eptr & 0x1fffff) >> 3);
+
+ p2len = read_eeprom_word(rrpriv, (void *)(0x83*4));
+ p2len = (p2len << 2);
+ p2size = read_eeprom_word(rrpriv, (void *)(0x84*4));
+ p2size = ((p2size & 0x1fffff) >> 3);
+
+ if ((eptr < p2size) || (eptr > (p2size + p2len))){
+ printk("%s: eptr is invalid\n", dev->name);
+ goto out;
+ }
+
+ revision = read_eeprom_word(rrpriv, &hw->manf.HeaderFmt);
+
+ if (revision != 1){
+ printk("%s: invalid firmware format (%i)\n",
+ dev->name, revision);
+ goto out;
+ }
+
+ nr_seg = read_eeprom_word(rrpriv, (void *)eptr);
+ eptr +=4;
+#if (DEBUG > 1)
+ printk("%s: nr_seg %i\n", dev->name, nr_seg);
+#endif
+
+ for (i = 0; i < nr_seg; i++){
+ sptr = read_eeprom_word(rrpriv, (void *)eptr);
+ eptr += 4;
+ len = read_eeprom_word(rrpriv, (void *)eptr);
+ eptr += 4;
+ segptr = read_eeprom_word(rrpriv, (void *)eptr);
+ segptr = ((segptr & 0x1fffff) >> 3);
+ eptr += 4;
+#if (DEBUG > 1)
+ printk("%s: segment %i, sram address %06x, length %04x, segptr %06x\n",
+ dev->name, i, sptr, len, segptr);
+#endif
+ for (j = 0; j < len; j++){
+ tmp = read_eeprom_word(rrpriv, (void *)segptr);
+ regs->WinBase = sptr;
+ regs->WinData = tmp;
+ segptr += 4;
+ sptr += 4;
+ }
+ }
+
+out:
+ regs->LocalCtrl = localctrl;
+ return 0;
+}
+
+
+static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+ struct rr_private *rrpriv;
+
+ rrpriv = (struct rr_private *)dev->priv;
+
+ switch(cmd){
+ case SIOCRRPFW:
+ if (!suser())
+ return -EPERM;
+
+ if (rrpriv->fw_running){
+ printk("%s: firmware already running\n", dev->name);
+ return -EPERM;
+ }
+ printk("%s: updating firmware", dev->name);
+ break;
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+
+/*
+ * Local variables:
+ * compile-command: "gcc -D__KERNEL__ -I../../include -Wall -Wstrict-prototypes -O2 -pipe -fomit-frame-pointer -fno-strength-reduce -m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2 -DCPU=686 -c rrunner.c"
+ * End:
+ */
diff --git a/drivers/net/rrunner.h b/drivers/net/rrunner.h
new file mode 100644
index 000000000..f6e6b3c31
--- /dev/null
+++ b/drivers/net/rrunner.h
@@ -0,0 +1,790 @@
+#ifndef _RRUNNER_H_
+#define _RRUNNER_H_
+
+#include<linux/config.h>
+
+#if ((BITS_PER_LONG != 32) && (BITS_PER_LONG != 64))
+#error "BITS_PER_LONG not defined or not valid"
+#endif
+
+
+struct rr_regs {
+
+ u32 pad0[16];
+
+ u32 HostCtrl;
+ u32 LocalCtrl;
+ u32 Pc;
+ u32 BrkPt;
+
+/* Timer increments every 0.97 micro-seconds (unsigned int) */
+ u32 Timer_Hi;
+ u32 Timer;
+ u32 TimerRef;
+ u32 PciState;
+
+ u32 Event;
+ u32 MbEvent;
+
+ u32 WinBase;
+ u32 WinData;
+ u32 RX_state;
+ u32 TX_state;
+
+ u32 Overhead;
+ u32 ExtIo;
+
+ u32 DmaWriteHostHi;
+ u32 DmaWriteHostLo;
+
+ u32 pad1[2];
+
+ u32 DmaReadHostHi;
+ u32 DmaReadHostLo;
+
+ u32 pad2;
+
+ u32 DmaReadLen;
+ u32 DmaWriteState;
+
+ u32 DmaWriteLcl;
+ u32 DmaWriteIPchecksum;
+ u32 DmaWriteLen;
+ u32 DmaReadState;
+ u32 DmaReadLcl;
+ u32 DmaReadIPchecksum;
+ u32 pad3;
+
+ u32 RxBase;
+ u32 RxPrd;
+ u32 RxCon;
+
+ u32 pad4;
+
+ u32 TxBase;
+ u32 TxPrd;
+ u32 TxCon;
+
+ u32 pad5;
+
+ u32 RxIndPro;
+ u32 RxIndCon;
+ u32 RxIndRef;
+
+ u32 pad6;
+
+ u32 TxIndPro;
+ u32 TxIndCon;
+ u32 TxIndRef;
+
+ u32 pad7[17];
+
+ u32 DrCmndPro;
+ u32 DrCmndCon;
+ u32 DrCmndRef;
+
+ u32 pad8;
+
+ u32 DwCmndPro;
+ u32 DwCmndCon;
+ u32 DwCmndRef;
+
+ u32 AssistState;
+
+ u32 DrDataPro;
+ u32 DrDataCon;
+ u32 DrDataRef;
+
+ u32 pad9;
+
+ u32 DwDataPro;
+ u32 DwDataCon;
+ u32 DwDataRef;
+
+ u32 pad10[33];
+
+ u32 EvtCon;
+
+ u32 pad11[5];
+
+ u32 TxPi;
+ u32 IpRxPi;
+
+ u32 pad11a[8];
+
+ u32 CmdRing[16];
+
+/* The ULA is in two registers the high order two bytes of the first
+ * word contain the RunCode features.
+ * ula0 res res byte0 byte1
+ * ula1 byte2 byte3 byte4 byte5
+ */
+ u32 Ula0;
+ u32 Ula1;
+
+ u32 RxRingHi;
+ u32 RxRingLo;
+
+ u32 InfoPtrHi;
+ u32 InfoPtrLo;
+
+ u32 Mode;
+
+ u32 ConRetry;
+ u32 ConRetryTmr;
+
+ u32 ConTmout;
+ u32 CtatTmr;
+
+ u32 MaxRxRng;
+
+ u32 IntrTmr;
+ u32 TxDataMvTimeout;
+ u32 RxDataMvTimeout;
+
+ u32 EvtPrd;
+ u32 TraceIdx;
+
+ u32 Fail1;
+ u32 Fail2;
+
+ u32 DrvPrm;
+
+ u32 FilterLA;
+
+ u32 FwRev;
+ u32 FwRes1;
+ u32 FwRes2;
+ u32 FwRes3;
+
+ u32 WriteDmaThresh;
+ u32 ReadDmaThresh;
+
+ u32 pad12[325];
+ u32 Window[512];
+};
+
+/*
+ * Host control register bits.
+ */
+
+#define RR_INT 0x01
+#define RR_CLEAR_INT 0x02
+#define NO_SWAP 0x04000004
+#define NO_SWAP1 0x00000004
+#define PCI_RESET_NIC 0x08
+#define HALT_NIC 0x10
+#define SSTEP_NIC 0x20
+#define MEM_READ_MULTI 0x40
+#define NIC_HALTED 0x100
+#define HALT_INST 0x200
+#define PARITY_ERR 0x400
+#define INVALID_INST_B 0x800
+#define RR_REV_2 0x20000000
+#define RR_REV_MASK 0xf0000000
+
+/*
+ * Local control register bits.
+ */
+
+#define INTA_STATE 0x01
+#define CLEAR_INTA 0x02
+#define FAST_EEPROM_ACCESS 0x08
+#define ENABLE_EXTRA_SRAM 0x100
+#define ENABLE_EXTRA_DESC 0x200
+#define ENABLE_PARITY 0x400
+#define FORCE_DMA_PARITY_ERROR 0x800
+#define ENABLE_EEPROM_WRITE 0x1000
+#define ENABLE_DATA_CACHE 0x2000
+#define SRAM_LO_PARITY_ERR 0x4000
+#define SRAM_HI_PARITY_ERR 0x8000
+
+/*
+ * PCI state bits.
+ */
+
+#define FORCE_PCI_RESET 0x01
+#define PROVIDE_LENGTH 0x02
+#define MASK_DMA_READ_MAX 0x1C
+#define RBURST_DISABLE 0x00
+#define RBURST_4 0x04
+#define RBURST_16 0x08
+#define RBURST_32 0x0C
+#define RBURST_64 0x10
+#define RBURST_128 0x14
+#define RBURST_256 0x18
+#define RBURST_1024 0x1C
+#define MASK_DMA_WRITE_MAX 0xE0
+#define WBURST_DISABLE 0x00
+#define WBURST_4 0x20
+#define WBURST_16 0x40
+#define WBURST_32 0x60
+#define WBURST_64 0x80
+#define WBURST_128 0xa0
+#define WBURST_256 0xc0
+#define WBURST_1024 0xe0
+#define MASK_MIN_DMA 0xFF00
+#define FIFO_RETRY_ENABLE 0x10000
+
+/*
+ * Event register
+ */
+
+#define DMA_WRITE_DONE 0x10000
+#define DMA_READ_DONE 0x20000
+#define DMA_WRITE_ERR 0x40000
+#define DMA_READ_ERR 0x80000
+
+/*
+ * Receive state
+ *
+ * RoadRunner HIPPI Receive State Register controls and monitors the
+ * HIPPI receive interface in the NIC. Look at err bits when a HIPPI
+ * receive Error Event occurs.
+ */
+
+#define ENABLE_NEW_CON 0x01
+#define RESET_RECV 0x02
+#define RECV_ALL 0x00
+#define RECV_1K 0x20
+#define RECV_2K 0x40
+#define RECV_4K 0x60
+#define RECV_8K 0x80
+#define RECV_16K 0xa0
+#define RECV_32K 0xc0
+#define RECV_64K 0xe0
+
+/*
+ * Transmit status.
+ */
+
+#define ENA_XMIT 0x01
+#define PERM_CON 0x02
+
+/*
+ * DMA write state
+ */
+
+#define RESET_DMA 0x01
+#define NO_SWAP_DMA 0x02
+#define DMA_ACTIVE 0x04
+#define THRESH_MASK 0x1F
+#define DMA_ERROR_MASK 0xff000000
+
+/*
+ * Gooddies stored in the ULA registers.
+ */
+
+#define TRACE_ON_WHAT_BIT 0x00020000 /* Traces on */
+#define ONEM_BUF_WHAT_BIT 0x00040000 /* 1Meg vs 256K */
+#define CHAR_API_WHAT_BIT 0x00080000 /* Char API vs network only */
+#define MS_DOS_WHAT_BIT 0x00100000 /* MS_DOS */
+#define CMD_EVT_WHAT_BIT 0x00200000 /* Command event */
+#define LONG_TX_WHAT_BIT 0x00400000
+#define LONG_RX_WHAT_BIT 0x00800000
+#define WHAT_BIT_MASK 0xFFFD0000 /* Feature bit mask */
+
+/*
+ * Mode status
+ */
+
+#define EVENT_OVFL 0x80000000
+#define FATAL_ERR 0x40000000
+#define LOOP_BACK 0x01
+#define MODE_PH 0x02
+#define MODE_FP 0x00
+#define PTR64BIT 0x04
+#define PTR32BIT 0x00
+#define PTR_WD_SWAP 0x08
+#define PTR_WD_NOSWAP 0x00
+#define POST_WARN_EVENT 0x10
+#define ERR_TERM 0x20
+#define DIRECT_CONN 0x40
+#define NO_NIC_WATCHDOG 0x80
+#define SWAP_DATA 0x100
+#define SWAP_CONTROL 0x200
+#define NIC_HALT_ON_ERR 0x400
+#define NIC_NO_RESTART 0x800
+#define HALF_DUP_TX 0x1000
+#define HALF_DUP_RX 0x2000
+
+
+/*
+ * Error codes
+ */
+
+/* Host Error Codes - values of fail1 */
+#define ERR_UNKNOWN_MBOX 0x1001
+#define ERR_UNKNOWN_CMD 0x1002
+#define ERR_MAX_RING 0x1003
+#define ERR_RING_CLOSED 0x1004
+#define ERR_RING_OPEN 0x1005
+/* Firmware internal errors */
+#define ERR_EVENT_RING_FULL 0x01
+#define ERR_DW_PEND_CMND_FULL 0x02
+#define ERR_DR_PEND_CMND_FULL 0x03
+#define ERR_DW_PEND_DATA_FULL 0x04
+#define ERR_DR_PEND_DATA_FULL 0x05
+#define ERR_ILLEGAL_JUMP 0x06
+#define ERR_UNIMPLEMENTED 0x07
+#define ERR_TX_INFO_FULL 0x08
+#define ERR_RX_INFO_FULL 0x09
+#define ERR_ILLEGAL_MODE 0x0A
+#define ERR_MAIN_TIMEOUT 0x0B
+#define ERR_EVENT_BITS 0x0C
+#define ERR_UNPEND_FULL 0x0D
+#define ERR_TIMER_QUEUE_FULL 0x0E
+#define ERR_TIMER_QUEUE_EMPTY 0x0F
+#define ERR_TIMER_NO_FREE 0x10
+#define ERR_INTR_START 0x11
+#define ERR_BAD_STARTUP 0x12
+#define ERR_NO_PKT_END 0x13
+#define ERR_HALTED_ON_ERR 0x14
+/* Hardware NIC Errors */
+#define ERR_WRITE_DMA 0x0101
+#define ERR_READ_DMA 0x0102
+#define ERR_EXT_SERIAL 0x0103
+#define ERR_TX_INT_PARITY 0x0104
+
+
+/*
+ * Event definitions
+ */
+
+#define EVT_RING_ENTRIES 64
+#define EVT_RING_SIZE (EVT_RING_ENTRIES * sizeof(struct event))
+
+struct event {
+#ifdef __LITTLE_ENDIAN
+ u16 index;
+ u8 ring;
+ u8 code;
+#else
+ u8 code;
+ u8 ring;
+ u16 index;
+#endif
+ u32 timestamp;
+};
+
+/*
+ * General Events
+ */
+
+#define E_NIC_UP 0x01
+#define E_WATCHDOG 0x02
+
+#define E_STAT_UPD 0x04
+#define E_INVAL_CMD 0x05
+#define E_SET_CMD_CONS 0x06
+#define E_LINK_ON 0x07
+#define E_LINK_OFF 0x08
+#define E_INTERN_ERR 0x09
+#define E_HOST_ERR 0x0A
+#define E_STATS_UPDATE 0x0B
+#define E_REJECTING 0x0C
+
+/*
+ * Send Events
+ */
+#define E_CON_REJ 0x13
+#define E_CON_TMOUT 0x14
+#define E_CON_NC_TMOUT 0x15 /* I , Connection No Campon Timeout */
+#define E_DISC_ERR 0x16
+#define E_INT_PRTY 0x17
+#define E_TX_IDLE 0x18
+#define E_TX_LINK_DROP 0x19
+#define E_TX_INV_RNG 0x1A
+#define E_TX_INV_BUF 0x1B
+#define E_TX_INV_DSC 0x1C
+
+/*
+ * Destination Events
+ */
+/*
+ * General Receive events
+ */
+#define E_VAL_RNG 0x20
+#define E_RX_RNG_ENER 0x21
+#define E_INV_RNG 0x22
+#define E_RX_RNG_SPC 0x23
+#define E_RX_RNG_OUT 0x24
+#define E_PKT_DISCARD 0x25
+#define E_INFO_EVT 0x27
+
+/*
+ * Data corrupted events
+ */
+#define E_RX_PAR_ERR 0x2B
+#define E_RX_LLRC_ERR 0x2C
+#define E_IP_CKSM_ERR 0x2D
+#define E_DTA_CKSM_ERR 0x2E
+#define E_SHT_BST 0x2F
+
+/*
+ * Data lost events
+ */
+#define E_LST_LNK_ERR 0x30
+#define E_FLG_SYN_ERR 0x31
+#define E_FRM_ERR 0x32
+#define E_RX_IDLE 0x33
+#define E_PKT_LN_ERR 0x34
+#define E_STATE_ERR 0x35
+#define E_UNEXP_DATA 0x3C
+
+/*
+ * Fatal events
+ */
+#define E_RX_INV_BUF 0x36
+#define E_RX_INV_DSC 0x37
+#define E_RNG_BLK 0x38
+
+/*
+ * Warning events
+ */
+#define E_RX_TO 0x39
+#define E_BFR_SPC 0x3A
+#define E_INV_ULP 0x3B
+
+#define E_NOT_IMPLEMENTED 0x40
+
+
+/*
+ * Commands
+ */
+
+#define CMD_RING_ENTRIES 16
+
+struct cmd {
+#ifdef __LITTLE_ENDIAN
+ u16 index;
+ u8 ring;
+ u8 code;
+#else
+ u8 code;
+ u8 ring;
+ u16 index;
+#endif
+};
+
+#define C_START_FW 0x01
+#define C_UPD_STAT 0x02
+#define C_WATCHDOG 0x05
+#define C_DEL_RNG 0x09
+#define C_NEW_RNG 0x0A
+#define C_CONN 0x0D
+
+
+/*
+ * Mode bits
+ */
+
+#define INTERRUPT 0x02
+#define TX_IP_CKSUM 0x04
+#define PACKET_END 0x08
+#define PACKET_START 0x10
+#define SAME_IFIELD 0x80
+
+
+/*
+ * TX ring
+ */
+
+#ifdef CONFIG_ROADRUNNER_LARGE_RINGS
+#define TX_RING_ENTRIES 32
+#else
+#define TX_RING_ENTRIES 16
+#endif
+#define TX_RING_SIZE (TX_RING_ENTRIES * sizeof(struct tx_desc))
+
+struct tx_desc{
+#if (BITS_PER_LONG == 64)
+ u64 addr;
+#else
+ u32 zero;
+ u32 addr;
+#endif
+ u32 res;
+#ifdef __LITTLE_ENDIAN
+ u16 size;
+ u8 pad;
+ u8 mode;
+#else
+ u8 mode;
+ u8 pad;
+ u16 size;
+#endif
+};
+
+
+#ifdef CONFIG_ROADRUNNER_LARGE_RINGS
+#define RX_RING_ENTRIES 32
+#else
+#define RX_RING_ENTRIES 16
+#endif
+#define RX_RING_SIZE (RX_RING_ENTRIES * sizeof(struct rx_desc))
+
+struct rx_desc{
+#if (BITS_PER_LONG == 64)
+ u64 addr;
+#else
+ u32 zero;
+ u32 addr;
+#endif
+ u32 res;
+#ifdef __LITTLE_ENDIAN
+ u16 size;
+ u8 pad;
+ u8 mode;
+#else
+ u8 mode;
+ u8 pad;
+ u16 size;
+#endif
+};
+
+
+/*
+ * ioctl's
+ */
+
+#define SIOCRRPFW SIOCDEVPRIVATE /* put firmware */
+#define SIOCRRGFW SIOCDEVPRIVATE+1 /* get firmware */
+
+
+struct seg_hdr {
+ u32 seg_start;
+ u32 seg_len;
+ u32 seg_eestart;
+};
+
+
+#define EEPROM_BASE 0x80000000
+
+struct eeprom_boot {
+ u32 key1;
+ u32 key2;
+ u32 sram_size;
+ struct seg_hdr loader;
+ u32 init_chksum;
+ u32 reserved1;
+};
+
+struct eeprom_manf {
+ u32 HeaderFmt;
+ u32 Firmware;
+ u32 BoardRevision;
+ u32 RoadrunnerRev;
+ char OpticsPart[8];
+ u32 OpticsRev;
+ u32 pad1;
+ char SramPart[8];
+ u32 SramRev;
+ u32 pad2;
+ char EepromPart[8];
+ u32 EepromRev;
+ u32 EepromSize;
+ char PalPart[8];
+ u32 PalRev;
+ u32 pad3;
+ char PalCodeFile[12];
+ u32 PalCodeRev;
+ char BoardULA[8];
+ char SerialNo[8];
+ char MfgDate[8];
+ char MfgTime[8];
+ char ModifyDate[8];
+ u32 ModCount;
+ u32 pad4[13];
+};
+
+
+struct eeprom_phase_info {
+ char phase1File[12];
+ u32 phase1Rev;
+ char phase1Date[8];
+ char phase2File[12];
+ u32 phase2Rev;
+ char phase2Date[8];
+ u32 reserved7[4];
+};
+
+struct eeprom_rncd_info {
+ u32 FwStart;
+ u32 FwRev;
+ char FwDate[8];
+ u32 AddrRunCodeSegs;
+ u32 FileNames;
+ char File[13][8];
+};
+
+
+/* Phase 1 region (starts are word offset 0x80) */
+struct phase1_hdr{
+ u32 jump;
+ u32 noop;
+ struct seg_hdr phase2Seg;
+};
+
+struct eeprom {
+ struct eeprom_boot boot;
+ u32 pad1[8];
+ struct eeprom_manf manf;
+ struct eeprom_phase_info phase_info;
+ struct eeprom_rncd_info rncd_info;
+ u32 pad2[15];
+ u32 hdr_checksum;
+ struct phase1_hdr phase1;
+};
+
+
+struct rr_stats {
+ u32 NicTimeStamp;
+ u32 RngCreated;
+ u32 RngDeleted;
+ u32 IntrGen;
+ u32 NEvtOvfl;
+ u32 InvCmd;
+ u32 DmaReadErrs;
+ u32 DmaWriteErrs;
+ u32 StatUpdtT;
+ u32 StatUpdtC;
+ u32 WatchDog;
+ u32 Trace;
+
+ /* Serial HIPPI */
+ u32 LnkRdyEst;
+ u32 GLinkErr;
+ u32 AltFlgErr;
+ u32 OvhdBit8Sync;
+ u32 RmtSerPrtyErr;
+ u32 RmtParPrtyErr;
+ u32 RmtLoopBk;
+ u32 pad1;
+
+ /* HIPPI tx */
+ u32 ConEst;
+ u32 ConRejS;
+ u32 ConRetry;
+ u32 ConTmOut;
+ u32 SndConDiscon;
+ u32 SndParErr;
+ u32 PktSnt;
+ u32 pad2[2];
+ u32 ShFBstSnt;
+ u64 BytSent;
+ u32 TxTimeout;
+ u32 pad3[3];
+
+ /* HIPPI rx */
+ u32 ConAcc;
+ u32 ConRejdiPrty;
+ u32 ConRejd64b;
+ u32 ConRejdBuf;
+ u32 RxConDiscon;
+ u32 RxConNoData;
+ u32 PktRx;
+ u32 pad4[2];
+ u32 ShFBstRx;
+ u64 BytRx;
+ u32 RxParErr;
+ u32 RxLLRCerr;
+ u32 RxBstSZerr;
+ u32 RxStateErr;
+ u32 RxRdyErr;
+ u32 RxInvULP;
+ u32 RxSpcBuf;
+ u32 RxSpcDesc;
+ u32 RxRngSpc;
+ u32 RxRngFull;
+ u32 RxPktLenErr;
+ u32 RxCksmErr;
+ u32 RxPktDrp;
+ u32 RngLowSpc;
+ u32 RngDataClose;
+ u32 RxTimeout;
+ u32 RxIdle;
+};
+
+
+/*
+ * This struct is shared with the NIC firmware.
+ */
+struct ring_ctrl {
+#if (BITS_PER_LONG == 64)
+ u64 rngptr;
+#else
+ u32 zero;
+ u32 rngptr;
+#endif
+#ifdef __LITTLE_ENDIAN
+ u16 entries;
+ u8 pad;
+ u8 entry_size;
+ u16 pi;
+ u16 mode;
+#else
+ u8 entry_size;
+ u8 pad;
+ u16 entries;
+ u16 mode;
+ u16 pi;
+#endif
+};
+
+struct rr_info {
+ union {
+ struct rr_stats stats;
+ u32 stati[128];
+ } s;
+ struct ring_ctrl evt_ctrl;
+ struct ring_ctrl cmd_ctrl;
+ struct ring_ctrl tx_ctrl;
+ u8 pad[464];
+ u8 trace[3072];
+};
+
+/*
+ * The linux structure for the RoadRunner.
+ *
+ * RX/TX descriptors are put first to make sure they are properly
+ * aligned and do not cross cache-line boundaries.
+ */
+
+struct rr_private
+{
+ struct rx_desc rx_ring[RX_RING_ENTRIES];
+ struct tx_desc tx_ring[TX_RING_ENTRIES];
+ struct event evt_ring[EVT_RING_ENTRIES];
+ struct sk_buff *tx_skbuff[TX_RING_ENTRIES];
+ struct sk_buff *rx_skbuff[RX_RING_ENTRIES];
+ struct rr_regs *regs; /* Register base */
+ struct ring_ctrl *rx_ctrl; /* Receive ring control */
+ struct rr_info *info; /* Shared info page */
+ spinlock_t lock;
+ struct timer_list timer;
+ u32 cur_rx, cur_cmd, cur_evt;
+ u32 dirty_rx, dirty_tx;
+ u32 tx_full;
+ short fw_running;
+ u8 pci_bus; /* PCI bus number */
+ u8 pci_dev_fun; /* PCI device numbers */
+ char name[24]; /* The assigned name */
+ struct net_device_stats stats;
+};
+
+
+/*
+ * Prototypes
+ */
+static int rr_init(struct device *dev);
+static int rr_init1(struct device *dev);
+static void rr_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+
+static int rr_open(struct device *dev);
+static int rr_start_xmit(struct sk_buff *skb, struct device *dev);
+static int rr_close(struct device *dev);
+static struct net_device_stats *rr_get_stats(struct device *dev);
+static int rr_ioctl(struct device *dev, struct ifreq *rq, int cmd);
+
+#endif /* _RRUNNER_H_ */
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index 69ed516f0..21f69fa3b 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -1,6 +1,6 @@
/* rtl8139.c: A RealTek RTL8129/8139 Fast Ethernet driver for Linux. */
/*
- Written 1997 by Donald Becker.
+ Written 1997-1998 by Donald Becker.
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
@@ -15,14 +15,27 @@
Support and updates available at
http://cesdis.gsfc.nasa.gov/linux/drivers/rtl8139.html
+
+ Twister-tuning code contributed by Kinston <shangh@realtek.com.tw>.
*/
static const char *version =
-"rtl8139.c:v0.14 12/9/97 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/rtl8139.html\n";
+"rtl8139.c:v1.04 9/22/98 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/rtl8139.html\n";
/* A few user-configurable values. */
/* Maximum events (Rx packets, etc.) to handle at each interrupt. */
-static int max_interrupt_work = 10;
+static int max_interrupt_work = 20;
+#define rtl8129_debug debug
+static int rtl8129_debug = 1;
+
+/* Maximum number of multicast addresses to filter (vs. Rx-all-multicast).
+ The RTL chips use a 64 element hash table based on the Ethernet CRC. */
+static int multicast_filter_limit = 32;
+
+/* Used to pass the full-duplex flag, etc. */
+#define MAX_UNITS 8 /* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
/* Size of the in-memory receive ring. */
#define RX_BUF_LEN_IDX 3 /* 0==8K, 1==16K, 2==32K, 3==64K */
@@ -37,101 +50,61 @@ static int max_interrupt_work = 10;
/* The following settings are log_2(bytes)-4: 0 == 16 bytes .. 6==1024. */
#define RX_FIFO_THRESH 4 /* Rx buffer level before first PCI xfer. */
#define RX_DMA_BURST 4 /* Maximum PCI burst, '4' is 256 bytes */
-#define TX_DMA_BURST 4
+#define TX_DMA_BURST 4 /* Calculate as 16<<val. */
/* Operational parameters that usually are not changed. */
/* Time in jiffies before concluding the transmitter is hung. */
-#define TX_TIMEOUT ((4000*HZ)/1000)
+#define TX_TIMEOUT (4*HZ)
-#include <linux/config.h>
-#ifdef MODULE
-#ifdef MODVERSIONS
-#include <linux/modversions.h>
-#endif
#include <linux/module.h>
#include <linux/version.h>
-#else
-#define MOD_INC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
-
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/string.h>
#include <linux/timer.h>
-#include <linux/ptrace.h>
#include <linux/errno.h>
#include <linux/ioport.h>
#include <linux/malloc.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
-#include <asm/processor.h> /* Processor type for cache alignment. */
-#include <asm/bitops.h>
-#include <asm/io.h>
-#include <asm/dma.h>
-
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
+#include <asm/processor.h> /* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
-/* Kernel compatibility defines, common to David Hind's PCMCIA package.
+/* Kernel compatibility defines, some common to David Hind's PCMCIA package.
This is only in the support-all-kernels source code. */
-#include <linux/version.h> /* Evil, but neccessary */
-
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10300
-#define RUN_AT(x) (x) /* What to put in timer->expires. */
-#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC)
-#define virt_to_bus(addr) ((unsigned long)addr)
-#define bus_to_virt(addr) ((void*)addr)
-#else /* 1.3.0 and later */
#define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
-#endif
-
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10338
-#ifdef MODULE
-#if !defined(CONFIG_MODVERSIONS) && !defined(__NO_VERSION__)
-char kernel_version[] = UTS_RELEASE;
-#endif
-#else
-#undef MOD_INC_USE_COUNT
-#define MOD_INC_USE_COUNT
-#undef MOD_DEC_USE_COUNT
-#define MOD_DEC_USE_COUNT
-#endif
-#endif /* 1.3.38 */
-#if (LINUX_VERSION_CODE >= 0x10344)
-#define NEW_MULTICAST
#include <linux/delay.h>
-#endif
-#ifdef SA_SHIRQ
-#define FREE_IRQ(irqnum, dev) free_irq(irqnum, dev)
-#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n, instance)
-#define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs)
+#if LINUX_VERSION_CODE < 0x20123
+#define test_and_set_bit(val, addr) set_bit(val, addr)
+#endif
+#if LINUX_VERSION_CODE <= 0x20139
+#define net_device_stats enet_statistics
#else
-#define FREE_IRQ(irqnum, dev) free_irq(irqnum)
-#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n)
-#define IRQ(irq, dev_id, pt_regs) (irq, pt_regs)
+#define NETSTATS_VER2
#endif
-
-#if (LINUX_VERSION_CODE < 0x20123)
-#define test_and_set_bit(val, addr) set_bit(val, addr)
+#if LINUX_VERSION_CODE < 0x20155 || defined(CARDBUS)
+/* Grrrr, the PCI code changed, but did not consider CardBus... */
#include <linux/bios32.h>
+#define PCI_SUPPORT_VER1
+#else
+#define PCI_SUPPORT_VER2
+#endif
+#if LINUX_VERSION_CODE < 0x20159
+#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE);
+#else
+#define dev_free_skb(skb) dev_kfree_skb(skb);
#endif
/* The I/O extent. */
#define RTL8129_TOTAL_SIZE 0x80
-#ifdef HAVE_DEVLIST
-struct netdev_entry rtl8139_drv =
-{"RTL8139", rtl8139_probe, RTL8129_TOTAL_SIZE, NULL};
-#endif
-
-static int rtl8129_debug = 1;
-
/*
Theory of Operation
@@ -177,16 +150,45 @@ http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
IVc. Errata
*/
+
+
+/* This table drives the PCI probe routines. It's mostly boilerplate in all
+ of the drivers, and will likely be provided by some future kernel.
+ Note the matching code -- the first table entry matchs all 56** cards but
+ second only the 1234 card.
+*/
+enum pci_flags_bit {
+ PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+ PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+};
+struct pci_id_info {
+ const char *name;
+ u16 vendor_id, device_id, device_id_mask, flags;
+ int io_size;
+ struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev,
+ long ioaddr, int irq, int chip_idx, int fnd_cnt);
+};
+
+static struct device * rtl8129_probe1(int pci_bus, int pci_devfn,
+ struct device *dev, long ioaddr,
+ int irq, int chp_idx, int fnd_cnt);
+
+static struct pci_id_info pci_tbl[] =
+{{ "RealTek RTL8129 Fast Ethernet",
+ 0x10ec, 0x8129, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x80, rtl8129_probe1},
+ { "RealTek RTL8139 Fast Ethernet",
+ 0x10ec, 0x8139, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x80, rtl8129_probe1},
+ { "RealTek RTL8139 Fast Ethernet (mislabeled)",
+ 0x1113, 0x1211, 0xffff, PCI_USES_IO|PCI_USES_MASTER, 0x80, rtl8129_probe1},
+ {0,}, /* 0 terminated list. */
+};
+
+/* The capability table matches the chip table above. */
+enum {HAS_MII_XCVR=0x01, HAS_CHIP_XCVR=0x02, HAS_LNK_CHNG=0x04};
+static int rtl_cap_tbl[] = {
+ HAS_MII_XCVR, HAS_CHIP_XCVR|HAS_LNK_CHNG, HAS_CHIP_XCVR|HAS_LNK_CHNG,
+};
-#ifndef PCI_VENDOR_ID_REALTEK
-#define PCI_VENDOR_ID_REALTEK 0x10ec
-#endif
-#ifndef PCI_DEVICE_ID_REALTEK_8129
-#define PCI_DEVICE_ID_REALTEK_8129 0x8129
-#endif
-#ifndef PCI_DEVICE_ID_REALTEK_8139
-#define PCI_DEVICE_ID_REALTEK_8139 0x8139
-#endif
/* The rest of these values should never change. */
#define NUM_TX_DESC 4 /* Number of Tx descriptor registers. */
@@ -195,7 +197,7 @@ IVc. Errata
enum RTL8129_registers {
MAC0=0, /* Ethernet hardware address. */
MAR0=8, /* Multicast filter. */
- TxStat0=0x10, /* Transmit status (Four 32bit registers). */
+ TxStatus0=0x10, /* Transmit status (Four 32bit registers). */
TxAddr0=0x20, /* Tx descriptors (also four 32bit). */
RxBuf=0x30, RxEarlyCnt=0x34, RxEarlyStatus=0x36,
ChipCmd=0x37, RxBufPtr=0x38, RxBufAddr=0x3A,
@@ -206,7 +208,12 @@ enum RTL8129_registers {
Cfg9346=0x50, Config0=0x51, Config1=0x52,
FlashReg=0x54, GPPinData=0x58, GPPinDir=0x59, MII_SMI=0x5A, HltClk=0x5B,
MultiIntr=0x5C, TxSummary=0x60,
- BMCR=0x62, BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68, NWayExpansion=0x6A,
+ MII_BMCR=0x62, MII_BMSR=0x64, NWayAdvert=0x66, NWayLPAR=0x68,
+ NWayExpansion=0x6A,
+ /* Undocumented registers, but required for proper operation. */
+ FIFOTMS=0x70, /* FIFO Test Mode Select */
+ CSCR=0x74, /* Chip Status and Configuration Register. */
+ PARA78=0x78, PARA7c=0x7c, /* Magic transceiver parameter register. */
};
enum ChipCmdBits {
@@ -228,25 +235,44 @@ enum RxStatusBits {
RxBadAlign=0x0002, RxStatusOK=0x0001,
};
+enum CSCRBits {
+ CSCR_LinkOKBit=0x0400, CSCR_LinkChangeBit=0x0800,
+ CSCR_LinkStatusBits=0x0f000, CSCR_LinkDownOffCmd=0x003c0,
+ CSCR_LinkDownCmd=0x0f3c0,
+};
+
+/* Twister tuning parameters from RealTek. Completely undocumented. */
+unsigned long param[4][4]={
+ {0x0cb39de43,0x0cb39ce43,0x0fb38de03,0x0cb38de43},
+ {0x0cb39de43,0x0cb39ce43,0x0cb39ce83,0x0cb39ce83},
+ {0x0cb39de43,0x0cb39ce43,0x0cb39ce83,0x0cb39ce83},
+ {0x0bb39de43,0x0bb39ce43,0x0bb39ce83,0x0bb39ce83}
+};
+
struct rtl8129_private {
char devname[8]; /* Used only for kernel debugging. */
const char *product_name;
struct device *next_module;
int chip_id;
int chip_revision;
+ unsigned char pci_bus, pci_devfn;
+#if LINUX_VERSION_CODE > 0x20139
+ struct net_device_stats stats;
+#else
struct enet_statistics stats;
+#endif
struct timer_list timer; /* Media selection timer. */
- unsigned int cur_rx, cur_tx; /* The next free and used entries */
- unsigned int dirty_rx, dirty_tx;
+ unsigned int cur_rx; /* Index into the Rx buffer of next Rx pkt. */
+ unsigned int cur_tx, dirty_tx, tx_flag;
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[NUM_TX_DESC];
unsigned char *tx_buf[NUM_TX_DESC]; /* Tx bounce buffers */
unsigned char *rx_ring;
unsigned char *tx_bufs; /* Tx bounce buffer region. */
- unsigned char mc_filter[8]; /* Current multicast filter. */
char phys[4]; /* MII device addresses. */
unsigned int tx_full:1; /* The Tx queue is full. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
+ unsigned int duplex_lock:1; /* Full-duplex operation requested. */
unsigned int default_port:4; /* Last dev->if_port value. */
unsigned int media2:4; /* Secondary monitored media port. */
unsigned int medialock:1; /* Don't sense media type. */
@@ -254,24 +280,21 @@ struct rtl8129_private {
};
#ifdef MODULE
-/* Used to pass the full-duplex flag, etc. */
-static int options[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int full_duplex[] = {-1, -1, -1, -1, -1, -1, -1, -1};
-#if LINUX_VERSION_CODE > 0x20118
+#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
MODULE_DESCRIPTION("RealTek RTL8129/8139 Fast Ethernet driver");
-MODULE_PARM(debug, "i");
-MODULE_PARM(options, "1-" __MODULE_STRING(8) "i");
-MODULE_PARM(full_duplex, "1-" __MODULE_STRING(8) "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(multicast_filter_limit, "i");
MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(debug, "i");
#endif
#endif
-static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
- int chip_id, int options, int card_idx);
static int rtl8129_open(struct device *dev);
-static int read_eeprom(int ioaddr, int location);
-static int mdio_read(int ioaddr, int phy_id, int location);
+static int read_eeprom(long ioaddr, int location);
+static int mdio_read(struct device *dev, int phy_id, int location);
+static void mdio_write(struct device *dev, int phy_id, int location, int val);
static void rtl8129_timer(unsigned long data);
static void rtl8129_tx_timeout(struct device *dev);
static void rtl8129_init_ring(struct device *dev);
@@ -279,161 +302,138 @@ static int rtl8129_start_xmit(struct sk_buff *skb, struct device *dev);
static int rtl8129_rx(struct device *dev);
static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static int rtl8129_close(struct device *dev);
+static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd);
static struct enet_statistics *rtl8129_get_stats(struct device *dev);
-#ifdef NEW_MULTICAST
+static inline u32 ether_crc(int length, unsigned char *data);
static void set_rx_mode(struct device *dev);
-#else
-static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
-#endif
-
-#ifdef MODULE
/* A list of all installed RTL8129 devices, for removing the driver module. */
static struct device *root_rtl8129_dev = NULL;
-#endif
+
+/* Ideally we would detect all network cards in slot order. That would
+ be best done a central PCI probe dispatch, which wouldn't work
+ well when dynamically adding drivers. So instead we detect just the
+ Rtl81*9 cards in slot order. */
int rtl8139_probe(struct device *dev)
{
int cards_found = 0;
- static int pci_index = 0; /* Static, for multiple probe calls. */
+ int pci_index = 0;
+ unsigned char pci_bus, pci_device_fn;
- /* Ideally we would detect all network cards in slot order. That would
- be best done a central PCI probe dispatch, which wouldn't work
- well with the current structure. So instead we detect just the
- Rtl81*9 cards in slot order. */
+ if ( ! pcibios_present())
+ return -ENODEV;
- if (pci_present()) {
- unsigned char pci_bus, pci_device_fn;
+ for (;pci_index < 0xff; pci_index++) {
+ u16 vendor, device, pci_command, new_command;
+ int chip_idx, irq;
+ long ioaddr;
- for (;pci_index < 0xff; pci_index++) {
- unsigned char pci_latency;
-#if LINUX_VERSION_CODE >= 0x20155
- unsigned int pci_irq_line;
- struct pci_dev *pdev;
-#else
- unsigned char pci_irq_line;
-#endif
- unsigned short pci_command, new_command, vendor, device;
- unsigned int pci_ioaddr;
-
- if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
-#ifdef REVERSE_PROBE_ORDER
- 0xff - pci_index,
-#else
- pci_index,
-#endif
- &pci_bus, &pci_device_fn)
- != PCIBIOS_SUCCESSFUL)
+ if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index,
+ &pci_bus, &pci_device_fn)
+ != PCIBIOS_SUCCESSFUL)
+ break;
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_VENDOR_ID, &vendor);
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_DEVICE_ID, &device);
+
+ for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++)
+ if (vendor == pci_tbl[chip_idx].vendor_id
+ && (device & pci_tbl[chip_idx].device_id_mask) ==
+ pci_tbl[chip_idx].device_id)
break;
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_VENDOR_ID, &vendor);
- if (vendor != PCI_VENDOR_ID_REALTEK)
- continue;
-
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_DEVICE_ID, &device);
-#if LINUX_VERSION_CODE >= 0x20155
- pdev = pci_find_slot(pci_bus, pci_device_fn);
- pci_irq_line = pdev->irq;
- pci_ioaddr = pdev->base_address[0];
+ if (pci_tbl[chip_idx].vendor_id == 0) /* Compiled out! */
+ continue;
+
+ {
+#if defined(PCI_SUPPORT_VER2)
+ struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
+ ioaddr = pdev->base_address[0] & ~3;
+ irq = pdev->irq;
#else
+ u32 pci_ioaddr;
+ u8 pci_irq_line;
pcibios_read_config_byte(pci_bus, pci_device_fn,
PCI_INTERRUPT_LINE, &pci_irq_line);
pcibios_read_config_dword(pci_bus, pci_device_fn,
PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ ioaddr = pci_ioaddr & ~3;
+ irq = pci_irq_line;
#endif
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
-
- if (device != PCI_DEVICE_ID_REALTEK_8129
- && device != PCI_DEVICE_ID_REALTEK_8139) {
- printk(KERN_NOTICE"Unknown RealTek PCI ethernet chip type "
- "%4.4x detected: not configured.\n", device);
- continue;
- }
- if (check_region(pci_ioaddr, RTL8129_TOTAL_SIZE))
- continue;
-
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
- new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
- if (pci_command != new_command) {
- printk(KERN_INFO " The PCI BIOS has not enabled this"
- " device! Updating PCI config %4.4x->%4.4x.\n",
- pci_command, new_command);
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, new_command);
- }
+ }
-#ifdef MODULE
- dev = rtl8129_probe1(dev, pci_ioaddr, pci_irq_line, device,
- options[cards_found], cards_found);
-#else
- dev = rtl8129_probe1(dev, pci_ioaddr, pci_irq_line, device,
- dev ? dev->mem_start : 0, -1);
-#endif
+ if ((pci_tbl[chip_idx].flags & PCI_USES_IO) &&
+ check_region(ioaddr, pci_tbl[chip_idx].io_size))
+ continue;
+
+ /* Activate the card: fix for brain-damaged Win98 BIOSes. */
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, &pci_command);
+ new_command = pci_command | (pci_tbl[chip_idx].flags & 7);
+ if (pci_command != new_command) {
+ printk(KERN_INFO " The PCI BIOS has not enabled the"
+ " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n",
+ pci_bus, pci_device_fn, pci_command, new_command);
+ pcibios_write_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, new_command);
+ }
+
+ dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr,
+ irq, chip_idx, cards_found);
- if (dev) {
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, &pci_latency);
- if (pci_latency < 32) {
- printk(KERN_NOTICE" PCI latency timer (CFLT) is "
- "unreasonably low at %d. Setting to 64 clocks.\n",
- pci_latency);
- pcibios_write_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, 64);
- } else if (rtl8129_debug > 1)
- printk(KERN_INFO" PCI latency timer (CFLT) is %#x.\n",
- pci_latency);
- dev = 0;
- cards_found++;
+ if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) {
+ u8 pci_latency;
+ pcibios_read_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, &pci_latency);
+ if (pci_latency < 32) {
+ printk(KERN_NOTICE " PCI latency timer (CFLT) is "
+ "unreasonably low at %d. Setting to 64 clocks.\n",
+ pci_latency);
+ pcibios_write_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, 64);
}
}
+ dev = 0;
+ cards_found++;
}
-#if defined (MODULE)
- return cards_found;
-#else
return cards_found ? 0 : -ENODEV;
-#endif
}
-static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
- int chip_id, int options, int card_idx)
+static struct device * rtl8129_probe1(int pci_bus, int pci_devfn,
+ struct device *dev, long ioaddr,
+ int irq, int chip_idx, int found_cnt)
{
static int did_version = 0; /* Already printed version info. */
struct rtl8129_private *tp;
- int i;
+ int i, option = found_cnt < MAX_UNITS ? options[found_cnt] : 0;
if (rtl8129_debug > 0 && did_version++ == 0)
printk(KERN_INFO "%s", version);
dev = init_etherdev(dev, 0);
- printk(KERN_INFO "%s: RealTek RTL%x at %#3x, IRQ %d, ",
- dev->name, chip_id, ioaddr, irq);
+ printk(KERN_INFO "%s: %s at %#lx, IRQ %d, ",
+ dev->name, pci_tbl[chip_idx].name, ioaddr, irq);
/* Bring the chip out of low-power mode. */
outb(0x00, ioaddr + Config1);
- /* Perhaps this should be read from the EEPROM? */
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + MAC0 + i);
+ if (read_eeprom(ioaddr, 0) != 0xffff)
+ for (i = 0; i < 3; i++)
+ ((u16 *)(dev->dev_addr))[i] = read_eeprom(ioaddr, i + 7);
+ else
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = inb(ioaddr + MAC0 + i);
for (i = 0; i < 5; i++)
printk("%2.2x:", dev->dev_addr[i]);
printk("%2.2x.\n", dev->dev_addr[i]);
- if (rtl8129_debug > 1) {
- printk(KERN_INFO "%s: EEPROM contents\n", dev->name);
- for (i = 0; i < 64; i++)
- printk(" %4.4x%s", read_eeprom(ioaddr, i),
- i%16 == 15 ? "\n"KERN_INFO : "");
- }
-
/* We do a request_region() to register /proc/ioports info. */
- request_region(ioaddr, RTL8129_TOTAL_SIZE, "RealTek RTL8129/39 Fast Ethernet");
+ request_region(ioaddr, pci_tbl[chip_idx].io_size, dev->name);
dev->base_addr = ioaddr;
dev->irq = irq;
@@ -443,22 +443,21 @@ static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
memset(tp, 0, sizeof(*tp));
dev->priv = tp;
-#ifdef MODULE
tp->next_module = root_rtl8129_dev;
root_rtl8129_dev = dev;
-#endif
- tp->chip_id = chip_id;
+ tp->chip_id = chip_idx;
+ tp->pci_bus = pci_bus;
+ tp->pci_devfn = pci_devfn;
/* Find the connected MII xcvrs.
Doing this in open() would allow detecting external xcvrs later, but
takes too much time. */
- if (chip_id == 0x8129) {
+ if (rtl_cap_tbl[chip_idx] & HAS_MII_XCVR) {
int phy, phy_idx;
for (phy = 0, phy_idx = 0; phy < 32 && phy_idx < sizeof(tp->phys);
phy++) {
- int mii_status = mdio_read(ioaddr, phy, 1);
-
+ int mii_status = mdio_read(dev, phy, 1);
if (mii_status != 0xffff && mii_status != 0x0000) {
tp->phys[phy_idx++] = phy;
printk(KERN_INFO "%s: MII transceiver found at address %d.\n",
@@ -472,7 +471,7 @@ static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
tp->phys[0] = -1;
}
} else {
- tp->phys[0] = -1;
+ tp->phys[0] = 32;
}
/* Put the chip into low-power mode. */
@@ -481,18 +480,21 @@ static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
outb('H', ioaddr + HltClk); /* 'R' would leave the clock running. */
/* The lower four bits are the media type. */
- if (options > 0) {
- tp->full_duplex = (options & 16) ? 1 : 0;
- tp->default_port = options & 15;
+ if (option > 0) {
+ tp->full_duplex = (option & 0x200) ? 1 : 0;
+ tp->default_port = option & 15;
if (tp->default_port)
tp->medialock = 1;
}
-#ifdef MODULE
- if (card_idx >= 0) {
- if (full_duplex[card_idx] >= 0)
- tp->full_duplex = full_duplex[card_idx];
+
+ if (found_cnt < MAX_UNITS && full_duplex[found_cnt] > 0)
+ tp->full_duplex = full_duplex[found_cnt];
+
+ if (tp->full_duplex) {
+ printk(KERN_INFO "%s: Media type forced to Full Duplex.\n", dev->name);
+ mdio_write(dev, tp->phys[0], 4, 0x141);
+ tp->duplex_lock = 1;
}
-#endif
/* The Rtl8129-specific entries in the device structure. */
dev->open = &rtl8129_open;
@@ -500,6 +502,7 @@ static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
dev->stop = &rtl8129_close;
dev->get_stats = &rtl8129_get_stats;
dev->set_multicast_list = &set_rx_mode;
+ dev->do_ioctl = &mii_ioctl;
return dev;
}
@@ -516,24 +519,21 @@ static struct device *rtl8129_probe1(struct device *dev, int ioaddr, int irq,
#define EE_ENB (0x80 | EE_CS)
/* Delay between EEPROM clock transitions.
- The 1.2 code is a "nasty" timing loop, but PC compatible machines are
- *supposed* to delay an ISA-compatible period for the SLOW_DOWN_IO macro. */
-#ifdef _LINUX_DELAY_H
-#define eeprom_delay(nanosec) udelay((nanosec + 999)/1000)
-#else
-#define eeprom_delay(nanosec) do { int _i = 3; while (--_i > 0) { __SLOW_DOWN_IO; }} while (0)
-#endif
+ No extra delay is needed with 33Mhz PCI, but 66Mhz may change this.
+ */
+
+#define eeprom_delay() inl(ee_addr)
/* The EEPROM commands include the alway-set leading bit. */
#define EE_WRITE_CMD (5 << 6)
#define EE_READ_CMD (6 << 6)
#define EE_ERASE_CMD (7 << 6)
-static int read_eeprom(int ioaddr, int location)
+static int read_eeprom(long ioaddr, int location)
{
int i;
- unsigned short retval = 0;
- short ee_addr = ioaddr + Cfg9346;
+ unsigned retval = 0;
+ long ee_addr = ioaddr + Cfg9346;
int read_cmd = location | EE_READ_CMD;
outb(EE_ENB & ~EE_CS, ee_addr);
@@ -541,22 +541,21 @@ static int read_eeprom(int ioaddr, int location)
/* Shift the read command bits out. */
for (i = 10; i >= 0; i--) {
- short dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
+ int dataval = (read_cmd & (1 << i)) ? EE_DATA_WRITE : 0;
outb(EE_ENB | dataval, ee_addr);
- eeprom_delay(100);
+ eeprom_delay();
outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
- eeprom_delay(150);
- outb(EE_ENB | dataval, ee_addr); /* Finish EEPROM a clock tick. */
- eeprom_delay(250);
+ eeprom_delay();
}
outb(EE_ENB, ee_addr);
+ eeprom_delay();
for (i = 16; i > 0; i--) {
outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
- eeprom_delay(100);
+ eeprom_delay();
retval = (retval << 1) | ((inb(ee_addr) & EE_DATA_READ) ? 1 : 0);
outb(EE_ENB, ee_addr);
- eeprom_delay(100);
+ eeprom_delay();
}
/* Terminate the EEPROM access. */
@@ -566,43 +565,50 @@ static int read_eeprom(int ioaddr, int location)
/* MII serial management: mostly bogus for now. */
/* Read and write the MII management registers using software-generated
- serial MDIO protocol. The maxium data clock rate is 2.5 Mhz. */
+ serial MDIO protocol.
+ The maximum data clock rate is 2.5 Mhz. The minimum timing is usually
+ met by back-to-back PCI I/O cycles, but we insert a delay to avoid
+ "overclocking" issues. */
#define MDIO_DIR 0x80
#define MDIO_DATA_OUT 0x04
#define MDIO_DATA_IN 0x02
#define MDIO_CLK 0x01
-#ifdef _LINUX_DELAY_H
-#define mdio_delay() udelay(1) /* Really 400ns. */
-#else
-#define mdio_delay() __SLOW_DOWN_IO;
-#endif
+#define MDIO_WRITE0 (MDIO_DIR)
+#define MDIO_WRITE1 (MDIO_DIR | MDIO_DATA_OUT)
+
+#define mdio_delay() inb(mdio_addr)
+
+static char mii_2_8139_map[8] = {MII_BMCR, MII_BMSR, 0, 0, NWayAdvert,
+ NWayLPAR, NWayExpansion, 0 };
/* Syncronize the MII management interface by shifting 32 one bits out. */
-static void mdio_sync(int ioaddr)
+static void mdio_sync(long mdio_addr)
{
int i;
- int mdio_addr = ioaddr + MII_SMI;
for (i = 32; i >= 0; i--) {
- outb(MDIO_DIR | MDIO_DATA_OUT, mdio_addr);
+ outb(MDIO_WRITE1, mdio_addr);
mdio_delay();
- outb(MDIO_DIR | MDIO_DATA_OUT | MDIO_CLK, mdio_addr);
+ outb(MDIO_WRITE1 | MDIO_CLK, mdio_addr);
mdio_delay();
}
return;
}
-static int mdio_read(int ioaddr, int phy_id, int location)
+static int mdio_read(struct device *dev, int phy_id, int location)
{
- int i;
- int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
+ long mdio_addr = dev->base_addr + MII_SMI;
+ int mii_cmd = (0xf6 << 10) | (phy_id << 5) | location;
int retval = 0;
- int mdio_addr = ioaddr + MII_SMI;
+ int i;
- mdio_sync(ioaddr);
+ if ((phy_id & 0x1f) == 0) { /* Really a 8139. Use internal registers. */
+ return location < 8 && mii_2_8139_map[location] ?
+ inw(dev->base_addr + mii_2_8139_map[location]) : 0;
+ }
+ mdio_sync(mdio_addr);
/* Shift the read command bits out. */
for (i = 15; i >= 0; i--) {
- int dataval =
- (read_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
+ int dataval = (mii_cmd & (1 << i)) ? MDIO_DATA_OUT : 0;
outb(MDIO_DIR | dataval, mdio_addr);
mdio_delay();
@@ -620,31 +626,52 @@ static int mdio_read(int ioaddr, int phy_id, int location)
}
return (retval>>1) & 0xffff;
}
+
+static void mdio_write(struct device *dev, int phy_id, int location, int value)
+{
+ long mdio_addr = dev->base_addr + MII_SMI;
+ int mii_cmd = (0x5002 << 16) | (phy_id << 23) | (location<<18) | value;
+ int i;
+
+ if (phy_id == 32) { /* Really a 8139. Use internal registers. */
+ if (location < 8 && mii_2_8139_map[location])
+ outw(value, dev->base_addr + mii_2_8139_map[location]);
+ return;
+ }
+ mdio_sync(mdio_addr);
+
+ /* Shift the command bits out. */
+ for (i = 31; i >= 0; i--) {
+ int dataval = (mii_cmd & (1 << i)) ? MDIO_WRITE1 : MDIO_WRITE0;
+ outb(dataval, mdio_addr);
+ mdio_delay();
+ outb(dataval | MDIO_CLK, mdio_addr);
+ mdio_delay();
+ }
+ /* Clear out extra bits. */
+ for (i = 2; i > 0; i--) {
+ outb(0, mdio_addr);
+ mdio_delay();
+ outb(MDIO_CLK, mdio_addr);
+ mdio_delay();
+ }
+ return;
+}
+
static int
rtl8129_open(struct device *dev)
{
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
int i;
- int full_duplex = 0;
/* Soft reset the chip. */
outb(CmdReset, ioaddr + ChipCmd);
-#ifdef SA_SHIRQ
- if (request_irq(dev->irq, &rtl8129_interrupt, SA_SHIRQ,
- "RealTek RTL8129/39 Fast Ethernet", dev)) {
- return -EAGAIN;
- }
-#else
- if (irq2dev_map[dev->irq] != NULL
- || (irq2dev_map[dev->irq] = dev) == NULL
- || dev->irq == 0
- || request_irq(dev->irq, &rtl8129_interrupt, 0, "RTL8129")) {
+ if (request_irq(dev->irq, &rtl8129_interrupt, SA_SHIRQ, dev->name, dev)) {
return -EAGAIN;
}
-#endif
MOD_INC_USE_COUNT;
@@ -660,20 +687,10 @@ rtl8129_open(struct device *dev)
}
rtl8129_init_ring(dev);
-#ifndef final_version
- /* Used to monitor rx ring overflow. */
- memset(tp->rx_ring + RX_BUF_LEN, 0xcc, 16);
-#endif
-
/* Check that the chip has finished the reset. */
for (i = 1000; i > 0; i--)
if ((inb(ioaddr + ChipCmd) & CmdReset) == 0)
break;
-#ifndef final_version
- if (rtl8129_debug > 2)
- printk(KERN_DEBUG"%s: reset finished with status %2.2x after %d loops.\n",
- dev->name, inb(ioaddr + ChipCmd), 1000-i);
-#endif
for (i = 0; i < 6; i++)
outb(dev->dev_addr[i], ioaddr + MAC0 + i);
@@ -683,29 +700,26 @@ rtl8129_open(struct device *dev)
outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) | (RX_DMA_BURST<<8),
ioaddr + RxConfig);
outl((TX_DMA_BURST<<8)|0x03000000, ioaddr + TxConfig);
+ tp->tx_flag = (TX_FIFO_THRESH<<11) & 0x003f0000;
- full_duplex = tp->full_duplex;
- if (tp->phys[0] >= 0 || tp->chip_id == 0x8139) {
- u16 mii_reg5;
- if (tp->chip_id == 0x8139)
- mii_reg5 = inw(ioaddr + NWayLPAR);
- else
- mii_reg5 = mdio_read(ioaddr, tp->phys[0], 5);
+ tp->full_duplex = tp->duplex_lock;
+ if (tp->phys[0] >= 0 || (rtl_cap_tbl[tp->chip_id] & HAS_MII_XCVR)) {
+ u16 mii_reg5 = mdio_read(dev, tp->phys[0], 5);
if (mii_reg5 == 0xffff)
; /* Not there */
else if ((mii_reg5 & 0x0100) == 0x0100
|| (mii_reg5 & 0x00C0) == 0x0040)
- full_duplex = 1;
+ tp->full_duplex = 1;
if (rtl8129_debug > 1)
printk(KERN_INFO"%s: Setting %s%s-duplex based on"
" auto-negotiated partner ability %4.4x.\n", dev->name,
mii_reg5 == 0 ? "" :
(mii_reg5 & 0x0180) ? "100mbps " : "10mbps ",
- full_duplex ? "full" : "half", mii_reg5);
+ tp->full_duplex ? "full" : "half", mii_reg5);
}
outb(0xC0, ioaddr + Cfg9346);
- outb(full_duplex ? 0x60 : 0x20, ioaddr + Config1);
+ outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
outb(0x00, ioaddr + Cfg9346);
outl(virt_to_bus(tp->rx_ring), ioaddr + RxBuf);
@@ -715,13 +729,6 @@ rtl8129_open(struct device *dev)
set_rx_mode(dev);
outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
-#ifndef final_version
- if (rtl8129_debug > 1)
- printk(KERN_DEBUG"%s: In rtl8129_open() Tx/Rx Config %8.8x/%8.8x"
- " Chip Config %2.2x/%2.2x.\n",
- dev->name, inl(ioaddr + TxConfig), inl(ioaddr + RxConfig),
- inb(ioaddr + Config0), inb(ioaddr + Config1));
-#endif
dev->tbusy = 0;
dev->interrupt = 0;
@@ -732,10 +739,10 @@ rtl8129_open(struct device *dev)
| TxErr | TxOK | RxErr | RxOK, ioaddr + IntrMask);
if (rtl8129_debug > 1)
- printk(KERN_DEBUG"%s: rtl8129_open() ioaddr %4.4x IRQ %d"
+ printk(KERN_DEBUG"%s: rtl8129_open() ioaddr %#lx IRQ %d"
" GP Pins %2.2x %s-duplex.\n",
dev->name, ioaddr, dev->irq, inb(ioaddr + GPPinData),
- full_duplex ? "full" : "half");
+ tp->full_duplex ? "full" : "half");
/* Set the timer to switch to check for link beat and perhaps switch
to an alternate media type. */
@@ -752,26 +759,26 @@ static void rtl8129_timer(unsigned long data)
{
struct device *dev = (struct device *)data;
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
int next_tick = 0;
-
- if (tp->chip_id == 0x8139) {
- u16 mii_reg5 = inw(ioaddr + NWayLPAR);
- if ((mii_reg5 & 0x0100) == 0x0100
- || (mii_reg5 & 0x00C0) == 0x0040)
- if ( ! tp->full_duplex) {
- tp->full_duplex = 1;
- if (rtl8129_debug > 0)
- printk(KERN_INFO "%s: Switching to full-duplex based on "
- "link partner ability of %4.4x.\n",
- dev->name, mii_reg5);
- outb(0xC0, ioaddr + Cfg9346);
- outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
- outb(0x00, ioaddr + Cfg9346);
- }
+ int mii_reg5 = mdio_read(dev, tp->phys[0], 5);
+
+ if (! tp->duplex_lock && mii_reg5 != 0xffff) {
+ int duplex = (mii_reg5&0x0100) || (mii_reg5 & 0x01C0) == 0x0040;
+ if (tp->full_duplex != duplex) {
+ tp->full_duplex = duplex;
+ printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link"
+ " partner ability of %4.4x.\n", dev->name,
+ tp->full_duplex ? "full" : "half", tp->phys[0], mii_reg5);
+ outb(0xC0, ioaddr + Cfg9346);
+ outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
+ outb(0x00, ioaddr + Cfg9346);
+ }
+ next_tick = 60*HZ;
}
+
if (rtl8129_debug > 2) {
- if (tp->chip_id == 0x8129)
+ if (rtl_cap_tbl[tp->chip_id] & HAS_MII_XCVR)
printk(KERN_DEBUG"%s: Media selection tick, GP pins %2.2x.\n",
dev->name, inb(ioaddr + GPPinData));
else
@@ -794,33 +801,80 @@ static void rtl8129_timer(unsigned long data)
static void rtl8129_tx_timeout(struct device *dev)
{
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
+ long ioaddr = dev->base_addr;
+ int mii_reg, i;
if (rtl8129_debug > 0)
- printk(KERN_WARNING "%s: Transmit timeout, status %2.2x %4.4x.\n",
- dev->name, inb(ioaddr + ChipCmd), inw(ioaddr + IntrStatus));
+ printk(KERN_WARNING "%s: Transmit timeout, status %2.2x %4.4x "
+ "media %2.2x.\n",
+ dev->name, inb(ioaddr + ChipCmd), inw(ioaddr + IntrStatus),
+ inb(ioaddr + GPPinData));
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ outw(0x0000, ioaddr + IntrMask);
+ /* Emit info to figure out what went wrong. */
+ printk("%s: Tx queue start entry %d dirty entry %d.\n",
+ dev->name, tp->cur_tx, tp->dirty_tx);
for (i = 0; i < NUM_TX_DESC; i++)
printk(KERN_DEBUG"%s: Tx descriptor %d is %8.8x.%s\n",
- dev->name, i, inl(ioaddr + TxStat0 + i*4),
+ dev->name, i, inl(ioaddr + TxStatus0 + i*4),
i == tp->dirty_tx % NUM_TX_DESC ? " (queue head)" : "");
- if (tp->chip_id == 0x8129) {
- int mii_reg;
- printk(KERN_DEBUG"%s: MII #%d registers are:", dev->name, tp->phys[0]);
- for (mii_reg = 0; mii_reg < 8; mii_reg++)
- printk(" %4.4x", mdio_read(ioaddr, tp->phys[0], mii_reg));
- printk(".\n");
- } else {
- printk(KERN_DEBUG"%s: MII status register is %4.4x.\n",
- dev->name, inw(ioaddr + BMSR));
- }
- /* Restart the chip Tx process. */
+ printk(KERN_DEBUG"%s: MII #%d registers are:", dev->name, tp->phys[0]);
+ for (mii_reg = 0; mii_reg < 8; mii_reg++)
+ printk(" %4.4x", mdio_read(dev, tp->phys[0], mii_reg));
+ printk(".\n");
+
+ /* Soft reset the chip. */
+ outb(CmdReset, ioaddr + ChipCmd);
+ /* Check that the chip has finished the reset. */
+ for (i = 1000; i > 0; i--)
+ if ((inb(ioaddr + ChipCmd) & CmdReset) == 0)
+ break;
+ for (i = 0; i < 6; i++)
+ outb(dev->dev_addr[i], ioaddr + MAC0 + i);
+
+ outb(0x00, ioaddr + Cfg9346);
+ tp->cur_rx = 0;
+ /* Must enable Tx/Rx before setting transfer thresholds! */
outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
- /* Continue from any transmit abort. */
- outl((TX_DMA_BURST<<8) || 0x03000001, ioaddr + TxConfig);
+ outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) | (RX_DMA_BURST<<8),
+ ioaddr + RxConfig);
+ outl((TX_DMA_BURST<<8), ioaddr + TxConfig);
+ set_rx_mode(dev);
+ { /* Save the unsent Tx packets. */
+ struct sk_buff *saved_skb[NUM_TX_DESC], *skb;
+ int j;
+ for (j = 0; tp->cur_tx - tp->dirty_tx > 0 ; j++, tp->dirty_tx++)
+ saved_skb[j] = tp->tx_skbuff[tp->dirty_tx % NUM_TX_DESC];
+ tp->dirty_tx = tp->cur_tx = 0;
+
+ for (i = 0; i < j; i++) {
+ skb = tp->tx_skbuff[i] = saved_skb[i];
+ if ((long)skb->data & 3) { /* Must use alignment buffer. */
+ memcpy(tp->tx_buf[i], skb->data, skb->len);
+ outl(virt_to_bus(tp->tx_buf[i]), ioaddr + TxAddr0 + i*4);
+ } else
+ outl(virt_to_bus(skb->data), ioaddr + TxAddr0 + i*4);
+ /* Note: the chip doesn't have auto-pad! */
+ outl(tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN),
+ ioaddr + TxStatus0 + i*4);
+ }
+ tp->cur_tx = i;
+ while (i < NUM_TX_DESC)
+ tp->tx_skbuff[i] = 0;
+ if (tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */
+ dev->tbusy = 0;
+ tp->tx_full = 0;
+ } else {
+ tp->tx_full = 1;
+ }
+ }
dev->trans_start = jiffies;
tp->stats.tx_errors++;
+ /* Enable all known interrupts by setting the interrupt mask. */
+ outw(PCIErr | PCSTimeout | RxUnderrun | RxOverflow | RxFIFOOver
+ | TxErr | TxOK | RxErr | RxOK, ioaddr + IntrMask);
return;
}
@@ -833,8 +887,8 @@ rtl8129_init_ring(struct device *dev)
int i;
tp->tx_full = 0;
- tp->cur_rx = tp->cur_tx = 0;
- tp->dirty_rx = tp->dirty_tx = 0;
+ tp->cur_rx = 0;
+ tp->dirty_tx = tp->cur_tx = 0;
for (i = 0; i < NUM_TX_DESC; i++) {
tp->tx_skbuff[i] = 0;
@@ -846,20 +900,9 @@ static int
rtl8129_start_xmit(struct sk_buff *skb, struct device *dev)
{
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
int entry;
-#ifndef final_version
- if (skb == NULL || skb->len <= 0) {
- printk(KERN_ERR"%s: Obsolete driver Tx request made: skbuff==NULL.\n",
- dev->name);
-#if 0
- dev_tint(dev);
-#endif
- return 0;
- }
-#endif
-
/* Block a timer-based transmit from overlapping. This could better be
done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
@@ -879,12 +922,11 @@ rtl8129_start_xmit(struct sk_buff *skb, struct device *dev)
} else
outl(virt_to_bus(skb->data), ioaddr + TxAddr0 + entry*4);
/* Note: the chip doesn't have auto-pad! */
- outl(((TX_FIFO_THRESH<<11) & 0x003f0000) |
- (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN),
- ioaddr + TxStat0 + entry*4);
+ outl(tp->tx_flag | (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN),
+ ioaddr + TxStatus0 + entry*4);
if (++tp->cur_tx - tp->dirty_tx < NUM_TX_DESC) {/* Typical path */
- dev->tbusy = 0;
+ clear_bit(0, (void*)&dev->tbusy);
} else {
tp->tx_full = 1;
}
@@ -892,36 +934,36 @@ rtl8129_start_xmit(struct sk_buff *skb, struct device *dev)
dev->trans_start = jiffies;
if (rtl8129_debug > 4)
printk(KERN_DEBUG"%s: Queued Tx packet at %p size %d to slot %d.\n",
- dev->name, skb->data, skb->len, entry);
+ dev->name, skb->data, (int)skb->len, entry);
return 0;
}
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
-static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs)
+static void rtl8129_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
-#ifdef SA_SHIRQ
struct device *dev = (struct device *)dev_instance;
-#else
- struct device *dev = (struct device *)(irq2dev_map[irq]);
-#endif
- struct rtl8129_private *tp;
- int ioaddr, boguscnt = max_interrupt_work;
+ struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+ int boguscnt = max_interrupt_work;
int status;
+ long ioaddr = dev->base_addr;
- if (dev == NULL) {
- printk (KERN_ERR"rtl8139_interrupt(): IRQ %d for unknown device.\n",
- irq);
+#if defined(__i386__)
+ /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
+ if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+ printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
+ dev->name);
+ dev->interrupt = 0; /* Avoid halting machine. */
return;
}
-
- ioaddr = dev->base_addr;
- tp = (struct rtl8129_private *)dev->priv;
- if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+#else
+ if (dev->interrupt) {
printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
return;
}
+ dev->interrupt = 1;
+#endif
do {
status = inw(ioaddr + IntrStatus);
@@ -944,9 +986,9 @@ static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *r
for (dirty_tx = tp->dirty_tx; dirty_tx < tp->cur_tx; dirty_tx++) {
int entry = dirty_tx % NUM_TX_DESC;
- int txstatus = inl(ioaddr + TxStat0 + entry*4);
+ int txstatus = inl(ioaddr + TxStatus0 + entry*4);
- if ( ! (txstatus & TxHostOwns))
+ if ( ! (txstatus & (TxStatOK | TxUnderrun | TxAborted)))
break; /* It still hasn't been Txed */
/* Note: TxCarrierLost is always asserted at 100mbps. */
@@ -973,15 +1015,20 @@ static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *r
/* No count for tp->stats.tx_deferred */
#endif
if (txstatus & TxUnderrun) {
- /* Todo: increase the Tx FIFO threshold. */
+ /* Add 64 to the Tx FIFO threshold. */
+ if (tp->tx_flag < 0x00300000)
+ tp->tx_flag += 0x00020000;
tp->stats.tx_fifo_errors++;
}
tp->stats.collisions += (txstatus >> 24) & 15;
+#if LINUX_VERSION_CODE > 0x20119
+ tp->stats.tx_bytes += txstatus & 0x7ff;
+#endif
tp->stats.tx_packets++;
}
/* Free the original skb. */
- dev_kfree_skb(tp->tx_skbuff[entry]);
+ dev_free_skb(tp->tx_skbuff[entry]);
tp->tx_skbuff[entry] = 0;
}
@@ -993,8 +1040,7 @@ static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *r
}
#endif
- if (tp->tx_full && dev->tbusy
- && dirty_tx > tp->cur_tx - NUM_TX_DESC) {
+ if (tp->tx_full && dirty_tx > tp->cur_tx - NUM_TX_DESC) {
/* The ring is no longer full, clear tbusy. */
tp->tx_full = 0;
dev->tbusy = 0;
@@ -1007,17 +1053,29 @@ static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *r
/* Check uncommon events with one test. */
if (status & (PCIErr|PCSTimeout |RxUnderrun|RxOverflow|RxFIFOOver
|TxErr|RxErr)) {
+ if (rtl8129_debug > 2)
+ printk(KERN_NOTICE"%s: Abnormal interrupt, status %8.8x.\n",
+ dev->name, status);
-#ifndef final_version
- if (rtl8129_debug > 0)
- printk(KERN_DEBUG"%s: Unusual error, status %4.4x.\n",
- dev->name, status);
-#endif
-
+ if (status == 0xffffffff)
+ break;
/* Update the error count. */
tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
outl(0, ioaddr + RxMissed);
+ if ((status & RxUnderrun) &&
+ (rtl_cap_tbl[tp->chip_id] & HAS_LNK_CHNG)) {
+ /* Really link-change on new chips. */
+ int lpar = inw(ioaddr + NWayLPAR);
+ int duplex = (lpar&0x0100)||(lpar & 0x01C0) == 0x0040;
+ if (tp->full_duplex != duplex) {
+ tp->full_duplex = duplex;
+ outb(0xC0, ioaddr + Cfg9346);
+ outb(tp->full_duplex ? 0x60 : 0x20, ioaddr + Config1);
+ outb(0x00, ioaddr + Cfg9346);
+ }
+ status &= ~RxUnderrun;
+ }
if (status & (RxUnderrun | RxOverflow | RxErr | RxFIFOOver))
tp->stats.rx_errors++;
@@ -1028,7 +1086,14 @@ static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *r
tp->cur_rx = inw(ioaddr + RxBufAddr) % RX_BUF_LEN;
outw(tp->cur_rx - 16, ioaddr + RxBufPtr);
}
- /* Error sources cleared above. */
+ if (status & PCIErr) {
+ u32 pci_cmd_status;
+ pcibios_read_config_dword(tp->pci_bus, tp->pci_devfn,
+ PCI_COMMAND, &pci_cmd_status);
+
+ printk(KERN_ERR "%s: PCI Bus error %4.4x.\n",
+ dev->name, pci_cmd_status);
+ }
}
if (--boguscnt < 0) {
printk(KERN_WARNING"%s: Too much work at interrupt, "
@@ -1044,29 +1109,20 @@ static void rtl8129_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *r
printk(KERN_DEBUG"%s: exiting interrupt, intr_status=%#4.4x.\n",
dev->name, inl(ioaddr + IntrStatus));
-#ifndef final_version
- /* Code that should never be run! Perhaps remove after testing.. */
- {
- static int stopit = 10;
- if (dev->start == 0 && --stopit < 0) {
- printk(KERN_ERR"%s: Emergency stop, looping startup interrupt.\n",
- dev->name);
- FREE_IRQ(irq, dev);
- }
- }
-#endif
-
+#if defined(__i386__)
+ clear_bit(0, (void*)&dev->interrupt);
+#else
dev->interrupt = 0;
+#endif
return;
}
-/* Todo: The data sheet doesn't describe the Rx ring at all, so I'm winging
- it here until I have a chip to play with. 8/30/97 */
-static int
-rtl8129_rx(struct device *dev)
+/* The data sheet doesn't describe the Rx ring at all, so I'm guessing at the
+ field alignments and semantics. */
+static int rtl8129_rx(struct device *dev)
{
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
unsigned char *rx_ring = tp->rx_ring;
u16 cur_rx = tp->cur_rx;
@@ -1077,9 +1133,9 @@ rtl8129_rx(struct device *dev)
inw(ioaddr + RxBufPtr), inb(ioaddr + ChipCmd));
while ((inb(ioaddr + ChipCmd) & 1) == 0) {
- u16 ring_offset = cur_rx % RX_BUF_LEN;
+ int ring_offset = cur_rx % RX_BUF_LEN;
u32 rx_status = *(u32*)(rx_ring + ring_offset);
- u16 rx_size = rx_status >> 16;
+ int rx_size = rx_status >> 16;
if (rtl8129_debug > 4) {
int i;
@@ -1105,12 +1161,18 @@ rtl8129_rx(struct device *dev)
tp->stats.rx_frame_errors++;
if (rx_status & (RxRunt|RxTooLong)) tp->stats.rx_length_errors++;
if (rx_status & RxCRCErr) tp->stats.rx_crc_errors++;
+ /* Reset the receiver, based on RealTek recommendation. (Bug?) */
+ tp->cur_rx = 0;
+ outb(CmdTxEnb, ioaddr + ChipCmd);
+ outb(CmdRxEnb | CmdTxEnb, ioaddr + ChipCmd);
+ outl((RX_FIFO_THRESH << 13) | (RX_BUF_LEN_IDX << 11) |
+ (RX_DMA_BURST<<8), ioaddr + RxConfig);
} else {
/* Malloc up new buffer, compatible with net-2e. */
/* Omit the four octet CRC from the length. */
struct sk_buff *skb;
- skb = DEV_ALLOC_SKB(rx_size + 2);
+ skb = dev_alloc_skb(rx_size + 2);
if (skb == NULL) {
printk(KERN_WARNING"%s: Memory squeeze, deferring packet.\n",
dev->name);
@@ -1129,26 +1191,32 @@ rtl8129_rx(struct device *dev)
rx_size-semi_count);
if (rtl8129_debug > 4) {
int i;
- printk(KERN_DEBUG"%s: Frame wrap @%d", dev->name, semi_count);
+ printk(KERN_DEBUG"%s: Frame wrap @%d",
+ dev->name, semi_count);
for (i = 0; i < 16; i++)
printk(" %2.2x", rx_ring[i]);
printk(".\n");
memset(rx_ring, 0xcc, 16);
}
- } else
+ } else {
+#if 1 /* USE_IP_COPYSUM */
+ eth_copy_and_sum(skb, &rx_ring[ring_offset + 4],
+ rx_size, 0);
+ skb_put(skb, rx_size);
+#else
memcpy(skb_put(skb, rx_size), &rx_ring[ring_offset + 4],
rx_size);
-#if LINUX_VERSION_CODE >= 0x10300
- skb->protocol = eth_type_trans(skb, dev);
-#else
- skb->len = rx_size;
#endif
+ }
+ skb->protocol = eth_type_trans(skb, dev);
netif_rx(skb);
+#if LINUX_VERSION_CODE > 0x20119
+ tp->stats.rx_bytes += rx_size;
+#endif
tp->stats.rx_packets++;
}
- cur_rx += rx_size + 4;
- cur_rx = (cur_rx + 3) & ~3;
+ cur_rx = (cur_rx + rx_size + 4 + 3) & ~3;
outw(cur_rx - 16, ioaddr + RxBufPtr);
}
if (rtl8129_debug > 4)
@@ -1163,7 +1231,7 @@ rtl8129_rx(struct device *dev)
static int
rtl8129_close(struct device *dev)
{
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
int i;
@@ -1186,29 +1254,11 @@ rtl8129_close(struct device *dev)
del_timer(&tp->timer);
-#ifdef SA_SHIRQ
free_irq(dev->irq, dev);
-#else
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-#endif
-
-#ifndef final_version
- /* Used to monitor rx ring overflow. */
- for (i = 0; i < 16; i++)
- if (tp->rx_ring[RX_BUF_LEN+i] != 0xcc) {
- printk(KERN_WARNING"%s: Rx ring overflowed! Values are ",
- dev->name);
- for (i = 0; i < 16; i++)
- printk(" %2.2x", tp->rx_ring[RX_BUF_LEN + i]);
- printk(".\n");
- break;
- }
-#endif
for (i = 0; i < NUM_TX_DESC; i++) {
if (tp->tx_skbuff[i])
- dev_kfree_skb(tp->tx_skbuff[i]);
+ dev_free_skb(tp->tx_skbuff[i]);
tp->tx_skbuff[i] = 0;
}
kfree(tp->rx_ring);
@@ -1224,11 +1274,33 @@ rtl8129_close(struct device *dev)
return 0;
}
+static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+ struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
+ u16 *data = (u16 *)&rq->ifr_data;
+
+ switch(cmd) {
+ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
+ data[0] = tp->phys[0] & 0x3f;
+ /* Fall Through */
+ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
+ data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
+ return 0;
+ case SIOCDEVPRIVATE+2: /* Write the specified MII register */
+ if (!suser())
+ return -EPERM;
+ mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
static struct enet_statistics *
rtl8129_get_stats(struct device *dev)
{
struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
if (dev->start) {
tp->stats.rx_missed_errors += inl(ioaddr + RxMissed);
@@ -1239,94 +1311,69 @@ rtl8129_get_stats(struct device *dev)
}
/* Set or clear the multicast filter for this adaptor.
- Note that we only use exclusion around actually queueing the
- new frame, not around filling tp->setup_frame. This is non-deterministic
- when re-entered but still correct. */
-
-/* The little-endian AUTODIN II ethernet CRC calculation.
- N.B. Do not use for bulk data, use a table-based routine instead.
- This is common code and should be moved to net/core/crc.c */
-static unsigned const ethernet_polynomial_le = 0xedb88320U;
-static inline unsigned ether_crc_le(int length, unsigned char *data)
+ This routine is not state sensitive and need not be SMP locked. */
+
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
{
- unsigned int crc = 0xffffffff; /* Initial value. */
- while(--length >= 0) {
+ int crc = -1;
+
+ while(--length >= 0) {
unsigned char current_octet = *data++;
int bit;
- for (bit = 8; --bit >= 0; current_octet >>= 1) {
- if ((crc ^ current_octet) & 1) {
- crc >>= 1;
- crc ^= ethernet_polynomial_le;
- } else
- crc >>= 1;
- }
- }
- return crc;
+ for (bit = 0; bit < 8; bit++, current_octet >>= 1)
+ crc = (crc << 1) ^
+ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+ }
+ return crc;
}
+/* Bits in RxConfig. */
+enum rx_mode_bits {
+ AcceptErr=0x20, AcceptRunt=0x10, AcceptBroadcast=0x08,
+ AcceptMulticast=0x04, AcceptMyPhys=0x02, AcceptAllPhys=0x01,
+};
-static void
-#ifdef NEW_MULTICAST
-set_rx_mode(struct device *dev)
-#else
-static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
-#endif
+static void set_rx_mode(struct device *dev)
{
- int ioaddr = dev->base_addr;
- struct rtl8129_private *tp = (struct rtl8129_private *)dev->priv;
- unsigned char mc_filter[8]; /* Multicast hash filter */
- int i;
+ long ioaddr = dev->base_addr;
+ u32 mc_filter[2]; /* Multicast hash filter */
+ int i, rx_mode;
- if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+ if (rtl8129_debug > 3)
+ printk(KERN_DEBUG"%s: set_rx_mode(%4.4x) done -- Rx config %8.8x.\n",
+ dev->name, dev->flags, inl(ioaddr + RxConfig));
+
+ /* Note: do not reorder, GCC is clever about common statements. */
+ if (dev->flags & IFF_PROMISC) {
/* Unconditionally log net taps. */
printk(KERN_NOTICE"%s: Promiscuous mode enabled.\n", dev->name);
- memset(mc_filter, 0xff, sizeof(mc_filter));
- outb(0x0F, ioaddr + RxConfig);
- } else if ((dev->mc_count > 1000) || (dev->flags & IFF_ALLMULTI)) {
+ rx_mode = AcceptBroadcast|AcceptMulticast|AcceptMyPhys|AcceptAllPhys;
+ mc_filter[1] = mc_filter[0] = 0xffffffff;
+ } else if ((dev->mc_count > multicast_filter_limit)
+ || (dev->flags & IFF_ALLMULTI)) {
/* Too many to filter perfectly -- accept all multicasts. */
- memset(mc_filter, 0xff, sizeof(mc_filter));
- outb(0x0E, ioaddr + RxConfig);
- } else if (dev->mc_count == 0) {
- outb(0x0A, ioaddr + RxConfig);
- return;
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ mc_filter[1] = mc_filter[0] = 0xffffffff;
} else {
struct dev_mc_list *mclist;
-
- memset(mc_filter, 0, sizeof(mc_filter));
+ rx_mode = AcceptBroadcast | AcceptMulticast | AcceptMyPhys;
+ mc_filter[1] = mc_filter[0] = 0;
for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
i++, mclist = mclist->next)
- set_bit(ether_crc_le(ETH_ALEN, mclist->dmi_addr) & 0x3f,
- mc_filter);
- }
- /* ToDo: perhaps we need to stop the Tx and Rx process here? */
- if (memcmp(mc_filter, tp->mc_filter, sizeof(mc_filter))) {
- for (i = 0; i < 2; i++)
- outl(((u32 *)mc_filter)[i], ioaddr + MAR0 + i*4);
- memcpy(tp->mc_filter, mc_filter, sizeof(mc_filter));
+ set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26, mc_filter);
}
- if (rtl8129_debug > 3)
- printk(KERN_DEBUG"%s: set_rx_mode(%4.4x) done -- Rx config %8.8x.\n",
- dev->name, dev->flags, inl(ioaddr + RxConfig));
+ /* We can safely update without stopping the chip. */
+ outb(rx_mode, ioaddr + RxConfig);
+ outl(mc_filter[0], ioaddr + MAR0 + 0);
+ outl(mc_filter[1], ioaddr + MAR0 + 4);
return;
}
#ifdef MODULE
-
-/* An additional parameter that may be passed in... */
-static int debug = -1;
-
-int
-init_module(void)
+int init_module(void)
{
- int cards_found;
-
- if (debug >= 0)
- rtl8129_debug = debug;
-
- root_rtl8129_dev = NULL;
- cards_found = rtl8139_probe(0);
-
- return cards_found ? 0 : -ENODEV;
+ return rtl8139_probe(0);
}
void
@@ -1336,9 +1383,13 @@ cleanup_module(void)
/* No need to check MOD_IN_USE, as sys_delete_module() checks. */
while (root_rtl8129_dev) {
- next_dev = ((struct rtl8129_private *)root_rtl8129_dev->priv)->next_module;
+ struct rtl8129_private *tp =
+ (struct rtl8129_private *)root_rtl8129_dev->priv;
+ next_dev = tp->next_module;
unregister_netdev(root_rtl8129_dev);
- release_region(root_rtl8129_dev->base_addr, RTL8129_TOTAL_SIZE);
+ release_region(root_rtl8129_dev->base_addr,
+ pci_tbl[tp->chip_id].io_size);
+ kfree(tp);
kfree(root_rtl8129_dev);
root_rtl8129_dev = next_dev;
}
@@ -1348,7 +1399,8 @@ cleanup_module(void)
/*
* Local variables:
- * compile-command: "gcc -DMODVERSIONS -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c rtl8139.c"
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c rtl8139.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
+ * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -Wall -Wstrict-prototypes -O6 -c rtl8139.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
diff --git a/drivers/net/sdla_fr.c b/drivers/net/sdla_fr.c
index a687135dc..0a886c6db 100644
--- a/drivers/net/sdla_fr.c
+++ b/drivers/net/sdla_fr.c
@@ -650,8 +650,8 @@ static int if_init(struct device *dev)
dev->irq = wandev->irq;
dev->dma = wandev->dma;
dev->base_addr = wandev->ioport;
- dev->mem_start = wandev->maddr;
- dev->mem_end = wandev->maddr + wandev->msize - 1;
+ dev->mem_start = (unsigned long)wandev->maddr;
+ dev->mem_end = dev->mem_start + wandev->msize - 1;
/* Set transmit buffer queue length */
dev->tx_queue_len = 10;
/* Initialize socket buffers */
diff --git a/drivers/net/sdla_ppp.c b/drivers/net/sdla_ppp.c
index 37c1d7889..69038be9a 100644
--- a/drivers/net/sdla_ppp.c
+++ b/drivers/net/sdla_ppp.c
@@ -412,8 +412,8 @@ static int if_init(struct device *dev)
dev->irq = wandev->irq;
dev->dma = wandev->dma;
dev->base_addr = wandev->ioport;
- dev->mem_start = wandev->maddr;
- dev->mem_end = wandev->maddr + wandev->msize - 1;
+ dev->mem_start = (unsigned long)wandev->maddr;
+ dev->mem_end = dev->mem_start + wandev->msize - 1;
/* Set transmit buffer queue length */
dev->tx_queue_len = 100;
/* Initialize socket buffers */
diff --git a/drivers/net/sdla_x25.c b/drivers/net/sdla_x25.c
index 4f9ac70f6..5aa649117 100644
--- a/drivers/net/sdla_x25.c
+++ b/drivers/net/sdla_x25.c
@@ -560,8 +560,8 @@ static int if_init (struct device* dev)
dev->irq = wandev->irq;
dev->dma = wandev->dma;
dev->base_addr = wandev->ioport;
- dev->mem_start = wandev->maddr;
- dev->mem_end = wandev->maddr + wandev->msize - 1;
+ dev->mem_start = (unsigned long)wandev->maddr;
+ dev->mem_end = dev->mem_end + wandev->msize - 1;
/* Set transmit buffer queue length */
dev->tx_queue_len = 10;
@@ -830,7 +830,7 @@ static struct net_device_stats* if_stats (struct device* dev)
{
x25_channel_t* chan = dev->priv;
if(chan==NULL)
- return chan;
+ return NULL;
return &chan->ifstats;
}
diff --git a/drivers/net/sdladrv.c b/drivers/net/sdladrv.c
index 5dbe2b37f..46992d97a 100644
--- a/drivers/net/sdladrv.c
+++ b/drivers/net/sdladrv.c
@@ -421,10 +421,10 @@ int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
return err;
}
}
- else if (!get_option_index(dpmbase_opt, virt_to_phys((void *)hw->dpmbase)))
+ else if (!get_option_index(dpmbase_opt, virt_to_phys(hw->dpmbase)))
{
printk(KERN_ERR "%s: memory address 0x%lX is illegal!\n",
- modname, hw->dpmbase)
+ modname, virt_to_phys(hw->dpmbase))
;
return -EINVAL;
}
@@ -432,16 +432,14 @@ int sdla_setup (sdlahw_t* hw, void* sfm, unsigned len)
{
printk(KERN_ERR
"%s: 8K memory region at 0x%lX is not available!\n",
- modname, hw->dpmbase)
- ;
+ modname, virt_to_phys(hw->dpmbase));
return -EINVAL;
}
printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n",
- modname, virt_to_phys((void *)hw->dpmbase))
- ;
+ modname, virt_to_phys(hw->dpmbase));
+
printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n",
- modname, hw->memory / 1024)
- ;
+ modname, hw->memory / 1024);
/* Load firmware. If loader fails then shut down adapter */
err = sdla_load(hw, sfm, len);
@@ -830,7 +828,7 @@ int sdla_peek (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
/* Relocate window and copy block of data */
err = sdla_mapmem(hw, curvec);
- memcpy((void*)buf, (void*)(hw->dpmbase + curpos), curlen);
+ memcpy(buf, (void *)((u8 *)hw->dpmbase + curpos), curlen);
addr += curlen;
(char*)buf += curlen;
len -= curlen;
@@ -872,7 +870,7 @@ int sdla_poke (sdlahw_t* hw, unsigned long addr, void* buf, unsigned len)
/* Relocate window and copy block of data */
sdla_mapmem(hw, curvec);
- memcpy((void*)(hw->dpmbase + curpos), (void*)buf, curlen);
+ memcpy((void*)((u8 *)hw->dpmbase + curpos), buf, curlen);
addr += curlen;
(char*)buf += curlen;
len -= curlen;
@@ -980,7 +978,7 @@ static int sdla_autodpm (sdlahw_t* hw)
for (i = opt[0]; i && err; --i)
{
- hw->dpmbase = (unsigned long )(phys_to_virt(opt[i]));
+ hw->dpmbase = phys_to_virt(opt[i]);
err = sdla_setdpm(hw);
}
return err;
@@ -1001,7 +999,7 @@ static int sdla_setdpm (sdlahw_t* hw)
/* Shut down card and verify memory region */
sdla_down(hw);
- if (check_memregion((void*)hw->dpmbase, hw->dpmsize))
+ if (check_memregion(hw->dpmbase, hw->dpmsize))
return -EINVAL
;
@@ -1154,7 +1152,7 @@ static unsigned long sdla_memtest (sdlahw_t* hw)
for (memsize = 0, winsize = hw->dpmsize;
!sdla_mapmem(hw, memsize) &&
- (test_memregion((void*)hw->dpmbase, winsize) == winsize)
+ (test_memregion(hw->dpmbase, winsize) == winsize)
;
memsize += winsize)
;
@@ -1176,7 +1174,7 @@ static int sdla_bootcfg (sdlahw_t* hw, sfm_info_t* sfminfo)
if (sdla_mapmem(hw, sfminfo->dataoffs) != 0)
return -EIO
;
- data = (void*)(hw->dpmbase + (sfminfo->dataoffs - hw->vector));
+ data = (void*)((u8 *)hw->dpmbase + (sfminfo->dataoffs - hw->vector));
memset(data, 0, sfminfo->datasize);
data[0x00] = make_config_byte(hw);
@@ -1229,7 +1227,7 @@ static unsigned char make_config_byte (sdlahw_t* hw)
static int sdla_start (sdlahw_t* hw, unsigned addr)
{
unsigned port = hw->port;
- unsigned char* bootp;
+ unsigned char *bootp;
int err, tmp, i;
if (!port) return -EFAULT;
@@ -1237,14 +1235,15 @@ static int sdla_start (sdlahw_t* hw, unsigned addr)
switch (hw->type)
{
case SDLA_S502A:
- bootp = (void*)(hw->dpmbase + 0x66);
+ bootp = hw->dpmbase;
+ bootp += 0x66;
break;
case SDLA_S502E:
case SDLA_S503:
case SDLA_S507:
case SDLA_S508:
- bootp = (void*)hw->dpmbase;
+ bootp = hw->dpmbase;
break;
default:
@@ -1333,7 +1332,7 @@ static int init_s502a (sdlahw_t* hw)
hw->regs[1] = 0xFF;
/* Verify configuration options */
- i = get_option_index(s502a_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+ i = get_option_index(s502a_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
return -EINVAL
;
@@ -1372,7 +1371,7 @@ static int init_s502e (sdlahw_t* hw)
;
/* Verify configuration options */
- i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+ i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
return -EINVAL
;
@@ -1416,7 +1415,7 @@ static int init_s503 (sdlahw_t* hw)
;
/* Verify configuration options */
- i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+ i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
return -EINVAL
;
@@ -1458,7 +1457,7 @@ static int init_s507 (sdlahw_t* hw)
;
/* Verify configuration options */
- i = get_option_index(s507_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+ i = get_option_index(s507_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
return -EINVAL
;
@@ -1515,7 +1514,7 @@ static int init_s508 (sdlahw_t* hw)
;
/* Verify configuration options */
- i = get_option_index(s508_dpmbase_options, virt_to_phys((void *)hw->dpmbase));
+ i = get_option_index(s508_dpmbase_options, virt_to_phys(hw->dpmbase));
if (i == 0)
return -EINVAL
;
diff --git a/drivers/net/sdlamain.c b/drivers/net/sdlamain.c
index bc6288197..00454c5d6 100644
--- a/drivers/net/sdlamain.c
+++ b/drivers/net/sdlamain.c
@@ -269,9 +269,9 @@ static int setup (wan_device_t* wandev, wandev_conf_t* conf)
card->hw.irq = (conf->irq == 9) ? 2 : conf->irq;
/* Compute the virtual address of the card in kernel space */
if(conf->maddr)
- card->hw.dpmbase = (unsigned long)phys_to_virt(conf->maddr);
+ card->hw.dpmbase = phys_to_virt(conf->maddr);
else /* But 0 means NULL */
- card->hw.dpmbase = conf->maddr;
+ card->hw.dpmbase = (void *)conf->maddr;
card->hw.dpmsize = SDLA_WINDOWSIZE;
card->hw.type = conf->hw_opt[0];
@@ -470,8 +470,8 @@ static int ioctl_dump (sdla_t* card, sdla_dump_t* u_dump)
}
/* FIXME::: COPY TO KERNEL BUFFER FIRST ?? */
sti(); /* Not ideal but tough we have to do this */
- if(copy_to_user((void*)(dump.ptr),
- (void*)(card->hw.dpmbase + pos), len))
+ if(copy_to_user((void *)dump.ptr,
+ (u8 *)card->hw.dpmbase + pos, len))
return -EFAULT;
cli();
dump.length -= len;
diff --git a/drivers/net/shaper.c b/drivers/net/shaper.c
index 9879f3de0..ab82b9d2b 100644
--- a/drivers/net/shaper.c
+++ b/drivers/net/shaper.c
@@ -157,7 +157,7 @@ static int shaper_qframe(struct shaper *shaper, struct sk_buff *skb)
skb->shapelatency=0;
skb->shapeclock=shaper->recovery;
- if(skb->shapeclock<jiffies)
+ if(time_before(skb->shapeclock, jiffies))
skb->shapeclock=jiffies;
skb->priority=0; /* short term bug fix */
skb->shapestamp=jiffies;
@@ -320,7 +320,7 @@ static void shaper_kick(struct shaper *shaper)
if(sh_debug)
printk("Clock = %d, jiffies = %ld\n", skb->shapeclock, jiffies);
- if(skb->shapeclock <= jiffies + SHAPER_BURST)
+ if(skb->shapeclock - jiffies <= SHAPER_BURST)
{
/*
* Pull the frame and get interrupts back on.
@@ -385,10 +385,14 @@ static int shaper_open(struct device *dev)
/*
* Can't open until attached.
+ * Also can't open until speed is set, or we'll get
+ * a division by zero.
*/
if(shaper->dev==NULL)
return -ENODEV;
+ if(shaper->bitspersec==0)
+ return -EINVAL;
MOD_INC_USE_COUNT;
return 0;
}
@@ -543,6 +547,7 @@ static int shaper_attach(struct device *shdev, struct shaper *sh, struct device
shdev->type=dev->type;
shdev->addr_len=dev->addr_len;
shdev->mtu=dev->mtu;
+ sh->bitspersec=0;
return 0;
}
@@ -564,7 +569,7 @@ static int shaper_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
case SHAPER_GET_DEV:
if(sh->dev==NULL)
return -ENODEV;
- memcpy(ss->ss_name, sh->dev->name, sizeof(ss->ss_name));
+ strcpy(ss->ss_name, sh->dev->name);
return 0;
case SHAPER_SET_SPEED:
shaper_setspeed(sh,ss->ss_speed);
diff --git a/drivers/net/sktr.c b/drivers/net/sktr.c
index 828807033..f86acd1fb 100644
--- a/drivers/net/sktr.c
+++ b/drivers/net/sktr.c
@@ -298,6 +298,7 @@ __initfunc(static int sktr_pci_chk_card(struct device *dev))
__initfunc(static int sktr_isa_chk_card(struct device *dev, int ioaddr))
{
int i, err;
+ unsigned long flags;
err = sktr_isa_chk_ioaddr(ioaddr);
if(err < 0)
@@ -373,9 +374,11 @@ __initfunc(static int sktr_isa_chk_card(struct device *dev, int ioaddr))
}
}
+ flags=claim_dma_lock();
disable_dma(dev->dma);
set_dma_mode(dev->dma, DMA_MODE_CASCADE);
enable_dma(dev->dma);
+ release_dma_lock(flags);
printk("%s: %s found at %#4x, using IRQ %d and DMA %d.\n",
dev->name, AdapterName, ioaddr, dev->irq, dev->dma);
@@ -1446,7 +1449,12 @@ static int sktr_close(struct device *dev)
sktr_disable_interrupts(dev);
if(dev->dma > 0)
+ {
+ unsigned long flags=claim_dma_lock();
disable_dma(dev->dma);
+ release_dma_lock(flags);
+ }
+
outw(0xFF00, dev->base_addr + SIFCMD);
if(dev->dma > 0)
outb(0xff, dev->base_addr + POSREG);
@@ -1518,12 +1526,11 @@ static void sktr_wait(unsigned long time)
{
long tmp;
- tmp = jiffies + time/(1000000/HZ);
+ tmp = time/(1000000/HZ);
do {
- current->timeout = tmp;
current->state = TASK_INTERRUPTIBLE;
- schedule();
- } while(tmp > jiffies);
+ tmp = schedule_timeout(tmp);
+ } while(tmp);
return;
}
diff --git a/drivers/net/strip.c b/drivers/net/strip.c
index 55e986d63..89b4d7154 100644
--- a/drivers/net/strip.c
+++ b/drivers/net/strip.c
@@ -14,7 +14,7 @@
* for kernel-based devices like TTY. It interfaces between a
* raw TTY, and the kernel's INET protocol layers (via DDI).
*
- * Version: @(#)strip.c 1.2 February 1997
+ * Version: @(#)strip.c 1.3 July 1997
*
* Author: Stuart Cheshire <cheshire@cs.stanford.edu>
*
@@ -60,12 +60,18 @@
*
* v1.2 January 1997 (SC)
* Put portables list back in
+ *
+ * v1.3 July 1997 (SC)
+ * Made STRIP driver set the radio's baud rate automatically.
+ * It is no longer necessarily to manually set the radio's
+ * rate permanently to 115200 -- the driver handles setting
+ * the rate automatically.
*/
#ifdef MODULE
-static const char StripVersion[] = "1.2-STUART.CHESHIRE-MODULAR";
+static const char StripVersion[] = "1.3-STUART.CHESHIRE-MODULAR";
#else
-static const char StripVersion[] = "1.2-STUART.CHESHIRE";
+static const char StripVersion[] = "1.3-STUART.CHESHIRE";
#endif
#define TICKLE_TIMERS 0
@@ -85,6 +91,7 @@ static const char StripVersion[] = "1.2-STUART.CHESHIRE";
#include <asm/system.h>
#include <linux/types.h>
#include <asm/uaccess.h>
+#include <asm/segment.h>
#include <asm/bitops.h>
/*
@@ -112,13 +119,12 @@ static const char StripVersion[] = "1.2-STUART.CHESHIRE";
#include <linux/if_arp.h>
#include <linux/if_strip.h>
#include <linux/proc_fs.h>
+#include <linux/serial.h>
#include <net/arp.h>
-#ifdef CONFIG_INET
#include <linux/ip.h>
#include <linux/tcp.h>
#include <linux/time.h>
-#endif
/************************************************************************/
@@ -286,6 +292,7 @@ struct strip
int working; /* Is radio working correctly? */
int firmware_level; /* Message structuring level */
int next_command; /* Next periodic command */
+ unsigned int user_baud; /* The user-selected baud rate */
int mtu; /* Our mtu (to spot changes!) */
long watchdog_doprobe; /* Next time to test the radio */
long watchdog_doreset; /* Time to do next reset */
@@ -460,7 +467,7 @@ static struct strip *struct_strip_list = NULL;
/* Macros */
/* Returns TRUE if text T begins with prefix P */
-#define has_prefix(T,P) (!strncmp((T), (P), sizeof(P)-1))
+#define has_prefix(T,L,P) (((L) >= sizeof(P)-1) && !strncmp((T), (P), sizeof(P)-1))
/* Returns TRUE if text T of length L is equal to string S */
#define text_equal(T,L,S) (((L) == sizeof(S)-1) && !strncmp((T), (S), sizeof(S)-1))
@@ -499,6 +506,24 @@ extern __inline__ void RestoreInterrupts(InterruptStatus x)
restore_flags(x);
}
+static int arp_query(unsigned char *haddr, u32 paddr, struct device * dev)
+{
+ struct neighbour *neighbor_entry;
+
+ neighbor_entry = neigh_lookup(&arp_tbl, &paddr, dev);
+
+ if (neighbor_entry != NULL)
+ {
+ neighbor_entry->used = jiffies;
+ if (neighbor_entry->nud_state & NUD_VALID)
+ {
+ memcpy(haddr, neighbor_entry->ha, dev->addr_len);
+ return 1;
+ }
+ }
+ return 0;
+}
+
static void DumpData(char *msg, struct strip *strip_info, __u8 *ptr, __u8 *end)
{
static const int MAX_DumpData = 80;
@@ -835,6 +860,41 @@ static __u8 *UnStuffData(__u8 *src, __u8 *end, __u8 *dst, __u32 dst_length)
/* General routines for STRIP */
/*
+ * get_baud returns the current baud rate, as one of the constants defined in
+ * termbits.h
+ * If the user has issued a baud rate override using the 'setserial' command
+ * and the logical current rate is set to 38.4, then the true baud rate
+ * currently in effect (57.6 or 115.2) is returned.
+ */
+static unsigned int get_baud(struct tty_struct *tty)
+ {
+ if (!tty || !tty->termios) return(0);
+ if ((tty->termios->c_cflag & CBAUD) == B38400 && tty->driver_data)
+ {
+ struct async_struct *info = (struct async_struct *)tty->driver_data;
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI ) return(B57600);
+ if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) return(B115200);
+ }
+ return(tty->termios->c_cflag & CBAUD);
+ }
+
+/*
+ * set_baud sets the baud rate to the rate defined by baudcode
+ * Note: The rate B38400 should be avoided, because the user may have
+ * issued a 'setserial' speed override to map that to a different speed.
+ * We could achieve a true rate of 38400 if we needed to by cancelling
+ * any user speed override that is in place, but that might annoy the
+ * user, so it is simplest to just avoid using 38400.
+ */
+static void set_baud(struct tty_struct *tty, unsigned int baudcode)
+ {
+ struct termios old_termios = *(tty->termios);
+ tty->termios->c_cflag &= ~CBAUD; /* Clear the old baud setting */
+ tty->termios->c_cflag |= baudcode; /* Set the new baud setting */
+ tty->driver.set_termios(tty, &old_termios);
+ }
+
+/*
* Convert a string to a Metricom Address.
*/
@@ -972,9 +1032,9 @@ static void strip_changedmtu(struct strip *strip_info)
static void strip_unlock(struct strip *strip_info)
{
/*
- * Set the time to go off in one second.
+ * Set the timer to go off in one second.
*/
- strip_info->idle_timer.expires = jiffies + 1*HZ;
+ strip_info->idle_timer.expires = jiffies + 1*HZ;
add_timer(&strip_info->idle_timer);
if (!test_and_clear_bit(0, (void *)&strip_info->dev.tbusy))
printk(KERN_ERR "%s: trying to unlock already unlocked device!\n",
@@ -1211,6 +1271,8 @@ static int get_status_info(char *buffer, char **start, off_t req_offset, int req
}
static const char proc_strip_status_name[] = "strip";
+
+#ifdef CONFIG_PROC_FS
static struct proc_dir_entry proc_strip_get_status_info =
{
PROC_NET_STRIP_STATUS, /* unsigned short low_ino */
@@ -1225,18 +1287,21 @@ static struct proc_dir_entry proc_strip_get_status_info =
NULL, NULL, NULL, /* struct proc_dir_entry *next, *parent, *subdir; */
NULL /* void *data; */
};
-
+#endif /* CONFIG_PROC_FS */
/************************************************************************/
/* Sending routines */
-#define InitString "ate0q1dt**starmode"
-
static void ResetRadio(struct strip *strip_info)
{
- static const char s[] = "\r" InitString "\r**";
+ struct tty_struct *tty = strip_info->tty;
+ static const char init[] = "ate0q1dt**starmode\r**";
+ StringDescriptor s = { init, sizeof(init)-1 };
- /* If the radio isn't working anymore, we should clear the old status information. */
+ /*
+ * If the radio isn't working anymore,
+ * we should clear the old status information.
+ */
if (strip_info->working)
{
printk(KERN_INFO "%s: No response: Resetting radio.\n", strip_info->dev.name);
@@ -1259,15 +1324,43 @@ static void ResetRadio(struct strip *strip_info)
/* Mark radio address as unknown */
*(MetricomAddress*)&strip_info->true_dev_addr = zero_address;
- if (!strip_info->manual_dev_addr) *(MetricomAddress*)strip_info->dev.dev_addr = zero_address;
+ if (!strip_info->manual_dev_addr)
+ *(MetricomAddress*)strip_info->dev.dev_addr = zero_address;
strip_info->working = FALSE;
strip_info->firmware_level = NoStructure;
strip_info->next_command = CompatibilityCommand;
strip_info->watchdog_doprobe = jiffies + 10 * HZ;
strip_info->watchdog_doreset = jiffies + 1 * HZ;
- strip_info->tty->driver.write(strip_info->tty, 0, (char *)s, sizeof(s)-1);
+
+ /* If the user has selected a baud rate above 38.4 see what magic we have to do */
+ if (strip_info->user_baud > B38400)
+ {
+ /*
+ * Subtle stuff: Pay attention :-)
+ * If the serial port is currently at the user's selected (>38.4) rate,
+ * then we temporarily switch to 19.2 and issue the ATS304 command
+ * to tell the radio to switch to the user's selected rate.
+ * If the serial port is not currently at that rate, that means we just
+ * issued the ATS304 command last time through, so this time we restore
+ * the user's selected rate and issue the normal starmode reset string.
+ */
+ if (strip_info->user_baud == get_baud(tty))
+ {
+ static const char b0[] = "ate0q1s304=57600\r";
+ static const char b1[] = "ate0q1s304=115200\r";
+ static const StringDescriptor baudstring[2] =
+ { { b0, sizeof(b0)-1 }, { b1, sizeof(b1)-1 } };
+ set_baud(tty, B19200);
+ if (strip_info->user_baud == B57600 ) s = baudstring[0];
+ else if (strip_info->user_baud == B115200) s = baudstring[1];
+ else s = baudstring[1]; /* For now */
+ }
+ else set_baud(tty, strip_info->user_baud);
+ }
+
+ tty->driver.write(tty, 0, s.string, s.length);
#ifdef EXT_COUNTERS
- strip_info->tx_ebytes += sizeof(s) - 1;
+ strip_info->tx_ebytes += s.length;
#endif
}
@@ -1357,25 +1450,37 @@ static unsigned char *strip_make_packet(unsigned char *buffer, struct strip *str
}
/*
+ * If we're sending to ourselves, discard the packet.
+ * (Metricom radios choke if they try to send a packet to their own address.)
+ */
+ if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
+ {
+ printk(KERN_ERR "%s: Dropping packet addressed to self\n", strip_info->dev.name);
+ return(NULL);
+ }
+
+ /*
* If this is a broadcast packet, send it to our designated Metricom
* 'broadcast hub' radio (First byte of address being 0xFF means broadcast)
*/
if (haddr.c[0] == 0xFF)
{
- memcpy(haddr.c, strip_info->dev.broadcast, sizeof(haddr));
- if (haddr.c[0] == 0xFF)
- {
- strip_info->tx_dropped++;
- return(NULL);
- }
+ struct in_device *in_dev = strip_info->dev.ip_ptr;
+ /* arp_query returns 1 if it succeeds in looking up the address, 0 if it fails */
+ if (!arp_query(haddr.c, in_dev->ifa_list->ifa_broadcast, &strip_info->dev))
+ {
+ printk(KERN_ERR "%s: Unable to send packet (no broadcast hub configured)\n",
+ strip_info->dev.name);
+ return(NULL);
+ }
+ /*
+ * If we are the broadcast hub, don't bother sending to ourselves.
+ * (Metricom radios choke if they try to send a packet to their own address.)
+ */
+ if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr))) return(NULL);
}
- /*
- * If we're sending to ourselves, discard the packet.
- * (Metricom radios choke if they try to send a packet to their own address.)
- */
- if (!memcmp(haddr.c, strip_info->true_dev_addr.c, sizeof(haddr)))
- return(NULL);
+ *ptr++ = 0x0D;
*ptr++ = '*';
*ptr++ = hextable[haddr.c[2] >> 4];
*ptr++ = hextable[haddr.c[2] & 0xF];
@@ -1402,9 +1507,11 @@ static unsigned char *strip_make_packet(unsigned char *buffer, struct strip *str
static void strip_send(struct strip *strip_info, struct sk_buff *skb)
{
+ MetricomAddress haddr;
unsigned char *ptr = strip_info->tx_buff;
int doreset = (long)jiffies - strip_info->watchdog_doreset >= 0;
int doprobe = (long)jiffies - strip_info->watchdog_doprobe >= 0 && !doreset;
+ struct in_device *in_dev = strip_info->dev.ip_ptr;
/*
* 1. If we have a packet, encapsulate it and put it in the buffer
@@ -1504,9 +1611,8 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
*/
if (strip_info->working && (long)jiffies - strip_info->gratuitous_arp >= 0 &&
memcmp(strip_info->dev.dev_addr, zero_address.c, sizeof(zero_address)) &&
- *strip_info->dev.broadcast!=0xFF)
+ arp_query(haddr.c, in_dev->ifa_list->ifa_broadcast, &strip_info->dev))
{
- struct in_device *in_dev = strip_info->dev.ip_ptr;
/*printk(KERN_INFO "%s: Sending gratuitous ARP with interval %ld\n",
strip_info->dev.name, strip_info->arp_interval / HZ);*/
strip_info->gratuitous_arp = jiffies + strip_info->arp_interval;
@@ -1514,13 +1620,14 @@ static void strip_send(struct strip *strip_info, struct sk_buff *skb)
if (strip_info->arp_interval > MaxARPInterval)
strip_info->arp_interval = MaxARPInterval;
if (in_dev && in_dev->ifa_list)
- arp_send(ARPOP_REPLY, ETH_P_ARP,
- in_dev->ifa_list->ifa_address,/* Target address of ARP packet is our address */
- &strip_info->dev, /* Device to send packet on */
- in_dev->ifa_list->ifa_address,/* Source IP address this ARP packet comes from */
- NULL, /* Destination HW address is NULL (broadcast it) */
- strip_info->dev.dev_addr, /* Source HW address is our HW address */
- strip_info->dev.dev_addr); /* Target HW address is our HW address (redundant) */
+ arp_send(
+ ARPOP_REPLY, ETH_P_ARP,
+ in_dev->ifa_list->ifa_address, /* Target address of ARP packet is our address */
+ &strip_info->dev, /* Device to send packet on */
+ in_dev->ifa_list->ifa_address, /* Source IP address this ARP packet comes from */
+ NULL, /* Destination HW address is NULL (broadcast it) */
+ strip_info->dev.dev_addr, /* Source HW address is our HW address */
+ strip_info->dev.dev_addr); /* Target HW address is our HW address (redundant) */
}
/*
@@ -1632,7 +1739,7 @@ static int strip_header(struct sk_buff *skb, struct device *dev,
static int strip_rebuild_header(struct sk_buff *skb)
{
#ifdef CONFIG_INET
- STRIP_Header *header = (STRIP_Header *)skb->data;
+ STRIP_Header *header = (STRIP_Header *) skb->data;
/* Arp find returns zero if if knows the address, */
/* or if it doesn't know the address it sends an ARP packet and returns non-zero */
@@ -1776,28 +1883,28 @@ static void RecvErr(char *msg, struct strip *strip_info)
strip_info->rx_errors++;
}
-static void RecvErr_Message(struct strip *strip_info, __u8 *sendername, const __u8 *msg)
+static void RecvErr_Message(struct strip *strip_info, __u8 *sendername, const __u8 *msg, u_long len)
{
- if (has_prefix(msg, "001")) /* Not in StarMode! */
+ if (has_prefix(msg, len, "001")) /* Not in StarMode! */
{
RecvErr("Error Msg:", strip_info);
printk(KERN_INFO "%s: Radio %s is not in StarMode\n",
strip_info->dev.name, sendername);
}
- else if (has_prefix(msg, "002")) /* Remap handle */
+ else if (has_prefix(msg, len, "002")) /* Remap handle */
{
/* We ignore "Remap handle" messages for now */
}
- else if (has_prefix(msg, "003")) /* Can't resolve name */
+ else if (has_prefix(msg, len, "003")) /* Can't resolve name */
{
RecvErr("Error Msg:", strip_info);
printk(KERN_INFO "%s: Destination radio name is unknown\n",
strip_info->dev.name);
}
- else if (has_prefix(msg, "004")) /* Name too small or missing */
+ else if (has_prefix(msg, len, "004")) /* Name too small or missing */
{
strip_info->watchdog_doreset = jiffies + LongTime;
#if TICKLE_TIMERS
@@ -1826,45 +1933,50 @@ static void RecvErr_Message(struct strip *strip_info, __u8 *sendername, const __
}
if (strip_info->firmware_level >= StructuredMessages)
{
+ /*
+ * If this message has a valid checksum on the end, then the call to verify_checksum
+ * will elevate the firmware_level to ChecksummedMessages for us. (The actual return
+ * code from verify_checksum is ignored here.)
+ */
verify_checksum(strip_info);
/*
- * If the radio has structured messages but we don't yet have all our information about it, we should do
- * probes without delay, until we have gathered all the information
+ * If the radio has structured messages but we don't yet have all our information about it,
+ * we should do probes without delay, until we have gathered all the information
*/
if (!GOT_ALL_RADIO_INFO(strip_info)) strip_info->watchdog_doprobe = jiffies;
}
}
- else if (has_prefix(msg, "005")) /* Bad count specification */
+ else if (has_prefix(msg, len, "005")) /* Bad count specification */
RecvErr("Error Msg:", strip_info);
- else if (has_prefix(msg, "006")) /* Header too big */
+ else if (has_prefix(msg, len, "006")) /* Header too big */
RecvErr("Error Msg:", strip_info);
- else if (has_prefix(msg, "007")) /* Body too big */
+ else if (has_prefix(msg, len, "007")) /* Body too big */
{
RecvErr("Error Msg:", strip_info);
printk(KERN_ERR "%s: Error! Packet size too big for radio.\n",
strip_info->dev.name);
}
- else if (has_prefix(msg, "008")) /* Bad character in name */
+ else if (has_prefix(msg, len, "008")) /* Bad character in name */
{
RecvErr("Error Msg:", strip_info);
printk(KERN_ERR "%s: Radio name contains illegal character\n",
strip_info->dev.name);
}
- else if (has_prefix(msg, "009")) /* No count or line terminator */
+ else if (has_prefix(msg, len, "009")) /* No count or line terminator */
RecvErr("Error Msg:", strip_info);
- else if (has_prefix(msg, "010")) /* Invalid checksum */
+ else if (has_prefix(msg, len, "010")) /* Invalid checksum */
RecvErr("Error Msg:", strip_info);
- else if (has_prefix(msg, "011")) /* Checksum didn't match */
+ else if (has_prefix(msg, len, "011")) /* Checksum didn't match */
RecvErr("Error Msg:", strip_info);
- else if (has_prefix(msg, "012")) /* Failed to transmit packet */
+ else if (has_prefix(msg, len, "012")) /* Failed to transmit packet */
RecvErr("Error Msg:", strip_info);
else
@@ -1873,9 +1985,11 @@ static void RecvErr_Message(struct strip *strip_info, __u8 *sendername, const __
static void process_AT_response(struct strip *strip_info, __u8 *ptr, __u8 *end)
{
+ u_long len;
__u8 *p = ptr;
while (p < end && p[-1] != 10) p++; /* Skip past first newline character */
/* Now ptr points to the AT command, and p points to the text of the response. */
+ len = p-ptr;
#if TICKLE_TIMERS
{
@@ -1886,13 +2000,13 @@ static void process_AT_response(struct strip *strip_info, __u8 *ptr, __u8 *end)
}
#endif
- if (has_prefix(ptr, "ATS300?" )) get_radio_version(strip_info, p, end);
- else if (has_prefix(ptr, "ATS305?" )) get_radio_address(strip_info, p);
- else if (has_prefix(ptr, "ATS311?" )) get_radio_neighbours(&strip_info->poletops, p, end);
- else if (has_prefix(ptr, "ATS319=7")) verify_checksum(strip_info);
- else if (has_prefix(ptr, "ATS325?" )) get_radio_voltage(strip_info, p, end);
- else if (has_prefix(ptr, "AT~LA" )) get_radio_neighbours(&strip_info->portables, p, end);
- else RecvErr("Unknown AT Response:", strip_info);
+ if (has_prefix(ptr, len, "ATS300?" )) get_radio_version(strip_info, p, end);
+ else if (has_prefix(ptr, len, "ATS305?" )) get_radio_address(strip_info, p);
+ else if (has_prefix(ptr, len, "ATS311?" )) get_radio_neighbours(&strip_info->poletops, p, end);
+ else if (has_prefix(ptr, len, "ATS319=7")) verify_checksum(strip_info);
+ else if (has_prefix(ptr, len, "ATS325?" )) get_radio_voltage(strip_info, p, end);
+ else if (has_prefix(ptr, len, "AT~LA" )) get_radio_neighbours(&strip_info->portables, p, end);
+ else RecvErr("Unknown AT Response:", strip_info);
}
static void process_ACK(struct strip *strip_info, __u8 *ptr, __u8 *end)
@@ -2073,11 +2187,11 @@ static void process_text_message(struct strip *strip_info)
if (text_equal(msg, len, "OK" )) return; /* Ignore 'OK' responses from prior commands */
if (text_equal(msg, len, "ERROR" )) return; /* Ignore 'ERROR' messages */
- if (text_equal(msg, len, InitString)) return; /* Ignore character echo back from the radio */
+ if (has_prefix(msg, len, "ate0q1" )) return; /* Ignore character echo back from the radio */
/* Catch other error messages */
/* (This is here for backwards compatibility with old firmware) */
- if (has_prefix(msg, "ERR_")) { RecvErr_Message(strip_info, NULL, &msg[4]); return; }
+ if (has_prefix(msg, len, "ERR_")) { RecvErr_Message(strip_info, NULL, &msg[4], len-4); return; }
RecvErr("No initial *", strip_info);
}
@@ -2182,7 +2296,7 @@ static void process_message(struct strip *strip_info)
process_Info(strip_info, ptr, end);
} else if (key.l == ERR_Key.l) {
strip_info->rx_ebytes += (end - ptr);
- RecvErr_Message(strip_info, sendername, ptr);
+ RecvErr_Message(strip_info, sendername, ptr, end-ptr);
} else RecvErr("Unrecognized protocol key", strip_info);
#else
if (key.l == SIP0Key.l) process_IP_packet (strip_info, &header, ptr, end);
@@ -2190,7 +2304,7 @@ static void process_message(struct strip *strip_info)
else if (key.l == ATR_Key.l) process_AT_response(strip_info, ptr, end);
else if (key.l == ACK_Key.l) process_ACK (strip_info, ptr, end);
else if (key.l == INF_Key.l) process_Info (strip_info, ptr, end);
- else if (key.l == ERR_Key.l) RecvErr_Message (strip_info, sendername, ptr);
+ else if (key.l == ERR_Key.l) RecvErr_Message (strip_info, sendername, ptr, end-ptr);
else RecvErr("Unrecognized protocol key", strip_info);
#endif
}
@@ -2306,12 +2420,12 @@ static int dev_set_mac_address(struct device *dev, void *addr)
return 0;
}
-static struct net_device_stats *strip_get_stats(struct device *dev)
+static struct enet_statistics *strip_get_stats(struct device *dev)
{
- static struct net_device_stats stats;
+ static struct enet_statistics stats;
struct strip *strip_info = (struct strip *)(dev->priv);
- memset(&stats, 0, sizeof(struct net_device_stats));
+ memset(&stats, 0, sizeof(struct enet_statistics));
stats.rx_packets = strip_info->rx_packets;
stats.tx_packets = strip_info->tx_packets;
@@ -2354,6 +2468,7 @@ static struct net_device_stats *strip_get_stats(struct device *dev)
static int strip_open_low(struct device *dev)
{
struct strip *strip_info = (struct strip *)(dev->priv);
+ struct in_device *in_dev = dev->ip_ptr;
if (strip_info->tty == NULL)
return(-ENODEV);
@@ -2361,19 +2476,27 @@ static int strip_open_low(struct device *dev)
if (!allocate_buffers(strip_info))
return(-ENOMEM);
+ strip_info->sx_count = 0;
+ strip_info->tx_left = 0;
+
strip_info->discard = 0;
strip_info->working = FALSE;
strip_info->firmware_level = NoStructure;
strip_info->next_command = CompatibilityCommand;
- strip_info->sx_count = 0;
- strip_info->tx_left = 0;
+ strip_info->user_baud = get_baud(strip_info->tty);
+ /*
+ * Needed because address '0' is special
+ */
+
+ if (in_dev->ifa_list->ifa_address == 0)
+ in_dev->ifa_list->ifa_address = ntohl(0xC0A80001);
dev->tbusy = 0;
dev->start = 1;
printk(KERN_INFO "%s: Initializing Radio.\n", strip_info->dev.name);
ResetRadio(strip_info);
- strip_info->idle_timer.expires = jiffies + 2 * HZ;
+ strip_info->idle_timer.expires = jiffies + 1*HZ;
add_timer(&strip_info->idle_timer);
return(0);
}
@@ -2443,12 +2566,6 @@ static int strip_dev_init(struct device *dev)
dev->addr_len = sizeof(MetricomAddress);
/*
- * Pointer to the interface buffers.
- */
-
- dev_init_buffers(dev);
-
- /*
* Pointers to interface service routines.
*/
@@ -2629,6 +2746,7 @@ static void strip_close(struct tty_struct *tty)
if (!strip_info || strip_info->magic != STRIP_MAGIC)
return;
+ dev_close(&strip_info->dev);
unregister_netdev(&strip_info->dev);
tty->disc_data = 0;
@@ -2649,7 +2767,6 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
unsigned int cmd, unsigned long arg)
{
struct strip *strip_info = (struct strip *) tty->disc_data;
- int err;
/*
* First make sure we're connected.
@@ -2661,21 +2778,18 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
switch(cmd)
{
case SIOCGIFNAME:
- err = verify_area(VERIFY_WRITE, (void*)arg, 16);
- if (err)
- return -err;
- return copy_to_user((void*)arg, strip_info->dev.name,
- strlen(strip_info->dev.name) + 1)?-EFAULT:0;
-
+ return copy_to_user((void*)arg, strip_info->dev.name,
+ strlen(strip_info->dev.name) + 1) ?
+ -EFAULT : 0;
+ break;
case SIOCSIFHWADDR:
{
MetricomAddress addr;
printk(KERN_INFO "%s: SIOCSIFHWADDR\n", strip_info->dev.name);
- if(copy_from_user(&addr, (void*)arg, sizeof(MetricomAddress)))
- return -EFAULT;
- return(set_mac_address(strip_info, &addr));
- }
-
+ return copy_from_user(&addr, (void*)arg, sizeof(MetricomAddress)) ?
+ -EFAULT : set_mac_address(strip_info, &addr);
+ break;
+ }
/*
* Allow stty to read, but not set, the serial port
*/
@@ -2684,9 +2798,10 @@ static int strip_ioctl(struct tty_struct *tty, struct file *file,
case TCGETA:
return n_tty_ioctl(tty, (struct file *) file, cmd,
(unsigned long) arg);
-
+ break;
default:
return -ENOIOCTLCMD;
+ break;
}
}
@@ -2735,10 +2850,12 @@ int strip_init_ctrl_dev(struct device *dummy)
/*
* Register the status file with /proc
*/
+#ifdef CONFIG_PROC_FS
if (proc_net_register(&proc_strip_get_status_info) != 0)
{
printk(KERN_ERR "strip: status proc_net_register() failed.\n");
}
+#endif
#ifdef MODULE
return status;
@@ -2769,7 +2886,9 @@ void cleanup_module(void)
strip_free(struct_strip_list);
/* Unregister with the /proc/net file here. */
+#ifdef CONFIG_PROC_FS
proc_net_unregister(PROC_NET_STRIP_STATUS);
+#endif
if ((i = tty_register_ldisc(N_STRIP, NULL)))
printk(KERN_ERR "STRIP: can't unregister line discipline (err = %d)\n", i);
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index 53bafee55..0b2eb82fc 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -38,6 +38,9 @@ static char *version =
#include <asm/system.h>
#include <asm/pgtable.h>
#include <asm/irq.h>
+#ifndef __sparc_v9__
+#include <asm/io-unit.h>
+#endif
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -1061,14 +1064,23 @@ static void happy_meal_init_rings(struct happy_meal *hp, int from_irq)
(RXFLAG_OWN |
((RX_BUF_ALLOC_SIZE-RX_OFFSET)<<16)),
(u32)virt_to_bus((volatile void *)skb->data));
- } else {
+ } else
#endif
+#ifndef __sparc_v9__
+ if (sparc_cpu_model == sun4d) {
+ __u32 va = (__u32)hp->sun4d_buffers + i * PAGE_SIZE;
+
+ hb->happy_meal_rxd[i].rx_addr =
+ iounit_map_dma_page(va, skb->data, hp->happy_sbus_dev->my_bus);
+ hb->happy_meal_rxd[i].rx_flags =
+ (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+ } else
+#endif
+ {
hb->happy_meal_rxd[i].rx_addr = (u32)((unsigned long) skb->data);
hb->happy_meal_rxd[i].rx_flags =
(RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
-#ifdef CONFIG_PCI
}
-#endif
skb_reserve(skb, RX_OFFSET);
}
@@ -1078,6 +1090,7 @@ static void happy_meal_init_rings(struct happy_meal *hp, int from_irq)
HMD(("done\n"));
}
+#ifndef __sparc_v9__
static void sun4c_happy_meal_init_rings(struct happy_meal *hp)
{
struct hmeal_init_block *hb = hp->happy_block;
@@ -1099,6 +1112,7 @@ static void sun4c_happy_meal_init_rings(struct happy_meal *hp)
hb->happy_meal_txd[i].tx_flags = 0;
HMD(("done\n"));
}
+#endif
static void happy_meal_begin_auto_negotiation(struct happy_meal *hp,
struct hmeal_tcvregs *tregs)
@@ -1234,9 +1248,11 @@ static int happy_meal_init(struct happy_meal *hp, int from_irq)
/* Alloc and reset the tx/rx descriptor chains. */
HMD(("happy_meal_init: to happy_meal_init_rings\n"));
+#ifndef __sparc_v9__
if(sparc_cpu_model == sun4c)
sun4c_happy_meal_init_rings(hp);
else
+#endif
happy_meal_init_rings(hp, from_irq);
/* Shut up the MIF. */
@@ -1676,9 +1692,13 @@ static inline void pci_happy_meal_tx(struct happy_meal *hp)
TXD(("[%d]", elem));
this = &txbase[elem];
+#ifdef __sparc_v9__
__asm__ __volatile__("lduwa [%1] %2, %0"
: "=r" (flags)
: "r" (&this->tx_flags), "i" (ASI_PL));
+#else
+ flags = flip_dword(this->tx_flags);
+#endif
if(flags & TXFLAG_OWN)
break;
skb = hp->tx_skbs[elem];
@@ -1695,6 +1715,7 @@ static inline void pci_happy_meal_tx(struct happy_meal *hp)
}
#endif
+#ifndef __sparc_v9__
static inline void sun4c_happy_meal_tx(struct happy_meal *hp)
{
struct happy_meal_txd *txbase = &hp->happy_block->happy_meal_txd[0];
@@ -1716,6 +1737,7 @@ static inline void sun4c_happy_meal_tx(struct happy_meal *hp)
hp->tx_old = elem;
TXD((">"));
}
+#endif
#ifdef RXDEBUG
#define RXD(x) printk x
@@ -1813,7 +1835,7 @@ static inline void happy_meal_rx(struct happy_meal *hp, struct device *dev,
}
/* This card is _fucking_ hot... */
- if(!~(csum))
+ if(!(csum ^ 0xffff))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
skb->ip_summed = CHECKSUM_NONE;
@@ -1845,9 +1867,13 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev,
RXD(("RX<"));
this = &rxbase[elem];
+#ifdef __sparc_v9__
__asm__ __volatile__("lduwa [%1] %2, %0"
: "=r" (flags)
: "r" (&this->rx_flags), "i" (ASI_PL));
+#else
+ flags = flip_dword(this->rx_flags); /* FIXME */
+#endif
while(!(flags & RXFLAG_OWN)) {
struct sk_buff *skb;
int len;
@@ -1934,9 +1960,13 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev,
next:
elem = NEXT_RX(elem);
this = &rxbase[elem];
+#ifdef __sparc_v9__
__asm__ __volatile__("lduwa [%1] %2, %0"
: "=r" (flags)
: "r" (&this->rx_flags), "i" (ASI_PL));
+#else
+ flags = flip_dword(this->rx_flags); /* FIXME */
+#endif
}
hp->rx_new = elem;
if(drops)
@@ -1945,6 +1975,7 @@ static inline void pci_happy_meal_rx(struct happy_meal *hp, struct device *dev,
}
#endif
+#ifndef __sparc_v9__
static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev,
struct hmeal_gregs *gregs)
{
@@ -2008,6 +2039,115 @@ static inline void sun4c_happy_meal_rx(struct happy_meal *hp, struct device *dev
RXD((">"));
}
+static inline void sun4d_happy_meal_rx(struct happy_meal *hp, struct device *dev,
+ struct hmeal_gregs *gregs)
+{
+ struct happy_meal_rxd *rxbase = &hp->happy_block->happy_meal_rxd[0];
+ struct happy_meal_rxd *this;
+ int elem = hp->rx_new, drops = 0;
+ __u32 va;
+
+ RXD(("RX<"));
+ this = &rxbase[elem];
+ while(!(this->rx_flags & RXFLAG_OWN)) {
+ struct sk_buff *skb;
+ unsigned int flags = this->rx_flags;
+ int len = flags >> 16;
+ u16 csum = flags & RXFLAG_CSUM;
+
+ RXD(("[%d ", elem));
+
+ /* Check for errors. */
+ if((len < ETH_ZLEN) || (flags & RXFLAG_OVERFLOW)) {
+ RXD(("ERR(%08x)]", flags));
+ hp->net_stats.rx_errors++;
+ if(len < ETH_ZLEN)
+ hp->net_stats.rx_length_errors++;
+ if(len & (RXFLAG_OVERFLOW >> 16)) {
+ hp->net_stats.rx_over_errors++;
+ hp->net_stats.rx_fifo_errors++;
+ }
+
+ /* Return it to the Happy meal. */
+ drop_it:
+ hp->net_stats.rx_dropped++;
+ va = (__u32)hp->sun4d_buffers + elem * PAGE_SIZE;
+ this->rx_addr = iounit_map_dma_page(va, hp->rx_skbs[elem]->data,
+ hp->happy_sbus_dev->my_bus);
+ this->rx_flags =
+ (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+ goto next;
+ }
+ skb = hp->rx_skbs[elem];
+ if(len > RX_COPY_THRESHOLD) {
+ struct sk_buff *new_skb;
+
+ /* Now refill the entry, if we can. */
+ new_skb = happy_meal_alloc_skb(RX_BUF_ALLOC_SIZE, GFP_ATOMIC);
+ if(!new_skb) {
+ drops++;
+ goto drop_it;
+ }
+
+ hp->rx_skbs[elem] = new_skb;
+ new_skb->dev = dev;
+ skb_put(new_skb, (ETH_FRAME_LEN + RX_OFFSET));
+ va = (__u32)hp->sun4d_buffers + elem * PAGE_SIZE;
+ rxbase[elem].rx_addr = iounit_map_dma_page(va, new_skb->data,
+ hp->happy_sbus_dev->my_bus);
+
+ skb_reserve(new_skb, RX_OFFSET);
+ rxbase[elem].rx_flags =
+ (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+
+ /* Trim the original skb for the netif. */
+ skb_trim(skb, len);
+ } else {
+ struct sk_buff *copy_skb = dev_alloc_skb(len+2);
+
+ if(!copy_skb) {
+ drops++;
+ goto drop_it;
+ }
+
+ copy_skb->dev = dev;
+ skb_reserve(copy_skb, 2);
+ skb_put(copy_skb, len);
+ memcpy(copy_skb->data, skb->data, len);
+
+ /* Reuse original ring buffer. */
+ va = (__u32)hp->sun4d_buffers + elem * PAGE_SIZE;
+ rxbase[elem].rx_addr = iounit_map_dma_page(va, skb->data,
+ hp->happy_sbus_dev->my_bus);
+ rxbase[elem].rx_flags =
+ (RXFLAG_OWN | ((RX_BUF_ALLOC_SIZE - RX_OFFSET) << 16));
+
+ skb = copy_skb;
+ }
+
+ /* This card is _fucking_ hot... */
+ if(!(csum ^ 0xffff))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+ else
+ skb->ip_summed = CHECKSUM_NONE;
+
+ RXD(("len=%d csum=%4x]", len, csum));
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+
+ hp->net_stats.rx_packets++;
+ hp->net_stats.rx_bytes+=len;
+ next:
+ elem = NEXT_RX(elem);
+ this = &rxbase[elem];
+ }
+ hp->rx_new = elem;
+ if(drops)
+ printk("%s: Memory squeeze, deferring packet.\n", hp->dev->name);
+ RXD((">"));
+}
+#endif
+
static void happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
struct device *dev = (struct device *) dev_id;
@@ -2142,6 +2282,50 @@ static void sun4c_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *re
dev->interrupt = 0;
HMD(("done\n"));
}
+
+static void sun4d_happy_meal_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+ struct device *dev = (struct device *) dev_id;
+ struct happy_meal *hp = (struct happy_meal *) dev->priv;
+ struct hmeal_gregs *gregs = hp->gregs;
+ struct hmeal_tcvregs *tregs = hp->tcvregs;
+ unsigned int happy_status = hme_read32(hp, &gregs->stat);
+
+ HMD(("happy_meal_interrupt: status=%08x ", happy_status));
+
+ dev->interrupt = 1;
+
+ if(happy_status & GREG_STAT_ERRORS) {
+ HMD(("ERRORS "));
+ if(happy_meal_is_not_so_happy(hp, gregs, /* un- */ happy_status)) {
+ dev->interrupt = 0;
+ return;
+ }
+ }
+
+ if(happy_status & GREG_STAT_MIFIRQ) {
+ HMD(("MIFIRQ "));
+ happy_meal_mif_interrupt(hp, gregs, tregs);
+ }
+
+ if(happy_status & GREG_STAT_TXALL) {
+ HMD(("TXALL "));
+ happy_meal_tx(hp);
+ }
+
+ if(happy_status & GREG_STAT_RXTOHOST) {
+ HMD(("RXTOHOST "));
+ sun4d_happy_meal_rx(hp, dev, gregs);
+ }
+
+ if(dev->tbusy && (TX_BUFFS_AVAIL(hp) >= 0)) {
+ hp->dev->tbusy = 0;
+ mark_bh(NET_BH);
+ }
+
+ dev->interrupt = 0;
+ HMD(("done\n"));
+}
#endif
static int happy_meal_open(struct device *dev)
@@ -2158,8 +2342,16 @@ static int happy_meal_open(struct device *dev)
printk("happy meal: Can't order irq %d to go.\n", dev->irq);
return -EAGAIN;
}
+ } else if (sparc_cpu_model == sun4d) {
+ if(request_irq(dev->irq, &sun4d_happy_meal_interrupt,
+ SA_SHIRQ, "HAPPY MEAL", (void *) dev)) {
+ HMD(("EAGAIN\n"));
+ printk("happy_meal(SBUS): Can't order irq %s to go.\n",
+ __irq_itoa(dev->irq));
+ return -EAGAIN;
+ }
} else
-#else
+#endif
#ifdef CONFIG_PCI
if(hp->happy_flags & HFLAG_PCI) {
if(request_irq(dev->irq, &pci_happy_meal_interrupt,
@@ -2171,7 +2363,6 @@ static int happy_meal_open(struct device *dev)
}
} else
#endif
-#endif
if(request_irq(dev->irq, &happy_meal_interrupt,
SA_SHIRQ, "HAPPY MEAL", (void *)dev)) {
HMD(("EAGAIN\n"));
@@ -2313,6 +2504,7 @@ static int pci_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
}
#endif
+#ifndef __sparc_v9__
static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
{
struct happy_meal *hp = (struct happy_meal *) dev->priv;
@@ -2369,6 +2561,59 @@ static int sun4c_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
return 0;
}
+static int sun4d_happy_meal_start_xmit(struct sk_buff *skb, struct device *dev)
+{
+ struct happy_meal *hp = (struct happy_meal *) dev->priv;
+ int len, entry;
+ __u32 va;
+
+ if(test_and_set_bit(0, (void *) &dev->tbusy) != 0) {
+ int tickssofar = jiffies - dev->trans_start;
+
+ if (tickssofar >= 40) {
+ printk ("%s: transmit timed out, resetting\n", dev->name);
+ hp->net_stats.tx_errors++;
+ tx_dump_log();
+ printk ("%s: Happy Status %08x TX[%08x:%08x]\n", dev->name,
+ hme_read32(hp, &hp->gregs->stat),
+ hme_read32(hp, &hp->etxregs->cfg),
+ hme_read32(hp, &hp->bigmacregs->tx_cfg));
+ happy_meal_init(hp, 0);
+ dev->tbusy = 0;
+ dev->trans_start = jiffies;
+ } else
+ tx_add_log(hp, TXLOG_ACTION_TXMIT|TXLOG_ACTION_TBUSY, 0);
+ return 1;
+ }
+
+ if(!TX_BUFFS_AVAIL(hp)) {
+ tx_add_log(hp, TXLOG_ACTION_TXMIT|TXLOG_ACTION_NBUFS, 0);
+ return 1;
+ }
+ len = skb->len;
+ entry = hp->tx_new;
+
+ SXD(("SX<l[%d]e[%d]>", len, entry));
+ hp->tx_skbs[entry] = skb;
+ va = (__u32)hp->sun4d_buffers + (RX_RING_SIZE + entry) * PAGE_SIZE;
+ hp->happy_block->happy_meal_txd[entry].tx_addr =
+ iounit_map_dma_page(va, skb->data, hp->happy_sbus_dev->my_bus);
+ hp->happy_block->happy_meal_txd[entry].tx_flags =
+ (TXFLAG_OWN | TXFLAG_SOP | TXFLAG_EOP | (len & TXFLAG_SIZE));
+ hp->tx_new = NEXT_TX(entry);
+
+ /* Get it going. */
+ dev->trans_start = jiffies;
+ hme_write32(hp, &hp->etxregs->tx_pnding, ETX_TP_DMAWAKEUP);
+
+ if(TX_BUFFS_AVAIL(hp))
+ dev->tbusy = 0;
+
+ tx_add_log(hp, TXLOG_ACTION_TXMIT, 0);
+ return 0;
+}
+#endif
+
static struct net_device_stats *happy_meal_get_stats(struct device *dev)
{
struct happy_meal *hp = (struct happy_meal *) dev->priv;
@@ -2547,11 +2792,17 @@ static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_de
sparc_dvma_malloc(PAGE_SIZE, "Happy Meal Init Block",
&hp->hblock_dvma);
+#ifndef __sparc_v9__
if(sparc_cpu_model == sun4c)
hp->sun4c_buffers = (struct hmeal_buffers *)
sparc_dvma_malloc(sizeof(struct hmeal_buffers), "Happy Meal Bufs",
&hp->s4c_buf_dvma);
+ else if (sparc_cpu_model == sun4d)
+ hp->sun4d_buffers = (struct hmeal_buffers *)
+ iounit_map_dma_init(hp->happy_sbus_dev->my_bus,
+ (RX_RING_SIZE + TX_RING_SIZE) * PAGE_SIZE);
else
+#endif
hp->sun4c_buffers = 0;
/* Force check of the link first time we are brought up. */
@@ -2569,9 +2820,13 @@ static inline int happy_meal_ether_init(struct device *dev, struct linux_sbus_de
hp->dev = dev;
dev->open = &happy_meal_open;
dev->stop = &happy_meal_close;
+#ifndef __sparc_v9__
if(sparc_cpu_model == sun4c)
dev->hard_start_xmit = &sun4c_happy_meal_start_xmit;
+ else if (sparc_cpu_model == sun4d)
+ dev->hard_start_xmit = &sun4d_happy_meal_start_xmit;
else
+#endif
dev->hard_start_xmit = &happy_meal_start_xmit;
dev->get_stats = &happy_meal_get_stats;
dev->set_multicast_list = &happy_meal_set_multicast;
@@ -2670,6 +2925,11 @@ __initfunc(int happy_meal_pci_init(struct device *dev, struct pci_dev *pdev))
}
hp->hblock_dvma = (u32) virt_to_bus(hp->happy_block);
+#ifndef __sparc_v9__
+ /* This case we currently need to use 'sparc_alloc_io' */
+ hp->happy_block = sparc_alloc_io (hp->hblock_dvma, NULL,
+ PAGE_SIZE, "sunhme", 0, 0);
+#endif
hp->sun4c_buffers = 0;
hp->linkcheck = 0;
@@ -2782,6 +3042,11 @@ cleanup_module(void)
sparc_free_io(hp->erxregs, sizeof(struct hmeal_erxregs));
sparc_free_io(hp->bigmacregs, sizeof(struct hmeal_bigmacregs));
sparc_free_io(hp->tcvregs, sizeof(struct hmeal_tcvregs));
+#ifndef __sparc_v9__
+ if (sparc_cpu_model == sun4d)
+ iounit_map_dma_finish(hp->happy_sbus_dev->my_bus,
+ (__u32)hp->sun4d_buffers, (RX_RING_SIZE + TX_RING_SIZE) * PAGE_SIZE);
+#endif
unregister_netdev(hp->dev);
kfree(hp->dev);
root_happy_dev = sunshine;
diff --git a/drivers/net/sunhme.h b/drivers/net/sunhme.h
index 15b408ece..c7d2bc813 100644
--- a/drivers/net/sunhme.h
+++ b/drivers/net/sunhme.h
@@ -525,6 +525,7 @@ struct happy_meal {
/* We may use this for Ultra as well, will have to see, maybe not. */
struct hmeal_buffers *sun4c_buffers; /* CPU visible address. */
+#define sun4d_buffers sun4c_buffers /* No need to make this a separate. */
__u32 s4c_buf_dvma; /* DVMA visible address. */
unsigned int happy_flags; /* Driver state flags */
@@ -632,6 +633,7 @@ extern inline void hme_write32(struct happy_meal *hp,
}
#ifdef CONFIG_PCI
+#ifdef __sparc_v9__
extern inline void pcihme_write_rxd(struct happy_meal_rxd *rp,
unsigned int flags,
unsigned int addr)
@@ -655,6 +657,25 @@ extern inline void pcihme_write_txd(struct happy_meal_txd *tp,
: "r" (&tp->tx_addr), "r" (&tp->tx_flags),
"i" (ASI_PL), "r" (addr), "r" (flags));
}
-#endif
+#else
+
+extern inline void pcihme_write_rxd(struct happy_meal_rxd *rp,
+ unsigned int flags,
+ unsigned int addr)
+{
+ rp->rx_addr = flip_dword(addr);
+ rp->rx_flags = flip_dword(flags);
+}
+
+extern inline void pcihme_write_txd(struct happy_meal_txd *tp,
+ unsigned int flags,
+ unsigned int addr)
+{
+ tp->tx_addr = flip_dword(addr);
+ tp->tx_flags = flip_dword(flags);
+}
+
+#endif /* def __sparc_v9__ */
+#endif /* def CONFIG_PCI */
#endif /* !(_SUNHME_H) */
diff --git a/drivers/net/syncppp.c b/drivers/net/syncppp.c
index 7113ba524..328878c73 100644
--- a/drivers/net/syncppp.c
+++ b/drivers/net/syncppp.c
@@ -770,6 +770,7 @@ static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
sp->obytes += skb->len;
/* Control is high priority so it doesnt get queued behind data */
skb->priority=1;
+ skb->dev = dev;
dev_queue_xmit(skb);
}
@@ -811,6 +812,7 @@ static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2)
ch->par2, ch->rel, ch->time0, ch->time1);
sp->obytes += skb->len;
skb->priority=1;
+ skb->dev = dev;
dev_queue_xmit(skb);
}
@@ -857,13 +859,23 @@ int sppp_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
if(dev->flags&IFF_UP)
return -EBUSY;
+ if(!capable(CAP_NET_ADMIN))
+ return -EPERM;
+
switch(cmd)
{
case SPPPIOCCISCO:
sp->pp_flags|=PP_CISCO;
+ dev->type = ARPHRD_HDLC;
break;
case SPPPIOCPPP:
sp->pp_flags&=~PP_CISCO;
+ dev->type = ARPHRD_PPP;
+ break;
+ case SPPPIOCDEBUG:
+ sp->pp_flags&=~PP_DEBUG;
+ if(ifr->ifr_flags)
+ sp->pp_flags|=PP_DEBUG;
break;
default:
return -EINVAL;
@@ -908,7 +920,7 @@ void sppp_attach(struct ppp_device *pd)
dev->hard_header = sppp_hard_header;
dev->rebuild_header = sppp_rebuild_header;
dev->tx_queue_len = 10;
- dev->type = ARPHRD_PPP;
+ dev->type = ARPHRD_HDLC;
dev->addr_len = 0;
dev->hard_header_len = sizeof(struct ppp_header);
dev->mtu = PPP_MTU;
@@ -924,7 +936,7 @@ void sppp_attach(struct ppp_device *pd)
dev->change_mtu = sppp_change_mtu;
dev->hard_header_cache = NULL;
dev->header_cache_update = NULL;
- dev->flags = IFF_MULTICAST;
+ dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP;
dev_init_buffers(dev);
}
@@ -1254,7 +1266,7 @@ struct packet_type sppp_packet_type=
void sync_ppp_init(void)
{
printk(KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n");
- printk(KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & Jan 'Yenya' Kasprzak.\n");
+ printk(KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & Jan \"Yenya\" Kasprzak.\n");
sppp_packet_type.type=htons(ETH_P_WAN_PPP);
dev_add_pack(&sppp_packet_type);
}
diff --git a/drivers/net/syncppp.h b/drivers/net/syncppp.h
index 5ae6f7398..1309bc972 100644
--- a/drivers/net/syncppp.h
+++ b/drivers/net/syncppp.h
@@ -20,6 +20,7 @@
#ifndef _SYNCPPP_H_
#define _SYNCPPP_H_ 1
+#ifdef __KERNEL__
struct slcp {
u16 state; /* state machine */
u32 magic; /* local magic number */
@@ -71,7 +72,6 @@ struct ppp_device
#define IPCP_STATE_ACK_SENT 2 /* IPCP state: conf-ack sent */
#define IPCP_STATE_OPENED 3 /* IPCP state: opened */
-#ifdef __KERNEL__
void sppp_attach (struct ppp_device *pd);
void sppp_detach (struct device *dev);
void sppp_input (struct device *dev, struct sk_buff *m);
@@ -85,5 +85,6 @@ int sppp_close (struct device *dev);
#define SPPPIOCCISCO (SIOCDEVPRIVATE)
#define SPPPIOCPPP (SIOCDEVPRIVATE+1)
+#define SPPPIOCDEBUG (SIOCDEVPRIVATE+2)
#endif /* _SYNCPPP_H_ */
diff --git a/drivers/net/tlan.c b/drivers/net/tlan.c
index 7d4eaa225..e93207339 100644
--- a/drivers/net/tlan.c
+++ b/drivers/net/tlan.c
@@ -25,6 +25,11 @@
* Microchip Technology, 24C01A/02A/04A Data Sheet
* available in PDF format from www.microchip.com
*
+ * Change History
+ *
+ * Tigran Aivazian <tigran@sco.com>: TLan_PciProbe() now uses
+ * new PCI BIOS interface.
+ *
********************************************************************/
@@ -32,7 +37,6 @@
#include "tlan.h"
-#include <linux/bios32.h>
#include <linux/ioport.h>
#include <linux/pci.h>
#include <linux/etherdevice.h>
@@ -152,7 +156,7 @@ static TLanAdapterEntry TLanAdapterList[] = {
};
-static int TLan_PciProbe( u8 *, u8 *, u8 *, u8 *, u32 *, u32 * );
+static int TLan_PciProbe( u8 *, u8 *, u8 *, u32 *, u32 * );
static int TLan_Init( struct device * );
static int TLan_Open(struct device *dev);
static int TLan_StartTx(struct sk_buff *, struct device *);
@@ -269,7 +273,6 @@ TLan_SetTimer( struct device *dev, u32 ticks, u32 type )
extern int init_module(void)
{
TLanPrivateInfo *priv;
- u8 bus;
struct device *dev;
size_t dev_size;
u8 dfn;
@@ -296,7 +299,7 @@ extern int init_module(void)
dev_size = sizeof(struct device) + sizeof(TLanPrivateInfo);
- while ( ( found = TLan_PciProbe( &bus, &dfn, &irq, &rev, &io_base, &index ) ) ) {
+ while ( ( found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index ) ) ) {
dev = (struct device *) kmalloc( dev_size, GFP_KERNEL );
if ( dev == NULL ) {
printk( "TLAN: Could not allocate memory for device.\n" );
@@ -417,10 +420,10 @@ extern int tlan_probe( struct device *dev )
TLanPrivateInfo *priv;
static int pad_allocated = 0;
int found;
- u8 bus, dfn, irq, rev;
+ u8 dfn, irq, rev;
u32 io_base, index;
- found = TLan_PciProbe( &bus, &dfn, &irq, &rev, &io_base, &index );
+ found = TLan_PciProbe( &dfn, &irq, &rev, &io_base, &index );
if ( ! found ) {
return -ENODEV;
@@ -502,8 +505,6 @@ extern int tlan_probe( struct device *dev )
* Returns:
* 1 if another TLAN card was found, 0 if not.
* Parms:
- * pci_bus The PCI bus the card was found
- * on.
* pci_dfn The PCI whatever the card was
* found at.
* pci_irq The IRQ of the found adapter.
@@ -522,33 +523,26 @@ extern int tlan_probe( struct device *dev )
*
**************************************************************/
-int TLan_PciProbe( u8 *pci_bus, u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 *dl_ix )
+int TLan_PciProbe(u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_io_base, u32 *dl_ix )
{
static int dl_index = 0;
- static int pci_index = 0;
-
- int not_found;
- u8 pci_latency;
+ static struct pci_dev * pdev = NULL;
u16 pci_command;
int reg;
- if ( ! pcibios_present() ) {
+ if ( ! pci_present() ) {
printk( "TLAN: PCI Bios not present.\n" );
return 0;
}
for (; TLanAdapterList[dl_index].vendorId != 0; dl_index++) {
- not_found = pcibios_find_device(
+ pdev = pci_find_device(
TLanAdapterList[dl_index].vendorId,
- TLanAdapterList[dl_index].deviceId,
- pci_index,
- pci_bus,
- pci_dfn
- );
+ TLanAdapterList[dl_index].deviceId, pdev);
- if ( ! not_found ) {
+ if ( pdev ) {
TLAN_DBG(
TLAN_DEBUG_GNRL,
@@ -557,19 +551,14 @@ int TLan_PciProbe( u8 *pci_bus, u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_
TLanAdapterList[dl_index].deviceId
);
- pcibios_read_config_byte ( *pci_bus, *pci_dfn, PCI_REVISION_ID, pci_rev);
- pcibios_read_config_byte ( *pci_bus, *pci_dfn, PCI_INTERRUPT_LINE, pci_irq);
- pcibios_read_config_word ( *pci_bus, *pci_dfn, PCI_COMMAND, &pci_command);
- pcibios_read_config_dword( *pci_bus, *pci_dfn, PCI_BASE_ADDRESS_0, pci_io_base);
- pcibios_read_config_byte ( *pci_bus, *pci_dfn, PCI_LATENCY_TIMER, &pci_latency);
-
- if (pci_latency < 0x10) {
- pcibios_write_config_byte( *pci_bus, *pci_dfn, PCI_LATENCY_TIMER, 0xff);
- TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN: Setting latency timer to max.\n");
- }
+ *pci_irq = pdev->irq;
+ *pci_io_base = pdev->base_address[0] & PCI_BASE_ADDRESS_IO_MASK;
+ *pci_dfn = pdev->devfn;
+ pci_read_config_byte ( pdev, PCI_REVISION_ID, pci_rev);
+ pci_read_config_word ( pdev, PCI_COMMAND, &pci_command);
for ( reg = PCI_BASE_ADDRESS_0; reg <= PCI_BASE_ADDRESS_5; reg +=4 ) {
- pcibios_read_config_dword( *pci_bus, *pci_dfn, reg, pci_io_base);
+ pci_read_config_dword( pdev, reg, pci_io_base);
if ((pci_command & PCI_COMMAND_IO) && (*pci_io_base & 0x3)) {
*pci_io_base &= PCI_BASE_ADDRESS_IO_MASK;
TLAN_DBG( TLAN_DEBUG_GNRL, "TLAN: IO mapping is available at %x.\n", *pci_io_base);
@@ -582,12 +571,7 @@ int TLan_PciProbe( u8 *pci_bus, u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_
if ( *pci_io_base == 0 )
printk("TLAN: IO mapping not available, ignoring device.\n");
- if ( ! ( pci_command & PCI_COMMAND_MASTER ) ) {
- pcibios_write_config_word ( *pci_bus, *pci_dfn, PCI_COMMAND, pci_command | PCI_COMMAND_MASTER );
- printk( "TLAN: Activating PCI bus mastering for this device.\n" );
- }
-
- pci_index++;
+ pci_set_master(pdev);
if ( *pci_io_base ) {
*dl_ix = dl_index;
@@ -595,7 +579,7 @@ int TLan_PciProbe( u8 *pci_bus, u8 *pci_dfn, u8 *pci_irq, u8 *pci_rev, u32 *pci_
}
} else {
- pci_index = 0;
+ pdev = NULL;
}
}
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
new file mode 100644
index 000000000..fead49fcb
--- /dev/null
+++ b/drivers/net/via-rhine.c
@@ -0,0 +1,1316 @@
+/* via-rhine.c: A Linux Ethernet device driver for VIA Rhine family chips. */
+/*
+ Written 1998 by Donald Becker.
+
+ This software may be used and distributed according to the terms
+ of the GNU Public License (GPL), incorporated herein by reference.
+ Drivers derived from this code also fall under the GPL and must retain
+ this authorship and copyright notice.
+
+ This driver is designed for the VIA VT86c100A Rhine-II PCI Fast Ethernet
+ controller. It also works with the older 3043 Rhine-I chip.
+
+ The author may be reached as becker@cesdis.edu, or
+ Donald Becker
+ 312 Severn Ave. #W302
+ Annapolis MD 21403
+
+ Support and updates available at
+ http://cesdis.gsfc.nasa.gov/linux/drivers/via-rhine.html
+*/
+
+static const char *versionA =
+"via-rhine.c:v1.00 9/5/98 Written by Donald Becker\n";
+static const char *versionB =
+" http://cesdis.gsfc.nasa.gov/linux/drivers/via-rhine.html\n";
+
+/* A few user-configurable values. These may be modified when a driver
+ module is loaded.*/
+
+static int debug = 1; /* 1 normal messages, 0 quiet .. 7 verbose. */
+static int max_interrupt_work = 20;
+static int min_pci_latency = 64;
+
+/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
+ Setting to > 1518 effectively disables this feature. */
+static int rx_copybreak = 0;
+
+/* Used to pass the media type, etc.
+ Both 'options[]' and 'full_duplex[]' should exist for driver
+ interoperability.
+ The media type is usually passed in 'options[]'.
+*/
+#define MAX_UNITS 8 /* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+/* Maximum number of multicast addresses to filter (vs. rx-all-multicast).
+ The Rhine has a 64 element 8390-like hash table. */
+static const int multicast_filter_limit = 32;
+
+/* Operational parameters that are set at compile time. */
+
+/* Keep the ring sizes a power of two for compile efficiency.
+ The compiler will convert <unsigned>'%'<2^N> into a bit mask.
+ Making the Tx ring too large decreases the effectiveness of channel
+ bonding and packet priority.
+ There are no ill effects from too-large receive rings. */
+#define TX_RING_SIZE 8
+#define RX_RING_SIZE 16
+
+/* Operational parameters that usually are not changed. */
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT (2*HZ)
+
+#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
+
+/* Include files, designed to support most kernel versions 2.0.0 and later. */
+#include <linux/version.h>
+#ifdef MODULE
+#ifdef MODVERSIONS
+#include <linux/modversions.h>
+#endif
+#include <linux/module.h>
+#else
+#define MOD_INC_USE_COUNT
+#define MOD_DEC_USE_COUNT
+#endif
+
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/malloc.h>
+#include <linux/interrupt.h>
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <asm/processor.h> /* Processor type for cache alignment. */
+#include <asm/bitops.h>
+#include <asm/io.h>
+
+/* This driver was written to use PCI memory space, however some boards
+ only work with I/O space accesses. */
+#define VIA_USE_IO
+#ifdef VIA_USE_IO
+#undef readb
+#undef readw
+#undef readl
+#undef writeb
+#undef writew
+#undef writel
+#define readb inb
+#define readw inw
+#define readl inl
+#define writeb outb
+#define writew outw
+#define writel outl
+#endif
+
+/* Kernel compatibility defines, some common to David Hind's PCMCIA package.
+ This is only in the support-all-kernels source code. */
+
+#define RUN_AT(x) (jiffies + (x))
+
+#if (LINUX_VERSION_CODE >= 0x20100)
+char kernel_version[] = UTS_RELEASE;
+#else
+#ifndef __alpha__
+#define ioremap vremap
+#define iounmap vfree
+#endif
+#endif
+#if defined(MODULE) && LINUX_VERSION_CODE > 0x20115
+MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
+MODULE_DESCRIPTION("VIA Rhine PCI Fast Ethernet driver");
+MODULE_PARM(max_interrupt_work, "i");
+MODULE_PARM(min_pci_latency, "i");
+MODULE_PARM(debug, "i");
+MODULE_PARM(rx_copybreak, "i");
+MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
+#endif
+#if LINUX_VERSION_CODE < 0x20123
+#define test_and_set_bit(val, addr) set_bit(val, addr)
+#endif
+#if LINUX_VERSION_CODE <= 0x20139
+#define net_device_stats enet_statistics
+#else
+#define NETSTATS_VER2
+#endif
+#if LINUX_VERSION_CODE < 0x20155 || defined(CARDBUS)
+/* Grrrr, the PCI code changed, but did not consider CardBus... */
+#include <linux/bios32.h>
+#define PCI_SUPPORT_VER1
+#else
+#define PCI_SUPPORT_VER2
+#endif
+#if LINUX_VERSION_CODE < 0x20159
+#define dev_free_skb(skb) dev_kfree_skb(skb, FREE_WRITE);
+#else
+#define dev_free_skb(skb) dev_kfree_skb(skb);
+#endif
+
+
+/*
+ Theory of Operation
+
+I. Board Compatibility
+
+This driver is designed for the VIA 86c100A Rhine-II PCI Fast Ethernet
+controller.
+
+II. Board-specific settings
+
+Boards with this chip are functional only in a bus-master PCI slot.
+
+Many operational settings are loaded from the EEPROM to the Config word at
+offset 0x78. This driver assumes that they are correct.
+If this driver is compiled to use PCI memory space operations the EEPROM
+must be configured to enable memory ops.
+
+III. Driver operation
+
+IIIa. Ring buffers
+
+This driver uses two statically allocated fixed-size descriptor lists
+formed into rings by a branch from the final descriptor to the beginning of
+the list. The ring sizes are set at compile time by RX/TX_RING_SIZE.
+
+IIIb/c. Transmit/Receive Structure
+
+This driver attempts to use a zero-copy receive and transmit scheme.
+
+Alas, all data buffers are required to start on a 32 bit boundary, so
+the driver must often copy transmit packets into bounce buffers.
+
+The driver allocates full frame size skbuffs for the Rx ring buffers at
+open() time and passes the skb->data field to the chip as receive data
+buffers. When an incoming frame is less than RX_COPYBREAK bytes long,
+a fresh skbuff is allocated and the frame is copied to the new skbuff.
+When the incoming frame is larger, the skbuff is passed directly up the
+protocol stack. Buffers consumed this way are replaced by newly allocated
+skbuffs in the last phase of netdev_rx().
+
+The RX_COPYBREAK value is chosen to trade-off the memory wasted by
+using a full-sized skbuff for small frames vs. the copying costs of larger
+frames. New boards are typically used in generously configured machines
+and the underfilled buffers have negligible impact compared to the benefit of
+a single allocation size, so the default value of zero results in never
+copying packets. When copying is done, the cost is usually mitigated by using
+a combined copy/checksum routine. Copying also preloads the cache, which is
+most useful with small frames.
+
+Since the VIA chips are only able to transfer data to buffers on 32 bit
+boundaries, the the IP header at offset 14 in an ethernet frame isn't
+longword aligned for further processing. Copying these unaligned buffers
+has the beneficial effect of 16-byte aligning the IP header.
+
+IIId. Synchronization
+
+The driver runs as two independent, single-threaded flows of control. One
+is the send-packet routine, which enforces single-threaded use by the
+dev->tbusy flag. The other thread is the interrupt handler, which is single
+threaded by the hardware and interrupt handling software.
+
+The send packet thread has partial control over the Tx ring and 'dev->tbusy'
+flag. It sets the tbusy flag whenever it's queuing a Tx packet. If the next
+queue slot is empty, it clears the tbusy flag when finished otherwise it sets
+the 'lp->tx_full' flag.
+
+The interrupt handler has exclusive control over the Rx ring and records stats
+from the Tx ring. After reaping the stats, it marks the Tx queue entry as
+empty by incrementing the dirty_tx mark. Iff the 'lp->tx_full' flag is set, it
+clears both the tx_full and tbusy flags.
+
+IV. Notes
+
+IVb. References
+
+Preliminary VT86C100A manual from http://www.via.com.tw/
+http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+
+IVc. Errata
+
+The VT86C100A manual is not reliable information.
+The chip does not handle unaligned transmit or receive buffers, resulting
+in significant performance degradation for bounce buffer copies on transmit
+and unaligned IP headers on receive.
+The chip does not pad to minimum transmit length.
+
+*/
+
+
+
+/* This table drives the PCI probe routines. It's mostly boilerplate in all
+ of the drivers, and will likely be provided by some future kernel.
+ Note the matching code -- the first table entry matchs all 56** cards but
+ second only the 1234 card.
+*/
+enum pci_flags_bit {
+ PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
+ PCI_ADDR0=0x10<<0, PCI_ADDR1=0x10<<1, PCI_ADDR2=0x10<<2, PCI_ADDR3=0x10<<3,
+};
+struct pci_id_info {
+ const char *name;
+ u16 vendor_id, device_id, device_id_mask, flags;
+ int io_size;
+ struct device *(*probe1)(int pci_bus, int pci_devfn, struct device *dev,
+ long ioaddr, int irq, int chip_idx, int fnd_cnt);
+};
+
+static struct device *via_probe1(int pci_bus, int pci_devfn,
+ struct device *dev, long ioaddr, int irq,
+ int chp_idx, int fnd_cnt);
+
+static struct pci_id_info pci_tbl[] = {
+ { "VIA VT86C100A Rhine-II", 0x1106, 0x6100, 0xffff,
+ PCI_USES_MEM|PCI_USES_IO|PCI_USES_MEM|PCI_USES_MASTER, 128, via_probe1},
+ { "VIA VT3043 Rhine", 0x1106, 0x3043, 0xffff,
+ PCI_USES_IO|PCI_USES_MEM|PCI_USES_MASTER, 128, via_probe1},
+ {0,}, /* 0 terminated list. */
+};
+
+
+/* A chip capabilities table, matching the entries in pci_tbl[] above. */
+enum chip_capability_flags {CanHaveMII=1, };
+struct chip_info {
+ int io_size;
+ int flags;
+} static cap_tbl[] = {
+ {128, CanHaveMII, },
+ {128, CanHaveMII, },
+};
+
+
+/* Offsets to the device registers.
+*/
+enum register_offsets {
+ StationAddr=0x00, RxConfig=0x06, TxConfig=0x07, ChipCmd=0x08,
+ IntrStatus=0x0C, IntrEnable=0x0E,
+ MulticastFilter0=0x10, MulticastFilter1=0x14,
+ RxRingPtr=0x18, TxRingPtr=0x1C,
+ MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIConfig=0x6E,
+ MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72,
+ Config=0x78, RxMissed=0x7C, RxCRCErrs=0x7E,
+};
+
+/* Bits in the interrupt status/mask registers. */
+enum intr_status_bits {
+ IntrRxDone=0x0001, IntrRxErr=0x0004, IntrRxEmpty=0x0020,
+ IntrTxDone=0x0002, IntrTxAbort=0x0008, IntrTxUnderrun=0x0010,
+ IntrPCIErr=0x0040,
+ IntrStatsMax=0x0080, IntrRxEarly=0x0100, IntrMIIChange=0x0200,
+ IntrRxOverflow=0x0400, IntrRxDropped=0x0800, IntrRxNoBuf=0x1000,
+ IntrTxAborted=0x2000, IntrLinkChange=0x4000,
+ IntrRxWakeUp=0x8000,
+ IntrNormalSummary=0x0003, IntrAbnormalSummary=0x8260,
+};
+
+
+/* The Rx and Tx buffer descriptors. */
+struct rx_desc {
+ u16 rx_status;
+ u16 rx_length;
+ u32 desc_length;
+ u32 addr;
+ u32 next_desc;
+};
+struct tx_desc {
+ u16 tx_status;
+ u16 tx_own;
+ u32 desc_length;
+ u32 addr;
+ u32 next_desc;
+};
+
+/* Bits in *_desc.status */
+enum rx_status_bits {
+ RxDescOwn=0x80000000, RxOK=0x8000, RxWholePkt=0x0300, RxErr=0x008F};
+enum desc_status_bits {
+ DescOwn=0x8000, DescEndPacket=0x4000, DescIntr=0x1000,
+};
+
+/* Bits in ChipCmd. */
+enum chip_cmd_bits {
+ CmdInit=0x0001, CmdStart=0x0002, CmdStop=0x0004, CmdRxOn=0x0008,
+ CmdTxOn=0x0010, CmdTxDemand=0x0020, CmdRxDemand=0x0040,
+ CmdEarlyRx=0x0100, CmdEarlyTx=0x0200, CmdFDuplex=0x0400,
+ CmdNoTxPoll=0x0800, CmdReset=0x8000,
+};
+
+struct netdev_private {
+ /* Descriptor rings first for alignment. */
+ struct rx_desc rx_ring[RX_RING_SIZE];
+ struct tx_desc tx_ring[TX_RING_SIZE];
+ /* The addresses of receive-in-place skbuffs. */
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
+ /* The saved address of a sent-in-place packet/buffer, for later free(). */
+ struct sk_buff* tx_skbuff[TX_RING_SIZE];
+ unsigned char *tx_buf[TX_RING_SIZE]; /* Tx bounce buffers */
+ unsigned char *tx_bufs; /* Tx bounce buffer region. */
+ struct device *next_module; /* Link for devices of this type. */
+ struct net_device_stats stats;
+ struct timer_list timer; /* Media monitoring timer. */
+ unsigned char pci_bus, pci_devfn;
+ /* Frequently used values: keep some adjacent for cache effect. */
+ int chip_id;
+ long in_interrupt; /* Word-long for SMP locks. */
+ struct rx_desc *rx_head_desc;
+ unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
+ unsigned int cur_tx, dirty_tx;
+ unsigned int rx_buf_sz; /* Based on MTU+slack. */
+ u16 chip_cmd; /* Current setting for ChipCmd */
+ unsigned int tx_full:1; /* The Tx queue is full. */
+ /* These values are keep track of the transceiver/media in use. */
+ unsigned int full_duplex:1; /* Full-duplex operation requested. */
+ unsigned int duplex_lock:1;
+ unsigned int medialock:1; /* Do not sense media. */
+ unsigned int default_port:4; /* Last dev->if_port value. */
+ u8 tx_thresh, rx_thresh;
+ /* MII transceiver section. */
+ int mii_cnt; /* MII device addresses. */
+ u16 advertising; /* NWay media advertisement */
+ unsigned char phys[2]; /* MII device addresses. */
+};
+
+static int mdio_read(struct device *dev, int phy_id, int location);
+static void mdio_write(struct device *dev, int phy_id, int location, int value);
+static int netdev_open(struct device *dev);
+static void check_duplex(struct device *dev);
+static void netdev_timer(unsigned long data);
+static void tx_timeout(struct device *dev);
+static void init_ring(struct device *dev);
+static int start_tx(struct sk_buff *skb, struct device *dev);
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *regs);
+static int netdev_rx(struct device *dev);
+static void netdev_error(struct device *dev, int intr_status);
+static void set_rx_mode(struct device *dev);
+static struct net_device_stats *get_stats(struct device *dev);
+static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd);
+static int netdev_close(struct device *dev);
+
+
+
+/* A list of our installed devices, for removing the driver module. */
+static struct device *root_net_dev = NULL;
+
+/* Ideally we would detect all network cards in slot order. That would
+ be best done a central PCI probe dispatch, which wouldn't work
+ well when dynamically adding drivers. So instead we detect just the
+ cards we know about in slot order. */
+
+static int pci_etherdev_probe(struct device *dev, struct pci_id_info pci_tbl[])
+{
+ int cards_found = 0;
+ int pci_index = 0;
+ unsigned char pci_bus, pci_device_fn;
+
+ if ( ! pcibios_present())
+ return -ENODEV;
+
+ for (;pci_index < 0xff; pci_index++) {
+ u16 vendor, device, pci_command, new_command;
+ int chip_idx, irq;
+ long pciaddr;
+ long ioaddr;
+
+ if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8, pci_index,
+ &pci_bus, &pci_device_fn)
+ != PCIBIOS_SUCCESSFUL)
+ break;
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_VENDOR_ID, &vendor);
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_DEVICE_ID, &device);
+
+ for (chip_idx = 0; pci_tbl[chip_idx].vendor_id; chip_idx++)
+ if (vendor == pci_tbl[chip_idx].vendor_id
+ && (device & pci_tbl[chip_idx].device_id_mask) ==
+ pci_tbl[chip_idx].device_id)
+ break;
+ if (pci_tbl[chip_idx].vendor_id == 0) /* Compiled out! */
+ continue;
+
+ {
+#if defined(PCI_SUPPORT_VER2)
+ struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
+#ifdef VIA_USE_IO
+ pciaddr = pdev->base_address[0];
+#else
+ pciaddr = pdev->base_address[1];
+#endif
+ irq = pdev->irq;
+#else
+ u32 pci_memaddr;
+ u8 pci_irq_line;
+ pcibios_read_config_byte(pci_bus, pci_device_fn,
+ PCI_INTERRUPT_LINE, &pci_irq_line);
+#ifdef VIA_USE_IO
+ pcibios_read_config_dword(pci_bus, pci_device_fn,
+ PCI_BASE_ADDRESS_0, &pci_memaddr);
+ pciaddr = pci_memaddr;
+#else
+ pcibios_read_config_dword(pci_bus, pci_device_fn,
+ PCI_BASE_ADDRESS_1, &pci_memaddr);
+ pciaddr = pci_memaddr;
+#endif
+ irq = pci_irq_line;
+#endif
+ }
+
+ if (debug > 2)
+ printk(KERN_INFO "Found %s at PCI address %#lx, IRQ %d.\n",
+ pci_tbl[chip_idx].name, pciaddr, irq);
+
+ if (pci_tbl[chip_idx].flags & PCI_USES_IO) {
+ if (check_region(pciaddr, pci_tbl[chip_idx].io_size))
+ continue;
+ ioaddr = pciaddr & ~3;
+ } else if ((ioaddr = (long)ioremap(pciaddr & ~0xf,
+ pci_tbl[chip_idx].io_size)) == 0) {
+ printk(KERN_INFO "Failed to map PCI address %#lx.\n",
+ pciaddr);
+ continue;
+ }
+
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, &pci_command);
+ new_command = pci_command | (pci_tbl[chip_idx].flags & 7);
+ if (pci_command != new_command) {
+ printk(KERN_INFO " The PCI BIOS has not enabled the"
+ " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n",
+ pci_bus, pci_device_fn, pci_command, new_command);
+ pcibios_write_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, new_command);
+ }
+
+ dev = pci_tbl[chip_idx].probe1(pci_bus, pci_device_fn, dev, ioaddr,
+ irq, chip_idx, cards_found);
+
+ if (dev && (pci_tbl[chip_idx].flags & PCI_COMMAND_MASTER)) {
+ u8 pci_latency;
+ pcibios_read_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, &pci_latency);
+ if (pci_latency < min_pci_latency) {
+ printk(KERN_INFO " PCI latency timer (CFLT) is "
+ "unreasonably low at %d. Setting to %d clocks.\n",
+ pci_latency, min_pci_latency);
+ pcibios_write_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, min_pci_latency);
+ }
+ }
+ dev = 0;
+ cards_found++;
+ }
+
+ return cards_found ? 0 : -ENODEV;
+}
+
+#ifndef MODULE
+int via_rhine_probe(struct device *dev)
+{
+ return pci_etherdev_probe(dev, pci_tbl);
+}
+#endif
+
+static struct device *via_probe1(int pci_bus, int pci_devfn,
+ struct device *dev, long ioaddr, int irq,
+ int chip_id, int card_idx)
+{
+ static int did_version = 0; /* Already printed version info */
+ struct netdev_private *np;
+ int i, option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+
+ if (debug > 0 && did_version++ == 0)
+ printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+
+ dev = init_etherdev(dev, 0);
+
+ printk(KERN_INFO "%s: %s at 0x%lx, ",
+ dev->name, pci_tbl[chip_id].name, ioaddr);
+
+ /* Ideally we would be read the EEPROM but access may be locked. */
+ for (i = 0; i <6; i++)
+ dev->dev_addr[i] = readb(ioaddr + StationAddr + i);
+ for (i = 0; i < 5; i++)
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
+
+#ifdef VIA_USE_IO
+ request_region(ioaddr, pci_tbl[chip_id].io_size, dev->name);
+#endif
+
+ /* Reset the chip to erase previous misconfiguration. */
+ writew(CmdReset, ioaddr + ChipCmd);
+
+ dev->base_addr = ioaddr;
+ dev->irq = irq;
+
+ /* Make certain the descriptor lists are cache-aligned. */
+ np = (void *)(((long)kmalloc(sizeof(*np), GFP_KERNEL) + 31) & ~31);
+ memset(np, 0, sizeof(*np));
+ dev->priv = np;
+
+ np->next_module = root_net_dev;
+ root_net_dev = dev;
+
+ np->pci_bus = pci_bus;
+ np->pci_devfn = pci_devfn;
+ np->chip_id = chip_id;
+
+ if (dev->mem_start)
+ option = dev->mem_start;
+
+ /* The lower four bits are the media type. */
+ if (option > 0) {
+ if (option & 0x200)
+ np->full_duplex = 1;
+ np->default_port = option & 15;
+ if (np->default_port)
+ np->medialock = 1;
+ }
+ if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
+ np->full_duplex = 1;
+
+ if (np->full_duplex)
+ np->duplex_lock = 1;
+
+ /* The chip-specific entries in the device structure. */
+ dev->open = &netdev_open;
+ dev->hard_start_xmit = &start_tx;
+ dev->stop = &netdev_close;
+ dev->get_stats = &get_stats;
+ dev->set_multicast_list = &set_rx_mode;
+ dev->do_ioctl = &mii_ioctl;
+
+ if (cap_tbl[np->chip_id].flags & CanHaveMII) {
+ int phy, phy_idx = 0;
+ np->phys[0] = 1; /* Standard for this chip. */
+ for (phy = 1; phy < 32 && phy_idx < 4; phy++) {
+ int mii_status = mdio_read(dev, phy, 1);
+ if (mii_status != 0xffff && mii_status != 0x0000) {
+ np->phys[phy_idx++] = phy;
+ np->advertising = mdio_read(dev, phy, 4);
+ printk(KERN_INFO "%s: MII PHY found at address %d, status "
+ "0x%4.4x advertising %4.4x Link %4.4x.\n",
+ dev->name, phy, mii_status, np->advertising,
+ mdio_read(dev, phy, 5));
+ }
+ }
+ np->mii_cnt = phy_idx;
+ }
+
+ return dev;
+}
+
+
+/* Read and write over the MII Management Data I/O (MDIO) interface. */
+
+static int mdio_read(struct device *dev, int phy_id, int regnum)
+{
+ long ioaddr = dev->base_addr;
+ int boguscnt = 1024;
+
+ /* Wait for a previous command to complete. */
+ while ((readb(ioaddr + MIICmd) & 0x60) && --boguscnt > 0)
+ ;
+ writeb(0x00, ioaddr + MIICmd);
+ writeb(phy_id, ioaddr + MIIPhyAddr);
+ writeb(regnum, ioaddr + MIIRegAddr);
+ writeb(0x40, ioaddr + MIICmd); /* Trigger read */
+ boguscnt = 1024;
+ while ((readb(ioaddr + MIICmd) & 0x40) && --boguscnt > 0)
+ ;
+ return readw(ioaddr + MIIData);
+}
+
+static void mdio_write(struct device *dev, int phy_id, int regnum, int value)
+{
+ long ioaddr = dev->base_addr;
+ int boguscnt = 1024;
+
+ /* Wait for a previous command to complete. */
+ while ((readb(ioaddr + MIICmd) & 0x60) && --boguscnt > 0)
+ ;
+ writeb(0x00, ioaddr + MIICmd);
+ writeb(phy_id, ioaddr + MIIPhyAddr);
+ writeb(regnum, ioaddr + MIIRegAddr);
+ writew(value, ioaddr + MIIData);
+ writeb(0x20, ioaddr + MIICmd); /* Trigger write. */
+ return;
+}
+
+
+static int netdev_open(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int i;
+
+ /* Reset the chip. */
+ writew(CmdReset, ioaddr + ChipCmd);
+
+ if (request_irq(dev->irq, &intr_handler, SA_SHIRQ, dev->name, dev))
+ return -EAGAIN;
+
+ if (debug > 1)
+ printk(KERN_DEBUG "%s: netdev_open() irq %d.\n",
+ dev->name, dev->irq);
+
+ MOD_INC_USE_COUNT;
+
+ init_ring(dev);
+
+ writel(virt_to_bus(np->rx_ring), ioaddr + RxRingPtr);
+ writel(virt_to_bus(np->tx_ring), ioaddr + TxRingPtr);
+
+ for (i = 0; i < 6; i++)
+ writeb(dev->dev_addr[i], ioaddr + StationAddr + i);
+
+ /* Initialize other registers. */
+ writew(0x0006, ioaddr + PCIConfig); /* Tune configuration??? */
+ /* Configure the FIFO thresholds. */
+ writeb(0x20, ioaddr + TxConfig); /* Initial threshold 32 bytes */
+ np->tx_thresh = 0x20;
+ np->rx_thresh = 0x60; /* Written in set_rx_mode(). */
+
+ if (dev->if_port == 0)
+ dev->if_port = np->default_port;
+
+ dev->tbusy = 0;
+ dev->interrupt = 0;
+ np->in_interrupt = 0;
+
+ set_rx_mode(dev);
+
+ dev->start = 1;
+
+ /* Enable interrupts by setting the interrupt mask. */
+ writew(IntrRxDone | IntrRxErr | IntrRxEmpty| IntrRxOverflow| IntrRxDropped|
+ IntrTxDone | IntrTxAbort | IntrTxUnderrun |
+ IntrPCIErr | IntrStatsMax | IntrLinkChange | IntrMIIChange,
+ ioaddr + IntrEnable);
+
+ np->chip_cmd = CmdStart|CmdTxOn|CmdRxOn|CmdNoTxPoll;
+ writew(np->chip_cmd, ioaddr + ChipCmd);
+
+ check_duplex(dev);
+
+ if (debug > 2)
+ printk(KERN_DEBUG "%s: Done netdev_open(), status %4.4x "
+ "MII status: %4.4x.\n",
+ dev->name, readw(ioaddr + ChipCmd),
+ mdio_read(dev, np->phys[0], 1));
+
+ /* Set the timer to check for link beat. */
+ init_timer(&np->timer);
+ np->timer.expires = RUN_AT(1);
+ np->timer.data = (unsigned long)dev;
+ np->timer.function = &netdev_timer; /* timer handler */
+ add_timer(&np->timer);
+
+ return 0;
+}
+
+static void check_duplex(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int mii_reg5 = mdio_read(dev, np->phys[0], 5);
+ int duplex;
+
+ if (np->duplex_lock || mii_reg5 == 0xffff)
+ return;
+ duplex = (mii_reg5 & 0x0100) || (mii_reg5 & 0x01C0) == 0x0040;
+ if (np->full_duplex != duplex) {
+ np->full_duplex = duplex;
+ if (debug)
+ printk(KERN_INFO "%s: Setting %s-duplex based on MII #%d link"
+ " partner capability of %4.4x.\n", dev->name,
+ duplex ? "full" : "half", np->phys[0], mii_reg5);
+ if (duplex)
+ np->chip_cmd |= CmdFDuplex;
+ else
+ np->chip_cmd &= ~CmdFDuplex;
+ writew(np->chip_cmd, ioaddr + ChipCmd);
+ }
+}
+
+static void netdev_timer(unsigned long data)
+{
+ struct device *dev = (struct device *)data;
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ int next_tick = 10*HZ;
+
+ if (debug > 3) {
+ printk(KERN_DEBUG "%s: VIA Rhine monitor tick, status %4.4x.\n",
+ dev->name, readw(ioaddr + IntrStatus));
+ }
+ check_duplex(dev);
+
+ np->timer.expires = RUN_AT(next_tick);
+ add_timer(&np->timer);
+}
+
+static void tx_timeout(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+
+ printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
+ "%4.4x, resetting...\n",
+ dev->name, readw(ioaddr + IntrStatus),
+ mdio_read(dev, np->phys[0], 1));
+
+ /* Perhaps we should reinitialize the hardware here. */
+ dev->if_port = 0;
+ /* Stop and restart the chip's Tx processes . */
+
+ /* Trigger an immediate transmit demand. */
+
+ dev->trans_start = jiffies;
+ np->stats.tx_errors++;
+ return;
+}
+
+
+/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
+static void init_ring(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+
+ np->tx_full = 0;
+ np->cur_rx = np->cur_tx = 0;
+ np->dirty_rx = np->dirty_tx = 0;
+
+ np->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+ np->rx_head_desc = &np->rx_ring[0];
+
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].rx_status = 0;
+ np->rx_ring[i].rx_length = 0;
+ np->rx_ring[i].desc_length = np->rx_buf_sz;
+ np->rx_ring[i].next_desc = virt_to_bus(&np->rx_ring[i+1]);
+ np->rx_skbuff[i] = 0;
+ }
+ /* Mark the last entry as wrapping the ring. */
+ np->rx_ring[i-1].next_desc = virt_to_bus(&np->rx_ring[0]);
+
+ /* Fill in the Rx buffers. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ struct sk_buff *skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[i] = skb;
+ if (skb == NULL)
+ break;
+ skb->dev = dev; /* Mark as being used by this device. */
+ np->rx_ring[i].addr = virt_to_bus(skb->tail);
+ np->rx_ring[i].rx_status = 0;
+ np->rx_ring[i].rx_length = DescOwn;
+ }
+ np->dirty_rx = (unsigned int)(i - RX_RING_SIZE);
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ np->tx_skbuff[i] = 0;
+ np->tx_ring[i].tx_own = 0;
+ np->tx_ring[i].desc_length = 0x00e08000;
+ np->tx_ring[i].next_desc = virt_to_bus(&np->tx_ring[i+1]);
+ np->tx_buf[i] = kmalloc(PKT_BUF_SZ, GFP_KERNEL);
+ }
+ np->tx_ring[i-1].next_desc = virt_to_bus(&np->tx_ring[0]);
+
+ return;
+}
+
+static int start_tx(struct sk_buff *skb, struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ unsigned entry;
+
+ /* Block a timer-based transmit from overlapping. This could better be
+ done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
+ if (test_and_set_bit(0, (void*)&dev->tbusy) != 0) {
+ if (jiffies - dev->trans_start < TX_TIMEOUT)
+ return 1;
+ tx_timeout(dev);
+ return 1;
+ }
+
+ /* Caution: the write order is important here, set the field
+ with the "ownership" bits last. */
+
+ /* Calculate the next Tx descriptor entry. */
+ entry = np->cur_tx % TX_RING_SIZE;
+
+ np->tx_skbuff[entry] = skb;
+
+ if ((long)skb->data & 3) { /* Must use alignment buffer. */
+ if (np->tx_buf[entry] == NULL &&
+ (np->tx_buf[entry] = kmalloc(PKT_BUF_SZ, GFP_KERNEL)) == NULL)
+ return 1;
+ memcpy(np->tx_buf[entry], skb->data, skb->len);
+ np->tx_ring[entry].addr = virt_to_bus(np->tx_buf[entry]);
+ } else
+ np->tx_ring[entry].addr = virt_to_bus(skb->data);
+
+ np->tx_ring[entry].desc_length = 0x00E08000 |
+ (skb->len >= ETH_ZLEN ? skb->len : ETH_ZLEN);
+ np->tx_ring[entry].tx_own = DescOwn;
+
+ np->cur_tx++;
+
+ /* Non-x86 Todo: explicitly flush cache lines here. */
+
+ /* Wake the potentially-idle transmit channel. */
+ writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+
+ if (np->cur_tx - np->dirty_tx < TX_RING_SIZE - 1)
+ clear_bit(0, (void*)&dev->tbusy); /* Typical path */
+ else
+ np->tx_full = 1;
+ dev->trans_start = jiffies;
+
+ if (debug > 4) {
+ printk(KERN_DEBUG "%s: Transmit frame #%d queued in slot %d.\n",
+ dev->name, np->cur_tx, entry);
+ }
+ return 0;
+}
+
+/* The interrupt handler does all of the Rx thread work and cleans up
+ after the Tx thread. */
+static void intr_handler(int irq, void *dev_instance, struct pt_regs *rgs)
+{
+ struct device *dev = (struct device *)dev_instance;
+ struct netdev_private *np;
+ long ioaddr, boguscnt = max_interrupt_work;
+
+ ioaddr = dev->base_addr;
+ np = (struct netdev_private *)dev->priv;
+#if defined(__i386__)
+ /* A lock to prevent simultaneous entry bug on Intel SMP machines. */
+ if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+ printk(KERN_ERR"%s: SMP simultaneous entry of an interrupt handler.\n",
+ dev->name);
+ dev->interrupt = 0; /* Avoid halting machine. */
+ return;
+ }
+#else
+ if (dev->interrupt) {
+ printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
+ return;
+ }
+ dev->interrupt = 1;
+#endif
+
+ do {
+ u32 intr_status = readw(ioaddr + IntrStatus);
+
+ /* Acknowledge all of the current interrupt sources ASAP. */
+ writew(intr_status & 0xffff, ioaddr + IntrStatus);
+
+ if (debug > 4)
+ printk(KERN_DEBUG "%s: Interrupt, status %4.4x.\n",
+ dev->name, intr_status);
+
+ if (intr_status == 0)
+ break;
+
+ if (intr_status & (IntrRxDone | IntrRxErr | IntrRxDropped |
+ IntrRxWakeUp | IntrRxEmpty | IntrRxNoBuf))
+ netdev_rx(dev);
+
+ for (; np->cur_tx - np->dirty_tx > 0; np->dirty_tx++) {
+ int entry = np->dirty_tx % TX_RING_SIZE;
+ int txstatus;
+ if (np->tx_ring[entry].tx_own)
+ break;
+ txstatus = np->tx_ring[entry].tx_status;
+ if (debug > 6)
+ printk(KERN_DEBUG " Tx scavenge %d status %4.4x.\n",
+ entry, txstatus);
+ if (txstatus & 0x8000) {
+ if (debug > 1)
+ printk(KERN_DEBUG "%s: Transmit error, Tx status %4.4x.\n",
+ dev->name, txstatus);
+ np->stats.tx_errors++;
+ if (txstatus & 0x0400) np->stats.tx_carrier_errors++;
+ if (txstatus & 0x0200) np->stats.tx_window_errors++;
+ if (txstatus & 0x0100) np->stats.tx_aborted_errors++;
+ if (txstatus & 0x0080) np->stats.tx_heartbeat_errors++;
+ if (txstatus & 0x0002) np->stats.tx_fifo_errors++;
+#ifdef ETHER_STATS
+ if (txstatus & 0x0100) np->stats.collisions16++;
+#endif
+ /* Transmitter restarted in 'abnormal' handler. */
+ } else {
+#ifdef ETHER_STATS
+ if (txstatus & 0x0001) np->stats.tx_deferred++;
+#endif
+ np->stats.collisions += (txstatus >> 3) & 15;
+#if defined(NETSTATS_VER2)
+ np->stats.tx_bytes += np->tx_ring[entry].desc_length & 0x7ff;
+#endif
+ np->stats.tx_packets++;
+ }
+ /* Free the original skb. */
+ dev_free_skb(np->tx_skbuff[entry]);
+ np->tx_skbuff[entry] = 0;
+ }
+ if (np->tx_full && dev->tbusy
+ && np->cur_tx - np->dirty_tx < TX_RING_SIZE - 4) {
+ /* The ring is no longer full, clear tbusy. */
+ np->tx_full = 0;
+ clear_bit(0, (void*)&dev->tbusy);
+ mark_bh(NET_BH);
+ }
+
+ /* Abnormal error summary/uncommon events handlers. */
+ if (intr_status & (IntrPCIErr | IntrLinkChange | IntrMIIChange |
+ IntrStatsMax | IntrTxAbort | IntrTxUnderrun))
+ netdev_error(dev, intr_status);
+
+ if (--boguscnt < 0) {
+ printk(KERN_WARNING "%s: Too much work at interrupt, "
+ "status=0x%4.4x.\n",
+ dev->name, intr_status);
+ break;
+ }
+ } while (1);
+
+ if (debug > 3)
+ printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
+ dev->name, readw(ioaddr + IntrStatus));
+
+#if defined(__i386__)
+ clear_bit(0, (void*)&dev->interrupt);
+#else
+ dev->interrupt = 0;
+#endif
+ return;
+}
+
+/* This routine is logically part of the interrupt handler, but isolated
+ for clarity and better register allocation. */
+static int netdev_rx(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int entry = np->cur_rx % RX_RING_SIZE;
+ int boguscnt = np->dirty_rx + RX_RING_SIZE - np->cur_rx;
+
+ if (debug > 4) {
+ printk(KERN_DEBUG " In netdev_rx(), entry %d status %4.4x.\n",
+ entry, np->rx_head_desc->rx_length);
+ }
+
+ /* If EOP is set on the next entry, it's a new packet. Send it up. */
+ while ( ! (np->rx_head_desc->rx_length & DescOwn)) {
+ struct rx_desc *desc = np->rx_head_desc;
+ int data_size = desc->rx_length;
+ u16 desc_status = desc->rx_status;
+
+ if (debug > 4)
+ printk(KERN_DEBUG " netdev_rx() status is %4.4x.\n",
+ desc_status);
+ if (--boguscnt < 0)
+ break;
+ if ( (desc_status & (RxWholePkt | RxErr)) != RxWholePkt) {
+ if ((desc_status & RxWholePkt) != RxWholePkt) {
+ printk(KERN_WARNING "%s: Oversized Ethernet frame spanned "
+ "multiple buffers, entry %#x length %d status %4.4x!\n",
+ dev->name, np->cur_rx, data_size, desc_status);
+ printk(KERN_WARNING "%s: Oversized Ethernet frame %p vs %p.\n",
+ dev->name, np->rx_head_desc,
+ &np->rx_ring[np->cur_rx % RX_RING_SIZE]);
+ np->stats.rx_length_errors++;
+ } else if (desc_status & RxErr) {
+ /* There was a error. */
+ if (debug > 2)
+ printk(KERN_DEBUG " netdev_rx() Rx error was %8.8x.\n",
+ desc_status);
+ np->stats.rx_errors++;
+ if (desc_status & 0x0030) np->stats.rx_length_errors++;
+ if (desc_status & 0x0048) np->stats.rx_fifo_errors++;
+ if (desc_status & 0x0004) np->stats.rx_frame_errors++;
+ if (desc_status & 0x0002) np->stats.rx_crc_errors++;
+ }
+ } else {
+ struct sk_buff *skb;
+ /* Length should omit the CRC */
+ u16 pkt_len = data_size - 4;
+
+ /* Check if the packet is long enough to accept without copying
+ to a minimally-sized skbuff. */
+ if (pkt_len < rx_copybreak
+ && (skb = dev_alloc_skb(pkt_len + 2)) != NULL) {
+ skb->dev = dev;
+ skb_reserve(skb, 2); /* 16 byte align the IP header */
+#if ! defined(__alpha__) || USE_IP_COPYSUM /* Avoid misaligned on Alpha */
+ eth_copy_and_sum(skb, bus_to_virt(desc->addr),
+ pkt_len, 0);
+ skb_put(skb, pkt_len);
+#else
+ memcpy(skb_put(skb,pkt_len), bus_to_virt(desc->addr), pkt_len);
+#endif
+ } else {
+ skb_put(skb = np->rx_skbuff[entry], pkt_len);
+ np->rx_skbuff[entry] = NULL;
+ }
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_rx(skb);
+ dev->last_rx = jiffies;
+ np->stats.rx_packets++;
+ }
+ entry = (++np->cur_rx) % RX_RING_SIZE;
+ np->rx_head_desc = &np->rx_ring[entry];
+ }
+
+ /* Refill the Rx ring buffers. */
+ for (; np->cur_rx - np->dirty_rx > 0; np->dirty_rx++) {
+ struct sk_buff *skb;
+ entry = np->dirty_rx % RX_RING_SIZE;
+ if (np->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(np->rx_buf_sz);
+ np->rx_skbuff[entry] = skb;
+ if (skb == NULL)
+ break; /* Better luck next round. */
+ skb->dev = dev; /* Mark as being used by this device. */
+ np->rx_ring[entry].addr = virt_to_bus(skb->tail);
+ }
+ np->rx_ring[entry].rx_status = 0;
+ np->rx_ring[entry].rx_length = DescOwn;
+ }
+
+ /* Pre-emptively restart Rx engine. */
+ writew(CmdRxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+ return 0;
+}
+
+static void netdev_error(struct device *dev, int intr_status)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+
+ if (intr_status & (IntrMIIChange | IntrLinkChange)) {
+ if (readb(ioaddr + MIIStatus) & 0x02)
+ /* Link failed, restart autonegotiation. */
+ mdio_write(dev, np->phys[0], 0, 0x3300);
+ else
+ check_duplex(dev);
+ if (debug)
+ printk(KERN_ERR "%s: MII status changed: Autonegotiation "
+ "advertising %4.4x partner %4.4x.\n", dev->name,
+ mdio_read(dev, np->phys[0], 4),
+ mdio_read(dev, np->phys[0], 5));
+ }
+ if (intr_status & IntrStatsMax) {
+ np->stats.rx_crc_errors += readw(ioaddr + RxCRCErrs);
+ np->stats.rx_missed_errors += readw(ioaddr + RxMissed);
+ writel(0, RxMissed);
+ }
+ if (intr_status & IntrTxAbort) {
+ /* Stats counted in Tx-done handler, just restart Tx. */
+ writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+ }
+ if (intr_status & IntrTxUnderrun) {
+ if (np->tx_thresh < 0xE0)
+ writeb(np->tx_thresh += 0x20, ioaddr + TxConfig);
+ if (debug > 1)
+ printk(KERN_INFO "%s: Transmitter underrun, increasing Tx "
+ "threshold setting to %2.2x.\n", dev->name, np->tx_thresh);
+ }
+ if ((intr_status & ~(IntrLinkChange|IntrStatsMax|IntrTxAbort)) && debug) {
+ printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
+ dev->name, intr_status);
+ /* Recovery for other fault sources not known. */
+ writew(CmdTxDemand | np->chip_cmd, dev->base_addr + ChipCmd);
+ }
+}
+
+static struct enet_statistics *get_stats(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+
+ /* Nominally we should lock this segment of code for SMP, although
+ the vulnerability window is very small and statistics are
+ non-critical. */
+ np->stats.rx_crc_errors += readw(ioaddr + RxCRCErrs);
+ np->stats.rx_missed_errors += readw(ioaddr + RxMissed);
+ writel(0, RxMissed);
+
+ return &np->stats;
+}
+
+/* The big-endian AUTODIN II ethernet CRC calculation.
+ N.B. Do not use for bulk data, use a table-based routine instead.
+ This is common code and should be moved to net/core/crc.c */
+static unsigned const ethernet_polynomial = 0x04c11db7U;
+static inline u32 ether_crc(int length, unsigned char *data)
+{
+ int crc = -1;
+
+ while(--length >= 0) {
+ unsigned char current_octet = *data++;
+ int bit;
+ for (bit = 0; bit < 8; bit++, current_octet >>= 1) {
+ crc = (crc << 1) ^
+ ((crc < 0) ^ (current_octet & 1) ? ethernet_polynomial : 0);
+ }
+ }
+ return crc;
+}
+
+static void set_rx_mode(struct device *dev)
+{
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ long ioaddr = dev->base_addr;
+ u32 mc_filter[2]; /* Multicast hash filter */
+ u8 rx_mode; /* Note: 0x02=accept runt, 0x01=accept errs */
+
+ if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
+ /* Unconditionally log net taps. */
+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
+ rx_mode = 0x1C;
+ } else if ((dev->mc_count > multicast_filter_limit)
+ || (dev->flags & IFF_ALLMULTI)) {
+ /* Too many to match, or accept all multicasts. */
+ rx_mode = 0x0C;
+ } else {
+ struct dev_mc_list *mclist;
+ int i;
+ memset(mc_filter, 0, sizeof(mc_filter));
+ for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
+ i++, mclist = mclist->next) {
+ set_bit(ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26,
+ mc_filter);
+ }
+ writel(mc_filter[0], ioaddr + MulticastFilter0);
+ writel(mc_filter[1], ioaddr + MulticastFilter1);
+ rx_mode = 0x0C;
+ }
+ writeb(np->rx_thresh | rx_mode, ioaddr + RxConfig);
+}
+
+static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+ u16 *data = (u16 *)&rq->ifr_data;
+
+ switch(cmd) {
+ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
+ data[0] = ((struct netdev_private *)dev->priv)->phys[0] & 0x1f;
+ /* Fall Through */
+ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
+ data[3] = mdio_read(dev, data[0] & 0x1f, data[1] & 0x1f);
+ return 0;
+ case SIOCDEVPRIVATE+2: /* Write the specified MII register */
+ if (!suser())
+ return -EPERM;
+ mdio_write(dev, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int netdev_close(struct device *dev)
+{
+ long ioaddr = dev->base_addr;
+ struct netdev_private *np = (struct netdev_private *)dev->priv;
+ int i;
+
+ dev->start = 0;
+ dev->tbusy = 1;
+
+ if (debug > 1)
+ printk(KERN_DEBUG "%s: Shutting down ethercard, status was %4.4x.\n",
+ dev->name, readw(ioaddr + ChipCmd));
+
+ /* Disable interrupts by clearing the interrupt mask. */
+ writew(0x0000, ioaddr + IntrEnable);
+
+ /* Stop the chip's Tx and Rx processes. */
+ writew(CmdStop, ioaddr + ChipCmd);
+
+ del_timer(&np->timer);
+
+ free_irq(dev->irq, dev);
+
+ /* Free all the skbuffs in the Rx queue. */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ np->rx_ring[i].rx_length = 0;
+ np->rx_ring[i].addr = 0xBADF00D0; /* An invalid address. */
+ if (np->rx_skbuff[i]) {
+#if LINUX_VERSION_CODE < 0x20100
+ np->rx_skbuff[i]->free = 1;
+#endif
+ dev_free_skb(np->rx_skbuff[i]);
+ }
+ np->rx_skbuff[i] = 0;
+ }
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ if (np->tx_skbuff[i])
+ dev_free_skb(np->tx_skbuff[i]);
+ np->tx_skbuff[i] = 0;
+ }
+
+ MOD_DEC_USE_COUNT;
+
+ return 0;
+}
+
+
+#ifdef MODULE
+int init_module(void)
+{
+ if (debug) /* Emit version even if no cards detected. */
+ printk(KERN_INFO "%s" KERN_INFO "%s", versionA, versionB);
+#ifdef CARDBUS
+ register_driver(&etherdev_ops);
+ return 0;
+#else
+ return pci_etherdev_probe(NULL, pci_tbl);
+#endif
+}
+
+void cleanup_module(void)
+{
+
+#ifdef CARDBUS
+ unregister_driver(&etherdev_ops);
+#endif
+
+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */
+ while (root_net_dev) {
+ struct netdev_private *np =
+ (struct netdev_private *)(root_net_dev->priv);
+ unregister_netdev(root_net_dev);
+#ifdef VIA_USE_IO
+ release_region(root_net_dev->base_addr, pci_tbl[np->chip_id].io_size);
+#else
+ iounmap((char *)(root_net_dev->base_addr));
+#endif
+ kfree(root_net_dev);
+ root_net_dev = np->next_module;
+#if 0
+ kfree(np); /* Assumption: no struct realignment. */
+#endif
+ }
+}
+
+#endif /* MODULE */
+
+/*
+ * Local variables:
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c via-rhine.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
+ * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c via-rhine.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
+ * c-indent-level: 4
+ * c-basic-offset: 4
+ * tab-width: 4
+ * End:
+ */
diff --git a/drivers/net/wavelan.c b/drivers/net/wavelan.c
index 0c46649d3..6e1cb958f 100644
--- a/drivers/net/wavelan.c
+++ b/drivers/net/wavelan.c
@@ -2950,8 +2950,8 @@ wv_mmc_init(device * dev)
/* Attempt to recognise 2.00 cards (2.4 GHz frequency selectable)
* Does it work for everybody, especially old cards? */
/* Note: WFREQSEL verifies that it is able to read a sensible
- * frequency from from EEPROM (address 0x00) and that
- * MMR_FEE_STATUS_ID is 0xA (Xilinx version) or 0xB (Ariadne version).
+ * frequency from EEPROM (address 0x00) and that MMR_FEE_STATUS_ID
+ * is 0xA (Xilinx version) or 0xB (Ariadne version).
* My test is more crude but does work. */
if(!(mmc_in(ioaddr, mmroff(0, mmr_fee_status)) &
(MMR_FEE_STATUS_DWLD | MMR_FEE_STATUS_BUSY)))
diff --git a/drivers/net/yellowfin.c b/drivers/net/yellowfin.c
index 93f5f7ea7..3411fd189 100644
--- a/drivers/net/yellowfin.c
+++ b/drivers/net/yellowfin.c
@@ -1,11 +1,12 @@
/* yellowfin.c: A Packet Engines G-NIC ethernet driver for linux. */
/*
- Written 1997 by Donald Becker.
+ Written 1997-1998 by Donald Becker.
This software may be used and distributed according to the terms
of the GNU Public License, incorporated herein by reference.
This driver is for the Packet Engines G-NIC PCI Gigabit Ethernet adapter.
+ It also supports the Symbios Logic version of the same chip core.
The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O
Center of Excellence in Space Data and Information Sciences
@@ -15,7 +16,9 @@
http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html
*/
-static const char *version = "yellowfin.c:v0.10 12/5/97 becker@cesdis.gsfc.nasa.gov\n";
+static const char *version =
+"yellowfin.c:v1.02 7/26/98 Written by Donald Becker, becker@cesdis.edu\n"
+" http://cesdis.gsfc.nasa.gov/linux/drivers/yellowfin.html\n";
/* A few user-configurable values. */
@@ -27,7 +30,7 @@ static int mtu = 0;
static int bogus_rx = 0;
static int dma_ctrl = 0x004A0263; /* Constrained by errata */
static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */
-#elif YF_NEW
+#elif YF_NEW /* A future perfect board :->. */
static int dma_ctrl = 0x00CAC277; /* Override when loading module! */
static int fifo_cfg = 0x0028;
#else
@@ -36,8 +39,18 @@ static int fifo_cfg = 0x0020; /* Bypass external Tx FIFO. */
#endif
/* Set the copy breakpoint for the copy-only-tiny-frames scheme.
- Setting to > 1518 effectively disables this feature. */
-static const int rx_copybreak = 100;
+ Setting to > 1514 effectively disables this feature. */
+static int rx_copybreak = 0;
+
+/* Used to pass the media type, etc.
+ No media types are currently defined. These exist for driver
+ interoperability.
+*/
+#define MAX_UNITS 8 /* More are supported, limit only on options */
+static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+
+/* Operational parameters that are set at compile time. */
/* Keep the ring sizes a power of two for efficiency.
Making the Tx ring too large decreases the effectiveness of channel
@@ -50,7 +63,6 @@ static const int rx_copybreak = 100;
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT ((2000*HZ)/1000)
-#include <linux/config.h>
#ifdef MODULE
#ifdef MODVERSIONS
#include <linux/modversions.h>
@@ -80,68 +92,35 @@ static const int rx_copybreak = 100;
#include <linux/etherdevice.h>
#include <linux/skbuff.h>
-/* Kernel compatibility defines, common to David Hind's PCMCIA package.
- This is only in the support-all-kernels source code. */
+/* Kernel compatibility defines, most common to the PCCard package. */
#include <linux/version.h> /* Evil, but neccessary */
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10300
-#define RUN_AT(x) (x) /* What to put in timer->expires. */
-#define DEV_ALLOC_SKB(len) alloc_skb(len, GFP_ATOMIC)
-#define virt_to_bus(addr) ((unsigned long)addr)
-#define bus_to_virt(addr) ((void*)addr)
-
-#else /* 1.3.0 and later */
#define RUN_AT(x) (jiffies + (x))
-#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2)
-#endif
-#if defined (LINUX_VERSION_CODE) && LINUX_VERSION_CODE < 0x10338
-#ifdef MODULE
-#if !defined(CONFIG_MODVERSIONS) && !defined(__NO_VERSION__)
+#if (LINUX_VERSION_CODE >= 0x20100)
char kernel_version[] = UTS_RELEASE;
#endif
-#else
-#undef MOD_INC_USE_COUNT
-#define MOD_INC_USE_COUNT
-#undef MOD_DEC_USE_COUNT
-#define MOD_DEC_USE_COUNT
+#if (LINUX_VERSION_CODE < 0x20123)
+#define test_and_set_bit(val, addr) set_bit(val, addr)
#endif
-#endif /* 1.3.38 */
-
-#if (LINUX_VERSION_CODE >= 0x10344)
-#define NEW_MULTICAST
-#include <linux/delay.h>
+#if LINUX_VERSION_CODE <= 0x20139
+#define net_device_stats enet_statistics
+#define NETSTATS_VER2
#endif
-#if (LINUX_VERSION_CODE >= 0x20100)
-#ifdef MODULE
-char kernel_version[] = UTS_RELEASE;
+#if LINUX_VERSION_CODE < 0x20155
+#define PCI_SUPPORT_VER1
+#define pci_present pcibios_present
#endif
-#endif
-#ifdef SA_SHIRQ
-#define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs)
+#if LINUX_VERSION_CODE < 0x20159
+#define DEV_FREE_SKB(skb) dev_kfree_skb(skb, FREE_WRITE);
#else
-#define IRQ(irq, dev_id, pt_regs) (irq, pt_regs)
+#define DEV_FREE_SKB(skb) dev_kfree_skb(skb);
#endif
-#if (LINUX_VERSION_CODE < 0x20123)
-#define test_and_set_bit(val, addr) set_bit(val, addr)
-#include <linux/bios32.h>
-#endif
-
-static const char *card_name = "Yellowfin G-NIC Gbit Ethernet";
/* The PCI I/O space extent. */
#define YELLOWFIN_TOTAL_SIZE 0x100
-#ifdef HAVE_DEVLIST
-struct netdev_entry yellowfin_drv =
-{card_name, yellowfin_pci_probe, YELLOWFIN_TOTAL_SIZE, NULL};
-#endif
-
-#ifdef YELLOWFIN_DEBUG
-int yellowfin_debug = YELLOWFIN_DEBUG;
-#else
int yellowfin_debug = 1;
-#endif
/*
Theory of Operation
@@ -204,15 +183,20 @@ clears both the tx_full and tbusy flags.
IV. Notes
Thanks to Kim Stearns of Packet Engines for providing a pair of G-NIC boards.
+Thanks to Bruce Faust of Digitalscape for providing both their SYM53C885 board
+and an AlphaStation to verifty the Alpha port!
IVb. References
Yellowfin Engineering Design Specification, 4/23/97 Preliminary/Confidential
+Symbios SYM53C885 PCI-SCSI/Fast Ethernet Multifunction Controller Preliminary
+ Data Manual v3.0
+http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
IVc. Errata
-See Packet Engines confidential appendix.
+See Packet Engines confidential appendix (prototype chips only).
*/
@@ -221,6 +205,7 @@ See Packet Engines confidential appendix.
#ifndef PCI_VENDOR_ID_PKT_ENG /* To be defined in linux/pci.h */
#define PCI_VENDOR_ID_PKT_ENG 0x1000 /* Hmm, likely number.. */
+#define PCI_DEVICE_ID_SYM58C885 0x0701
#define PCI_DEVICE_ID_YELLOWFIN 0x0702
#endif
@@ -228,6 +213,21 @@ See Packet Engines confidential appendix.
static void yellowfin_timer(unsigned long data);
+enum capability_flags {HasMII=1, FullTxStatus=2};
+struct chip_info {
+ u16 vendor_id, device_id, device_id_mask, pci_flags;
+ const char *name;
+ void (*media_timer)(unsigned long data);
+ u32 chip_rev; /* As read from ChipRev, not PCI dev ID. */
+ int flags;
+} chip_tbl[] = {
+ {0x1000, 0x0702, 0xffff, 0, "Yellowfin G-NIC Gbit Ethernet",
+ yellowfin_timer, 0x0702, FullTxStatus},
+ {0x1000, 0x0701, 0xffff, 0, "Symbios SYM83C885",
+ yellowfin_timer, 0x0701, HasMII},
+ {0,},
+};
+
/* Offsets to the Yellowfin registers. Various sizes and alignments. */
enum yellowfin_offsets {
TxCtrl=0x00, TxStatus=0x04, TxPtr=0x0C,
@@ -235,8 +235,13 @@ enum yellowfin_offsets {
RxCtrl=0x40, RxStatus=0x44, RxPtr=0x4C,
RxIntrSel=0x50, RxBranchSel=0x54, RxWaitSel=0x58,
EventStatus=0x80, IntrEnb=0x82, IntrClear=0x84, IntrStatus=0x86,
- ChipRev=0x8C, DMACtrl=0x90, Cnfg=0xA0, RxDepth=0xB8, FlowCtrl=0xBC,
+ ChipRev=0x8C, DMACtrl=0x90, Cnfg=0xA0, FrameGap0=0xA2, FrameGap1=0xA4,
+ MII_Cmd=0xA6, MII_Addr=0xA8, MII_Wr_Data=0xAA, MII_Rd_Data=0xAC,
+ MII_Status=0xAE,
+ RxDepth=0xB8, FlowCtrl=0xBC,
AddrMode=0xD0, StnAddr=0xD2, HashTbl=0xD8, FIFOcfg=0xF8,
+ EEStatus=0xF0, EECtrl=0xF1, EEAddr=0xF2, EERead=0xF3, EEWrite=0xF4,
+ EEFeature=0xF5,
};
/* The Yellowfin Rx and Tx buffer descriptors. */
@@ -280,27 +285,34 @@ struct yellowfin_private {
struct yellowfin_desc tx_ring[TX_RING_SIZE*2];
const char *product_name;
struct device *next_module;
+ /* The addresses of receive-in-place skbuffs. */
+ struct sk_buff* rx_skbuff[RX_RING_SIZE];
/* The saved address of a sent-in-place packet/buffer, for skfree(). */
struct sk_buff* tx_skbuff[TX_RING_SIZE];
struct tx_status_words tx_status[TX_RING_SIZE];
- /* The addresses of receive-in-place skbuffs. */
- struct sk_buff* rx_skbuff[RX_RING_SIZE];
- int chip_id;
- struct enet_statistics stats;
struct timer_list timer; /* Media selection timer. */
- unsigned int cur_rx, cur_tx; /* The next free ring entry */
- unsigned int dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
+ struct enet_statistics stats;
+ /* Frequently used and paired value: keep adjacent for cache effect. */
+ int chip_id;
+ int in_interrupt;
+ struct yellowfin_desc *rx_head_desc;
+ struct tx_status_words *tx_tail_desc;
+ unsigned int cur_rx, dirty_rx; /* Producer/consumer ring indices */
+ unsigned int cur_tx, dirty_tx;
+ unsigned int rx_buf_sz; /* Based on MTU+slack. */
unsigned int tx_full:1; /* The Tx queue is full. */
unsigned int full_duplex:1; /* Full-duplex operation requested. */
+ unsigned int duplex_lock:1;
unsigned int medialock:1; /* Do not sense media. */
unsigned int default_port:4; /* Last dev->if_port value. */
+ /* MII transceiver section. */
+ int mii_cnt; /* MII device addresses. */
+ u16 advertising; /* NWay media advertisement */
+ unsigned char phys[2]; /* MII device addresses. */
u32 pad[4]; /* Used for 32-byte alignment */
};
#ifdef MODULE
-/* Used to pass the media type, etc. */
-#define MAX_UNITS 8 /* More are supported, limit only on options */
-static int options[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
#if LINUX_VERSION_CODE > 0x20115
MODULE_AUTHOR("Donald Becker <becker@cesdis.gsfc.nasa.gov>");
@@ -311,169 +323,163 @@ MODULE_PARM(mtu, "i");
MODULE_PARM(debug, "i");
MODULE_PARM(rx_copybreak, "i");
MODULE_PARM(options, "1-" __MODULE_STRING(MAX_UNITS) "i");
+MODULE_PARM(full_duplex, "1-" __MODULE_STRING(MAX_UNITS) "i");
#endif
#endif
-static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq,
- int chip_id, int options);
+static struct device *yellowfin_probe1(struct device *dev, long ioaddr,
+ int irq, int chip_id, int options);
+static int read_eeprom(long ioaddr, int location);
+static int mdio_read(long ioaddr, int phy_id, int location);
+static void mdio_write(long ioaddr, int phy_id, int location, int value);
+#ifdef HAVE_PRIVATE_IOCTL
+static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd);
+#endif
static int yellowfin_open(struct device *dev);
static void yellowfin_timer(unsigned long data);
static void yellowfin_tx_timeout(struct device *dev);
static void yellowfin_init_ring(struct device *dev);
static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev);
+static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
static int yellowfin_rx(struct device *dev);
-static void yellowfin_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs);
+static void yellowfin_error(struct device *dev, int intr_status);
static int yellowfin_close(struct device *dev);
static struct enet_statistics *yellowfin_get_stats(struct device *dev);
-#ifdef NEW_MULTICAST
static void set_rx_mode(struct device *dev);
-#else
-static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
-#endif
-#ifdef MODULE
/* A list of all installed Yellowfin devices, for removing the driver module. */
static struct device *root_yellowfin_dev = NULL;
-#endif
int yellowfin_probe(struct device *dev)
{
int cards_found = 0;
- static int pci_index = 0; /* Static, for multiple probe calls. */
-
- /* Ideally we would detect all network cards in slot order. That would
- be best done a central PCI probe dispatch, which wouldn't work
- well with the current structure. So instead we detect just the
- Yellowfin cards in slot order. */
+ int pci_index = 0;
+ unsigned char pci_bus, pci_device_fn;
+
+ if ( ! pci_present())
+ return -ENODEV;
+
+ for (;pci_index < 0xff; pci_index++) {
+ u8 pci_latency;
+ u16 pci_command, new_command, vendor, device;
+ int chip_idx;
+ int irq;
+ long ioaddr;
+
+ if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
+ pci_index,
+ &pci_bus, &pci_device_fn)
+ != PCIBIOS_SUCCESSFUL)
+ break;
- if (pci_present()) {
- unsigned char pci_bus, pci_device_fn;
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_VENDOR_ID, &vendor);
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_DEVICE_ID, &device);
- for (;pci_index < 0xff; pci_index++) {
-#if LINUX_VERSION_CODE >= 0x20155
- unsigned int pci_irq_line;
- struct pci_dev *pdev;
-#else
- unsigned char pci_irq_line;
-#endif
- unsigned char pci_latency;
- unsigned short pci_command, vendor, device;
- unsigned int pci_ioaddr, chip_idx = 0;
-
-#ifdef REVERSE_PROBE_ORDER
- if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
- 0xfe - pci_index,
- &pci_bus, &pci_device_fn)
- != PCIBIOS_SUCCESSFUL)
- continue;
-#else
- if (pcibios_find_class (PCI_CLASS_NETWORK_ETHERNET << 8,
- pci_index,
- &pci_bus, &pci_device_fn)
- != PCIBIOS_SUCCESSFUL)
+ for (chip_idx = 0; chip_tbl[chip_idx].vendor_id; chip_idx++)
+ if (vendor == chip_tbl[chip_idx].vendor_id
+ && (device & chip_tbl[chip_idx].device_id_mask) ==
+ chip_tbl[chip_idx].device_id)
break;
-#endif
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_VENDOR_ID, &vendor);
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_DEVICE_ID, &device);
-#if LINUX_VERSION_CODE >= 0x20155
- pdev = pci_find_slot(pci_bus, pci_device_fn);
- pci_irq_line = pdev->irq;
- pci_ioaddr = pdev->base_address[0];
+ if (chip_tbl[chip_idx].vendor_id == 0) /* Compiled out! */
+ continue;
+
+ {
+#if LINUX_VERSION_CODE >= 0x20155 || PCI_SUPPORT_1
+ struct pci_dev *pdev = pci_find_slot(pci_bus, pci_device_fn);
+ ioaddr = pdev->base_address[0];
+ irq = pdev->irq;
#else
+ u32 pci_ioaddr;
+ u8 pci_irq_line;
pcibios_read_config_byte(pci_bus, pci_device_fn,
PCI_INTERRUPT_LINE, &pci_irq_line);
pcibios_read_config_dword(pci_bus, pci_device_fn,
PCI_BASE_ADDRESS_0, &pci_ioaddr);
+ ioaddr = pci_ioaddr;
+ irq = pci_irq_line;
#endif
- /* Remove I/O space marker in bit 0. */
- pci_ioaddr &= ~3;
-
- if (vendor != PCI_VENDOR_ID_PKT_ENG)
- continue;
-
- if (device != PCI_DEVICE_ID_YELLOWFIN)
- continue;
-
- if (yellowfin_debug > 2)
- printk("Found Packet Engines Yellowfin G-NIC at I/O %#x, IRQ %d.\n",
- pci_ioaddr, pci_irq_line);
+ }
+ /* Remove I/O space marker in bit 0. */
+ ioaddr &= ~3;
+
+ if (yellowfin_debug > 2)
+ printk(KERN_INFO "Found %s at I/O %#lx, IRQ %d.\n",
+ chip_tbl[chip_idx].name, ioaddr, irq);
+
+ if (check_region(ioaddr, YELLOWFIN_TOTAL_SIZE))
+ continue;
+
+ pcibios_read_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, &pci_command);
+ new_command = pci_command | PCI_COMMAND_MASTER|PCI_COMMAND_IO;
+ if (pci_command != new_command) {
+ printk(KERN_INFO " The PCI BIOS has not enabled the"
+ " device at %d/%d! Updating PCI command %4.4x->%4.4x.\n",
+ pci_bus, pci_device_fn, pci_command, new_command);
+ pcibios_write_config_word(pci_bus, pci_device_fn,
+ PCI_COMMAND, new_command);
+ }
- if (check_region(pci_ioaddr, YELLOWFIN_TOTAL_SIZE))
- continue;
+ dev = yellowfin_probe1(dev, ioaddr, irq, chip_idx, cards_found);
-#ifdef MODULE
- dev = yellowfin_probe1(dev, pci_ioaddr, pci_irq_line, chip_idx,
- cards_found < MAX_UNITS ? options[cards_found] : 0);
-#else
- dev = yellowfin_probe1(dev, pci_ioaddr, pci_irq_line, chip_idx,
- dev ? dev->mem_start : 0);
-#endif
-
- if (dev) {
- /* Get and check the bus-master and latency values. */
- pcibios_read_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, &pci_command);
- if ( ! (pci_command & PCI_COMMAND_MASTER)) {
- printk(" PCI Master Bit has not been set! Setting...\n");
- pci_command |= PCI_COMMAND_MASTER;
- pcibios_write_config_word(pci_bus, pci_device_fn,
- PCI_COMMAND, pci_command);
- }
- pcibios_read_config_byte(pci_bus, pci_device_fn,
- PCI_LATENCY_TIMER, &pci_latency);
- if (pci_latency < min_pci_latency) {
- printk(" PCI latency timer (CFLT) is unreasonably low at %d."
- " Setting to %d clocks.\n",
+ if (dev) {
+ /* Get and check the bus-master and latency values. */
+ pcibios_read_config_byte(pci_bus, pci_device_fn,
+ PCI_LATENCY_TIMER, &pci_latency);
+ if (pci_latency < min_pci_latency) {
+ printk(KERN_INFO " PCI latency timer (CFLT) is "
+ "unreasonably low at %d. Setting to %d clocks.\n",
pci_latency, min_pci_latency);
pcibios_write_config_byte(pci_bus, pci_device_fn,
PCI_LATENCY_TIMER, min_pci_latency);
- } else if (yellowfin_debug > 1)
- printk(" PCI latency timer (CFLT) is %#x.\n", pci_latency);
- dev = 0;
- cards_found++;
- }
+ } else if (yellowfin_debug > 1)
+ printk(KERN_INFO " PCI latency timer (CFLT) is %#x.\n",
+ pci_latency);
+ dev = 0;
+ cards_found++;
}
}
-#if defined (MODULE)
- return cards_found;
-#else
- return 0;
-#endif
+ return cards_found ? 0 : -ENODEV;
}
-static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq,
- int chip_id, int options)
+static struct device *yellowfin_probe1(struct device *dev, long ioaddr,
+ int irq, int chip_id, int card_idx)
{
static int did_version = 0; /* Already printed version info. */
struct yellowfin_private *yp;
- int i;
+ int option, i;
if (yellowfin_debug > 0 && did_version++ == 0)
printk(version);
dev = init_etherdev(dev, sizeof(struct yellowfin_private));
- printk("%s: P-E Yellowfin type %8x at %#3x, ",
- dev->name, inl(ioaddr + ChipRev), ioaddr);
+ printk(KERN_INFO "%s: %s type %8x at 0x%lx, ",
+ dev->name, chip_tbl[chip_id].name, inl(ioaddr + ChipRev), ioaddr);
+ if (inw(ioaddr + ChipRev) == 0x0702)
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = inb(ioaddr + StnAddr + i);
+ else {
+ int ee_offset = (read_eeprom(ioaddr, 6) == 0xff ? 0x100 : 0);
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = read_eeprom(ioaddr, ee_offset + i);
+ }
for (i = 0; i < 5; i++)
- printk("%2.2x:", inb(ioaddr + StnAddr + i));
- printk("%2.2x, IRQ %d.\n", inb(ioaddr + StnAddr + i), irq);
- for (i = 0; i < 6; i++)
- dev->dev_addr[i] = inb(ioaddr + StnAddr + i);
+ printk("%2.2x:", dev->dev_addr[i]);
+ printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
/* Reset the chip. */
outl(0x80000000, ioaddr + DMACtrl);
-
/* We do a request_region() only to register /proc/ioports info. */
- request_region(ioaddr, YELLOWFIN_TOTAL_SIZE, card_name);
+ request_region(ioaddr, YELLOWFIN_TOTAL_SIZE, dev->name);
dev->base_addr = ioaddr;
dev->irq = irq;
@@ -483,28 +489,28 @@ static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq,
memset(yp, 0, sizeof(*yp));
dev->priv = yp;
-#ifdef MODULE
yp->next_module = root_yellowfin_dev;
root_yellowfin_dev = dev;
-#endif
yp->chip_id = chip_id;
- yp->full_duplex = 1;
-#ifdef YELLOWFIN_DEFAULT_MEDIA
- yp->default_port = YELLOWFIN_DEFAULT_MEDIA;
-#endif
-#ifdef YELLOWFIN_NO_MEDIA_SWITCH
- yp->medialock = 1;
-#endif
+ option = card_idx < MAX_UNITS ? options[card_idx] : 0;
+ if (dev->mem_start)
+ option = dev->mem_start;
/* The lower four bits are the media type. */
- if (options > 0) {
- yp->full_duplex = (options & 16) ? 1 : 0;
- yp->default_port = options & 15;
+ if (option > 0) {
+ if (option & 0x200)
+ yp->full_duplex = 1;
+ yp->default_port = option & 15;
if (yp->default_port)
yp->medialock = 1;
}
+ if (card_idx < MAX_UNITS && full_duplex[card_idx] > 0)
+ yp->full_duplex = 1;
+
+ if (yp->full_duplex)
+ yp->duplex_lock = 1;
/* The Yellowfin-specific entries in the device structure. */
dev->open = &yellowfin_open;
@@ -512,40 +518,88 @@ static struct device *yellowfin_probe1(struct device *dev, int ioaddr, int irq,
dev->stop = &yellowfin_close;
dev->get_stats = &yellowfin_get_stats;
dev->set_multicast_list = &set_rx_mode;
+#ifdef HAVE_PRIVATE_IOCTL
+ dev->do_ioctl = &mii_ioctl;
+#endif
if (mtu)
dev->mtu = mtu;
- /* todo: Reset the xcvr interface and turn on heartbeat. */
+ if (chip_tbl[yp->chip_id].flags & HasMII) {
+ int phy, phy_idx = 0;
+ for (phy = 0; phy < 32 && phy_idx < 4; phy++) {
+ int mii_status = mdio_read(ioaddr, phy, 1);
+ if (mii_status != 0xffff &&
+ mii_status != 0x0000) {
+ yp->phys[phy_idx++] = phy;
+ yp->advertising = mdio_read(ioaddr, phy, 4);
+ printk(KERN_INFO "%s: MII PHY found at address %d, status "
+ "0x%4.4x advertising %4.4x.\n",
+ dev->name, phy, mii_status, yp->advertising);
+ }
+ }
+ yp->mii_cnt = phy_idx;
+ }
return dev;
}
+static int read_eeprom(long ioaddr, int location)
+{
+ int bogus_cnt = 1000;
+
+ outb(location, ioaddr + EEAddr);
+ outb(0x30 | ((location >> 8) & 7), ioaddr + EECtrl);
+ while ((inb(ioaddr + EEStatus) & 0x80) && --bogus_cnt > 0)
+ ;
+ return inb(ioaddr + EERead);
+}
+
+/* MII Managemen Data I/O accesses.
+ These routines assume the MDIO controller is idle, and do not exit until
+ the command is finished. */
+
+static int mdio_read(long ioaddr, int phy_id, int location)
+{
+ int i;
+
+ outw((phy_id<<8) + location, ioaddr + MII_Addr);
+ outw(1, ioaddr + MII_Cmd);
+ for (i = 10000; i >= 0; i--)
+ if ((inw(ioaddr + MII_Status) & 1) == 0)
+ break;
+ return inw(ioaddr + MII_Rd_Data);
+}
+
+static void mdio_write(long ioaddr, int phy_id, int location, int value)
+{
+ int i;
+
+ outw((phy_id<<8) + location, ioaddr + MII_Addr);
+ outw(value, ioaddr + MII_Wr_Data);
+
+ /* Wait for the command to finish. */
+ for (i = 10000; i >= 0; i--)
+ if ((inw(ioaddr + MII_Status) & 1) == 0)
+ break;
+ return;
+}
+
-static int
-yellowfin_open(struct device *dev)
+static int yellowfin_open(struct device *dev)
{
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
+ int i;
/* Reset the chip. */
outl(0x80000000, ioaddr + DMACtrl);
-#ifdef SA_SHIRQ
- if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ,
- card_name, dev)) {
- return -EAGAIN;
- }
-#else
- if (irq2dev_map[dev->irq] != NULL
- || (irq2dev_map[dev->irq] = dev) == NULL
- || dev->irq == 0
- || request_irq(dev->irq, &yellowfin_interrupt, 0, card_name)) {
+ if (request_irq(dev->irq, &yellowfin_interrupt, SA_SHIRQ, dev->name, dev))
return -EAGAIN;
- }
-#endif
if (yellowfin_debug > 1)
- printk("%s: yellowfin_open() irq %d.\n", dev->name, dev->irq);
+ printk(KERN_DEBUG "%s: yellowfin_open() irq %d.\n",
+ dev->name, dev->irq);
MOD_INC_USE_COUNT;
@@ -554,6 +608,9 @@ yellowfin_open(struct device *dev)
outl(virt_to_bus(yp->rx_ring), ioaddr + RxPtr);
outl(virt_to_bus(yp->tx_ring), ioaddr + TxPtr);
+ for (i = 0; i < 6; i++)
+ outb(dev->dev_addr[i], ioaddr + StnAddr + i);
+
/* Set up various condition 'select' registers.
There are no options here. */
outl(0x00800080, ioaddr + TxIntrSel); /* Interrupt on Tx abort */
@@ -575,17 +632,19 @@ yellowfin_open(struct device *dev)
dev->tbusy = 0;
dev->interrupt = 0;
-
- /* We are always in full-duplex mode with the current chip! */
- yp->full_duplex = 1;
+ yp->in_interrupt = 0;
/* Setting the Rx mode will start the Rx process. */
- outw(0x01CD | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
-#ifdef NEW_MULTICAST
+ if (yp->chip_id == 0) {
+ /* We are always in full-duplex mode with gigabit! */
+ yp->full_duplex = 1;
+ outw(0x01CF, ioaddr + Cnfg);
+ } else {
+ outw(0x0018, ioaddr + FrameGap0); /* 0060/4060 for non-MII 10baseT */
+ outw(0x1018, ioaddr + FrameGap1);
+ outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
+ }
set_rx_mode(dev);
-#else
- set_rx_mode(dev, 0, 0);
-#endif
dev->start = 1;
@@ -596,7 +655,7 @@ yellowfin_open(struct device *dev)
outl(0x80008000, ioaddr + TxCtrl);
if (yellowfin_debug > 2) {
- printk("%s: Done yellowfin_open().\n",
+ printk(KERN_DEBUG "%s: Done yellowfin_open().\n",
dev->name);
}
/* Set the timer to check for link beat. */
@@ -613,13 +672,36 @@ static void yellowfin_timer(unsigned long data)
{
struct device *dev = (struct device *)data;
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
- int ioaddr = dev->base_addr;
+ long ioaddr = dev->base_addr;
int next_tick = 0;
if (yellowfin_debug > 3) {
- printk("%s: Yellowfin timer tick, status %8.8x.\n",
- dev->name, inl(ioaddr + IntrStatus));
+ printk(KERN_DEBUG "%s: Yellowfin timer tick, status %8.8x.\n",
+ dev->name, inw(ioaddr + IntrStatus));
+ }
+
+ if (yp->mii_cnt) {
+ int mii_reg1 = mdio_read(ioaddr, yp->phys[0], 1);
+ int mii_reg5 = mdio_read(ioaddr, yp->phys[0], 5);
+ int negotiated = mii_reg5 & yp->advertising;
+ if (yellowfin_debug > 1)
+ printk(KERN_DEBUG "%s: MII #%d status register is %4.4x, "
+ "link partner capability %4.4x.\n",
+ dev->name, yp->phys[0], mii_reg1, mii_reg5);
+
+ if ( ! yp->duplex_lock &&
+ ((negotiated & 0x0300) == 0x0100
+ || (negotiated & 0x00C0) == 0x0040)) {
+ yp->full_duplex = 1;
+ }
+ outw(0x101C | (yp->full_duplex ? 2 : 0), ioaddr + Cnfg);
+
+ if (mii_reg1 & 0x0004)
+ next_tick = 60*HZ;
+ else
+ next_tick = 3*HZ;
}
+
if (next_tick) {
yp->timer.expires = RUN_AT(next_tick);
add_timer(&yp->timer);
@@ -629,20 +711,22 @@ static void yellowfin_timer(unsigned long data)
static void yellowfin_tx_timeout(struct device *dev)
{
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
- int ioaddr = dev->base_addr;
- int i;
+ long ioaddr = dev->base_addr;
- printk("%s: Yellowfin transmit timed out, status %8.8x, resetting...\n",
+ printk(KERN_WARNING "%s: Yellowfin transmit timed out, status %8.8x, resetting...\n",
dev->name, inl(ioaddr));
#ifndef __alpha__
- printk(" Rx ring %8.8x: ", (int)yp->rx_ring);
- for (i = 0; i < RX_RING_SIZE; i++)
- printk(" %8.8x", (unsigned int)yp->rx_ring[i].status);
- printk("\n Tx ring %8.8x: ", (int)yp->tx_ring);
- for (i = 0; i < TX_RING_SIZE; i++)
- printk(" %4.4x /%4.4x", yp->tx_status[i].tx_errs, yp->tx_ring[i].status);
- printk("\n");
+ {
+ int i;
+ printk(KERN_DEBUG " Rx ring %8.8x: ", (int)yp->rx_ring);
+ for (i = 0; i < RX_RING_SIZE; i++)
+ printk(" %8.8x", (unsigned int)yp->rx_ring[i].status);
+ printk("\n"KERN_DEBUG" Tx ring %8.8x: ", (int)yp->tx_ring);
+ for (i = 0; i < TX_RING_SIZE; i++)
+ printk(" %4.4x /%4.4x", yp->tx_status[i].tx_errs, yp->tx_ring[i].status);
+ printk("\n");
+ }
#endif
/* Perhaps we should reinitialize the hardware here. */
@@ -658,8 +742,7 @@ static void yellowfin_tx_timeout(struct device *dev)
/* Initialize the Rx and Tx rings, along with various 'dev' bits. */
-static void
-yellowfin_init_ring(struct device *dev)
+static void yellowfin_init_ring(struct device *dev)
{
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
int i;
@@ -668,24 +751,23 @@ yellowfin_init_ring(struct device *dev)
yp->cur_rx = yp->cur_tx = 0;
yp->dirty_rx = yp->dirty_tx = 0;
+ yp->rx_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
+ yp->rx_head_desc = &yp->rx_ring[0];
+
for (i = 0; i < RX_RING_SIZE; i++) {
struct sk_buff *skb;
- int pkt_buf_sz = (dev->mtu <= 1500 ? PKT_BUF_SZ : dev->mtu + 32);
- yp->rx_ring[i].request_cnt = pkt_buf_sz;
+ yp->rx_ring[i].request_cnt = yp->rx_buf_sz;
yp->rx_ring[i].cmd = CMD_RX_BUF | INTR_ALWAYS;
- skb = DEV_ALLOC_SKB(pkt_buf_sz);
- skb_reserve(skb, 2); /* 16 byte align the IP header. */
+ skb = dev_alloc_skb(yp->rx_buf_sz);
yp->rx_skbuff[i] = skb;
- if (skb == NULL)
- break; /* Bad news! */
- skb->dev = dev; /* Mark as being used by this device. */
-#if LINUX_VERSION_CODE > 0x10300
- yp->rx_ring[i].addr = virt_to_bus(skb->tail);
-#else
- yp->rx_ring[i].addr = virt_to_bus(skb->data);
-#endif
+ if (skb) {
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* 16 byte align the IP header. */
+ yp->rx_ring[i].addr = virt_to_bus(skb->tail);
+ } else if (yp->dirty_rx == 0)
+ yp->dirty_rx = (unsigned int)(0 - RX_RING_SIZE);
yp->rx_ring[i].branch_addr = virt_to_bus(&yp->rx_ring[i+1]);
}
/* Mark the last entry as wrapping the ring. */
@@ -709,19 +791,26 @@ yellowfin_init_ring(struct device *dev)
yp->tx_ring[i].cmd = CMD_STOP; /* Branch on Tx error. */
yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]);
i++;
- yp->tx_ring[i].cmd = CMD_TXSTATUS; /* Interrupt, no wait. */
- yp->tx_ring[i].request_cnt = sizeof(yp->tx_status[i]);
- yp->tx_ring[i].addr = virt_to_bus(&yp->tx_status[i/2]);
+ if (chip_tbl[yp->chip_id].flags & FullTxStatus) {
+ yp->tx_ring[i].cmd = CMD_TXSTATUS;
+ yp->tx_ring[i].request_cnt = sizeof(yp->tx_status[i]);
+ yp->tx_ring[i].addr = virt_to_bus(&yp->tx_status[i/2]);
+ } else { /* Symbios chips write only tx_errs word. */
+ yp->tx_ring[i].cmd = CMD_TXSTATUS | INTR_ALWAYS;
+ yp->tx_ring[i].request_cnt = 2;
+ yp->tx_ring[i].addr = virt_to_bus(&yp->tx_status[i/2].tx_errs);
+ }
yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[i+1]);
}
/* Wrap ring */
yp->tx_ring[--i].cmd = CMD_TXSTATUS | BRANCH_ALWAYS | INTR_ALWAYS;
yp->tx_ring[i].branch_addr = virt_to_bus(&yp->tx_ring[0]);
#endif
+ yp->tx_tail_desc = &yp->tx_status[0];
+ return;
}
-static int
-yellowfin_start_xmit(struct sk_buff *skb, struct device *dev)
+static int yellowfin_start_xmit(struct sk_buff *skb, struct device *dev)
{
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
unsigned entry;
@@ -773,19 +862,19 @@ yellowfin_start_xmit(struct sk_buff *skb, struct device *dev)
CMD_TX_PKT | BRANCH_IFTRUE;
#endif
- /* Todo: explicitly flush cache lines here. */
+ /* Non-x86 Todo: explicitly flush cache lines here. */
/* Wake the potentially-idle transmit channel. */
outl(0x10001000, dev->base_addr + TxCtrl);
if (yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 1)
- dev->tbusy = 0; /* Typical path */
+ clear_bit(0, (void*)&dev->tbusy); /* Typical path */
else
yp->tx_full = 1;
dev->trans_start = jiffies;
if (yellowfin_debug > 4) {
- printk("%s: Yellowfin transmit frame #%d queued in slot %d.\n",
+ printk(KERN_DEBUG "%s: Yellowfin transmit frame #%d queued in slot %d.\n",
dev->name, yp->cur_tx, entry);
}
return 0;
@@ -793,302 +882,320 @@ yellowfin_start_xmit(struct sk_buff *skb, struct device *dev)
/* The interrupt handler does all of the Rx thread work and cleans up
after the Tx thread. */
-static void yellowfin_interrupt IRQ(int irq, void *dev_instance, struct pt_regs *regs)
+static void yellowfin_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
{
-#ifdef SA_SHIRQ /* Use the now-standard shared IRQ implementation. */
struct device *dev = (struct device *)dev_instance;
-#else
- struct device *dev = (struct device *)(irq2dev_map[irq]);
-#endif
-
- struct yellowfin_private *lp;
- int ioaddr, boguscnt = max_interrupt_work;
+ struct yellowfin_private *yp;
+ long ioaddr, boguscnt = max_interrupt_work;
+#ifndef final_version /* Can never occur. */
if (dev == NULL) {
- printk ("yellowfin_interrupt(): irq %d for unknown device.\n", irq);
+ printk (KERN_ERR "yellowfin_interrupt(): irq %d for unknown device.\n", irq);
return;
}
+#endif
ioaddr = dev->base_addr;
- lp = (struct yellowfin_private *)dev->priv;
- if (test_and_set_bit(0, (void*)&dev->interrupt)) {
+ yp = (struct yellowfin_private *)dev->priv;
+ if (test_and_set_bit(0, (void*)&yp->in_interrupt)) {
+ dev->interrupt = 1;
printk(KERN_ERR "%s: Re-entering the interrupt handler.\n", dev->name);
return;
}
do {
u16 intr_status = inw(ioaddr + IntrClear);
- unsigned dirty_tx = lp->dirty_tx;
if (yellowfin_debug > 4)
- printk("%s: Yellowfin interrupt, status %4.4x.\n",
+ printk(KERN_DEBUG "%s: Yellowfin interrupt, status %4.4x.\n",
dev->name, intr_status);
if (intr_status == 0)
break;
- if (intr_status & (IntrRxDone | IntrEarlyRx))
+ if (intr_status & (IntrRxDone | IntrEarlyRx)) {
yellowfin_rx(dev);
+ outl(0x10001000, ioaddr + RxCtrl); /* Wake Rx engine. */
+ }
#ifdef NO_TXSTATS
- for (; dirty_tx < lp->cur_tx; dirty_tx++) {
- int entry = dirty_tx % TX_RING_SIZE;
- if (lp->tx_ring[entry].status == 0)
+ for (; yp->cur_tx - yp->dirty_tx > 0; yp->dirty_tx++) {
+ int entry = yp->dirty_tx % TX_RING_SIZE;
+ if (yp->tx_ring[entry].status == 0)
break;
/* Free the original skb. */
- dev_kfree_skb(lp->tx_skbuff[entry]);
- lp->tx_skbuff[entry] = 0;
- lp->stats.tx_packets++;
+ DEV_FREE_SKB(yp->tx_skbuff[entry]);
+ yp->tx_skbuff[entry] = 0;
+ yp->stats.tx_packets++;
}
- if (lp->tx_full && dev->tbusy
- && dirty_tx > lp->cur_tx - TX_RING_SIZE + 4) {
+ if (yp->tx_full && dev->tbusy
+ && yp->cur_tx - yp->dirty_tx < TX_RING_SIZE - 4) {
/* The ring is no longer full, clear tbusy. */
- lp->tx_full = 0;
- dev->tbusy = 0;
+ yp->tx_full = 0;
+ clear_bit(0, (void*)&dev->tbusy);
mark_bh(NET_BH);
}
- lp->dirty_tx = dirty_tx;
#else
if (intr_status & IntrTxDone
- || lp->tx_status[dirty_tx % TX_RING_SIZE].tx_errs) {
+ || yp->tx_tail_desc->tx_errs) {
+ unsigned dirty_tx = yp->dirty_tx;
- for (dirty_tx = lp->dirty_tx; dirty_tx < lp->cur_tx; dirty_tx++) {
+ for (dirty_tx = yp->dirty_tx; yp->cur_tx - dirty_tx > 0;
+ dirty_tx++) {
/* Todo: optimize this. */
int entry = dirty_tx % TX_RING_SIZE;
- u16 tx_errs = lp->tx_status[entry].tx_errs;
+ u16 tx_errs = yp->tx_status[entry].tx_errs;
+#ifndef final_version
+ if (yellowfin_debug > 5)
+ printk(KERN_DEBUG "%s: Tx queue %d check, Tx status "
+ "%4.4x %4.4x %4.4x %4.4x.\n",
+ dev->name, entry,
+ yp->tx_status[entry].tx_cnt,
+ yp->tx_status[entry].tx_errs,
+ yp->tx_status[entry].total_tx_cnt,
+ yp->tx_status[entry].paused);
+#endif
if (tx_errs == 0)
break; /* It still hasn't been Txed */
if (tx_errs & 0xF8100000) {
/* There was an major error, log it. */
#ifndef final_version
if (yellowfin_debug > 1)
- printk("%s: Transmit error, Tx status %4.4x.\n",
+ printk(KERN_DEBUG "%s: Transmit error, Tx status %4.4x.\n",
dev->name, tx_errs);
#endif
- lp->stats.tx_errors++;
- if (tx_errs & 0xF800) lp->stats.tx_aborted_errors++;
- if (tx_errs & 0x0800) lp->stats.tx_carrier_errors++;
- if (tx_errs & 0x2000) lp->stats.tx_window_errors++;
- if (tx_errs & 0x8000) lp->stats.tx_fifo_errors++;
+ yp->stats.tx_errors++;
+ if (tx_errs & 0xF800) yp->stats.tx_aborted_errors++;
+ if (tx_errs & 0x0800) yp->stats.tx_carrier_errors++;
+ if (tx_errs & 0x2000) yp->stats.tx_window_errors++;
+ if (tx_errs & 0x8000) yp->stats.tx_fifo_errors++;
#ifdef ETHER_STATS
- if (tx_errs & 0x1000) lp->stats.collisions16++;
+ if (tx_errs & 0x1000) yp->stats.collisions16++;
#endif
} else {
+#ifndef final_version
+ if (yellowfin_debug > 4)
+ printk(KERN_DEBUG "%s: Normal transmit, Tx status %4.4x.\n",
+ dev->name, tx_errs);
+#endif
#ifdef ETHER_STATS
- if (status & 0x0400) lp->stats.tx_deferred++;
+ if (tx_errs & 0x0400) yp->stats.tx_deferred++;
#endif
- lp->stats.collisions += tx_errs & 15;
- lp->stats.tx_packets++;
+ yp->stats.collisions += tx_errs & 15;
+ yp->stats.tx_packets++;
}
/* Free the original skb. */
- dev_kfree_skb(lp->tx_skbuff[entry]);
- lp->tx_skbuff[entry] = 0;
+ DEV_FREE_SKB(yp->tx_skbuff[entry]);
+ yp->tx_skbuff[entry] = 0;
/* Mark status as empty. */
- lp->tx_status[entry].tx_errs = 0;
+ yp->tx_status[entry].tx_errs = 0;
}
#ifndef final_version
- if (lp->cur_tx - dirty_tx > TX_RING_SIZE) {
- printk("%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
- dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
+ if (yp->cur_tx - dirty_tx > TX_RING_SIZE) {
+ printk(KERN_ERR "%s: Out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
+ dev->name, dirty_tx, yp->cur_tx, yp->tx_full);
dirty_tx += TX_RING_SIZE;
}
#endif
- if (lp->tx_full && dev->tbusy
- && dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
+ if (yp->tx_full && dev->tbusy
+ && yp->cur_tx - dirty_tx < TX_RING_SIZE - 2) {
/* The ring is no longer full, clear tbusy. */
- lp->tx_full = 0;
- dev->tbusy = 0;
+ yp->tx_full = 0;
+ clear_bit(0, (void*)&dev->tbusy);
mark_bh(NET_BH);
}
- lp->dirty_tx = dirty_tx;
+ yp->dirty_tx = dirty_tx;
+ yp->tx_tail_desc = &yp->tx_status[dirty_tx % TX_RING_SIZE];
}
#endif
- /* Log errors and other events. */
- if (intr_status & 0x2ee) { /* Abnormal error summary. */
- printk("%s: Something Wicked happened! %4.4x.\n",
- dev->name, intr_status);
- /* Hmmmmm, it's not clear what to do here. */
- if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
- lp->stats.tx_errors++;
- if (intr_status & (IntrRxPCIErr | IntrRxPCIFault))
- lp->stats.rx_errors++;
- }
+ /* Log errors and other uncommon events. */
+ if (intr_status & 0x2ee) /* Abnormal error summary. */
+ yellowfin_error(dev, intr_status);
+
if (--boguscnt < 0) {
- printk("%s: Too much work at interrupt, status=0x%4.4x.\n",
+ printk(KERN_WARNING "%s: Too much work at interrupt, status=0x%4.4x.\n",
dev->name, intr_status);
break;
}
} while (1);
if (yellowfin_debug > 3)
- printk("%s: exiting interrupt, status=%#4.4x.\n",
+ printk(KERN_DEBUG "%s: exiting interrupt, status=%#4.4x.\n",
dev->name, inw(ioaddr + IntrStatus));
/* Code that should never be run! Perhaps remove after testing.. */
{
static int stopit = 10;
if (dev->start == 0 && --stopit < 0) {
- printk("%s: Emergency stop, looping startup interrupt.\n",
+ printk(KERN_ERR "%s: Emergency stop, looping startup interrupt.\n",
dev->name);
-#ifdef SA_SHIRQ
free_irq(irq, dev);
-#else
- free_irq(irq);
-#endif
}
}
dev->interrupt = 0;
+ clear_bit(0, (void*)&yp->in_interrupt);
return;
}
/* This routine is logically part of the interrupt handler, but separated
for clarity and better register allocation. */
-static int
-yellowfin_rx(struct device *dev)
+static int yellowfin_rx(struct device *dev)
{
- struct yellowfin_private *lp = (struct yellowfin_private *)dev->priv;
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
- int entry = lp->cur_rx % RX_RING_SIZE;
+ int entry = yp->cur_rx % RX_RING_SIZE;
int boguscnt = 20;
if (yellowfin_debug > 4) {
- printk(" In yellowfin_rx(), entry %d status %4.4x.\n", entry,
- yp->rx_ring[entry].status);
- printk(" #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x.\n",
+ printk(KERN_DEBUG " In yellowfin_rx(), entry %d status %4.4x.\n",
+ entry, yp->rx_ring[entry].status);
+ printk(KERN_DEBUG " #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x.\n",
entry, yp->rx_ring[entry].cmd,
yp->rx_ring[entry].request_cnt, yp->rx_ring[entry].addr,
yp->rx_ring[entry].result_cnt, yp->rx_ring[entry].status);
}
-
/* If EOP is set on the next entry, it's a new packet. Send it up. */
- while (yp->rx_ring[entry].status) {
- /* Todo: optimize this mess. */
- u16 desc_status = yp->rx_ring[entry].status;
- struct yellowfin_desc *desc = &lp->rx_ring[entry];
- int frm_size = desc->request_cnt - desc->result_cnt;
- u8 *buf_addr = bus_to_virt(lp->rx_ring[entry].addr);
- s16 frame_status = *(s16*)&(buf_addr[frm_size - 2]);
+ while (yp->rx_head_desc->status) {
+ struct yellowfin_desc *desc = yp->rx_head_desc;
+ u16 desc_status = desc->status;
+ int data_size = desc->request_cnt - desc->result_cnt;
+ u8 *buf_addr = bus_to_virt(desc->addr);
+ s16 frame_status = *(s16*)&(buf_addr[data_size - 2]); /* ?Alpha safe on 885? */
if (yellowfin_debug > 4)
- printk(" yellowfin_rx() status was %4.4x.\n", frame_status);
+ printk(KERN_DEBUG " yellowfin_rx() status was %4.4x.\n",
+ frame_status);
if (--boguscnt < 0)
break;
if ( ! (desc_status & RX_EOP)) {
- printk("%s: Oversized Ethernet frame spanned multiple buffers,"
+ printk(KERN_WARNING "%s: Oversized Ethernet frame spanned multiple buffers,"
" status %4.4x!\n", dev->name, desc_status);
- lp->stats.rx_length_errors++;
- } else if (frame_status & 0x0038) {
+ yp->stats.rx_length_errors++;
+ } else if (yp->chip_id == 0 && (frame_status & 0x0038)) {
/* There was a error. */
if (yellowfin_debug > 3)
- printk(" yellowfin_rx() Rx error was %4.4x.\n", frame_status);
- lp->stats.rx_errors++;
- if (frame_status & 0x0060) lp->stats.rx_length_errors++;
- if (frame_status & 0x0008) lp->stats.rx_frame_errors++;
- if (frame_status & 0x0010) lp->stats.rx_crc_errors++;
- if (frame_status < 0) lp->stats.rx_dropped++;
+ printk(KERN_DEBUG " yellowfin_rx() Rx error was %4.4x.\n",
+ frame_status);
+ yp->stats.rx_errors++;
+ if (frame_status & 0x0060) yp->stats.rx_length_errors++;
+ if (frame_status & 0x0008) yp->stats.rx_frame_errors++;
+ if (frame_status & 0x0010) yp->stats.rx_crc_errors++;
+ if (frame_status < 0) yp->stats.rx_dropped++;
+ } else if (yp->chip_id != 0 &&
+ ((buf_addr[data_size-1] & 0x85) || buf_addr[data_size-2] & 0xC0)) {
+ u8 status1 = buf_addr[data_size-2];
+ u8 status2 = buf_addr[data_size-1];
+ yp->stats.rx_errors++;
+ if (status1 & 0xC0) yp->stats.rx_length_errors++;
+ if (status2 & 0x03) yp->stats.rx_frame_errors++;
+ if (status2 & 0x04) yp->stats.rx_crc_errors++;
+ if (status2 & 0x80) yp->stats.rx_dropped++;
#ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */
- } else if (memcmp(bus_to_virt(lp->rx_ring[entry].addr),
+ } else if (memcmp(bus_to_virt(yp->rx_ring[entry].addr),
dev->dev_addr, 6) != 0
- && memcmp(bus_to_virt(lp->rx_ring[entry].addr),
- "\0377\0377\0377\0377\0377\0377", 6) != 0) {
- printk("%s: Bad frame to %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
- dev->name,
- ((char *)bus_to_virt(lp->rx_ring[entry].addr))[0],
- ((char *)bus_to_virt(lp->rx_ring[entry].addr))[1],
- ((char *)bus_to_virt(lp->rx_ring[entry].addr))[2],
- ((char *)bus_to_virt(lp->rx_ring[entry].addr))[3],
- ((char *)bus_to_virt(lp->rx_ring[entry].addr))[4],
- ((char *)bus_to_virt(lp->rx_ring[entry].addr))[5]);
+ && memcmp(bus_to_virt(yp->rx_ring[entry].addr),
+ "\377\377\377\377\377\377", 6) != 0) {
+ printk(KERN_WARNING "%s: Bad frame to %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x.\n",
+ dev->name, buf_addr[0], buf_addr[1], buf_addr[2],
+ buf_addr[3], buf_addr[4], buf_addr[5]);
bogus_rx++;
#endif
} else {
- u8 bogus_cnt = buf_addr[frm_size - 8];
- short pkt_len = frm_size - 8 - bogus_cnt;
struct sk_buff *skb;
- int rx_in_place = 0;
+ int pkt_len = data_size -
+ (yp->chip_id ? 7 : 8 + buf_addr[data_size - 8]);
+ /* To verify: Yellowfin Length should omit the CRC! */
- /* Check if the packet is long enough to just accept without
- copying to a properly sized skbuff. */
+#ifndef final_version
+ if (yellowfin_debug > 4)
+ printk(KERN_DEBUG " yellowfin_rx() normal Rx pkt length %d"
+ " of %d, bogus_cnt %d.\n",
+ pkt_len, data_size, boguscnt);
+#endif
+ /* Check if the packet is long enough to just pass up the skbuff
+ without copying to a properly sized skbuff. */
if (pkt_len > rx_copybreak) {
- struct sk_buff *newskb;
- char *temp;
-
- /* Get a fresh skbuff to replace the filled one. */
- newskb = DEV_ALLOC_SKB(dev->mtu <= 1500 ? PKT_BUF_SZ
- : dev->mtu + 32);
- if (newskb == NULL) {
- skb = 0; /* No memory, drop the packet. */
- goto memory_squeeze;
- }
- /* Pass up the skb already on the Rx ring. */
- skb = lp->rx_skbuff[entry];
- temp = skb_put(skb, pkt_len);
- if (bus_to_virt(lp->rx_ring[entry].addr) != temp)
- printk("%s: Warning -- the skbuff addresses do not match"
- " in yellowfin_rx: %p vs. %p / %p.\n", dev->name,
- bus_to_virt(lp->rx_ring[entry].addr),
+ char *temp = skb_put(skb = yp->rx_skbuff[entry], pkt_len);
+#ifndef final_verison /* Remove after testing. */
+ if (bus_to_virt(yp->rx_ring[entry].addr) != temp)
+ printk(KERN_WARNING "%s: Warning -- the skbuff addresses "
+ "do not match in yellowfin_rx: %p vs. %p / %p.\n",
+ dev->name, bus_to_virt(yp->rx_ring[entry].addr),
skb->head, temp);
- rx_in_place = 1;
- lp->rx_skbuff[entry] = newskb;
- newskb->dev = dev;
- skb_reserve(newskb, 2); /* 16 byte align IP header */
- lp->rx_ring[entry].addr = virt_to_bus(newskb->tail);
- } else
- skb = DEV_ALLOC_SKB(pkt_len + 2);
- memory_squeeze:
- if (skb == NULL) {
- printk("%s: Memory squeeze, deferring packet.\n", dev->name);
- /* todo: Check that at least two ring entries are free.
- If not, free one and mark stats->rx_dropped++. */
- break;
- }
- skb->dev = dev;
- if (! rx_in_place) {
+#endif
+ yp->rx_skbuff[entry] = NULL;
+ } else {
+ skb = dev_alloc_skb(pkt_len + 2);
+ if (skb == NULL)
+ break;
+ skb->dev = dev;
skb_reserve(skb, 2); /* 16 byte align the data fields */
+#if 1
+ eth_copy_and_sum(skb, bus_to_virt(yp->rx_ring[entry].addr),
+ pkt_len, 0);
+ skb_put(skb, pkt_len);
+#else
memcpy(skb_put(skb, pkt_len),
- bus_to_virt(lp->rx_ring[entry].addr), pkt_len);
+ bus_to_virt(yp->rx_ring[entry].addr), pkt_len);
+#endif
}
-#if LINUX_VERSION_CODE > 0x10300
skb->protocol = eth_type_trans(skb, dev);
-#else
- skb->len = pkt_len;
-#endif
netif_rx(skb);
- lp->stats.rx_packets++;
+ dev->last_rx = jiffies;
+ yp->stats.rx_packets++;
}
+ entry = (++yp->cur_rx) % RX_RING_SIZE;
+ yp->rx_head_desc = &yp->rx_ring[entry];
+ }
- /* Mark this entry as being the end-of-list, and the prior entry
- as now valid. */
- lp->rx_ring[entry].cmd = CMD_STOP;
- yp->rx_ring[entry].status = 0;
- {
- int prev_entry = entry - 1;
- if (prev_entry < 0)
- lp->rx_ring[RX_RING_SIZE - 1].cmd =
- CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS;
- else
- lp->rx_ring[prev_entry].cmd = CMD_RX_BUF | INTR_ALWAYS;
+ /* Refill the Rx ring buffers. */
+ for (; yp->cur_rx - yp->dirty_rx > 0; yp->dirty_rx++) {
+ struct sk_buff *skb;
+ entry = yp->dirty_rx % RX_RING_SIZE;
+ if (yp->rx_skbuff[entry] == NULL) {
+ skb = dev_alloc_skb(yp->rx_buf_sz);
+ if (skb == NULL)
+ break; /* Better luck next round. */
+ skb->dev = dev; /* Mark as being used by this device. */
+ skb_reserve(skb, 2); /* Align IP on 16 byte boundaries */
+ yp->rx_ring[entry].addr = virt_to_bus(skb->tail);
+ yp->rx_skbuff[entry] = skb;
}
- entry = (++lp->cur_rx) % RX_RING_SIZE;
+ yp->rx_ring[entry].cmd = CMD_STOP;
+ yp->rx_ring[entry].status = 0; /* Clear complete bit. */
+ if (entry != 0)
+ yp->rx_ring[entry - 1].cmd = CMD_RX_BUF | INTR_ALWAYS;
+ else
+ yp->rx_ring[RX_RING_SIZE - 1].cmd =
+ CMD_RX_BUF | INTR_ALWAYS | BRANCH_ALWAYS;
}
- /* todo: restart Rx engine if stopped. For now we just make the Rx ring
- large enough to avoid this. */
return 0;
}
-static int
-yellowfin_close(struct device *dev)
+static void yellowfin_error(struct device *dev, int intr_status)
{
- int ioaddr = dev->base_addr;
+ struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
+
+ printk(KERN_ERR "%s: Something Wicked happened! %4.4x.\n",
+ dev->name, intr_status);
+ /* Hmmmmm, it's not clear what to do here. */
+ if (intr_status & (IntrTxPCIErr | IntrTxPCIFault))
+ yp->stats.tx_errors++;
+ if (intr_status & (IntrRxPCIErr | IntrRxPCIFault))
+ yp->stats.rx_errors++;
+}
+
+static int yellowfin_close(struct device *dev)
+{
+ long ioaddr = dev->base_addr;
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
int i;
@@ -1096,10 +1203,10 @@ yellowfin_close(struct device *dev)
dev->tbusy = 1;
if (yellowfin_debug > 1) {
- printk("%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n",
+ printk(KERN_DEBUG "%s: Shutting down ethercard, status was Tx %4.4x Rx %4.4x Int %2.2x.\n",
dev->name, inw(ioaddr + TxStatus),
- inw(ioaddr + RxStatus), inl(ioaddr + IntrStatus));
- printk("%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
+ inw(ioaddr + RxStatus), inw(ioaddr + IntrStatus));
+ printk(KERN_DEBUG "%s: Queue pointers were Tx %d / %d, Rx %d / %d.\n",
dev->name, yp->cur_tx, yp->dirty_tx, yp->cur_rx, yp->dirty_rx);
}
@@ -1112,8 +1219,9 @@ yellowfin_close(struct device *dev)
del_timer(&yp->timer);
+#ifdef __i386__
if (yellowfin_debug > 2) {
- printk("\n Tx ring at %8.8x:\n", (int)virt_to_bus(yp->tx_ring));
+ printk("\n"KERN_DEBUG" Tx ring at %8.8x:\n", (int)virt_to_bus(yp->tx_ring));
for (i = 0; i < TX_RING_SIZE*2; i++)
printk(" %c #%d desc. %4.4x %4.4x %8.8x %8.8x %4.4x %4.4x.\n",
inl(ioaddr + TxPtr) == (long)&yp->tx_ring[i] ? '>' : ' ',
@@ -1121,20 +1229,20 @@ yellowfin_close(struct device *dev)
yp->tx_ring[i].request_cnt, yp->tx_ring[i].addr,
yp->tx_ring[i].branch_addr,
yp->tx_ring[i].result_cnt, yp->tx_ring[i].status);
- printk(" Tx status %p:\n", yp->tx_status);
+ printk(KERN_DEBUG " Tx status %p:\n", yp->tx_status);
for (i = 0; i < TX_RING_SIZE; i++)
printk(" #%d status %4.4x %4.4x %4.4x %4.4x.\n",
i, yp->tx_status[i].tx_cnt, yp->tx_status[i].tx_errs,
yp->tx_status[i].total_tx_cnt, yp->tx_status[i].paused);
- printk("\n Rx ring %8.8x:\n", (int)virt_to_bus(yp->rx_ring));
+ printk("\n"KERN_DEBUG " Rx ring %8.8x:\n", (int)virt_to_bus(yp->rx_ring));
for (i = 0; i < RX_RING_SIZE; i++) {
- printk(" %c #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x\n",
+ printk(KERN_DEBUG " %c #%d desc. %4.4x %4.4x %8.8x %4.4x %4.4x\n",
inl(ioaddr + RxPtr) == (long)&yp->rx_ring[i] ? '>' : ' ',
i, yp->rx_ring[i].cmd,
yp->rx_ring[i].request_cnt, yp->rx_ring[i].addr,
yp->rx_ring[i].result_cnt, yp->rx_ring[i].status);
- if (yellowfin_debug > 5) {
+ if (yellowfin_debug > 6) {
if (*(u8*)yp->rx_ring[i].addr != 0x69) {
int j;
for (j = 0; j < 0x50; j++)
@@ -1144,13 +1252,9 @@ yellowfin_close(struct device *dev)
}
}
}
+#endif /* __i386__ debugging only */
-#ifdef SA_SHIRQ
free_irq(dev->irq, dev);
-#else
- free_irq(dev->irq);
- irq2dev_map[dev->irq] = 0;
-#endif
/* Free all the skbuffs in the Rx queue. */
for (i = 0; i < RX_RING_SIZE; i++) {
@@ -1160,19 +1264,19 @@ yellowfin_close(struct device *dev)
#if LINUX_VERSION_CODE < 0x20100
yp->rx_skbuff[i]->free = 1;
#endif
- dev_kfree_skb(yp->rx_skbuff[i]);
+ DEV_FREE_SKB(yp->rx_skbuff[i]);
}
yp->rx_skbuff[i] = 0;
}
for (i = 0; i < TX_RING_SIZE; i++) {
if (yp->tx_skbuff[i])
- dev_kfree_skb(yp->tx_skbuff[i]);
+ DEV_FREE_SKB(yp->tx_skbuff[i]);
yp->tx_skbuff[i] = 0;
}
#ifdef YF_PROTOTYPE /* Support for prototype hardware errata. */
if (yellowfin_debug > 0) {
- printk("%s: Received %d frames that we should not have.\n",
+ printk(KERN_DEBUG "%s: Received %d frames that we should not have.\n",
dev->name, bogus_rx);
}
#endif
@@ -1181,8 +1285,7 @@ yellowfin_close(struct device *dev)
return 0;
}
-static struct enet_statistics *
-yellowfin_get_stats(struct device *dev)
+static struct enet_statistics *yellowfin_get_stats(struct device *dev)
{
struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
return &yp->stats;
@@ -1194,6 +1297,7 @@ yellowfin_get_stats(struct device *dev)
N.B. Do not use for bulk data, use a table-based routine instead.
This is common code and should be moved to net/core/crc.c */
static unsigned const ethernet_polynomial_le = 0xedb88320U;
+
static inline unsigned ether_crc_le(int length, unsigned char *data)
{
unsigned int crc = 0xffffffff; /* Initial value. */
@@ -1212,25 +1316,20 @@ static inline unsigned ether_crc_le(int length, unsigned char *data)
}
-static void
-#ifdef NEW_MULTICAST
-set_rx_mode(struct device *dev)
-#else
-static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
-#endif
+static void set_rx_mode(struct device *dev)
{
- int ioaddr = dev->base_addr;
+ struct yellowfin_private *yp = (struct yellowfin_private *)dev->priv;
+ long ioaddr = dev->base_addr;
u16 cfg_value = inw(ioaddr + Cnfg);
/* Stop the Rx process to change any value. */
outw(cfg_value & ~0x1000, ioaddr + Cnfg);
if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
/* Unconditionally log net taps. */
- printk("%s: Promiscuous mode enabled.\n", dev->name);
+ printk(KERN_NOTICE "%s: Promiscuous mode enabled.\n", dev->name);
outw(0x000F, ioaddr + AddrMode);
} else if ((dev->mc_count > 64) || (dev->flags & IFF_ALLMULTI)) {
/* Too many to filter well, or accept all multicasts. */
- printk("%s: Set all-multicast mode.\n", dev->name);
outw(0x000B, ioaddr + AddrMode);
} else if (dev->mc_count > 0) { /* Must use the multicast hash table. */
struct dev_mc_list *mclist;
@@ -1241,49 +1340,67 @@ static void set_rx_mode(struct device *dev, int num_addrs, void *addrs);
i++, mclist = mclist->next) {
/* Due to a bug in the early chip versions, multiple filter
slots must be set for each address. */
- set_bit((ether_crc_le(3, mclist->dmi_addr) >> 3) & 0x3f,
- hash_table);
- set_bit((ether_crc_le(4, mclist->dmi_addr) >> 3) & 0x3f,
- hash_table);
- set_bit((ether_crc_le(5, mclist->dmi_addr) >> 3) & 0x3f,
- hash_table);
+ if (yp->chip_id == 0) {
+ set_bit((ether_crc_le(3, mclist->dmi_addr) >> 3) & 0x3f,
+ hash_table);
+ set_bit((ether_crc_le(4, mclist->dmi_addr) >> 3) & 0x3f,
+ hash_table);
+ set_bit((ether_crc_le(5, mclist->dmi_addr) >> 3) & 0x3f,
+ hash_table);
+ }
set_bit((ether_crc_le(6, mclist->dmi_addr) >> 3) & 0x3f,
hash_table);
}
/* Copy the hash table to the chip. */
for (i = 0; i < 4; i++)
outw(hash_table[i], ioaddr + HashTbl + i*2);
- printk("%s: Set multicast mode.\n", dev->name);
outw(0x0003, ioaddr + AddrMode);
} else { /* Normal, unicast/broadcast-only mode. */
- printk("%s: Set unicast mode.\n", dev->name);
outw(0x0001, ioaddr + AddrMode);
}
/* Restart the Rx process. */
outw(cfg_value | 0x1000, ioaddr + Cnfg);
}
+
+#ifdef HAVE_PRIVATE_IOCTL
+static int mii_ioctl(struct device *dev, struct ifreq *rq, int cmd)
+{
+ long ioaddr = dev->base_addr;
+ u16 *data = (u16 *)&rq->ifr_data;
+
+ switch(cmd) {
+ case SIOCDEVPRIVATE: /* Get the address of the PHY in use. */
+ data[0] = ((struct yellowfin_private *)dev->priv)->phys[0] & 0x1f;
+ /* Fall Through */
+ case SIOCDEVPRIVATE+1: /* Read the specified MII register. */
+ data[3] = mdio_read(ioaddr, data[0] & 0x1f, data[1] & 0x1f);
+ return 0;
+ case SIOCDEVPRIVATE+2: /* Write the specified MII register */
+ if (!suser())
+ return -EPERM;
+ mdio_write(ioaddr, data[0] & 0x1f, data[1] & 0x1f, data[2]);
+ return 0;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+#endif /* HAVE_PRIVATE_IOCTL */
+
#ifdef MODULE
/* An additional parameter that may be passed in... */
static int debug = -1;
-int
-init_module(void)
+int init_module(void)
{
- int cards_found;
-
if (debug >= 0)
yellowfin_debug = debug;
- root_yellowfin_dev = NULL;
- cards_found = yellowfin_probe(0);
-
- return cards_found ? 0 : -ENODEV;
+ return yellowfin_probe(0);
}
-void
-cleanup_module(void)
+void cleanup_module(void)
{
struct device *next_dev;
@@ -1301,7 +1418,9 @@ cleanup_module(void)
/*
* Local variables:
- * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c"
+ * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
+ * compile-command-alphaLX: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O2 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS` -fomit-frame-pointer -fno-strength-reduce -mno-fp-regs -Wa,-m21164a -DBWX_USABLE -DBWIO_ENABLED"
+ * SMP-compile-command: "gcc -D__SMP__ -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -c yellowfin.c `[ -f /usr/include/linux/modversions.h ] && echo -DMODVERSIONS`"
* c-indent-level: 4
* c-basic-offset: 4
* tab-width: 4
diff --git a/drivers/net/z85230.c b/drivers/net/z85230.c
index 25f70ad3f..26cf57793 100644
--- a/drivers/net/z85230.c
+++ b/drivers/net/z85230.c
@@ -152,8 +152,9 @@ u8 z8530_hdlc_kilostream[]=
3, ENT_HM|RxCRC_ENAB|Rx8,
5, TxCRC_ENAB|RTS|TxENAB|Tx8|DTR,
9, 0, /* Disable interrupts */
+ 6, 0xFF,
7, FLAG,
- 10, ABUNDER|MARKIDLE|NRZ|CRCPS,
+ 10, ABUNDER|NRZ|CRCPS,/*MARKIDLE ??*/
11, TCTRxCP,
14, DISDPLL,
15, DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE,
@@ -176,8 +177,9 @@ u8 z8530_hdlc_kilostream_85230[]=
3, ENT_HM|RxCRC_ENAB|Rx8,
5, TxCRC_ENAB|RTS|TxENAB|Tx8|DTR,
9, 0, /* Disable interrupts */
+ 6, 0xFF,
7, FLAG,
- 10, ABUNDER|MARKIDLE|NRZ|CRCPS,
+ 10, ABUNDER|NRZ|CRCPS, /* MARKIDLE?? */
11, TCTRxCP,
14, DISDPLL,
15, DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE,
@@ -389,7 +391,12 @@ static void z8530_dma_rx(struct z8530_channel *chan)
if(chan->rxdma_on)
{
/* Special condition check only */
- u8 status=read_zsreg(chan, R1);
+ u8 status;
+
+ read_zsreg(chan, R7);
+ read_zsreg(chan, R6);
+
+ status=read_zsreg(chan, R1);
if(status&END_FR)
{
z8530_rx_done(chan); /* Fire up the next one */
@@ -418,6 +425,7 @@ static void z8530_dma_tx(struct z8530_channel *chan)
static void z8530_dma_status(struct z8530_channel *chan)
{
+ unsigned long flags;
u8 status=read_zsreg(chan, R0);
u8 altered=chan->status^status;
@@ -427,10 +435,12 @@ static void z8530_dma_status(struct z8530_channel *chan)
{
if(status&TxEOM)
{
+ flags=claim_dma_lock();
/* Transmit underrun */
disable_dma(chan->txdma);
clear_dma_ff(chan->txdma);
chan->txdma_on=0;
+ release_dma_lock(flags);
z8530_tx_done(chan);
}
}
@@ -461,6 +471,15 @@ struct z8530_irqhandler z8530_dma_sync=
EXPORT_SYMBOL(z8530_dma_sync);
+struct z8530_irqhandler z8530_txdma_sync=
+{
+ z8530_rx,
+ z8530_dma_tx,
+ z8530_dma_status
+};
+
+EXPORT_SYMBOL(z8530_txdma_sync);
+
/*
* Interrupt vectors for a Z8530 that is in 'parked' mode.
* For machines with PCI Z85x30 cards, or level triggered interrupts
@@ -566,7 +585,7 @@ void z8530_interrupt(int irq, void *dev_id, struct pt_regs *regs)
irqs->status(&dev->chanB);
}
}
- if(work==200)
+ if(work==5000)
printk(KERN_ERR "%s: interrupt jammed - abort(0x%X)!\n", dev->name, intr);
/* Ok all done */
locker=0;
@@ -619,6 +638,8 @@ EXPORT_SYMBOL(z8530_sync_close);
int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c)
{
+ unsigned long flags;
+
c->sync = 1;
c->mtu = dev->mtu;
c->count = 0;
@@ -665,6 +686,7 @@ int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c)
return -ENOBUFS;
}
c->tx_dma_used=0;
+ c->dma_tx = 1;
c->dma_num=0;
c->dma_ready=1;
@@ -672,13 +694,23 @@ int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c)
* Enable DMA control mode
*/
- c->regs[R1]|= WT_RDY_RT|WT_FN_RDYFN;
+ /*
+ * TX DMA via DIR/REQ
+ */
+
+ c->regs[R14]|= DTRREQ;
+ write_zsreg(c, R14, c->regs[R14]);
+
+ /*
+ * RX DMA via W/Req
+ */
+
+ c->regs[R1]|= WT_FN_RDYFN;
+ c->regs[R1]|= WT_RDY_RT;
c->regs[R1]|= INT_ERR_Rx;
write_zsreg(c, R1, c->regs[R1]);
c->regs[R1]|= WT_RDY_ENAB;
write_zsreg(c, R1, c->regs[R1]);
- c->regs[R14]|= DTRREQ;
- write_zsreg(c, R14, c->regs[R14]);
/*
* DMA interrupts
@@ -688,9 +720,11 @@ int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c)
* Set up the DMA configuration
*/
+ flags=claim_dma_lock();
+
disable_dma(c->rxdma);
clear_dma_ff(c->rxdma);
- set_dma_mode(c->rxdma, DMA_MODE_READ);
+ set_dma_mode(c->rxdma, DMA_MODE_READ|0x10);
set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[0]));
set_dma_count(c->rxdma, c->mtu);
enable_dma(c->rxdma);
@@ -700,6 +734,8 @@ int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c)
set_dma_mode(c->txdma, DMA_MODE_WRITE);
disable_dma(c->txdma);
+ release_dma_lock(flags);
+
/*
* Select the DMA interrupt handlers
*/
@@ -719,6 +755,8 @@ EXPORT_SYMBOL(z8530_sync_dma_open);
int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c)
{
u8 chk;
+ unsigned long flags;
+
c->irqs = &z8530_nop;
c->max = 0;
c->sync = 0;
@@ -726,12 +764,17 @@ int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c)
/*
* Disable the PC DMA channels
*/
-
+
+ flags=claim_dma_lock();
disable_dma(c->rxdma);
clear_dma_ff(c->rxdma);
+
c->rxdma_on = 0;
+
disable_dma(c->txdma);
clear_dma_ff(c->txdma);
+ release_dma_lock(flags);
+
c->txdma_on = 0;
c->tx_dma_used = 0;
@@ -775,6 +818,137 @@ int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c)
EXPORT_SYMBOL(z8530_sync_dma_close);
+int z8530_sync_txdma_open(struct device *dev, struct z8530_channel *c)
+{
+ printk("Opening sync interface for TX-DMA\n");
+ c->sync = 1;
+ c->mtu = dev->mtu;
+ c->count = 0;
+ c->skb = NULL;
+ c->skb2 = NULL;
+
+ /*
+ * Load the PIO receive ring
+ */
+
+ z8530_rx_done(c);
+ z8530_rx_done(c);
+
+ /*
+ * Load the DMA interfaces up
+ */
+
+ c->rxdma_on = 0;
+ c->txdma_on = 0;
+
+ c->tx_dma_buf[0]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA);
+ if(c->tx_dma_buf[0]==NULL)
+ {
+ kfree(c->rx_buf[0]);
+ kfree(c->rx_buf[1]);
+ c->rx_buf[0]=NULL;
+ return -ENOBUFS;
+ }
+ c->tx_dma_buf[1]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA);
+ if(c->tx_dma_buf[1]==NULL)
+ {
+ kfree(c->tx_dma_buf[0]);
+ kfree(c->rx_buf[0]);
+ kfree(c->rx_buf[1]);
+ c->rx_buf[0]=NULL;
+ c->rx_buf[1]=NULL;
+ c->tx_dma_buf[0]=NULL;
+ return -ENOBUFS;
+ }
+ c->tx_dma_used=0;
+ c->dma_num=0;
+ c->dma_ready=1;
+ c->dma_tx = 1;
+
+ /*
+ * Enable DMA control mode
+ */
+
+ /*
+ * TX DMA via DIR/REQ
+ */
+ c->regs[R14]|= DTRREQ;
+ write_zsreg(c, R14, c->regs[R14]);
+
+ /*
+ * Set up the DMA configuration
+ */
+
+ disable_dma(c->txdma);
+ clear_dma_ff(c->txdma);
+ set_dma_mode(c->txdma, DMA_MODE_WRITE);
+ disable_dma(c->txdma);
+
+ /*
+ * Select the DMA interrupt handlers
+ */
+
+ c->rxdma_on = 0;
+ c->txdma_on = 1;
+ c->tx_dma_used = 1;
+
+ c->irqs = &z8530_txdma_sync;
+ printk("Loading RX\n");
+ z8530_rtsdtr(c,1);
+ printk("Rx interrupts ON\n");
+ write_zsreg(c, R3, c->regs[R3]|RxENABLE);
+ return 0;
+}
+
+EXPORT_SYMBOL(z8530_sync_txdma_open);
+
+int z8530_sync_txdma_close(struct device *dev, struct z8530_channel *c)
+{
+ u8 chk;
+ c->irqs = &z8530_nop;
+ c->max = 0;
+ c->sync = 0;
+
+ /*
+ * Disable the PC DMA channels
+ */
+
+ disable_dma(c->txdma);
+ clear_dma_ff(c->txdma);
+ c->txdma_on = 0;
+ c->tx_dma_used = 0;
+
+ /*
+ * Disable DMA control mode
+ */
+
+ c->regs[R1]&= ~WT_RDY_ENAB;
+ write_zsreg(c, R1, c->regs[R1]);
+ c->regs[R1]&= ~(WT_RDY_RT|WT_FN_RDYFN|INT_ERR_Rx);
+ c->regs[R1]|= INT_ALL_Rx;
+ write_zsreg(c, R1, c->regs[R1]);
+ c->regs[R14]&= ~DTRREQ;
+ write_zsreg(c, R14, c->regs[R14]);
+
+ if(c->tx_dma_buf[0])
+ {
+ kfree(c->tx_dma_buf[0]);
+ c->tx_dma_buf[0]=NULL;
+ }
+ if(c->tx_dma_buf[1])
+ {
+ kfree(c->tx_dma_buf[1]);
+ c->tx_dma_buf[1]=NULL;
+ }
+ chk=read_zsreg(c,R0);
+ write_zsreg(c, R3, c->regs[R3]);
+ z8530_rtsdtr(c,0);
+ return 0;
+}
+
+
+EXPORT_SYMBOL(z8530_sync_txdma_close);
+
/*
* Describe a Z8530 in a standard format. We must pass the I/O as
* the port offset isnt predictable. The main reason for this function
@@ -929,7 +1103,12 @@ static void z8530_tx_begin(struct z8530_channel *c)
if(c->tx_skb==NULL)
{
/* Idle on */
- disable_dma(c->txdma);
+ if(c->txdma)
+ {
+ flags=claim_dma_lock();
+ disable_dma(c->txdma);
+ release_dma_lock(flags);
+ }
c->txcount=0;
}
else
@@ -938,19 +1117,22 @@ static void z8530_tx_begin(struct z8530_channel *c)
c->txcount=c->tx_skb->len;
- if(c->tx_dma_used)
+ if(c->dma_tx)
{
/*
- * FIXME. DMA is broken for the non 85230,
+ * FIXME. DMA is broken for the original 8530,
* on the older parts we need to set a flag and
* wait for a further TX interrupt to fire this
* stage off
*/
+
+ flags=claim_dma_lock();
disable_dma(c->txdma);
clear_dma_ff(c->txdma);
set_dma_addr(c->txdma, virt_to_bus(c->tx_ptr));
set_dma_count(c->txdma, c->txcount);
enable_dma(c->txdma);
+ release_dma_lock(flags);
write_zsreg(c, R5, c->regs[R5]|TxENAB);
}
else
@@ -1020,16 +1202,21 @@ static void z8530_rx_done(struct z8530_channel *c)
* Save the ready state and the buffer currently
* being used as the DMA target
*/
+
int ready=c->dma_ready;
- char *rxb=c->rx_buf[c->dma_num];
+ unsigned char *rxb=c->rx_buf[c->dma_num];
+ unsigned long flags;
/*
* Complete this DMA. Neccessary to find the length
*/
+
+ flags=claim_dma_lock();
+
disable_dma(c->rxdma);
clear_dma_ff(c->rxdma);
c->rxdma_on=0;
- ct=c->mtu-get_dma_residue(c->rxdma)-4;
+ ct=c->mtu-get_dma_residue(c->rxdma);
if(ct<0)
ct=2; /* Shit happens.. */
c->dma_ready=0;
@@ -1042,16 +1229,21 @@ static void z8530_rx_done(struct z8530_channel *c)
if(ready)
{
c->dma_num^=1;
- set_dma_mode(c->rxdma, DMA_MODE_READ);
+ set_dma_mode(c->rxdma, DMA_MODE_READ|0x10);
set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[c->dma_num]));
set_dma_count(c->rxdma, c->mtu);
c->rxdma_on = 1;
enable_dma(c->rxdma);
+ /* Stop any frames that we missed the head of
+ from passing */
+ write_zsreg(c, R0, RES_Rx_CRC);
}
else
/* Can't occur as we dont reenable the DMA irq until
after the flip is done */
printk("DMA flip overrun!\n");
+
+ release_dma_lock(flags);
/*
* Shove the old buffer into an sk_buff. We can't DMA
@@ -1068,7 +1260,6 @@ static void z8530_rx_done(struct z8530_channel *c)
{
skb_put(skb, ct);
memcpy(skb->data, rxb, ct);
- skb_pull(skb,2);
}
c->dma_ready=1;
}
@@ -1127,6 +1318,21 @@ static void z8530_rx_done(struct z8530_channel *c)
printk("Lost a frame\n");
}
+/*
+ * Cannot DMA over a 64K boundary on a PC
+ */
+
+extern inline int spans_boundary(struct sk_buff *skb)
+{
+ unsigned long a=(unsigned long)skb->data;
+ a^=(a+skb->len);
+ if(a&0x00010000) /* If the 64K bit is different.. */
+ {
+ printk("spanner\n");
+ return 1;
+ }
+ return 0;
+}
/*
* Queue a packet for transmission. Because we have rather
@@ -1151,7 +1357,7 @@ int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb)
* limit, then copy to the flip buffer
*/
- if(c->dma_tx && (unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024)
+ if(c->dma_tx && ((unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024 || spans_boundary(skb)))
{
/*
* Send the flip buffer, and flip the flippy bit.
diff --git a/drivers/net/z85230.h b/drivers/net/z85230.h
index 1fcb3dc6e..0b3850061 100644
--- a/drivers/net/z85230.h
+++ b/drivers/net/z85230.h
@@ -272,8 +272,8 @@ struct z8530_channel
u8 status; /* Current DCD */
u8 sync; /* Set if in sync mode */
- u8 regs[16]; /* Register map for the chip */
- u8 pendregs[16]; /* Pending register values */
+ u8 regs[32]; /* Register map for the chip */
+ u8 pendregs[32]; /* Pending register values */
struct sk_buff *tx_skb; /* Buffer being transmitted */
struct sk_buff *tx_next_skb; /* Next transmit buffer */
@@ -401,6 +401,8 @@ extern int z8530_sync_open(struct device *, struct z8530_channel *);
extern int z8530_sync_close(struct device *, struct z8530_channel *);
extern int z8530_sync_dma_open(struct device *, struct z8530_channel *);
extern int z8530_sync_dma_close(struct device *, struct z8530_channel *);
+extern int z8530_sync_txdma_open(struct device *, struct z8530_channel *);
+extern int z8530_sync_txdma_close(struct device *, struct z8530_channel *);
extern int z8530_channel_load(struct z8530_channel *, u8 *);
extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb);
extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c);
diff --git a/drivers/net/znet.c b/drivers/net/znet.c
index da6d30a53..2dff6d16b 100644
--- a/drivers/net/znet.c
+++ b/drivers/net/znet.c
@@ -591,6 +591,7 @@ static void znet_rx(struct device *dev)
/* The inverse routine to znet_open(). */
static int znet_close(struct device *dev)
{
+ unsigned long flags;
int ioaddr = dev->base_addr;
dev->tbusy = 1;
@@ -598,8 +599,10 @@ static int znet_close(struct device *dev)
outb(CMD0_RESET, ioaddr); /* CMD0_RESET */
+ flags=claim_dma_lock();
disable_dma(zn.rx_dma);
disable_dma(zn.tx_dma);
+ release_dma_lock(flags);
free_irq(dev->irq, dev);
@@ -662,16 +665,21 @@ static void set_multicast_list(struct device *dev)
void show_dma(void)
{
+ unsigned long flags;
short dma_port = ((zn.tx_dma&3)<<2) + IO_DMA2_BASE;
unsigned addr = inb(dma_port);
addr |= inb(dma_port) << 8;
+
+ flags=claim_dma_lock();
printk("Addr: %04x cnt:%3x...", addr<<1, get_dma_residue(zn.tx_dma));
+ release_dma_lock(flags);
}
/* Initialize the hardware. We have to do this when the board is open()ed
or when we come out of suspend mode. */
static void hardware_init(struct device *dev)
{
+ unsigned long flags;
short ioaddr = dev->base_addr;
zn.rx_cur = zn.rx_start;
@@ -680,22 +688,22 @@ static void hardware_init(struct device *dev)
/* Reset the chip, and start it up. */
outb(CMD0_RESET, ioaddr);
- cli(); { /* Protect against a DMA flip-flop */
- disable_dma(zn.rx_dma); /* reset by an interrupting task. */
- clear_dma_ff(zn.rx_dma);
- set_dma_mode(zn.rx_dma, DMA_RX_MODE);
- set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
- set_dma_count(zn.rx_dma, RX_BUF_SIZE);
- enable_dma(zn.rx_dma);
- /* Now set up the Tx channel. */
- disable_dma(zn.tx_dma);
- clear_dma_ff(zn.tx_dma);
- set_dma_mode(zn.tx_dma, DMA_TX_MODE);
- set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
- set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
- enable_dma(zn.tx_dma);
- } sti();
-
+ flags=claim_dma_lock();
+ disable_dma(zn.rx_dma); /* reset by an interrupting task. */
+ clear_dma_ff(zn.rx_dma);
+ set_dma_mode(zn.rx_dma, DMA_RX_MODE);
+ set_dma_addr(zn.rx_dma, (unsigned int) zn.rx_start);
+ set_dma_count(zn.rx_dma, RX_BUF_SIZE);
+ enable_dma(zn.rx_dma);
+ /* Now set up the Tx channel. */
+ disable_dma(zn.tx_dma);
+ clear_dma_ff(zn.tx_dma);
+ set_dma_mode(zn.tx_dma, DMA_TX_MODE);
+ set_dma_addr(zn.tx_dma, (unsigned int) zn.tx_start);
+ set_dma_count(zn.tx_dma, zn.tx_buf_len<<1);
+ enable_dma(zn.tx_dma);
+ release_dma_lock(flags);
+
if (znet_debug > 1)
printk(KERN_DEBUG "%s: Initializing the i82593, tx buf %p... ", dev->name,
zn.tx_start);