aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/tokenring/3c359.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/tokenring/3c359.c')
-rw-r--r--drivers/net/tokenring/3c359.c63
1 files changed, 48 insertions, 15 deletions
diff --git a/drivers/net/tokenring/3c359.c b/drivers/net/tokenring/3c359.c
index 4a65fc2dd928..534c0f38483c 100644
--- a/drivers/net/tokenring/3c359.c
+++ b/drivers/net/tokenring/3c359.c
@@ -62,6 +62,7 @@
62#include <linux/pci.h> 62#include <linux/pci.h>
63#include <linux/spinlock.h> 63#include <linux/spinlock.h>
64#include <linux/bitops.h> 64#include <linux/bitops.h>
65#include <linux/firmware.h>
65 66
66#include <net/checksum.h> 67#include <net/checksum.h>
67 68
@@ -73,8 +74,10 @@
73static char version[] __devinitdata = 74static char version[] __devinitdata =
74"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ; 75"3c359.c v1.2.0 2/17/01 - Mike Phillips (mikep@linuxtr.net)" ;
75 76
77#define FW_NAME "3com/3C359.bin"
76MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ; 78MODULE_AUTHOR("Mike Phillips <mikep@linuxtr.net>") ;
77MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ; 79MODULE_DESCRIPTION("3Com 3C359 Velocity XL Token Ring Adapter Driver \n") ;
80MODULE_FIRMWARE(FW_NAME);
78 81
79/* Module paramters */ 82/* Module paramters */
80 83
@@ -114,8 +117,6 @@ MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ;
114 * will be stuck with 1555 lines of hex #'s in the code. 117 * will be stuck with 1555 lines of hex #'s in the code.
115 */ 118 */
116 119
117#include "3c359_microcode.h"
118
119static struct pci_device_id xl_pci_tbl[] = 120static struct pci_device_id xl_pci_tbl[] =
120{ 121{
121 {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, }, 122 {PCI_VENDOR_ID_3COM,PCI_DEVICE_ID_3COM_3C359, PCI_ANY_ID, PCI_ANY_ID, },
@@ -364,10 +365,30 @@ static int __devinit xl_probe(struct pci_dev *pdev,
364 return 0; 365 return 0;
365} 366}
366 367
368static int xl_init_firmware(struct xl_private *xl_priv)
369{
370 int err;
371
372 err = request_firmware(&xl_priv->fw, FW_NAME, &xl_priv->pdev->dev);
373 if (err) {
374 printk(KERN_ERR "Failed to load firmware \"%s\"\n", FW_NAME);
375 return err;
376 }
377
378 if (xl_priv->fw->size < 16) {
379 printk(KERN_ERR "Bogus length %zu in \"%s\"\n",
380 xl_priv->fw->size, FW_NAME);
381 release_firmware(xl_priv->fw);
382 err = -EINVAL;
383 }
384
385 return err;
386}
367 387
368static int __devinit xl_init(struct net_device *dev) 388static int __devinit xl_init(struct net_device *dev)
369{ 389{
370 struct xl_private *xl_priv = netdev_priv(dev); 390 struct xl_private *xl_priv = netdev_priv(dev);
391 int err;
371 392
372 printk(KERN_INFO "%s \n", version); 393 printk(KERN_INFO "%s \n", version);
373 printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n", 394 printk(KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n",
@@ -375,8 +396,11 @@ static int __devinit xl_init(struct net_device *dev)
375 396
376 spin_lock_init(&xl_priv->xl_lock) ; 397 spin_lock_init(&xl_priv->xl_lock) ;
377 398
378 return xl_hw_reset(dev) ; 399 err = xl_init_firmware(xl_priv);
400 if (err == 0)
401 err = xl_hw_reset(dev);
379 402
403 return err;
380} 404}
381 405
382 406
@@ -386,7 +410,7 @@ static int __devinit xl_init(struct net_device *dev)
386 */ 410 */
387 411
388static int xl_hw_reset(struct net_device *dev) 412static int xl_hw_reset(struct net_device *dev)
389{ 413{
390 struct xl_private *xl_priv = netdev_priv(dev); 414 struct xl_private *xl_priv = netdev_priv(dev);
391 u8 __iomem *xl_mmio = xl_priv->xl_mmio ; 415 u8 __iomem *xl_mmio = xl_priv->xl_mmio ;
392 unsigned long t ; 416 unsigned long t ;
@@ -396,6 +420,9 @@ static int xl_hw_reset(struct net_device *dev)
396 u16 start ; 420 u16 start ;
397 int j ; 421 int j ;
398 422
423 if (xl_priv->fw == NULL)
424 return -EINVAL;
425
399 /* 426 /*
400 * Reset the card. If the card has got the microcode on board, we have 427 * Reset the card. If the card has got the microcode on board, we have
401 * missed the initialization interrupt, so we must always do this. 428 * missed the initialization interrupt, so we must always do this.
@@ -458,25 +485,30 @@ static int xl_hw_reset(struct net_device *dev)
458 485
459 /* 486 /*
460 * Now to write the microcode into the shared ram 487 * Now to write the microcode into the shared ram
461 * The microcode must finish at position 0xFFFF, so we must subtract 488 * The microcode must finish at position 0xFFFF,
462 * to get the start position for the code 489 * so we must subtract to get the start position for the code
490 *
491 * Looks strange but ensures compiler only uses
492 * 16 bit unsigned int
463 */ 493 */
494 start = (0xFFFF - (xl_priv->fw->size) + 1) ;
464 495
465 start = (0xFFFF - (mc_size) + 1 ) ; /* Looks strange but ensures compiler only uses 16 bit unsigned int for this */
466
467 printk(KERN_INFO "3C359: Uploading Microcode: "); 496 printk(KERN_INFO "3C359: Uploading Microcode: ");
468 497
469 for (i = start, j = 0; j < mc_size; i++, j++) { 498 for (i = start, j = 0; j < xl_priv->fw->size; i++, j++) {
470 writel(MEM_BYTE_WRITE | 0XD0000 | i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 499 writel(MEM_BYTE_WRITE | 0XD0000 | i,
471 writeb(microcode[j],xl_mmio + MMIO_MACDATA) ; 500 xl_mmio + MMIO_MAC_ACCESS_CMD);
501 writeb(xl_priv->fw->data[j], xl_mmio + MMIO_MACDATA);
472 if (j % 1024 == 0) 502 if (j % 1024 == 0)
473 printk("."); 503 printk(".");
474 } 504 }
475 printk("\n") ; 505 printk("\n") ;
476 506
477 for (i=0;i < 16; i++) { 507 for (i = 0; i < 16; i++) {
478 writel( (MEM_BYTE_WRITE | 0xDFFF0) + i, xl_mmio + MMIO_MAC_ACCESS_CMD) ; 508 writel((MEM_BYTE_WRITE | 0xDFFF0) + i,
479 writeb(microcode[mc_size - 16 + i], xl_mmio + MMIO_MACDATA) ; 509 xl_mmio + MMIO_MAC_ACCESS_CMD);
510 writeb(xl_priv->fw->data[xl_priv->fw->size - 16 + i],
511 xl_mmio + MMIO_MACDATA);
480 } 512 }
481 513
482 /* 514 /*
@@ -1782,6 +1814,7 @@ static void __devexit xl_remove_one (struct pci_dev *pdev)
1782 struct net_device *dev = pci_get_drvdata(pdev); 1814 struct net_device *dev = pci_get_drvdata(pdev);
1783 struct xl_private *xl_priv=netdev_priv(dev); 1815 struct xl_private *xl_priv=netdev_priv(dev);
1784 1816
1817 release_firmware(xl_priv->fw);
1785 unregister_netdev(dev); 1818 unregister_netdev(dev);
1786 iounmap(xl_priv->xl_mmio) ; 1819 iounmap(xl_priv->xl_mmio) ;
1787 pci_release_regions(pdev) ; 1820 pci_release_regions(pdev) ;