if_ed.c (72193) | if_ed.c (73374) |
---|---|
1/* 2 * Copyright (c) 1995, David Greenman 3 * 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 --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * | 1/* 2 * Copyright (c) 1995, David Greenman 3 * 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 --- 10 unchanged lines hidden (view full) --- 19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25 * SUCH DAMAGE. 26 * |
27 * $FreeBSD: head/sys/dev/ed/if_ed.c 72193 2001-02-08 22:54:57Z luigi $ | 27 * $FreeBSD: head/sys/dev/ed/if_ed.c 73374 2001-03-03 08:31:37Z imp $ |
28 */ 29 30/* 31 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 32 * adapters. By David Greenman, 29-April-1993 33 * 34 * Currently supports the Western Digital/SMC 8003 and 8013 series, 35 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000, 36 * and a variety of similar clones. 37 * 38 */ 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/sockio.h> 43#include <sys/mbuf.h> | 28 */ 29 30/* 31 * Device driver for National Semiconductor DS8390/WD83C690 based ethernet 32 * adapters. By David Greenman, 29-April-1993 33 * 34 * Currently supports the Western Digital/SMC 8003 and 8013 series, 35 * the SMC Elite Ultra (8216), the 3Com 3c503, the NE1000 and NE2000, 36 * and a variety of similar clones. 37 * 38 */ 39 40#include <sys/param.h> 41#include <sys/systm.h> 42#include <sys/sockio.h> 43#include <sys/mbuf.h> |
44#include <sys/kernel.h> |
|
44#include <sys/socket.h> 45#include <sys/syslog.h> 46 47#include <sys/bus.h> 48 49#include <machine/bus.h> 50#include <sys/rman.h> 51#include <machine/resource.h> 52 53#include <net/ethernet.h> 54#include <net/if.h> 55#include <net/if_arp.h> 56#include <net/if_dl.h> 57#include <net/if_mib.h> | 45#include <sys/socket.h> 46#include <sys/syslog.h> 47 48#include <sys/bus.h> 49 50#include <machine/bus.h> 51#include <sys/rman.h> 52#include <machine/resource.h> 53 54#include <net/ethernet.h> 55#include <net/if.h> 56#include <net/if_arp.h> 57#include <net/if_dl.h> 58#include <net/if_mib.h> |
59#include <net/if_media.h> |
|
58 | 60 |
61#include <dev/mii/mii.h> 62#include <dev/mii/miivar.h> 63 |
|
59#include <net/bpf.h> 60#include "opt_bdg.h" 61#ifdef BRIDGE 62#include <net/bridge.h> 63#endif 64 65#include <machine/md_var.h> 66 67#include <dev/ed/if_edreg.h> 68#include <dev/ed/if_edvar.h> 69 70devclass_t ed_devclass; 71 72static void ed_init __P((void *)); 73static int ed_ioctl __P((struct ifnet *, u_long, caddr_t)); 74static void ed_start __P((struct ifnet *)); 75static void ed_reset __P((struct ifnet *)); 76static void ed_watchdog __P((struct ifnet *)); | 64#include <net/bpf.h> 65#include "opt_bdg.h" 66#ifdef BRIDGE 67#include <net/bridge.h> 68#endif 69 70#include <machine/md_var.h> 71 72#include <dev/ed/if_edreg.h> 73#include <dev/ed/if_edvar.h> 74 75devclass_t ed_devclass; 76 77static void ed_init __P((void *)); 78static int ed_ioctl __P((struct ifnet *, u_long, caddr_t)); 79static void ed_start __P((struct ifnet *)); 80static void ed_reset __P((struct ifnet *)); 81static void ed_watchdog __P((struct ifnet *)); |
82static void ed_tick __P((void *)); |
|
77 78static void ds_getmcaf __P((struct ed_softc *, u_int32_t *)); 79 80static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int)); 81 82static __inline void ed_rint __P((struct ed_softc *)); 83static __inline void ed_xmit __P((struct ed_softc *)); 84static __inline char * ed_ring_copy __P((struct ed_softc *, char *, char *, --- 1496 unchanged lines hidden (view full) --- 1581int 1582ed_attach(sc, unit, flags) 1583 struct ed_softc *sc; 1584 int unit; 1585 int flags; 1586{ 1587 struct ifnet *ifp = &sc->arpcom.ac_if; 1588 | 83 84static void ds_getmcaf __P((struct ed_softc *, u_int32_t *)); 85 86static void ed_get_packet __P((struct ed_softc *, char *, /* u_short */ int)); 87 88static __inline void ed_rint __P((struct ed_softc *)); 89static __inline void ed_xmit __P((struct ed_softc *)); 90static __inline char * ed_ring_copy __P((struct ed_softc *, char *, char *, --- 1496 unchanged lines hidden (view full) --- 1587int 1588ed_attach(sc, unit, flags) 1589 struct ed_softc *sc; 1590 int unit; 1591 int flags; 1592{ 1593 struct ifnet *ifp = &sc->arpcom.ac_if; 1594 |
1595 callout_handle_init(&sc->tick_ch); |
|
1589 /* 1590 * Set interface to stopped condition (reset) 1591 */ 1592 ed_stop(sc); 1593 1594 if (!ifp->if_name) { 1595 /* 1596 * Initialize ifnet structure --- 93 unchanged lines hidden (view full) --- 1690 * Take interface offline. 1691 */ 1692void 1693ed_stop(sc) 1694 struct ed_softc *sc; 1695{ 1696 int n = 5000; 1697 | 1596 /* 1597 * Set interface to stopped condition (reset) 1598 */ 1599 ed_stop(sc); 1600 1601 if (!ifp->if_name) { 1602 /* 1603 * Initialize ifnet structure --- 93 unchanged lines hidden (view full) --- 1697 * Take interface offline. 1698 */ 1699void 1700ed_stop(sc) 1701 struct ed_softc *sc; 1702{ 1703 int n = 5000; 1704 |
1705 untimeout(ed_tick, sc, sc->tick_ch); 1706 callout_handle_init(&sc->tick_ch); |
|
1698 if (sc->gone) 1699 return; 1700 /* 1701 * Stop everything on the interface, and select page 0 registers. 1702 */ 1703 ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_STP); 1704 1705 /* --- 18 unchanged lines hidden (view full) --- 1724 if (sc->gone) 1725 return; 1726 log(LOG_ERR, "ed%d: device timeout\n", ifp->if_unit); 1727 ifp->if_oerrors++; 1728 1729 ed_reset(ifp); 1730} 1731 | 1707 if (sc->gone) 1708 return; 1709 /* 1710 * Stop everything on the interface, and select page 0 registers. 1711 */ 1712 ed_nic_outb(sc, ED_P0_CR, sc->cr_proto | ED_CR_STP); 1713 1714 /* --- 18 unchanged lines hidden (view full) --- 1733 if (sc->gone) 1734 return; 1735 log(LOG_ERR, "ed%d: device timeout\n", ifp->if_unit); 1736 ifp->if_oerrors++; 1737 1738 ed_reset(ifp); 1739} 1740 |
1741static void 1742ed_tick(arg) 1743 void *arg; 1744{ 1745 struct ed_softc *sc = arg; 1746 struct mii_data *mii; 1747 int s; 1748 1749 if (sc->gone) { 1750 callout_handle_init(&sc->tick_ch); 1751 return; 1752 } 1753 s = splimp(); 1754 if (sc->miibus != NULL) { 1755 mii = device_get_softc(sc->miibus); 1756 mii_tick(mii); 1757 } 1758 sc->tick_ch = timeout(ed_tick, sc, hz); 1759 splx(s); 1760} 1761 |
|
1732/* 1733 * Initialize device. 1734 */ 1735static void 1736ed_init(xsc) 1737 void *xsc; 1738{ 1739 struct ed_softc *sc = xsc; --- 125 unchanged lines hidden (view full) --- 1865 if (sc->vendor == ED_VENDOR_3COM) { 1866 if (ifp->if_flags & IFF_ALTPHYS) { 1867 ed_asic_outb(sc, ED_3COM_CR, 0); 1868 } else { 1869 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 1870 } 1871 } 1872 | 1762/* 1763 * Initialize device. 1764 */ 1765static void 1766ed_init(xsc) 1767 void *xsc; 1768{ 1769 struct ed_softc *sc = xsc; --- 125 unchanged lines hidden (view full) --- 1895 if (sc->vendor == ED_VENDOR_3COM) { 1896 if (ifp->if_flags & IFF_ALTPHYS) { 1897 ed_asic_outb(sc, ED_3COM_CR, 0); 1898 } else { 1899 ed_asic_outb(sc, ED_3COM_CR, ED_3COM_CR_XSEL); 1900 } 1901 } 1902 |
1903 if (sc->miibus != NULL) { 1904 struct mii_data *mii; 1905 mii = device_get_softc(sc->miibus); 1906 mii_mediachg(mii); 1907 } |
|
1873 /* 1874 * Set 'running' flag, and clear output active flag. 1875 */ 1876 ifp->if_flags |= IFF_RUNNING; 1877 ifp->if_flags &= ~IFF_OACTIVE; 1878 1879 /* 1880 * ...and attempt to start output 1881 */ 1882 ed_start(ifp); 1883 | 1908 /* 1909 * Set 'running' flag, and clear output active flag. 1910 */ 1911 ifp->if_flags |= IFF_RUNNING; 1912 ifp->if_flags &= ~IFF_OACTIVE; 1913 1914 /* 1915 * ...and attempt to start output 1916 */ 1917 ed_start(ifp); 1918 |
1919 untimeout(ed_tick, sc, sc->tick_ch); 1920 sc->tick_ch = timeout(ed_tick, sc, hz); |
|
1884 (void) splx(s); 1885} 1886 1887/* 1888 * This routine actually starts the transmission on the interface 1889 */ 1890static __inline void 1891ed_xmit(sc) --- 595 unchanged lines hidden (view full) --- 2487 */ 2488static int 2489ed_ioctl(ifp, command, data) 2490 register struct ifnet *ifp; 2491 u_long command; 2492 caddr_t data; 2493{ 2494 struct ed_softc *sc = ifp->if_softc; | 1921 (void) splx(s); 1922} 1923 1924/* 1925 * This routine actually starts the transmission on the interface 1926 */ 1927static __inline void 1928ed_xmit(sc) --- 595 unchanged lines hidden (view full) --- 2524 */ 2525static int 2526ed_ioctl(ifp, command, data) 2527 register struct ifnet *ifp; 2528 u_long command; 2529 caddr_t data; 2530{ 2531 struct ed_softc *sc = ifp->if_softc; |
2532 struct ifreq *ifr = (struct ifreq *)data; 2533 struct mii_data *mii; |
|
2495 int s, error = 0; 2496 2497 if (sc == NULL || sc->gone) { 2498 ifp->if_flags &= ~IFF_RUNNING; 2499 return ENXIO; 2500 } 2501 s = splimp(); 2502 --- 46 unchanged lines hidden (view full) --- 2549 /* 2550 * Multicast list has changed; set the hardware filter 2551 * accordingly. 2552 */ 2553 ed_setrcr(sc); 2554 error = 0; 2555 break; 2556 | 2534 int s, error = 0; 2535 2536 if (sc == NULL || sc->gone) { 2537 ifp->if_flags &= ~IFF_RUNNING; 2538 return ENXIO; 2539 } 2540 s = splimp(); 2541 --- 46 unchanged lines hidden (view full) --- 2588 /* 2589 * Multicast list has changed; set the hardware filter 2590 * accordingly. 2591 */ 2592 ed_setrcr(sc); 2593 error = 0; 2594 break; 2595 |
2596 case SIOCGIFMEDIA: 2597 case SIOCSIFMEDIA: 2598 if (sc->miibus == NULL) { 2599 error = EINVAL; 2600 break; 2601 } 2602 mii = device_get_softc(sc->miibus); 2603 error = ifmedia_ioctl(ifp, ifr, &mii->mii_media, command); 2604 break; 2605 |
|
2557 default: 2558 error = EINVAL; 2559 } 2560 (void) splx(s); 2561 return (error); 2562} 2563 2564/* --- 603 unchanged lines hidden (view full) --- 3168 } 3169 3170 if (sc->hpp_mem_start) /* turn off memory mapped i/o */ 3171 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options); 3172 3173 return (total_len); 3174} 3175 | 2606 default: 2607 error = EINVAL; 2608 } 2609 (void) splx(s); 2610 return (error); 2611} 2612 2613/* --- 603 unchanged lines hidden (view full) --- 3217 } 3218 3219 if (sc->hpp_mem_start) /* turn off memory mapped i/o */ 3220 ed_asic_outw(sc, ED_HPP_OPTION, sc->hpp_options); 3221 3222 return (total_len); 3223} 3224 |
3225/* 3226 * MII bus support routines. 3227 */ 3228int 3229ed_miibus_readreg(dev, phy, reg) 3230 device_t dev; 3231 int phy, reg; 3232{ 3233 struct ed_softc *sc; 3234 int val; 3235 int failed; 3236 3237 sc = device_get_softc(dev); 3238 if (sc->gone) 3239 return 0; 3240 3241 (*sc->mii_writebits)(sc, 0xffffffff, 32); 3242 (*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS); 3243 (*sc->mii_writebits)(sc, ED_MII_READOP, ED_MII_OP_BITS); 3244 (*sc->mii_writebits)(sc, phy, ED_MII_PHY_BITS); 3245 (*sc->mii_writebits)(sc, reg, ED_MII_REG_BITS); 3246 3247 failed = (*sc->mii_readbits)(sc, ED_MII_ACK_BITS); 3248 val = (*sc->mii_readbits)(sc, ED_MII_DATA_BITS); 3249 (*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS); 3250 3251 return (failed ? 0 : val); 3252} 3253 3254void 3255ed_miibus_writereg(dev, phy, reg, data) 3256 device_t dev; 3257 int phy, reg, data; 3258{ 3259 struct ed_softc *sc; 3260 3261 sc = device_get_softc(dev); 3262 if (sc->gone) 3263 return; 3264 3265 (*sc->mii_writebits)(sc, 0xffffffff, 32); 3266 (*sc->mii_writebits)(sc, ED_MII_STARTDELIM, ED_MII_STARTDELIM_BITS); 3267 (*sc->mii_writebits)(sc, ED_MII_WRITEOP, ED_MII_OP_BITS); 3268 (*sc->mii_writebits)(sc, phy, ED_MII_PHY_BITS); 3269 (*sc->mii_writebits)(sc, reg, ED_MII_REG_BITS); 3270 (*sc->mii_writebits)(sc, ED_MII_TURNAROUND, ED_MII_TURNAROUND_BITS); 3271 (*sc->mii_writebits)(sc, data, ED_MII_DATA_BITS); 3272 (*sc->mii_writebits)(sc, ED_MII_IDLE, ED_MII_IDLE_BITS); 3273} 3274 3275int 3276ed_ifmedia_upd(ifp) 3277 struct ifnet *ifp; 3278{ 3279 struct ed_softc *sc; 3280 struct mii_data *mii; 3281 3282 sc = ifp->if_softc; 3283 if (sc->gone || sc->miibus == NULL) 3284 return (ENXIO); 3285 3286 mii = device_get_softc(sc->miibus); 3287 return mii_mediachg(mii); 3288} 3289 3290void 3291ed_ifmedia_sts(ifp, ifmr) 3292 struct ifnet *ifp; 3293 struct ifmediareq *ifmr; 3294{ 3295 struct ed_softc *sc; 3296 struct mii_data *mii; 3297 3298 sc = ifp->if_softc; 3299 if (sc->gone || sc->miibus == NULL) 3300 return; 3301 3302 mii = device_get_softc(sc->miibus); 3303 mii_pollstat(mii); 3304 ifmr->ifm_active = mii->mii_media_active; 3305 ifmr->ifm_status = mii->mii_media_status; 3306} 3307 3308void 3309ed_child_detached(dev, child) 3310 device_t dev; 3311 device_t child; 3312{ 3313 struct ed_softc *sc; 3314 3315 sc = device_get_softc(dev); 3316 if (child == sc->miibus) 3317 sc->miibus = NULL; 3318} 3319 |
|
3176static void 3177ed_setrcr(sc) 3178 struct ed_softc *sc; 3179{ 3180 struct ifnet *ifp = (struct ifnet *)sc; 3181 int i; 3182 u_char reg1; 3183 --- 119 unchanged lines hidden --- | 3320static void 3321ed_setrcr(sc) 3322 struct ed_softc *sc; 3323{ 3324 struct ifnet *ifp = (struct ifnet *)sc; 3325 int i; 3326 u_char reg1; 3327 --- 119 unchanged lines hidden --- |