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

Configure Feed

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

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