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