KVM: x86: update KVM_SAVE_MSRS_BEGIN to correct value
[cascardo/linux.git] / drivers / staging / bcm / InterfaceDld.c
1 #include "headers.h"
2
3 int 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
55 int 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
129 exit:
130         kfree(buff);
131         kfree(buff_readback);
132         return Status;
133 }
134
135 static 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
208 static 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
232 int 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
276 error:
277         kfree(buff);
278         return retval;
279 }
280
281 static 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
302 static 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
337 INT 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         }
352 error:
353         return status;
354 }