1/* 2 * Copyright (c) 1998-2008 Apple 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 * IOEthernetController.cpp 24 * 25 * Abstract Ethernet controller superclass. 26 * 27 * HISTORY 28 * 29 * Dec 3, 1998 jliu - C++ conversion. 30 */ 31 32#include <IOKit/assert.h> 33#include <IOKit/network/IOEthernetController.h> 34#include <IOKit/network/IOEthernetInterface.h> 35#include "IONetworkDebug.h" 36 37extern "C" { 38#include <sys/param.h> // mbuf limits defined here. 39#include <sys/mbuf.h> 40} 41 42//--------------------------------------------------------------------------- 43 44#define super IONetworkController 45 46OSDefineMetaClassAndAbstractStructors( IOEthernetController, IONetworkController) 47OSMetaClassDefineReservedUnused( IOEthernetController, 2); 48OSMetaClassDefineReservedUnused( IOEthernetController, 3); 49OSMetaClassDefineReservedUnused( IOEthernetController, 4); 50OSMetaClassDefineReservedUnused( IOEthernetController, 5); 51OSMetaClassDefineReservedUnused( IOEthernetController, 6); 52OSMetaClassDefineReservedUnused( IOEthernetController, 7); 53OSMetaClassDefineReservedUnused( IOEthernetController, 8); 54OSMetaClassDefineReservedUnused( IOEthernetController, 9); 55OSMetaClassDefineReservedUnused( IOEthernetController, 10); 56OSMetaClassDefineReservedUnused( IOEthernetController, 11); 57OSMetaClassDefineReservedUnused( IOEthernetController, 12); 58OSMetaClassDefineReservedUnused( IOEthernetController, 13); 59OSMetaClassDefineReservedUnused( IOEthernetController, 14); 60OSMetaClassDefineReservedUnused( IOEthernetController, 15); 61OSMetaClassDefineReservedUnused( IOEthernetController, 16); 62OSMetaClassDefineReservedUnused( IOEthernetController, 17); 63OSMetaClassDefineReservedUnused( IOEthernetController, 18); 64OSMetaClassDefineReservedUnused( IOEthernetController, 19); 65OSMetaClassDefineReservedUnused( IOEthernetController, 20); 66OSMetaClassDefineReservedUnused( IOEthernetController, 21); 67OSMetaClassDefineReservedUnused( IOEthernetController, 22); 68OSMetaClassDefineReservedUnused( IOEthernetController, 23); 69OSMetaClassDefineReservedUnused( IOEthernetController, 24); 70OSMetaClassDefineReservedUnused( IOEthernetController, 25); 71OSMetaClassDefineReservedUnused( IOEthernetController, 26); 72OSMetaClassDefineReservedUnused( IOEthernetController, 27); 73OSMetaClassDefineReservedUnused( IOEthernetController, 28); 74OSMetaClassDefineReservedUnused( IOEthernetController, 29); 75OSMetaClassDefineReservedUnused( IOEthernetController, 30); 76OSMetaClassDefineReservedUnused( IOEthernetController, 31); 77 78//--------------------------------------------------------------------------- 79// IOEthernetController class initializer. 80 81void IOEthernetController::initialize() 82{ 83} 84 85//--------------------------------------------------------------------------- 86// Initialize an IOEthernetController instance. 87 88bool IOEthernetController::init(OSDictionary * properties) 89{ 90 if (!super::init(properties)) 91 { 92 DLOG("IOEthernetController: super::init() failed\n"); 93 return false; 94 } 95 96 return true; 97} 98 99//--------------------------------------------------------------------------- 100// Free the IOEthernetController instance. 101 102void IOEthernetController::free() 103{ 104 // Any allocated resources should be released here. 105 106 super::free(); 107} 108 109//--------------------------------------------------------------------------- 110// Publish Ethernet controller capabilites and properties. 111 112bool IOEthernetController::publishProperties() 113{ 114 bool ret = false; 115 IOEthernetAddress addr; 116 OSDictionary * dict; 117 118 do { 119 // Let the superclass publish properties first. 120 121 if (super::publishProperties() == false) 122 break; 123 124 // Publish the controller's Ethernet address. 125 126 if ( (getHardwareAddress(&addr) != kIOReturnSuccess) || 127 (setProperty(kIOMACAddress, (void *) &addr, 128 kIOEthernetAddressSize) == false) ) 129 { 130 break; 131 } 132 133 // Publish Ethernet defined packet filters. 134 135 dict = OSDynamicCast(OSDictionary, getProperty(kIOPacketFilters)); 136 if ( dict ) 137 { 138 OSNumber * num; 139 OSDictionary * newdict; 140 UInt32 supported = 0; 141 UInt32 disabled = 0; 142 143 // Supported WOL filters 144 if ( getPacketFilters( 145 gIOEthernetWakeOnLANFilterGroup, 146 &supported) != kIOReturnSuccess ) 147 { 148 supported = 0; 149 } 150 151 // Disabled WOL filters 152 if ( getPacketFilters( 153 gIOEthernetDisabledWakeOnLANFilterGroup, 154 &disabled) != kIOReturnSuccess ) 155 { 156 disabled = 0; 157 } 158 159 newdict = OSDictionary::withDictionary( 160 dict, dict->getCount() + (supported ? 2 : 1)); 161 if (newdict) 162 { 163 // Supported WOL filters 164 num = OSNumber::withNumber(supported, sizeof(supported) * 8); 165 if (num) 166 { 167 ret = newdict->setObject(gIOEthernetWakeOnLANFilterGroup, num); 168 num->release(); 169 } 170 171 // Disabled WOL filters 172 if (supported) 173 { 174 num = OSNumber::withNumber(disabled, sizeof(disabled) * 8); 175 if (num) 176 { 177 ret = newdict->setObject( 178 gIOEthernetDisabledWakeOnLANFilterGroup, num); 179 num->release(); 180 } 181 } 182 183 if (ret) 184 setProperty(kIOPacketFilters, newdict); 185 186 newdict->release(); 187 } 188 } 189 } 190 while (false); 191 192 return ret; 193} 194 195//--------------------------------------------------------------------------- 196// Set or change the station address used by the Ethernet controller. 197 198IOReturn 199IOEthernetController::setHardwareAddress(const IOEthernetAddress * addr) 200{ 201 return kIOReturnUnsupported; 202} 203 204//--------------------------------------------------------------------------- 205// Enable or disable multicast mode. 206 207IOReturn IOEthernetController::setMulticastMode(bool active) 208{ 209 return kIOReturnUnsupported; 210} 211 212//--------------------------------------------------------------------------- 213// Enable or disable promiscuous mode. 214 215IOReturn IOEthernetController::setPromiscuousMode(bool active) 216{ 217 return kIOReturnUnsupported; 218} 219 220//--------------------------------------------------------------------------- 221// Enable or disable the wake on Magic Packet support. 222 223IOReturn IOEthernetController::setWakeOnMagicPacket(bool active) 224{ 225 return kIOReturnUnsupported; 226} 227 228//--------------------------------------------------------------------------- 229// Set the list of multicast addresses that the multicast filter should use 230// to match against the destination address of an incoming frame. The frame 231// should be accepted when a match occurs. 232 233IOReturn IOEthernetController::setMulticastList(IOEthernetAddress * /*addrs*/, 234 UInt32 /*count*/) 235{ 236 return kIOReturnUnsupported; 237} 238 239//--------------------------------------------------------------------------- 240// Allocate and return a new IOEthernetInterface instance. 241 242IONetworkInterface * IOEthernetController::createInterface() 243{ 244 IOEthernetInterface * netif = new IOEthernetInterface; 245 246 if ( netif && ( netif->init( this ) == false ) ) 247 { 248 netif->release(); 249 netif = 0; 250 } 251 return netif; 252} 253 254//--------------------------------------------------------------------------- 255// Returns all the packet filters supported by the Ethernet controller. 256// This method will perform a bitwise OR of: 257// 258// kIOPacketFilterUnicast 259// kIOPacketFilterBroadcast 260// kIOPacketFilterMulticast 261// kIOPacketFilterPromiscuous 262// 263// and write it to the argument provided if the group specified is 264// gIONetworkFilterGroup, otherwise 0 is returned. Drivers that support 265// a different set of filters should override this method. 266// 267// Returns kIOReturnSuccess. Drivers that override this method must return 268// kIOReturnSuccess to indicate success, or an error code otherwise. 269 270IOReturn 271IOEthernetController::getPacketFilters(const OSSymbol * group, 272 UInt32 * filters) const 273{ 274 *filters = 0; 275 276 if ( group == gIONetworkFilterGroup ) 277 { 278 return getPacketFilters(filters); 279 } 280 else 281 { 282 return kIOReturnSuccess; 283 } 284} 285 286IOReturn IOEthernetController::getPacketFilters(UInt32 * filters) const 287{ 288 *filters = ( kIOPacketFilterUnicast | 289 kIOPacketFilterBroadcast | 290 kIOPacketFilterMulticast | 291 kIOPacketFilterPromiscuous ); 292 293 return kIOReturnSuccess; 294} 295 296//--------------------------------------------------------------------------- 297// Enable a filter from the specified group. 298 299#define UCAST_BCAST_MASK \ 300 ( kIOPacketFilterUnicast | kIOPacketFilterBroadcast ) 301 302IOReturn IOEthernetController::enablePacketFilter( 303 const OSSymbol * group, 304 UInt32 aFilter, 305 UInt32 enabledFilters, 306 IOOptionBits options) 307{ 308 IOReturn ret = kIOReturnUnsupported; 309 UInt32 newFilters = enabledFilters | aFilter; 310 311 if ( group == gIONetworkFilterGroup ) 312 { 313 // The default action is to call setMulticastMode() or 314 // setPromiscuousMode() to handle multicast or promiscuous 315 // filter changes. 316 317 if ( aFilter == kIOPacketFilterMulticast ) 318 { 319 ret = setMulticastMode(true); 320 } 321 else if ( aFilter == kIOPacketFilterPromiscuous ) 322 { 323 ret = setPromiscuousMode(true); 324 } 325 else if ( (newFilters ^ enabledFilters) & UCAST_BCAST_MASK ) 326 { 327 ret = kIOReturnSuccess; 328 } 329 } 330 else if ( group == gIOEthernetWakeOnLANFilterGroup ) 331 { 332 if ( aFilter == kIOEthernetWakeOnMagicPacket ) 333 { 334 ret = setWakeOnMagicPacket(true); 335 } 336 } 337 338 return ret; 339} 340 341//--------------------------------------------------------------------------- 342// Disable a filter from the specifed filter group. 343 344IOReturn IOEthernetController::disablePacketFilter( 345 const OSSymbol * group, 346 UInt32 aFilter, 347 UInt32 enabledFilters, 348 IOOptionBits options) 349{ 350 IOReturn ret = kIOReturnUnsupported; 351 UInt32 newFilters = enabledFilters & ~aFilter; 352 353 if ( group == gIONetworkFilterGroup ) 354 { 355 // The default action is to call setMulticastMode() or 356 // setPromiscuousMode() to handle multicast or promiscuous 357 // filter changes. 358 359 if ( aFilter == kIOPacketFilterMulticast ) 360 { 361 ret = setMulticastMode(false); 362 } 363 else if ( aFilter == kIOPacketFilterPromiscuous ) 364 { 365 ret = setPromiscuousMode(false); 366 } 367 else if ( (newFilters ^ enabledFilters) & UCAST_BCAST_MASK ) 368 { 369 ret = kIOReturnSuccess; 370 } 371 } 372 else if ( group == gIOEthernetWakeOnLANFilterGroup ) 373 { 374 if ( aFilter == kIOEthernetWakeOnMagicPacket ) 375 { 376 ret = setWakeOnMagicPacket(false); 377 } 378 } 379 380 return ret; 381} 382 383//--------------------------------------------------------------------------- 384// Get the Ethernet controller's station address. 385// Call the Ethernet specific (overloaded) form. 386 387IOReturn 388IOEthernetController::getHardwareAddress(void * addr, 389 UInt32 * inOutAddrBytes) 390{ 391 UInt32 bufBytes; 392 393 if (inOutAddrBytes == 0) 394 return kIOReturnBadArgument; 395 396 // Cache the size of the caller's buffer, and replace it with the 397 // number of bytes required. 398 399 bufBytes = *inOutAddrBytes; 400 *inOutAddrBytes = kIOEthernetAddressSize; 401 402 // Make sure the buffer is large enough for a single Ethernet 403 // hardware address. 404 405 if ((addr == 0) || (bufBytes < kIOEthernetAddressSize)) 406 return kIOReturnNoSpace; 407 408 return getHardwareAddress((IOEthernetAddress *) addr); 409} 410 411//--------------------------------------------------------------------------- 412// Set or change the station address used by the Ethernet controller. 413// Call the Ethernet specific (overloaded) version of this method. 414 415IOReturn 416IOEthernetController::setHardwareAddress(const void * addr, 417 UInt32 addrBytes) 418{ 419 if ((addr == 0) || (addrBytes != kIOEthernetAddressSize)) 420 return kIOReturnBadArgument; 421 422 return setHardwareAddress((const IOEthernetAddress *) addr); 423} 424 425//--------------------------------------------------------------------------- 426// Report the max/min packet sizes, including the frame header and FCS bytes. 427 428IOReturn IOEthernetController::getMaxPacketSize(UInt32 * maxSize) const 429{ 430 *maxSize = kIOEthernetMaxPacketSize; 431 return kIOReturnSuccess; 432} 433 434IOReturn IOEthernetController::getMinPacketSize(UInt32 * minSize) const 435{ 436 *minSize = kIOEthernetMinPacketSize; 437 return kIOReturnSuccess; 438} 439 440OSMetaClassDefineReservedUsed( IOEthernetController, 0); 441bool IOEthernetController::getVlanTagDemand(mbuf_t mt, UInt32 *vlantag) 442{ 443 u_int16_t tag; 444 int rval = mbuf_get_vlan_tag(mt, &tag); 445 if(rval == 0) 446 { 447 *vlantag = tag; 448 return true; 449 } 450 return false; 451} 452 453OSMetaClassDefineReservedUsed( IOEthernetController, 1); 454void IOEthernetController::setVlanTag(mbuf_t mt, UInt32 vlantag) 455{ 456 mbuf_set_vlan_tag(mt, vlantag); 457} 458 459 460