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