#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)
{
	PMINI_ADAPTER       Adapter = NULL;
	PPER_TARANG_DATA    pTarang = NULL;

	Adapter = GET_BCM_ADAPTER(gblpnetdev);
	pTarang = kzalloc(sizeof(PER_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)
{
	PPER_TARANG_DATA pTarang, tmp, ptmp;
	PMINI_ADAPTER Adapter = NULL;
	struct sk_buff *pkt, *npkt;

	pTarang = (PPER_TARANG_DATA)filp->private_data;

	if (pTarang == NULL) {
		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
				"ptarang is null\n");
		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)
{
	PPER_TARANG_DATA pTarang = filp->private_data;
	PMINI_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 long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
{
	PPER_TARANG_DATA  pTarang = filp->private_data;
	void __user *argp = (void __user *)arg;
	PMINI_ADAPTER Adapter = pTarang->Adapter;
	INT Status = STATUS_FAILURE;
	int timeout = 0;
	IOCTL_BUFFER IoBuffer;
	int bytes;

	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: {
		RDM_BUFFER  sRdmBuffer = {0};
		PCHAR temp_buff;
		UINT Bufflen;
		u16 temp_value;

		/* Copy Ioctl Buffer structure */
		if (copy_from_user(&IoBuffer, argp, sizeof(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);
		break;
	}

	case IOCTL_BCM_REGISTER_WRITE_PRIVATE: {
		WRM_BUFFER  sWrmBuffer = {0};
		UINT uiTempVar = 0;
		/* Copy Ioctl Buffer structure */

		if (copy_from_user(&IoBuffer, argp, sizeof(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;
		}
		break;
	}

	case IOCTL_BCM_REGISTER_READ:
	case IOCTL_BCM_EEPROM_REGISTER_READ: {
		RDM_BUFFER  sRdmBuffer = {0};
		PCHAR temp_buff = NULL;
		UINT uiTempVar = 0;
		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(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);
		break;
	}
	case IOCTL_BCM_REGISTER_WRITE:
	case IOCTL_BCM_EEPROM_REGISTER_WRITE: {
		WRM_BUFFER  sWrmBuffer = {0};
		UINT uiTempVar = 0;
		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(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;
		}
		break;
	}
	case IOCTL_BCM_GPIO_SET_REQUEST: {
		UCHAR ucResetValue[4];
		UINT value = 0;
		UINT uiBit = 0;
		UINT uiOperation = 0;

		GPIO_INFO   gpio_info = {0};
		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(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);
			Status = -EINVAL;
			break;
		}

		/* 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);
				break;
			}
		} 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);
				break;
			}
		}

		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");
			break;
		} 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");
			break;
		}
	}
	break;

	case BCM_LED_THREAD_STATE_CHANGE_REQ: {
		USER_THREAD_REQ threadReq = {0};
		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");
			Status = -EACCES;
			break;
		}

		if (copy_from_user(&IoBuffer, argp, sizeof(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);
		}
	}
	break;

	case IOCTL_BCM_GPIO_STATUS_REQUEST: {
		ULONG uiBit = 0;
		UCHAR ucRead[4];
		GPIO_INFO   gpio_info = {0};

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

		if (copy_from_user(&IoBuffer, argp, sizeof(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;
		}
	}
	break;

	case IOCTL_BCM_GPIO_MULTI_REQUEST: {
		UCHAR ucResetValue[4];
		GPIO_MULTI_INFO gpio_multi_info[MAX_IDX];
		PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info;

		memset(pgpio_multi_info, 0, MAX_IDX * sizeof(GPIO_MULTI_INFO));

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

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

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

		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);
			Status = -EINVAL;
			break;
		}

		/* 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;
		}
	}
	break;

	case IOCTL_BCM_GPIO_MODE_REQUEST: {
		UCHAR ucResetValue[4];
		GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX];
		PGPIO_MULTI_MODE pgpio_multi_mode = (PGPIO_MULTI_MODE)gpio_multi_mode;

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

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

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

		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);
			Status = -EINVAL;
			break;
		}

		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");
				Status = -EFAULT;
				break;
			}
		} 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;
		}
	}
	break;

	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: {
		PVOID pvBuffer = NULL;

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

		if (IoBuffer.InputLength < sizeof(struct 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);
		break;
	}

	case IOCTL_BCM_BUFFER_DOWNLOAD_START: {
		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;
	}

	case IOCTL_BCM_BUFFER_DOWNLOAD: {
		FIRMWARE_INFO *psFwInfo = NULL;
		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);
			Status = -EINVAL;
			return Status;
		}

		/* Copy Ioctl Buffer structure */
		if (copy_from_user(&IoBuffer, argp, sizeof(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(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);
			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);
			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;
	}

	case IOCTL_BCM_BUFFER_DOWNLOAD_STOP: {
		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((PS_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;
	}

	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: {
		INT 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);
		break;
	}

	case IOCTL_QOS_THRESHOLD: {
		USHORT uiLoopIndex;

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

	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(PacketInfo)*NO_OF_QUEUES))
			return -EFAULT;
		Status = STATUS_SUCCESS;
		break;

	case IOCTL_BCM_SWITCH_TRANSFER_MODE: {
		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;
		}
		Status = STATUS_SUCCESS;
		break;
	}

	case IOCTL_BCM_GET_DRIVER_VERSION: {
		ulong len;

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

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

		if (copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, len))
			return -EFAULT;
		Status = STATUS_SUCCESS;
		break;
	}

	case IOCTL_BCM_GET_CURRENT_STATUS: {
		LINK_STATE link_state;

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

		if (IoBuffer.OutputLength != sizeof(link_state)) {
			Status = -EINVAL;
			break;
		}

		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;
		}
		Status = STATUS_SUCCESS;
		break;
	}

	case IOCTL_BCM_SET_MAC_TRACING: {
		UINT  tracing_flag;

		/* copy ioctl Buffer structure */
		if (copy_from_user(&IoBuffer, argp, sizeof(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;
		break;
	}

	case IOCTL_BCM_GET_DSX_INDICATION: {
		ULONG ulSFId = 0;
		if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
			return -EFAULT;

		if (IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt)) {
			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
					"Mismatch req: %lx needed is =0x%zx!!!",
					IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
			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);
		Status = STATUS_SUCCESS;
	}
	break;

	case IOCTL_BCM_GET_HOST_MIBS: {
		PVOID temp_buff;

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

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

		/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
		temp_buff = kzalloc(sizeof(S_MIBS_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(S_MIBS_HOST_STATS_MIBS))) {
				kfree(temp_buff);
				return -EFAULT;
			}

		kfree(temp_buff);
		break;
	}

	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: {
		PBULKWRM_BUFFER pBulkBuffer;
		UINT uiTempVar = 0;
		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");
			Status = -EACCES;
			break;
		}

		/* Copy Ioctl Buffer structure */
		if (copy_from_user(&IoBuffer, argp, sizeof(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 = (PBULKWRM_BUFFER)pvBuffer;

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

		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");
			Status = -EFAULT;
			break;
		}

		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);
		break;
	}

	case IOCTL_BCM_GET_NVM_SIZE:
		if (copy_from_user(&IoBuffer, argp, sizeof(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;
		}

		Status = STATUS_SUCCESS;
		break;

	case IOCTL_BCM_CAL_INIT: {
		UINT uiSectorSize = 0 ;
		if (Adapter->eNVMType == NVM_FLASH) {
			if (copy_from_user(&IoBuffer, argp, sizeof(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;
		}
	}
	break;

	case IOCTL_BCM_SET_DEBUG:
#ifdef DEBUG
	{
		USER_BCM_DBG_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(IOCTL_BUFFER)))
			return -EFAULT;

		if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_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
	break;

	case IOCTL_BCM_NVM_READ:
	case IOCTL_BCM_NVM_WRITE: {
		NVM_READWRITE  stNVMReadWrite;
		PUCHAR pReadData = NULL;
		ULONG ulDSDMagicNumInUsrBuff = 0;
		struct timeval tv0, tv1;
		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(IOCTL_BUFFER)))
			return -EFAULT;

		if (copy_from_user(&stNVMReadWrite,
					(IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
					sizeof(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) {
			/* BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset, 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;
	}

	case IOCTL_BCM_FLASH2X_SECTION_READ: {
		FLASH2X_READWRITE sFlash2xRead = {0};
		PUCHAR pReadBuff = NULL ;
		UINT NOB = 0;
		UINT BuffSize = 0;
		UINT ReadBytes = 0;
		UINT ReadOffset = 0;
		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(IOCTL_BUFFER)))
			return -EFAULT;

		/* Reading FLASH 2.x READ structure */
		if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(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);
	}
	break;

	case IOCTL_BCM_FLASH2X_SECTION_WRITE: {
		FLASH2X_READWRITE sFlash2xWrite = {0};
		PUCHAR pWriteBuff;
		void __user *InputAddr;
		UINT NOB = 0;
		UINT BuffSize = 0;
		UINT WriteOffset = 0;
		UINT WriteBytes = 0;

		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(IOCTL_BUFFER)))
			return -EFAULT;

		/* Reading FLASH 2.x READ structure */
		if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(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);
	}
	break;

	case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP: {
		PFLASH2X_BITMAP psFlash2xBitMap;
		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(IOCTL_BUFFER)))
			return -EFAULT;

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

		psFlash2xBitMap = kzalloc(sizeof(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(FLASH2X_BITMAP))) {
			kfree(psFlash2xBitMap);
			return -EFAULT;
		}

		kfree(psFlash2xBitMap);
	}
	break;

	case IOCTL_BCM_SET_ACTIVE_SECTION: {
		FLASH2X_SECTION_VAL eFlash2xSectionVal = 0;
		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(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);
	}
	break;

	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: {
		FLASH2X_COPY_SECTION sCopySectStrut = {0};
		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(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(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 exixt 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 exixt 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);
	}
	break;

	case IOCTL_BCM_GET_FLASH_CS_INFO: {
		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(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");
			Status = -EINVAL;
			break;
		}

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

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

			if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)))
				return -EFAULT;
		}
	}
	break;

	case IOCTL_BCM_SELECT_DSD: {
		UINT SectOfset = 0;
		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(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 exixt in Flash 2.x", eFlash2xSectionVal);
			return -EINVAL;
		}

		Adapter->bAllDSDWriteAllow = TRUE;
		Adapter->ulFlashCalStart = SectOfset;
		Adapter->eActiveDSD = eFlash2xSectionVal;
	}
	Status = STATUS_SUCCESS;
	break;

	case IOCTL_BCM_NVM_RAW_READ: {
		NVM_READWRITE stNVMRead;
		INT NOB ;
		INT BuffSize ;
		INT ReadOffset = 0;
		UINT ReadBytes = 0 ;
		PUCHAR pReadBuff;
		void __user *OutPutBuff;

		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(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(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");
			Status = -ENOMEM;
			break;
		}
		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);
		break;
	}

	case IOCTL_BCM_CNTRLMSG_MASK: {
		ULONG RxCntrlMsgBitMask = 0;

		/* Copy Ioctl Buffer structure */
		Status = copy_from_user(&IoBuffer, argp, sizeof(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)) {
			Status = -EINVAL;
			break;
		}

		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;
	}
	break;

	case IOCTL_BCM_GET_DEVICE_DRIVER_INFO: {
		DEVICE_DRIVER_INFO DevInfo;

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

		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(IOCTL_BUFFER)))
			return -EFAULT;

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

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

	case IOCTL_BCM_TIME_SINCE_NET_ENTRY: {
		ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};

		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(IOCTL_BUFFER)))
			return -EFAULT;

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

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

		if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
			return -EFAULT;
	}
	break;

	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(PMINI_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(PMINI_ADAPTER Adapter)
{
	if (Adapter->major > 0) {
		device_destroy(bcm_class, MKDEV(Adapter->major, 0));
		unregister_chrdev(Adapter->major, DEV_NAME);
	}
}

