@ -1704,6 +1704,124 @@ spider_net_enable_card(struct spider_net_card *card)
SPIDER_NET_GDTBSTA ) ;
}
/**
* spider_net_download_firmware - loads firmware into the adapter
* @ card : card structure
* @ firmware_ptr : pointer to firmware data
*
* spider_net_download_firmware loads the firmware data into the
* adapter . It assumes the length etc . to be allright .
*/
static int
spider_net_download_firmware ( struct spider_net_card * card ,
const void * firmware_ptr )
{
int sequencer , i ;
const u32 * fw_ptr = firmware_ptr ;
/* stop sequencers */
spider_net_write_reg ( card , SPIDER_NET_GSINIT ,
SPIDER_NET_STOP_SEQ_VALUE ) ;
for ( sequencer = 0 ; sequencer < SPIDER_NET_FIRMWARE_SEQS ;
sequencer + + ) {
spider_net_write_reg ( card ,
SPIDER_NET_GSnPRGADR + sequencer * 8 , 0 ) ;
for ( i = 0 ; i < SPIDER_NET_FIRMWARE_SEQWORDS ; i + + ) {
spider_net_write_reg ( card , SPIDER_NET_GSnPRGDAT +
sequencer * 8 , * fw_ptr ) ;
fw_ptr + + ;
}
}
if ( spider_net_read_reg ( card , SPIDER_NET_GSINIT ) )
return - EIO ;
spider_net_write_reg ( card , SPIDER_NET_GSINIT ,
SPIDER_NET_RUN_SEQ_VALUE ) ;
return 0 ;
}
/**
* spider_net_init_firmware - reads in firmware parts
* @ card : card structure
*
* Returns 0 on success , < 0 on failure
*
* spider_net_init_firmware opens the sequencer firmware and does some basic
* checks . This function opens and releases the firmware structure . A call
* to download the firmware is performed before the release .
*
* Firmware format
* = = = = = = = = = = = = = = =
* spider_fw . bin is expected to be a file containing 6 * 1024 * 4 bytes , 4 k being
* the program for each sequencer . Use the command
* tail - q - n + 2 Seq_code1_0x088 . txt Seq_code2_0x090 . txt \
* Seq_code3_0x098 . txt Seq_code4_0x0A0 . txt Seq_code5_0x0A8 . txt \
* Seq_code6_0x0B0 . txt | xxd - r - p - c4 > spider_fw . bin
*
* to generate spider_fw . bin , if you have sequencer programs with something
* like the following contents for each sequencer :
* < ONE LINE COMMENT >
* < FIRST 4 - BYTES - WORD FOR SEQUENCER >
* < SECOND 4 - BYTES - WORD FOR SEQUENCER >
* . . .
* < 1024 th 4 - BYTES - WORD FOR SEQUENCER >
*/
static int
spider_net_init_firmware ( struct spider_net_card * card )
{
struct firmware * firmware = NULL ;
struct device_node * dn ;
const u8 * fw_prop = NULL ;
int err = - ENOENT ;
int fw_size ;
if ( request_firmware ( ( const struct firmware * * ) & firmware ,
SPIDER_NET_FIRMWARE_NAME , & card - > pdev - > dev ) = = 0 ) {
if ( ( firmware - > size ! = SPIDER_NET_FIRMWARE_LEN ) & &
netif_msg_probe ( card ) ) {
pr_err ( " Incorrect size of spidernet firmware in " \
" filesystem. Looking in host firmware... \n " ) ;
goto try_host_fw ;
}
err = spider_net_download_firmware ( card , firmware - > data ) ;
release_firmware ( firmware ) ;
if ( err )
goto try_host_fw ;
goto done ;
}
try_host_fw :
dn = pci_device_to_OF_node ( card - > pdev ) ;
if ( ! dn )
goto out_err ;
fw_prop = get_property ( dn , " firmware " , & fw_size ) ;
if ( ! fw_prop )
goto out_err ;
if ( ( fw_size ! = SPIDER_NET_FIRMWARE_LEN ) & &
netif_msg_probe ( card ) ) {
pr_err ( " Incorrect size of spidernet firmware in " \
" host firmware \n " ) ;
goto done ;
}
err = spider_net_download_firmware ( card , fw_prop ) ;
done :
return err ;
out_err :
if ( netif_msg_probe ( card ) )
pr_err ( " Couldn't find spidernet firmware in filesystem " \
" or host firmware \n " ) ;
return err ;
}
/**
* spider_net_open - called upon ifonfig up
* @ netdev : interface device structure
@ -1719,6 +1837,10 @@ spider_net_open(struct net_device *netdev)
struct spider_net_card * card = netdev_priv ( netdev ) ;
int result ;
result = spider_net_init_firmware ( card ) ;
if ( result )
goto init_firmware_failed ;
/* start probing with copper */
spider_net_setup_aneg ( card ) ;
if ( card - > phy . def - > phy_id )
@ -1762,6 +1884,7 @@ alloc_rx_failed:
spider_net_free_chain ( card , & card - > tx_chain ) ;
alloc_tx_failed :
del_timer_sync ( & card - > aneg_timer ) ;
init_firmware_failed :
return result ;
}
@ -1872,124 +1995,6 @@ spider_net_setup_phy(struct spider_net_card *card)
return 0 ;
}
/**
* spider_net_download_firmware - loads firmware into the adapter
* @ card : card structure
* @ firmware_ptr : pointer to firmware data
*
* spider_net_download_firmware loads the firmware data into the
* adapter . It assumes the length etc . to be allright .
*/
static int
spider_net_download_firmware ( struct spider_net_card * card ,
const void * firmware_ptr )
{
int sequencer , i ;
const u32 * fw_ptr = firmware_ptr ;
/* stop sequencers */
spider_net_write_reg ( card , SPIDER_NET_GSINIT ,
SPIDER_NET_STOP_SEQ_VALUE ) ;
for ( sequencer = 0 ; sequencer < SPIDER_NET_FIRMWARE_SEQS ;
sequencer + + ) {
spider_net_write_reg ( card ,
SPIDER_NET_GSnPRGADR + sequencer * 8 , 0 ) ;
for ( i = 0 ; i < SPIDER_NET_FIRMWARE_SEQWORDS ; i + + ) {
spider_net_write_reg ( card , SPIDER_NET_GSnPRGDAT +
sequencer * 8 , * fw_ptr ) ;
fw_ptr + + ;
}
}
if ( spider_net_read_reg ( card , SPIDER_NET_GSINIT ) )
return - EIO ;
spider_net_write_reg ( card , SPIDER_NET_GSINIT ,
SPIDER_NET_RUN_SEQ_VALUE ) ;
return 0 ;
}
/**
* spider_net_init_firmware - reads in firmware parts
* @ card : card structure
*
* Returns 0 on success , < 0 on failure
*
* spider_net_init_firmware opens the sequencer firmware and does some basic
* checks . This function opens and releases the firmware structure . A call
* to download the firmware is performed before the release .
*
* Firmware format
* = = = = = = = = = = = = = = =
* spider_fw . bin is expected to be a file containing 6 * 1024 * 4 bytes , 4 k being
* the program for each sequencer . Use the command
* tail - q - n + 2 Seq_code1_0x088 . txt Seq_code2_0x090 . txt \
* Seq_code3_0x098 . txt Seq_code4_0x0A0 . txt Seq_code5_0x0A8 . txt \
* Seq_code6_0x0B0 . txt | xxd - r - p - c4 > spider_fw . bin
*
* to generate spider_fw . bin , if you have sequencer programs with something
* like the following contents for each sequencer :
* < ONE LINE COMMENT >
* < FIRST 4 - BYTES - WORD FOR SEQUENCER >
* < SECOND 4 - BYTES - WORD FOR SEQUENCER >
* . . .
* < 1024 th 4 - BYTES - WORD FOR SEQUENCER >
*/
static int
spider_net_init_firmware ( struct spider_net_card * card )
{
struct firmware * firmware = NULL ;
struct device_node * dn ;
const u8 * fw_prop = NULL ;
int err = - ENOENT ;
int fw_size ;
if ( request_firmware ( ( const struct firmware * * ) & firmware ,
SPIDER_NET_FIRMWARE_NAME , & card - > pdev - > dev ) = = 0 ) {
if ( ( firmware - > size ! = SPIDER_NET_FIRMWARE_LEN ) & &
netif_msg_probe ( card ) ) {
pr_err ( " Incorrect size of spidernet firmware in " \
" filesystem. Looking in host firmware... \n " ) ;
goto try_host_fw ;
}
err = spider_net_download_firmware ( card , firmware - > data ) ;
release_firmware ( firmware ) ;
if ( err )
goto try_host_fw ;
goto done ;
}
try_host_fw :
dn = pci_device_to_OF_node ( card - > pdev ) ;
if ( ! dn )
goto out_err ;
fw_prop = get_property ( dn , " firmware " , & fw_size ) ;
if ( ! fw_prop )
goto out_err ;
if ( ( fw_size ! = SPIDER_NET_FIRMWARE_LEN ) & &
netif_msg_probe ( card ) ) {
pr_err ( " Incorrect size of spidernet firmware in " \
" host firmware \n " ) ;
goto done ;
}
err = spider_net_download_firmware ( card , fw_prop ) ;
done :
return err ;
out_err :
if ( netif_msg_probe ( card ) )
pr_err ( " Couldn't find spidernet firmware in filesystem " \
" or host firmware \n " ) ;
return err ;
}
/**
* spider_net_workaround_rxramfull - work around firmware bug
* @ card : card structure
@ -2090,8 +2095,6 @@ spider_net_tx_timeout_task(struct work_struct *work)
if ( spider_net_setup_phy ( card ) )
goto out ;
if ( spider_net_init_firmware ( card ) )
goto out ;
spider_net_open ( netdev ) ;
spider_net_kick_tx_dma ( card ) ;
@ -2363,10 +2366,6 @@ spider_net_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if ( err )
goto out_undo_pci ;
err = spider_net_init_firmware ( card ) ;
if ( err )
goto out_undo_pci ;
err = spider_net_setup_netdev ( card ) ;
if ( err )
goto out_undo_pci ;