Merge branch 'x86-platform-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[pandora-kernel.git] / drivers / staging / bcm / InterfaceDld.c
1 #include "headers.h"
2
3 #ifndef BCM_SHM_INTERFACE
4
5 int InterfaceFileDownload( PVOID arg,
6                         struct file *flp,
7                         unsigned int on_chip_loc)
8 {
9     char            *buff=NULL;
10    // unsigned int    reg=0;
11     mm_segment_t    oldfs={0};
12     int             errno=0, len=0 /*,is_config_file = 0*/;
13     loff_t          pos=0;
14         PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
15         //PMINI_ADAPTER Adapter = psIntfAdapter->psAdapter;
16
17     buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
18     if(!buff)
19     {
20         return -ENOMEM;
21     }
22     while(1)
23     {
24         oldfs=get_fs(); set_fs(get_ds());
25         len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
26         set_fs(oldfs);
27         if(len<=0)
28         {
29             if(len<0)
30             {
31                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
32                 errno=len;
33             }
34             else
35             {
36                 errno = 0;
37                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
38             }
39             break;
40         }
41         //BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, buff, MAX_TRANSFER_CTRL_BYTE_USB);
42         errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len) ;
43                 if(errno)
44                 {
45             BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed! status: %d", errno);
46                         break;
47
48                 }
49         on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
50         }/* End of for(;;)*/
51
52         bcm_kfree(buff);
53     return errno;
54 }
55
56 int InterfaceFileReadbackFromChip( PVOID arg,
57                         struct file *flp,
58                         unsigned int on_chip_loc)
59 {
60     char            *buff=NULL, *buff_readback=NULL;
61     unsigned int    reg=0;
62     mm_segment_t    oldfs={0};
63     int             errno=0, len=0, is_config_file = 0;
64     loff_t          pos=0;
65     static int fw_down = 0;
66         INT                             Status = STATUS_SUCCESS;
67         PS_INTERFACE_ADAPTER psIntfAdapter = (PS_INTERFACE_ADAPTER)arg;
68
69     buff=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
70     buff_readback=(PCHAR)kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
71     if(!buff || !buff_readback)
72     {
73         bcm_kfree(buff);
74         bcm_kfree(buff_readback);
75
76         return -ENOMEM;
77     }
78
79         is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR)? 1:0;
80
81         memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
82         memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
83     while(1)
84     {
85         oldfs=get_fs(); set_fs(get_ds());
86         len=vfs_read(flp, (void __force __user *)buff, MAX_TRANSFER_CTRL_BYTE_USB, &pos);
87         set_fs(oldfs);
88         fw_down++;
89         if(len<=0)
90         {
91             if(len<0)
92             {
93                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len < 0");
94                 errno=len;
95             }
96             else
97             {
98                 errno = 0;
99                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Got end of file!");
100             }
101             break;
102         }
103
104
105                 Status = InterfaceRDM(psIntfAdapter, on_chip_loc, buff_readback, len);
106                 if(Status)
107                 {
108             BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "RDM of len %d Failed! %d", len, reg);
109                         goto exit;
110                 }
111                 reg++;
112         if((len-sizeof(unsigned int))<4)
113         {
114             if(memcmp(buff_readback, buff, len))
115             {
116                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
117                                 BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT,DBG_LVL_ALL,"Length is: %d",len);
118                                 Status = -EIO;
119                                 goto exit;
120             }
121         }
122         else
123         {
124             len-=4;
125             while(len)
126             {
127                 if(*(unsigned int*)&buff_readback[len] != *(unsigned int *)&buff[len])
128                 {
129                     BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper %d", fw_down);
130                     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]);
131                     BCM_DEBUG_PRINT(psIntfAdapter->psAdapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
132                                         Status = -EIO;
133                                         goto exit;
134                 }
135                 len-=4;
136             }
137         }
138         on_chip_loc+=MAX_TRANSFER_CTRL_BYTE_USB;
139     }/* End of while(1)*/
140 exit:
141     bcm_kfree(buff);
142     bcm_kfree(buff_readback);
143         return Status;
144 }
145
146 static int bcm_download_config_file(PMINI_ADAPTER Adapter,
147                                                                 FIRMWARE_INFO *psFwInfo)
148 {
149         int retval = STATUS_SUCCESS;
150         B_UINT32 value = 0;
151
152         if(Adapter->pstargetparams == NULL)
153     {
154         if((Adapter->pstargetparams =
155             kmalloc(sizeof(STARGETPARAMS), GFP_KERNEL)) == NULL)
156         {
157             return -ENOMEM;
158         }
159     }
160         if(psFwInfo->u32FirmwareLength != sizeof(STARGETPARAMS))
161         {
162                 return -EIO;
163         }
164         retval = copy_from_user(Adapter->pstargetparams,
165                         psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
166         if(retval)
167         {
168                 bcm_kfree (Adapter->pstargetparams);
169                 Adapter->pstargetparams = NULL;
170                 return -EFAULT;
171         }
172         /* Parse the structure and then Download the Firmware */
173         beceem_parse_target_struct(Adapter);
174
175         //Initializing the NVM.
176         BcmInitNVM(Adapter);
177
178         retval = InitLedSettings (Adapter);
179
180         if(retval)
181         {
182                 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "INIT LED Failed\n");
183                 return retval;
184         }
185
186         if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
187         {
188                 Adapter->LEDInfo.bLedInitDone = FALSE;
189                 Adapter->DriverState = DRIVER_INIT;
190                 wake_up(&Adapter->LEDInfo.notify_led_event);
191         }
192
193         if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
194         {
195                 Adapter->DriverState = FW_DOWNLOAD;
196                 wake_up(&Adapter->LEDInfo.notify_led_event);
197         }
198
199         /* Initialize the DDR Controller */
200         retval = ddr_init(Adapter);
201         if(retval)
202         {
203                 BCM_DEBUG_PRINT (Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "DDR Init Failed\n");
204                 return retval;
205         }
206
207         value = 0;
208         wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4, &value, sizeof(value));
209         wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8, &value, sizeof(value));
210
211         if(Adapter->eNVMType == NVM_FLASH)
212         {
213                 retval = PropagateCalParamsFromFlashToMemory(Adapter);
214                 if(retval)
215                 {
216                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"propagaion of cal param failed with status :%d", retval);
217                         return retval;
218                 }
219         }
220
221
222         retval =buffDnldVerify(Adapter,(PUCHAR)Adapter->pstargetparams,sizeof(STARGETPARAMS),CONFIG_BEGIN_ADDR);
223
224         if(retval)
225         {
226                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "configuration file not downloaded properly");
227         }
228         else
229                 Adapter->bCfgDownloaded = TRUE;
230
231
232         return retval;
233 }
234 #if 0
235 static int bcm_download_buffer(PMINI_ADAPTER Adapter,
236         unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
237         unsigned long u32StartingAddress)
238 {
239     char            *buff=NULL;
240     unsigned int    len = 0;
241         int                     retval = STATUS_SUCCESS;
242         buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
243
244         len = u32FirmwareLength;
245
246         while(u32FirmwareLength)
247         {
248                 len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
249                 if(STATUS_SUCCESS != (retval = copy_from_user(buff,
250                                 (unsigned char *)mappedbuffer, len)))
251                 {
252                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
253                         break;
254                 }
255                 retval = wrm (Adapter, u32StartingAddress, buff, len);
256                 if(retval)
257                 {
258                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed\n");
259                         break;
260                 }
261                 u32StartingAddress      += len;
262                 u32FirmwareLength       -= len;
263                 mappedbuffer            +=len;
264         }
265         bcm_kfree(buff);
266         return retval;
267 }
268 #endif
269 static int bcm_compare_buff_contents(unsigned char *readbackbuff,
270         unsigned char *buff,unsigned int len)
271 {
272         int retval = STATUS_SUCCESS;
273     PMINI_ADAPTER Adapter = GET_BCM_ADAPTER(gblpnetdev);
274     if((len-sizeof(unsigned int))<4)
275         {
276                 if(memcmp(readbackbuff , buff, len))
277                 {
278                         retval=-EINVAL;
279                 }
280         }
281         else
282         {
283                 len-=4;
284                 while(len)
285                 {
286                         if(*(unsigned int*)&readbackbuff[len] !=
287                                         *(unsigned int *)&buff[len])
288                         {
289                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "Firmware Download is not proper");
290                                 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]);
291                                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "len =%x!!!", len);
292                                 retval=-EINVAL;
293                                 break;
294                         }
295                         len-=4;
296                 }
297         }
298         return retval;
299 }
300 #if 0
301 static int bcm_buffer_readback(PMINI_ADAPTER Adapter,
302         unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
303         unsigned long u32StartingAddress)
304 {
305         unsigned char *buff = NULL;
306         unsigned char *readbackbuff = NULL;
307         unsigned int  len = u32FirmwareLength;
308         int retval = STATUS_SUCCESS;
309
310     buff=(unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
311         if(NULL == buff)
312                 return -ENOMEM;
313         readbackbuff =  (unsigned char *)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,
314                                         GFP_KERNEL);
315         if(NULL == readbackbuff)
316         {
317                 bcm_kfree(buff);
318                 return -ENOMEM;
319         }
320         while (u32FirmwareLength && !retval)
321         {
322                 len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
323
324                 /* read from the appl buff and then read from the target, compare */
325                 if(STATUS_SUCCESS != (retval = copy_from_user(buff,
326                                 (unsigned char *)mappedbuffer, len)))
327                 {
328                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copy_from_user failed\n");
329                         break;
330                 }
331                 retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
332                 if(retval)
333                 {
334                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed\n");
335                         break;
336                 }
337
338                 if (STATUS_SUCCESS !=
339                         (retval = bcm_compare_buff_contents (readbackbuff, buff, len)))
340                 {
341                         break;
342                 }
343                 u32StartingAddress      += len;
344                 u32FirmwareLength       -= len;
345                 mappedbuffer            +=len;
346         }/* end of while (u32FirmwareLength && !retval) */
347         bcm_kfree(buff);
348         bcm_kfree(readbackbuff);
349         return retval;
350 }
351 #endif
352 int bcm_ioctl_fw_download(PMINI_ADAPTER Adapter, FIRMWARE_INFO *psFwInfo)
353 {
354         int retval = STATUS_SUCCESS;
355         PUCHAR buff = NULL;
356
357         /*  Config File is needed for the Driver to download the Config file and
358                 Firmware. Check for the Config file to be first to be sent from the
359                 Application
360         */
361         atomic_set (&Adapter->uiMBupdate, FALSE);
362         if(!Adapter->bCfgDownloaded &&
363                 psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR)
364         {
365                 /*Can't Download Firmware.*/
366                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Download the config File first\n");
367                 return -EINVAL;
368         }
369
370         /* If Config File, Finish the DDR Settings and then Download CFG File */
371     if(psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
372     {
373                 retval = bcm_download_config_file (Adapter, psFwInfo);
374         }
375         else
376         {
377
378                 buff = (PUCHAR)kzalloc(psFwInfo->u32FirmwareLength,GFP_KERNEL);
379                 if(buff==NULL)
380                 {
381                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Failed in allocation memory");
382                         return -ENOMEM;
383                 }
384                 retval = copy_from_user(buff,psFwInfo->pvMappedFirmwareAddress, psFwInfo->u32FirmwareLength);
385                 if(retval != STATUS_SUCCESS)
386                 {
387                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "copying buffer from user space failed");
388                         retval = -EFAULT;
389                         goto error ;
390                 }
391
392                 #if 0
393                 retval = bcm_download_buffer(Adapter,
394                                 (unsigned char *)psFwInfo->pvMappedFirmwareAddress,
395                                 psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
396                 if(retval != STATUS_SUCCESS)
397                 {
398                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "User space buffer download fails....");
399                 }
400                 retval = bcm_buffer_readback (Adapter,
401                                 (unsigned char *)psFwInfo->pvMappedFirmwareAddress,
402                                 psFwInfo->u32FirmwareLength, psFwInfo->u32StartingAddress);
403
404                 if(retval != STATUS_SUCCESS)
405                 {
406                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "read back verifier failed ....");
407                 }
408                 #endif
409                 retval = buffDnldVerify(Adapter,
410                                         buff,
411                                         psFwInfo->u32FirmwareLength,
412                                         psFwInfo->u32StartingAddress);
413                 if(retval != STATUS_SUCCESS)
414                 {
415                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"f/w download failed status :%d", retval);
416                         goto error;
417                 }
418         }
419 error:
420         bcm_kfree(buff);
421         return retval;
422 }
423
424 static INT buffDnld(PMINI_ADAPTER Adapter, PUCHAR mappedbuffer, UINT u32FirmwareLength,
425                 ULONG u32StartingAddress)
426 {
427
428         unsigned int    len = 0;
429         int retval = STATUS_SUCCESS;
430         len = u32FirmwareLength;
431
432         while(u32FirmwareLength)
433         {
434                 len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
435                 retval = wrm (Adapter, u32StartingAddress, mappedbuffer, len);
436                 if(retval)
437                 {
438                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "wrm failed with status :%d", retval);
439                         break;
440                 }
441                 u32StartingAddress      += len;
442                 u32FirmwareLength       -= len;
443                 mappedbuffer            +=len;
444         }
445         return retval;
446
447 }
448
449 static INT buffRdbkVerify(PMINI_ADAPTER Adapter,
450                         PUCHAR mappedbuffer, UINT u32FirmwareLength,
451                         ULONG u32StartingAddress)
452 {
453         PUCHAR readbackbuff = NULL;
454         UINT len = u32FirmwareLength;
455         INT retval = STATUS_SUCCESS;
456
457         readbackbuff = (PUCHAR)kzalloc(MAX_TRANSFER_CTRL_BYTE_USB,GFP_KERNEL);
458         if(NULL == readbackbuff)
459         {
460                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "MEMORY ALLOCATION FAILED");
461                 return -ENOMEM;
462         }
463         while (u32FirmwareLength && !retval)
464         {
465
466                 len = MIN_VAL (u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
467
468                 retval = rdm (Adapter, u32StartingAddress, readbackbuff, len);
469                 if(retval)
470                 {
471                         BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL, "rdm failed with status %d" ,retval);
472                         break;
473                 }
474
475                 if (STATUS_SUCCESS != (retval = bcm_compare_buff_contents (readbackbuff, mappedbuffer, len)))
476                 {
477                         break;
478                 }
479                 u32StartingAddress      += len;
480                 u32FirmwareLength       -= len;
481                 mappedbuffer            +=len;
482         }/* end of while (u32FirmwareLength && !retval) */
483         bcm_kfree(readbackbuff);
484         return retval;
485 }
486
487 INT buffDnldVerify(PMINI_ADAPTER Adapter, unsigned char *mappedbuffer, unsigned int u32FirmwareLength,
488                 unsigned long u32StartingAddress)
489 {
490         INT status = STATUS_SUCCESS;
491
492         status = buffDnld(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress);
493         if(status != STATUS_SUCCESS)
494         {
495                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer download failed");
496                 goto error;
497         }
498
499         status= buffRdbkVerify(Adapter,mappedbuffer,u32FirmwareLength,u32StartingAddress);
500         if(status != STATUS_SUCCESS)
501         {
502                 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_INITEXIT, MP_INIT, DBG_LVL_ALL,"Buffer readback verifier failed");
503                 goto error;
504         }
505 error:
506         return status;
507 }
508
509 #endif
510