Linux Audio

Check our new training course

Yocto / OpenEmbedded training

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