1 /* $NetBSD: dm9000.c,v 1.46 2026/07/10 22:24:02 andvar Exp $ */ 2 3 /* 4 * Copyright (c) 2009 Paul Fleischer 5 * All rights reserved. 6 * 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. The name of the company nor the name of the author may be used to 13 * endorse or promote products derived from this software without specific 14 * prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26 * SUCH DAMAGE. 27 */ 28 29 /* based on sys/dev/ic/cs89x0.c */ 30 /* 31 * Copyright (c) 2004 Christopher Gilbert 32 * All rights reserved. 33 * 34 * 1. Redistributions of source code must retain the above copyright 35 * notice, this list of conditions and the following disclaimer. 36 * 2. Redistributions in binary form must reproduce the above copyright 37 * notice, this list of conditions and the following disclaimer in the 38 * documentation and/or other materials provided with the distribution. 39 * 3. The name of the company nor the name of the author may be used to 40 * endorse or promote products derived from this software without specific 41 * prior written permission. 42 * 43 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED 44 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 45 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 46 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 47 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 48 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 49 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 50 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 51 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 52 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 53 * SUCH DAMAGE. 54 */ 55 56 /* 57 * Copyright 1997 58 * Digital Equipment Corporation. All rights reserved. 59 * 60 * This software is furnished under license and may be used and 61 * copied only in accordance with the following terms and conditions. 62 * Subject to these conditions, you may download, copy, install, 63 * use, modify and distribute this software in source and/or binary 64 * form. No title or ownership is transferred hereby. 65 * 66 * 1) Any source code used, modified or distributed must reproduce 67 * and retain this copyright notice and list of conditions as 68 * they appear in the source file. 69 * 70 * 2) No right is granted to use any trade name, trademark, or logo of 71 * Digital Equipment Corporation. Neither the "Digital Equipment 72 * Corporation" name nor any trademark or logo of Digital Equipment 73 * Corporation may be used to endorse or promote products derived 74 * from this software without the prior written permission of 75 * Digital Equipment Corporation. 76 * 77 * 3) This software is provided "AS-IS" and any express or implied 78 * warranties, including but not limited to, any implied warranties 79 * of merchantability, fitness for a particular purpose, or 80 * non-infringement are disclaimed. In no event shall DIGITAL be 81 * liable for any damages whatsoever, and in particular, DIGITAL 82 * shall not be liable for special, indirect, consequential, or 83 * incidental damages or damages for lost profits, loss of 84 * revenue or loss of use, whether such damages arise in contract, 85 * negligence, tort, under statute, in equity, at law or otherwise, 86 * even if advised of the possibility of such damage. 87 */ 88 89 #include <sys/cdefs.h> 90 __KERNEL_RCSID(0, "$NetBSD: dm9000.c,v 1.46 2026/07/10 22:24:02 andvar Exp $"); 91 92 #include <sys/param.h> 93 #include <sys/bus.h> 94 #include <sys/intr.h> 95 #include <sys/device.h> 96 #include <sys/mbuf.h> 97 #include <sys/sockio.h> 98 #include <sys/errno.h> 99 #include <sys/cprng.h> 100 #include <sys/rndsource.h> 101 #include <sys/kernel.h> 102 #include <sys/systm.h> 103 104 #include <net/if.h> 105 #include <net/if_dl.h> 106 #include <net/if_ether.h> 107 #include <net/if_media.h> 108 #include <dev/mii/mii.h> 109 #include <dev/mii/miivar.h> 110 #include <net/bpf.h> 111 112 #include <dev/ic/dm9000var.h> 113 #include <dev/ic/dm9000reg.h> 114 115 #if 1 116 #undef DM9000_DEBUG 117 #undef DM9000_TX_DEBUG 118 #undef DM9000_TX_DATA_DEBUG 119 #undef DM9000_RX_DEBUG 120 #undef DM9000_RX_DATA_DEBUG 121 #else 122 #define DM9000_DEBUG 123 #define DM9000_TX_DEBUG 124 #define DM9000_TX_DATA_DEBUG 125 #define DM9000_RX_DEBUG 126 #define DM9000_RX_DATA_DEBUG 127 #endif 128 129 #ifdef DM9000_DEBUG 130 #define DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 131 #else 132 #define DPRINTF(s) do {} while (/*CONSTCOND*/0) 133 #endif 134 135 #ifdef DM9000_TX_DEBUG 136 #define TX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 137 #else 138 #define TX_DPRINTF(s) do {} while (/*CONSTCOND*/0) 139 #endif 140 141 #ifdef DM9000_RX_DEBUG 142 #define RX_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 143 #else 144 #define RX_DPRINTF(s) do {} while (/*CONSTCOND*/0) 145 #endif 146 147 #ifdef DM9000_RX_DATA_DEBUG 148 #define RX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 149 #else 150 #define RX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0) 151 #endif 152 153 #ifdef DM9000_TX_DATA_DEBUG 154 #define TX_DATA_DPRINTF(s) do {printf s; } while (/*CONSTCOND*/0) 155 #else 156 #define TX_DATA_DPRINTF(s) do {} while (/*CONSTCOND*/0) 157 #endif 158 159 static void dme_reset(struct dme_softc *); 160 static int dme_init(struct ifnet *); 161 static void dme_stop(struct ifnet *, int); 162 static void dme_start(struct ifnet *); 163 static int dme_ioctl(struct ifnet *, u_long, void *); 164 165 static void dme_set_rcvfilt(struct dme_softc *); 166 static void mii_statchg(struct ifnet *); 167 static void lnkchg(struct dme_softc *); 168 static void phy_tick(void *); 169 static int mii_readreg(device_t, int, int, uint16_t *); 170 static int mii_writereg(device_t, int, int, uint16_t); 171 172 static void dme_prepare(struct ifnet *); 173 static void dme_transmit(struct ifnet *); 174 static void dme_receive(struct ifnet *); 175 176 static int pkt_read_2(struct dme_softc *, struct mbuf **); 177 static int pkt_write_2(struct dme_softc *, struct mbuf *); 178 static int pkt_read_1(struct dme_softc *, struct mbuf **); 179 static int pkt_write_1(struct dme_softc *, struct mbuf *); 180 #define PKT_READ(ii,m) (*(ii)->sc_pkt_read)((ii),(m)) 181 #define PKT_WRITE(ii,m) (*(ii)->sc_pkt_write)((ii),(m)) 182 183 #define ETHER_IS_ONE(x) \ 184 (((x)[0] & (x)[1] & (x)[2] & (x)[3] & (x)[4] & (x)[5]) == 255) 185 #define ETHER_IS_ZERO(x) \ 186 (((x)[0] | (x)[1] | (x)[2] | (x)[3] | (x)[4] | (x)[5]) == 0) 187 188 int 189 dme_attach(struct dme_softc *sc, const uint8_t *notusedanymore) 190 { 191 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 192 struct mii_data *mii = &sc->sc_mii; 193 struct ifmedia *ifm = &mii->mii_media; 194 uint8_t b[2]; 195 uint16_t io_mode; 196 uint8_t enaddr[ETHER_ADDR_LEN]; 197 198 dme_read_c(sc, DM9000_VID0, b, 2); 199 sc->sc_vendor_id = le16toh((uint16_t)b[1] << 8 | b[0]); 200 dme_read_c(sc, DM9000_PID0, b, 2); 201 sc->sc_product_id = le16toh((uint16_t)b[1] << 8 | b[0]); 202 203 /* TODO: Check the vendor ID as well */ 204 if (sc->sc_product_id != 0x9000) { 205 panic("dme_attach: product id mismatch (0x%hx != 0x9000)", 206 sc->sc_product_id); 207 } 208 #if 1 || DM9000_DEBUG 209 { 210 dme_read_c(sc, DM9000_PAB0, enaddr, 6); 211 aprint_normal_dev(sc->sc_dev, 212 "DM9000 was configured with MAC address: %s\n", 213 ether_sprintf(enaddr)); 214 } 215 #endif 216 if (! ether_getaddr(sc->sc_dev, enaddr)) { 217 /* 218 * If we did not get an externally configured address, 219 * try to read one from the current setup, before 220 * resetting the chip. 221 */ 222 dme_read_c(sc, DM9000_PAB0, enaddr, 6); 223 if (ETHER_IS_ONE(enaddr) || ETHER_IS_ZERO(enaddr)) { 224 /* make a random MAC address */ 225 uint32_t maclo = 0x00f2 | (cprng_strong32() << 16); 226 uint32_t machi = cprng_strong32(); 227 enaddr[0] = maclo; 228 enaddr[1] = maclo >> 8; 229 enaddr[2] = maclo >> 16; 230 enaddr[3] = maclo >> 24; 231 enaddr[4] = machi; 232 enaddr[5] = machi >> 8; 233 } 234 } 235 /* TODO: perform explicit EEPROM read op if it's available */ 236 237 dme_reset(sc); 238 239 mii->mii_ifp = ifp; 240 mii->mii_readreg = mii_readreg; 241 mii->mii_writereg = mii_writereg; 242 mii->mii_statchg = mii_statchg; 243 244 /* assume davicom PHY at 1. ext PHY could be hooked but only at 0-3 */ 245 sc->sc_ethercom.ec_mii = mii; 246 ifmedia_init(ifm, 0, ether_mediachange, ether_mediastatus); 247 mii_attach(sc->sc_dev, mii, 0xffffffff, 1 /* PHY 1 */, 248 MII_OFFSET_ANY, 0); 249 if (LIST_FIRST(&mii->mii_phys) == NULL) { 250 ifmedia_add(ifm, IFM_ETHER | IFM_NONE, 0, NULL); 251 ifmedia_set(ifm, IFM_ETHER | IFM_NONE); 252 } else 253 ifmedia_set(ifm, IFM_ETHER | IFM_AUTO); 254 ifm->ifm_media = ifm->ifm_cur->ifm_media; 255 256 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 257 ifp->if_softc = sc; 258 ifp->if_flags = IFF_SIMPLEX | IFF_BROADCAST | IFF_MULTICAST; 259 ifp->if_init = dme_init; 260 ifp->if_start = dme_start; 261 ifp->if_stop = dme_stop; 262 ifp->if_ioctl = dme_ioctl; 263 ifp->if_watchdog = NULL; /* no watchdog used */ 264 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 265 IFQ_SET_READY(&ifp->if_snd); 266 267 if_attach(ifp); 268 ether_ifattach(ifp, enaddr); 269 if_deferred_start_init(ifp, NULL); 270 271 rnd_attach_source(&sc->rnd_source, device_xname(sc->sc_dev), 272 RND_TYPE_NET, RND_FLAG_DEFAULT); 273 274 /* might be unnecessary as link change interrupt works well */ 275 callout_init(&sc->sc_link_callout, 0); 276 callout_setfunc(&sc->sc_link_callout, phy_tick, sc); 277 278 io_mode = (dme_read(sc, DM9000_ISR) & 279 DM9000_IOMODE_MASK) >> DM9000_IOMODE_SHIFT; 280 281 /* frame body read/write ops in 2 byte quantity or byte-wise. */ 282 DPRINTF(("DM9000 Operation Mode: ")); 283 switch (io_mode) { 284 case DM9000_MODE_8BIT: 285 DPRINTF(("8-bit mode")); 286 sc->sc_data_width = 1; 287 sc->sc_pkt_write = pkt_write_1; 288 sc->sc_pkt_read = pkt_read_1; 289 break; 290 case DM9000_MODE_16BIT: 291 DPRINTF(("16-bit mode")); 292 sc->sc_data_width = 2; 293 sc->sc_pkt_write = pkt_write_2; 294 sc->sc_pkt_read = pkt_read_2; 295 break; 296 case DM9000_MODE_32BIT: 297 DPRINTF(("32-bit mode")); 298 sc->sc_data_width = 4; 299 panic("32bit mode is unsupported\n"); 300 break; 301 default: 302 DPRINTF(("Invalid mode")); 303 break; 304 } 305 DPRINTF(("\n")); 306 307 return 0; 308 } 309 310 int 311 dme_detach(struct dme_softc *sc) 312 { 313 return 0; 314 } 315 316 /* Software Initialize/Reset of the DM9000 */ 317 static void 318 dme_reset(struct dme_softc *sc) 319 { 320 uint8_t misc; 321 322 /* We only re-initialized the PHY in this function the first time it is 323 * called. */ 324 if (!sc->sc_phy_initialized) { 325 /* PHY Reset */ 326 mii_writereg(sc->sc_dev, 1, MII_BMCR, BMCR_RESET); 327 328 /* PHY Power Down */ 329 misc = dme_read(sc, DM9000_GPR); 330 dme_write(sc, DM9000_GPR, misc | DM9000_GPR_PHY_PWROFF); 331 } 332 333 /* Reset the DM9000 twice, as described in section 2 of the Programming 334 * Guide. 335 * The PHY is initialized and enabled between those two resets. 336 */ 337 338 /* Software Reset */ 339 dme_write(sc, DM9000_NCR, 340 DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL); 341 delay(20); 342 dme_write(sc, DM9000_NCR, 0x0); 343 344 if (!sc->sc_phy_initialized) { 345 /* PHY Enable */ 346 misc = dme_read(sc, DM9000_GPR); 347 dme_write(sc, DM9000_GPR, misc & ~DM9000_GPR_PHY_PWROFF); 348 misc = dme_read(sc, DM9000_GPCR); 349 dme_write(sc, DM9000_GPCR, misc | DM9000_GPCR_GPIO0_OUT); 350 351 dme_write(sc, DM9000_NCR, 352 DM9000_NCR_RST | DM9000_NCR_LBK_MAC_INTERNAL); 353 delay(20); 354 dme_write(sc, DM9000_NCR, 0x0); 355 } 356 357 /* Select internal PHY, no wakeup event, no collision mode, 358 * normal loopback mode. 359 */ 360 dme_write(sc, DM9000_NCR, DM9000_NCR_LBK_NORMAL); 361 362 /* Will clear TX1END, TX2END, and WAKEST fields by reading DM9000_NSR*/ 363 dme_read(sc, DM9000_NSR); 364 365 /* Enable wraparound of read/write pointer, frame received latch, 366 * and frame transmitted latch. 367 */ 368 dme_write(sc, DM9000_IMR, 369 DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM); 370 371 dme_write(sc, DM9000_RCR, 372 DM9000_RCR_DIS_CRC | DM9000_RCR_DIS_LONG | DM9000_RCR_WTDIS); 373 374 sc->sc_phy_initialized = 1; 375 } 376 377 static int 378 dme_init(struct ifnet *ifp) 379 { 380 struct dme_softc *sc = ifp->if_softc; 381 382 dme_stop(ifp, 0); 383 dme_reset(sc); 384 dme_write_c(sc, DM9000_PAB0, CLLADDR(ifp->if_sadl), ETHER_ADDR_LEN); 385 dme_set_rcvfilt(sc); 386 (void)ether_mediachange(ifp); 387 388 sc->txbusy = sc->txready = 0; 389 390 ifp->if_flags |= IFF_RUNNING; 391 callout_schedule(&sc->sc_link_callout, hz); 392 393 return 0; 394 } 395 396 /* Configure multicast filter */ 397 static void 398 dme_set_rcvfilt(struct dme_softc *sc) 399 { 400 struct ethercom *ec = &sc->sc_ethercom; 401 struct ifnet *ifp = &ec->ec_if; 402 struct ether_multi *enm; 403 struct ether_multistep step; 404 uint8_t mchash[8] = { 0, 0, 0, 0, 0, 0, 0, 0 }; /* 64bit mchash */ 405 uint32_t h = 0; 406 int rcr; 407 408 rcr = dme_read(sc, DM9000_RCR); 409 rcr &= ~(DM9000_RCR_PRMSC | DM9000_RCR_ALL); 410 dme_write(sc, DM9000_RCR, rcr &~ DM9000_RCR_RXEN); 411 412 ETHER_LOCK(ec); 413 if (ifp->if_flags & IFF_PROMISC) { 414 ec->ec_flags |= ETHER_F_ALLMULTI; 415 ETHER_UNLOCK(ec); 416 /* run promisc. mode */ 417 rcr |= DM9000_RCR_PRMSC; 418 goto update; 419 } 420 ec->ec_flags &= ~ETHER_F_ALLMULTI; 421 ETHER_FIRST_MULTI(step, ec, enm); 422 while (enm != NULL) { 423 if (memcpy(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 424 /* 425 * We must listen to a range of multicast addresses. 426 * For now, just accept all multicasts, rather than 427 * trying to set only those filter bits needed to match 428 * the range. (At this time, the only use of address 429 * ranges is for IP multicast routing, for which the 430 * range is big enough to require all bits set.) 431 */ 432 ec->ec_flags |= ETHER_F_ALLMULTI; 433 ETHER_UNLOCK(ec); 434 memset(mchash, 0xff, sizeof(mchash)); /* necessary? */ 435 /* accept all multicast frame */ 436 rcr |= DM9000_RCR_ALL; 437 goto update; 438 } 439 h = ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) & 0x3f; 440 /* 3(5:3) and 3(2:0) sampling to have uint8_t[8] */ 441 mchash[h / 8] |= 1 << (h % 8); 442 ETHER_NEXT_MULTI(step, enm); 443 } 444 ETHER_UNLOCK(ec); 445 /* DM9000 receive filter is always on */ 446 mchash[7] |= 0x80; /* to catch bcast frame */ 447 update: 448 dme_write_c(sc, DM9000_MAB0, mchash, sizeof(mchash)); 449 dme_write(sc, DM9000_RCR, rcr | DM9000_RCR_RXEN); 450 return; 451 } 452 453 void 454 lnkchg(struct dme_softc *sc) 455 { 456 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 457 struct ifmediareq ifmr; 458 459 ether_mediastatus(ifp, &ifmr); 460 } 461 462 static void 463 mii_statchg(struct ifnet *ifp) 464 { 465 struct dme_softc *sc = ifp->if_softc; 466 struct mii_data *mii = &sc->sc_mii; 467 uint8_t fcr, ncr; 468 469 #if 0 470 const uint8_t Mbps[2] = { 10, 100 }; 471 uint8_t nsr = dme_read(sc, DM9000_NSR); 472 int spd = Mbps[!!(nsr & DM9000_NSR_SPEED)]; 473 /* speed/duplexity available also in reg 0x11 of internal PHY */ 474 if (nsr & DM9000_NSR_LINKST) 475 printf("link up,spd%d", spd); 476 else 477 printf("link down"); 478 479 /* show resolved mii(4) parameters */ 480 printf("MII spd%d", 481 (int)(sc->sc_ethercom.ec_if.if_baudrate / IF_Mbps(1))); 482 if (mii->mii_media_active & IFM_FDX) 483 printf(",full-duplex"); 484 printf("\n"); 485 #endif 486 487 /* Adjust duplexity and PAUSE flow control. */ 488 fcr = dme_read(sc, DM9000_FCR) &~ DM9000_FCR_FLCE; 489 ncr = dme_read(sc, DM9000_NCR) &~ DM9000_NCR_FDX; 490 if ((mii->mii_media_active & IFM_FDX) 491 && (mii->mii_media_active & IFM_FLOW)) { 492 fcr |= DM9000_FCR_FLCE; 493 ncr |= DM9000_NCR_FDX; 494 } 495 dme_write(sc, DM9000_FCR, fcr); 496 dme_write(sc, DM9000_NCR, ncr); 497 } 498 499 static void 500 phy_tick(void *arg) 501 { 502 struct dme_softc *sc = arg; 503 struct mii_data *mii = &sc->sc_mii; 504 int s; 505 506 s = splnet(); 507 mii_tick(mii); 508 splx(s); 509 510 callout_schedule(&sc->sc_link_callout, hz); 511 } 512 513 static int 514 mii_readreg(device_t self, int phy, int reg, uint16_t *val) 515 { 516 struct dme_softc *sc = device_private(self); 517 518 if (phy != 1) 519 return EINVAL; 520 521 /* Select Register to read*/ 522 dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY + 523 (reg & DM9000_EPAR_EROA_MASK)); 524 /* Select read operation (DM9000_EPCR_ERPRR) from the PHY */ 525 dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRR + DM9000_EPCR_EPOS_PHY); 526 527 /* Wait until access to PHY has completed */ 528 while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE) 529 ; 530 531 /* Reset ERPRR-bit */ 532 dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY); 533 534 *val = dme_read(sc, DM9000_EPDRL) | (dme_read(sc, DM9000_EPDRH) << 8); 535 return 0; 536 } 537 538 static int 539 mii_writereg(device_t self, int phy, int reg, uint16_t val) 540 { 541 struct dme_softc *sc = device_private(self); 542 543 if (phy != 1) 544 return EINVAL; 545 546 /* Select Register to write */ 547 dme_write(sc, DM9000_EPAR, DM9000_EPAR_INT_PHY + 548 (reg & DM9000_EPAR_EROA_MASK)); 549 550 /* Write data to the two data registers */ 551 dme_write(sc, DM9000_EPDRL, val & 0xFF); 552 dme_write(sc, DM9000_EPDRH, (val >> 8) & 0xFF); 553 554 /* Select write operation (DM9000_EPCR_ERPRW) from the PHY */ 555 dme_write(sc, DM9000_EPCR, DM9000_EPCR_ERPRW + DM9000_EPCR_EPOS_PHY); 556 557 /* Wait until access to PHY has completed */ 558 while (dme_read(sc, DM9000_EPCR) & DM9000_EPCR_ERRE) 559 ; 560 561 /* Reset ERPRR-bit */ 562 dme_write(sc, DM9000_EPCR, DM9000_EPCR_EPOS_PHY); 563 564 return 0; 565 } 566 567 void 568 dme_stop(struct ifnet *ifp, int disable) 569 { 570 struct dme_softc *sc = ifp->if_softc; 571 572 /* Not quite sure what to do when called with disable == 0 */ 573 if (disable) { 574 /* Disable RX */ 575 dme_write(sc, DM9000_RCR, 0x0); 576 } 577 mii_down(&sc->sc_mii); 578 callout_stop(&sc->sc_link_callout); 579 580 ifp->if_flags &= ~IFF_RUNNING; 581 ifp->if_timer = 0; 582 } 583 584 static void 585 dme_start(struct ifnet *ifp) 586 { 587 struct dme_softc *sc = ifp->if_softc; 588 589 if ((ifp->if_flags & IFF_RUNNING) == 0) { 590 return; 591 } 592 if (!sc->txready) { 593 dme_prepare(ifp); 594 } 595 if (sc->txbusy) { 596 /* 597 * We need to wait until the current frame has 598 * been transmitted. 599 */ 600 return; 601 } 602 if (sc->txready) { 603 /* We are ready to transmit right away */ 604 dme_transmit(ifp); 605 } 606 dme_prepare(ifp); /* Prepare next one */ 607 } 608 609 /* Prepare data to be transmitted (i.e. dequeue and load it into the DM9000) */ 610 static void 611 dme_prepare(struct ifnet *ifp) 612 { 613 struct dme_softc *sc = ifp->if_softc; 614 uint16_t length; 615 struct mbuf *m; 616 617 KASSERT(!sc->txready); 618 619 IFQ_DEQUEUE(&ifp->if_snd, m); 620 if (m == NULL) { 621 TX_DPRINTF(("dme_prepare: Nothing to transmit\n")); 622 return; /* Nothing to transmit */ 623 } 624 625 /* Element has now been removed from the queue, so we better send it */ 626 627 bpf_mtap(ifp, m, BPF_D_OUT); 628 629 /* Setup the DM9000 to accept the writes, and then write each buf in 630 the chain. */ 631 632 TX_DATA_DPRINTF(("dme_prepare: Writing data: ")); 633 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io, DM9000_MWCMD); 634 length = PKT_WRITE(sc, m); 635 bpf_mtap(ifp, m, BPF_D_OUT); 636 TX_DATA_DPRINTF(("\n")); 637 638 if (length % sc->sc_data_width != 0) 639 panic("dme_prepare: length is not compatible with IO_MODE"); 640 641 sc->txready_length = length; 642 sc->txready = 1; 643 m_freem(m); 644 } 645 646 /* Transmit prepared data */ 647 static void 648 dme_transmit(struct ifnet *ifp) 649 { 650 struct dme_softc *sc = ifp->if_softc; 651 652 TX_DPRINTF(("dme_transmit: PRE: txready: %d, txbusy: %d\n", 653 sc->txready, sc->txbusy)); 654 655 /* prime frame length first */ 656 dme_write(sc, DM9000_TXPLL, sc->txready_length & 0xff); 657 dme_write(sc, DM9000_TXPLH, (sc->txready_length >> 8) & 0xff); 658 /* read isr next */ 659 dme_read(sc, DM9000_ISR); 660 /* finally issue a request to send */ 661 dme_write(sc, DM9000_TCR, DM9000_TCR_TXREQ); 662 sc->txready = 0; 663 sc->txbusy = 1; 664 sc->txready_length = 0; 665 } 666 667 /* Receive data */ 668 static void 669 dme_receive(struct ifnet *ifp) 670 { 671 struct dme_softc *sc = ifp->if_softc; 672 struct mbuf *m; 673 uint8_t avail; 674 int rsr; 675 676 DPRINTF(("inside dme_receive\n")); 677 678 /* frame has just arrived, retrieve it */ 679 /* called right after Rx frame available interrupt */ 680 do { 681 /* "no increment" read to get the avail byte without 682 moving past it. */ 683 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io, 684 DM9000_MRCMDX); 685 /* Read twice */ 686 avail = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 687 avail = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 688 avail &= 03; /* 1:0 we only want these bits */ 689 if (avail == 01) { 690 /* Read with address increment. */ 691 bus_space_write_1(sc->sc_iot, sc->sc_ioh, sc->dme_io, 692 DM9000_MRCMD); 693 rsr = PKT_READ(sc, &m); 694 if (rsr < 0) { 695 /* RX FIFO desync; recover like bad avail */ 696 if_statinc(ifp, if_ierrors); 697 printf("%s: Resetting chip\n", 698 device_xname(sc->sc_dev)); 699 dme_reset(sc); 700 break; 701 } 702 if (m == NULL) { 703 /* failed to allocate a receive buffer */ 704 RX_DPRINTF(("dme_receive: " 705 "Error allocating buffer\n")); 706 if_statinc(ifp, if_ierrors); 707 continue; 708 } 709 if (rsr & (DM9000_RSR_CE | DM9000_RSR_PLE)) { 710 /* Error while receiving the frame, 711 * discard it and keep track of counters 712 */ 713 RX_DPRINTF(("dme_receive: " 714 "Error receiving frame\n")); 715 if_statinc(ifp, if_ierrors); 716 continue; 717 } 718 if (rsr & DM9000_RSR_LCS) { 719 if_statinc(ifp, if_collisions); 720 continue; 721 } 722 /* pick and forward this frame to ifq */ 723 if_percpuq_enqueue(ifp->if_percpuq, m); 724 } else if (avail != 00) { 725 /* Should this be logged somehow? */ 726 printf("%s: Resetting chip\n", 727 device_xname(sc->sc_dev)); 728 dme_reset(sc); 729 break; 730 } 731 } while (avail == 01); 732 /* frame received successfully */ 733 } 734 735 int 736 dme_intr(void *arg) 737 { 738 struct dme_softc *sc = arg; 739 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 740 uint8_t isr, nsr, tsr; 741 742 DPRINTF(("dme_intr: Begin\n")); 743 744 /* Disable interrupts */ 745 dme_write(sc, DM9000_IMR, DM9000_IMR_PAR); 746 747 isr = dme_read(sc, DM9000_ISR); 748 dme_write(sc, DM9000_ISR, isr); /* write to clear */ 749 750 if (isr & DM9000_ISR_PRS) { 751 KASSERT(ifp->if_flags & IFF_RUNNING); 752 dme_receive(ifp); 753 } 754 if (isr & DM9000_ISR_LNKCHNG) 755 lnkchg(sc); 756 if (isr & DM9000_ISR_PTS) { 757 tsr = 0x01; /* Initialize to an error value */ 758 759 /* A frame has been transmitted */ 760 sc->txbusy = 0; 761 762 nsr = dme_read(sc, DM9000_NSR); 763 if (nsr & DM9000_NSR_TX1END) { 764 tsr = dme_read(sc, DM9000_TSR1); 765 TX_DPRINTF(("dme_intr: Sent using channel 0\n")); 766 } else if (nsr & DM9000_NSR_TX2END) { 767 tsr = dme_read(sc, DM9000_TSR2); 768 TX_DPRINTF(("dme_intr: Sent using channel 1\n")); 769 } 770 771 if (tsr == 0x0) { 772 /* Frame successfully sent */ 773 if_statinc(ifp, if_opackets); 774 } else { 775 if_statinc(ifp, if_oerrors); 776 } 777 778 /* If we have nothing ready to transmit, prepare something */ 779 if (!sc->txready) 780 dme_prepare(ifp); 781 782 if (sc->txready) 783 dme_transmit(ifp); 784 785 /* Prepare the next frame */ 786 dme_prepare(ifp); 787 788 if_schedule_deferred_start(ifp); 789 } 790 791 /* Enable interrupts again */ 792 dme_write(sc, DM9000_IMR, 793 DM9000_IMR_PAR | DM9000_IMR_PRM | DM9000_IMR_PTM); 794 795 DPRINTF(("dme_intr: End\n")); 796 797 return (isr != 0); 798 } 799 800 static int 801 dme_ioctl(struct ifnet *ifp, u_long cmd, void *data) 802 { 803 struct dme_softc *sc = ifp->if_softc; 804 struct ifreq *ifr = (struct ifreq *)data; 805 struct ifmedia *ifm = &sc->sc_mii.mii_media; 806 int s, error; 807 808 s = splnet(); 809 switch (cmd) { 810 case SIOCSIFMEDIA: 811 /* Flow control requires full-duplex mode. */ 812 if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO || 813 (ifr->ifr_media & IFM_FDX) == 0) 814 ifr->ifr_media &= ~IFM_ETH_FMASK; 815 if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) { 816 if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) { 817 ifr->ifr_media |= 818 IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE; 819 } 820 } 821 error = ifmedia_ioctl(ifp, ifr, ifm, cmd); 822 break; 823 default: 824 if ((error = ether_ioctl(ifp, cmd, data)) != ENETRESET) 825 break; 826 error = 0; 827 if (cmd == SIOCSIFCAP) 828 error = if_init(ifp); 829 else if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 830 ; 831 else if (ifp->if_flags && IFF_RUNNING) { 832 /* Address list has changed, reconfigure filter */ 833 dme_set_rcvfilt(sc); 834 } 835 break; 836 } 837 splx(s); 838 return error; 839 } 840 841 static struct mbuf * 842 dme_alloc_receive_buffer(struct ifnet *ifp, unsigned int frame_length) 843 { 844 struct dme_softc *sc = ifp->if_softc; 845 struct mbuf *m; 846 int pad, quantum; 847 848 quantum = sc->sc_data_width; 849 MGETHDR(m, M_DONTWAIT, MT_DATA); 850 if (m == NULL) 851 return NULL; 852 853 m_set_rcvif(m, ifp); 854 /* Ensure that we always allocate an even number of 855 * bytes in order to avoid writing beyond the buffer 856 */ 857 m->m_pkthdr.len = frame_length + (frame_length % quantum); 858 pad = ALIGN(sizeof(struct ether_header)) - 859 sizeof(struct ether_header); 860 /* All our frames have the CRC attached */ 861 m->m_flags |= M_HASFCS; 862 if (m->m_pkthdr.len + pad > MHLEN) { 863 MCLGET(m, M_DONTWAIT); 864 if ((m->m_flags & M_EXT) == 0) { 865 m_freem(m); 866 return NULL; 867 } 868 } 869 870 m->m_data += pad; 871 m->m_len = frame_length + (frame_length % quantum); 872 873 return m; 874 } 875 876 static int 877 pkt_write_2(struct dme_softc *sc, struct mbuf *bufChain) 878 { 879 int left_over_count = 0; /* Number of bytes from previous mbuf, which 880 need to be written with the next.*/ 881 uint16_t left_over_buf = 0; 882 int length = 0; 883 struct mbuf *buf; 884 uint8_t *write_ptr; 885 886 /* We expect that the DM9000 has been setup to accept writes before 887 this function is called. */ 888 889 for (buf = bufChain; buf != NULL; buf = buf->m_next) { 890 int to_write = buf->m_len; 891 892 length += to_write; 893 894 write_ptr = buf->m_data; 895 while (to_write > 0 || 896 (buf->m_next == NULL && left_over_count > 0)) { 897 if (left_over_count > 0) { 898 uint8_t b = 0; 899 DPRINTF(("pkt_write_16: " 900 "Writing left over byte\n")); 901 902 if (to_write > 0) { 903 b = *write_ptr; 904 to_write--; 905 write_ptr++; 906 907 DPRINTF(("Took single byte\n")); 908 } else { 909 DPRINTF(("Leftover in last run\n")); 910 length++; 911 } 912 913 /* Does shift direction depend on endianness? */ 914 left_over_buf = left_over_buf | (b << 8); 915 916 bus_space_write_2(sc->sc_iot, sc->sc_ioh, 917 sc->dme_data, left_over_buf); 918 TX_DATA_DPRINTF(("%02X ", left_over_buf)); 919 left_over_count = 0; 920 } else if ((long)write_ptr % 2 != 0) { 921 /* Misaligned data */ 922 DPRINTF(("pkt_write_16: " 923 "Detected misaligned data\n")); 924 left_over_buf = *write_ptr; 925 left_over_count = 1; 926 write_ptr++; 927 to_write--; 928 } else { 929 int i; 930 uint16_t *dptr = (uint16_t *)write_ptr; 931 932 /* A block of aligned data. */ 933 for (i = 0; i < to_write / 2; i++) { 934 /* buf will be half-word aligned 935 * all the time 936 */ 937 bus_space_write_2(sc->sc_iot, 938 sc->sc_ioh, sc->dme_data, *dptr); 939 TX_DATA_DPRINTF(("%02X %02X ", 940 *dptr & 0xFF, (*dptr >> 8) & 0xFF)); 941 dptr++; 942 } 943 944 write_ptr += i * 2; 945 if (to_write % 2 != 0) { 946 DPRINTF(("pkt_write_16: " 947 "to_write %% 2: %d\n", 948 to_write % 2)); 949 left_over_count = 1; 950 /* XXX: Does this depend on 951 * the endianness? 952 */ 953 left_over_buf = *write_ptr; 954 955 write_ptr++; 956 to_write--; 957 DPRINTF(("pkt_write_16: " 958 "to_write (after): %d\n", 959 to_write)); 960 DPRINTF(("pkt_write_16: i * 2: %d\n", 961 i*2)); 962 } 963 to_write -= i * 2; 964 } 965 } /* while (...) */ 966 } /* for (...) */ 967 968 return length; 969 } 970 971 static int 972 pkt_read_2(struct dme_softc *sc, struct mbuf **outBuf) 973 { 974 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 975 uint8_t rx_status; 976 struct mbuf *m; 977 uint16_t data; 978 uint16_t frame_length; 979 uint16_t i; 980 uint16_t *buf; 981 982 data = bus_space_read_2(sc->sc_iot, sc->sc_ioh, sc->dme_data); 983 rx_status = data & 0xFF; 984 985 frame_length = bus_space_read_2(sc->sc_iot, 986 sc->sc_ioh, sc->dme_data); 987 if (frame_length > ETHER_MAX_LEN) { 988 /* 989 * RX FIFO pointer has desynced from the chip 990 */ 991 printf("%s: bogus RX frame length %u, resetting\n", 992 device_xname(sc->sc_dev), frame_length); 993 *outBuf = NULL; 994 return -1; 995 } 996 RX_DPRINTF(("dme_receive: rx_statux: 0x%x, frame_length: %d\n", 997 rx_status, frame_length)); 998 999 m = dme_alloc_receive_buffer(ifp, frame_length); 1000 if (m == NULL) { 1001 /* 1002 * didn't get a receive buffer, so we read the rest of the 1003 * frame, throw it away and return an error 1004 */ 1005 for (i = 0; i < frame_length; i += 2) { 1006 data = bus_space_read_2(sc->sc_iot, 1007 sc->sc_ioh, sc->dme_data); 1008 } 1009 *outBuf = NULL; 1010 return 0; 1011 } 1012 1013 buf = mtod(m, uint16_t*); 1014 1015 RX_DPRINTF(("dme_receive: ")); 1016 1017 for (i = 0; i < frame_length; i += 2) { 1018 data = bus_space_read_2(sc->sc_iot, 1019 sc->sc_ioh, sc->dme_data); 1020 if ( (frame_length % 2 != 0) && 1021 (i == frame_length - 1) ) { 1022 data = data & 0xff; 1023 RX_DPRINTF((" L ")); 1024 } 1025 *buf = data; 1026 buf++; 1027 RX_DATA_DPRINTF(("%02X %02X ", data & 0xff, 1028 (data >> 8) & 0xff)); 1029 } 1030 1031 RX_DATA_DPRINTF(("\n")); 1032 RX_DPRINTF(("Read %d bytes\n", i)); 1033 1034 *outBuf = m; 1035 return rx_status; 1036 } 1037 1038 static int 1039 pkt_write_1(struct dme_softc *sc, struct mbuf *bufChain) 1040 { 1041 int length = 0, i; 1042 struct mbuf *buf; 1043 uint8_t *write_ptr; 1044 1045 /* 1046 * We expect that the DM9000 has been setup to accept writes before 1047 * this function is called. 1048 */ 1049 1050 for (buf = bufChain; buf != NULL; buf = buf->m_next) { 1051 int to_write = buf->m_len; 1052 1053 length += to_write; 1054 1055 write_ptr = buf->m_data; 1056 for (i = 0; i < to_write; i++) { 1057 bus_space_write_1(sc->sc_iot, sc->sc_ioh, 1058 sc->dme_data, *write_ptr); 1059 write_ptr++; 1060 } 1061 } /* for (...) */ 1062 1063 return length; 1064 } 1065 1066 static int 1067 pkt_read_1(struct dme_softc *sc, struct mbuf **outBuf) 1068 { 1069 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1070 uint8_t rx_status; 1071 struct mbuf *m; 1072 uint8_t *buf; 1073 uint16_t frame_length; 1074 uint16_t i, reg; 1075 uint8_t data; 1076 1077 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1078 reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8; 1079 rx_status = reg & 0xFF; 1080 1081 reg = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1082 reg |= bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data) << 8; 1083 frame_length = reg; 1084 1085 if (frame_length > ETHER_MAX_LEN) { 1086 /* see pkt_read_2 */ 1087 printf("%s: bogus RX frame length %u, resetting\n", 1088 device_xname(sc->sc_dev), frame_length); 1089 *outBuf = NULL; 1090 return -1; 1091 } 1092 RX_DPRINTF(("dme_receive: " 1093 "rx_statux: 0x%x, frame_length: %d\n", 1094 rx_status, frame_length)); 1095 1096 m = dme_alloc_receive_buffer(ifp, frame_length); 1097 if (m == NULL) { 1098 /* 1099 * didn't get a receive buffer, so we read the rest of the 1100 * frame, throw it away and return an error 1101 */ 1102 for (i = 0; i < frame_length; i++ ) { 1103 data = bus_space_read_2(sc->sc_iot, 1104 sc->sc_ioh, sc->dme_data); 1105 } 1106 *outBuf = NULL; 1107 return 0; 1108 } 1109 1110 buf = mtod(m, uint8_t *); 1111 1112 RX_DPRINTF(("dme_receive: ")); 1113 for (i = 0; i< frame_length; i += 1) { 1114 data = bus_space_read_1(sc->sc_iot, sc->sc_ioh, sc->dme_data); 1115 *buf = data; 1116 buf++; 1117 RX_DATA_DPRINTF(("%02X ", data)); 1118 } 1119 1120 RX_DATA_DPRINTF(("\n")); 1121 RX_DPRINTF(("Read %d bytes\n", i)); 1122 1123 *outBuf = m; 1124 return rx_status; 1125 } 1126