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