if_dc.c (226701) | if_dc.c (226995) |
---|---|
1/*- 2 * Copyright (c) 1997, 1998, 1999 3 * Bill Paul <wpaul@ee.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@ee.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/dc/if_dc.c 226701 2011-10-24 20:48:02Z yongari $"); | 34__FBSDID("$FreeBSD: head/sys/dev/dc/if_dc.c 226995 2011-11-01 16:13:59Z marius $"); |
35 36/* 37 * DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143 38 * series chips and several workalikes including the following: 39 * 40 * Macronix 98713/98715/98725/98727/98732 PMAC (www.macronix.com) 41 * Macronix/Lite-On 82c115 PNIC II (www.macronix.com) 42 * Lite-On 82c168/82c169 PNIC (www.litecom.com) --- 74 unchanged lines hidden (view full) --- 117#include <net/bpf.h> 118 119#include <machine/bus.h> 120#include <machine/resource.h> 121#include <sys/bus.h> 122#include <sys/rman.h> 123 124#include <dev/mii/mii.h> | 35 36/* 37 * DEC "tulip" clone ethernet driver. Supports the DEC/Intel 21143 38 * series chips and several workalikes including the following: 39 * 40 * Macronix 98713/98715/98725/98727/98732 PMAC (www.macronix.com) 41 * Macronix/Lite-On 82c115 PNIC II (www.macronix.com) 42 * Lite-On 82c168/82c169 PNIC (www.litecom.com) --- 74 unchanged lines hidden (view full) --- 117#include <net/bpf.h> 118 119#include <machine/bus.h> 120#include <machine/resource.h> 121#include <sys/bus.h> 122#include <sys/rman.h> 123 124#include <dev/mii/mii.h> |
125#include <dev/mii/mii_bitbang.h> |
|
125#include <dev/mii/miivar.h> 126 127#include <dev/pci/pcireg.h> 128#include <dev/pci/pcivar.h> 129 130#define DC_USEIOSPACE 131 132#include <dev/dc/if_dcreg.h> --- 11 unchanged lines hidden (view full) --- 144 * "device miibus" is required in kernel config. See GENERIC if you get 145 * errors here. 146 */ 147#include "miibus_if.h" 148 149/* 150 * Various supported device vendors/types and their names. 151 */ | 126#include <dev/mii/miivar.h> 127 128#include <dev/pci/pcireg.h> 129#include <dev/pci/pcivar.h> 130 131#define DC_USEIOSPACE 132 133#include <dev/dc/if_dcreg.h> --- 11 unchanged lines hidden (view full) --- 145 * "device miibus" is required in kernel config. See GENERIC if you get 146 * errors here. 147 */ 148#include "miibus_if.h" 149 150/* 151 * Various supported device vendors/types and their names. 152 */ |
152static const struct dc_type dc_devs[] = { | 153static const struct dc_type const dc_devs[] = { |
153 { DC_DEVID(DC_VENDORID_DEC, DC_DEVICEID_21143), 0, 154 "Intel 21143 10/100BaseTX" }, 155 { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9009), 0, 156 "Davicom DM9009 10/100BaseTX" }, 157 { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9100), 0, 158 "Davicom DM9100 10/100BaseTX" }, 159 { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9102), DC_REVISION_DM9102A, 160 "Davicom DM9102A 10/100BaseTX" }, --- 106 unchanged lines hidden (view full) --- 267static void dc_eeprom_idle(struct dc_softc *); 268static void dc_eeprom_putbyte(struct dc_softc *, int); 269static void dc_eeprom_getword(struct dc_softc *, int, uint16_t *); 270static void dc_eeprom_getword_pnic(struct dc_softc *, int, uint16_t *); 271static void dc_eeprom_getword_xircom(struct dc_softc *, int, uint16_t *); 272static void dc_eeprom_width(struct dc_softc *); 273static void dc_read_eeprom(struct dc_softc *, caddr_t, int, int, int); 274 | 154 { DC_DEVID(DC_VENDORID_DEC, DC_DEVICEID_21143), 0, 155 "Intel 21143 10/100BaseTX" }, 156 { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9009), 0, 157 "Davicom DM9009 10/100BaseTX" }, 158 { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9100), 0, 159 "Davicom DM9100 10/100BaseTX" }, 160 { DC_DEVID(DC_VENDORID_DAVICOM, DC_DEVICEID_DM9102), DC_REVISION_DM9102A, 161 "Davicom DM9102A 10/100BaseTX" }, --- 106 unchanged lines hidden (view full) --- 268static void dc_eeprom_idle(struct dc_softc *); 269static void dc_eeprom_putbyte(struct dc_softc *, int); 270static void dc_eeprom_getword(struct dc_softc *, int, uint16_t *); 271static void dc_eeprom_getword_pnic(struct dc_softc *, int, uint16_t *); 272static void dc_eeprom_getword_xircom(struct dc_softc *, int, uint16_t *); 273static void dc_eeprom_width(struct dc_softc *); 274static void dc_read_eeprom(struct dc_softc *, caddr_t, int, int, int); 275 |
275static void dc_mii_writebit(struct dc_softc *, int); 276static int dc_mii_readbit(struct dc_softc *); 277static void dc_mii_sync(struct dc_softc *); 278static void dc_mii_send(struct dc_softc *, uint32_t, int); 279static int dc_mii_readreg(struct dc_softc *, struct dc_mii_frame *); 280static int dc_mii_writereg(struct dc_softc *, struct dc_mii_frame *); | |
281static int dc_miibus_readreg(device_t, int, int); 282static int dc_miibus_writereg(device_t, int, int, int); 283static void dc_miibus_statchg(device_t); 284static void dc_miibus_mediainit(device_t); 285 286static void dc_setcfg(struct dc_softc *, int); 287static void dc_netcfg_wait(struct dc_softc *); 288static uint32_t dc_mchash_le(struct dc_softc *, const uint8_t *); --- 13 unchanged lines hidden (view full) --- 302static int dc_read_srom(struct dc_softc *, int); 303static int dc_parse_21143_srom(struct dc_softc *); 304static int dc_decode_leaf_sia(struct dc_softc *, struct dc_eblock_sia *); 305static int dc_decode_leaf_mii(struct dc_softc *, struct dc_eblock_mii *); 306static int dc_decode_leaf_sym(struct dc_softc *, struct dc_eblock_sym *); 307static void dc_apply_fixup(struct dc_softc *, int); 308static int dc_check_multiport(struct dc_softc *); 309 | 276static int dc_miibus_readreg(device_t, int, int); 277static int dc_miibus_writereg(device_t, int, int, int); 278static void dc_miibus_statchg(device_t); 279static void dc_miibus_mediainit(device_t); 280 281static void dc_setcfg(struct dc_softc *, int); 282static void dc_netcfg_wait(struct dc_softc *); 283static uint32_t dc_mchash_le(struct dc_softc *, const uint8_t *); --- 13 unchanged lines hidden (view full) --- 297static int dc_read_srom(struct dc_softc *, int); 298static int dc_parse_21143_srom(struct dc_softc *); 299static int dc_decode_leaf_sia(struct dc_softc *, struct dc_eblock_sia *); 300static int dc_decode_leaf_mii(struct dc_softc *, struct dc_eblock_mii *); 301static int dc_decode_leaf_sym(struct dc_softc *, struct dc_eblock_sym *); 302static void dc_apply_fixup(struct dc_softc *, int); 303static int dc_check_multiport(struct dc_softc *); 304 |
305/* 306 * MII bit-bang glue 307 */ 308static uint32_t dc_mii_bitbang_read(device_t); 309static void dc_mii_bitbang_write(device_t, uint32_t); 310 311static const struct mii_bitbang_ops dc_mii_bitbang_ops = { 312 dc_mii_bitbang_read, 313 dc_mii_bitbang_write, 314 { 315 DC_SIO_MII_DATAOUT, /* MII_BIT_MDO */ 316 DC_SIO_MII_DATAIN, /* MII_BIT_MDI */ 317 DC_SIO_MII_CLK, /* MII_BIT_MDC */ 318 0, /* MII_BIT_DIR_HOST_PHY */ 319 DC_SIO_MII_DIR, /* MII_BIT_DIR_PHY_HOST */ 320 } 321}; 322 |
|
310#ifdef DC_USEIOSPACE 311#define DC_RES SYS_RES_IOPORT 312#define DC_RID DC_PCI_CFBIO 313#else 314#define DC_RES SYS_RES_MEMORY 315#define DC_RID DC_PCI_CFBMA 316#endif 317 --- 288 unchanged lines hidden (view full) --- 606 if (be) 607 *ptr = be16toh(word); 608 else 609 *ptr = le16toh(word); 610 } 611} 612 613/* | 323#ifdef DC_USEIOSPACE 324#define DC_RES SYS_RES_IOPORT 325#define DC_RID DC_PCI_CFBIO 326#else 327#define DC_RES SYS_RES_MEMORY 328#define DC_RID DC_PCI_CFBMA 329#endif 330 --- 288 unchanged lines hidden (view full) --- 619 if (be) 620 *ptr = be16toh(word); 621 else 622 *ptr = le16toh(word); 623 } 624} 625 626/* |
614 * The following two routines are taken from the Macronix 98713 615 * Application Notes pp.19-21. | 627 * Write the MII serial port for the MII bit-bang module. |
616 */ | 628 */ |
617/* 618 * Write a bit to the MII bus. 619 */ | |
620static void | 629static void |
621dc_mii_writebit(struct dc_softc *sc, int bit) | 630dc_mii_bitbang_write(device_t dev, uint32_t val) |
622{ | 631{ |
623 uint32_t reg; | 632 struct dc_softc *sc; |
624 | 633 |
625 reg = DC_SIO_ROMCTL_WRITE | (bit != 0 ? DC_SIO_MII_DATAOUT : 0); 626 CSR_WRITE_4(sc, DC_SIO, reg); 627 CSR_BARRIER_4(sc, DC_SIO, 628 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 629 DELAY(1); | 634 sc = device_get_softc(dev); |
630 | 635 |
631 CSR_WRITE_4(sc, DC_SIO, reg | DC_SIO_MII_CLK); | 636 CSR_WRITE_4(sc, DC_SIO, val); |
632 CSR_BARRIER_4(sc, DC_SIO, 633 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); | 637 CSR_BARRIER_4(sc, DC_SIO, 638 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); |
634 DELAY(1); 635 CSR_WRITE_4(sc, DC_SIO, reg); 636 CSR_BARRIER_4(sc, DC_SIO, 637 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 638 DELAY(1); | |
639} 640 641/* | 639} 640 641/* |
642 * Read a bit from the MII bus. | 642 * Read the MII serial port for the MII bit-bang module. |
643 */ | 643 */ |
644static int 645dc_mii_readbit(struct dc_softc *sc) | 644static uint32_t 645dc_mii_bitbang_read(device_t dev) |
646{ | 646{ |
647 uint32_t reg; | 647 struct dc_softc *sc; 648 uint32_t val; |
648 | 649 |
649 reg = DC_SIO_ROMCTL_READ | DC_SIO_MII_DIR; 650 CSR_WRITE_4(sc, DC_SIO, reg); 651 CSR_BARRIER_4(sc, DC_SIO, 652 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 653 DELAY(1); 654 (void)CSR_READ_4(sc, DC_SIO); 655 CSR_WRITE_4(sc, DC_SIO, reg | DC_SIO_MII_CLK); 656 CSR_BARRIER_4(sc, DC_SIO, 657 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 658 DELAY(1); 659 CSR_WRITE_4(sc, DC_SIO, reg); 660 CSR_BARRIER_4(sc, DC_SIO, 661 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); 662 DELAY(1); 663 if (CSR_READ_4(sc, DC_SIO) & DC_SIO_MII_DATAIN) 664 return (1); | 650 sc = device_get_softc(dev); |
665 | 651 |
666 return (0); 667} 668 669/* 670 * Sync the PHYs by setting data bit and strobing the clock 32 times. 671 */ 672static void 673dc_mii_sync(struct dc_softc *sc) 674{ 675 int i; 676 677 CSR_WRITE_4(sc, DC_SIO, DC_SIO_ROMCTL_WRITE); | 652 val = CSR_READ_4(sc, DC_SIO); |
678 CSR_BARRIER_4(sc, DC_SIO, 679 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); | 653 CSR_BARRIER_4(sc, DC_SIO, 654 BUS_SPACE_BARRIER_READ | BUS_SPACE_BARRIER_WRITE); |
680 DELAY(1); | |
681 | 655 |
682 for (i = 0; i < 32; i++) 683 dc_mii_writebit(sc, 1); | 656 return (val); |
684} 685 | 657} 658 |
686/* 687 * Clock a series of bits through the MII. 688 */ 689static void 690dc_mii_send(struct dc_softc *sc, uint32_t bits, int cnt) 691{ 692 int i; 693 694 for (i = (0x1 << (cnt - 1)); i; i >>= 1) 695 dc_mii_writebit(sc, bits & i); 696} 697 698/* 699 * Read an PHY register through the MII. 700 */ | |
701static int | 659static int |
702dc_mii_readreg(struct dc_softc *sc, struct dc_mii_frame *frame) 703{ 704 int i; 705 706 /* 707 * Set up frame for RX. 708 */ 709 frame->mii_stdelim = DC_MII_STARTDELIM; 710 frame->mii_opcode = DC_MII_READOP; 711 712 /* 713 * Sync the PHYs. 714 */ 715 dc_mii_sync(sc); 716 717 /* 718 * Send command/address info. 719 */ 720 dc_mii_send(sc, frame->mii_stdelim, 2); 721 dc_mii_send(sc, frame->mii_opcode, 2); 722 dc_mii_send(sc, frame->mii_phyaddr, 5); 723 dc_mii_send(sc, frame->mii_regaddr, 5); 724 725 /* 726 * Now try reading data bits. If the turnaround failed, we still 727 * need to clock through 16 cycles to keep the PHY(s) in sync. 728 */ 729 frame->mii_turnaround = dc_mii_readbit(sc); 730 if (frame->mii_turnaround != 0) { 731 for (i = 0; i < 16; i++) 732 dc_mii_readbit(sc); 733 goto fail; 734 } 735 for (i = 0x8000; i; i >>= 1) { 736 if (dc_mii_readbit(sc)) 737 frame->mii_data |= i; 738 } 739 740fail: 741 742 /* Clock the idle bits. */ 743 dc_mii_writebit(sc, 0); 744 dc_mii_writebit(sc, 0); 745 746 if (frame->mii_turnaround != 0) 747 return (1); 748 return (0); 749} 750 751/* 752 * Write to a PHY register through the MII. 753 */ 754static int 755dc_mii_writereg(struct dc_softc *sc, struct dc_mii_frame *frame) 756{ 757 758 /* 759 * Set up frame for TX. 760 */ 761 frame->mii_stdelim = DC_MII_STARTDELIM; 762 frame->mii_opcode = DC_MII_WRITEOP; 763 frame->mii_turnaround = DC_MII_TURNAROUND; 764 765 /* 766 * Sync the PHYs. 767 */ 768 dc_mii_sync(sc); 769 770 dc_mii_send(sc, frame->mii_stdelim, 2); 771 dc_mii_send(sc, frame->mii_opcode, 2); 772 dc_mii_send(sc, frame->mii_phyaddr, 5); 773 dc_mii_send(sc, frame->mii_regaddr, 5); 774 dc_mii_send(sc, frame->mii_turnaround, 2); 775 dc_mii_send(sc, frame->mii_data, 16); 776 777 /* Clock the idle bits. */ 778 dc_mii_writebit(sc, 0); 779 dc_mii_writebit(sc, 0); 780 781 return (0); 782} 783 784static int | |
785dc_miibus_readreg(device_t dev, int phy, int reg) 786{ | 660dc_miibus_readreg(device_t dev, int phy, int reg) 661{ |
787 struct dc_mii_frame frame; 788 struct dc_softc *sc; | 662 struct dc_softc *sc; |
789 int i, rval, phy_reg = 0; 790 791 sc = device_get_softc(dev); | 663 int i, rval, phy_reg = 0; 664 665 sc = device_get_softc(dev); |
792 bzero(&frame, sizeof(frame)); | |
793 794 if (sc->dc_pmode != DC_PMODE_MII) { 795 if (phy == (MII_NPHY - 1)) { 796 switch (reg) { 797 case MII_BMSR: 798 /* 799 * Fake something to make the probe 800 * code think there's a PHY here. --- 75 unchanged lines hidden (view full) --- 876 default: 877 device_printf(dev, "phy_read: bad phy register %x\n", 878 reg); 879 return (0); 880 break; 881 } 882 883 rval = CSR_READ_4(sc, phy_reg) & 0x0000FFFF; | 666 667 if (sc->dc_pmode != DC_PMODE_MII) { 668 if (phy == (MII_NPHY - 1)) { 669 switch (reg) { 670 case MII_BMSR: 671 /* 672 * Fake something to make the probe 673 * code think there's a PHY here. --- 75 unchanged lines hidden (view full) --- 749 default: 750 device_printf(dev, "phy_read: bad phy register %x\n", 751 reg); 752 return (0); 753 break; 754 } 755 756 rval = CSR_READ_4(sc, phy_reg) & 0x0000FFFF; |
884 | |
885 if (rval == 0xFFFF) 886 return (0); 887 return (rval); 888 } 889 | 757 if (rval == 0xFFFF) 758 return (0); 759 return (rval); 760 } 761 |
890 frame.mii_phyaddr = phy; 891 frame.mii_regaddr = reg; | |
892 if (sc->dc_type == DC_TYPE_98713) { 893 phy_reg = CSR_READ_4(sc, DC_NETCFG); 894 CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL); 895 } | 762 if (sc->dc_type == DC_TYPE_98713) { 763 phy_reg = CSR_READ_4(sc, DC_NETCFG); 764 CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL); 765 } |
896 dc_mii_readreg(sc, &frame); | 766 rval = mii_bitbang_readreg(dev, &dc_mii_bitbang_ops, phy, reg); |
897 if (sc->dc_type == DC_TYPE_98713) 898 CSR_WRITE_4(sc, DC_NETCFG, phy_reg); 899 | 767 if (sc->dc_type == DC_TYPE_98713) 768 CSR_WRITE_4(sc, DC_NETCFG, phy_reg); 769 |
900 return (frame.mii_data); | 770 return (rval); |
901} 902 903static int 904dc_miibus_writereg(device_t dev, int phy, int reg, int data) 905{ 906 struct dc_softc *sc; | 771} 772 773static int 774dc_miibus_writereg(device_t dev, int phy, int reg, int data) 775{ 776 struct dc_softc *sc; |
907 struct dc_mii_frame frame; | |
908 int i, phy_reg = 0; 909 910 sc = device_get_softc(dev); | 777 int i, phy_reg = 0; 778 779 sc = device_get_softc(dev); |
911 bzero(&frame, sizeof(frame)); | |
912 913 if (DC_IS_PNIC(sc)) { 914 CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE | 915 (phy << 23) | (reg << 10) | data); 916 for (i = 0; i < DC_TIMEOUT; i++) { 917 if (!(CSR_READ_4(sc, DC_PN_MII) & DC_PN_MII_BUSY)) 918 break; 919 } --- 39 unchanged lines hidden (view full) --- 959 return (0); 960 break; 961 } 962 963 CSR_WRITE_4(sc, phy_reg, data); 964 return (0); 965 } 966 | 780 781 if (DC_IS_PNIC(sc)) { 782 CSR_WRITE_4(sc, DC_PN_MII, DC_PN_MIIOPCODE_WRITE | 783 (phy << 23) | (reg << 10) | data); 784 for (i = 0; i < DC_TIMEOUT; i++) { 785 if (!(CSR_READ_4(sc, DC_PN_MII) & DC_PN_MII_BUSY)) 786 break; 787 } --- 39 unchanged lines hidden (view full) --- 827 return (0); 828 break; 829 } 830 831 CSR_WRITE_4(sc, phy_reg, data); 832 return (0); 833 } 834 |
967 frame.mii_phyaddr = phy; 968 frame.mii_regaddr = reg; 969 frame.mii_data = data; 970 | |
971 if (sc->dc_type == DC_TYPE_98713) { 972 phy_reg = CSR_READ_4(sc, DC_NETCFG); 973 CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL); 974 } | 835 if (sc->dc_type == DC_TYPE_98713) { 836 phy_reg = CSR_READ_4(sc, DC_NETCFG); 837 CSR_WRITE_4(sc, DC_NETCFG, phy_reg & ~DC_NETCFG_PORTSEL); 838 } |
975 dc_mii_writereg(sc, &frame); | 839 mii_bitbang_writereg(dev, &dc_mii_bitbang_ops, phy, reg, data); |
976 if (sc->dc_type == DC_TYPE_98713) 977 CSR_WRITE_4(sc, DC_NETCFG, phy_reg); 978 979 return (0); 980} 981 982static void 983dc_miibus_statchg(device_t dev) --- 3309 unchanged lines hidden --- | 840 if (sc->dc_type == DC_TYPE_98713) 841 CSR_WRITE_4(sc, DC_NETCFG, phy_reg); 842 843 return (0); 844} 845 846static void 847dc_miibus_statchg(device_t dev) --- 3309 unchanged lines hidden --- |