1 #include "headers.h"
2 
3 
InterfaceFileDownload(PVOID arg,struct file * flp,unsigned int on_chip_loc)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 
InterfaceFileReadbackFromChip(PVOID arg,struct file * flp,unsigned int on_chip_loc)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 
bcm_download_config_file(PMINI_ADAPTER Adapter,FIRMWARE_INFO * psFwInfo)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 }
bcm_compare_buff_contents(unsigned char * readbackbuff,unsigned char * buff,unsigned int len)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 }
bcm_ioctl_fw_download(PMINI_ADAPTER Adapter,FIRMWARE_INFO * psFwInfo)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 
buffDnld(PMINI_ADAPTER Adapter,PUCHAR mappedbuffer,UINT u32FirmwareLength,ULONG u32StartingAddress)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 
buffRdbkVerify(PMINI_ADAPTER Adapter,PUCHAR mappedbuffer,UINT u32FirmwareLength,ULONG u32StartingAddress)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 
buffDnldVerify(PMINI_ADAPTER Adapter,unsigned char * mappedbuffer,unsigned int u32FirmwareLength,unsigned long u32StartingAddress)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 
403