]>
Commit | Line | Data |
---|---|---|
1c79356b A |
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) 1998-1999 Apple Software, Inc. | |
24 | * | |
25 | * Interface definition for the UniN Ethernet Controller | |
26 | * | |
27 | * HISTORY | |
28 | * | |
29 | */ | |
30 | ||
31 | #include <IOKit/network/IOEthernetController.h> | |
32 | #include <IOKit/network/IOEthernetInterface.h> | |
33 | #include <IOKit/network/IOGatedOutputQueue.h> | |
34 | #include <IOKit/IOInterruptEventSource.h> | |
35 | #include <IOKit/IOTimerEventSource.h> | |
36 | #include <IOKit/network/IOMbufMemoryCursor.h> | |
37 | #include <IOKit/IODeviceMemory.h> | |
38 | #include <IOKit/pci/IOPCIDevice.h> | |
39 | #include <IOKit/IOLib.h> /* bcopy */ | |
40 | ||
41 | extern "C" | |
42 | { | |
43 | #include <sys/param.h> | |
44 | #include <sys/mbuf.h> | |
45 | } | |
46 | ||
47 | //#define IOLog kprintf | |
48 | ||
49 | // No kernel tracing support at this time. | |
50 | // | |
51 | #define KERNEL_DEBUG(x,a,b,c,d,e) | |
52 | ||
53 | #include "UniNEnetRegisters.h" | |
54 | ||
55 | ||
56 | ||
57 | #define NETWORK_STAT_ADD( x ) (fpNetStats->x++) | |
58 | #define ETHERNET_STAT_ADD( x ) (fpEtherStats->x++) | |
59 | ||
60 | #define READ_REGISTER( REG ) OSReadLittleInt32( (void*)&fpRegs->REG, 0 ) | |
61 | #define DBG_WRITE 0 | |
62 | #if DBG_WRITE | |
63 | #define WRITE_REGISTER( REG, VAL ) writeRegister( &fpRegs->REG, VAL ) | |
64 | #else | |
65 | #define WRITE_REGISTER( REG, VAL ) OSWriteLittleInt32( (void*)&fpRegs->REG, 0, VAL ) | |
66 | #endif // DBG_WRITE | |
67 | ||
68 | ||
69 | typedef void * IOPPCAddress; | |
70 | ||
71 | #define NUM_RX_DESC 1 | |
72 | typedef struct enet_dma_cmd_t | |
73 | { | |
74 | GEMRxDescriptor desc_seg[NUM_RX_DESC]; | |
75 | } enet_dma_cmd_t; | |
76 | ||
77 | #define NUM_TX_DESC 1 | |
78 | typedef struct enet_txdma_cmd_t | |
79 | { | |
80 | GEMTxDescriptor desc_seg[NUM_TX_DESC]; | |
81 | } enet_txdma_cmd_t; | |
82 | ||
83 | ||
84 | typedef struct TxQueueElement | |
85 | { | |
86 | queue_chain_t next; | |
87 | queue_head_t * list; | |
88 | ||
89 | struct mbuf * mbuf; | |
90 | UInt32 slot; | |
91 | UInt32 count; | |
92 | } TxQueueElement; | |
93 | ||
94 | enum LinkStatus | |
95 | { | |
96 | kLinkStatusUnknown, | |
97 | kLinkStatusDown, | |
98 | kLinkStatusUp, | |
99 | }; | |
100 | ||
101 | #define kMaxUniNEnetPowerState 1 | |
102 | #define kUniNsettle_time 500 //guess 500 microseconds for settling | |
103 | ||
104 | ||
105 | class UniNEnet: public IOEthernetController | |
106 | { | |
107 | OSDeclareDefaultStructors( UniNEnet ) | |
108 | ||
109 | private: | |
110 | volatile GMAC_Registers *fpRegs; | |
111 | IOPCIDevice * nub; | |
112 | IOMemoryMap * ioMapEnet; | |
113 | volatile IOPPCAddress ioBaseEnet; | |
114 | ||
115 | IOEthernetInterface * networkInterface; | |
116 | IOBasicOutputQueue * transmitQueue; | |
117 | IOPacketQueue * debugQueue; | |
118 | IOKernelDebugger * debugger; | |
119 | ||
120 | IOWorkLoop * workLoop; | |
121 | IOInterruptEventSource * interruptSource; | |
122 | IONetworkStats * fpNetStats; | |
123 | IOEthernetStats * fpEtherStats; | |
124 | IOTimerEventSource * timerSource; | |
125 | IOMbufBigMemoryCursor * mbufCursor; | |
126 | IOSimpleLock * txQueueLock; | |
127 | ||
128 | bool ready; | |
129 | bool netifEnabled; | |
130 | bool debugEnabled; | |
131 | bool debugTxPoll; | |
132 | ||
133 | IOEthernetAddress myAddress; | |
134 | bool isPromiscuous; | |
135 | bool multicastEnabled; | |
136 | bool isFullDuplex; | |
137 | ||
138 | UInt32 phyType; | |
139 | UInt8 phyId; | |
140 | ||
141 | UInt16 phyStatusPrev; | |
142 | UInt32 linkStatusPrev; | |
143 | ||
144 | UInt16 phyBCMType; // 5400 or 5201 for PM | |
145 | ||
146 | OSDictionary * mediumDict; | |
147 | ||
148 | queue_head_t txActiveQueue; | |
149 | queue_head_t txFreeQueue; | |
150 | ||
151 | TxQueueElement * txElementPtrs[TX_RING_LENGTH]; | |
152 | struct mbuf * rxMbuf[RX_RING_LENGTH]; | |
153 | struct mbuf * txDebuggerPkt; | |
154 | ||
155 | void * debuggerPkt; | |
156 | u_int32_t debuggerPktSize; | |
157 | ||
158 | UInt32 txCommandHead; // TX ring descriptor index | |
159 | UInt32 txCommandTail; | |
160 | UInt32 rxCommandHead; // RX ring descriptor index | |
161 | UInt32 rxCommandTail; | |
162 | ||
163 | UInt32 dmaCommandsSize; | |
164 | UInt8 * dmaCommands; | |
165 | enet_txdma_cmd_t * txDMACommands; // TX descriptor ring ptr | |
166 | UInt32 txDMACommandsPhys; | |
167 | UInt32 txCommandsAvail; | |
168 | ||
169 | enet_dma_cmd_t * rxDMACommands; // RX descriptor ring ptr | |
170 | UInt32 rxDMACommandsPhys; | |
171 | ||
172 | UInt32 txIntCnt; | |
173 | UInt32 txRingIndexLast; | |
174 | UInt32 txWDInterrupts; | |
175 | UInt32 txWDCount; | |
176 | ||
177 | UInt32 rxWDInterrupts; | |
178 | UInt32 rxWDCount; | |
179 | UInt32 rxMacConfigReg; | |
180 | ||
181 | UInt16 hashTableUseCount[256]; | |
182 | UInt16 hashTableMask[16]; | |
183 | ||
184 | unsigned long currentPowerState; /* must be 0 or 1 */ | |
185 | ||
186 | bool allocateMemory(); | |
187 | bool initTxRing(); | |
188 | bool initRxRing(); | |
189 | void flushRings(); | |
190 | bool initChip(); | |
191 | bool resetChip(); | |
192 | void disableAdapterInterrupts(); | |
193 | void enableAdapterInterrupts(); | |
194 | void setDuplexMode(bool duplexMode); | |
195 | void startChip(); | |
196 | void stopChip(); | |
197 | bool updateDescriptorFromMbuf(struct mbuf * m, | |
198 | enet_dma_cmd_t * desc, | |
199 | bool isReceive); | |
200 | void monitorLinkStatus( bool firstPoll = false ); | |
201 | void restartTransmitter(); | |
202 | void stopTransmitDMA(); | |
203 | bool transmitPacket(struct mbuf * packet); | |
204 | bool transmitInterruptOccurred(); | |
205 | bool debugTransmitInterruptOccurred(); | |
206 | void debugTransmitCleanup(); | |
207 | bool receiveInterruptOccurred(); | |
208 | bool receivePackets(bool fDebugger); | |
209 | void packetToDebugger(struct mbuf * packet, u_int size); | |
210 | void restartReceiver(); | |
211 | void stopReceiveDMA(); | |
212 | bool resetAndEnable(bool enable); | |
213 | void sendDummyPacket(); | |
214 | void resetHashTableMask(); | |
215 | void addToHashTableMask(u_int8_t *addr); | |
216 | void removeFromHashTableMask(u_int8_t *addr); | |
217 | void updateHashTableMask(); | |
218 | ||
219 | ||
220 | TxQueueElement * getTxElement(); | |
221 | void releaseTxElement(TxQueueElement * txElement); | |
222 | ||
223 | #ifdef DEBUG | |
224 | void dumpRegisters(); | |
225 | #endif DEBUG | |
226 | ||
227 | void sendPacket(void * pkt, UInt32 pkt_len); | |
228 | void receivePacket(void * pkt, UInt32 * pkt_len, | |
229 | UInt32 timeout); | |
230 | ||
231 | bool miiReadWord(unsigned short * dataPtr, | |
232 | unsigned short reg, UInt8 phy); | |
233 | bool miiWriteWord(unsigned short data, | |
234 | unsigned short reg, UInt8 phy); | |
235 | void miiWrite(UInt32 miiData, UInt32 dataSize); | |
236 | bool miiResetPHY(UInt8 phy); | |
237 | bool miiWaitForLink(UInt8 phy); | |
238 | bool miiWaitForAutoNegotiation(UInt8 phy); | |
239 | void miiRestartAutoNegotiation(UInt8 phy); | |
240 | bool miiFindPHY(UInt8 * phy_num); | |
241 | bool miiInitializePHY(UInt8 phy); | |
242 | ||
243 | UInt32 outputPacket(struct mbuf * m, void * param); | |
244 | ||
245 | void interruptOccurred(IOInterruptEventSource * src, | |
246 | int count); | |
247 | void timeoutOccurred(IOTimerEventSource * timer); | |
248 | bool createMediumTables(); | |
249 | ||
250 | void writeRegister( UInt32 *pReg, UInt32 data ); | |
251 | ||
252 | void stopPHYChip(bool setupWOL); | |
253 | void startPHYChip(); | |
254 | bool resetPHYChip(); | |
255 | ||
256 | // callPlatformFunction symbols | |
257 | const OSSymbol *keyLargo_resetUniNEthernetPhy; | |
258 | ||
259 | IOService *keyLargo; | |
260 | ||
261 | public: | |
262 | virtual bool init(OSDictionary * properties = 0); | |
263 | virtual bool start(IOService * provider); | |
264 | virtual void free(); | |
265 | ||
266 | virtual bool createWorkLoop(); | |
267 | virtual IOWorkLoop * getWorkLoop() const; | |
268 | ||
269 | virtual IOReturn enable(IONetworkInterface * netif); | |
270 | virtual IOReturn disable(IONetworkInterface * netif); | |
271 | ||
272 | virtual IOReturn getHardwareAddress(IOEthernetAddress *addr); | |
273 | ||
274 | virtual IOReturn setMulticastMode(IOEnetMulticastMode mode); | |
275 | virtual IOReturn setMulticastList(IOEthernetAddress *addrs, UInt32 count); | |
276 | ||
277 | virtual IOReturn setPromiscuousMode(IOEnetPromiscuousMode mode); | |
278 | ||
279 | virtual IOOutputQueue * createOutputQueue(); | |
280 | ||
281 | virtual const OSString * newVendorString() const; | |
282 | virtual const OSString * newModelString() const; | |
283 | virtual const OSString * newRevisionString() const; | |
284 | ||
285 | virtual IOReturn enable(IOKernelDebugger * debugger); | |
286 | virtual IOReturn disable(IOKernelDebugger * debugger); | |
287 | ||
288 | virtual bool configureInterface(IONetworkInterface * netif); | |
289 | ||
290 | // Power management methods: | |
291 | virtual IOReturn registerWithPolicyMaker(IOService * policyMaker); | |
292 | virtual UInt32 maxCapabilityForDomainState(IOPMPowerFlags state); | |
293 | virtual UInt32 initialPowerStateForDomainState(IOPMPowerFlags state); | |
294 | virtual UInt32 powerStateForDomainState(IOPMPowerFlags state); | |
295 | virtual IOReturn setPowerState(UInt32 powerStateOrdinal, | |
296 | IOService * whatDevice); | |
297 | }; | |
298 | ||
299 | ||
300 | /* | |
301 | * Performance tracepoints | |
302 | * | |
303 | * DBG_UniN_RXIRQ - Receive ISR run time | |
304 | * DBG_UniN_TXIRQ - Transmit ISR run time | |
305 | * DBG_UniN_TXQUEUE - Transmit packet passed from network stack | |
306 | * DBG_UniN_TXCOMPLETE - Transmit packet sent | |
307 | * DBG_UniN_RXCOMPLETE - Receive packet passed to network stack | |
308 | */ | |
309 | #define DBG_UniN_ENET 0x0900 | |
310 | #define DBG_UniN_RXIRQ DRVDBG_CODE(DBG_DRVNETWORK,(DBG_UniN_ENET+1)) | |
311 | #define DBG_UniN_TXIRQ DRVDBG_CODE(DBG_DRVNETWORK,(DBG_UniN_ENET+2)) | |
312 | #define DBG_UniN_TXQUEUE DRVDBG_CODE(DBG_DRVNETWORK,(DBG_UniN_ENET+3)) | |
313 | #define DBG_UniN_TXCOMPLETE DRVDBG_CODE(DBG_DRVNETWORK,(DBG_UniN_ENET+4)) | |
314 | #define DBG_UniN_RXCOMPLETE DRVDBG_CODE(DBG_DRVNETWORK,(DBG_UniN_ENET+5)) |