1 /* $NetBSD: if_sq.c,v 1.61 2026/06/11 00:47:24 rumble Exp $ */ 2 3 /* 4 * Copyright (c) 2001 Rafal K. Boni 5 * Copyright (c) 1998, 1999, 2000 The NetBSD Foundation, Inc. 6 * All rights reserved. 7 * 8 * Portions of this code are derived from software contributed to The 9 * NetBSD Foundation by Jason R. Thorpe of the Numerical Aerospace 10 * Simulation Facility, NASA Ames Research Center. 11 * 12 * Redistribution and use in source and binary forms, with or without 13 * modification, are permitted provided that the following conditions 14 * are met: 15 * 1. Redistributions of source code must retain the above copyright 16 * notice, this list of conditions and the following disclaimer. 17 * 2. Redistributions in binary form must reproduce the above copyright 18 * notice, this list of conditions and the following disclaimer in the 19 * documentation and/or other materials provided with the distribution. 20 * 3. The name of the author may not be used to endorse or promote products 21 * derived from this software without specific prior written permission. 22 * 23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 32 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: if_sq.c,v 1.61 2026/06/11 00:47:24 rumble Exp $"); 37 38 39 #include <sys/param.h> 40 #include <sys/systm.h> 41 #include <sys/device.h> 42 #include <sys/callout.h> 43 #include <sys/mbuf.h> 44 #include <sys/kernel.h> 45 #include <sys/socket.h> 46 #include <sys/ioctl.h> 47 #include <sys/errno.h> 48 #include <sys/syslog.h> 49 50 #include <uvm/uvm_extern.h> 51 52 #include <machine/endian.h> 53 54 #include <net/if.h> 55 #include <net/if_dl.h> 56 #include <net/if_media.h> 57 #include <net/if_ether.h> 58 59 #include <net/bpf.h> 60 61 #include <sys/bus.h> 62 #include <machine/intr.h> 63 #include <machine/sysconf.h> 64 65 #include <dev/ic/seeq8003reg.h> 66 67 #include <sgimips/hpc/sqvar.h> 68 #include <sgimips/hpc/hpcvar.h> 69 #include <sgimips/hpc/hpcreg.h> 70 71 #include <dev/arcbios/arcbios.h> 72 #include <dev/arcbios/arcbiosvar.h> 73 74 #define static 75 76 /* 77 * Short TODO list: 78 * (1) Do counters for bad-RX packets. 79 * (2) Allow multi-segment transmits, instead of copying to a single, 80 * contiguous mbuf. 81 * (3) Verify sq_stop() turns off enough stuff; I was still getting 82 * seeq interrupts after sq_stop(). 83 * (4) Implement EDLC modes: especially packet auto-pad and simplex 84 * mode. 85 * (5) Should the driver filter out its own transmissions in non-EDLC 86 * mode? 87 * (6) Multicast support -- multicast filter, address management, ... 88 * (7) Deal with RB0 (recv buffer overflow) on reception. Will need 89 * to figure out if RB0 is read-only as stated in one spot in the 90 * HPC spec or read-write (ie, is the 'write a one to clear it') 91 * the correct thing? 92 */ 93 94 #if defined(SQ_DEBUG) 95 int sq_debug = 0; 96 #define SQ_DPRINTF(x) if (sq_debug) printf x 97 #else 98 #define SQ_DPRINTF(x) 99 #endif 100 101 static int sq_match(device_t, cfdata_t, void *); 102 static void sq_attach(device_t, device_t, void *); 103 static int sq_init(struct ifnet *); 104 static void sq_start(struct ifnet *); 105 static void sq_stop(struct ifnet *, int); 106 static void sq_watchdog(struct ifnet *); 107 static int sq_ioctl(struct ifnet *, u_long, void *); 108 109 static void sq_set_filter(struct sq_softc *); 110 static int sq_intr(void *); 111 static int sq_rxintr(struct sq_softc *); 112 static int sq_txintr(struct sq_softc *); 113 static void sq_txring_hpc1(struct sq_softc *); 114 static void sq_txring_hpc3(struct sq_softc *); 115 static void sq_reset(struct sq_softc *); 116 static int sq_add_rxbuf(struct sq_softc *, int); 117 static void sq_dump_buffer(paddr_t, psize_t); 118 static void sq_trace_dump(struct sq_softc *); 119 120 CFATTACH_DECL_NEW(sq, sizeof(struct sq_softc), 121 sq_match, sq_attach, NULL, NULL); 122 123 #define ETHER_PAD_LEN (ETHER_MIN_LEN - ETHER_CRC_LEN) 124 125 #define sq_seeq_read(sc, off) \ 126 bus_space_read_1(sc->sc_regt, sc->sc_regh, (off << 2) + 3) 127 #define sq_seeq_write(sc, off, val) \ 128 bus_space_write_1(sc->sc_regt, sc->sc_regh, (off << 2) + 3, val) 129 130 #define sq_hpc_read(sc, off) \ 131 bus_space_read_4(sc->sc_hpct, sc->sc_hpch, off) 132 #define sq_hpc_write(sc, off, val) \ 133 bus_space_write_4(sc->sc_hpct, sc->sc_hpch, off, val) 134 135 /* 136 * MAC addresses live in different places depending on whether we're dealing 137 * with a built-in or an optional interface. 138 * 139 * Some (all?) machines have MAC addresses in both locations in their onboard 140 * EEPROMs. 141 */ 142 #define SQ_ONB_HPC_EEPROM_ENADDR 122 143 #define SQ_EXT_HPC_EEPROM_ENADDR 250 144 145 #define SGI_OUI_0 0x08 146 #define SGI_OUI_1 0x00 147 #define SGI_OUI_2 0x69 148 149 static int 150 sq_match(device_t parent, cfdata_t cf, void *aux) 151 { 152 struct hpc_attach_args *ha = aux; 153 154 if (strcmp(ha->ha_name, cf->cf_name) == 0) { 155 vaddr_t reset, txstat; 156 157 reset = MIPS_PHYS_TO_KSEG1(ha->ha_sh + 158 ha->ha_dmaoff + ha->hpc_regs->enetr_reset); 159 txstat = MIPS_PHYS_TO_KSEG1(ha->ha_sh + 160 ha->ha_devoff + (SEEQ_TXSTAT << 2)); 161 162 if (platform.badaddr((void *)reset, sizeof(reset))) 163 return 0; 164 165 *(volatile uint32_t *)reset = 0x1; 166 delay(20); 167 *(volatile uint32_t *)reset = 0x0; 168 169 if (platform.badaddr((void *)txstat, sizeof(txstat))) 170 return 0; 171 172 if ((*(volatile uint32_t *)txstat & 0xff) == TXSTAT_OLDNEW) 173 return 1; 174 } 175 176 return 0; 177 } 178 179 static void 180 sq_attach(device_t parent, device_t self, void *aux) 181 { 182 int i, err; 183 const char* macaddr; 184 struct sq_softc *sc = device_private(self); 185 struct hpc_attach_args *haa = aux; 186 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 187 188 sc->sc_dev = self; 189 sc->sc_hpct = haa->ha_st; 190 sc->hpc_regs = haa->hpc_regs; /* HPC register definitions */ 191 192 if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh, 193 haa->ha_dmaoff, sc->hpc_regs->enet_regs_size, 194 &sc->sc_hpch)) != 0) { 195 printf(": unable to map HPC DMA registers, error = %d\n", err); 196 goto fail_0; 197 } 198 199 sc->sc_regt = haa->ha_st; 200 if ((err = bus_space_subregion(haa->ha_st, haa->ha_sh, 201 haa->ha_devoff, sc->hpc_regs->enet_devregs_size, 202 &sc->sc_regh)) != 0) { 203 printf(": unable to map Seeq registers, error = %d\n", err); 204 goto fail_0; 205 } 206 207 sc->sc_dmat = haa->ha_dmat; 208 209 if ((err = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct sq_control), 210 PAGE_SIZE, PAGE_SIZE, &sc->sc_cdseg, 1, &sc->sc_ncdseg, 211 BUS_DMA_NOWAIT)) != 0) { 212 printf(": unable to allocate control data, error = %d\n", err); 213 goto fail_0; 214 } 215 216 if ((err = bus_dmamem_map(sc->sc_dmat, &sc->sc_cdseg, sc->sc_ncdseg, 217 sizeof(struct sq_control), (void **)&sc->sc_control, 218 BUS_DMA_NOWAIT | BUS_DMA_COHERENT)) != 0) { 219 printf(": unable to map control data, error = %d\n", err); 220 goto fail_1; 221 } 222 223 if ((err = bus_dmamap_create(sc->sc_dmat, 224 sizeof(struct sq_control), 1, sizeof(struct sq_control), PAGE_SIZE, 225 BUS_DMA_NOWAIT, &sc->sc_cdmap)) != 0) { 226 printf(": unable to create DMA map for control data, error " 227 "= %d\n", err); 228 goto fail_2; 229 } 230 231 if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_cdmap, 232 sc->sc_control, sizeof(struct sq_control), NULL, 233 BUS_DMA_NOWAIT)) != 0) { 234 printf(": unable to load DMA map for control data, error " 235 "= %d\n", err); 236 goto fail_3; 237 } 238 239 memset(sc->sc_control, 0, sizeof(struct sq_control)); 240 241 /* Create transmit buffer DMA maps */ 242 for (i = 0; i < SQ_NTXDESC; i++) { 243 if ((err = bus_dmamap_create(sc->sc_dmat, 244 MCLBYTES, 1, MCLBYTES, 0, 245 BUS_DMA_NOWAIT, &sc->sc_txmap[i])) != 0) { 246 printf(": unable to create tx DMA map %d, error = %d\n", 247 i, err); 248 goto fail_4; 249 } 250 } 251 252 /* Create receive buffer DMA maps */ 253 for (i = 0; i < SQ_NRXDESC; i++) { 254 if ((err = bus_dmamap_create(sc->sc_dmat, 255 MCLBYTES, 1, MCLBYTES, 0, 256 BUS_DMA_NOWAIT, &sc->sc_rxmap[i])) != 0) { 257 printf(": unable to create rx DMA map %d, error = %d\n", 258 i, err); 259 goto fail_5; 260 } 261 } 262 263 /* Pre-allocate the receive buffers. */ 264 for (i = 0; i < SQ_NRXDESC; i++) { 265 if ((err = sq_add_rxbuf(sc, i)) != 0) { 266 printf(": unable to allocate or map rx buffer %d\n," 267 " error = %d\n", i, err); 268 goto fail_6; 269 } 270 } 271 272 /* 273 * Assume this is the onboard interface first and use that mac address 274 * if it's present. If not, try the location for option cards. 275 */ 276 memcpy(sc->sc_enaddr, &haa->hpc_eeprom[SQ_ONB_HPC_EEPROM_ENADDR], 277 ETHER_ADDR_LEN); 278 if (sc->sc_enaddr[0] != SGI_OUI_0 || 279 sc->sc_enaddr[1] != SGI_OUI_1 || 280 sc->sc_enaddr[2] != SGI_OUI_2) { 281 memcpy(sc->sc_enaddr, 282 &haa->hpc_eeprom[SQ_EXT_HPC_EEPROM_ENADDR], ETHER_ADDR_LEN); 283 } 284 285 /* 286 * If our mac address is bogus, obtain it from ARCBIOS. This will 287 * be true of the onboard HPC3 on IP22, since there is no eeprom, 288 * but rather the DS1386 RTC's battery-backed ram is used. 289 */ 290 if (sc->sc_enaddr[0] != SGI_OUI_0 || 291 sc->sc_enaddr[1] != SGI_OUI_1 || 292 sc->sc_enaddr[2] != SGI_OUI_2) { 293 macaddr = arcbios_GetEnvironmentVariable("eaddr"); 294 if (macaddr == NULL) { 295 printf(": unable to get MAC address!\n"); 296 goto fail_6; 297 } 298 ether_aton_r(sc->sc_enaddr, sizeof(sc->sc_enaddr), macaddr); 299 } 300 301 evcnt_attach_dynamic(&sc->sq_intrcnt, EVCNT_TYPE_INTR, NULL, 302 device_xname(self), "intr"); 303 304 if ((cpu_intr_establish(haa->ha_irq, IPL_NET, sq_intr, sc)) == NULL) { 305 printf(": unable to establish interrupt!\n"); 306 goto fail_6; 307 } 308 309 /* Reset the chip to a known state. */ 310 sq_reset(sc); 311 312 /* 313 * Determine if we're an 8003 or 80c03 by setting the first 314 * MAC address register to non-zero, and then reading it back. 315 * If it's zero, we have an 80c03, because we will have read 316 * the TxCollLSB register. 317 */ 318 sq_seeq_write(sc, SEEQ_TXCOLLS0, 0xa5); 319 if (sq_seeq_read(sc, SEEQ_TXCOLLS0) == 0) 320 sc->sc_type = SQ_TYPE_80C03; 321 else 322 sc->sc_type = SQ_TYPE_8003; 323 sq_seeq_write(sc, SEEQ_TXCOLLS0, 0x00); 324 325 printf(": SGI Seeq %s\n", 326 sc->sc_type == SQ_TYPE_80C03 ? "80c03" : "8003"); 327 328 printf("%s: Ethernet address %s\n", 329 device_xname(self), ether_sprintf(sc->sc_enaddr)); 330 331 strcpy(ifp->if_xname, device_xname(self)); 332 ifp->if_softc = sc; 333 ifp->if_mtu = ETHERMTU; 334 ifp->if_init = sq_init; 335 ifp->if_stop = sq_stop; 336 ifp->if_start = sq_start; 337 ifp->if_ioctl = sq_ioctl; 338 ifp->if_watchdog = sq_watchdog; 339 ifp->if_flags = IFF_BROADCAST | IFF_MULTICAST; 340 IFQ_SET_READY(&ifp->if_snd); 341 342 if_attach(ifp); 343 if_deferred_start_init(ifp, NULL); 344 ether_ifattach(ifp, sc->sc_enaddr); 345 346 memset(&sc->sq_trace, 0, sizeof(sc->sq_trace)); 347 /* Done! */ 348 return; 349 350 /* 351 * Free any resources we've allocated during the failed attach 352 * attempt. Do this in reverse order and fall through. 353 */ 354 fail_6: 355 for (i = 0; i < SQ_NRXDESC; i++) { 356 if (sc->sc_rxmbuf[i] != NULL) { 357 bus_dmamap_unload(sc->sc_dmat, sc->sc_rxmap[i]); 358 m_freem(sc->sc_rxmbuf[i]); 359 } 360 } 361 fail_5: 362 for (i = 0; i < SQ_NRXDESC; i++) { 363 if (sc->sc_rxmap[i] != NULL) 364 bus_dmamap_destroy(sc->sc_dmat, sc->sc_rxmap[i]); 365 } 366 fail_4: 367 for (i = 0; i < SQ_NTXDESC; i++) { 368 if (sc->sc_txmap[i] != NULL) 369 bus_dmamap_destroy(sc->sc_dmat, sc->sc_txmap[i]); 370 } 371 bus_dmamap_unload(sc->sc_dmat, sc->sc_cdmap); 372 fail_3: 373 bus_dmamap_destroy(sc->sc_dmat, sc->sc_cdmap); 374 fail_2: 375 bus_dmamem_unmap(sc->sc_dmat, 376 (void *)sc->sc_control, sizeof(struct sq_control)); 377 fail_1: 378 bus_dmamem_free(sc->sc_dmat, &sc->sc_cdseg, sc->sc_ncdseg); 379 fail_0: 380 return; 381 } 382 383 /* Set up data to get the interface up and running. */ 384 int 385 sq_init(struct ifnet *ifp) 386 { 387 int i; 388 struct sq_softc *sc = ifp->if_softc; 389 390 /* Cancel any in-progress I/O */ 391 sq_stop(ifp, 0); 392 393 sc->sc_nextrx = 0; 394 395 sc->sc_nfreetx = SQ_NTXDESC; 396 sc->sc_nexttx = sc->sc_prevtx = 0; 397 398 SQ_TRACE(SQ_RESET, sc, 0, 0); 399 400 /* Set into 8003 mode, bank 0 to program ethernet address */ 401 sq_seeq_write(sc, SEEQ_TXCMD, TXCMD_BANK0); 402 403 /* Now write the address */ 404 for (i = 0; i < ETHER_ADDR_LEN; i++) 405 sq_seeq_write(sc, i, sc->sc_enaddr[i]); 406 407 sc->sc_rxcmd = 408 RXCMD_IE_CRC | 409 RXCMD_IE_DRIB | 410 RXCMD_IE_SHORT | 411 RXCMD_IE_END | 412 RXCMD_IE_GOOD; 413 414 /* 415 * Set the receive filter -- this will add some bits to the 416 * prototype RXCMD register. Do this before setting the 417 * transmit config register, since we might need to switch 418 * banks. 419 */ 420 sq_set_filter(sc); 421 422 /* Set up Seeq transmit command register */ 423 sq_seeq_write(sc, SEEQ_TXCMD, 424 TXCMD_IE_UFLOW | 425 TXCMD_IE_COLL | 426 TXCMD_IE_16COLL | 427 TXCMD_IE_GOOD); 428 429 /* Now write the receive command register. */ 430 sq_seeq_write(sc, SEEQ_RXCMD, sc->sc_rxcmd); 431 432 /* 433 * Set up HPC ethernet PIO and DMA configurations. 434 * 435 * The PROM appears to do most of this for the onboard HPC3, but 436 * not for the Challenge S's IOPLUS chip. We copy how the onboard 437 * chip is configured and assume that it's correct for both. 438 */ 439 if (sc->hpc_regs->revision == 3) { 440 uint32_t dmareg, pioreg; 441 442 pioreg = 443 HPC3_ENETR_PIOCFG_P1(1) | 444 HPC3_ENETR_PIOCFG_P2(6) | 445 HPC3_ENETR_PIOCFG_P3(1); 446 447 dmareg = 448 HPC3_ENETR_DMACFG_D1(6) | 449 HPC3_ENETR_DMACFG_D2(2) | 450 HPC3_ENETR_DMACFG_D3(0) | 451 HPC3_ENETR_DMACFG_FIX_RXDC | 452 HPC3_ENETR_DMACFG_FIX_INTR | 453 HPC3_ENETR_DMACFG_FIX_EOP | 454 HPC3_ENETR_DMACFG_TIMEOUT; 455 456 sq_hpc_write(sc, HPC3_ENETR_PIOCFG, pioreg); 457 sq_hpc_write(sc, HPC3_ENETR_DMACFG, dmareg); 458 } 459 460 /* Pass the start of the receive ring to the HPC */ 461 sq_hpc_write(sc, sc->hpc_regs->enetr_ndbp, SQ_CDRXADDR(sc, 0)); 462 463 /* And turn on the HPC ethernet receive channel */ 464 sq_hpc_write(sc, sc->hpc_regs->enetr_ctl, 465 sc->hpc_regs->enetr_ctl_active); 466 467 /* 468 * Turn off delayed receive interrupts on HPC1. 469 * (see Hollywood HPC Specification 2.1.4.3) 470 */ 471 if (sc->hpc_regs->revision != 3) 472 sq_hpc_write(sc, HPC1_ENET_INTDELAY, HPC1_ENET_INTDELAY_OFF); 473 474 ifp->if_flags |= IFF_RUNNING; 475 476 return 0; 477 } 478 479 static void 480 sq_set_filter(struct sq_softc *sc) 481 { 482 struct ethercom *ec = &sc->sc_ethercom; 483 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 484 struct ether_multi *enm; 485 struct ether_multistep step; 486 487 /* 488 * Check for promiscuous mode. Also implies 489 * all-multicast. 490 */ 491 if (ifp->if_flags & IFF_PROMISC) { 492 sc->sc_rxcmd |= RXCMD_REC_ALL; 493 ifp->if_flags |= IFF_ALLMULTI; 494 return; 495 } 496 497 /* 498 * The 8003 has no hash table. If we have any multicast 499 * addresses on the list, enable reception of all multicast 500 * frames. 501 * 502 * XXX The 80c03 has a hash table. We should use it. 503 */ 504 505 ETHER_FIRST_MULTI(step, ec, enm); 506 507 if (enm == NULL) { 508 sc->sc_rxcmd &= ~RXCMD_REC_MASK; 509 sc->sc_rxcmd |= RXCMD_REC_BROAD; 510 511 ifp->if_flags &= ~IFF_ALLMULTI; 512 return; 513 } 514 515 sc->sc_rxcmd |= RXCMD_REC_MULTI; 516 ifp->if_flags |= IFF_ALLMULTI; 517 } 518 519 int 520 sq_ioctl(struct ifnet *ifp, u_long cmd, void *data) 521 { 522 int s, error = 0; 523 524 SQ_TRACE(SQ_IOCTL, (struct sq_softc *)ifp->if_softc, 0, 0); 525 526 s = splnet(); 527 528 error = ether_ioctl(ifp, cmd, data); 529 if (error == ENETRESET) { 530 /* 531 * Multicast list has changed; set the hardware filter 532 * accordingly. 533 */ 534 if (ifp->if_flags & IFF_RUNNING) 535 error = sq_init(ifp); 536 else 537 error = 0; 538 } 539 540 splx(s); 541 return error; 542 } 543 544 void 545 sq_start(struct ifnet *ifp) 546 { 547 struct sq_softc *sc = ifp->if_softc; 548 uint32_t status; 549 struct mbuf *m0, *m; 550 bus_dmamap_t dmamap; 551 int err, totlen, nexttx, firsttx, lasttx = -1, ofree, seg; 552 553 if ((ifp->if_flags & IFF_RUNNING) == 0) 554 return; 555 556 /* 557 * Remember the previous number of free descriptors and 558 * the first descriptor we'll use. 559 */ 560 ofree = sc->sc_nfreetx; 561 firsttx = sc->sc_nexttx; 562 563 /* 564 * Loop through the send queue, setting up transmit descriptors 565 * until we drain the queue, or use up all available transmit 566 * descriptors. 567 */ 568 while (sc->sc_nfreetx != 0) { 569 /* 570 * Grab a packet off the queue. 571 */ 572 IFQ_POLL(&ifp->if_snd, m0); 573 if (m0 == NULL) 574 break; 575 m = NULL; 576 577 dmamap = sc->sc_txmap[sc->sc_nexttx]; 578 579 /* 580 * Load the DMA map. If this fails, the packet either 581 * didn't fit in the allotted number of segments, or we were 582 * short on resources. In this case, we'll copy and try 583 * again. 584 * Also copy it if we need to pad, so that we are sure there 585 * is room for the pad buffer. 586 * XXX the right way of doing this is to use a static buffer 587 * for padding and adding it to the transmit descriptor (see 588 * sys/dev/pci/if_tl.c for example). We can't do this here yet 589 * because we can't send packets with more than one fragment. 590 */ 591 if (m0->m_pkthdr.len < ETHER_PAD_LEN || 592 bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, m0, 593 BUS_DMA_NOWAIT) != 0) { 594 MGETHDR(m, M_DONTWAIT, MT_DATA); 595 if (m == NULL) { 596 printf("%s: unable to allocate Tx mbuf\n", 597 device_xname(sc->sc_dev)); 598 break; 599 } 600 if (m0->m_pkthdr.len > MHLEN) { 601 MCLGET(m, M_DONTWAIT); 602 if ((m->m_flags & M_EXT) == 0) { 603 printf("%s: unable to allocate Tx " 604 "cluster\n", 605 device_xname(sc->sc_dev)); 606 m_freem(m); 607 break; 608 } 609 } 610 611 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *)); 612 if (m0->m_pkthdr.len < ETHER_PAD_LEN) { 613 memset(mtod(m, char *) + m0->m_pkthdr.len, 0, 614 ETHER_PAD_LEN - m0->m_pkthdr.len); 615 m->m_pkthdr.len = m->m_len = ETHER_PAD_LEN; 616 } else 617 m->m_pkthdr.len = m->m_len = m0->m_pkthdr.len; 618 619 if ((err = bus_dmamap_load_mbuf(sc->sc_dmat, dmamap, 620 m, BUS_DMA_NOWAIT)) != 0) { 621 printf("%s: unable to load Tx buffer, " 622 "error = %d\n", 623 device_xname(sc->sc_dev), err); 624 break; 625 } 626 } 627 628 /* 629 * Ensure we have enough descriptors free to describe 630 * the packet. 631 */ 632 if (dmamap->dm_nsegs > sc->sc_nfreetx) { 633 /* 634 * Not enough free descriptors to transmit this 635 * packet. We haven't committed to anything yet, 636 * so just unload the DMA map, put the packet 637 * back on the queue, and punt. 638 * 639 * XXX We could allocate an mbuf and copy, but 640 * XXX it is worth it? 641 */ 642 bus_dmamap_unload(sc->sc_dmat, dmamap); 643 m_freem(m); 644 break; 645 } 646 647 IFQ_DEQUEUE(&ifp->if_snd, m0); 648 /* 649 * Pass the packet to any BPF listeners. 650 */ 651 bpf_mtap(ifp, m0, BPF_D_OUT); 652 if (m != NULL) { 653 m_freem(m0); 654 m0 = m; 655 } 656 657 /* 658 * WE ARE NOW COMMITTED TO TRANSMITTING THE PACKET. 659 */ 660 661 SQ_TRACE(SQ_ENQUEUE, sc, sc->sc_nexttx, 0); 662 663 /* Sync the DMA map. */ 664 bus_dmamap_sync(sc->sc_dmat, dmamap, 0, dmamap->dm_mapsize, 665 BUS_DMASYNC_PREWRITE); 666 667 /* 668 * Initialize the transmit descriptors. 669 */ 670 for (nexttx = sc->sc_nexttx, seg = 0, totlen = 0; 671 seg < dmamap->dm_nsegs; 672 seg++, nexttx = SQ_NEXTTX(nexttx)) { 673 if (sc->hpc_regs->revision == 3) { 674 sc->sc_txdesc[nexttx].hpc3_hdd_bufptr = 675 dmamap->dm_segs[seg].ds_addr; 676 sc->sc_txdesc[nexttx].hpc3_hdd_ctl = 677 dmamap->dm_segs[seg].ds_len; 678 } else { 679 sc->sc_txdesc[nexttx].hpc1_hdd_bufptr = 680 dmamap->dm_segs[seg].ds_addr; 681 sc->sc_txdesc[nexttx].hpc1_hdd_ctl = 682 dmamap->dm_segs[seg].ds_len; 683 } 684 sc->sc_txdesc[nexttx].hdd_descptr = 685 SQ_CDTXADDR(sc, SQ_NEXTTX(nexttx)); 686 lasttx = nexttx; 687 totlen += dmamap->dm_segs[seg].ds_len; 688 } 689 690 /* Last descriptor gets end-of-packet */ 691 KASSERT(lasttx != -1); 692 if (sc->hpc_regs->revision == 3) 693 sc->sc_txdesc[lasttx].hpc3_hdd_ctl |= 694 HPC3_HDD_CTL_EOPACKET; 695 else 696 sc->sc_txdesc[lasttx].hpc1_hdd_ctl |= 697 HPC1_HDD_CTL_EOPACKET; 698 699 SQ_DPRINTF(("%s: transmit %d-%d, len %d\n", 700 device_xname(sc->sc_dev), sc->sc_nexttx, lasttx, totlen)); 701 702 if (ifp->if_flags & IFF_DEBUG) { 703 printf(" transmit chain:\n"); 704 for (seg = sc->sc_nexttx;; seg = SQ_NEXTTX(seg)) { 705 printf(" descriptor %d:\n", seg); 706 printf(" hdd_bufptr: 0x%08x\n", 707 (sc->hpc_regs->revision == 3) ? 708 sc->sc_txdesc[seg].hpc3_hdd_bufptr : 709 sc->sc_txdesc[seg].hpc1_hdd_bufptr); 710 printf(" hdd_ctl: 0x%08x\n", 711 (sc->hpc_regs->revision == 3) ? 712 sc->sc_txdesc[seg].hpc3_hdd_ctl: 713 sc->sc_txdesc[seg].hpc1_hdd_ctl); 714 printf(" hdd_descptr: 0x%08x\n", 715 sc->sc_txdesc[seg].hdd_descptr); 716 717 if (seg == lasttx) 718 break; 719 } 720 } 721 722 /* Sync the descriptors we're using. */ 723 SQ_CDTXSYNC(sc, sc->sc_nexttx, dmamap->dm_nsegs, 724 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 725 726 /* Store a pointer to the packet so we can free it later */ 727 sc->sc_txmbuf[sc->sc_nexttx] = m0; 728 729 /* Advance the tx pointer. */ 730 sc->sc_nfreetx -= dmamap->dm_nsegs; 731 sc->sc_nexttx = nexttx; 732 } 733 734 if (sc->sc_nfreetx != ofree) { 735 SQ_DPRINTF(("%s: %d packets enqueued, first %d, INTR on %d\n", 736 device_xname(sc->sc_dev), lasttx - firsttx + 1, 737 firsttx, lasttx)); 738 739 /* 740 * Cause a transmit interrupt to happen on the 741 * last packet we enqueued, mark it as the last 742 * descriptor. 743 * 744 * HPC1_HDD_CTL_INTR will generate an interrupt on 745 * HPC1. HPC3 requires HPC3_HDD_CTL_EOPACKET in 746 * addition to HPC3_HDD_CTL_INTR to interrupt. 747 */ 748 KASSERT(lasttx != -1); 749 if (sc->hpc_regs->revision == 3) { 750 sc->sc_txdesc[lasttx].hpc3_hdd_ctl |= 751 HPC3_HDD_CTL_INTR | HPC3_HDD_CTL_EOCHAIN; 752 } else { 753 sc->sc_txdesc[lasttx].hpc1_hdd_ctl |= HPC1_HDD_CTL_INTR; 754 sc->sc_txdesc[lasttx].hpc1_hdd_bufptr |= 755 HPC1_HDD_CTL_EOCHAIN; 756 } 757 758 SQ_CDTXSYNC(sc, lasttx, 1, 759 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 760 761 /* 762 * There is a potential race condition here if the HPC 763 * DMA channel is active and we try and either update 764 * the 'next descriptor' pointer in the HPC PIO space 765 * or the 'next descriptor' pointer in a previous desc- 766 * riptor. 767 * 768 * To avoid this, if the channel is active, we rely on 769 * the transmit interrupt routine noticing that there 770 * are more packets to send and restarting the HPC DMA 771 * engine, rather than mucking with the DMA state here. 772 */ 773 status = sq_hpc_read(sc, sc->hpc_regs->enetx_ctl); 774 775 if ((status & sc->hpc_regs->enetx_ctl_active) != 0) { 776 SQ_TRACE(SQ_ADD_TO_DMA, sc, firsttx, status); 777 778 /* 779 * NB: hpc3_hdd_ctl == hpc1_hdd_bufptr, and 780 * HPC1_HDD_CTL_EOCHAIN == HPC3_HDD_CTL_EOCHAIN 781 */ 782 sc->sc_txdesc[SQ_PREVTX(firsttx)].hpc3_hdd_ctl &= 783 ~HPC3_HDD_CTL_EOCHAIN; 784 785 if (sc->hpc_regs->revision != 3) 786 sc->sc_txdesc[SQ_PREVTX(firsttx)].hpc1_hdd_ctl 787 &= ~HPC1_HDD_CTL_INTR; 788 789 SQ_CDTXSYNC(sc, SQ_PREVTX(firsttx), 1, 790 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 791 } else if (sc->hpc_regs->revision == 3) { 792 SQ_TRACE(SQ_START_DMA, sc, firsttx, status); 793 794 sq_hpc_write(sc, HPC3_ENETX_NDBP, SQ_CDTXADDR(sc, 795 firsttx)); 796 797 /* Kick DMA channel into life */ 798 sq_hpc_write(sc, HPC3_ENETX_CTL, HPC3_ENETX_CTL_ACTIVE); 799 } else { 800 /* 801 * In the HPC1 case where transmit DMA is 802 * inactive, we can either kick off if 803 * the ring was previously empty, or call 804 * our transmit interrupt handler to 805 * figure out if the ring stopped short 806 * and restart at the right place. 807 */ 808 if (ofree == SQ_NTXDESC) { 809 SQ_TRACE(SQ_START_DMA, sc, firsttx, status); 810 811 sq_hpc_write(sc, HPC1_ENETX_NDBP, 812 SQ_CDTXADDR(sc, firsttx)); 813 sq_hpc_write(sc, HPC1_ENETX_CFXBP, 814 SQ_CDTXADDR(sc, firsttx)); 815 sq_hpc_write(sc, HPC1_ENETX_CBP, 816 SQ_CDTXADDR(sc, firsttx)); 817 818 /* Kick DMA channel into life */ 819 sq_hpc_write(sc, HPC1_ENETX_CTL, 820 HPC1_ENETX_CTL_ACTIVE); 821 } else 822 sq_txring_hpc1(sc); 823 } 824 825 /* Set a watchdog timer in case the chip flakes out. */ 826 ifp->if_timer = 5; 827 } 828 } 829 830 void 831 sq_stop(struct ifnet *ifp, int disable) 832 { 833 int i; 834 struct sq_softc *sc = ifp->if_softc; 835 836 for (i = 0; i < SQ_NTXDESC; i++) { 837 if (sc->sc_txmbuf[i] != NULL) { 838 bus_dmamap_unload(sc->sc_dmat, sc->sc_txmap[i]); 839 m_freem(sc->sc_txmbuf[i]); 840 sc->sc_txmbuf[i] = NULL; 841 } 842 } 843 844 /* Clear Seeq transmit/receive command registers */ 845 sq_seeq_write(sc, SEEQ_TXCMD, 0); 846 sq_seeq_write(sc, SEEQ_RXCMD, 0); 847 848 sq_reset(sc); 849 850 ifp->if_flags &= ~IFF_RUNNING; 851 ifp->if_timer = 0; 852 } 853 854 /* Device timeout/watchdog routine. */ 855 void 856 sq_watchdog(struct ifnet *ifp) 857 { 858 uint32_t status; 859 struct sq_softc *sc = ifp->if_softc; 860 861 status = sq_hpc_read(sc, sc->hpc_regs->enetx_ctl); 862 log(LOG_ERR, "%s: device timeout (prev %d, next %d, free %d, " 863 "status %08x)\n", device_xname(sc->sc_dev), sc->sc_prevtx, 864 sc->sc_nexttx, sc->sc_nfreetx, status); 865 866 sq_trace_dump(sc); 867 868 memset(&sc->sq_trace, 0, sizeof(sc->sq_trace)); 869 sc->sq_trace_idx = 0; 870 871 if_statinc(ifp, if_oerrors); 872 873 sq_init(ifp); 874 } 875 876 static void 877 sq_trace_dump(struct sq_softc *sc) 878 { 879 int i; 880 const char *act; 881 882 for (i = 0; i < sc->sq_trace_idx; i++) { 883 switch (sc->sq_trace[i].action) { 884 case SQ_RESET: act = "SQ_RESET"; break; 885 case SQ_ADD_TO_DMA: act = "SQ_ADD_TO_DMA"; break; 886 case SQ_START_DMA: act = "SQ_START_DMA"; break; 887 case SQ_DONE_DMA: act = "SQ_DONE_DMA"; break; 888 case SQ_RESTART_DMA: act = "SQ_RESTART_DMA"; break; 889 case SQ_TXINTR_ENTER: act = "SQ_TXINTR_ENTER"; break; 890 case SQ_TXINTR_EXIT: act = "SQ_TXINTR_EXIT"; break; 891 case SQ_TXINTR_BUSY: act = "SQ_TXINTR_BUSY"; break; 892 case SQ_IOCTL: act = "SQ_IOCTL"; break; 893 case SQ_ENQUEUE: act = "SQ_ENQUEUE"; break; 894 default: act = "UNKNOWN"; 895 } 896 897 printf("%s: [%03d] action %-16s buf %03d free %03d " 898 "status %08x line %d\n", device_xname(sc->sc_dev), i, act, 899 sc->sq_trace[i].bufno, sc->sq_trace[i].freebuf, 900 sc->sq_trace[i].status, sc->sq_trace[i].line); 901 } 902 } 903 904 static int 905 sq_intr(void *arg) 906 { 907 struct sq_softc *sc = arg; 908 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 909 int handled = 0; 910 uint32_t stat; 911 912 stat = sq_hpc_read(sc, sc->hpc_regs->enetr_reset); 913 914 if ((stat & 2) == 0) { 915 SQ_DPRINTF(("%s: Unexpected interrupt!\n", 916 device_xname(sc->sc_dev))); 917 } else 918 sq_hpc_write(sc, sc->hpc_regs->enetr_reset, (stat | 2)); 919 920 /* 921 * If the interface isn't running, the interrupt couldn't 922 * possibly have come from us. 923 */ 924 if ((ifp->if_flags & IFF_RUNNING) == 0) 925 return 0; 926 927 sc->sq_intrcnt.ev_count++; 928 929 /* Always check for received packets */ 930 if (sq_rxintr(sc) != 0) 931 handled++; 932 933 /* Only handle transmit interrupts if we actually sent something */ 934 if (sc->sc_nfreetx < SQ_NTXDESC) { 935 sq_txintr(sc); 936 handled++; 937 } 938 939 if (handled) 940 rnd_add_uint32(&sc->rnd_source, stat); 941 return handled; 942 } 943 944 static int 945 sq_rxintr(struct sq_softc *sc) 946 { 947 int count = 0; 948 struct mbuf* m; 949 int i, framelen; 950 uint8_t pktstat; 951 uint32_t status; 952 uint32_t ctl_reg; 953 int new_end, orig_end; 954 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 955 956 for (i = sc->sc_nextrx;; i = SQ_NEXTRX(i)) { 957 SQ_CDRXSYNC(sc, i, 958 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 959 960 /* 961 * If this is a CPU-owned buffer, we're at the end of the list. 962 */ 963 if (sc->hpc_regs->revision == 3) 964 ctl_reg = 965 sc->sc_rxdesc[i].hpc3_hdd_ctl & HPC3_HDD_CTL_OWN; 966 else 967 ctl_reg = 968 sc->sc_rxdesc[i].hpc1_hdd_ctl & HPC1_HDD_CTL_OWN; 969 970 if (ctl_reg) { 971 #if defined(SQ_DEBUG) 972 uint32_t reg; 973 974 reg = sq_hpc_read(sc, sc->hpc_regs->enetr_ctl); 975 SQ_DPRINTF(("%s: rxintr: done at %d (ctl %08x)\n", 976 device_xname(sc->sc_dev), i, reg)); 977 #endif 978 break; 979 } 980 981 count++; 982 983 m = sc->sc_rxmbuf[i]; 984 framelen = m->m_ext.ext_size - 3; 985 if (sc->hpc_regs->revision == 3) 986 framelen -= 987 HPC3_HDD_CTL_BYTECNT(sc->sc_rxdesc[i].hpc3_hdd_ctl); 988 else 989 framelen -= 990 HPC1_HDD_CTL_BYTECNT(sc->sc_rxdesc[i].hpc1_hdd_ctl); 991 992 /* Now sync the actual packet data */ 993 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[i], 0, 994 sc->sc_rxmap[i]->dm_mapsize, BUS_DMASYNC_POSTREAD); 995 996 pktstat = *((uint8_t *)m->m_data + framelen + 2); 997 998 if ((pktstat & RXSTAT_GOOD) == 0) { 999 if_statinc(ifp, if_ierrors); 1000 1001 if (pktstat & RXSTAT_OFLOW) 1002 printf("%s: receive FIFO overflow\n", 1003 device_xname(sc->sc_dev)); 1004 1005 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[i], 0, 1006 sc->sc_rxmap[i]->dm_mapsize, BUS_DMASYNC_PREREAD); 1007 SQ_INIT_RXDESC(sc, i); 1008 SQ_DPRINTF(("%s: sq_rxintr: buf %d no RXSTAT_GOOD\n", 1009 device_xname(sc->sc_dev), i)); 1010 continue; 1011 } 1012 1013 if (sq_add_rxbuf(sc, i) != 0) { 1014 if_statinc(ifp, if_ierrors); 1015 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[i], 0, 1016 sc->sc_rxmap[i]->dm_mapsize, BUS_DMASYNC_PREREAD); 1017 SQ_INIT_RXDESC(sc, i); 1018 SQ_DPRINTF(("%s: sq_rxintr: buf %d sq_add_rxbuf() " 1019 "failed\n", device_xname(sc->sc_dev), i)); 1020 continue; 1021 } 1022 1023 1024 m->m_data += 2; 1025 m_set_rcvif(m, ifp); 1026 m->m_pkthdr.len = m->m_len = framelen; 1027 1028 SQ_DPRINTF(("%s: sq_rxintr: buf %d len %d\n", 1029 device_xname(sc->sc_dev), i, framelen)); 1030 1031 if_percpuq_enqueue(ifp->if_percpuq, m); 1032 } 1033 1034 1035 /* If anything happened, move ring start/end pointers to new spot */ 1036 if (i != sc->sc_nextrx) { 1037 /* 1038 * NB: hpc3_hdd_ctl == hpc1_hdd_bufptr, and 1039 * HPC1_HDD_CTL_EOCHAIN == HPC3_HDD_CTL_EOCHAIN 1040 */ 1041 1042 new_end = SQ_PREVRX(i); 1043 sc->sc_rxdesc[new_end].hpc3_hdd_ctl |= HPC3_HDD_CTL_EOCHAIN; 1044 SQ_CDRXSYNC(sc, new_end, 1045 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1046 1047 orig_end = SQ_PREVRX(sc->sc_nextrx); 1048 sc->sc_rxdesc[orig_end].hpc3_hdd_ctl &= ~HPC3_HDD_CTL_EOCHAIN; 1049 SQ_CDRXSYNC(sc, orig_end, 1050 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1051 1052 sc->sc_nextrx = i; 1053 } 1054 1055 status = sq_hpc_read(sc, sc->hpc_regs->enetr_ctl); 1056 1057 /* If receive channel is stopped, restart it... */ 1058 if ((status & sc->hpc_regs->enetr_ctl_active) == 0) { 1059 /* Pass the start of the receive ring to the HPC */ 1060 sq_hpc_write(sc, sc->hpc_regs->enetr_ndbp, 1061 SQ_CDRXADDR(sc, sc->sc_nextrx)); 1062 1063 /* And turn on the HPC ethernet receive channel */ 1064 sq_hpc_write(sc, sc->hpc_regs->enetr_ctl, 1065 sc->hpc_regs->enetr_ctl_active); 1066 } 1067 1068 return count; 1069 } 1070 1071 static int 1072 sq_txintr(struct sq_softc *sc) 1073 { 1074 int shift = 0; 1075 uint32_t status, tmp; 1076 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1077 1078 if (sc->hpc_regs->revision != 3) 1079 shift = 16; 1080 1081 status = sq_hpc_read(sc, sc->hpc_regs->enetx_ctl) >> shift; 1082 1083 SQ_TRACE(SQ_TXINTR_ENTER, sc, sc->sc_prevtx, status); 1084 1085 net_stat_ref_t nsr = IF_STAT_GETREF(ifp); 1086 tmp = (sc->hpc_regs->enetx_ctl_active >> shift) | TXSTAT_GOOD; 1087 if ((status & tmp) == 0) { 1088 if (status & TXSTAT_COLL) 1089 if_statinc_ref(ifp, nsr, if_collisions); 1090 1091 if (status & TXSTAT_UFLOW) { 1092 printf("%s: transmit underflow\n", 1093 device_xname(sc->sc_dev)); 1094 if_statinc_ref(ifp, nsr, if_oerrors); 1095 } 1096 1097 if (status & TXSTAT_16COLL) { 1098 printf("%s: max collisions reached\n", 1099 device_xname(sc->sc_dev)); 1100 if_statinc_ref(ifp, nsr, if_oerrors); 1101 if_statadd_ref(ifp, nsr, if_collisions, 16); 1102 } 1103 } 1104 IF_STAT_PUTREF(ifp); 1105 1106 /* prevtx now points to next xmit packet not yet finished */ 1107 if (sc->hpc_regs->revision == 3) 1108 sq_txring_hpc3(sc); 1109 else 1110 sq_txring_hpc1(sc); 1111 1112 /* If all packets have left the coop, cancel watchdog */ 1113 if (sc->sc_nfreetx == SQ_NTXDESC) 1114 ifp->if_timer = 0; 1115 1116 SQ_TRACE(SQ_TXINTR_EXIT, sc, sc->sc_prevtx, status); 1117 if_schedule_deferred_start(ifp); 1118 1119 return 1; 1120 } 1121 1122 /* 1123 * Reclaim used transmit descriptors and restart the transmit DMA 1124 * engine if necessary. 1125 */ 1126 static void 1127 sq_txring_hpc1(struct sq_softc *sc) 1128 { 1129 /* 1130 * HPC1 doesn't tag transmitted descriptors, however, 1131 * the NDBP register points to the next descriptor that 1132 * has not yet been processed. If DMA is not in progress, 1133 * we can safely reclaim all descriptors up to NDBP, and, 1134 * if necessary, restart DMA at NDBP. Otherwise, if DMA 1135 * is active, we can only safely reclaim up to CBP. 1136 * 1137 * For now, we'll only reclaim on inactive DMA and assume 1138 * that a sufficiently large ring keeps us out of trouble. 1139 */ 1140 uint32_t reclaimto, status; 1141 int reclaimall, i = sc->sc_prevtx; 1142 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1143 1144 status = sq_hpc_read(sc, HPC1_ENETX_CTL); 1145 if (status & HPC1_ENETX_CTL_ACTIVE) { 1146 SQ_TRACE(SQ_TXINTR_BUSY, sc, i, status); 1147 return; 1148 } else 1149 reclaimto = sq_hpc_read(sc, HPC1_ENETX_NDBP); 1150 1151 if (sc->sc_nfreetx == 0 && SQ_CDTXADDR(sc, i) == reclaimto) 1152 reclaimall = 1; 1153 else 1154 reclaimall = 0; 1155 1156 while (sc->sc_nfreetx < SQ_NTXDESC) { 1157 if (SQ_CDTXADDR(sc, i) == reclaimto && !reclaimall) 1158 break; 1159 1160 SQ_CDTXSYNC(sc, i, sc->sc_txmap[i]->dm_nsegs, 1161 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1162 1163 /* Sync the packet data, unload DMA map, free mbuf */ 1164 bus_dmamap_sync(sc->sc_dmat, sc->sc_txmap[i], 1165 0, sc->sc_txmap[i]->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1166 bus_dmamap_unload(sc->sc_dmat, sc->sc_txmap[i]); 1167 m_freem(sc->sc_txmbuf[i]); 1168 sc->sc_txmbuf[i] = NULL; 1169 1170 if_statinc(ifp, if_opackets); 1171 sc->sc_nfreetx++; 1172 1173 SQ_TRACE(SQ_DONE_DMA, sc, i, status); 1174 1175 i = SQ_NEXTTX(i); 1176 } 1177 1178 if (sc->sc_nfreetx < SQ_NTXDESC) { 1179 SQ_TRACE(SQ_RESTART_DMA, sc, i, status); 1180 1181 KASSERT(reclaimto == SQ_CDTXADDR(sc, i)); 1182 1183 sq_hpc_write(sc, HPC1_ENETX_CFXBP, reclaimto); 1184 sq_hpc_write(sc, HPC1_ENETX_CBP, reclaimto); 1185 1186 /* Kick DMA channel into life */ 1187 sq_hpc_write(sc, HPC1_ENETX_CTL, HPC1_ENETX_CTL_ACTIVE); 1188 1189 /* 1190 * Set a watchdog timer in case the chip 1191 * flakes out. 1192 */ 1193 ifp->if_timer = 5; 1194 } 1195 1196 sc->sc_prevtx = i; 1197 } 1198 1199 /* 1200 * Reclaim used transmit descriptors and restart the transmit DMA 1201 * engine if necessary. 1202 */ 1203 static void 1204 sq_txring_hpc3(struct sq_softc *sc) 1205 { 1206 /* 1207 * HPC3 tags descriptors with a bit once they've been 1208 * transmitted. We need only free each XMITDONE'd 1209 * descriptor, and restart the DMA engine if any 1210 * descriptors are left over. 1211 */ 1212 int i; 1213 uint32_t status = 0; 1214 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1215 1216 i = sc->sc_prevtx; 1217 while (sc->sc_nfreetx < SQ_NTXDESC) { 1218 /* 1219 * Check status first so we don't end up with a case of 1220 * the buffer not being finished while the DMA channel 1221 * has gone idle. 1222 */ 1223 status = sq_hpc_read(sc, HPC3_ENETX_CTL); 1224 1225 SQ_CDTXSYNC(sc, i, sc->sc_txmap[i]->dm_nsegs, 1226 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1227 1228 /* Check for used descriptor and restart DMA chain if needed */ 1229 if ((sc->sc_txdesc[i].hpc3_hdd_ctl & 1230 HPC3_HDD_CTL_XMITDONE) == 0) { 1231 if ((status & HPC3_ENETX_CTL_ACTIVE) == 0) { 1232 SQ_TRACE(SQ_RESTART_DMA, sc, i, status); 1233 1234 sq_hpc_write(sc, HPC3_ENETX_NDBP, 1235 SQ_CDTXADDR(sc, i)); 1236 1237 /* Kick DMA channel into life */ 1238 sq_hpc_write(sc, HPC3_ENETX_CTL, 1239 HPC3_ENETX_CTL_ACTIVE); 1240 1241 /* 1242 * Set a watchdog timer in case the chip 1243 * flakes out. 1244 */ 1245 ifp->if_timer = 5; 1246 } else 1247 SQ_TRACE(SQ_TXINTR_BUSY, sc, i, status); 1248 break; 1249 } 1250 1251 /* Sync the packet data, unload DMA map, free mbuf */ 1252 bus_dmamap_sync(sc->sc_dmat, sc->sc_txmap[i], 1253 0, sc->sc_txmap[i]->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1254 bus_dmamap_unload(sc->sc_dmat, sc->sc_txmap[i]); 1255 m_freem(sc->sc_txmbuf[i]); 1256 sc->sc_txmbuf[i] = NULL; 1257 1258 if_statinc(ifp, if_opackets); 1259 sc->sc_nfreetx++; 1260 1261 SQ_TRACE(SQ_DONE_DMA, sc, i, status); 1262 i = SQ_NEXTTX(i); 1263 } 1264 1265 sc->sc_prevtx = i; 1266 } 1267 1268 void 1269 sq_reset(struct sq_softc *sc) 1270 { 1271 1272 /* Stop HPC dma channels */ 1273 sq_hpc_write(sc, sc->hpc_regs->enetr_ctl, 0); 1274 sq_hpc_write(sc, sc->hpc_regs->enetx_ctl, 0); 1275 1276 sq_hpc_write(sc, sc->hpc_regs->enetr_reset, 3); 1277 delay(20); 1278 sq_hpc_write(sc, sc->hpc_regs->enetr_reset, 0); 1279 } 1280 1281 /* sq_add_rxbuf: Add a receive buffer to the indicated descriptor. */ 1282 int 1283 sq_add_rxbuf(struct sq_softc *sc, int idx) 1284 { 1285 int err; 1286 struct mbuf *m; 1287 1288 MGETHDR(m, M_DONTWAIT, MT_DATA); 1289 if (m == NULL) 1290 return ENOBUFS; 1291 1292 MCLGET(m, M_DONTWAIT); 1293 if ((m->m_flags & M_EXT) == 0) { 1294 m_freem(m); 1295 return ENOBUFS; 1296 } 1297 1298 if (sc->sc_rxmbuf[idx] != NULL) 1299 bus_dmamap_unload(sc->sc_dmat, sc->sc_rxmap[idx]); 1300 1301 sc->sc_rxmbuf[idx] = m; 1302 1303 if ((err = bus_dmamap_load(sc->sc_dmat, sc->sc_rxmap[idx], 1304 m->m_ext.ext_buf, m->m_ext.ext_size, NULL, BUS_DMA_NOWAIT)) != 0) { 1305 printf("%s: can't load rx DMA map %d, error = %d\n", 1306 device_xname(sc->sc_dev), idx, err); 1307 panic("sq_add_rxbuf"); /* XXX */ 1308 } 1309 1310 bus_dmamap_sync(sc->sc_dmat, sc->sc_rxmap[idx], 1311 0, sc->sc_rxmap[idx]->dm_mapsize, BUS_DMASYNC_PREREAD); 1312 1313 SQ_INIT_RXDESC(sc, idx); 1314 1315 return 0; 1316 } 1317 1318 void 1319 sq_dump_buffer(paddr_t addr, psize_t len) 1320 { 1321 u_int i; 1322 uint8_t *physaddr = (uint8_t *)MIPS_PHYS_TO_KSEG1(addr); 1323 1324 if (len == 0) 1325 return; 1326 1327 printf("%p: ", physaddr); 1328 1329 for (i = 0; i < len; i++) { 1330 printf("%02x ", *(physaddr + i) & 0xff); 1331 if ((i % 16) == 15 && i != len - 1) 1332 printf("\n%p: ", physaddr + i); 1333 } 1334 1335 printf("\n"); 1336 } 1337