|
|
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.