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