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