if_ste.c (221407) | if_ste.c (226995) |
---|---|
1/*- 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> | 1/*- 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 17 unchanged lines hidden (view full) --- 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 30 * THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 33#include <sys/cdefs.h> |
34__FBSDID("$FreeBSD: head/sys/dev/ste/if_ste.c 221407 2011-05-03 19:51:29Z marius $"); | 34__FBSDID("$FreeBSD: head/sys/dev/ste/if_ste.c 226995 2011-11-01 16:13:59Z marius $"); |
35 36#ifdef HAVE_KERNEL_OPTION_HEADERS 37#include "opt_device_polling.h" 38#endif 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/bus.h> --- 16 unchanged lines hidden (view full) --- 59#include <net/if_media.h> 60#include <net/if_types.h> 61#include <net/if_vlan_var.h> 62 63#include <machine/bus.h> 64#include <machine/resource.h> 65 66#include <dev/mii/mii.h> | 35 36#ifdef HAVE_KERNEL_OPTION_HEADERS 37#include "opt_device_polling.h" 38#endif 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/bus.h> --- 16 unchanged lines hidden (view full) --- 59#include <net/if_media.h> 60#include <net/if_types.h> 61#include <net/if_vlan_var.h> 62 63#include <machine/bus.h> 64#include <machine/resource.h> 65 66#include <dev/mii/mii.h> |
67#include <dev/mii/mii_bitbang.h> |
|
67#include <dev/mii/miivar.h> 68 69#include <dev/pci/pcireg.h> 70#include <dev/pci/pcivar.h> 71 72#include <dev/ste/if_stereg.h> 73 74/* "device miibus" required. See GENERIC if you get errors here. */ --- 4 unchanged lines hidden (view full) --- 79MODULE_DEPEND(ste, miibus, 1, 1, 1); 80 81/* Define to show Tx error status. */ 82#define STE_SHOW_TXERRORS 83 84/* 85 * Various supported device vendors/types and their names. 86 */ | 68#include <dev/mii/miivar.h> 69 70#include <dev/pci/pcireg.h> 71#include <dev/pci/pcivar.h> 72 73#include <dev/ste/if_stereg.h> 74 75/* "device miibus" required. See GENERIC if you get errors here. */ --- 4 unchanged lines hidden (view full) --- 80MODULE_DEPEND(ste, miibus, 1, 1, 1); 81 82/* Define to show Tx error status. */ 83#define STE_SHOW_TXERRORS 84 85/* 86 * Various supported device vendors/types and their names. 87 */ |
87static struct ste_type ste_devs[] = { | 88static const struct ste_type const ste_devs[] = { |
88 { ST_VENDORID, ST_DEVICEID_ST201_1, "Sundance ST201 10/100BaseTX" }, 89 { ST_VENDORID, ST_DEVICEID_ST201_2, "Sundance ST201 10/100BaseTX" }, 90 { DL_VENDORID, DL_DEVICEID_DL10050, "D-Link DL10050 10/100BaseTX" }, 91 { 0, 0, NULL } 92}; 93 94static int ste_attach(device_t); 95static int ste_detach(device_t); --- 11 unchanged lines hidden (view full) --- 107static int ste_ifmedia_upd(struct ifnet *); 108static void ste_ifmedia_sts(struct ifnet *, struct ifmediareq *); 109static void ste_init(void *); 110static void ste_init_locked(struct ste_softc *); 111static int ste_init_rx_list(struct ste_softc *); 112static void ste_init_tx_list(struct ste_softc *); 113static void ste_intr(void *); 114static int ste_ioctl(struct ifnet *, u_long, caddr_t); | 89 { ST_VENDORID, ST_DEVICEID_ST201_1, "Sundance ST201 10/100BaseTX" }, 90 { ST_VENDORID, ST_DEVICEID_ST201_2, "Sundance ST201 10/100BaseTX" }, 91 { DL_VENDORID, DL_DEVICEID_DL10050, "D-Link DL10050 10/100BaseTX" }, 92 { 0, 0, NULL } 93}; 94 95static int ste_attach(device_t); 96static int ste_detach(device_t); --- 11 unchanged lines hidden (view full) --- 108static int ste_ifmedia_upd(struct ifnet *); 109static void ste_ifmedia_sts(struct ifnet *, struct ifmediareq *); 110static void ste_init(void *); 111static void ste_init_locked(struct ste_softc *); 112static int ste_init_rx_list(struct ste_softc *); 113static void ste_init_tx_list(struct ste_softc *); 114static void ste_intr(void *); 115static int ste_ioctl(struct ifnet *, u_long, caddr_t); |
115static int ste_mii_readreg(struct ste_softc *, struct ste_mii_frame *); 116static void ste_mii_send(struct ste_softc *, uint32_t, int); 117static void ste_mii_sync(struct ste_softc *); 118static int ste_mii_writereg(struct ste_softc *, struct ste_mii_frame *); | 116static uint32_t ste_mii_bitbang_read(device_t); 117static void ste_mii_bitbang_write(device_t, uint32_t); |
119static int ste_miibus_readreg(device_t, int, int); 120static void ste_miibus_statchg(device_t); 121static int ste_miibus_writereg(device_t, int, int, int); 122static int ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *); 123static int ste_read_eeprom(struct ste_softc *, uint16_t *, int, int); 124static void ste_reset(struct ste_softc *); 125static void ste_restart_tx(struct ste_softc *); 126static int ste_rxeof(struct ste_softc *, int); --- 6 unchanged lines hidden (view full) --- 133static void ste_stop(struct ste_softc *); 134static void ste_sysctl_node(struct ste_softc *); 135static void ste_tick(void *); 136static void ste_txeoc(struct ste_softc *); 137static void ste_txeof(struct ste_softc *); 138static void ste_wait(struct ste_softc *); 139static void ste_watchdog(struct ste_softc *); 140 | 118static int ste_miibus_readreg(device_t, int, int); 119static void ste_miibus_statchg(device_t); 120static int ste_miibus_writereg(device_t, int, int, int); 121static int ste_newbuf(struct ste_softc *, struct ste_chain_onefrag *); 122static int ste_read_eeprom(struct ste_softc *, uint16_t *, int, int); 123static void ste_reset(struct ste_softc *); 124static void ste_restart_tx(struct ste_softc *); 125static int ste_rxeof(struct ste_softc *, int); --- 6 unchanged lines hidden (view full) --- 132static void ste_stop(struct ste_softc *); 133static void ste_sysctl_node(struct ste_softc *); 134static void ste_tick(void *); 135static void ste_txeoc(struct ste_softc *); 136static void ste_txeof(struct ste_softc *); 137static void ste_wait(struct ste_softc *); 138static void ste_watchdog(struct ste_softc *); 139 |
140/* 141 * MII bit-bang glue 142 */ 143static const struct mii_bitbang_ops ste_mii_bitbang_ops = { 144 ste_mii_bitbang_read, 145 ste_mii_bitbang_write, 146 { 147 STE_PHYCTL_MDATA, /* MII_BIT_MDO */ 148 STE_PHYCTL_MDATA, /* MII_BIT_MDI */ 149 STE_PHYCTL_MCLK, /* MII_BIT_MDC */ 150 STE_PHYCTL_MDIR, /* MII_BIT_DIR_HOST_PHY */ 151 0, /* MII_BIT_DIR_PHY_HOST */ 152 } 153}; 154 |
|
141static device_method_t ste_methods[] = { 142 /* Device interface */ 143 DEVMETHOD(device_probe, ste_probe), 144 DEVMETHOD(device_attach, ste_attach), 145 DEVMETHOD(device_detach, ste_detach), 146 DEVMETHOD(device_shutdown, ste_shutdown), 147 DEVMETHOD(device_suspend, ste_suspend), 148 DEVMETHOD(device_resume, ste_resume), --- 34 unchanged lines hidden (view full) --- 183 CSR_WRITE_2(sc, reg, CSR_READ_2(sc, reg) & ~(x)) 184 185#define STE_SETBIT1(sc, reg, x) \ 186 CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) | (x)) 187 188#define STE_CLRBIT1(sc, reg, x) \ 189 CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) & ~(x)) 190 | 155static device_method_t ste_methods[] = { 156 /* Device interface */ 157 DEVMETHOD(device_probe, ste_probe), 158 DEVMETHOD(device_attach, ste_attach), 159 DEVMETHOD(device_detach, ste_detach), 160 DEVMETHOD(device_shutdown, ste_shutdown), 161 DEVMETHOD(device_suspend, ste_suspend), 162 DEVMETHOD(device_resume, ste_resume), --- 34 unchanged lines hidden (view full) --- 197 CSR_WRITE_2(sc, reg, CSR_READ_2(sc, reg) & ~(x)) 198 199#define STE_SETBIT1(sc, reg, x) \ 200 CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) | (x)) 201 202#define STE_CLRBIT1(sc, reg, x) \ 203 CSR_WRITE_1(sc, reg, CSR_READ_1(sc, reg) & ~(x)) 204 |
191 192#define MII_SET(x) STE_SETBIT1(sc, STE_PHYCTL, x) 193#define MII_CLR(x) STE_CLRBIT1(sc, STE_PHYCTL, x) 194 | |
195/* | 205/* |
196 * Sync the PHYs by setting data bit and strobing the clock 32 times. | 206 * Read the MII serial port for the MII bit-bang module. |
197 */ | 207 */ |
198static void 199ste_mii_sync(struct ste_softc *sc) | 208static uint32_t 209ste_mii_bitbang_read(device_t dev) |
200{ | 210{ |
201 int i; | 211 struct ste_softc *sc; 212 uint32_t val; |
202 | 213 |
203 MII_SET(STE_PHYCTL_MDIR|STE_PHYCTL_MDATA); | 214 sc = device_get_softc(dev); |
204 | 215 |
205 for (i = 0; i < 32; i++) { 206 MII_SET(STE_PHYCTL_MCLK); 207 DELAY(1); 208 MII_CLR(STE_PHYCTL_MCLK); 209 DELAY(1); 210 } | 216 val = CSR_READ_1(sc, STE_PHYCTL); 217 CSR_BARRIER(sc, STE_PHYCTL, 1, 218 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 219 220 return (val); |
211} 212 213/* | 221} 222 223/* |
214 * Clock a series of bits through the MII. | 224 * Write the MII serial port for the MII bit-bang module. |
215 */ 216static void | 225 */ 226static void |
217ste_mii_send(struct ste_softc *sc, uint32_t bits, int cnt) | 227ste_mii_bitbang_write(device_t dev, uint32_t val) |
218{ | 228{ |
219 int i; | 229 struct ste_softc *sc; |
220 | 230 |
221 MII_CLR(STE_PHYCTL_MCLK); | 231 sc = device_get_softc(dev); |
222 | 232 |
223 for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 224 if (bits & i) { 225 MII_SET(STE_PHYCTL_MDATA); 226 } else { 227 MII_CLR(STE_PHYCTL_MDATA); 228 } 229 DELAY(1); 230 MII_CLR(STE_PHYCTL_MCLK); 231 DELAY(1); 232 MII_SET(STE_PHYCTL_MCLK); 233 } | 233 CSR_WRITE_1(sc, STE_PHYCTL, val); 234 CSR_BARRIER(sc, STE_PHYCTL, 1, 235 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); |
234} 235 | 236} 237 |
236/* 237 * Read an PHY register through the MII. 238 */ | |
239static int | 238static int |
240ste_mii_readreg(struct ste_softc *sc, struct ste_mii_frame *frame) 241{ 242 int i, ack; 243 244 /* 245 * Set up frame for RX. 246 */ 247 frame->mii_stdelim = STE_MII_STARTDELIM; 248 frame->mii_opcode = STE_MII_READOP; 249 frame->mii_turnaround = 0; 250 frame->mii_data = 0; 251 252 CSR_WRITE_2(sc, STE_PHYCTL, 0); 253 /* 254 * Turn on data xmit. 255 */ 256 MII_SET(STE_PHYCTL_MDIR); 257 258 ste_mii_sync(sc); 259 260 /* 261 * Send command/address info. 262 */ 263 ste_mii_send(sc, frame->mii_stdelim, 2); 264 ste_mii_send(sc, frame->mii_opcode, 2); 265 ste_mii_send(sc, frame->mii_phyaddr, 5); 266 ste_mii_send(sc, frame->mii_regaddr, 5); 267 268 /* Turn off xmit. */ 269 MII_CLR(STE_PHYCTL_MDIR); 270 271 /* Idle bit */ 272 MII_CLR((STE_PHYCTL_MCLK|STE_PHYCTL_MDATA)); 273 DELAY(1); 274 MII_SET(STE_PHYCTL_MCLK); 275 DELAY(1); 276 277 /* Check for ack */ 278 MII_CLR(STE_PHYCTL_MCLK); 279 DELAY(1); 280 ack = CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA; 281 MII_SET(STE_PHYCTL_MCLK); 282 DELAY(1); 283 284 /* 285 * Now try reading data bits. If the ack failed, we still 286 * need to clock through 16 cycles to keep the PHY(s) in sync. 287 */ 288 if (ack) { 289 for (i = 0; i < 16; i++) { 290 MII_CLR(STE_PHYCTL_MCLK); 291 DELAY(1); 292 MII_SET(STE_PHYCTL_MCLK); 293 DELAY(1); 294 } 295 goto fail; 296 } 297 298 for (i = 0x8000; i; i >>= 1) { 299 MII_CLR(STE_PHYCTL_MCLK); 300 DELAY(1); 301 if (!ack) { 302 if (CSR_READ_2(sc, STE_PHYCTL) & STE_PHYCTL_MDATA) 303 frame->mii_data |= i; 304 DELAY(1); 305 } 306 MII_SET(STE_PHYCTL_MCLK); 307 DELAY(1); 308 } 309 310fail: 311 312 MII_CLR(STE_PHYCTL_MCLK); 313 DELAY(1); 314 MII_SET(STE_PHYCTL_MCLK); 315 DELAY(1); 316 317 if (ack) 318 return (1); 319 return (0); 320} 321 322/* 323 * Write to a PHY register through the MII. 324 */ 325static int 326ste_mii_writereg(struct ste_softc *sc, struct ste_mii_frame *frame) 327{ 328 329 /* 330 * Set up frame for TX. 331 */ 332 333 frame->mii_stdelim = STE_MII_STARTDELIM; 334 frame->mii_opcode = STE_MII_WRITEOP; 335 frame->mii_turnaround = STE_MII_TURNAROUND; 336 337 /* 338 * Turn on data output. 339 */ 340 MII_SET(STE_PHYCTL_MDIR); 341 342 ste_mii_sync(sc); 343 344 ste_mii_send(sc, frame->mii_stdelim, 2); 345 ste_mii_send(sc, frame->mii_opcode, 2); 346 ste_mii_send(sc, frame->mii_phyaddr, 5); 347 ste_mii_send(sc, frame->mii_regaddr, 5); 348 ste_mii_send(sc, frame->mii_turnaround, 2); 349 ste_mii_send(sc, frame->mii_data, 16); 350 351 /* Idle bit. */ 352 MII_SET(STE_PHYCTL_MCLK); 353 DELAY(1); 354 MII_CLR(STE_PHYCTL_MCLK); 355 DELAY(1); 356 357 /* 358 * Turn off xmit. 359 */ 360 MII_CLR(STE_PHYCTL_MDIR); 361 362 return (0); 363} 364 365static int | |
366ste_miibus_readreg(device_t dev, int phy, int reg) 367{ | 239ste_miibus_readreg(device_t dev, int phy, int reg) 240{ |
368 struct ste_softc *sc; 369 struct ste_mii_frame frame; | |
370 | 241 |
371 sc = device_get_softc(dev); 372 bzero((char *)&frame, sizeof(frame)); 373 374 frame.mii_phyaddr = phy; 375 frame.mii_regaddr = reg; 376 ste_mii_readreg(sc, &frame); 377 378 return (frame.mii_data); | 242 return (mii_bitbang_readreg(dev, &ste_mii_bitbang_ops, phy, reg)); |
379} 380 381static int 382ste_miibus_writereg(device_t dev, int phy, int reg, int data) 383{ | 243} 244 245static int 246ste_miibus_writereg(device_t dev, int phy, int reg, int data) 247{ |
384 struct ste_softc *sc; 385 struct ste_mii_frame frame; | |
386 | 248 |
387 sc = device_get_softc(dev); 388 bzero((char *)&frame, sizeof(frame)); | 249 mii_bitbang_writereg(dev, &ste_mii_bitbang_ops, phy, reg, data); |
389 | 250 |
390 frame.mii_phyaddr = phy; 391 frame.mii_regaddr = reg; 392 frame.mii_data = data; 393 394 ste_mii_writereg(sc, &frame); 395 | |
396 return (0); 397} 398 399static void 400ste_miibus_statchg(device_t dev) 401{ 402 struct ste_softc *sc; 403 struct mii_data *mii; --- 618 unchanged lines hidden (view full) --- 1022 1023/* 1024 * Probe for a Sundance ST201 chip. Check the PCI vendor and device 1025 * IDs against our list and return a device name if we find a match. 1026 */ 1027static int 1028ste_probe(device_t dev) 1029{ | 251 return (0); 252} 253 254static void 255ste_miibus_statchg(device_t dev) 256{ 257 struct ste_softc *sc; 258 struct mii_data *mii; --- 618 unchanged lines hidden (view full) --- 877 878/* 879 * Probe for a Sundance ST201 chip. Check the PCI vendor and device 880 * IDs against our list and return a device name if we find a match. 881 */ 882static int 883ste_probe(device_t dev) 884{ |
1030 struct ste_type *t; | 885 const struct ste_type *t; |
1031 1032 t = ste_devs; 1033 1034 while (t->ste_name != NULL) { 1035 if ((pci_get_vendor(dev) == t->ste_vid) && 1036 (pci_get_device(dev) == t->ste_did)) { 1037 device_set_desc(dev, t->ste_name); 1038 return (BUS_PROBE_DEFAULT); --- 1244 unchanged lines hidden --- | 886 887 t = ste_devs; 888 889 while (t->ste_name != NULL) { 890 if ((pci_get_vendor(dev) == t->ste_vid) && 891 (pci_get_device(dev) == t->ste_did)) { 892 device_set_desc(dev, t->ste_name); 893 return (BUS_PROBE_DEFAULT); --- 1244 unchanged lines hidden --- |