Deleted Added
full compact
if_bm.c (221813) if_bm.c (226995)
1/*-
2 * Copyright 2008 Nathan Whitehorn. All rights reserved.
3 * Copyright 2003 by Peter Grehan. All rights reserved.
4 * Copyright (C) 1998, 1999, 2000 Tsubai Masanari. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 22 unchanged lines hidden (view full) ---

31 */
32
33/*
34 * BMAC/BMAC+ Macio cell 10/100 ethernet driver
35 * The low-cost, low-feature Apple variant of the Sun HME
36 */
37
38#include <sys/cdefs.h>
1/*-
2 * Copyright 2008 Nathan Whitehorn. All rights reserved.
3 * Copyright 2003 by Peter Grehan. All rights reserved.
4 * Copyright (C) 1998, 1999, 2000 Tsubai Masanari. All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 22 unchanged lines hidden (view full) ---

31 */
32
33/*
34 * BMAC/BMAC+ Macio cell 10/100 ethernet driver
35 * The low-cost, low-feature Apple variant of the Sun HME
36 */
37
38#include <sys/cdefs.h>
39__FBSDID("$FreeBSD: head/sys/dev/bm/if_bm.c 221813 2011-05-12 14:27:28Z nwhitehorn $");
39__FBSDID("$FreeBSD: head/sys/dev/bm/if_bm.c 226995 2011-11-01 16:13:59Z marius $");
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/sockio.h>
44#include <sys/endian.h>
45#include <sys/mbuf.h>
46#include <sys/module.h>
47#include <sys/malloc.h>

--- 10 unchanged lines hidden (view full) ---

58
59#include <machine/pio.h>
60#include <machine/bus.h>
61#include <machine/resource.h>
62#include <sys/bus.h>
63#include <sys/rman.h>
64
65#include <dev/mii/mii.h>
40
41#include <sys/param.h>
42#include <sys/systm.h>
43#include <sys/sockio.h>
44#include <sys/endian.h>
45#include <sys/mbuf.h>
46#include <sys/module.h>
47#include <sys/malloc.h>

--- 10 unchanged lines hidden (view full) ---

58
59#include <machine/pio.h>
60#include <machine/bus.h>
61#include <machine/resource.h>
62#include <sys/bus.h>
63#include <sys/rman.h>
64
65#include <dev/mii/mii.h>
66#include <dev/mii/mii_bitbang.h>
66#include <dev/mii/miivar.h>
67
68#include <dev/ofw/ofw_bus.h>
69#include <dev/ofw/openfirm.h>
70#include <machine/dbdma.h>
71
72MODULE_DEPEND(bm, ether, 1, 1, 1);
73MODULE_DEPEND(bm, miibus, 1, 1, 1);

--- 26 unchanged lines hidden (view full) ---

100static int bm_add_rxbuf_dma (struct bm_softc *sc, int i);
101static void bm_enable_interrupts (struct bm_softc *sc);
102static void bm_disable_interrupts (struct bm_softc *sc);
103static void bm_tick (void *xsc);
104
105static int bm_ifmedia_upd (struct ifnet *);
106static void bm_ifmedia_sts (struct ifnet *, struct ifmediareq *);
107
67#include <dev/mii/miivar.h>
68
69#include <dev/ofw/ofw_bus.h>
70#include <dev/ofw/openfirm.h>
71#include <machine/dbdma.h>
72
73MODULE_DEPEND(bm, ether, 1, 1, 1);
74MODULE_DEPEND(bm, miibus, 1, 1, 1);

--- 26 unchanged lines hidden (view full) ---

101static int bm_add_rxbuf_dma (struct bm_softc *sc, int i);
102static void bm_enable_interrupts (struct bm_softc *sc);
103static void bm_disable_interrupts (struct bm_softc *sc);
104static void bm_tick (void *xsc);
105
106static int bm_ifmedia_upd (struct ifnet *);
107static void bm_ifmedia_sts (struct ifnet *, struct ifmediareq *);
108
108static void bm_miicsr_dwrite (struct bm_softc *, u_int16_t);
109static void bm_mii_writebit (struct bm_softc *, int);
110static int bm_mii_readbit (struct bm_softc *);
111static void bm_mii_sync (struct bm_softc *);
112static void bm_mii_send (struct bm_softc *, u_int32_t, int);
113static int bm_mii_readreg (struct bm_softc *, struct bm_mii_frame *);
114static int bm_mii_writereg (struct bm_softc *, struct bm_mii_frame *);
115static int bm_miibus_readreg (device_t, int, int);
116static int bm_miibus_writereg (device_t, int, int, int);
117static void bm_miibus_statchg (device_t);
118
109static int bm_miibus_readreg (device_t, int, int);
110static int bm_miibus_writereg (device_t, int, int, int);
111static void bm_miibus_statchg (device_t);
112
113/*
114 * MII bit-bang glue
115 */
116static uint32_t bm_mii_bitbang_read(device_t);
117static void bm_mii_bitbang_write(device_t, uint32_t);
118
119static const struct mii_bitbang_ops bm_mii_bitbang_ops = {
120 bm_mii_bitbang_read,
121 bm_mii_bitbang_write,
122 {
123 BM_MII_DATAOUT, /* MII_BIT_MDO */
124 BM_MII_DATAIN, /* MII_BIT_MDI */
125 BM_MII_CLK, /* MII_BIT_MDC */
126 BM_MII_OENABLE, /* MII_BIT_DIR_HOST_PHY */
127 0, /* MII_BIT_DIR_PHY_HOST */
128 }
129};
130
119static device_method_t bm_methods[] = {
120 /* Device interface */
121 DEVMETHOD(device_probe, bm_probe),
122 DEVMETHOD(device_attach, bm_attach),
123 DEVMETHOD(device_detach, bm_detach),
124 DEVMETHOD(device_shutdown, bm_shutdown),
125
126 /* bus interface, for miibus */

--- 18 unchanged lines hidden (view full) ---

145DRIVER_MODULE(bm, macio, bm_macio_driver, bm_devclass, 0, 0);
146DRIVER_MODULE(miibus, bm, miibus_driver, miibus_devclass, 0, 0);
147
148/*
149 * MII internal routines
150 */
151
152/*
131static device_method_t bm_methods[] = {
132 /* Device interface */
133 DEVMETHOD(device_probe, bm_probe),
134 DEVMETHOD(device_attach, bm_attach),
135 DEVMETHOD(device_detach, bm_detach),
136 DEVMETHOD(device_shutdown, bm_shutdown),
137
138 /* bus interface, for miibus */

--- 18 unchanged lines hidden (view full) ---

157DRIVER_MODULE(bm, macio, bm_macio_driver, bm_devclass, 0, 0);
158DRIVER_MODULE(miibus, bm, miibus_driver, miibus_devclass, 0, 0);
159
160/*
161 * MII internal routines
162 */
163
164/*
153 * Write to the MII csr, introducing a delay to allow valid
154 * MII clock pulses to be formed
165 * Write the MII serial port for the MII bit-bang module.
155 */
156static void
166 */
167static void
157bm_miicsr_dwrite(struct bm_softc *sc, u_int16_t val)
168bm_mii_bitbang_write(device_t dev, uint32_t val)
158{
169{
159 CSR_WRITE_2(sc, BM_MII_CSR, val);
160 /*
161 * Assume this is a clock toggle and generate a 1us delay
162 * to cover both MII's 160ns high/low minimum and 400ns
163 * cycle miniumum
164 */
165 DELAY(1);
166}
170 struct bm_softc *sc;
167
171
168/*
169 * Write a bit to the MII bus.
170 */
171static void
172bm_mii_writebit(struct bm_softc *sc, int bit)
173{
174 u_int16_t regval;
172 sc = device_get_softc(dev);
175
173
176 regval = BM_MII_OENABLE;
177 if (bit)
178 regval |= BM_MII_DATAOUT;
179
180 bm_miicsr_dwrite(sc, regval);
181 bm_miicsr_dwrite(sc, regval | BM_MII_CLK);
182 bm_miicsr_dwrite(sc, regval);
174 CSR_WRITE_2(sc, BM_MII_CSR, val);
175 CSR_BARRIER(sc, BM_MII_CSR, 2,
176 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
183}
184
185/*
177}
178
179/*
186 * Read a bit from the MII bus.
180 * Read the MII serial port for the MII bit-bang module.
187 */
181 */
188static int
189bm_mii_readbit(struct bm_softc *sc)
182static uint32_t
183bm_mii_bitbang_read(device_t dev)
190{
184{
191 u_int16_t regval, bitin;
185 struct bm_softc *sc;
186 uint32_t reg;
192
187
193 /* ~BM_MII_OENABLE */
194 regval = 0;
188 sc = device_get_softc(dev);
195
189
196 bm_miicsr_dwrite(sc, regval);
197 bm_miicsr_dwrite(sc, regval | BM_MII_CLK);
198 bm_miicsr_dwrite(sc, regval);
199 bitin = CSR_READ_2(sc, BM_MII_CSR) & BM_MII_DATAIN;
190 reg = CSR_READ_2(sc, BM_MII_CSR);
191 CSR_BARRIER(sc, BM_MII_CSR, 2,
192 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
200
193
201 return (bitin == BM_MII_DATAIN);
194 return (reg);
202}
203
204/*
195}
196
197/*
205 * Sync the PHYs by setting data bit and strobing the clock 32 times.
206 */
207static void
208bm_mii_sync(struct bm_softc *sc)
209{
210 int i;
211 u_int16_t regval;
212
213 regval = BM_MII_OENABLE | BM_MII_DATAOUT;
214
215 bm_miicsr_dwrite(sc, regval);
216 for (i = 0; i < 32; i++) {
217 bm_miicsr_dwrite(sc, regval | BM_MII_CLK);
218 bm_miicsr_dwrite(sc, regval);
219 }
220}
221
222/*
223 * Clock a series of bits through the MII.
224 */
225static void
226bm_mii_send(struct bm_softc *sc, u_int32_t bits, int cnt)
227{
228 int i;
229
230 for (i = (0x1 << (cnt - 1)); i; i >>= 1)
231 bm_mii_writebit(sc, bits & i);
232}
233
234/*
235 * Read a PHY register through the MII.
236 */
237static int
238bm_mii_readreg(struct bm_softc *sc, struct bm_mii_frame *frame)
239{
240 int i, ack, bit;
241
242 /*
243 * Set up frame for RX.
244 */
245 frame->mii_stdelim = BM_MII_STARTDELIM;
246 frame->mii_opcode = BM_MII_READOP;
247 frame->mii_turnaround = 0;
248 frame->mii_data = 0;
249
250 /*
251 * Sync the PHYs
252 */
253 bm_mii_sync(sc);
254
255 /*
256 * Send command/address info
257 */
258 bm_mii_send(sc, frame->mii_stdelim, 2);
259 bm_mii_send(sc, frame->mii_opcode, 2);
260 bm_mii_send(sc, frame->mii_phyaddr, 5);
261 bm_mii_send(sc, frame->mii_regaddr, 5);
262
263 /*
264 * Check for ack.
265 */
266 ack = bm_mii_readbit(sc);
267
268 /*
269 * Now try reading data bits. If the ack failed, we still
270 * need to clock through 16 cycles to keep the PHY(s) in sync.
271 */
272 for (i = 0x8000; i; i >>= 1) {
273 bit = bm_mii_readbit(sc);
274 if (!ack && bit)
275 frame->mii_data |= i;
276 }
277
278 /*
279 * Skip through idle bit-times
280 */
281 bm_mii_writebit(sc, 0);
282 bm_mii_writebit(sc, 0);
283
284 return ((ack) ? 1 : 0);
285}
286
287/*
288 * Write to a PHY register through the MII.
289 */
290static int
291bm_mii_writereg(struct bm_softc *sc, struct bm_mii_frame *frame)
292{
293 /*
294 * Set up frame for tx
295 */
296 frame->mii_stdelim = BM_MII_STARTDELIM;
297 frame->mii_opcode = BM_MII_WRITEOP;
298 frame->mii_turnaround = BM_MII_TURNAROUND;
299
300 /*
301 * Sync the phy and start the bitbang write sequence
302 */
303 bm_mii_sync(sc);
304
305 bm_mii_send(sc, frame->mii_stdelim, 2);
306 bm_mii_send(sc, frame->mii_opcode, 2);
307 bm_mii_send(sc, frame->mii_phyaddr, 5);
308 bm_mii_send(sc, frame->mii_regaddr, 5);
309 bm_mii_send(sc, frame->mii_turnaround, 2);
310 bm_mii_send(sc, frame->mii_data, 16);
311
312 /*
313 * Idle bit.
314 */
315 bm_mii_writebit(sc, 0);
316
317 return (0);
318}
319
320/*
321 * MII bus i/f
322 */
323static int
324bm_miibus_readreg(device_t dev, int phy, int reg)
325{
198 * MII bus i/f
199 */
200static int
201bm_miibus_readreg(device_t dev, int phy, int reg)
202{
326 struct bm_softc *sc;
327 struct bm_mii_frame frame;
328
203
329 sc = device_get_softc(dev);
330 bzero(&frame, sizeof(frame));
331
332 frame.mii_phyaddr = phy;
333 frame.mii_regaddr = reg;
334
335 bm_mii_readreg(sc, &frame);
336
337 return (frame.mii_data);
204 return (mii_bitbang_readreg(dev, &bm_mii_bitbang_ops, phy, reg));
338}
339
340static int
341bm_miibus_writereg(device_t dev, int phy, int reg, int data)
342{
205}
206
207static int
208bm_miibus_writereg(device_t dev, int phy, int reg, int data)
209{
343 struct bm_softc *sc;
344 struct bm_mii_frame frame;
345
210
346 sc = device_get_softc(dev);
347 bzero(&frame, sizeof(frame));
211 mii_bitbang_readreg(dev, &bm_mii_bitbang_ops, phy, reg);
348
212
349 frame.mii_phyaddr = phy;
350 frame.mii_regaddr = reg;
351 frame.mii_data = data;
352
353 bm_mii_writereg(sc, &frame);
354
355 return (0);
356}
357
358static void
359bm_miibus_statchg(device_t dev)
360{
361 struct bm_softc *sc = device_get_softc(dev);
362 uint16_t reg;

--- 1078 unchanged lines hidden ---
213 return (0);
214}
215
216static void
217bm_miibus_statchg(device_t dev)
218{
219 struct bm_softc *sc = device_get_softc(dev);
220 uint16_t reg;

--- 1078 unchanged lines hidden ---