aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/staging/bcm/InterfaceDld.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/staging/bcm/InterfaceDld.c')
-rw-r--r--drivers/staging/bcm/InterfaceDld.c510
1 files changed, 510 insertions, 0 deletions
diff --git a/drivers/staging/bcm/InterfaceDld.c b/drivers/staging/bcm/InterfaceDld.c
new file mode 100644
index 000000000000..60c0f29f3eef
--- /dev/null
+++ b/drivers/staging/bcm/InterfaceDld.c
@@ -0,0 +1,510 @@
+#include "headers.h"
+
+#ifndef BCM_SHM_INTERFACE
+
+int InterfaceFileDownload( PVOID arg,
+ struct file *flp,
+ unsigned int on_chip_loc)
+{
+ char *buff=NULL;
+ // 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;
+
+ buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+ if(!buff)
+ {
+ return -ENOMEM;
+ }
+ 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);
+ 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(;;)*/
+
+ bcm_kfree(buff);
+ return errno;
+}
+
+int InterfaceFileReadbackFromChip( PVOID arg,
+ struct file *flp,
+ unsigned int on_chip_loc)
+{
+ char *buff=NULL, *buff_readback=NULL;
+ 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;
+
+ buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
+ buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
+ if(!buff || !buff_readback)
+ {
+ bcm_kfree(buff);
+ bcm_kfree(buff_readback);
+
+ 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());
+ len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
+ 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:
+ bcm_kfree(buff);
+ bcm_kfree(buff_readback);
+ 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)
+ {
+ bcm_kfree (Adapter->pstargetparams);
+ Adapter->pstargetparams = NULL;
+ return -EFAULT;
+ }
+ /* 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;
+}
+#if 0
+static int bcm_download_buffer(PMINI_ADAPTER Adapter,
+ unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
+ unsigned long u32StartingAddress)
+{
+ char *buff=NULL;
+ unsigned int len = 0;
+ int retval = STATUS_SUCCESS;
+ buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+
+ len = u32FirmwareLength;
+
+ while(u32FirmwareLength)
+ {
+ len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
+ if(STATUS_SUCCESS != (retval = copy_from_user(buff,
+ (unsigned char *)mappedbuffer, len)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
+ break;
+ }
+ retval = wrm (Adapter, u32StartingAddress, buff, len);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n");
+ break;
+ }
+ u32StartingAddress += len;
+ u32FirmwareLength -= len;
+ mappedbuffer +=len;
+ }
+ bcm_kfree(buff);
+ return retval;
+}
+#endif
+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;
+}
+#if 0
+static int bcm_buffer_readback(PMINI_ADAPTER Adapter,
+ unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
+ unsigned long u32StartingAddress)
+{
+ unsigned char *buff = NULL;
+ unsigned char *readbackbuff = NULL;
+ unsigned int len = u32FirmwareLength;
+ int retval = STATUS_SUCCESS;
+
+ buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
+ if(NULL == buff)
+ return -ENOMEM;
+ readbackbuff = (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,
+ GFP_KERNEL);
+ if(NULL == readbackbuff)
+ {
+ bcm_kfree(buff);
+ return -ENOMEM;
+ }
+ while (u32FirmwareLength && !retval)
+ {
+ len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
+
+ /* read from the appl buff and then read from the target, compare */
+ if(STATUS_SUCCESS != (retval = copy_from_user(buff,
+ (unsigned char *)mappedbuffer, len)))
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
+ break;
+ }
+ retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
+ if(retval)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n");
+ break;
+ }
+
+ if (STATUS_SUCCESS !=
+ (retval = bcm_compare_buff_contents (readbackbuff, buff, len)))
+ {
+ break;
+ }
+ u32StartingAddress += len;
+ u32FirmwareLength -= len;
+ mappedbuffer +=len;
+ }/* end of while (u32FirmwareLength && !retval) */
+ bcm_kfree(buff);
+ bcm_kfree(readbackbuff);
+ return retval;
+}
+#endif
+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
+ {
+
+ buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
+ if(buff==NULL)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
+ return -ENOMEM;
+ }
+ 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");
+ retval = -EFAULT;
+ goto error ;
+ }
+
+ #if 0
+ retval = bcm_download_buffer(Adapter,
+ (unsigned char *)psFwInfo->pvMappedFirmwareAddress,
+ psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails....");
+ }
+ retval = bcm_buffer_readback (Adapter,
+ (unsigned char *)psFwInfo->pvMappedFirmwareAddress,
+ psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
+
+ if(retval != STATUS_SUCCESS)
+ {
+ BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ....");
+ }
+ #endif
+ 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:
+ bcm_kfree(buff);
+ 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)
+{
+ PUCHAR readbackbuff = NULL;
+ UINT len = u32FirmwareLength;
+ INT retval = STATUS_SUCCESS;
+
+ readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
+ 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) */
+ bcm_kfree(readbackbuff);
+ 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;
+}
+
+#endif
+