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 --- |