1 /* $OpenBSD: if_mc.c,v 1.28 2016/04/13 11:34:00 mpi Exp $ */ 2 /* $NetBSD: if_mc.c,v 1.9.16.1 2006/06/21 14:53:13 yamt Exp $ */ 3 4 /*- 5 * Copyright (c) 1997 David Huang <khym@bga.com> 6 * All rights reserved. 7 * 8 * Portions of this code are based on code by Denton Gentry <denny1@home.com> 9 * and Yanagisawa Takeshi <yanagisw@aa.ap.titech.ac.jp>. 10 * 11 * Redistribution and use in source and binary forms, with or without 12 * modification, are permitted provided that the following conditions 13 * are met: 14 * 1. Redistributions of source code must retain the above copyright 15 * notice, this list of conditions and the following disclaimer. 16 * 2. The name of the author may not be used to endorse or promote products 17 * derived from this software without specific prior written permission 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 20 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 21 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 22 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 24 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 */ 31 32 /* 33 * AMD AM79C940 (MACE) driver with DBDMA bus attachment and DMA routines 34 * for onboard ethernet found on most old world macs. 35 */ 36 37 #include <sys/param.h> 38 #include <sys/systm.h> 39 #include <sys/mbuf.h> 40 #include <sys/buf.h> 41 #include <sys/protosw.h> 42 #include <sys/socket.h> 43 #include <sys/syslog.h> 44 #include <sys/ioctl.h> 45 #include <sys/errno.h> 46 #include <sys/device.h> 47 #include <sys/timeout.h> 48 49 #include <net/if.h> 50 #include <net/if_media.h> 51 52 #include <netinet/in.h> 53 #include <netinet/if_ether.h> 54 55 #include "bpfilter.h" 56 #if NBPFILTER > 0 57 #include <net/bpf.h> 58 #endif 59 60 #include <dev/ofw/openfirm.h> 61 #include <machine/pio.h> 62 #include <machine/bus.h> 63 #include <machine/autoconf.h> 64 65 #include <macppc/dev/dbdma.h> 66 67 #define MC_REGSPACING 16 68 #define MC_REGSIZE MACE_NREGS * MC_REGSPACING 69 #define MACE_REG(x) ((x)*MC_REGSPACING) 70 #define MACE_BUFLEN 2048 71 #define MACE_TXBUFS 2 72 #define MACE_RXBUFS 8 73 74 #define MC_RXDMABUFS 4 75 76 #define MACE_BUFSZ ((MACE_RXBUFS + MACE_TXBUFS + 2) * MACE_BUFLEN) 77 78 #define NIC_GET(sc, reg) (in8rb(sc->sc_reg + MACE_REG(reg))) 79 80 #define NIC_PUT(sc, reg, val) (out8rb(sc->sc_reg + MACE_REG(reg), (val))) 81 82 /* 83 * AMD MACE (Am79C940) register definitions 84 */ 85 #define MACE_RCVFIFO 0 /* Receive FIFO [15-00] (read only) */ 86 #define MACE_XMTFIFO 1 /* Transmit FIFO [15-00] (write only) */ 87 #define MACE_XMTFC 2 /* Transmit Frame Control (read/write) */ 88 #define MACE_XMTFS 3 /* Transmit Frame Status (read only) */ 89 #define MACE_XMTRC 4 /* Transmit Retry Count (read only) */ 90 #define MACE_RCVFC 5 /* Receive Frame Control (read/write) */ 91 #define MACE_RCVFS 6 /* Receive Frame Status (4 bytes) (read only) */ 92 #define MACE_FIFOFC 7 /* FIFO Frame Count (read only) */ 93 #define MACE_IR 8 /* Interrupt Register (read only) */ 94 #define MACE_IMR 9 /* Interrupt Mask Register (read/write) */ 95 #define MACE_PR 10 /* Poll Register (read only) */ 96 #define MACE_BIUCC 11 /* BIU Configuration Control (read/write) */ 97 #define MACE_FIFOCC 12 /* FIFO Configuration Control (read/write) */ 98 #define MACE_MACCC 13 /* MAC Configuration Control (read/write) */ 99 #define MACE_PLSCC 14 /* PLS Configuration Control (read/write) */ 100 #define MACE_PHYCC 15 /* PHY Confiuration Control (read/write) */ 101 #define MACE_CHIPIDL 16 /* Chip ID Register [07-00] (read only) */ 102 #define MACE_CHIPIDH 17 /* Chip ID Register [15-08] (read only) */ 103 #define MACE_IAC 18 /* Internal Address Configuration (read/write) */ 104 /* RESERVED 19 Reserved (read/write as 0) */ 105 #define MACE_LADRF 20 /* Logical Address Filter (8 bytes) (read/write) */ 106 #define MACE_PADR 21 /* Physical Address (6 bytes) (read/write) */ 107 /* RESERVED 22 Reserved (read/write as 0) */ 108 /* RESERVED 23 Reserved (read/write as 0) */ 109 #define MACE_MPC 24 /* Missed Packet Count (read only) */ 110 /* RESERVED 25 Reserved (read/write as 0) */ 111 #define MACE_RNTPC 26 /* Runt Packet Count (read only) */ 112 #define MACE_RCVCC 27 /* Receive Collision Count (read only) */ 113 /* RESERVED 28 Reserved (read/write as 0) */ 114 #define MACE_UTR 29 /* User Test Register (read/write) */ 115 #define MACE_RTR1 30 /* Reserved Test Register 1 (read/write as 0) */ 116 #define MACE_RTR2 31 /* Reserved Test Register 2 (read/write as 0) */ 117 118 #define MACE_NREGS 32 119 120 /* 2: Transmit Frame Control (XMTFC) */ 121 #define DRTRY 0x80 /* Disable Retry */ 122 #define DXMTFCS 0x08 /* Disable Transmit FCS */ 123 #define APADXMT 0x01 /* Auto Pad Transmit */ 124 125 /* 3: Transmit Frame Status (XMTFS) */ 126 #define XMTSV 0x80 /* Transmit Status Valid */ 127 #define UFLO 0x40 /* Underflow */ 128 #define LCOL 0x20 /* Late Collision */ 129 #define MORE 0x10 /* More than one retry needed */ 130 #define ONE 0x08 /* Exactly one retry needed */ 131 #define DEFER 0x04 /* Transmission deferred */ 132 #define LCAR 0x02 /* Loss of Carrier */ 133 #define RTRY 0x01 /* Retry Error */ 134 135 /* 4: Transmit Retry Count (XMTRC) */ 136 #define EXDEF 0x80 /* Excessive Defer */ 137 #define XMTRC 0x0f /* Transmit Retry Count */ 138 139 /* 5: Receive Frame Control (RCVFC) */ 140 #define LLRCV 0x08 /* Low Latency Receive */ 141 #define MR 0x04 /* Match/Reject */ 142 #define ASTRPRCV 0x01 /* Auto Strip Receive */ 143 144 /* 6: Receive Frame Status (RCVFS) */ 145 /* 4 byte register; read 4 times to get all of the bytes */ 146 /* Read 1: RFS0 - Receive Message Byte Count [7-0] (RCVCNT) */ 147 148 /* Read 2: RFS1 - Receive Status (RCVSTS) */ 149 #define OFLO 0x80 /* Overflow flag */ 150 #define CLSN 0x40 /* Collision flag */ 151 #define FRAM 0x20 /* Framing Error flag */ 152 #define FCS 0x10 /* FCS Error flag */ 153 #define RCVCNT 0x0f /* Receive Message Byte Count [11-8] */ 154 155 /* Read 3: RFS2 - Runt Packet Count (RNTPC) [7-0] */ 156 157 /* Read 4: RFS3 - Receive Collision Count (RCVCC) [7-0] */ 158 159 /* 7: FIFO Frame Count (FIFOFC) */ 160 #define RCVFC 0xf0 /* Receive Frame Count */ 161 #define XMTFC 0x0f /* Transmit Frame Count */ 162 163 /* 8: Interrupt Register (IR) */ 164 #define JAB 0x80 /* Jabber Error */ 165 #define BABL 0x40 /* Babble Error */ 166 #define CERR 0x20 /* Collision Error */ 167 #define RCVCCO 0x10 /* Receive Collision Count Overflow */ 168 #define RNTPCO 0x08 /* Runt Packet Count Overflow */ 169 #define MPCO 0x04 /* Missed Packet Count Overflow */ 170 #define RCVINT 0x02 /* Receive Interrupt */ 171 #define XMTINT 0x01 /* Transmit Interrupt */ 172 173 /* 9: Interrut Mask Register (IMR) */ 174 #define JABM 0x80 /* Jabber Error Mask */ 175 #define BABLM 0x40 /* Babble Error Mask */ 176 #define CERRM 0x20 /* Collision Error Mask */ 177 #define RCVCCOM 0x10 /* Receive Collision Count Overflow Mask */ 178 #define RNTPCOM 0x08 /* Runt Packet Count Overflow Mask */ 179 #define MPCOM 0x04 /* Missed Packet Count Overflow Mask */ 180 #define RCVINTM 0x02 /* Receive Interrupt Mask */ 181 #define XMTINTM 0x01 /* Transmit Interrupt Mask */ 182 183 /* 10: Poll Register (PR) */ 184 #define XMTSV 0x80 /* Transmit Status Valid */ 185 #define TDTREQ 0x40 /* Transmit Data Transfer Request */ 186 #define RDTREQ 0x20 /* Receive Data Transfer Request */ 187 188 /* 11: BIU Configuration Control (BIUCC) */ 189 #define BSWP 0x40 /* Byte Swap */ 190 #define XMTSP 0x30 /* Transmit Start Point */ 191 #define XMTSP_4 0x00 /* 4 bytes */ 192 #define XMTSP_16 0x10 /* 16 bytes */ 193 #define XMTSP_64 0x20 /* 64 bytes */ 194 #define XMTSP_112 0x30 /* 112 bytes */ 195 #define SWRST 0x01 /* Software Reset */ 196 197 /* 12: FIFO Configuration Control (FIFOCC) */ 198 #define XMTFW 0xc0 /* Transmit FIFO Watermark */ 199 #define XMTFW_8 0x00 /* 8 write cycles */ 200 #define XMTFW_16 0x40 /* 16 write cycles */ 201 #define XMTFW_32 0x80 /* 32 write cycles */ 202 #define RCVFW 0x30 /* Receive FIFO Watermark */ 203 #define RCVFW_16 0x00 /* 16 bytes */ 204 #define RCVFW_32 0x10 /* 32 bytes */ 205 #define RCVFW_64 0x20 /* 64 bytes */ 206 #define XMTFWU 0x08 /* Transmit FIFO Watermark Update */ 207 #define RCVFWU 0x04 /* Receive FIFO Watermark Update */ 208 #define XMTBRST 0x02 /* Transmit Burst */ 209 #define RCVBRST 0x01 /* Receive Burst */ 210 211 /* 13: MAC Configuration (MACCC) */ 212 #define PROM 0x80 /* Promiscuous */ 213 #define DXMT2PD 0x40 /* Disable Transmit Two Part Deferral */ 214 #define EMBA 0x20 /* Enable Modified Back-off Algorithm */ 215 #define DRCVPA 0x08 /* Disable Receive Physical Address */ 216 #define DRCVBC 0x04 /* Disable Receive Broadcast */ 217 #define ENXMT 0x02 /* Enable Transmit */ 218 #define ENRCV 0x01 /* Enable Receive */ 219 220 /* 14: PLS Configuration Control (PLSCC) */ 221 #define XMTSEL 0x08 /* Transmit Mode Select */ 222 #define PORTSEL 0x06 /* Port Select */ 223 #define PORTSEL_AUI 0x00 /* Select AUI */ 224 #define PORTSEL_10BT 0x02 /* Select 10BASE-T */ 225 #define PORTSEL_DAI 0x04 /* Select DAI port */ 226 #define PORTSEL_GPSI 0x06 /* Select GPSI */ 227 #define ENPLSIO 0x01 /* Enable PLS I/O */ 228 229 /* 15: PHY Configuration (PHYCC) */ 230 #define LNKFL 0x80 /* Link Fail */ 231 #define DLNKTST 0x40 /* Disable Link Test */ 232 #define REVPOL 0x20 /* Reversed Polarity */ 233 #define DAPC 0x10 /* Disable Auto Polarity Correction */ 234 #define LRT 0x08 /* Low Receive Threshold */ 235 #define ASEL 0x04 /* Auto Select */ 236 #define RWAKE 0x02 /* Remote Wake */ 237 #define AWAKE 0x01 /* Auto Wake */ 238 239 /* 18: Internal Address Configuration (IAC) */ 240 #define ADDRCHG 0x80 /* Address Change */ 241 #define PHYADDR 0x04 /* Physical Address Reset */ 242 #define LOGADDR 0x02 /* Logical Address Reset */ 243 244 /* 28: User Test Register (UTR) */ 245 #define RTRE 0x80 /* Reserved Test Register Enable */ 246 #define RTRD 0x40 /* Reserved Test Register Disable */ 247 #define RPA 0x20 /* Run Packet Accept */ 248 #define FCOLL 0x10 /* Force Collision */ 249 #define RCVFCSE 0x08 /* Receive FCS Enable */ 250 #define LOOP 0x06 /* Loopback Control */ 251 #define LOOP_NONE 0x00 /* No Loopback */ 252 #define LOOP_EXT 0x02 /* External Loopback */ 253 #define LOOP_INT 0x04 /* Internal Loopback, excludes MENDEC */ 254 #define LOOP_INT_MENDEC 0x06 /* Internal Loopback, includes MENDEC */ 255 256 struct mc_rxframe { 257 u_int8_t rx_rcvcnt; 258 u_int8_t rx_rcvsts; 259 u_int8_t rx_rntpc; 260 u_int8_t rx_rcvcc; 261 u_char *rx_frame; 262 }; 263 264 struct mc_softc { 265 struct device sc_dev; /* base device glue */ 266 struct arpcom sc_arpcom; /* Ethernet common part */ 267 struct timeout sc_tick_ch; 268 269 struct mc_rxframe sc_rxframe; 270 u_int8_t sc_biucc; 271 u_int8_t sc_fifocc; 272 u_int8_t sc_plscc; 273 u_int8_t sc_enaddr[6]; 274 u_int8_t sc_pad[2]; 275 int sc_havecarrier; /* carrier status */ 276 277 char *sc_reg; 278 bus_dma_tag_t sc_dmat; 279 bus_dmamap_t sc_bufmap; 280 bus_dma_segment_t sc_bufseg[1]; 281 282 dbdma_regmap_t *sc_txdma; 283 dbdma_regmap_t *sc_rxdma; 284 dbdma_command_t *sc_txdmacmd; 285 dbdma_command_t *sc_rxdmacmd; 286 dbdma_t sc_txdbdma; 287 dbdma_t sc_rxdbdma; 288 289 caddr_t sc_txbuf; 290 caddr_t sc_rxbuf; 291 paddr_t sc_txbuf_pa; 292 paddr_t sc_rxbuf_pa; 293 int sc_tail; 294 int sc_rxset; 295 int sc_txset; 296 int sc_txseti; 297 }; 298 299 int mc_match(struct device *, void *, void *); 300 void mc_attach(struct device *, struct device *, void *); 301 302 struct cfattach mc_ca = { 303 sizeof(struct mc_softc), mc_match, mc_attach 304 }; 305 306 struct cfdriver mc_cd = { 307 NULL, "mc", DV_IFNET 308 }; 309 310 void mc_init(struct mc_softc *sc); 311 void mc_put(struct mc_softc *sc, u_int len); 312 int mc_dmaintr(void *arg); 313 void mc_reset_rxdma(struct mc_softc *sc); 314 void mc_reset_txdma(struct mc_softc *sc); 315 int mc_stop(struct mc_softc *sc); 316 int mc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data); 317 void mc_start(struct ifnet *ifp); 318 void mc_reset(struct mc_softc *sc); 319 void mc_tint(struct mc_softc *sc); 320 void mc_rint(struct mc_softc *sc); 321 int mc_intr(void *); 322 void mc_watchdog(struct ifnet *ifp); 323 324 u_int maceput(struct mc_softc *sc, struct mbuf *); 325 void mace_read(struct mc_softc *, caddr_t, int); 326 struct mbuf *mace_get(struct mc_softc *, caddr_t, int); 327 static void mace_calcladrf(struct mc_softc *, u_int8_t *); 328 void mc_putpacket(struct mc_softc *, u_int); 329 330 int 331 mc_match(struct device *parent, void *arg, void *aux) 332 { 333 struct confargs *ca = aux; 334 335 if (strcmp(ca->ca_name, "mace") != 0) 336 return 0; 337 338 /* requires 6 regs */ 339 if (ca->ca_nreg / sizeof(int) != 6) 340 return 0; 341 342 /* requires 3 intrs */ 343 if (ca->ca_nintr / sizeof(int) != 3) 344 return 0; 345 346 return 1; 347 } 348 349 void 350 mc_attach(struct device *parent, struct device *self, void *aux) 351 { 352 struct confargs *ca = aux; 353 struct mc_softc *sc = (struct mc_softc *)self; 354 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 355 u_int8_t lladdr[ETHER_ADDR_LEN]; 356 int nseg, error; 357 358 if (OF_getprop(ca->ca_node, "local-mac-address", lladdr, 359 ETHER_ADDR_LEN) != ETHER_ADDR_LEN) { 360 printf(": failed to get MAC address.\n"); 361 return; 362 } 363 364 ca->ca_reg[0] += ca->ca_baseaddr; 365 ca->ca_reg[2] += ca->ca_baseaddr; 366 ca->ca_reg[4] += ca->ca_baseaddr; 367 368 if ((sc->sc_reg = mapiodev(ca->ca_reg[0], ca->ca_reg[1])) == NULL) { 369 printf(": cannot map registers\n"); 370 return; 371 } 372 373 sc->sc_dmat = ca->ca_dmat; 374 sc->sc_tail = 0; 375 376 if ((sc->sc_txdma = mapiodev(ca->ca_reg[2], ca->ca_reg[3])) == NULL) { 377 printf(": cannot map TX DMA registers\n"); 378 goto notxdma; 379 } 380 if ((sc->sc_rxdma = mapiodev(ca->ca_reg[4], ca->ca_reg[5])) == NULL) { 381 printf(": cannot map RX DMA registers\n"); 382 goto norxdma; 383 } 384 if ((sc->sc_txdbdma = dbdma_alloc(sc->sc_dmat, 2)) == NULL) { 385 printf(": cannot alloc TX DMA descriptors\n"); 386 goto notxdbdma; 387 } 388 sc->sc_txdmacmd = sc->sc_txdbdma->d_addr; 389 390 if ((sc->sc_rxdbdma = dbdma_alloc(sc->sc_dmat, 8 + 1)) == NULL) { 391 printf(": cannot alloc RX DMA descriptors\n"); 392 goto norxdbdma; 393 } 394 sc->sc_rxdmacmd = sc->sc_rxdbdma->d_addr; 395 396 if ((error = bus_dmamem_alloc(sc->sc_dmat, MACE_BUFSZ, PAGE_SIZE, 0, 397 sc->sc_bufseg, 1, &nseg, BUS_DMA_NOWAIT))) { 398 printf(": cannot allocate DMA mem (%d)\n", error); 399 goto nodmamem; 400 } 401 402 if ((error = bus_dmamem_map(sc->sc_dmat, sc->sc_bufseg, nseg, 403 MACE_BUFSZ, &sc->sc_txbuf, BUS_DMA_NOWAIT))) { 404 printf(": cannot map DMA mem (%d)\n", error); 405 goto nodmamap; 406 } 407 408 if ((error = bus_dmamap_create(sc->sc_dmat, MACE_BUFSZ, 1, MACE_BUFSZ, 409 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &sc->sc_bufmap))) { 410 printf(": cannot create DMA map (%d)\n", error); 411 goto nodmacreate; 412 } 413 414 if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_bufmap, sc->sc_txbuf, 415 MACE_BUFSZ, NULL, BUS_DMA_NOWAIT))) { 416 printf(": cannot load DMA map (%d)\n", error); 417 goto nodmaload; 418 } 419 420 sc->sc_txbuf_pa = sc->sc_bufmap->dm_segs->ds_addr; 421 sc->sc_rxbuf = sc->sc_txbuf + MACE_BUFLEN * MACE_TXBUFS; 422 sc->sc_rxbuf_pa = sc->sc_txbuf_pa + MACE_BUFLEN * MACE_TXBUFS; 423 424 printf(": irq %d,%d,%d", ca->ca_intr[0], ca->ca_intr[1], 425 ca->ca_intr[2]); 426 427 /* disable receive DMA */ 428 dbdma_reset(sc->sc_rxdma); 429 430 /* disable transmit DMA */ 431 dbdma_reset(sc->sc_txdma); 432 433 /* install interrupt handlers */ 434 mac_intr_establish(parent, ca->ca_intr[2], IST_LEVEL, IPL_NET, 435 mc_dmaintr, sc, sc->sc_dev.dv_xname); 436 mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_NET, 437 mc_intr, sc, sc->sc_dev.dv_xname); 438 439 sc->sc_biucc = XMTSP_64; 440 sc->sc_fifocc = XMTFW_16 | RCVFW_64 | XMTFWU | RCVFWU | 441 XMTBRST | RCVBRST; 442 sc->sc_plscc = PORTSEL_GPSI | ENPLSIO; 443 444 /* reset the chip and disable all interrupts */ 445 NIC_PUT(sc, MACE_BIUCC, SWRST); 446 DELAY(100); 447 448 NIC_PUT(sc, MACE_IMR, ~0); 449 450 bcopy(lladdr, sc->sc_enaddr, ETHER_ADDR_LEN); 451 bcopy(sc->sc_enaddr, sc->sc_arpcom.ac_enaddr, ETHER_ADDR_LEN); 452 printf(": address %s\n", ether_sprintf(lladdr)); 453 454 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 455 ifp->if_softc = sc; 456 ifp->if_ioctl = mc_ioctl; 457 ifp->if_start = mc_start; 458 ifp->if_flags = 459 IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 460 ifp->if_watchdog = mc_watchdog; 461 ifp->if_timer = 0; 462 463 if_attach(ifp); 464 ether_ifattach(ifp); 465 466 return; 467 nodmaload: 468 bus_dmamap_destroy(sc->sc_dmat, sc->sc_bufmap); 469 nodmacreate: 470 bus_dmamem_unmap(sc->sc_dmat, sc->sc_txbuf, MACE_BUFSZ); 471 nodmamap: 472 bus_dmamem_free(sc->sc_dmat, sc->sc_bufseg, 1); 473 nodmamem: 474 dbdma_free(sc->sc_rxdbdma); 475 norxdbdma: 476 dbdma_free(sc->sc_txdbdma); 477 notxdbdma: 478 unmapiodev((void *)sc->sc_rxdma, ca->ca_reg[5]); 479 norxdma: 480 unmapiodev((void *)sc->sc_txdma, ca->ca_reg[3]); 481 notxdma: 482 unmapiodev(sc->sc_reg, ca->ca_reg[1]); 483 } 484 485 int 486 mc_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) 487 { 488 struct mc_softc *sc = ifp->if_softc; 489 int s, err = 0; 490 491 s = splnet(); 492 493 switch (cmd) { 494 case SIOCSIFADDR: 495 ifp->if_flags |= IFF_UP; 496 if (!(ifp->if_flags & IFF_RUNNING)) 497 mc_init(sc); 498 break; 499 500 case SIOCSIFFLAGS: 501 if ((ifp->if_flags & IFF_UP) == 0 && 502 (ifp->if_flags & IFF_RUNNING) != 0) { 503 /* 504 * If interface is marked down and it is running, 505 * then stop it. 506 */ 507 mc_stop(sc); 508 } else if ((ifp->if_flags & IFF_UP) != 0 && 509 (ifp->if_flags & IFF_RUNNING) == 0) { 510 /* 511 * If interface is marked up and it is stopped, 512 * then start it. 513 */ 514 mc_init(sc); 515 } else { 516 /* 517 * reset the interface to pick up any other changes 518 * in flags 519 */ 520 mc_reset(sc); 521 mc_start(ifp); 522 } 523 break; 524 525 default: 526 err = ether_ioctl(ifp, &sc->sc_arpcom, cmd, data); 527 } 528 529 if (err == ENETRESET) { 530 if (ifp->if_flags & IFF_RUNNING) 531 mc_reset(sc); 532 err = 0; 533 } 534 535 splx(s); 536 return (err); 537 } 538 539 /* 540 * Encapsulate a packet of type family for the local net. 541 */ 542 void 543 mc_start(struct ifnet *ifp) 544 { 545 struct mc_softc *sc = ifp->if_softc; 546 struct mbuf *m; 547 548 if (!(ifp->if_flags & IFF_RUNNING) || ifq_is_oactive(&ifp->if_snd)) 549 return; 550 551 while (1) { 552 if (ifq_is_oactive(&ifp->if_snd)) 553 return; 554 555 IFQ_DEQUEUE(&ifp->if_snd, m); 556 if (m == NULL) 557 return; 558 559 #if NBPFILTER > 0 560 /* 561 * If bpf is listening on this interface, let it 562 * see the packet before we commit it to the wire. 563 */ 564 if (ifp->if_bpf) 565 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 566 #endif 567 568 /* 569 * Copy the mbuf chain into the transmit buffer. 570 */ 571 ifq_set_oactive(&ifp->if_snd); 572 maceput(sc, m); 573 574 ifp->if_opackets++; /* # of pkts */ 575 } 576 } 577 578 /* 579 * reset and restart the MACE. Called in case of fatal 580 * hardware/software errors. 581 */ 582 void 583 mc_reset(struct mc_softc *sc) 584 { 585 mc_stop(sc); 586 mc_init(sc); 587 } 588 589 void 590 mc_init(struct mc_softc *sc) 591 { 592 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 593 u_int8_t maccc, ladrf[8]; 594 int s, i; 595 596 s = splnet(); 597 598 NIC_PUT(sc, MACE_BIUCC, sc->sc_biucc); 599 NIC_PUT(sc, MACE_FIFOCC, sc->sc_fifocc); 600 NIC_PUT(sc, MACE_IMR, ~0); /* disable all interrupts */ 601 NIC_PUT(sc, MACE_PLSCC, sc->sc_plscc); 602 603 NIC_PUT(sc, MACE_UTR, RTRD); /* disable reserved test registers */ 604 605 /* set MAC address */ 606 NIC_PUT(sc, MACE_IAC, ADDRCHG); 607 while (NIC_GET(sc, MACE_IAC) & ADDRCHG) 608 ; 609 NIC_PUT(sc, MACE_IAC, PHYADDR); 610 for (i = 0; i < ETHER_ADDR_LEN; i++) 611 out8rb(sc->sc_reg + MACE_REG(MACE_PADR) + i, 612 sc->sc_enaddr[i]); 613 614 /* set logical address filter */ 615 mace_calcladrf(sc, ladrf); 616 617 NIC_PUT(sc, MACE_IAC, ADDRCHG); 618 while (NIC_GET(sc, MACE_IAC) & ADDRCHG) 619 ; 620 NIC_PUT(sc, MACE_IAC, LOGADDR); 621 for (i = 0; i < 8; i++) 622 out8rb(sc->sc_reg + MACE_REG(MACE_LADRF) + i, 623 ladrf[i]); 624 625 NIC_PUT(sc, MACE_XMTFC, APADXMT); 626 /* 627 * No need to autostrip padding on receive... Ethernet frames 628 * don't have a length field, unlike 802.3 frames, so the MACE 629 * can't figure out the length of the packet anyways. 630 */ 631 NIC_PUT(sc, MACE_RCVFC, 0); 632 633 maccc = ENXMT | ENRCV; 634 if (ifp->if_flags & IFF_PROMISC) 635 maccc |= PROM; 636 637 NIC_PUT(sc, MACE_MACCC, maccc); 638 639 mc_reset_rxdma(sc); 640 mc_reset_txdma(sc); 641 /* 642 * Enable all interrupts except receive, since we use the DMA 643 * completion interrupt for that. 644 */ 645 NIC_PUT(sc, MACE_IMR, RCVINTM); 646 647 /* flag interface as "running" */ 648 ifp->if_flags |= IFF_RUNNING; 649 ifq_clr_oactive(&ifp->if_snd); 650 651 splx(s); 652 } 653 654 /* 655 * Close down an interface and free its buffers. 656 * Called on final close of device, or if mcinit() fails 657 * part way through. 658 */ 659 int 660 mc_stop(struct mc_softc *sc) 661 { 662 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 663 int s; 664 665 s = splnet(); 666 667 NIC_PUT(sc, MACE_BIUCC, SWRST); 668 DELAY(100); 669 670 ifp->if_timer = 0; 671 ifp->if_flags &= ~IFF_RUNNING; 672 ifq_clr_oactive(&ifp->if_snd); 673 674 splx(s); 675 return (0); 676 } 677 678 /* 679 * Called if any Tx packets remain unsent after 5 seconds, 680 * In all cases we just reset the chip, and any retransmission 681 * will be handled by higher level protocol timeouts. 682 */ 683 void 684 mc_watchdog(struct ifnet *ifp) 685 { 686 struct mc_softc *sc = ifp->if_softc; 687 688 printf("mcwatchdog: resetting chip\n"); 689 mc_reset(sc); 690 } 691 692 int 693 mc_intr(void *arg) 694 { 695 struct mc_softc *sc = arg; 696 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 697 u_int8_t ir; 698 699 ir = NIC_GET(sc, MACE_IR) & ~NIC_GET(sc, MACE_IMR); 700 701 if (ir & JAB) { 702 #ifdef MCDEBUG 703 printf("%s: jabber error\n", sc->sc_dev.dv_xname); 704 #endif 705 ifp->if_oerrors++; 706 } 707 708 if (ir & BABL) { 709 #ifdef MCDEBUG 710 printf("%s: babble\n", sc->sc_dev.dv_xname); 711 #endif 712 ifp->if_oerrors++; 713 } 714 715 if (ir & CERR) { 716 #ifdef MCDEBUG 717 printf("%s: collision error\n", sc->sc_dev.dv_xname); 718 #endif 719 ifp->if_collisions++; 720 } 721 722 /* 723 * Pretend we have carrier; if we don't this will be cleared 724 * shortly. 725 */ 726 sc->sc_havecarrier = 1; 727 728 if (ir & XMTINT) 729 mc_tint(sc); 730 731 if (ir & RCVINT) 732 mc_rint(sc); 733 734 return(1); 735 } 736 737 void 738 mc_tint(struct mc_softc *sc) 739 { 740 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 741 u_int8_t xmtrc, xmtfs; 742 743 xmtrc = NIC_GET(sc, MACE_XMTRC); 744 xmtfs = NIC_GET(sc, MACE_XMTFS); 745 746 if ((xmtfs & XMTSV) == 0) 747 return; 748 749 if (xmtfs & UFLO) { 750 printf("%s: underflow\n", sc->sc_dev.dv_xname); 751 mc_reset(sc); 752 return; 753 } 754 755 if (xmtfs & LCOL) { 756 printf("%s: late collision\n", sc->sc_dev.dv_xname); 757 ifp->if_oerrors++; 758 ifp->if_collisions++; 759 } 760 761 if (xmtfs & MORE) 762 /* Real number is unknown. */ 763 ifp->if_collisions += 2; 764 else if (xmtfs & ONE) 765 ifp->if_collisions++; 766 else if (xmtfs & RTRY) { 767 printf("%s: excessive collisions\n", sc->sc_dev.dv_xname); 768 ifp->if_collisions += 16; 769 ifp->if_oerrors++; 770 } 771 772 if (xmtfs & LCAR) { 773 sc->sc_havecarrier = 0; 774 printf("%s: lost carrier\n", sc->sc_dev.dv_xname); 775 ifp->if_oerrors++; 776 } 777 778 ifq_clr_oactive(&ifp->if_snd); 779 ifp->if_timer = 0; 780 mc_start(ifp); 781 } 782 783 void 784 mc_rint(struct mc_softc *sc) 785 { 786 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 787 #define rxf sc->sc_rxframe 788 u_int len; 789 790 len = (rxf.rx_rcvcnt | ((rxf.rx_rcvsts & 0xf) << 8)) - 4; 791 792 #ifdef MCDEBUG 793 if (rxf.rx_rcvsts & 0xf0) 794 printf("%s: rcvcnt %02x rcvsts %02x rntpc 0x%02x rcvcc 0x%02x\n", 795 sc->sc_dev.dv_xname, rxf.rx_rcvcnt, rxf.rx_rcvsts, 796 rxf.rx_rntpc, rxf.rx_rcvcc); 797 #endif 798 799 if (rxf.rx_rcvsts & OFLO) { 800 #ifdef MCDEBUG 801 printf("%s: receive FIFO overflow\n", sc->sc_dev.dv_xname); 802 #endif 803 ifp->if_ierrors++; 804 return; 805 } 806 807 if (rxf.rx_rcvsts & CLSN) 808 ifp->if_collisions++; 809 810 if (rxf.rx_rcvsts & FRAM) { 811 #ifdef MCDEBUG 812 printf("%s: framing error\n", sc->sc_dev.dv_xname); 813 #endif 814 ifp->if_ierrors++; 815 return; 816 } 817 818 if (rxf.rx_rcvsts & FCS) { 819 #ifdef MCDEBUG 820 printf("%s: frame control checksum error\n", sc->sc_dev.dv_xname); 821 #endif 822 ifp->if_ierrors++; 823 return; 824 } 825 826 mace_read(sc, rxf.rx_frame, len); 827 #undef rxf 828 } 829 /* 830 * stuff packet into MACE (at splnet) 831 */ 832 u_int 833 maceput(struct mc_softc *sc, struct mbuf *m) 834 { 835 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 836 struct mbuf *n; 837 u_int len, totlen = 0; 838 u_char *buff; 839 840 buff = sc->sc_txbuf; 841 842 for (; m; m = n) { 843 u_char *data = mtod(m, u_char *); 844 len = m->m_len; 845 totlen += len; 846 bcopy(data, buff, len); 847 buff += len; 848 n = m_free(m); 849 } 850 851 if (totlen > PAGE_SIZE) 852 panic("%s: maceput: packet overflow", sc->sc_dev.dv_xname); 853 854 #if 0 855 if (totlen < ETHERMIN + sizeof(struct ether_header)) { 856 int pad = ETHERMIN + sizeof(struct ether_header) - totlen; 857 bzero(sc->sc_txbuf + totlen, pad); 858 totlen = ETHERMIN + sizeof(struct ether_header); 859 } 860 #endif 861 862 863 /* 5 seconds to watch for failing to transmit */ 864 ifp->if_timer = 5; 865 mc_putpacket(sc, totlen); 866 return (totlen); 867 } 868 869 void 870 mace_read(struct mc_softc *sc, caddr_t pkt, int len) 871 { 872 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 873 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 874 struct mbuf *m; 875 876 if (len <= sizeof(struct ether_header) || 877 len > ETHERMTU + sizeof(struct ether_header)) { 878 #ifdef MCDEBUG 879 printf("%s: invalid packet size %d; dropping\n", 880 sc->sc_dev.dv_xname, len); 881 #endif 882 ifp->if_ierrors++; 883 return; 884 } 885 886 m = mace_get(sc, pkt, len); 887 if (m == NULL) { 888 ifp->if_ierrors++; 889 return; 890 } 891 892 ml_enqueue(&ml, m); 893 if_input(ifp, &ml); 894 } 895 896 /* 897 * Pull data off an interface. 898 * Len is length of data, with local net header stripped. 899 * We copy the data into mbufs. When full cluster sized units are present 900 * we copy into clusters. 901 */ 902 struct mbuf * 903 mace_get(struct mc_softc *sc, caddr_t pkt, int totlen) 904 { 905 struct mbuf *m; 906 struct mbuf *top, **mp; 907 int len; 908 909 MGETHDR(m, M_DONTWAIT, MT_DATA); 910 if (m == NULL) 911 return (NULL); 912 913 m->m_pkthdr.len = totlen; 914 len = MHLEN; 915 top = 0; 916 mp = ⊤ 917 918 while (totlen > 0) { 919 if (top) { 920 MGET(m, M_DONTWAIT, MT_DATA); 921 if (m == NULL) { 922 m_freem(top); 923 return (NULL); 924 } 925 len = MLEN; 926 } 927 if (totlen >= MINCLSIZE) { 928 MCLGET(m, M_DONTWAIT); 929 if ((m->m_flags & M_EXT) == 0) { 930 m_free(m); 931 m_freem(top); 932 return (NULL); 933 } 934 len = MCLBYTES; 935 } 936 m->m_len = len = min(totlen, len); 937 bcopy(pkt, mtod(m, caddr_t), len); 938 pkt += len; 939 totlen -= len; 940 *mp = m; 941 mp = &m->m_next; 942 } 943 944 return (top); 945 } 946 947 void 948 mc_putpacket(struct mc_softc *sc, u_int len) 949 { 950 dbdma_command_t *cmd = sc->sc_txdmacmd; 951 952 DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, len, sc->sc_txbuf_pa, 953 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 954 cmd++; 955 DBDMA_BUILD(cmd, DBDMA_CMD_STOP, 0, 0, 0, DBDMA_INT_ALWAYS, 956 DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 957 958 dbdma_start(sc->sc_txdma, sc->sc_txdbdma); 959 } 960 961 /* 962 * Interrupt handler for the MACE DMA completion interrupts 963 */ 964 int 965 mc_dmaintr(void *arg) 966 { 967 struct mc_softc *sc = arg; 968 int status, offset, statoff; 969 int datalen, resid; 970 int i, n, count; 971 dbdma_command_t *cmd; 972 973 /* We've received some packets from the MACE */ 974 /* Loop through, processing each of the packets */ 975 i = sc->sc_tail; 976 for (n = 0; n < MC_RXDMABUFS; n++, i++) { 977 if (i == MC_RXDMABUFS) 978 i = 0; 979 980 cmd = &sc->sc_rxdmacmd[i]; 981 status = dbdma_ld16(&cmd->d_status); 982 resid = dbdma_ld16(&cmd->d_resid); 983 984 if ((status & DBDMA_CNTRL_ACTIVE) == 0) { 985 continue; 986 } 987 988 count = dbdma_ld16(&cmd->d_count); 989 datalen = count - resid; 990 datalen -= 4; /* 4 == status bytes */ 991 992 if (datalen < 4 + sizeof(struct ether_header)) { 993 printf("short packet len=%d\n", datalen); 994 /* continue; */ 995 goto next; 996 } 997 DBDMA_BUILD_CMD(cmd, DBDMA_CMD_STOP, 0, 0, 0, 0); 998 999 offset = i * MACE_BUFLEN; 1000 statoff = offset + datalen; 1001 sc->sc_rxframe.rx_rcvcnt = sc->sc_rxbuf[statoff + 0]; 1002 sc->sc_rxframe.rx_rcvsts = sc->sc_rxbuf[statoff + 1]; 1003 sc->sc_rxframe.rx_rntpc = sc->sc_rxbuf[statoff + 2]; 1004 sc->sc_rxframe.rx_rcvcc = sc->sc_rxbuf[statoff + 3]; 1005 sc->sc_rxframe.rx_frame = sc->sc_rxbuf + offset; 1006 1007 mc_rint(sc); 1008 1009 next: 1010 DBDMA_BUILD_CMD(cmd, DBDMA_CMD_IN_LAST, 0, DBDMA_INT_ALWAYS, 1011 DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 1012 1013 cmd->d_status = 0; 1014 cmd->d_resid = 0; 1015 sc->sc_tail = i + 1; 1016 } 1017 1018 dbdma_continue(sc->sc_rxdma); 1019 1020 return 1; 1021 } 1022 1023 void 1024 mc_reset_rxdma(struct mc_softc *sc) 1025 { 1026 dbdma_command_t *cmd = sc->sc_rxdmacmd; 1027 int i; 1028 u_int8_t maccc; 1029 1030 /* Disable receiver, reset the DMA channels */ 1031 maccc = NIC_GET(sc, MACE_MACCC); 1032 NIC_PUT(sc, MACE_MACCC, maccc & ~ENRCV); 1033 1034 dbdma_reset(sc->sc_rxdma); 1035 1036 bzero(sc->sc_rxdmacmd, 8 * sizeof(dbdma_command_t)); 1037 for (i = 0; i < MC_RXDMABUFS; i++) { 1038 DBDMA_BUILD(cmd, DBDMA_CMD_IN_LAST, 0, MACE_BUFLEN, 1039 sc->sc_rxbuf_pa + MACE_BUFLEN * i, DBDMA_INT_ALWAYS, 1040 DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 1041 cmd++; 1042 } 1043 1044 DBDMA_BUILD(cmd, DBDMA_CMD_NOP, 0, 0, 0, 1045 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_ALWAYS); 1046 dbdma_st32(&cmd->d_cmddep, sc->sc_rxdbdma->d_paddr); 1047 cmd++; 1048 1049 sc->sc_tail = 0; 1050 1051 dbdma_start(sc->sc_rxdma, sc->sc_rxdbdma); 1052 /* Reenable receiver, reenable DMA */ 1053 NIC_PUT(sc, MACE_MACCC, maccc); 1054 } 1055 1056 void 1057 mc_reset_txdma(struct mc_softc *sc) 1058 { 1059 dbdma_command_t *cmd = sc->sc_txdmacmd; 1060 dbdma_regmap_t *dmareg = sc->sc_txdma; 1061 u_int8_t maccc; 1062 1063 /* disable transmitter */ 1064 maccc = NIC_GET(sc, MACE_MACCC); 1065 NIC_PUT(sc, MACE_MACCC, maccc & ~ENXMT); 1066 1067 dbdma_reset(sc->sc_txdma); 1068 1069 bzero(sc->sc_txdmacmd, 2 * sizeof(dbdma_command_t)); 1070 DBDMA_BUILD(cmd, DBDMA_CMD_OUT_LAST, 0, 0, sc->sc_txbuf_pa, 1071 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 1072 cmd++; 1073 DBDMA_BUILD(cmd, DBDMA_CMD_STOP, 0, 0, 0, 1074 DBDMA_INT_NEVER, DBDMA_WAIT_NEVER, DBDMA_BRANCH_NEVER); 1075 1076 out32rb(&dmareg->d_cmdptrhi, 0); 1077 out32rb(&dmareg->d_cmdptrlo, sc->sc_txdbdma->d_paddr); 1078 1079 /* restore old value */ 1080 NIC_PUT(sc, MACE_MACCC, maccc); 1081 } 1082 1083 /* 1084 * Go through the list of multicast addresses and calculate the logical 1085 * address filter. 1086 */ 1087 void 1088 mace_calcladrf(struct mc_softc *sc, u_int8_t *af) 1089 { 1090 struct ether_multi *enm; 1091 u_int32_t crc; 1092 struct ifnet *ifp = &sc->sc_arpcom.ac_if; 1093 struct arpcom *ac = &sc->sc_arpcom; 1094 struct ether_multistep step; 1095 /* 1096 * Set up multicast address filter by passing all multicast addresses 1097 * through a crc generator, and then using the high order 6 bits as an 1098 * index into the 64 bit logical address filter. The high order bit 1099 * selects the word, while the rest of the bits select the bit within 1100 * the word. 1101 */ 1102 1103 if (ac->ac_multirangecnt > 0) 1104 goto allmulti; 1105 1106 *((u_int32_t *)af) = *((u_int32_t *)af + 1) = 0; 1107 ETHER_FIRST_MULTI(step, ac, enm); 1108 while (enm != NULL) { 1109 crc = ether_crc32_le(enm->enm_addrlo, sizeof(enm->enm_addrlo)); 1110 1111 /* Just want the 6 most significant bits. */ 1112 crc >>= 26; 1113 1114 /* Set the corresponding bit in the filter. */ 1115 af[crc >> 3] |= 1 << (crc & 7); 1116 1117 ETHER_NEXT_MULTI(step, enm); 1118 } 1119 ifp->if_flags &= ~IFF_ALLMULTI; 1120 return; 1121 1122 allmulti: 1123 ifp->if_flags |= IFF_ALLMULTI; 1124 *((u_int32_t *)af) = *((u_int32_t *)af + 1) = 0xffffffff; 1125 } 1126