62
62
#include <linux/pci.h>
63
63
#include <linux/spinlock.h>
64
64
#include <linux/bitops.h>
65
+ #include <linux/firmware.h>
65
66
66
67
#include <net/checksum.h>
67
68
73
74
static char version [] __devinitdata =
74
75
"3c359.c v1.2.0 2/17/01 - Mike Phillips ([email protected] )" ;
75
76
77
+ #define FW_NAME "3com/3C359.bin"
76
78
MODULE_AUTHOR (
"Mike Phillips <[email protected] >" ) ;
77
79
MODULE_DESCRIPTION ("3Com 3C359 Velocity XL Token Ring Adapter Driver \n" ) ;
80
+ MODULE_FIRMWARE (FW_NAME );
78
81
79
82
/* Module paramters */
80
83
@@ -114,8 +117,6 @@ MODULE_PARM_DESC(message_level, "3c359: Level of reported messages") ;
114
117
* will be stuck with 1555 lines of hex #'s in the code.
115
118
*/
116
119
117
- #include "3c359_microcode.h"
118
-
119
120
static struct pci_device_id xl_pci_tbl [] =
120
121
{
121
122
{PCI_VENDOR_ID_3COM ,PCI_DEVICE_ID_3COM_3C359 , PCI_ANY_ID , PCI_ANY_ID , },
@@ -364,19 +365,42 @@ static int __devinit xl_probe(struct pci_dev *pdev,
364
365
return 0 ;
365
366
}
366
367
368
+ static 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
368
388
static int __devinit xl_init (struct net_device * dev )
369
389
{
370
390
struct xl_private * xl_priv = netdev_priv (dev );
391
+ int err ;
371
392
372
393
printk (KERN_INFO "%s \n" , version );
373
394
printk (KERN_INFO "%s: I/O at %hx, MMIO at %p, using irq %d\n" ,
374
395
xl_priv -> xl_card_name , (unsigned int )dev -> base_addr ,xl_priv -> xl_mmio , dev -> irq );
375
396
376
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
388
412
static int xl_hw_reset (struct net_device * dev )
389
- {
413
+ {
390
414
struct xl_private * xl_priv = netdev_priv (dev );
391
415
u8 __iomem * xl_mmio = xl_priv -> xl_mmio ;
392
416
unsigned long t ;
@@ -396,6 +420,9 @@ static int xl_hw_reset(struct net_device *dev)
396
420
u16 start ;
397
421
int j ;
398
422
423
+ if (xl_priv -> fw == NULL )
424
+ return - EINVAL ;
425
+
399
426
/*
400
427
* Reset the card. If the card has got the microcode on board, we have
401
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
487
* Now to write the microcode into the shared ram
461
- * The microcode must finish at position 0xFFFF, so we must subtract
462
- * to get the start position for the code
488
+ * The microcode must finish at position 0xFFFF,
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
496
printk (KERN_INFO "3C359: Uploading Microcode: " );
468
-
469
- for (i = start , j = 0 ; j < mc_size ; i ++ , j ++ ) {
470
- writel (MEM_BYTE_WRITE | 0XD0000 | i , xl_mmio + MMIO_MAC_ACCESS_CMD ) ;
471
- writeb (microcode [j ],xl_mmio + MMIO_MACDATA ) ;
497
+
498
+ for (i = start , j = 0 ; j < xl_priv -> fw -> size ; i ++ , j ++ ) {
499
+ writel (MEM_BYTE_WRITE | 0XD0000 | i ,
500
+ xl_mmio + MMIO_MAC_ACCESS_CMD );
501
+ writeb (xl_priv -> fw -> data [j ], xl_mmio + MMIO_MACDATA );
472
502
if (j % 1024 == 0 )
473
503
printk ("." );
474
504
}
475
505
printk ("\n" ) ;
476
506
477
- for (i = 0 ;i < 16 ; i ++ ) {
478
- writel ( (MEM_BYTE_WRITE | 0xDFFF0 ) + i , xl_mmio + MMIO_MAC_ACCESS_CMD ) ;
479
- writeb (microcode [mc_size - 16 + i ], xl_mmio + MMIO_MACDATA ) ;
507
+ for (i = 0 ; i < 16 ; i ++ ) {
508
+ writel ((MEM_BYTE_WRITE | 0xDFFF0 ) + i ,
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
1814
struct net_device * dev = pci_get_drvdata (pdev );
1783
1815
struct xl_private * xl_priv = netdev_priv (dev );
1784
1816
1817
+ release_firmware (xl_priv -> fw );
1785
1818
unregister_netdev (dev );
1786
1819
iounmap (xl_priv -> xl_mmio ) ;
1787
1820
pci_release_regions (pdev ) ;
0 commit comments