2010-09-08 15:46:36 -06:00
# include "headers.h"
int InterfaceFileDownload ( PVOID arg ,
struct file * flp ,
unsigned int on_chip_loc )
{
// unsigned int reg=0;
mm_segment_t oldfs = { 0 } ;
int errno = 0 , len = 0 /*,is_config_file = 0*/ ;
loff_t pos = 0 ;
PS_INTERFACE_ADAPTER psIntfAdapter = ( PS_INTERFACE_ADAPTER ) arg ;
//PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
2010-11-10 13:31:38 -07:00
char * buff = kmalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_KERNEL ) ;
2010-09-08 15:46:36 -06:00
if ( ! buff )
{
return - ENOMEM ;
}
while ( 1 )
{
oldfs = get_fs ( ) ; set_fs ( get_ds ( ) ) ;
2010-09-30 02:24:12 -06:00
len = vfs_read ( flp , ( void __force __user * ) buff , MAX_TRANSFER_CTRL_BYTE_USB , & pos ) ;
2010-09-08 15:46:36 -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, DBG_LVL_ALL, buff, MAX_TRANSFER_CTRL_BYTE_USB);
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 ;
}
on_chip_loc + = MAX_TRANSFER_CTRL_BYTE_USB ;
} /* End of for(;;)*/
2010-11-01 07:35:21 -06:00
kfree ( buff ) ;
2010-09-08 15:46:36 -06:00
return errno ;
}
int InterfaceFileReadbackFromChip ( PVOID arg ,
struct file * flp ,
unsigned int on_chip_loc )
{
2010-11-10 13:31:38 -07:00
char * buff , * buff_readback ;
2010-09-08 15:46:36 -06:00
unsigned int reg = 0 ;
mm_segment_t oldfs = { 0 } ;
int errno = 0 , len = 0 , is_config_file = 0 ;
loff_t pos = 0 ;
static int fw_down = 0 ;
INT Status = STATUS_SUCCESS ;
PS_INTERFACE_ADAPTER psIntfAdapter = ( PS_INTERFACE_ADAPTER ) arg ;
2010-11-10 13:31:38 -07:00
buff = kmalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA ) ;
buff_readback = kmalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA ) ;
2010-09-08 15:46:36 -06:00
if ( ! buff | | ! buff_readback )
{
2010-11-01 07:35:21 -06:00
kfree ( buff ) ;
kfree ( buff_readback ) ;
2010-09-08 15:46:36 -06:00
return - ENOMEM ;
}
is_config_file = ( on_chip_loc = = CONFIG_BEGIN_ADDR ) ? 1 : 0 ;
memset ( buff_readback , 0 , MAX_TRANSFER_CTRL_BYTE_USB ) ;
memset ( buff , 0 , MAX_TRANSFER_CTRL_BYTE_USB ) ;
while ( 1 )
{
oldfs = get_fs ( ) ; set_fs ( get_ds ( ) ) ;
2010-09-30 02:24:12 -06:00
len = vfs_read ( flp , ( void __force __user * ) buff , MAX_TRANSFER_CTRL_BYTE_USB , & pos ) ;
2010-09-08 15:46:36 -06:00
set_fs ( oldfs ) ;
fw_down + + ;
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 ;
}
Status = InterfaceRDM ( psIntfAdapter , on_chip_loc , buff_readback , len ) ;
if ( Status )
{
BCM_DEBUG_PRINT ( psIntfAdapter - > psAdapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " RDM of len %d Failed! %d " , len , reg ) ;
goto exit ;
}
reg + + ;
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 ) ;
Status = - EIO ;
goto exit ;
}
}
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 ) ;
Status = - EIO ;
goto exit ;
}
len - = 4 ;
}
}
on_chip_loc + = MAX_TRANSFER_CTRL_BYTE_USB ;
} /* End of while(1)*/
exit :
2010-11-01 07:35:21 -06:00
kfree ( buff ) ;
kfree ( buff_readback ) ;
2010-09-08 15:46:36 -06:00
return Status ;
}
static int bcm_download_config_file ( PMINI_ADAPTER Adapter ,
FIRMWARE_INFO * psFwInfo )
{
int retval = STATUS_SUCCESS ;
B_UINT32 value = 0 ;
if ( Adapter - > pstargetparams = = NULL )
{
if ( ( Adapter - > pstargetparams =
kmalloc ( sizeof ( STARGETPARAMS ) , GFP_KERNEL ) ) = = NULL )
{
return - ENOMEM ;
}
}
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
}
/* Parse the structure and then Download the Firmware */
beceem_parse_target_struct ( Adapter ) ;
//Initializing the NVM.
BcmInitNVM ( Adapter ) ;
retval = InitLedSettings ( Adapter ) ;
if ( retval )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " INIT LED Failed \n " ) ;
return retval ;
}
if ( Adapter - > LEDInfo . led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY )
{
Adapter - > LEDInfo . bLedInitDone = FALSE ;
Adapter - > DriverState = DRIVER_INIT ;
wake_up ( & Adapter - > LEDInfo . notify_led_event ) ;
}
if ( Adapter - > LEDInfo . led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY )
{
Adapter - > DriverState = FW_DOWNLOAD ;
wake_up ( & Adapter - > LEDInfo . notify_led_event ) ;
}
/* Initialize the DDR Controller */
retval = ddr_init ( Adapter ) ;
if ( retval )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " DDR Init Failed \n " ) ;
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 ) ) ;
if ( Adapter - > eNVMType = = NVM_FLASH )
{
retval = PropagateCalParamsFromFlashToMemory ( Adapter ) ;
if ( retval )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " propagaion of cal param failed with status :%d " , retval ) ;
return retval ;
}
}
retval = buffDnldVerify ( Adapter , ( PUCHAR ) Adapter - > pstargetparams , sizeof ( STARGETPARAMS ) , CONFIG_BEGIN_ADDR ) ;
if ( retval )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " configuration file not downloaded properly " ) ;
}
else
Adapter - > bCfgDownloaded = TRUE ;
return retval ;
}
static int bcm_compare_buff_contents ( unsigned char * readbackbuff ,
unsigned char * buff , unsigned int len )
{
int retval = STATUS_SUCCESS ;
PMINI_ADAPTER Adapter = GET_BCM_ADAPTER ( gblpnetdev ) ;
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 ;
break ;
}
len - = 4 ;
}
}
return retval ;
}
int bcm_ioctl_fw_download ( PMINI_ADAPTER Adapter , FIRMWARE_INFO * psFwInfo )
{
int retval = STATUS_SUCCESS ;
PUCHAR buff = NULL ;
/* 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 " ) ;
return - EINVAL ;
}
/* If Config File, Finish the DDR Settings and then Download CFG File */
if ( psFwInfo - > u32StartingAddress = = CONFIG_BEGIN_ADDR )
{
retval = bcm_download_config_file ( Adapter , psFwInfo ) ;
}
else
{
2010-11-10 13:31:38 -07:00
buff = kzalloc ( psFwInfo - > u32FirmwareLength , GFP_KERNEL ) ;
2010-09-08 15:46:36 -06:00
if ( buff = = NULL )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " Failed in allocation memory " ) ;
return - ENOMEM ;
}
2010-09-30 02:24:12 -06:00
retval = copy_from_user ( buff , psFwInfo - > pvMappedFirmwareAddress , psFwInfo - > u32FirmwareLength ) ;
2010-09-08 15:46:36 -06:00
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 ;
2010-09-08 15:46:36 -06:00
goto error ;
}
retval = buffDnldVerify ( Adapter ,
buff ,
psFwInfo - > u32FirmwareLength ,
psFwInfo - > u32StartingAddress ) ;
if ( retval ! = STATUS_SUCCESS )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " f/w download failed status :%d " , retval ) ;
goto error ;
}
}
error :
2010-11-01 07:35:21 -06:00
kfree ( buff ) ;
2010-09-08 15:46:36 -06:00
return retval ;
}
static INT buffDnld ( PMINI_ADAPTER Adapter , PUCHAR mappedbuffer , UINT u32FirmwareLength ,
ULONG u32StartingAddress )
{
unsigned int len = 0 ;
int retval = STATUS_SUCCESS ;
len = u32FirmwareLength ;
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 ) ;
break ;
}
u32StartingAddress + = len ;
u32FirmwareLength - = len ;
mappedbuffer + = len ;
}
return retval ;
}
static INT buffRdbkVerify ( PMINI_ADAPTER Adapter ,
PUCHAR mappedbuffer , UINT u32FirmwareLength ,
ULONG u32StartingAddress )
{
UINT len = u32FirmwareLength ;
INT retval = STATUS_SUCCESS ;
2010-11-10 13:31:38 -07:00
PUCHAR readbackbuff = kzalloc ( MAX_TRANSFER_CTRL_BYTE_USB , GFP_KERNEL ) ;
2010-09-08 15:46:36 -06:00
if ( NULL = = readbackbuff )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " MEMORY ALLOCATION FAILED " ) ;
return - ENOMEM ;
}
while ( u32FirmwareLength & & ! retval )
{
len = MIN_VAL ( u32FirmwareLength , MAX_TRANSFER_CTRL_BYTE_USB ) ;
retval = rdm ( Adapter , u32StartingAddress , readbackbuff , len ) ;
if ( retval )
{
BCM_DEBUG_PRINT ( Adapter , DBG_TYPE_INITEXIT , MP_INIT , DBG_LVL_ALL , " rdm failed with status %d " , retval ) ;
break ;
}
if ( STATUS_SUCCESS ! = ( retval = bcm_compare_buff_contents ( readbackbuff , mappedbuffer , len ) ) )
{
break ;
}
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 ;
}
INT buffDnldVerify ( PMINI_ADAPTER Adapter , unsigned char * mappedbuffer , unsigned int u32FirmwareLength ,
unsigned long u32StartingAddress )
{
INT status = STATUS_SUCCESS ;
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 " ) ;
goto error ;
}
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 " ) ;
goto error ;
}
error :
return status ;
}