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