]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/network/drvIntel82557/i82557eeprom.cpp
a0a479cee2fce8dcda8a945be262e3aa0b69e07a
[apple/xnu.git] / iokit / Drivers / network / drvIntel82557 / i82557eeprom.cpp
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) 1996 NeXT Software, Inc.
24 *
25 * i82557eeprom.m
26 * - Intel 82557 eeprom access object
27 *
28 * HISTORY
29 *
30 * 6-Mar-96 Dieter Siegmund (dieter) at NeXT
31 * Created.
32 */
33
34 #include <IOKit/network/IOEthernetController.h>
35 #include "i82557eeprom.h"
36
37 #define super OSObject
38 OSDefineMetaClassAndStructors( i82557eeprom, OSObject )
39
40 static __inline__ void
41 _logAddr(unsigned char * addr)
42 {
43 int i;
44 for (i = 0; i < NUM_EN_ADDR_BYTES; i++) {
45 IOLog("%s%02x", i > 0 ? ":" : "", addr[i]);
46 }
47 return;
48 }
49
50 void i82557eeprom::dumpContents()
51 {
52 EEPROM_t * eeprom_p = &image.fields;
53
54 IOLog("The EEPROM contains the following information:\n");
55
56 IOLog("ethernet address: ");
57 _logAddr((unsigned char *) &eeprom_p->addr);
58 IOLog("\n");
59
60 if (eeprom_p->compatibility_0 & EEPROM_C0_MC_10)
61 IOLog("compatibility: MCSETUP workaround required for 10 Mbits\n");
62 if (eeprom_p->compatibility_0 & EEPROM_C0_MC_100)
63 IOLog("compatibility: MCSETUP workaround required for 100 Mbits\n");
64
65 IOLog("connectors: %s %s %s %s\n",
66 eeprom_p->connectors & EEPROM_CON_RJ45 ? "RJ-45" : "",
67 eeprom_p->connectors & EEPROM_CON_BNC ? "BNC" : "",
68 eeprom_p->connectors & EEPROM_CON_AUI ? "AUI" : "",
69 eeprom_p->connectors & EEPROM_CON_MII ? "MII" : "");
70
71 IOLog("controller type: %d\n", eeprom_p->controllerType);
72
73 for (int i = 0; i < NUM_PHYS; i++) {
74 char * s = (i == PRIMARY_PHY) ? "primary" : "secondary";
75 UInt16 phy = OSReadLE16(&eeprom_p->phys[i]);
76
77 IOLog("%s PHY: %s\n", s,
78 PHYDeviceNames(CSR_VALUE(EEPROM_PHY_DEVICE, phy)));
79 if (CSR_VALUE(EEPROM_PHY_DEVICE, phy) != PHYDevice_None_e) {
80 if (phy & EEPROM_PHY_VSCR)
81 IOLog("%s PHY: vendor specific code required\n", s);
82 if (phy & EEPROM_PHY_10)
83 IOLog("%s PHY: 10 Mbits only, requires 503 interface\n", s);
84 IOLog("%s PHY address: 0x%x\n", s,
85 CSR_VALUE(EEPROM_PHY_ADDRESS, phy));
86 }
87 }
88
89 IOLog("PWA Number: %d %d %d-0%d\n", eeprom_p->PWANumber[1],
90 eeprom_p->PWANumber[0], eeprom_p->PWANumber[3],
91 eeprom_p->PWANumber[2]);
92
93 IOLog("Checksum: 0x%x\n", OSReadLE16(&eeprom_p->checkSum));
94 #if 0
95 if (eeprom_p->checkSum != image.words[NUM_EEPROM_WORDS - 1])
96 IOLog("the checksum in the struct doesn't match that in the array\n");
97 #endif
98 return;
99 }
100
101 i82557eeprom * i82557eeprom::withAddress(volatile eeprom_control_t * p)
102 {
103 i82557eeprom * eeprom = new i82557eeprom;
104
105 if (eeprom && !eeprom->initWithAddress(p)) {
106 eeprom->release();
107 return 0;
108 }
109 return eeprom;
110 }
111
112 bool i82557eeprom::initWithAddress(volatile eeprom_control_t * p)
113 {
114 int i;
115 UInt16 sum;
116
117 if (!super::init())
118 return false;
119
120 ee_p = p;
121
122 /*
123 * Find out the number of bits in the address by issuing a read to address
124 * 0 ie. keep feeding eeprom address bits with value 0, until the eeprom
125 * says that the address is complete. It tells us by setting EEDO to 0
126 * after a write cycle.
127 */
128 EEPROMEnable(ee_p);
129 EEPROMWriteBit(ee_p, 1); /* read */
130 EEPROMWriteBit(ee_p, 1);
131 EEPROMWriteBit(ee_p, 0);
132 nbits = 1;
133
134 do {
135 EEPROMWriteBit(ee_p, 0);
136 if ((OSReadLE16(ee_p) & EEPROM_CONTROL_EEDO) == 0)
137 break;
138 nbits++;
139 } while (nbits <= 32);
140
141 // IOLog("nbits: %d\n", nbits);
142
143 EEPROMDisable(ee_p);
144 for (sum = 0, i = 0; i < NUM_EEPROM_WORDS; i++) {
145 UInt16 w = readWord(i);
146 sum += w;
147 OSWriteLE16(&image.words[i], w);
148 }
149 if (sum != EEPROM_CHECKSUM_VALUE) {
150 IOLog("i82557eeprom: checksum %x incorrect\n", sum);
151 return false;
152 }
153
154 return true;
155 }
156
157 /* READ command bit sequence: 1 1 0 a5a4a3a2a1a0 */
158 UInt16 i82557eeprom::readWord(int offset)
159 {
160 int i;
161 UInt16 value;
162
163 EEPROMEnable(ee_p);
164 EEPROMWriteBit(ee_p, 1);
165 EEPROMWriteBit(ee_p, 1);
166 EEPROMWriteBit(ee_p, 0);
167 for (i = (nbits - 1); i >= 0; i--) {
168 EEPROMWriteBit(ee_p, (offset >> i) & 1);
169 }
170 value = 0;
171 for (i = BITS_IN_SHORT - 1; i >= 0; i--) {
172 value |= (EEPROMReadBit(ee_p) << i);
173 }
174 EEPROMDisable(ee_p);
175 return (value);
176 }
177
178 EEPROM_t * i82557eeprom::getContents()
179 {
180 return (&image.fields);
181 }
182