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