74
74
#include <linux/slab.h>
75
75
#include <linux/delay.h>
76
76
#include <linux/init.h>
77
+ #include <linux/vmalloc.h>
77
78
#include <linux/ioport.h>
78
79
#include <linux/pci.h>
79
80
#include <linux/mm.h>
91
92
#include <linux/ip.h>
92
93
#include <linux/tcp.h>
93
94
#include <linux/mutex.h>
95
+ #include <linux/firmware.h>
94
96
95
97
#include <net/checksum.h>
96
98
@@ -197,6 +199,7 @@ static int link_mode;
197
199
MODULE_AUTHOR (
"Adrian Sun ([email protected] )" );
198
200
MODULE_DESCRIPTION ("Sun Cassini(+) ethernet driver" );
199
201
MODULE_LICENSE ("GPL" );
202
+ MODULE_FIRMWARE ("sun/cassini.bin" );
200
203
module_param (cassini_debug , int , 0 );
201
204
MODULE_PARM_DESC (cassini_debug , "Cassini bitmapped debugging message enable value" );
202
205
module_param (link_mode , int , 0 );
@@ -812,9 +815,44 @@ static int cas_reset_mii_phy(struct cas *cp)
812
815
return (limit <= 0 );
813
816
}
814
817
818
+ static int cas_saturn_firmware_init (struct cas * cp )
819
+ {
820
+ const struct firmware * fw ;
821
+ const char fw_name [] = "sun/cassini.bin" ;
822
+ int err ;
823
+
824
+ if (PHY_NS_DP83065 != cp -> phy_id )
825
+ return 0 ;
826
+
827
+ err = request_firmware (& fw , fw_name , & cp -> pdev -> dev );
828
+ if (err ) {
829
+ printk (KERN_ERR "cassini: Failed to load firmware \"%s\"\n" ,
830
+ fw_name );
831
+ return err ;
832
+ }
833
+ if (fw -> size < 2 ) {
834
+ printk (KERN_ERR "cassini: bogus length %zu in \"%s\"\n" ,
835
+ fw -> size , fw_name );
836
+ err = - EINVAL ;
837
+ goto out ;
838
+ }
839
+ cp -> fw_load_addr = fw -> data [1 ] << 8 | fw -> data [0 ];
840
+ cp -> fw_size = fw -> size - 2 ;
841
+ cp -> fw_data = vmalloc (cp -> fw_size );
842
+ if (!cp -> fw_data ) {
843
+ err = - ENOMEM ;
844
+ printk (KERN_ERR "cassini: \"%s\" Failed %d\n" , fw_name , err );
845
+ goto out ;
846
+ }
847
+ memcpy (cp -> fw_data , & fw -> data [2 ], cp -> fw_size );
848
+ out :
849
+ release_firmware (fw );
850
+ return err ;
851
+ }
852
+
815
853
static void cas_saturn_firmware_load (struct cas * cp )
816
854
{
817
- cas_saturn_patch_t * patch = cas_saturn_patch ;
855
+ int i ;
818
856
819
857
cas_phy_powerdown (cp );
820
858
@@ -833,11 +871,9 @@ static void cas_saturn_firmware_load(struct cas *cp)
833
871
834
872
/* download new firmware */
835
873
cas_phy_write (cp , DP83065_MII_MEM , 0x1 );
836
- cas_phy_write (cp , DP83065_MII_REGE , patch -> addr );
837
- while (patch -> addr ) {
838
- cas_phy_write (cp , DP83065_MII_REGD , patch -> val );
839
- patch ++ ;
840
- }
874
+ cas_phy_write (cp , DP83065_MII_REGE , cp -> fw_load_addr );
875
+ for (i = 0 ; i < cp -> fw_size ; i ++ )
876
+ cas_phy_write (cp , DP83065_MII_REGD , cp -> fw_data [i ]);
841
877
842
878
/* enable firmware */
843
879
cas_phy_write (cp , DP83065_MII_REGE , 0x8ff8 );
@@ -5108,6 +5144,9 @@ static int __devinit cas_init_one(struct pci_dev *pdev,
5108
5144
cas_reset (cp , 0 );
5109
5145
if (cas_check_invariants (cp ))
5110
5146
goto err_out_iounmap ;
5147
+ if (cp -> cas_flags & CAS_FLAG_SATURN )
5148
+ if (cas_saturn_firmware_init (cp ))
5149
+ goto err_out_iounmap ;
5111
5150
5112
5151
cp -> init_block = (struct cas_init_block * )
5113
5152
pci_alloc_consistent (pdev , sizeof (struct cas_init_block ),
@@ -5217,6 +5256,9 @@ static void __devexit cas_remove_one(struct pci_dev *pdev)
5217
5256
cp = netdev_priv (dev );
5218
5257
unregister_netdev (dev );
5219
5258
5259
+ if (cp -> fw_data )
5260
+ vfree (cp -> fw_data );
5261
+
5220
5262
mutex_lock (& cp -> pm_mutex );
5221
5263
flush_scheduled_work ();
5222
5264
if (cp -> hw_running )
0 commit comments