Staging: bcm: Bcmchar: Fix style issues on bcm_char_open()
[linux-2.6.git] / drivers / staging / bcm / Bcmchar.c
blobedcd0c02eb85a3677f247c98a92fb22dd51e28c3
1 #include <linux/fs.h>
3 #include "headers.h"
4 /***************************************************************
5 * Function - bcm_char_open()
7 * Description - This is the "open" entry point for the character
8 * driver.
10 * Parameters - inode: Pointer to the Inode structure of char device
11 * filp : File pointer of the char device
13 * Returns - Zero(Success)
14 ****************************************************************/
16 static int bcm_char_open(struct inode *inode, struct file * filp)
18 PMINI_ADAPTER Adapter = NULL;
19 PPER_TARANG_DATA pTarang = NULL;
21 Adapter = GET_BCM_ADAPTER(gblpnetdev);
22 pTarang = (PPER_TARANG_DATA)kmalloc(sizeof(PER_TARANG_DATA),
23 GFP_KERNEL);
24 if (!pTarang)
25 return -ENOMEM;
27 memset(pTarang, 0, sizeof(PER_TARANG_DATA));
28 pTarang->Adapter = Adapter;
29 pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);
31 down(&Adapter->RxAppControlQueuelock);
32 pTarang->next = Adapter->pTarangs;
33 Adapter->pTarangs = pTarang;
34 up(&Adapter->RxAppControlQueuelock);
36 /* Store the Adapter structure */
37 filp->private_data = pTarang;
39 /*Start Queuing the control response Packets*/
40 atomic_inc(&Adapter->ApplicationRunning);
42 nonseekable_open(inode, filp);
43 return 0;
46 static int bcm_char_release(struct inode *inode, struct file *filp)
48 PPER_TARANG_DATA pTarang, tmp, ptmp;
49 PMINI_ADAPTER Adapter=NULL;
50 struct sk_buff * pkt, * npkt;
52 pTarang = (PPER_TARANG_DATA)filp->private_data;
54 if(pTarang == NULL)
56 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "ptarang is null\n");
57 return 0;
60 Adapter = pTarang->Adapter;
62 down( &Adapter->RxAppControlQueuelock);
64 tmp = Adapter->pTarangs;
65 for ( ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next )
67 if ( tmp == pTarang )
68 break;
71 if ( tmp )
73 if ( !ptmp )
74 Adapter->pTarangs = tmp->next;
75 else
76 ptmp->next = tmp->next;
79 else
81 up( &Adapter->RxAppControlQueuelock);
82 return 0;
85 pkt = pTarang->RxAppControlHead;
86 while ( pkt )
88 npkt = pkt->next;
89 kfree_skb(pkt);
90 pkt = npkt;
93 up( &Adapter->RxAppControlQueuelock);
95 /*Stop Queuing the control response Packets*/
96 atomic_dec(&Adapter->ApplicationRunning);
98 kfree(pTarang);
100 /* remove this filp from the asynchronously notified filp's */
101 filp->private_data = NULL;
102 return 0;
105 static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size, loff_t *f_pos)
107 PPER_TARANG_DATA pTarang = filp->private_data;
108 PMINI_ADAPTER Adapter = pTarang->Adapter;
109 struct sk_buff* Packet = NULL;
110 ssize_t PktLen = 0;
111 int wait_ret_val=0;
113 wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
114 (pTarang->RxAppControlHead || Adapter->device_removed));
115 if((wait_ret_val == -ERESTARTSYS))
117 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Exiting as i've been asked to exit!!!\n");
118 return wait_ret_val;
121 if(Adapter->device_removed)
123 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Device Removed... Killing the Apps...\n");
124 return -ENODEV;
127 if(FALSE == Adapter->fw_download_done)
128 return -EACCES;
130 down( &Adapter->RxAppControlQueuelock);
132 if(pTarang->RxAppControlHead)
134 Packet = pTarang->RxAppControlHead;
135 DEQUEUEPACKET(pTarang->RxAppControlHead,pTarang->RxAppControlTail);
136 pTarang->AppCtrlQueueLen--;
139 up(&Adapter->RxAppControlQueuelock);
141 if(Packet)
143 PktLen = Packet->len;
144 if(copy_to_user(buf, Packet->data, min_t(size_t, PktLen, size)))
146 dev_kfree_skb(Packet);
147 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "\nReturning from copy to user failure \n");
148 return -EFAULT;
150 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
151 "Read %zd Bytes From Adapter packet = %p by process %d!\n",
152 PktLen, Packet, current->pid);
153 dev_kfree_skb(Packet);
156 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<====\n");
157 return PktLen;
160 static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
162 PPER_TARANG_DATA pTarang = filp->private_data;
163 void __user *argp = (void __user *)arg;
164 PMINI_ADAPTER Adapter = pTarang->Adapter;
165 INT Status = STATUS_FAILURE;
166 int timeout = 0;
167 IOCTL_BUFFER IoBuffer;
169 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);
171 if(_IOC_TYPE(cmd) != BCM_IOCTL)
172 return -EFAULT;
173 if(_IOC_DIR(cmd) & _IOC_READ)
174 Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
175 else if (_IOC_DIR(cmd) & _IOC_WRITE)
176 Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
177 else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
178 Status = STATUS_SUCCESS;
180 if(Status)
181 return -EFAULT;
183 if(Adapter->device_removed)
185 return -EFAULT;
188 if(FALSE == Adapter->fw_download_done)
190 switch (cmd)
192 case IOCTL_MAC_ADDR_REQ:
193 case IOCTL_LINK_REQ:
194 case IOCTL_CM_REQUEST:
195 case IOCTL_SS_INFO_REQ:
196 case IOCTL_SEND_CONTROL_MESSAGE:
197 case IOCTL_IDLE_REQ:
198 case IOCTL_BCM_GPIO_SET_REQUEST:
199 case IOCTL_BCM_GPIO_STATUS_REQUEST:
200 return -EACCES;
201 default:
202 break;
206 Status = vendorextnIoctl(Adapter, cmd, arg);
207 if(Status != CONTINUE_COMMON_PATH )
208 return Status;
210 switch(cmd){
211 // Rdms for Swin Idle...
212 case IOCTL_BCM_REGISTER_READ_PRIVATE:
214 RDM_BUFFER sRdmBuffer = {0};
215 PCHAR temp_buff;
216 UINT Bufflen;
218 /* Copy Ioctl Buffer structure */
219 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
220 return -EFAULT;
222 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
223 return -EINVAL;
225 if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
226 return -EFAULT;
228 /* FIXME: need to restrict BuffLen */
229 Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4;
230 temp_buff = kmalloc(Bufflen, GFP_KERNEL);
231 if(!temp_buff)
232 return -ENOMEM;
234 Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
235 (PUINT)temp_buff, Bufflen);
236 if(Status == STATUS_SUCCESS)
238 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
239 Status = -EFAULT;
242 kfree(temp_buff);
243 break;
245 case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
247 WRM_BUFFER sWrmBuffer = {0};
248 UINT uiTempVar=0;
249 /* Copy Ioctl Buffer structure */
251 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
252 return -EFAULT;
254 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
255 return -EINVAL;
257 /* Get WrmBuffer structure */
258 if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
259 return -EFAULT;
261 uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
262 if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
263 ((uiTempVar == EEPROM_REJECT_REG_1)||
264 (uiTempVar == EEPROM_REJECT_REG_2) ||
265 (uiTempVar == EEPROM_REJECT_REG_3) ||
266 (uiTempVar == EEPROM_REJECT_REG_4)))
268 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
269 return -EFAULT;
271 Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
272 (PUINT)sWrmBuffer.Data, sizeof(ULONG));
273 if(Status == STATUS_SUCCESS)
275 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n");
277 else
279 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
280 Status = -EFAULT;
282 break;
285 case IOCTL_BCM_REGISTER_READ:
286 case IOCTL_BCM_EEPROM_REGISTER_READ:
288 RDM_BUFFER sRdmBuffer = {0};
289 PCHAR temp_buff = NULL;
290 UINT uiTempVar = 0;
291 if((Adapter->IdleMode == TRUE) ||
292 (Adapter->bShutStatus ==TRUE) ||
293 (Adapter->bPreparingForLowPowerMode ==TRUE))
295 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
296 return -EACCES;
298 /* Copy Ioctl Buffer structure */
299 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
300 return -EFAULT;
302 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
303 return -EINVAL;
305 if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
306 return -EFAULT;
308 /* FIXME: don't trust user supplied length */
309 temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
310 if(!temp_buff)
311 return STATUS_FAILURE;
313 if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
314 ((ULONG)sRdmBuffer.Register & 0x3))
316 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n",
317 (int)sRdmBuffer.Register);
318 return -EINVAL;
321 uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
322 Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
323 (PUINT)temp_buff, IoBuffer.OutputLength);
324 if(Status == STATUS_SUCCESS)
325 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
326 Status = -EFAULT;
328 kfree(temp_buff);
329 break;
331 case IOCTL_BCM_REGISTER_WRITE:
332 case IOCTL_BCM_EEPROM_REGISTER_WRITE:
334 WRM_BUFFER sWrmBuffer = {0};
335 UINT uiTempVar=0;
336 if((Adapter->IdleMode == TRUE) ||
337 (Adapter->bShutStatus ==TRUE) ||
338 (Adapter->bPreparingForLowPowerMode ==TRUE))
340 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
341 return -EACCES;
344 /* Copy Ioctl Buffer structure */
345 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
346 return -EFAULT;
348 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
349 return -EINVAL;
351 /* Get WrmBuffer structure */
352 if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
353 return -EFAULT;
355 if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
356 ((ULONG)sWrmBuffer.Register & 0x3) )
358 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n",
359 (int)sWrmBuffer.Register);
360 return -EINVAL;
363 uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
364 if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
365 ((uiTempVar == EEPROM_REJECT_REG_1)||
366 (uiTempVar == EEPROM_REJECT_REG_2) ||
367 (uiTempVar == EEPROM_REJECT_REG_3) ||
368 (uiTempVar == EEPROM_REJECT_REG_4)) &&
369 (cmd == IOCTL_BCM_REGISTER_WRITE))
371 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
372 return -EFAULT;
375 Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
376 (PUINT)sWrmBuffer.Data, sWrmBuffer.Length);
377 if(Status == STATUS_SUCCESS)
379 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
381 else
383 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
384 Status = -EFAULT;
386 break;
388 case IOCTL_BCM_GPIO_SET_REQUEST:
390 UCHAR ucResetValue[4];
391 UINT value =0;
392 UINT uiBit = 0;
393 UINT uiOperation = 0;
395 GPIO_INFO gpio_info = {0};
396 if((Adapter->IdleMode == TRUE) ||
397 (Adapter->bShutStatus ==TRUE) ||
398 (Adapter->bPreparingForLowPowerMode ==TRUE))
400 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
401 return -EACCES;
403 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
404 return -EFAULT;
405 if (IoBuffer.InputLength > sizeof(gpio_info))
406 return -EINVAL;
407 if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
408 return -EFAULT;
409 uiBit = gpio_info.uiGpioNumber;
410 uiOperation = gpio_info.uiGpioValue;
412 value= (1<<uiBit);
414 if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE)
416 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",value);
417 Status = -EINVAL;
418 break;
422 if(uiOperation)//Set - setting 1
424 //Set the gpio output register
425 Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG ,
426 (PUINT)(&value), sizeof(UINT));
427 if(Status == STATUS_SUCCESS)
429 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
431 else
433 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit);
434 break;
437 else//Unset - setting 0
439 //Set the gpio output register
440 Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG ,
441 (PUINT)(&value), sizeof(UINT));
442 if(Status == STATUS_SUCCESS)
444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n");
446 else
448 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit);
449 break;
453 Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
454 (PUINT)ucResetValue, sizeof(UINT));
455 if (STATUS_SUCCESS != Status)
457 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed");
458 break;
460 //Set the gpio mode register to output
461 *(UINT*)ucResetValue |= (1<<uiBit);
462 Status = wrmaltWithLock(Adapter,GPIO_MODE_REGISTER ,
463 (PUINT)ucResetValue, sizeof(UINT));
464 if(Status == STATUS_SUCCESS)
466 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n");
468 else
470 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n");
471 break;
474 break;
475 case BCM_LED_THREAD_STATE_CHANGE_REQ:
477 USER_THREAD_REQ threadReq = { 0 };
478 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive");
480 if((Adapter->IdleMode == TRUE) ||
481 (Adapter->bShutStatus ==TRUE) ||
482 (Adapter->bPreparingForLowPowerMode ==TRUE))
484 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
485 Status = -EACCES;
486 break;
489 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
490 return -EFAULT;
492 if (IoBuffer.InputLength > sizeof(threadReq))
493 return -EINVAL;
495 if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
496 return -EFAULT;
498 //if LED thread is running(Actively or Inactively) set it state to make inactive
499 if(Adapter->LEDInfo.led_thread_running)
501 if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ)
503 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req");
504 Adapter->DriverState = LED_THREAD_ACTIVE;
506 else
508 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req.....");
509 Adapter->DriverState = LED_THREAD_INACTIVE;
512 //signal thread.
513 wake_up(&Adapter->LEDInfo.notify_led_event);
517 break;
518 case IOCTL_BCM_GPIO_STATUS_REQUEST:
520 ULONG uiBit = 0;
521 UCHAR ucRead[4];
522 GPIO_INFO gpio_info = {0};
523 if((Adapter->IdleMode == TRUE) ||
524 (Adapter->bShutStatus ==TRUE) ||
525 (Adapter->bPreparingForLowPowerMode ==TRUE))
526 return -EACCES;
527 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
528 return -EFAULT;
529 if (IoBuffer.InputLength > sizeof(gpio_info))
530 return -EINVAL;
531 if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
532 return -EFAULT;
533 uiBit = gpio_info.uiGpioNumber;
534 //Set the gpio output register
535 Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
536 (PUINT)ucRead, sizeof(UINT));
537 if(Status != STATUS_SUCCESS)
539 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
540 return Status;
544 break;
545 case IOCTL_BCM_GPIO_MULTI_REQUEST:
547 UCHAR ucResetValue[4];
548 GPIO_MULTI_INFO gpio_multi_info[MAX_IDX];
549 PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info;
551 memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO));
553 if((Adapter->IdleMode == TRUE) ||
554 (Adapter->bShutStatus ==TRUE) ||
555 (Adapter->bPreparingForLowPowerMode ==TRUE))
556 return -EINVAL;
557 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
558 return -EFAULT;
559 if (IoBuffer.InputLength > sizeof(gpio_multi_info))
560 return -EINVAL;
561 if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
562 return -EFAULT;
564 if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE)
566 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);
567 Status = -EINVAL;
568 break;
571 /* Set the gpio output register */
573 if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
574 ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand))
576 /* Set 1's in GPIO OUTPUT REGISTER */
577 *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
578 pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
579 pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
581 if( *(UINT*) ucResetValue)
582 Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG));
584 if( Status != STATUS_SUCCESS)
586 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
587 return Status;
590 /* Clear to 0's in GPIO OUTPUT REGISTER */
591 *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
592 pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
593 ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
595 if( *(UINT*) ucResetValue)
596 Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG));
598 if( Status != STATUS_SUCCESS)
600 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." );
601 return Status;
605 if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask)
607 Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
609 if(Status != STATUS_SUCCESS)
611 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed.");
612 return Status;
615 pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue &
616 pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
619 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength);
620 if(Status)
622 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
623 break;
626 break;
627 case IOCTL_BCM_GPIO_MODE_REQUEST:
629 UCHAR ucResetValue[4];
630 GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX];
631 PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode;
633 if((Adapter->IdleMode == TRUE) ||
634 (Adapter->bShutStatus ==TRUE) ||
635 (Adapter->bPreparingForLowPowerMode ==TRUE))
636 return -EINVAL;
638 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
639 return -EFAULT;
640 if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
641 return -EINVAL;
642 if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength))
643 return -EFAULT;
645 Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT));
646 if( STATUS_SUCCESS != Status)
648 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed");
649 return Status;
652 //Validating the request
653 if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE)
655 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);
656 Status = -EINVAL;
657 break;
660 if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)
662 /* write all OUT's (1's) */
663 *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
664 pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
665 /* write all IN's (0's) */
666 *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
667 pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
669 /* Currently implemented return the modes of all GPIO's
670 * else needs to bit AND with mask
671 * */
672 pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue;
674 Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG));
675 if( Status == STATUS_SUCCESS)
677 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done");
679 else
681 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed");
682 Status = -EFAULT;
683 break;
686 else /* if uiGPIOMask is 0 then return mode register configuration */
688 pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue;
690 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength);
691 if(Status)
693 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
694 break;
697 break;
699 case IOCTL_MAC_ADDR_REQ:
700 case IOCTL_LINK_REQ:
701 case IOCTL_CM_REQUEST:
702 case IOCTL_SS_INFO_REQ:
703 case IOCTL_SEND_CONTROL_MESSAGE:
704 case IOCTL_IDLE_REQ:
706 PVOID pvBuffer=NULL;
708 /* Copy Ioctl Buffer structure */
709 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
710 return -EFAULT;
712 /* FIXME: don't accept any length from user */
713 pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
714 if(!pvBuffer)
715 return -ENOMEM;
717 if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
719 Status = -EFAULT;
720 kfree(pvBuffer);
721 break;
724 down(&Adapter->LowPowerModeSync);
725 Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
726 !Adapter->bPreparingForLowPowerMode,
727 (1 * HZ));
728 if(Status == -ERESTARTSYS)
729 goto cntrlEnd;
731 if(Adapter->bPreparingForLowPowerMode)
733 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n");
734 Status = STATUS_FAILURE ;
735 goto cntrlEnd ;
737 Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
738 cntrlEnd:
739 up(&Adapter->LowPowerModeSync);
740 kfree(pvBuffer);
741 break;
743 case IOCTL_BCM_BUFFER_DOWNLOAD_START:
745 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ;
746 if(NVMAccess)
748 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");
749 return -EACCES;
751 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
752 if(!down_trylock(&Adapter->fw_download_sema))
754 Adapter->bBinDownloaded=FALSE;
755 Adapter->fw_download_process_pid=current->pid;
756 Adapter->bCfgDownloaded=FALSE;
757 Adapter->fw_download_done=FALSE;
758 netif_carrier_off(Adapter->dev);
759 netif_stop_queue(Adapter->dev);
760 Status = reset_card_proc(Adapter);
761 if(Status)
763 pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
764 up(&Adapter->fw_download_sema);
765 up(&Adapter->NVMRdmWrmLock);
766 break;
768 mdelay(10);
770 else
773 Status = -EBUSY;
776 up(&Adapter->NVMRdmWrmLock);
777 break;
779 case IOCTL_BCM_BUFFER_DOWNLOAD:
781 FIRMWARE_INFO *psFwInfo = NULL;
782 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
784 if(!down_trylock(&Adapter->fw_download_sema))
786 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n");
787 Status=-EINVAL;
788 break;
791 /* Copy Ioctl Buffer structure */
792 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
793 return -EFAULT;
795 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n",
796 IoBuffer.InputLength);
798 if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO))
799 return -EINVAL;
801 psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
802 if(!psFwInfo)
803 return -ENOMEM;
805 if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength))
806 return -EFAULT;
808 if(!psFwInfo->pvMappedFirmwareAddress ||
809 (psFwInfo->u32FirmwareLength == 0))
811 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
812 psFwInfo->u32FirmwareLength);
813 Status = -EINVAL;
814 break;
816 Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
817 if(Status != STATUS_SUCCESS)
819 if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR)
821 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
823 else
825 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n");
827 //up(&Adapter->fw_download_sema);
829 if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
831 Adapter->DriverState = DRIVER_INIT;
832 Adapter->LEDInfo.bLedInitDone = FALSE;
833 wake_up(&Adapter->LEDInfo.notify_led_event);
836 break ;
837 }while(0);
839 if(Status != STATUS_SUCCESS)
840 up(&Adapter->fw_download_sema);
841 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n");
842 kfree(psFwInfo);
843 break;
845 case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
847 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
848 if(NVMAccess)
850 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n");
851 up(&Adapter->fw_download_sema);
852 return -EACCES;
854 if(down_trylock(&Adapter->fw_download_sema))
856 Adapter->bBinDownloaded=TRUE;
857 Adapter->bCfgDownloaded=TRUE;
858 atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
860 Adapter->CurrNumRecvDescs=0;
861 Adapter->downloadDDR = 0;
863 //setting the Mips to Run
864 Status = run_card_proc(Adapter);
865 if(Status)
867 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n");
868 up(&Adapter->fw_download_sema);
869 up(&Adapter->NVMRdmWrmLock);
870 break;
872 else
873 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n");
874 mdelay(10);
875 /* Wait for MailBox Interrupt */
876 if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
878 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
880 timeout = 5*HZ;
881 Adapter->waiting_to_fw_download_done = FALSE;
882 wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
883 Adapter->waiting_to_fw_download_done, timeout);
884 Adapter->fw_download_process_pid=INVALID_PID;
885 Adapter->fw_download_done=TRUE;
886 atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
887 Adapter->CurrNumRecvDescs = 0;
888 Adapter->PrevNumRecvDescs = 0;
889 atomic_set(&Adapter->cntrlpktCnt,0);
890 Adapter->LinkUpStatus = 0;
891 Adapter->LinkStatus = 0;
893 if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
895 Adapter->DriverState = FW_DOWNLOAD_DONE;
896 wake_up(&Adapter->LEDInfo.notify_led_event);
899 if(!timeout)
901 Status = -ENODEV;
904 else
906 Status = -EINVAL;
908 up(&Adapter->fw_download_sema);
909 up(&Adapter->NVMRdmWrmLock);
910 break;
912 case IOCTL_BE_BUCKET_SIZE:
913 Status = 0;
914 if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
915 Status = -EFAULT;
916 break;
918 case IOCTL_RTPS_BUCKET_SIZE:
919 Status = 0;
920 if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg))
921 Status = -EFAULT;
922 break;
923 case IOCTL_CHIP_RESET:
925 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
926 if(NVMAccess)
928 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
929 return -EACCES;
931 down(&Adapter->RxAppControlQueuelock);
932 Status = reset_card_proc(Adapter);
933 flushAllAppQ();
934 up(&Adapter->RxAppControlQueuelock);
935 up(&Adapter->NVMRdmWrmLock);
936 ResetCounters(Adapter);
937 break;
939 case IOCTL_QOS_THRESHOLD:
941 USHORT uiLoopIndex;
943 Status = 0;
944 for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
945 if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
946 (unsigned long __user *)arg)) {
947 Status = -EFAULT;
948 break;
951 break;
954 case IOCTL_DUMP_PACKET_INFO:
956 DumpPackInfo(Adapter);
957 DumpPhsRules(&Adapter->stBCMPhsContext);
958 Status = STATUS_SUCCESS;
959 break;
961 case IOCTL_GET_PACK_INFO:
962 if(copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES))
963 return -EFAULT;
964 Status = STATUS_SUCCESS;
965 break;
966 case IOCTL_BCM_SWITCH_TRANSFER_MODE:
968 UINT uiData = 0;
969 if(copy_from_user(&uiData, argp, sizeof(UINT)))
970 return -EFAULT;
972 if(uiData) /* Allow All Packets */
974 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
975 Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
977 else /* Allow IP only Packets */
979 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
980 Adapter->TransferMode = IP_PACKET_ONLY_MODE;
982 Status = STATUS_SUCCESS;
983 break;
986 case IOCTL_BCM_GET_DRIVER_VERSION:
988 /* Copy Ioctl Buffer structure */
989 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
990 return -EFAULT;
992 if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength))
993 return -EFAULT;
994 Status = STATUS_SUCCESS;
995 break;
997 case IOCTL_BCM_GET_CURRENT_STATUS:
999 LINK_STATE link_state;
1001 /* Copy Ioctl Buffer structure */
1002 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1004 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
1005 Status = -EFAULT;
1006 break;
1008 if (IoBuffer.OutputLength != sizeof(link_state)) {
1009 Status = -EINVAL;
1010 break;
1013 memset(&link_state, 0, sizeof(link_state));
1014 link_state.bIdleMode = Adapter->IdleMode;
1015 link_state.bShutdownMode = Adapter->bShutStatus;
1016 link_state.ucLinkStatus = Adapter->LinkStatus;
1018 if (copy_to_user(IoBuffer.OutputBuffer, &link_state,
1019 min_t(size_t, sizeof(link_state), IoBuffer.OutputLength)))
1021 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
1022 Status = -EFAULT;
1023 break;
1025 Status = STATUS_SUCCESS;
1026 break;
1028 case IOCTL_BCM_SET_MAC_TRACING:
1030 UINT tracing_flag;
1032 /* copy ioctl Buffer structure */
1033 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1034 return -EFAULT;
1036 if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT)))
1037 return -EFAULT;
1039 if (tracing_flag)
1040 Adapter->pTarangs->MacTracingEnabled = TRUE;
1041 else
1042 Adapter->pTarangs->MacTracingEnabled = FALSE;
1043 break;
1045 case IOCTL_BCM_GET_DSX_INDICATION:
1047 ULONG ulSFId=0;
1048 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1049 return -EFAULT;
1051 if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt))
1053 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,
1054 "Mismatch req: %lx needed is =0x%zx!!!",
1055 IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
1056 return -EINVAL;
1059 if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
1060 return -EFAULT;
1062 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId );
1063 get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
1064 Status=STATUS_SUCCESS;
1066 break;
1067 case IOCTL_BCM_GET_HOST_MIBS:
1069 PVOID temp_buff;
1071 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1072 return -EFAULT;
1074 if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS))
1076 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,
1077 "Length Check failed %lu %zd\n",
1078 IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS));
1079 return -EINVAL;
1082 /* FIXME: HOST_STATS are too big for kmalloc (122048)! */
1083 temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL);
1084 if(!temp_buff)
1085 return STATUS_FAILURE;
1087 Status = ProcessGetHostMibs(Adapter, temp_buff);
1088 GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
1090 if (Status != STATUS_FAILURE)
1091 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS)))
1092 Status = -EFAULT;
1094 kfree(temp_buff);
1095 break;
1098 case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
1099 if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode))
1101 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
1102 Adapter->bWakeUpDevice = TRUE;
1103 wake_up(&Adapter->process_rx_cntrlpkt);
1105 Status = STATUS_SUCCESS;
1106 break;
1108 case IOCTL_BCM_BULK_WRM:
1110 PBULKWRM_BUFFER pBulkBuffer;
1111 UINT uiTempVar=0;
1112 PCHAR pvBuffer = NULL;
1114 if((Adapter->IdleMode == TRUE) ||
1115 (Adapter->bShutStatus ==TRUE) ||
1116 (Adapter->bPreparingForLowPowerMode ==TRUE))
1118 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n");
1119 Status = -EACCES;
1120 break;
1123 /* Copy Ioctl Buffer structure */
1124 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1125 return -EFAULT;
1127 /* FIXME: restrict length */
1128 pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
1129 if(!pvBuffer)
1130 return -ENOMEM;
1132 /* Get WrmBuffer structure */
1133 if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
1135 kfree(pvBuffer);
1136 Status = -EFAULT;
1137 break;
1140 pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
1142 if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
1143 ((ULONG)pBulkBuffer->Register & 0x3))
1145 kfree(pvBuffer);
1146 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register);
1147 Status = -EINVAL;
1148 break;
1152 uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
1153 if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE)
1154 && ((uiTempVar == EEPROM_REJECT_REG_1)||
1155 (uiTempVar == EEPROM_REJECT_REG_2) ||
1156 (uiTempVar == EEPROM_REJECT_REG_3) ||
1157 (uiTempVar == EEPROM_REJECT_REG_4)) &&
1158 (cmd == IOCTL_BCM_REGISTER_WRITE))
1160 kfree(pvBuffer);
1161 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n");
1162 Status = -EFAULT;
1163 break;
1166 if(pBulkBuffer->SwapEndian == FALSE)
1167 Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
1168 else
1169 Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
1171 if(Status != STATUS_SUCCESS)
1173 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
1176 kfree(pvBuffer);
1177 break;
1180 case IOCTL_BCM_GET_NVM_SIZE:
1181 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1182 return -EFAULT;
1184 if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) {
1185 if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT)))
1186 return -EFAULT;
1188 Status = STATUS_SUCCESS ;
1189 break;
1191 case IOCTL_BCM_CAL_INIT :
1194 UINT uiSectorSize = 0 ;
1195 if(Adapter->eNVMType == NVM_FLASH)
1197 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1198 return -EFAULT;
1200 if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
1201 return -EFAULT;
1203 if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
1205 if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize,
1206 sizeof(UINT)))
1207 return -EFAULT;
1209 else
1211 if(IsFlash2x(Adapter))
1213 if (copy_to_user(IoBuffer.OutputBuffer,
1214 &Adapter->uiSectorSize ,
1215 sizeof(UINT)))
1216 return -EFAULT;
1218 else
1220 if((TRUE == Adapter->bShutStatus) ||
1221 (TRUE == Adapter->IdleMode))
1223 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n");
1224 return -EACCES;
1227 Adapter->uiSectorSize = uiSectorSize ;
1228 BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize);
1231 Status = STATUS_SUCCESS ;
1233 else
1235 Status = STATUS_FAILURE;
1238 break;
1239 case IOCTL_BCM_SET_DEBUG :
1240 #ifdef DEBUG
1242 USER_BCM_DBG_STATE sUserDebugState;
1244 // BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG );
1246 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
1247 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1248 return -EFAULT;
1250 if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)))
1251 return -EFAULT;
1254 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
1255 sUserDebugState.OnOff, sUserDebugState.Type);
1256 //sUserDebugState.Subtype <<= 1;
1257 sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
1258 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype);
1260 // Update new 'DebugState' in the Adapter
1261 Adapter->stDebugState.type |= sUserDebugState.Type;
1262 /* Subtype: A bitmap of 32 bits for Subtype per Type.
1263 * Valid indexes in 'subtype' array: 1,2,4,8
1264 * corresponding to valid Type values. Hence we can use the 'Type' field
1265 * as the index value, ignoring the array entries 0,3,5,6,7 !
1267 if (sUserDebugState.OnOff)
1268 Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype;
1269 else
1270 Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype;
1272 BCM_SHOW_DEBUG_BITMAP(Adapter);
1275 #endif
1276 break;
1277 case IOCTL_BCM_NVM_READ:
1278 case IOCTL_BCM_NVM_WRITE:
1280 NVM_READWRITE stNVMReadWrite;
1281 PUCHAR pReadData = NULL;
1282 ULONG ulDSDMagicNumInUsrBuff = 0;
1283 struct timeval tv0, tv1;
1284 memset(&tv0,0,sizeof(struct timeval));
1285 memset(&tv1,0,sizeof(struct timeval));
1286 if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0))
1288 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
1289 Status = -EFAULT;
1290 break;
1293 if(IsFlash2x(Adapter))
1295 if((Adapter->eActiveDSD != DSD0) &&
1296 (Adapter->eActiveDSD != DSD1) &&
1297 (Adapter->eActiveDSD != DSD2))
1299 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked");
1300 return STATUS_FAILURE ;
1304 /* Copy Ioctl Buffer structure */
1306 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1307 return -EFAULT;
1309 if(copy_from_user(&stNVMReadWrite,
1310 (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
1311 sizeof(NVM_READWRITE)))
1312 return -EFAULT;
1315 // Deny the access if the offset crosses the cal area limit.
1317 if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize)
1319 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset ,
1320 // stNVMReadWrite.uiNumBytes);
1321 Status = STATUS_FAILURE;
1322 break;
1325 pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
1326 if(!pReadData)
1327 return -ENOMEM;
1329 if(copy_from_user(pReadData, stNVMReadWrite.pBuffer,
1330 stNVMReadWrite.uiNumBytes))
1332 Status = -EFAULT;
1333 kfree(pReadData);
1334 break;
1337 do_gettimeofday(&tv0);
1338 if(IOCTL_BCM_NVM_READ == cmd)
1340 down(&Adapter->NVMRdmWrmLock);
1342 if((Adapter->IdleMode == TRUE) ||
1343 (Adapter->bShutStatus ==TRUE) ||
1344 (Adapter->bPreparingForLowPowerMode ==TRUE))
1346 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1347 up(&Adapter->NVMRdmWrmLock);
1348 kfree(pReadData);
1349 return -EACCES;
1352 Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
1353 stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
1355 up(&Adapter->NVMRdmWrmLock);
1357 if(Status != STATUS_SUCCESS)
1359 kfree(pReadData);
1360 return Status;
1362 if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes))
1364 kfree(pReadData);
1365 Status = -EFAULT;
1368 else
1371 down(&Adapter->NVMRdmWrmLock);
1373 if((Adapter->IdleMode == TRUE) ||
1374 (Adapter->bShutStatus ==TRUE) ||
1375 (Adapter->bPreparingForLowPowerMode ==TRUE))
1377 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1378 up(&Adapter->NVMRdmWrmLock);
1379 kfree(pReadData);
1380 return -EACCES;
1383 Adapter->bHeaderChangeAllowed = TRUE ;
1384 if(IsFlash2x(Adapter))
1387 New Requirement:-
1388 DSD section updation will be allowed in two case:-
1389 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull
1390 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is
1391 corrupted then user space program first modify the DSD header with valid DSD sig so
1392 that this as well as further write may be worthwhile.
1394 This restriction has been put assuming that if DSD sig is corrupted, DSD
1395 data won't be considered valid.
1399 Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD);
1400 if(Status != STATUS_SUCCESS)
1402 if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) ||
1403 (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE))
1405 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
1406 up(&Adapter->NVMRdmWrmLock);
1407 kfree(pReadData);
1408 return Status;
1411 ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
1412 if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER)
1414 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
1415 up(&Adapter->NVMRdmWrmLock);
1416 kfree(pReadData);
1417 return Status;
1421 Status = BeceemNVMWrite(Adapter, (PUINT )pReadData,
1422 stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
1423 if(IsFlash2x(Adapter))
1424 BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD);
1426 Adapter->bHeaderChangeAllowed = FALSE ;
1428 up(&Adapter->NVMRdmWrmLock);
1431 if(Status != STATUS_SUCCESS)
1433 kfree(pReadData);
1434 return Status;
1437 do_gettimeofday(&tv1);
1438 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);
1441 kfree(pReadData);
1442 Status = STATUS_SUCCESS;
1444 break;
1445 case IOCTL_BCM_FLASH2X_SECTION_READ :
1448 FLASH2X_READWRITE sFlash2xRead = {0};
1449 PUCHAR pReadBuff = NULL ;
1450 UINT NOB = 0;
1451 UINT BuffSize = 0;
1452 UINT ReadBytes = 0;
1453 UINT ReadOffset = 0;
1454 void __user *OutPutBuff;
1456 if(IsFlash2x(Adapter) != TRUE)
1458 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1459 return -EINVAL;
1462 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
1463 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1464 return -EFAULT;
1466 //Reading FLASH 2.x READ structure
1467 if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)))
1468 return -EFAULT;
1471 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section);
1472 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset);
1473 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes);
1474 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify);
1476 //This was internal to driver for raw read. now it has ben exposed to user space app.
1477 if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE)
1478 return STATUS_FAILURE ;
1480 NOB = sFlash2xRead.numOfBytes;
1481 if(NOB > Adapter->uiSectorSize )
1482 BuffSize = Adapter->uiSectorSize;
1483 else
1484 BuffSize = NOB ;
1486 ReadOffset = sFlash2xRead.offset ;
1487 OutPutBuff = IoBuffer.OutputBuffer;
1490 pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
1491 if(pReadBuff == NULL)
1493 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
1494 return -ENOMEM;
1496 down(&Adapter->NVMRdmWrmLock);
1498 if((Adapter->IdleMode == TRUE) ||
1499 (Adapter->bShutStatus ==TRUE) ||
1500 (Adapter->bPreparingForLowPowerMode ==TRUE))
1502 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1503 up(&Adapter->NVMRdmWrmLock);
1504 kfree(pReadBuff);
1505 return -EACCES;
1508 while(NOB)
1511 if(NOB > Adapter->uiSectorSize )
1512 ReadBytes = Adapter->uiSectorSize;
1513 else
1514 ReadBytes = NOB;
1517 //Reading the data from Flash 2.x
1519 Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes);
1520 if(Status)
1522 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status);
1523 break ;
1526 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes);
1528 Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
1529 if(Status)
1531 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status);
1532 break;
1534 NOB = NOB - ReadBytes;
1535 if(NOB)
1537 ReadOffset = ReadOffset + ReadBytes ;
1538 OutPutBuff = OutPutBuff + ReadBytes ;
1542 up(&Adapter->NVMRdmWrmLock);
1543 kfree(pReadBuff);
1546 break ;
1547 case IOCTL_BCM_FLASH2X_SECTION_WRITE :
1549 FLASH2X_READWRITE sFlash2xWrite = {0};
1550 PUCHAR pWriteBuff;
1551 void __user *InputAddr;
1552 UINT NOB = 0;
1553 UINT BuffSize = 0;
1554 UINT WriteOffset = 0;
1555 UINT WriteBytes = 0;
1557 if(IsFlash2x(Adapter) != TRUE)
1559 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1560 return -EINVAL;
1563 //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite
1564 Adapter->bAllDSDWriteAllow = FALSE;
1567 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
1568 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1569 return -EFAULT;
1571 //Reading FLASH 2.x READ structure
1572 if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
1573 return -EFAULT;
1575 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section);
1576 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset);
1577 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes);
1578 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify);
1579 if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) &&
1580 (sFlash2xWrite.Section != VSA2) )
1582 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed");
1583 return -EINVAL;
1586 if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE)
1587 return STATUS_FAILURE ;
1589 InputAddr = sFlash2xWrite.pDataBuff;
1590 WriteOffset = sFlash2xWrite.offset ;
1591 NOB = sFlash2xWrite.numOfBytes;
1593 if(NOB > Adapter->uiSectorSize )
1594 BuffSize = Adapter->uiSectorSize;
1595 else
1596 BuffSize = NOB ;
1598 pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
1599 if(pWriteBuff == NULL)
1600 return -ENOMEM;
1603 //extracting the remainder of the given offset.
1604 WriteBytes = Adapter->uiSectorSize ;
1605 if(WriteOffset % Adapter->uiSectorSize)
1606 WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);
1607 if(NOB < WriteBytes)
1608 WriteBytes = NOB;
1610 down(&Adapter->NVMRdmWrmLock);
1612 if((Adapter->IdleMode == TRUE) ||
1613 (Adapter->bShutStatus ==TRUE) ||
1614 (Adapter->bPreparingForLowPowerMode ==TRUE))
1616 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1617 up(&Adapter->NVMRdmWrmLock);
1618 kfree(pWriteBuff);
1619 return -EACCES;
1622 BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section);
1625 Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes);
1626 if(Status)
1628 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status);
1629 break ;
1631 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes);
1632 //Writing the data from Flash 2.x
1633 Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify);
1635 if(Status)
1637 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
1638 break ;
1641 NOB = NOB - WriteBytes;
1642 if(NOB)
1644 WriteOffset = WriteOffset + WriteBytes ;
1645 InputAddr = InputAddr + WriteBytes ;
1646 if(NOB > Adapter->uiSectorSize )
1647 WriteBytes = Adapter->uiSectorSize;
1648 else
1649 WriteBytes = NOB;
1653 } while(NOB > 0);
1654 BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section);
1655 up(&Adapter->NVMRdmWrmLock);
1656 kfree(pWriteBuff);
1658 break ;
1659 case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP :
1662 PFLASH2X_BITMAP psFlash2xBitMap;
1663 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
1665 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1666 return -EFAULT;
1668 if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
1669 return -EINVAL;
1671 psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
1672 if(psFlash2xBitMap == NULL)
1674 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available");
1675 return -ENOMEM ;
1677 //Reading the Flash Sectio Bit map
1678 down(&Adapter->NVMRdmWrmLock);
1680 if((Adapter->IdleMode == TRUE) ||
1681 (Adapter->bShutStatus ==TRUE) ||
1682 (Adapter->bPreparingForLowPowerMode ==TRUE))
1684 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1685 up(&Adapter->NVMRdmWrmLock);
1686 kfree(psFlash2xBitMap);
1687 return -EACCES;
1690 BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
1691 up(&Adapter->NVMRdmWrmLock);
1692 if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)))
1693 Status = -EFAULT;
1695 kfree(psFlash2xBitMap);
1697 break ;
1698 case IOCTL_BCM_SET_ACTIVE_SECTION :
1700 FLASH2X_SECTION_VAL eFlash2xSectionVal = 0;
1701 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called");
1703 if(IsFlash2x(Adapter) != TRUE)
1705 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1706 return -EINVAL;
1709 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1710 if(Status)
1712 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1713 return Status;
1716 Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT));
1717 if(Status)
1719 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
1720 return Status;
1723 down(&Adapter->NVMRdmWrmLock);
1725 if((Adapter->IdleMode == TRUE) ||
1726 (Adapter->bShutStatus ==TRUE) ||
1727 (Adapter->bPreparingForLowPowerMode ==TRUE))
1729 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1730 up(&Adapter->NVMRdmWrmLock);
1731 return -EACCES;
1734 Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal);
1735 if(Status)
1737 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status);
1739 up(&Adapter->NVMRdmWrmLock);
1741 break ;
1742 case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION :
1744 //Right Now we are taking care of only DSD
1745 Adapter->bAllDSDWriteAllow = FALSE ;
1746 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
1748 Status = STATUS_SUCCESS ;
1750 break ;
1751 case IOCTL_BCM_COPY_SECTION :
1753 FLASH2X_COPY_SECTION sCopySectStrut = {0};
1754 Status = STATUS_SUCCESS;
1755 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called");
1757 Adapter->bAllDSDWriteAllow = FALSE ;
1758 if(IsFlash2x(Adapter) != TRUE)
1760 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1761 return -EINVAL;
1764 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1765 if(Status)
1767 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
1768 return Status;
1771 Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
1772 if(Status)
1774 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
1775 return Status;
1777 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection);
1778 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection);
1779 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset);
1780 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes);
1783 if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE)
1785 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection);
1786 return -EINVAL;
1789 if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE)
1791 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection);
1792 return -EINVAL;
1795 if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection)
1797 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different");
1798 return -EINVAL;
1801 down(&Adapter->NVMRdmWrmLock);
1803 if((Adapter->IdleMode == TRUE) ||
1804 (Adapter->bShutStatus ==TRUE) ||
1805 (Adapter->bPreparingForLowPowerMode ==TRUE))
1807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1808 up(&Adapter->NVMRdmWrmLock);
1809 return -EACCES;
1812 if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2)
1814 if(IsNonCDLessDevice(Adapter))
1816 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!");
1817 Status = -EINVAL ;
1819 else if(sCopySectStrut.numOfBytes == 0)
1821 Status = BcmCopyISO(Adapter,sCopySectStrut);
1823 else
1825 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed..");
1826 Status = STATUS_FAILURE ;
1828 up(&Adapter->NVMRdmWrmLock);
1829 return Status;
1832 Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
1833 sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes);
1834 up(&Adapter->NVMRdmWrmLock);
1836 break ;
1837 case IOCTL_BCM_GET_FLASH_CS_INFO :
1839 Status = STATUS_SUCCESS;
1840 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
1842 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1843 if(Status)
1845 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1846 break;
1848 if(Adapter->eNVMType != NVM_FLASH)
1850 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash");
1851 Status = -EINVAL;
1852 break;
1854 if(IsFlash2x(Adapter) == TRUE)
1857 if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO))
1858 return -EINVAL;
1860 if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)))
1861 return -EFAULT;
1863 else
1865 if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO))
1866 return -EINVAL;
1868 if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)))
1869 return -EFAULT;
1873 break ;
1874 case IOCTL_BCM_SELECT_DSD :
1876 UINT SectOfset = 0;
1877 FLASH2X_SECTION_VAL eFlash2xSectionVal;
1878 eFlash2xSectionVal = NO_SECTION_VAL ;
1879 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called");
1881 if(IsFlash2x(Adapter) != TRUE)
1883 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1884 return -EINVAL;
1887 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1888 if(Status)
1890 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1891 return Status;
1893 Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
1894 if(Status)
1896 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
1897 return Status;
1900 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal);
1901 if((eFlash2xSectionVal != DSD0) &&
1902 (eFlash2xSectionVal != DSD1) &&
1903 (eFlash2xSectionVal != DSD2) )
1905 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal);
1906 return STATUS_FAILURE ;
1909 SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
1910 if(SectOfset == INVALID_OFFSET)
1912 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal);
1913 return -EINVAL;
1916 Adapter->bAllDSDWriteAllow = TRUE ;
1918 Adapter->ulFlashCalStart = SectOfset ;
1919 Adapter->eActiveDSD = eFlash2xSectionVal;
1921 Status = STATUS_SUCCESS ;
1922 break;
1924 case IOCTL_BCM_NVM_RAW_READ :
1927 NVM_READWRITE stNVMRead;
1928 INT NOB ;
1929 INT BuffSize ;
1930 INT ReadOffset = 0;
1931 UINT ReadBytes = 0 ;
1932 PUCHAR pReadBuff;
1933 void __user *OutPutBuff;
1935 if(Adapter->eNVMType != NVM_FLASH)
1937 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash ");
1938 return -EINVAL ;
1941 /* Copy Ioctl Buffer structure */
1942 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1944 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
1945 Status = -EFAULT;
1946 break;
1949 if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE)))
1950 return -EFAULT;
1952 NOB = stNVMRead.uiNumBytes;
1953 //In Raw-Read max Buff size : 64MB
1955 if(NOB > DEFAULT_BUFF_SIZE)
1956 BuffSize = DEFAULT_BUFF_SIZE;
1957 else
1958 BuffSize = NOB ;
1960 ReadOffset = stNVMRead.uiOffset;
1961 OutPutBuff = stNVMRead.pBuffer;
1963 pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
1964 if(pReadBuff == NULL)
1966 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
1967 Status = -ENOMEM;
1968 break;
1970 down(&Adapter->NVMRdmWrmLock);
1972 if((Adapter->IdleMode == TRUE) ||
1973 (Adapter->bShutStatus ==TRUE) ||
1974 (Adapter->bPreparingForLowPowerMode ==TRUE))
1976 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1977 kfree(pReadBuff);
1978 up(&Adapter->NVMRdmWrmLock);
1979 return -EACCES;
1982 Adapter->bFlashRawRead = TRUE ;
1983 while(NOB)
1985 if(NOB > DEFAULT_BUFF_SIZE )
1986 ReadBytes = DEFAULT_BUFF_SIZE;
1987 else
1988 ReadBytes = NOB;
1990 //Reading the data from Flash 2.x
1991 Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes);
1992 if(Status)
1994 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
1995 break;
1998 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes);
2000 Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
2001 if(Status)
2003 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status);
2004 break;
2006 NOB = NOB - ReadBytes;
2007 if(NOB)
2009 ReadOffset = ReadOffset + ReadBytes ;
2010 OutPutBuff = OutPutBuff + ReadBytes ;
2014 Adapter->bFlashRawRead = FALSE ;
2015 up(&Adapter->NVMRdmWrmLock);
2016 kfree(pReadBuff);
2017 break ;
2020 case IOCTL_BCM_CNTRLMSG_MASK:
2022 ULONG RxCntrlMsgBitMask = 0 ;
2024 /* Copy Ioctl Buffer structure */
2025 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
2026 if(Status)
2028 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space");
2029 Status = -EFAULT;
2030 break;
2033 if (IoBuffer.InputLength != sizeof(unsigned long)) {
2034 Status = -EINVAL;
2035 break;
2038 Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength);
2039 if(Status)
2041 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space");
2042 Status = -EFAULT;
2043 break;
2045 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask);
2046 pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ;
2048 break;
2049 case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
2051 DEVICE_DRIVER_INFO DevInfo;
2053 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
2055 DevInfo.MaxRDMBufferSize = BUFFER_4K;
2056 DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
2057 DevInfo.u32RxAlignmentCorrection = 0;
2058 DevInfo.u32NVMType = Adapter->eNVMType;
2059 DevInfo.u32InterfaceType = BCM_USB;
2061 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
2062 return -EFAULT;
2064 if(IoBuffer.OutputLength < sizeof(DevInfo))
2065 return -EINVAL;
2067 if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
2068 return -EFAULT;
2070 break ;
2072 case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
2074 ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
2076 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
2078 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
2079 return -EFAULT;
2081 if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
2082 return -EINVAL;
2084 stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
2086 if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
2087 return -EFAULT;
2090 break;
2092 case IOCTL_CLOSE_NOTIFICATION:
2093 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION");
2094 break;
2096 default:
2097 pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
2098 Status = STATUS_FAILURE;
2099 break;
2101 return Status;
2105 static struct file_operations bcm_fops = {
2106 .owner = THIS_MODULE,
2107 .open = bcm_char_open,
2108 .release = bcm_char_release,
2109 .read = bcm_char_read,
2110 .unlocked_ioctl = bcm_char_ioctl,
2111 .llseek = no_llseek,
2114 extern struct class *bcm_class;
2116 int register_control_device_interface(PMINI_ADAPTER Adapter)
2119 if(Adapter->major>0)
2120 return Adapter->major;
2122 Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops);
2123 if(Adapter->major < 0) {
2124 pr_err(DRV_NAME ": could not created character device\n");
2125 return Adapter->major;
2128 Adapter->pstCreatedClassDevice = device_create (bcm_class, NULL,
2129 MKDEV(Adapter->major, 0), Adapter,
2130 DEV_NAME);
2132 if(IS_ERR(Adapter->pstCreatedClassDevice)) {
2133 pr_err(DRV_NAME ": class device create failed\n");
2134 unregister_chrdev(Adapter->major, DEV_NAME);
2135 return PTR_ERR(Adapter->pstCreatedClassDevice);
2138 return 0;
2141 void unregister_control_device_interface(PMINI_ADAPTER Adapter)
2143 if(Adapter->major > 0) {
2144 device_destroy (bcm_class, MKDEV(Adapter->major, 0));
2145 unregister_chrdev(Adapter->major, DEV_NAME);