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 _IOKIT_NETWORK_IOMBUFMEMORYCURSOR_H
24#define _IOKIT_NETWORK_IOMBUFMEMORYCURSOR_H
25
26#include <IOKit/IOMemoryCursor.h>
27
28
29/*! @class IOMbufMemoryCursor
30    @abstract A mechanism to convert mbuf chains to physical addresses.
31    @discussion The IOMbufMemoryCursor defines the super class that all
32    specific mbuf cursors must inherit from, but a mbuf cursor can be created
33    without a specific formal subclass by just providing a segment function to
34    the initializers. This class performs the task of walking a given
35    mbuf chain and creating a physical scatter/gather list appropriate for
36    the target hardware. When necessary, this class may also coalesce
37    mbuf chains when the generated scatter/gather list exceeds the specified
38    hardware limit. However, this should be avoided since it exacts a
39    performance cost.
40    <br><br>
41    A driver is expected to create a mbuf cursor and configure it to match the
42    limitations of it's DMA hardware; for instance the mbuf cursor used by
43    an Ethernet controller driver may have a maximum physical segment size
44    of 1520, and allow for up to 6 physical segments. Thus it would create a
45    mbuf cursor with a maxSegmentSize of 1520 and a maxNumSegments of 6.
46    The driver may choose to supply an OutputSegmentFunc function to
47    format the output of each scatter/gather segment to match the
48    hardware descriptor format, or it may use a subclass of
49    IOMbufMemoryCursor to generate IOPhysicalSegment segments with
50    various byte orders.
51    <br><br>
52    A driver may also create more than one mbuf cursor, perhaps one
53    dedicated for the transmit thread, and the other for the receive thread.
54    This becomes a requirement when the driver is multi-threaded, since the
55    mbuf cursor maintains state and does not support reentrancy. */
56
57class IOMbufMemoryCursor : public IOMemoryCursor
58{
59    OSDeclareDefaultStructors(IOMbufMemoryCursor)
60
61protected:
62    UInt32 maxNumSegments;
63    UInt32 coalesceCount;
64    UInt32 packetTooBigErrors;
65
66    struct ExpansionData { };
67    /*! @var reserved
68        Reserved for future use.  (Internal use only)  */
69    ExpansionData *reserved;
70
71    virtual bool initWithSpecification(OutputSegmentFunc outSeg,
72                                       UInt32 maxSegmentSize,
73                                       UInt32 maxTransferSize,
74                                       UInt32 align);
75
76public:
77/*! @function initWithSpecification
78    @abstract Primary initializer for the IOMbufMemoryCursor class.
79    @param outSeg Function to call to output one physical segment.
80    @param maxSegmentSize Maximum allowable size for one segment.
81    @param maxNumSegments Maximum number of segments.
82    @result Returns true if the inherited classes and this instance initialized
83    successfully.
84*/
85
86    virtual bool initWithSpecification(OutputSegmentFunc outSeg,
87                                       UInt32 maxSegmentSize,
88                                       UInt32 maxNumSegments);
89
90/*! @function genPhysicalSegments
91    @abstract Generates a physical scatter/gather list given a mbuf packet.
92    @discussion Generates a list of physical segments from the given mbuf.
93    @param packet The mbuf packet.
94    @param vector Void pointer to base of output physical scatter/gather list.
95    Always passed directly onto the OutputSegmentFunc without interpretation
96    by the cursor.
97    @param maxSegs Maximum number of segments that can be written to segments
98    array.
99    @param doCoalesce Set to true to perform coalescing when the required
100    number of segments exceeds the specified limit, otherwise abort and
101    return 0.
102    @result Returns the number of segments that were filled in, or
103    0 if an error occurred.
104*/
105
106    virtual UInt32 genPhysicalSegments(mbuf_t packet, void * vector,
107                                       UInt32 maxSegs, bool doCoalesce);
108
109/*! @function getAndResetCoalesceCount
110    @abstract Returns a count of the total number of mbuf chains coalesced
111    by genPhysicalSegments().
112    @discussion This method returns a count of the total number of mbuf chains coalesced
113    by genPhysicalSegments(). The counter is then reset to 0.
114    @result Returns the coalesce count.
115*/
116
117    UInt32 getAndResetCoalesceCount();
118
119    // Virtual function padding
120    OSMetaClassDeclareReservedUnused( IOMbufMemoryCursor,  0);
121    OSMetaClassDeclareReservedUnused( IOMbufMemoryCursor,  1);
122    OSMetaClassDeclareReservedUnused( IOMbufMemoryCursor,  2);
123    OSMetaClassDeclareReservedUnused( IOMbufMemoryCursor,  3);
124};
125
126
127/*! @class IOMbufNaturalMemoryCursor
128    @abstract An IOMbufMemoryCursor subclass that outputs a vector of
129    IOPhysicalSegments in the natural byte orientation for the cpu.
130    @discussion The IOMbufNaturalMemoryCursor would be used when it is too
131    difficult to implement an OutputSegmentFunc that is more appropriate for
132    your hardware.  This cursor just outputs an array of IOPhysicalSegments.
133*/
134
135class IOMbufNaturalMemoryCursor : public IOMbufMemoryCursor
136{
137    OSDeclareDefaultStructors(IOMbufNaturalMemoryCursor)
138
139public:
140
141/*! @function withSpecification
142    @abstract Factory function that creates and initializes an
143    IOMbufNaturalMemoryCursor in one operation.
144    @discussion See also IOMbufMemoryCursor::initWithSpecification.
145    @param maxSegmentSize Maximum allowable size for one segment.
146    @param maxNumSegments Maximum number of segments.
147    @result Returns a new mbuf cursor if successfully created and initialized,
148    0 otherwise.
149*/
150
151    static IOMbufNaturalMemoryCursor * withSpecification(UInt32 maxSegmentSize,
152                                                         UInt32 maxNumSegments);
153
154/*! @function getPhysicalSegments
155    @abstract Generates a cpu natural physical scatter/gather list from a given
156    mbuf.
157    @param packet The mbuf packet.
158    @param vector Pointer to an array of IOPhysicalSegments for the output
159    physical scatter/gather list.
160    @param numVectorSegments Maximum number of IOPhysicalSegments accepted.
161    @result Returns the number of segments that were filled in, or
162    0 if an error occurred.
163*/
164
165    UInt32 getPhysicalSegments(mbuf_t packet,
166                               struct IOPhysicalSegment * vector,
167                               UInt32 numVectorSegments = 0);
168
169/*! @function getPhysicalSegmentsWithCoalesce
170    @abstract Generates a cpu natural physical scatter/gather list from a given
171    mbuf.
172    @discussion Generate a cpu natural physical scatter/gather list from a
173    given mbuf. Coalesce mbuf chain when the number of segments in the
174    scatter/gather list exceeds numVectorSegments.
175    @param packet The mbuf packet.
176    @param vector Pointer to an array of IOPhysicalSegments for the output
177    physical scatter/gather list.
178    @param numVectorSegments Maximum number of IOPhysicalSegments accepted.
179    @result Returns the number of segments that were filled in, or
180    0 if an error occurred.
181*/
182
183    UInt32 getPhysicalSegmentsWithCoalesce(mbuf_t packet,
184                                           struct IOPhysicalSegment * vector,
185                                           UInt32 numVectorSegments = 0);
186};
187
188//===========================================================================
189//===========================================================================
190
191/*! @class IOMbufBigMemoryCursor
192    @abstract An IOMbufMemoryCursor subclass that outputs a vector of
193    IOPhysicalSegments in the big endian byte order.
194    @discussion The IOMbufBigMemoryCursor would be used when the DMA hardware
195    requires a big endian address and length pair.  This cursor outputs an
196    array of IOPhysicalSegments that are encoded in big-endian format.
197*/
198
199class IOMbufBigMemoryCursor : public IOMbufMemoryCursor
200{
201    OSDeclareDefaultStructors(IOMbufBigMemoryCursor)
202
203public:
204
205/*! @function withSpecification
206    @abstract Factory function that creates and initializes an
207    IOMbufBigMemoryCursor in one operation.
208    @discussion See also IOMbufMemoryCursor::initWithSpecification.
209    @param maxSegmentSize Maximum allowable size for one segment.
210    @param maxNumSegments Maximum number of segments.
211    @result Returns a new mbuf cursor if successfully created and initialized,
212    0 otherwise.
213*/
214
215    static IOMbufBigMemoryCursor * withSpecification(UInt32 maxSegmentSize,
216                                                     UInt32 maxNumSegments);
217
218/*! @function getPhysicalSegments
219    @abstract Generates a big endian physical scatter/gather list from a given
220    mbuf.
221    @param packet The mbuf packet.
222    @param vector Pointer to an array of IOPhysicalSegments for the output
223    physical scatter/gather list.
224    @param numVectorSegments Maximum number of IOPhysicalSegments accepted.
225    @result Returns the number of segments that were filled in, or
226    0 if an error occurred.
227*/
228
229    UInt32 getPhysicalSegments(mbuf_t packet,
230                               struct IOPhysicalSegment * vector,
231                               UInt32 numVectorSegments = 0);
232
233/*! @function getPhysicalSegmentsWithCoalesce
234    @abstract Generates a big endian physical scatter/gather list from a given
235    mbuf.
236    @discussion Generate a big endian physical scatter/gather list from a
237    given mbuf. Coalesce mbuf chain when the number of segments in the
238    scatter/gather list exceeds numVectorSegments.
239    @param packet The mbuf packet.
240    @param vector Pointer to an array of IOPhysicalSegments for the output
241    physical scatter/gather list.
242    @param numVectorSegments Maximum number of IOPhysicalSegments accepted.
243    @result Returns the number of segments that were filled in, or
244    0 if an error occurred.
245*/
246
247    UInt32 getPhysicalSegmentsWithCoalesce(mbuf_t packet,
248                                           struct IOPhysicalSegment * vector,
249                                           UInt32 numVectorSegments = 0);
250};
251
252//===========================================================================
253//===========================================================================
254
255/*! @class IOMbufLittleMemoryCursor
256    @abstract An IOMbufMemoryCursor subclass that outputs a vector of
257    IOPhysicalSegments in the little endian byte order.
258    @discussion The IOMbufLittleMemoryCursor would be used when the DMA
259    hardware requires a little endian address and length pair.  This cursor
260    outputs an array of IOPhysicalSegments that are encoded in little endian
261    format.
262*/
263
264class IOMbufLittleMemoryCursor : public IOMbufMemoryCursor
265{
266    OSDeclareDefaultStructors(IOMbufLittleMemoryCursor)
267
268public:
269
270/*! @function withSpecification
271    @abstract Factory function that creates and initializes an
272    IOMbufLittleMemoryCursor in one operation.
273    @discussion See also IOMbufMemoryCursor::initWithSpecification.
274    @param maxSegmentSize Maximum allowable size for one segment.
275    @param maxNumSegments Maximum number of segments.
276    @result Returns a new mbuf cursor if successfully created and initialized,
277    0 otherwise.
278*/
279
280    static IOMbufLittleMemoryCursor * withSpecification(UInt32 maxSegmentSize,
281                                                        UInt32 maxNumSegments);
282
283/*! @function getPhysicalSegments
284    @abstract Generates a little endian physical scatter/gather list from a
285    given mbuf.
286    @param packet The mbuf packet.
287    @param vector Pointer to an array of IOPhysicalSegments for the output
288    physical scatter/gather list.
289    @param numVectorSegments Maximum number of IOPhysicalSegments accepted.
290    @result Returns the number of segments that were filled in, or
291    0 if an error occurred.
292*/
293
294    UInt32 getPhysicalSegments(mbuf_t packet,
295                               struct IOPhysicalSegment * vector,
296                               UInt32 numVectorSegments = 0);
297
298/*! @function getPhysicalSegmentsWithCoalesce
299    @abstract Generates a little endian physical scatter/gather list from a
300    given mbuf.
301    @discussion Generate a little endian physical scatter/gather list from a
302    given mbuf. Coalesce mbuf chain when the number of segments in the
303    scatter/gather list exceeds numVectorSegments.
304    @param packet The mbuf packet.
305    @param vector Pointer to an array of IOPhysicalSegments for the output
306    physical scatter/gather list.
307    @param numVectorSegments Maximum number of IOPhysicalSegments accepted.
308    @result Returns the number of segments that were filled in, or
309    0 if an error occurred.
310*/
311
312    UInt32 getPhysicalSegmentsWithCoalesce(mbuf_t packet,
313                                           struct IOPhysicalSegment * vector,
314                                           UInt32 numVectorSegments = 0);
315};
316
317#ifdef __ppc__
318
319struct IODBDMADescriptor;
320
321//===========================================================================
322//===========================================================================
323
324/*! @class IOMbufDBDMAMemoryCursor
325    @abstract An IOMbufMemoryCursor subclass that outputs a vector of
326    IODBDMADescriptors.
327*/
328
329class IOMbufDBDMAMemoryCursor : public IOMbufMemoryCursor
330{
331    OSDeclareDefaultStructors(IOMbufDBDMAMemoryCursor)
332
333public:
334
335/*! @function withSpecification
336    @abstract Factory function that creates and initializes an
337    IOMbufDBDMAMemoryCursor in one operation.
338    @discussion See also IOMbufMemoryCursor::initWithSpecification.
339    @param maxSegmentSize Maximum allowable size for one segment.
340    @param maxNumSegments Maximum number of segments.
341    @result Returns a new mbuf cursor if successfully created and initialized,
342    0 otherwise.
343*/
344
345    static IOMbufDBDMAMemoryCursor * withSpecification(UInt32 maxSegmentSize,
346                                                       UInt32 maxNumSegments);
347
348/*! @function getPhysicalSegments
349    @abstract Generates a DBDMA descriptor list from a given mbuf.
350    @param packet The mbuf packet.
351    @param vector Pointer to an array of IODBDMADescriptor for the output list.
352    @param numVectorSegments Maximum number of IODBDMADescriptors accepted.
353    @result Returns the number of segments that were filled in, or
354    0 if an error occurred.
355*/
356
357    UInt32 getPhysicalSegments(mbuf_t packet,
358                               struct IODBDMADescriptor *vector,
359                               UInt32 numVectorSegments = 0);
360
361/*! @function getPhysicalSegmentsWithCoalesce
362    @abstract Generates a DBDMA descriptor list from a given mbuf.
363    @discussion Generate a DBDMA descriptor list from a given mbuf.
364    Coalesce mbuf chain when the number of elements in the list exceeds
365    numVectorSegments.
366    @param packet The mbuf packet.
367    @param vector Pointer to an array of IODBDMADescriptor for the output list.
368    @param numVectorSegments Maximum number of IODBDMADescriptors accepted.
369    @result Returns the number of segments that were filled in, or
370    0 if an error occurred.
371*/
372
373    UInt32 getPhysicalSegmentsWithCoalesce(mbuf_t packet,
374                                           struct IODBDMADescriptor * vector,
375                                           UInt32 numVectorSegments = 0);
376};
377
378#endif /* __ppc__ */
379
380#endif /* !_IOKIT_NETWORK_IOMBUFMEMORYCURSOR_H */
381
382