1 /* $NetBSD: sbmac.c,v 1.36 2010/01/19 22:06:21 pooka Exp $ */ 2 3 /* 4 * Copyright 2000, 2001, 2004 5 * Broadcom Corporation. All rights reserved. 6 * 7 * This software is furnished under license and may be used and copied only 8 * in accordance with the following terms and conditions. Subject to these 9 * conditions, you may download, copy, install, use, modify and distribute 10 * modified or unmodified copies of this software in source and/or binary 11 * form. No title or ownership is transferred hereby. 12 * 13 * 1) Any source code used, modified or distributed must reproduce and 14 * retain this copyright notice and list of conditions as they appear in 15 * the source file. 16 * 17 * 2) No right is granted to use any trade name, trademark, or logo of 18 * Broadcom Corporation. The "Broadcom Corporation" name may not be 19 * used to endorse or promote products derived from this software 20 * without the prior written permission of Broadcom Corporation. 21 * 22 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR IMPLIED 23 * WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED WARRANTIES OF 24 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR 25 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL BROADCOM BE LIABLE 26 * FOR ANY DAMAGES WHATSOEVER, AND IN PARTICULAR, BROADCOM SHALL NOT BE 27 * LIABLE FOR DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 30 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 31 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 32 * OR OTHERWISE), EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/cdefs.h> 36 __KERNEL_RCSID(0, "$NetBSD: sbmac.c,v 1.36 2010/01/19 22:06:21 pooka Exp $"); 37 38 #include "opt_inet.h" 39 #include "opt_ns.h" 40 41 #include <sys/param.h> 42 #include <sys/systm.h> 43 #include <sys/sockio.h> 44 #include <sys/mbuf.h> 45 #include <sys/malloc.h> 46 #include <sys/kernel.h> 47 #include <sys/socket.h> 48 #include <sys/queue.h> 49 #include <sys/device.h> 50 51 #include <net/if.h> 52 #include <net/if_arp.h> 53 #include <net/if_ether.h> 54 #include <net/if_dl.h> 55 #include <net/if_media.h> 56 57 #include <net/bpf.h> 58 59 #ifdef INET 60 #include <netinet/in.h> 61 #include <netinet/if_inarp.h> 62 #endif 63 64 #ifdef NS 65 #include <netns/ns.h> 66 #include <netns/ns_if.h> 67 #endif 68 69 #include <machine/locore.h> 70 71 #include "sbobiovar.h" 72 73 #include <dev/mii/mii.h> 74 #include <dev/mii/miivar.h> 75 #include <dev/mii/mii_bitbang.h> 76 77 #include <mips/sibyte/include/sb1250_defs.h> 78 #include <mips/sibyte/include/sb1250_regs.h> 79 #include <mips/sibyte/include/sb1250_mac.h> 80 #include <mips/sibyte/include/sb1250_dma.h> 81 #include <mips/sibyte/include/sb1250_scd.h> 82 83 /* Simple types */ 84 85 typedef u_long sbmac_port_t; 86 typedef uint64_t sbmac_physaddr_t; 87 typedef uint64_t sbmac_enetaddr_t; 88 89 typedef enum { sbmac_speed_auto, sbmac_speed_10, 90 sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t; 91 92 typedef enum { sbmac_duplex_auto, sbmac_duplex_half, 93 sbmac_duplex_full } sbmac_duplex_t; 94 95 typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame, 96 sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t; 97 98 typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on, 99 sbmac_state_broken } sbmac_state_t; 100 101 102 /* Macros */ 103 104 #define SBMAC_EVENT_COUNTERS /* Include counters for various events */ 105 106 #define SBDMA_NEXTBUF(d, f) ((f + 1) & (d)->sbdma_dscr_mask) 107 108 #define CACHELINESIZE 32 109 #define NUMCACHEBLKS(x) (((x)+CACHELINESIZE-1)/CACHELINESIZE) 110 #define KMALLOC(x) malloc((x), M_DEVBUF, M_DONTWAIT) 111 #define KVTOPHYS(x) kvtophys((vaddr_t)(x)) 112 113 #ifdef SBMACDEBUG 114 #define dprintf(x) printf x 115 #else 116 #define dprintf(x) 117 #endif 118 119 #define SBMAC_READCSR(t) mips3_ld((volatile uint64_t *) (t)) 120 #define SBMAC_WRITECSR(t, v) mips3_sd((volatile uint64_t *) (t), (v)) 121 122 #define PKSEG1(x) ((sbmac_port_t) MIPS_PHYS_TO_KSEG1(x)) 123 124 /* These are limited to fit within one virtual page, and must be 2**N. */ 125 #define SBMAC_MAX_TXDESCR 256 /* should be 1024 */ 126 #define SBMAC_MAX_RXDESCR 256 /* should be 512 */ 127 128 #define ETHER_ALIGN 2 129 130 /* DMA Descriptor structure */ 131 132 typedef struct sbdmadscr_s { 133 uint64_t dscr_a; 134 uint64_t dscr_b; 135 } sbdmadscr_t; 136 137 138 /* DMA Controller structure */ 139 140 typedef struct sbmacdma_s { 141 142 /* 143 * This stuff is used to identify the channel and the registers 144 * associated with it. 145 */ 146 147 struct sbmac_softc *sbdma_eth; /* back pointer to associated MAC */ 148 int sbdma_channel; /* channel number */ 149 int sbdma_txdir; /* direction (1=transmit) */ 150 int sbdma_maxdescr; /* total # of descriptors in ring */ 151 sbmac_port_t sbdma_config0; /* DMA config register 0 */ 152 sbmac_port_t sbdma_config1; /* DMA config register 1 */ 153 sbmac_port_t sbdma_dscrbase; /* Descriptor base address */ 154 sbmac_port_t sbdma_dscrcnt; /* Descriptor count register */ 155 sbmac_port_t sbdma_curdscr; /* current descriptor address */ 156 157 /* 158 * This stuff is for maintenance of the ring 159 */ 160 sbdmadscr_t *sbdma_dscrtable; /* base of descriptor table */ 161 struct mbuf **sbdma_ctxtable; /* context table, one per descr */ 162 unsigned int sbdma_dscr_mask; /* sbdma_maxdescr - 1 */ 163 paddr_t sbdma_dscrtable_phys; /* and also the phys addr */ 164 unsigned int sbdma_add_index; /* next dscr for sw to add */ 165 unsigned int sbdma_rem_index; /* next dscr for sw to remove */ 166 } sbmacdma_t; 167 168 169 /* Ethernet softc structure */ 170 171 struct sbmac_softc { 172 173 /* 174 * NetBSD-specific things 175 */ 176 struct device sc_dev; /* base device (must be first) */ 177 struct ethercom sc_ethercom; /* Ethernet common part */ 178 struct mii_data sc_mii; 179 struct callout sc_tick_ch; 180 181 int sbm_if_flags; 182 void *sbm_intrhand; 183 184 /* 185 * Controller-specific things 186 */ 187 188 sbmac_port_t sbm_base; /* MAC's base address */ 189 sbmac_state_t sbm_state; /* current state */ 190 191 sbmac_port_t sbm_macenable; /* MAC Enable Register */ 192 sbmac_port_t sbm_maccfg; /* MAC Configuration Register */ 193 sbmac_port_t sbm_fifocfg; /* FIFO configuration register */ 194 sbmac_port_t sbm_framecfg; /* Frame configuration register */ 195 sbmac_port_t sbm_rxfilter; /* receive filter register */ 196 sbmac_port_t sbm_isr; /* Interrupt status register */ 197 sbmac_port_t sbm_imr; /* Interrupt mask register */ 198 199 sbmac_speed_t sbm_speed; /* current speed */ 200 sbmac_duplex_t sbm_duplex; /* current duplex */ 201 sbmac_fc_t sbm_fc; /* current flow control setting */ 202 int sbm_rxflags; /* received packet flags */ 203 204 u_char sbm_hwaddr[ETHER_ADDR_LEN]; 205 206 sbmacdma_t sbm_txdma; /* for now, only use channel 0 */ 207 sbmacdma_t sbm_rxdma; 208 209 int sbm_pass3_dma; /* chip has pass3 SOC DMA features */ 210 211 #ifdef SBMAC_EVENT_COUNTERS 212 struct evcnt sbm_ev_rxintr; /* Rx interrupts */ 213 struct evcnt sbm_ev_txintr; /* Tx interrupts */ 214 struct evcnt sbm_ev_txdrop; /* Tx dropped due to no mbuf alloc failed */ 215 struct evcnt sbm_ev_txstall; /* Tx stalled due to no descriptors free */ 216 217 struct evcnt sbm_ev_txsplit; /* pass3 Tx split mbuf */ 218 struct evcnt sbm_ev_txkeep; /* pass3 Tx didn't split mbuf */ 219 #endif 220 }; 221 222 223 #ifdef SBMAC_EVENT_COUNTERS 224 #define SBMAC_EVCNT_INCR(ev) (ev).ev_count++ 225 #else 226 #define SBMAC_EVCNT_INCR(ev) do { /* nothing */ } while (0) 227 #endif 228 229 /* Externs */ 230 231 extern paddr_t kvtophys(vaddr_t); 232 233 /* Prototypes */ 234 235 static void sbdma_initctx(sbmacdma_t *d, struct sbmac_softc *s, int chan, 236 int txrx, int maxdescr); 237 static void sbdma_channel_start(sbmacdma_t *d); 238 static int sbdma_add_rcvbuffer(sbmacdma_t *d, struct mbuf *m); 239 static int sbdma_add_txbuffer(sbmacdma_t *d, struct mbuf *m); 240 static void sbdma_emptyring(sbmacdma_t *d); 241 static void sbdma_fillring(sbmacdma_t *d); 242 static void sbdma_rx_process(struct sbmac_softc *sc, sbmacdma_t *d); 243 static void sbdma_tx_process(struct sbmac_softc *sc, sbmacdma_t *d); 244 static void sbmac_initctx(struct sbmac_softc *s); 245 static void sbmac_channel_start(struct sbmac_softc *s); 246 static void sbmac_channel_stop(struct sbmac_softc *s); 247 static sbmac_state_t sbmac_set_channel_state(struct sbmac_softc *, 248 sbmac_state_t); 249 static void sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff); 250 static void sbmac_init_and_start(struct sbmac_softc *sc); 251 static uint64_t sbmac_addr2reg(u_char *ptr); 252 static void sbmac_intr(void *xsc, uint32_t status, vaddr_t pc); 253 static void sbmac_start(struct ifnet *ifp); 254 static void sbmac_setmulti(struct sbmac_softc *sc); 255 static int sbmac_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data); 256 static int sbmac_ioctl(struct ifnet *, u_long, void *); 257 static void sbmac_watchdog(struct ifnet *ifp); 258 static int sbmac_match(struct device *parent, struct cfdata *match, void *aux); 259 static void sbmac_attach(struct device *parent, struct device *self, void *aux); 260 static int sbmac_set_speed(struct sbmac_softc *s, sbmac_speed_t speed); 261 static int sbmac_set_duplex(struct sbmac_softc *s, sbmac_duplex_t duplex, 262 sbmac_fc_t fc); 263 static void sbmac_tick(void *arg); 264 265 266 /* Globals */ 267 268 CFATTACH_DECL(sbmac, sizeof(struct sbmac_softc), 269 sbmac_match, sbmac_attach, NULL, NULL); 270 271 static uint32_t sbmac_mii_bitbang_read(struct device *self); 272 static void sbmac_mii_bitbang_write(struct device *self, uint32_t val); 273 274 static const struct mii_bitbang_ops sbmac_mii_bitbang_ops = { 275 sbmac_mii_bitbang_read, 276 sbmac_mii_bitbang_write, 277 { 278 (uint32_t)M_MAC_MDIO_OUT, /* MII_BIT_MDO */ 279 (uint32_t)M_MAC_MDIO_IN, /* MII_BIT_MDI */ 280 (uint32_t)M_MAC_MDC, /* MII_BIT_MDC */ 281 0, /* MII_BIT_DIR_HOST_PHY */ 282 (uint32_t)M_MAC_MDIO_DIR /* MII_BIT_DIR_PHY_HOST */ 283 } 284 }; 285 286 static uint32_t 287 sbmac_mii_bitbang_read(struct device *self) 288 { 289 struct sbmac_softc *sc = (void *) self; 290 sbmac_port_t reg; 291 292 reg = PKSEG1(sc->sbm_base + R_MAC_MDIO); 293 return (uint32_t) SBMAC_READCSR(reg); 294 } 295 296 static void 297 sbmac_mii_bitbang_write(struct device *self, uint32_t val) 298 { 299 struct sbmac_softc *sc = (void *) self; 300 sbmac_port_t reg; 301 302 reg = PKSEG1(sc->sbm_base + R_MAC_MDIO); 303 304 SBMAC_WRITECSR(reg, (val & 305 (M_MAC_MDC|M_MAC_MDIO_DIR|M_MAC_MDIO_OUT|M_MAC_MDIO_IN))); 306 } 307 308 /* 309 * Read an PHY register through the MII. 310 */ 311 static int 312 sbmac_mii_readreg(struct device *self, int phy, int reg) 313 { 314 315 return (mii_bitbang_readreg(self, &sbmac_mii_bitbang_ops, phy, reg)); 316 } 317 318 /* 319 * Write to a PHY register through the MII. 320 */ 321 static void 322 sbmac_mii_writereg(struct device *self, int phy, int reg, int val) 323 { 324 325 mii_bitbang_writereg(self, &sbmac_mii_bitbang_ops, phy, reg, val); 326 } 327 328 static void 329 sbmac_mii_statchg(struct device *self) 330 { 331 struct sbmac_softc *sc = (struct sbmac_softc *)self; 332 sbmac_state_t oldstate; 333 334 /* Stop the MAC in preparation for changing all of the parameters. */ 335 oldstate = sbmac_set_channel_state(sc, sbmac_state_off); 336 337 switch (sc->sc_ethercom.ec_if.if_baudrate) { 338 default: /* if autonegotiation fails, assume 10Mbit */ 339 case IF_Mbps(10): 340 sbmac_set_speed(sc, sbmac_speed_10); 341 break; 342 343 case IF_Mbps(100): 344 sbmac_set_speed(sc, sbmac_speed_100); 345 break; 346 347 case IF_Mbps(1000): 348 sbmac_set_speed(sc, sbmac_speed_1000); 349 break; 350 } 351 352 if (sc->sc_mii.mii_media_active & IFM_FDX) { 353 /* Configure for full-duplex */ 354 /* XXX: is flow control right for 10, 100? */ 355 sbmac_set_duplex(sc, sbmac_duplex_full, sbmac_fc_frame); 356 } else { 357 /* Configure for half-duplex */ 358 /* XXX: is flow control right? */ 359 sbmac_set_duplex(sc, sbmac_duplex_half, sbmac_fc_disabled); 360 } 361 362 /* And put it back into its former state. */ 363 sbmac_set_channel_state(sc, oldstate); 364 } 365 366 /* 367 * SBDMA_INITCTX(d, s, chan, txrx, maxdescr) 368 * 369 * Initialize a DMA channel context. Since there are potentially 370 * eight DMA channels per MAC, it's nice to do this in a standard 371 * way. 372 * 373 * Input parameters: 374 * d - sbmacdma_t structure (DMA channel context) 375 * s - sbmac_softc structure (pointer to a MAC) 376 * chan - channel number (0..1 right now) 377 * txrx - Identifies DMA_TX or DMA_RX for channel direction 378 * maxdescr - number of descriptors 379 * 380 * Return value: 381 * nothing 382 */ 383 384 static void 385 sbdma_initctx(sbmacdma_t *d, struct sbmac_softc *s, int chan, int txrx, 386 int maxdescr) 387 { 388 /* 389 * Save away interesting stuff in the structure 390 */ 391 392 d->sbdma_eth = s; 393 d->sbdma_channel = chan; 394 d->sbdma_txdir = txrx; 395 396 /* 397 * initialize register pointers 398 */ 399 400 d->sbdma_config0 = PKSEG1(s->sbm_base + 401 R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_CONFIG0)); 402 d->sbdma_config1 = PKSEG1(s->sbm_base + 403 R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_CONFIG1)); 404 d->sbdma_dscrbase = PKSEG1(s->sbm_base + 405 R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_DSCR_BASE)); 406 d->sbdma_dscrcnt = PKSEG1(s->sbm_base + 407 R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_DSCR_CNT)); 408 d->sbdma_curdscr = PKSEG1(s->sbm_base + 409 R_MAC_DMA_REGISTER(txrx, chan, R_MAC_DMA_CUR_DSCRADDR)); 410 411 /* 412 * Allocate memory for the ring 413 */ 414 415 d->sbdma_maxdescr = maxdescr; 416 d->sbdma_dscr_mask = d->sbdma_maxdescr - 1; 417 418 d->sbdma_dscrtable = (sbdmadscr_t *) 419 KMALLOC(d->sbdma_maxdescr * sizeof(sbdmadscr_t)); 420 421 memset(d->sbdma_dscrtable, 0, d->sbdma_maxdescr*sizeof(sbdmadscr_t)); 422 423 d->sbdma_dscrtable_phys = KVTOPHYS(d->sbdma_dscrtable); 424 425 /* 426 * And context table 427 */ 428 429 d->sbdma_ctxtable = (struct mbuf **) 430 KMALLOC(d->sbdma_maxdescr*sizeof(struct mbuf *)); 431 432 memset(d->sbdma_ctxtable, 0, d->sbdma_maxdescr*sizeof(struct mbuf *)); 433 } 434 435 /* 436 * SBDMA_CHANNEL_START(d) 437 * 438 * Initialize the hardware registers for a DMA channel. 439 * 440 * Input parameters: 441 * d - DMA channel to init (context must be previously init'd 442 * 443 * Return value: 444 * nothing 445 */ 446 447 static void 448 sbdma_channel_start(sbmacdma_t *d) 449 { 450 /* 451 * Turn on the DMA channel 452 */ 453 454 SBMAC_WRITECSR(d->sbdma_config1, 0); 455 456 SBMAC_WRITECSR(d->sbdma_dscrbase, d->sbdma_dscrtable_phys); 457 458 SBMAC_WRITECSR(d->sbdma_config0, V_DMA_RINGSZ(d->sbdma_maxdescr) | 0); 459 460 /* 461 * Initialize ring pointers 462 */ 463 464 d->sbdma_add_index = 0; 465 d->sbdma_rem_index = 0; 466 } 467 468 /* 469 * SBDMA_ADD_RCVBUFFER(d, m) 470 * 471 * Add a buffer to the specified DMA channel. For receive channels, 472 * this queues a buffer for inbound packets. 473 * 474 * Input parameters: 475 * d - DMA channel descriptor 476 * m - mbuf to add, or NULL if we should allocate one. 477 * 478 * Return value: 479 * 0 if buffer could not be added (ring is full) 480 * 1 if buffer added successfully 481 */ 482 483 static int 484 sbdma_add_rcvbuffer(sbmacdma_t *d, struct mbuf *m) 485 { 486 unsigned int dsc, nextdsc; 487 struct mbuf *m_new = NULL; 488 489 /* get pointer to our current place in the ring */ 490 491 dsc = d->sbdma_add_index; 492 nextdsc = SBDMA_NEXTBUF(d, d->sbdma_add_index); 493 494 /* 495 * figure out if the ring is full - if the next descriptor 496 * is the same as the one that we're going to remove from 497 * the ring, the ring is full 498 */ 499 500 if (nextdsc == d->sbdma_rem_index) 501 return ENOSPC; 502 503 /* 504 * Allocate an mbuf if we don't already have one. 505 * If we do have an mbuf, reset it so that it's empty. 506 */ 507 508 if (m == NULL) { 509 MGETHDR(m_new, M_DONTWAIT, MT_DATA); 510 if (m_new == NULL) { 511 printf("%s: mbuf allocation failed\n", 512 d->sbdma_eth->sc_dev.dv_xname); 513 return ENOBUFS; 514 } 515 516 MCLGET(m_new, M_DONTWAIT); 517 if (!(m_new->m_flags & M_EXT)) { 518 printf("%s: mbuf cluster allocation failed\n", 519 d->sbdma_eth->sc_dev.dv_xname); 520 m_freem(m_new); 521 return ENOBUFS; 522 } 523 524 m_new->m_len = m_new->m_pkthdr.len= MCLBYTES; 525 m_adj(m_new, ETHER_ALIGN); 526 } else { 527 m_new = m; 528 m_new->m_len = m_new->m_pkthdr.len = MCLBYTES; 529 m_new->m_data = m_new->m_ext.ext_buf; 530 m_adj(m_new, ETHER_ALIGN); 531 } 532 533 /* 534 * fill in the descriptor 535 */ 536 537 d->sbdma_dscrtable[dsc].dscr_a = KVTOPHYS(mtod(m_new, void *)) | 538 V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(ETHER_ALIGN + m_new->m_len)) | 539 M_DMA_DSCRA_INTERRUPT; 540 541 /* receiving: no options */ 542 d->sbdma_dscrtable[dsc].dscr_b = 0; 543 544 /* 545 * fill in the context 546 */ 547 548 d->sbdma_ctxtable[dsc] = m_new; 549 550 /* 551 * point at next packet 552 */ 553 554 d->sbdma_add_index = nextdsc; 555 556 /* 557 * Give the buffer to the DMA engine. 558 */ 559 560 SBMAC_WRITECSR(d->sbdma_dscrcnt, 1); 561 562 return 0; /* we did it */ 563 } 564 565 /* 566 * SBDMA_ADD_TXBUFFER(d, m) 567 * 568 * Add a transmit buffer to the specified DMA channel, causing a 569 * transmit to start. 570 * 571 * Input parameters: 572 * d - DMA channel descriptor 573 * m - mbuf to add 574 * 575 * Return value: 576 * 0 transmit queued successfully 577 * otherwise error code 578 */ 579 580 static int 581 sbdma_add_txbuffer(sbmacdma_t *d, struct mbuf *m) 582 { 583 unsigned int dsc, nextdsc, prevdsc, origdesc; 584 int length; 585 int num_mbufs = 0; 586 struct sbmac_softc *sc = d->sbdma_eth; 587 588 /* get pointer to our current place in the ring */ 589 590 dsc = d->sbdma_add_index; 591 nextdsc = SBDMA_NEXTBUF(d, d->sbdma_add_index); 592 593 /* 594 * figure out if the ring is full - if the next descriptor 595 * is the same as the one that we're going to remove from 596 * the ring, the ring is full 597 */ 598 599 if (nextdsc == d->sbdma_rem_index) { 600 SBMAC_EVCNT_INCR(sc->sbm_ev_txstall); 601 return ENOSPC; 602 } 603 604 /* 605 * PASS3 parts do not have buffer alignment restriction. 606 * No need to copy/coalesce to new mbuf. Also has different 607 * descriptor format 608 */ 609 if (sc->sbm_pass3_dma) { 610 struct mbuf *m_temp = NULL; 611 612 /* 613 * Loop thru this mbuf record. 614 * The head mbuf will have SOP set. 615 */ 616 d->sbdma_dscrtable[dsc].dscr_a = KVTOPHYS(mtod(m,void *)) | 617 M_DMA_ETHTX_SOP; 618 619 /* 620 * transmitting: set outbound options,buffer A size(+ low 5 621 * bits of start addr),and packet length. 622 */ 623 d->sbdma_dscrtable[dsc].dscr_b = 624 V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) | 625 V_DMA_DSCRB_A_SIZE((m->m_len + 626 (mtod(m,uintptr_t) & 0x0000001F))) | 627 V_DMA_DSCRB_PKT_SIZE_MSB((m->m_pkthdr.len & 0xc000) >> 14) | 628 V_DMA_DSCRB_PKT_SIZE(m->m_pkthdr.len & 0x3fff); 629 630 d->sbdma_add_index = nextdsc; 631 origdesc = prevdsc = dsc; 632 dsc = d->sbdma_add_index; 633 num_mbufs++; 634 635 /* Start with first non-head mbuf */ 636 for(m_temp = m->m_next; m_temp != 0; m_temp = m_temp->m_next) { 637 int len, next_len; 638 uint64_t addr; 639 640 if (m_temp->m_len == 0) 641 continue; /* Skip 0-length mbufs */ 642 643 len = m_temp->m_len; 644 addr = KVTOPHYS(mtod(m_temp, void *)); 645 646 /* 647 * Check to see if the mbuf spans a page boundary. If 648 * it does, and the physical pages behind the virtual 649 * pages are not contiguous, split it so that each 650 * virtual page uses it's own Tx descriptor. 651 */ 652 if (trunc_page(addr) != trunc_page(addr + len - 1)) { 653 next_len = (addr + len) - trunc_page(addr + len); 654 655 len -= next_len; 656 657 if (addr + len == 658 KVTOPHYS(mtod(m_temp, char *) + len)) { 659 SBMAC_EVCNT_INCR(sc->sbm_ev_txkeep); 660 len += next_len; 661 next_len = 0; 662 } else { 663 SBMAC_EVCNT_INCR(sc->sbm_ev_txsplit); 664 } 665 } else { 666 next_len = 0; 667 } 668 669 again: 670 /* 671 * fill in the descriptor 672 */ 673 d->sbdma_dscrtable[dsc].dscr_a = addr; 674 675 /* 676 * transmitting: set outbound options,buffer A 677 * size(+ low 5 bits of start addr) 678 */ 679 d->sbdma_dscrtable[dsc].dscr_b = V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_NOTSOP) | 680 V_DMA_DSCRB_A_SIZE((len + (addr & 0x0000001F))); 681 682 d->sbdma_ctxtable[dsc] = NULL; 683 684 /* 685 * point at next descriptor 686 */ 687 nextdsc = SBDMA_NEXTBUF(d, d->sbdma_add_index); 688 if (nextdsc == d->sbdma_rem_index) { 689 d->sbdma_add_index = origdesc; 690 SBMAC_EVCNT_INCR(sc->sbm_ev_txstall); 691 return ENOSPC; 692 } 693 d->sbdma_add_index = nextdsc; 694 695 prevdsc = dsc; 696 dsc = d->sbdma_add_index; 697 num_mbufs++; 698 699 if (next_len != 0) { 700 addr = KVTOPHYS(mtod(m_temp, char *) + len); 701 len = next_len; 702 703 next_len = 0; 704 goto again; 705 } 706 707 } 708 /* Set head mbuf to last context index */ 709 d->sbdma_ctxtable[prevdsc] = m; 710 711 /* Interrupt on last dscr of packet. */ 712 d->sbdma_dscrtable[prevdsc].dscr_a |= M_DMA_DSCRA_INTERRUPT; 713 } else { 714 struct mbuf *m_new = NULL; 715 /* 716 * [BEGIN XXX] 717 * XXX Copy/coalesce the mbufs into a single mbuf cluster (we 718 * assume it will fit). This is a temporary hack to get us 719 * going. 720 */ 721 722 MGETHDR(m_new,M_DONTWAIT,MT_DATA); 723 if (m_new == NULL) { 724 printf("%s: mbuf allocation failed\n", 725 d->sbdma_eth->sc_dev.dv_xname); 726 SBMAC_EVCNT_INCR(sc->sbm_ev_txdrop); 727 return ENOBUFS; 728 } 729 730 MCLGET(m_new,M_DONTWAIT); 731 if (!(m_new->m_flags & M_EXT)) { 732 printf("%s: mbuf cluster allocation failed\n", 733 d->sbdma_eth->sc_dev.dv_xname); 734 m_freem(m_new); 735 SBMAC_EVCNT_INCR(sc->sbm_ev_txdrop); 736 return ENOBUFS; 737 } 738 739 m_new->m_len = m_new->m_pkthdr.len= MCLBYTES; 740 /*m_adj(m_new,ETHER_ALIGN);*/ 741 742 /* 743 * XXX Don't forget to include the offset portion in the 744 * XXX cache block calculation when this code is rewritten! 745 */ 746 747 /* 748 * Copy data 749 */ 750 751 m_copydata(m,0,m->m_pkthdr.len,mtod(m_new,void *)); 752 m_new->m_len = m_new->m_pkthdr.len = m->m_pkthdr.len; 753 754 /* Free old mbuf 'm', actual mbuf is now 'm_new' */ 755 756 // XXX: CALLERS WILL FREE, they might have to bpf_mtap() if this 757 // XXX: function succeeds. 758 // m_freem(m); 759 length = m_new->m_len; 760 761 /* [END XXX] */ 762 /* 763 * fill in the descriptor 764 */ 765 766 d->sbdma_dscrtable[dsc].dscr_a = KVTOPHYS(mtod(m_new,void *)) | 767 V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(m_new->m_len)) | 768 M_DMA_DSCRA_INTERRUPT | 769 M_DMA_ETHTX_SOP; 770 771 /* transmitting: set outbound options and length */ 772 d->sbdma_dscrtable[dsc].dscr_b = 773 V_DMA_DSCRB_OPTIONS(K_DMA_ETHTX_APPENDCRC_APPENDPAD) | 774 V_DMA_DSCRB_PKT_SIZE(length); 775 776 num_mbufs++; 777 778 /* 779 * fill in the context 780 */ 781 782 d->sbdma_ctxtable[dsc] = m_new; 783 784 /* 785 * point at next packet 786 */ 787 d->sbdma_add_index = nextdsc; 788 } 789 790 /* 791 * Give the buffer to the DMA engine. 792 */ 793 794 SBMAC_WRITECSR(d->sbdma_dscrcnt, num_mbufs); 795 796 return 0; /* we did it */ 797 } 798 799 /* 800 * SBDMA_EMPTYRING(d) 801 * 802 * Free all allocated mbufs on the specified DMA channel; 803 * 804 * Input parameters: 805 * d - DMA channel 806 * 807 * Return value: 808 * nothing 809 */ 810 811 static void 812 sbdma_emptyring(sbmacdma_t *d) 813 { 814 int idx; 815 struct mbuf *m; 816 817 for (idx = 0; idx < d->sbdma_maxdescr; idx++) { 818 m = d->sbdma_ctxtable[idx]; 819 if (m) { 820 m_freem(m); 821 d->sbdma_ctxtable[idx] = NULL; 822 } 823 } 824 } 825 826 /* 827 * SBDMA_FILLRING(d) 828 * 829 * Fill the specified DMA channel (must be receive channel) 830 * with mbufs 831 * 832 * Input parameters: 833 * d - DMA channel 834 * 835 * Return value: 836 * nothing 837 */ 838 839 static void 840 sbdma_fillring(sbmacdma_t *d) 841 { 842 int idx; 843 844 for (idx = 0; idx < SBMAC_MAX_RXDESCR-1; idx++) 845 if (sbdma_add_rcvbuffer(d, NULL) != 0) 846 break; 847 } 848 849 /* 850 * SBDMA_RX_PROCESS(sc, d) 851 * 852 * Process "completed" receive buffers on the specified DMA channel. 853 * Note that this isn't really ideal for priority channels, since 854 * it processes all of the packets on a given channel before 855 * returning. 856 * 857 * Input parameters: 858 * sc - softc structure 859 * d - DMA channel context 860 * 861 * Return value: 862 * nothing 863 */ 864 865 static void 866 sbdma_rx_process(struct sbmac_softc *sc, sbmacdma_t *d) 867 { 868 int curidx; 869 int hwidx; 870 sbdmadscr_t *dscp; 871 struct mbuf *m; 872 int len; 873 874 struct ifnet *ifp = &(sc->sc_ethercom.ec_if); 875 876 for (;;) { 877 /* 878 * figure out where we are (as an index) and where 879 * the hardware is (also as an index) 880 * 881 * This could be done faster if (for example) the 882 * descriptor table was page-aligned and contiguous in 883 * both virtual and physical memory -- you could then 884 * just compare the low-order bits of the virtual address 885 * (sbdma_rem_index) and the physical address 886 * (sbdma_curdscr CSR). 887 */ 888 889 curidx = d->sbdma_rem_index; 890 hwidx = (int) 891 (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - 892 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); 893 894 /* 895 * If they're the same, that means we've processed all 896 * of the descriptors up to (but not including) the one that 897 * the hardware is working on right now. 898 */ 899 900 if (curidx == hwidx) 901 break; 902 903 /* 904 * Otherwise, get the packet's mbuf ptr back 905 */ 906 907 dscp = &(d->sbdma_dscrtable[curidx]); 908 m = d->sbdma_ctxtable[curidx]; 909 d->sbdma_ctxtable[curidx] = NULL; 910 911 len = (int)G_DMA_DSCRB_PKT_SIZE(dscp->dscr_b) - 4; 912 913 /* 914 * Check packet status. If good, process it. 915 * If not, silently drop it and put it back on the 916 * receive ring. 917 */ 918 919 if (! (dscp->dscr_a & M_DMA_ETHRX_BAD)) { 920 921 /* 922 * Set length into the packet 923 * XXX do we remove the CRC here? 924 */ 925 m->m_pkthdr.len = m->m_len = len; 926 927 ifp->if_ipackets++; 928 m->m_pkthdr.rcvif = ifp; 929 930 931 /* 932 * Add a new buffer to replace the old one. 933 */ 934 sbdma_add_rcvbuffer(d, NULL); 935 936 /* 937 * Handle BPF listeners. Let the BPF user see the 938 * packet, but don't pass it up to the ether_input() 939 * layer unless it's a broadcast packet, multicast 940 * packet, matches our ethernet address or the 941 * interface is in promiscuous mode. 942 */ 943 944 if (ifp->if_bpf) 945 bpf_ops->bpf_mtap(ifp->if_bpf, m); 946 /* 947 * Pass the buffer to the kernel 948 */ 949 (*ifp->if_input)(ifp, m); 950 } else { 951 /* 952 * Packet was mangled somehow. Just drop it and 953 * put it back on the receive ring. 954 */ 955 sbdma_add_rcvbuffer(d, m); 956 } 957 958 /* 959 * .. and advance to the next buffer. 960 */ 961 962 d->sbdma_rem_index = SBDMA_NEXTBUF(d, d->sbdma_rem_index); 963 } 964 } 965 966 /* 967 * SBDMA_TX_PROCESS(sc, d) 968 * 969 * Process "completed" transmit buffers on the specified DMA channel. 970 * This is normally called within the interrupt service routine. 971 * Note that this isn't really ideal for priority channels, since 972 * it processes all of the packets on a given channel before 973 * returning. 974 * 975 * Input parameters: 976 * sc - softc structure 977 * d - DMA channel context 978 * 979 * Return value: 980 * nothing 981 */ 982 983 static void 984 sbdma_tx_process(struct sbmac_softc *sc, sbmacdma_t *d) 985 { 986 int curidx; 987 int hwidx; 988 struct mbuf *m; 989 990 struct ifnet *ifp = &(sc->sc_ethercom.ec_if); 991 992 for (;;) { 993 /* 994 * figure out where we are (as an index) and where 995 * the hardware is (also as an index) 996 * 997 * This could be done faster if (for example) the 998 * descriptor table was page-aligned and contiguous in 999 * both virtual and physical memory -- you could then 1000 * just compare the low-order bits of the virtual address 1001 * (sbdma_rem_index) and the physical address 1002 * (sbdma_curdscr CSR). 1003 */ 1004 1005 curidx = d->sbdma_rem_index; 1006 hwidx = (int) 1007 (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - 1008 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); 1009 1010 /* 1011 * If they're the same, that means we've processed all 1012 * of the descriptors up to (but not including) the one that 1013 * the hardware is working on right now. 1014 */ 1015 1016 if (curidx == hwidx) 1017 break; 1018 1019 /* 1020 * Otherwise, get the packet's mbuf ptr back 1021 */ 1022 1023 m = d->sbdma_ctxtable[curidx]; 1024 d->sbdma_ctxtable[curidx] = NULL; 1025 1026 /* 1027 * for transmits we just free buffers and count packets. 1028 */ 1029 ifp->if_opackets++; 1030 m_freem(m); 1031 1032 /* 1033 * .. and advance to the next buffer. 1034 */ 1035 1036 d->sbdma_rem_index = SBDMA_NEXTBUF(d, d->sbdma_rem_index); 1037 } 1038 1039 /* 1040 * Decide what to set the IFF_OACTIVE bit in the interface to. 1041 * It's supposed to reflect if the interface is actively 1042 * transmitting, but that's really hard to do quickly. 1043 */ 1044 1045 ifp->if_flags &= ~IFF_OACTIVE; 1046 } 1047 1048 /* 1049 * SBMAC_INITCTX(s) 1050 * 1051 * Initialize an Ethernet context structure - this is called 1052 * once per MAC on the 1250. Memory is allocated here, so don't 1053 * call it again from inside the ioctl routines that bring the 1054 * interface up/down 1055 * 1056 * Input parameters: 1057 * s - sbmac context structure 1058 * 1059 * Return value: 1060 * 0 1061 */ 1062 1063 static void 1064 sbmac_initctx(struct sbmac_softc *s) 1065 { 1066 uint64_t sysrev; 1067 1068 /* 1069 * figure out the addresses of some ports 1070 */ 1071 1072 s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE); 1073 s->sbm_maccfg = PKSEG1(s->sbm_base + R_MAC_CFG); 1074 s->sbm_fifocfg = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG); 1075 s->sbm_framecfg = PKSEG1(s->sbm_base + R_MAC_FRAMECFG); 1076 s->sbm_rxfilter = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG); 1077 s->sbm_isr = PKSEG1(s->sbm_base + R_MAC_STATUS); 1078 s->sbm_imr = PKSEG1(s->sbm_base + R_MAC_INT_MASK); 1079 1080 /* 1081 * Initialize the DMA channels. Right now, only one per MAC is used 1082 * Note: Only do this _once_, as it allocates memory from the kernel! 1083 */ 1084 1085 sbdma_initctx(&(s->sbm_txdma), s, 0, DMA_TX, SBMAC_MAX_TXDESCR); 1086 sbdma_initctx(&(s->sbm_rxdma), s, 0, DMA_RX, SBMAC_MAX_RXDESCR); 1087 1088 /* 1089 * initial state is OFF 1090 */ 1091 1092 s->sbm_state = sbmac_state_off; 1093 1094 /* 1095 * Initial speed is (XXX TEMP) 10MBit/s HDX no FC 1096 */ 1097 1098 s->sbm_speed = sbmac_speed_10; 1099 s->sbm_duplex = sbmac_duplex_half; 1100 s->sbm_fc = sbmac_fc_disabled; 1101 1102 /* 1103 * Determine SOC type. 112x has Pass3 SOC features. 1104 */ 1105 sysrev = SBMAC_READCSR( PKSEG1(A_SCD_SYSTEM_REVISION) ); 1106 s->sbm_pass3_dma = (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1120 || 1107 SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125 || 1108 SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125H || 1109 (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250 && 1110 G_SYS_REVISION(sysrev) >= K_SYS_REVISION_BCM1250_PASS3)); 1111 #ifdef SBMAC_EVENT_COUNTERS 1112 evcnt_attach_dynamic(&s->sbm_ev_rxintr, EVCNT_TYPE_INTR, 1113 NULL, s->sc_dev.dv_xname, "rxintr"); 1114 evcnt_attach_dynamic(&s->sbm_ev_txintr, EVCNT_TYPE_INTR, 1115 NULL, s->sc_dev.dv_xname, "txintr"); 1116 evcnt_attach_dynamic(&s->sbm_ev_txdrop, EVCNT_TYPE_MISC, 1117 NULL, s->sc_dev.dv_xname, "txdrop"); 1118 evcnt_attach_dynamic(&s->sbm_ev_txstall, EVCNT_TYPE_MISC, 1119 NULL, s->sc_dev.dv_xname, "txstall"); 1120 if (s->sbm_pass3_dma) { 1121 evcnt_attach_dynamic(&s->sbm_ev_txsplit, EVCNT_TYPE_MISC, 1122 NULL, s->sc_dev.dv_xname, "pass3tx-split"); 1123 evcnt_attach_dynamic(&s->sbm_ev_txkeep, EVCNT_TYPE_MISC, 1124 NULL, s->sc_dev.dv_xname, "pass3tx-keep"); 1125 } 1126 #endif 1127 } 1128 1129 /* 1130 * SBMAC_CHANNEL_START(s) 1131 * 1132 * Start packet processing on this MAC. 1133 * 1134 * Input parameters: 1135 * s - sbmac structure 1136 * 1137 * Return value: 1138 * nothing 1139 */ 1140 1141 static void 1142 sbmac_channel_start(struct sbmac_softc *s) 1143 { 1144 uint64_t reg; 1145 sbmac_port_t port; 1146 uint64_t cfg, fifo, framecfg; 1147 int idx; 1148 uint64_t dma_cfg0, fifo_cfg; 1149 sbmacdma_t *txdma; 1150 1151 /* 1152 * Don't do this if running 1153 */ 1154 1155 if (s->sbm_state == sbmac_state_on) 1156 return; 1157 1158 /* 1159 * Bring the controller out of reset, but leave it off. 1160 */ 1161 1162 SBMAC_WRITECSR(s->sbm_macenable, 0); 1163 1164 /* 1165 * Ignore all received packets 1166 */ 1167 1168 SBMAC_WRITECSR(s->sbm_rxfilter, 0); 1169 1170 /* 1171 * Calculate values for various control registers. 1172 */ 1173 1174 cfg = M_MAC_RETRY_EN | 1175 M_MAC_TX_HOLD_SOP_EN | 1176 V_MAC_TX_PAUSE_CNT_16K | 1177 M_MAC_AP_STAT_EN | 1178 M_MAC_SS_EN | 1179 0; 1180 1181 fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ 1182 V_MAC_TX_RD_THRSH(4) | 1183 V_MAC_TX_RL_THRSH(4) | 1184 V_MAC_RX_PL_THRSH(4) | 1185 V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ 1186 V_MAC_RX_PL_THRSH(4) | 1187 V_MAC_RX_RL_THRSH(8) | 1188 0; 1189 1190 framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | 1191 V_MAC_MAX_FRAMESZ_DEFAULT | 1192 V_MAC_BACKOFF_SEL(1); 1193 1194 /* 1195 * Clear out the hash address map 1196 */ 1197 1198 port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE); 1199 for (idx = 0; idx < MAC_HASH_COUNT; idx++) { 1200 SBMAC_WRITECSR(port, 0); 1201 port += sizeof(uint64_t); 1202 } 1203 1204 /* 1205 * Clear out the exact-match table 1206 */ 1207 1208 port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); 1209 for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { 1210 SBMAC_WRITECSR(port, 0); 1211 port += sizeof(uint64_t); 1212 } 1213 1214 /* 1215 * Clear out the DMA Channel mapping table registers 1216 */ 1217 1218 port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE); 1219 for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { 1220 SBMAC_WRITECSR(port, 0); 1221 port += sizeof(uint64_t); 1222 } 1223 1224 port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE); 1225 for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { 1226 SBMAC_WRITECSR(port, 0); 1227 port += sizeof(uint64_t); 1228 } 1229 1230 /* 1231 * Program the hardware address. It goes into the hardware-address 1232 * register as well as the first filter register. 1233 */ 1234 1235 reg = sbmac_addr2reg(s->sbm_hwaddr); 1236 1237 port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); 1238 SBMAC_WRITECSR(port, reg); 1239 port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR); 1240 SBMAC_WRITECSR(port, 0); // pass1 workaround 1241 1242 /* 1243 * Set the receive filter for no packets, and write values 1244 * to the various config registers 1245 */ 1246 1247 SBMAC_WRITECSR(s->sbm_rxfilter, 0); 1248 SBMAC_WRITECSR(s->sbm_imr, 0); 1249 SBMAC_WRITECSR(s->sbm_framecfg, framecfg); 1250 SBMAC_WRITECSR(s->sbm_fifocfg, fifo); 1251 SBMAC_WRITECSR(s->sbm_maccfg, cfg); 1252 1253 /* 1254 * Initialize DMA channels (rings should be ok now) 1255 */ 1256 1257 sbdma_channel_start(&(s->sbm_rxdma)); 1258 sbdma_channel_start(&(s->sbm_txdma)); 1259 1260 /* 1261 * Configure the speed, duplex, and flow control 1262 */ 1263 1264 sbmac_set_speed(s, s->sbm_speed); 1265 sbmac_set_duplex(s, s->sbm_duplex, s->sbm_fc); 1266 1267 /* 1268 * Fill the receive ring 1269 */ 1270 1271 sbdma_fillring(&(s->sbm_rxdma)); 1272 1273 /* 1274 * Turn on the rest of the bits in the enable register 1275 */ 1276 1277 SBMAC_WRITECSR(s->sbm_macenable, M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0 | 1278 M_MAC_RX_ENABLE | M_MAC_TX_ENABLE); 1279 1280 1281 /* 1282 * Accept any kind of interrupt on TX and RX DMA channel 0 1283 */ 1284 SBMAC_WRITECSR(s->sbm_imr, 1285 (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | 1286 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)); 1287 1288 /* 1289 * Enable receiving unicasts and broadcasts 1290 */ 1291 1292 SBMAC_WRITECSR(s->sbm_rxfilter, M_MAC_UCAST_EN | M_MAC_BCAST_EN); 1293 1294 /* 1295 * On chips which support unaligned DMA features, set the descriptor 1296 * ring for transmit channels to use the unaligned buffer format. 1297 */ 1298 txdma = &(s->sbm_txdma); 1299 1300 if (s->sbm_pass3_dma) { 1301 dma_cfg0 = SBMAC_READCSR(txdma->sbdma_config0); 1302 dma_cfg0 |= V_DMA_DESC_TYPE(K_DMA_DESC_TYPE_RING_UAL_RMW) | 1303 M_DMA_TBX_EN | M_DMA_TDX_EN; 1304 SBMAC_WRITECSR(txdma->sbdma_config0,dma_cfg0); 1305 1306 fifo_cfg = SBMAC_READCSR(s->sbm_fifocfg); 1307 fifo_cfg |= V_MAC_TX_WR_THRSH(8) | 1308 V_MAC_TX_RD_THRSH(8) | V_MAC_TX_RL_THRSH(8); 1309 SBMAC_WRITECSR(s->sbm_fifocfg,fifo_cfg); 1310 } 1311 1312 /* 1313 * we're running now. 1314 */ 1315 1316 s->sbm_state = sbmac_state_on; 1317 s->sc_ethercom.ec_if.if_flags |= IFF_RUNNING; 1318 1319 /* 1320 * Program multicast addresses 1321 */ 1322 1323 sbmac_setmulti(s); 1324 1325 /* 1326 * If channel was in promiscuous mode before, turn that on 1327 */ 1328 1329 if (s->sc_ethercom.ec_if.if_flags & IFF_PROMISC) 1330 sbmac_promiscuous_mode(s, 1); 1331 1332 /* 1333 * Turn on the once-per-second timer 1334 */ 1335 1336 callout_reset(&(s->sc_tick_ch), hz, sbmac_tick, s); 1337 } 1338 1339 /* 1340 * SBMAC_CHANNEL_STOP(s) 1341 * 1342 * Stop packet processing on this MAC. 1343 * 1344 * Input parameters: 1345 * s - sbmac structure 1346 * 1347 * Return value: 1348 * nothing 1349 */ 1350 1351 static void 1352 sbmac_channel_stop(struct sbmac_softc *s) 1353 { 1354 uint64_t ctl; 1355 1356 /* don't do this if already stopped */ 1357 1358 if (s->sbm_state == sbmac_state_off) 1359 return; 1360 1361 /* don't accept any packets, disable all interrupts */ 1362 1363 SBMAC_WRITECSR(s->sbm_rxfilter, 0); 1364 SBMAC_WRITECSR(s->sbm_imr, 0); 1365 1366 /* Turn off ticker */ 1367 1368 callout_stop(&(s->sc_tick_ch)); 1369 1370 /* turn off receiver and transmitter */ 1371 1372 ctl = SBMAC_READCSR(s->sbm_macenable); 1373 ctl &= ~(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0); 1374 SBMAC_WRITECSR(s->sbm_macenable, ctl); 1375 1376 /* We're stopped now. */ 1377 1378 s->sbm_state = sbmac_state_off; 1379 s->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING; 1380 1381 /* Empty the receive and transmit rings */ 1382 1383 sbdma_emptyring(&(s->sbm_rxdma)); 1384 sbdma_emptyring(&(s->sbm_txdma)); 1385 } 1386 1387 /* 1388 * SBMAC_SET_CHANNEL_STATE(state) 1389 * 1390 * Set the channel's state ON or OFF 1391 * 1392 * Input parameters: 1393 * state - new state 1394 * 1395 * Return value: 1396 * old state 1397 */ 1398 1399 static sbmac_state_t 1400 sbmac_set_channel_state(struct sbmac_softc *sc, sbmac_state_t state) 1401 { 1402 sbmac_state_t oldstate = sc->sbm_state; 1403 1404 /* 1405 * If same as previous state, return 1406 */ 1407 1408 if (state == oldstate) 1409 return oldstate; 1410 1411 /* 1412 * If new state is ON, turn channel on 1413 */ 1414 1415 if (state == sbmac_state_on) 1416 sbmac_channel_start(sc); 1417 else 1418 sbmac_channel_stop(sc); 1419 1420 /* 1421 * Return previous state 1422 */ 1423 1424 return oldstate; 1425 } 1426 1427 /* 1428 * SBMAC_PROMISCUOUS_MODE(sc, onoff) 1429 * 1430 * Turn on or off promiscuous mode 1431 * 1432 * Input parameters: 1433 * sc - softc 1434 * onoff - 1 to turn on, 0 to turn off 1435 * 1436 * Return value: 1437 * nothing 1438 */ 1439 1440 static void 1441 sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff) 1442 { 1443 uint64_t reg; 1444 1445 if (sc->sbm_state != sbmac_state_on) 1446 return; 1447 1448 if (onoff) { 1449 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1450 reg |= M_MAC_ALLPKT_EN; 1451 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1452 } else { 1453 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1454 reg &= ~M_MAC_ALLPKT_EN; 1455 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1456 } 1457 } 1458 1459 /* 1460 * SBMAC_INIT_AND_START(sc) 1461 * 1462 * Stop the channel and restart it. This is generally used 1463 * when we have to do something to the channel that requires 1464 * a swift kick. 1465 * 1466 * Input parameters: 1467 * sc - softc 1468 */ 1469 1470 static void 1471 sbmac_init_and_start(struct sbmac_softc *sc) 1472 { 1473 int s; 1474 1475 s = splnet(); 1476 1477 mii_pollstat(&sc->sc_mii); /* poll phy for current speed */ 1478 sbmac_mii_statchg((struct device *) sc); /* set state to new speed */ 1479 sbmac_set_channel_state(sc, sbmac_state_on); 1480 1481 splx(s); 1482 } 1483 1484 /* 1485 * SBMAC_ADDR2REG(ptr) 1486 * 1487 * Convert six bytes into the 64-bit register value that 1488 * we typically write into the SBMAC's address/mcast registers 1489 * 1490 * Input parameters: 1491 * ptr - pointer to 6 bytes 1492 * 1493 * Return value: 1494 * register value 1495 */ 1496 1497 static uint64_t 1498 sbmac_addr2reg(u_char *ptr) 1499 { 1500 uint64_t reg = 0; 1501 1502 ptr += 6; 1503 1504 reg |= (uint64_t) *(--ptr); 1505 reg <<= 8; 1506 reg |= (uint64_t) *(--ptr); 1507 reg <<= 8; 1508 reg |= (uint64_t) *(--ptr); 1509 reg <<= 8; 1510 reg |= (uint64_t) *(--ptr); 1511 reg <<= 8; 1512 reg |= (uint64_t) *(--ptr); 1513 reg <<= 8; 1514 reg |= (uint64_t) *(--ptr); 1515 1516 return reg; 1517 } 1518 1519 /* 1520 * SBMAC_SET_SPEED(s, speed) 1521 * 1522 * Configure LAN speed for the specified MAC. 1523 * Warning: must be called when MAC is off! 1524 * 1525 * Input parameters: 1526 * s - sbmac structure 1527 * speed - speed to set MAC to (see sbmac_speed_t enum) 1528 * 1529 * Return value: 1530 * 1 if successful 1531 * 0 indicates invalid parameters 1532 */ 1533 1534 static int 1535 sbmac_set_speed(struct sbmac_softc *s, sbmac_speed_t speed) 1536 { 1537 uint64_t cfg; 1538 uint64_t framecfg; 1539 1540 /* 1541 * Save new current values 1542 */ 1543 1544 s->sbm_speed = speed; 1545 1546 if (s->sbm_state != sbmac_state_off) 1547 panic("sbmac_set_speed while MAC not off"); 1548 1549 /* 1550 * Read current register values 1551 */ 1552 1553 cfg = SBMAC_READCSR(s->sbm_maccfg); 1554 framecfg = SBMAC_READCSR(s->sbm_framecfg); 1555 1556 /* 1557 * Mask out the stuff we want to change 1558 */ 1559 1560 cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL); 1561 framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH | 1562 M_MAC_SLOT_SIZE); 1563 1564 /* 1565 * Now add in the new bits 1566 */ 1567 1568 switch (speed) { 1569 case sbmac_speed_10: 1570 framecfg |= V_MAC_IFG_RX_10 | 1571 V_MAC_IFG_TX_10 | 1572 K_MAC_IFG_THRSH_10 | 1573 V_MAC_SLOT_SIZE_10; 1574 cfg |= V_MAC_SPEED_SEL_10MBPS; 1575 break; 1576 1577 case sbmac_speed_100: 1578 framecfg |= V_MAC_IFG_RX_100 | 1579 V_MAC_IFG_TX_100 | 1580 V_MAC_IFG_THRSH_100 | 1581 V_MAC_SLOT_SIZE_100; 1582 cfg |= V_MAC_SPEED_SEL_100MBPS ; 1583 break; 1584 1585 case sbmac_speed_1000: 1586 framecfg |= V_MAC_IFG_RX_1000 | 1587 V_MAC_IFG_TX_1000 | 1588 V_MAC_IFG_THRSH_1000 | 1589 V_MAC_SLOT_SIZE_1000; 1590 cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN; 1591 break; 1592 1593 case sbmac_speed_auto: /* XXX not implemented */ 1594 /* fall through */ 1595 default: 1596 return 0; 1597 } 1598 1599 /* 1600 * Send the bits back to the hardware 1601 */ 1602 1603 SBMAC_WRITECSR(s->sbm_framecfg, framecfg); 1604 SBMAC_WRITECSR(s->sbm_maccfg, cfg); 1605 1606 return 1; 1607 } 1608 1609 /* 1610 * SBMAC_SET_DUPLEX(s, duplex, fc) 1611 * 1612 * Set Ethernet duplex and flow control options for this MAC 1613 * Warning: must be called when MAC is off! 1614 * 1615 * Input parameters: 1616 * s - sbmac structure 1617 * duplex - duplex setting (see sbmac_duplex_t) 1618 * fc - flow control setting (see sbmac_fc_t) 1619 * 1620 * Return value: 1621 * 1 if ok 1622 * 0 if an invalid parameter combination was specified 1623 */ 1624 1625 static int 1626 sbmac_set_duplex(struct sbmac_softc *s, sbmac_duplex_t duplex, sbmac_fc_t fc) 1627 { 1628 uint64_t cfg; 1629 1630 /* 1631 * Save new current values 1632 */ 1633 1634 s->sbm_duplex = duplex; 1635 s->sbm_fc = fc; 1636 1637 if (s->sbm_state != sbmac_state_off) 1638 panic("sbmac_set_duplex while MAC not off"); 1639 1640 /* 1641 * Read current register values 1642 */ 1643 1644 cfg = SBMAC_READCSR(s->sbm_maccfg); 1645 1646 /* 1647 * Mask off the stuff we're about to change 1648 */ 1649 1650 cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN); 1651 1652 switch (duplex) { 1653 case sbmac_duplex_half: 1654 switch (fc) { 1655 case sbmac_fc_disabled: 1656 cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED; 1657 break; 1658 1659 case sbmac_fc_collision: 1660 cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED; 1661 break; 1662 1663 case sbmac_fc_carrier: 1664 cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR; 1665 break; 1666 1667 case sbmac_fc_auto: /* XXX not implemented */ 1668 /* fall through */ 1669 case sbmac_fc_frame: /* not valid in half duplex */ 1670 default: /* invalid selection */ 1671 panic("%s: invalid half duplex fc selection %d", 1672 s->sc_dev.dv_xname, fc); 1673 return 0; 1674 } 1675 break; 1676 1677 case sbmac_duplex_full: 1678 switch (fc) { 1679 case sbmac_fc_disabled: 1680 cfg |= V_MAC_FC_CMD_DISABLED; 1681 break; 1682 1683 case sbmac_fc_frame: 1684 cfg |= V_MAC_FC_CMD_ENABLED; 1685 break; 1686 1687 case sbmac_fc_collision: /* not valid in full duplex */ 1688 case sbmac_fc_carrier: /* not valid in full duplex */ 1689 case sbmac_fc_auto: /* XXX not implemented */ 1690 /* fall through */ 1691 default: 1692 panic("%s: invalid full duplex fc selection %d", 1693 s->sc_dev.dv_xname, fc); 1694 return 0; 1695 } 1696 break; 1697 1698 default: 1699 /* fall through */ 1700 case sbmac_duplex_auto: 1701 panic("%s: bad duplex %d", s->sc_dev.dv_xname, duplex); 1702 /* XXX not implemented */ 1703 break; 1704 } 1705 1706 /* 1707 * Send the bits back to the hardware 1708 */ 1709 1710 SBMAC_WRITECSR(s->sbm_maccfg, cfg); 1711 1712 return 1; 1713 } 1714 1715 /* 1716 * SBMAC_INTR() 1717 * 1718 * Interrupt handler for MAC interrupts 1719 * 1720 * Input parameters: 1721 * MAC structure 1722 * 1723 * Return value: 1724 * nothing 1725 */ 1726 1727 /* ARGSUSED */ 1728 static void 1729 sbmac_intr(void *xsc, uint32_t status, vaddr_t pc) 1730 { 1731 struct sbmac_softc *sc = (struct sbmac_softc *) xsc; 1732 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1733 uint64_t isr; 1734 1735 for (;;) { 1736 1737 /* 1738 * Read the ISR (this clears the bits in the real register) 1739 */ 1740 1741 isr = SBMAC_READCSR(sc->sbm_isr); 1742 1743 if (isr == 0) 1744 break; 1745 1746 /* 1747 * Transmits on channel 0 1748 */ 1749 1750 if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) { 1751 sbdma_tx_process(sc, &(sc->sbm_txdma)); 1752 SBMAC_EVCNT_INCR(sc->sbm_ev_txintr); 1753 } 1754 1755 /* 1756 * Receives on channel 0 1757 */ 1758 1759 if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) { 1760 sbdma_rx_process(sc, &(sc->sbm_rxdma)); 1761 SBMAC_EVCNT_INCR(sc->sbm_ev_rxintr); 1762 } 1763 } 1764 1765 /* try to get more packets going */ 1766 sbmac_start(ifp); 1767 } 1768 1769 1770 /* 1771 * SBMAC_START(ifp) 1772 * 1773 * Start output on the specified interface. Basically, we 1774 * queue as many buffers as we can until the ring fills up, or 1775 * we run off the end of the queue, whichever comes first. 1776 * 1777 * Input parameters: 1778 * ifp - interface 1779 * 1780 * Return value: 1781 * nothing 1782 */ 1783 1784 static void 1785 sbmac_start(struct ifnet *ifp) 1786 { 1787 struct sbmac_softc *sc; 1788 struct mbuf *m_head = NULL; 1789 int rv; 1790 1791 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 1792 return; 1793 1794 sc = ifp->if_softc; 1795 1796 for (;;) { 1797 1798 IF_DEQUEUE(&ifp->if_snd, m_head); 1799 if (m_head == NULL) 1800 break; 1801 1802 /* 1803 * Put the buffer on the transmit ring. If we 1804 * don't have room, set the OACTIVE flag and wait 1805 * for the NIC to drain the ring. 1806 */ 1807 1808 rv = sbdma_add_txbuffer(&(sc->sbm_txdma), m_head); 1809 1810 if (rv == 0) { 1811 /* 1812 * If there's a BPF listener, bounce a copy of this 1813 * frame to it. 1814 */ 1815 if (ifp->if_bpf) 1816 bpf_ops->bpf_mtap(ifp->if_bpf, m_head); 1817 if (!sc->sbm_pass3_dma) { 1818 /* 1819 * Don't free mbuf if we're not copying to new 1820 * mbuf in sbdma_add_txbuffer. It will be 1821 * freed in sbdma_tx_process. 1822 */ 1823 m_freem(m_head); 1824 } 1825 } else { 1826 IF_PREPEND(&ifp->if_snd, m_head); 1827 ifp->if_flags |= IFF_OACTIVE; 1828 break; 1829 } 1830 } 1831 } 1832 1833 /* 1834 * SBMAC_SETMULTI(sc) 1835 * 1836 * Reprogram the multicast table into the hardware, given 1837 * the list of multicasts associated with the interface 1838 * structure. 1839 * 1840 * Input parameters: 1841 * sc - softc 1842 * 1843 * Return value: 1844 * nothing 1845 */ 1846 1847 static void 1848 sbmac_setmulti(struct sbmac_softc *sc) 1849 { 1850 struct ifnet *ifp; 1851 uint64_t reg; 1852 sbmac_port_t port; 1853 int idx; 1854 struct ether_multi *enm; 1855 struct ether_multistep step; 1856 1857 ifp = &sc->sc_ethercom.ec_if; 1858 1859 /* 1860 * Clear out entire multicast table. We do this by nuking 1861 * the entire hash table and all the direct matches except 1862 * the first one, which is used for our station address 1863 */ 1864 1865 for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { 1866 port = PKSEG1(sc->sbm_base + 1867 R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); 1868 SBMAC_WRITECSR(port, 0); 1869 } 1870 1871 for (idx = 0; idx < MAC_HASH_COUNT; idx++) { 1872 port = PKSEG1(sc->sbm_base + 1873 R_MAC_HASH_BASE+(idx*sizeof(uint64_t))); 1874 SBMAC_WRITECSR(port, 0); 1875 } 1876 1877 /* 1878 * Clear the filter to say we don't want any multicasts. 1879 */ 1880 1881 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1882 reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN); 1883 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1884 1885 if (ifp->if_flags & IFF_ALLMULTI) { 1886 /* 1887 * Enable ALL multicasts. Do this by inverting the 1888 * multicast enable bit. 1889 */ 1890 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1891 reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN); 1892 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1893 return; 1894 } 1895 1896 /* 1897 * Progam new multicast entries. For now, only use the 1898 * perfect filter. In the future we'll need to use the 1899 * hash filter if the perfect filter overflows 1900 */ 1901 1902 /* 1903 * XXX only using perfect filter for now, need to use hash 1904 * XXX if the table overflows 1905 */ 1906 1907 idx = 1; /* skip station address */ 1908 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1909 while ((enm != NULL) && (idx < MAC_ADDR_COUNT)) { 1910 reg = sbmac_addr2reg(enm->enm_addrlo); 1911 port = PKSEG1(sc->sbm_base + 1912 R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); 1913 SBMAC_WRITECSR(port, reg); 1914 idx++; 1915 ETHER_NEXT_MULTI(step, enm); 1916 } 1917 1918 /* 1919 * Enable the "accept multicast bits" if we programmed at least one 1920 * multicast. 1921 */ 1922 1923 if (idx > 1) { 1924 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1925 reg |= M_MAC_MCAST_EN; 1926 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1927 } 1928 } 1929 1930 /* 1931 * SBMAC_ETHER_IOCTL(ifp, cmd, data) 1932 * 1933 * Generic IOCTL requests for this interface. The basic 1934 * stuff is handled here for bringing the interface up, 1935 * handling multicasts, etc. 1936 * 1937 * Input parameters: 1938 * ifp - interface structure 1939 * cmd - command code 1940 * data - pointer to data 1941 * 1942 * Return value: 1943 * return value (0 is success) 1944 */ 1945 1946 static int 1947 sbmac_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1948 { 1949 struct ifaddr *ifa = (struct ifaddr *) data; 1950 struct sbmac_softc *sc = ifp->if_softc; 1951 1952 switch (cmd) { 1953 case SIOCINITIFADDR: 1954 ifp->if_flags |= IFF_UP; 1955 1956 switch (ifa->ifa_addr->sa_family) { 1957 #ifdef INET 1958 case AF_INET: 1959 sbmac_init_and_start(sc); 1960 arp_ifinit(ifp, ifa); 1961 break; 1962 #endif 1963 #ifdef NS 1964 case AF_NS: 1965 { 1966 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 1967 1968 if (ns_nullhost(*ina)) 1969 ina->x_host = 1970 *(union ns_host *)LLADDR(ifp->if_sadl); 1971 else 1972 memcpy(LLADDR(ifp->if_sadl), ina->x_host.c_host, 1973 ifp->if_addrlen); 1974 /* Set new address. */ 1975 sbmac_init_and_start(sc); 1976 break; 1977 } 1978 #endif 1979 default: 1980 sbmac_init_and_start(sc); 1981 break; 1982 } 1983 break; 1984 1985 default: 1986 return ENOTTY; 1987 } 1988 1989 return (0); 1990 } 1991 1992 /* 1993 * SBMAC_IOCTL(ifp, cmd, data) 1994 * 1995 * Main IOCTL handler - dispatches to other IOCTLs for various 1996 * types of requests. 1997 * 1998 * Input parameters: 1999 * ifp - interface pointer 2000 * cmd - command code 2001 * data - pointer to argument data 2002 * 2003 * Return value: 2004 * 0 if ok 2005 * else error code 2006 */ 2007 2008 static int 2009 sbmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2010 { 2011 struct sbmac_softc *sc = ifp->if_softc; 2012 struct ifreq *ifr = (struct ifreq *) data; 2013 int s, error = 0; 2014 2015 s = splnet(); 2016 2017 switch (cmd) { 2018 case SIOCINITIFADDR: 2019 error = sbmac_ether_ioctl(ifp, cmd, data); 2020 break; 2021 case SIOCSIFMTU: 2022 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) 2023 error = EINVAL; 2024 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 2025 /* XXX Program new MTU here */ 2026 error = 0; 2027 break; 2028 case SIOCSIFFLAGS: 2029 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 2030 break; 2031 if (ifp->if_flags & IFF_UP) { 2032 /* 2033 * If only the state of the PROMISC flag changed, 2034 * just tweak the hardware registers. 2035 */ 2036 if ((ifp->if_flags & IFF_RUNNING) && 2037 (ifp->if_flags & IFF_PROMISC)) { 2038 /* turn on promiscuous mode */ 2039 sbmac_promiscuous_mode(sc, 1); 2040 } else if (ifp->if_flags & IFF_RUNNING && 2041 !(ifp->if_flags & IFF_PROMISC)) { 2042 /* turn off promiscuous mode */ 2043 sbmac_promiscuous_mode(sc, 0); 2044 } else 2045 sbmac_set_channel_state(sc, sbmac_state_on); 2046 } else { 2047 if (ifp->if_flags & IFF_RUNNING) 2048 sbmac_set_channel_state(sc, sbmac_state_off); 2049 } 2050 2051 sc->sbm_if_flags = ifp->if_flags; 2052 error = 0; 2053 break; 2054 2055 case SIOCADDMULTI: 2056 case SIOCDELMULTI: 2057 case SIOCSIFMEDIA: 2058 case SIOCGIFMEDIA: 2059 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 2060 error = 0; 2061 if (ifp->if_flags & IFF_RUNNING) 2062 sbmac_setmulti(sc); 2063 } 2064 break; 2065 default: 2066 error = ether_ioctl(ifp, cmd, data); 2067 break; 2068 } 2069 2070 (void)splx(s); 2071 2072 return(error); 2073 } 2074 2075 /* 2076 * SBMAC_IFMEDIA_UPD(ifp) 2077 * 2078 * Configure an appropriate media type for this interface, 2079 * given the data in the interface structure 2080 * 2081 * Input parameters: 2082 * ifp - interface 2083 * 2084 * Return value: 2085 * 0 if ok 2086 * else error code 2087 */ 2088 2089 /* 2090 * SBMAC_IFMEDIA_STS(ifp, ifmr) 2091 * 2092 * Report current media status (used by ifconfig, for example) 2093 * 2094 * Input parameters: 2095 * ifp - interface structure 2096 * ifmr - media request structure 2097 * 2098 * Return value: 2099 * nothing 2100 */ 2101 2102 /* 2103 * SBMAC_WATCHDOG(ifp) 2104 * 2105 * Called periodically to make sure we're still happy. 2106 * 2107 * Input parameters: 2108 * ifp - interface structure 2109 * 2110 * Return value: 2111 * nothing 2112 */ 2113 2114 static void 2115 sbmac_watchdog(struct ifnet *ifp) 2116 { 2117 2118 /* XXX do something */ 2119 } 2120 2121 /* 2122 * One second timer, used to tick MII. 2123 */ 2124 static void 2125 sbmac_tick(void *arg) 2126 { 2127 struct sbmac_softc *sc = arg; 2128 int s; 2129 2130 s = splnet(); 2131 mii_tick(&sc->sc_mii); 2132 splx(s); 2133 2134 callout_reset(&sc->sc_tick_ch, hz, sbmac_tick, sc); 2135 } 2136 2137 2138 /* 2139 * SBMAC_MATCH(parent, match, aux) 2140 * 2141 * Part of the config process - see if this device matches the 2142 * info about what we expect to find on the bus. 2143 * 2144 * Input parameters: 2145 * parent - parent bus structure 2146 * match - 2147 * aux - bus-specific args 2148 * 2149 * Return value: 2150 * 1 if we match 2151 * 0 if we don't match 2152 */ 2153 2154 static int 2155 sbmac_match(struct device *parent, struct cfdata *match, void *aux) 2156 { 2157 struct sbobio_attach_args *sap = aux; 2158 2159 /* 2160 * Make sure it's a MAC 2161 */ 2162 2163 if (sap->sa_locs.sa_type != SBOBIO_DEVTYPE_MAC) 2164 return 0; 2165 2166 /* 2167 * Yup, it is. 2168 */ 2169 2170 return 1; 2171 } 2172 2173 /* 2174 * SBMAC_PARSE_XDIGIT(str) 2175 * 2176 * Parse a hex digit, returning its value 2177 * 2178 * Input parameters: 2179 * str - character 2180 * 2181 * Return value: 2182 * hex value, or -1 if invalid 2183 */ 2184 2185 static int 2186 sbmac_parse_xdigit(char str) 2187 { 2188 int digit; 2189 2190 if ((str >= '0') && (str <= '9')) 2191 digit = str - '0'; 2192 else if ((str >= 'a') && (str <= 'f')) 2193 digit = str - 'a' + 10; 2194 else if ((str >= 'A') && (str <= 'F')) 2195 digit = str - 'A' + 10; 2196 else 2197 digit = -1; 2198 2199 return digit; 2200 } 2201 2202 /* 2203 * SBMAC_PARSE_HWADDR(str, hwaddr) 2204 * 2205 * Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte 2206 * Ethernet address. 2207 * 2208 * Input parameters: 2209 * str - string 2210 * hwaddr - pointer to hardware address 2211 * 2212 * Return value: 2213 * 0 if ok, else -1 2214 */ 2215 2216 static int 2217 sbmac_parse_hwaddr(const char *str, u_char *hwaddr) 2218 { 2219 int digit1, digit2; 2220 int idx = 6; 2221 2222 while (*str && (idx > 0)) { 2223 digit1 = sbmac_parse_xdigit(*str); 2224 if (digit1 < 0) 2225 return -1; 2226 str++; 2227 if (!*str) 2228 return -1; 2229 2230 if ((*str == ':') || (*str == '-')) { 2231 digit2 = digit1; 2232 digit1 = 0; 2233 } else { 2234 digit2 = sbmac_parse_xdigit(*str); 2235 if (digit2 < 0) 2236 return -1; 2237 str++; 2238 } 2239 2240 *hwaddr++ = (digit1 << 4) | digit2; 2241 idx--; 2242 2243 if (*str == '-') 2244 str++; 2245 if (*str == ':') 2246 str++; 2247 } 2248 return 0; 2249 } 2250 2251 /* 2252 * SBMAC_ATTACH(parent, self, aux) 2253 * 2254 * Attach routine - init hardware and hook ourselves into NetBSD. 2255 * 2256 * Input parameters: 2257 * parent - parent bus device 2258 * self - our softc 2259 * aux - attach data 2260 * 2261 * Return value: 2262 * nothing 2263 */ 2264 2265 static void 2266 sbmac_attach(struct device *parent, struct device *self, void *aux) 2267 { 2268 struct ifnet *ifp; 2269 struct sbmac_softc *sc; 2270 struct sbobio_attach_args *sap = aux; 2271 u_char *eaddr; 2272 static int unit = 0; /* XXX */ 2273 uint64_t ea_reg; 2274 int idx; 2275 2276 sc = (struct sbmac_softc *)self; 2277 2278 /* Determine controller base address */ 2279 2280 sc->sbm_base = sap->sa_locs.sa_addr; 2281 2282 eaddr = sc->sbm_hwaddr; 2283 2284 /* 2285 * Initialize context (get pointers to registers and stuff), then 2286 * allocate the memory for the descriptor tables. 2287 */ 2288 2289 sbmac_initctx(sc); 2290 2291 callout_init(&(sc->sc_tick_ch), 0); 2292 2293 /* 2294 * Read the ethernet address. The firwmare left this programmed 2295 * for us in the ethernet address register for each mac. 2296 */ 2297 2298 ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR)); 2299 for (idx = 0; idx < 6; idx++) { 2300 eaddr[idx] = (uint8_t) (ea_reg & 0xFF); 2301 ea_reg >>= 8; 2302 } 2303 2304 #define SBMAC_DEFAULT_HWADDR "40:00:00:00:01:00" 2305 if (eaddr[0] == 0 && eaddr[1] == 0 && eaddr[2] == 0 && 2306 eaddr[3] == 0 && eaddr[4] == 0 && eaddr[5] == 0) { 2307 sbmac_parse_hwaddr(SBMAC_DEFAULT_HWADDR, eaddr); 2308 eaddr[5] = unit; 2309 } 2310 2311 #ifdef SBMAC_ETH0_HWADDR 2312 if (unit == 0) 2313 sbmac_parse_hwaddr(SBMAC_ETH0_HWADDR, eaddr); 2314 #endif 2315 #ifdef SBMAC_ETH1_HWADDR 2316 if (unit == 1) 2317 sbmac_parse_hwaddr(SBMAC_ETH1_HWADDR, eaddr); 2318 #endif 2319 #ifdef SBMAC_ETH2_HWADDR 2320 if (unit == 2) 2321 sbmac_parse_hwaddr(SBMAC_ETH2_HWADDR, eaddr); 2322 #endif 2323 unit++; 2324 2325 /* 2326 * Display Ethernet address (this is called during the config process 2327 * so we need to finish off the config message that was being displayed) 2328 */ 2329 printf(": Ethernet%s\n", 2330 sc->sbm_pass3_dma ? ", using unaligned tx DMA" : ""); 2331 printf("%s: Ethernet address: %s\n", self->dv_xname, 2332 ether_sprintf(eaddr)); 2333 2334 2335 /* 2336 * Set up ifnet structure 2337 */ 2338 2339 ifp = &sc->sc_ethercom.ec_if; 2340 ifp->if_softc = sc; 2341 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); 2342 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | 2343 IFF_NOTRAILERS; 2344 ifp->if_ioctl = sbmac_ioctl; 2345 ifp->if_start = sbmac_start; 2346 ifp->if_watchdog = sbmac_watchdog; 2347 ifp->if_snd.ifq_maxlen = SBMAC_MAX_TXDESCR - 1; 2348 2349 /* 2350 * Set up ifmedia support. 2351 */ 2352 2353 /* 2354 * Initialize MII/media info. 2355 */ 2356 sc->sc_mii.mii_ifp = ifp; 2357 sc->sc_mii.mii_readreg = sbmac_mii_readreg; 2358 sc->sc_mii.mii_writereg = sbmac_mii_writereg; 2359 sc->sc_mii.mii_statchg = sbmac_mii_statchg; 2360 sc->sc_ethercom.ec_mii = &sc->sc_mii; 2361 ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange, 2362 ether_mediastatus); 2363 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 2364 MII_OFFSET_ANY, 0); 2365 2366 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 2367 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); 2368 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); 2369 } else { 2370 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 2371 } 2372 2373 2374 /* 2375 * map/route interrupt 2376 */ 2377 2378 sc->sbm_intrhand = cpu_intr_establish(sap->sa_locs.sa_intr[0], IPL_NET, 2379 sbmac_intr, sc); 2380 2381 /* 2382 * Call MI attach routines. 2383 */ 2384 if_attach(ifp); 2385 ether_ifattach(ifp, eaddr); 2386 } 2387