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