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