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 struct bcm_interface_adapter *psIntfAdapter = arg; 10 /* struct bcm_mini_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 errno = len; 25 else 26 errno = 0; 27 break; 28 } 29 /* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, 30 * DBG_LVL_ALL, buff, 31 * MAX_TRANSFER_CTRL_BYTE_USB); 32 */ 33 errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len); 34 if (errno) 35 break; 36 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; 37 } 38 39 kfree(buff); 40 return errno; 41} 42 43int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, 44 unsigned int on_chip_loc) 45{ 46 char *buff, *buff_readback; 47 unsigned int reg = 0; 48 mm_segment_t oldfs = {0}; 49 int errno = 0, len = 0, is_config_file = 0; 50 loff_t pos = 0; 51 static int fw_down; 52 INT Status = STATUS_SUCCESS; 53 struct bcm_interface_adapter *psIntfAdapter = arg; 54 int bytes; 55 56 buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA); 57 buff_readback = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA); 58 if (!buff || !buff_readback) { 59 kfree(buff); 60 kfree(buff_readback); 61 62 return -ENOMEM; 63 } 64 65 is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0; 66 67 while (1) { 68 oldfs = get_fs(); 69 set_fs(get_ds()); 70 len = vfs_read(flp, (void __force __user *)buff, 71 MAX_TRANSFER_CTRL_BYTE_USB, &pos); 72 set_fs(oldfs); 73 fw_down++; 74 75 if (len <= 0) { 76 if (len < 0) 77 errno = len; 78 else 79 errno = 0; 80 break; 81 } 82 83 bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, 84 buff_readback, len); 85 if (bytes < 0) { 86 Status = bytes; 87 goto exit; 88 } 89 reg++; 90 if ((len-sizeof(unsigned int)) < 4) { 91 if (memcmp(buff_readback, buff, len)) { 92 Status = -EIO; 93 goto exit; 94 } 95 } else { 96 len -= 4; 97 98 while (len) { 99 if (*(unsigned int *)&buff_readback[len] != 100 *(unsigned int *)&buff[len]) { 101 Status = -EIO; 102 goto exit; 103 } 104 len -= 4; 105 } 106 } 107 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB; 108 } /* End of while(1) */ 109 110exit: 111 kfree(buff); 112 kfree(buff_readback); 113 return Status; 114} 115 116static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, 117 struct bcm_firmware_info *psFwInfo) 118{ 119 int retval = STATUS_SUCCESS; 120 B_UINT32 value = 0; 121 122 if (Adapter->pstargetparams == NULL) { 123 Adapter->pstargetparams = 124 kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL); 125 if (Adapter->pstargetparams == NULL) 126 return -ENOMEM; 127 } 128 129 if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params)) 130 return -EIO; 131 132 retval = copy_from_user(Adapter->pstargetparams, 133 psFwInfo->pvMappedFirmwareAddress, 134 psFwInfo->u32FirmwareLength); 135 if (retval) { 136 kfree(Adapter->pstargetparams); 137 Adapter->pstargetparams = NULL; 138 return -EFAULT; 139 } 140 141 /* Parse the structure and then Download the Firmware */ 142 beceem_parse_target_struct(Adapter); 143 144 /* Initializing the NVM. */ 145 BcmInitNVM(Adapter); 146 retval = InitLedSettings(Adapter); 147 148 if (retval) 149 return retval; 150 151 if (Adapter->LEDInfo.led_thread_running & 152 BCM_LED_THREAD_RUNNING_ACTIVELY) { 153 Adapter->LEDInfo.bLedInitDone = false; 154 Adapter->DriverState = DRIVER_INIT; 155 wake_up(&Adapter->LEDInfo.notify_led_event); 156 } 157 158 if (Adapter->LEDInfo.led_thread_running & 159 BCM_LED_THREAD_RUNNING_ACTIVELY) { 160 Adapter->DriverState = FW_DOWNLOAD; 161 wake_up(&Adapter->LEDInfo.notify_led_event); 162 } 163 164 /* Initialize the DDR Controller */ 165 retval = ddr_init(Adapter); 166 if (retval) 167 return retval; 168 169 value = 0; 170 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, 171 &value, sizeof(value)); 172 wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, 173 &value, sizeof(value)); 174 175 if (Adapter->eNVMType == NVM_FLASH) { 176 retval = PropagateCalParamsFromFlashToMemory(Adapter); 177 if (retval) 178 return retval; 179 } 180 181 retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, 182 sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR); 183 184 if (retval) 185 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, 186 MP_INIT, DBG_LVL_ALL, 187 "configuration file not downloaded properly"); 188 else 189 Adapter->bCfgDownloaded = TRUE; 190 191 return retval; 192} 193 194int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, 195 struct bcm_firmware_info *psFwInfo) 196{ 197 int retval = STATUS_SUCCESS; 198 PUCHAR buff = NULL; 199 200 /* Config File is needed for the Driver to download the Config file and 201 * Firmware. Check for the Config file to be first to be sent from the 202 * Application 203 */ 204 atomic_set(&Adapter->uiMBupdate, false); 205 if (!Adapter->bCfgDownloaded && 206 psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) { 207 /* Can't Download Firmware. */ 208 return -EINVAL; 209 } 210 211 /* If Config File, Finish the DDR Settings and then Download CFG File */ 212 if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) { 213 retval = bcm_download_config_file(Adapter, psFwInfo); 214 } else { 215 buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL); 216 if (buff == NULL) 217 return -ENOMEM; 218 219 retval = copy_from_user(buff, 220 psFwInfo->pvMappedFirmwareAddress, 221 psFwInfo->u32FirmwareLength); 222 if (retval != STATUS_SUCCESS) { 223 retval = -EFAULT; 224 goto error; 225 } 226 227 retval = buffDnldVerify(Adapter, 228 buff, 229 psFwInfo->u32FirmwareLength, 230 psFwInfo->u32StartingAddress); 231 232 if (retval != STATUS_SUCCESS) 233 goto error; 234 } 235 236error: 237 kfree(buff); 238 return retval; 239} 240 241static INT buffDnld(struct bcm_mini_adapter *Adapter, 242 PUCHAR mappedbuffer, UINT u32FirmwareLength, 243 ULONG u32StartingAddress) 244{ 245 unsigned int len = 0; 246 int retval = STATUS_SUCCESS; 247 248 len = u32FirmwareLength; 249 250 while (u32FirmwareLength) { 251 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); 252 retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len); 253 254 if (retval) 255 break; 256 u32StartingAddress += len; 257 u32FirmwareLength -= len; 258 mappedbuffer += len; 259 } 260 return retval; 261} 262 263static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, 264 PUCHAR mappedbuffer, UINT u32FirmwareLength, 265 ULONG u32StartingAddress) 266{ 267 UINT len = u32FirmwareLength; 268 INT retval = STATUS_SUCCESS; 269 PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL); 270 int bytes; 271 272 if (NULL == readbackbuff) 273 return -ENOMEM; 274 275 while (u32FirmwareLength && !retval) { 276 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB); 277 bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len); 278 279 if (bytes < 0) { 280 retval = bytes; 281 break; 282 } 283 284 if (memcmp(readbackbuff, mappedbuffer, len) != 0) { 285 pr_err("%s() failed. The firmware doesn't match what was written", 286 __func__); 287 retval = -EIO; 288 } 289 290 u32StartingAddress += len; 291 u32FirmwareLength -= len; 292 mappedbuffer += len; 293 294 } /* end of while (u32FirmwareLength && !retval) */ 295 kfree(readbackbuff); 296 return retval; 297} 298 299INT buffDnldVerify(struct bcm_mini_adapter *Adapter, 300 unsigned char *mappedbuffer, 301 unsigned int u32FirmwareLength, 302 unsigned long u32StartingAddress) 303{ 304 INT status = STATUS_SUCCESS; 305 306 status = buffDnld(Adapter, mappedbuffer, 307 u32FirmwareLength, u32StartingAddress); 308 if (status != STATUS_SUCCESS) 309 goto error; 310 311 status = buffRdbkVerify(Adapter, mappedbuffer, 312 u32FirmwareLength, u32StartingAddress); 313 if (status != STATUS_SUCCESS) 314 goto error; 315error: 316 return status; 317} 318