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