]> Pileus Git - ~andy/linux/blob - drivers/staging/bcm/Bcmchar.c
Merge branches 'powercap' and 'acpi-lpss' with new device IDs
[~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         struct bcm_mini_adapter *Adapter = NULL;
19         struct bcm_tarang_data *pTarang = NULL;
20
21         Adapter = GET_BCM_ADAPTER(gblpnetdev);
22         pTarang = kzalloc(sizeof(struct bcm_tarang_data), GFP_KERNEL);
23         if (!pTarang)
24                 return -ENOMEM;
25
26         pTarang->Adapter = Adapter;
27         pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);
28
29         down(&Adapter->RxAppControlQueuelock);
30         pTarang->next = Adapter->pTarangs;
31         Adapter->pTarangs = pTarang;
32         up(&Adapter->RxAppControlQueuelock);
33
34         /* Store the Adapter structure */
35         filp->private_data = pTarang;
36
37         /* Start Queuing the control response Packets */
38         atomic_inc(&Adapter->ApplicationRunning);
39
40         nonseekable_open(inode, filp);
41         return 0;
42 }
43
44 static int bcm_char_release(struct inode *inode, struct file *filp)
45 {
46         struct bcm_tarang_data *pTarang, *tmp, *ptmp;
47         struct bcm_mini_adapter *Adapter = NULL;
48         struct sk_buff *pkt, *npkt;
49
50         pTarang = (struct bcm_tarang_data *)filp->private_data;
51
52         if (pTarang == NULL)
53                 return 0;
54
55         Adapter = pTarang->Adapter;
56
57         down(&Adapter->RxAppControlQueuelock);
58
59         tmp = Adapter->pTarangs;
60         for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) {
61                 if (tmp == pTarang)
62                         break;
63         }
64
65         if (tmp) {
66                 if (!ptmp)
67                         Adapter->pTarangs = tmp->next;
68                 else
69                         ptmp->next = tmp->next;
70         } else {
71                 up(&Adapter->RxAppControlQueuelock);
72                 return 0;
73         }
74
75         pkt = pTarang->RxAppControlHead;
76         while (pkt) {
77                 npkt = pkt->next;
78                 kfree_skb(pkt);
79                 pkt = npkt;
80         }
81
82         up(&Adapter->RxAppControlQueuelock);
83
84         /* Stop Queuing the control response Packets */
85         atomic_dec(&Adapter->ApplicationRunning);
86
87         kfree(pTarang);
88
89         /* remove this filp from the asynchronously notified filp's */
90         filp->private_data = NULL;
91         return 0;
92 }
93
94 static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size,
95                              loff_t *f_pos)
96 {
97         struct bcm_tarang_data *pTarang = filp->private_data;
98         struct bcm_mini_adapter *Adapter = pTarang->Adapter;
99         struct sk_buff *Packet = NULL;
100         ssize_t PktLen = 0;
101         int wait_ret_val = 0;
102         unsigned long ret = 0;
103
104         wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
105                                                 (pTarang->RxAppControlHead ||
106                                                  Adapter->device_removed));
107         if ((wait_ret_val == -ERESTARTSYS)) {
108                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
109                                 "Exiting as i've been asked to exit!!!\n");
110                 return wait_ret_val;
111         }
112
113         if (Adapter->device_removed) {
114                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
115                                 "Device Removed... Killing the Apps...\n");
116                 return -ENODEV;
117         }
118
119         if (false == Adapter->fw_download_done)
120                 return -EACCES;
121
122         down(&Adapter->RxAppControlQueuelock);
123
124         if (pTarang->RxAppControlHead) {
125                 Packet = pTarang->RxAppControlHead;
126                 DEQUEUEPACKET(pTarang->RxAppControlHead,
127                               pTarang->RxAppControlTail);
128                 pTarang->AppCtrlQueueLen--;
129         }
130
131         up(&Adapter->RxAppControlQueuelock);
132
133         if (Packet) {
134                 PktLen = Packet->len;
135                 ret = copy_to_user(buf, Packet->data,
136                                    min_t(size_t, PktLen, size));
137                 if (ret) {
138                         dev_kfree_skb(Packet);
139                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
140                                         "Returning from copy to user failure\n");
141                         return -EFAULT;
142                 }
143                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
144                                 "Read %zd Bytes From Adapter packet = %p by process %d!\n",
145                                 PktLen, Packet, current->pid);
146                 dev_kfree_skb(Packet);
147         }
148
149         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n");
150         return PktLen;
151 }
152
153 static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
154 {
155         struct bcm_tarang_data *pTarang = filp->private_data;
156         void __user *argp = (void __user *)arg;
157         struct bcm_mini_adapter *Adapter = pTarang->Adapter;
158         INT Status = STATUS_FAILURE;
159         int timeout = 0;
160         struct bcm_ioctl_buffer IoBuffer;
161         int bytes;
162
163         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);
164
165         if (_IOC_TYPE(cmd) != BCM_IOCTL)
166                 return -EFAULT;
167         if (_IOC_DIR(cmd) & _IOC_READ)
168                 Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
169         else if (_IOC_DIR(cmd) & _IOC_WRITE)
170                 Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
171         else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
172                 Status = STATUS_SUCCESS;
173
174         if (Status)
175                 return -EFAULT;
176
177         if (Adapter->device_removed)
178                 return -EFAULT;
179
180         if (false == Adapter->fw_download_done) {
181                 switch (cmd) {
182                 case IOCTL_MAC_ADDR_REQ:
183                 case IOCTL_LINK_REQ:
184                 case IOCTL_CM_REQUEST:
185                 case IOCTL_SS_INFO_REQ:
186                 case IOCTL_SEND_CONTROL_MESSAGE:
187                 case IOCTL_IDLE_REQ:
188                 case IOCTL_BCM_GPIO_SET_REQUEST:
189                 case IOCTL_BCM_GPIO_STATUS_REQUEST:
190                         return -EACCES;
191                 default:
192                         break;
193                 }
194         }
195
196         Status = vendorextnIoctl(Adapter, cmd, arg);
197         if (Status != CONTINUE_COMMON_PATH)
198                 return Status;
199
200         switch (cmd) {
201         /* Rdms for Swin Idle... */
202         case IOCTL_BCM_REGISTER_READ_PRIVATE: {
203                 struct bcm_rdm_buffer sRdmBuffer = {0};
204                 PCHAR temp_buff;
205                 UINT Bufflen;
206                 u16 temp_value;
207
208                 /* Copy Ioctl Buffer structure */
209                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
210                         return -EFAULT;
211
212                 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
213                         return -EINVAL;
214
215                 if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
216                         return -EFAULT;
217
218                 if (IoBuffer.OutputLength > USHRT_MAX ||
219                         IoBuffer.OutputLength == 0) {
220                         return -EINVAL;
221                 }
222
223                 Bufflen = IoBuffer.OutputLength;
224                 temp_value = 4 - (Bufflen % 4);
225                 Bufflen += temp_value % 4;
226
227                 temp_buff = kmalloc(Bufflen, GFP_KERNEL);
228                 if (!temp_buff)
229                         return -ENOMEM;
230
231                 bytes = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
232                                 (PUINT)temp_buff, Bufflen);
233                 if (bytes > 0) {
234                         Status = STATUS_SUCCESS;
235                         if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
236                                 kfree(temp_buff);
237                                 return -EFAULT;
238                         }
239                 } else {
240                         Status = bytes;
241                 }
242
243                 kfree(temp_buff);
244                 break;
245         }
246
247         case IOCTL_BCM_REGISTER_WRITE_PRIVATE: {
248                 struct bcm_wrm_buffer sWrmBuffer = {0};
249                 UINT uiTempVar = 0;
250                 /* Copy Ioctl Buffer structure */
251
252                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
253                         return -EFAULT;
254
255                 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
256                         return -EINVAL;
257
258                 /* Get WrmBuffer structure */
259                 if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
260                         return -EFAULT;
261
262                 uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
263                 if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
264                         ((uiTempVar == EEPROM_REJECT_REG_1) ||
265                                 (uiTempVar == EEPROM_REJECT_REG_2) ||
266                                 (uiTempVar == EEPROM_REJECT_REG_3) ||
267                                 (uiTempVar == EEPROM_REJECT_REG_4))) {
268
269                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
270                         return -EFAULT;
271                 }
272
273                 Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
274                                 (PUINT)sWrmBuffer.Data, sizeof(ULONG));
275
276                 if (Status == STATUS_SUCCESS) {
277                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
278                 } else {
279                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
280                         Status = -EFAULT;
281                 }
282                 break;
283         }
284
285         case IOCTL_BCM_REGISTER_READ:
286         case IOCTL_BCM_EEPROM_REGISTER_READ: {
287                 struct bcm_rdm_buffer sRdmBuffer = {0};
288                 PCHAR temp_buff = NULL;
289                 UINT uiTempVar = 0;
290                 if ((Adapter->IdleMode == TRUE) ||
291                         (Adapter->bShutStatus == TRUE) ||
292                         (Adapter->bPreparingForLowPowerMode == TRUE)) {
293
294                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
295                         return -EACCES;
296                 }
297
298                 /* Copy Ioctl Buffer structure */
299                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
300                         return -EFAULT;
301
302                 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
303                         return -EINVAL;
304
305                 if (copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
306                         return -EFAULT;
307
308                 if (IoBuffer.OutputLength > USHRT_MAX ||
309                         IoBuffer.OutputLength == 0) {
310                         return -EINVAL;
311                 }
312
313                 temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
314                 if (!temp_buff)
315                         return STATUS_FAILURE;
316
317                 if ((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
318                         ((ULONG)sRdmBuffer.Register & 0x3)) {
319
320                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n",
321                                         (int)sRdmBuffer.Register);
322
323                         kfree(temp_buff);
324                         return -EINVAL;
325                 }
326
327                 uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
328                 bytes = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register, (PUINT)temp_buff, IoBuffer.OutputLength);
329
330                 if (bytes > 0) {
331                         Status = STATUS_SUCCESS;
332                         if (copy_to_user(IoBuffer.OutputBuffer, temp_buff, bytes)) {
333                                 kfree(temp_buff);
334                                 return -EFAULT;
335                         }
336                 } else {
337                         Status = bytes;
338                 }
339
340                 kfree(temp_buff);
341                 break;
342         }
343         case IOCTL_BCM_REGISTER_WRITE:
344         case IOCTL_BCM_EEPROM_REGISTER_WRITE: {
345                 struct bcm_wrm_buffer sWrmBuffer = {0};
346                 UINT uiTempVar = 0;
347
348                 if ((Adapter->IdleMode == TRUE) ||
349                         (Adapter->bShutStatus == TRUE) ||
350                         (Adapter->bPreparingForLowPowerMode == TRUE)) {
351
352                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
353                         return -EACCES;
354                 }
355
356                 /* Copy Ioctl Buffer structure */
357                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
358                         return -EFAULT;
359
360                 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
361                         return -EINVAL;
362
363                 /* Get WrmBuffer structure */
364                 if (copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
365                         return -EFAULT;
366
367                 if ((((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
368                         ((ULONG)sWrmBuffer.Register & 0x3)) {
369
370                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)sWrmBuffer.Register);
371                         return -EINVAL;
372                 }
373
374                 uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
375                 if (!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
376                                 ((uiTempVar == EEPROM_REJECT_REG_1) ||
377                                 (uiTempVar == EEPROM_REJECT_REG_2) ||
378                                 (uiTempVar == EEPROM_REJECT_REG_3) ||
379                                 (uiTempVar == EEPROM_REJECT_REG_4)) &&
380                                 (cmd == IOCTL_BCM_REGISTER_WRITE)) {
381
382                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
383                                 return -EFAULT;
384                 }
385
386                 Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
387                                         (PUINT)sWrmBuffer.Data, sWrmBuffer.Length);
388
389                 if (Status == STATUS_SUCCESS) {
390                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
391                 } else {
392                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
393                         Status = -EFAULT;
394                 }
395                 break;
396         }
397         case IOCTL_BCM_GPIO_SET_REQUEST: {
398                 UCHAR ucResetValue[4];
399                 UINT value = 0;
400                 UINT uiBit = 0;
401                 UINT uiOperation = 0;
402                 struct bcm_gpio_info gpio_info = {0};
403
404                 if ((Adapter->IdleMode == TRUE) ||
405                         (Adapter->bShutStatus == TRUE) ||
406                         (Adapter->bPreparingForLowPowerMode == TRUE)) {
407
408                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode");
409                         return -EACCES;
410                 }
411
412                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
413                         return -EFAULT;
414
415                 if (IoBuffer.InputLength > sizeof(gpio_info))
416                         return -EINVAL;
417
418                 if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
419                         return -EFAULT;
420
421                 uiBit  = gpio_info.uiGpioNumber;
422                 uiOperation = gpio_info.uiGpioValue;
423                 value = (1<<uiBit);
424
425                 if (IsReqGpioIsLedInNVM(Adapter, value) == false) {
426                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!", value);
427                         Status = -EINVAL;
428                         break;
429                 }
430
431                 /* Set - setting 1 */
432                 if (uiOperation) {
433                         /* Set the gpio output register */
434                         Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG, (PUINT)(&value), sizeof(UINT));
435
436                         if (Status == STATUS_SUCCESS) {
437                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
438                         } else {
439                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to set the %dth GPIO\n", uiBit);
440                                 break;
441                         }
442                 } else {
443                         /* Set the gpio output register */
444                         Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)(&value), sizeof(UINT));
445
446                         if (Status == STATUS_SUCCESS) {
447                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
448                         } else {
449                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to clear the %dth GPIO\n", uiBit);
450                                 break;
451                         }
452                 }
453
454                 bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
455                 if (bytes < 0) {
456                         Status = bytes;
457                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
458                                         "GPIO_MODE_REGISTER read failed");
459                         break;
460                 } else {
461                         Status = STATUS_SUCCESS;
462                 }
463
464                 /* Set the gpio mode register to output */
465                 *(UINT *)ucResetValue |= (1<<uiBit);
466                 Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER,
467                                         (PUINT)ucResetValue, sizeof(UINT));
468
469                 if (Status == STATUS_SUCCESS) {
470                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO to output Mode\n");
471                 } else {
472                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n");
473                         break;
474                 }
475         }
476         break;
477
478         case BCM_LED_THREAD_STATE_CHANGE_REQ: {
479                 struct bcm_user_thread_req threadReq = {0};
480                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "User made LED thread InActive");
481
482                 if ((Adapter->IdleMode == TRUE) ||
483                         (Adapter->bShutStatus == TRUE) ||
484                         (Adapter->bPreparingForLowPowerMode == TRUE)) {
485
486                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "GPIO Can't be set/clear in Low power Mode");
487                         Status = -EACCES;
488                         break;
489                 }
490
491                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
492                         return -EFAULT;
493
494                 if (IoBuffer.InputLength > sizeof(threadReq))
495                         return -EINVAL;
496
497                 if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
498                         return -EFAULT;
499
500                 /* if LED thread is running(Actively or Inactively) set it state to make inactive */
501                 if (Adapter->LEDInfo.led_thread_running) {
502                         if (threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ) {
503                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Activating thread req");
504                                 Adapter->DriverState = LED_THREAD_ACTIVE;
505                         } else {
506                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "DeActivating Thread req.....");
507                                 Adapter->DriverState = LED_THREAD_INACTIVE;
508                         }
509
510                         /* signal thread. */
511                         wake_up(&Adapter->LEDInfo.notify_led_event);
512                 }
513         }
514         break;
515
516         case IOCTL_BCM_GPIO_STATUS_REQUEST: {
517                 ULONG uiBit = 0;
518                 UCHAR ucRead[4];
519                 struct bcm_gpio_info gpio_info = {0};
520
521                 if ((Adapter->IdleMode == TRUE) ||
522                         (Adapter->bShutStatus == TRUE) ||
523                         (Adapter->bPreparingForLowPowerMode == TRUE))
524                         return -EACCES;
525
526                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
527                         return -EFAULT;
528
529                 if (IoBuffer.InputLength > sizeof(gpio_info))
530                         return -EINVAL;
531
532                 if (copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
533                         return -EFAULT;
534
535                 uiBit = gpio_info.uiGpioNumber;
536
537                 /* Set the gpio output register */
538                 bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
539                                         (PUINT)ucRead, sizeof(UINT));
540
541                 if (bytes < 0) {
542                         Status = bytes;
543                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
544                         return Status;
545                 } else {
546                         Status = STATUS_SUCCESS;
547                 }
548         }
549         break;
550
551         case IOCTL_BCM_GPIO_MULTI_REQUEST: {
552                 UCHAR ucResetValue[4];
553                 struct bcm_gpio_multi_info gpio_multi_info[MAX_IDX];
554                 struct bcm_gpio_multi_info *pgpio_multi_info = (struct bcm_gpio_multi_info *)gpio_multi_info;
555
556                 memset(pgpio_multi_info, 0, MAX_IDX * sizeof(struct bcm_gpio_multi_info));
557
558                 if ((Adapter->IdleMode == TRUE) ||
559                         (Adapter->bShutStatus == TRUE) ||
560                         (Adapter->bPreparingForLowPowerMode == TRUE))
561                         return -EINVAL;
562
563                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
564                         return -EFAULT;
565
566                 if (IoBuffer.InputLength > sizeof(gpio_multi_info))
567                         return -EINVAL;
568
569                 if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
570                         return -EFAULT;
571
572                 if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_info[WIMAX_IDX].uiGPIOMask) == false) {
573                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
574                                         "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
575                                         pgpio_multi_info[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap);
576                         Status = -EINVAL;
577                         break;
578                 }
579
580                 /* Set the gpio output register */
581                 if ((pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
582                         (pgpio_multi_info[WIMAX_IDX].uiGPIOCommand)) {
583                         /* Set 1's in GPIO OUTPUT REGISTER */
584                         *(UINT *)ucResetValue =  pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
585                                 pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
586                                 pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
587
588                         if (*(UINT *) ucResetValue)
589                                 Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_SET_REG,
590                                                         (PUINT)ucResetValue, sizeof(ULONG));
591
592                         if (Status != STATUS_SUCCESS) {
593                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
594                                 return Status;
595                         }
596
597                         /* Clear to 0's in GPIO OUTPUT REGISTER */
598                         *(UINT *)ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
599                                                 pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
600                                                 (~(pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
601
602                         if (*(UINT *) ucResetValue)
603                                 Status = wrmaltWithLock(Adapter, BCM_GPIO_OUTPUT_CLR_REG, (PUINT)ucResetValue, sizeof(ULONG));
604
605                         if (Status != STATUS_SUCCESS) {
606                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM to BCM_GPIO_OUTPUT_CLR_REG Failed.");
607                                 return Status;
608                         }
609                 }
610
611                 if (pgpio_multi_info[WIMAX_IDX].uiGPIOMask) {
612                         bytes = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
613
614                         if (bytes < 0) {
615                                 Status = bytes;
616                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "RDM to GPIO_PIN_STATE_REGISTER Failed.");
617                                 return Status;
618                         } else {
619                                 Status = STATUS_SUCCESS;
620                         }
621
622                         pgpio_multi_info[WIMAX_IDX].uiGPIOValue = (*(UINT *)ucResetValue &
623                                                                 pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
624                 }
625
626                 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength);
627                 if (Status) {
628                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
629                                         "Failed while copying Content to IOBufer for user space err:%d", Status);
630                         return -EFAULT;
631                 }
632         }
633         break;
634
635         case IOCTL_BCM_GPIO_MODE_REQUEST: {
636                 UCHAR ucResetValue[4];
637                 struct bcm_gpio_multi_mode gpio_multi_mode[MAX_IDX];
638                 struct bcm_gpio_multi_mode *pgpio_multi_mode = (struct bcm_gpio_multi_mode *)gpio_multi_mode;
639
640                 if ((Adapter->IdleMode == TRUE) ||
641                         (Adapter->bShutStatus == TRUE) ||
642                         (Adapter->bPreparingForLowPowerMode == TRUE))
643                         return -EINVAL;
644
645                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
646                         return -EFAULT;
647
648                 if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
649                         return -EINVAL;
650
651                 if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength))
652                         return -EFAULT;
653
654                 bytes = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
655
656                 if (bytes < 0) {
657                         Status = bytes;
658                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Read of GPIO_MODE_REGISTER failed");
659                         return Status;
660                 } else {
661                         Status = STATUS_SUCCESS;
662                 }
663
664                 /* Validating the request */
665                 if (IsReqGpioIsLedInNVM(Adapter, pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) == false) {
666                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
667                                         "Sorry, Requested GPIO<0x%X> is not correspond to NVM LED bit map<0x%X>!!!",
668                                         pgpio_multi_mode[WIMAX_IDX].uiGPIOMask, Adapter->gpioBitMap);
669                         Status = -EINVAL;
670                         break;
671                 }
672
673                 if (pgpio_multi_mode[WIMAX_IDX].uiGPIOMask) {
674                         /* write all OUT's (1's) */
675                         *(UINT *) ucResetValue |= (pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
676                                                 pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
677
678                         /* write all IN's (0's) */
679                         *(UINT *) ucResetValue &= ~((~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
680                                                 pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
681
682                         /* Currently implemented return the modes of all GPIO's
683                          * else needs to bit AND with  mask
684                          */
685                         pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
686
687                         Status = wrmaltWithLock(Adapter, GPIO_MODE_REGISTER, (PUINT)ucResetValue, sizeof(ULONG));
688                         if (Status == STATUS_SUCCESS) {
689                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
690                                                 "WRM to GPIO_MODE_REGISTER Done");
691                         } else {
692                                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
693                                                 "WRM to GPIO_MODE_REGISTER Failed");
694                                 Status = -EFAULT;
695                                 break;
696                         }
697                 } else {
698 /* if uiGPIOMask is 0 then return mode register configuration */
699                         pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT *)ucResetValue;
700                 }
701
702                 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength);
703                 if (Status) {
704                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
705                                         "Failed while copying Content to IOBufer for user space err:%d", Status);
706                         return -EFAULT;
707                 }
708         }
709         break;
710
711         case IOCTL_MAC_ADDR_REQ:
712         case IOCTL_LINK_REQ:
713         case IOCTL_CM_REQUEST:
714         case IOCTL_SS_INFO_REQ:
715         case IOCTL_SEND_CONTROL_MESSAGE:
716         case IOCTL_IDLE_REQ: {
717                 PVOID pvBuffer = NULL;
718
719                 /* Copy Ioctl Buffer structure */
720                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
721                         return -EFAULT;
722
723                 if (IoBuffer.InputLength < sizeof(struct bcm_link_request))
724                         return -EINVAL;
725
726                 if (IoBuffer.InputLength > MAX_CNTL_PKT_SIZE)
727                         return -EINVAL;
728
729                 pvBuffer = memdup_user(IoBuffer.InputBuffer,
730                                        IoBuffer.InputLength);
731                 if (IS_ERR(pvBuffer))
732                         return PTR_ERR(pvBuffer);
733
734                 down(&Adapter->LowPowerModeSync);
735                 Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
736                                                         !Adapter->bPreparingForLowPowerMode,
737                                                         (1 * HZ));
738                 if (Status == -ERESTARTSYS)
739                         goto cntrlEnd;
740
741                 if (Adapter->bPreparingForLowPowerMode) {
742                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
743                                         "Preparing Idle Mode is still True - Hence Rejecting control message\n");
744                         Status = STATUS_FAILURE;
745                         goto cntrlEnd;
746                 }
747                 Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
748
749 cntrlEnd:
750                 up(&Adapter->LowPowerModeSync);
751                 kfree(pvBuffer);
752                 break;
753         }
754
755         case IOCTL_BCM_BUFFER_DOWNLOAD_START: {
756                 if (down_trylock(&Adapter->NVMRdmWrmLock)) {
757                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
758                                         "IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
759                         return -EACCES;
760                 }
761
762                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
763                                 "Starting the firmware download PID =0x%x!!!!\n", current->pid);
764
765                 if (down_trylock(&Adapter->fw_download_sema))
766                         return -EBUSY;
767
768                 Adapter->bBinDownloaded = false;
769                 Adapter->fw_download_process_pid = current->pid;
770                 Adapter->bCfgDownloaded = false;
771                 Adapter->fw_download_done = false;
772                 netif_carrier_off(Adapter->dev);
773                 netif_stop_queue(Adapter->dev);
774                 Status = reset_card_proc(Adapter);
775                 if (Status) {
776                         pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
777                         up(&Adapter->fw_download_sema);
778                         up(&Adapter->NVMRdmWrmLock);
779                         return Status;
780                 }
781                 mdelay(10);
782
783                 up(&Adapter->NVMRdmWrmLock);
784                 return Status;
785         }
786
787         case IOCTL_BCM_BUFFER_DOWNLOAD: {
788                 struct bcm_firmware_info *psFwInfo = NULL;
789                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
790
791                 if (!down_trylock(&Adapter->fw_download_sema)) {
792                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
793                                         "Invalid way to download buffer. Use Start and then call this!!!\n");
794                         up(&Adapter->fw_download_sema);
795                         Status = -EINVAL;
796                         return Status;
797                 }
798
799                 /* Copy Ioctl Buffer structure */
800                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer))) {
801                         up(&Adapter->fw_download_sema);
802                         return -EFAULT;
803                 }
804
805                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
806                                 "Length for FW DLD is : %lx\n", IoBuffer.InputLength);
807
808                 if (IoBuffer.InputLength > sizeof(struct bcm_firmware_info)) {
809                         up(&Adapter->fw_download_sema);
810                         return -EINVAL;
811                 }
812
813                 psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
814                 if (!psFwInfo) {
815                         up(&Adapter->fw_download_sema);
816                         return -ENOMEM;
817                 }
818
819                 if (copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength)) {
820                         up(&Adapter->fw_download_sema);
821                         kfree(psFwInfo);
822                         return -EFAULT;
823                 }
824
825                 if (!psFwInfo->pvMappedFirmwareAddress ||
826                         (psFwInfo->u32FirmwareLength == 0)) {
827
828                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
829                                         psFwInfo->u32FirmwareLength);
830                         up(&Adapter->fw_download_sema);
831                         kfree(psFwInfo);
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((struct bcm_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(struct bcm_packet_info)*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(struct bcm_ioctl_buffer)))
1002                         return -EFAULT;
1003
1004                 len = min_t(ulong, IoBuffer.OutputLength, strlen(DRV_VERSION) + 1);
1005
1006                 if (copy_to_user(IoBuffer.OutputBuffer, DRV_VERSION, len))
1007                         return -EFAULT;
1008                 Status = STATUS_SUCCESS;
1009                 break;
1010         }
1011
1012         case IOCTL_BCM_GET_CURRENT_STATUS: {
1013                 struct bcm_link_state link_state;
1014
1015                 /* Copy Ioctl Buffer structure */
1016                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_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(struct bcm_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(struct bcm_ioctl_buffer)))
1059                         return -EFAULT;
1060
1061                 if (IoBuffer.OutputLength < sizeof(struct bcm_add_indication_alt)) {
1062                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1063                                         "Mismatch req: %lx needed is =0x%zx!!!",
1064                                         IoBuffer.OutputLength, sizeof(struct bcm_add_indication_alt));
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(struct bcm_ioctl_buffer)))
1081                         return -EFAULT;
1082
1083                 if (IoBuffer.OutputLength != sizeof(struct bcm_host_stats_mibs)) {
1084                         BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
1085                                         "Length Check failed %lu %zd\n",
1086                                         IoBuffer.OutputLength, sizeof(struct bcm_host_stats_mibs));
1087                         return -EINVAL;
1088                 }
1089
1090                 /* FIXME: HOST_STATS are too big for kmalloc (122048)! */
1091                 temp_buff = kzalloc(sizeof(struct bcm_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(struct bcm_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                 struct bcm_bulk_wrm_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(struct bcm_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 = (struct bcm_bulk_wrm_buffer *)pvBuffer;
1145
1146                 if (((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
1147                         ((ULONG)pBulkBuffer->Register & 0x3)) {
1148                         BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n", (int)pBulkBuffer->Register);
1149                         kfree(pvBuffer);
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(struct bcm_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(struct bcm_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                 struct bcm_user_debug_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(struct bcm_ioctl_buffer)))
1233                         return -EFAULT;
1234
1235                 if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(struct bcm_user_debug_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                 struct bcm_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(struct bcm_ioctl_buffer)))
1286                         return -EFAULT;
1287
1288                 if (copy_from_user(&stNVMReadWrite,
1289                                         (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
1290                                         sizeof(struct bcm_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                 struct bcm_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(struct bcm_ioctl_buffer)))
1420                         return -EFAULT;
1421
1422                 /* Reading FLASH 2.x READ structure */
1423                 if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer, sizeof(struct bcm_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                 struct bcm_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(struct bcm_ioctl_buffer)))
1515                         return -EFAULT;
1516
1517                 /* Reading FLASH 2.x READ structure */
1518                 if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(struct bcm_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                 struct bcm_flash2x_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(struct bcm_ioctl_buffer)))
1609                         return -EFAULT;
1610
1611                 if (IoBuffer.OutputLength != sizeof(struct bcm_flash2x_bitmap))
1612                         return -EINVAL;
1613
1614                 psFlash2xBitMap = kzalloc(sizeof(struct bcm_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(struct bcm_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                 enum bcm_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(struct bcm_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                 struct bcm_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(struct bcm_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(struct bcm_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(struct bcm_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(struct bcm_flash2x_cs_info))
1784                                 return -EINVAL;
1785
1786                         if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(struct bcm_flash2x_cs_info)))
1787                                 return -EFAULT;
1788                 } else {
1789                         if (IoBuffer.OutputLength < sizeof(struct bcm_flash_cs_info))
1790                                 return -EINVAL;
1791
1792                         if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(struct bcm_flash_cs_info)))
1793                                 return -EFAULT;
1794                 }
1795         }
1796         break;
1797
1798         case IOCTL_BCM_SELECT_DSD: {
1799                 UINT SectOfset = 0;
1800                 enum bcm_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(struct bcm_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                 struct bcm_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(struct bcm_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(struct bcm_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(struct bcm_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                 struct bcm_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                 memset(&DevInfo, 0, sizeof(DevInfo));
1961                 DevInfo.MaxRDMBufferSize = BUFFER_4K;
1962                 DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
1963                 DevInfo.u32RxAlignmentCorrection = 0;
1964                 DevInfo.u32NVMType = Adapter->eNVMType;
1965                 DevInfo.u32InterfaceType = BCM_USB;
1966
1967                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1968                         return -EFAULT;
1969
1970                 if (IoBuffer.OutputLength < sizeof(DevInfo))
1971                         return -EINVAL;
1972
1973                 if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
1974                         return -EFAULT;
1975         }
1976         break;
1977
1978         case IOCTL_BCM_TIME_SINCE_NET_ENTRY: {
1979                 struct bcm_time_elapsed stTimeElapsedSinceNetEntry = {0};
1980
1981                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
1982
1983                 if (copy_from_user(&IoBuffer, argp, sizeof(struct bcm_ioctl_buffer)))
1984                         return -EFAULT;
1985
1986                 if (IoBuffer.OutputLength < sizeof(struct bcm_time_elapsed))
1987                         return -EINVAL;
1988
1989                 stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
1990
1991                 if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(struct bcm_time_elapsed)))
1992                         return -EFAULT;
1993         }
1994         break;
1995
1996         case IOCTL_CLOSE_NOTIFICATION:
1997                 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_CLOSE_NOTIFICATION");
1998                 break;
1999
2000         default:
2001                 pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
2002                 Status = STATUS_FAILURE;
2003                 break;
2004         }
2005         return Status;
2006 }
2007
2008
2009 static const struct file_operations bcm_fops = {
2010         .owner    = THIS_MODULE,
2011         .open     = bcm_char_open,
2012         .release  = bcm_char_release,
2013         .read     = bcm_char_read,
2014         .unlocked_ioctl    = bcm_char_ioctl,
2015         .llseek = no_llseek,
2016 };
2017
2018 int register_control_device_interface(struct bcm_mini_adapter *Adapter)
2019 {
2020
2021         if (Adapter->major > 0)
2022                 return Adapter->major;
2023
2024         Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops);
2025         if (Adapter->major < 0) {
2026                 pr_err(DRV_NAME ": could not created character device\n");
2027                 return Adapter->major;
2028         }
2029
2030         Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL,
2031                                                 MKDEV(Adapter->major, 0),
2032                                                 Adapter, DEV_NAME);
2033
2034         if (IS_ERR(Adapter->pstCreatedClassDevice)) {
2035                 pr_err(DRV_NAME ": class device create failed\n");
2036                 unregister_chrdev(Adapter->major, DEV_NAME);
2037                 return PTR_ERR(Adapter->pstCreatedClassDevice);
2038         }
2039
2040         return 0;
2041 }
2042
2043 void unregister_control_device_interface(struct bcm_mini_adapter *Adapter)
2044 {
2045         if (Adapter->major > 0) {
2046                 device_destroy(bcm_class, MKDEV(Adapter->major, 0));
2047                 unregister_chrdev(Adapter->major, DEV_NAME);
2048         }
2049 }
2050