Linux Audio

Check our new training course

Loading...
Note: File does not exist in v6.9.4.
   1#include <linux/fs.h>
   2
   3#include "headers.h"
   4/***************************************************************
   5* Function	  - bcm_char_open()
   6*
   7* Description - This is the "open" entry point for the character
   8*				driver.
   9*
  10* Parameters  - inode: Pointer to the Inode structure of char device
  11*				filp : File pointer of the char device
  12*
  13* Returns	  - Zero(Success)
  14****************************************************************/
  15
  16static int bcm_char_open(struct inode *inode, struct file *filp)
  17{
  18	struct bcm_mini_adapter *Adapter = NULL;
  19	struct bcm_tarang_data *pTarang = NULL;
  20
  21	Adapter = GET_BCM_ADAPTER(gblpnetdev);
  22	pTarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL);
  23	if (!pTarang)
  24		return -ENOMEM;
  25
  26	pTarang->Adapter = Adapter;
  27	pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);
  28
  29	down(&Adapter->RxAppControlQueuelock);
  30	pTarang->next = Adapter->pTarangs;
  31	Adapter->pTarangs = pTarang;
  32	up(&Adapter->RxAppControlQueuelock);
  33
  34	/* Store the Adapter structure */
  35	filp->private_data = pTarang;
  36
  37	/* Start Queuing the control response Packets */
  38	atomic_inc(&Adapter->ApplicationRunning);
  39
  40	nonseekable_open(inode, filp);
  41	return 0;
  42}
  43
  44static int bcm_char_release(struct inode *inode, struct file *filp)
  45{
  46	struct bcm_tarang_data *pTarang, *tmp, *ptmp;
  47	struct bcm_mini_adapter *Adapter = NULL;
  48	struct sk_buff *pkt, *npkt;
  49
  50	pTarang = (struct bcm_tarang_data *)filp->private_data;
  51
  52	if (pTarang == NULL)
  53		return 0;
  54
  55	Adapter = pTarang->Adapter;
  56
  57	down(&Adapter->RxAppControlQueuelock);
  58
  59	tmp = Adapter->pTarangs;
  60	for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) {
  61		if (tmp == pTarang)
  62			break;
  63	}
  64
  65	if (tmp) {
  66		if (!ptmp)
  67			Adapter->pTarangs = tmp->next;
  68		else
  69			ptmp->next = tmp->next;
  70	} else {
  71		up(&Adapter->RxAppControlQueuelock);
  72		return 0;
  73	}
  74
  75	pkt = pTarang->RxAppControlHead;
  76	while (pkt) {
  77		npkt = pkt->next;
  78		kfree_skb(pkt);
  79		pkt = npkt;
  80	}
  81
  82	up(&Adapter->RxAppControlQueuelock);
  83
  84	/* Stop Queuing the control response Packets */
  85	atomic_dec(&Adapter->ApplicationRunning);
  86
  87	kfree(pTarang);
  88
  89	/* remove this filp from the asynchronously notified filp's */
  90	filp->private_data = NULL;
  91	return 0;
  92}
  93
  94static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size,
  95			     loff_t *f_pos)
  96{
  97	struct bcm_tarang_data *pTarang = filp->private_data;
  98	struct bcm_mini_adapter *Adapter = pTarang->Adapter;
  99	struct sk_buff *Packet = NULL;
 100	ssize_t PktLen = 0;
 101	int wait_ret_val = 0;
 102	unsigned long ret = 0;
 103
 104	wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
 105						(pTarang->RxAppControlHead ||
 106						 Adapter->device_removed));
 107	if ((wait_ret_val == -ERESTARTSYS)) {
 108		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 109				"Exiting as i've been asked to exit!!!\n");
 110		return wait_ret_val;
 111	}
 112
 113	if (Adapter->device_removed) {
 114		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 115				"Device Removed... Killing the Apps...\n");
 116		return -ENODEV;
 117	}
 118
 119	if (false == Adapter->fw_download_done)
 120		return -EACCES;
 121
 122	down(&Adapter->RxAppControlQueuelock);
 123
 124	if (pTarang->RxAppControlHead) {
 125		Packet = pTarang->RxAppControlHead;
 126		DEQUEUEPACKET(pTarang->RxAppControlHead,
 127			      pTarang->RxAppControlTail);
 128		pTarang->AppCtrlQueueLen--;
 129	}
 130
 131	up(&Adapter->RxAppControlQueuelock);
 132
 133	if (Packet) {
 134		PktLen = Packet->len;
 135		ret = copy_to_user(buf, Packet->data,
 136				   min_t(size_t, PktLen, size));
 137		if (ret) {
 138			dev_kfree_skb(Packet);
 139			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 140					"Returning from copy to user failure\n");
 141			return -EFAULT;
 142		}
 143		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 144				"Read %zd Bytes From Adapter packet = %p by process %d!\n",
 145				PktLen, Packet, current->pid);
 146		dev_kfree_skb(Packet);
 147	}
 148
 149	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n");
 150	return PktLen;
 151}
 152
 153static int bcm_char_ioctl_reg_read_private(void __user *argp,
 154	struct bcm_mini_adapter *Adapter)
 155{
 156	struct bcm_rdm_buffer sRdmBuffer = {0};
 157	struct bcm_ioctl_buffer IoBuffer;
 158	PCHAR temp_buff;
 159	INT Status = STATUS_FAILURE;
 160	UINT Bufflen;
 161	u16 temp_value;
 162	int bytes;
 163
 164	/* Copy Ioctl Buffer structure */
 165	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 166		return -EFAULT;
 167
 168	if (IoBuffer.InputLength > sizeof(sRdmBuffer))
 169		return -EINVAL;
 170
 171	if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
 172		IoBuffer.InputLength))
 173		return -EFAULT;
 174
 175	if (IoBuffer.OutputLength > USHRT_MAX ||
 176		IoBuffer.OutputLength == 0) {
 177		return -EINVAL;
 178	}
 179
 180	Bufflen = IoBuffer.OutputLength;
 181	temp_value = 4 - (Bufflen % 4);
 182	Bufflen += temp_value % 4;
 183
 184	temp_buff = kmalloc(Bufflen, GFP_KERNEL);
 185	if (!temp_buff)
 186		return -ENOMEM;
 187
 188	bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
 189			(PUINT)temp_buff, Bufflen);
 190	if (bytes > 0) {
 191		Status = STATUS_SUCCESS;
 192		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
 193			kfree(temp_buff);
 194			return -EFAULT;
 195		}
 196	} else {
 197		Status = bytes;
 198	}
 199
 200	kfree(temp_buff);
 201	return Status;
 202}
 203
 204static int bcm_char_ioctl_reg_write_private(void __user *argp,
 205	struct bcm_mini_adapter *Adapter)
 206{
 207	struct bcm_wrm_buffer sWrmBuffer = {0};
 208	struct bcm_ioctl_buffer IoBuffer;
 209	UINT uiTempVar = 0;
 210	INT Status;
 211
 212	/* Copy Ioctl Buffer structure */
 213
 214	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 215		return -EFAULT;
 216
 217	if (IoBuffer.InputLength > sizeof(sWrmBuffer))
 218		return -EINVAL;
 219
 220	/* Get WrmBuffer structure */
 221	if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
 222		IoBuffer.InputLength))
 223		return -EFAULT;
 224
 225	uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
 226	if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
 227		((uiTempVar == EEPROM_REJECT_REG_1) ||
 228			(uiTempVar == EEPROM_REJECT_REG_2) ||
 229			(uiTempVar == EEPROM_REJECT_REG_3) ||
 230			(uiTempVar == EEPROM_REJECT_REG_4))) {
 231
 232		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 233				"EEPROM Access Denied, not in VSG Mode\n");
 234		return -EFAULT;
 235	}
 236
 237	Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
 238			(PUINT)sWrmBuffer.Data, sizeof(ULONG));
 239
 240	if (Status == STATUS_SUCCESS) {
 241		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 242				DBG_LVL_ALL, "WRM Done\n");
 243	} else {
 244		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 245				DBG_LVL_ALL, "WRM Failed\n");
 246		Status = -EFAULT;
 247	}
 248	return Status;
 249}
 250
 251static int bcm_char_ioctl_eeprom_reg_read(void __user *argp,
 252	struct bcm_mini_adapter *Adapter)
 253{
 254	struct bcm_rdm_buffer sRdmBuffer = {0};
 255	struct bcm_ioctl_buffer IoBuffer;
 256	PCHAR temp_buff = NULL;
 257	UINT uiTempVar = 0;
 258	INT Status;
 259	int bytes;
 260
 261	if ((Adapter->IdleMode == TRUE) ||
 262		(Adapter->bShutStatus == TRUE) ||
 263		(Adapter->bPreparingForLowPowerMode == TRUE)) {
 264
 265		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 266				"Device in Idle Mode, Blocking Rdms\n");
 267		return -EACCES;
 268	}
 269
 270	/* Copy Ioctl Buffer structure */
 271	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 272		return -EFAULT;
 273
 274	if (IoBuffer.InputLength > sizeof(sRdmBuffer))
 275		return -EINVAL;
 276
 277	if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer,
 278		IoBuffer.InputLength))
 279		return -EFAULT;
 280
 281	if (IoBuffer.OutputLength > USHRT_MAX ||
 282		IoBuffer.OutputLength == 0) {
 283		return -EINVAL;
 284	}
 285
 286	temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
 287	if (!temp_buff)
 288		return STATUS_FAILURE;
 289
 290	if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
 291		((ULONG)sRdmBuffer.Register & 0x3)) {
 292
 293		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 294				"RDM Done On invalid Address : %x Access Denied.\n",
 295				(int)sRdmBuffer.Register);
 296
 297		kfree(temp_buff);
 298		return -EINVAL;
 299	}
 300
 301	uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
 302	bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
 303			       (PUINT)temp_buff, IoBuffer.OutputLength);
 304
 305	if (bytes > 0) {
 306		Status = STATUS_SUCCESS;
 307		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
 308			kfree(temp_buff);
 309			return -EFAULT;
 310		}
 311	} else {
 312		Status = bytes;
 313	}
 314
 315	kfree(temp_buff);
 316	return Status;
 317}
 318
 319static int bcm_char_ioctl_eeprom_reg_write(void __user *argp,
 320	struct bcm_mini_adapter *Adapter, UINT cmd)
 321{
 322	struct bcm_wrm_buffer sWrmBuffer = {0};
 323	struct bcm_ioctl_buffer IoBuffer;
 324	UINT uiTempVar = 0;
 325	INT Status;
 326
 327	if ((Adapter->IdleMode == TRUE) ||
 328		(Adapter->bShutStatus == TRUE) ||
 329		(Adapter->bPreparingForLowPowerMode == TRUE)) {
 330
 331		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 332				"Device in Idle Mode, Blocking Wrms\n");
 333		return -EACCES;
 334	}
 335
 336	/* Copy Ioctl Buffer structure */
 337	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 338		return -EFAULT;
 339
 340	if (IoBuffer.InputLength > sizeof(sWrmBuffer))
 341		return -EINVAL;
 342
 343	/* Get WrmBuffer structure */
 344	if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer,
 345		IoBuffer.InputLength))
 346		return -EFAULT;
 347
 348	if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
 349		((ULONG)sWrmBuffer.Register & 0x3)) {
 350
 351		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 352				"WRM Done On invalid Address : %x Access Denied.\n",
 353				(int)sWrmBuffer.Register);
 354		return -EINVAL;
 355	}
 356
 357	uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
 358	if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
 359			((uiTempVar == EEPROM_REJECT_REG_1) ||
 360			(uiTempVar == EEPROM_REJECT_REG_2) ||
 361			(uiTempVar == EEPROM_REJECT_REG_3) ||
 362			(uiTempVar == EEPROM_REJECT_REG_4)) &&
 363			(cmd == IOCTL_BCM_REGISTER_WRITE)) {
 364
 365			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 366					"EEPROM Access Denied, not in VSG Mode\n");
 367			return -EFAULT;
 368	}
 369
 370	Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
 371				(PUINT)sWrmBuffer.Data,
 372				sWrmBuffer.Length);
 373
 374	if (Status == STATUS_SUCCESS) {
 375		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG,
 376				DBG_LVL_ALL, "WRM Done\n");
 377	} else {
 378		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 379				DBG_LVL_ALL, "WRM Failed\n");
 380		Status = -EFAULT;
 381	}
 382	return Status;
 383}
 384
 385static int bcm_char_ioctl_gpio_set_request(void __user *argp,
 386	struct bcm_mini_adapter *Adapter)
 387{
 388	struct bcm_gpio_info gpio_info = {0};
 389	struct bcm_ioctl_buffer IoBuffer;
 390	UCHAR ucResetValue[4];
 391	UINT value = 0;
 392	UINT uiBit = 0;
 393	UINT uiOperation = 0;
 394	INT Status;
 395	int bytes;
 396
 397	if ((Adapter->IdleMode == TRUE) ||
 398		(Adapter->bShutStatus == TRUE) ||
 399		(Adapter->bPreparingForLowPowerMode == TRUE)) {
 400
 401		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 402				DBG_LVL_ALL,
 403				"GPIO Can't be set/clear in Low power Mode");
 404		return -EACCES;
 405	}
 406
 407	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 408		return -EFAULT;
 409
 410	if (IoBuffer.InputLength > sizeof(gpio_info))
 411		return -EINVAL;
 412
 413	if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
 414		return -EFAULT;
 415
 416	uiBit  = gpio_info.uiGpioNumber;
 417	uiOperation = gpio_info.uiGpioValue;
 418	value = (1<<uiBit);
 419
 420	if (IsReqGpioIsLedInNVM(Adapter, value) == false) {
 421		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 422				DBG_LVL_ALL,
 423				"Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",
 424				value);
 425		return -EINVAL;
 426	}
 427
 428	/* Set - setting 1 */
 429	if (uiOperation) {
 430		/* Set the gpio output register */
 431		Status = wrmaltWithLock(Adapter,
 432					BCM_GPIO_OUTPUT_SET_REG,
 433					(PUINT)(&value), sizeof(UINT));
 434
 435		if (Status == STATUS_SUCCESS) {
 436			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 437					OSAL_DBG, DBG_LVL_ALL,
 438					"Set the GPIO bit\n");
 439		} else {
 440			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 441					OSAL_DBG, DBG_LVL_ALL,
 442					"Failed to set the %dth GPIO\n",
 443					uiBit);
 444			return Status;
 445		}
 446	} else {
 447		/* Set the gpio output register */
 448		Status = wrmaltWithLock(Adapter,
 449					BCM_GPIO_OUTPUT_CLR_REG,
 450					(PUINT)(&value), sizeof(UINT));
 451
 452		if (Status == STATUS_SUCCESS) {
 453			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 454					OSAL_DBG, DBG_LVL_ALL,
 455					"Set the GPIO bit\n");
 456		} else {
 457			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 458					OSAL_DBG, DBG_LVL_ALL,
 459					"Failed to clear the %dth GPIO\n",
 460					uiBit);
 461			return Status;
 462		}
 463	}
 464
 465	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
 466			       (PUINT)ucResetValue, sizeof(UINT));
 467	if (bytes < 0) {
 468		Status = bytes;
 469		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 470				"GPIO_MODE_REGISTER read failed");
 471		return Status;
 472	} else {
 473		Status = STATUS_SUCCESS;
 474	}
 475
 476	/* Set the gpio mode register to output */
 477	*(UINT *)ucResetValue |= (1<<uiBit);
 478	Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
 479				(PUINT)ucResetValue, sizeof(UINT));
 480
 481	if (Status == STATUS_SUCCESS) {
 482		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 483				DBG_LVL_ALL,
 484				"Set the GPIO to output Mode\n");
 485	} else {
 486		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 487				DBG_LVL_ALL,
 488				"Failed to put GPIO in Output Mode\n");
 489	}
 490
 491	return Status;
 492}
 493
 494static int bcm_char_ioctl_led_thread_state_change_req(void __user *argp,
 495	struct bcm_mini_adapter *Adapter)
 496{
 497	struct bcm_user_thread_req threadReq = {0};
 498	struct bcm_ioctl_buffer IoBuffer;
 499
 500	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 501			"User made LED thread InActive");
 502
 503	if ((Adapter->IdleMode == TRUE) ||
 504		(Adapter->bShutStatus == TRUE) ||
 505		(Adapter->bPreparingForLowPowerMode == TRUE)) {
 506
 507		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 508				DBG_LVL_ALL,
 509				"GPIO Can't be set/clear in Low power Mode");
 510		return -EACCES;
 511	}
 512
 513	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 514		return -EFAULT;
 515
 516	if (IoBuffer.InputLength > sizeof(threadReq))
 517		return -EINVAL;
 518
 519	if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
 520		return -EFAULT;
 521
 522	/* if LED thread is running(Actively or Inactively)
 523	 * set it state to make inactive
 524	 */
 525	if (Adapter->LEDInfo.led_thread_running) {
 526		if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) {
 527			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 528					OSAL_DBG, DBG_LVL_ALL,
 529					"Activating thread req");
 530			Adapter->DriverState = LED_THREAD_ACTIVE;
 531		} else {
 532			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
 533					OSAL_DBG, DBG_LVL_ALL,
 534					"DeActivating Thread req.....");
 535			Adapter->DriverState = LED_THREAD_INACTIVE;
 536		}
 537
 538		/* signal thread. */
 539		wake_up(&Adapter->LEDInfo.notify_led_event);
 540	}
 541	return STATUS_SUCCESS;
 542}
 543
 544static int bcm_char_ioctl_gpio_status_request(void __user *argp,
 545	struct bcm_mini_adapter *Adapter)
 546{
 547	struct bcm_gpio_info gpio_info = {0};
 548	struct bcm_ioctl_buffer IoBuffer;
 549	ULONG uiBit = 0;
 550	UCHAR ucRead[4];
 551	INT Status;
 552	int bytes;
 553
 554	if ((Adapter->IdleMode == TRUE) ||
 555		(Adapter->bShutStatus == TRUE) ||
 556		(Adapter->bPreparingForLowPowerMode == TRUE))
 557		return -EACCES;
 558
 559	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 560		return -EFAULT;
 561
 562	if (IoBuffer.InputLength > sizeof(gpio_info))
 563		return -EINVAL;
 564
 565	if (copy_from_user(&gpio_info, IoBuffer.InputBuffer,
 566		IoBuffer.InputLength))
 567		return -EFAULT;
 568
 569	uiBit = gpio_info.uiGpioNumber;
 570
 571	/* Set the gpio output register */
 572	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
 573				(PUINT)ucRead, sizeof(UINT));
 574
 575	if (bytes < 0) {
 576		Status = bytes;
 577		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 578				"RDM Failed\n");
 579		return Status;
 580	} else {
 581		Status = STATUS_SUCCESS;
 582	}
 583	return Status;
 584}
 585
 586static int bcm_char_ioctl_gpio_multi_request(void __user *argp,
 587	struct bcm_mini_adapter *Adapter)
 588{
 589	struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
 590	struct bcm_gpio_multi_info *pgpio_multi_info =
 591		(struct bcm_gpio_multi_info *)gpio_multi_info;
 592	struct bcm_ioctl_buffer IoBuffer;
 593	UCHAR ucResetValue[4];
 594	INT Status = STATUS_FAILURE;
 595	int bytes;
 596
 597	memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));
 598
 599	if ((Adapter->IdleMode == TRUE) ||
 600		(Adapter->bShutStatus == TRUE) ||
 601		(Adapter->bPreparingForLowPowerMode == TRUE))
 602		return -EINVAL;
 603
 604	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 605		return -EFAULT;
 606
 607	if (IoBuffer.InputLength > sizeof(gpio_multi_info))
 608		return -EINVAL;
 609	if (IoBuffer.OutputLength > sizeof(gpio_multi_info))
 610		IoBuffer.OutputLength = sizeof(gpio_multi_info);
 611
 612	if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer,
 613		IoBuffer.InputLength))
 614		return -EFAULT;
 615
 616	if (IsReqGpioIsLedInNVM(Adapter,
 617		pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
 618		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 619				DBG_LVL_ALL,
 620				"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
 621				pgpio_multi_info[WIMAX_IDX].uiGPIOMask,
 622				Adapter->gpioBitMap);
 623		return -EINVAL;
 624	}
 625
 626	/* Set the gpio output register */
 627	if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
 628		(pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) {
 629		/* Set 1's in GPIO OUTPUT REGISTER */
 630		*(UINT *)ucResetValue =  pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
 631			pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
 632			pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
 633
 634		if (*(UINT *) ucResetValue)
 635			Status = wrmaltWithLock(Adapter,
 636				BCM_GPIO_OUTPUT_SET_REG,
 637				(PUINT)ucResetValue, sizeof(ULONG));
 638
 639		if (Status != STATUS_SUCCESS) {
 640			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 641				"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
 642			return Status;
 643		}
 644
 645		/* Clear to 0's in GPIO OUTPUT REGISTER */
 646		*(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
 647			pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
 648			(~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
 649
 650		if (*(UINT *) ucResetValue)
 651			Status = wrmaltWithLock(Adapter,
 652				BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue,
 653				sizeof(ULONG));
 654
 655		if (Status != STATUS_SUCCESS) {
 656			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 657					"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
 658			return Status;
 659		}
 660	}
 661
 662	if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
 663		bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
 664			(PUINT)ucResetValue, sizeof(UINT));
 665
 666		if (bytes < 0) {
 667			Status = bytes;
 668			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 669					"RDM to GPIO_PIN_STATE_REGISTER Failed.");
 670			return Status;
 671		} else {
 672			Status = STATUS_SUCCESS;
 673		}
 674
 675		pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue &
 676			pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
 677	}
 678
 679	Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info,
 680		IoBuffer.OutputLength);
 681	if (Status) {
 682		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 683			"Failed while copying Content to IOBufer for user space err:%d",
 684			Status);
 685		return -EFAULT;
 686	}
 687	return Status;
 688}
 689
 690static int bcm_char_ioctl_gpio_mode_request(void __user *argp,
 691	struct bcm_mini_adapter *Adapter)
 692{
 693	struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
 694	struct bcm_gpio_multi_mode *pgpio_multi_mode =
 695		(struct bcm_gpio_multi_mode *)gpio_multi_mode;
 696	struct bcm_ioctl_buffer IoBuffer;
 697	UCHAR ucResetValue[4];
 698	INT Status;
 699	int bytes;
 700
 701	if ((Adapter->IdleMode == TRUE) ||
 702		(Adapter->bShutStatus == TRUE) ||
 703		(Adapter->bPreparingForLowPowerMode == TRUE))
 704		return -EINVAL;
 705
 706	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 707		return -EFAULT;
 708
 709	if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
 710		return -EINVAL;
 711	if (IoBuffer.OutputLength > sizeof(gpio_multi_mode))
 712		IoBuffer.OutputLength = sizeof(gpio_multi_mode);
 713
 714	if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer,
 715		IoBuffer.InputLength))
 716		return -EFAULT;
 717
 718	bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
 719		(PUINT)ucResetValue, sizeof(UINT));
 720
 721	if (bytes < 0) {
 722		Status = bytes;
 723		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 724			"Read of GPIO_MODE_REGISTER failed");
 725		return Status;
 726	} else {
 727		Status = STATUS_SUCCESS;
 728	}
 729
 730	/* Validating the request */
 731	if (IsReqGpioIsLedInNVM(Adapter,
 732		pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == false) {
 733		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 734				"Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
 735				pgpio_multi_mode[WIMAX_IDX].uiGPIOMask,
 736				Adapter->gpioBitMap);
 737		return -EINVAL;
 738	}
 739
 740	if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) {
 741		/* write all OUT's (1's) */
 742		*(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
 743					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
 744
 745		/* write all IN's (0's) */
 746		*(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
 747					pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
 748
 749		/* Currently implemented return the modes of all GPIO's
 750		 * else needs to bit AND with  mask
 751		 */
 752		pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
 753
 754		Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
 755			(PUINT)ucResetValue, sizeof(ULONG));
 756		if (Status == STATUS_SUCCESS) {
 757			BCM_DEBUG_PRINT(Adapter,
 758				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 759				"WRM to GPIO_MODE_REGISTER Done");
 760		} else {
 761			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 762					"WRM to GPIO_MODE_REGISTER Failed");
 763			return -EFAULT;
 764		}
 765	} else {
 766		/* if uiGPIOMask is 0 then return mode register configuration */
 767		pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
 768	}
 769
 770	Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode,
 771		IoBuffer.OutputLength);
 772	if (Status) {
 773		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 774			"Failed while copying Content to IOBufer for user space err:%d",
 775			Status);
 776		return -EFAULT;
 777	}
 778	return Status;
 779}
 780
 781static int bcm_char_ioctl_misc_request(void __user *argp,
 782	struct bcm_mini_adapter *Adapter)
 783{
 784	struct bcm_ioctl_buffer IoBuffer;
 785	PVOID pvBuffer = NULL;
 786	INT Status;
 787
 788	/* Copy Ioctl Buffer structure */
 789	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
 790		return -EFAULT;
 791
 792	if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
 793		return -EINVAL;
 794
 795	if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
 796		return -EINVAL;
 797
 798	pvBuffer = memdup_user(IoBuffer.InputBuffer,
 799			       IoBuffer.InputLength);
 800	if (IS_ERR(pvBuffer))
 801		return PTR_ERR(pvBuffer);
 802
 803	down(&Adapter->LowPowerModeSync);
 804	Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
 805		!Adapter->bPreparingForLowPowerMode,
 806		(1 * HZ));
 807	if (Status == -ERESTARTSYS)
 808		goto cntrlEnd;
 809
 810	if (Adapter->bPreparingForLowPowerMode) {
 811		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 812				"Preparing Idle Mode is still True - Hence Rejecting control message\n");
 813		Status = STATUS_FAILURE;
 814		goto cntrlEnd;
 815	}
 816	Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
 817
 818cntrlEnd:
 819	up(&Adapter->LowPowerModeSync);
 820	kfree(pvBuffer);
 821	return Status;
 822}
 823
 824static int bcm_char_ioctl_buffer_download_start(
 825	struct bcm_mini_adapter *Adapter)
 826{
 827	INT Status;
 828
 829	if (down_trylock(&Adapter->NVMRdmWrmLock)) {
 830		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
 831				"IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
 832		return -EACCES;
 833	}
 834
 835	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 836		"Starting the firmware download PID =0x%x!!!!\n", current->pid);
 837
 838	if (down_trylock(&Adapter->fw_download_sema))
 839		return -EBUSY;
 840
 841	Adapter->bBinDownloaded = false;
 842	Adapter->fw_download_process_pid = current->pid;
 843	Adapter->bCfgDownloaded = false;
 844	Adapter->fw_download_done = false;
 845	netif_carrier_off(Adapter->dev);
 846	netif_stop_queue(Adapter->dev);
 847	Status = reset_card_proc(Adapter);
 848	if (Status) {
 849		pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
 850		up(&Adapter->fw_download_sema);
 851		up(&Adapter->NVMRdmWrmLock);
 852		return Status;
 853	}
 854	mdelay(10);
 855
 856	up(&Adapter->NVMRdmWrmLock);
 857	return Status;
 858}
 859
 860static int bcm_char_ioctl_buffer_download(void __user *argp,
 861	struct bcm_mini_adapter *Adapter)
 862{
 863	struct bcm_firmware_info *psFwInfo = NULL;
 864	struct bcm_ioctl_buffer IoBuffer;
 865	INT Status;
 866
 867	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 868		"Starting the firmware download PID =0x%x!!!!\n", current->pid);
 869
 870	if (!down_trylock(&Adapter->fw_download_sema)) {
 871		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 872				"Invalid way to download buffer. Use Start and then call this!!!\n");
 873		up(&Adapter->fw_download_sema);
 874		return -EINVAL;
 875	}
 876
 877	/* Copy Ioctl Buffer structure */
 878	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
 879		up(&Adapter->fw_download_sema);
 880		return -EFAULT;
 881	}
 882
 883	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 884			"Length for FW DLD is : %lx\n", IoBuffer.InputLength);
 885
 886	if (IoBuffer.InputLength > sizeof(struct bcm_firmware_info)) {
 887		up(&Adapter->fw_download_sema);
 888		return -EINVAL;
 889	}
 890
 891	psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
 892	if (!psFwInfo) {
 893		up(&Adapter->fw_download_sema);
 894		return -ENOMEM;
 895	}
 896
 897	if (copy_from_user(psFwInfo, IoBuffer.InputBuffer,
 898		IoBuffer.InputLength)) {
 899		up(&Adapter->fw_download_sema);
 900		kfree(psFwInfo);
 901		return -EFAULT;
 902	}
 903
 904	if (!psFwInfo->pvMappedFirmwareAddress ||
 905		(psFwInfo->u32FirmwareLength == 0)) {
 906
 907		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 908				"Something else is wrong %lu\n",
 909				psFwInfo->u32FirmwareLength);
 910		up(&Adapter->fw_download_sema);
 911		kfree(psFwInfo);
 912		Status = -EINVAL;
 913		return Status;
 914	}
 915
 916	Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
 917
 918	if (Status != STATUS_SUCCESS) {
 919		if (psFwInfo->u32StartingAddress == CONFIG_BEGIN_ADDR)
 920			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 921				"IOCTL: Configuration File Upload Failed\n");
 922		else
 923			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 924				"IOCTL: Firmware File Upload Failed\n");
 925
 926		/* up(&Adapter->fw_download_sema); */
 927
 928		if (Adapter->LEDInfo.led_thread_running &
 929			BCM_LED_THREAD_RUNNING_ACTIVELY) {
 930			Adapter->DriverState = DRIVER_INIT;
 931			Adapter->LEDInfo.bLedInitDone = false;
 932			wake_up(&Adapter->LEDInfo.notify_led_event);
 933		}
 934	}
 935
 936	if (Status != STATUS_SUCCESS)
 937		up(&Adapter->fw_download_sema);
 938
 939	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL,
 940		"IOCTL: Firmware File Uploaded\n");
 941	kfree(psFwInfo);
 942	return Status;
 943}
 944
 945static int bcm_char_ioctl_buffer_download_stop(void __user *argp,
 946	struct bcm_mini_adapter *Adapter)
 947{
 948	INT Status;
 949	int timeout = 0;
 950
 951	if (!down_trylock(&Adapter->fw_download_sema)) {
 952		up(&Adapter->fw_download_sema);
 953		return -EINVAL;
 954	}
 955
 956	if (down_trylock(&Adapter->NVMRdmWrmLock)) {
 957		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 958				"FW download blocked as EEPROM Read/Write is in progress\n");
 959		up(&Adapter->fw_download_sema);
 960		return -EACCES;
 961	}
 962
 963	Adapter->bBinDownloaded = TRUE;
 964	Adapter->bCfgDownloaded = TRUE;
 965	atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
 966	Adapter->CurrNumRecvDescs = 0;
 967	Adapter->downloadDDR = 0;
 968
 969	/* setting the Mips to Run */
 970	Status = run_card_proc(Adapter);
 971
 972	if (Status) {
 973		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 974			"Firm Download Failed\n");
 975		up(&Adapter->fw_download_sema);
 976		up(&Adapter->NVMRdmWrmLock);
 977		return Status;
 978	} else {
 979		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
 980				DBG_LVL_ALL, "Firm Download Over...\n");
 981	}
 982
 983	mdelay(10);
 984
 985	/* Wait for MailBox Interrupt */
 986	if (StartInterruptUrb((struct bcm_interface_adapter *)Adapter->pvInterfaceAdapter))
 987		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
 988			"Unable to send interrupt...\n");
 989
 990	timeout = 5*HZ;
 991	Adapter->waiting_to_fw_download_done = false;
 992	wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
 993			Adapter->waiting_to_fw_download_done, timeout);
 994	Adapter->fw_download_process_pid = INVALID_PID;
 995	Adapter->fw_download_done = TRUE;
 996	atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
 997	Adapter->CurrNumRecvDescs = 0;
 998	Adapter->PrevNumRecvDescs = 0;
 999	atomic_set(&Adapter->cntrlpktCnt, 0);
1000	Adapter->LinkUpStatus = 0;
1001	Adapter->LinkStatus = 0;
1002
1003	if (Adapter->LEDInfo.led_thread_running &
1004		BCM_LED_THREAD_RUNNING_ACTIVELY) {
1005		Adapter->DriverState = FW_DOWNLOAD_DONE;
1006		wake_up(&Adapter->LEDInfo.notify_led_event);
1007	}
1008
1009	if (!timeout)
1010		Status = -ENODEV;
1011
1012	up(&Adapter->fw_download_sema);
1013	up(&Adapter->NVMRdmWrmLock);
1014	return Status;
1015}
1016
1017static int bcm_char_ioctl_chip_reset(struct bcm_mini_adapter *Adapter)
1018{
1019	INT Status;
1020	INT NVMAccess;
1021
1022	NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
1023	if (NVMAccess) {
1024		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1025			" IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
1026		return -EACCES;
1027	}
1028
1029	down(&Adapter->RxAppControlQueuelock);
1030	Status = reset_card_proc(Adapter);
1031	flushAllAppQ();
1032	up(&Adapter->RxAppControlQueuelock);
1033	up(&Adapter->NVMRdmWrmLock);
1034	ResetCounters(Adapter);
1035	return Status;
1036}
1037
1038static int bcm_char_ioctl_qos_threshold(ULONG arg,
1039	struct bcm_mini_adapter *Adapter)
1040{
1041	USHORT uiLoopIndex;
1042
1043	for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
1044		if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
1045				(unsigned long __user *)arg)) {
1046			return -EFAULT;
1047		}
1048	}
1049	return 0;
1050}
1051
1052static int bcm_char_ioctl_switch_transfer_mode(void __user *argp,
1053	struct bcm_mini_adapter *Adapter)
1054{
1055	UINT uiData = 0;
1056
1057	if (copy_from_user(&uiData, argp, sizeof(UINT)))
1058		return -EFAULT;
1059
1060	if (uiData) {
1061		/* Allow All Packets */
1062		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1063			"IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
1064			Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
1065	} else {
1066		/* Allow IP only Packets */
1067		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1068			"IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
1069		Adapter->TransferMode = IP_PACKET_ONLY_MODE;
1070	}
1071	return STATUS_SUCCESS;
1072}
1073
1074static int bcm_char_ioctl_get_driver_version(void __user *argp)
1075{
1076	struct bcm_ioctl_buffer IoBuffer;
1077	ulong len;
1078
1079	/* Copy Ioctl Buffer structure */
1080	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1081		return -EFAULT;
1082
1083	len = min_t(ulong, IoBuffer.OutputLength, strlen(DRV_VERSION) + 1);
1084
1085	if (copy_to_user(IoBuffer.OutputBuffer, DRV_VERSION, len))
1086		return -EFAULT;
1087
1088	return STATUS_SUCCESS;
1089}
1090
1091static int bcm_char_ioctl_get_current_status(void __user *argp,
1092	struct bcm_mini_adapter *Adapter)
1093{
1094	struct bcm_link_state link_state;
1095	struct bcm_ioctl_buffer IoBuffer;
1096
1097	/* Copy Ioctl Buffer structure */
1098	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
1099		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1100			"copy_from_user failed..\n");
1101		return -EFAULT;
1102	}
1103
1104	if (IoBuffer.OutputLength != sizeof(link_state))
1105		return -EINVAL;
1106
1107	memset(&link_state, 0, sizeof(link_state));
1108	link_state.bIdleMode = Adapter->IdleMode;
1109	link_state.bShutdownMode = Adapter->bShutStatus;
1110	link_state.ucLinkStatus = Adapter->LinkStatus;
1111
1112	if (copy_to_user(IoBuffer.OutputBuffer, &link_state, min_t(size_t,
1113		sizeof(link_state), IoBuffer.OutputLength))) {
1114		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1115			"Copy_to_user Failed..\n");
1116		return -EFAULT;
1117	}
1118	return STATUS_SUCCESS;
1119}
1120
1121
1122static int bcm_char_ioctl_set_mac_tracing(void __user *argp,
1123	struct bcm_mini_adapter *Adapter)
1124{
1125	struct bcm_ioctl_buffer IoBuffer;
1126	UINT tracing_flag;
1127
1128	/* copy ioctl Buffer structure */
1129	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1130		return -EFAULT;
1131
1132	if (copy_from_user(&tracing_flag, IoBuffer.InputBuffer, sizeof(UINT)))
1133		return -EFAULT;
1134
1135	if (tracing_flag)
1136		Adapter->pTarangs->MacTracingEnabled = TRUE;
1137	else
1138		Adapter->pTarangs->MacTracingEnabled = false;
1139
1140	return STATUS_SUCCESS;
1141}
1142
1143static int bcm_char_ioctl_get_dsx_indication(void __user *argp,
1144	struct bcm_mini_adapter *Adapter)
1145{
1146	struct bcm_ioctl_buffer IoBuffer;
1147	ULONG ulSFId = 0;
1148
1149	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1150		return -EFAULT;
1151
1152	if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
1153		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1154			"Mismatch req: %lx needed is =0x%zx!!!",
1155			IoBuffer.OutputLength,
1156			sizeof(struct bcm_add_indication_alt));
1157		return -EINVAL;
1158	}
1159
1160	if (copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
1161		return -EFAULT;
1162
1163	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1164		"Get DSX Data SF ID is =%lx\n", ulSFId);
1165	get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
1166	return STATUS_SUCCESS;
1167}
1168
1169static int bcm_char_ioctl_get_host_mibs(void __user *argp,
1170	struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang)
1171{
1172	struct bcm_ioctl_buffer IoBuffer;
1173	INT Status = STATUS_FAILURE;
1174	PVOID temp_buff;
1175
1176	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1177		return -EFAULT;
1178
1179	if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
1180		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1181			"Length Check failed %lu %zd\n", IoBuffer.OutputLength,
1182			sizeof(struct bcm_host_stats_mibs));
1183		return -EINVAL;
1184	}
1185
1186	/* FIXME: HOST_STATS are too big for kmalloc (122048)! */
1187	temp_buff = kzalloc(sizeof(struct bcm_host_stats_mibs), GFP_KERNEL);
1188	if (!temp_buff)
1189		return STATUS_FAILURE;
1190
1191	Status = ProcessGetHostMibs(Adapter, temp_buff);
1192	GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
1193
1194	if (Status != STATUS_FAILURE) {
1195		if (copy_to_user(IoBuffer.OutputBuffer, temp_buff,
1196			sizeof(struct bcm_host_stats_mibs))) {
1197			kfree(temp_buff);
1198			return -EFAULT;
1199		}
1200	}
1201
1202	kfree(temp_buff);
1203	return Status;
1204}
1205
1206static int bcm_char_ioctl_bulk_wrm(void __user *argp,
1207	struct bcm_mini_adapter *Adapter, UINT cmd)
1208{
1209	struct bcm_bulk_wrm_buffer *pBulkBuffer;
1210	struct bcm_ioctl_buffer IoBuffer;
1211	UINT uiTempVar = 0;
1212	INT Status = STATUS_FAILURE;
1213	PCHAR pvBuffer = NULL;
1214
1215	if ((Adapter->IdleMode == TRUE) ||
1216		(Adapter->bShutStatus == TRUE) ||
1217		(Adapter->bPreparingForLowPowerMode == TRUE)) {
1218
1219		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
1220			"Device in Idle/Shutdown Mode, Blocking Wrms\n");
1221		return -EACCES;
1222	}
1223
1224	/* Copy Ioctl Buffer structure */
1225	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1226		return -EFAULT;
1227
1228	if (IoBuffer.InputLength < sizeof(ULONG) * 2)
1229		return -EINVAL;
1230
1231	pvBuffer = memdup_user(IoBuffer.InputBuffer,
1232			       IoBuffer.InputLength);
1233	if (IS_ERR(pvBuffer))
1234		return PTR_ERR(pvBuffer);
1235
1236	pBulkBuffer = (struct bcm_bulk_wrm_buffer *)pvBuffer;
1237
1238	if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
1239		((ULONG)pBulkBuffer->Register & 0x3)) {
1240		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
1241			"WRM Done On invalid Address : %x Access Denied.\n",
1242			(int)pBulkBuffer->Register);
1243		kfree(pvBuffer);
1244		return -EINVAL;
1245	}
1246
1247	uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
1248	if (!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE) &&
1249		((uiTempVar == EEPROM_REJECT_REG_1) ||
1250			(uiTempVar == EEPROM_REJECT_REG_2) ||
1251			(uiTempVar == EEPROM_REJECT_REG_3) ||
1252			(uiTempVar == EEPROM_REJECT_REG_4)) &&
1253		(cmd == IOCTL_BCM_REGISTER_WRITE)) {
1254
1255		kfree(pvBuffer);
1256		BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
1257			"EEPROM Access Denied, not in VSG Mode\n");
1258		return -EFAULT;
1259	}
1260
1261	if (pBulkBuffer->SwapEndian == false)
1262		Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register,
1263			(PCHAR)pBulkBuffer->Values,
1264			IoBuffer.InputLength - 2*sizeof(ULONG));
1265	else
1266		Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register,
1267			(PUINT)pBulkBuffer->Values,
1268			IoBuffer.InputLength - 2*sizeof(ULONG));
1269
1270	if (Status != STATUS_SUCCESS)
1271		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
1272
1273	kfree(pvBuffer);
1274	return Status;
1275}
1276
1277static int bcm_char_ioctl_get_nvm_size(void __user *argp,
1278	struct bcm_mini_adapter *Adapter)
1279{
1280	struct bcm_ioctl_buffer IoBuffer;
1281
1282	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1283		return -EFAULT;
1284
1285	if (Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH) {
1286		if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize,
1287			sizeof(UINT)))
1288			return -EFAULT;
1289	}
1290
1291	return STATUS_SUCCESS;
1292}
1293
1294static int bcm_char_ioctl_cal_init(void __user *argp,
1295	struct bcm_mini_adapter *Adapter)
1296{
1297	struct bcm_ioctl_buffer IoBuffer;
1298	UINT uiSectorSize = 0;
1299	INT Status = STATUS_FAILURE;
1300
1301	if (Adapter->eNVMType == NVM_FLASH) {
1302		if (copy_from_user(&IoBuffer, argp,
1303			sizeof(struct bcm_ioctl_buffer)))
1304			return -EFAULT;
1305
1306		if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer,
1307			sizeof(UINT)))
1308			return -EFAULT;
1309
1310		if ((uiSectorSize < MIN_SECTOR_SIZE) ||
1311			(uiSectorSize > MAX_SECTOR_SIZE)) {
1312			if (copy_to_user(IoBuffer.OutputBuffer,
1313				&Adapter->uiSectorSize, sizeof(UINT)))
1314				return -EFAULT;
1315		} else {
1316			if (IsFlash2x(Adapter)) {
1317				if (copy_to_user(IoBuffer.OutputBuffer,
1318					&Adapter->uiSectorSize, sizeof(UINT)))
1319					return -EFAULT;
1320			} else {
1321				if ((TRUE == Adapter->bShutStatus) ||
1322					(TRUE == Adapter->IdleMode)) {
1323					BCM_DEBUG_PRINT(Adapter,
1324						DBG_TYPE_PRINTK, 0, 0,
1325						"Device is in Idle/Shutdown Mode\n");
1326					return -EACCES;
1327				}
1328
1329				Adapter->uiSectorSize = uiSectorSize;
1330				BcmUpdateSectorSize(Adapter,
1331					Adapter->uiSectorSize);
1332			}
1333		}
1334		Status = STATUS_SUCCESS;
1335	} else {
1336		Status = STATUS_FAILURE;
1337	}
1338	return Status;
1339}
1340
1341static int bcm_char_ioctl_set_debug(void __user *argp,
1342	struct bcm_mini_adapter *Adapter)
1343{
1344#ifdef DEBUG
1345	struct bcm_ioctl_buffer IoBuffer;
1346	struct bcm_user_debug_state sUserDebugState;
1347
1348	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1349		"In SET_DEBUG ioctl\n");
1350	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1351		return -EFAULT;
1352
1353	if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer,
1354		sizeof(struct bcm_user_debug_state)))
1355		return -EFAULT;
1356
1357	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
1358			"IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
1359			sUserDebugState.OnOff, sUserDebugState.Type);
1360	/* sUserDebugState.Subtype <<= 1; */
1361	sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
1362	BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,
1363		"actual Subtype=0x%x\n", sUserDebugState.Subtype);
1364
1365	/* Update new 'DebugState' in the Adapter */
1366	Adapter->stDebugState.type |= sUserDebugState.Type;
1367	/* Subtype: A bitmap of 32 bits for Subtype per Type.
1368	 * Valid indexes in 'subtype' array: 1,2,4,8
1369	 * corresponding to valid Type values. Hence we can use the 'Type' field
1370	 * as the index value, ignoring the array entries 0,3,5,6,7 !
1371	 */
1372	if (sUserDebugState.OnOff)
1373		Adapter->stDebugState.subtype[sUserDebugState.Type] |=
1374			sUserDebugState.Subtype;
1375	else
1376		Adapter->stDebugState.subtype[sUserDebugState.Type] &=
1377			~sUserDebugState.Subtype;
1378
1379	BCM_SHOW_DEBUG_BITMAP(Adapter);
1380#endif
1381	return STATUS_SUCCESS;
1382}
1383
1384static int bcm_char_ioctl_nvm_rw(void __user *argp,
1385	struct bcm_mini_adapter *Adapter, UINT cmd)
1386{
1387	struct bcm_nvm_readwrite stNVMReadWrite;
1388	struct timeval tv0, tv1;
1389	struct bcm_ioctl_buffer IoBuffer;
1390	PUCHAR pReadData = NULL;
1391	ULONG ulDSDMagicNumInUsrBuff = 0;
1392	INT Status = STATUS_FAILURE;
1393
1394	memset(&tv0, 0, sizeof(struct timeval));
1395	memset(&tv1, 0, sizeof(struct timeval));
1396	if ((Adapter->eNVMType == NVM_FLASH) &&
1397		(Adapter->uiFlashLayoutMajorVersion == 0)) {
1398		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1399			"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
1400		return -EFAULT;
1401	}
1402
1403	if (IsFlash2x(Adapter)) {
1404		if ((Adapter->eActiveDSD != DSD0) &&
1405			(Adapter->eActiveDSD != DSD1) &&
1406			(Adapter->eActiveDSD != DSD2)) {
1407
1408			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1409				"No DSD is active..hence NVM Command is blocked");
1410			return STATUS_FAILURE;
1411		}
1412	}
1413
1414	/* Copy Ioctl Buffer structure */
1415	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1416		return -EFAULT;
1417
1418	if (copy_from_user(&stNVMReadWrite,
1419				(IOCTL_BCM_NVM_READ == cmd) ?
1420				IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
1421				sizeof(struct bcm_nvm_readwrite)))
1422		return -EFAULT;
1423
1424	/*
1425	 * Deny the access if the offset crosses the cal area limit.
1426	 */
1427	if (stNVMReadWrite.uiNumBytes > Adapter->uiNVMDSDSize)
1428		return STATUS_FAILURE;
1429
1430	if (stNVMReadWrite.uiOffset >
1431		Adapter->uiNVMDSDSize - stNVMReadWrite.uiNumBytes)
1432		return STATUS_FAILURE;
1433
1434	pReadData = memdup_user(stNVMReadWrite.pBuffer,
1435				stNVMReadWrite.uiNumBytes);
1436	if (IS_ERR(pReadData))
1437		return PTR_ERR(pReadData);
1438
1439	do_gettimeofday(&tv0);
1440	if (IOCTL_BCM_NVM_READ == cmd) {
1441		down(&Adapter->NVMRdmWrmLock);
1442
1443		if ((Adapter->IdleMode == TRUE) ||
1444			(Adapter->bShutStatus == TRUE) ||
1445			(Adapter->bPreparingForLowPowerMode == TRUE)) {
1446
1447			BCM_DEBUG_PRINT(Adapter,
1448				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1449				"Device is in Idle/Shutdown Mode\n");
1450			up(&Adapter->NVMRdmWrmLock);
1451			kfree(pReadData);
1452			return -EACCES;
1453		}
1454
1455		Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
1456			stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
1457		up(&Adapter->NVMRdmWrmLock);
1458
1459		if (Status != STATUS_SUCCESS) {
1460			kfree(pReadData);
1461			return Status;
1462		}
1463
1464		if (copy_to_user(stNVMReadWrite.pBuffer, pReadData,
1465			stNVMReadWrite.uiNumBytes)) {
1466			kfree(pReadData);
1467			return -EFAULT;
1468		}
1469	} else {
1470		down(&Adapter->NVMRdmWrmLock);
1471
1472		if ((Adapter->IdleMode == TRUE) ||
1473			(Adapter->bShutStatus == TRUE) ||
1474			(Adapter->bPreparingForLowPowerMode == TRUE)) {
1475
1476			BCM_DEBUG_PRINT(Adapter,
1477				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1478				"Device is in Idle/Shutdown Mode\n");
1479			up(&Adapter->NVMRdmWrmLock);
1480			kfree(pReadData);
1481			return -EACCES;
1482		}
1483
1484		Adapter->bHeaderChangeAllowed = TRUE;
1485		if (IsFlash2x(Adapter)) {
1486			/*
1487			 * New Requirement:-
1488			 * DSD section updation will be allowed in two case:-
1489			 * 1.  if DSD sig is present in DSD header means dongle
1490			 * is ok and updation is fruitfull
1491			 * 2.  if point 1 failes then user buff should have
1492			 * DSD sig. this point ensures that if dongle is
1493			 * corrupted then user space program first modify
1494			 * the DSD header with valid DSD sig so that this
1495			 * as well as further write may be worthwhile.
1496			 *
1497			 * This restriction has been put assuming that
1498			 * if DSD sig is corrupted, DSD data won't be
1499			 * considered valid.
1500			 */
1501
1502			Status = BcmFlash2xCorruptSig(Adapter,
1503				Adapter->eActiveDSD);
1504			if (Status != STATUS_SUCCESS) {
1505				if (((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) !=
1506					Adapter->uiNVMDSDSize) ||
1507					(stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE)) {
1508
1509					BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS,
1510						OSAL_DBG, DBG_LVL_ALL,
1511						"DSD Sig is present neither in Flash nor User provided Input..");
1512					up(&Adapter->NVMRdmWrmLock);
1513					kfree(pReadData);
1514					return Status;
1515				}
1516
1517				ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
1518				if (ulDSDMagicNumInUsrBuff !=
1519					DSD_IMAGE_MAGIC_NUMBER) {
1520					BCM_DEBUG_PRINT(Adapter,
1521					DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1522						"DSD Sig is present neither in Flash nor User provided Input..");
1523					up(&Adapter->NVMRdmWrmLock);
1524					kfree(pReadData);
1525					return Status;
1526				}
1527			}
1528		}
1529
1530		Status = BeceemNVMWrite(Adapter, (PUINT)pReadData,
1531			stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes,
1532			stNVMReadWrite.bVerify);
1533		if (IsFlash2x(Adapter))
1534			BcmFlash2xWriteSig(Adapter, Adapter->eActiveDSD);
1535
1536		Adapter->bHeaderChangeAllowed = false;
1537
1538		up(&Adapter->NVMRdmWrmLock);
1539
1540		if (Status != STATUS_SUCCESS) {
1541			kfree(pReadData);
1542			return Status;
1543		}
1544	}
1545
1546	do_gettimeofday(&tv1);
1547	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1548		" timetaken by Write/read :%ld msec\n",
1549		(tv1.tv_sec - tv0.tv_sec)*1000 + (tv1.tv_usec - tv0.tv_usec)/1000);
1550
1551	kfree(pReadData);
1552	return STATUS_SUCCESS;
1553}
1554
1555static int bcm_char_ioctl_flash2x_section_read(void __user *argp,
1556	struct bcm_mini_adapter *Adapter)
1557{
1558	struct bcm_flash2x_readwrite sFlash2xRead = {0};
1559	struct bcm_ioctl_buffer IoBuffer;
1560	PUCHAR pReadBuff = NULL;
1561	UINT NOB = 0;
1562	UINT BuffSize = 0;
1563	UINT ReadBytes = 0;
1564	UINT ReadOffset = 0;
1565	INT Status = STATUS_FAILURE;
1566	void __user *OutPutBuff;
1567
1568	if (IsFlash2x(Adapter) != TRUE)	{
1569		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1570			"Flash Does not have 2.x map");
1571		return -EINVAL;
1572	}
1573
1574	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
1575		DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
1576	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1577		return -EFAULT;
1578
1579	/* Reading FLASH 2.x READ structure */
1580	if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,
1581		sizeof(struct bcm_flash2x_readwrite)))
1582		return -EFAULT;
1583
1584	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1585		"\nsFlash2xRead.Section :%x", sFlash2xRead.Section);
1586	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1587		"\nsFlash2xRead.offset :%x", sFlash2xRead.offset);
1588	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1589		"\nsFlash2xRead.numOfBytes :%x", sFlash2xRead.numOfBytes);
1590	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1591		"\nsFlash2xRead.bVerify :%x\n", sFlash2xRead.bVerify);
1592
1593	/* This was internal to driver for raw read.
1594	 * now it has ben exposed to user space app.
1595	 */
1596	if (validateFlash2xReadWrite(Adapter, &sFlash2xRead) == false)
1597		return STATUS_FAILURE;
1598
1599	NOB = sFlash2xRead.numOfBytes;
1600	if (NOB > Adapter->uiSectorSize)
1601		BuffSize = Adapter->uiSectorSize;
1602	else
1603		BuffSize = NOB;
1604
1605	ReadOffset = sFlash2xRead.offset;
1606	OutPutBuff = IoBuffer.OutputBuffer;
1607	pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
1608
1609	if (pReadBuff == NULL) {
1610		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1611			"Memory allocation failed for Flash 2.x Read Structure");
1612		return -ENOMEM;
1613	}
1614	down(&Adapter->NVMRdmWrmLock);
1615
1616	if ((Adapter->IdleMode == TRUE) ||
1617		(Adapter->bShutStatus == TRUE) ||
1618		(Adapter->bPreparingForLowPowerMode == TRUE)) {
1619
1620		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
1621			DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
1622		up(&Adapter->NVMRdmWrmLock);
1623		kfree(pReadBuff);
1624		return -EACCES;
1625	}
1626
1627	while (NOB) {
1628		if (NOB > Adapter->uiSectorSize)
1629			ReadBytes = Adapter->uiSectorSize;
1630		else
1631			ReadBytes = NOB;
1632
1633		/* Reading the data from Flash 2.x */
1634		Status = BcmFlash2xBulkRead(Adapter, (PUINT)pReadBuff,
1635			sFlash2xRead.Section, ReadOffset, ReadBytes);
1636		if (Status) {
1637			BCM_DEBUG_PRINT(Adapter,
1638				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1639				"Flash 2x read err with Status :%d",
1640				Status);
1641			break;
1642		}
1643
1644		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
1645			DBG_LVL_ALL, pReadBuff, ReadBytes);
1646
1647		Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
1648		if (Status) {
1649			BCM_DEBUG_PRINT(Adapter,
1650				DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1651				"Copy to use failed with status :%d", Status);
1652			up(&Adapter->NVMRdmWrmLock);
1653			kfree(pReadBuff);
1654			return -EFAULT;
1655		}
1656		NOB = NOB - ReadBytes;
1657		if (NOB) {
1658			ReadOffset = ReadOffset + ReadBytes;
1659			OutPutBuff = OutPutBuff + ReadBytes;
1660		}
1661	}
1662
1663	up(&Adapter->NVMRdmWrmLock);
1664	kfree(pReadBuff);
1665	return Status;
1666}
1667
1668static int bcm_char_ioctl_flash2x_section_write(void __user *argp,
1669	struct bcm_mini_adapter *Adapter)
1670{
1671	struct bcm_flash2x_readwrite sFlash2xWrite = {0};
1672	struct bcm_ioctl_buffer IoBuffer;
1673	PUCHAR pWriteBuff;
1674	void __user *InputAddr;
1675	UINT NOB = 0;
1676	UINT BuffSize = 0;
1677	UINT WriteOffset = 0;
1678	UINT WriteBytes = 0;
1679	INT Status = STATUS_FAILURE;
1680
1681	if (IsFlash2x(Adapter) != TRUE) {
1682		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1683			"Flash Does not have 2.x map");
1684		return -EINVAL;
1685	}
1686
1687	/* First make this False so that we can enable the Sector
1688	 * Permission Check in BeceemFlashBulkWrite
1689	 */
1690	Adapter->bAllDSDWriteAllow = false;
1691
1692	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1693		"IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
1694
1695	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1696		return -EFAULT;
1697
1698	/* Reading FLASH 2.x READ structure */
1699	if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer,
1700		sizeof(struct bcm_flash2x_readwrite)))
1701		return -EFAULT;
1702
1703	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1704		"\nsFlash2xRead.Section :%x", sFlash2xWrite.Section);
1705	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1706		"\nsFlash2xRead.offset :%d", sFlash2xWrite.offset);
1707	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1708		"\nsFlash2xRead.numOfBytes :%x", sFlash2xWrite.numOfBytes);
1709	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1710		"\nsFlash2xRead.bVerify :%x\n", sFlash2xWrite.bVerify);
1711
1712	if ((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1)
1713		&& (sFlash2xWrite.Section != VSA2)) {
1714		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1715			"Only VSA write is allowed");
1716		return -EINVAL;
1717	}
1718
1719	if (validateFlash2xReadWrite(Adapter, &sFlash2xWrite) == false)
1720		return STATUS_FAILURE;
1721
1722	InputAddr = sFlash2xWrite.pDataBuff;
1723	WriteOffset = sFlash2xWrite.offset;
1724	NOB = sFlash2xWrite.numOfBytes;
1725
1726	if (NOB > Adapter->uiSectorSize)
1727		BuffSize = Adapter->uiSectorSize;
1728	else
1729		BuffSize = NOB;
1730
1731	pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
1732
1733	if (pWriteBuff == NULL)
1734		return -ENOMEM;
1735
1736	/* extracting the remainder of the given offset. */
1737	WriteBytes = Adapter->uiSectorSize;
1738	if (WriteOffset % Adapter->uiSectorSize)
1739		WriteBytes = Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);
1740
1741	if (NOB < WriteBytes)
1742		WriteBytes = NOB;
1743
1744	down(&Adapter->NVMRdmWrmLock);
1745
1746	if ((Adapter->IdleMode == TRUE) ||
1747		(Adapter->bShutStatus == TRUE) ||
1748		(Adapter->bPreparingForLowPowerMode == TRUE)) {
1749
1750		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1751			"Device is in Idle/Shutdown Mode\n");
1752		up(&Adapter->NVMRdmWrmLock);
1753		kfree(pWriteBuff);
1754		return -EACCES;
1755	}
1756
1757	BcmFlash2xCorruptSig(Adapter, sFlash2xWrite.Section);
1758	do {
1759		Status = copy_from_user(pWriteBuff, InputAddr, WriteBytes);
1760		if (Status) {
1761			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1762				"Copy to user failed with status :%d", Status);
1763			up(&Adapter->NVMRdmWrmLock);
1764			kfree(pWriteBuff);
1765			return -EFAULT;
1766		}
1767		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS,
1768			OSAL_DBG, DBG_LVL_ALL, pWriteBuff, WriteBytes);
1769
1770		/* Writing the data from Flash 2.x */
1771		Status = BcmFlash2xBulkWrite(Adapter, (PUINT)pWriteBuff,
1772			sFlash2xWrite.Section, WriteOffset, WriteBytes,
1773			sFlash2xWrite.bVerify);
1774
1775		if (Status) {
1776			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1777				"Flash 2x read err with Status :%d", Status);
1778			break;
1779		}
1780
1781		NOB = NOB - WriteBytes;
1782		if (NOB) {
1783			WriteOffset = WriteOffset + WriteBytes;
1784			InputAddr = InputAddr + WriteBytes;
1785			if (NOB > Adapter->uiSectorSize)
1786				WriteBytes = Adapter->uiSectorSize;
1787			else
1788				WriteBytes = NOB;
1789		}
1790	} while (NOB > 0);
1791
1792	BcmFlash2xWriteSig(Adapter, sFlash2xWrite.Section);
1793	up(&Adapter->NVMRdmWrmLock);
1794	kfree(pWriteBuff);
1795	return Status;
1796}
1797
1798static int bcm_char_ioctl_flash2x_section_bitmap(void __user *argp,
1799	struct bcm_mini_adapter *Adapter)
1800{
1801	struct bcm_flash2x_bitmap *psFlash2xBitMap;
1802	struct bcm_ioctl_buffer IoBuffer;
1803	INT Status = STATUS_FAILURE;
1804
1805BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1806	"IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
1807
1808	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1809		return -EFAULT;
1810
1811	if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
1812		return -EINVAL;
1813
1814	psFlash2xBitMap = kzalloc(sizeof(struct bcm_flash2x_bitmap), GFP_KERNEL);
1815	if (psFlash2xBitMap == NULL) {
1816		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1817			"Memory is not available");
1818		return -ENOMEM;
1819	}
1820
1821	/* Reading the Flash Sectio Bit map */
1822	down(&Adapter->NVMRdmWrmLock);
1823
1824	if ((Adapter->IdleMode == TRUE) ||
1825		(Adapter->bShutStatus == TRUE) ||
1826		(Adapter->bPreparingForLowPowerMode == TRUE)) {
1827
1828		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1829			"Device is in Idle/Shutdown Mode\n");
1830		up(&Adapter->NVMRdmWrmLock);
1831		kfree(psFlash2xBitMap);
1832		return -EACCES;
1833	}
1834
1835	BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
1836	up(&Adapter->NVMRdmWrmLock);
1837	if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap,
1838		sizeof(struct bcm_flash2x_bitmap))) {
1839		kfree(psFlash2xBitMap);
1840		return -EFAULT;
1841	}
1842
1843	kfree(psFlash2xBitMap);
1844	return Status;
1845}
1846
1847static int bcm_char_ioctl_set_active_section(void __user *argp,
1848	struct bcm_mini_adapter *Adapter)
1849{
1850	enum bcm_flash2x_section_val eFlash2xSectionVal = 0;
1851	INT Status = STATUS_FAILURE;
1852	struct bcm_ioctl_buffer IoBuffer;
1853
1854	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1855		"IOCTL_BCM_SET_ACTIVE_SECTION Called");
1856
1857	if (IsFlash2x(Adapter) != TRUE) {
1858		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1859			"Flash Does not have 2.x map");
1860		return -EINVAL;
1861	}
1862
1863	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
1864	if (Status) {
1865		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1866			"Copy of IOCTL BUFFER failed");
1867		return -EFAULT;
1868	}
1869
1870	Status = copy_from_user(&eFlash2xSectionVal,
1871		IoBuffer.InputBuffer, sizeof(INT));
1872	if (Status) {
1873		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1874			"Copy of flash section val failed");
1875		return -EFAULT;
1876	}
1877
1878	down(&Adapter->NVMRdmWrmLock);
1879
1880	if ((Adapter->IdleMode == TRUE) ||
1881		(Adapter->bShutStatus == TRUE) ||
1882		(Adapter->bPreparingForLowPowerMode == TRUE)) {
1883
1884		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1885			"Device is in Idle/Shutdown Mode\n");
1886		up(&Adapter->NVMRdmWrmLock);
1887		return -EACCES;
1888	}
1889
1890	Status = BcmSetActiveSection(Adapter, eFlash2xSectionVal);
1891	if (Status)
1892		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1893			"Failed to make it's priority Highest. Status %d",
1894			Status);
1895
1896	up(&Adapter->NVMRdmWrmLock);
1897
1898	return Status;
1899}
1900
1901static int bcm_char_ioctl_copy_section(void __user *argp,
1902	struct bcm_mini_adapter *Adapter)
1903{
1904	struct bcm_flash2x_copy_section sCopySectStrut = {0};
1905	struct bcm_ioctl_buffer IoBuffer;
1906	INT Status = STATUS_SUCCESS;
1907
1908	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1909		"IOCTL_BCM_COPY_SECTION  Called");
1910
1911	Adapter->bAllDSDWriteAllow = false;
1912	if (IsFlash2x(Adapter) != TRUE) {
1913		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1914			"Flash Does not have 2.x map");
1915		return -EINVAL;
1916	}
1917
1918	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
1919	if (Status) {
1920		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1921			"Copy of IOCTL BUFFER failed Status :%d", Status);
1922		return -EFAULT;
1923	}
1924
1925	Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer,
1926			sizeof(struct bcm_flash2x_copy_section));
1927	if (Status) {
1928		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1929			"Copy of Copy_Section_Struct failed with Status :%d",
1930			Status);
1931		return -EFAULT;
1932	}
1933
1934	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1935		"Source SEction :%x", sCopySectStrut.SrcSection);
1936	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1937		"Destination SEction :%x", sCopySectStrut.DstSection);
1938	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1939		"offset :%x", sCopySectStrut.offset);
1940	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1941		"NOB :%x", sCopySectStrut.numOfBytes);
1942
1943	if (IsSectionExistInFlash(Adapter, sCopySectStrut.SrcSection) == false) {
1944		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1945			"Source Section<%x> does not exist in Flash ",
1946			sCopySectStrut.SrcSection);
1947		return -EINVAL;
1948	}
1949
1950	if (IsSectionExistInFlash(Adapter, sCopySectStrut.DstSection) == false) {
1951		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1952			"Destinatio Section<%x> does not exist in Flash ",
1953			sCopySectStrut.DstSection);
1954		return -EINVAL;
1955	}
1956
1957	if (sCopySectStrut.SrcSection == sCopySectStrut.DstSection) {
1958		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1959			"Source and Destination section should be different");
1960		return -EINVAL;
1961	}
1962
1963	down(&Adapter->NVMRdmWrmLock);
1964
1965	if ((Adapter->IdleMode == TRUE) ||
1966		(Adapter->bShutStatus == TRUE) ||
1967		(Adapter->bPreparingForLowPowerMode == TRUE)) {
1968
1969		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
1970			"Device is in Idle/Shutdown Mode\n");
1971		up(&Adapter->NVMRdmWrmLock);
1972		return -EACCES;
1973	}
1974
1975	if (sCopySectStrut.SrcSection == ISO_IMAGE1 ||
1976		sCopySectStrut.SrcSection == ISO_IMAGE2) {
1977		if (IsNonCDLessDevice(Adapter)) {
1978			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1979				"Device is Non-CDLess hence won't have ISO !!");
1980			Status = -EINVAL;
1981		} else if (sCopySectStrut.numOfBytes == 0) {
1982			Status = BcmCopyISO(Adapter, sCopySectStrut);
1983		} else {
1984			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1985				"Partial Copy of ISO section is not Allowed..");
1986			Status = STATUS_FAILURE;
1987		}
1988		up(&Adapter->NVMRdmWrmLock);
1989		return Status;
1990	}
1991
1992	Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
1993				sCopySectStrut.DstSection,
1994				sCopySectStrut.offset,
1995				sCopySectStrut.numOfBytes);
1996	up(&Adapter->NVMRdmWrmLock);
1997	return Status;
1998}
1999
2000static int bcm_char_ioctl_get_flash_cs_info(void __user *argp,
2001	struct bcm_mini_adapter *Adapter)
2002{
2003	struct bcm_ioctl_buffer IoBuffer;
2004	INT Status = STATUS_SUCCESS;
2005
2006	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2007		" IOCTL_BCM_GET_FLASH_CS_INFO Called");
2008
2009	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
2010	if (Status) {
2011		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2012			"Copy of IOCTL BUFFER failed");
2013		return -EFAULT;
2014	}
2015
2016	if (Adapter->eNVMType != NVM_FLASH) {
2017		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2018			"Connected device does not have flash");
2019		return -EINVAL;
2020	}
2021
2022	if (IsFlash2x(Adapter) == TRUE) {
2023		if (IoBuffer.OutputLength < sizeof(struct bcm_flash2x_cs_info))
2024			return -EINVAL;
2025
2026		if (copy_to_user(IoBuffer.OutputBuffer,
2027			Adapter->psFlash2xCSInfo,
2028			sizeof(struct bcm_flash2x_cs_info)))
2029			return -EFAULT;
2030	} else {
2031		if (IoBuffer.OutputLength < sizeof(struct bcm_flash_cs_info))
2032			return -EINVAL;
2033
2034		if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo,
2035			sizeof(struct bcm_flash_cs_info)))
2036			return -EFAULT;
2037	}
2038	return Status;
2039}
2040
2041static int bcm_char_ioctl_select_dsd(void __user *argp,
2042	struct bcm_mini_adapter *Adapter)
2043{
2044	struct bcm_ioctl_buffer IoBuffer;
2045	INT Status = STATUS_FAILURE;
2046	UINT SectOfset = 0;
2047	enum bcm_flash2x_section_val eFlash2xSectionVal;
2048
2049	eFlash2xSectionVal = NO_SECTION_VAL;
2050	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2051		"IOCTL_BCM_SELECT_DSD Called");
2052
2053	if (IsFlash2x(Adapter) != TRUE) {
2054		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2055			"Flash Does not have 2.x map");
2056		return -EINVAL;
2057	}
2058
2059	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
2060	if (Status) {
2061		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2062			"Copy of IOCTL BUFFER failed");
2063		return -EFAULT;
2064	}
2065	Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer,
2066		sizeof(INT));
2067	if (Status) {
2068		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2069			"Copy of flash section val failed");
2070		return -EFAULT;
2071	}
2072
2073	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2074		"Read Section :%d", eFlash2xSectionVal);
2075	if ((eFlash2xSectionVal != DSD0) &&
2076		(eFlash2xSectionVal != DSD1) &&
2077		(eFlash2xSectionVal != DSD2)) {
2078
2079		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2080			"Passed section<%x> is not DSD section",
2081			eFlash2xSectionVal);
2082		return STATUS_FAILURE;
2083	}
2084
2085	SectOfset = BcmGetSectionValStartOffset(Adapter, eFlash2xSectionVal);
2086	if (SectOfset == INVALID_OFFSET) {
2087		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2088			"Provided Section val <%d> does not exist in Flash 2.x",
2089			eFlash2xSectionVal);
2090		return -EINVAL;
2091	}
2092
2093	Adapter->bAllDSDWriteAllow = TRUE;
2094	Adapter->ulFlashCalStart = SectOfset;
2095	Adapter->eActiveDSD = eFlash2xSectionVal;
2096
2097	return STATUS_SUCCESS;
2098}
2099
2100static int bcm_char_ioctl_nvm_raw_read(void __user *argp,
2101	struct bcm_mini_adapter *Adapter)
2102{
2103	struct bcm_nvm_readwrite stNVMRead;
2104	struct bcm_ioctl_buffer IoBuffer;
2105	unsigned int NOB;
2106	INT BuffSize;
2107	INT ReadOffset = 0;
2108	UINT ReadBytes = 0;
2109	PUCHAR pReadBuff;
2110	void __user *OutPutBuff;
2111	INT Status = STATUS_FAILURE;
2112
2113	if (Adapter->eNVMType != NVM_FLASH) {
2114		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2115			"NVM TYPE is not Flash");
2116		return -EINVAL;
2117	}
2118
2119	/* Copy Ioctl Buffer structure */
2120	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
2121		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2122			"copy_from_user 1 failed\n");
2123		return -EFAULT;
2124	}
2125
2126	if (copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,
2127		sizeof(struct bcm_nvm_readwrite)))
2128		return -EFAULT;
2129
2130	NOB = stNVMRead.uiNumBytes;
2131	/* In Raw-Read max Buff size : 64MB */
2132
2133	if (NOB > DEFAULT_BUFF_SIZE)
2134		BuffSize = DEFAULT_BUFF_SIZE;
2135	else
2136		BuffSize = NOB;
2137
2138	ReadOffset = stNVMRead.uiOffset;
2139	OutPutBuff = stNVMRead.pBuffer;
2140
2141	pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
2142	if (pReadBuff == NULL) {
2143		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2144			"Memory allocation failed for Flash 2.x Read Structure");
2145		return -ENOMEM;
2146	}
2147	down(&Adapter->NVMRdmWrmLock);
2148
2149	if ((Adapter->IdleMode == TRUE) ||
2150		(Adapter->bShutStatus == TRUE) ||
2151		(Adapter->bPreparingForLowPowerMode == TRUE)) {
2152
2153		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
2154			DBG_LVL_ALL, "Device is in Idle/Shutdown Mode\n");
2155		kfree(pReadBuff);
2156		up(&Adapter->NVMRdmWrmLock);
2157		return -EACCES;
2158	}
2159
2160	Adapter->bFlashRawRead = TRUE;
2161
2162	while (NOB) {
2163		if (NOB > DEFAULT_BUFF_SIZE)
2164			ReadBytes = DEFAULT_BUFF_SIZE;
2165		else
2166			ReadBytes = NOB;
2167
2168		/* Reading the data from Flash 2.x */
2169		Status = BeceemNVMRead(Adapter, (PUINT)pReadBuff,
2170			ReadOffset, ReadBytes);
2171		if (Status) {
2172			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2173				"Flash 2x read err with Status :%d", Status);
2174			break;
2175		}
2176
2177		BCM_DEBUG_PRINT_BUFFER(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
2178			DBG_LVL_ALL, pReadBuff, ReadBytes);
2179
2180		Status = copy_to_user(OutPutBuff, pReadBuff, ReadBytes);
2181		if (Status) {
2182			BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
2183				"Copy to use failed with status :%d", Status);
2184			up(&Adapter->NVMRdmWrmLock);
2185			kfree(pReadBuff);
2186			return -EFAULT;
2187		}
2188		NOB = NOB - ReadBytes;
2189		if (NOB) {
2190			ReadOffset = ReadOffset + ReadBytes;
2191			OutPutBuff = OutPutBuff + ReadBytes;
2192		}
2193	}
2194	Adapter->bFlashRawRead = false;
2195	up(&Adapter->NVMRdmWrmLock);
2196	kfree(pReadBuff);
2197	return Status;
2198}
2199
2200static int bcm_char_ioctl_cntrlmsg_mask(void __user *argp,
2201	struct bcm_mini_adapter *Adapter, struct bcm_tarang_data *pTarang)
2202{
2203	struct bcm_ioctl_buffer IoBuffer;
2204	INT Status = STATUS_FAILURE;
2205	ULONG RxCntrlMsgBitMask = 0;
2206
2207	/* Copy Ioctl Buffer structure */
2208	Status = copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer));
2209	if (Status) {
2210		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2211			"copy of Ioctl buffer is failed from user space");
2212		return -EFAULT;
2213	}
2214
2215	if (IoBuffer.InputLength != sizeof(unsigned long))
2216		return -EINVAL;
2217
2218	Status = copy_from_user(&RxCntrlMsgBitMask,
2219		IoBuffer.InputBuffer, IoBuffer.InputLength);
2220	if (Status) {
2221		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2222			"copy of control bit mask failed from user space");
2223		return -EFAULT;
2224	}
2225	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2226		"\n Got user defined cntrl msg bit mask :%lx",
2227		RxCntrlMsgBitMask);
2228	pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask;
2229
2230	return Status;
2231}
2232
2233static int bcm_char_ioctl_get_device_driver_info(void __user *argp,
2234	struct bcm_mini_adapter *Adapter)
2235{
2236	struct bcm_driver_info DevInfo;
2237	struct bcm_ioctl_buffer IoBuffer;
2238
2239	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
2240		DBG_LVL_ALL, "Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
2241
2242	memset(&DevInfo, 0, sizeof(DevInfo));
2243	DevInfo.MaxRDMBufferSize = BUFFER_4K;
2244	DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
2245	DevInfo.u32RxAlignmentCorrection = 0;
2246	DevInfo.u32NVMType = Adapter->eNVMType;
2247	DevInfo.u32InterfaceType = BCM_USB;
2248
2249	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
2250		return -EFAULT;
2251
2252	if (IoBuffer.OutputLength < sizeof(DevInfo))
2253		return -EINVAL;
2254
2255	if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
2256		return -EFAULT;
2257
2258	return STATUS_SUCCESS;
2259}
2260
2261static int bcm_char_ioctl_time_since_net_entry(void __user *argp,
2262	struct bcm_mini_adapter *Adapter)
2263{
2264	struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
2265	struct bcm_ioctl_buffer IoBuffer;
2266
2267	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2268		"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
2269
2270	if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
2271		return -EFAULT;
2272
2273	if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
2274		return -EINVAL;
2275
2276	stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry =
2277		get_seconds() - Adapter->liTimeSinceLastNetEntry;
2278
2279	if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry,
2280		sizeof(struct bcm_time_elapsed)))
2281		return -EFAULT;
2282
2283	return STATUS_SUCCESS;
2284}
2285
2286
2287static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
2288{
2289	struct bcm_tarang_data *pTarang = filp->private_data;
2290	void __user *argp = (void __user *)arg;
2291	struct bcm_mini_adapter *Adapter = pTarang->Adapter;
2292	INT Status = STATUS_FAILURE;
2293
2294	BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2295			"Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX",
2296			cmd, arg);
2297
2298	if (_IOC_TYPE(cmd) != BCM_IOCTL)
2299		return -EFAULT;
2300	if (_IOC_DIR(cmd) & _IOC_READ)
2301		Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
2302	else if (_IOC_DIR(cmd) & _IOC_WRITE)
2303		Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
2304	else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
2305		Status = STATUS_SUCCESS;
2306
2307	if (Status)
2308		return -EFAULT;
2309
2310	if (Adapter->device_removed)
2311		return -EFAULT;
2312
2313	if (false == Adapter->fw_download_done) {
2314		switch (cmd) {
2315		case IOCTL_MAC_ADDR_REQ:
2316		case IOCTL_LINK_REQ:
2317		case IOCTL_CM_REQUEST:
2318		case IOCTL_SS_INFO_REQ:
2319		case IOCTL_SEND_CONTROL_MESSAGE:
2320		case IOCTL_IDLE_REQ:
2321		case IOCTL_BCM_GPIO_SET_REQUEST:
2322		case IOCTL_BCM_GPIO_STATUS_REQUEST:
2323			return -EACCES;
2324		default:
2325			break;
2326		}
2327	}
2328
2329	Status = vendorextnIoctl(Adapter, cmd, arg);
2330	if (Status != CONTINUE_COMMON_PATH)
2331		return Status;
2332
2333	switch (cmd) {
2334	/* Rdms for Swin Idle... */
2335	case IOCTL_BCM_REGISTER_READ_PRIVATE:
2336		Status = bcm_char_ioctl_reg_read_private(argp, Adapter);
2337		return Status;
2338
2339	case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
2340		Status = bcm_char_ioctl_reg_write_private(argp, Adapter);
2341		return Status;
2342
2343	case IOCTL_BCM_REGISTER_READ:
2344	case IOCTL_BCM_EEPROM_REGISTER_READ:
2345		Status = bcm_char_ioctl_eeprom_reg_read(argp, Adapter);
2346		return Status;
2347
2348	case IOCTL_BCM_REGISTER_WRITE:
2349	case IOCTL_BCM_EEPROM_REGISTER_WRITE:
2350		Status = bcm_char_ioctl_eeprom_reg_write(argp, Adapter, cmd);
2351		return Status;
2352
2353	case IOCTL_BCM_GPIO_SET_REQUEST:
2354		Status = bcm_char_ioctl_gpio_set_request(argp, Adapter);
2355		return Status;
2356
2357	case BCM_LED_THREAD_STATE_CHANGE_REQ:
2358		Status = bcm_char_ioctl_led_thread_state_change_req(argp, Adapter);
2359		return Status;
2360
2361	case IOCTL_BCM_GPIO_STATUS_REQUEST:
2362		Status = bcm_char_ioctl_gpio_status_request(argp, Adapter);
2363		return Status;
2364
2365	case IOCTL_BCM_GPIO_MULTI_REQUEST:
2366		Status = bcm_char_ioctl_gpio_multi_request(argp, Adapter);
2367		return Status;
2368
2369	case IOCTL_BCM_GPIO_MODE_REQUEST:
2370		Status = bcm_char_ioctl_gpio_mode_request(argp, Adapter);
2371		return Status;
2372
2373	case IOCTL_MAC_ADDR_REQ:
2374	case IOCTL_LINK_REQ:
2375	case IOCTL_CM_REQUEST:
2376	case IOCTL_SS_INFO_REQ:
2377	case IOCTL_SEND_CONTROL_MESSAGE:
2378	case IOCTL_IDLE_REQ:
2379		Status = bcm_char_ioctl_misc_request(argp, Adapter);
2380		return Status;
2381
2382	case IOCTL_BCM_BUFFER_DOWNLOAD_START:
2383		Status = bcm_char_ioctl_buffer_download_start(Adapter);
2384		return Status;
2385
2386	case IOCTL_BCM_BUFFER_DOWNLOAD:
2387		Status = bcm_char_ioctl_buffer_download(argp, Adapter);
2388		return Status;
2389
2390	case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
2391		Status = bcm_char_ioctl_buffer_download_stop(argp, Adapter);
2392		return Status;
2393
2394
2395	case IOCTL_BE_BUCKET_SIZE:
2396		Status = 0;
2397		if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
2398			Status = -EFAULT;
2399		break;
2400
2401	case IOCTL_RTPS_BUCKET_SIZE:
2402		Status = 0;
2403		if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg))
2404			Status = -EFAULT;
2405		break;
2406
2407	case IOCTL_CHIP_RESET:
2408		Status = bcm_char_ioctl_chip_reset(Adapter);
2409		return Status;
2410
2411	case IOCTL_QOS_THRESHOLD:
2412		Status = bcm_char_ioctl_qos_threshold(arg, Adapter);
2413		return Status;
2414
2415	case IOCTL_DUMP_PACKET_INFO:
2416		DumpPackInfo(Adapter);
2417		DumpPhsRules(&Adapter->stBCMPhsContext);
2418		Status = STATUS_SUCCESS;
2419		break;
2420
2421	case IOCTL_GET_PACK_INFO:
2422		if (copy_to_user(argp, &Adapter->PackInfo,
2423			sizeof(struct bcm_packet_info)*NO_OF_QUEUES))
2424			return -EFAULT;
2425		Status = STATUS_SUCCESS;
2426		break;
2427
2428	case IOCTL_BCM_SWITCH_TRANSFER_MODE:
2429		Status = bcm_char_ioctl_switch_transfer_mode(argp, Adapter);
2430		return Status;
2431
2432	case IOCTL_BCM_GET_DRIVER_VERSION:
2433		Status = bcm_char_ioctl_get_driver_version(argp);
2434		return Status;
2435
2436	case IOCTL_BCM_GET_CURRENT_STATUS:
2437		Status = bcm_char_ioctl_get_current_status(argp, Adapter);
2438		return Status;
2439
2440	case IOCTL_BCM_SET_MAC_TRACING:
2441		Status = bcm_char_ioctl_set_mac_tracing(argp, Adapter);
2442		return Status;
2443
2444	case IOCTL_BCM_GET_DSX_INDICATION:
2445		Status = bcm_char_ioctl_get_dsx_indication(argp, Adapter);
2446		return Status;
2447
2448	case IOCTL_BCM_GET_HOST_MIBS:
2449		Status = bcm_char_ioctl_get_host_mibs(argp, Adapter, pTarang);
2450		return Status;
2451
2452	case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
2453		if ((false == Adapter->bTriedToWakeUpFromlowPowerMode) &&
2454			(TRUE == Adapter->IdleMode)) {
2455			Adapter->usIdleModePattern = ABORT_IDLE_MODE;
2456			Adapter->bWakeUpDevice = TRUE;
2457			wake_up(&Adapter->process_rx_cntrlpkt);
2458		}
2459
2460		Status = STATUS_SUCCESS;
2461		break;
2462
2463	case IOCTL_BCM_BULK_WRM:
2464		Status = bcm_char_ioctl_bulk_wrm(argp, Adapter, cmd);
2465		return Status;
2466
2467	case IOCTL_BCM_GET_NVM_SIZE:
2468		Status = bcm_char_ioctl_get_nvm_size(argp, Adapter);
2469		return Status;
2470
2471	case IOCTL_BCM_CAL_INIT:
2472		Status = bcm_char_ioctl_cal_init(argp, Adapter);
2473		return Status;
2474
2475	case IOCTL_BCM_SET_DEBUG:
2476		Status = bcm_char_ioctl_set_debug(argp, Adapter);
2477		return Status;
2478
2479	case IOCTL_BCM_NVM_READ:
2480	case IOCTL_BCM_NVM_WRITE:
2481		Status = bcm_char_ioctl_nvm_rw(argp, Adapter, cmd);
2482		return Status;
2483
2484	case IOCTL_BCM_FLASH2X_SECTION_READ:
2485		Status = bcm_char_ioctl_flash2x_section_read(argp, Adapter);
2486		return Status;
2487
2488	case IOCTL_BCM_FLASH2X_SECTION_WRITE:
2489		Status = bcm_char_ioctl_flash2x_section_write(argp, Adapter);
2490		return Status;
2491
2492	case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP:
2493		Status = bcm_char_ioctl_flash2x_section_bitmap(argp, Adapter);
2494		return Status;
2495
2496	case IOCTL_BCM_SET_ACTIVE_SECTION:
2497		Status = bcm_char_ioctl_set_active_section(argp, Adapter);
2498		return Status;
2499
2500	case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION:
2501		/* Right Now we are taking care of only DSD */
2502		Adapter->bAllDSDWriteAllow = false;
2503		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
2504			"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
2505		Status = STATUS_SUCCESS;
2506		break;
2507
2508	case IOCTL_BCM_COPY_SECTION:
2509		Status = bcm_char_ioctl_copy_section(argp, Adapter);
2510		return Status;
2511
2512	case IOCTL_BCM_GET_FLASH_CS_INFO:
2513		Status = bcm_char_ioctl_get_flash_cs_info(argp, Adapter);
2514		return Status;
2515
2516	case IOCTL_BCM_SELECT_DSD:
2517		Status = bcm_char_ioctl_select_dsd(argp, Adapter);
2518		return Status;
2519
2520	case IOCTL_BCM_NVM_RAW_READ:
2521		Status = bcm_char_ioctl_nvm_raw_read(argp, Adapter);
2522		return Status;
2523
2524	case IOCTL_BCM_CNTRLMSG_MASK:
2525		Status = bcm_char_ioctl_cntrlmsg_mask(argp, Adapter, pTarang);
2526		return Status;
2527
2528	case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
2529		Status = bcm_char_ioctl_get_device_driver_info(argp, Adapter);
2530		return Status;
2531
2532	case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
2533		Status = bcm_char_ioctl_time_since_net_entry(argp, Adapter);
2534		return Status;
2535
2536	case IOCTL_CLOSE_NOTIFICATION:
2537		BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG,
2538			DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION");
2539		break;
2540
2541	default:
2542		pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
2543		Status = STATUS_FAILURE;
2544		break;
2545	}
2546	return Status;
2547}
2548
2549
2550static const struct file_operations bcm_fops = {
2551	.owner    = THIS_MODULE,
2552	.open     = bcm_char_open,
2553	.release  = bcm_char_release,
2554	.read     = bcm_char_read,
2555	.unlocked_ioctl    = bcm_char_ioctl,
2556	.llseek = no_llseek,
2557};
2558
2559int register_control_device_interface(struct bcm_mini_adapter *Adapter)
2560{
2561
2562	if (Adapter->major > 0)
2563		return Adapter->major;
2564
2565	Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops);
2566	if (Adapter->major < 0) {
2567		pr_err(DRV_NAME ": could not created character device\n");
2568		return Adapter->major;
2569	}
2570
2571	Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL,
2572						MKDEV(Adapter->major, 0),
2573						Adapter, DEV_NAME);
2574
2575	if (IS_ERR(Adapter->pstCreatedClassDevice)) {
2576		pr_err(DRV_NAME ": class device create failed\n");
2577		unregister_chrdev(Adapter->major, DEV_NAME);
2578		return PTR_ERR(Adapter->pstCreatedClassDevice);
2579	}
2580
2581	return 0;
2582}
2583
2584void unregister_control_device_interface(struct bcm_mini_adapter *Adapter)
2585{
2586	if (Adapter->major > 0) {
2587		device_destroy(bcm_class, MKDEV(Adapter->major, 0));
2588		unregister_chrdev(Adapter->major, DEV_NAME);
2589	}
2590}
2591