net: spread __net_init, __net_exit
[safe/jmp/linux-2.6] / drivers / net / myri_sbus.c
index 899ed06..8b43130 100644 (file)
@@ -25,6 +25,7 @@ static char version[] =
 #include <linux/dma-mapping.h>
 #include <linux/of.h>
 #include <linux/of_device.h>
+#include <linux/firmware.h>
 
 #include <net/dst.h>
 #include <net/arp.h>
@@ -43,7 +44,6 @@ static char version[] =
 #include <asm/irq.h>
 
 #include "myri_sbus.h"
-#include "myri_code.h"
 
 /* #define DEBUG_DETECT */
 /* #define DEBUG_IRQ */
@@ -81,6 +81,9 @@ static char version[] =
 #define DHDR(x)
 #endif
 
+/* Firmware name */
+#define FWNAME         "myricom/lanai.bin"
+
 static void myri_reset_off(void __iomem *lp, void __iomem *cregs)
 {
        /* Clear IRQ mask. */
@@ -171,10 +174,11 @@ static int myri_do_handshake(struct myri_eth *mp)
 
 static int __devinit myri_load_lanai(struct myri_eth *mp)
 {
+       const struct firmware   *fw;
        struct net_device       *dev = mp->dev;
        struct myri_shmem __iomem *shmem = mp->shmem;
        void __iomem            *rptr;
-       int                     i;
+       int                     i, lanai4_data_size;
 
        myri_disable_irq(mp->lregs, mp->cregs);
        myri_reset_on(mp->cregs);
@@ -186,13 +190,27 @@ static int __devinit myri_load_lanai(struct myri_eth *mp)
        if (mp->eeprom.cpuvers >= CPUVERS_3_0)
                sbus_writel(mp->eeprom.cval, mp->lregs + LANAI_CVAL);
 
+       i = request_firmware(&fw, FWNAME, &mp->myri_op->dev);
+       if (i) {
+               printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
+                      FWNAME, i);
+               return i;
+       }
+       if (fw->size < 2) {
+               printk(KERN_ERR "Bogus length %zu in image \"%s\"\n",
+                      fw->size, FWNAME);
+               release_firmware(fw);
+               return -EINVAL;
+       }
+       lanai4_data_size = fw->data[0] << 8 | fw->data[1];
+
        /* Load executable code. */
-       for (i = 0; i < sizeof(lanai4_code); i++)
-               sbus_writeb(lanai4_code[i], rptr + (lanai4_code_off * 2) + i);
+       for (i = 2; i < fw->size; i++)
+               sbus_writeb(fw->data[i], rptr++);
 
        /* Load data segment. */
-       for (i = 0; i < sizeof(lanai4_data); i++)
-               sbus_writeb(lanai4_data[i], rptr + (lanai4_data_off * 2) + i);
+       for (i = 0; i < lanai4_data_size; i++)
+               sbus_writeb(0, rptr++);
 
        /* Set device address. */
        sbus_writeb(0, &shmem->addr[0]);
@@ -228,6 +246,7 @@ static int __devinit myri_load_lanai(struct myri_eth *mp)
        if (mp->eeprom.cpuvers == CPUVERS_4_0)
                sbus_writel(0, mp->lregs + LANAI_VERS);
 
+       release_firmware(fw);
        return i;
 }
 
@@ -621,7 +640,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
        if (!TX_BUFFS_AVAIL(head, tail)) {
                DTX(("no buffs available, returning 1\n"));
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
        spin_lock_irqsave(&mp->irq_lock, flags);
@@ -673,7 +692,7 @@ static int myri_start_xmit(struct sk_buff *skb, struct net_device *dev)
        DTX(("tbusy=0, returning 0\n"));
        netif_start_queue(dev);
        spin_unlock_irqrestore(&mp->irq_lock, flags);
-       return 0;
+       return NETDEV_TX_OK;
 }
 
 /* Create the MyriNet MAC header for an arbitrary protocol layer
@@ -697,10 +716,10 @@ static int myri_header(struct sk_buff *skb, struct net_device *dev,
        pad[0] = MYRI_PAD_LEN;
        pad[1] = 0xab;
 
-       /* Set the protocol type. For a packet of type ETH_P_802_3 we put the length
-        * in here instead. It is up to the 802.2 layer to carry protocol information.
+       /* Set the protocol type. For a packet of type ETH_P_802_3/2 we put the
+        * length in here instead.
         */
-       if (type != ETH_P_802_3)
+       if (type != ETH_P_802_3 && type != ETH_P_802_2)
                eth->h_proto = htons(type);
        else
                eth->h_proto = htons(len);
@@ -748,7 +767,7 @@ static int myri_rebuild_header(struct sk_buff *skb)
        switch (eth->h_proto)
        {
 #ifdef CONFIG_INET
-       case __constant_htons(ETH_P_IP):
+       case cpu_to_be16(ETH_P_IP):
                return arp_find(eth->h_dest, skb);
 #endif
 
@@ -896,6 +915,17 @@ static const struct header_ops myri_header_ops = {
        .cache_update   = myri_header_cache_update,
 };
 
+static const struct net_device_ops myri_ops = {
+       .ndo_open               = myri_open,
+       .ndo_stop               = myri_close,
+       .ndo_start_xmit         = myri_start_xmit,
+       .ndo_set_multicast_list = myri_set_multicast,
+       .ndo_tx_timeout         = myri_tx_timeout,
+       .ndo_change_mtu         = myri_change_mtu,
+       .ndo_set_mac_address    = eth_mac_addr,
+       .ndo_validate_addr      = eth_validate_addr,
+};
+
 static int __devinit myri_sbus_probe(struct of_device *op, const struct of_device_id *match)
 {
        struct device_node *dp = op->node;
@@ -1048,31 +1078,29 @@ static int __devinit myri_sbus_probe(struct of_device *op, const struct of_devic
        sbus_writel((1 << i), mp->cregs + MYRICTRL_IRQLVL);
 
        mp->dev = dev;
-       dev->open = &myri_open;
-       dev->stop = &myri_close;
-       dev->hard_start_xmit = &myri_start_xmit;
-       dev->tx_timeout = &myri_tx_timeout;
        dev->watchdog_timeo = 5*HZ;
-       dev->set_multicast_list = &myri_set_multicast;
        dev->irq = op->irqs[0];
+       dev->netdev_ops = &myri_ops;
 
        /* Register interrupt handler now. */
        DET(("Requesting MYRIcom IRQ line.\n"));
-       if (request_irq(dev->irq, &myri_interrupt,
+       if (request_irq(dev->irq, myri_interrupt,
                        IRQF_SHARED, "MyriCOM Ethernet", (void *) dev)) {
                printk("MyriCOM: Cannot register interrupt handler.\n");
                goto err;
        }
 
        dev->mtu                = MYRINET_MTU;
-       dev->change_mtu         = myri_change_mtu;
        dev->header_ops         = &myri_header_ops;
 
        dev->hard_header_len    = (ETH_HLEN + MYRI_PAD_LEN);
 
        /* Load code onto the LANai. */
        DET(("Loading LANAI firmware\n"));
-       myri_load_lanai(mp);
+       if (myri_load_lanai(mp)) {
+               printk(KERN_ERR "MyriCOM: Cannot Load LANAI firmware.\n");
+               goto err_free_irq;
+       }
 
        if (register_netdev(dev)) {
                printk("MyriCOM: Cannot register device.\n");
@@ -1153,3 +1181,4 @@ module_init(myri_sbus_init);
 module_exit(myri_sbus_exit);
 
 MODULE_LICENSE("GPL");
+MODULE_FIRMWARE(FWNAME);