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