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