1/* 2 * Copyright (c) 1998-2001 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * The contents of this file constitute Original Code as defined in and 7 * are subject to the Apple Public Source License Version 1.1 (the 8 * "License"). You may not use this file except in compliance with the 9 * License. Please obtain a copy of the License at 10 * http://www.apple.com/publicsource and read it before using this file. 11 * 12 * This Original Code and all software distributed under the License are 13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER 14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the 17 * License for the specific language governing rights and limitations 18 * under the License. 19 * 20 * @APPLE_LICENSE_HEADER_END@ 21 */ 22#include "IOFireWireIP.h" 23#include "IOFireWireIPCommand.h" 24#include <IOKit/firewire/IOFireWireController.h> 25 26extern "C" 27{ 28void _logMbuf(struct mbuf * m); 29void _logPkt(void *pkt, UInt16 len); 30} 31 32#define super IOFWController 33 34OSDefineMetaClassAndStructors(IOFireWireIP, IOFWController); 35 36#pragma mark - 37#pragma mark ��� IOService methods ��� 38 39bool IOFireWireIP::start(IOService *provider) 40{ 41 IOReturn ioStat = kIOReturnSuccess; 42 43 if(fStarted) 44 return fStarted; 45 46 // Create the lock 47 if(ioStat == kIOReturnSuccess) 48 { 49 // Allocate lock 50 ipLock = IORecursiveLockAlloc(); 51 52 if(ipLock == NULL) 53 ioStat = kIOReturnNoMemory; 54 } 55 56 if(ioStat == kIOReturnSuccess) 57 { 58 recursiveScopeLock lock(ipLock); 59 60 fIPoFWDiagnostics.fMaxPktSize = 0; 61 netifEnabled = false; 62 busifEnabled = false; 63 fClientStarting = false; 64 fIPoFWDiagnostics.fDoFastRetry = false; 65 66 fDevice = OSDynamicCast(IOFireWireNub, provider); 67 68 if(!fDevice) 69 return false; 70 71 fControl = fDevice->getController(); 72 73 if(!fControl) 74 return false; 75 76 fControl->retain(); 77 78 OSObject * prop = fDevice->getProperty(gFireWire_GUID); 79 if( prop ) 80 { 81 setProperty( gFireWire_GUID, prop ); 82 } 83 84 // Initialize the LCB 85 fLcb = (LCB*)IOMalloc(sizeof(LCB)); 86 if(fLcb == NULL) 87 return false; 88 89 memset(fLcb, 0, sizeof(LCB)); 90 91 fDiagnostics_Symbol = OSSymbol::withCStringNoCopy("Diagnostics"); 92 93 fDiagnostics = IOFireWireIPDiagnostics::createDiagnostics(this); 94 if( fDiagnostics ) 95 { 96 if(fDiagnostics_Symbol) 97 setProperty( fDiagnostics_Symbol, fDiagnostics ); 98 fDiagnostics->release(); 99 } 100 101 if(ioStat == kIOReturnSuccess) { 102 103 CSRNodeUniqueID fwuid = fDevice->getUniqueID(); 104 105 // Construct the ethernet address 106 makeEthernetAddress(&fwuid, macAddr, GUID_TYPE); 107 } 108 109 // IONetworkingFamily attachments 110 if (!super::start(provider)) 111 return false; 112 113 if (getHardwareAddress(&myAddress) != kIOReturnSuccess) 114 { 115 return false; 116 } 117 118 if(!createMediumState()) 119 { 120 IOLog( "IOFireWireIP::start - Couldn't allocate IONetworkMedium\n" ); 121 return false; 122 } 123 124 125 if(ioStat == kIOReturnSuccess) 126 { 127 // Add unit notification for units disappearing 128 fIPUnitNotifier = IOService::addMatchingNotification(gIOPublishNotification, 129 serviceMatching("IOFireWireIPUnit"), 130 &fwIPUnitAttach, this, (void*)IP1394_VERSION, 0); 131 } 132 133 if(ioStat == kIOReturnSuccess) 134 { 135 // Add unit notification for units disappearing 136 fIPv6UnitNotifier = IOService::addMatchingNotification(gIOPublishNotification, 137 serviceMatching("IOFireWireIPUnit"), 138 &fwIPUnitAttach, this, (void*)IP1394v6_VERSION, 0); 139 } 140 141 // Create config rom entry 142 if(ioStat == kIOReturnSuccess) 143 ioStat = createIPConfigRomEntry(); 144 145 if(ioStat == kIOReturnSuccess) 146 { 147 fDevice->getNodeIDGeneration(fLcb->busGeneration, fLcb->ownNodeID); 148 fLcb->ownMaxSpeed = fDevice->FWSpeed(); 149 fLcb->maxBroadcastPayload = fDevice->maxPackLog(true); 150 fLcb->maxBroadcastSpeed = fDevice->FWSpeed(); 151 fLcb->ownMaxPayload = fDevice->maxPackLog(true); 152 153 IP1394_HDW_ADDR hwAddr; 154 155 CSRNodeUniqueID fwuid = fDevice->getUniqueID(); 156 157 memset(&hwAddr, 0, sizeof(IP1394_HDW_ADDR)); 158 hwAddr.eui64.hi = OSSwapHostToBigInt32((UInt32)(fwuid >> 32)); 159 hwAddr.eui64.lo = OSSwapHostToBigInt32((UInt32)(fwuid & 0xffffffff)); 160 161 hwAddr.maxRec = fControl->getMaxRec(); 162 hwAddr.spd = fDevice->FWSpeed(); 163 164 hwAddr.unicastFifoHi = kUnicastHi; 165 hwAddr.unicastFifoLo = kUnicastLo; 166 167 memcpy(&fLcb->ownHardwareAddress, &hwAddr, sizeof(IP1394_HDW_ADDR)); 168 169 UInt32 size = getMaxARDMAPacketSize(); 170 171 if(size > 0) 172 fLcb->ownHardwareAddress.maxRec = getMaxARDMARec(size); 173 174 setProperty(kIOFWHWAddr, (void *)&fLcb->ownHardwareAddress, sizeof(IP1394_HDW_ADDR)); 175 } 176 177 if(ioStat != kIOReturnSuccess) 178 { 179 IOLog( "IOFireWireIP::start - failed\n" ); 180 return false; 181 } 182 183 if (!attachInterface((IONetworkInterface**)&networkInterface, false )) 184 { 185 return false; 186 } 187 188 fPrivateInterface = NULL; 189 190 networkInterface->setIfnetMTU( 1 << fDevice->maxPackLog(true) ); 191 192 transmitQueue = (IOGatedOutputQueue*)getOutputQueue(); 193 if ( !transmitQueue ) 194 { 195 IOLog( "IOFireWireIP::start - Output queue initialization failed\n" ); 196 return false; 197 } 198 transmitQueue->retain(); 199 200 // Publish interface name if tunnelled Thunderbolt device 201 OSBoolean * tunnelled = OSDynamicCast( OSBoolean, getProperty("IOPCITunnelled", gIOServicePlane, kIORegistryIterateParents | kIORegistryIterateRecursively) ); 202 if ( (tunnelled != NULL) ) 203 { 204 if ( (tunnelled->isTrue()) ) 205 { 206 OSData * tbtVendorID = (OSData *)getProperty("Tunnel Endpoint Device Vendor ID", gIOServicePlane, kIORegistryIterateParents | kIORegistryIterateRecursively); 207 OSData * tbtModelID = (OSData *)getProperty("Tunnel Endpoint Device Model ID", gIOServicePlane, kIORegistryIterateParents | kIORegistryIterateRecursively); 208 209 if ( tbtVendorID && tbtModelID ) 210 { 211 uint32_t j59VendorID = 0x00000001; 212 uint32_t j59ModelID = 0x00008002; 213 uint32_t * tbtVendorIDPtr = (uint32_t *)(tbtVendorID->getBytesNoCopy(0, 4)); 214 uint32_t * tbtModelIDPtr = (uint32_t *)(tbtModelID->getBytesNoCopy(0, 4)); 215 216 //IOLog( "IOFireWireIP: VID: 0x%x MID: 0x%x\n", *tbtVendorIDPtr, *tbtModelIDPtr ); 217 218 if ( j59VendorID == *tbtVendorIDPtr && j59ModelID == *tbtModelIDPtr ) 219 { 220 setProperty("Product Name", "Display FireWire"); 221 } 222 else 223 { 224 OSData * tbtUID = (OSData *)getProperty("Tunnel Endpoint GUID", gIOServicePlane, kIORegistryIterateParents | kIORegistryIterateRecursively); 225 226 if ( tbtUID ) 227 { 228 OSDictionary * matchDict = serviceMatching( "IOThunderboltSwitch" ); 229 const OSSymbol * uidSym = OSSymbol::withCString( "UID" ); 230 OSNumber * tbtUIDNumber = OSNumber::withNumber( *((uint64_t *)(tbtUID->getBytesNoCopy(0, 8))), 64 ); 231 232 if ( matchDict && uidSym && tbtUIDNumber ) 233 { 234 matchDict = propertyMatching( uidSym, tbtUIDNumber, matchDict ); 235 236 mach_timespec_t timeout = { 10, 0 }; 237 IOService * tbtSwitch = waitForService( matchDict, &timeout ); 238 239 if ( tbtSwitch ) 240 { 241 /* 242 OSString * modelName = (OSString *)(tbtSwitch->getProperty("Device Model Name", gIOServicePlane, 0)); 243 244 if ( modelName ) 245 { 246 char propertyName[256]; 247 bzero(propertyName, sizeof(propertyName)); 248 249 // could be ugly with devices with "FireWire" in the name 250 snprintf(propertyName, sizeof(propertyName)-1, "%s (FireWire)", modelName->getCStringNoCopy()); 251 252 setProperty("Product Name", propertyName); 253 } 254 */ 255 256 setProperty("Product Name", "Thunderbolt FireWire"); 257 } 258 } 259 } 260 } 261 } 262 } 263 } 264 265 networkInterface->registerService(); 266 267 registerService(); 268 269 fStarted = true; 270 } 271 272 return fStarted; 273} // end start 274 275bool IOFireWireIP::matchPropertyTable(OSDictionary * table) 276{ 277 // 278 // If the service object wishes to compare some of its properties in its 279 // property table against the supplied matching dictionary, 280 // it should do so in this method and return truth on success. 281 // 282 if (!IOService::matchPropertyTable(table)) return false; 283 284 // We return success if the following expression is true -- individual 285 // comparisions evaluate to truth if the named property is not present 286 // in the supplied matching dictionary. 287 return compareProperty(table, gFireWire_GUID); 288} 289 290bool IOFireWireIP::finalize(IOOptionBits options) 291{ 292 return super::finalize(options); 293} 294 295void IOFireWireIP::stop(IOService *provider) 296{ 297 recursiveScopeLock lock(ipLock); 298 299 if(fDiagnostics_Symbol != NULL) 300 fDiagnostics_Symbol->release(); 301 302 fDiagnostics_Symbol = 0; 303 304 // Free the firewire stuff 305 if (fLocalIP1394v6ConfigDirectory != NULL) 306 { 307 // clear the unit directory in config rom 308 fDevice->getBus()->RemoveUnitDirectory(fLocalIP1394v6ConfigDirectory) ; 309 fLocalIP1394v6ConfigDirectory->release(); 310 } 311 fLocalIP1394v6ConfigDirectory = NULL; 312 313 // Free the firewire stuff 314 if (fLocalIP1394ConfigDirectory != NULL) 315 { 316 // clear the unit directory in config rom 317 fDevice->getBus()->RemoveUnitDirectory(fLocalIP1394ConfigDirectory) ; 318 fLocalIP1394ConfigDirectory->release(); 319 } 320 321 fLocalIP1394ConfigDirectory = NULL; 322 323 if(fwOwnAddr != NULL) 324 fwOwnAddr->release(); 325 326 fwOwnAddr = NULL; 327 328 if (transmitQueue != NULL) 329 transmitQueue->release(); 330 331 transmitQueue = NULL; 332 333 if(fIPv6UnitNotifier != NULL) 334 fIPv6UnitNotifier->remove(); 335 336 fIPv6UnitNotifier = NULL; 337 338 // Remove IOFireWireIPUnit notification 339 if(fIPUnitNotifier != NULL) 340 fIPUnitNotifier->remove(); 341 342 fIPUnitNotifier = NULL; 343 344 if(fLcb != NULL) 345 IOFree(fLcb, sizeof(LCB)); 346 347 fLcb = NULL; 348 349 if (networkInterface != NULL) 350 { 351 detachInterface(networkInterface); 352 networkInterface->release(); 353 } 354 355 networkInterface = NULL; 356 357 if(fControl != NULL) 358 fControl->release(); 359 360 fControl = NULL; 361 362 super::stop(provider); 363} 364 365void IOFireWireIP::free(void) 366{ 367 if (ipLock != NULL) 368 IORecursiveLockFree(ipLock); 369 370 ipLock = NULL; 371 372 return super::free(); 373} 374 375IOReturn IOFireWireIP::message(UInt32 type, IOService *provider, void *argument) 376{ 377 IOReturn res = kIOReturnUnsupported; 378 379 switch (type) 380 { 381 case kIOMessageServiceIsTerminated: 382 case kIOMessageServiceIsSuspended: 383 case kIOMessageServiceIsResumed: 384 case kIOMessageServiceIsRequestingClose: 385 if(busifEnabled) 386 messageClients(type, this); 387 res = kIOReturnSuccess; 388 break; 389 390 default: 391 break; 392 } 393 394 return res; 395} 396 397#pragma mark - 398#pragma mark ��� IOFWController methods ��� 399 400IOReturn IOFireWireIP::setMaxPacketSize(UInt32 maxSize) 401{ 402 if (maxSize > kIOFWMaxPacketSize) 403 return kIOReturnError; 404 405 return kIOReturnSuccess; 406} 407 408IOReturn IOFireWireIP::getMaxPacketSize(UInt32 * maxSize) const 409{ 410 *maxSize = kIOFWMaxPacketSize; 411 412 return kIOReturnSuccess; 413} 414 415IOReturn IOFireWireIP::getHardwareAddress(IOFWAddress *ea) 416{ 417 memcpy(ea->bytes, macAddr, kIOFWAddressSize); 418 419 return kIOReturnSuccess; 420} // end getHardwareAddress 421 422 423bool IOFireWireIP::configureInterface( IONetworkInterface *netif ) 424{ 425 IONetworkData *nd; 426 427 if ( super::configureInterface( netif ) == false ) 428 return false; 429 430 // Grab a pointer to the statistics structure in the interface: 431 nd = netif->getNetworkData( kIONetworkStatsKey ); 432 if (!nd || !(fpNetStats = (IONetworkStats *) nd->getBuffer())) 433 { 434 IOLog("IOFireWireIP: invalid network statistics\n"); 435 return false; 436 } 437 438 // Get the Ethernet statistics structure: 439 nd = netif->getParameter( kIOFWStatsKey ); 440 if ( !nd || !(fpEtherStats = (IOFWStats*)nd->getBuffer()) ) 441 { 442 IOLog( "IOFireWireIP::configureInterface - invalid ethernet statistics\n" ); 443 return false; 444 } 445 446 /* 447 * Set the driver/stack reentrancy flag. This is meant to reduce 448 * context switches. May become irrelevant in the future. 449 */ 450 return true; 451 452} // end configureInterface 453 454void IOFireWireIP::receivePackets(mbuf_t pkt, UInt32 pkt_len, UInt32 options) 455{ 456 if(options == true) 457 fPacketsQueued = true; 458 459 IORecursiveLockLock(ipLock); 460 461 networkInterface->inputPacket(pkt, pkt_len, options); 462 networkStatAdd(&fpNetStats->inputPackets); 463 464 IORecursiveLockUnlock(ipLock); 465} 466 467IOOutputQueue* IOFireWireIP::createOutputQueue() 468{ 469 return IOGatedOutputQueue::withTarget(this, getWorkLoop(), TRANSMIT_QUEUE_SIZE); 470} 471 472/*------------------------------------------------------------------------- 473 * Override IONetworkController::createWorkLoop() method and create 474 * a workloop. 475 *-------------------------------------------------------------------------*/ 476bool IOFireWireIP::createWorkLoop() 477{ 478 workLoop = fDevice->getController()->getWorkLoop(); 479 480 return ( workLoop != 0 ); 481} // end createWorkLoop 482 483 484// Override IOService::getWorkLoop() method to return our workloop. 485IOWorkLoop* IOFireWireIP::getWorkLoop() const 486{ 487 return workLoop; 488} // end getWorkLoop 489 490IOOutputAction IOFireWireIP::getOutputHandler() const 491{ 492 return (IOOutputAction) &IOFireWireIP::transmitPacket; 493} 494 495bool IOFireWireIP::multicastCacheHandler(IOFWAddress *addrs, UInt32 count) 496{ 497 bool ret = false; 498 499 if( busifEnabled ) 500 { 501 IORecursiveLockLock(ipLock); 502 503 if( fUpdateMulticastCache ) 504 ret = (*fUpdateMulticastCache)(fPrivateInterface, addrs, count); 505 506 IORecursiveLockUnlock(ipLock); 507 } 508 509 return ret; 510} 511 512bool IOFireWireIP::arpCacheHandler(IP1394_ARP *fwa) 513{ 514 bool ret = false; 515 516 if( busifEnabled ) 517 { 518 IORecursiveLockLock(ipLock); 519 520 if( fUpdateARPCache ) 521 ret = (*fUpdateARPCache)(fPrivateInterface, fwa); 522 523 IORecursiveLockUnlock(ipLock); 524 } 525 526 return ret; 527} 528 529UInt32 IOFireWireIP::transmitPacket(mbuf_t m, void * param) 530{ 531 IOReturn status = kIOReturnOutputDropped; 532 533 if( busifEnabled ) 534 { 535 IORecursiveLockLock(ipLock); 536 537 if( fOutAction ) 538 status = (*fOutAction)(m, (void*)fPrivateInterface); 539 540 IORecursiveLockUnlock(ipLock); 541 } 542 else 543 freePacket(m); 544 545 return status; 546} 547 548UInt32 IOFireWireIP::outputPacket(mbuf_t pkt, void * param) 549{ 550 IOReturn status = kIOReturnOutputDropped; 551 552 // Its just a sink, until we get a valid unit on the bus. 553 ((IOFireWireIP*)param)->freePacket(pkt); 554 555 return status; 556} 557 558/*------------------------------------------------------------------------- 559 * Called by IOEthernetInterface client to enable the controller. 560 * This method is always called while running on the default workloop 561 * thread. 562 *-------------------------------------------------------------------------*/ 563IOReturn IOFireWireIP::enable(IONetworkInterface * netif) 564{ 565 /* 566 * If an interface client has previously enabled us, 567 * and we know there can only be one interface client 568 * for this driver, then simply return true. 569 */ 570 if (netifEnabled) 571 { 572 IOLog("IOFireWireIP: already enabled\n"); 573 return kIOReturnSuccess; 574 } 575 576 /* 577 * Mark the controller as enabled by the interface. 578 */ 579 netifEnabled = true; 580 581 /* 582 * Start our IOOutputQueue object. 583 */ 584 transmitQueue->setCapacity( TRANSMIT_QUEUE_SIZE ); 585 transmitQueue->start(); 586 587 return kIOReturnSuccess; 588 589}// end enable netif 590 591 592/*------------------------------------------------------------------------- 593 * Called by IOEthernetInterface client to disable the controller. 594 * This method is always called while running on the default workloop 595 * thread. 596 *-------------------------------------------------------------------------*/ 597IOReturn IOFireWireIP::disable(IONetworkInterface * /*netif*/) 598{ 599 netifEnabled = false; 600 601 /* 602 * Disable our IOOutputQueue object. This will prevent the 603 * outputPacket() method from being called. 604 */ 605 transmitQueue->stop(); 606 607 /* 608 * Flush all packets currently in the output queue. 609 */ 610 transmitQueue->setCapacity( 0 ); 611 transmitQueue->flush(); 612 613 return kIOReturnSuccess; 614 615}// end disable netif 616 617 618IOReturn IOFireWireIP::getPacketFilters( const OSSymbol *group, UInt32 *filters ) const 619{ 620 return super::getPacketFilters( group, filters ); 621}// end getPacketFilters 622 623 624IOReturn IOFireWireIP::setWakeOnMagicPacket( bool active ) 625{ 626 return kIOReturnSuccess; 627}// end setWakeOnMagicPacket 628 629const OSString * IOFireWireIP::newVendorString() const 630{ 631 return OSString::withCString("Apple"); 632} 633 634const OSString * IOFireWireIP::newModelString() const 635{ 636 return OSString::withCString("fw+"); 637} 638 639const OSString * IOFireWireIP::newRevisionString() const 640{ 641 return OSString::withCString(""); 642} 643 644IOReturn IOFireWireIP::setPromiscuousMode( bool active ) 645{ 646 isPromiscuous = active; 647 648 return kIOReturnSuccess; 649} // end setPromiscuousMode 650 651IOReturn IOFireWireIP::setMulticastMode( bool active ) 652{ 653 multicastEnabled = active; 654 655 return kIOReturnSuccess; 656}// end setMulticastMode 657 658IOReturn IOFireWireIP::setMulticastList(IOFWAddress *addrs, UInt32 count) 659{ 660 multicastCacheHandler(addrs, count); 661 662 return kIOReturnSuccess; 663} 664 665/*! 666 @function createMediumState 667 @abstract 668 @param none. 669 @result create a supported medium information and 670 attach to the IONetworkingFamily. 671*/ 672bool IOFireWireIP::createMediumState() 673{ 674 OSDictionary * mediumDict = OSDictionary::withCapacity(5); 675 if (!mediumDict) 676 { 677 return false; 678 } 679 680 IONetworkMedium * medium = IONetworkMedium::medium( 681 (IOMediumType)kIOMediumEthernetAuto | 682 kIOMediumOptionFullDuplex, fLcb->maxBroadcastSpeed); 683 if (medium) 684 { 685 mediumDict->setObject(medium->getKey(), medium); 686 setCurrentMedium(medium); 687 medium->release(); 688 } 689 690 if (!publishMediumDictionary(mediumDict)) 691 { 692 return false; 693 } 694 695 if( mediumDict ) 696 { 697 mediumDict->release(); 698 } 699 700 // Link status is Valid and inactive 701 return setLinkStatus( kIONetworkLinkValid, getCurrentMedium(), 0 ); 702} 703 704/*! 705 @function getFeatures 706 @abstract 707 @param none. 708 @result Tell family we can handle multipage mbufs. kIONetworkFeatureMultiPages 709*/ 710UInt32 IOFireWireIP::getFeatures() const 711{ 712 UInt32 result = 0; 713 714#if VERSION_MAJOR >= 9 715 result |= kIONetworkFeatureMultiPages; 716#endif 717 718 return result; 719} 720 721#pragma mark - 722#pragma mark ��� IOFirewireIP methods ��� 723 724 725/*! 726 @function getBytesFromGUID 727 @abstract constructs byte array from the GUID. 728 @param fwuid - GUID of the node. 729 @param bufAddr - pointer to the buffer. 730 @result void. 731*/ 732void IOFireWireIP::getBytesFromGUID(void *guid, UInt8 *bufAddr, UInt8 type) 733{ 734 u_long lo=0, hi=0; 735 736 if(type == GUID_TYPE) 737 { 738 CSRNodeUniqueID *fwuid = (CSRNodeUniqueID*)guid; 739 hi = (u_long)(*fwuid >> 32); 740 lo = (u_long)(*fwuid & 0xffffffff); 741 } 742 else 743 { 744 UWIDE *eui64 = (UWIDE*)guid; 745 hi = eui64->hi; 746 lo = eui64->lo; 747 } 748 749 bufAddr[0] = (unsigned char)((hi >> 24) & 0x000000ff); 750 bufAddr[1] = (unsigned char)((hi >> 16) & 0x000000ff); 751 bufAddr[2] = (unsigned char)((hi >> 8) & 0x000000ff); 752 bufAddr[3] = (unsigned char)((hi) & 0x000000ff); 753 754 bufAddr[4] = (unsigned char)((lo >> 24) & 0x000000ff); 755 bufAddr[5] = (unsigned char)((lo >> 16) & 0x000000ff); 756 bufAddr[6] = (unsigned char)((lo >> 8) & 0x000000ff); 757 bufAddr[7] = (unsigned char)((lo) & 0x000000ff); 758} 759 760/*! 761 @function makeEthernetAddress 762 @abstract constructs mac address from the GUID. 763 @param fwuid - GUID of the node. 764 @param bufAddr - pointer to the buffer. 765 @param vendorID - vendorID. 766 @result void. 767*/ 768void IOFireWireIP::makeEthernetAddress(CSRNodeUniqueID *fwuid, UInt8 *bufAddr, UInt32 vendorID) 769{ 770 getBytesFromGUID(fwuid, bufAddr, GUID_TYPE); 771} 772 773void IOFireWireIP::updateMTU(UInt32 mtu) 774{ 775 networkInterface->setIfnetMTU( mtu ); 776} 777 778UInt32 IOFireWireIP::getMaxARDMAPacketSize() 779{ 780 UInt32 maxARDMASize = 0; 781 782 OSObject *regProperty = fControl->getProperty("FWARDMAMax", gIOServicePlane); 783 784 if(regProperty != NULL) 785 { 786 maxARDMASize = ((OSNumber*)regProperty)->unsigned32BitValue(); 787 maxARDMASize -= sizeof(IP1394_UNFRAG_HDR); 788 } 789 790 return maxARDMASize; 791} 792 793UInt8 IOFireWireIP::getMaxARDMARec(UInt32 size) 794{ 795 UInt8 maxRecLog = 1; 796 797 while( (size >= 8) && (maxRecLog < 15) ) 798 { 799 size >>= 1; 800 maxRecLog++; 801 } 802 803 return maxRecLog; 804} 805 806bool IOFireWireIP::clientStarting() 807{ 808 IORecursiveLockLock(ipLock); 809 810 bool status = fClientStarting; 811 812 if ( fClientStarting == false ) 813 { 814 fClientStarting = true; 815 } 816 817 IORecursiveLockUnlock(ipLock); 818 819 return status; 820} 821 822void IOFireWireIP::registerFWIPPrivateHandlers(IOFireWireIPPrivateHandlers *privateSelf) 823{ 824 if(busifEnabled) 825 return; 826 827 IORecursiveLockLock(ipLock); 828 829 fPrivateInterface = privateSelf->newService; 830 fOutAction = privateSelf->transmitPacket; 831 fUpdateARPCache = privateSelf->updateARPCache; 832 fUpdateMulticastCache = privateSelf->updateMulticastCache; 833 834 busifEnabled = true; 835 836 IORecursiveLockUnlock(ipLock); 837} 838 839void IOFireWireIP::deRegisterFWIPPrivateHandlers() 840{ 841 if ( not busifEnabled) 842 return; 843 844 IORecursiveLockLock(ipLock); 845 846 // Last unit is going away 847 busifEnabled = false; 848 fPrivateInterface = NULL; 849 fOutAction = NULL; 850 fUpdateARPCache = NULL; 851 fClientStarting = false; 852 853 IORecursiveLockUnlock(ipLock); 854} 855 856/*! 857 @function fwIPUnitAttach 858 @abstract Callback for a Unit attached of type IP1394 859 @param target - callback data. 860 @param refcon - callback data. 861 @param newService - handle to the new IP1394 unit created. 862 @result bool. 863*/ 864bool IOFireWireIP::fwIPUnitAttach(void * target, void * refCon, IOService * newService, IONotifier * notifier) 865{ 866 if(target == NULL || newService == NULL) 867 return false; 868 869 IOFireWireIP *fwIPObject = OSDynamicCast(IOFireWireIP, (IOService *)target); 870 if ( not fwIPObject ) 871 return false; 872 873 // Create the device reference block for this IP device 874 IOFireWireNub *fDevice = OSDynamicCast(IOFireWireNub, newService->getProvider()); 875 if ( not fDevice ) 876 return false; 877 878 // mismatch of new controller and localnode controller results in false 879 if(fwIPObject->fControl != fDevice->getController()) 880 return false; 881 882 return true; 883} 884 885/*! 886 @function createIPConfigRomEntry 887 @abstract creates the config rom entry for IP over Firewire. 888 @param none 889 @result IOReturn - kIOReturnSuccess or error if failure. 890*/ 891IOReturn IOFireWireIP::createIPConfigRomEntry() 892{ 893 IOReturn ioStat = kIOReturnSuccess; 894 // Create entries for UnitSpecID and UnitSwVersion 895 fLocalIP1394ConfigDirectory = IOLocalConfigDirectory::create(); 896 897 if (!fLocalIP1394ConfigDirectory){ 898 ioStat = kIOReturnError; 899 } 900 901 if(ioStat == kIOReturnSuccess) 902 ioStat = fLocalIP1394ConfigDirectory->addEntry(kConfigUnitSpecIdKey, IP1394_SPEC_ID) ; 903 904 if(ioStat == kIOReturnSuccess) 905 ioStat = fLocalIP1394ConfigDirectory->addEntry(kConfigUnitSwVersionKey, IP1394_VERSION) ; 906 907 // lets publish it 908 if(ioStat == kIOReturnSuccess) 909 ioStat = fControl->AddUnitDirectory(fLocalIP1394ConfigDirectory) ; 910 911 // Create entries for IPv6 UnitSpecID and UnitSwVersion 912 fLocalIP1394v6ConfigDirectory = IOLocalConfigDirectory::create(); 913 914 if (!fLocalIP1394v6ConfigDirectory){ 915 ioStat = kIOReturnError; 916 } 917 918 if(ioStat == kIOReturnSuccess) 919 ioStat = fLocalIP1394v6ConfigDirectory->addEntry(kConfigUnitSpecIdKey, IP1394_SPEC_ID) ; 920 921 if(ioStat == kIOReturnSuccess) 922 ioStat = fLocalIP1394v6ConfigDirectory->addEntry(kConfigUnitSwVersionKey, IP1394v6_VERSION) ; 923 924 if(ioStat == kIOReturnSuccess) 925 ioStat = fControl->AddUnitDirectory(fLocalIP1394v6ConfigDirectory) ; 926 927 return ioStat; 928} 929 930#ifdef DEBUG 931void _logMbuf(mbuf_t m) 932{ 933 UInt8 *bytePtr; 934 935 if (!m) { 936 IOLog("logMbuf: NULL mbuf\n"); 937 return; 938 } 939 940 while (m) { 941 IOLog("m_next : %p\n", (void*) mbuf_next(m)); 942 IOLog("m_nextpkt: %p\n", (void*) mbuf_nextpkt(m)); 943 IOLog("m_len : %d\n", (UInt) mbuf_len(m)); 944 IOLog("m_data : %p\n", (void*) mbuf_data(m)); 945 IOLog("m_type : %08x\n", (UInt) mbuf_type(m)); 946 IOLog("m_flags : %08x\n", (UInt) mbuf_flags(m)); 947 948 if (mbuf_flags(m) & MBUF_PKTHDR) 949 IOLog("mbuf_pkthdr.len : %d\n", (UInt) mbuf_pkthdr_len(m)); 950 951 if (mbuf_flags(m) & M_EXT) { 952 // IOLog("m_ext.ext_buf : %08x\n", (UInt) mbuf_ext(m)); 953 // IOLog("m_ext.ext_size: %d\n", (UInt) m->m_ext.ext_size); 954 } 955 956 IOLog("m_data -> \t\t") ; 957 958 if( mbuf_data(m) != NULL){ 959 960 bytePtr = (UInt8*)mbuf_data(m); 961 962 for(SInt32 index=0; index < min(mbuf_len(m), 12); index++) 963 { 964 if ((index & 0x3) == 0) 965 { 966 IOLog(" ") ; 967 if ((index & 0x7) == 0) 968 { 969 IOLog(" ") ; 970 if ((index & 0xF) == 0) 971 IOLog("\n\t\t") ; 972 } 973 } 974 IOLog("%02X", (unsigned char)bytePtr[index]) ; 975 } 976 IOLog("\n\n") ; 977 } 978 979 m = mbuf_next(m); 980 } 981 IOLog("\n"); 982} 983 984void _logPkt(void *pkt, UInt16 len) 985{ 986 UInt8 *bytePtr; 987 988 bytePtr = (UInt8*)pkt; 989 990 IOLog("pkt {\n") ; 991 992 for(SInt32 index=0; index<len; index++) 993 { 994 if ((index & 0x3) == 0) 995 { 996 IOLog(" ") ; 997 if ((index & 0x7) == 0) 998 { 999 IOLog(" ") ; 1000 if ((index & 0xF) == 0) 1001 IOLog("\n\t\t") ; 1002 } 1003 } 1004 IOLog("%02X", (unsigned char)bytePtr[index]) ; 1005 } 1006 IOLog("}\n\n") ; 1007} 1008#endif 1009