Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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