#include "headers.h"

int InterfaceFileDownload(PVOID arg, struct file *flp, unsigned int on_chip_loc)
{
	/* unsigned int reg = 0; */
	mm_segment_t oldfs = {0};
	int errno = 0, len = 0; /* ,is_config_file = 0 */
	loff_t pos = 0;
	struct bcm_interface_adapter *psIntfAdapter = arg;
	/* struct bcm_mini_adapter *Adapter = psIntfAdapter->psAdapter; */
	char *buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);

	if (!buff)
		return -ENOMEM;

	while (1) {
		oldfs = get_fs();
		set_fs(get_ds());
		len = vfs_read(flp, (void __force __user *)buff,
			MAX_TRANSFER_CTRL_BYTE_USB, &pos);
		set_fs(oldfs);
		if (len <= 0) {
			if (len < 0)
				errno = len;
			else
				errno = 0;
			break;
		}
		/* BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_INITEXIT, MP_INIT,
		 *			  DBG_LVL_ALL, buff,
		 *			  MAX_TRANSFER_CTRL_BYTE_USB);
		 */
		errno = InterfaceWRM(psIntfAdapter, on_chip_loc, buff, len);
		if (errno)
			break;
		on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
	}

	kfree(buff);
	return errno;
}

int InterfaceFileReadbackFromChip(PVOID arg, struct file *flp,
				unsigned int on_chip_loc)
{
	char *buff, *buff_readback;
	unsigned int reg = 0;
	mm_segment_t oldfs = {0};
	int errno = 0, len = 0, is_config_file = 0;
	loff_t pos = 0;
	static int fw_down;
	INT Status = STATUS_SUCCESS;
	struct bcm_interface_adapter *psIntfAdapter = arg;
	int bytes;

	buff = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_DMA);
	buff_readback = kmalloc(MAX_TRANSFER_CTRL_BYTE_USB , GFP_DMA);
	if (!buff || !buff_readback) {
		kfree(buff);
		kfree(buff_readback);

		return -ENOMEM;
	}

	is_config_file = (on_chip_loc == CONFIG_BEGIN_ADDR) ? 1 : 0;

	memset(buff_readback, 0, MAX_TRANSFER_CTRL_BYTE_USB);
	memset(buff, 0, MAX_TRANSFER_CTRL_BYTE_USB);
	while (1) {
		oldfs = get_fs();
		set_fs(get_ds());
		len = vfs_read(flp, (void __force __user *)buff,
				MAX_TRANSFER_CTRL_BYTE_USB, &pos);
		set_fs(oldfs);
		fw_down++;

		if (len <= 0) {
			if (len < 0)
				errno = len;
			else
				errno = 0;
			break;
		}

		bytes = InterfaceRDM(psIntfAdapter, on_chip_loc,
					buff_readback, len);
		if (bytes < 0) {
			Status = bytes;
			goto exit;
		}
		reg++;
		if ((len-sizeof(unsigned int)) < 4) {
			if (memcmp(buff_readback, buff, len)) {
				Status = -EIO;
				goto exit;
			}
		} else {
			len -= 4;

			while (len) {
				if (*(unsigned int *)&buff_readback[len] !=
						 *(unsigned int *)&buff[len]) {
					Status = -EIO;
					goto exit;
				}
				len -= 4;
			}
		}
		on_chip_loc += MAX_TRANSFER_CTRL_BYTE_USB;
	} /* End of while(1) */

exit:
	kfree(buff);
	kfree(buff_readback);
	return Status;
}

static int bcm_download_config_file(struct bcm_mini_adapter *Adapter,
				struct bcm_firmware_info *psFwInfo)
{
	int retval = STATUS_SUCCESS;
	B_UINT32 value = 0;

	if (Adapter->pstargetparams == NULL) {
		Adapter->pstargetparams =
			kmalloc(sizeof(struct bcm_target_params), GFP_KERNEL);
		if (Adapter->pstargetparams == NULL)
			return -ENOMEM;
	}

	if (psFwInfo->u32FirmwareLength != sizeof(struct bcm_target_params))
		return -EIO;

	retval = copy_from_user(Adapter->pstargetparams,
			psFwInfo->pvMappedFirmwareAddress,
			psFwInfo->u32FirmwareLength);
	if (retval) {
		kfree(Adapter->pstargetparams);
		Adapter->pstargetparams = NULL;
		return -EFAULT;
	}

	/* Parse the structure and then Download the Firmware */
	beceem_parse_target_struct(Adapter);

	/* Initializing the NVM. */
	BcmInitNVM(Adapter);
	retval = InitLedSettings(Adapter);

	if (retval)
		return retval;

	if (Adapter->LEDInfo.led_thread_running &
			BCM_LED_THREAD_RUNNING_ACTIVELY) {
		Adapter->LEDInfo.bLedInitDone = false;
		Adapter->DriverState = DRIVER_INIT;
		wake_up(&Adapter->LEDInfo.notify_led_event);
	}

	if (Adapter->LEDInfo.led_thread_running &
			BCM_LED_THREAD_RUNNING_ACTIVELY) {
		Adapter->DriverState = FW_DOWNLOAD;
		wake_up(&Adapter->LEDInfo.notify_led_event);
	}

	/* Initialize the DDR Controller */
	retval = ddr_init(Adapter);
	if (retval)
		return retval;

	value = 0;
	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 4,
				&value, sizeof(value));
	wrmalt(Adapter, EEPROM_CAL_DATA_INTERNAL_LOC - 8,
				&value, sizeof(value));

	if (Adapter->eNVMType == NVM_FLASH) {
		retval = PropagateCalParamsFromFlashToMemory(Adapter);
		if (retval)
			return retval;
	}

	retval = buffDnldVerify(Adapter, (PUCHAR)Adapter->pstargetparams,
			sizeof(struct bcm_target_params), CONFIG_BEGIN_ADDR);

	if (retval)
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_INITEXIT,
				MP_INIT, DBG_LVL_ALL,
				"configuration file not downloaded properly");
	else
		Adapter->bCfgDownloaded = TRUE;

	return retval;
}

int bcm_ioctl_fw_download(struct bcm_mini_adapter *Adapter,
			struct bcm_firmware_info *psFwInfo)
{
	int retval = STATUS_SUCCESS;
	PUCHAR buff = NULL;

	/* Config File is needed for the Driver to download the Config file and
	 * Firmware. Check for the Config file to be first to be sent from the
	 * Application
	 */
	atomic_set(&Adapter->uiMBupdate, false);
	if (!Adapter->bCfgDownloaded &&
		psFwInfo->u32StartingAddress != CONFIG_BEGIN_ADDR) {
		/* Can't Download Firmware. */
		return -EINVAL;
	}

	/* If Config File, Finish the DDR Settings and then Download CFG File */
	if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR) {
		retval = bcm_download_config_file(Adapter, psFwInfo);
	} else {
		buff = kzalloc(psFwInfo->u32FirmwareLength, GFP_KERNEL);
		if (buff == NULL)
			return -ENOMEM;

		retval = copy_from_user(buff,
			psFwInfo->pvMappedFirmwareAddress,
			psFwInfo->u32FirmwareLength);
		if (retval != STATUS_SUCCESS) {
			retval = -EFAULT;
			goto error;
		}

		retval = buffDnldVerify(Adapter,
					buff,
					psFwInfo->u32FirmwareLength,
					psFwInfo->u32StartingAddress);

		if (retval != STATUS_SUCCESS)
			goto error;
	}

error:
	kfree(buff);
	return retval;
}

static INT buffDnld(struct bcm_mini_adapter *Adapter,
			PUCHAR mappedbuffer, UINT u32FirmwareLength,
			ULONG u32StartingAddress)
{
	unsigned int len = 0;
	int retval = STATUS_SUCCESS;
	len = u32FirmwareLength;

	while (u32FirmwareLength) {
		len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
		retval = wrm(Adapter, u32StartingAddress, mappedbuffer, len);

		if (retval)
			break;
		u32StartingAddress += len;
		u32FirmwareLength -= len;
		mappedbuffer += len;
	}
	return retval;
}

static INT buffRdbkVerify(struct bcm_mini_adapter *Adapter,
			PUCHAR mappedbuffer, UINT u32FirmwareLength,
			ULONG u32StartingAddress)
{
	UINT len = u32FirmwareLength;
	INT retval = STATUS_SUCCESS;
	PUCHAR readbackbuff = kzalloc(MAX_TRANSFER_CTRL_BYTE_USB, GFP_KERNEL);
	int bytes;

	if (NULL == readbackbuff)
		return -ENOMEM;

	while (u32FirmwareLength && !retval) {
		len = MIN_VAL(u32FirmwareLength, MAX_TRANSFER_CTRL_BYTE_USB);
		bytes = rdm(Adapter, u32StartingAddress, readbackbuff, len);

		if (bytes < 0) {
			retval = bytes;
			break;
		}

		if (memcmp(readbackbuff, mappedbuffer, len) != 0) {
			pr_err("%s() failed.  The firmware doesn't match what was written",
			       __func__);
			retval = -EIO;
		}

		u32StartingAddress += len;
		u32FirmwareLength -= len;
		mappedbuffer += len;

	} /* end of while (u32FirmwareLength && !retval) */
	kfree(readbackbuff);
	return retval;
}

INT buffDnldVerify(struct bcm_mini_adapter *Adapter,
			unsigned char *mappedbuffer,
			unsigned int u32FirmwareLength,
			unsigned long u32StartingAddress)
{
	INT status = STATUS_SUCCESS;

	status = buffDnld(Adapter, mappedbuffer,
			u32FirmwareLength, u32StartingAddress);
	if (status != STATUS_SUCCESS)
		goto error;

	status = buffRdbkVerify(Adapter, mappedbuffer,
			u32FirmwareLength, u32StartingAddress);
	if (status != STATUS_SUCCESS)
		goto error;
error:
	return status;
}
