Merge 3.9-rc5 into staging-next
[deliverable/linux.git] / drivers / staging / bcm / InterfaceDld.c
CommitLineData
f8942e07
SH
1#include "headers.h"
2
43664e14 3int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
f8942e07 4{
a5e4b81e 5 /* unsigned int reg = 0; */
43664e14 6 mm_segment_t oldfs = {0};
a5e4b81e 7 int errno = 0, len = 0; /* ,is_config_file = 0 */
43664e14 8 loff_t pos = 0;
d6861cfe 9 struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
2979460d 10 /* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
43664e14 11 char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
f8942e07 12
43664e14
MPS
13 if (!buff)
14 return -ENOMEM;
f8942e07 15
43664e14
MPS
16 while (1) {
17 oldfs = get_fs();
18 set_fs(get_ds());
19 len = vfs_read(flp, (void __force __user *)buff,
a5e4b81e 20 MAX_TRANSFER_CTRL_BYTE_USB, &pos);
43664e14
MPS
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,
a5e4b81e
KM
38 * DBG_LVL_ALL, buff,
39 * MAX_TRANSFER_CTRL_BYTE_USB);
40 */
43664e14
MPS
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;
f8942e07 47 }
43664e14
MPS
48 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
49 }
f8942e07 50
082e889b 51 kfree(buff);
43664e14 52 return errno;
f8942e07
SH
53}
54
a5e4b81e 55int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp, unsigned int on_chip_loc)
f8942e07 56{
43664e14
MPS
57 char *buff, *buff_readback;
58 unsigned int reg = 0;
a5e4b81e
KM
59 mm_segment_t oldfs = {0};
60 int errno = 0, len = 0, is_config_file = 0;
61 loff_t pos = 0;
a8658182 62 static int fw_down;
a5e4b81e 63 INT Status = STATUS_SUCCESS;
d6861cfe 64 struct bcm_interface_adapter *psIntfAdapter = (struct bcm_interface_adapter *)arg;
41c7b7c0 65 int bytes;
f8942e07 66
a5e4b81e
KM
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);
f8942e07 72
a5e4b81e
KM
73 return -ENOMEM;
74 }
f8942e07 75
a5e4b81e 76 is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;
f8942e07
SH
77
78 memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
79 memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
a5e4b81e
KM
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++;
f8942e07 86
a5e4b81e
KM
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 }
f8942e07 97
41c7b7c0
KM
98 bytes = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
99 if (bytes < 0) {
100 Status = bytes;
a5e4b81e 101 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
f8942e07
SH
102 goto exit;
103 }
104 reg++;
a5e4b81e
KM
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);
f8942e07
SH
109 Status = -EIO;
110 goto exit;
a5e4b81e
KM
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);
f8942e07
SH
120 Status = -EIO;
121 goto exit;
a5e4b81e
KM
122 }
123 len -= 4;
124 }
125 }
126 on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
127 } /* End of while(1) */
128
f8942e07 129exit:
a5e4b81e
KM
130 kfree(buff);
131 kfree(buff_readback);
f8942e07
SH
132 return Status;
133}
134
2979460d 135static int bcm_download_config_file(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo)
f8942e07
SH
136{
137 int retval = STATUS_SUCCESS;
138 B_UINT32 value = 0;
139
a5e4b81e 140 if (Adapter->pstargetparams == NULL) {
c8182334 141 Adapter->pstargetparams = kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL);
a8658182 142 if (Adapter->pstargetparams == NULL)
a5e4b81e 143 return -ENOMEM;
f8942e07 144 }
a5e4b81e 145
c8182334 146 if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params))
a5e4b81e
KM
147 return -EIO;
148
149 retval = copy_from_user(Adapter->pstargetparams, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
150 if (retval) {
082e889b 151 kfree(Adapter->pstargetparams);
f8942e07 152 Adapter->pstargetparams = NULL;
ef5d2056 153 return -EFAULT;
f8942e07 154 }
a5e4b81e 155
f8942e07
SH
156 /* Parse the structure and then Download the Firmware */
157 beceem_parse_target_struct(Adapter);
158
a5e4b81e 159 /* Initializing the NVM. */
f8942e07 160 BcmInitNVM(Adapter);
a5e4b81e 161 retval = InitLedSettings(Adapter);
f8942e07 162
a5e4b81e
KM
163 if (retval) {
164 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
f8942e07
SH
165 return retval;
166 }
167
a5e4b81e 168 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
f8942e07
SH
169 Adapter->LEDInfo.bLedInitDone = FALSE;
170 Adapter->DriverState = DRIVER_INIT;
171 wake_up(&Adapter->LEDInfo.notify_led_event);
172 }
173
a5e4b81e 174 if (Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY) {
f8942e07
SH
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);
a5e4b81e
KM
181 if (retval) {
182 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
f8942e07
SH
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
a5e4b81e 190 if (Adapter->eNVMType == NVM_FLASH) {
f8942e07 191 retval = PropagateCalParamsFromFlashToMemory(Adapter);
a5e4b81e
KM
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);
f8942e07
SH
194 return retval;
195 }
196 }
197
c8182334 198 retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams, sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR);
f8942e07 199
a5e4b81e
KM
200 if (retval)
201 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
f8942e07
SH
202 else
203 Adapter->bCfgDownloaded = TRUE;
204
f8942e07
SH
205 return retval;
206}
a5e4b81e 207
2979460d 208int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter, struct bcm_firmware_info *psFwInfo)
f8942e07
SH
209{
210 int retval = STATUS_SUCCESS;
211 PUCHAR buff = NULL;
212
a5e4b81e
KM
213 /* Config File is needed for the Driver to download the Config file and
214 * Firmware. Check for the Config file to be first to be sent from the
215 * Application
216 */
217 atomic_set(&Adapter->uiMBupdate, FALSE);
218 if (!Adapter->bCfgDownloaded && psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
219 /* Can't Download Firmware. */
220 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Download the config File first\n");
f8942e07
SH
221 return -EINVAL;
222 }
223
224 /* If Config File, Finish the DDR Settings and then Download CFG File */
a5e4b81e
KM
225 if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
226 retval = bcm_download_config_file(Adapter, psFwInfo);
227 } else {
228 buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
229 if (buff == NULL) {
230 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Failed in allocation memory");
f8942e07
SH
231 return -ENOMEM;
232 }
a5e4b81e
KM
233
234 retval = copy_from_user(buff, psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
235 if (retval != STATUS_SUCCESS) {
236 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
ef5d2056 237 retval = -EFAULT;
a5e4b81e 238 goto error;
f8942e07
SH
239 }
240
f8942e07
SH
241 retval = buffDnldVerify(Adapter,
242 buff,
243 psFwInfo->u32FirmwareLength,
244 psFwInfo->u32StartingAddress);
a5e4b81e
KM
245
246 if (retval != STATUS_SUCCESS) {
247 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "f/w download failed status :%d", retval);
f8942e07
SH
248 goto error;
249 }
250 }
a5e4b81e 251
f8942e07 252error:
082e889b 253 kfree(buff);
f8942e07
SH
254 return retval;
255}
256
2979460d 257static INT buffDnld(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
f8942e07 258{
a5e4b81e 259 unsigned int len = 0;
f8942e07
SH
260 int retval = STATUS_SUCCESS;
261 len = u32FirmwareLength;
262
a5e4b81e
KM
263 while (u32FirmwareLength) {
264 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
265 retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);
266
267 if (retval) {
268 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
f8942e07
SH
269 break;
270 }
a5e4b81e
KM
271 u32StartingAddress += len;
272 u32FirmwareLength -= len;
273 mappedbuffer += len;
f8942e07
SH
274 }
275 return retval;
f8942e07
SH
276}
277
2979460d 278static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength, ULONG u32StartingAddress)
f8942e07 279{
f8942e07
SH
280 UINT len = u32FirmwareLength;
281 INT retval = STATUS_SUCCESS;
a5e4b81e 282 PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
41c7b7c0 283 int bytes;
f8942e07 284
a5e4b81e
KM
285 if (NULL == readbackbuff) {
286 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
f8942e07
SH
287 return -ENOMEM;
288 }
f8942e07 289
a5e4b81e
KM
290 while (u32FirmwareLength && !retval) {
291 len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
41c7b7c0 292 bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len);
f8942e07 293
41c7b7c0
KM
294 if (bytes < 0) {
295 retval = bytes;
a5e4b81e 296 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d", retval);
f8942e07
SH
297 break;
298 }
299
2c5270ac
DC
300 if (memcmp(readbackbuff, mappedbuffer, len) != 0) {
301 pr_err("%s() failed. The firmware doesn't match what was written",
302 __func__);
303 retval = -EIO;
304 }
a5e4b81e
KM
305
306 u32StartingAddress += len;
307 u32FirmwareLength -= len;
308 mappedbuffer += len;
309
310 } /* end of while (u32FirmwareLength && !retval) */
082e889b 311 kfree(readbackbuff);
f8942e07
SH
312 return retval;
313}
314
2979460d 315INT buffDnldVerify(struct bcm_mini_adapter *Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength, unsigned long u32StartingAddress)
f8942e07
SH
316{
317 INT status = STATUS_SUCCESS;
318
a5e4b81e
KM
319 status = buffDnld(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
320 if (status != STATUS_SUCCESS) {
321 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer download failed");
f8942e07
SH
322 goto error;
323 }
324
a5e4b81e
KM
325 status = buffRdbkVerify(Adapter, mappedbuffer, u32FirmwareLength, u32StartingAddress);
326 if (status != STATUS_SUCCESS) {
327 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Buffer readback verifier failed");
f8942e07
SH
328 goto error;
329 }
330error:
331 return status;
332}
This page took 0.444371 seconds and 5 git commands to generate.