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