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