1 1.98 thorpej /* $NetBSD: be.c,v 1.98 2022/09/25 18:03:04 thorpej Exp $ */ 2 1.1 pk 3 1.1 pk /*- 4 1.1 pk * Copyright (c) 1999 The NetBSD Foundation, Inc. 5 1.1 pk * All rights reserved. 6 1.1 pk * 7 1.1 pk * This code is derived from software contributed to The NetBSD Foundation 8 1.1 pk * by Paul Kranenburg. 9 1.1 pk * 10 1.1 pk * Redistribution and use in source and binary forms, with or without 11 1.1 pk * modification, are permitted provided that the following conditions 12 1.1 pk * are met: 13 1.1 pk * 1. Redistributions of source code must retain the above copyright 14 1.1 pk * notice, this list of conditions and the following disclaimer. 15 1.1 pk * 2. Redistributions in binary form must reproduce the above copyright 16 1.1 pk * notice, this list of conditions and the following disclaimer in the 17 1.1 pk * documentation and/or other materials provided with the distribution. 18 1.1 pk * 19 1.1 pk * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 1.1 pk * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 1.1 pk * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 1.1 pk * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 1.1 pk * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 1.1 pk * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 1.1 pk * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 1.1 pk * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 1.1 pk * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 1.1 pk * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 1.1 pk * POSSIBILITY OF SUCH DAMAGE. 30 1.1 pk */ 31 1.1 pk 32 1.1 pk /* 33 1.1 pk * Copyright (c) 1998 Theo de Raadt and Jason L. Wright. 34 1.1 pk * All rights reserved. 35 1.1 pk * 36 1.1 pk * Redistribution and use in source and binary forms, with or without 37 1.1 pk * modification, are permitted provided that the following conditions 38 1.1 pk * are met: 39 1.1 pk * 1. Redistributions of source code must retain the above copyright 40 1.1 pk * notice, this list of conditions and the following disclaimer. 41 1.1 pk * 2. Redistributions in binary form must reproduce the above copyright 42 1.1 pk * notice, this list of conditions and the following disclaimer in the 43 1.1 pk * documentation and/or other materials provided with the distribution. 44 1.1 pk * 3. The name of the authors may not be used to endorse or promote products 45 1.1 pk * derived from this software without specific prior written permission. 46 1.1 pk * 47 1.1 pk * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR 48 1.1 pk * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 49 1.1 pk * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 50 1.1 pk * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT, 51 1.1 pk * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 52 1.1 pk * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 53 1.1 pk * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 54 1.1 pk * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 55 1.1 pk * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 56 1.1 pk * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 57 1.1 pk */ 58 1.29 lukem 59 1.29 lukem #include <sys/cdefs.h> 60 1.98 thorpej __KERNEL_RCSID(0, "$NetBSD: be.c,v 1.98 2022/09/25 18:03:04 thorpej Exp $"); 61 1.1 pk 62 1.1 pk #include "opt_ddb.h" 63 1.1 pk #include "opt_inet.h" 64 1.1 pk 65 1.1 pk #include <sys/param.h> 66 1.1 pk #include <sys/systm.h> 67 1.17 thorpej #include <sys/callout.h> 68 1.1 pk #include <sys/kernel.h> 69 1.1 pk #include <sys/errno.h> 70 1.1 pk #include <sys/ioctl.h> 71 1.1 pk #include <sys/mbuf.h> 72 1.1 pk #include <sys/socket.h> 73 1.1 pk #include <sys/syslog.h> 74 1.1 pk #include <sys/device.h> 75 1.1 pk 76 1.1 pk #include <net/if.h> 77 1.1 pk #include <net/if_dl.h> 78 1.1 pk #include <net/if_types.h> 79 1.1 pk #include <net/if_media.h> 80 1.1 pk #include <net/if_ether.h> 81 1.87 msaitoh #include <net/bpf.h> 82 1.1 pk 83 1.1 pk #ifdef INET 84 1.1 pk #include <netinet/in.h> 85 1.1 pk #include <netinet/if_inarp.h> 86 1.1 pk #include <netinet/in_systm.h> 87 1.1 pk #include <netinet/in_var.h> 88 1.1 pk #include <netinet/ip.h> 89 1.1 pk #endif 90 1.1 pk 91 1.55 ad #include <sys/bus.h> 92 1.55 ad #include <sys/intr.h> 93 1.1 pk #include <machine/autoconf.h> 94 1.1 pk 95 1.1 pk #include <dev/mii/mii.h> 96 1.1 pk #include <dev/mii/miivar.h> 97 1.1 pk 98 1.92 msaitoh #include <dev/sbus/sbusvar.h> 99 1.1 pk #include <dev/sbus/qecreg.h> 100 1.1 pk #include <dev/sbus/qecvar.h> 101 1.1 pk #include <dev/sbus/bereg.h> 102 1.1 pk 103 1.1 pk struct be_softc { 104 1.69 tsutsui device_t sc_dev; 105 1.39 wiz bus_space_tag_t sc_bustag; /* bus & DMA tags */ 106 1.1 pk bus_dma_tag_t sc_dmatag; 107 1.18 pk bus_dmamap_t sc_dmamap; 108 1.1 pk struct ethercom sc_ethercom; 109 1.1 pk /*struct ifmedia sc_ifmedia; -* interface media */ 110 1.1 pk struct mii_data sc_mii; /* MII media control */ 111 1.1 pk #define sc_media sc_mii.mii_media/* shorthand */ 112 1.11 pk int sc_phys[2]; /* MII instance -> phy */ 113 1.1 pk 114 1.17 thorpej struct callout sc_tick_ch; 115 1.17 thorpej 116 1.12 pk /* 117 1.12 pk * Some `mii_softc' items we need to emulate MII operation 118 1.12 pk * for our internal transceiver. 119 1.12 pk */ 120 1.12 pk int sc_mii_inst; /* instance of internal phy */ 121 1.12 pk int sc_mii_active; /* currently active medium */ 122 1.12 pk int sc_mii_ticks; /* tick counter */ 123 1.13 pk int sc_mii_flags; /* phy status flags */ 124 1.13 pk #define MIIF_HAVELINK 0x04000000 125 1.13 pk int sc_intphy_curspeed; /* Established link speed */ 126 1.12 pk 127 1.1 pk struct qec_softc *sc_qec; /* QEC parent */ 128 1.1 pk 129 1.1 pk bus_space_handle_t sc_qr; /* QEC registers */ 130 1.1 pk bus_space_handle_t sc_br; /* BE registers */ 131 1.1 pk bus_space_handle_t sc_cr; /* channel registers */ 132 1.1 pk bus_space_handle_t sc_tr; /* transceiver registers */ 133 1.1 pk 134 1.1 pk u_int sc_rev; 135 1.1 pk 136 1.1 pk int sc_channel; /* channel number */ 137 1.1 pk int sc_burst; 138 1.1 pk 139 1.92 msaitoh struct qec_ring sc_rb; /* Packet Ring Buffer */ 140 1.1 pk 141 1.1 pk /* MAC address */ 142 1.73 tsutsui uint8_t sc_enaddr[ETHER_ADDR_LEN]; 143 1.43 pk #ifdef BEDEBUG 144 1.43 pk int sc_debug; 145 1.43 pk #endif 146 1.1 pk }; 147 1.1 pk 148 1.72 tsutsui static int bematch(device_t, cfdata_t, void *); 149 1.72 tsutsui static void beattach(device_t, device_t, void *); 150 1.1 pk 151 1.72 tsutsui static int beinit(struct ifnet *); 152 1.72 tsutsui static void bestart(struct ifnet *); 153 1.72 tsutsui static void bestop(struct ifnet *, int); 154 1.72 tsutsui static void bewatchdog(struct ifnet *); 155 1.72 tsutsui static int beioctl(struct ifnet *, u_long, void *); 156 1.72 tsutsui static void bereset(struct be_softc *); 157 1.72 tsutsui static void behwreset(struct be_softc *); 158 1.72 tsutsui 159 1.72 tsutsui static int beintr(void *); 160 1.72 tsutsui static int berint(struct be_softc *); 161 1.72 tsutsui static int betint(struct be_softc *); 162 1.73 tsutsui static int beqint(struct be_softc *, uint32_t); 163 1.73 tsutsui static int beeint(struct be_softc *, uint32_t); 164 1.45 perry 165 1.45 perry static void be_read(struct be_softc *, int, int); 166 1.45 perry static int be_put(struct be_softc *, int, struct mbuf *); 167 1.45 perry static struct mbuf *be_get(struct be_softc *, int, int); 168 1.1 pk 169 1.72 tsutsui static void be_pal_gate(struct be_softc *, int); 170 1.1 pk 171 1.1 pk /* ifmedia callbacks */ 172 1.72 tsutsui static void be_ifmedia_sts(struct ifnet *, struct ifmediareq *); 173 1.72 tsutsui static int be_ifmedia_upd(struct ifnet *); 174 1.2 pk 175 1.72 tsutsui static void be_mcreset(struct be_softc *); 176 1.1 pk 177 1.1 pk /* MII methods & callbacks */ 178 1.90 msaitoh static int be_mii_readreg(device_t, int, int, uint16_t *); 179 1.90 msaitoh static int be_mii_writereg(device_t, int, int, uint16_t); 180 1.79 matt static void be_mii_statchg(struct ifnet *); 181 1.1 pk 182 1.1 pk /* MII helpers */ 183 1.45 perry static void be_mii_sync(struct be_softc *); 184 1.73 tsutsui static void be_mii_sendbits(struct be_softc *, int, uint32_t, int); 185 1.45 perry static int be_mii_reset(struct be_softc *, int); 186 1.45 perry static int be_tcvr_read_bit(struct be_softc *, int); 187 1.45 perry static void be_tcvr_write_bit(struct be_softc *, int, int); 188 1.45 perry 189 1.72 tsutsui static void be_tick(void *); 190 1.72 tsutsui #if 0 191 1.72 tsutsui static void be_intphy_auto(struct be_softc *); 192 1.72 tsutsui #endif 193 1.72 tsutsui static void be_intphy_status(struct be_softc *); 194 1.72 tsutsui static int be_intphy_service(struct be_softc *, struct mii_data *, int); 195 1.1 pk 196 1.1 pk 197 1.69 tsutsui CFATTACH_DECL_NEW(be, sizeof(struct be_softc), 198 1.37 thorpej bematch, beattach, NULL, NULL); 199 1.1 pk 200 1.1 pk int 201 1.65 cegger bematch(device_t parent, cfdata_t cf, void *aux) 202 1.1 pk { 203 1.1 pk struct sbus_attach_args *sa = aux; 204 1.1 pk 205 1.73 tsutsui return strcmp(cf->cf_name, sa->sa_name) == 0; 206 1.1 pk } 207 1.1 pk 208 1.1 pk void 209 1.65 cegger beattach(device_t parent, device_t self, void *aux) 210 1.1 pk { 211 1.1 pk struct sbus_attach_args *sa = aux; 212 1.67 tsutsui struct qec_softc *qec = device_private(parent); 213 1.67 tsutsui struct be_softc *sc = device_private(self); 214 1.1 pk struct ifnet *ifp = &sc->sc_ethercom.ec_if; 215 1.1 pk struct mii_data *mii = &sc->sc_mii; 216 1.11 pk struct mii_softc *child; 217 1.1 pk int node = sa->sa_node; 218 1.18 pk bus_dma_tag_t dmatag = sa->sa_dmatag; 219 1.1 pk bus_dma_segment_t seg; 220 1.1 pk bus_size_t size; 221 1.18 pk int instance; 222 1.1 pk int rseg, error; 223 1.73 tsutsui uint32_t v; 224 1.1 pk 225 1.69 tsutsui sc->sc_dev = self; 226 1.69 tsutsui 227 1.1 pk if (sa->sa_nreg < 3) { 228 1.70 tsutsui printf(": only %d register sets\n", sa->sa_nreg); 229 1.1 pk return; 230 1.1 pk } 231 1.1 pk 232 1.30 pk if (bus_space_map(sa->sa_bustag, 233 1.73 tsutsui (bus_addr_t)BUS_ADDR(sa->sa_reg[0].oa_space, sa->sa_reg[0].oa_base), 234 1.73 tsutsui (bus_size_t)sa->sa_reg[0].oa_size, 235 1.73 tsutsui 0, &sc->sc_cr) != 0) { 236 1.70 tsutsui printf(": cannot map registers\n"); 237 1.1 pk return; 238 1.1 pk } 239 1.1 pk 240 1.30 pk if (bus_space_map(sa->sa_bustag, 241 1.73 tsutsui (bus_addr_t)BUS_ADDR(sa->sa_reg[1].oa_space, sa->sa_reg[1].oa_base), 242 1.73 tsutsui (bus_size_t)sa->sa_reg[1].oa_size, 243 1.73 tsutsui 0, &sc->sc_br) != 0) { 244 1.70 tsutsui printf(": cannot map registers\n"); 245 1.1 pk return; 246 1.1 pk } 247 1.1 pk 248 1.30 pk if (bus_space_map(sa->sa_bustag, 249 1.73 tsutsui (bus_addr_t)BUS_ADDR(sa->sa_reg[2].oa_space, sa->sa_reg[2].oa_base), 250 1.73 tsutsui (bus_size_t)sa->sa_reg[2].oa_size, 251 1.73 tsutsui 0, &sc->sc_tr) != 0) { 252 1.70 tsutsui printf(": cannot map registers\n"); 253 1.1 pk return; 254 1.1 pk } 255 1.1 pk 256 1.27 eeh sc->sc_bustag = sa->sa_bustag; 257 1.1 pk sc->sc_qec = qec; 258 1.1 pk sc->sc_qr = qec->sc_regs; 259 1.1 pk 260 1.42 pk sc->sc_rev = prom_getpropint(node, "board-version", -1); 261 1.70 tsutsui printf(": rev %x,", sc->sc_rev); 262 1.1 pk 263 1.61 macallan callout_init(&sc->sc_tick_ch, 0); 264 1.61 macallan 265 1.42 pk sc->sc_channel = prom_getpropint(node, "channel#", -1); 266 1.1 pk if (sc->sc_channel == -1) 267 1.1 pk sc->sc_channel = 0; 268 1.1 pk 269 1.42 pk sc->sc_burst = prom_getpropint(node, "burst-sizes", -1); 270 1.1 pk if (sc->sc_burst == -1) 271 1.1 pk sc->sc_burst = qec->sc_burst; 272 1.1 pk 273 1.1 pk /* Clamp at parent's burst sizes */ 274 1.1 pk sc->sc_burst &= qec->sc_burst; 275 1.1 pk 276 1.9 pk /* Establish interrupt handler */ 277 1.9 pk if (sa->sa_nintr) 278 1.21 pk (void)bus_intr_establish(sa->sa_bustag, sa->sa_pri, IPL_NET, 279 1.73 tsutsui beintr, sc); 280 1.1 pk 281 1.41 pk prom_getether(node, sc->sc_enaddr); 282 1.1 pk printf(" address %s\n", ether_sprintf(sc->sc_enaddr)); 283 1.1 pk 284 1.1 pk /* 285 1.1 pk * Allocate descriptor ring and buffers. 286 1.1 pk */ 287 1.2 pk 288 1.2 pk /* for now, allocate as many bufs as there are ring descriptors */ 289 1.2 pk sc->sc_rb.rb_ntbuf = QEC_XD_RING_MAXSIZE; 290 1.2 pk sc->sc_rb.rb_nrbuf = QEC_XD_RING_MAXSIZE; 291 1.1 pk 292 1.73 tsutsui size = 293 1.73 tsutsui QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) + 294 1.73 tsutsui QEC_XD_RING_MAXSIZE * sizeof(struct qec_xd) + 295 1.73 tsutsui sc->sc_rb.rb_ntbuf * BE_PKT_BUF_SZ + 296 1.73 tsutsui sc->sc_rb.rb_nrbuf * BE_PKT_BUF_SZ; 297 1.18 pk 298 1.19 pk /* Get a DMA handle */ 299 1.19 pk if ((error = bus_dmamap_create(dmatag, size, 1, size, 0, 300 1.73 tsutsui BUS_DMA_NOWAIT, &sc->sc_dmamap)) != 0) { 301 1.57 cegger aprint_error_dev(self, "DMA map create error %d\n", error); 302 1.18 pk return; 303 1.18 pk } 304 1.18 pk 305 1.18 pk /* Allocate DMA buffer */ 306 1.20 pk if ((error = bus_dmamem_alloc(sa->sa_dmatag, size, 0, 0, 307 1.73 tsutsui &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) { 308 1.73 tsutsui aprint_error_dev(self, "DMA buffer alloc error %d\n", error); 309 1.1 pk return; 310 1.1 pk } 311 1.18 pk 312 1.18 pk /* Map DMA memory in CPU addressable space */ 313 1.1 pk if ((error = bus_dmamem_map(sa->sa_dmatag, &seg, rseg, size, 314 1.92 msaitoh &sc->sc_rb.rb_membase, BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 315 1.73 tsutsui aprint_error_dev(self, "DMA buffer map error %d\n", error); 316 1.1 pk bus_dmamem_free(sa->sa_dmatag, &seg, rseg); 317 1.25 thorpej return; 318 1.25 thorpej } 319 1.25 thorpej 320 1.25 thorpej /* Load the buffer */ 321 1.25 thorpej if ((error = bus_dmamap_load(dmatag, sc->sc_dmamap, 322 1.73 tsutsui sc->sc_rb.rb_membase, size, NULL, BUS_DMA_NOWAIT)) != 0) { 323 1.73 tsutsui aprint_error_dev(self, "DMA buffer map load error %d\n", error); 324 1.25 thorpej bus_dmamem_unmap(dmatag, sc->sc_rb.rb_membase, size); 325 1.25 thorpej bus_dmamem_free(dmatag, &seg, rseg); 326 1.1 pk return; 327 1.1 pk } 328 1.26 pk sc->sc_rb.rb_dmabase = sc->sc_dmamap->dm_segs[0].ds_addr; 329 1.1 pk 330 1.1 pk /* 331 1.1 pk * Initialize our media structures and MII info. 332 1.1 pk */ 333 1.1 pk mii->mii_ifp = ifp; 334 1.1 pk mii->mii_readreg = be_mii_readreg; 335 1.1 pk mii->mii_writereg = be_mii_writereg; 336 1.10 pk mii->mii_statchg = be_mii_statchg; 337 1.1 pk 338 1.94 msaitoh sc->sc_ethercom.ec_mii = mii; 339 1.1 pk ifmedia_init(&mii->mii_media, 0, be_ifmedia_upd, be_ifmedia_sts); 340 1.1 pk 341 1.11 pk /* 342 1.11 pk * Initialize transceiver and determine which PHY connection to use. 343 1.11 pk */ 344 1.11 pk be_mii_sync(sc); 345 1.11 pk v = bus_space_read_4(sc->sc_bustag, sc->sc_tr, BE_TRI_MGMTPAL); 346 1.11 pk 347 1.11 pk instance = 0; 348 1.11 pk 349 1.11 pk if ((v & MGMT_PAL_EXT_MDIO) != 0) { 350 1.10 pk 351 1.67 tsutsui mii_attach(self, mii, 0xffffffff, BE_PHY_EXTERNAL, 352 1.15 thorpej MII_OFFSET_ANY, 0); 353 1.1 pk 354 1.11 pk child = LIST_FIRST(&mii->mii_phys); 355 1.11 pk if (child == NULL) { 356 1.1 pk /* No PHY attached */ 357 1.11 pk ifmedia_add(&sc->sc_media, 358 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, instance), 359 1.73 tsutsui 0, NULL); 360 1.11 pk ifmedia_set(&sc->sc_media, 361 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_NONE, 0, instance)); 362 1.1 pk } else { 363 1.1 pk /* 364 1.11 pk * Note: we support just one PHY on the external 365 1.11 pk * MII connector. 366 1.11 pk */ 367 1.11 pk #ifdef DIAGNOSTIC 368 1.11 pk if (LIST_NEXT(child, mii_list) != NULL) { 369 1.67 tsutsui aprint_error_dev(self, 370 1.67 tsutsui "spurious MII device %s attached\n", 371 1.67 tsutsui device_xname(child->mii_dev)); 372 1.11 pk } 373 1.11 pk #endif 374 1.11 pk if (child->mii_phy != BE_PHY_EXTERNAL || 375 1.11 pk child->mii_inst > 0) { 376 1.67 tsutsui aprint_error_dev(self, 377 1.67 tsutsui "cannot accommodate MII device %s" 378 1.67 tsutsui " at phy %d, instance %d\n", 379 1.59 xtraeme device_xname(child->mii_dev), 380 1.11 pk child->mii_phy, child->mii_inst); 381 1.11 pk } else { 382 1.11 pk sc->sc_phys[instance] = child->mii_phy; 383 1.11 pk } 384 1.11 pk 385 1.11 pk /* 386 1.1 pk * XXX - we can really do the following ONLY if the 387 1.1 pk * phy indeed has the auto negotiation capability!! 388 1.1 pk */ 389 1.11 pk ifmedia_set(&sc->sc_media, 390 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance)); 391 1.11 pk 392 1.11 pk /* Mark our current media setting */ 393 1.11 pk be_pal_gate(sc, BE_PHY_EXTERNAL); 394 1.11 pk instance++; 395 1.1 pk } 396 1.11 pk 397 1.11 pk } 398 1.11 pk 399 1.11 pk if ((v & MGMT_PAL_INT_MDIO) != 0) { 400 1.1 pk /* 401 1.1 pk * The be internal phy looks vaguely like MII hardware, 402 1.1 pk * but not enough to be able to use the MII device 403 1.1 pk * layer. Hence, we have to take care of media selection 404 1.1 pk * ourselves. 405 1.1 pk */ 406 1.1 pk 407 1.12 pk sc->sc_mii_inst = instance; 408 1.11 pk sc->sc_phys[instance] = BE_PHY_INTERNAL; 409 1.11 pk 410 1.1 pk /* Use `ifm_data' to store BMCR bits */ 411 1.1 pk ifmedia_add(&sc->sc_media, 412 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_10_T, 0, instance), 413 1.73 tsutsui 0, NULL); 414 1.1 pk ifmedia_add(&sc->sc_media, 415 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_100_TX, 0, instance), 416 1.73 tsutsui BMCR_S100, NULL); 417 1.1 pk ifmedia_add(&sc->sc_media, 418 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance), 419 1.73 tsutsui 0, NULL); 420 1.11 pk 421 1.13 pk printf("on-board transceiver at %s: 10baseT, 100baseTX, auto\n", 422 1.73 tsutsui device_xname(self)); 423 1.13 pk 424 1.12 pk be_mii_reset(sc, BE_PHY_INTERNAL); 425 1.11 pk /* Only set default medium here if there's no external PHY */ 426 1.11 pk if (instance == 0) { 427 1.11 pk be_pal_gate(sc, BE_PHY_INTERNAL); 428 1.11 pk ifmedia_set(&sc->sc_media, 429 1.73 tsutsui IFM_MAKEWORD(IFM_ETHER, IFM_AUTO, 0, instance)); 430 1.12 pk } else 431 1.67 tsutsui be_mii_writereg(self, 432 1.73 tsutsui BE_PHY_INTERNAL, MII_BMCR, BMCR_ISO); 433 1.1 pk } 434 1.1 pk 435 1.67 tsutsui memcpy(ifp->if_xname, device_xname(self), IFNAMSIZ); 436 1.1 pk ifp->if_softc = sc; 437 1.1 pk ifp->if_start = bestart; 438 1.1 pk ifp->if_ioctl = beioctl; 439 1.1 pk ifp->if_watchdog = bewatchdog; 440 1.68 tsutsui ifp->if_init = beinit; 441 1.68 tsutsui ifp->if_stop = bestop; 442 1.91 msaitoh ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 443 1.23 thorpej IFQ_SET_READY(&ifp->if_snd); 444 1.1 pk 445 1.40 pk /* claim 802.1q capability */ 446 1.40 pk sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 447 1.40 pk 448 1.1 pk /* Attach the interface. */ 449 1.1 pk if_attach(ifp); 450 1.1 pk ether_ifattach(ifp, sc->sc_enaddr); 451 1.1 pk } 452 1.1 pk 453 1.1 pk 454 1.1 pk /* 455 1.1 pk * Routine to copy from mbuf chain to transmit buffer in 456 1.1 pk * network buffer memory. 457 1.1 pk */ 458 1.48 perry static inline int 459 1.62 dsl be_put(struct be_softc *sc, int idx, struct mbuf *m) 460 1.1 pk { 461 1.1 pk struct mbuf *n; 462 1.1 pk int len, tlen = 0, boff = 0; 463 1.75 tsutsui uint8_t *bp; 464 1.2 pk 465 1.71 tsutsui bp = sc->sc_rb.rb_txbuf + (idx % sc->sc_rb.rb_ntbuf) * BE_PKT_BUF_SZ; 466 1.1 pk 467 1.1 pk for (; m; m = n) { 468 1.1 pk len = m->m_len; 469 1.1 pk if (len == 0) { 470 1.84 christos n = m_free(m); 471 1.1 pk continue; 472 1.1 pk } 473 1.75 tsutsui memcpy(bp + boff, mtod(m, void *), len); 474 1.1 pk boff += len; 475 1.1 pk tlen += len; 476 1.84 christos n = m_free(m); 477 1.1 pk } 478 1.73 tsutsui return tlen; 479 1.1 pk } 480 1.1 pk 481 1.1 pk /* 482 1.1 pk * Pull data off an interface. 483 1.1 pk * Len is the length of data, with local net header stripped. 484 1.1 pk * We copy the data into mbufs. When full cluster sized units are present, 485 1.1 pk * we copy into clusters. 486 1.1 pk */ 487 1.48 perry static inline struct mbuf * 488 1.63 dsl be_get(struct be_softc *sc, int idx, int totlen) 489 1.1 pk { 490 1.1 pk struct ifnet *ifp = &sc->sc_ethercom.ec_if; 491 1.1 pk struct mbuf *m; 492 1.1 pk struct mbuf *top, **mp; 493 1.1 pk int len, pad, boff = 0; 494 1.75 tsutsui uint8_t *bp; 495 1.2 pk 496 1.71 tsutsui bp = sc->sc_rb.rb_rxbuf + (idx % sc->sc_rb.rb_nrbuf) * BE_PKT_BUF_SZ; 497 1.1 pk 498 1.1 pk MGETHDR(m, M_DONTWAIT, MT_DATA); 499 1.1 pk if (m == NULL) 500 1.1 pk return (NULL); 501 1.83 ozaki m_set_rcvif(m, ifp); 502 1.1 pk m->m_pkthdr.len = totlen; 503 1.1 pk 504 1.1 pk pad = ALIGN(sizeof(struct ether_header)) - sizeof(struct ether_header); 505 1.1 pk m->m_data += pad; 506 1.1 pk len = MHLEN - pad; 507 1.1 pk top = NULL; 508 1.1 pk mp = ⊤ 509 1.1 pk 510 1.1 pk while (totlen > 0) { 511 1.1 pk if (top) { 512 1.1 pk MGET(m, M_DONTWAIT, MT_DATA); 513 1.1 pk if (m == NULL) { 514 1.1 pk m_freem(top); 515 1.1 pk return (NULL); 516 1.1 pk } 517 1.1 pk len = MLEN; 518 1.1 pk } 519 1.1 pk if (top && totlen >= MINCLSIZE) { 520 1.1 pk MCLGET(m, M_DONTWAIT); 521 1.1 pk if (m->m_flags & M_EXT) 522 1.1 pk len = MCLBYTES; 523 1.1 pk } 524 1.89 riastrad m->m_len = len = uimin(totlen, len); 525 1.75 tsutsui memcpy(mtod(m, void *), bp + boff, len); 526 1.1 pk boff += len; 527 1.1 pk totlen -= len; 528 1.1 pk *mp = m; 529 1.1 pk mp = &m->m_next; 530 1.1 pk } 531 1.1 pk 532 1.73 tsutsui return top; 533 1.1 pk } 534 1.1 pk 535 1.1 pk /* 536 1.1 pk * Pass a packet to the higher levels. 537 1.1 pk */ 538 1.48 perry static inline void 539 1.63 dsl be_read(struct be_softc *sc, int idx, int len) 540 1.1 pk { 541 1.1 pk struct ifnet *ifp = &sc->sc_ethercom.ec_if; 542 1.1 pk struct mbuf *m; 543 1.1 pk 544 1.43 pk if (len <= sizeof(struct ether_header) || 545 1.46 bouyer len > ETHER_MAX_LEN + ETHER_VLAN_ENCAP_LEN) { 546 1.43 pk #ifdef BEDEBUG 547 1.43 pk if (sc->sc_debug) 548 1.43 pk printf("%s: invalid packet size %d; dropping\n", 549 1.73 tsutsui ifp->if_xname, len); 550 1.43 pk #endif 551 1.95 thorpej if_statinc(ifp, if_ierrors); 552 1.1 pk return; 553 1.1 pk } 554 1.1 pk 555 1.1 pk /* 556 1.1 pk * Pull packet off interface. 557 1.1 pk */ 558 1.1 pk m = be_get(sc, idx, len); 559 1.1 pk if (m == NULL) { 560 1.95 thorpej if_statinc(ifp, if_ierrors); 561 1.1 pk return; 562 1.1 pk } 563 1.1 pk 564 1.6 thorpej /* Pass the packet up. */ 565 1.82 ozaki if_percpuq_enqueue(ifp->if_percpuq, m); 566 1.1 pk } 567 1.1 pk 568 1.1 pk /* 569 1.1 pk * Start output on interface. 570 1.96 thorpej * We make an assumption here: 571 1.1 pk * 1) that the current priority is set to splnet _before_ this code 572 1.1 pk * is called *and* is returned to the appropriate priority after 573 1.1 pk * return 574 1.1 pk */ 575 1.1 pk void 576 1.62 dsl bestart(struct ifnet *ifp) 577 1.1 pk { 578 1.67 tsutsui struct be_softc *sc = ifp->if_softc; 579 1.2 pk struct qec_xd *txd = sc->sc_rb.rb_txd; 580 1.1 pk struct mbuf *m; 581 1.1 pk unsigned int bix, len; 582 1.2 pk unsigned int ntbuf = sc->sc_rb.rb_ntbuf; 583 1.1 pk 584 1.96 thorpej if ((ifp->if_flags & IFF_RUNNING) != IFF_RUNNING) 585 1.1 pk return; 586 1.1 pk 587 1.2 pk bix = sc->sc_rb.rb_tdhead; 588 1.1 pk 589 1.96 thorpej while (sc->sc_rb.rb_td_nbusy < ntbuf) { 590 1.23 thorpej IFQ_DEQUEUE(&ifp->if_snd, m); 591 1.1 pk if (m == 0) 592 1.1 pk break; 593 1.1 pk 594 1.1 pk /* 595 1.1 pk * If BPF is listening on this interface, let it see the 596 1.1 pk * packet before we commit it to the wire. 597 1.1 pk */ 598 1.88 msaitoh bpf_mtap(ifp, m, BPF_D_OUT); 599 1.1 pk 600 1.1 pk /* 601 1.1 pk * Copy the mbuf chain into the transmit buffer. 602 1.1 pk */ 603 1.1 pk len = be_put(sc, bix, m); 604 1.1 pk 605 1.1 pk /* 606 1.1 pk * Initialize transmit registers and start transmission 607 1.1 pk */ 608 1.1 pk txd[bix].xd_flags = QEC_XD_OWN | QEC_XD_SOP | QEC_XD_EOP | 609 1.73 tsutsui (len & QEC_XD_LENGTH); 610 1.73 tsutsui bus_space_write_4(sc->sc_bustag, sc->sc_cr, 611 1.73 tsutsui BE_CRI_CTRL, BE_CR_CTRL_TWAKEUP); 612 1.1 pk 613 1.1 pk if (++bix == QEC_XD_RING_MAXSIZE) 614 1.1 pk bix = 0; 615 1.1 pk 616 1.96 thorpej sc->sc_rb.rb_td_nbusy++; 617 1.1 pk } 618 1.1 pk 619 1.2 pk sc->sc_rb.rb_tdhead = bix; 620 1.1 pk } 621 1.1 pk 622 1.1 pk void 623 1.68 tsutsui bestop(struct ifnet *ifp, int disable) 624 1.1 pk { 625 1.68 tsutsui struct be_softc *sc = ifp->if_softc; 626 1.1 pk 627 1.17 thorpej callout_stop(&sc->sc_tick_ch); 628 1.8 thorpej 629 1.12 pk /* Down the MII. */ 630 1.12 pk mii_down(&sc->sc_mii); 631 1.12 pk (void)be_intphy_service(sc, &sc->sc_mii, MII_DOWN); 632 1.1 pk 633 1.68 tsutsui behwreset(sc); 634 1.68 tsutsui } 635 1.68 tsutsui 636 1.68 tsutsui void 637 1.68 tsutsui behwreset(struct be_softc *sc) 638 1.68 tsutsui { 639 1.68 tsutsui int n; 640 1.68 tsutsui bus_space_tag_t t = sc->sc_bustag; 641 1.68 tsutsui bus_space_handle_t br = sc->sc_br; 642 1.68 tsutsui 643 1.1 pk /* Stop the transmitter */ 644 1.1 pk bus_space_write_4(t, br, BE_BRI_TXCFG, 0); 645 1.1 pk for (n = 32; n > 0; n--) { 646 1.1 pk if (bus_space_read_4(t, br, BE_BRI_TXCFG) == 0) 647 1.1 pk break; 648 1.1 pk DELAY(20); 649 1.1 pk } 650 1.1 pk 651 1.1 pk /* Stop the receiver */ 652 1.1 pk bus_space_write_4(t, br, BE_BRI_RXCFG, 0); 653 1.1 pk for (n = 32; n > 0; n--) { 654 1.1 pk if (bus_space_read_4(t, br, BE_BRI_RXCFG) == 0) 655 1.1 pk break; 656 1.1 pk DELAY(20); 657 1.1 pk } 658 1.1 pk } 659 1.1 pk 660 1.1 pk /* 661 1.1 pk * Reset interface. 662 1.1 pk */ 663 1.1 pk void 664 1.62 dsl bereset(struct be_softc *sc) 665 1.1 pk { 666 1.68 tsutsui struct ifnet *ifp = &sc->sc_ethercom.ec_if; 667 1.1 pk int s; 668 1.1 pk 669 1.1 pk s = splnet(); 670 1.68 tsutsui behwreset(sc); 671 1.13 pk if ((sc->sc_ethercom.ec_if.if_flags & IFF_UP) != 0) 672 1.68 tsutsui beinit(ifp); 673 1.1 pk splx(s); 674 1.1 pk } 675 1.1 pk 676 1.1 pk void 677 1.62 dsl bewatchdog(struct ifnet *ifp) 678 1.1 pk { 679 1.1 pk struct be_softc *sc = ifp->if_softc; 680 1.1 pk 681 1.69 tsutsui log(LOG_ERR, "%s: device timeout\n", device_xname(sc->sc_dev)); 682 1.95 thorpej if_statinc(ifp, if_oerrors); 683 1.1 pk 684 1.1 pk bereset(sc); 685 1.1 pk } 686 1.1 pk 687 1.1 pk int 688 1.67 tsutsui beintr(void *arg) 689 1.1 pk { 690 1.67 tsutsui struct be_softc *sc = arg; 691 1.1 pk bus_space_tag_t t = sc->sc_bustag; 692 1.73 tsutsui uint32_t whyq, whyb, whyc; 693 1.1 pk int r = 0; 694 1.1 pk 695 1.1 pk /* Read QEC status, channel status and BE status */ 696 1.1 pk whyq = bus_space_read_4(t, sc->sc_qr, QEC_QRI_STAT); 697 1.1 pk whyc = bus_space_read_4(t, sc->sc_cr, BE_CRI_STAT); 698 1.1 pk whyb = bus_space_read_4(t, sc->sc_br, BE_BRI_STAT); 699 1.1 pk 700 1.1 pk if (whyq & QEC_STAT_BM) 701 1.1 pk r |= beeint(sc, whyb); 702 1.1 pk 703 1.1 pk if (whyq & QEC_STAT_ER) 704 1.1 pk r |= beqint(sc, whyc); 705 1.1 pk 706 1.1 pk if (whyq & QEC_STAT_TX && whyc & BE_CR_STAT_TXIRQ) 707 1.1 pk r |= betint(sc); 708 1.1 pk 709 1.1 pk if (whyq & QEC_STAT_RX && whyc & BE_CR_STAT_RXIRQ) 710 1.1 pk r |= berint(sc); 711 1.1 pk 712 1.73 tsutsui return r; 713 1.1 pk } 714 1.1 pk 715 1.1 pk /* 716 1.1 pk * QEC Interrupt. 717 1.1 pk */ 718 1.1 pk int 719 1.73 tsutsui beqint(struct be_softc *sc, uint32_t why) 720 1.1 pk { 721 1.69 tsutsui device_t self = sc->sc_dev; 722 1.1 pk int r = 0, rst = 0; 723 1.1 pk 724 1.1 pk if (why & BE_CR_STAT_TXIRQ) 725 1.1 pk r |= 1; 726 1.1 pk if (why & BE_CR_STAT_RXIRQ) 727 1.1 pk r |= 1; 728 1.1 pk 729 1.1 pk if (why & BE_CR_STAT_BERROR) { 730 1.1 pk r |= 1; 731 1.1 pk rst = 1; 732 1.67 tsutsui aprint_error_dev(self, "bigmac error\n"); 733 1.1 pk } 734 1.1 pk 735 1.1 pk if (why & BE_CR_STAT_TXDERR) { 736 1.1 pk r |= 1; 737 1.1 pk rst = 1; 738 1.67 tsutsui aprint_error_dev(self, "bogus tx descriptor\n"); 739 1.1 pk } 740 1.1 pk 741 1.1 pk if (why & (BE_CR_STAT_TXLERR | BE_CR_STAT_TXPERR | BE_CR_STAT_TXSERR)) { 742 1.1 pk r |= 1; 743 1.1 pk rst = 1; 744 1.67 tsutsui aprint_error_dev(self, "tx DMA error ( "); 745 1.1 pk if (why & BE_CR_STAT_TXLERR) 746 1.1 pk printf("Late "); 747 1.1 pk if (why & BE_CR_STAT_TXPERR) 748 1.1 pk printf("Parity "); 749 1.1 pk if (why & BE_CR_STAT_TXSERR) 750 1.1 pk printf("Generic "); 751 1.1 pk printf(")\n"); 752 1.1 pk } 753 1.1 pk 754 1.1 pk if (why & BE_CR_STAT_RXDROP) { 755 1.1 pk r |= 1; 756 1.1 pk rst = 1; 757 1.67 tsutsui aprint_error_dev(self, "out of rx descriptors\n"); 758 1.1 pk } 759 1.1 pk 760 1.1 pk if (why & BE_CR_STAT_RXSMALL) { 761 1.1 pk r |= 1; 762 1.1 pk rst = 1; 763 1.67 tsutsui aprint_error_dev(self, "rx descriptor too small\n"); 764 1.1 pk } 765 1.1 pk 766 1.1 pk if (why & (BE_CR_STAT_RXLERR | BE_CR_STAT_RXPERR | BE_CR_STAT_RXSERR)) { 767 1.1 pk r |= 1; 768 1.1 pk rst = 1; 769 1.67 tsutsui aprint_error_dev(self, "rx DMA error ( "); 770 1.1 pk if (why & BE_CR_STAT_RXLERR) 771 1.1 pk printf("Late "); 772 1.1 pk if (why & BE_CR_STAT_RXPERR) 773 1.1 pk printf("Parity "); 774 1.1 pk if (why & BE_CR_STAT_RXSERR) 775 1.1 pk printf("Generic "); 776 1.1 pk printf(")\n"); 777 1.1 pk } 778 1.1 pk 779 1.1 pk if (!r) { 780 1.1 pk rst = 1; 781 1.67 tsutsui aprint_error_dev(self, "unexpected error interrupt %08x\n", 782 1.73 tsutsui why); 783 1.1 pk } 784 1.1 pk 785 1.1 pk if (rst) { 786 1.67 tsutsui printf("%s: resetting\n", device_xname(self)); 787 1.1 pk bereset(sc); 788 1.1 pk } 789 1.1 pk 790 1.73 tsutsui return r; 791 1.1 pk } 792 1.1 pk 793 1.1 pk /* 794 1.1 pk * Error interrupt. 795 1.1 pk */ 796 1.1 pk int 797 1.73 tsutsui beeint(struct be_softc *sc, uint32_t why) 798 1.1 pk { 799 1.69 tsutsui device_t self = sc->sc_dev; 800 1.1 pk int r = 0, rst = 0; 801 1.1 pk 802 1.1 pk if (why & BE_BR_STAT_RFIFOVF) { 803 1.1 pk r |= 1; 804 1.1 pk rst = 1; 805 1.67 tsutsui aprint_error_dev(self, "receive fifo overrun\n"); 806 1.1 pk } 807 1.1 pk if (why & BE_BR_STAT_TFIFO_UND) { 808 1.1 pk r |= 1; 809 1.1 pk rst = 1; 810 1.67 tsutsui aprint_error_dev(self, "transmit fifo underrun\n"); 811 1.1 pk } 812 1.1 pk if (why & BE_BR_STAT_MAXPKTERR) { 813 1.1 pk r |= 1; 814 1.1 pk rst = 1; 815 1.67 tsutsui aprint_error_dev(self, "max packet size error\n"); 816 1.1 pk } 817 1.1 pk 818 1.1 pk if (!r) { 819 1.1 pk rst = 1; 820 1.67 tsutsui aprint_error_dev(self, "unexpected error interrupt %08x\n", 821 1.73 tsutsui why); 822 1.1 pk } 823 1.1 pk 824 1.1 pk if (rst) { 825 1.67 tsutsui printf("%s: resetting\n", device_xname(self)); 826 1.1 pk bereset(sc); 827 1.1 pk } 828 1.1 pk 829 1.73 tsutsui return r; 830 1.1 pk } 831 1.1 pk 832 1.1 pk /* 833 1.1 pk * Transmit interrupt. 834 1.1 pk */ 835 1.1 pk int 836 1.62 dsl betint(struct be_softc *sc) 837 1.1 pk { 838 1.1 pk struct ifnet *ifp = &sc->sc_ethercom.ec_if; 839 1.1 pk bus_space_tag_t t = sc->sc_bustag; 840 1.1 pk bus_space_handle_t br = sc->sc_br; 841 1.1 pk unsigned int bix, txflags; 842 1.1 pk 843 1.1 pk /* 844 1.1 pk * Unload collision counters 845 1.1 pk */ 846 1.95 thorpej if_statadd(ifp, if_collisions, 847 1.73 tsutsui bus_space_read_4(t, br, BE_BRI_NCCNT) + 848 1.73 tsutsui bus_space_read_4(t, br, BE_BRI_FCCNT) + 849 1.73 tsutsui bus_space_read_4(t, br, BE_BRI_EXCNT) + 850 1.95 thorpej bus_space_read_4(t, br, BE_BRI_LTCNT)); 851 1.1 pk 852 1.1 pk /* 853 1.1 pk * the clear the hardware counters 854 1.1 pk */ 855 1.1 pk bus_space_write_4(t, br, BE_BRI_NCCNT, 0); 856 1.1 pk bus_space_write_4(t, br, BE_BRI_FCCNT, 0); 857 1.1 pk bus_space_write_4(t, br, BE_BRI_EXCNT, 0); 858 1.1 pk bus_space_write_4(t, br, BE_BRI_LTCNT, 0); 859 1.1 pk 860 1.2 pk bix = sc->sc_rb.rb_tdtail; 861 1.1 pk 862 1.1 pk for (;;) { 863 1.2 pk if (sc->sc_rb.rb_td_nbusy <= 0) 864 1.1 pk break; 865 1.1 pk 866 1.2 pk txflags = sc->sc_rb.rb_txd[bix].xd_flags; 867 1.1 pk 868 1.1 pk if (txflags & QEC_XD_OWN) 869 1.1 pk break; 870 1.1 pk 871 1.95 thorpej if_statinc(ifp, if_opackets); 872 1.1 pk 873 1.1 pk if (++bix == QEC_XD_RING_MAXSIZE) 874 1.1 pk bix = 0; 875 1.1 pk 876 1.2 pk --sc->sc_rb.rb_td_nbusy; 877 1.1 pk } 878 1.1 pk 879 1.2 pk sc->sc_rb.rb_tdtail = bix; 880 1.1 pk 881 1.1 pk bestart(ifp); 882 1.1 pk 883 1.2 pk if (sc->sc_rb.rb_td_nbusy == 0) 884 1.1 pk ifp->if_timer = 0; 885 1.1 pk 886 1.73 tsutsui return 1; 887 1.1 pk } 888 1.1 pk 889 1.1 pk /* 890 1.1 pk * Receive interrupt. 891 1.1 pk */ 892 1.1 pk int 893 1.62 dsl berint(struct be_softc *sc) 894 1.1 pk { 895 1.2 pk struct qec_xd *xd = sc->sc_rb.rb_rxd; 896 1.1 pk unsigned int bix, len; 897 1.2 pk unsigned int nrbuf = sc->sc_rb.rb_nrbuf; 898 1.1 pk 899 1.2 pk bix = sc->sc_rb.rb_rdtail; 900 1.1 pk 901 1.1 pk /* 902 1.1 pk * Process all buffers with valid data. 903 1.1 pk */ 904 1.1 pk for (;;) { 905 1.1 pk len = xd[bix].xd_flags; 906 1.1 pk if (len & QEC_XD_OWN) 907 1.1 pk break; 908 1.1 pk 909 1.1 pk len &= QEC_XD_LENGTH; 910 1.1 pk be_read(sc, bix, len); 911 1.1 pk 912 1.1 pk /* ... */ 913 1.1 pk xd[(bix+nrbuf) % QEC_XD_RING_MAXSIZE].xd_flags = 914 1.73 tsutsui QEC_XD_OWN | (BE_PKT_BUF_SZ & QEC_XD_LENGTH); 915 1.1 pk 916 1.1 pk if (++bix == QEC_XD_RING_MAXSIZE) 917 1.1 pk bix = 0; 918 1.1 pk } 919 1.1 pk 920 1.2 pk sc->sc_rb.rb_rdtail = bix; 921 1.1 pk 922 1.73 tsutsui return 1; 923 1.1 pk } 924 1.1 pk 925 1.1 pk int 926 1.60 dyoung beioctl(struct ifnet *ifp, u_long cmd, void *data) 927 1.1 pk { 928 1.94 msaitoh #ifdef BEDEBUG 929 1.1 pk struct be_softc *sc = ifp->if_softc; 930 1.94 msaitoh #endif 931 1.67 tsutsui struct ifaddr *ifa = data; 932 1.1 pk int s, error = 0; 933 1.1 pk 934 1.1 pk s = splnet(); 935 1.1 pk 936 1.1 pk switch (cmd) { 937 1.60 dyoung case SIOCINITIFADDR: 938 1.1 pk ifp->if_flags |= IFF_UP; 939 1.68 tsutsui beinit(ifp); 940 1.1 pk switch (ifa->ifa_addr->sa_family) { 941 1.1 pk #ifdef INET 942 1.1 pk case AF_INET: 943 1.1 pk arp_ifinit(ifp, ifa); 944 1.1 pk break; 945 1.1 pk #endif /* INET */ 946 1.1 pk default: 947 1.1 pk break; 948 1.1 pk } 949 1.1 pk break; 950 1.1 pk 951 1.1 pk case SIOCSIFFLAGS: 952 1.60 dyoung if ((error = ifioctl_common(ifp, cmd, data)) != 0) 953 1.60 dyoung break; 954 1.60 dyoung /* XXX re-use ether_ioctl() */ 955 1.92 msaitoh switch (ifp->if_flags & (IFF_UP | IFF_RUNNING)) { 956 1.60 dyoung case IFF_RUNNING: 957 1.1 pk /* 958 1.1 pk * If interface is marked down and it is running, then 959 1.1 pk * stop it. 960 1.1 pk */ 961 1.68 tsutsui bestop(ifp, 0); 962 1.1 pk ifp->if_flags &= ~IFF_RUNNING; 963 1.60 dyoung break; 964 1.60 dyoung case IFF_UP: 965 1.1 pk /* 966 1.1 pk * If interface is marked up and it is stopped, then 967 1.1 pk * start it. 968 1.1 pk */ 969 1.68 tsutsui beinit(ifp); 970 1.60 dyoung break; 971 1.60 dyoung default: 972 1.1 pk /* 973 1.1 pk * Reset the interface to pick up changes in any other 974 1.1 pk * flags that affect hardware registers. 975 1.1 pk */ 976 1.68 tsutsui bestop(ifp, 0); 977 1.68 tsutsui beinit(ifp); 978 1.60 dyoung break; 979 1.1 pk } 980 1.1 pk #ifdef BEDEBUG 981 1.1 pk if (ifp->if_flags & IFF_DEBUG) 982 1.2 pk sc->sc_debug = 1; 983 1.1 pk else 984 1.1 pk sc->sc_debug = 0; 985 1.1 pk #endif 986 1.1 pk break; 987 1.1 pk 988 1.68 tsutsui default: 989 1.54 dyoung if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 990 1.1 pk /* 991 1.1 pk * Multicast list has changed; set the hardware filter 992 1.1 pk * accordingly. 993 1.1 pk */ 994 1.44 thorpej if (ifp->if_flags & IFF_RUNNING) 995 1.68 tsutsui error = beinit(ifp); 996 1.68 tsutsui else 997 1.68 tsutsui error = 0; 998 1.1 pk } 999 1.1 pk break; 1000 1.1 pk } 1001 1.1 pk splx(s); 1002 1.73 tsutsui return error; 1003 1.1 pk } 1004 1.1 pk 1005 1.1 pk 1006 1.68 tsutsui int 1007 1.68 tsutsui beinit(struct ifnet *ifp) 1008 1.1 pk { 1009 1.68 tsutsui struct be_softc *sc = ifp->if_softc; 1010 1.1 pk bus_space_tag_t t = sc->sc_bustag; 1011 1.1 pk bus_space_handle_t br = sc->sc_br; 1012 1.1 pk bus_space_handle_t cr = sc->sc_cr; 1013 1.1 pk struct qec_softc *qec = sc->sc_qec; 1014 1.73 tsutsui uint32_t v; 1015 1.73 tsutsui uint32_t qecaddr; 1016 1.73 tsutsui uint8_t *ea; 1017 1.56 dyoung int rc, s; 1018 1.1 pk 1019 1.24 thorpej s = splnet(); 1020 1.1 pk 1021 1.2 pk qec_meminit(&sc->sc_rb, BE_PKT_BUF_SZ); 1022 1.1 pk 1023 1.68 tsutsui bestop(ifp, 1); 1024 1.1 pk 1025 1.1 pk ea = sc->sc_enaddr; 1026 1.1 pk bus_space_write_4(t, br, BE_BRI_MACADDR0, (ea[0] << 8) | ea[1]); 1027 1.1 pk bus_space_write_4(t, br, BE_BRI_MACADDR1, (ea[2] << 8) | ea[3]); 1028 1.1 pk bus_space_write_4(t, br, BE_BRI_MACADDR2, (ea[4] << 8) | ea[5]); 1029 1.1 pk 1030 1.16 pk /* Clear hash table */ 1031 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB0, 0); 1032 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB1, 0); 1033 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB2, 0); 1034 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB3, 0); 1035 1.1 pk 1036 1.16 pk /* Re-initialize RX configuration */ 1037 1.16 pk v = BE_BR_RXCFG_FIFO; 1038 1.16 pk bus_space_write_4(t, br, BE_BRI_RXCFG, v); 1039 1.16 pk 1040 1.5 pk be_mcreset(sc); 1041 1.1 pk 1042 1.1 pk bus_space_write_4(t, br, BE_BRI_RANDSEED, 0xbd); 1043 1.1 pk 1044 1.73 tsutsui bus_space_write_4(t, br, 1045 1.73 tsutsui BE_BRI_XIFCFG, BE_BR_XCFG_ODENABLE | BE_BR_XCFG_RESV); 1046 1.1 pk 1047 1.1 pk bus_space_write_4(t, br, BE_BRI_JSIZE, 4); 1048 1.1 pk 1049 1.1 pk /* 1050 1.1 pk * Turn off counter expiration interrupts as well as 1051 1.1 pk * 'gotframe' and 'sentframe' 1052 1.1 pk */ 1053 1.1 pk bus_space_write_4(t, br, BE_BRI_IMASK, 1054 1.73 tsutsui BE_BR_IMASK_GOTFRAME | 1055 1.73 tsutsui BE_BR_IMASK_RCNTEXP | 1056 1.73 tsutsui BE_BR_IMASK_ACNTEXP | 1057 1.73 tsutsui BE_BR_IMASK_CCNTEXP | 1058 1.73 tsutsui BE_BR_IMASK_LCNTEXP | 1059 1.73 tsutsui BE_BR_IMASK_CVCNTEXP | 1060 1.73 tsutsui BE_BR_IMASK_SENTFRAME | 1061 1.73 tsutsui BE_BR_IMASK_NCNTEXP | 1062 1.73 tsutsui BE_BR_IMASK_ECNTEXP | 1063 1.73 tsutsui BE_BR_IMASK_LCCNTEXP | 1064 1.73 tsutsui BE_BR_IMASK_FCNTEXP | 1065 1.73 tsutsui BE_BR_IMASK_DTIMEXP); 1066 1.1 pk 1067 1.1 pk /* Channel registers: */ 1068 1.73 tsutsui bus_space_write_4(t, cr, BE_CRI_RXDS, (uint32_t)sc->sc_rb.rb_rxddma); 1069 1.73 tsutsui bus_space_write_4(t, cr, BE_CRI_TXDS, (uint32_t)sc->sc_rb.rb_txddma); 1070 1.1 pk 1071 1.1 pk qecaddr = sc->sc_channel * qec->sc_msize; 1072 1.1 pk bus_space_write_4(t, cr, BE_CRI_RXWBUF, qecaddr); 1073 1.1 pk bus_space_write_4(t, cr, BE_CRI_RXRBUF, qecaddr); 1074 1.1 pk bus_space_write_4(t, cr, BE_CRI_TXWBUF, qecaddr + qec->sc_rsize); 1075 1.1 pk bus_space_write_4(t, cr, BE_CRI_TXRBUF, qecaddr + qec->sc_rsize); 1076 1.1 pk 1077 1.1 pk bus_space_write_4(t, cr, BE_CRI_RIMASK, 0); 1078 1.1 pk bus_space_write_4(t, cr, BE_CRI_TIMASK, 0); 1079 1.1 pk bus_space_write_4(t, cr, BE_CRI_QMASK, 0); 1080 1.1 pk bus_space_write_4(t, cr, BE_CRI_BMASK, 0); 1081 1.1 pk bus_space_write_4(t, cr, BE_CRI_CCNT, 0); 1082 1.40 pk 1083 1.40 pk /* Set max packet length */ 1084 1.40 pk v = ETHER_MAX_LEN; 1085 1.40 pk if (sc->sc_ethercom.ec_capenable & ETHERCAP_VLAN_MTU) 1086 1.40 pk v += ETHER_VLAN_ENCAP_LEN; 1087 1.40 pk bus_space_write_4(t, br, BE_BRI_RXMAX, v); 1088 1.40 pk bus_space_write_4(t, br, BE_BRI_TXMAX, v); 1089 1.1 pk 1090 1.1 pk /* Enable transmitter */ 1091 1.73 tsutsui bus_space_write_4(t, br, 1092 1.73 tsutsui BE_BRI_TXCFG, BE_BR_TXCFG_FIFO | BE_BR_TXCFG_ENABLE); 1093 1.1 pk 1094 1.1 pk /* Enable receiver */ 1095 1.16 pk v = bus_space_read_4(t, br, BE_BRI_RXCFG); 1096 1.16 pk v |= BE_BR_RXCFG_FIFO | BE_BR_RXCFG_ENABLE; 1097 1.16 pk bus_space_write_4(t, br, BE_BRI_RXCFG, v); 1098 1.1 pk 1099 1.56 dyoung if ((rc = be_ifmedia_upd(ifp)) != 0) 1100 1.56 dyoung goto out; 1101 1.56 dyoung 1102 1.1 pk ifp->if_flags |= IFF_RUNNING; 1103 1.1 pk 1104 1.17 thorpej callout_reset(&sc->sc_tick_ch, hz, be_tick, sc); 1105 1.68 tsutsui 1106 1.86 maxv splx(s); 1107 1.68 tsutsui return 0; 1108 1.56 dyoung out: 1109 1.1 pk splx(s); 1110 1.68 tsutsui return rc; 1111 1.1 pk } 1112 1.1 pk 1113 1.1 pk void 1114 1.62 dsl be_mcreset(struct be_softc *sc) 1115 1.1 pk { 1116 1.2 pk struct ethercom *ec = &sc->sc_ethercom; 1117 1.1 pk struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1118 1.1 pk bus_space_tag_t t = sc->sc_bustag; 1119 1.1 pk bus_space_handle_t br = sc->sc_br; 1120 1.74 tsutsui uint32_t v; 1121 1.73 tsutsui uint32_t crc; 1122 1.73 tsutsui uint16_t hash[4]; 1123 1.1 pk struct ether_multi *enm; 1124 1.1 pk struct ether_multistep step; 1125 1.1 pk 1126 1.5 pk if (ifp->if_flags & IFF_PROMISC) { 1127 1.5 pk v = bus_space_read_4(t, br, BE_BRI_RXCFG); 1128 1.5 pk v |= BE_BR_RXCFG_PMISC; 1129 1.5 pk bus_space_write_4(t, br, BE_BRI_RXCFG, v); 1130 1.5 pk return; 1131 1.5 pk } 1132 1.5 pk 1133 1.1 pk if (ifp->if_flags & IFF_ALLMULTI) { 1134 1.16 pk hash[3] = hash[2] = hash[1] = hash[0] = 0xffff; 1135 1.16 pk goto chipit; 1136 1.1 pk } 1137 1.1 pk 1138 1.1 pk hash[3] = hash[2] = hash[1] = hash[0] = 0; 1139 1.1 pk 1140 1.93 msaitoh ETHER_LOCK(ec); 1141 1.2 pk ETHER_FIRST_MULTI(step, ec, enm); 1142 1.1 pk while (enm != NULL) { 1143 1.32 wiz if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 1144 1.1 pk /* 1145 1.1 pk * We must listen to a range of multicast 1146 1.1 pk * addresses. For now, just accept all 1147 1.1 pk * multicasts, rather than trying to set only 1148 1.1 pk * those filter bits needed to match the range. 1149 1.1 pk * (At this time, the only use of address 1150 1.1 pk * ranges is for IP multicast routing, for 1151 1.1 pk * which the range is big enough to require 1152 1.1 pk * all bits set.) 1153 1.1 pk */ 1154 1.16 pk hash[3] = hash[2] = hash[1] = hash[0] = 0xffff; 1155 1.1 pk ifp->if_flags |= IFF_ALLMULTI; 1156 1.93 msaitoh ETHER_UNLOCK(ec); 1157 1.16 pk goto chipit; 1158 1.1 pk } 1159 1.1 pk 1160 1.74 tsutsui crc = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN); 1161 1.74 tsutsui /* Just want the 6 most significant bits. */ 1162 1.74 tsutsui crc >>= 26; 1163 1.1 pk 1164 1.1 pk hash[crc >> 4] |= 1 << (crc & 0xf); 1165 1.1 pk ETHER_NEXT_MULTI(step, enm); 1166 1.1 pk } 1167 1.93 msaitoh ETHER_UNLOCK(ec); 1168 1.1 pk 1169 1.16 pk ifp->if_flags &= ~IFF_ALLMULTI; 1170 1.16 pk 1171 1.16 pk chipit: 1172 1.16 pk /* Enable the hash filter */ 1173 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB0, hash[0]); 1174 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB1, hash[1]); 1175 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB2, hash[2]); 1176 1.1 pk bus_space_write_4(t, br, BE_BRI_HASHTAB3, hash[3]); 1177 1.16 pk 1178 1.16 pk v = bus_space_read_4(t, br, BE_BRI_RXCFG); 1179 1.16 pk v &= ~BE_BR_RXCFG_PMISC; 1180 1.16 pk v |= BE_BR_RXCFG_HENABLE; 1181 1.16 pk bus_space_write_4(t, br, BE_BRI_RXCFG, v); 1182 1.1 pk } 1183 1.1 pk 1184 1.1 pk /* 1185 1.1 pk * Set the tcvr to an idle state 1186 1.1 pk */ 1187 1.1 pk void 1188 1.62 dsl be_mii_sync(struct be_softc *sc) 1189 1.1 pk { 1190 1.1 pk bus_space_tag_t t = sc->sc_bustag; 1191 1.1 pk bus_space_handle_t tr = sc->sc_tr; 1192 1.10 pk int n = 32; 1193 1.1 pk 1194 1.1 pk while (n--) { 1195 1.1 pk bus_space_write_4(t, tr, BE_TRI_MGMTPAL, 1196 1.73 tsutsui MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | MGMT_PAL_OENAB); 1197 1.1 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1198 1.1 pk bus_space_write_4(t, tr, BE_TRI_MGMTPAL, 1199 1.73 tsutsui MGMT_PAL_INT_MDIO | MGMT_PAL_EXT_MDIO | 1200 1.73 tsutsui MGMT_PAL_OENAB | MGMT_PAL_DCLOCK); 1201 1.1 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1202 1.1 pk } 1203 1.1 pk } 1204 1.1 pk 1205 1.11 pk void 1206 1.62 dsl be_pal_gate(struct be_softc *sc, int phy) 1207 1.11 pk { 1208 1.11 pk bus_space_tag_t t = sc->sc_bustag; 1209 1.11 pk bus_space_handle_t tr = sc->sc_tr; 1210 1.73 tsutsui uint32_t v; 1211 1.11 pk 1212 1.11 pk be_mii_sync(sc); 1213 1.11 pk 1214 1.11 pk v = ~(TCVR_PAL_EXTLBACK | TCVR_PAL_MSENSE | TCVR_PAL_LTENABLE); 1215 1.11 pk if (phy == BE_PHY_INTERNAL) 1216 1.11 pk v &= ~TCVR_PAL_SERIAL; 1217 1.11 pk 1218 1.11 pk bus_space_write_4(t, tr, BE_TRI_TCVRPAL, v); 1219 1.11 pk (void)bus_space_read_4(t, tr, BE_TRI_TCVRPAL); 1220 1.11 pk } 1221 1.11 pk 1222 1.10 pk static int 1223 1.62 dsl be_tcvr_read_bit(struct be_softc *sc, int phy) 1224 1.1 pk { 1225 1.1 pk bus_space_tag_t t = sc->sc_bustag; 1226 1.1 pk bus_space_handle_t tr = sc->sc_tr; 1227 1.1 pk int ret; 1228 1.1 pk 1229 1.1 pk if (phy == BE_PHY_INTERNAL) { 1230 1.1 pk bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_EXT_MDIO); 1231 1.1 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1232 1.73 tsutsui bus_space_write_4(t, tr, 1233 1.73 tsutsui BE_TRI_MGMTPAL, MGMT_PAL_EXT_MDIO | MGMT_PAL_DCLOCK); 1234 1.1 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1235 1.1 pk ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) & 1236 1.73 tsutsui MGMT_PAL_INT_MDIO) >> MGMT_PAL_INT_MDIO_SHIFT; 1237 1.1 pk } else { 1238 1.1 pk bus_space_write_4(t, tr, BE_TRI_MGMTPAL, MGMT_PAL_INT_MDIO); 1239 1.1 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1240 1.1 pk ret = (bus_space_read_4(t, tr, BE_TRI_MGMTPAL) & 1241 1.73 tsutsui MGMT_PAL_EXT_MDIO) >> MGMT_PAL_EXT_MDIO_SHIFT; 1242 1.73 tsutsui bus_space_write_4(t, tr, 1243 1.73 tsutsui BE_TRI_MGMTPAL, MGMT_PAL_INT_MDIO | MGMT_PAL_DCLOCK); 1244 1.1 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1245 1.1 pk } 1246 1.1 pk 1247 1.73 tsutsui return ret; 1248 1.1 pk } 1249 1.1 pk 1250 1.10 pk static void 1251 1.62 dsl be_tcvr_write_bit(struct be_softc *sc, int phy, int bit) 1252 1.1 pk { 1253 1.1 pk bus_space_tag_t t = sc->sc_bustag; 1254 1.1 pk bus_space_handle_t tr = sc->sc_tr; 1255 1.73 tsutsui uint32_t v; 1256 1.1 pk 1257 1.1 pk if (phy == BE_PHY_INTERNAL) { 1258 1.10 pk v = ((bit & 1) << MGMT_PAL_INT_MDIO_SHIFT) | 1259 1.73 tsutsui MGMT_PAL_OENAB | MGMT_PAL_EXT_MDIO; 1260 1.1 pk } else { 1261 1.73 tsutsui v = ((bit & 1) << MGMT_PAL_EXT_MDIO_SHIFT) | 1262 1.73 tsutsui MGMT_PAL_OENAB | MGMT_PAL_INT_MDIO; 1263 1.1 pk } 1264 1.12 pk bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v); 1265 1.12 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1266 1.12 pk bus_space_write_4(t, tr, BE_TRI_MGMTPAL, v | MGMT_PAL_DCLOCK); 1267 1.12 pk (void)bus_space_read_4(t, tr, BE_TRI_MGMTPAL); 1268 1.1 pk } 1269 1.1 pk 1270 1.10 pk static void 1271 1.73 tsutsui be_mii_sendbits(struct be_softc *sc, int phy, uint32_t data, int nbits) 1272 1.1 pk { 1273 1.1 pk int i; 1274 1.1 pk 1275 1.1 pk for (i = 1 << (nbits - 1); i != 0; i >>= 1) { 1276 1.1 pk be_tcvr_write_bit(sc, phy, (data & i) != 0); 1277 1.1 pk } 1278 1.1 pk } 1279 1.1 pk 1280 1.4 pk static int 1281 1.90 msaitoh be_mii_readreg(device_t self, int phy, int reg, uint16_t *val) 1282 1.1 pk { 1283 1.67 tsutsui struct be_softc *sc = device_private(self); 1284 1.90 msaitoh int i; 1285 1.90 msaitoh uint16_t data = 0; 1286 1.1 pk 1287 1.1 pk /* 1288 1.1 pk * Read the PHY register by manually driving the MII control lines. 1289 1.1 pk */ 1290 1.1 pk be_mii_sync(sc); 1291 1.1 pk be_mii_sendbits(sc, phy, MII_COMMAND_START, 2); 1292 1.1 pk be_mii_sendbits(sc, phy, MII_COMMAND_READ, 2); 1293 1.1 pk be_mii_sendbits(sc, phy, phy, 5); 1294 1.1 pk be_mii_sendbits(sc, phy, reg, 5); 1295 1.1 pk 1296 1.73 tsutsui (void)be_tcvr_read_bit(sc, phy); 1297 1.73 tsutsui (void)be_tcvr_read_bit(sc, phy); 1298 1.1 pk 1299 1.1 pk for (i = 15; i >= 0; i--) 1300 1.90 msaitoh data |= (be_tcvr_read_bit(sc, phy) << i); 1301 1.1 pk 1302 1.73 tsutsui (void)be_tcvr_read_bit(sc, phy); 1303 1.73 tsutsui (void)be_tcvr_read_bit(sc, phy); 1304 1.73 tsutsui (void)be_tcvr_read_bit(sc, phy); 1305 1.1 pk 1306 1.90 msaitoh *val = data; 1307 1.90 msaitoh return 0; 1308 1.1 pk } 1309 1.1 pk 1310 1.90 msaitoh int 1311 1.90 msaitoh be_mii_writereg(device_t self, int phy, int reg, uint16_t val) 1312 1.1 pk { 1313 1.67 tsutsui struct be_softc *sc = device_private(self); 1314 1.1 pk int i; 1315 1.1 pk 1316 1.1 pk /* 1317 1.1 pk * Write the PHY register by manually driving the MII control lines. 1318 1.1 pk */ 1319 1.1 pk be_mii_sync(sc); 1320 1.1 pk be_mii_sendbits(sc, phy, MII_COMMAND_START, 2); 1321 1.1 pk be_mii_sendbits(sc, phy, MII_COMMAND_WRITE, 2); 1322 1.1 pk be_mii_sendbits(sc, phy, phy, 5); 1323 1.1 pk be_mii_sendbits(sc, phy, reg, 5); 1324 1.1 pk 1325 1.1 pk be_tcvr_write_bit(sc, phy, 1); 1326 1.1 pk be_tcvr_write_bit(sc, phy, 0); 1327 1.1 pk 1328 1.1 pk for (i = 15; i >= 0; i--) 1329 1.1 pk be_tcvr_write_bit(sc, phy, (val >> i) & 1); 1330 1.90 msaitoh 1331 1.90 msaitoh return 0; 1332 1.1 pk } 1333 1.1 pk 1334 1.1 pk int 1335 1.62 dsl be_mii_reset(struct be_softc *sc, int phy) 1336 1.1 pk { 1337 1.69 tsutsui device_t self = sc->sc_dev; 1338 1.1 pk int n; 1339 1.1 pk 1340 1.73 tsutsui be_mii_writereg(self, phy, MII_BMCR, BMCR_LOOP | BMCR_PDOWN | BMCR_ISO); 1341 1.67 tsutsui be_mii_writereg(self, phy, MII_BMCR, BMCR_RESET); 1342 1.1 pk 1343 1.1 pk for (n = 16; n >= 0; n--) { 1344 1.90 msaitoh uint16_t bmcr; 1345 1.90 msaitoh 1346 1.90 msaitoh be_mii_readreg(self, phy, MII_BMCR, &bmcr); 1347 1.1 pk if ((bmcr & BMCR_RESET) == 0) 1348 1.1 pk break; 1349 1.1 pk DELAY(20); 1350 1.1 pk } 1351 1.1 pk if (n == 0) { 1352 1.67 tsutsui aprint_error_dev(self, "bmcr reset failed\n"); 1353 1.73 tsutsui return EIO; 1354 1.1 pk } 1355 1.13 pk 1356 1.73 tsutsui return 0; 1357 1.1 pk } 1358 1.1 pk 1359 1.1 pk void 1360 1.62 dsl be_tick(void *arg) 1361 1.12 pk { 1362 1.12 pk struct be_softc *sc = arg; 1363 1.12 pk int s = splnet(); 1364 1.12 pk 1365 1.12 pk mii_tick(&sc->sc_mii); 1366 1.12 pk (void)be_intphy_service(sc, &sc->sc_mii, MII_TICK); 1367 1.12 pk 1368 1.12 pk splx(s); 1369 1.17 thorpej callout_reset(&sc->sc_tick_ch, hz, be_tick, sc); 1370 1.12 pk } 1371 1.12 pk 1372 1.12 pk void 1373 1.79 matt be_mii_statchg(struct ifnet *ifp) 1374 1.1 pk { 1375 1.79 matt struct be_softc *sc = ifp->if_softc; 1376 1.10 pk bus_space_tag_t t = sc->sc_bustag; 1377 1.10 pk bus_space_handle_t br = sc->sc_br; 1378 1.73 tsutsui uint instance; 1379 1.73 tsutsui uint32_t v; 1380 1.10 pk 1381 1.11 pk instance = IFM_INST(sc->sc_mii.mii_media.ifm_cur->ifm_media); 1382 1.11 pk #ifdef DIAGNOSTIC 1383 1.11 pk if (instance > 1) 1384 1.11 pk panic("be_mii_statchg: instance %d out of range", instance); 1385 1.11 pk #endif 1386 1.1 pk 1387 1.10 pk /* Update duplex mode in TX configuration */ 1388 1.10 pk v = bus_space_read_4(t, br, BE_BRI_TXCFG); 1389 1.10 pk if ((IFM_OPTIONS(sc->sc_mii.mii_media_active) & IFM_FDX) != 0) 1390 1.10 pk v |= BE_BR_TXCFG_FULLDPLX; 1391 1.10 pk else 1392 1.10 pk v &= ~BE_BR_TXCFG_FULLDPLX; 1393 1.10 pk bus_space_write_4(t, br, BE_BRI_TXCFG, v); 1394 1.11 pk 1395 1.11 pk /* Change to appropriate gate in transceiver PAL */ 1396 1.11 pk be_pal_gate(sc, sc->sc_phys[instance]); 1397 1.1 pk } 1398 1.1 pk 1399 1.12 pk /* 1400 1.12 pk * Get current media settings. 1401 1.12 pk */ 1402 1.1 pk void 1403 1.62 dsl be_ifmedia_sts(struct ifnet *ifp, struct ifmediareq *ifmr) 1404 1.12 pk { 1405 1.12 pk struct be_softc *sc = ifp->if_softc; 1406 1.12 pk 1407 1.12 pk mii_pollstat(&sc->sc_mii); 1408 1.12 pk (void)be_intphy_service(sc, &sc->sc_mii, MII_POLLSTAT); 1409 1.12 pk 1410 1.12 pk ifmr->ifm_status = sc->sc_mii.mii_media_status; 1411 1.12 pk ifmr->ifm_active = sc->sc_mii.mii_media_active; 1412 1.12 pk } 1413 1.12 pk 1414 1.12 pk /* 1415 1.12 pk * Set media options. 1416 1.12 pk */ 1417 1.12 pk int 1418 1.62 dsl be_ifmedia_upd(struct ifnet *ifp) 1419 1.1 pk { 1420 1.12 pk struct be_softc *sc = ifp->if_softc; 1421 1.12 pk int error; 1422 1.1 pk 1423 1.56 dyoung if ((error = mii_mediachg(&sc->sc_mii)) == ENXIO) 1424 1.56 dyoung error = 0; 1425 1.56 dyoung else if (error != 0) 1426 1.56 dyoung return error; 1427 1.1 pk 1428 1.73 tsutsui return be_intphy_service(sc, &sc->sc_mii, MII_MEDIACHG); 1429 1.1 pk } 1430 1.1 pk 1431 1.12 pk /* 1432 1.12 pk * Service routine for our pseudo-MII internal transceiver. 1433 1.12 pk */ 1434 1.12 pk int 1435 1.62 dsl be_intphy_service(struct be_softc *sc, struct mii_data *mii, int cmd) 1436 1.1 pk { 1437 1.12 pk struct ifmedia_entry *ife = mii->mii_media.ifm_cur; 1438 1.69 tsutsui device_t self = sc->sc_dev; 1439 1.90 msaitoh uint16_t bmcr, bmsr; 1440 1.13 pk int error; 1441 1.1 pk 1442 1.12 pk switch (cmd) { 1443 1.12 pk case MII_POLLSTAT: 1444 1.12 pk /* 1445 1.12 pk * If we're not polling our PHY instance, just return. 1446 1.12 pk */ 1447 1.12 pk if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst) 1448 1.73 tsutsui return 0; 1449 1.12 pk 1450 1.12 pk break; 1451 1.12 pk 1452 1.12 pk case MII_MEDIACHG: 1453 1.12 pk 1454 1.12 pk /* 1455 1.12 pk * If the media indicates a different PHY instance, 1456 1.12 pk * isolate ourselves. 1457 1.12 pk */ 1458 1.12 pk if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst) { 1459 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1460 1.67 tsutsui be_mii_writereg(self, 1461 1.67 tsutsui BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO); 1462 1.13 pk sc->sc_mii_flags &= ~MIIF_HAVELINK; 1463 1.13 pk sc->sc_intphy_curspeed = 0; 1464 1.73 tsutsui return 0; 1465 1.12 pk } 1466 1.12 pk 1467 1.12 pk 1468 1.13 pk if ((error = be_mii_reset(sc, BE_PHY_INTERNAL)) != 0) 1469 1.73 tsutsui return error; 1470 1.13 pk 1471 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1472 1.13 pk 1473 1.13 pk /* 1474 1.13 pk * Select the new mode and take out of isolation 1475 1.13 pk */ 1476 1.12 pk if (IFM_SUBTYPE(ife->ifm_media) == IFM_100_TX) 1477 1.12 pk bmcr |= BMCR_S100; 1478 1.12 pk else if (IFM_SUBTYPE(ife->ifm_media) == IFM_10_T) 1479 1.12 pk bmcr &= ~BMCR_S100; 1480 1.13 pk else if (IFM_SUBTYPE(ife->ifm_media) == IFM_AUTO) { 1481 1.13 pk if ((sc->sc_mii_flags & MIIF_HAVELINK) != 0) { 1482 1.13 pk bmcr &= ~BMCR_S100; 1483 1.13 pk bmcr |= sc->sc_intphy_curspeed; 1484 1.13 pk } else { 1485 1.13 pk /* Keep isolated until link is up */ 1486 1.13 pk bmcr |= BMCR_ISO; 1487 1.13 pk sc->sc_mii_flags |= MIIF_DOINGAUTO; 1488 1.13 pk } 1489 1.13 pk } 1490 1.12 pk 1491 1.12 pk if ((IFM_OPTIONS(ife->ifm_media) & IFM_FDX) != 0) 1492 1.12 pk bmcr |= BMCR_FDX; 1493 1.12 pk else 1494 1.12 pk bmcr &= ~BMCR_FDX; 1495 1.12 pk 1496 1.67 tsutsui be_mii_writereg(self, BE_PHY_INTERNAL, MII_BMCR, bmcr); 1497 1.12 pk break; 1498 1.12 pk 1499 1.12 pk case MII_TICK: 1500 1.12 pk /* 1501 1.12 pk * If we're not currently selected, just return. 1502 1.12 pk */ 1503 1.12 pk if (IFM_INST(ife->ifm_media) != sc->sc_mii_inst) 1504 1.73 tsutsui return 0; 1505 1.12 pk 1506 1.12 pk /* Is the interface even up? */ 1507 1.12 pk if ((mii->mii_ifp->if_flags & IFF_UP) == 0) 1508 1.73 tsutsui return 0; 1509 1.12 pk 1510 1.80 msaitoh /* Only used for automatic media selection */ 1511 1.80 msaitoh if (IFM_SUBTYPE(ife->ifm_media) != IFM_AUTO) 1512 1.80 msaitoh break; 1513 1.80 msaitoh 1514 1.12 pk /* 1515 1.12 pk * Check link status; if we don't have a link, try another 1516 1.12 pk * speed. We can't detect duplex mode, so half-duplex is 1517 1.12 pk * what we have to settle for. 1518 1.12 pk */ 1519 1.1 pk 1520 1.12 pk /* Read twice in case the register is latched */ 1521 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMSR, &bmsr); 1522 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMSR, &bmsr); 1523 1.12 pk 1524 1.12 pk if ((bmsr & BMSR_LINK) != 0) { 1525 1.12 pk /* We have a carrier */ 1526 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1527 1.13 pk 1528 1.13 pk if ((sc->sc_mii_flags & MIIF_DOINGAUTO) != 0) { 1529 1.90 msaitoh be_mii_readreg(self, 1530 1.90 msaitoh BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1531 1.13 pk 1532 1.13 pk sc->sc_mii_flags |= MIIF_HAVELINK; 1533 1.13 pk sc->sc_intphy_curspeed = (bmcr & BMCR_S100); 1534 1.13 pk sc->sc_mii_flags &= ~MIIF_DOINGAUTO; 1535 1.13 pk 1536 1.13 pk bmcr &= ~BMCR_ISO; 1537 1.67 tsutsui be_mii_writereg(self, 1538 1.67 tsutsui BE_PHY_INTERNAL, MII_BMCR, bmcr); 1539 1.13 pk 1540 1.13 pk printf("%s: link up at %s Mbps\n", 1541 1.67 tsutsui device_xname(self), 1542 1.67 tsutsui (bmcr & BMCR_S100) ? "100" : "10"); 1543 1.13 pk } 1544 1.80 msaitoh break; 1545 1.12 pk } 1546 1.1 pk 1547 1.13 pk if ((sc->sc_mii_flags & MIIF_DOINGAUTO) == 0) { 1548 1.13 pk sc->sc_mii_flags |= MIIF_DOINGAUTO; 1549 1.13 pk sc->sc_mii_flags &= ~MIIF_HAVELINK; 1550 1.13 pk sc->sc_intphy_curspeed = 0; 1551 1.67 tsutsui printf("%s: link down\n", device_xname(self)); 1552 1.13 pk } 1553 1.13 pk 1554 1.12 pk /* Only retry autonegotiation every 5 seconds. */ 1555 1.13 pk if (++sc->sc_mii_ticks < 5) 1556 1.73 tsutsui return 0; 1557 1.12 pk 1558 1.12 pk sc->sc_mii_ticks = 0; 1559 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1560 1.12 pk /* Just flip the fast speed bit */ 1561 1.12 pk bmcr ^= BMCR_S100; 1562 1.67 tsutsui be_mii_writereg(self, BE_PHY_INTERNAL, MII_BMCR, bmcr); 1563 1.1 pk 1564 1.12 pk break; 1565 1.1 pk 1566 1.12 pk case MII_DOWN: 1567 1.13 pk /* Isolate this phy */ 1568 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1569 1.67 tsutsui be_mii_writereg(self, 1570 1.67 tsutsui BE_PHY_INTERNAL, MII_BMCR, bmcr | BMCR_ISO); 1571 1.73 tsutsui return 0; 1572 1.1 pk } 1573 1.1 pk 1574 1.12 pk /* Update the media status. */ 1575 1.12 pk be_intphy_status(sc); 1576 1.10 pk 1577 1.12 pk /* Callback if something changed. */ 1578 1.12 pk if (sc->sc_mii_active != mii->mii_media_active || cmd == MII_MEDIACHG) { 1579 1.79 matt (*mii->mii_statchg)(mii->mii_ifp); 1580 1.12 pk sc->sc_mii_active = mii->mii_media_active; 1581 1.12 pk } 1582 1.73 tsutsui return 0; 1583 1.1 pk } 1584 1.1 pk 1585 1.1 pk /* 1586 1.12 pk * Determine status of internal transceiver 1587 1.1 pk */ 1588 1.1 pk void 1589 1.62 dsl be_intphy_status(struct be_softc *sc) 1590 1.1 pk { 1591 1.12 pk struct mii_data *mii = &sc->sc_mii; 1592 1.69 tsutsui device_t self = sc->sc_dev; 1593 1.10 pk int media_active, media_status; 1594 1.90 msaitoh uint16_t bmcr, bmsr; 1595 1.1 pk 1596 1.10 pk media_status = IFM_AVALID; 1597 1.10 pk media_active = 0; 1598 1.10 pk 1599 1.1 pk /* 1600 1.1 pk * Internal transceiver; do the work here. 1601 1.1 pk */ 1602 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMCR, &bmcr); 1603 1.1 pk 1604 1.1 pk switch (bmcr & (BMCR_S100 | BMCR_FDX)) { 1605 1.1 pk case (BMCR_S100 | BMCR_FDX): 1606 1.10 pk media_active = IFM_ETHER | IFM_100_TX | IFM_FDX; 1607 1.1 pk break; 1608 1.1 pk case BMCR_S100: 1609 1.10 pk media_active = IFM_ETHER | IFM_100_TX | IFM_HDX; 1610 1.1 pk break; 1611 1.1 pk case BMCR_FDX: 1612 1.10 pk media_active = IFM_ETHER | IFM_10_T | IFM_FDX; 1613 1.1 pk break; 1614 1.1 pk case 0: 1615 1.10 pk media_active = IFM_ETHER | IFM_10_T | IFM_HDX; 1616 1.1 pk break; 1617 1.1 pk } 1618 1.1 pk 1619 1.1 pk /* Read twice in case the register is latched */ 1620 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMSR, &bmsr); 1621 1.90 msaitoh be_mii_readreg(self, BE_PHY_INTERNAL, MII_BMSR, &bmsr); 1622 1.1 pk if (bmsr & BMSR_LINK) 1623 1.92 msaitoh media_status |= IFM_ACTIVE; 1624 1.10 pk 1625 1.12 pk mii->mii_media_status = media_status; 1626 1.12 pk mii->mii_media_active = media_active; 1627 1.1 pk } 1628