Deleted Added
full compact
if_xl.c (223385) if_xl.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/xl/if_xl.c 223385 2011-06-21 22:17:28Z imp $");
34__FBSDID("$FreeBSD: head/sys/dev/xl/if_xl.c 226995 2011-11-01 16:13:59Z marius $");
35
36/*
37 * 3Com 3c90x Etherlink XL PCI NIC driver
38 *
39 * Supports the 3Com "boomerang", "cyclone" and "hurricane" PCI
40 * bus-master chips (3c90x cards and embedded controllers) including
41 * the following:
42 *

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

122#include <net/bpf.h>
123
124#include <machine/bus.h>
125#include <machine/resource.h>
126#include <sys/bus.h>
127#include <sys/rman.h>
128
129#include <dev/mii/mii.h>
35
36/*
37 * 3Com 3c90x Etherlink XL PCI NIC driver
38 *
39 * Supports the 3Com "boomerang", "cyclone" and "hurricane" PCI
40 * bus-master chips (3c90x cards and embedded controllers) including
41 * the following:
42 *

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

122#include <net/bpf.h>
123
124#include <machine/bus.h>
125#include <machine/resource.h>
126#include <sys/bus.h>
127#include <sys/rman.h>
128
129#include <dev/mii/mii.h>
130#include <dev/mii/mii_bitbang.h>
130#include <dev/mii/miivar.h>
131
132#include <dev/pci/pcireg.h>
133#include <dev/pci/pcivar.h>
134
135MODULE_DEPEND(xl, pci, 1, 1, 1);
136MODULE_DEPEND(xl, ether, 1, 1, 1);
137MODULE_DEPEND(xl, miibus, 1, 1, 1);

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

155#define XL905B_CSUM_FEATURES 0
156#else
157#define XL905B_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
158#endif
159
160/*
161 * Various supported device vendors/types and their names.
162 */
131#include <dev/mii/miivar.h>
132
133#include <dev/pci/pcireg.h>
134#include <dev/pci/pcivar.h>
135
136MODULE_DEPEND(xl, pci, 1, 1, 1);
137MODULE_DEPEND(xl, ether, 1, 1, 1);
138MODULE_DEPEND(xl, miibus, 1, 1, 1);

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

156#define XL905B_CSUM_FEATURES 0
157#else
158#define XL905B_CSUM_FEATURES (CSUM_IP | CSUM_TCP | CSUM_UDP)
159#endif
160
161/*
162 * Various supported device vendors/types and their names.
163 */
163static const struct xl_type xl_devs[] = {
164static const struct xl_type const xl_devs[] = {
164 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
165 "3Com 3c900-TPO Etherlink XL" },
166 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
167 "3Com 3c900-COMBO Etherlink XL" },
168 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10_100BT,
169 "3Com 3c905-TX Fast Etherlink XL" },
170 { TC_VENDORID, TC_DEVICEID_BOOMERANG_100BT4,
171 "3Com 3c905-T4 Fast Etherlink XL" },

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

253static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
254#endif
255
256static int xl_ifmedia_upd(struct ifnet *);
257static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
258
259static int xl_eeprom_wait(struct xl_softc *);
260static int xl_read_eeprom(struct xl_softc *, caddr_t, int, int, int);
165 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT,
166 "3Com 3c900-TPO Etherlink XL" },
167 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10BT_COMBO,
168 "3Com 3c900-COMBO Etherlink XL" },
169 { TC_VENDORID, TC_DEVICEID_BOOMERANG_10_100BT,
170 "3Com 3c905-TX Fast Etherlink XL" },
171 { TC_VENDORID, TC_DEVICEID_BOOMERANG_100BT4,
172 "3Com 3c905-T4 Fast Etherlink XL" },

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

254static int xl_poll_locked(struct ifnet *ifp, enum poll_cmd cmd, int count);
255#endif
256
257static int xl_ifmedia_upd(struct ifnet *);
258static void xl_ifmedia_sts(struct ifnet *, struct ifmediareq *);
259
260static int xl_eeprom_wait(struct xl_softc *);
261static int xl_read_eeprom(struct xl_softc *, caddr_t, int, int, int);
261static void xl_mii_sync(struct xl_softc *);
262static void xl_mii_send(struct xl_softc *, u_int32_t, int);
263static int xl_mii_readreg(struct xl_softc *, struct xl_mii_frame *);
264static int xl_mii_writereg(struct xl_softc *, struct xl_mii_frame *);
265
266static void xl_rxfilter(struct xl_softc *);
267static void xl_rxfilter_90x(struct xl_softc *);
268static void xl_rxfilter_90xB(struct xl_softc *);
269static void xl_setcfg(struct xl_softc *);
270static void xl_setmode(struct xl_softc *, int);
271static void xl_reset(struct xl_softc *);
272static int xl_list_rx_init(struct xl_softc *);

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

281static void xl_testpacket(struct xl_softc *);
282#endif
283
284static int xl_miibus_readreg(device_t, int, int);
285static int xl_miibus_writereg(device_t, int, int, int);
286static void xl_miibus_statchg(device_t);
287static void xl_miibus_mediainit(device_t);
288
262
263static void xl_rxfilter(struct xl_softc *);
264static void xl_rxfilter_90x(struct xl_softc *);
265static void xl_rxfilter_90xB(struct xl_softc *);
266static void xl_setcfg(struct xl_softc *);
267static void xl_setmode(struct xl_softc *, int);
268static void xl_reset(struct xl_softc *);
269static int xl_list_rx_init(struct xl_softc *);

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

278static void xl_testpacket(struct xl_softc *);
279#endif
280
281static int xl_miibus_readreg(device_t, int, int);
282static int xl_miibus_writereg(device_t, int, int, int);
283static void xl_miibus_statchg(device_t);
284static void xl_miibus_mediainit(device_t);
285
286/*
287 * MII bit-bang glue
288 */
289static uint32_t xl_mii_bitbang_read(device_t);
290static void xl_mii_bitbang_write(device_t, uint32_t);
291
292static const struct mii_bitbang_ops xl_mii_bitbang_ops = {
293 xl_mii_bitbang_read,
294 xl_mii_bitbang_write,
295 {
296 XL_MII_DATA, /* MII_BIT_MDO */
297 XL_MII_DATA, /* MII_BIT_MDI */
298 XL_MII_CLK, /* MII_BIT_MDC */
299 XL_MII_DIR, /* MII_BIT_DIR_HOST_PHY */
300 0, /* MII_BIT_DIR_PHY_HOST */
301 }
302};
303
289static device_method_t xl_methods[] = {
290 /* Device interface */
291 DEVMETHOD(device_probe, xl_probe),
292 DEVMETHOD(device_attach, xl_attach),
293 DEVMETHOD(device_detach, xl_detach),
294 DEVMETHOD(device_shutdown, xl_shutdown),
295 DEVMETHOD(device_suspend, xl_suspend),
296 DEVMETHOD(device_resume, xl_resume),

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

354 * MII access routines are provided for adapters with external
355 * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
356 * autoneg logic that's faked up to look like a PHY (3c905B-TX).
357 * Note: if you don't perform the MDIO operations just right,
358 * it's possible to end up with code that works correctly with
359 * some chips/CPUs/processor speeds/bus speeds/etc but not
360 * with others.
361 */
304static device_method_t xl_methods[] = {
305 /* Device interface */
306 DEVMETHOD(device_probe, xl_probe),
307 DEVMETHOD(device_attach, xl_attach),
308 DEVMETHOD(device_detach, xl_detach),
309 DEVMETHOD(device_shutdown, xl_shutdown),
310 DEVMETHOD(device_suspend, xl_suspend),
311 DEVMETHOD(device_resume, xl_resume),

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

369 * MII access routines are provided for adapters with external
370 * PHYs (3c905-TX, 3c905-T4, 3c905B-T4) and those with built-in
371 * autoneg logic that's faked up to look like a PHY (3c905B-TX).
372 * Note: if you don't perform the MDIO operations just right,
373 * it's possible to end up with code that works correctly with
374 * some chips/CPUs/processor speeds/bus speeds/etc but not
375 * with others.
376 */
362#define MII_SET(x) \
363 CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \
364 CSR_READ_2(sc, XL_W4_PHY_MGMT) | (x))
365
377
366#define MII_CLR(x) \
367 CSR_WRITE_2(sc, XL_W4_PHY_MGMT, \
368 CSR_READ_2(sc, XL_W4_PHY_MGMT) & ~(x))
369
370/*
378/*
371 * Sync the PHYs by setting data bit and strobing the clock 32 times.
379 * Read the MII serial port for the MII bit-bang module.
372 */
380 */
373static void
374xl_mii_sync(struct xl_softc *sc)
381static uint32_t
382xl_mii_bitbang_read(device_t dev)
375{
383{
376 register int i;
384 struct xl_softc *sc;
385 uint32_t val;
377
386
378 XL_SEL_WIN(4);
379 MII_SET(XL_MII_DIR|XL_MII_DATA);
387 sc = device_get_softc(dev);
380
388
381 for (i = 0; i < 32; i++) {
382 MII_SET(XL_MII_CLK);
383 MII_SET(XL_MII_DATA);
384 MII_SET(XL_MII_DATA);
385 MII_CLR(XL_MII_CLK);
386 MII_SET(XL_MII_DATA);
387 MII_SET(XL_MII_DATA);
388 }
389 /* We're already in window 4. */
390 val = CSR_READ_2(sc, XL_W4_PHY_MGMT);
391 CSR_BARRIER(sc, XL_W4_PHY_MGMT, 2,
392 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
393
394 return (val);
389}
390
391/*
395}
396
397/*
392 * Clock a series of bits through the MII.
398 * Write the MII serial port for the MII bit-bang module.
393 */
394static void
399 */
400static void
395xl_mii_send(struct xl_softc *sc, u_int32_t bits, int cnt)
401xl_mii_bitbang_write(device_t dev, uint32_t val)
396{
402{
397 int i;
403 struct xl_softc *sc;
398
404
399 XL_SEL_WIN(4);
400 MII_CLR(XL_MII_CLK);
405 sc = device_get_softc(dev);
401
406
402 for (i = (0x1 << (cnt - 1)); i; i >>= 1) {
403 if (bits & i) {
404 MII_SET(XL_MII_DATA);
405 } else {
406 MII_CLR(XL_MII_DATA);
407 }
408 MII_CLR(XL_MII_CLK);
409 MII_SET(XL_MII_CLK);
410 }
407 /* We're already in window 4. */
408 CSR_WRITE_2(sc, XL_W4_PHY_MGMT, val);
409 CSR_BARRIER(sc, XL_W4_PHY_MGMT, 2,
410 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE);
411}
412
411}
412
413/*
414 * Read an PHY register through the MII.
415 */
416static int
413static int
417xl_mii_readreg(struct xl_softc *sc, struct xl_mii_frame *frame)
418{
419 int i, ack;
420
421 /* Set up frame for RX. */
422 frame->mii_stdelim = XL_MII_STARTDELIM;
423 frame->mii_opcode = XL_MII_READOP;
424 frame->mii_turnaround = 0;
425 frame->mii_data = 0;
426
427 /* Select register window 4. */
428 XL_SEL_WIN(4);
429
430 CSR_WRITE_2(sc, XL_W4_PHY_MGMT, 0);
431 /* Turn on data xmit. */
432 MII_SET(XL_MII_DIR);
433
434 xl_mii_sync(sc);
435
436 /* Send command/address info. */
437 xl_mii_send(sc, frame->mii_stdelim, 2);
438 xl_mii_send(sc, frame->mii_opcode, 2);
439 xl_mii_send(sc, frame->mii_phyaddr, 5);
440 xl_mii_send(sc, frame->mii_regaddr, 5);
441
442 /* Idle bit */
443 MII_CLR((XL_MII_CLK|XL_MII_DATA));
444 MII_SET(XL_MII_CLK);
445
446 /* Turn off xmit. */
447 MII_CLR(XL_MII_DIR);
448
449 /* Check for ack */
450 MII_CLR(XL_MII_CLK);
451 ack = CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA;
452 MII_SET(XL_MII_CLK);
453
454 /*
455 * Now try reading data bits. If the ack failed, we still
456 * need to clock through 16 cycles to keep the PHY(s) in sync.
457 */
458 if (ack) {
459 for (i = 0; i < 16; i++) {
460 MII_CLR(XL_MII_CLK);
461 MII_SET(XL_MII_CLK);
462 }
463 goto fail;
464 }
465
466 for (i = 0x8000; i; i >>= 1) {
467 MII_CLR(XL_MII_CLK);
468 if (!ack) {
469 if (CSR_READ_2(sc, XL_W4_PHY_MGMT) & XL_MII_DATA)
470 frame->mii_data |= i;
471 }
472 MII_SET(XL_MII_CLK);
473 }
474
475fail:
476 MII_CLR(XL_MII_CLK);
477 MII_SET(XL_MII_CLK);
478
479 return (ack ? 1 : 0);
480}
481
482/*
483 * Write to a PHY register through the MII.
484 */
485static int
486xl_mii_writereg(struct xl_softc *sc, struct xl_mii_frame *frame)
487{
488
489 /* Set up frame for TX. */
490 frame->mii_stdelim = XL_MII_STARTDELIM;
491 frame->mii_opcode = XL_MII_WRITEOP;
492 frame->mii_turnaround = XL_MII_TURNAROUND;
493
494 /* Select the window 4. */
495 XL_SEL_WIN(4);
496
497 /* Turn on data output. */
498 MII_SET(XL_MII_DIR);
499
500 xl_mii_sync(sc);
501
502 xl_mii_send(sc, frame->mii_stdelim, 2);
503 xl_mii_send(sc, frame->mii_opcode, 2);
504 xl_mii_send(sc, frame->mii_phyaddr, 5);
505 xl_mii_send(sc, frame->mii_regaddr, 5);
506 xl_mii_send(sc, frame->mii_turnaround, 2);
507 xl_mii_send(sc, frame->mii_data, 16);
508
509 /* Idle bit. */
510 MII_SET(XL_MII_CLK);
511 MII_CLR(XL_MII_CLK);
512
513 /* Turn off xmit. */
514 MII_CLR(XL_MII_DIR);
515
516 return (0);
517}
518
519static int
520xl_miibus_readreg(device_t dev, int phy, int reg)
521{
522 struct xl_softc *sc;
414xl_miibus_readreg(device_t dev, int phy, int reg)
415{
416 struct xl_softc *sc;
523 struct xl_mii_frame frame;
524
525 sc = device_get_softc(dev);
526
417
418 sc = device_get_softc(dev);
419
527 bzero((char *)&frame, sizeof(frame));
528 frame.mii_phyaddr = phy;
529 frame.mii_regaddr = reg;
420 /* Select the window 4. */
421 XL_SEL_WIN(4);
530
422
531 xl_mii_readreg(sc, &frame);
532
533 return (frame.mii_data);
423 return (mii_bitbang_readreg(dev, &xl_mii_bitbang_ops, phy, reg));
534}
535
536static int
537xl_miibus_writereg(device_t dev, int phy, int reg, int data)
538{
539 struct xl_softc *sc;
424}
425
426static int
427xl_miibus_writereg(device_t dev, int phy, int reg, int data)
428{
429 struct xl_softc *sc;
540 struct xl_mii_frame frame;
541
542 sc = device_get_softc(dev);
543
430
431 sc = device_get_softc(dev);
432
544 bzero((char *)&frame, sizeof(frame));
545 frame.mii_phyaddr = phy;
546 frame.mii_regaddr = reg;
547 frame.mii_data = data;
433 /* Select the window 4. */
434 XL_SEL_WIN(4);
548
435
549 xl_mii_writereg(sc, &frame);
436 mii_bitbang_writereg(dev, &xl_mii_bitbang_ops, phy, reg, data);
550
551 return (0);
552}
553
554static void
555xl_miibus_statchg(device_t dev)
556{
557 struct xl_softc *sc;

--- 2853 unchanged lines hidden ---
437
438 return (0);
439}
440
441static void
442xl_miibus_statchg(device_t dev)
443{
444 struct xl_softc *sc;

--- 2853 unchanged lines hidden ---