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