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