1/*
2 *
3 * @APPLE_LICENSE_HEADER_START@
4 *
5 * Copyright (c) 1998-2003 Apple Computer, Inc.  All Rights Reserved.
6 *
7 * This file contains Original Code and/or Modifications of Original Code
8 * as defined in and that are subject to the Apple Public Source License
9 * Version 2.0 (the 'License'). You may not use this file except in
10 * compliance with the License. Please obtain a copy of the License at
11 * http://www.opensource.apple.com/apsl/ and read it before using this
12 * file.
13 *
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
19 * Please see the License for the specific language governing rights and
20 * limitations under the License.
21 *
22 * @APPLE_LICENSE_HEADER_END@
23 */
24
25#ifndef __APPLEUSBCDCEEM__
26#define __APPLEUSBCDCEEM__
27
28#include "AppleUSBCDCCommon.h"
29#include "AppleUSBCDC.h"
30
31#define LDEBUG		0			// for debugging
32#define USE_ELG		0			// to Event LoG (via kprintf and Firewire) - LDEBUG must also be set
33#define USE_IOL		0			// to IOLog - LDEBUG must also be set
34#define	LOG_DATA	0			// logs data to the appropriate log - LDEBUG must also be set
35#define DUMPALL		0			// Dumps all the data to the log - LOG_DATA must also be set
36
37#define Sleep_Time	20
38
39#define Log IOLog
40#if USE_ELG
41    #undef Log
42    #define Log	kprintf
43#endif
44
45#if LDEBUG
46    #if USE_ELG
47		#define XTRACE(ID,A,B,STRING) {Log("%8p %8x %8x " DEBUG_NAME ": " STRING "\n",(void *)(ID),(unsigned int)(A),(unsigned int)(B));}
48    #else /* not USE_ELG */
49        #if USE_IOL
50            #define XTRACE(ID,A,B,STRING) {Log("%8p %8x %8x " DEBUG_NAME ": " STRING "\n",(void *)(ID),(unsigned int)(A),(unsigned int)(B)); IOSleep(Sleep_Time);}
51        #else
52            #define XTRACE(id, x, y, msg)
53        #endif /* USE_IOL */
54    #endif /* USE_ELG */
55    #if LOG_DATA
56        #define LogData(D, C, b)	USBLogData((UInt8)D, (UInt32)C, (char *)b)
57        #define meLogData(D, C, b)	me->USBLogData((UInt8)D, (UInt32)C, (char *)b)
58        #define DumpData(b, C)		dumpData(char *)b, (SInt32)C)
59        #define meDumpData(b, C)	me->dumpData(char *)b, (SInt32)C)
60    #else /* not LOG_DATA */
61        #define LogData(D, C, b)
62        #define meLogData(D, C, b)
63        #define DumpData(b, C)
64        #define meDumpData(b, C)
65    #endif /* LOG_DATA */
66#else /* not LDEBUG */
67    #define XTRACE(id, x, y, msg)
68    #define LogData(D, C, b)
69    #define meLogData(D, C, b)
70    #define DumpData(b, C)
71    #define meDumpData(b, C)
72    #undef USE_ELG
73    #undef USE_IOL
74    #undef LOG_DATA
75#endif /* LDEBUG */
76
77#define ALERT(A,B,STRING)	Log("%8x %8x " DEBUG_NAME ": " STRING "\n", (unsigned int)(A), (unsigned int)(B))
78
79enum
80{
81    kDataIn			= 0,
82    kDataOut,
83    kDataOther,
84    kDataNone
85};
86
87#define TRANSMIT_QUEUE_SIZE     4096
88#define WATCHDOG_TIMER_MS       1000
89
90#define MAX_BLOCK_SIZE		PAGE_SIZE
91#define COMM_BUFF_SIZE		16
92
93#define nameLength		32				// Arbitrary length
94#define defaultName		"USB EEM"
95
96#define kFiltersSupportedMask	0xefff
97#define kPipeStalled		1
98
99    // Default and Maximum buffer pool values
100
101#define kInBufPool		4
102#define kOutBufPool		2
103
104#define kMaxInBufPool		kInBufPool*16
105#define kMaxOutBufPool		kOutBufPool*8
106
107#define	inputTag		"InputBuffers"
108#define	outputTag		"OutputBuffers"
109
110typedef struct
111{
112    IOBufferMemoryDescriptor	*pipeOutMDP;
113    UInt8			*pipeOutBuffer;
114    mbuf_t			m;
115    bool			avail;
116    IOUSBCompletion		writeCompletionInfo;
117	UInt32			indx;
118} pipeOutBuffers;
119
120typedef struct
121{
122    IOBufferMemoryDescriptor	*pipeInMDP;
123    UInt8			*pipeInBuffer;
124    bool			dead;
125    IOUSBCompletion		readCompletionInfo;
126	UInt32			indx;
127} pipeInBuffers;
128
129	// EEM bit definitions and masks
130
131#define bmTypeData			0x0000
132#define bmTypeCommand		0x8000
133#define bmCRC				0x4000
134
135	// EEM Data packet masks
136
137#define bmCRCMask			0x7fff
138#define frameLenMask		0x3fff
139
140	// EEM Command packet masks
141
142#define bmEEMCmdMask		0x3fff
143#define	bmEEMCmdParamMask	0x07ff
144
145	// EEM Commands
146
147#define EEMEcho					0x00
148#define EEMEchoResponse			0x08
149#define EEMSuspendHint			0x10
150#define EEMResponseHint			0x18
151#define EEMResponseCompleteHint	0x20
152#define EEMTickle				0x28
153
154class AppleUSBCDC;
155
156class AppleUSBCDCEEM : public IOEthernetController
157{
158    OSDeclareDefaultStructors(AppleUSBCDCEEM);	// Constructor & Destructor stuff
159
160private:
161    bool			fTerminate;				// Are we being terminated (ie the device was unplugged)
162    UInt16			fVendorID;
163    UInt16			fProductID;
164
165    IOEthernetInterface		*fNetworkInterface;
166    IOBasicOutputQueue		*fTransmitQueue;
167
168    OSDictionary		*fMediumDict;
169
170    bool			fReady;
171    bool			fNetifEnabled;
172    bool			fWOL;
173    UInt8			fLinkStatus;
174
175    IOUSBPipe			*fInPipe;
176    IOUSBPipe			*fOutPipe;
177
178    pipeInBuffers		fPipeInBuff[kMaxInBufPool];
179    pipeOutBuffers		fPipeOutBuff[kMaxOutBufPool];
180    UInt16			fOutPoolIndex;
181
182    UInt32			fCount;
183    UInt32			fOutPacketSize;
184
185    static void			dataReadComplete(void *obj, void *param, IOReturn ior, UInt32 remaining);
186    static void			dataWriteComplete(void *obj, void *param, IOReturn ior, UInt32 remaining);
187
188           // CDC EEM Driver instance Methods
189
190    void			USBLogData(UInt8 Dir, SInt32 Count, char *buf);
191    void			dumpData(char *buf, SInt32 size);
192    bool			configureData(void);
193    bool			wakeUp(void);
194    void			putToSleep(void);
195    bool			createMediumTables(void);
196    bool 			allocateResources(void);
197    void			releaseResources(void);
198    bool			createNetworkInterface(void);
199    UInt32			outputPacket(mbuf_t pkt, void *param);
200    IOReturn		USBTransmitPacket(mbuf_t packet);
201	bool			getOutputBuffer(UInt32 *bufIndx);
202	IOReturn		USBSendCommand(UInt16 command, UInt16 length, UInt8 *anyData);
203    IOReturn		clearPipeStall(IOUSBPipe *thePipe);
204    void			receivePacket(UInt8 *packet, UInt32 size);
205	void			processEEMCommand(UInt16 EEMHeader, UInt32 poolIndx, SInt16 dataIndx, SInt16 *len);
206
207public:
208
209    IOUSBInterface		*fDataInterface;
210    IOWorkLoop			*fWorkLoop;
211    IOLock			*fBufferPoolLock;
212    UInt8			fDataInterfaceNumber;
213
214    UInt16			fInBufPool;
215    UInt16			fOutBufPool;
216    bool			fTxStalled;
217
218	UInt16			fMax_Block_Size;
219
220    UInt8			fConfigAttributes;
221
222    IONetworkStats		*fpNetStats;
223    IOEthernetStats		*fpEtherStats;
224
225        // IOKit methods
226
227	virtual IOService   *probe(IOService *provider, SInt32 *score);
228    virtual bool		init(OSDictionary *properties = 0);
229    virtual bool		start(IOService *provider);
230    virtual void		stop(IOService *provider);
231    virtual IOReturn 		message(UInt32 type, IOService *provider, void *argument = 0);
232
233        // IOEthernetController methods
234
235    virtual IOReturn		enable(IONetworkInterface *netif);
236    virtual IOReturn		disable(IONetworkInterface *netif);
237    virtual IOReturn		setWakeOnMagicPacket(bool active);
238    virtual IOReturn		getPacketFilters(const OSSymbol	*group, UInt32 *filters ) const;
239    virtual IOReturn		selectMedium(const IONetworkMedium *medium);
240    virtual IOReturn		getHardwareAddress(IOEthernetAddress *addr);
241    virtual IOReturn		setMulticastMode(IOEnetMulticastMode mode);
242    virtual IOReturn		setMulticastList(IOEthernetAddress *addrs, UInt32 count);
243    virtual IOReturn		setPromiscuousMode(IOEnetPromiscuousMode mode);
244    virtual IOOutputQueue	*createOutputQueue(void);
245    virtual const OSString	*newVendorString(void) const;
246    virtual const OSString	*newModelString(void) const;
247    virtual const OSString	*newRevisionString(void) const;
248    virtual bool		configureInterface(IONetworkInterface *netif);
249
250}; /* end class AppleUSBCDCEEM */
251#endif