-
Notifications
You must be signed in to change notification settings - Fork 6
/
BCM5722D.h
executable file
·325 lines (260 loc) · 9.44 KB
/
BCM5722D.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
/*
* BCM5722D
* Copyright (C) 2010 Adlan Razalan <dev at adlan dot name dot my>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef BCM5722D_BCM5722D_H
#define BCM5722D_BCM5722D_H
#ifdef __cplusplus
extern "C" {
#endif // __cplusplus
#include <libkern/libkern.h>
#include <libkern/OSAtomic.h>
#include <machine/limits.h>
#include <net/ethernet.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_var.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip6.h>
#include <netinet/tcp.h>
#include <sys/appleapiopts.h>
#include <sys/errno.h>
#include <sys/kpi_mbuf.h>
#ifdef __cplusplus
}
#endif // __cplusplus
#ifdef __cplusplus
#include <IOKit/network/IOMbufMemoryCursor.h>
#include <IOKit/IOBufferMemoryDescriptor.h>
#include <IOKit/IOCommandGate.h>
#include <IOKit/IOFilterInterruptEventSource.h>
#include <IOKit/IOLib.h>
#include <IOKit/IOLocks.h>
#include <IOKit/IOTimerEventSource.h>
#include <IOKit/IOTypes.h>
#include <IOKit/network/IOEthernetController.h>
#include <IOKit/network/IOEthernetInterface.h>
#include <IOKit/network/IOBasicOutputQueue.h>
#include <IOKit/pci/IOPCIDevice.h>
#endif // __cplusplus
#include "Common.h"
#include "PHY.h"
#define BCM5722D my_name_adlan_BCM5722D
#define BUMP_NETSTAT(x) do { networkStats->x += 1; } while (0)
#define BUMP_ETHSTAT(x) do { ethernetStats->dot3StatsEntry.x += 1; } while (0)
#define BUMP_TXSTAT(x) do { ethernetStats->dot3TxExtraEntry.x += 1; } while (0)
#define BUMP_RXSTAT(x) do { ethernetStats->dot3RxExtraEntry.x += 1; } while (0)
enum
{
kMaxPacketSize = kIOEthernetMaxPacketSize + 4,
kTxBDCount = 512,
kRxBDCount = 512,
kTxMaxSegmentCount = 384, // 0.75 *ring size(512) = 384
kRxMaxSegmentCount = 1,
kWatchDogTimeout = 5000 // ms
};
enum BOption
{
kOptionDefault = 0,
kBDOptionReuse, // [configureRxDescriptor] Reuse the buffer descriptor
};
class BCM5722D : public IOEthernetController
{
OSDeclareDefaultStructors(BCM5722D);
private:
IOPCIDevice *pciNub;
IOMemoryMap *csrMap;
IOWorkLoop *workLoop;
volatile void *csrBase;
IOInterruptEventSource *interruptSource;
IOEthernetInterface *netIface;
IOTimerEventSource *timerSource;
IOEthernetAddress ethAddress;
IOOutputQueue *transmitQueue;
IONetworkStats *networkStats;
IOEthernetStats *ethernetStats;
OSDictionary *mediumDict;
IOBufferMemoryDescriptor *txMD;
BTxBufferDescriptor *txBD;
IOPhysicalAddress txAddress;
IOMbufNaturalMemoryCursor *txCursor;
mbuf_t txPacketArray[kTxBDCount];
IOBufferMemoryDescriptor *rxMD;
BRxBufferDescriptor *rxBD;
IOPhysicalAddress rxAddress;
IOMbufNaturalMemoryCursor *rxCursor;
mbuf_t rxPacketArray[kRxBDCount];
IOBufferMemoryDescriptor *rxReturnMD;
BRxBufferDescriptor *rxReturnBD;
IOPhysicalAddress rxReturnAddress;
IOBufferMemoryDescriptor *statusBlockMD;
BStatusBlock *statusBlock;
IOPhysicalAddress statusBlockAddress;
UInt16 asicRevision;
UInt16 deviceID;
UInt32 txQueueLength;
bool queueStalled;
bool magicPacketSupported;
bool wakeOnLanEnabled;
bool adapterEnabled;
bool interruptEnabled;
bool promiscuousModeEnabled;
unsigned long currentPowerState;
UInt16 txProducerIdx;
UInt16 txLocalConsumerIdx;
SInt16 txFreeSlot;
UInt16 rxProducerIdx;
UInt16 rxReturnConsumerIdx;
UInt16 rxSegmentLength[kRxBDCount];
UInt32 rxMode;
UInt32 txMode;
UInt32 macMode;
UInt32 pciMiscHostControl;
bool autoNegotiate;
UInt8 currentMediumIndex;
UInt32 phyID;
UInt16 phyFlags;
MediaStatus media;
public:
#pragma mark -
#pragma mark IOService Methods
virtual bool start(IOService *provider);
virtual void stop(IOService *provider);
virtual void free(void);
#pragma mark -
#pragma mark IONetworkController Methods
virtual IOReturn enable(IONetworkInterface *iface);
virtual IOReturn disable(IONetworkInterface *iface);
virtual void systemWillShutdown(IOOptionBits specifier);
virtual bool createWorkLoop();
virtual IOWorkLoop *getWorkLoop(void) const;
virtual IOOutputQueue *createOutputQueue();
virtual bool configureInterface(IONetworkInterface *iface);
virtual IOReturn getChecksumSupport(UInt32 *checksumMask,
UInt32 checksumFamily,
bool isOutput);
virtual IOReturn getPacketFilters(const OSSymbol *group,
UInt32 *filters) const;
virtual IOReturn getMaxPacketSize(UInt32 *maxSize) const;
virtual IOReturn registerWithPolicyMaker(IOService *policyMaker);
virtual IOReturn setPowerState(unsigned long powerStateOrdinal,
IOService *policyMaker);
virtual UInt32 outputPacket(mbuf_t m,
void *param);
virtual IOReturn selectMedium(const IONetworkMedium *medium);
virtual const OSString *newModelString() const;
virtual const OSString *newRevisionString() const;
virtual const OSString *newVendorString() const;
#pragma mark -
#pragma mark IOEthernetController Methods
virtual IOReturn getHardwareAddress(IOEthernetAddress *address);
virtual IOReturn setHardwareAddress(const IOEthernetAddress *address);
virtual IOReturn setWakeOnMagicPacket(bool active);
virtual IOReturn setMulticastMode(bool active);
virtual IOReturn setMulticastList(IOEthernetAddress *addrs,
UInt32 count);
virtual IOReturn setPromiscuousMode(bool active);
#pragma mark -
#pragma mark MAC
#pragma mark -
#pragma mark -
#pragma mark Initialization/Reset
bool setupDriver(IOService *provider);
bool resetAdapter();
void initializePCIConfig();
void prepareDriver();
bool initializeAdapter();
void stopAdapter();
IOReturn lockNVRAM();
void configureMACAddress();
void clearStatistics();
void updateStatistics();
#pragma mark -
#pragma mark Memory/Ring
bool allocateDescriptorMemory(IOBufferMemoryDescriptor **memory,
IOByteCount size);
void freeDescriptorMemory(IOBufferMemoryDescriptor **memory);
bool allocateDriverMemory();
bool configureRxDescriptor(UInt16 index, BOption options = kOptionDefault);
bool initTxRing();
void freeTxRing();
bool initRxRing();
void freeRxRing();
#pragma mark -
#pragma mark Interrupt Handling
void enableInterrupts(bool active);
void interruptOccurred(IOInterruptEventSource *source, int count);
void timeoutOccurred(IOTimerEventSource *source);
void serviceTxInterrupt(UInt16 consumerIdx);
void serviceRxInterrupt(UInt16 producerIdx);
#pragma mark -
#pragma mark Reader/Writer
void writeCSR(UInt32 offset, UInt32 value);
UInt32 readCSR(UInt32 offset);
void writeMemoryIndirect(UInt32 offset, UInt32 value);
UInt32 readMemoryIndirect(UInt32 offset);
void writeMailbox(UInt32 offset, UInt32 value);
UInt32 readMailbox(UInt32 offset);
void clearBit(UInt32 offset, UInt32 bit);
void setBit(UInt32 offset, UInt32 bit);
#pragma mark -
#pragma mark Helper
UInt32 computeEthernetCRC(const UInt8 *address, int length);
void prepareForWakeOnLanMode();
#pragma mark -
#pragma mark PHY
#pragma mark -
#pragma mark -
#pragma mark Initialization/Reset/Fixes
bool probePHY();
bool setupPHY();
IOReturn resetPHY();
void acknowledgeInterrupt();
void configureMAC();
void enableLoopback();
void fixJitterBug();
void fixAdjustTrim();
#pragma mark -
#pragma mark Medium
void addNetworkMedium(UInt32 type,
UInt32 speed,
UInt32 index);
void probeMediaCapability();
IOReturn setMedium(const IONetworkMedium *medium);
#pragma mark -
#pragma mark Link
UInt16 resolvePauseAdvertisement(FlowControl flowControl);
void setupFlowControl(UInt16 local, UInt16 partner);
void configureLinkAdvertisement(LinkSpeed linkSpeed,
LinkDuplex linkDuplex);
bool startAutoNegotiation(LinkSpeed changeSpeed,
LinkDuplex changeDuplex);
bool forceLinkSpeedDuplex(LinkSpeed changeSpeed,
LinkDuplex changeDuplex);
void resolveOperatingSpeedAndLinkDuplex(UInt16 status);
void enableAutoMDIX(bool active);
void enableEthernetAtWirespeed();
void reportLinkStatus();
#pragma mark -
#pragma mark Interrupt Handling
void serviceLinkInterrupt();
#pragma mark -
#pragma mark Reader/Writer
IOReturn writeMII(UInt8 reg, UInt16 value);
IOReturn readMII(UInt8 reg, UInt16 *value);
};
#endif