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