1/* 2 * Copyright 2006-2007, Nathan Whitehorn. 3 * Distributed under the terms of the GPL License. 4 */ 5 6 7#include "b44mm.h" 8#include "b44lm.h" 9#include "mempool.h" 10 11#include <ether_driver.h> 12#ifdef HAIKU_TARGET_PLATFORM_HAIKU 13# include <net/if_media.h> 14#endif 15 16#include <PCI.h> 17#include <Drivers.h> 18#include <KernelExport.h> 19 20#include <malloc.h> 21#include <string.h> 22 23 24struct pci_module_info *pci = NULL; 25 26#define MAX_CARDS 4 27 28static char *sDeviceNames[MAX_CARDS + 1]; 29static int sCardsFound = 0; 30struct be_b44_dev be_b44_dev_cards[MAX_CARDS]; 31 32int b44_Packet_Desc_Size = sizeof(struct B_UM_PACKET); 33 34#define ROUND_UP_TO_PAGE(size) ((size % 4096 != 0) ? 4096 - (size % 4096) + size : size) 35 36/* -------- BeOS Driver Hooks ------------ */ 37 38status_t b44_open(const char *name, uint32 flags, void **cookie); 39status_t b44_close(void *cookie); 40status_t b44_free(void *cookie); 41status_t b44_ioctl(void *cookie,uint32 op,void *data,size_t len); 42status_t b44_read(void *cookie,off_t pos,void *data,size_t *numBytes); 43status_t b44_write(void *cookie,off_t pos,const void *data,size_t *numBytes); 44int32 b44_interrupt(void *cookie); 45int32 tx_cleanup_thread(void *us); 46 47 48int32 api_version = B_CUR_DRIVER_API_VERSION; 49 50 51status_t 52init_hardware(void) 53{ 54 return B_OK; 55} 56 57 58const char ** 59publish_devices() 60{ 61 return (const char **)sDeviceNames; 62} 63 64 65device_hooks * 66find_device(const char *name) 67{ 68 static device_hooks b44_hooks = { 69 b44_open, 70 b44_close, 71 b44_free, 72 b44_ioctl, 73 b44_read, 74 b44_write, 75 NULL, 76 NULL, 77 NULL, 78 NULL 79 }; 80 return &b44_hooks; 81} 82 83 84status_t 85init_driver(void) 86{ 87 int i = 0; 88 pci_info dev_info; 89 90 if (get_module(B_PCI_MODULE_NAME,(module_info **)&pci) < B_OK) 91 return ENOSYS; 92 93 while (pci->get_nth_pci_info(i++, &dev_info) == 0) { 94 if (dev_info.class_base != PCI_network 95 || dev_info.class_sub != PCI_ethernet 96 || dev_info.vendor_id != 0x14e4 97 || (dev_info.device_id != 0x4401 98 && dev_info.device_id != 0x4402 99 && dev_info.device_id != 0x170c)) 100 continue; 101 102 if (sCardsFound >= MAX_CARDS) 103 break; 104 105 sDeviceNames[sCardsFound] = (char *)malloc(16 /* net/bcm440x/xx */); 106 sprintf(sDeviceNames[sCardsFound], "net/bcm440x/%d", sCardsFound); 107 be_b44_dev_cards[sCardsFound].pci_data = dev_info; 108 be_b44_dev_cards[sCardsFound].packet_release_sem = create_sem(0, 109 sDeviceNames[sCardsFound]); 110 be_b44_dev_cards[sCardsFound].mem_list_num = 0; 111 be_b44_dev_cards[sCardsFound].lockmem_list_num = 0; 112 be_b44_dev_cards[sCardsFound].opened = 0; 113 be_b44_dev_cards[sCardsFound].block = 1; 114 be_b44_dev_cards[sCardsFound].lock = 0; 115#ifdef HAIKU_TARGET_PLATFORM_HAIKU 116 be_b44_dev_cards[sCardsFound].linkChangeSem = -1; 117#endif 118 119 if (b44_LM_GetAdapterInfo(&be_b44_dev_cards[sCardsFound].lm_dev) != LM_STATUS_SUCCESS) { 120 for (i = 0; i < sCardsFound; i++) { 121 free((void *)sDeviceNames[i]); 122 delete_sem(be_b44_dev_cards[i].packet_release_sem); 123 } 124 put_module(B_PCI_MODULE_NAME); 125 return ENODEV; 126 } 127 128 QQ_InitQueue(&be_b44_dev_cards[sCardsFound].RxPacketReadQ.Container, 129 MAX_RX_PACKET_DESC_COUNT); 130 131 sCardsFound++; 132 } 133 134 mempool_init((MAX_RX_PACKET_DESC_COUNT+10) * sCardsFound); 135 136 sDeviceNames[sCardsFound] = NULL; 137 return B_OK; 138} 139 140 141void 142uninit_driver(void) 143{ 144 struct be_b44_dev *pUmDevice; 145 int i, j; 146 147 for (j = 0; j < sCardsFound; j++) { 148 pUmDevice = &be_b44_dev_cards[j]; 149 for (i = 0; i < pUmDevice->mem_list_num; i++) 150 free(pUmDevice->mem_list[i]); 151 for (i = 0; i < pUmDevice->lockmem_list_num; i++) 152 delete_area(pUmDevice->lockmem_list[i]); 153 154 delete_area(pUmDevice->mem_base); 155 156 delete_sem(be_b44_dev_cards[j].packet_release_sem); 157 free((void *)sDeviceNames[j]); 158 } 159 160 mempool_exit(); 161} 162 163 164status_t 165b44_open(const char *name, uint32 flags, void **cookie) 166{ 167 struct be_b44_dev *pDevice = NULL; 168 int i; 169 170 *cookie = NULL; 171 for (i = 0; i < sCardsFound; i++) { 172 if (strcmp(sDeviceNames[i], name) == 0) { 173 *cookie = pDevice = &be_b44_dev_cards[i]; 174 break; 175 } 176 } 177 178 if (*cookie == NULL) 179 return B_FILE_NOT_FOUND; 180 181 if (atomic_or(&pDevice->opened,1)) { 182 *cookie = pDevice = NULL; 183 return B_BUSY; 184 } 185 186 install_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line, 187 b44_interrupt, *cookie, 0); 188 if (b44_LM_InitializeAdapter(&pDevice->lm_dev) != LM_STATUS_SUCCESS) { 189 atomic_and(&pDevice->opened, 0); 190 remove_io_interrupt_handler(pDevice->pci_data.u.h0.interrupt_line, 191 b44_interrupt, *cookie); 192 *cookie = NULL; 193 return B_ERROR; 194 } 195 196 /*QQ_InitQueue(&pDevice->rx_out_of_buf_q.Container, 197 MAX_RX_PACKET_DESC_COUNT);*/ 198 199 b44_LM_EnableInterrupt(&pDevice->lm_dev); 200 return B_OK; 201} 202 203 204status_t 205b44_close(void *cookie) 206{ 207 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie; 208 if (cookie == NULL) 209 return B_OK; 210 211 atomic_and(&pUmDevice->opened,0); 212 b44_LM_Halt(&pUmDevice->lm_dev); 213 214 return B_OK; 215} 216 217 218status_t 219b44_free(void *cookie) 220{ 221 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie; 222 if (cookie == NULL) 223 return B_OK; 224 225 remove_io_interrupt_handler(pUmDevice->pci_data.u.h0.interrupt_line, 226 b44_interrupt, cookie); 227 return B_OK; 228} 229 230 231status_t 232b44_ioctl(void *cookie,uint32 op, void *data, size_t len) 233{ 234 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie; 235 236 switch (op) { 237 case ETHER_INIT: 238 return B_OK; 239 case ETHER_GETADDR: 240 if (data == NULL) 241 return B_ERROR; 242 243 memcpy(data, pUmDevice->lm_dev.NodeAddress, 6); 244 return B_OK; 245 case ETHER_NONBLOCK: 246 pUmDevice->block = !*((uint8 *)data); 247 return B_OK; 248 case ETHER_ADDMULTI: 249 return (b44_LM_MulticastAdd(&pUmDevice->lm_dev,(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR; 250 case ETHER_REMMULTI: 251 return (b44_LM_MulticastDel(&pUmDevice->lm_dev,(PLM_UINT8)(data)) == LM_STATUS_SUCCESS) ? B_OK : B_ERROR; 252 case ETHER_SETPROMISC: 253 if (*((uint8 *)(data))) { 254 b44_LM_SetReceiveMask(&pUmDevice->lm_dev, 255 pUmDevice->lm_dev.ReceiveMask | LM_PROMISCUOUS_MODE); 256 } else { 257 b44_LM_SetReceiveMask(&pUmDevice->lm_dev, 258 pUmDevice->lm_dev.ReceiveMask & ~LM_PROMISCUOUS_MODE); 259 } 260 return B_OK; 261#ifndef HAIKU_TARGET_PLATFORM_HAIKU 262 case ETHER_GETLINKSTATE: 263 { 264 ether_link_state_t *state_buffer = (ether_link_state_t *)(data); 265 state_buffer->link_speed = (pUmDevice->lm_dev.LineSpeed == LM_LINE_SPEED_10MBPS) ? 10 : 100; 266 state_buffer->link_quality = (pUmDevice->lm_dev.LinkStatus == LM_STATUS_LINK_DOWN) ? 0.0 : 1.0; 267 state_buffer->duplex_mode = (pUmDevice->lm_dev.DuplexMode == LM_DUPLEX_MODE_FULL); 268 return B_OK; 269 } 270#else 271 case ETHER_GET_LINK_STATE: 272 { 273 ether_link_state_t state; 274 275 if (pUmDevice->lm_dev.corerev < 7) { 276 b44_LM_PollLink(&pUmDevice->lm_dev); 277 } 278 state.media = (pUmDevice->lm_dev.LinkStatus 279 == LM_STATUS_LINK_DOWN ? 0 : IFM_ACTIVE) | IFM_ETHER; 280 switch (pUmDevice->lm_dev.LineSpeed) { 281 case LM_LINE_SPEED_10MBPS: 282 state.media |= IFM_10_T; 283 state.speed = 10000000; 284 break; 285 case LM_LINE_SPEED_100MBPS: 286 state.media |= IFM_100_TX; 287 state.speed = 100000000; 288 break; 289 default: 290 state.speed = 0; 291 } 292 state.media |= (pUmDevice->lm_dev.DuplexMode 293 == LM_DUPLEX_MODE_FULL ? IFM_FULL_DUPLEX : IFM_HALF_DUPLEX); 294 state.quality = 1000; 295 296 return user_memcpy(data, &state, sizeof(ether_link_state_t)); 297 } 298 299 case ETHER_SET_LINK_STATE_SEM: 300 { 301 if (user_memcpy(&pUmDevice->linkChangeSem, data, sizeof(sem_id)) < B_OK) { 302 pUmDevice->linkChangeSem = -1; 303 return B_BAD_ADDRESS; 304 } 305 return B_OK; 306 } 307 308#endif 309 } 310 return B_ERROR; 311} 312 313 314int32 315b44_interrupt(void *cookie) 316{ 317 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie; 318 PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice; 319 320 if (!pDevice->InitDone) 321 return B_UNHANDLED_INTERRUPT; 322 323 if (b44_LM_ServiceInterrupts(pDevice) == 12) 324 return B_UNHANDLED_INTERRUPT; 325 326 if (QQ_GetEntryCnt(&pDevice->RxPacketFreeQ.Container)) { 327 b44_LM_QueueRxPackets(pDevice); 328 return B_INVOKE_SCHEDULER; 329 } 330 331 return B_HANDLED_INTERRUPT; 332} 333 334 335status_t 336b44_read(void *cookie, off_t pos, void *data, size_t *numBytes) 337{ 338 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie; 339 PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice; 340 PLM_PACKET pPacket; 341 struct B_UM_PACKET *pUmPacket; 342 cpu_status cpu; 343 344 if (pUmDevice->block) 345 acquire_sem(pUmDevice->packet_release_sem); 346 else 347 acquire_sem_etc(pUmDevice->packet_release_sem,1,B_RELATIVE_TIMEOUT,0); // Decrement the receive sem anyway, but don't block 348 349 cpu = disable_interrupts(); 350 acquire_spinlock(&pUmDevice->lock); 351 352 pPacket = (PLM_PACKET) 353 QQ_PopHead(&pUmDevice->RxPacketReadQ.Container); 354 355 release_spinlock(&pUmDevice->lock); 356 restore_interrupts(cpu); 357 358 if (pPacket == 0) { 359 *numBytes = -1; 360 return B_ERROR; 361 } 362 363 pUmPacket = (struct B_UM_PACKET *)pPacket; 364 if (pPacket->PacketStatus != LM_STATUS_SUCCESS 365 || pPacket->PacketSize > 1518) { 366 cpu = disable_interrupts(); 367 acquire_spinlock(&pUmDevice->lock); 368 369 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket); 370 371 release_spinlock(&pUmDevice->lock); 372 restore_interrupts(cpu); 373 *numBytes = -1; 374 return B_ERROR; 375 } 376 377 if (pPacket->PacketSize/*-pDevice->rxoffset*/ < *numBytes) 378 *numBytes = pPacket->PacketSize/*-pDevice->rxoffset*/; 379 380 memcpy(data, pUmPacket->data + pDevice->rxoffset, *numBytes); 381 cpu = disable_interrupts(); 382 acquire_spinlock(&pUmDevice->lock); 383 384 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket); 385 386 release_spinlock(&pUmDevice->lock); 387 restore_interrupts(cpu); 388 389 return B_OK; 390} 391 392 393status_t 394b44_write(void *cookie, off_t pos, const void *data, size_t *numBytes) 395{ 396 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)cookie; 397 PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK) pUmDevice; 398 PLM_PACKET pPacket; 399 struct B_UM_PACKET *pUmPacket; 400 401 /*if ((pDevice->LinkStatus == LM_STATUS_LINK_DOWN) || !pDevice->InitDone) 402 { 403 return ENETDOWN; 404 }*/ 405 406 pPacket = (PLM_PACKET) 407 QQ_PopHead(&pDevice->TxPacketFreeQ.Container); 408 if (pPacket == 0) 409 return B_ERROR; 410 411 pUmPacket = (struct B_UM_PACKET *)pPacket; 412 pUmPacket->data = chunk_pool_get(); 413 414 memcpy(pUmPacket->data/*+pDevice->dataoffset*/,data,*numBytes); /* no guarantee data is contiguous, so we have to copy */ 415 pPacket->PacketSize = pUmPacket->size = *numBytes/*+pDevice->rxoffset*/; 416 417 pPacket->u.Tx.FragCount = 1; 418 419 tx_cleanup_thread(pUmDevice); 420 421 b44_LM_SendPacket(pDevice, pPacket); 422 return B_OK; 423} 424 425 426// #pragma mark - Broadcom MM hooks 427 428 429LM_STATUS 430b44_MM_ReadConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, 431 LM_UINT16 *pValue16) 432{ 433 if (pci == NULL) 434 get_module(B_PCI_MODULE_NAME,(module_info **)&pci); 435 436 *pValue16 = (LM_UINT16)pci->read_pci_config(((struct be_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT16)); 437 return LM_STATUS_SUCCESS; 438} 439 440 441LM_STATUS 442b44_MM_WriteConfig16(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, 443 LM_UINT16 Value16) 444{ 445 if (pci == NULL) 446 get_module(B_PCI_MODULE_NAME,(module_info **)&pci); 447 448 pci->write_pci_config(((struct be_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT16),(uint32)Value16); 449 return LM_STATUS_SUCCESS; 450} 451 452 453LM_STATUS 454b44_MM_ReadConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, 455 LM_UINT32 *pValue32) 456{ 457 if (pci == NULL) 458 get_module(B_PCI_MODULE_NAME,(module_info **)&pci); 459 460 *pValue32 = (LM_UINT32)pci->read_pci_config(((struct be_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT32)); 461 return LM_STATUS_SUCCESS; 462} 463 464 465LM_STATUS 466b44_MM_WriteConfig32(PLM_DEVICE_BLOCK pDevice, LM_UINT32 Offset, 467 LM_UINT32 Value32) 468{ 469 if (pci == NULL) 470 get_module(B_PCI_MODULE_NAME,(module_info **)&pci); 471 472 pci->write_pci_config(((struct be_b44_dev *)(pDevice))->pci_data.bus,((struct be_b44_dev *)(pDevice))->pci_data.device,((struct be_b44_dev *)(pDevice))->pci_data.function,(uchar)Offset,sizeof(LM_UINT32),(uint32)Value32); 473 return LM_STATUS_SUCCESS; 474} 475 476 477LM_STATUS 478b44_MM_MapMemBase(PLM_DEVICE_BLOCK pDevice) 479{ 480 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)(pDevice); 481 size_t size = pUmDevice->pci_data.u.h0.base_register_sizes[0]; 482 483 if (pci == NULL) 484 get_module(B_PCI_MODULE_NAME,(module_info **)&pci); 485 486 size = ROUNDUP(size,B_PAGE_SIZE); 487 pUmDevice->mem_base = map_physical_memory("bcm440x_regs", 488 pUmDevice->pci_data.u.h0.base_registers[0], size, 489 B_ANY_KERNEL_BLOCK_ADDRESS, B_READ_AREA | B_WRITE_AREA, 490 (void **)(&pDevice->pMappedMemBase)); 491 492 return LM_STATUS_SUCCESS; 493} 494 495 496/* 497LM_STATUS 498b44_MM_MapIoBase(PLM_DEVICE_BLOCK pDevice) 499{ 500 if (pci == NULL) 501 get_module(B_PCI_MODULE_NAME,(module_info **)&pci); 502 503 pDevice->pMappedMemBase = pci->ram_address(((struct be_b44_dev *)(pDevice))->pci_data.memory_base); 504 return LM_STATUS_SUCCESS; 505} 506*/ 507 508 509LM_STATUS 510b44_MM_IndicateRxPackets(PLM_DEVICE_BLOCK pDevice) 511{ 512 struct be_b44_dev *dev = (struct be_b44_dev *)pDevice; 513 PLM_PACKET pPacket; 514 515 while (1) { 516 pPacket = (PLM_PACKET) 517 QQ_PopHead(&pDevice->RxPacketReceivedQ.Container); 518 if (pPacket == 0) 519 break; 520 521 acquire_spinlock(&dev->lock); 522 release_sem_etc(dev->packet_release_sem, 1, B_DO_NOT_RESCHEDULE); 523 release_spinlock(&dev->lock); 524 QQ_PushTail(&dev->RxPacketReadQ.Container, pPacket); 525 } 526 527 return LM_STATUS_SUCCESS; 528} 529 530 531LM_STATUS 532b44_MM_IndicateTxPackets(PLM_DEVICE_BLOCK pDevice) 533{ 534 return LM_STATUS_SUCCESS; 535} 536 537 538int32 539tx_cleanup_thread(void *us) 540{ 541 PLM_PACKET pPacket; 542 PLM_DEVICE_BLOCK pDevice = (PLM_DEVICE_BLOCK)(us); 543 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)(us); 544 struct B_UM_PACKET *pUmPacket; 545 cpu_status cpu; 546 547 while (1) { 548 cpu = disable_interrupts(); 549 acquire_spinlock(&pUmDevice->lock); 550 551 pPacket = (PLM_PACKET) 552 QQ_PopHead(&pDevice->TxPacketXmittedQ.Container); 553 554 release_spinlock(&pUmDevice->lock); 555 restore_interrupts(cpu); 556 if (pPacket == 0) 557 break; 558 559 pUmPacket = (struct B_UM_PACKET *)(pPacket); 560 chunk_pool_put(pUmPacket->data); 561 pUmPacket->data = NULL; 562 563 cpu = disable_interrupts(); 564 acquire_spinlock(&pUmDevice->lock); 565 QQ_PushTail(&pDevice->TxPacketFreeQ.Container, pPacket); 566 release_spinlock(&pUmDevice->lock); 567 restore_interrupts(cpu); 568 } 569 return LM_STATUS_SUCCESS; 570} 571 572/*LM_STATUS b44_MM_StartTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket); 573LM_STATUS b44_MM_CompleteTxDma(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket);*/ 574 575 576LM_STATUS 577b44_MM_AllocateMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize, 578 PLM_VOID *pMemoryBlockVirt) 579{ 580 struct be_b44_dev *dev = (struct be_b44_dev *)(pDevice); 581 582 if (dev->mem_list_num == 16) 583 return LM_STATUS_FAILURE; 584 585 *pMemoryBlockVirt = dev->mem_list[(dev->mem_list_num)++] = (void *)malloc(BlockSize); 586 return LM_STATUS_SUCCESS; 587} 588 589 590LM_STATUS 591b44_MM_AllocateSharedMemory(PLM_DEVICE_BLOCK pDevice, LM_UINT32 BlockSize, 592 PLM_VOID *pMemoryBlockVirt, PLM_PHYSICAL_ADDRESS pMemoryBlockPhy) 593{ 594 struct be_b44_dev *dev; 595 void *pvirt = NULL; 596 area_id area_desc; 597 physical_entry entry; 598 599 dev = (struct be_b44_dev *)(pDevice); 600 area_desc = dev->lockmem_list[dev->lockmem_list_num++] = create_area("broadcom_shared_mem", 601 &pvirt, B_ANY_KERNEL_ADDRESS, ROUND_UP_TO_PAGE(BlockSize), 602 B_32_BIT_FULL_LOCK, B_READ_AREA | B_WRITE_AREA); 603 if (area_desc < B_OK) 604 return LM_STATUS_FAILURE; 605 606 memset(pvirt, 0, BlockSize); 607 *pMemoryBlockVirt = (PLM_VOID) pvirt; 608 609 get_memory_map(pvirt,BlockSize,&entry,1); 610 *pMemoryBlockPhy = entry.address; 611 612 return LM_STATUS_SUCCESS; 613} 614 615 616LM_STATUS 617b44_MM_GetConfig(PLM_DEVICE_BLOCK pDevice) 618{ 619 pDevice->DisableAutoNeg = FALSE; 620 pDevice->RequestedLineSpeed = LM_LINE_SPEED_AUTO; 621 pDevice->RequestedDuplexMode = LM_DUPLEX_MODE_FULL; 622 pDevice->FlowControlCap |= LM_FLOW_CONTROL_AUTO_PAUSE; 623 //pDevice->TxPacketDescCnt = tx_pkt_desc_cnt[DEFAULT_TX_PACKET_DESC_COUNT]; 624 pDevice->RxPacketDescCnt = DEFAULT_RX_PACKET_DESC_COUNT; 625 626 return LM_STATUS_SUCCESS; 627} 628 629 630LM_STATUS 631b44_MM_IndicateStatus(PLM_DEVICE_BLOCK pDevice, LM_STATUS Status) 632{ 633#ifdef HAIKU_TARGET_PLATFORM_HAIKU 634 struct be_b44_dev *pUmDevice = (struct be_b44_dev *)pDevice; 635 636 if (pUmDevice->linkChangeSem != -1) 637 release_sem_etc(pUmDevice->linkChangeSem, 1, 638 B_DO_NOT_RESCHEDULE); 639#endif 640 641 return LM_STATUS_SUCCESS; 642} 643 644 645LM_STATUS 646b44_MM_InitializeUmPackets(PLM_DEVICE_BLOCK pDevice) 647{ 648 int i; 649 struct B_UM_PACKET *pUmPacket; 650 PLM_PACKET pPacket; 651 652 for (i = 0; i < pDevice->RxPacketDescCnt; i++) { 653 pPacket = QQ_PopHead(&pDevice->RxPacketFreeQ.Container); 654 pUmPacket = (struct B_UM_PACKET *) pPacket; 655 pUmPacket->data = chunk_pool_get(); 656 /*if (pUmPacket->data == 0) { 657 QQ_PushTail(&pUmDevice->rx_out_of_buf_q.Container, pPacket); 658 continue; 659 }*/ 660 pPacket->u.Rx.pRxBufferVirt = pUmPacket->data; 661 QQ_PushTail(&pDevice->RxPacketFreeQ.Container, pPacket); 662 } 663 664 return LM_STATUS_SUCCESS; 665} 666 667 668LM_STATUS 669b44_MM_FreeRxBuffer(PLM_DEVICE_BLOCK pDevice, PLM_PACKET pPacket) 670{ 671 struct B_UM_PACKET *pUmPacket; 672 pUmPacket = (struct B_UM_PACKET *)pPacket; 673 chunk_pool_put(pUmPacket->data); 674 pUmPacket->data = NULL; 675 return LM_STATUS_SUCCESS; 676} 677