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