mwl8k: remove (mostly) write-only variable priv->current_channel
[safe/jmp/linux-2.6] / drivers / net / tokenring / 3c359.c
index e7a9446..cf552d1 100644 (file)
@@ -62,6 +62,7 @@
 #include <linux/pci.h>
 #include <linux/spinlock.h>
 #include <linux/bitops.h>
+#include <linux/firmware.h>
 
 #include <net/checksum.h>
 
 static char version[] __devinitdata  = 
 "3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ; 
 
+#define FW_NAME                "3com/3C359.bin"
 MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; 
 MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
+MODULE_FIRMWARE(FW_NAME);
 
-/* Module paramters */
+/* Module parameters */
 
 /* Ring Speed 0,4,16 
  * 0 = Autosense   
@@ -114,8 +117,6 @@ MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ;
  *     will be stuck with 1555 lines of hex #'s in the code.
  */
 
-#include "3c359_microcode.h" 
-
 static struct pci_device_id xl_pci_tbl[] =
 {
        {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
@@ -127,7 +128,7 @@ static int xl_init(struct net_device *dev);
 static int xl_open(struct net_device *dev);
 static int xl_open_hw(struct net_device *dev) ;  
 static int xl_hw_reset(struct net_device *dev); 
-static int xl_xmit(struct sk_buff *skb, struct net_device *dev);
+static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev);
 static void xl_dn_comp(struct net_device *dev); 
 static int xl_close(struct net_device *dev);
 static void xl_set_rx_mode(struct net_device *dev);
@@ -274,6 +275,15 @@ static void  xl_ee_write(struct net_device *dev, int ee_addr, u16 ee_value)
        
        return ; 
 }
+
+static const struct net_device_ops xl_netdev_ops = {
+       .ndo_open               = xl_open,
+       .ndo_stop               = xl_close,
+       .ndo_start_xmit         = xl_xmit,
+       .ndo_change_mtu         = xl_change_mtu,
+       .ndo_set_multicast_list = xl_set_rx_mode,
+       .ndo_set_mac_address    = xl_set_mac_address,
+};
  
 static int __devinit xl_probe(struct pci_dev *pdev,
                              const struct pci_device_id *ent) 
@@ -296,8 +306,9 @@ static int __devinit xl_probe(struct pci_dev *pdev,
        } ; 
 
        /* 
-        * Allowing init_trdev to allocate the dev->priv structure will align xl_private
-        * on a 32 bytes boundary which we need for the rx/tx descriptors
+        * Allowing init_trdev to allocate the private data will align
+        * xl_private on a 32 bytes boundary which we need for the rx/tx
+        * descriptors
         */
 
        dev = alloc_trdev(sizeof(struct xl_private)) ; 
@@ -336,13 +347,7 @@ static int __devinit xl_probe(struct pci_dev *pdev,
                return i ; 
        }                               
 
-       dev->open=&xl_open;
-       dev->hard_start_xmit=&xl_xmit;
-       dev->change_mtu=&xl_change_mtu;
-       dev->stop=&xl_close;
-       dev->do_ioctl=NULL;
-       dev->set_multicast_list=&xl_set_rx_mode;
-       dev->set_mac_address=&xl_set_mac_address ; 
+       dev->netdev_ops = &xl_netdev_ops;
        SET_NETDEV_DEV(dev, &pdev->dev);
 
        pci_set_drvdata(pdev,dev) ; 
@@ -360,10 +365,30 @@ static int __devinit xl_probe(struct pci_dev *pdev,
        return 0; 
 }
 
+static int xl_init_firmware(struct xl_private *xl_priv)
+{
+       int err;
+
+       err = request_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev);
+       if (err) {
+               printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME);
+               return err;
+       }
+
+       if (xl_priv->fw->size < 16) {
+               printk(KERN_ERR "Bogus length %zu in \"%s\"\n",
+                      xl_priv->fw->size, FW_NAME);
+               release_firmware(xl_priv->fw);
+               err = -EINVAL;
+       }
+
+       return err;
+}
 
 static int __devinit xl_init(struct net_device *dev) 
 {
        struct xl_private *xl_priv = netdev_priv(dev);
+       int err;
 
        printk(KERN_INFO "%s \n", version);
        printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
@@ -371,8 +396,11 @@ static int __devinit xl_init(struct net_device *dev)
 
        spin_lock_init(&xl_priv->xl_lock) ; 
 
-       return xl_hw_reset(dev) ; 
+       err = xl_init_firmware(xl_priv);
+       if (err == 0)
+               err = xl_hw_reset(dev);
 
+       return err;
 }
 
 
@@ -382,7 +410,7 @@ static int __devinit xl_init(struct net_device *dev)
  */
 
 static int xl_hw_reset(struct net_device *dev) 
-{ 
+{
        struct xl_private *xl_priv = netdev_priv(dev);
        u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 
        unsigned long t ; 
@@ -392,6 +420,9 @@ static int xl_hw_reset(struct net_device *dev)
        u16 start ; 
        int j ;
 
+       if (xl_priv->fw == NULL)
+               return -EINVAL;
+
        /*
         *  Reset the card.  If the card has got the microcode on board, we have 
          *  missed the initialization interrupt, so we must always do this.
@@ -454,25 +485,30 @@ static int xl_hw_reset(struct net_device *dev)
 
                /* 
                 * Now to write the microcode into the shared ram 
-                * The microcode must finish at position 0xFFFF, so we must subtract
-                * to get the start position for the code
+                * The microcode must finish at position 0xFFFF,
+                * so we must subtract to get the start position for the code
+                *
+                * Looks strange but ensures compiler only uses
+                * 16 bit unsigned int
                 */
+               start = (0xFFFF - (xl_priv->fw->size) + 1) ;
 
-               start = (0xFFFF - (mc_size) + 1 ) ; /* Looks strange but ensures compiler only uses 16 bit unsigned int for this */ 
-               
                printk(KERN_INFO "3C359: Uploading Microcode: "); 
-               
-               for (i = start, j = 0; j < mc_size; i++, j++) { 
-                       writel(MEM_BYTE_WRITE | 0XD0000 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
-                       writeb(microcode[j],xl_mmio + MMIO_MACDATA) ; 
+
+               for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) {
+                       writel(MEM_BYTE_WRITE | 0XD0000 | i,
+                              xl_mmio + MMIO_MAC_ACCESS_CMD);
+                       writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA);
                        if (j % 1024 == 0)
                                printk(".");
                }
                printk("\n") ; 
 
-               for (i=0;i < 16; i++) { 
-                       writel( (MEM_BYTE_WRITE | 0xDFFF0) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 
-                       writeb(microcode[mc_size - 16 + i], xl_mmio + MMIO_MACDATA) ; 
+               for (i = 0; i < 16; i++) {
+                       writel((MEM_BYTE_WRITE | 0xDFFF0) + i,
+                              xl_mmio + MMIO_MAC_ACCESS_CMD);
+                       writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i],
+                              xl_mmio + MMIO_MACDATA);
                }
 
                /*
@@ -574,9 +610,8 @@ static int xl_open(struct net_device *dev)
 
        u16 switchsettings, switchsettings_eeprom  ;
  
-       if(request_irq(dev->irq, &xl_interrupt, IRQF_SHARED , "3c359", dev)) {
+       if (request_irq(dev->irq, xl_interrupt, IRQF_SHARED , "3c359", dev))
                return -EAGAIN;
-       }
 
        /* 
         * Read the information from the EEPROM that we need.
@@ -1157,7 +1192,7 @@ static irqreturn_t xl_interrupt(int irq, void *dev_id)
  *     Tx - Polling configuration
  */
        
-static int xl_xmit(struct sk_buff *skb, struct net_device *dev) 
+static netdev_tx_t xl_xmit(struct sk_buff *skb, struct net_device *dev)
 {
        struct xl_private *xl_priv=netdev_priv(dev);
        struct xl_tx_desc *txd ; 
@@ -1204,10 +1239,10 @@ static int xl_xmit(struct sk_buff *skb, struct net_device *dev)
 
                spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
  
-               return 0;
+               return NETDEV_TX_OK;
        } else {
                spin_unlock_irqrestore(&xl_priv->xl_lock,flags) ; 
-               return 1;
+               return NETDEV_TX_BUSY;
        }
 
 }
@@ -1778,6 +1813,7 @@ static void __devexit xl_remove_one (struct pci_dev *pdev)
        struct net_device *dev = pci_get_drvdata(pdev);
        struct xl_private *xl_priv=netdev_priv(dev);
        
+       release_firmware(xl_priv->fw);
        unregister_netdev(dev);
        iounmap(xl_priv->xl_mmio) ; 
        pci_release_regions(pdev) ;