#include <linux/fs.h>

#include "headers.h"
/***************************************************************
* Function	  - bcm_char_open()
*
* Description - This is the "open" entry point for the character
*				driver.
*
* Parameters  - inode: Pointer to the Inode structure of char device
*				filp : File pointer of the char device
*
* Returns	  - Zero(Success)
****************************************************************/

static int bcm_char_open(struct inode *inode, struct file *filp)
{
	struct bcm_mini_adapter *Adapter = NULL;
	struct bcm_tarang_data *pTarang = NULL;

	Adapter = GET_BCM_ADAPTER(gblpnetdev);
	pTarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL);
	if (!pTarang)
		return -ENOMEM;

	pTarang->Adapter = Adapter;
	pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);

	down(&Adapter->RxAppControlQueuelock);
	pTarang->next = Adapter->pTarangs;
	Adapter->pTarangs = pTarang;
	up(&Adapter->RxAppControlQueuelock);

	/* Store the Adapter structure */
	filp->private_data = pTarang;

	/* Start Queuing the control response Packets */
	atomic_inc(&Adapter->ApplicationRunning);

	nonseekable_open(inode, filp);
	return 0;
}

static int bcm_char_release(struct inode *inode, struct file *filp)
{
	struct bcm_tarang_data *pTarang, *tmp, *ptmp;
	struct bcm_mini_adapter *Adapter = NULL;
	struct sk_buff *pkt, *npkt;

	pTarang = (struct bcm_tarang_data *)filp->private_data;

	if (pTarang == NULL)
		return 0;

	Adapter = pTarang->Adapter;

	down(&Adapter->RxAppControlQueuelock);

	tmp = Adapter->pTarangs;
	for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) {
		if (tmp == pTarang)
			break;
	}

	if (tmp) {
		if (!ptmp)
			Adapter->pTarangs = tmp->next;
		else
			ptmp->next = tmp->next;
	} else {
		up(&Adapter->RxAppControlQueuelock);
		return 0;
	}

	pkt = pTarang->RxAppControlHead;
	while (pkt) {
		npkt = pkt->next;
		kfree_skb(pkt);
		pkt = npkt;
	}

	up(&Adapter->RxAppControlQueuelock);

	/* Stop Queuing the control response Packets */
	atomic_dec(&Adapter->ApplicationRunning);

	kfree(pTarang);

	/* remove this filp from the asynchronously notified filp's */
	filp->private_data = NULL;
	return 0;
}

static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size,
			     loff_t *f_pos)
{
	struct bcm_tarang_data *pTarang = filp->private_data;
	struct bcm_mini_adapter *Adapter = pTarang->Adapter;
	struct sk_buff *Packet = NULL;
	ssize_t PktLen = 0;
	int wait_ret_val = 0;
	unsigned long ret = 0;

	wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
						(pTarang->RxAppControlHead ||
						 Adapter->device_removed));
	if ((wait_ret_val == -ERESTARTSYS)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Exiting as i've been asked to exit!!!\n");
		return wait_ret_val;
	}

	if (Adapter->device_removed) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Device Removed... Killing the Apps...\n");
		return -ENODEV;
	}

	if (false == Adapter->fw_download_done)
		return -EACCES;

	down(&Adapter->RxAppControlQueuelock);

	if (pTarang->RxAppControlHead) {
		Packet = pTarang->RxAppControlHead;
		DEQUEUEPACKET(pTarang->RxAppControlHead,
			      pTarang->RxAppControlTail);
		pTarang->AppCtrlQueueLen--;
	}

	up(&Adapter->RxAppControlQueuelock);

	if (Packet) {
		PktLen = Packet->len;
		ret = copy_to_user(buf, Packet->data,
				   min_t(size_t, PktLen, size));
		if (ret) {
			dev_kfree_skb(Packet);
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
					"Returning from copy to user failure\n");
			return -EFAULT;
		}
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Read %zd Bytes From Adapter packet = %p by process %d!\n",
				PktLen, Packet, current->pid);
		dev_kfree_skb(Packet);
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n");
	return PktLen;
}

static int bcm_char_ioctl_reg_read_private(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_rdm_buffer sRdmBuffer = {0};
	struct bcm_ioctl_buffer IoBuffer;
	PCHAR temp_buff;
	INT Status = STATUS_FAILURE;
	UINT Bufflen;
	u16 temp_value;
	int bytes;

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(sRdmBuffer))
		return -EINVAL;

	if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	if (IoBuffer.OutputLength > USHRT_MAX ||
		IoBuffer.OutputLength == 0) {
		return -EINVAL;
	}

	Bufflen = IoBuffer.OutputLength;
	temp_value = 4 - (Bufflen % 4);
	Bufflen += temp_value % 4;

	temp_buff = kmalloc(Bufflen, GFP_KERNEL);
	if (!temp_buff)
		return -ENOMEM;

	bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
			(PUINT)temp_buff, Bufflen);
	if (bytes > 0) {
		Status = STATUS_SUCCESS;
		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
			kfree(temp_buff);
			return -EFAULT;
		}
	} else {
		Status = bytes;
	}

	kfree(temp_buff);
	return Status;
}

static int bcm_char_ioctl_reg_write_private(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_wrm_buffer sWrmBuffer = {0};
	struct bcm_ioctl_buffer IoBuffer;
	UINT uiTempVar = 0;
	INT Status;

	/* Copy Ioctl Buffer structure */

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(sWrmBuffer))
		return -EINVAL;

	/* Get WrmBuffer structure */
	if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
	if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
		((uiTempVar == EEPROM_REJECT_REG_1) ||
			(uiTempVar == EEPROM_REJECT_REG_2) ||
			(uiTempVar == EEPROM_REJECT_REG_3) ||
			(uiTempVar == EEPROM_REJECT_REG_4))) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"EEPROM Access Denied, not in VSG Mode\n");
		return -EFAULT;
	}

	Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
			(PUINT)sWrmBuffer.Data, sizeof(ULONG));

	if (Status == STATUS_SUCCESS) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL, "WRM Done\n");
	} else {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL, "WRM Failed\n");
		Status = -EFAULT;
	}
	return Status;
}

static int bcm_char_ioctl_eeprom_reg_read(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_rdm_buffer sRdmBuffer = {0};
	struct bcm_ioctl_buffer IoBuffer;
	PCHAR temp_buff = NULL;
	UINT uiTempVar = 0;
	INT Status;
	int bytes;

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Device in Idle Mode, Blocking Rdms\n");
		return -EACCES;
	}

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(sRdmBuffer))
		return -EINVAL;

	if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	if (IoBuffer.OutputLength > USHRT_MAX ||
		IoBuffer.OutputLength == 0) {
		return -EINVAL;
	}

	temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
	if (!temp_buff)
		return STATUS_FAILURE;

	if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
		((ULONG)sRdmBuffer.Register & 0x3)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"RDM Done On invalid Address : %x Access Denied.\n",
				(int)sRdmBuffer.Register);

		kfree(temp_buff);
		return -EINVAL;
	}

	uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
	bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
			       (PUINT)temp_buff, IoBuffer.OutputLength);

	if (bytes > 0) {
		Status = STATUS_SUCCESS;
		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
			kfree(temp_buff);
			return -EFAULT;
		}
	} else {
		Status = bytes;
	}

	kfree(temp_buff);
	return Status;
}

static int bcm_char_ioctl_eeprom_reg_write(void __user *argp,
	struct bcm_mini_adapter *Adapter, UINT cmd)
{
	struct bcm_wrm_buffer sWrmBuffer = {0};
	struct bcm_ioctl_buffer IoBuffer;
	UINT uiTempVar = 0;
	INT Status;

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Device in Idle Mode, Blocking Wrms\n");
		return -EACCES;
	}

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(sWrmBuffer))
		return -EINVAL;

	/* Get WrmBuffer structure */
	if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
		((ULONG)sWrmBuffer.Register & 0x3)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"WRM Done On invalid Address : %x Access Denied.\n",
				(int)sWrmBuffer.Register);
		return -EINVAL;
	}

	uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
	if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
			((uiTempVar == EEPROM_REJECT_REG_1) ||
			(uiTempVar == EEPROM_REJECT_REG_2) ||
			(uiTempVar == EEPROM_REJECT_REG_3) ||
			(uiTempVar == EEPROM_REJECT_REG_4)) &&
			(cmd == IOCTL_BCM_REGISTER_WRITE)) {

			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
					"EEPROM Access Denied, not in VSG Mode\n");
			return -EFAULT;
	}

	Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
				(PUINT)sWrmBuffer.Data,
				sWrmBuffer.Length);

	if (Status == STATUS_SUCCESS) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG,
				DBG_LVL_ALL, "WRM Done\n");
	} else {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL, "WRM Failed\n");
		Status = -EFAULT;
	}
	return Status;
}

static int bcm_char_ioctl_gpio_set_request(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_gpio_info gpio_info = {0};
	struct bcm_ioctl_buffer IoBuffer;
	UCHAR ucResetValue[4];
	UINT value = 0;
	UINT uiBit = 0;
	UINT uiOperation = 0;
	INT Status;
	int bytes;

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL,
				"GPIO Can't be set/clear in Low power Mode");
		return -EACCES;
	}

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(gpio_info))
		return -EINVAL;

	if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
		return -EFAULT;

	uiBit  = gpio_info.uiGpioNumber;
	uiOperation = gpio_info.uiGpioValue;
	value = (1<<uiBit);

	if (IsReqGpioIsLedInNVM(Adapter, value) == false) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL,
				"Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",
				value);
		return -EINVAL;
	}

	/* Set - setting 1 */
	if (uiOperation) {
		/* Set the gpio output register */
		Status = wrmaltWithLock(Adapter,
					BCM_GPIO_OUTPUT_SET_REG,
					(PUINT)(&value), sizeof(UINT));

		if (Status == STATUS_SUCCESS) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					OSAL_DBG, DBG_LVL_ALL,
					"Set the GPIO bit\n");
		} else {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					OSAL_DBG, DBG_LVL_ALL,
					"Failed to set the %dth GPIO\n",
					uiBit);
			return Status;
		}
	} else {
		/* Set the gpio output register */
		Status = wrmaltWithLock(Adapter,
					BCM_GPIO_OUTPUT_CLR_REG,
					(PUINT)(&value), sizeof(UINT));

		if (Status == STATUS_SUCCESS) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					OSAL_DBG, DBG_LVL_ALL,
					"Set the GPIO bit\n");
		} else {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					OSAL_DBG, DBG_LVL_ALL,
					"Failed to clear the %dth GPIO\n",
					uiBit);
			return Status;
		}
	}

	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
			       (PUINT)ucResetValue, sizeof(UINT));
	if (bytes < 0) {
		Status = bytes;
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"GPIO_MODE_REGISTER read failed");
		return Status;
	} else {
		Status = STATUS_SUCCESS;
	}

	/* Set the gpio mode register to output */
	*(UINT *)ucResetValue |= (1<<uiBit);
	Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
				(PUINT)ucResetValue, sizeof(UINT));

	if (Status == STATUS_SUCCESS) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL,
				"Set the GPIO to output Mode\n");
	} else {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL,
				"Failed to put GPIO in Output Mode\n");
	}

	return Status;
}

static int bcm_char_ioctl_led_thread_state_change_req(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_user_thread_req threadReq = {0};
	struct bcm_ioctl_buffer IoBuffer;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"User made LED thread InActive");

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL,
				"GPIO Can't be set/clear in Low power Mode");
		return -EACCES;
	}

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(threadReq))
		return -EINVAL;

	if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
		return -EFAULT;

	/* if LED thread is running(Actively or Inactively)
	 * set it state to make inactive
	 */
	if (Adapter->LEDInfo.led_thread_running) {
		if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					OSAL_DBG, DBG_LVL_ALL,
					"Activating thread req");
			Adapter->DriverState = LED_THREAD_ACTIVE;
		} else {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
					OSAL_DBG, DBG_LVL_ALL,
					"DeActivating Thread req.....");
			Adapter->DriverState = LED_THREAD_INACTIVE;
		}

		/* signal thread. */
		wake_up(&Adapter->LEDInfo.notify_led_event);
	}
	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_gpio_status_request(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_gpio_info gpio_info = {0};
	struct bcm_ioctl_buffer IoBuffer;
	ULONG uiBit = 0;
	UCHAR ucRead[4];
	INT Status;
	int bytes;

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE))
		return -EACCES;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(gpio_info))
		return -EINVAL;

	if (copy_from_user(&gpio_info, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	uiBit = gpio_info.uiGpioNumber;

	/* Set the gpio output register */
	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
				(PUINT)ucRead, sizeof(UINT));

	if (bytes < 0) {
		Status = bytes;
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"RDM Failed\n");
		return Status;
	} else {
		Status = STATUS_SUCCESS;
	}
	return Status;
}

static int bcm_char_ioctl_gpio_multi_request(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
	struct bcm_gpio_multi_info *pgpio_multi_info =
		(struct bcm_gpio_multi_info *)gpio_multi_info;
	struct bcm_ioctl_buffer IoBuffer;
	UCHAR ucResetValue[4];
	INT Status = STATUS_FAILURE;
	int bytes;

	memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE))
		return -EINVAL;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(gpio_multi_info))
		return -EINVAL;
	if (IoBuffer.OutputLength > sizeof(gpio_multi_info))
		IoBuffer.OutputLength = sizeof(gpio_multi_info);

	if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	if (IsReqGpioIsLedInNVM(Adapter,
		pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL,
				"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
				pgpio_multi_info[WIMAX_IDX].uiGPIOMask,
				Adapter->gpioBitMap);
		return -EINVAL;
	}

	/* Set the gpio output register */
	if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
		(pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) {
		/* Set 1's in GPIO OUTPUT REGISTER */
		*(UINT *)ucResetValue =  pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
			pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
			pgpio_multi_info[WIMAX_IDX].uiGPIOValue;

		if (*(UINT *) ucResetValue)
			Status = wrmaltWithLock(Adapter,
				BCM_GPIO_OUTPUT_SET_REG,
				(PUINT)ucResetValue, sizeof(ULONG));

		if (Status != STATUS_SUCCESS) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
			return Status;
		}

		/* Clear to 0's in GPIO OUTPUT REGISTER */
		*(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
			pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
			(~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));

		if (*(UINT *) ucResetValue)
			Status = wrmaltWithLock(Adapter,
				BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue,
				sizeof(ULONG));

		if (Status != STATUS_SUCCESS) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
					"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
			return Status;
		}
	}

	if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
			(PUINT)ucResetValue, sizeof(UINT));

		if (bytes < 0) {
			Status = bytes;
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
					"RDM to GPIO_PIN_STATE_REGISTER Failed.");
			return Status;
		} else {
			Status = STATUS_SUCCESS;
		}

		pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue &
			pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
	}

	Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info,
		IoBuffer.OutputLength);
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Failed while copying Content to IOBufer for user space err:%d",
			Status);
		return -EFAULT;
	}
	return Status;
}

static int bcm_char_ioctl_gpio_mode_request(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
	struct bcm_gpio_multi_mode *pgpio_multi_mode =
		(struct bcm_gpio_multi_mode *)gpio_multi_mode;
	struct bcm_ioctl_buffer IoBuffer;
	UCHAR ucResetValue[4];
	INT Status;
	int bytes;

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE))
		return -EINVAL;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
		return -EINVAL;
	if (IoBuffer.OutputLength > sizeof(gpio_multi_mode))
		IoBuffer.OutputLength = sizeof(gpio_multi_mode);

	if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer,
		IoBuffer.InputLength))
		return -EFAULT;

	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
		(PUINT)ucResetValue, sizeof(UINT));

	if (bytes < 0) {
		Status = bytes;
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Read of GPIO_MODE_REGISTER failed");
		return Status;
	} else {
		Status = STATUS_SUCCESS;
	}

	/* Validating the request */
	if (IsReqGpioIsLedInNVM(Adapter,
		pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == false) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
				pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,
				Adapter->gpioBitMap);
		return -EINVAL;
	}

	if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) {
		/* write all OUT's (1's) */
		*(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);

		/* write all IN's (0's) */
		*(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);

		/* Currently implemented return the modes of all GPIO's
		 * else needs to bit AND with  mask
		 */
		pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;

		Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
			(PUINT)ucResetValue, sizeof(ULONG));
		if (Status == STATUS_SUCCESS) {
			BCM_DEBUG_PRINT(Adapter,
				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"WRM to GPIO_MODE_REGISTER Done");
		} else {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
					"WRM to GPIO_MODE_REGISTER Failed");
			return -EFAULT;
		}
	} else {
		/* if uiGPIOMask is 0 then return mode register configuration */
		pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
	}

	Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode,
		IoBuffer.OutputLength);
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Failed while copying Content to IOBufer for user space err:%d",
			Status);
		return -EFAULT;
	}
	return Status;
}

static int bcm_char_ioctl_misc_request(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;
	PVOID pvBuffer = NULL;
	INT Status;

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
		return -EINVAL;

	if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
		return -EINVAL;

	pvBuffer = memdup_user(IoBuffer.InputBuffer,
			       IoBuffer.InputLength);
	if (IS_ERR(pvBuffer))
		return PTR_ERR(pvBuffer);

	down(&Adapter->LowPowerModeSync);
	Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
		!Adapter->bPreparingForLowPowerMode,
		(1 * HZ));
	if (Status == -ERESTARTSYS)
		goto cntrlEnd;

	if (Adapter->bPreparingForLowPowerMode) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Preparing Idle Mode is still True - Hence Rejecting control message\n");
		Status = STATUS_FAILURE;
		goto cntrlEnd;
	}
	Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);

cntrlEnd:
	up(&Adapter->LowPowerModeSync);
	kfree(pvBuffer);
	return Status;
}

static int bcm_char_ioctl_buffer_download_start(
	struct bcm_mini_adapter *Adapter)
{
	INT Status;

	if (down_trylock(&Adapter->NVMRdmWrmLock)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
		return -EACCES;
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
		"Starting the firmware download PID =0x%x!!!!\n", current->pid);

	if (down_trylock(&Adapter->fw_download_sema))
		return -EBUSY;

	Adapter->bBinDownloaded = false;
	Adapter->fw_download_process_pid = current->pid;
	Adapter->bCfgDownloaded = false;
	Adapter->fw_download_done = false;
	netif_carrier_off(Adapter->dev);
	netif_stop_queue(Adapter->dev);
	Status = reset_card_proc(Adapter);
	if (Status) {
		pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
		up(&Adapter->fw_download_sema);
		up(&Adapter->NVMRdmWrmLock);
		return Status;
	}
	mdelay(10);

	up(&Adapter->NVMRdmWrmLock);
	return Status;
}

static int bcm_char_ioctl_buffer_download(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_firmware_info *psFwInfo = NULL;
	struct bcm_ioctl_buffer IoBuffer;
	INT Status;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
		"Starting the firmware download PID =0x%x!!!!\n", current->pid);

	if (!down_trylock(&Adapter->fw_download_sema)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Invalid way to download buffer. Use Start and then call this!!!\n");
		up(&Adapter->fw_download_sema);
		return -EINVAL;
	}

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
		up(&Adapter->fw_download_sema);
		return -EFAULT;
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Length for FW DLD is : %lx\n", IoBuffer.InputLength);

	if (IoBuffer.InputLength > sizeof(struct bcm_firmware_info)) {
		up(&Adapter->fw_download_sema);
		return -EINVAL;
	}

	psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
	if (!psFwInfo) {
		up(&Adapter->fw_download_sema);
		return -ENOMEM;
	}

	if (copy_from_user(psFwInfo, IoBuffer.InputBuffer,
		IoBuffer.InputLength)) {
		up(&Adapter->fw_download_sema);
		kfree(psFwInfo);
		return -EFAULT;
	}

	if (!psFwInfo->pvMappedFirmwareAddress ||
		(psFwInfo->u32FirmwareLength == 0)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Something else is wrong %lu\n",
				psFwInfo->u32FirmwareLength);
		up(&Adapter->fw_download_sema);
		kfree(psFwInfo);
		Status = -EINVAL;
		return Status;
	}

	Status = bcm_ioctl_fw_download(Adapter, psFwInfo);

	if (Status != STATUS_SUCCESS) {
		if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"IOCTL: Configuration File Upload Failed\n");
		else
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"IOCTL: Firmware File Upload Failed\n");

		/* up(&Adapter->fw_download_sema); */

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

	if (Status != STATUS_SUCCESS)
		up(&Adapter->fw_download_sema);

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL,
		"IOCTL: Firmware File Uploaded\n");
	kfree(psFwInfo);
	return Status;
}

static int bcm_char_ioctl_buffer_download_stop(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	INT Status;
	int timeout = 0;

	if (!down_trylock(&Adapter->fw_download_sema)) {
		up(&Adapter->fw_download_sema);
		return -EINVAL;
	}

	if (down_trylock(&Adapter->NVMRdmWrmLock)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"FW download blocked as EEPROM Read/Write is in progress\n");
		up(&Adapter->fw_download_sema);
		return -EACCES;
	}

	Adapter->bBinDownloaded = TRUE;
	Adapter->bCfgDownloaded = TRUE;
	atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
	Adapter->CurrNumRecvDescs = 0;
	Adapter->downloadDDR = 0;

	/* setting the Mips to Run */
	Status = run_card_proc(Adapter);

	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Firm Download Failed\n");
		up(&Adapter->fw_download_sema);
		up(&Adapter->NVMRdmWrmLock);
		return Status;
	} else {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
				DBG_LVL_ALL, "Firm Download Over...\n");
	}

	mdelay(10);

	/* Wait for MailBox Interrupt */
	if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter))
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Unable to send interrupt...\n");

	timeout = 5*HZ;
	Adapter->waiting_to_fw_download_done = false;
	wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
			Adapter->waiting_to_fw_download_done, timeout);
	Adapter->fw_download_process_pid = INVALID_PID;
	Adapter->fw_download_done = TRUE;
	atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
	Adapter->CurrNumRecvDescs = 0;
	Adapter->PrevNumRecvDescs = 0;
	atomic_set(&Adapter->cntrlpktCnt, 0);
	Adapter->LinkUpStatus = 0;
	Adapter->LinkStatus = 0;

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

	if (!timeout)
		Status = -ENODEV;

	up(&Adapter->fw_download_sema);
	up(&Adapter->NVMRdmWrmLock);
	return Status;
}

static int bcm_char_ioctl_chip_reset(struct bcm_mini_adapter *Adapter)
{
	INT Status;
	INT NVMAccess;

	NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
	if (NVMAccess) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			" IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
		return -EACCES;
	}

	down(&Adapter->RxAppControlQueuelock);
	Status = reset_card_proc(Adapter);
	flushAllAppQ();
	up(&Adapter->RxAppControlQueuelock);
	up(&Adapter->NVMRdmWrmLock);
	ResetCounters(Adapter);
	return Status;
}

static int bcm_char_ioctl_qos_threshold(ULONG arg,
	struct bcm_mini_adapter *Adapter)
{
	USHORT uiLoopIndex;

	for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
		if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
				(unsigned long __user *)arg)) {
			return -EFAULT;
		}
	}
	return 0;
}

static int bcm_char_ioctl_switch_transfer_mode(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	UINT uiData = 0;

	if (copy_from_user(&uiData, argp, sizeof(UINT)))
		return -EFAULT;

	if (uiData) {
		/* Allow All Packets */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
			Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
	} else {
		/* Allow IP only Packets */
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
		Adapter->TransferMode = IP_PACKET_ONLY_MODE;
	}
	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_get_driver_version(void __user *argp)
{
	struct bcm_ioctl_buffer IoBuffer;
	ulong len;

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	len = min_t(ulong, IoBuffer.OutputLength, strlen(DRV_VERSION) + 1);

	if (copy_to_user(IoBuffer.OutputBuffer, DRV_VERSION, len))
		return -EFAULT;

	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_get_current_status(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_link_state link_state;
	struct bcm_ioctl_buffer IoBuffer;

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"copy_from_user failed..\n");
		return -EFAULT;
	}

	if (IoBuffer.OutputLength != sizeof(link_state))
		return -EINVAL;

	memset(&link_state, 0, sizeof(link_state));
	link_state.bIdleMode = Adapter->IdleMode;
	link_state.bShutdownMode = Adapter->bShutStatus;
	link_state.ucLinkStatus = Adapter->LinkStatus;

	if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t,
		sizeof(link_state), IoBuffer.OutputLength))) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy_to_user Failed..\n");
		return -EFAULT;
	}
	return STATUS_SUCCESS;
}


static int bcm_char_ioctl_set_mac_tracing(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;
	UINT tracing_flag;

	/* copy ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT)))
		return -EFAULT;

	if (tracing_flag)
		Adapter->pTarangs->MacTracingEnabled = TRUE;
	else
		Adapter->pTarangs->MacTracingEnabled = false;

	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_get_dsx_indication(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;
	ULONG ulSFId = 0;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Mismatch req: %lx needed is =0x%zx!!!",
			IoBuffer.OutputLength,
			sizeof(struct bcm_add_indication_alt));
		return -EINVAL;
	}

	if (copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
		return -EFAULT;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"Get DSX Data SF ID is =%lx\n", ulSFId);
	get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_get_host_mibs(void __user *argp,
	struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang)
{
	struct bcm_ioctl_buffer IoBuffer;
	INT Status = STATUS_FAILURE;
	PVOID temp_buff;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Length Check failed %lu %zd\n", IoBuffer.OutputLength,
			sizeof(struct bcm_host_stats_mibs));
		return -EINVAL;
	}

	/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
	temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
	if (!temp_buff)
		return STATUS_FAILURE;

	Status = ProcessGetHostMibs(Adapter, temp_buff);
	GetDroppedAppCntrlPktMibs(temp_buff, pTarang);

	if (Status != STATUS_FAILURE) {
		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff,
			sizeof(struct bcm_host_stats_mibs))) {
			kfree(temp_buff);
			return -EFAULT;
		}
	}

	kfree(temp_buff);
	return Status;
}

static int bcm_char_ioctl_bulk_wrm(void __user *argp,
	struct bcm_mini_adapter *Adapter, UINT cmd)
{
	struct bcm_bulk_wrm_buffer *pBulkBuffer;
	struct bcm_ioctl_buffer IoBuffer;
	UINT uiTempVar = 0;
	INT Status = STATUS_FAILURE;
	PCHAR pvBuffer = NULL;

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Device in Idle/Shutdown Mode, Blocking Wrms\n");
		return -EACCES;
	}

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.InputLength < sizeof(ULONG) * 2)
		return -EINVAL;

	pvBuffer = memdup_user(IoBuffer.InputBuffer,
			       IoBuffer.InputLength);
	if (IS_ERR(pvBuffer))
		return PTR_ERR(pvBuffer);

	pBulkBuffer = (struct bcm_bulk_wrm_buffer *)pvBuffer;

	if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
		((ULONG)pBulkBuffer->Register & 0x3)) {
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
			"WRM Done On invalid Address : %x Access Denied.\n",
			(int)pBulkBuffer->Register);
		kfree(pvBuffer);
		return -EINVAL;
	}

	uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
	if (!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) &&
		((uiTempVar == EEPROM_REJECT_REG_1) ||
			(uiTempVar == EEPROM_REJECT_REG_2) ||
			(uiTempVar == EEPROM_REJECT_REG_3) ||
			(uiTempVar == EEPROM_REJECT_REG_4)) &&
		(cmd == IOCTL_BCM_REGISTER_WRITE)) {

		kfree(pvBuffer);
		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
			"EEPROM Access Denied, not in VSG Mode\n");
		return -EFAULT;
	}

	if (pBulkBuffer->SwapEndian == false)
		Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register,
			(PCHAR)pBulkBuffer->Values,
			IoBuffer.InputLength - 2*sizeof(ULONG));
	else
		Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register,
			(PUINT)pBulkBuffer->Values,
			IoBuffer.InputLength - 2*sizeof(ULONG));

	if (Status != STATUS_SUCCESS)
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");

	kfree(pvBuffer);
	return Status;
}

static int bcm_char_ioctl_get_nvm_size(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) {
		if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize,
			sizeof(UINT)))
			return -EFAULT;
	}

	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_cal_init(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;
	UINT uiSectorSize = 0;
	INT Status = STATUS_FAILURE;

	if (Adapter->eNVMType == NVM_FLASH) {
		if (copy_from_user(&IoBuffer, argp,
			sizeof(struct bcm_ioctl_buffer)))
			return -EFAULT;

		if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer,
			sizeof(UINT)))
			return -EFAULT;

		if ((uiSectorSize < MIN_SECTOR_SIZE) ||
			(uiSectorSize > MAX_SECTOR_SIZE)) {
			if (copy_to_user(IoBuffer.OutputBuffer,
				&Adapter->uiSectorSize, sizeof(UINT)))
				return -EFAULT;
		} else {
			if (IsFlash2x(Adapter)) {
				if (copy_to_user(IoBuffer.OutputBuffer,
					&Adapter->uiSectorSize, sizeof(UINT)))
					return -EFAULT;
			} else {
				if ((TRUE == Adapter->bShutStatus) ||
					(TRUE == Adapter->IdleMode)) {
					BCM_DEBUG_PRINT(Adapter,
						DBG_TYPE_PRINTK, 0, 0,
						"Device is in Idle/Shutdown Mode\n");
					return -EACCES;
				}

				Adapter->uiSectorSize = uiSectorSize;
				BcmUpdateSectorSize(Adapter,
					Adapter->uiSectorSize);
			}
		}
		Status = STATUS_SUCCESS;
	} else {
		Status = STATUS_FAILURE;
	}
	return Status;
}

static int bcm_char_ioctl_set_debug(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
#ifdef DEBUG
	struct bcm_ioctl_buffer IoBuffer;
	struct bcm_user_debug_state sUserDebugState;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"In SET_DEBUG ioctl\n");
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer,
		sizeof(struct bcm_user_debug_state)))
		return -EFAULT;

	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
			"IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
			sUserDebugState.OnOff, sUserDebugState.Type);
	/* sUserDebugState.Subtype <<= 1; */
	sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
		"actual Subtype=0x%x\n", sUserDebugState.Subtype);

	/* Update new 'DebugState' in the Adapter */
	Adapter->stDebugState.type |= sUserDebugState.Type;
	/* Subtype: A bitmap of 32 bits for Subtype per Type.
	 * Valid indexes in 'subtype' array: 1,2,4,8
	 * corresponding to valid Type values. Hence we can use the 'Type' field
	 * as the index value, ignoring the array entries 0,3,5,6,7 !
	 */
	if (sUserDebugState.OnOff)
		Adapter->stDebugState.subtype[sUserDebugState.Type] |=
			sUserDebugState.Subtype;
	else
		Adapter->stDebugState.subtype[sUserDebugState.Type] &=
			~sUserDebugState.Subtype;

	BCM_SHOW_DEBUG_BITMAP(Adapter);
#endif
	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_nvm_rw(void __user *argp,
	struct bcm_mini_adapter *Adapter, UINT cmd)
{
	struct bcm_nvm_readwrite stNVMReadWrite;
	struct timeval tv0, tv1;
	struct bcm_ioctl_buffer IoBuffer;
	PUCHAR pReadData = NULL;
	ULONG ulDSDMagicNumInUsrBuff = 0;
	INT Status = STATUS_FAILURE;

	memset(&tv0, 0, sizeof(struct timeval));
	memset(&tv1, 0, sizeof(struct timeval));
	if ((Adapter->eNVMType == NVM_FLASH) &&
		(Adapter->uiFlashLayoutMajorVersion == 0)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
		return -EFAULT;
	}

	if (IsFlash2x(Adapter)) {
		if ((Adapter->eActiveDSD != DSD0) &&
			(Adapter->eActiveDSD != DSD1) &&
			(Adapter->eActiveDSD != DSD2)) {

			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"No DSD is active..hence NVM Command is blocked");
			return STATUS_FAILURE;
		}
	}

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (copy_from_user(&stNVMReadWrite,
				(IOCTL_BCM_NVM_READ == cmd) ?
				IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
				sizeof(struct bcm_nvm_readwrite)))
		return -EFAULT;

	/*
	 * Deny the access if the offset crosses the cal area limit.
	 */
	if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
		return STATUS_FAILURE;

	if (stNVMReadWrite.uiOffset >
		Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes)
		return STATUS_FAILURE;

	pReadData = memdup_user(stNVMReadWrite.pBuffer,
				stNVMReadWrite.uiNumBytes);
	if (IS_ERR(pReadData))
		return PTR_ERR(pReadData);

	do_gettimeofday(&tv0);
	if (IOCTL_BCM_NVM_READ == cmd) {
		down(&Adapter->NVMRdmWrmLock);

		if ((Adapter->IdleMode == TRUE) ||
			(Adapter->bShutStatus == TRUE) ||
			(Adapter->bPreparingForLowPowerMode == TRUE)) {

			BCM_DEBUG_PRINT(Adapter,
				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Device is in Idle/Shutdown Mode\n");
			up(&Adapter->NVMRdmWrmLock);
			kfree(pReadData);
			return -EACCES;
		}

		Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
			stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
		up(&Adapter->NVMRdmWrmLock);

		if (Status != STATUS_SUCCESS) {
			kfree(pReadData);
			return Status;
		}

		if (copy_to_user(stNVMReadWrite.pBuffer, pReadData,
			stNVMReadWrite.uiNumBytes)) {
			kfree(pReadData);
			return -EFAULT;
		}
	} else {
		down(&Adapter->NVMRdmWrmLock);

		if ((Adapter->IdleMode == TRUE) ||
			(Adapter->bShutStatus == TRUE) ||
			(Adapter->bPreparingForLowPowerMode == TRUE)) {

			BCM_DEBUG_PRINT(Adapter,
				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Device is in Idle/Shutdown Mode\n");
			up(&Adapter->NVMRdmWrmLock);
			kfree(pReadData);
			return -EACCES;
		}

		Adapter->bHeaderChangeAllowed = TRUE;
		if (IsFlash2x(Adapter)) {
			/*
			 * New Requirement:-
			 * DSD section updation will be allowed in two case:-
			 * 1.  if DSD sig is present in DSD header means dongle
			 * is ok and updation is fruitfull
			 * 2.  if point 1 failes then user buff should have
			 * DSD sig. this point ensures that if dongle is
			 * corrupted then user space program first modify
			 * the DSD header with valid DSD sig so that this
			 * as well as further write may be worthwhile.
			 *
			 * This restriction has been put assuming that
			 * if DSD sig is corrupted, DSD data won't be
			 * considered valid.
			 */

			Status = BcmFlash2xCorruptSig(Adapter,
				Adapter->eActiveDSD);
			if (Status != STATUS_SUCCESS) {
				if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) !=
					Adapter->uiNVMDSDSize) ||
					(stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) {

					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
						OSAL_DBG, DBG_LVL_ALL,
						"DSD Sig is present neither in Flash nor User provided Input..");
					up(&Adapter->NVMRdmWrmLock);
					kfree(pReadData);
					return Status;
				}

				ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
				if (ulDSDMagicNumInUsrBuff !=
					DSD_IMAGE_MAGIC_NUMBER) {
					BCM_DEBUG_PRINT(Adapter,
					DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
						"DSD Sig is present neither in Flash nor User provided Input..");
					up(&Adapter->NVMRdmWrmLock);
					kfree(pReadData);
					return Status;
				}
			}
		}

		Status = BeceemNVMWrite(Adapter, (PUINT)pReadData,
			stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes,
			stNVMReadWrite.bVerify);
		if (IsFlash2x(Adapter))
			BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);

		Adapter->bHeaderChangeAllowed = false;

		up(&Adapter->NVMRdmWrmLock);

		if (Status != STATUS_SUCCESS) {
			kfree(pReadData);
			return Status;
		}
	}

	do_gettimeofday(&tv1);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		" timetaken by Write/read :%ld msec\n",
		(tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);

	kfree(pReadData);
	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_flash2x_section_read(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_flash2x_readwrite sFlash2xRead = {0};
	struct bcm_ioctl_buffer IoBuffer;
	PUCHAR pReadBuff = NULL;
	UINT NOB = 0;
	UINT BuffSize = 0;
	UINT ReadBytes = 0;
	UINT ReadOffset = 0;
	INT Status = STATUS_FAILURE;
	void __user *OutPutBuff;

	if (IsFlash2x(Adapter) != TRUE)	{
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Flash Does not have 2.x map");
		return -EINVAL;
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
		DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	/* Reading FLASH 2.x READ structure */
	if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,
		sizeof(struct bcm_flash2x_readwrite)))
		return -EFAULT;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.Section :%x", sFlash2xRead.Section);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.offset :%x", sFlash2xRead.offset);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.numOfBytes :%x", sFlash2xRead.numOfBytes);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify);

	/* This was internal to driver for raw read.
	 * now it has ben exposed to user space app.
	 */
	if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == false)
		return STATUS_FAILURE;

	NOB = sFlash2xRead.numOfBytes;
	if (NOB > Adapter->uiSectorSize)
		BuffSize = Adapter->uiSectorSize;
	else
		BuffSize = NOB;

	ReadOffset = sFlash2xRead.offset;
	OutPutBuff = IoBuffer.OutputBuffer;
	pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);

	if (pReadBuff == NULL) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Memory allocation failed for Flash 2.x Read Structure");
		return -ENOMEM;
	}
	down(&Adapter->NVMRdmWrmLock);

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
			DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
		up(&Adapter->NVMRdmWrmLock);
		kfree(pReadBuff);
		return -EACCES;
	}

	while (NOB) {
		if (NOB > Adapter->uiSectorSize)
			ReadBytes = Adapter->uiSectorSize;
		else
			ReadBytes = NOB;

		/* Reading the data from Flash 2.x */
		Status = BcmFlash2xBulkRead(Adapter, (PUINT)pReadBuff,
			sFlash2xRead.Section, ReadOffset, ReadBytes);
		if (Status) {
			BCM_DEBUG_PRINT(Adapter,
				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Flash 2x read err with Status :%d",
				Status);
			break;
		}

		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
			DBG_LVL_ALL, pReadBuff, ReadBytes);

		Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
		if (Status) {
			BCM_DEBUG_PRINT(Adapter,
				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
				"Copy to use failed with status :%d", Status);
			up(&Adapter->NVMRdmWrmLock);
			kfree(pReadBuff);
			return -EFAULT;
		}
		NOB = NOB - ReadBytes;
		if (NOB) {
			ReadOffset = ReadOffset + ReadBytes;
			OutPutBuff = OutPutBuff + ReadBytes;
		}
	}

	up(&Adapter->NVMRdmWrmLock);
	kfree(pReadBuff);
	return Status;
}

static int bcm_char_ioctl_flash2x_section_write(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_flash2x_readwrite sFlash2xWrite = {0};
	struct bcm_ioctl_buffer IoBuffer;
	PUCHAR pWriteBuff;
	void __user *InputAddr;
	UINT NOB = 0;
	UINT BuffSize = 0;
	UINT WriteOffset = 0;
	UINT WriteBytes = 0;
	INT Status = STATUS_FAILURE;

	if (IsFlash2x(Adapter) != TRUE) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Flash Does not have 2.x map");
		return -EINVAL;
	}

	/* First make this False so that we can enable the Sector
	 * Permission Check in BeceemFlashBulkWrite
	 */
	Adapter->bAllDSDWriteAllow = false;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"IOCTL_BCM_FLASH2X_SECTION_WRITE Called");

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	/* Reading FLASH 2.x READ structure */
	if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer,
		sizeof(struct bcm_flash2x_readwrite)))
		return -EFAULT;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.Section :%x", sFlash2xWrite.Section);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.offset :%d", sFlash2xWrite.offset);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.numOfBytes :%x", sFlash2xWrite.numOfBytes);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\nsFlash2xRead.bVerify :%x\n", sFlash2xWrite.bVerify);

	if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1)
		&& (sFlash2xWrite.Section != VSA2)) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Only VSA write is allowed");
		return -EINVAL;
	}

	if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == false)
		return STATUS_FAILURE;

	InputAddr = sFlash2xWrite.pDataBuff;
	WriteOffset = sFlash2xWrite.offset;
	NOB = sFlash2xWrite.numOfBytes;

	if (NOB > Adapter->uiSectorSize)
		BuffSize = Adapter->uiSectorSize;
	else
		BuffSize = NOB;

	pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);

	if (pWriteBuff == NULL)
		return -ENOMEM;

	/* extracting the remainder of the given offset. */
	WriteBytes = Adapter->uiSectorSize;
	if (WriteOffset % Adapter->uiSectorSize)
		WriteBytes = Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);

	if (NOB < WriteBytes)
		WriteBytes = NOB;

	down(&Adapter->NVMRdmWrmLock);

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Device is in Idle/Shutdown Mode\n");
		up(&Adapter->NVMRdmWrmLock);
		kfree(pWriteBuff);
		return -EACCES;
	}

	BcmFlash2xCorruptSig(Adapter, sFlash2xWrite.Section);
	do {
		Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes);
		if (Status) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Copy to user failed with status :%d", Status);
			up(&Adapter->NVMRdmWrmLock);
			kfree(pWriteBuff);
			return -EFAULT;
		}
		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS,
			OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes);

		/* Writing the data from Flash 2.x */
		Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pWriteBuff,
			sFlash2xWrite.Section, WriteOffset, WriteBytes,
			sFlash2xWrite.bVerify);

		if (Status) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Flash 2x read err with Status :%d", Status);
			break;
		}

		NOB = NOB - WriteBytes;
		if (NOB) {
			WriteOffset = WriteOffset + WriteBytes;
			InputAddr = InputAddr + WriteBytes;
			if (NOB > Adapter->uiSectorSize)
				WriteBytes = Adapter->uiSectorSize;
			else
				WriteBytes = NOB;
		}
	} while (NOB > 0);

	BcmFlash2xWriteSig(Adapter, sFlash2xWrite.Section);
	up(&Adapter->NVMRdmWrmLock);
	kfree(pWriteBuff);
	return Status;
}

static int bcm_char_ioctl_flash2x_section_bitmap(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_flash2x_bitmap *psFlash2xBitMap;
	struct bcm_ioctl_buffer IoBuffer;
	INT Status = STATUS_FAILURE;

BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
	"IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
		return -EINVAL;

	psFlash2xBitMap = kzalloc(sizeof(struct bcm_flash2x_bitmap), GFP_KERNEL);
	if (psFlash2xBitMap == NULL) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Memory is not available");
		return -ENOMEM;
	}

	/* Reading the Flash Sectio Bit map */
	down(&Adapter->NVMRdmWrmLock);

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Device is in Idle/Shutdown Mode\n");
		up(&Adapter->NVMRdmWrmLock);
		kfree(psFlash2xBitMap);
		return -EACCES;
	}

	BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
	up(&Adapter->NVMRdmWrmLock);
	if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap,
		sizeof(struct bcm_flash2x_bitmap))) {
		kfree(psFlash2xBitMap);
		return -EFAULT;
	}

	kfree(psFlash2xBitMap);
	return Status;
}

static int bcm_char_ioctl_set_active_section(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	enum bcm_flash2x_section_val eFlash2xSectionVal = 0;
	INT Status = STATUS_FAILURE;
	struct bcm_ioctl_buffer IoBuffer;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"IOCTL_BCM_SET_ACTIVE_SECTION Called");

	if (IsFlash2x(Adapter) != TRUE) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Flash Does not have 2.x map");
		return -EINVAL;
	}

	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of IOCTL BUFFER failed");
		return -EFAULT;
	}

	Status = copy_from_user(&eFlash2xSectionVal,
		IoBuffer.InputBuffer, sizeof(INT));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of flash section val failed");
		return -EFAULT;
	}

	down(&Adapter->NVMRdmWrmLock);

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Device is in Idle/Shutdown Mode\n");
		up(&Adapter->NVMRdmWrmLock);
		return -EACCES;
	}

	Status = BcmSetActiveSection(Adapter, eFlash2xSectionVal);
	if (Status)
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Failed to make it's priority Highest. Status %d",
			Status);

	up(&Adapter->NVMRdmWrmLock);

	return Status;
}

static int bcm_char_ioctl_copy_section(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_flash2x_copy_section sCopySectStrut = {0};
	struct bcm_ioctl_buffer IoBuffer;
	INT Status = STATUS_SUCCESS;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"IOCTL_BCM_COPY_SECTION  Called");

	Adapter->bAllDSDWriteAllow = false;
	if (IsFlash2x(Adapter) != TRUE) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Flash Does not have 2.x map");
		return -EINVAL;
	}

	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of IOCTL BUFFER failed Status :%d", Status);
		return -EFAULT;
	}

	Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer,
			sizeof(struct bcm_flash2x_copy_section));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of Copy_Section_Struct failed with Status :%d",
			Status);
		return -EFAULT;
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"Source SEction :%x", sCopySectStrut.SrcSection);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"Destination SEction :%x", sCopySectStrut.DstSection);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"offset :%x", sCopySectStrut.offset);
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"NOB :%x", sCopySectStrut.numOfBytes);

	if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == false) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Source Section<%x> does not exist in Flash ",
			sCopySectStrut.SrcSection);
		return -EINVAL;
	}

	if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == false) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Destinatio Section<%x> does not exist in Flash ",
			sCopySectStrut.DstSection);
		return -EINVAL;
	}

	if (sCopySectStrut.SrcSection == sCopySectStrut.DstSection) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Source and Destination section should be different");
		return -EINVAL;
	}

	down(&Adapter->NVMRdmWrmLock);

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Device is in Idle/Shutdown Mode\n");
		up(&Adapter->NVMRdmWrmLock);
		return -EACCES;
	}

	if (sCopySectStrut.SrcSection == ISO_IMAGE1 ||
		sCopySectStrut.SrcSection == ISO_IMAGE2) {
		if (IsNonCDLessDevice(Adapter)) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Device is Non-CDLess hence won't have ISO !!");
			Status = -EINVAL;
		} else if (sCopySectStrut.numOfBytes == 0) {
			Status = BcmCopyISO(Adapter, sCopySectStrut);
		} else {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Partial Copy of ISO section is not Allowed..");
			Status = STATUS_FAILURE;
		}
		up(&Adapter->NVMRdmWrmLock);
		return Status;
	}

	Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
				sCopySectStrut.DstSection,
				sCopySectStrut.offset,
				sCopySectStrut.numOfBytes);
	up(&Adapter->NVMRdmWrmLock);
	return Status;
}

static int bcm_char_ioctl_get_flash_cs_info(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;
	INT Status = STATUS_SUCCESS;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		" IOCTL_BCM_GET_FLASH_CS_INFO Called");

	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of IOCTL BUFFER failed");
		return -EFAULT;
	}

	if (Adapter->eNVMType != NVM_FLASH) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Connected device does not have flash");
		return -EINVAL;
	}

	if (IsFlash2x(Adapter) == TRUE) {
		if (IoBuffer.OutputLength < sizeof(struct bcm_flash2x_cs_info))
			return -EINVAL;

		if (copy_to_user(IoBuffer.OutputBuffer,
			Adapter->psFlash2xCSInfo,
			sizeof(struct bcm_flash2x_cs_info)))
			return -EFAULT;
	} else {
		if (IoBuffer.OutputLength < sizeof(struct bcm_flash_cs_info))
			return -EINVAL;

		if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo,
			sizeof(struct bcm_flash_cs_info)))
			return -EFAULT;
	}
	return Status;
}

static int bcm_char_ioctl_select_dsd(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_ioctl_buffer IoBuffer;
	INT Status = STATUS_FAILURE;
	UINT SectOfset = 0;
	enum bcm_flash2x_section_val eFlash2xSectionVal;

	eFlash2xSectionVal = NO_SECTION_VAL;
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"IOCTL_BCM_SELECT_DSD Called");

	if (IsFlash2x(Adapter) != TRUE) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Flash Does not have 2.x map");
		return -EINVAL;
	}

	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of IOCTL BUFFER failed");
		return -EFAULT;
	}
	Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer,
		sizeof(INT));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Copy of flash section val failed");
		return -EFAULT;
	}

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"Read Section :%d", eFlash2xSectionVal);
	if ((eFlash2xSectionVal != DSD0) &&
		(eFlash2xSectionVal != DSD1) &&
		(eFlash2xSectionVal != DSD2)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Passed section<%x> is not DSD section",
			eFlash2xSectionVal);
		return STATUS_FAILURE;
	}

	SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
	if (SectOfset == INVALID_OFFSET) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Provided Section val <%d> does not exist in Flash 2.x",
			eFlash2xSectionVal);
		return -EINVAL;
	}

	Adapter->bAllDSDWriteAllow = TRUE;
	Adapter->ulFlashCalStart = SectOfset;
	Adapter->eActiveDSD = eFlash2xSectionVal;

	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_nvm_raw_read(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_nvm_readwrite stNVMRead;
	struct bcm_ioctl_buffer IoBuffer;
	unsigned int NOB;
	INT BuffSize;
	INT ReadOffset = 0;
	UINT ReadBytes = 0;
	PUCHAR pReadBuff;
	void __user *OutPutBuff;
	INT Status = STATUS_FAILURE;

	if (Adapter->eNVMType != NVM_FLASH) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"NVM TYPE is not Flash");
		return -EINVAL;
	}

	/* Copy Ioctl Buffer structure */
	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"copy_from_user 1 failed\n");
		return -EFAULT;
	}

	if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,
		sizeof(struct bcm_nvm_readwrite)))
		return -EFAULT;

	NOB = stNVMRead.uiNumBytes;
	/* In Raw-Read max Buff size : 64MB */

	if (NOB > DEFAULT_BUFF_SIZE)
		BuffSize = DEFAULT_BUFF_SIZE;
	else
		BuffSize = NOB;

	ReadOffset = stNVMRead.uiOffset;
	OutPutBuff = stNVMRead.pBuffer;

	pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
	if (pReadBuff == NULL) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
			"Memory allocation failed for Flash 2.x Read Structure");
		return -ENOMEM;
	}
	down(&Adapter->NVMRdmWrmLock);

	if ((Adapter->IdleMode == TRUE) ||
		(Adapter->bShutStatus == TRUE) ||
		(Adapter->bPreparingForLowPowerMode == TRUE)) {

		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
			DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
		kfree(pReadBuff);
		up(&Adapter->NVMRdmWrmLock);
		return -EACCES;
	}

	Adapter->bFlashRawRead = TRUE;

	while (NOB) {
		if (NOB > DEFAULT_BUFF_SIZE)
			ReadBytes = DEFAULT_BUFF_SIZE;
		else
			ReadBytes = NOB;

		/* Reading the data from Flash 2.x */
		Status = BeceemNVMRead(Adapter, (PUINT)pReadBuff,
			ReadOffset, ReadBytes);
		if (Status) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Flash 2x read err with Status :%d", Status);
			break;
		}

		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
			DBG_LVL_ALL, pReadBuff, ReadBytes);

		Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
		if (Status) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"Copy to use failed with status :%d", Status);
			up(&Adapter->NVMRdmWrmLock);
			kfree(pReadBuff);
			return -EFAULT;
		}
		NOB = NOB - ReadBytes;
		if (NOB) {
			ReadOffset = ReadOffset + ReadBytes;
			OutPutBuff = OutPutBuff + ReadBytes;
		}
	}
	Adapter->bFlashRawRead = false;
	up(&Adapter->NVMRdmWrmLock);
	kfree(pReadBuff);
	return Status;
}

static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp,
	struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang)
{
	struct bcm_ioctl_buffer IoBuffer;
	INT Status = STATUS_FAILURE;
	ULONG RxCntrlMsgBitMask = 0;

	/* Copy Ioctl Buffer structure */
	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"copy of Ioctl buffer is failed from user space");
		return -EFAULT;
	}

	if (IoBuffer.InputLength != sizeof(unsigned long))
		return -EINVAL;

	Status = copy_from_user(&RxCntrlMsgBitMask,
		IoBuffer.InputBuffer, IoBuffer.InputLength);
	if (Status) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"copy of control bit mask failed from user space");
		return -EFAULT;
	}
	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"\n Got user defined cntrl msg bit mask :%lx",
		RxCntrlMsgBitMask);
	pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask;

	return Status;
}

static int bcm_char_ioctl_get_device_driver_info(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_driver_info DevInfo;
	struct bcm_ioctl_buffer IoBuffer;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
		DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");

	memset(&DevInfo, 0, sizeof(DevInfo));
	DevInfo.MaxRDMBufferSize = BUFFER_4K;
	DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
	DevInfo.u32RxAlignmentCorrection = 0;
	DevInfo.u32NVMType = Adapter->eNVMType;
	DevInfo.u32InterfaceType = BCM_USB;

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.OutputLength < sizeof(DevInfo))
		return -EINVAL;

	if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
		return -EFAULT;

	return STATUS_SUCCESS;
}

static int bcm_char_ioctl_time_since_net_entry(void __user *argp,
	struct bcm_mini_adapter *Adapter)
{
	struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
	struct bcm_ioctl_buffer IoBuffer;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
		"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");

	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
		return -EFAULT;

	if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
		return -EINVAL;

	stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry =
		get_seconds() - Adapter->liTimeSinceLastNetEntry;

	if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry,
		sizeof(struct bcm_time_elapsed)))
		return -EFAULT;

	return STATUS_SUCCESS;
}


static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
{
	struct bcm_tarang_data *pTarang = filp->private_data;
	void __user *argp = (void __user *)arg;
	struct bcm_mini_adapter *Adapter = pTarang->Adapter;
	INT Status = STATUS_FAILURE;

	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX",
			cmd, arg);

	if (_IOC_TYPE(cmd) != BCM_IOCTL)
		return -EFAULT;
	if (_IOC_DIR(cmd) & _IOC_READ)
		Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
		Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
	else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
		Status = STATUS_SUCCESS;

	if (Status)
		return -EFAULT;

	if (Adapter->device_removed)
		return -EFAULT;

	if (false == Adapter->fw_download_done) {
		switch (cmd) {
		case IOCTL_MAC_ADDR_REQ:
		case IOCTL_LINK_REQ:
		case IOCTL_CM_REQUEST:
		case IOCTL_SS_INFO_REQ:
		case IOCTL_SEND_CONTROL_MESSAGE:
		case IOCTL_IDLE_REQ:
		case IOCTL_BCM_GPIO_SET_REQUEST:
		case IOCTL_BCM_GPIO_STATUS_REQUEST:
			return -EACCES;
		default:
			break;
		}
	}

	Status = vendorextnIoctl(Adapter, cmd, arg);
	if (Status != CONTINUE_COMMON_PATH)
		return Status;

	switch (cmd) {
	/* Rdms for Swin Idle... */
	case IOCTL_BCM_REGISTER_READ_PRIVATE:
		Status = bcm_char_ioctl_reg_read_private(argp, Adapter);
		return Status;

	case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
		Status = bcm_char_ioctl_reg_write_private(argp, Adapter);
		return Status;

	case IOCTL_BCM_REGISTER_READ:
	case IOCTL_BCM_EEPROM_REGISTER_READ:
		Status = bcm_char_ioctl_eeprom_reg_read(argp, Adapter);
		return Status;

	case IOCTL_BCM_REGISTER_WRITE:
	case IOCTL_BCM_EEPROM_REGISTER_WRITE:
		Status = bcm_char_ioctl_eeprom_reg_write(argp, Adapter, cmd);
		return Status;

	case IOCTL_BCM_GPIO_SET_REQUEST:
		Status = bcm_char_ioctl_gpio_set_request(argp, Adapter);
		return Status;

	case BCM_LED_THREAD_STATE_CHANGE_REQ:
		Status = bcm_char_ioctl_led_thread_state_change_req(argp, Adapter);
		return Status;

	case IOCTL_BCM_GPIO_STATUS_REQUEST:
		Status = bcm_char_ioctl_gpio_status_request(argp, Adapter);
		return Status;

	case IOCTL_BCM_GPIO_MULTI_REQUEST:
		Status = bcm_char_ioctl_gpio_multi_request(argp, Adapter);
		return Status;

	case IOCTL_BCM_GPIO_MODE_REQUEST:
		Status = bcm_char_ioctl_gpio_mode_request(argp, Adapter);
		return Status;

	case IOCTL_MAC_ADDR_REQ:
	case IOCTL_LINK_REQ:
	case IOCTL_CM_REQUEST:
	case IOCTL_SS_INFO_REQ:
	case IOCTL_SEND_CONTROL_MESSAGE:
	case IOCTL_IDLE_REQ:
		Status = bcm_char_ioctl_misc_request(argp, Adapter);
		return Status;

	case IOCTL_BCM_BUFFER_DOWNLOAD_START:
		Status = bcm_char_ioctl_buffer_download_start(Adapter);
		return Status;

	case IOCTL_BCM_BUFFER_DOWNLOAD:
		Status = bcm_char_ioctl_buffer_download(argp, Adapter);
		return Status;

	case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
		Status = bcm_char_ioctl_buffer_download_stop(argp, Adapter);
		return Status;


	case IOCTL_BE_BUCKET_SIZE:
		Status = 0;
		if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
			Status = -EFAULT;
		break;

	case IOCTL_RTPS_BUCKET_SIZE:
		Status = 0;
		if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg))
			Status = -EFAULT;
		break;

	case IOCTL_CHIP_RESET:
		Status = bcm_char_ioctl_chip_reset(Adapter);
		return Status;

	case IOCTL_QOS_THRESHOLD:
		Status = bcm_char_ioctl_qos_threshold(arg, Adapter);
		return Status;

	case IOCTL_DUMP_PACKET_INFO:
		DumpPackInfo(Adapter);
		DumpPhsRules(&Adapter->stBCMPhsContext);
		Status = STATUS_SUCCESS;
		break;

	case IOCTL_GET_PACK_INFO:
		if (copy_to_user(argp, &Adapter->PackInfo,
			sizeof(struct bcm_packet_info)*NO_OF_QUEUES))
			return -EFAULT;
		Status = STATUS_SUCCESS;
		break;

	case IOCTL_BCM_SWITCH_TRANSFER_MODE:
		Status = bcm_char_ioctl_switch_transfer_mode(argp, Adapter);
		return Status;

	case IOCTL_BCM_GET_DRIVER_VERSION:
		Status = bcm_char_ioctl_get_driver_version(argp);
		return Status;

	case IOCTL_BCM_GET_CURRENT_STATUS:
		Status = bcm_char_ioctl_get_current_status(argp, Adapter);
		return Status;

	case IOCTL_BCM_SET_MAC_TRACING:
		Status = bcm_char_ioctl_set_mac_tracing(argp, Adapter);
		return Status;

	case IOCTL_BCM_GET_DSX_INDICATION:
		Status = bcm_char_ioctl_get_dsx_indication(argp, Adapter);
		return Status;

	case IOCTL_BCM_GET_HOST_MIBS:
		Status = bcm_char_ioctl_get_host_mibs(argp, Adapter, pTarang);
		return Status;

	case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
		if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) &&
			(TRUE == Adapter->IdleMode)) {
			Adapter->usIdleModePattern = ABORT_IDLE_MODE;
			Adapter->bWakeUpDevice = TRUE;
			wake_up(&Adapter->process_rx_cntrlpkt);
		}

		Status = STATUS_SUCCESS;
		break;

	case IOCTL_BCM_BULK_WRM:
		Status = bcm_char_ioctl_bulk_wrm(argp, Adapter, cmd);
		return Status;

	case IOCTL_BCM_GET_NVM_SIZE:
		Status = bcm_char_ioctl_get_nvm_size(argp, Adapter);
		return Status;

	case IOCTL_BCM_CAL_INIT:
		Status = bcm_char_ioctl_cal_init(argp, Adapter);
		return Status;

	case IOCTL_BCM_SET_DEBUG:
		Status = bcm_char_ioctl_set_debug(argp, Adapter);
		return Status;

	case IOCTL_BCM_NVM_READ:
	case IOCTL_BCM_NVM_WRITE:
		Status = bcm_char_ioctl_nvm_rw(argp, Adapter, cmd);
		return Status;

	case IOCTL_BCM_FLASH2X_SECTION_READ:
		Status = bcm_char_ioctl_flash2x_section_read(argp, Adapter);
		return Status;

	case IOCTL_BCM_FLASH2X_SECTION_WRITE:
		Status = bcm_char_ioctl_flash2x_section_write(argp, Adapter);
		return Status;

	case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP:
		Status = bcm_char_ioctl_flash2x_section_bitmap(argp, Adapter);
		return Status;

	case IOCTL_BCM_SET_ACTIVE_SECTION:
		Status = bcm_char_ioctl_set_active_section(argp, Adapter);
		return Status;

	case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION:
		/* Right Now we are taking care of only DSD */
		Adapter->bAllDSDWriteAllow = false;
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
			"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
		Status = STATUS_SUCCESS;
		break;

	case IOCTL_BCM_COPY_SECTION:
		Status = bcm_char_ioctl_copy_section(argp, Adapter);
		return Status;

	case IOCTL_BCM_GET_FLASH_CS_INFO:
		Status = bcm_char_ioctl_get_flash_cs_info(argp, Adapter);
		return Status;

	case IOCTL_BCM_SELECT_DSD:
		Status = bcm_char_ioctl_select_dsd(argp, Adapter);
		return Status;

	case IOCTL_BCM_NVM_RAW_READ:
		Status = bcm_char_ioctl_nvm_raw_read(argp, Adapter);
		return Status;

	case IOCTL_BCM_CNTRLMSG_MASK:
		Status = bcm_char_ioctl_cntrlmsg_mask(argp, Adapter, pTarang);
		return Status;

	case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
		Status = bcm_char_ioctl_get_device_driver_info(argp, Adapter);
		return Status;

	case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
		Status = bcm_char_ioctl_time_since_net_entry(argp, Adapter);
		return Status;

	case IOCTL_CLOSE_NOTIFICATION:
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
			DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION");
		break;

	default:
		pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
		Status = STATUS_FAILURE;
		break;
	}
	return Status;
}


static const struct file_operations bcm_fops = {
	.owner    = THIS_MODULE,
	.open     = bcm_char_open,
	.release  = bcm_char_release,
	.read     = bcm_char_read,
	.unlocked_ioctl    = bcm_char_ioctl,
	.llseek = no_llseek,
};

int register_control_device_interface(struct bcm_mini_adapter *Adapter)
{

	if (Adapter->major > 0)
		return Adapter->major;

	Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops);
	if (Adapter->major < 0) {
		pr_err(DRV_NAME ": could not created character device\n");
		return Adapter->major;
	}

	Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL,
						MKDEV(Adapter->major, 0),
						Adapter, DEV_NAME);

	if (IS_ERR(Adapter->pstCreatedClassDevice)) {
		pr_err(DRV_NAME ": class device create failed\n");
		unregister_chrdev(Adapter->major, DEV_NAME);
		return PTR_ERR(Adapter->pstCreatedClassDevice);
	}

	return 0;
}

void unregister_control_device_interface(struct bcm_mini_adapter *Adapter)
{
	if (Adapter->major > 0) {
		device_destroy(bcm_class, MKDEV(Adapter->major, 0));
		unregister_chrdev(Adapter->major, DEV_NAME);
	}
}

