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