1 #include <linux/fs.h>
2
3 #include "headers.h"
4 /***************************************************************
5 * Function - bcm_char_open()
6 *
7 * Description - This is the "open" entry point for the character
8 * driver.
9 *
10 * Parameters - inode: Pointer to the Inode structure of char device
11 * filp : File pointer of the char device
12 *
13 * Returns - Zero(Success)
14 ****************************************************************/
15
bcm_char_open(struct inode * inode,struct file * filp)16 static int bcm_char_open(struct inode *inode, struct file * filp)
17 {
18 PMINI_ADAPTER Adapter = NULL;
19 PPER_TARANG_DATA pTarang = NULL;
20
21 Adapter = GET_BCM_ADAPTER(gblpnetdev);
22 pTarang = kzalloc(sizeof(PER_TARANG_DATA), GFP_KERNEL);
23 if (!pTarang)
24 return -ENOMEM;
25
26 pTarang->Adapter = Adapter;
27 pTarang->RxCntrlMsgBitMask = 0xFFFFFFFF & ~(1 << 0xB);
28
29 down(&Adapter->RxAppControlQueuelock);
30 pTarang->next = Adapter->pTarangs;
31 Adapter->pTarangs = pTarang;
32 up(&Adapter->RxAppControlQueuelock);
33
34 /* Store the Adapter structure */
35 filp->private_data = pTarang;
36
37 /*Start Queuing the control response Packets*/
38 atomic_inc(&Adapter->ApplicationRunning);
39
40 nonseekable_open(inode, filp);
41 return 0;
42 }
43
bcm_char_release(struct inode * inode,struct file * filp)44 static int bcm_char_release(struct inode *inode, struct file *filp)
45 {
46 PPER_TARANG_DATA pTarang, tmp, ptmp;
47 PMINI_ADAPTER Adapter = NULL;
48 struct sk_buff *pkt, *npkt;
49
50 pTarang = (PPER_TARANG_DATA)filp->private_data;
51
52 if (pTarang == NULL) {
53 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_PRINTK, 0, 0,
54 "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 if (tmp == pTarang)
65 break;
66 }
67
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;
76 }
77
78 pkt = pTarang->RxAppControlHead;
79 while (pkt) {
80 npkt = pkt->next;
81 kfree_skb(pkt);
82 pkt = npkt;
83 }
84
85 up(&Adapter->RxAppControlQueuelock);
86
87 /*Stop Queuing the control response Packets*/
88 atomic_dec(&Adapter->ApplicationRunning);
89
90 kfree(pTarang);
91
92 /* remove this filp from the asynchronously notified filp's */
93 filp->private_data = NULL;
94 return 0;
95 }
96
bcm_char_read(struct file * filp,char __user * buf,size_t size,loff_t * f_pos)97 static ssize_t bcm_char_read(struct file *filp, char __user *buf, size_t size,
98 loff_t *f_pos)
99 {
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;
106
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;
114 }
115
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;
120 }
121
122 if (FALSE == Adapter->fw_download_done)
123 return -EACCES;
124
125 down(&Adapter->RxAppControlQueuelock);
126
127 if (pTarang->RxAppControlHead) {
128 Packet = pTarang->RxAppControlHead;
129 DEQUEUEPACKET(pTarang->RxAppControlHead,
130 pTarang->RxAppControlTail);
131 pTarang->AppCtrlQueueLen--;
132 }
133
134 up(&Adapter->RxAppControlQueuelock);
135
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;
145 }
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);
150 }
151
152 BCM_DEBUG_PRINT(Adapter, DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "<\n");
153 return PktLen;
154 }
155
bcm_char_ioctl(struct file * filp,UINT cmd,ULONG arg)156 static long bcm_char_ioctl(struct file *filp, UINT cmd, ULONG arg)
157 {
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;
164
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);
166
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;
175
176 if(Status)
177 return -EFAULT;
178
179 if(Adapter->device_removed)
180 {
181 return -EFAULT;
182 }
183
184 if(FALSE == Adapter->fw_download_done)
185 {
186 switch (cmd)
187 {
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;
199 }
200 }
201
202 Status = vendorextnIoctl(Adapter, cmd, arg);
203 if(Status != CONTINUE_COMMON_PATH )
204 return Status;
205
206 switch(cmd){
207 // Rdms for Swin Idle...
208 case IOCTL_BCM_REGISTER_READ_PRIVATE:
209 {
210 RDM_BUFFER sRdmBuffer = {0};
211 PCHAR temp_buff;
212 UINT Bufflen;
213
214 /* Copy Ioctl Buffer structure */
215 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
216 return -EFAULT;
217
218 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
219 return -EINVAL;
220
221 if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
222 return -EFAULT;
223
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;
229
230 Status = rdmalt(Adapter, (UINT)sRdmBuffer.Register,
231 (PUINT)temp_buff, Bufflen);
232 if(Status == STATUS_SUCCESS)
233 {
234 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, IoBuffer.OutputLength))
235 Status = -EFAULT;
236 }
237
238 kfree(temp_buff);
239 break;
240 }
241 case IOCTL_BCM_REGISTER_WRITE_PRIVATE:
242 {
243 WRM_BUFFER sWrmBuffer = {0};
244 UINT uiTempVar=0;
245 /* Copy Ioctl Buffer structure */
246
247 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
248 return -EFAULT;
249
250 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
251 return -EINVAL;
252
253 /* Get WrmBuffer structure */
254 if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
255 return -EFAULT;
256
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)))
263 {
264 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
265 return -EFAULT;
266 }
267 Status = wrmalt(Adapter, (UINT)sWrmBuffer.Register,
268 (PUINT)sWrmBuffer.Data, sizeof(ULONG));
269 if(Status == STATUS_SUCCESS)
270 {
271 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"WRM Done\n");
272 }
273 else
274 {
275 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
276 Status = -EFAULT;
277 }
278 break;
279 }
280
281 case IOCTL_BCM_REGISTER_READ:
282 case IOCTL_BCM_EEPROM_REGISTER_READ:
283 {
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))
290 {
291 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Rdms\n");
292 return -EACCES;
293 }
294 /* Copy Ioctl Buffer structure */
295 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
296 return -EFAULT;
297
298 if (IoBuffer.InputLength > sizeof(sRdmBuffer))
299 return -EINVAL;
300
301 if(copy_from_user(&sRdmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
302 return -EFAULT;
303
304 /* FIXME: don't trust user supplied length */
305 temp_buff = kmalloc(IoBuffer.OutputLength, GFP_KERNEL);
306 if(!temp_buff)
307 return STATUS_FAILURE;
308
309 if((((ULONG)sRdmBuffer.Register & 0x0F000000) != 0x0F000000) ||
310 ((ULONG)sRdmBuffer.Register & 0x3))
311 {
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;
315 }
316
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;
323
324 kfree(temp_buff);
325 break;
326 }
327 case IOCTL_BCM_REGISTER_WRITE:
328 case IOCTL_BCM_EEPROM_REGISTER_WRITE:
329 {
330 WRM_BUFFER sWrmBuffer = {0};
331 UINT uiTempVar=0;
332 if((Adapter->IdleMode == TRUE) ||
333 (Adapter->bShutStatus ==TRUE) ||
334 (Adapter->bPreparingForLowPowerMode ==TRUE))
335 {
336 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Device in Idle Mode, Blocking Wrms\n");
337 return -EACCES;
338 }
339
340 /* Copy Ioctl Buffer structure */
341 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
342 return -EFAULT;
343
344 if (IoBuffer.InputLength > sizeof(sWrmBuffer))
345 return -EINVAL;
346
347 /* Get WrmBuffer structure */
348 if(copy_from_user(&sWrmBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
349 return -EFAULT;
350
351 if( (((ULONG)sWrmBuffer.Register & 0x0F000000) != 0x0F000000) ||
352 ((ULONG)sWrmBuffer.Register & 0x3) )
353 {
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;
357 }
358
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))
366 {
367 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "EEPROM Access Denied, not in VSG Mode\n");
368 return -EFAULT;
369 }
370
371 Status = wrmaltWithLock(Adapter, (UINT)sWrmBuffer.Register,
372 (PUINT)sWrmBuffer.Data, sWrmBuffer.Length);
373 if(Status == STATUS_SUCCESS)
374 {
375 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, OSAL_DBG, DBG_LVL_ALL, "WRM Done\n");
376 }
377 else
378 {
379 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM Failed\n");
380 Status = -EFAULT;
381 }
382 break;
383 }
384 case IOCTL_BCM_GPIO_SET_REQUEST:
385 {
386 UCHAR ucResetValue[4];
387 UINT value =0;
388 UINT uiBit = 0;
389 UINT uiOperation = 0;
390
391 GPIO_INFO gpio_info = {0};
392 if((Adapter->IdleMode == TRUE) ||
393 (Adapter->bShutStatus ==TRUE) ||
394 (Adapter->bPreparingForLowPowerMode ==TRUE))
395 {
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;
398 }
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;
407
408 value= (1<<uiBit);
409
410 if(IsReqGpioIsLedInNVM(Adapter,value) ==FALSE)
411 {
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;
415 }
416
417
418 if(uiOperation)//Set - setting 1
419 {
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)
424 {
425 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Set the GPIO bit\n");
426 }
427 else
428 {
429 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to set the %dth GPIO \n",uiBit);
430 break;
431 }
432 }
433 else//Unset - setting 0
434 {
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)
439 {
440 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO bit\n");
441 }
442 else
443 {
444 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Failed to clear the %dth GPIO \n",uiBit);
445 break;
446 }
447 }
448
449 Status = rdmaltWithLock(Adapter, (UINT)GPIO_MODE_REGISTER,
450 (PUINT)ucResetValue, sizeof(UINT));
451 if (STATUS_SUCCESS != Status)
452 {
453 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"GPIO_MODE_REGISTER read failed");
454 break;
455 }
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)
461 {
462 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Set the GPIO to output Mode\n");
463 }
464 else
465 {
466 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "Failed to put GPIO in Output Mode\n");
467 break;
468 }
469 }
470 break;
471 case BCM_LED_THREAD_STATE_CHANGE_REQ:
472 {
473 USER_THREAD_REQ threadReq = { 0 };
474 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"User made LED thread InActive");
475
476 if((Adapter->IdleMode == TRUE) ||
477 (Adapter->bShutStatus ==TRUE) ||
478 (Adapter->bPreparingForLowPowerMode ==TRUE))
479 {
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;
483 }
484
485 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
486 return -EFAULT;
487
488 if (IoBuffer.InputLength > sizeof(threadReq))
489 return -EINVAL;
490
491 if (copy_from_user(&threadReq, IoBuffer.InputBuffer, IoBuffer.InputLength))
492 return -EFAULT;
493
494 //if LED thread is running(Actively or Inactively) set it state to make inactive
495 if(Adapter->LEDInfo.led_thread_running)
496 {
497 if(threadReq.ThreadState == LED_THREAD_ACTIVATION_REQ)
498 {
499 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Activating thread req");
500 Adapter->DriverState = LED_THREAD_ACTIVE;
501 }
502 else
503 {
504 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"DeActivating Thread req.....");
505 Adapter->DriverState = LED_THREAD_INACTIVE;
506 }
507
508 //signal thread.
509 wake_up(&Adapter->LEDInfo.notify_led_event);
510
511 }
512 }
513 break;
514 case IOCTL_BCM_GPIO_STATUS_REQUEST:
515 {
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)
534 {
535 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "RDM Failed\n");
536 return Status;
537 }
538
539 }
540 break;
541 case IOCTL_BCM_GPIO_MULTI_REQUEST:
542 {
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;
546
547 memset( pgpio_multi_info, 0, MAX_IDX * sizeof( GPIO_MULTI_INFO));
548
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;
559
560 if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_info[WIMAX_IDX].uiGPIOMask)== FALSE)
561 {
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;
565 }
566
567 /* Set the gpio output register */
568
569 if( ( pgpio_multi_info[WIMAX_IDX].uiGPIOMask) &
570 ( pgpio_multi_info[WIMAX_IDX].uiGPIOCommand))
571 {
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;
576
577 if( *(UINT*) ucResetValue)
578 Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_SET_REG , (PUINT) ucResetValue, sizeof(ULONG));
579
580 if( Status != STATUS_SUCCESS)
581 {
582 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_SET_REG Failed.");
583 return Status;
584 }
585
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)));
590
591 if( *(UINT*) ucResetValue)
592 Status = wrmaltWithLock( Adapter, BCM_GPIO_OUTPUT_CLR_REG , (PUINT) ucResetValue, sizeof(ULONG));
593
594 if( Status != STATUS_SUCCESS)
595 {
596 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to BCM_GPIO_OUTPUT_CLR_REG Failed." );
597 return Status;
598 }
599 }
600
601 if( pgpio_multi_info[WIMAX_IDX].uiGPIOMask)
602 {
603 Status = rdmaltWithLock(Adapter, (UINT)GPIO_PIN_STATE_REGISTER, (PUINT)ucResetValue, sizeof(UINT));
604
605 if(Status != STATUS_SUCCESS)
606 {
607 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"RDM to GPIO_PIN_STATE_REGISTER Failed.");
608 return Status;
609 }
610
611 pgpio_multi_info[WIMAX_IDX].uiGPIOValue = ( *(UINT*)ucResetValue &
612 pgpio_multi_info[WIMAX_IDX].uiGPIOMask);
613 }
614
615 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_info, IoBuffer.OutputLength);
616 if(Status)
617 {
618 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
619 break;
620 }
621 }
622 break;
623 case IOCTL_BCM_GPIO_MODE_REQUEST:
624 {
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;
628
629 if((Adapter->IdleMode == TRUE) ||
630 (Adapter->bShutStatus ==TRUE) ||
631 (Adapter->bPreparingForLowPowerMode ==TRUE))
632 return -EINVAL;
633
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;
640
641 Status = rdmaltWithLock( Adapter, ( UINT) GPIO_MODE_REGISTER, ( PUINT) ucResetValue, sizeof( UINT));
642 if( STATUS_SUCCESS != Status)
643 {
644 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Read of GPIO_MODE_REGISTER failed");
645 return Status;
646 }
647
648 //Validating the request
649 if(IsReqGpioIsLedInNVM(Adapter,pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)== FALSE)
650 {
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;
654 }
655
656 if( pgpio_multi_mode[WIMAX_IDX].uiGPIOMask)
657 {
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);
664
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;
669
670 Status = wrmaltWithLock( Adapter, GPIO_MODE_REGISTER , ( PUINT) ucResetValue, sizeof( ULONG));
671 if( Status == STATUS_SUCCESS)
672 {
673 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "WRM to GPIO_MODE_REGISTER Done");
674 }
675 else
676 {
677 BCM_DEBUG_PRINT( Adapter,DBG_TYPE_PRINTK, 0, 0,"WRM to GPIO_MODE_REGISTER Failed");
678 Status = -EFAULT;
679 break;
680 }
681 }
682 else /* if uiGPIOMask is 0 then return mode register configuration */
683 {
684 pgpio_multi_mode[WIMAX_IDX].uiGPIOMode = *( UINT*) ucResetValue;
685 }
686 Status = copy_to_user(IoBuffer.OutputBuffer, &gpio_multi_mode, IoBuffer.OutputLength);
687 if(Status)
688 {
689 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed while copying Content to IOBufer for user space err:%d",Status);
690 break;
691 }
692 }
693 break;
694
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:
701 {
702 PVOID pvBuffer=NULL;
703
704 /* Copy Ioctl Buffer structure */
705 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
706 return -EFAULT;
707
708 /* FIXME: don't accept any length from user */
709 pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
710 if(!pvBuffer)
711 return -ENOMEM;
712
713 if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
714 {
715 Status = -EFAULT;
716 kfree(pvBuffer);
717 break;
718 }
719
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;
726
727 if(Adapter->bPreparingForLowPowerMode)
728 {
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 ;
732 }
733 Status = CopyBufferToControlPacket(Adapter, (PVOID)pvBuffer);
734 cntrlEnd:
735 up(&Adapter->LowPowerModeSync);
736 kfree(pvBuffer);
737 break;
738 }
739 case IOCTL_BCM_BUFFER_DOWNLOAD_START:
740 {
741 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock) ;
742 if(NVMAccess)
743 {
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;
746 }
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))
749 {
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)
758 {
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;
763 }
764 mdelay(10);
765 }
766 else
767 {
768
769 Status = -EBUSY;
770
771 }
772 up(&Adapter->NVMRdmWrmLock);
773 break;
774 }
775 case IOCTL_BCM_BUFFER_DOWNLOAD:
776 {
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);
779 do{
780 if(!down_trylock(&Adapter->fw_download_sema))
781 {
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;
785 }
786
787 /* Copy Ioctl Buffer structure */
788 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
789 return -EFAULT;
790
791 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Length for FW DLD is : %lx\n",
792 IoBuffer.InputLength);
793
794 if (IoBuffer.InputLength > sizeof(FIRMWARE_INFO))
795 return -EINVAL;
796
797 psFwInfo = kmalloc(sizeof(*psFwInfo), GFP_KERNEL);
798 if(!psFwInfo)
799 return -ENOMEM;
800
801 if(copy_from_user(psFwInfo, IoBuffer.InputBuffer, IoBuffer.InputLength))
802 return -EFAULT;
803
804 if(!psFwInfo->pvMappedFirmwareAddress ||
805 (psFwInfo->u32FirmwareLength == 0))
806 {
807 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Something else is wrong %lu\n",
808 psFwInfo->u32FirmwareLength);
809 Status = -EINVAL;
810 break;
811 }
812 Status = bcm_ioctl_fw_download(Adapter, psFwInfo);
813 if(Status != STATUS_SUCCESS)
814 {
815 if(psFwInfo->u32StartingAddress==CONFIG_BEGIN_ADDR)
816 {
817 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Configuration File Upload Failed\n");
818 }
819 else
820 {
821 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "IOCTL: Firmware File Upload Failed\n");
822 }
823 //up(&Adapter->fw_download_sema);
824
825 if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
826 {
827 Adapter->DriverState = DRIVER_INIT;
828 Adapter->LEDInfo.bLedInitDone = FALSE;
829 wake_up(&Adapter->LEDInfo.notify_led_event);
830 }
831 }
832 break ;
833 }while(0);
834
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;
840 }
841 case IOCTL_BCM_BUFFER_DOWNLOAD_STOP:
842 {
843 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
844 if(NVMAccess)
845 {
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;
849 }
850 if(down_trylock(&Adapter->fw_download_sema))
851 {
852 Adapter->bBinDownloaded=TRUE;
853 Adapter->bCfgDownloaded=TRUE;
854 atomic_set(&Adapter->CurrNumFreeTxDesc, 0);
855
856 Adapter->CurrNumRecvDescs=0;
857 Adapter->downloadDDR = 0;
858
859 //setting the Mips to Run
860 Status = run_card_proc(Adapter);
861 if(Status)
862 {
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;
867 }
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))
873 {
874 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Unable to send interrupt...\n");
875 }
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;
888
889 if(Adapter->LEDInfo.led_thread_running & BCM_LED_THREAD_RUNNING_ACTIVELY)
890 {
891 Adapter->DriverState = FW_DOWNLOAD_DONE;
892 wake_up(&Adapter->LEDInfo.notify_led_event);
893 }
894
895 if(!timeout)
896 {
897 Status = -ENODEV;
898 }
899 }
900 else
901 {
902 Status = -EINVAL;
903 }
904 up(&Adapter->fw_download_sema);
905 up(&Adapter->NVMRdmWrmLock);
906 break;
907 }
908 case IOCTL_BE_BUCKET_SIZE:
909 Status = 0;
910 if (get_user(Adapter->BEBucketSize, (unsigned long __user *)arg))
911 Status = -EFAULT;
912 break;
913
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:
920 {
921 INT NVMAccess = down_trylock(&Adapter->NVMRdmWrmLock);
922 if(NVMAccess)
923 {
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;
926 }
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;
934 }
935 case IOCTL_QOS_THRESHOLD:
936 {
937 USHORT uiLoopIndex;
938
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;
945 }
946 }
947 break;
948 }
949
950 case IOCTL_DUMP_PACKET_INFO:
951
952 DumpPackInfo(Adapter);
953 DumpPhsRules(&Adapter->stBCMPhsContext);
954 Status = STATUS_SUCCESS;
955 break;
956
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:
963 {
964 UINT uiData = 0;
965 if(copy_from_user(&uiData, argp, sizeof(UINT)))
966 return -EFAULT;
967
968 if(uiData) /* Allow All Packets */
969 {
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;
972 }
973 else /* Allow IP only Packets */
974 {
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;
977 }
978 Status = STATUS_SUCCESS;
979 break;
980 }
981
982 case IOCTL_BCM_GET_DRIVER_VERSION:
983 {
984 /* Copy Ioctl Buffer structure */
985 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
986 return -EFAULT;
987
988 if(copy_to_user(IoBuffer.OutputBuffer, VER_FILEVERSION_STR, IoBuffer.OutputLength))
989 return -EFAULT;
990 Status = STATUS_SUCCESS;
991 break;
992 }
993 case IOCTL_BCM_GET_CURRENT_STATUS:
994 {
995 LINK_STATE link_state;
996
997 /* Copy Ioctl Buffer structure */
998 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
999 {
1000 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user failed..\n");
1001 Status = -EFAULT;
1002 break;
1003 }
1004 if (IoBuffer.OutputLength != sizeof(link_state)) {
1005 Status = -EINVAL;
1006 break;
1007 }
1008
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;
1013
1014 if (copy_to_user(IoBuffer.OutputBuffer, &link_state,
1015 min_t(size_t, sizeof(link_state), IoBuffer.OutputLength)))
1016 {
1017 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy_to_user Failed..\n");
1018 Status = -EFAULT;
1019 break;
1020 }
1021 Status = STATUS_SUCCESS;
1022 break;
1023 }
1024 case IOCTL_BCM_SET_MAC_TRACING:
1025 {
1026 UINT tracing_flag;
1027
1028 /* copy ioctl Buffer structure */
1029 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1030 return -EFAULT;
1031
1032 if(copy_from_user(&tracing_flag,IoBuffer.InputBuffer,sizeof(UINT)))
1033 return -EFAULT;
1034
1035 if (tracing_flag)
1036 Adapter->pTarangs->MacTracingEnabled = TRUE;
1037 else
1038 Adapter->pTarangs->MacTracingEnabled = FALSE;
1039 break;
1040 }
1041 case IOCTL_BCM_GET_DSX_INDICATION:
1042 {
1043 ULONG ulSFId=0;
1044 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1045 return -EFAULT;
1046
1047 if(IoBuffer.OutputLength < sizeof(stLocalSFAddIndicationAlt))
1048 {
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;
1053 }
1054
1055 if(copy_from_user(&ulSFId, IoBuffer.InputBuffer, sizeof(ulSFId)))
1056 return -EFAULT;
1057
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;
1061 }
1062 break;
1063 case IOCTL_BCM_GET_HOST_MIBS:
1064 {
1065 PVOID temp_buff;
1066
1067 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1068 return -EFAULT;
1069
1070 if(IoBuffer.OutputLength != sizeof(S_MIBS_HOST_STATS_MIBS))
1071 {
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;
1076 }
1077
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;
1082
1083 Status = ProcessGetHostMibs(Adapter, temp_buff);
1084 GetDroppedAppCntrlPktMibs(temp_buff, pTarang);
1085
1086 if (Status != STATUS_FAILURE)
1087 if(copy_to_user(IoBuffer.OutputBuffer, temp_buff, sizeof(S_MIBS_HOST_STATS_MIBS)))
1088 Status = -EFAULT;
1089
1090 kfree(temp_buff);
1091 break;
1092 }
1093
1094 case IOCTL_BCM_WAKE_UP_DEVICE_FROM_IDLE:
1095 if((FALSE == Adapter->bTriedToWakeUpFromlowPowerMode) && (TRUE==Adapter->IdleMode))
1096 {
1097 Adapter->usIdleModePattern = ABORT_IDLE_MODE;
1098 Adapter->bWakeUpDevice = TRUE;
1099 wake_up(&Adapter->process_rx_cntrlpkt);
1100 }
1101 Status = STATUS_SUCCESS;
1102 break;
1103
1104 case IOCTL_BCM_BULK_WRM:
1105 {
1106 PBULKWRM_BUFFER pBulkBuffer;
1107 UINT uiTempVar=0;
1108 PCHAR pvBuffer = NULL;
1109
1110 if((Adapter->IdleMode == TRUE) ||
1111 (Adapter->bShutStatus ==TRUE) ||
1112 (Adapter->bPreparingForLowPowerMode ==TRUE))
1113 {
1114 BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Device in Idle/Shutdown Mode, Blocking Wrms\n");
1115 Status = -EACCES;
1116 break;
1117 }
1118
1119 /* Copy Ioctl Buffer structure */
1120 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1121 return -EFAULT;
1122
1123 /* FIXME: restrict length */
1124 pvBuffer = kmalloc(IoBuffer.InputLength, GFP_KERNEL);
1125 if(!pvBuffer)
1126 return -ENOMEM;
1127
1128 /* Get WrmBuffer structure */
1129 if(copy_from_user(pvBuffer, IoBuffer.InputBuffer, IoBuffer.InputLength))
1130 {
1131 kfree(pvBuffer);
1132 Status = -EFAULT;
1133 break;
1134 }
1135
1136 pBulkBuffer = (PBULKWRM_BUFFER)pvBuffer;
1137
1138 if(((ULONG)pBulkBuffer->Register & 0x0F000000) != 0x0F000000 ||
1139 ((ULONG)pBulkBuffer->Register & 0x3))
1140 {
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;
1145 }
1146
1147
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))
1155 {
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;
1160 }
1161
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));
1166
1167 if(Status != STATUS_SUCCESS)
1168 {
1169 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "WRM Failed\n");
1170 }
1171
1172 kfree(pvBuffer);
1173 break;
1174 }
1175
1176 case IOCTL_BCM_GET_NVM_SIZE:
1177 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1178 return -EFAULT;
1179
1180 if(Adapter->eNVMType == NVM_EEPROM || Adapter->eNVMType == NVM_FLASH ) {
1181 if(copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiNVMDSDSize, sizeof(UINT)))
1182 return -EFAULT;
1183 }
1184 Status = STATUS_SUCCESS ;
1185 break;
1186
1187 case IOCTL_BCM_CAL_INIT :
1188
1189 {
1190 UINT uiSectorSize = 0 ;
1191 if(Adapter->eNVMType == NVM_FLASH)
1192 {
1193 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1194 return -EFAULT;
1195
1196 if (copy_from_user(&uiSectorSize, IoBuffer.InputBuffer, sizeof(UINT)))
1197 return -EFAULT;
1198
1199 if((uiSectorSize < MIN_SECTOR_SIZE) || (uiSectorSize > MAX_SECTOR_SIZE))
1200 {
1201 if (copy_to_user(IoBuffer.OutputBuffer, &Adapter->uiSectorSize,
1202 sizeof(UINT)))
1203 return -EFAULT;
1204 }
1205 else
1206 {
1207 if(IsFlash2x(Adapter))
1208 {
1209 if (copy_to_user(IoBuffer.OutputBuffer,
1210 &Adapter->uiSectorSize ,
1211 sizeof(UINT)))
1212 return -EFAULT;
1213 }
1214 else
1215 {
1216 if((TRUE == Adapter->bShutStatus) ||
1217 (TRUE == Adapter->IdleMode))
1218 {
1219 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is in Idle/Shutdown Mode\n");
1220 return -EACCES;
1221 }
1222
1223 Adapter->uiSectorSize = uiSectorSize ;
1224 BcmUpdateSectorSize(Adapter,Adapter->uiSectorSize);
1225 }
1226 }
1227 Status = STATUS_SUCCESS ;
1228 }
1229 else
1230 {
1231 Status = STATUS_FAILURE;
1232 }
1233 }
1234 break;
1235 case IOCTL_BCM_SET_DEBUG :
1236 #ifdef DEBUG
1237 {
1238 USER_BCM_DBG_STATE sUserDebugState;
1239
1240 // BCM_DEBUG_PRINT (Adapter, DBG_TYPE_PRINTK, 0, 0, "Entered the ioctl %x \n", IOCTL_BCM_SET_DEBUG );
1241
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;
1245
1246 if (copy_from_user(&sUserDebugState, IoBuffer.InputBuffer, sizeof(USER_BCM_DBG_STATE)))
1247 return -EFAULT;
1248
1249
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);
1255
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 !
1262 */
1263 if (sUserDebugState.OnOff)
1264 Adapter->stDebugState.subtype[sUserDebugState.Type] |= sUserDebugState.Subtype;
1265 else
1266 Adapter->stDebugState.subtype[sUserDebugState.Type] &= ~sUserDebugState.Subtype;
1267
1268 BCM_SHOW_DEBUG_BITMAP(Adapter);
1269
1270 }
1271 #endif
1272 break;
1273 case IOCTL_BCM_NVM_READ:
1274 case IOCTL_BCM_NVM_WRITE:
1275 {
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))
1283 {
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;
1287 }
1288
1289 if(IsFlash2x(Adapter))
1290 {
1291 if((Adapter->eActiveDSD != DSD0) &&
1292 (Adapter->eActiveDSD != DSD1) &&
1293 (Adapter->eActiveDSD != DSD2))
1294 {
1295 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"No DSD is active..hence NVM Command is blocked");
1296 return STATUS_FAILURE ;
1297 }
1298 }
1299
1300 /* Copy Ioctl Buffer structure */
1301
1302 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1303 return -EFAULT;
1304
1305 if(copy_from_user(&stNVMReadWrite,
1306 (IOCTL_BCM_NVM_READ == cmd) ? IoBuffer.OutputBuffer : IoBuffer.InputBuffer,
1307 sizeof(NVM_READWRITE)))
1308 return -EFAULT;
1309
1310 //
1311 // Deny the access if the offset crosses the cal area limit.
1312 //
1313 if((stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) > Adapter->uiNVMDSDSize)
1314 {
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;
1319 }
1320
1321 pReadData = kzalloc(stNVMReadWrite.uiNumBytes, GFP_KERNEL);
1322 if(!pReadData)
1323 return -ENOMEM;
1324
1325 if(copy_from_user(pReadData, stNVMReadWrite.pBuffer,
1326 stNVMReadWrite.uiNumBytes))
1327 {
1328 Status = -EFAULT;
1329 kfree(pReadData);
1330 break;
1331 }
1332
1333 do_gettimeofday(&tv0);
1334 if(IOCTL_BCM_NVM_READ == cmd)
1335 {
1336 down(&Adapter->NVMRdmWrmLock);
1337
1338 if((Adapter->IdleMode == TRUE) ||
1339 (Adapter->bShutStatus ==TRUE) ||
1340 (Adapter->bPreparingForLowPowerMode ==TRUE))
1341 {
1342 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Device is in Idle/Shutdown Mode\n");
1343 up(&Adapter->NVMRdmWrmLock);
1344 kfree(pReadData);
1345 return -EACCES;
1346 }
1347
1348 Status = BeceemNVMRead(Adapter, (PUINT)pReadData,
1349 stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes);
1350
1351 up(&Adapter->NVMRdmWrmLock);
1352
1353 if(Status != STATUS_SUCCESS)
1354 {
1355 kfree(pReadData);
1356 return Status;
1357 }
1358 if(copy_to_user(stNVMReadWrite.pBuffer,pReadData, stNVMReadWrite.uiNumBytes))
1359 {
1360 kfree(pReadData);
1361 Status = -EFAULT;
1362 }
1363 }
1364 else
1365 {
1366
1367 down(&Adapter->NVMRdmWrmLock);
1368
1369 if((Adapter->IdleMode == TRUE) ||
1370 (Adapter->bShutStatus ==TRUE) ||
1371 (Adapter->bPreparingForLowPowerMode ==TRUE))
1372 {
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;
1377 }
1378
1379 Adapter->bHeaderChangeAllowed = TRUE ;
1380 if(IsFlash2x(Adapter))
1381 {
1382 /*
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.
1389
1390 This restriction has been put assuming that if DSD sig is corrupted, DSD
1391 data won't be considered valid.
1392
1393
1394 */
1395 Status = BcmFlash2xCorruptSig(Adapter,Adapter->eActiveDSD);
1396 if(Status != STATUS_SUCCESS)
1397 {
1398 if(( (stNVMReadWrite.uiOffset + stNVMReadWrite.uiNumBytes) != Adapter->uiNVMDSDSize ) ||
1399 (stNVMReadWrite.uiNumBytes < SIGNATURE_SIZE))
1400 {
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;
1405 }
1406
1407 ulDSDMagicNumInUsrBuff = ntohl(*(PUINT)(pReadData + stNVMReadWrite.uiNumBytes - SIGNATURE_SIZE));
1408 if(ulDSDMagicNumInUsrBuff != DSD_IMAGE_MAGIC_NUMBER)
1409 {
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;
1414 }
1415 }
1416 }
1417 Status = BeceemNVMWrite(Adapter, (PUINT )pReadData,
1418 stNVMReadWrite.uiOffset, stNVMReadWrite.uiNumBytes, stNVMReadWrite.bVerify);
1419 if(IsFlash2x(Adapter))
1420 BcmFlash2xWriteSig(Adapter,Adapter->eActiveDSD);
1421
1422 Adapter->bHeaderChangeAllowed = FALSE ;
1423
1424 up(&Adapter->NVMRdmWrmLock);
1425
1426
1427 if(Status != STATUS_SUCCESS)
1428 {
1429 kfree(pReadData);
1430 return Status;
1431 }
1432 }
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);
1435
1436
1437 kfree(pReadData);
1438 Status = STATUS_SUCCESS;
1439 }
1440 break;
1441 case IOCTL_BCM_FLASH2X_SECTION_READ :
1442 {
1443
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;
1451
1452 if(IsFlash2x(Adapter) != TRUE)
1453 {
1454 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1455 return -EINVAL;
1456 }
1457
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;
1461
1462 //Reading FLASH 2.x READ structure
1463 if (copy_from_user(&sFlash2xRead, IoBuffer.InputBuffer,sizeof(FLASH2X_READWRITE)))
1464 return -EFAULT;
1465
1466
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);
1471
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 ;
1475
1476 NOB = sFlash2xRead.numOfBytes;
1477 if(NOB > Adapter->uiSectorSize )
1478 BuffSize = Adapter->uiSectorSize;
1479 else
1480 BuffSize = NOB ;
1481
1482 ReadOffset = sFlash2xRead.offset ;
1483 OutPutBuff = IoBuffer.OutputBuffer;
1484
1485
1486 pReadBuff = (PCHAR)kzalloc(BuffSize , GFP_KERNEL);
1487 if(pReadBuff == NULL)
1488 {
1489 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
1490 return -ENOMEM;
1491 }
1492 down(&Adapter->NVMRdmWrmLock);
1493
1494 if((Adapter->IdleMode == TRUE) ||
1495 (Adapter->bShutStatus ==TRUE) ||
1496 (Adapter->bPreparingForLowPowerMode ==TRUE))
1497 {
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;
1502 }
1503
1504 while(NOB)
1505 {
1506
1507 if(NOB > Adapter->uiSectorSize )
1508 ReadBytes = Adapter->uiSectorSize;
1509 else
1510 ReadBytes = NOB;
1511
1512
1513 //Reading the data from Flash 2.x
1514
1515 Status = BcmFlash2xBulkRead(Adapter,(PUINT)pReadBuff,sFlash2xRead.Section,ReadOffset,ReadBytes);
1516 if(Status)
1517 {
1518 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Flash 2x read err with Status :%d", Status);
1519 break ;
1520 }
1521
1522 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff, ReadBytes);
1523
1524 Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
1525 if(Status)
1526 {
1527 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Copy to use failed with status :%d", Status);
1528 break;
1529 }
1530 NOB = NOB - ReadBytes;
1531 if(NOB)
1532 {
1533 ReadOffset = ReadOffset + ReadBytes ;
1534 OutPutBuff = OutPutBuff + ReadBytes ;
1535 }
1536
1537 }
1538 up(&Adapter->NVMRdmWrmLock);
1539 kfree(pReadBuff);
1540
1541 }
1542 break ;
1543 case IOCTL_BCM_FLASH2X_SECTION_WRITE :
1544 {
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;
1552
1553 if(IsFlash2x(Adapter) != TRUE)
1554 {
1555 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1556 return -EINVAL;
1557 }
1558
1559 //First make this False so that we can enable the Sector Permission Check in BeceemFlashBulkWrite
1560 Adapter->bAllDSDWriteAllow = FALSE;
1561
1562
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;
1566
1567 //Reading FLASH 2.x READ structure
1568 if (copy_from_user(&sFlash2xWrite, IoBuffer.InputBuffer, sizeof(FLASH2X_READWRITE)))
1569 return -EFAULT;
1570
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) )
1577 {
1578 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Only VSA write is allowed");
1579 return -EINVAL;
1580 }
1581
1582 if(validateFlash2xReadWrite(Adapter,&sFlash2xWrite) == FALSE)
1583 return STATUS_FAILURE ;
1584
1585 InputAddr = sFlash2xWrite.pDataBuff;
1586 WriteOffset = sFlash2xWrite.offset ;
1587 NOB = sFlash2xWrite.numOfBytes;
1588
1589 if(NOB > Adapter->uiSectorSize )
1590 BuffSize = Adapter->uiSectorSize;
1591 else
1592 BuffSize = NOB ;
1593
1594 pWriteBuff = kmalloc(BuffSize, GFP_KERNEL);
1595 if(pWriteBuff == NULL)
1596 return -ENOMEM;
1597
1598
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;
1605
1606 down(&Adapter->NVMRdmWrmLock);
1607
1608 if((Adapter->IdleMode == TRUE) ||
1609 (Adapter->bShutStatus ==TRUE) ||
1610 (Adapter->bPreparingForLowPowerMode ==TRUE))
1611 {
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;
1616 }
1617
1618 BcmFlash2xCorruptSig(Adapter,sFlash2xWrite.Section);
1619 do
1620 {
1621 Status = copy_from_user(pWriteBuff,InputAddr,WriteBytes);
1622 if(Status)
1623 {
1624 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to user failed with status :%d", Status);
1625 break ;
1626 }
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);
1630
1631 if(Status)
1632 {
1633 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
1634 break ;
1635 }
1636
1637 NOB = NOB - WriteBytes;
1638 if(NOB)
1639 {
1640 WriteOffset = WriteOffset + WriteBytes ;
1641 InputAddr = InputAddr + WriteBytes ;
1642 if(NOB > Adapter->uiSectorSize )
1643 WriteBytes = Adapter->uiSectorSize;
1644 else
1645 WriteBytes = NOB;
1646 }
1647
1648
1649 } while(NOB > 0);
1650 BcmFlash2xWriteSig(Adapter,sFlash2xWrite.Section);
1651 up(&Adapter->NVMRdmWrmLock);
1652 kfree(pWriteBuff);
1653 }
1654 break ;
1655 case IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP :
1656 {
1657
1658 PFLASH2X_BITMAP psFlash2xBitMap;
1659 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, "IOCTL_BCM_GET_FLASH2X_SECTION_BITMAP Called");
1660
1661 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1662 return -EFAULT;
1663
1664 if(IoBuffer.OutputLength != sizeof(FLASH2X_BITMAP))
1665 return -EINVAL;
1666
1667 psFlash2xBitMap = kzalloc(sizeof(FLASH2X_BITMAP), GFP_KERNEL);
1668 if(psFlash2xBitMap == NULL)
1669 {
1670 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory is not available");
1671 return -ENOMEM ;
1672 }
1673 //Reading the Flash Sectio Bit map
1674 down(&Adapter->NVMRdmWrmLock);
1675
1676 if((Adapter->IdleMode == TRUE) ||
1677 (Adapter->bShutStatus ==TRUE) ||
1678 (Adapter->bPreparingForLowPowerMode ==TRUE))
1679 {
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;
1684 }
1685
1686 BcmGetFlash2xSectionalBitMap(Adapter, psFlash2xBitMap);
1687 up(&Adapter->NVMRdmWrmLock);
1688 if (copy_to_user(IoBuffer.OutputBuffer, psFlash2xBitMap, sizeof(FLASH2X_BITMAP)))
1689 Status = -EFAULT;
1690
1691 kfree(psFlash2xBitMap);
1692 }
1693 break ;
1694 case IOCTL_BCM_SET_ACTIVE_SECTION :
1695 {
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");
1698
1699 if(IsFlash2x(Adapter) != TRUE)
1700 {
1701 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1702 return -EINVAL;
1703 }
1704
1705 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1706 if(Status)
1707 {
1708 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1709 return Status;
1710 }
1711
1712 Status = copy_from_user(&eFlash2xSectionVal,IoBuffer.InputBuffer, sizeof(INT));
1713 if(Status)
1714 {
1715 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
1716 return Status;
1717 }
1718
1719 down(&Adapter->NVMRdmWrmLock);
1720
1721 if((Adapter->IdleMode == TRUE) ||
1722 (Adapter->bShutStatus ==TRUE) ||
1723 (Adapter->bPreparingForLowPowerMode ==TRUE))
1724 {
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;
1728 }
1729
1730 Status = BcmSetActiveSection(Adapter,eFlash2xSectionVal);
1731 if(Status)
1732 {
1733 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Failed to make it's priority Highest. Status %d", Status);
1734 }
1735 up(&Adapter->NVMRdmWrmLock);
1736 }
1737 break ;
1738 case IOCTL_BCM_IDENTIFY_ACTIVE_SECTION :
1739 {
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");
1743
1744 Status = STATUS_SUCCESS ;
1745 }
1746 break ;
1747 case IOCTL_BCM_COPY_SECTION :
1748 {
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");
1752
1753 Adapter->bAllDSDWriteAllow = FALSE ;
1754 if(IsFlash2x(Adapter) != TRUE)
1755 {
1756 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1757 return -EINVAL;
1758 }
1759
1760 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1761 if(Status)
1762 {
1763 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed Status :%d", Status);
1764 return Status;
1765 }
1766
1767 Status = copy_from_user(&sCopySectStrut, IoBuffer.InputBuffer, sizeof(FLASH2X_COPY_SECTION));
1768 if(Status)
1769 {
1770 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of Copy_Section_Struct failed with Status :%d", Status);
1771 return Status;
1772 }
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);
1777
1778
1779 if(IsSectionExistInFlash(Adapter,sCopySectStrut.SrcSection) == FALSE)
1780 {
1781 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Source Section<%x> does not exixt in Flash ", sCopySectStrut.SrcSection);
1782 return -EINVAL;
1783 }
1784
1785 if(IsSectionExistInFlash(Adapter,sCopySectStrut.DstSection) == FALSE)
1786 {
1787 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Destinatio Section<%x> does not exixt in Flash ", sCopySectStrut.DstSection);
1788 return -EINVAL;
1789 }
1790
1791 if(sCopySectStrut.SrcSection == sCopySectStrut.DstSection)
1792 {
1793 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Source and Destination section should be different");
1794 return -EINVAL;
1795 }
1796
1797 down(&Adapter->NVMRdmWrmLock);
1798
1799 if((Adapter->IdleMode == TRUE) ||
1800 (Adapter->bShutStatus ==TRUE) ||
1801 (Adapter->bPreparingForLowPowerMode ==TRUE))
1802 {
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;
1806 }
1807
1808 if(sCopySectStrut.SrcSection == ISO_IMAGE1 || sCopySectStrut.SrcSection == ISO_IMAGE2)
1809 {
1810 if(IsNonCDLessDevice(Adapter))
1811 {
1812 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Device is Non-CDLess hence won't have ISO !!");
1813 Status = -EINVAL ;
1814 }
1815 else if(sCopySectStrut.numOfBytes == 0)
1816 {
1817 Status = BcmCopyISO(Adapter,sCopySectStrut);
1818 }
1819 else
1820 {
1821 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Partial Copy of ISO section is not Allowed..");
1822 Status = STATUS_FAILURE ;
1823 }
1824 up(&Adapter->NVMRdmWrmLock);
1825 return Status;
1826 }
1827
1828 Status = BcmCopySection(Adapter, sCopySectStrut.SrcSection,
1829 sCopySectStrut.DstSection,sCopySectStrut.offset,sCopySectStrut.numOfBytes);
1830 up(&Adapter->NVMRdmWrmLock);
1831 }
1832 break ;
1833 case IOCTL_BCM_GET_FLASH_CS_INFO :
1834 {
1835 Status = STATUS_SUCCESS;
1836 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL, " IOCTL_BCM_GET_FLASH_CS_INFO Called");
1837
1838 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1839 if(Status)
1840 {
1841 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1842 break;
1843 }
1844 if(Adapter->eNVMType != NVM_FLASH)
1845 {
1846 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Connected device does not have flash");
1847 Status = -EINVAL;
1848 break;
1849 }
1850 if(IsFlash2x(Adapter) == TRUE)
1851 {
1852
1853 if(IoBuffer.OutputLength < sizeof(FLASH2X_CS_INFO))
1854 return -EINVAL;
1855
1856 if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlash2xCSInfo, sizeof(FLASH2X_CS_INFO)))
1857 return -EFAULT;
1858 }
1859 else
1860 {
1861 if(IoBuffer.OutputLength < sizeof(FLASH_CS_INFO))
1862 return -EINVAL;
1863
1864 if (copy_to_user(IoBuffer.OutputBuffer, Adapter->psFlashCSInfo, sizeof(FLASH_CS_INFO)))
1865 return -EFAULT;
1866
1867 }
1868 }
1869 break ;
1870 case IOCTL_BCM_SELECT_DSD :
1871 {
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");
1876
1877 if(IsFlash2x(Adapter) != TRUE)
1878 {
1879 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash Does not have 2.x map");
1880 return -EINVAL;
1881 }
1882
1883 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
1884 if(Status)
1885 {
1886 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of IOCTL BUFFER failed");
1887 return Status;
1888 }
1889 Status = copy_from_user(&eFlash2xSectionVal, IoBuffer.InputBuffer, sizeof(INT));
1890 if(Status)
1891 {
1892 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "Copy of flash section val failed");
1893 return Status;
1894 }
1895
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) )
1900 {
1901 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Passed section<%x> is not DSD section", eFlash2xSectionVal);
1902 return STATUS_FAILURE ;
1903 }
1904
1905 SectOfset= BcmGetSectionValStartOffset(Adapter,eFlash2xSectionVal);
1906 if(SectOfset == INVALID_OFFSET)
1907 {
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;
1910 }
1911
1912 Adapter->bAllDSDWriteAllow = TRUE ;
1913
1914 Adapter->ulFlashCalStart = SectOfset ;
1915 Adapter->eActiveDSD = eFlash2xSectionVal;
1916 }
1917 Status = STATUS_SUCCESS ;
1918 break;
1919
1920 case IOCTL_BCM_NVM_RAW_READ :
1921 {
1922
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;
1930
1931 if(Adapter->eNVMType != NVM_FLASH)
1932 {
1933 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"NVM TYPE is not Flash ");
1934 return -EINVAL ;
1935 }
1936
1937 /* Copy Ioctl Buffer structure */
1938 if(copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
1939 {
1940 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0, "copy_from_user 1 failed\n");
1941 Status = -EFAULT;
1942 break;
1943 }
1944
1945 if(copy_from_user(&stNVMRead, IoBuffer.OutputBuffer,sizeof(NVM_READWRITE)))
1946 return -EFAULT;
1947
1948 NOB = stNVMRead.uiNumBytes;
1949 //In Raw-Read max Buff size : 64MB
1950
1951 if(NOB > DEFAULT_BUFF_SIZE)
1952 BuffSize = DEFAULT_BUFF_SIZE;
1953 else
1954 BuffSize = NOB ;
1955
1956 ReadOffset = stNVMRead.uiOffset;
1957 OutPutBuff = stNVMRead.pBuffer;
1958
1959 pReadBuff = kzalloc(BuffSize , GFP_KERNEL);
1960 if(pReadBuff == NULL)
1961 {
1962 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Memory allocation failed for Flash 2.x Read Structure");
1963 Status = -ENOMEM;
1964 break;
1965 }
1966 down(&Adapter->NVMRdmWrmLock);
1967
1968 if((Adapter->IdleMode == TRUE) ||
1969 (Adapter->bShutStatus ==TRUE) ||
1970 (Adapter->bPreparingForLowPowerMode ==TRUE))
1971 {
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;
1976 }
1977
1978 Adapter->bFlashRawRead = TRUE ;
1979 while(NOB)
1980 {
1981 if(NOB > DEFAULT_BUFF_SIZE )
1982 ReadBytes = DEFAULT_BUFF_SIZE;
1983 else
1984 ReadBytes = NOB;
1985
1986 //Reading the data from Flash 2.x
1987 Status = BeceemNVMRead(Adapter,(PUINT)pReadBuff,ReadOffset,ReadBytes);
1988 if(Status)
1989 {
1990 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Flash 2x read err with Status :%d", Status);
1991 break;
1992 }
1993
1994 BCM_DEBUG_PRINT_BUFFER(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,pReadBuff,ReadBytes);
1995
1996 Status = copy_to_user(OutPutBuff, pReadBuff,ReadBytes);
1997 if(Status)
1998 {
1999 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_PRINTK, 0, 0,"Copy to use failed with status :%d", Status);
2000 break;
2001 }
2002 NOB = NOB - ReadBytes;
2003 if(NOB)
2004 {
2005 ReadOffset = ReadOffset + ReadBytes ;
2006 OutPutBuff = OutPutBuff + ReadBytes ;
2007 }
2008
2009 }
2010 Adapter->bFlashRawRead = FALSE ;
2011 up(&Adapter->NVMRdmWrmLock);
2012 kfree(pReadBuff);
2013 break ;
2014 }
2015
2016 case IOCTL_BCM_CNTRLMSG_MASK:
2017 {
2018 ULONG RxCntrlMsgBitMask = 0 ;
2019
2020 /* Copy Ioctl Buffer structure */
2021 Status = copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER));
2022 if(Status)
2023 {
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;
2027 }
2028
2029 if (IoBuffer.InputLength != sizeof(unsigned long)) {
2030 Status = -EINVAL;
2031 break;
2032 }
2033
2034 Status = copy_from_user(&RxCntrlMsgBitMask, IoBuffer.InputBuffer, IoBuffer.InputLength);
2035 if(Status)
2036 {
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;
2040 }
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 ;
2043 }
2044 break;
2045 case IOCTL_BCM_GET_DEVICE_DRIVER_INFO:
2046 {
2047 DEVICE_DRIVER_INFO DevInfo;
2048
2049 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"Called IOCTL_BCM_GET_DEVICE_DRIVER_INFO\n");
2050
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;
2056
2057 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
2058 return -EFAULT;
2059
2060 if(IoBuffer.OutputLength < sizeof(DevInfo))
2061 return -EINVAL;
2062
2063 if (copy_to_user(IoBuffer.OutputBuffer, &DevInfo, sizeof(DevInfo)))
2064 return -EFAULT;
2065 }
2066 break ;
2067
2068 case IOCTL_BCM_TIME_SINCE_NET_ENTRY:
2069 {
2070 ST_TIME_ELAPSED stTimeElapsedSinceNetEntry = {0};
2071
2072 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_BCM_TIME_SINCE_NET_ENTRY called");
2073
2074 if (copy_from_user(&IoBuffer, argp, sizeof(IOCTL_BUFFER)))
2075 return -EFAULT;
2076
2077 if(IoBuffer.OutputLength < sizeof(ST_TIME_ELAPSED))
2078 return -EINVAL;
2079
2080 stTimeElapsedSinceNetEntry.ul64TimeElapsedSinceNetEntry = get_seconds() - Adapter->liTimeSinceLastNetEntry;
2081
2082 if (copy_to_user(IoBuffer.OutputBuffer, &stTimeElapsedSinceNetEntry, sizeof(ST_TIME_ELAPSED)))
2083 return -EFAULT;
2084
2085 }
2086 break;
2087
2088 case IOCTL_CLOSE_NOTIFICATION:
2089 BCM_DEBUG_PRINT(Adapter,DBG_TYPE_OTHERS, OSAL_DBG, DBG_LVL_ALL,"IOCTL_CLOSE_NOTIFICATION");
2090 break;
2091
2092 default:
2093 pr_info(DRV_NAME ": unknown ioctl cmd=%#x\n", cmd);
2094 Status = STATUS_FAILURE;
2095 break;
2096 }
2097 return Status;
2098 }
2099
2100
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,
2108 };
2109
2110 extern struct class *bcm_class;
2111
register_control_device_interface(PMINI_ADAPTER Adapter)2112 int register_control_device_interface(PMINI_ADAPTER Adapter)
2113 {
2114
2115 if (Adapter->major > 0)
2116 return Adapter->major;
2117
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;
2122 }
2123
2124 Adapter->pstCreatedClassDevice = device_create(bcm_class, NULL,
2125 MKDEV(Adapter->major, 0),
2126 Adapter, DEV_NAME);
2127
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);
2132 }
2133
2134 return 0;
2135 }
2136
unregister_control_device_interface(PMINI_ADAPTER Adapter)2137 void unregister_control_device_interface(PMINI_ADAPTER Adapter)
2138 {
2139 if (Adapter->major > 0) {
2140 device_destroy(bcm_class, MKDEV(Adapter->major, 0));
2141 unregister_chrdev(Adapter->major, DEV_NAME);
2142 }
2143 }
2144