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