Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/upstream-linus
[linux-btrfs-devel.git] / drivers / staging / bcm / Bcmchar.c
blob867dbf1c9926dee8078670692b520b5c334c08cf
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 = kzalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL);
23 if (!pTarang)
24 return -ENOMEM;
26 pTarang->Adapter = Adapter;
27 pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);
29 down(&Adapter->RxAppControlQueuelock);
30 pTarang->next = Adapter->pTarangs;
31 Adapter->pTarangs = pTarang;
32 up(&Adapter->RxAppControlQueuelock);
34 /* Store the Adapter structure */
35 filp->private_data = pTarang;
37 /*Start Queuing the control response Packets*/
38 atomic_inc(&Adapter->ApplicationRunning);
40 nonseekable_open(inode, filp);
41 return 0;
44 static int bcm_char_release(struct inode *inode, struct file *filp)
46 PPER_TARANG_DATA pTarang, tmp, ptmp;
47 PMINI_ADAPTER Adapter = NULL;
48 struct sk_buff *pkt, *npkt;
50 pTarang = (PPER_TARANG_DATA)filp->private_data;
52 if (pTarang == NULL) {
53 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
54 "ptarang is null\n");
55 return 0;
58 Adapter = pTarang->Adapter;
60 down(&Adapter->RxAppControlQueuelock);
62 tmp = Adapter->pTarangs;
63 for (ptmp = NULL; tmp; ptmp = tmp, tmp = tmp->next) {
64 if (tmp == pTarang)
65 break;
68 if (tmp) {
69 if (!ptmp)
70 Adapter->pTarangs = tmp->next;
71 else
72 ptmp->next = tmp->next;
73 } else {
74 up(&Adapter->RxAppControlQueuelock);
75 return 0;
78 pkt = pTarang->RxAppControlHead;
79 while (pkt) {
80 npkt = pkt->next;
81 kfree_skb(pkt);
82 pkt = npkt;
85 up(&Adapter->RxAppControlQueuelock);
87 /*Stop Queuing the control response Packets*/
88 atomic_dec(&Adapter->ApplicationRunning);
90 kfree(pTarang);
92 /* remove this filp from the asynchronously notified filp's */
93 filp->private_data = NULL;
94 return 0;
97 static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size,
98 loff_t *f_pos)
100 PPER_TARANG_DATA pTarang = filp->private_data;
101 PMINI_ADAPTER Adapter = pTarang->Adapter;
102 struct sk_buff *Packet = NULL;
103 ssize_t PktLen = 0;
104 int wait_ret_val = 0;
105 unsigned long ret = 0;
107 wait_ret_val = wait_event_interruptible(Adapter->process_read_wait_queue,
108 (pTarang->RxAppControlHead ||
109 Adapter->device_removed));
110 if ((wait_ret_val == -ERESTARTSYS)) {
111 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
112 "Exiting as i've been asked to exit!!!\n");
113 return wait_ret_val;
116 if (Adapter->device_removed) {
117 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
118 "Device Removed... Killing the Apps...\n");
119 return -ENODEV;
122 if (FALSE == Adapter->fw_download_done)
123 return -EACCES;
125 down(&Adapter->RxAppControlQueuelock);
127 if (pTarang->RxAppControlHead) {
128 Packet = pTarang->RxAppControlHead;
129 DEQUEUEPACKET(pTarang->RxAppControlHead,
130 pTarang->RxAppControlTail);
131 pTarang->AppCtrlQueueLen--;
134 up(&Adapter->RxAppControlQueuelock);
136 if (Packet) {
137 PktLen = Packet->len;
138 ret = copy_to_user(buf, Packet->data,
139 min_t(size_t, PktLen, size));
140 if (ret) {
141 dev_kfree_skb(Packet);
142 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
143 "Returning from copy to user failure\n");
144 return -EFAULT;
146 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,
147 "Read %zd Bytes From Adapter packet = %p by process %d!\n",
148 PktLen, Packet, current->pid);
149 dev_kfree_skb(Packet);
152 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n");
153 return PktLen;
156 static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
158 PPER_TARANG_DATA pTarang = filp->private_data;
159 void __user *argp = (void __user *)arg;
160 PMINI_ADAPTER Adapter = pTarang->Adapter;
161 INT Status = STATUS_FAILURE;
162 int timeout = 0;
163 IOCTL_BUFFER IoBuffer;
165 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Parameters Passed to control IOCTL cmd=0x%X arg=0x%lX", cmd, arg);
167 if(_IOC_TYPE(cmd) != BCM_IOCTL)
168 return -EFAULT;
169 if(_IOC_DIR(cmd) & _IOC_READ)
170 Status = !access_ok(VERIFY_WRITE, argp, _IOC_SIZE(cmd));
171 else if (_IOC_DIR(cmd) & _IOC_WRITE)
172 Status = !access_ok(VERIFY_READ, argp, _IOC_SIZE(cmd));
173 else if (_IOC_NONE == (_IOC_DIR(cmd) & _IOC_NONE))
174 Status = STATUS_SUCCESS;
176 if(Status)
177 return -EFAULT;
179 if(Adapter->device_removed)
181 return -EFAULT;
184 if(FALSE == Adapter->fw_download_done)
186 switch (cmd)
188 case IOCTL_MAC_ADDR_REQ:
189 case IOCTL_LINK_REQ:
190 case IOCTL_CM_REQUEST:
191 case IOCTL_SS_INFO_REQ:
192 case IOCTL_SEND_CONTROL_MESSAGE:
193 case IOCTL_IDLE_REQ:
194 case IOCTL_BCM_GPIO_SET_REQUEST:
195 case IOCTL_BCM_GPIO_STATUS_REQUEST:
196 return -EACCES;
197 default:
198 break;
202 Status = vendorextnIoctl(Adapter, cmd, arg);
203 if(Status != CONTINUE_COMMON_PATH )
204 return Status;
206 switch(cmd){
207 // Rdms for Swin Idle...
208 case IOCTL_BCM_REGISTER_READ_PRIVATE:
210 RDM_BUFFER sRdmBuffer = {0};
211 PCHAR temp_buff;
212 UINT Bufflen;
214 /* Copy Ioctl Buffer structure */
215 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
216 return -EFAULT;
218 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
219 return -EINVAL;
221 if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
222 return -EFAULT;
224 /* FIXME: need to restrict BuffLen */
225 Bufflen = IoBuffer.OutputLength + (4 - IoBuffer.OutputLength%4)%4;
226 temp_buff = kmalloc(Bufflen, GFP_KERNEL);
227 if(!temp_buff)
228 return -ENOMEM;
230 Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
231 (PUINT)temp_buff, Bufflen);
232 if(Status == STATUS_SUCCESS)
234 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
235 Status = -EFAULT;
238 kfree(temp_buff);
239 break;
241 case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
243 WRM_BUFFER sWrmBuffer = {0};
244 UINT uiTempVar=0;
245 /* Copy Ioctl Buffer structure */
247 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
248 return -EFAULT;
250 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
251 return -EINVAL;
253 /* Get WrmBuffer structure */
254 if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
255 return -EFAULT;
257 uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
258 if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
259 ((uiTempVar == EEPROM_REJECT_REG_1)||
260 (uiTempVar == EEPROM_REJECT_REG_2) ||
261 (uiTempVar == EEPROM_REJECT_REG_3) ||
262 (uiTempVar == EEPROM_REJECT_REG_4)))
264 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
265 return -EFAULT;
267 Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
268 (PUINT)sWrmBuffer.Data, sizeof(ULONG));
269 if(Status == STATUS_SUCCESS)
271 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n");
273 else
275 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
276 Status = -EFAULT;
278 break;
281 case IOCTL_BCM_REGISTER_READ:
282 case IOCTL_BCM_EEPROM_REGISTER_READ:
284 RDM_BUFFER sRdmBuffer = {0};
285 PCHAR temp_buff = NULL;
286 UINT uiTempVar = 0;
287 if((Adapter->IdleMode == TRUE) ||
288 (Adapter->bShutStatus ==TRUE) ||
289 (Adapter->bPreparingForLowPowerMode ==TRUE))
291 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
292 return -EACCES;
294 /* Copy Ioctl Buffer structure */
295 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
296 return -EFAULT;
298 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
299 return -EINVAL;
301 if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
302 return -EFAULT;
304 /* FIXME: don't trust user supplied length */
305 temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
306 if(!temp_buff)
307 return STATUS_FAILURE;
309 if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
310 ((ULONG)sRdmBuffer.Register & 0x3))
312 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Done On invalid Address : %x Access Denied.\n",
313 (int)sRdmBuffer.Register);
314 return -EINVAL;
317 uiTempVar = sRdmBuffer.Register & EEPROM_REJECT_MASK;
318 Status = rdmaltWithLock(Adapter, (UINT)sRdmBuffer.Register,
319 (PUINT)temp_buff, IoBuffer.OutputLength);
320 if(Status == STATUS_SUCCESS)
321 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
322 Status = -EFAULT;
324 kfree(temp_buff);
325 break;
327 case IOCTL_BCM_REGISTER_WRITE:
328 case IOCTL_BCM_EEPROM_REGISTER_WRITE:
330 WRM_BUFFER sWrmBuffer = {0};
331 UINT uiTempVar=0;
332 if((Adapter->IdleMode == TRUE) ||
333 (Adapter->bShutStatus ==TRUE) ||
334 (Adapter->bPreparingForLowPowerMode ==TRUE))
336 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
337 return -EACCES;
340 /* Copy Ioctl Buffer structure */
341 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
342 return -EFAULT;
344 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
345 return -EINVAL;
347 /* Get WrmBuffer structure */
348 if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
349 return -EFAULT;
351 if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
352 ((ULONG)sWrmBuffer.Register & 0x3) )
354 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Done On invalid Address : %x Access Denied.\n",
355 (int)sWrmBuffer.Register);
356 return -EINVAL;
359 uiTempVar = sWrmBuffer.Register & EEPROM_REJECT_MASK;
360 if(!((Adapter->pstargetparams->m_u32Customize) & VSG_MODE) &&
361 ((uiTempVar == EEPROM_REJECT_REG_1)||
362 (uiTempVar == EEPROM_REJECT_REG_2) ||
363 (uiTempVar == EEPROM_REJECT_REG_3) ||
364 (uiTempVar == EEPROM_REJECT_REG_4)) &&
365 (cmd == IOCTL_BCM_REGISTER_WRITE))
367 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
368 return -EFAULT;
371 Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
372 (PUINT)sWrmBuffer.Data, sWrmBuffer.Length);
373 if(Status == STATUS_SUCCESS)
375 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
377 else
379 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
380 Status = -EFAULT;
382 break;
384 case IOCTL_BCM_GPIO_SET_REQUEST:
386 UCHAR ucResetValue[4];
387 UINT value =0;
388 UINT uiBit = 0;
389 UINT uiOperation = 0;
391 GPIO_INFO gpio_info = {0};
392 if((Adapter->IdleMode == TRUE) ||
393 (Adapter->bShutStatus ==TRUE) ||
394 (Adapter->bPreparingForLowPowerMode ==TRUE))
396 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
397 return -EACCES;
399 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
400 return -EFAULT;
401 if (IoBuffer.InputLength > sizeof(gpio_info))
402 return -EINVAL;
403 if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
404 return -EFAULT;
405 uiBit = gpio_info.uiGpioNumber;
406 uiOperation = gpio_info.uiGpioValue;
408 value= (1<<uiBit);
410 if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE)
412 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Sorry, Requested GPIO<0x%X> is not correspond to LED !!!",value);
413 Status = -EINVAL;
414 break;
418 if(uiOperation)//Set - setting 1
420 //Set the gpio output register
421 Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_SET_REG ,
422 (PUINT)(&value), sizeof(UINT));
423 if(Status == STATUS_SUCCESS)
425 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
427 else
429 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit);
430 break;
433 else//Unset - setting 0
435 //Set the gpio output register
436 Status = wrmaltWithLock(Adapter,BCM_GPIO_OUTPUT_CLR_REG ,
437 (PUINT)(&value), sizeof(UINT));
438 if(Status == STATUS_SUCCESS)
440 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n");
442 else
444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit);
445 break;
449 Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
450 (PUINT)ucResetValue, sizeof(UINT));
451 if (STATUS_SUCCESS != Status)
453 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed");
454 break;
456 //Set the gpio mode register to output
457 *(UINT*)ucResetValue |= (1<<uiBit);
458 Status = wrmaltWithLock(Adapter,GPIO_MODE_REGISTER ,
459 (PUINT)ucResetValue, sizeof(UINT));
460 if(Status == STATUS_SUCCESS)
462 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n");
464 else
466 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n");
467 break;
470 break;
471 case BCM_LED_THREAD_STATE_CHANGE_REQ:
473 USER_THREAD_REQ threadReq = { 0 };
474 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive");
476 if((Adapter->IdleMode == TRUE) ||
477 (Adapter->bShutStatus ==TRUE) ||
478 (Adapter->bPreparingForLowPowerMode ==TRUE))
480 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO Can't be set/clear in Low power Mode");
481 Status = -EACCES;
482 break;
485 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
486 return -EFAULT;
488 if (IoBuffer.InputLength > sizeof(threadReq))
489 return -EINVAL;
491 if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
492 return -EFAULT;
494 //if LED thread is running(Actively or Inactively) set it state to make inactive
495 if(Adapter->LEDInfo.led_thread_running)
497 if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ)
499 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req");
500 Adapter->DriverState = LED_THREAD_ACTIVE;
502 else
504 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req.....");
505 Adapter->DriverState = LED_THREAD_INACTIVE;
508 //signal thread.
509 wake_up(&Adapter->LEDInfo.notify_led_event);
513 break;
514 case IOCTL_BCM_GPIO_STATUS_REQUEST:
516 ULONG uiBit = 0;
517 UCHAR ucRead[4];
518 GPIO_INFO gpio_info = {0};
519 if((Adapter->IdleMode == TRUE) ||
520 (Adapter->bShutStatus ==TRUE) ||
521 (Adapter->bPreparingForLowPowerMode ==TRUE))
522 return -EACCES;
523 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
524 return -EFAULT;
525 if (IoBuffer.InputLength > sizeof(gpio_info))
526 return -EINVAL;
527 if(copy_from_user(&gpio_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
528 return -EFAULT;
529 uiBit = gpio_info.uiGpioNumber;
530 //Set the gpio output register
531 Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER,
532 (PUINT)ucRead, sizeof(UINT));
533 if(Status != STATUS_SUCCESS)
535 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
536 return Status;
540 break;
541 case IOCTL_BCM_GPIO_MULTI_REQUEST:
543 UCHAR ucResetValue[4];
544 GPIO_MULTI_INFO gpio_multi_info[MAX_IDX];
545 PGPIO_MULTI_INFO pgpio_multi_info = (PGPIO_MULTI_INFO)gpio_multi_info;
547 memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO));
549 if((Adapter->IdleMode == TRUE) ||
550 (Adapter->bShutStatus ==TRUE) ||
551 (Adapter->bPreparingForLowPowerMode ==TRUE))
552 return -EINVAL;
553 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
554 return -EFAULT;
555 if (IoBuffer.InputLength > sizeof(gpio_multi_info))
556 return -EINVAL;
557 if (copy_from_user(&gpio_multi_info, IoBuffer.InputBuffer, IoBuffer.InputLength))
558 return -EFAULT;
560 if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE)
562 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);
563 Status = -EINVAL;
564 break;
567 /* Set the gpio output register */
569 if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
570 ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand))
572 /* Set 1's in GPIO OUTPUT REGISTER */
573 *(UINT*) ucResetValue = pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
574 pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
575 pgpio_multi_info[WIMAX_IDX].uiGPIOValue;
577 if( *(UINT*) ucResetValue)
578 Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG));
580 if( Status != STATUS_SUCCESS)
582 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
583 return Status;
586 /* Clear to 0's in GPIO OUTPUT REGISTER */
587 *(UINT*) ucResetValue = (pgpio_multi_info[WIMAX_IDX].uiGPIOMask &
588 pgpio_multi_info[WIMAX_IDX].uiGPIOCommand &
589 ( ~( pgpio_multi_info[WIMAX_IDX].uiGPIOValue)));
591 if( *(UINT*) ucResetValue)
592 Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG));
594 if( Status != STATUS_SUCCESS)
596 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." );
597 return Status;
601 if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask)
603 Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
605 if(Status != STATUS_SUCCESS)
607 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed.");
608 return Status;
611 pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue &
612 pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
615 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength);
616 if(Status)
618 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
619 break;
622 break;
623 case IOCTL_BCM_GPIO_MODE_REQUEST:
625 UCHAR ucResetValue[4];
626 GPIO_MULTI_MODE gpio_multi_mode[MAX_IDX];
627 PGPIO_MULTI_MODE pgpio_multi_mode = ( PGPIO_MULTI_MODE) gpio_multi_mode;
629 if((Adapter->IdleMode == TRUE) ||
630 (Adapter->bShutStatus ==TRUE) ||
631 (Adapter->bPreparingForLowPowerMode ==TRUE))
632 return -EINVAL;
634 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
635 return -EFAULT;
636 if (IoBuffer.InputLength > sizeof(gpio_multi_mode))
637 return -EINVAL;
638 if (copy_from_user(&gpio_multi_mode, IoBuffer.InputBuffer, IoBuffer.InputLength))
639 return -EFAULT;
641 Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT));
642 if( STATUS_SUCCESS != Status)
644 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed");
645 return Status;
648 //Validating the request
649 if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE)
651 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);
652 Status = -EINVAL;
653 break;
656 if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)
658 /* write all OUT's (1's) */
659 *( UINT*) ucResetValue |= ( pgpio_multi_mode[WIMAX_IDX].uiGPIOMode &
660 pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
661 /* write all IN's (0's) */
662 *( UINT*) ucResetValue &= ~( ( ~pgpio_multi_mode[WIMAX_IDX].uiGPIOMode) &
663 pgpio_multi_mode[WIMAX_IDX].uiGPIOMask);
665 /* Currently implemented return the modes of all GPIO's
666 * else needs to bit AND with mask
667 * */
668 pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *(UINT*)ucResetValue;
670 Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG));
671 if( Status == STATUS_SUCCESS)
673 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done");
675 else
677 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed");
678 Status = -EFAULT;
679 break;
682 else /* if uiGPIOMask is 0 then return mode register configuration */
684 pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue;
686 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength);
687 if(Status)
689 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
690 break;
693 break;
695 case IOCTL_MAC_ADDR_REQ:
696 case IOCTL_LINK_REQ:
697 case IOCTL_CM_REQUEST:
698 case IOCTL_SS_INFO_REQ:
699 case IOCTL_SEND_CONTROL_MESSAGE:
700 case IOCTL_IDLE_REQ:
702 PVOID pvBuffer=NULL;
704 /* Copy Ioctl Buffer structure */
705 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
706 return -EFAULT;
708 /* FIXME: don't accept any length from user */
709 pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
710 if(!pvBuffer)
711 return -ENOMEM;
713 if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
715 Status = -EFAULT;
716 kfree(pvBuffer);
717 break;
720 down(&Adapter->LowPowerModeSync);
721 Status = wait_event_interruptible_timeout(Adapter->lowpower_mode_wait_queue,
722 !Adapter->bPreparingForLowPowerMode,
723 (1 * HZ));
724 if(Status == -ERESTARTSYS)
725 goto cntrlEnd;
727 if(Adapter->bPreparingForLowPowerMode)
729 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Preparing Idle Mode is still True - Hence Rejecting control message\n");
730 Status = STATUS_FAILURE ;
731 goto cntrlEnd ;
733 Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
734 cntrlEnd:
735 up(&Adapter->LowPowerModeSync);
736 kfree(pvBuffer);
737 break;
739 case IOCTL_BCM_BUFFER_DOWNLOAD_START:
741 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ;
742 if(NVMAccess)
744 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");
745 return -EACCES;
747 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
748 if(!down_trylock(&Adapter->fw_download_sema))
750 Adapter->bBinDownloaded=FALSE;
751 Adapter->fw_download_process_pid=current->pid;
752 Adapter->bCfgDownloaded=FALSE;
753 Adapter->fw_download_done=FALSE;
754 netif_carrier_off(Adapter->dev);
755 netif_stop_queue(Adapter->dev);
756 Status = reset_card_proc(Adapter);
757 if(Status)
759 pr_err(PFX "%s: reset_card_proc Failed!\n", Adapter->dev->name);
760 up(&Adapter->fw_download_sema);
761 up(&Adapter->NVMRdmWrmLock);
762 break;
764 mdelay(10);
766 else
769 Status = -EBUSY;
772 up(&Adapter->NVMRdmWrmLock);
773 break;
775 case IOCTL_BCM_BUFFER_DOWNLOAD:
777 FIRMWARE_INFO *psFwInfo = NULL;
778 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Starting the firmware download PID =0x%x!!!!\n", current->pid);
780 if(!down_trylock(&Adapter->fw_download_sema))
782 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Invalid way to download buffer. Use Start and then call this!!!\n");
783 Status=-EINVAL;
784 break;
787 /* Copy Ioctl Buffer structure */
788 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
789 return -EFAULT;
791 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n",
792 IoBuffer.InputLength);
794 if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO))
795 return -EINVAL;
797 psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
798 if(!psFwInfo)
799 return -ENOMEM;
801 if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength))
802 return -EFAULT;
804 if(!psFwInfo->pvMappedFirmwareAddress ||
805 (psFwInfo->u32FirmwareLength == 0))
807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
808 psFwInfo->u32FirmwareLength);
809 Status = -EINVAL;
810 break;
812 Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
813 if(Status != STATUS_SUCCESS)
815 if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR)
817 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
819 else
821 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n");
823 //up(&Adapter->fw_download_sema);
825 if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
827 Adapter->DriverState = DRIVER_INIT;
828 Adapter->LEDInfo.bLedInitDone = FALSE;
829 wake_up(&Adapter->LEDInfo.notify_led_event);
832 break ;
833 }while(0);
835 if(Status != STATUS_SUCCESS)
836 up(&Adapter->fw_download_sema);
837 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "IOCTL: Firmware File Uploaded\n");
838 kfree(psFwInfo);
839 break;
841 case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
843 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
844 if(NVMAccess)
846 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " FW download blocked as EEPROM Read/Write is in progress\n");
847 up(&Adapter->fw_download_sema);
848 return -EACCES;
850 if(down_trylock(&Adapter->fw_download_sema))
852 Adapter->bBinDownloaded=TRUE;
853 Adapter->bCfgDownloaded=TRUE;
854 atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
856 Adapter->CurrNumRecvDescs=0;
857 Adapter->downloadDDR = 0;
859 //setting the Mips to Run
860 Status = run_card_proc(Adapter);
861 if(Status)
863 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Firm Download Failed\n");
864 up(&Adapter->fw_download_sema);
865 up(&Adapter->NVMRdmWrmLock);
866 break;
868 else
869 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Firm Download Over...\n");
870 mdelay(10);
871 /* Wait for MailBox Interrupt */
872 if(StartInterruptUrb((PS_INTERFACE_ADAPTER)Adapter->pvInterfaceAdapter))
874 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
876 timeout = 5*HZ;
877 Adapter->waiting_to_fw_download_done = FALSE;
878 wait_event_timeout(Adapter->ioctl_fw_dnld_wait_queue,
879 Adapter->waiting_to_fw_download_done, timeout);
880 Adapter->fw_download_process_pid=INVALID_PID;
881 Adapter->fw_download_done=TRUE;
882 atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
883 Adapter->CurrNumRecvDescs = 0;
884 Adapter->PrevNumRecvDescs = 0;
885 atomic_set(&Adapter->cntrlpktCnt,0);
886 Adapter->LinkUpStatus = 0;
887 Adapter->LinkStatus = 0;
889 if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
891 Adapter->DriverState = FW_DOWNLOAD_DONE;
892 wake_up(&Adapter->LEDInfo.notify_led_event);
895 if(!timeout)
897 Status = -ENODEV;
900 else
902 Status = -EINVAL;
904 up(&Adapter->fw_download_sema);
905 up(&Adapter->NVMRdmWrmLock);
906 break;
908 case IOCTL_BE_BUCKET_SIZE:
909 Status = 0;
910 if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
911 Status = -EFAULT;
912 break;
914 case IOCTL_RTPS_BUCKET_SIZE:
915 Status = 0;
916 if (get_user(Adapter->rtPSBucketSize, (unsigned long __user *)arg))
917 Status = -EFAULT;
918 break;
919 case IOCTL_CHIP_RESET:
921 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
922 if(NVMAccess)
924 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, " IOCTL_BCM_CHIP_RESET not allowed as EEPROM Read/Write is in progress\n");
925 return -EACCES;
927 down(&Adapter->RxAppControlQueuelock);
928 Status = reset_card_proc(Adapter);
929 flushAllAppQ();
930 up(&Adapter->RxAppControlQueuelock);
931 up(&Adapter->NVMRdmWrmLock);
932 ResetCounters(Adapter);
933 break;
935 case IOCTL_QOS_THRESHOLD:
937 USHORT uiLoopIndex;
939 Status = 0;
940 for (uiLoopIndex = 0; uiLoopIndex < NO_OF_QUEUES; uiLoopIndex++) {
941 if (get_user(Adapter->PackInfo[uiLoopIndex].uiThreshold,
942 (unsigned long __user *)arg)) {
943 Status = -EFAULT;
944 break;
947 break;
950 case IOCTL_DUMP_PACKET_INFO:
952 DumpPackInfo(Adapter);
953 DumpPhsRules(&Adapter->stBCMPhsContext);
954 Status = STATUS_SUCCESS;
955 break;
957 case IOCTL_GET_PACK_INFO:
958 if(copy_to_user(argp, &Adapter->PackInfo, sizeof(PacketInfo)*NO_OF_QUEUES))
959 return -EFAULT;
960 Status = STATUS_SUCCESS;
961 break;
962 case IOCTL_BCM_SWITCH_TRANSFER_MODE:
964 UINT uiData = 0;
965 if(copy_from_user(&uiData, argp, sizeof(UINT)))
966 return -EFAULT;
968 if(uiData) /* Allow All Packets */
970 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: ETH_PACKET_TUNNELING_MODE\n");
971 Adapter->TransferMode = ETH_PACKET_TUNNELING_MODE;
973 else /* Allow IP only Packets */
975 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SWITCH_TRANSFER_MODE: IP_PACKET_ONLY_MODE\n");
976 Adapter->TransferMode = IP_PACKET_ONLY_MODE;
978 Status = STATUS_SUCCESS;
979 break;
982 case IOCTL_BCM_GET_DRIVER_VERSION:
984 /* Copy Ioctl Buffer structure */
985 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
986 return -EFAULT;
988 if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength))
989 return -EFAULT;
990 Status = STATUS_SUCCESS;
991 break;
993 case IOCTL_BCM_GET_CURRENT_STATUS:
995 LINK_STATE link_state;
997 /* Copy Ioctl Buffer structure */
998 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1000 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
1001 Status = -EFAULT;
1002 break;
1004 if (IoBuffer.OutputLength != sizeof(link_state)) {
1005 Status = -EINVAL;
1006 break;
1009 memset(&link_state, 0, sizeof(link_state));
1010 link_state.bIdleMode = Adapter->IdleMode;
1011 link_state.bShutdownMode = Adapter->bShutStatus;
1012 link_state.ucLinkStatus = Adapter->LinkStatus;
1014 if (copy_to_user(IoBuffer.OutputBuffer, &link_state,
1015 min_t(size_t, sizeof(link_state), IoBuffer.OutputLength)))
1017 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
1018 Status = -EFAULT;
1019 break;
1021 Status = STATUS_SUCCESS;
1022 break;
1024 case IOCTL_BCM_SET_MAC_TRACING:
1026 UINT tracing_flag;
1028 /* copy ioctl Buffer structure */
1029 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1030 return -EFAULT;
1032 if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT)))
1033 return -EFAULT;
1035 if (tracing_flag)
1036 Adapter->pTarangs->MacTracingEnabled = TRUE;
1037 else
1038 Adapter->pTarangs->MacTracingEnabled = FALSE;
1039 break;
1041 case IOCTL_BCM_GET_DSX_INDICATION:
1043 ULONG ulSFId=0;
1044 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1045 return -EFAULT;
1047 if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt))
1049 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,
1050 "Mismatch req: %lx needed is =0x%zx!!!",
1051 IoBuffer.OutputLength, sizeof(stLocalSFAddIndicationAlt));
1052 return -EINVAL;
1055 if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
1056 return -EFAULT;
1058 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Get DSX Data SF ID is =%lx\n", ulSFId );
1059 get_dsx_sf_data_to_application(Adapter, ulSFId, IoBuffer.OutputBuffer);
1060 Status=STATUS_SUCCESS;
1062 break;
1063 case IOCTL_BCM_GET_HOST_MIBS:
1065 PVOID temp_buff;
1067 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1068 return -EFAULT;
1070 if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS))
1072 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,
1073 "Length Check failed %lu %zd\n",
1074 IoBuffer.OutputLength, sizeof(S_MIBS_HOST_STATS_MIBS));
1075 return -EINVAL;
1078 /* FIXME: HOST_STATS are too big for kmalloc (122048)! */
1079 temp_buff = kzalloc(sizeof(S_MIBS_HOST_STATS_MIBS), GFP_KERNEL);
1080 if(!temp_buff)
1081 return STATUS_FAILURE;
1083 Status = ProcessGetHostMibs(Adapter, temp_buff);
1084 GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
1086 if (Status != STATUS_FAILURE)
1087 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS)))
1088 Status = -EFAULT;
1090 kfree(temp_buff);
1091 break;
1094 case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
1095 if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode))
1097 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
1098 Adapter->bWakeUpDevice = TRUE;
1099 wake_up(&Adapter->process_rx_cntrlpkt);
1101 Status = STATUS_SUCCESS;
1102 break;
1104 case IOCTL_BCM_BULK_WRM:
1106 PBULKWRM_BUFFER pBulkBuffer;
1107 UINT uiTempVar=0;
1108 PCHAR pvBuffer = NULL;
1110 if((Adapter->IdleMode == TRUE) ||
1111 (Adapter->bShutStatus ==TRUE) ||
1112 (Adapter->bPreparingForLowPowerMode ==TRUE))
1114 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n");
1115 Status = -EACCES;
1116 break;
1119 /* Copy Ioctl Buffer structure */
1120 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1121 return -EFAULT;
1123 /* FIXME: restrict length */
1124 pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
1125 if(!pvBuffer)
1126 return -ENOMEM;
1128 /* Get WrmBuffer structure */
1129 if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
1131 kfree(pvBuffer);
1132 Status = -EFAULT;
1133 break;
1136 pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
1138 if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
1139 ((ULONG)pBulkBuffer->Register & 0x3))
1141 kfree(pvBuffer);
1142 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"WRM Done On invalid Address : %x Access Denied.\n",(int)pBulkBuffer->Register);
1143 Status = -EINVAL;
1144 break;
1148 uiTempVar = pBulkBuffer->Register & EEPROM_REJECT_MASK;
1149 if(!((Adapter->pstargetparams->m_u32Customize)&VSG_MODE)
1150 && ((uiTempVar == EEPROM_REJECT_REG_1)||
1151 (uiTempVar == EEPROM_REJECT_REG_2) ||
1152 (uiTempVar == EEPROM_REJECT_REG_3) ||
1153 (uiTempVar == EEPROM_REJECT_REG_4)) &&
1154 (cmd == IOCTL_BCM_REGISTER_WRITE))
1156 kfree(pvBuffer);
1157 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0,"EEPROM Access Denied, not in VSG Mode\n");
1158 Status = -EFAULT;
1159 break;
1162 if(pBulkBuffer->SwapEndian == FALSE)
1163 Status = wrmWithLock(Adapter, (UINT)pBulkBuffer->Register, (PCHAR)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
1164 else
1165 Status = wrmaltWithLock(Adapter, (UINT)pBulkBuffer->Register, (PUINT)pBulkBuffer->Values, IoBuffer.InputLength - 2*sizeof(ULONG));
1167 if(Status != STATUS_SUCCESS)
1169 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
1172 kfree(pvBuffer);
1173 break;
1176 case IOCTL_BCM_GET_NVM_SIZE:
1177 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1178 return -EFAULT;
1180 if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) {
1181 if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT)))
1182 return -EFAULT;
1184 Status = STATUS_SUCCESS ;
1185 break;
1187 case IOCTL_BCM_CAL_INIT :
1190 UINT uiSectorSize = 0 ;
1191 if(Adapter->eNVMType == NVM_FLASH)
1193 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1194 return -EFAULT;
1196 if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
1197 return -EFAULT;
1199 if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
1201 if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize,
1202 sizeof(UINT)))
1203 return -EFAULT;
1205 else
1207 if(IsFlash2x(Adapter))
1209 if (copy_to_user(IoBuffer.OutputBuffer,
1210 &Adapter->uiSectorSize ,
1211 sizeof(UINT)))
1212 return -EFAULT;
1214 else
1216 if((TRUE == Adapter->bShutStatus) ||
1217 (TRUE == Adapter->IdleMode))
1219 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n");
1220 return -EACCES;
1223 Adapter->uiSectorSize = uiSectorSize ;
1224 BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize);
1227 Status = STATUS_SUCCESS ;
1229 else
1231 Status = STATUS_FAILURE;
1234 break;
1235 case IOCTL_BCM_SET_DEBUG :
1236 #ifdef DEBUG
1238 USER_BCM_DBG_STATE sUserDebugState;
1240 // BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG );
1242 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "In SET_DEBUG ioctl\n");
1243 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1244 return -EFAULT;
1246 if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)))
1247 return -EFAULT;
1250 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "IOCTL_BCM_SET_DEBUG: OnOff=%d Type = 0x%x ",
1251 sUserDebugState.OnOff, sUserDebugState.Type);
1252 //sUserDebugState.Subtype <<= 1;
1253 sUserDebugState.Subtype = 1 << sUserDebugState.Subtype;
1254 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "actual Subtype=0x%x\n", sUserDebugState.Subtype);
1256 // Update new 'DebugState' in the Adapter
1257 Adapter->stDebugState.type |= sUserDebugState.Type;
1258 /* Subtype: A bitmap of 32 bits for Subtype per Type.
1259 * Valid indexes in 'subtype' array: 1,2,4,8
1260 * corresponding to valid Type values. Hence we can use the 'Type' field
1261 * as the index value, ignoring the array entries 0,3,5,6,7 !
1263 if (sUserDebugState.OnOff)
1264 Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype;
1265 else
1266 Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype;
1268 BCM_SHOW_DEBUG_BITMAP(Adapter);
1271 #endif
1272 break;
1273 case IOCTL_BCM_NVM_READ:
1274 case IOCTL_BCM_NVM_WRITE:
1276 NVM_READWRITE stNVMReadWrite;
1277 PUCHAR pReadData = NULL;
1278 ULONG ulDSDMagicNumInUsrBuff = 0;
1279 struct timeval tv0, tv1;
1280 memset(&tv0,0,sizeof(struct timeval));
1281 memset(&tv1,0,sizeof(struct timeval));
1282 if((Adapter->eNVMType == NVM_FLASH) && (Adapter->uiFlashLayoutMajorVersion == 0))
1284 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,"The Flash Control Section is Corrupted. Hence Rejection on NVM Read/Write\n");
1285 Status = -EFAULT;
1286 break;
1289 if(IsFlash2x(Adapter))
1291 if((Adapter->eActiveDSD != DSD0) &&
1292 (Adapter->eActiveDSD != DSD1) &&
1293 (Adapter->eActiveDSD != DSD2))
1295 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked");
1296 return STATUS_FAILURE ;
1300 /* Copy Ioctl Buffer structure */
1302 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1303 return -EFAULT;
1305 if(copy_from_user(&stNVMReadWrite,
1306 (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
1307 sizeof(NVM_READWRITE)))
1308 return -EFAULT;
1311 // Deny the access if the offset crosses the cal area limit.
1313 if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize)
1315 //BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Can't allow access beyond NVM Size: 0x%x 0x%x\n", stNVMReadWrite.uiOffset ,
1316 // stNVMReadWrite.uiNumBytes);
1317 Status = STATUS_FAILURE;
1318 break;
1321 pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
1322 if(!pReadData)
1323 return -ENOMEM;
1325 if(copy_from_user(pReadData, stNVMReadWrite.pBuffer,
1326 stNVMReadWrite.uiNumBytes))
1328 Status = -EFAULT;
1329 kfree(pReadData);
1330 break;
1333 do_gettimeofday(&tv0);
1334 if(IOCTL_BCM_NVM_READ == cmd)
1336 down(&Adapter->NVMRdmWrmLock);
1338 if((Adapter->IdleMode == TRUE) ||
1339 (Adapter->bShutStatus ==TRUE) ||
1340 (Adapter->bPreparingForLowPowerMode ==TRUE))
1342 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1343 up(&Adapter->NVMRdmWrmLock);
1344 kfree(pReadData);
1345 return -EACCES;
1348 Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
1349 stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
1351 up(&Adapter->NVMRdmWrmLock);
1353 if(Status != STATUS_SUCCESS)
1355 kfree(pReadData);
1356 return Status;
1358 if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes))
1360 kfree(pReadData);
1361 Status = -EFAULT;
1364 else
1367 down(&Adapter->NVMRdmWrmLock);
1369 if((Adapter->IdleMode == TRUE) ||
1370 (Adapter->bShutStatus ==TRUE) ||
1371 (Adapter->bPreparingForLowPowerMode ==TRUE))
1373 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1374 up(&Adapter->NVMRdmWrmLock);
1375 kfree(pReadData);
1376 return -EACCES;
1379 Adapter->bHeaderChangeAllowed = TRUE ;
1380 if(IsFlash2x(Adapter))
1383 New Requirement:-
1384 DSD section updation will be allowed in two case:-
1385 1. if DSD sig is present in DSD header means dongle is ok and updation is fruitfull
1386 2. if point 1 failes then user buff should have DSD sig. this point ensures that if dongle is
1387 corrupted then user space program first modify the DSD header with valid DSD sig so
1388 that this as well as further write may be worthwhile.
1390 This restriction has been put assuming that if DSD sig is corrupted, DSD
1391 data won't be considered valid.
1395 Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD);
1396 if(Status != STATUS_SUCCESS)
1398 if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) ||
1399 (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE))
1401 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
1402 up(&Adapter->NVMRdmWrmLock);
1403 kfree(pReadData);
1404 return Status;
1407 ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
1408 if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER)
1410 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DSD Sig is present neither in Flash nor User provided Input..");
1411 up(&Adapter->NVMRdmWrmLock);
1412 kfree(pReadData);
1413 return Status;
1417 Status = BeceemNVMWrite(Adapter, (PUINT )pReadData,
1418 stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
1419 if(IsFlash2x(Adapter))
1420 BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD);
1422 Adapter->bHeaderChangeAllowed = FALSE ;
1424 up(&Adapter->NVMRdmWrmLock);
1427 if(Status != STATUS_SUCCESS)
1429 kfree(pReadData);
1430 return Status;
1433 do_gettimeofday(&tv1);
1434 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 kfree(pReadData);
1438 Status = STATUS_SUCCESS;
1440 break;
1441 case IOCTL_BCM_FLASH2X_SECTION_READ :
1444 FLASH2X_READWRITE sFlash2xRead = {0};
1445 PUCHAR pReadBuff = NULL ;
1446 UINT NOB = 0;
1447 UINT BuffSize = 0;
1448 UINT ReadBytes = 0;
1449 UINT ReadOffset = 0;
1450 void __user *OutPutBuff;
1452 if(IsFlash2x(Adapter) != TRUE)
1454 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1455 return -EINVAL;
1458 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_FLASH2X_SECTION_READ Called");
1459 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1460 return -EFAULT;
1462 //Reading FLASH 2.x READ structure
1463 if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)))
1464 return -EFAULT;
1467 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xRead.Section);
1468 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%x" ,sFlash2xRead.offset);
1469 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xRead.numOfBytes);
1470 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xRead.bVerify);
1472 //This was internal to driver for raw read. now it has ben exposed to user space app.
1473 if(validateFlash2xReadWrite(Adapter,&sFlash2xRead) == FALSE)
1474 return STATUS_FAILURE ;
1476 NOB = sFlash2xRead.numOfBytes;
1477 if(NOB > Adapter->uiSectorSize )
1478 BuffSize = Adapter->uiSectorSize;
1479 else
1480 BuffSize = NOB ;
1482 ReadOffset = sFlash2xRead.offset ;
1483 OutPutBuff = IoBuffer.OutputBuffer;
1486 pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
1487 if(pReadBuff == NULL)
1489 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
1490 return -ENOMEM;
1492 down(&Adapter->NVMRdmWrmLock);
1494 if((Adapter->IdleMode == TRUE) ||
1495 (Adapter->bShutStatus ==TRUE) ||
1496 (Adapter->bPreparingForLowPowerMode ==TRUE))
1498 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1499 up(&Adapter->NVMRdmWrmLock);
1500 kfree(pReadBuff);
1501 return -EACCES;
1504 while(NOB)
1507 if(NOB > Adapter->uiSectorSize )
1508 ReadBytes = Adapter->uiSectorSize;
1509 else
1510 ReadBytes = NOB;
1513 //Reading the data from Flash 2.x
1515 Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes);
1516 if(Status)
1518 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status);
1519 break ;
1522 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes);
1524 Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
1525 if(Status)
1527 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status);
1528 break;
1530 NOB = NOB - ReadBytes;
1531 if(NOB)
1533 ReadOffset = ReadOffset + ReadBytes ;
1534 OutPutBuff = OutPutBuff + ReadBytes ;
1538 up(&Adapter->NVMRdmWrmLock);
1539 kfree(pReadBuff);
1542 break ;
1543 case IOCTL_BCM_FLASH2X_SECTION_WRITE :
1545 FLASH2X_READWRITE sFlash2xWrite = {0};
1546 PUCHAR pWriteBuff;
1547 void __user *InputAddr;
1548 UINT NOB = 0;
1549 UINT BuffSize = 0;
1550 UINT WriteOffset = 0;
1551 UINT WriteBytes = 0;
1553 if(IsFlash2x(Adapter) != TRUE)
1555 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1556 return -EINVAL;
1559 //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite
1560 Adapter->bAllDSDWriteAllow = FALSE;
1563 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_FLASH2X_SECTION_WRITE Called");
1564 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1565 return -EFAULT;
1567 //Reading FLASH 2.x READ structure
1568 if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
1569 return -EFAULT;
1571 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.Section :%x" ,sFlash2xWrite.Section);
1572 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.offset :%d" ,sFlash2xWrite.offset);
1573 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.numOfBytes :%x" ,sFlash2xWrite.numOfBytes);
1574 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\nsFlash2xRead.bVerify :%x\n" ,sFlash2xWrite.bVerify);
1575 if((sFlash2xWrite.Section != VSA0) && (sFlash2xWrite.Section != VSA1) &&
1576 (sFlash2xWrite.Section != VSA2) )
1578 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed");
1579 return -EINVAL;
1582 if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE)
1583 return STATUS_FAILURE ;
1585 InputAddr = sFlash2xWrite.pDataBuff;
1586 WriteOffset = sFlash2xWrite.offset ;
1587 NOB = sFlash2xWrite.numOfBytes;
1589 if(NOB > Adapter->uiSectorSize )
1590 BuffSize = Adapter->uiSectorSize;
1591 else
1592 BuffSize = NOB ;
1594 pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
1595 if(pWriteBuff == NULL)
1596 return -ENOMEM;
1599 //extracting the remainder of the given offset.
1600 WriteBytes = Adapter->uiSectorSize ;
1601 if(WriteOffset % Adapter->uiSectorSize)
1602 WriteBytes =Adapter->uiSectorSize - (WriteOffset % Adapter->uiSectorSize);
1603 if(NOB < WriteBytes)
1604 WriteBytes = NOB;
1606 down(&Adapter->NVMRdmWrmLock);
1608 if((Adapter->IdleMode == TRUE) ||
1609 (Adapter->bShutStatus ==TRUE) ||
1610 (Adapter->bPreparingForLowPowerMode ==TRUE))
1612 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1613 up(&Adapter->NVMRdmWrmLock);
1614 kfree(pWriteBuff);
1615 return -EACCES;
1618 BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section);
1621 Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes);
1622 if(Status)
1624 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status);
1625 break ;
1627 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pWriteBuff,WriteBytes);
1628 //Writing the data from Flash 2.x
1629 Status = BcmFlash2xBulkWrite(Adapter,(PUINT)pWriteBuff,sFlash2xWrite.Section,WriteOffset,WriteBytes,sFlash2xWrite.bVerify);
1631 if(Status)
1633 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
1634 break ;
1637 NOB = NOB - WriteBytes;
1638 if(NOB)
1640 WriteOffset = WriteOffset + WriteBytes ;
1641 InputAddr = InputAddr + WriteBytes ;
1642 if(NOB > Adapter->uiSectorSize )
1643 WriteBytes = Adapter->uiSectorSize;
1644 else
1645 WriteBytes = NOB;
1649 } while(NOB > 0);
1650 BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section);
1651 up(&Adapter->NVMRdmWrmLock);
1652 kfree(pWriteBuff);
1654 break ;
1655 case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP :
1658 PFLASH2X_BITMAP psFlash2xBitMap;
1659 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
1661 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1662 return -EFAULT;
1664 if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
1665 return -EINVAL;
1667 psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
1668 if(psFlash2xBitMap == NULL)
1670 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available");
1671 return -ENOMEM ;
1673 //Reading the Flash Sectio Bit map
1674 down(&Adapter->NVMRdmWrmLock);
1676 if((Adapter->IdleMode == TRUE) ||
1677 (Adapter->bShutStatus ==TRUE) ||
1678 (Adapter->bPreparingForLowPowerMode ==TRUE))
1680 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1681 up(&Adapter->NVMRdmWrmLock);
1682 kfree(psFlash2xBitMap);
1683 return -EACCES;
1686 BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
1687 up(&Adapter->NVMRdmWrmLock);
1688 if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)))
1689 Status = -EFAULT;
1691 kfree(psFlash2xBitMap);
1693 break ;
1694 case IOCTL_BCM_SET_ACTIVE_SECTION :
1696 FLASH2X_SECTION_VAL eFlash2xSectionVal = 0;
1697 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_SET_ACTIVE_SECTION Called");
1699 if(IsFlash2x(Adapter) != TRUE)
1701 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1702 return -EINVAL;
1705 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1706 if(Status)
1708 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1709 return Status;
1712 Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT));
1713 if(Status)
1715 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
1716 return Status;
1719 down(&Adapter->NVMRdmWrmLock);
1721 if((Adapter->IdleMode == TRUE) ||
1722 (Adapter->bShutStatus ==TRUE) ||
1723 (Adapter->bPreparingForLowPowerMode ==TRUE))
1725 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1726 up(&Adapter->NVMRdmWrmLock);
1727 return -EACCES;
1730 Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal);
1731 if(Status)
1733 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status);
1735 up(&Adapter->NVMRdmWrmLock);
1737 break ;
1738 case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION :
1740 //Right Now we are taking care of only DSD
1741 Adapter->bAllDSDWriteAllow = FALSE ;
1742 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_IDENTIFY_ACTIVE_SECTION called");
1744 Status = STATUS_SUCCESS ;
1746 break ;
1747 case IOCTL_BCM_COPY_SECTION :
1749 FLASH2X_COPY_SECTION sCopySectStrut = {0};
1750 Status = STATUS_SUCCESS;
1751 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_COPY_SECTION Called");
1753 Adapter->bAllDSDWriteAllow = FALSE ;
1754 if(IsFlash2x(Adapter) != TRUE)
1756 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1757 return -EINVAL;
1760 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1761 if(Status)
1763 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
1764 return Status;
1767 Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
1768 if(Status)
1770 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
1771 return Status;
1773 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Source SEction :%x", sCopySectStrut.SrcSection);
1774 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Destination SEction :%x", sCopySectStrut.DstSection);
1775 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "offset :%x", sCopySectStrut.offset);
1776 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "NOB :%x", sCopySectStrut.numOfBytes);
1779 if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE)
1781 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection);
1782 return -EINVAL;
1785 if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE)
1787 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection);
1788 return -EINVAL;
1791 if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection)
1793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different");
1794 return -EINVAL;
1797 down(&Adapter->NVMRdmWrmLock);
1799 if((Adapter->IdleMode == TRUE) ||
1800 (Adapter->bShutStatus ==TRUE) ||
1801 (Adapter->bPreparingForLowPowerMode ==TRUE))
1803 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1804 up(&Adapter->NVMRdmWrmLock);
1805 return -EACCES;
1808 if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2)
1810 if(IsNonCDLessDevice(Adapter))
1812 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!");
1813 Status = -EINVAL ;
1815 else if(sCopySectStrut.numOfBytes == 0)
1817 Status = BcmCopyISO(Adapter,sCopySectStrut);
1819 else
1821 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed..");
1822 Status = STATUS_FAILURE ;
1824 up(&Adapter->NVMRdmWrmLock);
1825 return Status;
1828 Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
1829 sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes);
1830 up(&Adapter->NVMRdmWrmLock);
1832 break ;
1833 case IOCTL_BCM_GET_FLASH_CS_INFO :
1835 Status = STATUS_SUCCESS;
1836 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
1838 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1839 if(Status)
1841 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1842 break;
1844 if(Adapter->eNVMType != NVM_FLASH)
1846 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash");
1847 Status = -EINVAL;
1848 break;
1850 if(IsFlash2x(Adapter) == TRUE)
1853 if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO))
1854 return -EINVAL;
1856 if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)))
1857 return -EFAULT;
1859 else
1861 if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO))
1862 return -EINVAL;
1864 if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)))
1865 return -EFAULT;
1869 break ;
1870 case IOCTL_BCM_SELECT_DSD :
1872 UINT SectOfset = 0;
1873 FLASH2X_SECTION_VAL eFlash2xSectionVal;
1874 eFlash2xSectionVal = NO_SECTION_VAL ;
1875 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_SELECT_DSD Called");
1877 if(IsFlash2x(Adapter) != TRUE)
1879 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1880 return -EINVAL;
1883 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1884 if(Status)
1886 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1887 return Status;
1889 Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
1890 if(Status)
1892 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
1893 return Status;
1896 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Read Section :%d", eFlash2xSectionVal);
1897 if((eFlash2xSectionVal != DSD0) &&
1898 (eFlash2xSectionVal != DSD1) &&
1899 (eFlash2xSectionVal != DSD2) )
1901 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal);
1902 return STATUS_FAILURE ;
1905 SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
1906 if(SectOfset == INVALID_OFFSET)
1908 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Provided Section val <%d> does not exixt in Flash 2.x", eFlash2xSectionVal);
1909 return -EINVAL;
1912 Adapter->bAllDSDWriteAllow = TRUE ;
1914 Adapter->ulFlashCalStart = SectOfset ;
1915 Adapter->eActiveDSD = eFlash2xSectionVal;
1917 Status = STATUS_SUCCESS ;
1918 break;
1920 case IOCTL_BCM_NVM_RAW_READ :
1923 NVM_READWRITE stNVMRead;
1924 INT NOB ;
1925 INT BuffSize ;
1926 INT ReadOffset = 0;
1927 UINT ReadBytes = 0 ;
1928 PUCHAR pReadBuff;
1929 void __user *OutPutBuff;
1931 if(Adapter->eNVMType != NVM_FLASH)
1933 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash ");
1934 return -EINVAL ;
1937 /* Copy Ioctl Buffer structure */
1938 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1940 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
1941 Status = -EFAULT;
1942 break;
1945 if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE)))
1946 return -EFAULT;
1948 NOB = stNVMRead.uiNumBytes;
1949 //In Raw-Read max Buff size : 64MB
1951 if(NOB > DEFAULT_BUFF_SIZE)
1952 BuffSize = DEFAULT_BUFF_SIZE;
1953 else
1954 BuffSize = NOB ;
1956 ReadOffset = stNVMRead.uiOffset;
1957 OutPutBuff = stNVMRead.pBuffer;
1959 pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
1960 if(pReadBuff == NULL)
1962 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
1963 Status = -ENOMEM;
1964 break;
1966 down(&Adapter->NVMRdmWrmLock);
1968 if((Adapter->IdleMode == TRUE) ||
1969 (Adapter->bShutStatus ==TRUE) ||
1970 (Adapter->bPreparingForLowPowerMode ==TRUE))
1972 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1973 kfree(pReadBuff);
1974 up(&Adapter->NVMRdmWrmLock);
1975 return -EACCES;
1978 Adapter->bFlashRawRead = TRUE ;
1979 while(NOB)
1981 if(NOB > DEFAULT_BUFF_SIZE )
1982 ReadBytes = DEFAULT_BUFF_SIZE;
1983 else
1984 ReadBytes = NOB;
1986 //Reading the data from Flash 2.x
1987 Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes);
1988 if(Status)
1990 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
1991 break;
1994 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes);
1996 Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
1997 if(Status)
1999 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status);
2000 break;
2002 NOB = NOB - ReadBytes;
2003 if(NOB)
2005 ReadOffset = ReadOffset + ReadBytes ;
2006 OutPutBuff = OutPutBuff + ReadBytes ;
2010 Adapter->bFlashRawRead = FALSE ;
2011 up(&Adapter->NVMRdmWrmLock);
2012 kfree(pReadBuff);
2013 break ;
2016 case IOCTL_BCM_CNTRLMSG_MASK:
2018 ULONG RxCntrlMsgBitMask = 0 ;
2020 /* Copy Ioctl Buffer structure */
2021 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
2022 if(Status)
2024 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of Ioctl buffer is failed from user space");
2025 Status = -EFAULT;
2026 break;
2029 if (IoBuffer.InputLength != sizeof(unsigned long)) {
2030 Status = -EINVAL;
2031 break;
2034 Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength);
2035 if(Status)
2037 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"copy of control bit mask failed from user space");
2038 Status = -EFAULT;
2039 break;
2041 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"\n Got user defined cntrl msg bit mask :%lx", RxCntrlMsgBitMask);
2042 pTarang->RxCntrlMsgBitMask = RxCntrlMsgBitMask ;
2044 break;
2045 case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
2047 DEVICE_DRIVER_INFO DevInfo;
2049 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
2051 DevInfo.MaxRDMBufferSize = BUFFER_4K;
2052 DevInfo.u32DSDStartOffset = EEPROM_CALPARAM_START;
2053 DevInfo.u32RxAlignmentCorrection = 0;
2054 DevInfo.u32NVMType = Adapter->eNVMType;
2055 DevInfo.u32InterfaceType = BCM_USB;
2057 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
2058 return -EFAULT;
2060 if(IoBuffer.OutputLength < sizeof(DevInfo))
2061 return -EINVAL;
2063 if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
2064 return -EFAULT;
2066 break ;
2068 case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
2070 ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
2072 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
2074 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
2075 return -EFAULT;
2077 if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
2078 return -EINVAL;
2080 stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
2082 if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
2083 return -EFAULT;
2086 break;
2088 case IOCTL_CLOSE_NOTIFICATION:
2089 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION");
2090 break;
2092 default:
2093 pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
2094 Status = STATUS_FAILURE;
2095 break;
2097 return Status;
2101 static const struct file_operations bcm_fops = {
2102 .owner = THIS_MODULE,
2103 .open = bcm_char_open,
2104 .release = bcm_char_release,
2105 .read = bcm_char_read,
2106 .unlocked_ioctl = bcm_char_ioctl,
2107 .llseek = no_llseek,
2110 extern struct class *bcm_class;
2112 int register_control_device_interface(PMINI_ADAPTER Adapter)
2115 if (Adapter->major > 0)
2116 return Adapter->major;
2118 Adapter->major = register_chrdev(0, DEV_NAME, &bcm_fops);
2119 if (Adapter->major < 0) {
2120 pr_err(DRV_NAME ": could not created character device\n");
2121 return Adapter->major;
2124 Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL,
2125 MKDEV(Adapter->major, 0),
2126 Adapter, DEV_NAME);
2128 if (IS_ERR(Adapter->pstCreatedClassDevice)) {
2129 pr_err(DRV_NAME ": class device create failed\n");
2130 unregister_chrdev(Adapter->major, DEV_NAME);
2131 return PTR_ERR(Adapter->pstCreatedClassDevice);
2134 return 0;
2137 void unregister_control_device_interface(PMINI_ADAPTER Adapter)
2139 if (Adapter->major > 0) {
2140 device_destroy(bcm_class, MKDEV(Adapter->major, 0));
2141 unregister_chrdev(Adapter->major, DEV_NAME);