[go: nahoru, domu]

1#include "headers.h"
2
3int 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	struct bcm_interface_adapter *psIntfAdapter = arg;
10	/* struct bcm_mini_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				errno = len;
25			else
26				errno = 0;
27			break;
28		}
29		/* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
30		 *			  DBG_LVL_ALL, buff,
31		 *			  MAX_TRANSFER_CTRL_BYTE_USB);
32		 */
33		errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len);
34		if (errno)
35			break;
36		on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
37	}
38
39	kfree(buff);
40	return errno;
41}
42
43int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp,
44				unsigned int on_chip_loc)
45{
46	char *buff, *buff_readback;
47	unsigned int reg = 0;
48	mm_segment_t oldfs = {0};
49	int errno = 0, len = 0, is_config_file = 0;
50	loff_t pos = 0;
51	static int fw_down;
52	INT Status = STATUS_SUCCESS;
53	struct bcm_interface_adapter *psIntfAdapter = arg;
54	int bytes;
55
56	buff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
57	buff_readback = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
58	if (!buff || !buff_readback) {
59		kfree(buff);
60		kfree(buff_readback);
61
62		return -ENOMEM;
63	}
64
65	is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;
66
67	while (1) {
68		oldfs = get_fs();
69		set_fs(get_ds());
70		len = vfs_read(flp, (void __force __user *)buff,
71				MAX_TRANSFER_CTRL_BYTE_USB, &pos);
72		set_fs(oldfs);
73		fw_down++;
74
75		if (len <= 0) {
76			if (len < 0)
77				errno = len;
78			else
79				errno = 0;
80			break;
81		}
82
83		bytes = InterfaceRDM(psIntfAdapter, on_chip_loc,
84					buff_readback, len);
85		if (bytes < 0) {
86			Status = bytes;
87			goto exit;
88		}
89		reg++;
90		if ((len-sizeof(unsigned int)) < 4) {
91			if (memcmp(buff_readback, buff, len)) {
92				Status = -EIO;
93				goto exit;
94			}
95		} else {
96			len -= 4;
97
98			while (len) {
99				if (*(unsigned int *)&buff_readback[len] !=
100						 *(unsigned int *)&buff[len]) {
101					Status = -EIO;
102					goto exit;
103				}
104				len -= 4;
105			}
106		}
107		on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
108	} /* End of while(1) */
109
110exit:
111	kfree(buff);
112	kfree(buff_readback);
113	return Status;
114}
115
116static int bcm_download_config_file(struct bcm_mini_adapter *Adapter,
117				struct bcm_firmware_info *psFwInfo)
118{
119	int retval = STATUS_SUCCESS;
120	B_UINT32 value = 0;
121
122	if (Adapter->pstargetparams == NULL) {
123		Adapter->pstargetparams =
124			kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL);
125		if (Adapter->pstargetparams == NULL)
126			return -ENOMEM;
127	}
128
129	if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params))
130		return -EIO;
131
132	retval = copy_from_user(Adapter->pstargetparams,
133			psFwInfo->pvMappedFirmwareAddress,
134			psFwInfo->u32FirmwareLength);
135	if (retval) {
136		kfree(Adapter->pstargetparams);
137		Adapter->pstargetparams = NULL;
138		return -EFAULT;
139	}
140
141	/* Parse the structure and then Download the Firmware */
142	beceem_parse_target_struct(Adapter);
143
144	/* Initializing the NVM. */
145	BcmInitNVM(Adapter);
146	retval = InitLedSettings(Adapter);
147
148	if (retval)
149		return retval;
150
151	if (Adapter->LEDInfo.led_thread_running &
152			BCM_LED_THREAD_RUNNING_ACTIVELY) {
153		Adapter->LEDInfo.bLedInitDone = false;
154		Adapter->DriverState = DRIVER_INIT;
155		wake_up(&Adapter->LEDInfo.notify_led_event);
156	}
157
158	if (Adapter->LEDInfo.led_thread_running &
159			BCM_LED_THREAD_RUNNING_ACTIVELY) {
160		Adapter->DriverState = FW_DOWNLOAD;
161		wake_up(&Adapter->LEDInfo.notify_led_event);
162	}
163
164	/* Initialize the DDR Controller */
165	retval = ddr_init(Adapter);
166	if (retval)
167		return retval;
168
169	value = 0;
170	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4,
171				&value, sizeof(value));
172	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8,
173				&value, sizeof(value));
174
175	if (Adapter->eNVMType == NVM_FLASH) {
176		retval = PropagateCalParamsFromFlashToMemory(Adapter);
177		if (retval)
178			return retval;
179	}
180
181	retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams,
182			sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR);
183
184	if (retval)
185		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT,
186				MP_INIT, DBG_LVL_ALL,
187				"configuration file not downloaded properly");
188	else
189		Adapter->bCfgDownloaded = TRUE;
190
191	return retval;
192}
193
194int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter,
195			struct bcm_firmware_info *psFwInfo)
196{
197	int retval = STATUS_SUCCESS;
198	PUCHAR buff = NULL;
199
200	/* Config File is needed for the Driver to download the Config file and
201	 * Firmware. Check for the Config file to be first to be sent from the
202	 * Application
203	 */
204	atomic_set(&Adapter->uiMBupdate, false);
205	if (!Adapter->bCfgDownloaded &&
206		psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
207		/* Can't Download Firmware. */
208		return -EINVAL;
209	}
210
211	/* If Config File, Finish the DDR Settings and then Download CFG File */
212	if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
213		retval = bcm_download_config_file(Adapter, psFwInfo);
214	} else {
215		buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
216		if (buff == NULL)
217			return -ENOMEM;
218
219		retval = copy_from_user(buff,
220			psFwInfo->pvMappedFirmwareAddress,
221			psFwInfo->u32FirmwareLength);
222		if (retval != STATUS_SUCCESS) {
223			retval = -EFAULT;
224			goto error;
225		}
226
227		retval = buffDnldVerify(Adapter,
228					buff,
229					psFwInfo->u32FirmwareLength,
230					psFwInfo->u32StartingAddress);
231
232		if (retval != STATUS_SUCCESS)
233			goto error;
234	}
235
236error:
237	kfree(buff);
238	return retval;
239}
240
241static INT buffDnld(struct bcm_mini_adapter *Adapter,
242			PUCHAR mappedbuffer, UINT u32FirmwareLength,
243			ULONG u32StartingAddress)
244{
245	unsigned int len = 0;
246	int retval = STATUS_SUCCESS;
247
248	len = u32FirmwareLength;
249
250	while (u32FirmwareLength) {
251		len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
252		retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);
253
254		if (retval)
255			break;
256		u32StartingAddress += len;
257		u32FirmwareLength -= len;
258		mappedbuffer += len;
259	}
260	return retval;
261}
262
263static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter,
264			PUCHAR mappedbuffer, UINT u32FirmwareLength,
265			ULONG u32StartingAddress)
266{
267	UINT len = u32FirmwareLength;
268	INT retval = STATUS_SUCCESS;
269	PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
270	int bytes;
271
272	if (NULL == readbackbuff)
273		return -ENOMEM;
274
275	while (u32FirmwareLength && !retval) {
276		len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
277		bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len);
278
279		if (bytes < 0) {
280			retval = bytes;
281			break;
282		}
283
284		if (memcmp(readbackbuff, mappedbuffer, len) != 0) {
285			pr_err("%s() failed.  The firmware doesn't match what was written",
286			       __func__);
287			retval = -EIO;
288		}
289
290		u32StartingAddress += len;
291		u32FirmwareLength -= len;
292		mappedbuffer += len;
293
294	} /* end of while (u32FirmwareLength && !retval) */
295	kfree(readbackbuff);
296	return retval;
297}
298
299INT buffDnldVerify(struct bcm_mini_adapter *Adapter,
300			unsigned char *mappedbuffer,
301			unsigned int u32FirmwareLength,
302			unsigned long u32StartingAddress)
303{
304	INT status = STATUS_SUCCESS;
305
306	status = buffDnld(Adapter, mappedbuffer,
307			u32FirmwareLength, u32StartingAddress);
308	if (status != STATUS_SUCCESS)
309		goto error;
310
311	status = buffRdbkVerify(Adapter, mappedbuffer,
312			u32FirmwareLength, u32StartingAddress);
313	if (status != STATUS_SUCCESS)
314		goto error;
315error:
316	return status;
317}
318