|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1998-2000 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: /* ! 23: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 24: * ! 25: * IOEthernetController.cpp ! 26: * ! 27: * Abstract Ethernet controller superclass. ! 28: * ! 29: * HISTORY ! 30: * ! 31: * Dec 3, 1998 jliu - C++ conversion. ! 32: */ ! 33: ! 34: #include <IOKit/assert.h> ! 35: #include <IOKit/network/IOEthernetController.h> ! 36: #include <IOKit/network/IOEthernetInterface.h> ! 37: ! 38: //--------------------------------------------------------------------------- ! 39: ! 40: #define super IONetworkController ! 41: ! 42: OSDefineMetaClass( IOEthernetController, IONetworkController ) ! 43: ! 44: OSDefineAbstractStructors( IOEthernetController, IONetworkController ) ! 45: ! 46: //------------------------------------------------------------------------- ! 47: // Macros ! 48: ! 49: #ifdef DEBUG ! 50: #define DLOG(fmt, args...) IOLog(fmt, ## args) ! 51: #else ! 52: #define DLOG ! 53: #endif ! 54: ! 55: // Define SYNC_REQ macro to simplify syncRequest() calls. ! 56: // ! 57: #define SYNC_REQ(sender, action, ret, args...) \ ! 58: syncRequest(sender, this, (IONetworkAction) action, (UInt32 *) ret, \ ! 59: ## args) ! 60: ! 61: #define DO_SYNC_REQ(action, args...) \ ! 62: { \ ! 63: IOReturn ret = kIOReturnNotReady; \ ! 64: syncRequest(client, this, \ ! 65: (RequestAction) &IOEthernetController:: ## action, \ ! 66: (UInt32 *) &ret, ## args); \ ! 67: return ret; \ ! 68: } ! 69: ! 70: //--------------------------------------------------------------------------- ! 71: // Initialize an IOEthernetController instance. ! 72: ! 73: bool IOEthernetController::init(OSDictionary * properties) ! 74: { ! 75: if (!super::init(properties)) ! 76: { ! 77: DLOG("IOEthernetController: super::init() failed\n"); ! 78: return false; ! 79: } ! 80: ! 81: _mcMode = kIOEnetMulticastModeOff; ! 82: _prMode = kIOEnetPromiscuousModeOff; ! 83: ! 84: return true; ! 85: } ! 86: ! 87: //--------------------------------------------------------------------------- ! 88: // Frees the IOEthernetController instance. ! 89: ! 90: void IOEthernetController::free() ! 91: { ! 92: super::free(); ! 93: } ! 94: ! 95: //--------------------------------------------------------------------------- ! 96: // Publish Ethernet specific properties to the property ! 97: // table. For instance, getHardwareAddress() is called to fetch the ! 98: // hardware address. This method is called by the superclass and ! 99: // should never be called by drivers. ! 100: // ! 101: // Returns true if all capabilities were discovered and published ! 102: // successfully, false otherwise. Returning false will prevent client ! 103: // objects from attaching to the Ethernet controller since a property ! 104: // that a client depends on may be missing ! 105: ! 106: bool IOEthernetController::publishCapabilities() ! 107: { ! 108: bool ret = false; ! 109: enet_addr_t addr; ! 110: ! 111: if (!super::publishCapabilities()) ! 112: return false; ! 113: ! 114: // Publish the controller's MAC address. The Ethernet interface ! 115: // object will also publish this attribute, but the idea is that ! 116: // the controller will always publish the initial address read ! 117: // from the hardware, and it will remain static. While the ! 118: // address recorded by the interface may change if for instance ! 119: // a setHardwareAddress() is accepted by the controller. ! 120: ! 121: if (getHardwareAddress(&addr) == kIOReturnSuccess) ! 122: ret = setProperty(kIOMACAddress, (void *) &addr, NUM_EN_ADDR_BYTES); ! 123: ! 124: return ret; ! 125: } ! 126: ! 127: //--------------------------------------------------------------------------- ! 128: // Called when a client wishes to change the unicast address used ! 129: // by the controller's hardware filter. Implementation of this method is ! 130: // optional. ! 131: // ! 132: // addr: Pointer to an enet_addr_t containing the new Ethernet address. ! 133: // ! 134: // Returns kIOReturnUnsupported. Drivers that implement this method ! 135: // must return an appropriate return code. ! 136: ! 137: IOReturn IOEthernetController::setHardwareAddress(const enet_addr_t * /*addr*/) ! 138: { ! 139: return kIOReturnUnsupported; ! 140: } ! 141: ! 142: //--------------------------------------------------------------------------- ! 143: // Called by enablePacketFilters() when the controller's multicast filter ! 144: // mode needs to be changed. See IOEnetMulticastMode for the list of defined ! 145: // modes. ! 146: // ! 147: // mode: The new multicast filter mode. ! 148: // ! 149: // Returns kIOReturnUnsupported. Drivers must return kIOReturnSuccess to ! 150: // indicate success, or an error otherwise. ! 151: ! 152: IOReturn IOEthernetController::setMulticastMode(IOEnetMulticastMode /*mode*/) ! 153: { ! 154: return kIOReturnUnsupported; ! 155: } ! 156: ! 157: //--------------------------------------------------------------------------- ! 158: // Called by an interface client when its multicast group membership changes. ! 159: // Drivers that support multicasting should override this method and update ! 160: // the hardware filter using the address list provided. ! 161: // ! 162: // Perfect multicast filtering is preferred if supported by the hardware, ! 163: // in order to reduce the number of unwanted packets that are received. ! 164: // If the number of multicast addresses in the list exceed the limit ! 165: // set by the hardware, or if perfect filtering is not supported, ! 166: // then ideally the hardware should be programmed to perform imperfect ! 167: // filtering, perhaps through a hash table built by the driver. ! 168: // ! 169: // This method may be called only if getPacketFilters() ! 170: // reports that kIOPacketFilterMulticast is supported. ! 171: // ! 172: // addrs: Pointer to a list of multicast addresses. Not valid if ! 173: // the count argument is 0. ! 174: // count: The number of multicast addresses in the list. May be zero ! 175: // if the list is empty. ! 176: // ! 177: // Returns kIOReturnUnsupported. Drivers must return kIOReturnSuccess to ! 178: // indicate success, or an error otherwise. ! 179: ! 180: IOReturn IOEthernetController::setMulticastList(enet_addr_t * /*addrs*/, ! 181: UInt /*count*/) ! 182: { ! 183: return kIOReturnUnsupported; ! 184: } ! 185: ! 186: //--------------------------------------------------------------------------- ! 187: // Called by enablePacketFilters() when the controller's promiscuous filter ! 188: // mode needs to be changed. See IOEnetPromiscuousMode for the list of defined ! 189: // modes. ! 190: // ! 191: // mode: The new promiscuous filter mode. ! 192: // ! 193: // Returns kIOReturnUnsupported. Drivers must return kIOReturnSuccess to ! 194: // indicate success, or an error otherwise. ! 195: ! 196: IOReturn IOEthernetController::setPromiscuousMode(IOEnetPromiscuousMode /*m*/) ! 197: { ! 198: return kIOReturnUnsupported; ! 199: } ! 200: ! 201: //--------------------------------------------------------------------------- ! 202: // Report Ethernet family specific feature set. ! 203: ! 204: UInt32 IOEthernetController::getFamilyFeatureSet() const ! 205: { ! 206: return 0; ! 207: } ! 208: ! 209: //--------------------------------------------------------------------------- ! 210: // Allocate and return a new IOEthernetInterface instance. The controller ! 211: // class from each network family must implement this method inherited from ! 212: // IONetworkController to return the corresponding interface object when ! 213: // attachInterface() is called. Subclasses of IOEthernetController ! 214: // (Ethernet drivers) have little reason to override this implementation. ! 215: // ! 216: // Returns the allocated and initialized IOEthernetInterface instance. ! 217: ! 218: IONetworkInterface * IOEthernetController::createInterface() ! 219: { ! 220: IOEthernetInterface * enetIf = new IOEthernetInterface; ! 221: ! 222: if (enetIf && !enetIf->init()) ! 223: { ! 224: enetIf->release(); ! 225: enetIf = 0; ! 226: } ! 227: return enetIf; ! 228: } ! 229: ! 230: //--------------------------------------------------------------------------- ! 231: // Returns all the packet filters supported by the Ethernet controller. ! 232: // See IONetworkController for the list of packet filters. ! 233: // This method will perform a bitwise OR of: ! 234: // ! 235: // kIOPacketFilterUnicast ! 236: // kIOPacketFilterBroadcast ! 237: // kIOPacketFilterMulticast ! 238: // kIOPacketFilterPromiscuous ! 239: // ! 240: // and write the result to the integer pointed by 'filtersP'. Drivers that ! 241: // support a different set of filters should override this method. ! 242: // ! 243: // Returns kIOReturnSuccess. Drivers that override this method must return ! 244: // kIOReturnSuccess to indicate success, or an error otherwise. ! 245: ! 246: IOReturn IOEthernetController::getPacketFilters(UInt32 * filters) ! 247: { ! 248: *filters = (kIOPacketFilterUnicast | ! 249: kIOPacketFilterBroadcast | ! 250: kIOPacketFilterMulticast | ! 251: kIOPacketFilterPromiscuous); ! 252: ! 253: return kIOReturnSuccess; ! 254: } ! 255: ! 256: //--------------------------------------------------------------------------- ! 257: // Called by an interface object to change the set of packet filters that ! 258: // are enabled by the controller. The implementation in IOEthernetController ! 259: // will trap any changes to multicast or promiscuous filters and translate ! 260: // the changes into a filter mode for setMulticastMode() and ! 261: // setPromiscuousMode() methods. This is done strictly as a convenience for ! 262: // drivers, which may choose to override this method to handle the filter ! 263: // changes directly. Unicast and Broadcast filters are assumed to be always ! 264: // enabled, no driver intervention is required. ! 265: // ! 266: // filters: Each bit set indicates a particular filter that should be ! 267: // enabled. Filter bits that are not turned on must be disabled. ! 268: // activeFiltersP: Updated by this method to reflect the real set ! 269: // of active filters. Ideally, it should be the same as ! 270: // the set specified by the first argument. ! 271: // ! 272: // Returns kIOReturnSuccess for success, otherwise an error code is returned. ! 273: ! 274: IOReturn IOEthernetController::enablePacketFilters(UInt32 filters, ! 275: UInt32 * activeFiltersP) ! 276: { ! 277: IOEnetMulticastMode mcMode; ! 278: IOEnetPromiscuousMode prMode; ! 279: IOReturn ret = kIOReturnSuccess; ! 280: IOReturn err; ! 281: ! 282: #define ACTIVATE_FILTERS(x) (*activeFiltersP |= (filters & (x))) ! 283: ! 284: *activeFiltersP = 0; ! 285: ! 286: // Assume Unicast and Broadcast filters are always active. ! 287: // ! 288: if (filters & (kIOPacketFilterUnicast | kIOPacketFilterBroadcast)) ! 289: ACTIVATE_FILTERS(kIOPacketFilterUnicast | kIOPacketFilterBroadcast); ! 290: ! 291: // Update multicast mode. Avoid redundant mode transitions by ! 292: // caching the last successful multicast mode. ! 293: // ! 294: if (filters & kIOPacketFilterMulticastAll) ! 295: mcMode = kIOEnetMulticastModeAll; ! 296: else if (filters & kIOPacketFilterMulticast) ! 297: mcMode = kIOEnetMulticastModeFilter; ! 298: else ! 299: mcMode = kIOEnetMulticastModeOff; ! 300: ! 301: if (mcMode != _mcMode) ! 302: { ! 303: err = setMulticastMode(mcMode); ! 304: if (err == kIOReturnSuccess) ! 305: { ! 306: _mcMode = mcMode; ! 307: ACTIVATE_FILTERS(kIOPacketFilterMulticastAll | ! 308: kIOPacketFilterMulticast); ! 309: } ! 310: else { ! 311: _mcMode = kIOEnetMulticastModeOff; ! 312: ret = err; ! 313: } ! 314: } ! 315: else { ! 316: ACTIVATE_FILTERS(kIOPacketFilterMulticastAll | ! 317: kIOPacketFilterMulticast); ! 318: } ! 319: ! 320: // Update promiscuous mode. Avoid redundant mode transitions by ! 321: // caching the last successful promiscuous mode. ! 322: // ! 323: if (filters & kIOPacketFilterPromiscuousAll) ! 324: prMode = kIOEnetPromiscuousModeAll; ! 325: else if (filters & kIOPacketFilterPromiscuous) ! 326: prMode = kIOEnetPromiscuousModeOn; ! 327: else ! 328: prMode = kIOEnetPromiscuousModeOff; ! 329: ! 330: if (prMode != _prMode) ! 331: { ! 332: err = setPromiscuousMode(prMode); ! 333: if (err == kIOReturnSuccess) ! 334: { ! 335: _prMode = prMode; ! 336: ACTIVATE_FILTERS(kIOPacketFilterPromiscuousAll | ! 337: kIOPacketFilterPromiscuous); ! 338: } ! 339: else { ! 340: _prMode = kIOEnetPromiscuousModeOff; ! 341: ret = err; ! 342: } ! 343: } ! 344: else { ! 345: ACTIVATE_FILTERS(kIOPacketFilterPromiscuousAll | ! 346: kIOPacketFilterPromiscuous); ! 347: } ! 348: ! 349: return ret; ! 350: } ! 351: ! 352: //--------------------------------------------------------------------------- ! 353: // Call getHardwareAddress() through syncRequest(). See getHardwareAddress(). ! 354: ! 355: IOReturn ! 356: IOEthernetController::doGetHardwareAddress(IOService * client, ! 357: enet_addr_t * addr) ! 358: { ! 359: DO_SYNC_REQ(getHardwareAddress, (void *) addr) ! 360: } ! 361: ! 362: //--------------------------------------------------------------------------- ! 363: // Call setHardwareAddress() through syncRequest(). See setHardwareAddress(). ! 364: ! 365: IOReturn ! 366: IOEthernetController::doSetHardwareAddress(IOService * client, ! 367: const enet_addr_t * addr) ! 368: { ! 369: DO_SYNC_REQ(setHardwareAddress, (void *) addr) ! 370: } ! 371: ! 372: //--------------------------------------------------------------------------- ! 373: // Call setMulticastList() through syncRequest(). See setMulticastList(). ! 374: ! 375: IOReturn ! 376: IOEthernetController::doSetMulticastList(IOService * client, ! 377: enet_addr_t * addrs, ! 378: UInt count) ! 379: { ! 380: DO_SYNC_REQ(setMulticastList, (void *) addrs, (void *) count) ! 381: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.