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