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#ifndef _IOOUTPUTQUEUE_H
24#define _IOOUTPUTQUEUE_H
25
26#include <IOKit/network/IONetworkInterface.h>
27
28// Forward declarations.
29//
30struct mbuf;
31class  IONetworkData;
32
33// FIXME - We do not want the enqueue/dequeue macros defined in queue.h.
34//
35#undef enqueue
36#undef dequeue
37
38// FIXME - Belongs in IOBasicOutputQueue.h
39//
40/*! @enum OutputPacketStatus
41    @abstract The status of the packet sent to the target.
42    @constant kIOOutputStatusMask Define the status field in the return code.
43    @constant kIOOutputStatusAccept Packet was accepted by the target.
44    @constant kIOOutputStatusDropped Packet accepted, but was also dropped.
45    @constant kIOOutputStatusRetry Target ran out of resources, and is unable
46    to accept the packet. The ownership of the packet reverts back to the
47    queue.
48*/
49
50enum {
51    kIOOutputStatusMask     = 0x00ff,
52    kIOOutputStatusAccepted = 0x0000,
53    kIOOutputStatusDropped  = 0x0001,
54    kIOOutputStatusRetry    = 0x0002
55};
56
57/*! @enum OutputCommands
58    @abstract A command requested by the target.
59    @constant kIOOutputCommandMask Define the command field in the return code.
60    @constant kIOOutputCommandNone No command.
61    @constant kIOOutputCommandStall A command to stall the queue.
62*/
63
64enum {
65    kIOOutputCommandMask    = 0xff00,
66    kIOOutputCommandNone    = 0x0000,
67    kIOOutputCommandStall   = 0x0100
68};
69
70/*! @enum OutputHandlerReturnCodes
71    @abstract Common return codes returned by the target's output handler.
72    @constant kIOReturnOutputSuccess Packet was accepted.
73    @constant kIOReturnOutputDropped Packet was dropped.
74    @constant kIOReturnOutputStall   Stall the queue and retry the same packet
75              when the queue is restarted.
76*/
77
78enum {
79    kIOReturnOutputSuccess = (kIOOutputStatusAccepted | kIOOutputCommandNone),
80    kIOReturnOutputDropped = (kIOOutputStatusDropped  | kIOOutputCommandNone),
81    kIOReturnOutputStall   = (kIOOutputStatusRetry    | kIOOutputCommandStall)
82};
83
84/*! @class IOOutputQueue
85    @abstract A packet queue that supports multiple producers and a single
86    consumer.
87    @discussion Each producer, or a client thread, will deliver a chain of packets
88    to the queue. A single consumer will remove packets from the queue one at a
89    time and forward it to the registered target/action. This object may be used
90    by an IONetworkController on the output (transmit) side to handle the output
91    packet flow downstream from an IONetworkInterface, and then call the driver's
92    output function. IOOutputQueue is an abstract class that provides an interface
93    for its subclasses. Concrete subclasses will complete the implementation, and
94    specify the context that the target is called for packets removed from
95    the queue.
96*/
97
98class IOOutputQueue : public OSObject
99{
100    OSDeclareAbstractStructors( IOOutputQueue )
101
102private:
103
104    static void runServiceThread(thread_call_param_t, thread_call_param_t);
105
106protected:
107
108    thread_call_t  _callEntry;  // callout entry structure.
109
110    struct ExpansionData { };
111    /*! @var reserved
112        Reserved for future use.  (Internal use only)  */
113    ExpansionData *_reserved;
114
115
116/*! @function init
117    @abstract Initializes an IOOutputQueue object.
118    @result Returns true if initialized successfully, false otherwise.
119*/
120
121    virtual bool init();
122
123/*! @function free
124    @abstract Frees the IOOutputQueue object.
125    @discussion Release allocated resources, then call super::free().
126*/
127
128    virtual void free();
129
130/*! @function scheduleServiceThread
131    @abstract Schedules a service thread callout.
132    @discussion This method can be called by service() to schedule
133    a thread that will call serviceThread() when it starts running.
134    @param param A parameter to pass to the serviceThread() method.
135    @result Returns true if a thread callout was scheduled, false otherwise.
136*/
137
138    virtual bool scheduleServiceThread(void * param = 0);
139
140/*! @function cancelServiceThread
141    @abstract Cancels any pending service thread callout.
142    @result Returns true if a previously scheduled thread callout was canceled,
143    false otherwise.
144*/
145
146    virtual bool cancelServiceThread();
147
148/*! @function serviceThread
149    @abstract Method called by the scheduled service thread when it
150    starts to run.
151    @discussion Must be implemented by a subclass that calls
152    scheduleServiceThread(). The default implementation does nothing.
153    @param param A parameter that was given to scheduleServiceThread()
154    when the service thread was scheduled.
155*/
156
157    virtual void serviceThread(void * param);
158
159public:
160
161/*! @function start
162    @abstract Starts up the queue.
163    @discussion This method is called by the target to start the queue. This will allow
164    packets to be removed from the queue, then delivered to the target.
165    @result Returns true if the queue was started successfully, false otherwise.
166*/
167
168    virtual bool start() = 0;
169
170/*! @function stop
171    @abstract Stops the queue.
172    @discussion Stop the queue and prevent it from sending packets to its
173    target.
174    @result Returns the previous running state of the queue,
175    true if the queue was running, false if the queue was already stopped.
176*/
177
178    virtual bool stop() = 0;
179
180/*! @function service
181    @abstract Services the queue.
182    @discussion Manage the queue after it has been started.
183    @param options Options for the service request.
184    @result Returns a return value to indicate the service result.
185*/
186
187    virtual bool service(IOOptionBits options = 0) = 0;
188
189/*! @function flush
190    @abstract Drops and frees all packets currently held by the queue.
191    @result Returns the number of packets that were dropped and freed.
192*/
193
194    virtual UInt32 flush() = 0;
195
196/*! @function setCapacity
197    @abstract Changes the number of packets that the queue can hold
198    before it begins to drop excess packets.
199    @param capacity The new desired capacity.
200    @result Returns true if the new capacity was accepted, false otherwise.
201*/
202
203    virtual bool setCapacity(UInt32 capacity) = 0;
204
205/*! @function getCapacity
206    @abstract Gets the number of packets that the queue can hold.
207    @discussion The queue will begin to drop incoming packets when the
208    size of queue reaches its capacity.
209    @result Returns the current queue capacity.
210*/
211
212    virtual UInt32 getCapacity() const = 0;
213
214/*! @function getSize
215    @abstract Gets the number of packets currently held in the queue.
216    @result Returns the size of the queue.
217*/
218
219    virtual UInt32 getSize() const = 0;
220
221/*! @function enqueue
222    @abstract Adds a packet, or a chain of packets, to the queue.
223    @discussion This method is called by a client to add a packet, or a chain of packets,
224    to the queue.  A packet is described by an mbuf chain, while a chain
225    of packets is constructed by linking multiple mbuf chains via the
226    m_nextpkt field.
227    @param m A single packet, or a chain of packets.
228    @param param A parameter provided by the caller.
229    @result Returns a return code.
230*/
231
232    virtual UInt32 enqueue(mbuf_t m, void * param) = 0;
233
234/*! @function getOutputHandler
235    @abstract Returns the address of a function that is designated to handle
236    incoming packets sent to the queue object.
237    @result Returns the address of the enqueue() method.
238*/
239
240    virtual IOOutputAction getOutputHandler() const;
241
242/*! @function getStatisticsData
243    @abstract Returns an IONetworkData object containing statistics counters
244    updated by the queue.
245    @result Returns an IONetworkData object. This implementation will always return
246    0.
247*/
248
249    virtual IONetworkData * getStatisticsData() const;
250
251    /*! @function getMbufPriority
252     @abstract Determines an mbuf's traffic priority.  The highest priority is 0.
253     @discussion A queue can prioritize certain classes of traffic. This method
254     facilitates that by evaluating an mbuf and returning its priority.
255     @param m An mbuf to analyze.
256     @result Returns a UInt32 representing the priority of the packet.  0 is the highest priority.
257     */
258
259    OSMetaClassDeclareReservedUsed( IOOutputQueue,  0);
260    virtual UInt32 getMbufPriority(mbuf_t m);
261
262    // Virtual function padding
263    OSMetaClassDeclareReservedUnused( IOOutputQueue,  1);
264    OSMetaClassDeclareReservedUnused( IOOutputQueue,  2);
265    OSMetaClassDeclareReservedUnused( IOOutputQueue,  3);
266    OSMetaClassDeclareReservedUnused( IOOutputQueue,  4);
267    OSMetaClassDeclareReservedUnused( IOOutputQueue,  5);
268    OSMetaClassDeclareReservedUnused( IOOutputQueue,  6);
269    OSMetaClassDeclareReservedUnused( IOOutputQueue,  7);
270    OSMetaClassDeclareReservedUnused( IOOutputQueue,  8);
271    OSMetaClassDeclareReservedUnused( IOOutputQueue,  9);
272    OSMetaClassDeclareReservedUnused( IOOutputQueue, 10);
273    OSMetaClassDeclareReservedUnused( IOOutputQueue, 11);
274    OSMetaClassDeclareReservedUnused( IOOutputQueue, 12);
275    OSMetaClassDeclareReservedUnused( IOOutputQueue, 13);
276    OSMetaClassDeclareReservedUnused( IOOutputQueue, 14);
277    OSMetaClassDeclareReservedUnused( IOOutputQueue, 15);
278};
279
280#endif /* !_IOOUTPUTQUEUE_H */
281