2010-09-08 15:46:36 -06:00
# include "headers.h"
2011-09-22 21:20:09 -06:00
int InterfaceFileDownload ( PVOID arg , struct file * flp , unsigned int on_chip_loc )
2010-09-08 15:46:36 -06:00
{
2011-10-20 06:15:22 -06:00
/* unsigned int reg = 0; */
2011-09-22 21:20:09 -06:00
mm_segment_t oldfs = { 0 } ;
2011-10-20 06:15:22 -06:00
int errno = 0 , len = 0 ; /* ,is_config_file = 0 */
2011-09-22 21:20:09 -06:00
loff_t pos = 0 ;
2010-09-08 15:46:36 -06:00
PS_INTERFACE_ADAPTER psIntfAdapter = ( PS_INTERFACE_ADAPTER ) arg ;
2012-05-26 10:05:12 -06:00
/* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
2011-09-22 21:20:09 -06:00
char * buff = kmalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_KERNEL ) ;
2010-09-08 15:46:36 -06:00
2011-09-22 21:20:09 -06:00
if ( ! buff )
return - ENOMEM ;
2010-09-08 15:46:36 -06:00
2011-09-22 21:20:09 -06:00
while ( 1 ) {
oldfs = get_fs ( ) ;
set_fs ( get_ds ( ) ) ;
len = vfs_read ( flp , ( void __force __user * ) buff ,
2011-10-20 06:15:22 -06:00
MAX_TRANSFER_CTRL_BYTE_USB , & pos ) ;
2011-09-22 21:20:09 -06:00
set_fs ( oldfs ) ;
if ( len < = 0 ) {
if ( len < 0 ) {
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter ,
DBG_TYPE_INITEXIT , MP_INIT ,
DBG_LVL_ALL , " len < 0 " ) ;
errno = len ;
} else {
errno = 0 ;
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter ,
DBG_TYPE_INITEXIT , MP_INIT ,
DBG_LVL_ALL ,
" Got end of file! " ) ;
}
break ;
}
/* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
2011-10-20 06:15:22 -06:00
* DBG_LVL_ALL , buff ,
* MAX_TRANSFER_CTRL_BYTE_USB ) ;
*/
2011-09-22 21:20:09 -06:00
errno = InterfaceWRM ( psIntfAdapter , on_chip_loc , buff , len ) ;
if ( errno ) {
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter ,
DBG_TYPE_PRINTK , 0 , 0 ,
" WRM Failed! status: %d " , errno ) ;
break ;
2010-09-08 15:46:36 -06:00
}
2011-09-22 21:20:09 -06:00
on_chip_loc + = MAX_TRANSFER_CTRL_BYTE_USB ;
}
2010-09-08 15:46:36 -06:00
2010-11-01 07:35:21 -06:00
kfree ( buff ) ;
2011-09-22 21:20:09 -06:00
return errno ;
2010-09-08 15:46:36 -06:00
}
2011-10-20 06:15:22 -06:00
int InterfaceFileReadbackFromChip ( PVOID arg , struct file * flp , unsigned int on_chip_loc )
2010-09-08 15:46:36 -06:00
{
2011-09-22 21:20:09 -06:00
char * buff , * buff_readback ;
unsigned int reg = 0 ;
2011-10-20 06:15:22 -06:00
mm_segment_t oldfs = { 0 } ;
int errno = 0 , len = 0 , is_config_file = 0 ;
loff_t pos = 0 ;
2011-10-20 06:15:23 -06:00
static int fw_down ;
2011-10-20 06:15:22 -06:00
INT Status = STATUS_SUCCESS ;
2010-09-08 15:46:36 -06:00
PS_INTERFACE_ADAPTER psIntfAdapter = ( PS_INTERFACE_ADAPTER ) arg ;
2011-11-06 07:40:11 -07:00
int bytes ;
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
buff = kmalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA ) ;
buff_readback = kmalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA ) ;
if ( ! buff | | ! buff_readback ) {
kfree ( buff ) ;
kfree ( buff_readback ) ;
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
return - ENOMEM ;
}
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
is_config_file = ( on_chip_loc = = CONFIG_BEGIN_ADDR ) ? 1 : 0 ;
2010-09-08 15:46:36 -06:00
memset ( buff_readback , 0 , MAX_TRANSFER_CTRL_BYTE_USB ) ;
memset ( buff , 0 , MAX_TRANSFER_CTRL_BYTE_USB ) ;
2011-10-20 06:15:22 -06:00
while ( 1 ) {
oldfs = get_fs ( ) ;
set_fs ( get_ds ( ) ) ;
len = vfs_read ( flp , ( void __force __user * ) buff , MAX_TRANSFER_CTRL_BYTE_USB , & pos ) ;
set_fs ( oldfs ) ;
fw_down + + ;
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
if ( len < = 0 ) {
if ( len < 0 ) {
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " len < 0 " ) ;
errno = len ;
} else {
errno = 0 ;
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Got end of file! " ) ;
}
break ;
}
2010-09-08 15:46:36 -06:00
2011-11-06 07:40:11 -07:00
bytes = InterfaceRDM ( psIntfAdapter , on_chip_loc , buff_readback , len ) ;
if ( bytes < 0 ) {
Status = bytes ;
2011-10-20 06:15:22 -06:00
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " RDM of len %d Failed! %d " , len , reg ) ;
2010-09-08 15:46:36 -06:00
goto exit ;
}
reg + + ;
2011-10-20 06:15:22 -06:00
if ( ( len - sizeof ( unsigned int ) ) < 4 ) {
if ( memcmp ( buff_readback , buff , len ) ) {
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Firmware Download is not proper %d " , fw_down ) ;
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Length is: %d " , len ) ;
2010-09-08 15:46:36 -06:00
Status = - EIO ;
goto exit ;
2011-10-20 06:15:22 -06:00
}
} else {
len - = 4 ;
while ( len ) {
if ( * ( unsigned int * ) & buff_readback [ len ] ! = * ( unsigned int * ) & buff [ len ] ) {
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Firmware Download is not proper %d " , fw_down ) ;
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Val from Binary %x, Val From Read Back %x " , * ( unsigned int * ) & buff [ len ] , * ( unsigned int * ) & buff_readback [ len ] ) ;
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " len =%x!!! " , len ) ;
2010-09-08 15:46:36 -06:00
Status = - EIO ;
goto exit ;
2011-10-20 06:15:22 -06:00
}
len - = 4 ;
}
}
on_chip_loc + = MAX_TRANSFER_CTRL_BYTE_USB ;
} /* End of while(1) */
2010-09-08 15:46:36 -06:00
exit :
2011-10-20 06:15:22 -06:00
kfree ( buff ) ;
kfree ( buff_readback ) ;
2010-09-08 15:46:36 -06:00
return Status ;
}
2012-05-26 10:05:12 -06:00
static int bcm_download_config_file ( struct bcm_mini_adapter * Adapter , struct bcm_firmware_info * psFwInfo )
2010-09-08 15:46:36 -06:00
{
int retval = STATUS_SUCCESS ;
B_UINT32 value = 0 ;
2011-10-20 06:15:22 -06:00
if ( Adapter - > pstargetparams = = NULL ) {
2011-10-20 06:15:23 -06:00
Adapter - > pstargetparams = kmalloc ( sizeof ( STARGETPARAMS ) , GFP_KERNEL ) ;
if ( Adapter - > pstargetparams = = NULL )
2011-10-20 06:15:22 -06:00
return - ENOMEM ;
2010-09-08 15:46:36 -06:00
}
2011-10-20 06:15:22 -06:00
if ( psFwInfo - > u32FirmwareLength ! = sizeof ( STARGETPARAMS ) )
return - EIO ;
retval = copy_from_user ( Adapter - > pstargetparams , psFwInfo - > pvMappedFirmwareAddress , psFwInfo - > u32FirmwareLength ) ;
if ( retval ) {
2010-11-01 07:35:21 -06:00
kfree ( Adapter - > pstargetparams ) ;
2010-09-08 15:46:36 -06:00
Adapter - > pstargetparams = NULL ;
2010-10-08 06:56:58 -06:00
return - EFAULT ;
2010-09-08 15:46:36 -06:00
}
2011-10-20 06:15:22 -06:00
2010-09-08 15:46:36 -06:00
/* Parse the structure and then Download the Firmware */
beceem_parse_target_struct ( Adapter ) ;
2011-10-20 06:15:22 -06:00
/* Initializing the NVM. */
2010-09-08 15:46:36 -06:00
BcmInitNVM ( Adapter ) ;
2011-10-20 06:15:22 -06:00
retval = InitLedSettings ( Adapter ) ;
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
if ( retval ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " INIT LED Failed \n " ) ;
2010-09-08 15:46:36 -06:00
return retval ;
}
2011-10-20 06:15:22 -06:00
if ( Adapter - > LEDInfo . led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY ) {
2010-09-08 15:46:36 -06:00
Adapter - > LEDInfo . bLedInitDone = FALSE ;
Adapter - > DriverState = DRIVER_INIT ;
wake_up ( & Adapter - > LEDInfo . notify_led_event ) ;
}
2011-10-20 06:15:22 -06:00
if ( Adapter - > LEDInfo . led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY ) {
2010-09-08 15:46:36 -06:00
Adapter - > DriverState = FW_DOWNLOAD ;
wake_up ( & Adapter - > LEDInfo . notify_led_event ) ;
}
/* Initialize the DDR Controller */
retval = ddr_init ( Adapter ) ;
2011-10-20 06:15:22 -06:00
if ( retval ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " DDR Init Failed \n " ) ;
2010-09-08 15:46:36 -06:00
return retval ;
}
value = 0 ;
wrmalt ( Adapter , EEPROM_CAL_DATA_INTERNAL_LOC - 4 , & value , sizeof ( value ) ) ;
wrmalt ( Adapter , EEPROM_CAL_DATA_INTERNAL_LOC - 8 , & value , sizeof ( value ) ) ;
2011-10-20 06:15:22 -06:00
if ( Adapter - > eNVMType = = NVM_FLASH ) {
2010-09-08 15:46:36 -06:00
retval = PropagateCalParamsFromFlashToMemory ( Adapter ) ;
2011-10-20 06:15:22 -06:00
if ( retval ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " propagaion of cal param failed with status :%d " , retval ) ;
2010-09-08 15:46:36 -06:00
return retval ;
}
}
2011-10-20 06:15:22 -06:00
retval = buffDnldVerify ( Adapter , ( PUCHAR ) Adapter - > pstargetparams , sizeof ( STARGETPARAMS ) , CONFIG_BEGIN_ADDR ) ;
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
if ( retval )
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " configuration file not downloaded properly " ) ;
2010-09-08 15:46:36 -06:00
else
Adapter - > bCfgDownloaded = TRUE ;
return retval ;
}
2011-10-20 06:15:22 -06:00
static int bcm_compare_buff_contents ( unsigned char * readbackbuff , unsigned char * buff , unsigned int len )
2010-09-08 15:46:36 -06:00
{
int retval = STATUS_SUCCESS ;
2012-05-26 10:05:12 -06:00
struct bcm_mini_adapter * Adapter = GET_BCM_ADAPTER ( gblpnetdev ) ;
2011-10-20 06:15:22 -06:00
if ( ( len - sizeof ( unsigned int ) ) < 4 ) {
if ( memcmp ( readbackbuff , buff , len ) )
retval = - EINVAL ;
} else {
len - = 4 ;
while ( len ) {
if ( * ( unsigned int * ) & readbackbuff [ len ] ! = * ( unsigned int * ) & buff [ len ] ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Firmware Download is not proper " ) ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Val from Binary %x, Val From Read Back %x " , * ( unsigned int * ) & buff [ len ] , * ( unsigned int * ) & readbackbuff [ len ] ) ;
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " len =%x!!! " , len ) ;
retval = - EINVAL ;
2010-09-08 15:46:36 -06:00
break ;
}
2011-10-20 06:15:22 -06:00
len - = 4 ;
2010-09-08 15:46:36 -06:00
}
}
return retval ;
}
2011-10-20 06:15:22 -06:00
2012-05-26 10:05:12 -06:00
int bcm_ioctl_fw_download ( struct bcm_mini_adapter * Adapter , struct bcm_firmware_info * psFwInfo )
2010-09-08 15:46:36 -06:00
{
int retval = STATUS_SUCCESS ;
PUCHAR buff = NULL ;
2011-10-20 06:15:22 -06:00
/* Config File is needed for the Driver to download the Config file and
* Firmware . Check for the Config file to be first to be sent from the
* Application
*/
atomic_set ( & Adapter - > uiMBupdate , FALSE ) ;
if ( ! Adapter - > bCfgDownloaded & & psFwInfo - > u32StartingAddress ! = CONFIG_BEGIN_ADDR ) {
/* Can't Download Firmware. */
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Download the config File first \n " ) ;
2010-09-08 15:46:36 -06:00
return - EINVAL ;
}
/* If Config File, Finish the DDR Settings and then Download CFG File */
2011-10-20 06:15:22 -06:00
if ( psFwInfo - > u32StartingAddress = = CONFIG_BEGIN_ADDR ) {
retval = bcm_download_config_file ( Adapter , psFwInfo ) ;
} else {
buff = kzalloc ( psFwInfo - > u32FirmwareLength , GFP_KERNEL ) ;
if ( buff = = NULL ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Failed in allocation memory " ) ;
2010-09-08 15:46:36 -06:00
return - ENOMEM ;
}
2011-10-20 06:15:22 -06:00
retval = copy_from_user ( buff , psFwInfo - > pvMappedFirmwareAddress , psFwInfo - > u32FirmwareLength ) ;
if ( retval ! = STATUS_SUCCESS ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " copying buffer from user space failed " ) ;
2010-10-08 06:56:58 -06:00
retval = - EFAULT ;
2011-10-20 06:15:22 -06:00
goto error ;
2010-09-08 15:46:36 -06:00
}
retval = buffDnldVerify ( Adapter ,
buff ,
psFwInfo - > u32FirmwareLength ,
psFwInfo - > u32StartingAddress ) ;
2011-10-20 06:15:22 -06:00
if ( retval ! = STATUS_SUCCESS ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " f/w download failed status :%d " , retval ) ;
2010-09-08 15:46:36 -06:00
goto error ;
}
}
2011-10-20 06:15:22 -06:00
2010-09-08 15:46:36 -06:00
error :
2010-11-01 07:35:21 -06:00
kfree ( buff ) ;
2010-09-08 15:46:36 -06:00
return retval ;
}
2012-05-26 10:05:12 -06:00
static INT buffDnld ( struct bcm_mini_adapter * Adapter , PUCHAR mappedbuffer , UINT u32FirmwareLength , ULONG u32StartingAddress )
2010-09-08 15:46:36 -06:00
{
2011-10-20 06:15:22 -06:00
unsigned int len = 0 ;
2010-09-08 15:46:36 -06:00
int retval = STATUS_SUCCESS ;
len = u32FirmwareLength ;
2011-10-20 06:15:22 -06:00
while ( u32FirmwareLength ) {
len = MIN_VAL ( u32FirmwareLength , MAX_TRANSFER_CTRL_BYTE_USB ) ;
retval = wrm ( Adapter , u32StartingAddress , mappedbuffer , len ) ;
if ( retval ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " wrm failed with status :%d " , retval ) ;
2010-09-08 15:46:36 -06:00
break ;
}
2011-10-20 06:15:22 -06:00
u32StartingAddress + = len ;
u32FirmwareLength - = len ;
mappedbuffer + = len ;
2010-09-08 15:46:36 -06:00
}
return retval ;
}
2012-05-26 10:05:12 -06:00
static INT buffRdbkVerify ( struct bcm_mini_adapter * Adapter , PUCHAR mappedbuffer , UINT u32FirmwareLength , ULONG u32StartingAddress )
2010-09-08 15:46:36 -06:00
{
UINT len = u32FirmwareLength ;
INT retval = STATUS_SUCCESS ;
2011-10-20 06:15:22 -06:00
PUCHAR readbackbuff = kzalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_KERNEL ) ;
2011-11-06 07:40:11 -07:00
int bytes ;
2010-09-08 15:46:36 -06:00
2011-10-20 06:15:22 -06:00
if ( NULL = = readbackbuff ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " MEMORY ALLOCATION FAILED " ) ;
2010-09-08 15:46:36 -06:00
return - ENOMEM ;
}
2011-10-20 06:15:22 -06:00
while ( u32FirmwareLength & & ! retval ) {
len = MIN_VAL ( u32FirmwareLength , MAX_TRANSFER_CTRL_BYTE_USB ) ;
2011-11-06 07:40:11 -07:00
bytes = rdm ( Adapter , u32StartingAddress , readbackbuff , len ) ;
2010-09-08 15:46:36 -06:00
2011-11-06 07:40:11 -07:00
if ( bytes < 0 ) {
retval = bytes ;
2011-10-20 06:15:22 -06:00
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " rdm failed with status %d " , retval ) ;
2010-09-08 15:46:36 -06:00
break ;
}
2011-10-20 06:15:23 -06:00
retval = bcm_compare_buff_contents ( readbackbuff , mappedbuffer , len ) ;
if ( STATUS_SUCCESS ! = retval )
2010-09-08 15:46:36 -06:00
break ;
2011-10-20 06:15:22 -06:00
u32StartingAddress + = len ;
u32FirmwareLength - = len ;
mappedbuffer + = len ;
} /* end of while (u32FirmwareLength && !retval) */
2010-11-01 07:35:21 -06:00
kfree ( readbackbuff ) ;
2010-09-08 15:46:36 -06:00
return retval ;
}
2012-05-26 10:05:12 -06:00
INT buffDnldVerify ( struct bcm_mini_adapter * Adapter , unsigned char * mappedbuffer , unsigned int u32FirmwareLength , unsigned long u32StartingAddress )
2010-09-08 15:46:36 -06:00
{
INT status = STATUS_SUCCESS ;
2011-10-20 06:15:22 -06:00
status = buffDnld ( Adapter , mappedbuffer , u32FirmwareLength , u32StartingAddress ) ;
if ( status ! = STATUS_SUCCESS ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Buffer download failed " ) ;
2010-09-08 15:46:36 -06:00
goto error ;
}
2011-10-20 06:15:22 -06:00
status = buffRdbkVerify ( Adapter , mappedbuffer , u32FirmwareLength , u32StartingAddress ) ;
if ( status ! = STATUS_SUCCESS ) {
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Buffer readback verifier failed " ) ;
2010-09-08 15:46:36 -06:00
goto error ;
}
error :
return status ;
}