2 * (C) Copyright 2009 Industrie Dial Face S.p.A.
8 * See file CREDITS for list of people who contributed to this
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation; either version 2 of
14 * the License, or (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
28 * This provides a bit-banged interface to the ethernet MII management
34 #include <ppc_asm.tmpl>
37 #define BB_MII_RELOCATE(v,off) (v += (v?off:0))
39 DECLARE_GLOBAL_DATA_PTR;
41 #ifndef CONFIG_BITBANGMII_MULTI
44 * If CONFIG_BITBANGMII_MULTI is not defined we use a
45 * compatibility layer with the previous miiphybb implementation
46 * based on macros usage.
49 static int bb_mii_init_wrap(struct bb_miiphy_bus *bus)
57 static int bb_mdio_active_wrap(struct bb_miiphy_bus *bus)
66 static int bb_mdio_tristate_wrap(struct bb_miiphy_bus *bus)
75 static int bb_set_mdio_wrap(struct bb_miiphy_bus *bus, int v)
84 static int bb_get_mdio_wrap(struct bb_miiphy_bus *bus, int *v)
93 static int bb_set_mdc_wrap(struct bb_miiphy_bus *bus, int v)
102 static int bb_delay_wrap(struct bb_miiphy_bus *bus)
108 struct bb_miiphy_bus bb_miiphy_buses[] = {
110 .name = BB_MII_DEVNAME,
111 .init = bb_mii_init_wrap,
112 .mdio_active = bb_mdio_active_wrap,
113 .mdio_tristate = bb_mdio_tristate_wrap,
114 .set_mdio = bb_set_mdio_wrap,
115 .get_mdio = bb_get_mdio_wrap,
116 .set_mdc = bb_set_mdc_wrap,
117 .delay = bb_delay_wrap,
121 int bb_miiphy_buses_num = sizeof(bb_miiphy_buses) /
122 sizeof(bb_miiphy_buses[0]);
125 void bb_miiphy_init(void)
129 for (i = 0; i < bb_miiphy_buses_num; i++) {
130 #if !defined(CONFIG_RELOC_FIXUP_WORKS)
131 /* Relocate the hook pointers*/
132 BB_MII_RELOCATE(bb_miiphy_buses[i].init, gd->reloc_off);
133 BB_MII_RELOCATE(bb_miiphy_buses[i].mdio_active, gd->reloc_off);
134 BB_MII_RELOCATE(bb_miiphy_buses[i].mdio_tristate, gd->reloc_off);
135 BB_MII_RELOCATE(bb_miiphy_buses[i].set_mdio, gd->reloc_off);
136 BB_MII_RELOCATE(bb_miiphy_buses[i].get_mdio, gd->reloc_off);
137 BB_MII_RELOCATE(bb_miiphy_buses[i].set_mdc, gd->reloc_off);
138 BB_MII_RELOCATE(bb_miiphy_buses[i].delay, gd->reloc_off);
140 if (bb_miiphy_buses[i].init != NULL) {
141 bb_miiphy_buses[i].init(&bb_miiphy_buses[i]);
146 static inline struct bb_miiphy_bus *bb_miiphy_getbus(const char *devname)
148 #ifdef CONFIG_BITBANGMII_MULTI
151 /* Search the correct bus */
152 for (i = 0; i < bb_miiphy_buses_num; i++) {
153 if (!strcmp(bb_miiphy_buses[i].name, devname)) {
154 return &bb_miiphy_buses[i];
159 /* We have just one bitbanging bus */
160 return &bb_miiphy_buses[0];
164 /*****************************************************************************
166 * Utility to send the preamble, address, and register (common to read
169 static void miiphy_pre(struct bb_miiphy_bus *bus, char read,
170 unsigned char addr, unsigned char reg)
175 * Send a 32 bit preamble ('1's) with an extra '1' bit for good measure.
176 * The IEEE spec says this is a PHY optional requirement. The AMD
177 * 79C874 requires one after power up and one after a MII communications
178 * error. This means that we are doing more preambles than we need,
179 * but it is safer and will be much more robust.
182 bus->mdio_active(bus);
183 bus->set_mdio(bus, 1);
184 for (j = 0; j < 32; j++) {
185 bus->set_mdc(bus, 0);
187 bus->set_mdc(bus, 1);
191 /* send the start bit (01) and the read opcode (10) or write (10) */
192 bus->set_mdc(bus, 0);
193 bus->set_mdio(bus, 0);
195 bus->set_mdc(bus, 1);
197 bus->set_mdc(bus, 0);
198 bus->set_mdio(bus, 1);
200 bus->set_mdc(bus, 1);
202 bus->set_mdc(bus, 0);
203 bus->set_mdio(bus, read);
205 bus->set_mdc(bus, 1);
207 bus->set_mdc(bus, 0);
208 bus->set_mdio(bus, !read);
210 bus->set_mdc(bus, 1);
213 /* send the PHY address */
214 for (j = 0; j < 5; j++) {
215 bus->set_mdc(bus, 0);
216 if ((addr & 0x10) == 0) {
217 bus->set_mdio(bus, 0);
219 bus->set_mdio(bus, 1);
222 bus->set_mdc(bus, 1);
227 /* send the register address */
228 for (j = 0; j < 5; j++) {
229 bus->set_mdc(bus, 0);
230 if ((reg & 0x10) == 0) {
231 bus->set_mdio(bus, 0);
233 bus->set_mdio(bus, 1);
236 bus->set_mdc(bus, 1);
242 /*****************************************************************************
244 * Read a MII PHY register.
249 int bb_miiphy_read(const char *devname, unsigned char addr,
250 unsigned char reg, unsigned short *value)
252 short rdreg; /* register working value */
255 struct bb_miiphy_bus *bus;
257 bus = bb_miiphy_getbus(devname);
263 puts("NULL value pointer\n");
267 miiphy_pre (bus, 1, addr, reg);
269 /* tri-state our MDIO I/O pin so we can read */
270 bus->set_mdc(bus, 0);
271 bus->mdio_tristate(bus);
273 bus->set_mdc(bus, 1);
276 /* check the turnaround bit: the PHY should be driving it to zero */
277 bus->get_mdio(bus, &v);
279 /* puts ("PHY didn't drive TA low\n"); */
280 for (j = 0; j < 32; j++) {
281 bus->set_mdc(bus, 0);
283 bus->set_mdc(bus, 1);
286 /* There is no PHY, set value to 0xFFFF and return */
291 bus->set_mdc(bus, 0);
294 /* read 16 bits of register data, MSB first */
296 for (j = 0; j < 16; j++) {
297 bus->set_mdc(bus, 1);
300 bus->get_mdio(bus, &v);
302 bus->set_mdc(bus, 0);
306 bus->set_mdc(bus, 1);
308 bus->set_mdc(bus, 0);
310 bus->set_mdc(bus, 1);
316 printf ("miiphy_read(0x%x) @ 0x%x = 0x%04x\n", reg, addr, *value);
323 /*****************************************************************************
325 * Write a MII PHY register.
330 int bb_miiphy_write (const char *devname, unsigned char addr,
331 unsigned char reg, unsigned short value)
333 struct bb_miiphy_bus *bus;
336 bus = bb_miiphy_getbus(devname);
342 miiphy_pre (bus, 0, addr, reg);
344 /* send the turnaround (10) */
345 bus->set_mdc(bus, 0);
346 bus->set_mdio(bus, 1);
348 bus->set_mdc(bus, 1);
350 bus->set_mdc(bus, 0);
351 bus->set_mdio(bus, 0);
353 bus->set_mdc(bus, 1);
356 /* write 16 bits of register data, MSB first */
357 for (j = 0; j < 16; j++) {
358 bus->set_mdc(bus, 0);
359 if ((value & 0x00008000) == 0) {
360 bus->set_mdio(bus, 0);
362 bus->set_mdio(bus, 1);
365 bus->set_mdc(bus, 1);
371 * Tri-state the MDIO line.
373 bus->mdio_tristate(bus);
374 bus->set_mdc(bus, 0);
376 bus->set_mdc(bus, 1);