if_stge.c (226173) | if_stge.c (226995) |
---|---|
1/* $NetBSD: if_stge.c,v 1.32 2005/12/11 12:22:49 christos Exp $ */ 2 3/*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. --- 21 unchanged lines hidden (view full) --- 30 */ 31 32/* 33 * Device driver for the Sundance Tech. TC9021 10/100/1000 34 * Ethernet controller. 35 */ 36 37#include <sys/cdefs.h> | 1/* $NetBSD: if_stge.c,v 1.32 2005/12/11 12:22:49 christos Exp $ */ 2 3/*- 4 * Copyright (c) 2001 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Jason R. Thorpe. --- 21 unchanged lines hidden (view full) --- 30 */ 31 32/* 33 * Device driver for the Sundance Tech. TC9021 10/100/1000 34 * Ethernet controller. 35 */ 36 37#include <sys/cdefs.h> |
38__FBSDID("$FreeBSD: head/sys/dev/stge/if_stge.c 226173 2011-10-09 20:27:20Z marius $"); | 38__FBSDID("$FreeBSD: head/sys/dev/stge/if_stge.c 226995 2011-11-01 16:13:59Z marius $"); |
39 40#ifdef HAVE_KERNEL_OPTION_HEADERS 41#include "opt_device_polling.h" 42#endif 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/endian.h> --- 15 unchanged lines hidden (view full) --- 62#include <net/if_vlan_var.h> 63 64#include <machine/bus.h> 65#include <machine/resource.h> 66#include <sys/bus.h> 67#include <sys/rman.h> 68 69#include <dev/mii/mii.h> | 39 40#ifdef HAVE_KERNEL_OPTION_HEADERS 41#include "opt_device_polling.h" 42#endif 43 44#include <sys/param.h> 45#include <sys/systm.h> 46#include <sys/endian.h> --- 15 unchanged lines hidden (view full) --- 62#include <net/if_vlan_var.h> 63 64#include <machine/bus.h> 65#include <machine/resource.h> 66#include <sys/bus.h> 67#include <sys/rman.h> 68 69#include <dev/mii/mii.h> |
70#include <dev/mii/mii_bitbang.h> |
|
70#include <dev/mii/miivar.h> 71 72#include <dev/pci/pcireg.h> 73#include <dev/pci/pcivar.h> 74 75#include <dev/stge/if_stgereg.h> 76 77#define STGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) 78 79MODULE_DEPEND(stge, pci, 1, 1, 1); 80MODULE_DEPEND(stge, ether, 1, 1, 1); 81MODULE_DEPEND(stge, miibus, 1, 1, 1); 82 83/* "device miibus" required. See GENERIC if you get errors here. */ 84#include "miibus_if.h" 85 86/* 87 * Devices supported by this driver. 88 */ | 71#include <dev/mii/miivar.h> 72 73#include <dev/pci/pcireg.h> 74#include <dev/pci/pcivar.h> 75 76#include <dev/stge/if_stgereg.h> 77 78#define STGE_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP) 79 80MODULE_DEPEND(stge, pci, 1, 1, 1); 81MODULE_DEPEND(stge, ether, 1, 1, 1); 82MODULE_DEPEND(stge, miibus, 1, 1, 1); 83 84/* "device miibus" required. See GENERIC if you get errors here. */ 85#include "miibus_if.h" 86 87/* 88 * Devices supported by this driver. 89 */ |
89static struct stge_product { | 90static const struct stge_product { |
90 uint16_t stge_vendorid; 91 uint16_t stge_deviceid; 92 const char *stge_name; | 91 uint16_t stge_vendorid; 92 uint16_t stge_deviceid; 93 const char *stge_name; |
93} stge_products[] = { | 94} const stge_products[] = { |
94 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST1023, 95 "Sundance ST-1023 Gigabit Ethernet" }, 96 97 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST2021, 98 "Sundance ST-2021 Gigabit Ethernet" }, 99 100 { VENDOR_TAMARACK, DEVICEID_TAMARACK_TC9021, 101 "Tamarack TC9021 Gigabit Ethernet" }, --- 53 unchanged lines hidden (view full) --- 155static void stge_txeof(struct stge_softc *); 156static int stge_rxeof(struct stge_softc *); 157static __inline void stge_discard_rxbuf(struct stge_softc *, int); 158static int stge_newbuf(struct stge_softc *, int); 159#ifndef __NO_STRICT_ALIGNMENT 160static __inline struct mbuf *stge_fixup_rx(struct stge_softc *, struct mbuf *); 161#endif 162 | 95 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST1023, 96 "Sundance ST-1023 Gigabit Ethernet" }, 97 98 { VENDOR_SUNDANCETI, DEVICEID_SUNDANCETI_ST2021, 99 "Sundance ST-2021 Gigabit Ethernet" }, 100 101 { VENDOR_TAMARACK, DEVICEID_TAMARACK_TC9021, 102 "Tamarack TC9021 Gigabit Ethernet" }, --- 53 unchanged lines hidden (view full) --- 156static void stge_txeof(struct stge_softc *); 157static int stge_rxeof(struct stge_softc *); 158static __inline void stge_discard_rxbuf(struct stge_softc *, int); 159static int stge_newbuf(struct stge_softc *, int); 160#ifndef __NO_STRICT_ALIGNMENT 161static __inline struct mbuf *stge_fixup_rx(struct stge_softc *, struct mbuf *); 162#endif 163 |
163static void stge_mii_sync(struct stge_softc *); 164static void stge_mii_send(struct stge_softc *, uint32_t, int); 165static int stge_mii_readreg(struct stge_softc *, struct stge_mii_frame *); 166static int stge_mii_writereg(struct stge_softc *, struct stge_mii_frame *); | |
167static int stge_miibus_readreg(device_t, int, int); 168static int stge_miibus_writereg(device_t, int, int, int); 169static void stge_miibus_statchg(device_t); 170static int stge_mediachange(struct ifnet *); 171static void stge_mediastatus(struct ifnet *, struct ifmediareq *); 172 173static void stge_dmamap_cb(void *, bus_dma_segment_t *, int, int); 174static int stge_dma_alloc(struct stge_softc *); --- 5 unchanged lines hidden (view full) --- 180static int stge_poll(struct ifnet *, enum poll_cmd, int); 181#endif 182 183static void stge_setwol(struct stge_softc *); 184static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int); 185static int sysctl_hw_stge_rxint_nframe(SYSCTL_HANDLER_ARGS); 186static int sysctl_hw_stge_rxint_dmawait(SYSCTL_HANDLER_ARGS); 187 | 164static int stge_miibus_readreg(device_t, int, int); 165static int stge_miibus_writereg(device_t, int, int, int); 166static void stge_miibus_statchg(device_t); 167static int stge_mediachange(struct ifnet *); 168static void stge_mediastatus(struct ifnet *, struct ifmediareq *); 169 170static void stge_dmamap_cb(void *, bus_dma_segment_t *, int, int); 171static int stge_dma_alloc(struct stge_softc *); --- 5 unchanged lines hidden (view full) --- 177static int stge_poll(struct ifnet *, enum poll_cmd, int); 178#endif 179 180static void stge_setwol(struct stge_softc *); 181static int sysctl_int_range(SYSCTL_HANDLER_ARGS, int, int); 182static int sysctl_hw_stge_rxint_nframe(SYSCTL_HANDLER_ARGS); 183static int sysctl_hw_stge_rxint_dmawait(SYSCTL_HANDLER_ARGS); 184 |
185/* 186 * MII bit-bang glue 187 */ 188static uint32_t stge_mii_bitbang_read(device_t); 189static void stge_mii_bitbang_write(device_t, uint32_t); 190 191static const struct mii_bitbang_ops stge_mii_bitbang_ops = { 192 stge_mii_bitbang_read, 193 stge_mii_bitbang_write, 194 { 195 PC_MgmtData, /* MII_BIT_MDO */ 196 PC_MgmtData, /* MII_BIT_MDI */ 197 PC_MgmtClk, /* MII_BIT_MDC */ 198 PC_MgmtDir, /* MII_BIT_DIR_HOST_PHY */ 199 0, /* MII_BIT_DIR_PHY_HOST */ 200 } 201}; 202 |
|
188static device_method_t stge_methods[] = { 189 /* Device interface */ 190 DEVMETHOD(device_probe, stge_probe), 191 DEVMETHOD(device_attach, stge_attach), 192 DEVMETHOD(device_detach, stge_detach), 193 DEVMETHOD(device_shutdown, stge_shutdown), 194 DEVMETHOD(device_suspend, stge_suspend), 195 DEVMETHOD(device_resume, stge_resume), --- 24 unchanged lines hidden (view full) --- 220}; 221 222static struct resource_spec stge_res_spec_mem[] = { 223 { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE }, 224 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 225 { -1, 0, 0 } 226}; 227 | 203static device_method_t stge_methods[] = { 204 /* Device interface */ 205 DEVMETHOD(device_probe, stge_probe), 206 DEVMETHOD(device_attach, stge_attach), 207 DEVMETHOD(device_detach, stge_detach), 208 DEVMETHOD(device_shutdown, stge_shutdown), 209 DEVMETHOD(device_suspend, stge_suspend), 210 DEVMETHOD(device_resume, stge_resume), --- 24 unchanged lines hidden (view full) --- 235}; 236 237static struct resource_spec stge_res_spec_mem[] = { 238 { SYS_RES_MEMORY, PCIR_BAR(1), RF_ACTIVE }, 239 { SYS_RES_IRQ, 0, RF_ACTIVE | RF_SHAREABLE }, 240 { -1, 0, 0 } 241}; 242 |
228#define MII_SET(x) \ 229 CSR_WRITE_1(sc, STGE_PhyCtrl, CSR_READ_1(sc, STGE_PhyCtrl) | (x)) 230#define MII_CLR(x) \ 231 CSR_WRITE_1(sc, STGE_PhyCtrl, CSR_READ_1(sc, STGE_PhyCtrl) & ~(x)) 232 | |
233/* | 243/* |
234 * Sync the PHYs by setting data bit and strobing the clock 32 times. | 244 * stge_mii_bitbang_read: [mii bit-bang interface function] 245 * 246 * Read the MII serial port for the MII bit-bang module. |
235 */ | 247 */ |
236static void 237stge_mii_sync(struct stge_softc *sc) | 248static uint32_t 249stge_mii_bitbang_read(device_t dev) |
238{ | 250{ |
239 int i; | 251 struct stge_softc *sc; 252 uint32_t val; |
240 | 253 |
241 MII_SET(PC_MgmtDir | PC_MgmtData); | 254 sc = device_get_softc(dev); |
242 | 255 |
243 for (i = 0; i < 32; i++) { 244 MII_SET(PC_MgmtClk); 245 DELAY(1); 246 MII_CLR(PC_MgmtClk); 247 DELAY(1); 248 } | 256 val = CSR_READ_1(sc, STGE_PhyCtrl); 257 CSR_BARRIER(sc, STGE_PhyCtrl, 1, 258 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 259 return (val); |
249} 250 251/* | 260} 261 262/* |
252 * Clock a series of bits through the MII. | 263 * stge_mii_bitbang_write: [mii big-bang interface function] 264 * 265 * Write the MII serial port for the MII bit-bang module. |
253 */ 254static void | 266 */ 267static void |
255stge_mii_send(struct stge_softc *sc, uint32_t bits, int cnt) | 268stge_mii_bitbang_write(device_t dev, uint32_t val) |
256{ | 269{ |
257 int i; | 270 struct stge_softc *sc; |
258 | 271 |
259 MII_CLR(PC_MgmtClk); | 272 sc = device_get_softc(dev); |
260 | 273 |
261 for (i = (0x1 << (cnt - 1)); i; i >>= 1) { 262 if (bits & i) 263 MII_SET(PC_MgmtData); 264 else 265 MII_CLR(PC_MgmtData); 266 DELAY(1); 267 MII_CLR(PC_MgmtClk); 268 DELAY(1); 269 MII_SET(PC_MgmtClk); 270 } | 274 CSR_WRITE_1(sc, STGE_PhyCtrl, val); 275 CSR_BARRIER(sc, STGE_PhyCtrl, 1, 276 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); |
271} 272 273/* | 277} 278 279/* |
274 * Read an PHY register through the MII. 275 */ 276static int 277stge_mii_readreg(struct stge_softc *sc, struct stge_mii_frame *frame) 278{ 279 int i, ack; 280 281 /* 282 * Set up frame for RX. 283 */ 284 frame->mii_stdelim = STGE_MII_STARTDELIM; 285 frame->mii_opcode = STGE_MII_READOP; 286 frame->mii_turnaround = 0; 287 frame->mii_data = 0; 288 289 CSR_WRITE_1(sc, STGE_PhyCtrl, 0 | sc->sc_PhyCtrl); 290 /* 291 * Turn on data xmit. 292 */ 293 MII_SET(PC_MgmtDir); 294 295 stge_mii_sync(sc); 296 297 /* 298 * Send command/address info. 299 */ 300 stge_mii_send(sc, frame->mii_stdelim, 2); 301 stge_mii_send(sc, frame->mii_opcode, 2); 302 stge_mii_send(sc, frame->mii_phyaddr, 5); 303 stge_mii_send(sc, frame->mii_regaddr, 5); 304 305 /* Turn off xmit. */ 306 MII_CLR(PC_MgmtDir); 307 308 /* Idle bit */ 309 MII_CLR((PC_MgmtClk | PC_MgmtData)); 310 DELAY(1); 311 MII_SET(PC_MgmtClk); 312 DELAY(1); 313 314 /* Check for ack */ 315 MII_CLR(PC_MgmtClk); 316 DELAY(1); 317 ack = CSR_READ_1(sc, STGE_PhyCtrl) & PC_MgmtData; 318 MII_SET(PC_MgmtClk); 319 DELAY(1); 320 321 /* 322 * Now try reading data bits. If the ack failed, we still 323 * need to clock through 16 cycles to keep the PHY(s) in sync. 324 */ 325 if (ack) { 326 for(i = 0; i < 16; i++) { 327 MII_CLR(PC_MgmtClk); 328 DELAY(1); 329 MII_SET(PC_MgmtClk); 330 DELAY(1); 331 } 332 goto fail; 333 } 334 335 for (i = 0x8000; i; i >>= 1) { 336 MII_CLR(PC_MgmtClk); 337 DELAY(1); 338 if (!ack) { 339 if (CSR_READ_1(sc, STGE_PhyCtrl) & PC_MgmtData) 340 frame->mii_data |= i; 341 DELAY(1); 342 } 343 MII_SET(PC_MgmtClk); 344 DELAY(1); 345 } 346 347fail: 348 MII_CLR(PC_MgmtClk); 349 DELAY(1); 350 MII_SET(PC_MgmtClk); 351 DELAY(1); 352 353 if (ack) 354 return(1); 355 return(0); 356} 357 358/* 359 * Write to a PHY register through the MII. 360 */ 361static int 362stge_mii_writereg(struct stge_softc *sc, struct stge_mii_frame *frame) 363{ 364 365 /* 366 * Set up frame for TX. 367 */ 368 frame->mii_stdelim = STGE_MII_STARTDELIM; 369 frame->mii_opcode = STGE_MII_WRITEOP; 370 frame->mii_turnaround = STGE_MII_TURNAROUND; 371 372 /* 373 * Turn on data output. 374 */ 375 MII_SET(PC_MgmtDir); 376 377 stge_mii_sync(sc); 378 379 stge_mii_send(sc, frame->mii_stdelim, 2); 380 stge_mii_send(sc, frame->mii_opcode, 2); 381 stge_mii_send(sc, frame->mii_phyaddr, 5); 382 stge_mii_send(sc, frame->mii_regaddr, 5); 383 stge_mii_send(sc, frame->mii_turnaround, 2); 384 stge_mii_send(sc, frame->mii_data, 16); 385 386 /* Idle bit. */ 387 MII_SET(PC_MgmtClk); 388 DELAY(1); 389 MII_CLR(PC_MgmtClk); 390 DELAY(1); 391 392 /* 393 * Turn off xmit. 394 */ 395 MII_CLR(PC_MgmtDir); 396 397 return(0); 398} 399 400/* | |
401 * sc_miibus_readreg: [mii interface function] 402 * 403 * Read a PHY register on the MII of the TC9021. 404 */ 405static int 406stge_miibus_readreg(device_t dev, int phy, int reg) 407{ 408 struct stge_softc *sc; | 280 * sc_miibus_readreg: [mii interface function] 281 * 282 * Read a PHY register on the MII of the TC9021. 283 */ 284static int 285stge_miibus_readreg(device_t dev, int phy, int reg) 286{ 287 struct stge_softc *sc; |
409 struct stge_mii_frame frame; 410 int error; | 288 int error, val; |
411 412 sc = device_get_softc(dev); 413 414 if (reg == STGE_PhyCtrl) { 415 /* XXX allow ip1000phy read STGE_PhyCtrl register. */ 416 STGE_MII_LOCK(sc); 417 error = CSR_READ_1(sc, STGE_PhyCtrl); 418 STGE_MII_UNLOCK(sc); 419 return (error); 420 } | 289 290 sc = device_get_softc(dev); 291 292 if (reg == STGE_PhyCtrl) { 293 /* XXX allow ip1000phy read STGE_PhyCtrl register. */ 294 STGE_MII_LOCK(sc); 295 error = CSR_READ_1(sc, STGE_PhyCtrl); 296 STGE_MII_UNLOCK(sc); 297 return (error); 298 } |
421 bzero(&frame, sizeof(frame)); 422 frame.mii_phyaddr = phy; 423 frame.mii_regaddr = reg; | |
424 425 STGE_MII_LOCK(sc); | 299 300 STGE_MII_LOCK(sc); |
426 error = stge_mii_readreg(sc, &frame); | 301 val = mii_bitbang_readreg(dev, &stge_mii_bitbang_ops, phy, reg); |
427 STGE_MII_UNLOCK(sc); | 302 STGE_MII_UNLOCK(sc); |
428 429 if (error != 0) { 430 /* Don't show errors for PHY probe request */ 431 if (reg != 1) 432 device_printf(sc->sc_dev, "phy read fail\n"); 433 return (0); 434 } 435 return (frame.mii_data); | 303 return (val); |
436} 437 438/* 439 * stge_miibus_writereg: [mii interface function] 440 * 441 * Write a PHY register on the MII of the TC9021. 442 */ 443static int 444stge_miibus_writereg(device_t dev, int phy, int reg, int val) 445{ 446 struct stge_softc *sc; | 304} 305 306/* 307 * stge_miibus_writereg: [mii interface function] 308 * 309 * Write a PHY register on the MII of the TC9021. 310 */ 311static int 312stge_miibus_writereg(device_t dev, int phy, int reg, int val) 313{ 314 struct stge_softc *sc; |
447 struct stge_mii_frame frame; 448 int error; | |
449 450 sc = device_get_softc(dev); 451 | 315 316 sc = device_get_softc(dev); 317 |
452 bzero(&frame, sizeof(frame)); 453 frame.mii_phyaddr = phy; 454 frame.mii_regaddr = reg; 455 frame.mii_data = val; 456 | |
457 STGE_MII_LOCK(sc); | 318 STGE_MII_LOCK(sc); |
458 error = stge_mii_writereg(sc, &frame); | 319 mii_bitbang_writereg(dev, &stge_mii_bitbang_ops, phy, reg, val); |
459 STGE_MII_UNLOCK(sc); | 320 STGE_MII_UNLOCK(sc); |
460 461 if (error != 0) 462 device_printf(sc->sc_dev, "phy write fail\n"); | |
463 return (0); 464} 465 466/* 467 * stge_miibus_statchg: [mii interface function] 468 * 469 * Callback from MII layer when media changes. 470 */ --- 74 unchanged lines hidden (view full) --- 545 device_printf(sc->sc_dev, "EEPROM read timed out\n"); 546 *data = CSR_READ_2(sc, STGE_EepromData); 547} 548 549 550static int 551stge_probe(device_t dev) 552{ | 321 return (0); 322} 323 324/* 325 * stge_miibus_statchg: [mii interface function] 326 * 327 * Callback from MII layer when media changes. 328 */ --- 74 unchanged lines hidden (view full) --- 403 device_printf(sc->sc_dev, "EEPROM read timed out\n"); 404 *data = CSR_READ_2(sc, STGE_EepromData); 405} 406 407 408static int 409stge_probe(device_t dev) 410{ |
553 struct stge_product *sp; | 411 const struct stge_product *sp; |
554 int i; 555 uint16_t vendor, devid; 556 557 vendor = pci_get_vendor(dev); 558 devid = pci_get_device(dev); 559 sp = stge_products; 560 for (i = 0; i < sizeof(stge_products)/sizeof(stge_products[0]); 561 i++, sp++) { --- 2188 unchanged lines hidden --- | 412 int i; 413 uint16_t vendor, devid; 414 415 vendor = pci_get_vendor(dev); 416 devid = pci_get_device(dev); 417 sp = stge_products; 418 for (i = 0; i < sizeof(stge_products)/sizeof(stge_products[0]); 419 i++, sp++) { --- 2188 unchanged lines hidden --- |