1 1.154 rin /* $NetBSD: elink3.c,v 1.154 2024/07/05 04:31:51 rin Exp $ */ 2 1.41 thorpej 3 1.41 thorpej /*- 4 1.93 jdolecek * Copyright (c) 1998, 2001 The NetBSD Foundation, Inc. 5 1.41 thorpej * All rights reserved. 6 1.41 thorpej * 7 1.41 thorpej * This code is derived from software contributed to The NetBSD Foundation 8 1.41 thorpej * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 9 1.41 thorpej * NASA Ames Research Center. 10 1.41 thorpej * 11 1.41 thorpej * Redistribution and use in source and binary forms, with or without 12 1.41 thorpej * modification, are permitted provided that the following conditions 13 1.41 thorpej * are met: 14 1.41 thorpej * 1. Redistributions of source code must retain the above copyright 15 1.41 thorpej * notice, this list of conditions and the following disclaimer. 16 1.41 thorpej * 2. Redistributions in binary form must reproduce the above copyright 17 1.41 thorpej * notice, this list of conditions and the following disclaimer in the 18 1.41 thorpej * documentation and/or other materials provided with the distribution. 19 1.41 thorpej * 20 1.41 thorpej * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 21 1.41 thorpej * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 22 1.41 thorpej * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 23 1.41 thorpej * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 24 1.41 thorpej * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 25 1.41 thorpej * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 26 1.41 thorpej * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 27 1.41 thorpej * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 28 1.41 thorpej * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 29 1.41 thorpej * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 30 1.41 thorpej * POSSIBILITY OF SUCH DAMAGE. 31 1.41 thorpej */ 32 1.1 thorpej 33 1.1 thorpej /* 34 1.19 jonathan * Copyright (c) 1996, 1997 Jonathan Stone <jonathan (at) NetBSD.org> 35 1.6 thorpej * Copyright (c) 1994 Herb Peyerl <hpeyerl (at) beer.org> 36 1.1 thorpej * All rights reserved. 37 1.1 thorpej * 38 1.1 thorpej * Redistribution and use in source and binary forms, with or without 39 1.1 thorpej * modification, are permitted provided that the following conditions 40 1.1 thorpej * are met: 41 1.1 thorpej * 1. Redistributions of source code must retain the above copyright 42 1.1 thorpej * notice, this list of conditions and the following disclaimer. 43 1.1 thorpej * 2. Redistributions in binary form must reproduce the above copyright 44 1.1 thorpej * notice, this list of conditions and the following disclaimer in the 45 1.1 thorpej * documentation and/or other materials provided with the distribution. 46 1.1 thorpej * 3. All advertising materials mentioning features or use of this software 47 1.1 thorpej * must display the following acknowledgement: 48 1.1 thorpej * This product includes software developed by Herb Peyerl. 49 1.1 thorpej * 4. The name of Herb Peyerl may not be used to endorse or promote products 50 1.1 thorpej * derived from this software without specific prior written permission. 51 1.1 thorpej * 52 1.1 thorpej * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 53 1.1 thorpej * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 54 1.1 thorpej * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 55 1.1 thorpej * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 56 1.1 thorpej * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 57 1.1 thorpej * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 58 1.1 thorpej * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 59 1.1 thorpej * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 60 1.1 thorpej * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 61 1.1 thorpej * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 62 1.1 thorpej */ 63 1.100 lukem 64 1.100 lukem #include <sys/cdefs.h> 65 1.154 rin __KERNEL_RCSID(0, "$NetBSD: elink3.c,v 1.154 2024/07/05 04:31:51 rin Exp $"); 66 1.1 thorpej 67 1.39 jonathan #include "opt_inet.h" 68 1.1 thorpej 69 1.1 thorpej #include <sys/param.h> 70 1.3 christos #include <sys/systm.h> 71 1.78 thorpej #include <sys/callout.h> 72 1.41 thorpej #include <sys/kernel.h> 73 1.1 thorpej #include <sys/mbuf.h> 74 1.1 thorpej #include <sys/socket.h> 75 1.1 thorpej #include <sys/ioctl.h> 76 1.1 thorpej #include <sys/errno.h> 77 1.1 thorpej #include <sys/syslog.h> 78 1.1 thorpej #include <sys/select.h> 79 1.1 thorpej #include <sys/device.h> 80 1.136 riastrad #include <sys/rndsource.h> 81 1.1 thorpej 82 1.1 thorpej #include <net/if.h> 83 1.1 thorpej #include <net/if_dl.h> 84 1.21 is #include <net/if_ether.h> 85 1.22 jonathan #include <net/if_media.h> 86 1.1 thorpej #include <net/bpf.h> 87 1.1 thorpej 88 1.124 ad #include <sys/cpu.h> 89 1.124 ad #include <sys/bus.h> 90 1.124 ad #include <sys/intr.h> 91 1.1 thorpej 92 1.41 thorpej #include <dev/mii/mii.h> 93 1.41 thorpej #include <dev/mii/miivar.h> 94 1.67 thorpej #include <dev/mii/mii_bitbang.h> 95 1.41 thorpej 96 1.1 thorpej #include <dev/ic/elink3var.h> 97 1.1 thorpej #include <dev/ic/elink3reg.h> 98 1.1 thorpej 99 1.36 jonathan #ifdef DEBUG 100 1.36 jonathan int epdebug = 0; 101 1.36 jonathan #endif 102 1.36 jonathan 103 1.23 jonathan /* 104 1.55 jonathan * XXX endian workaround for big-endian CPUs with pcmcia: 105 1.55 jonathan * if stream methods for bus_space_multi are not provided, define them 106 1.55 jonathan * using non-stream bus_space_{read,write}_multi_. 107 1.55 jonathan * Assumes host CPU is same endian-ness as bus. 108 1.55 jonathan */ 109 1.55 jonathan #ifndef __BUS_SPACE_HAS_STREAM_METHODS 110 1.55 jonathan #define bus_space_read_multi_stream_2 bus_space_read_multi_2 111 1.55 jonathan #define bus_space_read_multi_stream_4 bus_space_read_multi_4 112 1.55 jonathan #define bus_space_write_multi_stream_2 bus_space_write_multi_2 113 1.55 jonathan #define bus_space_write_multi_stream_4 bus_space_write_multi_4 114 1.55 jonathan #endif /* __BUS_SPACE_HAS_STREAM_METHODS */ 115 1.55 jonathan 116 1.55 jonathan /* 117 1.41 thorpej * Structure to map media-present bits in boards to ifmedia codes and 118 1.41 thorpej * printable media names. Used for table-driven ifmedia initialization. 119 1.23 jonathan */ 120 1.23 jonathan struct ep_media { 121 1.41 thorpej int epm_mpbit; /* media present bit */ 122 1.41 thorpej const char *epm_name; /* name of medium */ 123 1.23 jonathan int epm_ifmedia; /* ifmedia word for medium */ 124 1.47 fvdl int epm_epmedia; /* ELINKMEDIA_* constant */ 125 1.23 jonathan }; 126 1.23 jonathan 127 1.23 jonathan /* 128 1.41 thorpej * Media table for the Demon/Vortex/Boomerang chipsets. 129 1.41 thorpej * 130 1.41 thorpej * Note that MII on the Demon and Vortex (3c59x) indicates an external 131 1.41 thorpej * MII connector (for connecting an external PHY) ... I think. Treat 132 1.41 thorpej * it as `manual' on these chips. 133 1.23 jonathan * 134 1.41 thorpej * Any Boomerang (3c90x) chips with MII really do have an internal 135 1.41 thorpej * MII and real PHYs attached; no `native' media. 136 1.23 jonathan */ 137 1.87 jdolecek const struct ep_media ep_vortex_media[] = { 138 1.149 msaitoh { ELINK_PCI_10BASE_T, "10baseT", IFM_ETHER | IFM_10_T, 139 1.47 fvdl ELINKMEDIA_10BASE_T }, 140 1.149 msaitoh { ELINK_PCI_10BASE_T, "10baseT-FDX", IFM_ETHER | IFM_10_T | IFM_FDX, 141 1.47 fvdl ELINKMEDIA_10BASE_T }, 142 1.149 msaitoh { ELINK_PCI_AUI, "10base5", IFM_ETHER | IFM_10_5, 143 1.47 fvdl ELINKMEDIA_AUI }, 144 1.149 msaitoh { ELINK_PCI_BNC, "10base2", IFM_ETHER | IFM_10_2, 145 1.47 fvdl ELINKMEDIA_10BASE_2 }, 146 1.149 msaitoh { ELINK_PCI_100BASE_TX, "100baseTX", IFM_ETHER | IFM_100_TX, 147 1.47 fvdl ELINKMEDIA_100BASE_TX }, 148 1.149 msaitoh { ELINK_PCI_100BASE_TX, "100baseTX-FDX",IFM_ETHER | IFM_100_TX|IFM_FDX, 149 1.47 fvdl ELINKMEDIA_100BASE_TX }, 150 1.149 msaitoh { ELINK_PCI_100BASE_FX, "100baseFX", IFM_ETHER | IFM_100_FX, 151 1.47 fvdl ELINKMEDIA_100BASE_FX }, 152 1.149 msaitoh { ELINK_PCI_100BASE_MII,"manual", IFM_ETHER | IFM_MANUAL, 153 1.47 fvdl ELINKMEDIA_MII }, 154 1.149 msaitoh { ELINK_PCI_100BASE_T4, "100baseT4", IFM_ETHER | IFM_100_T4, 155 1.47 fvdl ELINKMEDIA_100BASE_T4 }, 156 1.41 thorpej { 0, NULL, 0, 157 1.41 thorpej 0 }, 158 1.23 jonathan }; 159 1.23 jonathan 160 1.23 jonathan /* 161 1.41 thorpej * Media table for the older 3Com Etherlink III chipset, used 162 1.41 thorpej * in the 3c509, 3c579, and 3c589. 163 1.23 jonathan */ 164 1.87 jdolecek const struct ep_media ep_509_media[] = { 165 1.149 msaitoh { ELINK_W0_CC_UTP, "10baseT", IFM_ETHER | IFM_10_T, 166 1.47 fvdl ELINKMEDIA_10BASE_T }, 167 1.149 msaitoh { ELINK_W0_CC_AUI, "10base5", IFM_ETHER | IFM_10_5, 168 1.47 fvdl ELINKMEDIA_AUI }, 169 1.149 msaitoh { ELINK_W0_CC_BNC, "10base2", IFM_ETHER | IFM_10_2, 170 1.47 fvdl ELINKMEDIA_10BASE_2 }, 171 1.41 thorpej { 0, NULL, 0, 172 1.41 thorpej 0 }, 173 1.23 jonathan }; 174 1.23 jonathan 175 1.110 perry void ep_internalconfig(struct ep_softc *sc); 176 1.110 perry void ep_vortex_probemedia(struct ep_softc *sc); 177 1.110 perry void ep_509_probemedia(struct ep_softc *sc); 178 1.110 perry 179 1.110 perry static void eptxstat(struct ep_softc *); 180 1.110 perry static int epstatus(struct ep_softc *); 181 1.110 perry int epinit(struct ifnet *); 182 1.110 perry void epstop(struct ifnet *, int); 183 1.121 christos int epioctl(struct ifnet *, u_long, void *); 184 1.110 perry void epstart(struct ifnet *); 185 1.110 perry void epwatchdog(struct ifnet *); 186 1.110 perry void epreset(struct ep_softc *); 187 1.128 tsutsui static bool epshutdown(device_t, int); 188 1.110 perry void epread(struct ep_softc *); 189 1.110 perry struct mbuf *epget(struct ep_softc *, int); 190 1.110 perry void epmbuffill(void *); 191 1.110 perry void epmbufempty(struct ep_softc *); 192 1.110 perry void epsetfilter(struct ep_softc *); 193 1.110 perry void ep_roadrunner_mii_enable(struct ep_softc *); 194 1.110 perry void epsetmedia(struct ep_softc *); 195 1.23 jonathan 196 1.23 jonathan /* ifmedia callbacks */ 197 1.110 perry int ep_media_change(struct ifnet *ifp); 198 1.110 perry void ep_media_status(struct ifnet *ifp, struct ifmediareq *req); 199 1.1 thorpej 200 1.41 thorpej /* MII callbacks */ 201 1.144 msaitoh int ep_mii_readreg(device_t, int, int, uint16_t *); 202 1.144 msaitoh int ep_mii_writereg(device_t, int, int, uint16_t); 203 1.133 matt void ep_statchg(struct ifnet *); 204 1.110 perry 205 1.110 perry void ep_tick(void *); 206 1.110 perry 207 1.110 perry static int epbusyeeprom(struct ep_softc *); 208 1.110 perry u_int16_t ep_read_eeprom(struct ep_softc *, u_int16_t); 209 1.110 perry static inline void ep_reset_cmd(struct ep_softc *sc, u_int cmd, u_int arg); 210 1.110 perry static inline void ep_finish_reset(bus_space_tag_t, bus_space_handle_t); 211 1.110 perry static inline void ep_discard_rxtop(bus_space_tag_t, bus_space_handle_t); 212 1.114 perry static inline int ep_w1_reg(struct ep_softc *, int); 213 1.19 jonathan 214 1.42 thorpej /* 215 1.67 thorpej * MII bit-bang glue. 216 1.67 thorpej */ 217 1.127 christos u_int32_t ep_mii_bitbang_read(device_t); 218 1.127 christos void ep_mii_bitbang_write(device_t, u_int32_t); 219 1.67 thorpej 220 1.67 thorpej const struct mii_bitbang_ops ep_mii_bitbang_ops = { 221 1.67 thorpej ep_mii_bitbang_read, 222 1.67 thorpej ep_mii_bitbang_write, 223 1.67 thorpej { 224 1.67 thorpej PHYSMGMT_DATA, /* MII_BIT_MDO */ 225 1.67 thorpej PHYSMGMT_DATA, /* MII_BIT_MDI */ 226 1.67 thorpej PHYSMGMT_CLK, /* MII_BIT_MDC */ 227 1.67 thorpej PHYSMGMT_DIR, /* MII_BIT_DIR_HOST_PHY */ 228 1.67 thorpej 0, /* MII_BIT_DIR_PHY_HOST */ 229 1.67 thorpej } 230 1.67 thorpej }; 231 1.67 thorpej 232 1.67 thorpej /* 233 1.42 thorpej * Some chips (3c515 [Corkscrew] and 3c574 [RoadRunner]) have 234 1.42 thorpej * Window 1 registers offset! 235 1.42 thorpej */ 236 1.114 perry static inline int 237 1.127 christos ep_w1_reg(struct ep_softc *sc, int reg) 238 1.42 thorpej { 239 1.42 thorpej 240 1.42 thorpej switch (sc->ep_chipset) { 241 1.47 fvdl case ELINK_CHIPSET_CORKSCREW: 242 1.42 thorpej return (reg + 0x10); 243 1.42 thorpej 244 1.47 fvdl case ELINK_CHIPSET_ROADRUNNER: 245 1.42 thorpej switch (reg) { 246 1.47 fvdl case ELINK_W1_FREE_TX: 247 1.47 fvdl case ELINK_W1_RUNNER_RDCTL: 248 1.47 fvdl case ELINK_W1_RUNNER_WRCTL: 249 1.42 thorpej return (reg); 250 1.42 thorpej } 251 1.42 thorpej return (reg + 0x10); 252 1.42 thorpej } 253 1.42 thorpej 254 1.42 thorpej return (reg); 255 1.42 thorpej } 256 1.19 jonathan 257 1.19 jonathan /* 258 1.56 jonathan * Wait for any pending reset to complete. 259 1.19 jonathan * On newer hardware we could poll SC_COMMAND_IN_PROGRESS, 260 1.19 jonathan * but older hardware doesn't implement it and we must delay. 261 1.19 jonathan */ 262 1.19 jonathan static inline void 263 1.127 christos ep_finish_reset(bus_space_tag_t iot, bus_space_handle_t ioh) 264 1.56 jonathan { 265 1.57 jonathan int i; 266 1.56 jonathan 267 1.57 jonathan for (i = 0; i < 10000; i++) { 268 1.60 enami if ((bus_space_read_2(iot, ioh, ELINK_STATUS) & 269 1.102 christos COMMAND_IN_PROGRESS) == 0) 270 1.57 jonathan break; 271 1.57 jonathan DELAY(10); 272 1.56 jonathan } 273 1.56 jonathan } 274 1.56 jonathan 275 1.56 jonathan /* 276 1.56 jonathan * Issue a (reset) command, and be sure it has completed. 277 1.56 jonathan * Used for global reset, TX_RESET, RX_RESET. 278 1.56 jonathan */ 279 1.56 jonathan static inline void 280 1.127 christos ep_reset_cmd(struct ep_softc *sc, u_int cmd, u_int arg) 281 1.19 jonathan { 282 1.79 augustss bus_space_tag_t iot = sc->sc_iot; 283 1.79 augustss bus_space_handle_t ioh = sc->sc_ioh; 284 1.19 jonathan 285 1.19 jonathan bus_space_write_2(iot, ioh, cmd, arg); 286 1.56 jonathan ep_finish_reset(iot, ioh); 287 1.56 jonathan } 288 1.56 jonathan 289 1.56 jonathan 290 1.56 jonathan static inline void 291 1.127 christos ep_discard_rxtop(bus_space_tag_t iot, bus_space_handle_t ioh) 292 1.56 jonathan { 293 1.57 jonathan int i; 294 1.56 jonathan 295 1.56 jonathan bus_space_write_2(iot, ioh, ELINK_COMMAND, RX_DISCARD_TOP_PACK); 296 1.57 jonathan 297 1.57 jonathan /* 298 1.57 jonathan * Spin for about 1 msec, to avoid forcing a DELAY() between 299 1.57 jonathan * every received packet (adding latency and limiting pkt-recv rate). 300 1.57 jonathan * On PCI, at 4 30-nsec PCI bus cycles for a read, 8000 iterations 301 1.57 jonathan * is about right. 302 1.57 jonathan */ 303 1.57 jonathan for (i = 0; i < 8000; i++) { 304 1.60 enami if ((bus_space_read_2(iot, ioh, ELINK_STATUS) & 305 1.102 christos COMMAND_IN_PROGRESS) == 0) 306 1.57 jonathan return; 307 1.57 jonathan } 308 1.57 jonathan 309 1.57 jonathan /* Didn't complete in a hurry. Do DELAY()s. */ 310 1.56 jonathan ep_finish_reset(iot, ioh); 311 1.19 jonathan } 312 1.19 jonathan 313 1.20 jonathan /* 314 1.20 jonathan * Back-end attach and configure. 315 1.20 jonathan */ 316 1.75 enami int 317 1.127 christos epconfig(struct ep_softc *sc, u_short chipset, u_int8_t *enaddr) 318 1.1 thorpej { 319 1.21 is struct ifnet *ifp = &sc->sc_ethercom.ec_if; 320 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 321 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 322 1.149 msaitoh struct mii_data *mii = &sc->sc_mii; 323 1.7 thorpej u_int16_t i; 324 1.83 tsutsui u_int8_t myla[ETHER_ADDR_LEN]; 325 1.1 thorpej 326 1.122 ad callout_init(&sc->sc_mii_callout, 0); 327 1.152 thorpej callout_setfunc(&sc->sc_mii_callout, ep_tick, sc); 328 1.152 thorpej 329 1.122 ad callout_init(&sc->sc_mbuf_callout, 0); 330 1.152 thorpej callout_setfunc(&sc->sc_mbuf_callout, epmbuffill, sc); 331 1.78 thorpej 332 1.20 jonathan sc->ep_chipset = chipset; 333 1.32 thorpej 334 1.32 thorpej /* 335 1.32 thorpej * We could have been groveling around in other register 336 1.32 thorpej * windows in the front-end; make sure we're in window 0 337 1.32 thorpej * to read the EEPROM. 338 1.32 thorpej */ 339 1.32 thorpej GO_WINDOW(0); 340 1.1 thorpej 341 1.34 thorpej if (enaddr == NULL) { 342 1.34 thorpej /* 343 1.59 thorpej * Read the station address from the eeprom. 344 1.34 thorpej */ 345 1.83 tsutsui for (i = 0; i < ETHER_ADDR_LEN / 2; i++) { 346 1.59 thorpej u_int16_t x = ep_read_eeprom(sc, i); 347 1.34 thorpej myla[(i << 1)] = x >> 8; 348 1.34 thorpej myla[(i << 1) + 1] = x; 349 1.34 thorpej } 350 1.34 thorpej enaddr = myla; 351 1.1 thorpej } 352 1.1 thorpej 353 1.12 jonathan /* 354 1.41 thorpej * Vortex-based (3c59x pci,eisa) and Boomerang (3c900) cards 355 1.23 jonathan * allow FDDI-sized (4500) byte packets. Commands only take an 356 1.23 jonathan * 11-bit parameter, and 11 bits isn't enough to hold a full-size 357 1.23 jonathan * packet length. 358 1.12 jonathan * Commands to these cards implicitly upshift a packet size 359 1.111 perry * or threshold by 2 bits. 360 1.12 jonathan * To detect cards with large-packet support, we probe by setting 361 1.12 jonathan * the transmit threshold register, then change windows and 362 1.12 jonathan * read back the threshold register directly, and see if the 363 1.12 jonathan * threshold value was shifted or not. 364 1.12 jonathan */ 365 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, 366 1.111 perry SET_TX_AVAIL_THRESH | ELINK_LARGEWIN_PROBE); 367 1.12 jonathan GO_WINDOW(5); 368 1.47 fvdl i = bus_space_read_2(iot, ioh, ELINK_W5_TX_AVAIL_THRESH); 369 1.12 jonathan GO_WINDOW(1); 370 1.148 msaitoh switch (i) { 371 1.47 fvdl case ELINK_LARGEWIN_PROBE: 372 1.47 fvdl case (ELINK_LARGEWIN_PROBE & ELINK_LARGEWIN_MASK): 373 1.12 jonathan sc->ep_pktlenshift = 0; 374 1.12 jonathan break; 375 1.12 jonathan 376 1.47 fvdl case (ELINK_LARGEWIN_PROBE << 2): 377 1.12 jonathan sc->ep_pktlenshift = 2; 378 1.12 jonathan break; 379 1.12 jonathan 380 1.12 jonathan default: 381 1.127 christos aprint_error_dev(sc->sc_dev, 382 1.125 cegger "wrote 0x%x to TX_AVAIL_THRESH, read back 0x%x. " 383 1.14 cjs "Interface disabled\n", 384 1.125 cegger ELINK_LARGEWIN_PROBE, (int) i); 385 1.75 enami return (1); 386 1.12 jonathan } 387 1.20 jonathan 388 1.12 jonathan /* 389 1.111 perry * Ensure Tx-available interrupts are enabled for 390 1.12 jonathan * start the interface. 391 1.23 jonathan * XXX should be in epinit()? 392 1.12 jonathan */ 393 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, 394 1.12 jonathan SET_TX_AVAIL_THRESH | (1600 >> sc->ep_pktlenshift)); 395 1.12 jonathan 396 1.127 christos strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 397 1.23 jonathan ifp->if_softc = sc; 398 1.23 jonathan ifp->if_start = epstart; 399 1.23 jonathan ifp->if_ioctl = epioctl; 400 1.23 jonathan ifp->if_watchdog = epwatchdog; 401 1.88 jdolecek ifp->if_init = epinit; 402 1.88 jdolecek ifp->if_stop = epstop; 403 1.146 msaitoh ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 404 1.86 thorpej IFQ_SET_READY(&ifp->if_snd); 405 1.23 jonathan 406 1.23 jonathan if_attach(ifp); 407 1.34 thorpej ether_ifattach(ifp, enaddr); 408 1.23 jonathan 409 1.23 jonathan /* 410 1.111 perry * Finish configuration: 411 1.23 jonathan * determine chipset if the front-end couldn't do so, 412 1.23 jonathan * show board details, set media. 413 1.23 jonathan */ 414 1.23 jonathan 415 1.41 thorpej /* 416 1.41 thorpej * Print RAM size. We also print the Ethernet address in here. 417 1.41 thorpej * It's extracted from the ifp, so we have to make sure it's 418 1.41 thorpej * been attached first. 419 1.41 thorpej */ 420 1.23 jonathan ep_internalconfig(sc); 421 1.23 jonathan GO_WINDOW(0); 422 1.23 jonathan 423 1.41 thorpej /* 424 1.44 thorpej * Display some additional information, if pertinent. 425 1.44 thorpej */ 426 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER) 427 1.127 christos aprint_normal_dev(sc->sc_dev, "RoadRunner FIFO buffer enabled\n"); 428 1.44 thorpej 429 1.44 thorpej /* 430 1.41 thorpej * Initialize our media structures and MII info. We'll 431 1.41 thorpej * probe the MII if we discover that we have one. 432 1.20 jonathan */ 433 1.149 msaitoh mii->mii_ifp = ifp; 434 1.149 msaitoh mii->mii_readreg = ep_mii_readreg; 435 1.149 msaitoh mii->mii_writereg = ep_mii_writereg; 436 1.149 msaitoh mii->mii_statchg = ep_statchg; 437 1.149 msaitoh sc->sc_ethercom.ec_mii = mii; 438 1.149 msaitoh ifmedia_init(&mii->mii_media, IFM_IMASK, ep_media_change, 439 1.41 thorpej ep_media_status); 440 1.20 jonathan 441 1.20 jonathan /* 442 1.97 thorpej * All CORKSCREW chips have MII. 443 1.97 thorpej */ 444 1.97 thorpej if (sc->ep_chipset == ELINK_CHIPSET_CORKSCREW) 445 1.97 thorpej sc->ep_flags |= ELINK_FLAGS_MII; 446 1.97 thorpej 447 1.97 thorpej /* 448 1.41 thorpej * Now, determine which media we have. 449 1.20 jonathan */ 450 1.20 jonathan switch (sc->ep_chipset) { 451 1.59 thorpej case ELINK_CHIPSET_ROADRUNNER: 452 1.59 thorpej if (sc->ep_flags & ELINK_FLAGS_MII) { 453 1.59 thorpej ep_roadrunner_mii_enable(sc); 454 1.59 thorpej GO_WINDOW(0); 455 1.59 thorpej } 456 1.59 thorpej /* FALLTHROUGH */ 457 1.59 thorpej 458 1.97 thorpej case ELINK_CHIPSET_CORKSCREW: 459 1.47 fvdl case ELINK_CHIPSET_BOOMERANG: 460 1.41 thorpej /* 461 1.41 thorpej * If the device has MII, probe it. We won't be using 462 1.41 thorpej * any `native' media in this case, only PHYs. If 463 1.41 thorpej * we don't, just treat the Boomerang like the Vortex. 464 1.41 thorpej */ 465 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_MII) { 466 1.149 msaitoh mii_attach(sc->sc_dev, mii, 0xffffffff, 467 1.73 thorpej MII_PHY_ANY, MII_OFFSET_ANY, 0); 468 1.149 msaitoh if (LIST_FIRST(&mii->mii_phys) == NULL) { 469 1.149 msaitoh ifmedia_add(&mii->mii_media, 470 1.149 msaitoh IFM_ETHER | IFM_NONE, 0, NULL); 471 1.149 msaitoh ifmedia_set(&mii->mii_media, 472 1.149 msaitoh IFM_ETHER | IFM_NONE); 473 1.41 thorpej } else { 474 1.149 msaitoh ifmedia_set(&mii->mii_media, 475 1.149 msaitoh IFM_ETHER | IFM_AUTO); 476 1.41 thorpej } 477 1.41 thorpej break; 478 1.41 thorpej } 479 1.41 thorpej /* FALLTHROUGH */ 480 1.41 thorpej 481 1.47 fvdl case ELINK_CHIPSET_VORTEX: 482 1.20 jonathan ep_vortex_probemedia(sc); 483 1.20 jonathan break; 484 1.20 jonathan 485 1.20 jonathan default: 486 1.41 thorpej ep_509_probemedia(sc); 487 1.20 jonathan break; 488 1.20 jonathan } 489 1.23 jonathan 490 1.20 jonathan GO_WINDOW(1); /* Window 1 is operating window */ 491 1.20 jonathan 492 1.127 christos rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 493 1.135 tls RND_TYPE_NET, RND_FLAG_DEFAULT); 494 1.35 explorer 495 1.1 thorpej sc->tx_start_thresh = 20; /* probably a good starting point. */ 496 1.12 jonathan 497 1.16 jonathan /* Establish callback to reset card when we reboot. */ 498 1.128 tsutsui if (pmf_device_register1(sc->sc_dev, NULL, NULL, epshutdown)) 499 1.128 tsutsui pmf_class_network_register(sc->sc_dev, ifp); 500 1.128 tsutsui else 501 1.128 tsutsui aprint_error_dev(sc->sc_dev, 502 1.128 tsutsui "couldn't establish power handler\n"); 503 1.16 jonathan 504 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET); 505 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET); 506 1.81 jhawk 507 1.81 jhawk /* The attach is successful. */ 508 1.81 jhawk sc->sc_flags |= ELINK_FLAGS_ATTACHED; 509 1.75 enami return (0); 510 1.1 thorpej } 511 1.1 thorpej 512 1.23 jonathan 513 1.1 thorpej /* 514 1.15 jonathan * Show interface-model-independent info from window 3 515 1.15 jonathan * internal-configuration register. 516 1.15 jonathan */ 517 1.15 jonathan void 518 1.127 christos ep_internalconfig(struct ep_softc *sc) 519 1.15 jonathan { 520 1.15 jonathan bus_space_tag_t iot = sc->sc_iot; 521 1.15 jonathan bus_space_handle_t ioh = sc->sc_ioh; 522 1.15 jonathan 523 1.15 jonathan u_int config0; 524 1.15 jonathan u_int config1; 525 1.15 jonathan 526 1.105 simonb int ram_size, ram_width, ram_split; 527 1.15 jonathan /* 528 1.15 jonathan * NVRAM buffer Rx:Tx config names for busmastering cards 529 1.15 jonathan * (Demon, Vortex, and later). 530 1.15 jonathan */ 531 1.103 yamt const char *const onboard_ram_config[] = { 532 1.38 augustss "5:3", "3:1", "1:1", "3:5" }; 533 1.15 jonathan 534 1.15 jonathan GO_WINDOW(3); 535 1.47 fvdl config0 = (u_int)bus_space_read_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG); 536 1.60 enami config1 = (u_int)bus_space_read_2(iot, ioh, 537 1.60 enami ELINK_W3_INTERNAL_CONFIG + 2); 538 1.15 jonathan GO_WINDOW(0); 539 1.15 jonathan 540 1.15 jonathan ram_size = (config0 & CONFIG_RAMSIZE) >> CONFIG_RAMSIZE_SHIFT; 541 1.15 jonathan ram_width = (config0 & CONFIG_RAMWIDTH) >> CONFIG_RAMWIDTH_SHIFT; 542 1.15 jonathan 543 1.15 jonathan ram_split = (config1 & CONFIG_RAMSPLIT) >> CONFIG_RAMSPLIT_SHIFT; 544 1.15 jonathan 545 1.127 christos aprint_normal_dev(sc->sc_dev, "address %s, %dKB %s-wide FIFO, %s Rx:Tx split\n", 546 1.123 dyoung ether_sprintf(CLLADDR(sc->sc_ethercom.ec_if.if_sadl)), 547 1.23 jonathan 8 << ram_size, 548 1.23 jonathan (ram_width) ? "word" : "byte", 549 1.23 jonathan onboard_ram_config[ram_split]); 550 1.15 jonathan } 551 1.15 jonathan 552 1.23 jonathan 553 1.20 jonathan /* 554 1.23 jonathan * Find supported media on 3c509-generation hardware that doesn't have 555 1.20 jonathan * a "reset_options" register in window 3. 556 1.23 jonathan * Use the config_cntrl register in window 0 instead. 557 1.23 jonathan * Used on original, 10Mbit ISA (3c509), 3c509B, and pre-Demon EISA cards 558 1.23 jonathan * that implement CONFIG_CTRL. We don't have a good way to set the 559 1.89 jdolecek * default active medium; punt to ifconfig instead. 560 1.20 jonathan */ 561 1.20 jonathan void 562 1.127 christos ep_509_probemedia(struct ep_softc *sc) 563 1.20 jonathan { 564 1.20 jonathan bus_space_tag_t iot = sc->sc_iot; 565 1.20 jonathan bus_space_handle_t ioh = sc->sc_ioh; 566 1.41 thorpej struct ifmedia *ifm = &sc->sc_mii.mii_media; 567 1.23 jonathan u_int16_t ep_w0_config, port; 568 1.87 jdolecek const struct ep_media *epm; 569 1.41 thorpej const char *sep = "", *defmedianame = NULL; 570 1.41 thorpej int defmedia = 0; 571 1.23 jonathan 572 1.20 jonathan GO_WINDOW(0); 573 1.47 fvdl ep_w0_config = bus_space_read_2(iot, ioh, ELINK_W0_CONFIG_CTRL); 574 1.23 jonathan 575 1.127 christos aprint_normal_dev(sc->sc_dev, ""); 576 1.23 jonathan 577 1.41 thorpej /* Sanity check that there are any media! */ 578 1.47 fvdl if ((ep_w0_config & ELINK_W0_CC_MEDIAMASK) == 0) { 579 1.106 thorpej aprint_error("no media present!\n"); 580 1.149 msaitoh ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL); 581 1.149 msaitoh ifmedia_set(ifm, IFM_ETHER | IFM_NONE); 582 1.41 thorpej return; 583 1.23 jonathan } 584 1.23 jonathan 585 1.41 thorpej /* 586 1.41 thorpej * Get the default media from the EEPROM. 587 1.41 thorpej */ 588 1.59 thorpej port = ep_read_eeprom(sc, EEPROM_ADDR_CFG) >> 14; 589 1.23 jonathan 590 1.106 thorpej #define PRINT(str) aprint_normal("%s%s", sep, str); sep = ", " 591 1.23 jonathan 592 1.41 thorpej for (epm = ep_509_media; epm->epm_name != NULL; epm++) { 593 1.41 thorpej if (ep_w0_config & epm->epm_mpbit) { 594 1.46 thorpej /* 595 1.46 thorpej * This simple test works because 509 chipsets 596 1.46 thorpej * don't do full-duplex. 597 1.46 thorpej */ 598 1.41 thorpej if (epm->epm_epmedia == port || defmedia == 0) { 599 1.41 thorpej defmedia = epm->epm_ifmedia; 600 1.41 thorpej defmedianame = epm->epm_name; 601 1.41 thorpej } 602 1.41 thorpej ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_epmedia, 603 1.41 thorpej NULL); 604 1.41 thorpej PRINT(epm->epm_name); 605 1.41 thorpej } 606 1.41 thorpej } 607 1.41 thorpej 608 1.41 thorpej #undef PRINT 609 1.41 thorpej 610 1.41 thorpej #ifdef DIAGNOSTIC 611 1.41 thorpej if (defmedia == 0) 612 1.41 thorpej panic("ep_509_probemedia: impossible"); 613 1.41 thorpej #endif 614 1.41 thorpej 615 1.106 thorpej aprint_normal(" (default %s)\n", defmedianame); 616 1.41 thorpej ifmedia_set(ifm, defmedia); 617 1.20 jonathan } 618 1.20 jonathan 619 1.15 jonathan /* 620 1.23 jonathan * Find media present on large-packet-capable elink3 devices. 621 1.23 jonathan * Show onboard configuration of large-packet-capable elink3 devices 622 1.23 jonathan * (Demon, Vortex, Boomerang), which do not implement CONFIG_CTRL in window 0. 623 1.23 jonathan * Use media and card-version info in window 3 instead. 624 1.15 jonathan */ 625 1.15 jonathan void 626 1.127 christos ep_vortex_probemedia(struct ep_softc *sc) 627 1.15 jonathan { 628 1.15 jonathan bus_space_tag_t iot = sc->sc_iot; 629 1.15 jonathan bus_space_handle_t ioh = sc->sc_ioh; 630 1.41 thorpej struct ifmedia *ifm = &sc->sc_mii.mii_media; 631 1.87 jdolecek const struct ep_media *epm; 632 1.41 thorpej u_int config1; 633 1.15 jonathan int reset_options; 634 1.28 veego int default_media; /* 3-bit encoding of default (EEPROM) media */ 635 1.41 thorpej int defmedia = 0; 636 1.41 thorpej const char *sep = "", *defmedianame = NULL; 637 1.15 jonathan 638 1.15 jonathan GO_WINDOW(3); 639 1.60 enami config1 = (u_int)bus_space_read_2(iot, ioh, 640 1.60 enami ELINK_W3_INTERNAL_CONFIG + 2); 641 1.107 mycroft reset_options = (int)bus_space_read_2(iot, ioh, ELINK_W3_RESET_OPTIONS); 642 1.15 jonathan GO_WINDOW(0); 643 1.15 jonathan 644 1.23 jonathan default_media = (config1 & CONFIG_MEDIAMASK) >> CONFIG_MEDIAMASK_SHIFT; 645 1.15 jonathan 646 1.127 christos aprint_normal_dev(sc->sc_dev, ""); 647 1.41 thorpej 648 1.41 thorpej /* Sanity check that there are any media! */ 649 1.47 fvdl if ((reset_options & ELINK_PCI_MEDIAMASK) == 0) { 650 1.106 thorpej aprint_error("no media present!\n"); 651 1.149 msaitoh ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL); 652 1.149 msaitoh ifmedia_set(ifm, IFM_ETHER | IFM_NONE); 653 1.41 thorpej return; 654 1.41 thorpej } 655 1.41 thorpej 656 1.106 thorpej #define PRINT(str) aprint_normal("%s%s", sep, str); sep = ", " 657 1.23 jonathan 658 1.41 thorpej for (epm = ep_vortex_media; epm->epm_name != NULL; epm++) { 659 1.41 thorpej if (reset_options & epm->epm_mpbit) { 660 1.46 thorpej /* 661 1.46 thorpej * Default media is a little more complicated 662 1.46 thorpej * on the Vortex. We support full-duplex which 663 1.46 thorpej * uses the same reset options bit. 664 1.46 thorpej * 665 1.46 thorpej * XXX Check EEPROM for default to FDX? 666 1.46 thorpej */ 667 1.46 thorpej if (epm->epm_epmedia == default_media) { 668 1.46 thorpej if ((epm->epm_ifmedia & IFM_FDX) == 0) { 669 1.46 thorpej defmedia = epm->epm_ifmedia; 670 1.46 thorpej defmedianame = epm->epm_name; 671 1.46 thorpej } 672 1.46 thorpej } else if (defmedia == 0) { 673 1.41 thorpej defmedia = epm->epm_ifmedia; 674 1.41 thorpej defmedianame = epm->epm_name; 675 1.41 thorpej } 676 1.41 thorpej ifmedia_add(ifm, epm->epm_ifmedia, epm->epm_epmedia, 677 1.41 thorpej NULL); 678 1.41 thorpej PRINT(epm->epm_name); 679 1.23 jonathan } 680 1.23 jonathan } 681 1.15 jonathan 682 1.41 thorpej #undef PRINT 683 1.41 thorpej 684 1.41 thorpej #ifdef DIAGNOSTIC 685 1.41 thorpej if (defmedia == 0) 686 1.41 thorpej panic("ep_vortex_probemedia: impossible"); 687 1.41 thorpej #endif 688 1.41 thorpej 689 1.106 thorpej aprint_normal(" (default %s)\n", defmedianame); 690 1.41 thorpej ifmedia_set(ifm, defmedia); 691 1.41 thorpej } 692 1.41 thorpej 693 1.41 thorpej /* 694 1.41 thorpej * One second timer, used to tick the MII. 695 1.41 thorpej */ 696 1.41 thorpej void 697 1.127 christos ep_tick(void *arg) 698 1.41 thorpej { 699 1.41 thorpej struct ep_softc *sc = arg; 700 1.41 thorpej int s; 701 1.15 jonathan 702 1.41 thorpej #ifdef DIAGNOSTIC 703 1.47 fvdl if ((sc->ep_flags & ELINK_FLAGS_MII) == 0) 704 1.41 thorpej panic("ep_tick"); 705 1.41 thorpej #endif 706 1.31 jonathan 707 1.127 christos if (!device_is_active(sc->sc_dev)) 708 1.74 enami return; 709 1.74 enami 710 1.41 thorpej s = splnet(); 711 1.41 thorpej mii_tick(&sc->sc_mii); 712 1.41 thorpej splx(s); 713 1.15 jonathan 714 1.152 thorpej callout_schedule(&sc->sc_mii_callout, hz); 715 1.15 jonathan } 716 1.15 jonathan 717 1.15 jonathan /* 718 1.20 jonathan * Bring device up. 719 1.20 jonathan * 720 1.1 thorpej * The order in here seems important. Otherwise we may not receive 721 1.1 thorpej * interrupts. ?! 722 1.1 thorpej */ 723 1.88 jdolecek int 724 1.127 christos epinit(struct ifnet *ifp) 725 1.1 thorpej { 726 1.88 jdolecek struct ep_softc *sc = ifp->if_softc; 727 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 728 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 729 1.88 jdolecek int i, error; 730 1.123 dyoung const u_int8_t *addr; 731 1.88 jdolecek 732 1.88 jdolecek if (!sc->enabled && (error = epenable(sc)) != 0) 733 1.88 jdolecek return (error); 734 1.1 thorpej 735 1.88 jdolecek /* Make sure any pending reset has completed before touching board */ 736 1.56 jonathan ep_finish_reset(iot, ioh); 737 1.56 jonathan 738 1.62 enami /* 739 1.88 jdolecek * Cancel any pending I/O. 740 1.62 enami */ 741 1.88 jdolecek epstop(ifp, 0); 742 1.1 thorpej 743 1.89 jdolecek if (sc->bustype != ELINK_BUS_PCI && sc->bustype != ELINK_BUS_EISA 744 1.89 jdolecek && sc->bustype != ELINK_BUS_MCA) { 745 1.1 thorpej GO_WINDOW(0); 746 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W0_CONFIG_CTRL, 0); 747 1.60 enami bus_space_write_2(iot, ioh, ELINK_W0_CONFIG_CTRL, 748 1.60 enami ENABLE_DRQ_IRQ); 749 1.1 thorpej } 750 1.1 thorpej 751 1.47 fvdl if (sc->bustype == ELINK_BUS_PCMCIA) { 752 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W0_RESOURCE_CFG, 0x3f00); 753 1.1 thorpej } 754 1.1 thorpej 755 1.1 thorpej GO_WINDOW(2); 756 1.107 mycroft /* Reload the ether_addr. */ 757 1.123 dyoung addr = CLLADDR(ifp->if_sadl); 758 1.107 mycroft for (i = 0; i < 6; i += 2) 759 1.107 mycroft bus_space_write_2(iot, ioh, ELINK_W2_ADDR_0 + i, 760 1.107 mycroft (addr[i] << 0) | (addr[i + 1] << 8)); 761 1.8 christos 762 1.12 jonathan /* 763 1.12 jonathan * Reset the station-address receive filter. 764 1.41 thorpej * A bug workaround for busmastering (Vortex, Demon) cards. 765 1.12 jonathan */ 766 1.107 mycroft for (i = 0; i < 6; i += 2) 767 1.107 mycroft bus_space_write_2(iot, ioh, ELINK_W2_RECVMASK_0 + i, 0); 768 1.1 thorpej 769 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET); 770 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET); 771 1.1 thorpej 772 1.1 thorpej GO_WINDOW(1); /* Window 1 is operating window */ 773 1.1 thorpej for (i = 0; i < 31; i++) 774 1.116 nakayama (void)bus_space_read_2(iot, ioh, 775 1.116 nakayama ep_w1_reg(sc, ELINK_W1_TX_STATUS)); 776 1.31 jonathan 777 1.88 jdolecek /* Set threshold for Tx-space available interrupt. */ 778 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, 779 1.31 jonathan SET_TX_AVAIL_THRESH | (1600 >> sc->ep_pktlenshift)); 780 1.1 thorpej 781 1.47 fvdl if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) { 782 1.44 thorpej /* 783 1.44 thorpej * Enable options in the PCMCIA LAN COR register, via 784 1.44 thorpej * RoadRunner Window 1. 785 1.44 thorpej * 786 1.44 thorpej * XXX MAGIC CONSTANTS! 787 1.44 thorpej */ 788 1.44 thorpej u_int16_t cor; 789 1.44 thorpej 790 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, (1 << 11)); 791 1.44 thorpej 792 1.44 thorpej cor = bus_space_read_2(iot, ioh, 0) & ~0x30; 793 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_USESHAREDMEM) 794 1.44 thorpej cor |= 0x10; 795 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_FORCENOWAIT) 796 1.44 thorpej cor |= 0x20; 797 1.44 thorpej bus_space_write_2(iot, ioh, 0, cor); 798 1.44 thorpej 799 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL, 0); 800 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0); 801 1.59 thorpej 802 1.59 thorpej if (sc->ep_flags & ELINK_FLAGS_MII) { 803 1.59 thorpej ep_roadrunner_mii_enable(sc); 804 1.59 thorpej GO_WINDOW(1); 805 1.59 thorpej } 806 1.44 thorpej } 807 1.44 thorpej 808 1.18 jonathan /* Enable interrupts. */ 809 1.60 enami bus_space_write_2(iot, ioh, ELINK_COMMAND, 810 1.102 christos SET_RD_0_MASK | WATCHED_INTERRUPTS); 811 1.60 enami bus_space_write_2(iot, ioh, ELINK_COMMAND, 812 1.102 christos SET_INTR_MASK | WATCHED_INTERRUPTS); 813 1.1 thorpej 814 1.1 thorpej /* 815 1.98 wiz * Attempt to get rid of any stray interrupts that occurred during 816 1.1 thorpej * configuration. On the i386 this isn't possible because one may 817 1.1 thorpej * already be queued. However, a single stray interrupt is 818 1.1 thorpej * unimportant. 819 1.1 thorpej */ 820 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, ACK_INTR | 0xff); 821 1.1 thorpej 822 1.1 thorpej epsetfilter(sc); 823 1.41 thorpej epsetmedia(sc); 824 1.1 thorpej 825 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, RX_ENABLE); 826 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE); 827 1.1 thorpej 828 1.1 thorpej epmbuffill(sc); 829 1.1 thorpej 830 1.1 thorpej /* Interface is now `running', with no output active. */ 831 1.1 thorpej ifp->if_flags |= IFF_RUNNING; 832 1.1 thorpej ifp->if_flags &= ~IFF_OACTIVE; 833 1.1 thorpej 834 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_MII) { 835 1.41 thorpej /* Start the one second clock. */ 836 1.152 thorpej callout_schedule(&sc->sc_mii_callout, hz); 837 1.41 thorpej } 838 1.41 thorpej 839 1.1 thorpej /* Attempt to start output, if any. */ 840 1.1 thorpej epstart(ifp); 841 1.88 jdolecek 842 1.88 jdolecek return (0); 843 1.1 thorpej } 844 1.1 thorpej 845 1.20 jonathan 846 1.20 jonathan /* 847 1.111 perry * Set multicast receive filter. 848 1.20 jonathan * elink3 hardware has no selective multicast filter in hardware. 849 1.20 jonathan * Enable reception of all multicasts and filter in software. 850 1.20 jonathan */ 851 1.1 thorpej void 852 1.127 christos epsetfilter(struct ep_softc *sc) 853 1.1 thorpej { 854 1.79 augustss struct ifnet *ifp = &sc->sc_ethercom.ec_if; 855 1.1 thorpej 856 1.1 thorpej GO_WINDOW(1); /* Window 1 is operating window */ 857 1.60 enami bus_space_write_2(sc->sc_iot, sc->sc_ioh, ELINK_COMMAND, 858 1.60 enami SET_RX_FILTER | FIL_INDIVIDUAL | FIL_BRDCST | 859 1.60 enami ((ifp->if_flags & IFF_MULTICAST) ? FIL_MULTICAST : 0) | 860 1.60 enami ((ifp->if_flags & IFF_PROMISC) ? FIL_PROMISC : 0)); 861 1.1 thorpej } 862 1.1 thorpej 863 1.23 jonathan int 864 1.127 christos ep_media_change(struct ifnet *ifp) 865 1.23 jonathan { 866 1.79 augustss struct ep_softc *sc = ifp->if_softc; 867 1.23 jonathan 868 1.41 thorpej if (sc->enabled && (ifp->if_flags & IFF_UP) != 0) 869 1.41 thorpej epreset(sc); 870 1.34 thorpej 871 1.34 thorpej return (0); 872 1.23 jonathan } 873 1.23 jonathan 874 1.15 jonathan /* 875 1.59 thorpej * Reset and enable the MII on the RoadRunner. 876 1.59 thorpej */ 877 1.59 thorpej void 878 1.127 christos ep_roadrunner_mii_enable(struct ep_softc *sc) 879 1.59 thorpej { 880 1.59 thorpej bus_space_tag_t iot = sc->sc_iot; 881 1.59 thorpej bus_space_handle_t ioh = sc->sc_ioh; 882 1.59 thorpej 883 1.59 thorpej GO_WINDOW(3); 884 1.59 thorpej bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS, 885 1.149 msaitoh ELINK_PCI_100BASE_MII | ELINK_RUNNER_ENABLE_MII); 886 1.59 thorpej delay(1000); 887 1.59 thorpej bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS, 888 1.149 msaitoh ELINK_PCI_100BASE_MII | ELINK_RUNNER_MII_RESET | 889 1.59 thorpej ELINK_RUNNER_ENABLE_MII); 890 1.59 thorpej ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET); 891 1.59 thorpej ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET); 892 1.59 thorpej delay(1000); 893 1.59 thorpej bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS, 894 1.149 msaitoh ELINK_PCI_100BASE_MII | ELINK_RUNNER_ENABLE_MII); 895 1.59 thorpej } 896 1.59 thorpej 897 1.59 thorpej /* 898 1.41 thorpej * Set the card to use the specified media. 899 1.15 jonathan */ 900 1.34 thorpej void 901 1.127 christos epsetmedia(struct ep_softc *sc) 902 1.1 thorpej { 903 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 904 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 905 1.23 jonathan 906 1.41 thorpej /* Turn everything off. First turn off linkbeat and UTP. */ 907 1.1 thorpej GO_WINDOW(4); 908 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE, 0x0); 909 1.23 jonathan 910 1.23 jonathan /* Turn off coax */ 911 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, STOP_TRANSCEIVER); 912 1.23 jonathan delay(1000); 913 1.23 jonathan 914 1.29 jonathan /* 915 1.41 thorpej * If the device has MII, select it, and then tell the 916 1.41 thorpej * PHY which media to use. 917 1.41 thorpej */ 918 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_MII) { 919 1.41 thorpej int config0, config1; 920 1.41 thorpej 921 1.41 thorpej GO_WINDOW(3); 922 1.44 thorpej 923 1.47 fvdl if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) { 924 1.44 thorpej int resopt; 925 1.44 thorpej 926 1.44 thorpej resopt = bus_space_read_2(iot, ioh, 927 1.47 fvdl ELINK_W3_RESET_OPTIONS); 928 1.60 enami bus_space_write_2(iot, ioh, ELINK_W3_RESET_OPTIONS, 929 1.60 enami resopt | ELINK_RUNNER_ENABLE_MII); 930 1.44 thorpej } 931 1.44 thorpej 932 1.41 thorpej config0 = (u_int)bus_space_read_2(iot, ioh, 933 1.47 fvdl ELINK_W3_INTERNAL_CONFIG); 934 1.41 thorpej config1 = (u_int)bus_space_read_2(iot, ioh, 935 1.47 fvdl ELINK_W3_INTERNAL_CONFIG + 2); 936 1.41 thorpej 937 1.41 thorpej config1 = config1 & ~CONFIG_MEDIAMASK; 938 1.47 fvdl config1 |= (ELINKMEDIA_MII << CONFIG_MEDIAMASK_SHIFT); 939 1.41 thorpej 940 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG, config0); 941 1.60 enami bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG + 2, 942 1.60 enami config1); 943 1.41 thorpej GO_WINDOW(1); /* back to operating window */ 944 1.41 thorpej 945 1.41 thorpej mii_mediachg(&sc->sc_mii); 946 1.41 thorpej return; 947 1.41 thorpej } 948 1.41 thorpej 949 1.41 thorpej /* 950 1.29 jonathan * Now turn on the selected media/transceiver. 951 1.29 jonathan */ 952 1.29 jonathan GO_WINDOW(4); 953 1.41 thorpej switch (IFM_SUBTYPE(sc->sc_mii.mii_media.ifm_cur->ifm_media)) { 954 1.41 thorpej case IFM_10_T: 955 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE, 956 1.41 thorpej JABBER_GUARD_ENABLE|LINKBEAT_ENABLE); 957 1.23 jonathan break; 958 1.23 jonathan 959 1.41 thorpej case IFM_10_2: 960 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, START_TRANSCEIVER); 961 1.23 jonathan DELAY(1000); /* 50ms not enmough? */ 962 1.23 jonathan break; 963 1.23 jonathan 964 1.41 thorpej case IFM_100_TX: 965 1.41 thorpej case IFM_100_FX: 966 1.41 thorpej case IFM_100_T4: /* XXX check documentation */ 967 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE, 968 1.41 thorpej LINKBEAT_ENABLE); 969 1.23 jonathan DELAY(1000); /* not strictly necessary? */ 970 1.23 jonathan break; 971 1.23 jonathan 972 1.41 thorpej case IFM_10_5: 973 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W4_MEDIA_TYPE, 974 1.41 thorpej SQE_ENABLE); 975 1.41 thorpej DELAY(1000); /* not strictly necessary? */ 976 1.41 thorpej break; 977 1.41 thorpej 978 1.41 thorpej case IFM_MANUAL: 979 1.41 thorpej /* 980 1.41 thorpej * Nothing to do here; we are actually enabling the 981 1.41 thorpej * external PHY on the MII port. 982 1.41 thorpej */ 983 1.23 jonathan break; 984 1.41 thorpej 985 1.41 thorpej case IFM_NONE: 986 1.127 christos printf("%s: interface disabled\n", device_xname(sc->sc_dev)); 987 1.41 thorpej return; 988 1.41 thorpej 989 1.23 jonathan default: 990 1.41 thorpej panic("epsetmedia: impossible"); 991 1.1 thorpej } 992 1.23 jonathan 993 1.23 jonathan /* 994 1.41 thorpej * Tell the chip which port to use. 995 1.23 jonathan */ 996 1.41 thorpej switch (sc->ep_chipset) { 997 1.47 fvdl case ELINK_CHIPSET_VORTEX: 998 1.47 fvdl case ELINK_CHIPSET_BOOMERANG: 999 1.41 thorpej { 1000 1.45 thorpej int mctl, config0, config1; 1001 1.23 jonathan 1002 1.23 jonathan GO_WINDOW(3); 1003 1.23 jonathan config0 = (u_int)bus_space_read_2(iot, ioh, 1004 1.47 fvdl ELINK_W3_INTERNAL_CONFIG); 1005 1.23 jonathan config1 = (u_int)bus_space_read_2(iot, ioh, 1006 1.47 fvdl ELINK_W3_INTERNAL_CONFIG + 2); 1007 1.23 jonathan 1008 1.23 jonathan config1 = config1 & ~CONFIG_MEDIAMASK; 1009 1.41 thorpej config1 |= (sc->sc_mii.mii_media.ifm_cur->ifm_data << 1010 1.41 thorpej CONFIG_MEDIAMASK_SHIFT); 1011 1.41 thorpej 1012 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG, config0); 1013 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W3_INTERNAL_CONFIG + 2, 1014 1.47 fvdl config1); 1015 1.45 thorpej 1016 1.47 fvdl mctl = bus_space_read_2(iot, ioh, ELINK_W3_MAC_CONTROL); 1017 1.45 thorpej if (sc->sc_mii.mii_media.ifm_cur->ifm_media & IFM_FDX) 1018 1.45 thorpej mctl |= MAC_CONTROL_FDX; 1019 1.45 thorpej else 1020 1.45 thorpej mctl &= ~MAC_CONTROL_FDX; 1021 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, mctl); 1022 1.41 thorpej break; 1023 1.41 thorpej } 1024 1.41 thorpej default: 1025 1.41 thorpej { 1026 1.41 thorpej int w0_addr_cfg; 1027 1.28 veego 1028 1.28 veego GO_WINDOW(0); 1029 1.47 fvdl w0_addr_cfg = bus_space_read_2(iot, ioh, ELINK_W0_ADDRESS_CFG); 1030 1.29 jonathan w0_addr_cfg &= 0x3fff; 1031 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W0_ADDRESS_CFG, w0_addr_cfg | 1032 1.41 thorpej (sc->sc_mii.mii_media.ifm_cur->ifm_data << 14)); 1033 1.28 veego DELAY(1000); 1034 1.41 thorpej break; 1035 1.41 thorpej } 1036 1.23 jonathan } 1037 1.23 jonathan 1038 1.23 jonathan GO_WINDOW(1); /* Window 1 is operating window */ 1039 1.23 jonathan } 1040 1.23 jonathan 1041 1.23 jonathan /* 1042 1.23 jonathan * Get currently-selected media from card. 1043 1.23 jonathan * (if_media callback, may be called before interface is brought up). 1044 1.23 jonathan */ 1045 1.23 jonathan void 1046 1.127 christos ep_media_status(struct ifnet *ifp, struct ifmediareq *req) 1047 1.23 jonathan { 1048 1.79 augustss struct ep_softc *sc = ifp->if_softc; 1049 1.23 jonathan bus_space_tag_t iot = sc->sc_iot; 1050 1.23 jonathan bus_space_handle_t ioh = sc->sc_ioh; 1051 1.23 jonathan 1052 1.34 thorpej if (sc->enabled == 0) { 1053 1.149 msaitoh req->ifm_active = IFM_ETHER | IFM_NONE; 1054 1.34 thorpej req->ifm_status = 0; 1055 1.34 thorpej return; 1056 1.34 thorpej } 1057 1.34 thorpej 1058 1.41 thorpej /* 1059 1.41 thorpej * If we have MII, go ask the PHY what's going on. 1060 1.41 thorpej */ 1061 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_MII) { 1062 1.41 thorpej mii_pollstat(&sc->sc_mii); 1063 1.41 thorpej req->ifm_active = sc->sc_mii.mii_media_active; 1064 1.41 thorpej req->ifm_status = sc->sc_mii.mii_media_status; 1065 1.41 thorpej return; 1066 1.41 thorpej } 1067 1.41 thorpej 1068 1.41 thorpej /* 1069 1.41 thorpej * Ok, at this point we claim that our active media is 1070 1.41 thorpej * the currently selected media. We'll update our status 1071 1.41 thorpej * if our chipset allows us to detect link. 1072 1.41 thorpej */ 1073 1.41 thorpej req->ifm_active = sc->sc_mii.mii_media.ifm_cur->ifm_media; 1074 1.41 thorpej req->ifm_status = 0; 1075 1.41 thorpej 1076 1.23 jonathan switch (sc->ep_chipset) { 1077 1.47 fvdl case ELINK_CHIPSET_VORTEX: 1078 1.47 fvdl case ELINK_CHIPSET_BOOMERANG: 1079 1.23 jonathan GO_WINDOW(4); 1080 1.41 thorpej req->ifm_status = IFM_AVALID; 1081 1.47 fvdl if (bus_space_read_2(iot, ioh, ELINK_W4_MEDIA_TYPE) & 1082 1.41 thorpej LINKBEAT_DETECT) 1083 1.41 thorpej req->ifm_status |= IFM_ACTIVE; 1084 1.41 thorpej GO_WINDOW(1); /* back to operating window */ 1085 1.23 jonathan break; 1086 1.1 thorpej } 1087 1.1 thorpej } 1088 1.1 thorpej 1089 1.23 jonathan 1090 1.23 jonathan 1091 1.1 thorpej /* 1092 1.1 thorpej * Start outputting on the interface. 1093 1.1 thorpej * Always called as splnet(). 1094 1.1 thorpej */ 1095 1.1 thorpej void 1096 1.127 christos epstart(struct ifnet *ifp) 1097 1.1 thorpej { 1098 1.79 augustss struct ep_softc *sc = ifp->if_softc; 1099 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1100 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1101 1.1 thorpej struct mbuf *m, *m0; 1102 1.1 thorpej int sh, len, pad; 1103 1.101 soren bus_size_t txreg; 1104 1.1 thorpej 1105 1.1 thorpej /* Don't transmit if interface is busy or not running */ 1106 1.28 veego if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 1107 1.1 thorpej return; 1108 1.1 thorpej 1109 1.1 thorpej startagain: 1110 1.1 thorpej /* Sneak a peek at the next packet */ 1111 1.86 thorpej IFQ_POLL(&ifp->if_snd, m0); 1112 1.1 thorpej if (m0 == 0) 1113 1.1 thorpej return; 1114 1.1 thorpej 1115 1.1 thorpej /* We need to use m->m_pkthdr.len, so require the header */ 1116 1.1 thorpej if ((m0->m_flags & M_PKTHDR) == 0) 1117 1.1 thorpej panic("epstart: no header mbuf"); 1118 1.1 thorpej len = m0->m_pkthdr.len; 1119 1.1 thorpej 1120 1.1 thorpej pad = (4 - len) & 3; 1121 1.1 thorpej 1122 1.1 thorpej /* 1123 1.1 thorpej * The 3c509 automatically pads short packets to minimum ethernet 1124 1.1 thorpej * length, but we drop packets that are too large. Perhaps we should 1125 1.1 thorpej * truncate them instead? 1126 1.1 thorpej */ 1127 1.1 thorpej if (len + pad > ETHER_MAX_LEN) { 1128 1.1 thorpej /* packet is obviously too large: toss it */ 1129 1.150 thorpej if_statinc(ifp, if_oerrors); 1130 1.86 thorpej IFQ_DEQUEUE(&ifp->if_snd, m0); 1131 1.1 thorpej m_freem(m0); 1132 1.1 thorpej goto readcheck; 1133 1.1 thorpej } 1134 1.1 thorpej 1135 1.47 fvdl if (bus_space_read_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_FREE_TX)) < 1136 1.42 thorpej len + pad + 4) { 1137 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, 1138 1.12 jonathan SET_TX_AVAIL_THRESH | 1139 1.12 jonathan ((len + pad + 4) >> sc->ep_pktlenshift)); 1140 1.1 thorpej /* not enough room in FIFO */ 1141 1.1 thorpej ifp->if_flags |= IFF_OACTIVE; 1142 1.1 thorpej return; 1143 1.1 thorpej } else { 1144 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, 1145 1.60 enami SET_TX_AVAIL_THRESH | ELINK_THRESH_DISABLE); 1146 1.1 thorpej } 1147 1.1 thorpej 1148 1.86 thorpej IFQ_DEQUEUE(&ifp->if_snd, m0); 1149 1.1 thorpej if (m0 == 0) /* not really needed */ 1150 1.1 thorpej return; 1151 1.1 thorpej 1152 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_TX_START_THRESH | 1153 1.60 enami ((len / 4 + sc->tx_start_thresh) /* >> sc->ep_pktlenshift*/)); 1154 1.1 thorpej 1155 1.142 msaitoh bpf_mtap(ifp, m0, BPF_D_OUT); 1156 1.1 thorpej 1157 1.1 thorpej /* 1158 1.82 thorpej * Do the output at a high interrupt priority level so that an 1159 1.82 thorpej * interrupt from another device won't cause a FIFO underrun. 1160 1.82 thorpej * We choose splsched() since that blocks essentially everything 1161 1.82 thorpej * except for interrupts from serial devices (which typically 1162 1.88 jdolecek * lose data if their interrupt isn't serviced fast enough). 1163 1.82 thorpej * 1164 1.82 thorpej * XXX THIS CAN CAUSE CLOCK DRIFT! 1165 1.1 thorpej */ 1166 1.82 thorpej sh = splsched(); 1167 1.1 thorpej 1168 1.47 fvdl txreg = ep_w1_reg(sc, ELINK_W1_TX_PIO_WR_1); 1169 1.42 thorpej 1170 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER) { 1171 1.44 thorpej /* 1172 1.44 thorpej * Prime the FIFO buffer counter (number of 16-bit 1173 1.44 thorpej * words about to be written to the FIFO). 1174 1.44 thorpej * 1175 1.44 thorpej * NOTE: NO OTHER ACCESS CAN BE PERFORMED WHILE THIS 1176 1.44 thorpej * COUNTER IS NON-ZERO! 1177 1.44 thorpej */ 1178 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL, 1179 1.44 thorpej (len + pad) >> 1); 1180 1.44 thorpej } 1181 1.44 thorpej 1182 1.42 thorpej bus_space_write_2(iot, ioh, txreg, len); 1183 1.42 thorpej bus_space_write_2(iot, ioh, txreg, 0xffff); /* Second is meaningless */ 1184 1.47 fvdl if (ELINK_IS_BUS_32(sc->bustype)) { 1185 1.60 enami for (m = m0; m;) { 1186 1.148 msaitoh if (m->m_len > 3) { 1187 1.14 cjs /* align our reads from core */ 1188 1.148 msaitoh if (mtod(m, u_long) & 3) { 1189 1.14 cjs u_long count = 1190 1.14 cjs 4 - (mtod(m, u_long) & 3); 1191 1.14 cjs bus_space_write_multi_1(iot, ioh, 1192 1.42 thorpej txreg, mtod(m, u_int8_t *), count); 1193 1.14 cjs m->m_data = 1194 1.14 cjs (void *)(mtod(m, u_long) + count); 1195 1.14 cjs m->m_len -= count; 1196 1.14 cjs } 1197 1.55 jonathan bus_space_write_multi_stream_4(iot, ioh, 1198 1.42 thorpej txreg, mtod(m, u_int32_t *), m->m_len >> 2); 1199 1.14 cjs m->m_data = (void *)(mtod(m, u_long) + 1200 1.14 cjs (u_long)(m->m_len & ~3)); 1201 1.14 cjs m->m_len -= m->m_len & ~3; 1202 1.14 cjs } 1203 1.148 msaitoh if (m->m_len) { 1204 1.11 thorpej bus_space_write_multi_1(iot, ioh, 1205 1.42 thorpej txreg, mtod(m, u_int8_t *), m->m_len); 1206 1.14 cjs } 1207 1.139 christos m = m0 = m_free(m); 1208 1.1 thorpej } 1209 1.1 thorpej } else { 1210 1.60 enami for (m = m0; m;) { 1211 1.148 msaitoh if (m->m_len > 1) { 1212 1.148 msaitoh if (mtod(m, u_long) & 1) { 1213 1.14 cjs bus_space_write_1(iot, ioh, 1214 1.42 thorpej txreg, *(mtod(m, u_int8_t *))); 1215 1.14 cjs m->m_data = 1216 1.14 cjs (void *)(mtod(m, u_long) + 1); 1217 1.14 cjs m->m_len -= 1; 1218 1.14 cjs } 1219 1.55 jonathan bus_space_write_multi_stream_2(iot, ioh, 1220 1.42 thorpej txreg, mtod(m, u_int16_t *), 1221 1.14 cjs m->m_len >> 1); 1222 1.14 cjs } 1223 1.148 msaitoh if (m->m_len & 1) { 1224 1.42 thorpej bus_space_write_1(iot, ioh, txreg, 1225 1.2 thorpej *(mtod(m, u_int8_t *) + m->m_len - 1)); 1226 1.14 cjs } 1227 1.139 christos m = m0 = m_free(m); 1228 1.1 thorpej } 1229 1.1 thorpej } 1230 1.1 thorpej while (pad--) 1231 1.42 thorpej bus_space_write_1(iot, ioh, txreg, 0); 1232 1.1 thorpej 1233 1.1 thorpej splx(sh); 1234 1.1 thorpej 1235 1.150 thorpej if_statinc(ifp, if_opackets); 1236 1.1 thorpej 1237 1.1 thorpej readcheck: 1238 1.47 fvdl if ((bus_space_read_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_RX_STATUS)) & 1239 1.42 thorpej ERR_INCOMPLETE) == 0) { 1240 1.1 thorpej /* We received a complete packet. */ 1241 1.47 fvdl u_int16_t status = bus_space_read_2(iot, ioh, ELINK_STATUS); 1242 1.1 thorpej 1243 1.102 christos if ((status & INTR_LATCH) == 0) { 1244 1.1 thorpej /* 1245 1.1 thorpej * No interrupt, read the packet and continue 1246 1.111 perry * Is this supposed to happen? Is my motherboard 1247 1.1 thorpej * completely busted? 1248 1.1 thorpej */ 1249 1.1 thorpej epread(sc); 1250 1.28 veego } else { 1251 1.1 thorpej /* Got an interrupt, return so that it gets serviced. */ 1252 1.1 thorpej return; 1253 1.28 veego } 1254 1.28 veego } else { 1255 1.1 thorpej /* Check if we are stuck and reset [see XXX comment] */ 1256 1.1 thorpej if (epstatus(sc)) { 1257 1.1 thorpej if (ifp->if_flags & IFF_DEBUG) 1258 1.10 christos printf("%s: adapter reset\n", 1259 1.127 christos device_xname(sc->sc_dev)); 1260 1.1 thorpej epreset(sc); 1261 1.1 thorpej } 1262 1.1 thorpej } 1263 1.1 thorpej 1264 1.1 thorpej goto startagain; 1265 1.1 thorpej } 1266 1.1 thorpej 1267 1.1 thorpej 1268 1.1 thorpej /* 1269 1.1 thorpej * XXX: The 3c509 card can get in a mode where both the fifo status bit 1270 1.1 thorpej * FIFOS_RX_OVERRUN and the status bit ERR_INCOMPLETE are set 1271 1.1 thorpej * We detect this situation and we reset the adapter. 1272 1.1 thorpej * It happens at times when there is a lot of broadcast traffic 1273 1.1 thorpej * on the cable (once in a blue moon). 1274 1.1 thorpej */ 1275 1.1 thorpej static int 1276 1.127 christos epstatus(struct ep_softc *sc) 1277 1.1 thorpej { 1278 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1279 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1280 1.7 thorpej u_int16_t fifost; 1281 1.1 thorpej 1282 1.1 thorpej /* 1283 1.1 thorpej * Check the FIFO status and act accordingly 1284 1.1 thorpej */ 1285 1.1 thorpej GO_WINDOW(4); 1286 1.47 fvdl fifost = bus_space_read_2(iot, ioh, ELINK_W4_FIFO_DIAG); 1287 1.1 thorpej GO_WINDOW(1); 1288 1.1 thorpej 1289 1.1 thorpej if (fifost & FIFOS_RX_UNDERRUN) { 1290 1.21 is if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG) 1291 1.127 christos printf("%s: RX underrun\n", device_xname(sc->sc_dev)); 1292 1.1 thorpej epreset(sc); 1293 1.1 thorpej return 0; 1294 1.1 thorpej } 1295 1.1 thorpej 1296 1.1 thorpej if (fifost & FIFOS_RX_STATUS_OVERRUN) { 1297 1.21 is if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG) 1298 1.127 christos printf("%s: RX Status overrun\n", device_xname(sc->sc_dev)); 1299 1.1 thorpej return 1; 1300 1.1 thorpej } 1301 1.1 thorpej 1302 1.1 thorpej if (fifost & FIFOS_RX_OVERRUN) { 1303 1.21 is if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG) 1304 1.127 christos printf("%s: RX overrun\n", device_xname(sc->sc_dev)); 1305 1.1 thorpej return 1; 1306 1.1 thorpej } 1307 1.1 thorpej 1308 1.1 thorpej if (fifost & FIFOS_TX_OVERRUN) { 1309 1.21 is if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG) 1310 1.127 christos printf("%s: TX overrun\n", device_xname(sc->sc_dev)); 1311 1.1 thorpej epreset(sc); 1312 1.1 thorpej return 0; 1313 1.1 thorpej } 1314 1.1 thorpej 1315 1.1 thorpej return 0; 1316 1.1 thorpej } 1317 1.1 thorpej 1318 1.1 thorpej 1319 1.1 thorpej static void 1320 1.127 christos eptxstat(struct ep_softc *sc) 1321 1.1 thorpej { 1322 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1323 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1324 1.150 thorpej struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1325 1.1 thorpej int i; 1326 1.1 thorpej 1327 1.1 thorpej /* 1328 1.1 thorpej * We need to read+write TX_STATUS until we get a 0 status 1329 1.1 thorpej * in order to turn off the interrupt flag. 1330 1.1 thorpej */ 1331 1.107 mycroft while ((i = bus_space_read_2(iot, ioh, 1332 1.60 enami ep_w1_reg(sc, ELINK_W1_TX_STATUS))) & TXS_COMPLETE) { 1333 1.107 mycroft bus_space_write_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_TX_STATUS), 1334 1.42 thorpej 0x0); 1335 1.1 thorpej 1336 1.1 thorpej if (i & TXS_JABBER) { 1337 1.150 thorpej if_statinc(ifp, if_oerrors); 1338 1.21 is if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG) 1339 1.10 christos printf("%s: jabber (%x)\n", 1340 1.127 christos device_xname(sc->sc_dev), i); 1341 1.1 thorpej epreset(sc); 1342 1.1 thorpej } else if (i & TXS_UNDERRUN) { 1343 1.150 thorpej if_statinc(ifp, if_oerrors); 1344 1.21 is if (sc->sc_ethercom.ec_if.if_flags & IFF_DEBUG) 1345 1.10 christos printf("%s: fifo underrun (%x) @%d\n", 1346 1.127 christos device_xname(sc->sc_dev), i, 1347 1.1 thorpej sc->tx_start_thresh); 1348 1.1 thorpej if (sc->tx_succ_ok < 100) 1349 1.143 riastrad sc->tx_start_thresh = uimin(ETHER_MAX_LEN, 1350 1.1 thorpej sc->tx_start_thresh + 20); 1351 1.1 thorpej sc->tx_succ_ok = 0; 1352 1.1 thorpej epreset(sc); 1353 1.1 thorpej } else if (i & TXS_MAX_COLLISION) { 1354 1.150 thorpej if_statinc(ifp, if_collisions); 1355 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_ENABLE); 1356 1.21 is sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 1357 1.1 thorpej } else 1358 1.1 thorpej sc->tx_succ_ok = (sc->tx_succ_ok+1) & 127; 1359 1.1 thorpej } 1360 1.1 thorpej } 1361 1.1 thorpej 1362 1.1 thorpej int 1363 1.127 christos epintr(void *arg) 1364 1.1 thorpej { 1365 1.79 augustss struct ep_softc *sc = arg; 1366 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1367 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1368 1.21 is struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1369 1.7 thorpej u_int16_t status; 1370 1.1 thorpej int ret = 0; 1371 1.1 thorpej 1372 1.127 christos if (sc->enabled == 0 || !device_is_active(sc->sc_dev)) 1373 1.34 thorpej return (0); 1374 1.34 thorpej 1375 1.102 christos 1376 1.1 thorpej for (;;) { 1377 1.47 fvdl status = bus_space_read_2(iot, ioh, ELINK_STATUS); 1378 1.1 thorpej 1379 1.102 christos if ((status & WATCHED_INTERRUPTS) == 0) { 1380 1.102 christos if ((status & INTR_LATCH) == 0) { 1381 1.34 thorpej #if 0 1382 1.102 christos printf("%s: intr latch cleared\n", 1383 1.134 chs device_xname(sc->sc_dev)); 1384 1.34 thorpej #endif 1385 1.34 thorpej break; 1386 1.34 thorpej } 1387 1.34 thorpej } 1388 1.1 thorpej 1389 1.1 thorpej ret = 1; 1390 1.1 thorpej 1391 1.1 thorpej /* 1392 1.1 thorpej * Acknowledge any interrupts. It's important that we do this 1393 1.1 thorpej * first, since there would otherwise be a race condition. 1394 1.1 thorpej * Due to the i386 interrupt queueing, we may get spurious 1395 1.1 thorpej * interrupts occasionally. 1396 1.1 thorpej */ 1397 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, ACK_INTR | 1398 1.102 christos (status & (INTR_LATCH | ALL_INTERRUPTS))); 1399 1.34 thorpej 1400 1.34 thorpej #if 0 1401 1.47 fvdl status = bus_space_read_2(iot, ioh, ELINK_STATUS); 1402 1.34 thorpej 1403 1.134 chs printf("%s: intr%s%s%s%s\n", device_xname(sc->sc_dev), 1404 1.102 christos (status & RX_COMPLETE)?" RX_COMPLETE":"", 1405 1.102 christos (status & TX_COMPLETE)?" TX_COMPLETE":"", 1406 1.102 christos (status & TX_AVAIL)?" TX_AVAIL":"", 1407 1.102 christos (status & CARD_FAILURE)?" CARD_FAILURE":""); 1408 1.34 thorpej #endif 1409 1.1 thorpej 1410 1.102 christos if (status & RX_COMPLETE) { 1411 1.1 thorpej epread(sc); 1412 1.35 explorer } 1413 1.102 christos if (status & TX_AVAIL) { 1414 1.21 is sc->sc_ethercom.ec_if.if_flags &= ~IFF_OACTIVE; 1415 1.21 is epstart(&sc->sc_ethercom.ec_if); 1416 1.1 thorpej } 1417 1.102 christos if (status & CARD_FAILURE) { 1418 1.10 christos printf("%s: adapter failure (%x)\n", 1419 1.127 christos device_xname(sc->sc_dev), status); 1420 1.59 thorpej #if 1 1421 1.88 jdolecek epinit(ifp); 1422 1.59 thorpej #else 1423 1.1 thorpej epreset(sc); 1424 1.59 thorpej #endif 1425 1.1 thorpej return (1); 1426 1.1 thorpej } 1427 1.102 christos if (status & TX_COMPLETE) { 1428 1.1 thorpej eptxstat(sc); 1429 1.1 thorpej epstart(ifp); 1430 1.1 thorpej } 1431 1.35 explorer 1432 1.35 explorer if (status) 1433 1.35 explorer rnd_add_uint32(&sc->rnd_source, status); 1434 1.111 perry } 1435 1.1 thorpej 1436 1.1 thorpej /* no more interrupts */ 1437 1.1 thorpej return (ret); 1438 1.1 thorpej } 1439 1.1 thorpej 1440 1.1 thorpej void 1441 1.127 christos epread(struct ep_softc *sc) 1442 1.1 thorpej { 1443 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1444 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1445 1.21 is struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1446 1.1 thorpej struct mbuf *m; 1447 1.1 thorpej int len; 1448 1.1 thorpej 1449 1.47 fvdl len = bus_space_read_2(iot, ioh, ep_w1_reg(sc, ELINK_W1_RX_STATUS)); 1450 1.1 thorpej 1451 1.1 thorpej again: 1452 1.1 thorpej if (ifp->if_flags & IFF_DEBUG) { 1453 1.1 thorpej int err = len & ERR_MASK; 1454 1.112 christos const char *s = NULL; 1455 1.1 thorpej 1456 1.1 thorpej if (len & ERR_INCOMPLETE) 1457 1.1 thorpej s = "incomplete packet"; 1458 1.1 thorpej else if (err == ERR_OVERRUN) 1459 1.1 thorpej s = "packet overrun"; 1460 1.1 thorpej else if (err == ERR_RUNT) 1461 1.1 thorpej s = "runt packet"; 1462 1.1 thorpej else if (err == ERR_ALIGNMENT) 1463 1.1 thorpej s = "bad alignment"; 1464 1.1 thorpej else if (err == ERR_CRC) 1465 1.1 thorpej s = "bad crc"; 1466 1.1 thorpej else if (err == ERR_OVERSIZE) 1467 1.1 thorpej s = "oversized packet"; 1468 1.1 thorpej else if (err == ERR_DRIBBLE) 1469 1.1 thorpej s = "dribble bits"; 1470 1.1 thorpej 1471 1.1 thorpej if (s) 1472 1.127 christos printf("%s: %s\n", device_xname(sc->sc_dev), s); 1473 1.1 thorpej } 1474 1.1 thorpej 1475 1.1 thorpej if (len & ERR_INCOMPLETE) 1476 1.1 thorpej return; 1477 1.1 thorpej 1478 1.1 thorpej if (len & ERR_RX) { 1479 1.150 thorpej if_statinc(ifp, if_ierrors); 1480 1.1 thorpej goto abort; 1481 1.1 thorpej } 1482 1.1 thorpej 1483 1.1 thorpej len &= RX_BYTES_MASK; /* Lower 11 bits = RX bytes. */ 1484 1.1 thorpej 1485 1.1 thorpej /* Pull packet off interface. */ 1486 1.1 thorpej m = epget(sc, len); 1487 1.1 thorpej if (m == 0) { 1488 1.150 thorpej if_statinc(ifp, if_ierrors); 1489 1.1 thorpej goto abort; 1490 1.1 thorpej } 1491 1.1 thorpej 1492 1.137 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 1493 1.1 thorpej 1494 1.1 thorpej /* 1495 1.1 thorpej * In periods of high traffic we can actually receive enough 1496 1.1 thorpej * packets so that the fifo overrun bit will be set at this point, 1497 1.1 thorpej * even though we just read a packet. In this case we 1498 1.1 thorpej * are not going to receive any more interrupts. We check for 1499 1.1 thorpej * this condition and read again until the fifo is not full. 1500 1.1 thorpej * We could simplify this test by not using epstatus(), but 1501 1.1 thorpej * rechecking the RX_STATUS register directly. This test could 1502 1.1 thorpej * result in unnecessary looping in cases where there is a new 1503 1.1 thorpej * packet but the fifo is not full, but it will not fix the 1504 1.1 thorpej * stuck behavior. 1505 1.1 thorpej * 1506 1.1 thorpej * Even with this improvement, we still get packet overrun errors 1507 1.1 thorpej * which are hurting performance. Maybe when I get some more time 1508 1.1 thorpej * I'll modify epread() so that it can handle RX_EARLY interrupts. 1509 1.1 thorpej */ 1510 1.1 thorpej if (epstatus(sc)) { 1511 1.42 thorpej len = bus_space_read_2(iot, ioh, 1512 1.47 fvdl ep_w1_reg(sc, ELINK_W1_RX_STATUS)); 1513 1.1 thorpej /* Check if we are stuck and reset [see XXX comment] */ 1514 1.1 thorpej if (len & ERR_INCOMPLETE) { 1515 1.1 thorpej if (ifp->if_flags & IFF_DEBUG) 1516 1.10 christos printf("%s: adapter reset\n", 1517 1.127 christos device_xname(sc->sc_dev)); 1518 1.1 thorpej epreset(sc); 1519 1.1 thorpej return; 1520 1.1 thorpej } 1521 1.1 thorpej goto again; 1522 1.1 thorpej } 1523 1.1 thorpej 1524 1.1 thorpej return; 1525 1.1 thorpej 1526 1.1 thorpej abort: 1527 1.56 jonathan ep_discard_rxtop(iot, ioh); 1528 1.56 jonathan 1529 1.1 thorpej } 1530 1.1 thorpej 1531 1.1 thorpej struct mbuf * 1532 1.127 christos epget(struct ep_softc *sc, int totlen) 1533 1.1 thorpej { 1534 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1535 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1536 1.21 is struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1537 1.93 jdolecek struct mbuf *m; 1538 1.101 soren bus_size_t rxreg; 1539 1.14 cjs int len, remaining; 1540 1.93 jdolecek int s; 1541 1.121 christos void *newdata; 1542 1.93 jdolecek u_long offset; 1543 1.1 thorpej 1544 1.1 thorpej m = sc->mb[sc->next_mb]; 1545 1.1 thorpej sc->mb[sc->next_mb] = 0; 1546 1.1 thorpej if (m == 0) { 1547 1.1 thorpej MGETHDR(m, M_DONTWAIT, MT_DATA); 1548 1.1 thorpej if (m == 0) 1549 1.1 thorpej return 0; 1550 1.1 thorpej } else { 1551 1.1 thorpej /* If the queue is no longer full, refill. */ 1552 1.1 thorpej if (sc->last_mb == sc->next_mb) 1553 1.152 thorpej callout_schedule(&sc->sc_mbuf_callout, 1); 1554 1.93 jdolecek 1555 1.1 thorpej /* Convert one of our saved mbuf's. */ 1556 1.1 thorpej sc->next_mb = (sc->next_mb + 1) % MAX_MBS; 1557 1.1 thorpej m->m_data = m->m_pktdat; 1558 1.1 thorpej m->m_flags = M_PKTHDR; 1559 1.95 thorpej memset(&m->m_pkthdr, 0, sizeof(m->m_pkthdr)); 1560 1.1 thorpej } 1561 1.138 ozaki m_set_rcvif(m, ifp); 1562 1.1 thorpej m->m_pkthdr.len = totlen; 1563 1.1 thorpej len = MHLEN; 1564 1.93 jdolecek 1565 1.93 jdolecek /* 1566 1.93 jdolecek * Allocate big enough space to hold whole packet, to avoid 1567 1.93 jdolecek * allocating new mbufs on splsched(). 1568 1.93 jdolecek */ 1569 1.93 jdolecek if (totlen + ALIGNBYTES > len) { 1570 1.93 jdolecek if (totlen + ALIGNBYTES > MCLBYTES) { 1571 1.93 jdolecek len = ALIGN(totlen + ALIGNBYTES); 1572 1.93 jdolecek MEXTMALLOC(m, len, M_DONTWAIT); 1573 1.93 jdolecek } else { 1574 1.93 jdolecek len = MCLBYTES; 1575 1.93 jdolecek MCLGET(m, M_DONTWAIT); 1576 1.93 jdolecek } 1577 1.93 jdolecek if ((m->m_flags & M_EXT) == 0) { 1578 1.93 jdolecek m_free(m); 1579 1.93 jdolecek return 0; 1580 1.93 jdolecek } 1581 1.93 jdolecek } 1582 1.93 jdolecek 1583 1.93 jdolecek /* align the struct ip header */ 1584 1.121 christos newdata = (char *)ALIGN(m->m_data + sizeof(struct ether_header)) 1585 1.121 christos - sizeof(struct ether_header); 1586 1.93 jdolecek m->m_data = newdata; 1587 1.93 jdolecek m->m_len = totlen; 1588 1.93 jdolecek 1589 1.93 jdolecek rxreg = ep_w1_reg(sc, ELINK_W1_RX_PIO_RD_1); 1590 1.93 jdolecek remaining = totlen; 1591 1.93 jdolecek offset = mtod(m, u_long); 1592 1.1 thorpej 1593 1.1 thorpej /* 1594 1.82 thorpej * We read the packet at a high interrupt priority level so that 1595 1.82 thorpej * an interrupt from another device won't cause the card's packet 1596 1.82 thorpej * buffer to overflow. We choose splsched() since that blocks 1597 1.82 thorpej * essentially everything except for interrupts from serial 1598 1.91 jdolecek * devices (which typically lose data if their interrupt isn't 1599 1.82 thorpej * serviced fast enough). 1600 1.82 thorpej * 1601 1.82 thorpej * XXX THIS CAN CAUSE CLOCK DRIFT! 1602 1.1 thorpej */ 1603 1.93 jdolecek s = splsched(); 1604 1.42 thorpej 1605 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER) { 1606 1.44 thorpej /* 1607 1.44 thorpej * Prime the FIFO buffer counter (number of 16-bit 1608 1.44 thorpej * words about to be read from the FIFO). 1609 1.44 thorpej * 1610 1.44 thorpej * NOTE: NO OTHER ACCESS CAN BE PERFORMED WHILE THIS 1611 1.44 thorpej * COUNTER IS NON-ZERO! 1612 1.44 thorpej */ 1613 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, totlen >> 1); 1614 1.44 thorpej } 1615 1.44 thorpej 1616 1.93 jdolecek if (ELINK_IS_BUS_32(sc->bustype)) { 1617 1.93 jdolecek /* 1618 1.93 jdolecek * Read bytes up to the point where we are aligned. 1619 1.93 jdolecek * (We can align to 4 bytes, rather than ALIGNBYTES, 1620 1.93 jdolecek * here because we're later reading 4-byte chunks.) 1621 1.93 jdolecek */ 1622 1.148 msaitoh if ((remaining > 3) && (offset & 3)) { 1623 1.93 jdolecek int count = (4 - (offset & 3)); 1624 1.93 jdolecek bus_space_read_multi_1(iot, ioh, 1625 1.93 jdolecek rxreg, (u_int8_t *) offset, count); 1626 1.93 jdolecek offset += count; 1627 1.93 jdolecek remaining -= count; 1628 1.93 jdolecek } 1629 1.93 jdolecek if (remaining > 3) { 1630 1.93 jdolecek bus_space_read_multi_stream_4(iot, ioh, 1631 1.93 jdolecek rxreg, (u_int32_t *) offset, 1632 1.93 jdolecek remaining >> 2); 1633 1.93 jdolecek offset += remaining & ~3; 1634 1.93 jdolecek remaining &= 3; 1635 1.93 jdolecek } 1636 1.148 msaitoh if (remaining) { 1637 1.93 jdolecek bus_space_read_multi_1(iot, ioh, 1638 1.93 jdolecek rxreg, (u_int8_t *) offset, remaining); 1639 1.1 thorpej } 1640 1.93 jdolecek } else { 1641 1.153 rin /* (offset & 1) == 0 since IP header is aligned */ 1642 1.93 jdolecek if (remaining > 1) { 1643 1.93 jdolecek bus_space_read_multi_stream_2(iot, ioh, 1644 1.93 jdolecek rxreg, (u_int16_t *) offset, 1645 1.93 jdolecek remaining >> 1); 1646 1.93 jdolecek offset += remaining & ~1; 1647 1.1 thorpej } 1648 1.148 msaitoh if (remaining & 1) { 1649 1.153 rin *(uint8_t *)offset = 1650 1.153 rin bus_space_read_1(iot, ioh, rxreg); 1651 1.1 thorpej } 1652 1.1 thorpej } 1653 1.1 thorpej 1654 1.56 jonathan ep_discard_rxtop(iot, ioh); 1655 1.1 thorpej 1656 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_USEFIFOBUFFER) 1657 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0); 1658 1.93 jdolecek splx(s); 1659 1.1 thorpej 1660 1.93 jdolecek return (m); 1661 1.1 thorpej } 1662 1.1 thorpej 1663 1.1 thorpej int 1664 1.127 christos epioctl(struct ifnet *ifp, u_long cmd, void *data) 1665 1.1 thorpej { 1666 1.5 thorpej struct ep_softc *sc = ifp->if_softc; 1667 1.1 thorpej int s, error = 0; 1668 1.1 thorpej 1669 1.1 thorpej s = splnet(); 1670 1.1 thorpej 1671 1.1 thorpej switch (cmd) { 1672 1.1 thorpej case SIOCADDMULTI: 1673 1.1 thorpej case SIOCDELMULTI: 1674 1.34 thorpej if (sc->enabled == 0) { 1675 1.34 thorpej error = EIO; 1676 1.34 thorpej break; 1677 1.34 thorpej } 1678 1.34 thorpej 1679 1.145 mrg /* FALLTHROUGH */ 1680 1.88 jdolecek default: 1681 1.88 jdolecek error = ether_ioctl(ifp, cmd, data); 1682 1.1 thorpej 1683 1.1 thorpej if (error == ENETRESET) { 1684 1.1 thorpej /* 1685 1.1 thorpej * Multicast list has changed; set the hardware filter 1686 1.1 thorpej * accordingly. 1687 1.1 thorpej */ 1688 1.108 thorpej if (ifp->if_flags & IFF_RUNNING) 1689 1.108 thorpej epreset(sc); 1690 1.1 thorpej error = 0; 1691 1.1 thorpej } 1692 1.1 thorpej break; 1693 1.1 thorpej } 1694 1.1 thorpej 1695 1.1 thorpej splx(s); 1696 1.1 thorpej return (error); 1697 1.1 thorpej } 1698 1.1 thorpej 1699 1.1 thorpej void 1700 1.127 christos epreset(struct ep_softc *sc) 1701 1.1 thorpej { 1702 1.1 thorpej int s; 1703 1.1 thorpej 1704 1.1 thorpej s = splnet(); 1705 1.88 jdolecek epinit(&sc->sc_ethercom.ec_if); 1706 1.1 thorpej splx(s); 1707 1.1 thorpej } 1708 1.1 thorpej 1709 1.1 thorpej void 1710 1.127 christos epwatchdog(struct ifnet *ifp) 1711 1.1 thorpej { 1712 1.5 thorpej struct ep_softc *sc = ifp->if_softc; 1713 1.1 thorpej 1714 1.127 christos log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 1715 1.150 thorpej if_statinc(ifp, if_oerrors); 1716 1.1 thorpej 1717 1.1 thorpej epreset(sc); 1718 1.1 thorpej } 1719 1.1 thorpej 1720 1.1 thorpej void 1721 1.127 christos epstop(struct ifnet *ifp, int disable) 1722 1.1 thorpej { 1723 1.88 jdolecek struct ep_softc *sc = ifp->if_softc; 1724 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1725 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1726 1.1 thorpej 1727 1.47 fvdl if (sc->ep_flags & ELINK_FLAGS_MII) { 1728 1.41 thorpej /* Stop the one second clock. */ 1729 1.78 thorpej callout_stop(&sc->sc_mbuf_callout); 1730 1.66 thorpej 1731 1.66 thorpej /* Down the MII. */ 1732 1.66 thorpej mii_down(&sc->sc_mii); 1733 1.44 thorpej } 1734 1.44 thorpej 1735 1.47 fvdl if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) { 1736 1.44 thorpej /* 1737 1.44 thorpej * Clear the FIFO buffer count, thus halting 1738 1.44 thorpej * any currently-running transactions. 1739 1.44 thorpej */ 1740 1.44 thorpej GO_WINDOW(1); /* sanity */ 1741 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_WRCTL, 0); 1742 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W1_RUNNER_RDCTL, 0); 1743 1.41 thorpej } 1744 1.41 thorpej 1745 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, RX_DISABLE); 1746 1.56 jonathan ep_discard_rxtop(iot, ioh); 1747 1.56 jonathan 1748 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, TX_DISABLE); 1749 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, STOP_TRANSCEIVER); 1750 1.18 jonathan 1751 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, RX_RESET); 1752 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, TX_RESET); 1753 1.18 jonathan 1754 1.102 christos bus_space_write_2(iot, ioh, ELINK_COMMAND, ACK_INTR | INTR_LATCH); 1755 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_RD_0_MASK); 1756 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_INTR_MASK); 1757 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_COMMAND, SET_RX_FILTER); 1758 1.1 thorpej 1759 1.1 thorpej epmbufempty(sc); 1760 1.88 jdolecek 1761 1.88 jdolecek if (disable) 1762 1.88 jdolecek epdisable(sc); 1763 1.88 jdolecek 1764 1.88 jdolecek ifp->if_flags &= ~IFF_RUNNING; 1765 1.1 thorpej } 1766 1.16 jonathan 1767 1.16 jonathan 1768 1.16 jonathan /* 1769 1.16 jonathan * Before reboots, reset card completely. 1770 1.16 jonathan */ 1771 1.128 tsutsui static bool 1772 1.128 tsutsui epshutdown(device_t self, int howto) 1773 1.16 jonathan { 1774 1.128 tsutsui struct ep_softc *sc = device_private(self); 1775 1.111 perry int s = splnet(); 1776 1.16 jonathan 1777 1.34 thorpej if (sc->enabled) { 1778 1.109 briggs epstop(&sc->sc_ethercom.ec_if, 0); 1779 1.56 jonathan ep_reset_cmd(sc, ELINK_COMMAND, GLOBAL_RESET); 1780 1.109 briggs epdisable(sc); 1781 1.56 jonathan sc->enabled = 0; 1782 1.34 thorpej } 1783 1.56 jonathan splx(s); 1784 1.128 tsutsui 1785 1.128 tsutsui return true; 1786 1.16 jonathan } 1787 1.1 thorpej 1788 1.1 thorpej /* 1789 1.1 thorpej * We get eeprom data from the id_port given an offset into the 1790 1.1 thorpej * eeprom. Basically; after the ID_sequence is sent to all of 1791 1.1 thorpej * the cards; they enter the ID_CMD state where they will accept 1792 1.1 thorpej * command requests. 0x80-0xbf loads the eeprom data. We then 1793 1.1 thorpej * read the port 16 times and with every read; the cards check 1794 1.1 thorpej * for contention (ie: if one card writes a 0 bit and another 1795 1.1 thorpej * writes a 1 bit then the host sees a 0. At the end of the cycle; 1796 1.1 thorpej * each card compares the data on the bus; if there is a difference 1797 1.1 thorpej * then that card goes into ID_WAIT state again). In the meantime; 1798 1.1 thorpej * one bit of data is returned in the AX register which is conveniently 1799 1.107 mycroft * returned to us by bus_space_read_2(). Hence; we read 16 times getting one 1800 1.1 thorpej * bit of data with each read. 1801 1.2 thorpej * 1802 1.2 thorpej * NOTE: the caller must provide an i/o handle for ELINK_ID_PORT! 1803 1.1 thorpej */ 1804 1.2 thorpej u_int16_t 1805 1.127 christos epreadeeprom(bus_space_tag_t iot, bus_space_handle_t ioh, int offset) 1806 1.1 thorpej { 1807 1.2 thorpej u_int16_t data = 0; 1808 1.2 thorpej int i; 1809 1.1 thorpej 1810 1.107 mycroft bus_space_write_2(iot, ioh, 0, 0x80 + offset); 1811 1.1 thorpej delay(1000); 1812 1.1 thorpej for (i = 0; i < 16; i++) 1813 1.11 thorpej data = (data << 1) | (bus_space_read_2(iot, ioh, 0) & 1); 1814 1.1 thorpej return (data); 1815 1.1 thorpej } 1816 1.1 thorpej 1817 1.1 thorpej static int 1818 1.127 christos epbusyeeprom(struct ep_softc *sc) 1819 1.1 thorpej { 1820 1.11 thorpej bus_space_tag_t iot = sc->sc_iot; 1821 1.11 thorpej bus_space_handle_t ioh = sc->sc_ioh; 1822 1.101 soren bus_size_t eecmd; 1823 1.1 thorpej int i = 100, j; 1824 1.96 thorpej uint16_t busybit; 1825 1.1 thorpej 1826 1.47 fvdl if (sc->bustype == ELINK_BUS_PCMCIA) { 1827 1.1 thorpej delay(1000); 1828 1.1 thorpej return 0; 1829 1.1 thorpej } 1830 1.1 thorpej 1831 1.96 thorpej if (sc->ep_chipset == ELINK_CHIPSET_CORKSCREW) { 1832 1.96 thorpej eecmd = CORK_ASIC_EEPROM_COMMAND; 1833 1.96 thorpej busybit = CORK_EEPROM_BUSY; 1834 1.96 thorpej } else { 1835 1.96 thorpej eecmd = ELINK_W0_EEPROM_COMMAND; 1836 1.96 thorpej busybit = EEPROM_BUSY; 1837 1.96 thorpej } 1838 1.96 thorpej 1839 1.33 jonathan j = 0; /* bad GCC flow analysis */ 1840 1.1 thorpej while (i--) { 1841 1.96 thorpej j = bus_space_read_2(iot, ioh, eecmd); 1842 1.96 thorpej if (j & busybit) 1843 1.1 thorpej delay(100); 1844 1.1 thorpej else 1845 1.1 thorpej break; 1846 1.1 thorpej } 1847 1.96 thorpej if (i == 0) { 1848 1.125 cegger aprint_normal("\n"); 1849 1.127 christos aprint_error_dev(sc->sc_dev, "eeprom failed to come ready\n"); 1850 1.1 thorpej return (1); 1851 1.1 thorpej } 1852 1.96 thorpej if (sc->ep_chipset != ELINK_CHIPSET_CORKSCREW && 1853 1.96 thorpej (j & EEPROM_TST_MODE) != 0) { 1854 1.29 jonathan /* XXX PnP mode? */ 1855 1.127 christos printf("\n%s: erase pencil mark!\n", device_xname(sc->sc_dev)); 1856 1.1 thorpej return (1); 1857 1.1 thorpej } 1858 1.1 thorpej return (0); 1859 1.59 thorpej } 1860 1.59 thorpej 1861 1.59 thorpej u_int16_t 1862 1.127 christos ep_read_eeprom(struct ep_softc *sc, u_int16_t offset) 1863 1.59 thorpej { 1864 1.101 soren bus_size_t eecmd, eedata; 1865 1.59 thorpej u_int16_t readcmd; 1866 1.59 thorpej 1867 1.96 thorpej if (sc->ep_chipset == ELINK_CHIPSET_CORKSCREW) { 1868 1.96 thorpej eecmd = CORK_ASIC_EEPROM_COMMAND; 1869 1.96 thorpej eedata = CORK_ASIC_EEPROM_DATA; 1870 1.96 thorpej } else { 1871 1.96 thorpej eecmd = ELINK_W0_EEPROM_COMMAND; 1872 1.96 thorpej eedata = ELINK_W0_EEPROM_DATA; 1873 1.96 thorpej } 1874 1.96 thorpej 1875 1.59 thorpej /* 1876 1.59 thorpej * RoadRunner has a larger EEPROM, so a different read command 1877 1.59 thorpej * is required. 1878 1.59 thorpej */ 1879 1.59 thorpej if (sc->ep_chipset == ELINK_CHIPSET_ROADRUNNER) 1880 1.59 thorpej readcmd = READ_EEPROM_RR; 1881 1.59 thorpej else 1882 1.59 thorpej readcmd = READ_EEPROM; 1883 1.59 thorpej 1884 1.59 thorpej if (epbusyeeprom(sc)) 1885 1.59 thorpej return (0); /* XXX why is eeprom busy? */ 1886 1.96 thorpej 1887 1.96 thorpej bus_space_write_2(sc->sc_iot, sc->sc_ioh, eecmd, readcmd | offset); 1888 1.96 thorpej 1889 1.59 thorpej if (epbusyeeprom(sc)) 1890 1.59 thorpej return (0); /* XXX why is eeprom busy? */ 1891 1.96 thorpej 1892 1.96 thorpej return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, eedata)); 1893 1.1 thorpej } 1894 1.1 thorpej 1895 1.1 thorpej void 1896 1.127 christos epmbuffill(void *v) 1897 1.1 thorpej { 1898 1.3 christos struct ep_softc *sc = v; 1899 1.51 mycroft struct mbuf *m; 1900 1.1 thorpej int s, i; 1901 1.1 thorpej 1902 1.1 thorpej s = splnet(); 1903 1.1 thorpej i = sc->last_mb; 1904 1.1 thorpej do { 1905 1.51 mycroft if (sc->mb[i] == 0) { 1906 1.51 mycroft MGET(m, M_DONTWAIT, MT_DATA); 1907 1.51 mycroft if (m == 0) 1908 1.51 mycroft break; 1909 1.51 mycroft sc->mb[i] = m; 1910 1.51 mycroft } 1911 1.1 thorpej i = (i + 1) % MAX_MBS; 1912 1.1 thorpej } while (i != sc->next_mb); 1913 1.1 thorpej sc->last_mb = i; 1914 1.1 thorpej /* If the queue was not filled, try again. */ 1915 1.1 thorpej if (sc->last_mb != sc->next_mb) 1916 1.152 thorpej callout_schedule(&sc->sc_mbuf_callout, 1); 1917 1.1 thorpej splx(s); 1918 1.1 thorpej } 1919 1.1 thorpej 1920 1.1 thorpej void 1921 1.127 christos epmbufempty(struct ep_softc *sc) 1922 1.1 thorpej { 1923 1.1 thorpej int s, i; 1924 1.1 thorpej 1925 1.1 thorpej s = splnet(); 1926 1.127 christos for (i = 0; i < MAX_MBS; i++) { 1927 1.154 rin m_freem(sc->mb[i]); 1928 1.154 rin sc->mb[i] = NULL; 1929 1.1 thorpej } 1930 1.1 thorpej sc->last_mb = sc->next_mb = 0; 1931 1.78 thorpej callout_stop(&sc->sc_mbuf_callout); 1932 1.1 thorpej splx(s); 1933 1.34 thorpej } 1934 1.34 thorpej 1935 1.34 thorpej int 1936 1.127 christos epenable(struct ep_softc *sc) 1937 1.34 thorpej { 1938 1.34 thorpej 1939 1.34 thorpej if (sc->enabled == 0 && sc->enable != NULL) { 1940 1.34 thorpej if ((*sc->enable)(sc) != 0) { 1941 1.127 christos aprint_error_dev(sc->sc_dev, "device enable failed\n"); 1942 1.34 thorpej return (EIO); 1943 1.34 thorpej } 1944 1.34 thorpej } 1945 1.34 thorpej 1946 1.34 thorpej sc->enabled = 1; 1947 1.34 thorpej return (0); 1948 1.34 thorpej } 1949 1.34 thorpej 1950 1.34 thorpej void 1951 1.127 christos epdisable(struct ep_softc *sc) 1952 1.34 thorpej { 1953 1.34 thorpej 1954 1.34 thorpej if (sc->enabled != 0 && sc->disable != NULL) { 1955 1.34 thorpej (*sc->disable)(sc); 1956 1.34 thorpej sc->enabled = 0; 1957 1.34 thorpej } 1958 1.50 thorpej } 1959 1.50 thorpej 1960 1.74 enami /* 1961 1.74 enami * ep_activate: 1962 1.74 enami * 1963 1.74 enami * Handle device activation/deactivation requests. 1964 1.74 enami */ 1965 1.50 thorpej int 1966 1.127 christos ep_activate(device_t self, enum devact act) 1967 1.50 thorpej { 1968 1.127 christos struct ep_softc *sc = device_private(self); 1969 1.50 thorpej 1970 1.50 thorpej switch (act) { 1971 1.50 thorpej case DVACT_DEACTIVATE: 1972 1.129 dyoung if_deactivate(&sc->sc_ethercom.ec_if); 1973 1.129 dyoung return 0; 1974 1.129 dyoung default: 1975 1.129 dyoung return EOPNOTSUPP; 1976 1.50 thorpej } 1977 1.68 augustss } 1978 1.68 augustss 1979 1.74 enami /* 1980 1.74 enami * ep_detach: 1981 1.74 enami * 1982 1.74 enami * Detach a elink3 interface. 1983 1.74 enami */ 1984 1.68 augustss int 1985 1.127 christos ep_detach(device_t self, int flags) 1986 1.68 augustss { 1987 1.127 christos struct ep_softc *sc = device_private(self); 1988 1.70 augustss struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1989 1.81 jhawk 1990 1.81 jhawk /* Succeed now if there's no work to do. */ 1991 1.81 jhawk if ((sc->sc_flags & ELINK_FLAGS_ATTACHED) == 0) 1992 1.81 jhawk return (0); 1993 1.68 augustss 1994 1.70 augustss epdisable(sc); 1995 1.68 augustss 1996 1.78 thorpej callout_stop(&sc->sc_mii_callout); 1997 1.78 thorpej callout_stop(&sc->sc_mbuf_callout); 1998 1.71 augustss 1999 1.74 enami if (sc->ep_flags & ELINK_FLAGS_MII) { 2000 1.74 enami /* Detach all PHYs */ 2001 1.74 enami mii_detach(&sc->sc_mii, MII_PHY_ANY, MII_OFFSET_ANY); 2002 1.74 enami } 2003 1.74 enami 2004 1.72 augustss rnd_detach_source(&sc->rnd_source); 2005 1.70 augustss ether_ifdetach(ifp); 2006 1.70 augustss if_detach(ifp); 2007 1.70 augustss 2008 1.151 thorpej /* Delete all remaining media. */ 2009 1.151 thorpej ifmedia_fini(&sc->sc_mii.mii_media); 2010 1.151 thorpej 2011 1.128 tsutsui pmf_device_deregister(sc->sc_dev); 2012 1.68 augustss 2013 1.68 augustss return (0); 2014 1.41 thorpej } 2015 1.41 thorpej 2016 1.67 thorpej u_int32_t 2017 1.127 christos ep_mii_bitbang_read(device_t self) 2018 1.41 thorpej { 2019 1.127 christos struct ep_softc *sc = device_private(self); 2020 1.41 thorpej 2021 1.67 thorpej /* We're already in Window 4. */ 2022 1.67 thorpej return (bus_space_read_2(sc->sc_iot, sc->sc_ioh, 2023 1.67 thorpej ELINK_W4_BOOM_PHYSMGMT)); 2024 1.41 thorpej } 2025 1.41 thorpej 2026 1.41 thorpej void 2027 1.127 christos ep_mii_bitbang_write(device_t self, u_int32_t val) 2028 1.41 thorpej { 2029 1.127 christos struct ep_softc *sc = device_private(self); 2030 1.41 thorpej 2031 1.67 thorpej /* We're already in Window 4. */ 2032 1.67 thorpej bus_space_write_2(sc->sc_iot, sc->sc_ioh, 2033 1.67 thorpej ELINK_W4_BOOM_PHYSMGMT, val); 2034 1.41 thorpej } 2035 1.41 thorpej 2036 1.41 thorpej int 2037 1.144 msaitoh ep_mii_readreg(device_t self, int phy, int reg, uint16_t *val) 2038 1.41 thorpej { 2039 1.127 christos struct ep_softc *sc = device_private(self); 2040 1.144 msaitoh int rv; 2041 1.41 thorpej 2042 1.41 thorpej GO_WINDOW(4); 2043 1.41 thorpej 2044 1.144 msaitoh rv = mii_bitbang_readreg(self, &ep_mii_bitbang_ops, phy, reg, val); 2045 1.41 thorpej 2046 1.67 thorpej GO_WINDOW(1); 2047 1.41 thorpej 2048 1.144 msaitoh return rv; 2049 1.41 thorpej } 2050 1.41 thorpej 2051 1.144 msaitoh int 2052 1.144 msaitoh ep_mii_writereg(device_t self, int phy, int reg, uint16_t val) 2053 1.41 thorpej { 2054 1.127 christos struct ep_softc *sc = device_private(self); 2055 1.144 msaitoh int rv; 2056 1.41 thorpej 2057 1.41 thorpej GO_WINDOW(4); 2058 1.41 thorpej 2059 1.144 msaitoh rv = mii_bitbang_writereg(self, &ep_mii_bitbang_ops, phy, reg, val); 2060 1.41 thorpej 2061 1.67 thorpej GO_WINDOW(1); 2062 1.144 msaitoh 2063 1.144 msaitoh return rv; 2064 1.41 thorpej } 2065 1.41 thorpej 2066 1.41 thorpej void 2067 1.133 matt ep_statchg(struct ifnet *ifp) 2068 1.41 thorpej { 2069 1.133 matt struct ep_softc *sc = ifp->if_softc; 2070 1.45 thorpej bus_space_tag_t iot = sc->sc_iot; 2071 1.45 thorpej bus_space_handle_t ioh = sc->sc_ioh; 2072 1.45 thorpej int mctl; 2073 1.45 thorpej 2074 1.45 thorpej GO_WINDOW(3); 2075 1.47 fvdl mctl = bus_space_read_2(iot, ioh, ELINK_W3_MAC_CONTROL); 2076 1.45 thorpej if (sc->sc_mii.mii_media_active & IFM_FDX) 2077 1.45 thorpej mctl |= MAC_CONTROL_FDX; 2078 1.45 thorpej else 2079 1.45 thorpej mctl &= ~MAC_CONTROL_FDX; 2080 1.47 fvdl bus_space_write_2(iot, ioh, ELINK_W3_MAC_CONTROL, mctl); 2081 1.45 thorpej GO_WINDOW(1); /* back to operating window */ 2082 1.1 thorpej } 2083 1.117 peter 2084 1.117 peter void 2085 1.117 peter ep_power(int why, void *arg) 2086 1.117 peter { 2087 1.117 peter struct ep_softc *sc = arg; 2088 1.117 peter struct ifnet *ifp = &sc->sc_ethercom.ec_if; 2089 1.117 peter int s; 2090 1.117 peter 2091 1.117 peter s = splnet(); 2092 1.117 peter switch (why) { 2093 1.117 peter case PWR_SUSPEND: 2094 1.117 peter case PWR_STANDBY: 2095 1.117 peter epstop(ifp, 1); 2096 1.117 peter break; 2097 1.117 peter case PWR_RESUME: 2098 1.117 peter if (ifp->if_flags & IFF_UP) { 2099 1.117 peter (void)epinit(ifp); 2100 1.117 peter } 2101 1.117 peter break; 2102 1.117 peter case PWR_SOFTSUSPEND: 2103 1.117 peter case PWR_SOFTSTANDBY: 2104 1.117 peter case PWR_SOFTRESUME: 2105 1.117 peter break; 2106 1.117 peter } 2107 1.117 peter splx(s); 2108 1.117 peter } 2109