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