| #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; |
| char *buff=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(;;)*/ |
| |
| kfree(buff); |
| return errno; |
| } |
| |
| int InterfaceFileReadbackFromChip( PVOID arg, |
| struct file *flp, |
| unsigned int on_chip_loc) |
| { |
| char *buff, *buff_readback; |
| 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=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); |
| |
| 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: |
| kfree(buff); |
| 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) |
| { |
| 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; |
| } |
| 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 |
| { |
| |
| 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"); |
| 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 ; |
| } |
| |
| 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: |
| 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) |
| { |
| UINT len = u32FirmwareLength; |
| INT retval = STATUS_SUCCESS; |
| PUCHAR readbackbuff = 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) */ |
| 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; |
| } |
| |
| |