1#include "headers.h" 2 3int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc) 4{ 5 /* unsigned int reg = 0; */ 6 mm_segment_t oldfs = {0}; 7 int errno = 0, len = 0; /* ,is_config_file = 0 */ 8 loff_t pos = 0; 9 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; 10 /* PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter; */ 11 char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); 12 13 if (!buff) 14 return -ENOMEM; 15 16 while (1) { 17 oldfs = get_fs(); 18 set_fs(get_ds()); 19 len = vfs_read(flp, (void __force __user *)buff, 20 MAX_TRANSFER_CTRL_BYTE_USB, &pos); 21 set_fs(oldfs); 22 if (len <= 0) { 23 if (len < 0) { 24 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, 25 DBG_TYPE_INITEXIT, MP_INIT, 26 DBG_LVL_ALL, "len < 0"); 27 errno = len; 28 } else { 29 errno = 0; 30 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, 31 DBG_TYPE_INITEXIT, MP_INIT, 32 DBG_LVL_ALL, 33 "Got end of file!"); 34 } 35 break; 36 } 37 /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, 38 * DBG_LVL_ALL, buff, 39 * MAX_TRANSFER_CTRL_BYTE_USB); 40 */ 41 errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); 42 if (errno) { 43 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, 44 DBG_TYPE_PRINTK, 0, 0, 45 "WRM Failed! status: %d", errno); 46 break; 47 } 48 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; 49 } 50 51 kfree(buff); 52 return errno; 53} 54 55int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc) 56{ 57 char *buff, *buff_readback; 58 unsigned int reg = 0; 59 mm_segment_t oldfs = {0}; 60 int errno = 0, len = 0, is_config_file = 0; 61 loff_t pos = 0; 62 static int fw_down; 63 INT Status = STATUS_SUCCESS; 64 PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg; 65 int bytes; 66 67 buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); 68 buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); 69 if (!buff || !buff_readback) { 70 kfree(buff); 71 kfree(buff_readback); 72 73 return -ENOMEM; 74 } 75 76 is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0; 77 78 memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB); 79 memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB); 80 while (1) { 81 oldfs = get_fs(); 82 set_fs(get_ds()); 83 len = vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos); 84 set_fs(oldfs); 85 fw_down++; 86 87 if (len <= 0) { 88 if (len < 0) { 89 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0"); 90 errno = len; 91 } else { 92 errno = 0; 93 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!"); 94 } 95 break; 96 } 97 98 bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len); 99 if (bytes < 0) { 100 Status = bytes; 101 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg); 102 goto exit; 103 } 104 reg++; 105 if ((len-sizeof(unsigned int)) < 4) { 106 if (memcmp(buff_readback, buff, len)) { 107 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); 108 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Length is: %d", len); 109 Status = -EIO; 110 goto exit; 111 } 112 } else { 113 len -= 4; 114 115 while (len) { 116 if (*(unsigned int *)&buff_readback[len] != *(unsigned int *)&buff[len]) { 117 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down); 118 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]); 119 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); 120 Status = -EIO; 121 goto exit; 122 } 123 len -= 4; 124 } 125 } 126 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; 127 } /* End of while(1) */ 128 129exit: 130 kfree(buff); 131 kfree(buff_readback); 132 return Status; 133} 134 135static int bcm_download_config_file(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) 136{ 137 int retval = STATUS_SUCCESS; 138 B_UINT32 value = 0; 139 140 if (Adapter->pstargetparams == NULL) { 141 Adapter->pstargetparams = kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL); 142 if (Adapter->pstargetparams == NULL) 143 return -ENOMEM; 144 } 145 146 if (psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS)) 147 return -EIO; 148 149 retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); 150 if (retval) { 151 kfree(Adapter->pstargetparams); 152 Adapter->pstargetparams = NULL; 153 return -EFAULT; 154 } 155 156 /* Parse the structure and then Download the Firmware */ 157 beceem_parse_target_struct(Adapter); 158 159 /* Initializing the NVM. */ 160 BcmInitNVM(Adapter); 161 retval = InitLedSettings(Adapter); 162 163 if (retval) { 164 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n"); 165 return retval; 166 } 167 168 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { 169 Adapter->LEDInfo.bLedInitDone = FALSE; 170 Adapter->DriverState = DRIVER_INIT; 171 wake_up(&Adapter->LEDInfo.notify_led_event); 172 } 173 174 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) { 175 Adapter->DriverState = FW_DOWNLOAD; 176 wake_up(&Adapter->LEDInfo.notify_led_event); 177 } 178 179 /* Initialize the DDR Controller */ 180 retval = ddr_init(Adapter); 181 if (retval) { 182 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n"); 183 return retval; 184 } 185 186 value = 0; 187 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value)); 188 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value)); 189 190 if (Adapter->eNVMType == NVM_FLASH) { 191 retval = PropagateCalParamsFromFlashToMemory(Adapter); 192 if (retval) { 193 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "propagaion of cal param failed with status :%d", retval); 194 return retval; 195 } 196 } 197 198 retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(STARGETPARAMS), CONFIG_BEGIN_ADDR); 199 200 if (retval) 201 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly"); 202 else 203 Adapter->bCfgDownloaded = TRUE; 204 205 return retval; 206} 207 208static int bcm_compare_buff_contents(unsigned char *readbackbuff, unsigned char *buff, unsigned int len) 209{ 210 int retval = STATUS_SUCCESS; 211 PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev); 212 if ((len-sizeof(unsigned int)) < 4) { 213 if (memcmp(readbackbuff , buff, len)) 214 retval = -EINVAL; 215 } else { 216 len -= 4; 217 218 while (len) { 219 if (*(unsigned int *)&readbackbuff[len] != *(unsigned int *)&buff[len]) { 220 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper"); 221 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]); 222 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len); 223 retval = -EINVAL; 224 break; 225 } 226 len -= 4; 227 } 228 } 229 return retval; 230} 231 232int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo) 233{ 234 int retval = STATUS_SUCCESS; 235 PUCHAR buff = NULL; 236 237 /* Config File is needed for the Driver to download the Config file and 238 * Firmware. Check for the Config file to be first to be sent from the 239 * Application 240 */ 241 atomic_set(&Adapter->uiMBupdate, FALSE); 242 if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { 243 /* Can't Download Firmware. */ 244 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n"); 245 return -EINVAL; 246 } 247 248 /* If Config File, Finish the DDR Settings and then Download CFG File */ 249 if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) { 250 retval = bcm_download_config_file(Adapter, psFwInfo); 251 } else { 252 buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL); 253 if (buff == NULL) { 254 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory"); 255 return -ENOMEM; 256 } 257 258 retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength); 259 if (retval != STATUS_SUCCESS) { 260 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed"); 261 retval = -EFAULT; 262 goto error; 263 } 264 265 retval = buffDnldVerify(Adapter, 266 buff, 267 psFwInfo->u32FirmwareLength, 268 psFwInfo->u32StartingAddress); 269 270 if (retval != STATUS_SUCCESS) { 271 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval); 272 goto error; 273 } 274 } 275 276error: 277 kfree(buff); 278 return retval; 279} 280 281static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) 282{ 283 unsigned int len = 0; 284 int retval = STATUS_SUCCESS; 285 len = u32FirmwareLength; 286 287 while (u32FirmwareLength) { 288 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); 289 retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len); 290 291 if (retval) { 292 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval); 293 break; 294 } 295 u32StartingAddress += len; 296 u32FirmwareLength -= len; 297 mappedbuffer += len; 298 } 299 return retval; 300} 301 302static INT buffRdbkVerify(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress) 303{ 304 UINT len = u32FirmwareLength; 305 INT retval = STATUS_SUCCESS; 306 PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); 307 int bytes; 308 309 if (NULL == readbackbuff) { 310 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED"); 311 return -ENOMEM; 312 } 313 314 while (u32FirmwareLength && !retval) { 315 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); 316 bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len); 317 318 if (bytes < 0) { 319 retval = bytes; 320 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval); 321 break; 322 } 323 324 retval = bcm_compare_buff_contents(readbackbuff, mappedbuffer, len); 325 if (STATUS_SUCCESS != retval) 326 break; 327 328 u32StartingAddress += len; 329 u32FirmwareLength -= len; 330 mappedbuffer += len; 331 332 } /* end of while (u32FirmwareLength && !retval) */ 333 kfree(readbackbuff); 334 return retval; 335} 336 337INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress) 338{ 339 INT status = STATUS_SUCCESS; 340 341 status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress); 342 if (status != STATUS_SUCCESS) { 343 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed"); 344 goto error; 345 } 346 347 status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress); 348 if (status != STATUS_SUCCESS) { 349 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed"); 350 goto error; 351 } 352error: 353 return status; 354} 355