1 /* $NetBSD: sbmac.c,v 1.37 2010/04/05 07:19:31 joerg 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.37 2010/04/05 07:19:31 joerg 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 bpf_mtap(ifp, m); 945 /* 946 * Pass the buffer to the kernel 947 */ 948 (*ifp->if_input)(ifp, m); 949 } else { 950 /* 951 * Packet was mangled somehow. Just drop it and 952 * put it back on the receive ring. 953 */ 954 sbdma_add_rcvbuffer(d, m); 955 } 956 957 /* 958 * .. and advance to the next buffer. 959 */ 960 961 d->sbdma_rem_index = SBDMA_NEXTBUF(d, d->sbdma_rem_index); 962 } 963 } 964 965 /* 966 * SBDMA_TX_PROCESS(sc, d) 967 * 968 * Process "completed" transmit buffers on the specified DMA channel. 969 * This is normally called within the interrupt service routine. 970 * Note that this isn't really ideal for priority channels, since 971 * it processes all of the packets on a given channel before 972 * returning. 973 * 974 * Input parameters: 975 * sc - softc structure 976 * d - DMA channel context 977 * 978 * Return value: 979 * nothing 980 */ 981 982 static void 983 sbdma_tx_process(struct sbmac_softc *sc, sbmacdma_t *d) 984 { 985 int curidx; 986 int hwidx; 987 struct mbuf *m; 988 989 struct ifnet *ifp = &(sc->sc_ethercom.ec_if); 990 991 for (;;) { 992 /* 993 * figure out where we are (as an index) and where 994 * the hardware is (also as an index) 995 * 996 * This could be done faster if (for example) the 997 * descriptor table was page-aligned and contiguous in 998 * both virtual and physical memory -- you could then 999 * just compare the low-order bits of the virtual address 1000 * (sbdma_rem_index) and the physical address 1001 * (sbdma_curdscr CSR). 1002 */ 1003 1004 curidx = d->sbdma_rem_index; 1005 hwidx = (int) 1006 (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) - 1007 d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t)); 1008 1009 /* 1010 * If they're the same, that means we've processed all 1011 * of the descriptors up to (but not including) the one that 1012 * the hardware is working on right now. 1013 */ 1014 1015 if (curidx == hwidx) 1016 break; 1017 1018 /* 1019 * Otherwise, get the packet's mbuf ptr back 1020 */ 1021 1022 m = d->sbdma_ctxtable[curidx]; 1023 d->sbdma_ctxtable[curidx] = NULL; 1024 1025 /* 1026 * for transmits we just free buffers and count packets. 1027 */ 1028 ifp->if_opackets++; 1029 m_freem(m); 1030 1031 /* 1032 * .. and advance to the next buffer. 1033 */ 1034 1035 d->sbdma_rem_index = SBDMA_NEXTBUF(d, d->sbdma_rem_index); 1036 } 1037 1038 /* 1039 * Decide what to set the IFF_OACTIVE bit in the interface to. 1040 * It's supposed to reflect if the interface is actively 1041 * transmitting, but that's really hard to do quickly. 1042 */ 1043 1044 ifp->if_flags &= ~IFF_OACTIVE; 1045 } 1046 1047 /* 1048 * SBMAC_INITCTX(s) 1049 * 1050 * Initialize an Ethernet context structure - this is called 1051 * once per MAC on the 1250. Memory is allocated here, so don't 1052 * call it again from inside the ioctl routines that bring the 1053 * interface up/down 1054 * 1055 * Input parameters: 1056 * s - sbmac context structure 1057 * 1058 * Return value: 1059 * 0 1060 */ 1061 1062 static void 1063 sbmac_initctx(struct sbmac_softc *s) 1064 { 1065 uint64_t sysrev; 1066 1067 /* 1068 * figure out the addresses of some ports 1069 */ 1070 1071 s->sbm_macenable = PKSEG1(s->sbm_base + R_MAC_ENABLE); 1072 s->sbm_maccfg = PKSEG1(s->sbm_base + R_MAC_CFG); 1073 s->sbm_fifocfg = PKSEG1(s->sbm_base + R_MAC_THRSH_CFG); 1074 s->sbm_framecfg = PKSEG1(s->sbm_base + R_MAC_FRAMECFG); 1075 s->sbm_rxfilter = PKSEG1(s->sbm_base + R_MAC_ADFILTER_CFG); 1076 s->sbm_isr = PKSEG1(s->sbm_base + R_MAC_STATUS); 1077 s->sbm_imr = PKSEG1(s->sbm_base + R_MAC_INT_MASK); 1078 1079 /* 1080 * Initialize the DMA channels. Right now, only one per MAC is used 1081 * Note: Only do this _once_, as it allocates memory from the kernel! 1082 */ 1083 1084 sbdma_initctx(&(s->sbm_txdma), s, 0, DMA_TX, SBMAC_MAX_TXDESCR); 1085 sbdma_initctx(&(s->sbm_rxdma), s, 0, DMA_RX, SBMAC_MAX_RXDESCR); 1086 1087 /* 1088 * initial state is OFF 1089 */ 1090 1091 s->sbm_state = sbmac_state_off; 1092 1093 /* 1094 * Initial speed is (XXX TEMP) 10MBit/s HDX no FC 1095 */ 1096 1097 s->sbm_speed = sbmac_speed_10; 1098 s->sbm_duplex = sbmac_duplex_half; 1099 s->sbm_fc = sbmac_fc_disabled; 1100 1101 /* 1102 * Determine SOC type. 112x has Pass3 SOC features. 1103 */ 1104 sysrev = SBMAC_READCSR( PKSEG1(A_SCD_SYSTEM_REVISION) ); 1105 s->sbm_pass3_dma = (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1120 || 1106 SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125 || 1107 SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1125H || 1108 (SYS_SOC_TYPE(sysrev) == K_SYS_SOC_TYPE_BCM1250 && 1109 G_SYS_REVISION(sysrev) >= K_SYS_REVISION_BCM1250_PASS3)); 1110 #ifdef SBMAC_EVENT_COUNTERS 1111 evcnt_attach_dynamic(&s->sbm_ev_rxintr, EVCNT_TYPE_INTR, 1112 NULL, s->sc_dev.dv_xname, "rxintr"); 1113 evcnt_attach_dynamic(&s->sbm_ev_txintr, EVCNT_TYPE_INTR, 1114 NULL, s->sc_dev.dv_xname, "txintr"); 1115 evcnt_attach_dynamic(&s->sbm_ev_txdrop, EVCNT_TYPE_MISC, 1116 NULL, s->sc_dev.dv_xname, "txdrop"); 1117 evcnt_attach_dynamic(&s->sbm_ev_txstall, EVCNT_TYPE_MISC, 1118 NULL, s->sc_dev.dv_xname, "txstall"); 1119 if (s->sbm_pass3_dma) { 1120 evcnt_attach_dynamic(&s->sbm_ev_txsplit, EVCNT_TYPE_MISC, 1121 NULL, s->sc_dev.dv_xname, "pass3tx-split"); 1122 evcnt_attach_dynamic(&s->sbm_ev_txkeep, EVCNT_TYPE_MISC, 1123 NULL, s->sc_dev.dv_xname, "pass3tx-keep"); 1124 } 1125 #endif 1126 } 1127 1128 /* 1129 * SBMAC_CHANNEL_START(s) 1130 * 1131 * Start packet processing on this MAC. 1132 * 1133 * Input parameters: 1134 * s - sbmac structure 1135 * 1136 * Return value: 1137 * nothing 1138 */ 1139 1140 static void 1141 sbmac_channel_start(struct sbmac_softc *s) 1142 { 1143 uint64_t reg; 1144 sbmac_port_t port; 1145 uint64_t cfg, fifo, framecfg; 1146 int idx; 1147 uint64_t dma_cfg0, fifo_cfg; 1148 sbmacdma_t *txdma; 1149 1150 /* 1151 * Don't do this if running 1152 */ 1153 1154 if (s->sbm_state == sbmac_state_on) 1155 return; 1156 1157 /* 1158 * Bring the controller out of reset, but leave it off. 1159 */ 1160 1161 SBMAC_WRITECSR(s->sbm_macenable, 0); 1162 1163 /* 1164 * Ignore all received packets 1165 */ 1166 1167 SBMAC_WRITECSR(s->sbm_rxfilter, 0); 1168 1169 /* 1170 * Calculate values for various control registers. 1171 */ 1172 1173 cfg = M_MAC_RETRY_EN | 1174 M_MAC_TX_HOLD_SOP_EN | 1175 V_MAC_TX_PAUSE_CNT_16K | 1176 M_MAC_AP_STAT_EN | 1177 M_MAC_SS_EN | 1178 0; 1179 1180 fifo = V_MAC_TX_WR_THRSH(4) | /* Must be '4' or '8' */ 1181 V_MAC_TX_RD_THRSH(4) | 1182 V_MAC_TX_RL_THRSH(4) | 1183 V_MAC_RX_PL_THRSH(4) | 1184 V_MAC_RX_RD_THRSH(4) | /* Must be '4' */ 1185 V_MAC_RX_PL_THRSH(4) | 1186 V_MAC_RX_RL_THRSH(8) | 1187 0; 1188 1189 framecfg = V_MAC_MIN_FRAMESZ_DEFAULT | 1190 V_MAC_MAX_FRAMESZ_DEFAULT | 1191 V_MAC_BACKOFF_SEL(1); 1192 1193 /* 1194 * Clear out the hash address map 1195 */ 1196 1197 port = PKSEG1(s->sbm_base + R_MAC_HASH_BASE); 1198 for (idx = 0; idx < MAC_HASH_COUNT; idx++) { 1199 SBMAC_WRITECSR(port, 0); 1200 port += sizeof(uint64_t); 1201 } 1202 1203 /* 1204 * Clear out the exact-match table 1205 */ 1206 1207 port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); 1208 for (idx = 0; idx < MAC_ADDR_COUNT; idx++) { 1209 SBMAC_WRITECSR(port, 0); 1210 port += sizeof(uint64_t); 1211 } 1212 1213 /* 1214 * Clear out the DMA Channel mapping table registers 1215 */ 1216 1217 port = PKSEG1(s->sbm_base + R_MAC_CHUP0_BASE); 1218 for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { 1219 SBMAC_WRITECSR(port, 0); 1220 port += sizeof(uint64_t); 1221 } 1222 1223 port = PKSEG1(s->sbm_base + R_MAC_CHLO0_BASE); 1224 for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) { 1225 SBMAC_WRITECSR(port, 0); 1226 port += sizeof(uint64_t); 1227 } 1228 1229 /* 1230 * Program the hardware address. It goes into the hardware-address 1231 * register as well as the first filter register. 1232 */ 1233 1234 reg = sbmac_addr2reg(s->sbm_hwaddr); 1235 1236 port = PKSEG1(s->sbm_base + R_MAC_ADDR_BASE); 1237 SBMAC_WRITECSR(port, reg); 1238 port = PKSEG1(s->sbm_base + R_MAC_ETHERNET_ADDR); 1239 SBMAC_WRITECSR(port, 0); // pass1 workaround 1240 1241 /* 1242 * Set the receive filter for no packets, and write values 1243 * to the various config registers 1244 */ 1245 1246 SBMAC_WRITECSR(s->sbm_rxfilter, 0); 1247 SBMAC_WRITECSR(s->sbm_imr, 0); 1248 SBMAC_WRITECSR(s->sbm_framecfg, framecfg); 1249 SBMAC_WRITECSR(s->sbm_fifocfg, fifo); 1250 SBMAC_WRITECSR(s->sbm_maccfg, cfg); 1251 1252 /* 1253 * Initialize DMA channels (rings should be ok now) 1254 */ 1255 1256 sbdma_channel_start(&(s->sbm_rxdma)); 1257 sbdma_channel_start(&(s->sbm_txdma)); 1258 1259 /* 1260 * Configure the speed, duplex, and flow control 1261 */ 1262 1263 sbmac_set_speed(s, s->sbm_speed); 1264 sbmac_set_duplex(s, s->sbm_duplex, s->sbm_fc); 1265 1266 /* 1267 * Fill the receive ring 1268 */ 1269 1270 sbdma_fillring(&(s->sbm_rxdma)); 1271 1272 /* 1273 * Turn on the rest of the bits in the enable register 1274 */ 1275 1276 SBMAC_WRITECSR(s->sbm_macenable, M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0 | 1277 M_MAC_RX_ENABLE | M_MAC_TX_ENABLE); 1278 1279 1280 /* 1281 * Accept any kind of interrupt on TX and RX DMA channel 0 1282 */ 1283 SBMAC_WRITECSR(s->sbm_imr, 1284 (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) | 1285 (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)); 1286 1287 /* 1288 * Enable receiving unicasts and broadcasts 1289 */ 1290 1291 SBMAC_WRITECSR(s->sbm_rxfilter, M_MAC_UCAST_EN | M_MAC_BCAST_EN); 1292 1293 /* 1294 * On chips which support unaligned DMA features, set the descriptor 1295 * ring for transmit channels to use the unaligned buffer format. 1296 */ 1297 txdma = &(s->sbm_txdma); 1298 1299 if (s->sbm_pass3_dma) { 1300 dma_cfg0 = SBMAC_READCSR(txdma->sbdma_config0); 1301 dma_cfg0 |= V_DMA_DESC_TYPE(K_DMA_DESC_TYPE_RING_UAL_RMW) | 1302 M_DMA_TBX_EN | M_DMA_TDX_EN; 1303 SBMAC_WRITECSR(txdma->sbdma_config0,dma_cfg0); 1304 1305 fifo_cfg = SBMAC_READCSR(s->sbm_fifocfg); 1306 fifo_cfg |= V_MAC_TX_WR_THRSH(8) | 1307 V_MAC_TX_RD_THRSH(8) | V_MAC_TX_RL_THRSH(8); 1308 SBMAC_WRITECSR(s->sbm_fifocfg,fifo_cfg); 1309 } 1310 1311 /* 1312 * we're running now. 1313 */ 1314 1315 s->sbm_state = sbmac_state_on; 1316 s->sc_ethercom.ec_if.if_flags |= IFF_RUNNING; 1317 1318 /* 1319 * Program multicast addresses 1320 */ 1321 1322 sbmac_setmulti(s); 1323 1324 /* 1325 * If channel was in promiscuous mode before, turn that on 1326 */ 1327 1328 if (s->sc_ethercom.ec_if.if_flags & IFF_PROMISC) 1329 sbmac_promiscuous_mode(s, 1); 1330 1331 /* 1332 * Turn on the once-per-second timer 1333 */ 1334 1335 callout_reset(&(s->sc_tick_ch), hz, sbmac_tick, s); 1336 } 1337 1338 /* 1339 * SBMAC_CHANNEL_STOP(s) 1340 * 1341 * Stop packet processing on this MAC. 1342 * 1343 * Input parameters: 1344 * s - sbmac structure 1345 * 1346 * Return value: 1347 * nothing 1348 */ 1349 1350 static void 1351 sbmac_channel_stop(struct sbmac_softc *s) 1352 { 1353 uint64_t ctl; 1354 1355 /* don't do this if already stopped */ 1356 1357 if (s->sbm_state == sbmac_state_off) 1358 return; 1359 1360 /* don't accept any packets, disable all interrupts */ 1361 1362 SBMAC_WRITECSR(s->sbm_rxfilter, 0); 1363 SBMAC_WRITECSR(s->sbm_imr, 0); 1364 1365 /* Turn off ticker */ 1366 1367 callout_stop(&(s->sc_tick_ch)); 1368 1369 /* turn off receiver and transmitter */ 1370 1371 ctl = SBMAC_READCSR(s->sbm_macenable); 1372 ctl &= ~(M_MAC_RXDMA_EN0 | M_MAC_TXDMA_EN0); 1373 SBMAC_WRITECSR(s->sbm_macenable, ctl); 1374 1375 /* We're stopped now. */ 1376 1377 s->sbm_state = sbmac_state_off; 1378 s->sc_ethercom.ec_if.if_flags &= ~IFF_RUNNING; 1379 1380 /* Empty the receive and transmit rings */ 1381 1382 sbdma_emptyring(&(s->sbm_rxdma)); 1383 sbdma_emptyring(&(s->sbm_txdma)); 1384 } 1385 1386 /* 1387 * SBMAC_SET_CHANNEL_STATE(state) 1388 * 1389 * Set the channel's state ON or OFF 1390 * 1391 * Input parameters: 1392 * state - new state 1393 * 1394 * Return value: 1395 * old state 1396 */ 1397 1398 static sbmac_state_t 1399 sbmac_set_channel_state(struct sbmac_softc *sc, sbmac_state_t state) 1400 { 1401 sbmac_state_t oldstate = sc->sbm_state; 1402 1403 /* 1404 * If same as previous state, return 1405 */ 1406 1407 if (state == oldstate) 1408 return oldstate; 1409 1410 /* 1411 * If new state is ON, turn channel on 1412 */ 1413 1414 if (state == sbmac_state_on) 1415 sbmac_channel_start(sc); 1416 else 1417 sbmac_channel_stop(sc); 1418 1419 /* 1420 * Return previous state 1421 */ 1422 1423 return oldstate; 1424 } 1425 1426 /* 1427 * SBMAC_PROMISCUOUS_MODE(sc, onoff) 1428 * 1429 * Turn on or off promiscuous mode 1430 * 1431 * Input parameters: 1432 * sc - softc 1433 * onoff - 1 to turn on, 0 to turn off 1434 * 1435 * Return value: 1436 * nothing 1437 */ 1438 1439 static void 1440 sbmac_promiscuous_mode(struct sbmac_softc *sc, int onoff) 1441 { 1442 uint64_t reg; 1443 1444 if (sc->sbm_state != sbmac_state_on) 1445 return; 1446 1447 if (onoff) { 1448 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1449 reg |= M_MAC_ALLPKT_EN; 1450 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1451 } else { 1452 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1453 reg &= ~M_MAC_ALLPKT_EN; 1454 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1455 } 1456 } 1457 1458 /* 1459 * SBMAC_INIT_AND_START(sc) 1460 * 1461 * Stop the channel and restart it. This is generally used 1462 * when we have to do something to the channel that requires 1463 * a swift kick. 1464 * 1465 * Input parameters: 1466 * sc - softc 1467 */ 1468 1469 static void 1470 sbmac_init_and_start(struct sbmac_softc *sc) 1471 { 1472 int s; 1473 1474 s = splnet(); 1475 1476 mii_pollstat(&sc->sc_mii); /* poll phy for current speed */ 1477 sbmac_mii_statchg((struct device *) sc); /* set state to new speed */ 1478 sbmac_set_channel_state(sc, sbmac_state_on); 1479 1480 splx(s); 1481 } 1482 1483 /* 1484 * SBMAC_ADDR2REG(ptr) 1485 * 1486 * Convert six bytes into the 64-bit register value that 1487 * we typically write into the SBMAC's address/mcast registers 1488 * 1489 * Input parameters: 1490 * ptr - pointer to 6 bytes 1491 * 1492 * Return value: 1493 * register value 1494 */ 1495 1496 static uint64_t 1497 sbmac_addr2reg(u_char *ptr) 1498 { 1499 uint64_t reg = 0; 1500 1501 ptr += 6; 1502 1503 reg |= (uint64_t) *(--ptr); 1504 reg <<= 8; 1505 reg |= (uint64_t) *(--ptr); 1506 reg <<= 8; 1507 reg |= (uint64_t) *(--ptr); 1508 reg <<= 8; 1509 reg |= (uint64_t) *(--ptr); 1510 reg <<= 8; 1511 reg |= (uint64_t) *(--ptr); 1512 reg <<= 8; 1513 reg |= (uint64_t) *(--ptr); 1514 1515 return reg; 1516 } 1517 1518 /* 1519 * SBMAC_SET_SPEED(s, speed) 1520 * 1521 * Configure LAN speed for the specified MAC. 1522 * Warning: must be called when MAC is off! 1523 * 1524 * Input parameters: 1525 * s - sbmac structure 1526 * speed - speed to set MAC to (see sbmac_speed_t enum) 1527 * 1528 * Return value: 1529 * 1 if successful 1530 * 0 indicates invalid parameters 1531 */ 1532 1533 static int 1534 sbmac_set_speed(struct sbmac_softc *s, sbmac_speed_t speed) 1535 { 1536 uint64_t cfg; 1537 uint64_t framecfg; 1538 1539 /* 1540 * Save new current values 1541 */ 1542 1543 s->sbm_speed = speed; 1544 1545 if (s->sbm_state != sbmac_state_off) 1546 panic("sbmac_set_speed while MAC not off"); 1547 1548 /* 1549 * Read current register values 1550 */ 1551 1552 cfg = SBMAC_READCSR(s->sbm_maccfg); 1553 framecfg = SBMAC_READCSR(s->sbm_framecfg); 1554 1555 /* 1556 * Mask out the stuff we want to change 1557 */ 1558 1559 cfg &= ~(M_MAC_BURST_EN | M_MAC_SPEED_SEL); 1560 framecfg &= ~(M_MAC_IFG_RX | M_MAC_IFG_TX | M_MAC_IFG_THRSH | 1561 M_MAC_SLOT_SIZE); 1562 1563 /* 1564 * Now add in the new bits 1565 */ 1566 1567 switch (speed) { 1568 case sbmac_speed_10: 1569 framecfg |= V_MAC_IFG_RX_10 | 1570 V_MAC_IFG_TX_10 | 1571 K_MAC_IFG_THRSH_10 | 1572 V_MAC_SLOT_SIZE_10; 1573 cfg |= V_MAC_SPEED_SEL_10MBPS; 1574 break; 1575 1576 case sbmac_speed_100: 1577 framecfg |= V_MAC_IFG_RX_100 | 1578 V_MAC_IFG_TX_100 | 1579 V_MAC_IFG_THRSH_100 | 1580 V_MAC_SLOT_SIZE_100; 1581 cfg |= V_MAC_SPEED_SEL_100MBPS ; 1582 break; 1583 1584 case sbmac_speed_1000: 1585 framecfg |= V_MAC_IFG_RX_1000 | 1586 V_MAC_IFG_TX_1000 | 1587 V_MAC_IFG_THRSH_1000 | 1588 V_MAC_SLOT_SIZE_1000; 1589 cfg |= V_MAC_SPEED_SEL_1000MBPS | M_MAC_BURST_EN; 1590 break; 1591 1592 case sbmac_speed_auto: /* XXX not implemented */ 1593 /* fall through */ 1594 default: 1595 return 0; 1596 } 1597 1598 /* 1599 * Send the bits back to the hardware 1600 */ 1601 1602 SBMAC_WRITECSR(s->sbm_framecfg, framecfg); 1603 SBMAC_WRITECSR(s->sbm_maccfg, cfg); 1604 1605 return 1; 1606 } 1607 1608 /* 1609 * SBMAC_SET_DUPLEX(s, duplex, fc) 1610 * 1611 * Set Ethernet duplex and flow control options for this MAC 1612 * Warning: must be called when MAC is off! 1613 * 1614 * Input parameters: 1615 * s - sbmac structure 1616 * duplex - duplex setting (see sbmac_duplex_t) 1617 * fc - flow control setting (see sbmac_fc_t) 1618 * 1619 * Return value: 1620 * 1 if ok 1621 * 0 if an invalid parameter combination was specified 1622 */ 1623 1624 static int 1625 sbmac_set_duplex(struct sbmac_softc *s, sbmac_duplex_t duplex, sbmac_fc_t fc) 1626 { 1627 uint64_t cfg; 1628 1629 /* 1630 * Save new current values 1631 */ 1632 1633 s->sbm_duplex = duplex; 1634 s->sbm_fc = fc; 1635 1636 if (s->sbm_state != sbmac_state_off) 1637 panic("sbmac_set_duplex while MAC not off"); 1638 1639 /* 1640 * Read current register values 1641 */ 1642 1643 cfg = SBMAC_READCSR(s->sbm_maccfg); 1644 1645 /* 1646 * Mask off the stuff we're about to change 1647 */ 1648 1649 cfg &= ~(M_MAC_FC_SEL | M_MAC_FC_CMD | M_MAC_HDX_EN); 1650 1651 switch (duplex) { 1652 case sbmac_duplex_half: 1653 switch (fc) { 1654 case sbmac_fc_disabled: 1655 cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_DISABLED; 1656 break; 1657 1658 case sbmac_fc_collision: 1659 cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENABLED; 1660 break; 1661 1662 case sbmac_fc_carrier: 1663 cfg |= M_MAC_HDX_EN | V_MAC_FC_CMD_ENAB_FALSECARR; 1664 break; 1665 1666 case sbmac_fc_auto: /* XXX not implemented */ 1667 /* fall through */ 1668 case sbmac_fc_frame: /* not valid in half duplex */ 1669 default: /* invalid selection */ 1670 panic("%s: invalid half duplex fc selection %d", 1671 s->sc_dev.dv_xname, fc); 1672 return 0; 1673 } 1674 break; 1675 1676 case sbmac_duplex_full: 1677 switch (fc) { 1678 case sbmac_fc_disabled: 1679 cfg |= V_MAC_FC_CMD_DISABLED; 1680 break; 1681 1682 case sbmac_fc_frame: 1683 cfg |= V_MAC_FC_CMD_ENABLED; 1684 break; 1685 1686 case sbmac_fc_collision: /* not valid in full duplex */ 1687 case sbmac_fc_carrier: /* not valid in full duplex */ 1688 case sbmac_fc_auto: /* XXX not implemented */ 1689 /* fall through */ 1690 default: 1691 panic("%s: invalid full duplex fc selection %d", 1692 s->sc_dev.dv_xname, fc); 1693 return 0; 1694 } 1695 break; 1696 1697 default: 1698 /* fall through */ 1699 case sbmac_duplex_auto: 1700 panic("%s: bad duplex %d", s->sc_dev.dv_xname, duplex); 1701 /* XXX not implemented */ 1702 break; 1703 } 1704 1705 /* 1706 * Send the bits back to the hardware 1707 */ 1708 1709 SBMAC_WRITECSR(s->sbm_maccfg, cfg); 1710 1711 return 1; 1712 } 1713 1714 /* 1715 * SBMAC_INTR() 1716 * 1717 * Interrupt handler for MAC interrupts 1718 * 1719 * Input parameters: 1720 * MAC structure 1721 * 1722 * Return value: 1723 * nothing 1724 */ 1725 1726 /* ARGSUSED */ 1727 static void 1728 sbmac_intr(void *xsc, uint32_t status, vaddr_t pc) 1729 { 1730 struct sbmac_softc *sc = (struct sbmac_softc *) xsc; 1731 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1732 uint64_t isr; 1733 1734 for (;;) { 1735 1736 /* 1737 * Read the ISR (this clears the bits in the real register) 1738 */ 1739 1740 isr = SBMAC_READCSR(sc->sbm_isr); 1741 1742 if (isr == 0) 1743 break; 1744 1745 /* 1746 * Transmits on channel 0 1747 */ 1748 1749 if (isr & (M_MAC_INT_CHANNEL << S_MAC_TX_CH0)) { 1750 sbdma_tx_process(sc, &(sc->sbm_txdma)); 1751 SBMAC_EVCNT_INCR(sc->sbm_ev_txintr); 1752 } 1753 1754 /* 1755 * Receives on channel 0 1756 */ 1757 1758 if (isr & (M_MAC_INT_CHANNEL << S_MAC_RX_CH0)) { 1759 sbdma_rx_process(sc, &(sc->sbm_rxdma)); 1760 SBMAC_EVCNT_INCR(sc->sbm_ev_rxintr); 1761 } 1762 } 1763 1764 /* try to get more packets going */ 1765 sbmac_start(ifp); 1766 } 1767 1768 1769 /* 1770 * SBMAC_START(ifp) 1771 * 1772 * Start output on the specified interface. Basically, we 1773 * queue as many buffers as we can until the ring fills up, or 1774 * we run off the end of the queue, whichever comes first. 1775 * 1776 * Input parameters: 1777 * ifp - interface 1778 * 1779 * Return value: 1780 * nothing 1781 */ 1782 1783 static void 1784 sbmac_start(struct ifnet *ifp) 1785 { 1786 struct sbmac_softc *sc; 1787 struct mbuf *m_head = NULL; 1788 int rv; 1789 1790 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 1791 return; 1792 1793 sc = ifp->if_softc; 1794 1795 for (;;) { 1796 1797 IF_DEQUEUE(&ifp->if_snd, m_head); 1798 if (m_head == NULL) 1799 break; 1800 1801 /* 1802 * Put the buffer on the transmit ring. If we 1803 * don't have room, set the OACTIVE flag and wait 1804 * for the NIC to drain the ring. 1805 */ 1806 1807 rv = sbdma_add_txbuffer(&(sc->sbm_txdma), m_head); 1808 1809 if (rv == 0) { 1810 /* 1811 * If there's a BPF listener, bounce a copy of this 1812 * frame to it. 1813 */ 1814 bpf_mtap(ifp, m_head); 1815 if (!sc->sbm_pass3_dma) { 1816 /* 1817 * Don't free mbuf if we're not copying to new 1818 * mbuf in sbdma_add_txbuffer. It will be 1819 * freed in sbdma_tx_process. 1820 */ 1821 m_freem(m_head); 1822 } 1823 } else { 1824 IF_PREPEND(&ifp->if_snd, m_head); 1825 ifp->if_flags |= IFF_OACTIVE; 1826 break; 1827 } 1828 } 1829 } 1830 1831 /* 1832 * SBMAC_SETMULTI(sc) 1833 * 1834 * Reprogram the multicast table into the hardware, given 1835 * the list of multicasts associated with the interface 1836 * structure. 1837 * 1838 * Input parameters: 1839 * sc - softc 1840 * 1841 * Return value: 1842 * nothing 1843 */ 1844 1845 static void 1846 sbmac_setmulti(struct sbmac_softc *sc) 1847 { 1848 struct ifnet *ifp; 1849 uint64_t reg; 1850 sbmac_port_t port; 1851 int idx; 1852 struct ether_multi *enm; 1853 struct ether_multistep step; 1854 1855 ifp = &sc->sc_ethercom.ec_if; 1856 1857 /* 1858 * Clear out entire multicast table. We do this by nuking 1859 * the entire hash table and all the direct matches except 1860 * the first one, which is used for our station address 1861 */ 1862 1863 for (idx = 1; idx < MAC_ADDR_COUNT; idx++) { 1864 port = PKSEG1(sc->sbm_base + 1865 R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); 1866 SBMAC_WRITECSR(port, 0); 1867 } 1868 1869 for (idx = 0; idx < MAC_HASH_COUNT; idx++) { 1870 port = PKSEG1(sc->sbm_base + 1871 R_MAC_HASH_BASE+(idx*sizeof(uint64_t))); 1872 SBMAC_WRITECSR(port, 0); 1873 } 1874 1875 /* 1876 * Clear the filter to say we don't want any multicasts. 1877 */ 1878 1879 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1880 reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN); 1881 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1882 1883 if (ifp->if_flags & IFF_ALLMULTI) { 1884 /* 1885 * Enable ALL multicasts. Do this by inverting the 1886 * multicast enable bit. 1887 */ 1888 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1889 reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN); 1890 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1891 return; 1892 } 1893 1894 /* 1895 * Progam new multicast entries. For now, only use the 1896 * perfect filter. In the future we'll need to use the 1897 * hash filter if the perfect filter overflows 1898 */ 1899 1900 /* 1901 * XXX only using perfect filter for now, need to use hash 1902 * XXX if the table overflows 1903 */ 1904 1905 idx = 1; /* skip station address */ 1906 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 1907 while ((enm != NULL) && (idx < MAC_ADDR_COUNT)) { 1908 reg = sbmac_addr2reg(enm->enm_addrlo); 1909 port = PKSEG1(sc->sbm_base + 1910 R_MAC_ADDR_BASE+(idx*sizeof(uint64_t))); 1911 SBMAC_WRITECSR(port, reg); 1912 idx++; 1913 ETHER_NEXT_MULTI(step, enm); 1914 } 1915 1916 /* 1917 * Enable the "accept multicast bits" if we programmed at least one 1918 * multicast. 1919 */ 1920 1921 if (idx > 1) { 1922 reg = SBMAC_READCSR(sc->sbm_rxfilter); 1923 reg |= M_MAC_MCAST_EN; 1924 SBMAC_WRITECSR(sc->sbm_rxfilter, reg); 1925 } 1926 } 1927 1928 /* 1929 * SBMAC_ETHER_IOCTL(ifp, cmd, data) 1930 * 1931 * Generic IOCTL requests for this interface. The basic 1932 * stuff is handled here for bringing the interface up, 1933 * handling multicasts, etc. 1934 * 1935 * Input parameters: 1936 * ifp - interface structure 1937 * cmd - command code 1938 * data - pointer to data 1939 * 1940 * Return value: 1941 * return value (0 is success) 1942 */ 1943 1944 static int 1945 sbmac_ether_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1946 { 1947 struct ifaddr *ifa = (struct ifaddr *) data; 1948 struct sbmac_softc *sc = ifp->if_softc; 1949 1950 switch (cmd) { 1951 case SIOCINITIFADDR: 1952 ifp->if_flags |= IFF_UP; 1953 1954 switch (ifa->ifa_addr->sa_family) { 1955 #ifdef INET 1956 case AF_INET: 1957 sbmac_init_and_start(sc); 1958 arp_ifinit(ifp, ifa); 1959 break; 1960 #endif 1961 #ifdef NS 1962 case AF_NS: 1963 { 1964 struct ns_addr *ina = &IA_SNS(ifa)->sns_addr; 1965 1966 if (ns_nullhost(*ina)) 1967 ina->x_host = 1968 *(union ns_host *)LLADDR(ifp->if_sadl); 1969 else 1970 memcpy(LLADDR(ifp->if_sadl), ina->x_host.c_host, 1971 ifp->if_addrlen); 1972 /* Set new address. */ 1973 sbmac_init_and_start(sc); 1974 break; 1975 } 1976 #endif 1977 default: 1978 sbmac_init_and_start(sc); 1979 break; 1980 } 1981 break; 1982 1983 default: 1984 return ENOTTY; 1985 } 1986 1987 return (0); 1988 } 1989 1990 /* 1991 * SBMAC_IOCTL(ifp, cmd, data) 1992 * 1993 * Main IOCTL handler - dispatches to other IOCTLs for various 1994 * types of requests. 1995 * 1996 * Input parameters: 1997 * ifp - interface pointer 1998 * cmd - command code 1999 * data - pointer to argument data 2000 * 2001 * Return value: 2002 * 0 if ok 2003 * else error code 2004 */ 2005 2006 static int 2007 sbmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 2008 { 2009 struct sbmac_softc *sc = ifp->if_softc; 2010 struct ifreq *ifr = (struct ifreq *) data; 2011 int s, error = 0; 2012 2013 s = splnet(); 2014 2015 switch (cmd) { 2016 case SIOCINITIFADDR: 2017 error = sbmac_ether_ioctl(ifp, cmd, data); 2018 break; 2019 case SIOCSIFMTU: 2020 if (ifr->ifr_mtu < ETHERMIN || ifr->ifr_mtu > ETHERMTU) 2021 error = EINVAL; 2022 else if ((error = ifioctl_common(ifp, cmd, data)) == ENETRESET) 2023 /* XXX Program new MTU here */ 2024 error = 0; 2025 break; 2026 case SIOCSIFFLAGS: 2027 if ((error = ifioctl_common(ifp, cmd, data)) != 0) 2028 break; 2029 if (ifp->if_flags & IFF_UP) { 2030 /* 2031 * If only the state of the PROMISC flag changed, 2032 * just tweak the hardware registers. 2033 */ 2034 if ((ifp->if_flags & IFF_RUNNING) && 2035 (ifp->if_flags & IFF_PROMISC)) { 2036 /* turn on promiscuous mode */ 2037 sbmac_promiscuous_mode(sc, 1); 2038 } else if (ifp->if_flags & IFF_RUNNING && 2039 !(ifp->if_flags & IFF_PROMISC)) { 2040 /* turn off promiscuous mode */ 2041 sbmac_promiscuous_mode(sc, 0); 2042 } else 2043 sbmac_set_channel_state(sc, sbmac_state_on); 2044 } else { 2045 if (ifp->if_flags & IFF_RUNNING) 2046 sbmac_set_channel_state(sc, sbmac_state_off); 2047 } 2048 2049 sc->sbm_if_flags = ifp->if_flags; 2050 error = 0; 2051 break; 2052 2053 case SIOCADDMULTI: 2054 case SIOCDELMULTI: 2055 case SIOCSIFMEDIA: 2056 case SIOCGIFMEDIA: 2057 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 2058 error = 0; 2059 if (ifp->if_flags & IFF_RUNNING) 2060 sbmac_setmulti(sc); 2061 } 2062 break; 2063 default: 2064 error = ether_ioctl(ifp, cmd, data); 2065 break; 2066 } 2067 2068 (void)splx(s); 2069 2070 return(error); 2071 } 2072 2073 /* 2074 * SBMAC_IFMEDIA_UPD(ifp) 2075 * 2076 * Configure an appropriate media type for this interface, 2077 * given the data in the interface structure 2078 * 2079 * Input parameters: 2080 * ifp - interface 2081 * 2082 * Return value: 2083 * 0 if ok 2084 * else error code 2085 */ 2086 2087 /* 2088 * SBMAC_IFMEDIA_STS(ifp, ifmr) 2089 * 2090 * Report current media status (used by ifconfig, for example) 2091 * 2092 * Input parameters: 2093 * ifp - interface structure 2094 * ifmr - media request structure 2095 * 2096 * Return value: 2097 * nothing 2098 */ 2099 2100 /* 2101 * SBMAC_WATCHDOG(ifp) 2102 * 2103 * Called periodically to make sure we're still happy. 2104 * 2105 * Input parameters: 2106 * ifp - interface structure 2107 * 2108 * Return value: 2109 * nothing 2110 */ 2111 2112 static void 2113 sbmac_watchdog(struct ifnet *ifp) 2114 { 2115 2116 /* XXX do something */ 2117 } 2118 2119 /* 2120 * One second timer, used to tick MII. 2121 */ 2122 static void 2123 sbmac_tick(void *arg) 2124 { 2125 struct sbmac_softc *sc = arg; 2126 int s; 2127 2128 s = splnet(); 2129 mii_tick(&sc->sc_mii); 2130 splx(s); 2131 2132 callout_reset(&sc->sc_tick_ch, hz, sbmac_tick, sc); 2133 } 2134 2135 2136 /* 2137 * SBMAC_MATCH(parent, match, aux) 2138 * 2139 * Part of the config process - see if this device matches the 2140 * info about what we expect to find on the bus. 2141 * 2142 * Input parameters: 2143 * parent - parent bus structure 2144 * match - 2145 * aux - bus-specific args 2146 * 2147 * Return value: 2148 * 1 if we match 2149 * 0 if we don't match 2150 */ 2151 2152 static int 2153 sbmac_match(struct device *parent, struct cfdata *match, void *aux) 2154 { 2155 struct sbobio_attach_args *sap = aux; 2156 2157 /* 2158 * Make sure it's a MAC 2159 */ 2160 2161 if (sap->sa_locs.sa_type != SBOBIO_DEVTYPE_MAC) 2162 return 0; 2163 2164 /* 2165 * Yup, it is. 2166 */ 2167 2168 return 1; 2169 } 2170 2171 /* 2172 * SBMAC_PARSE_XDIGIT(str) 2173 * 2174 * Parse a hex digit, returning its value 2175 * 2176 * Input parameters: 2177 * str - character 2178 * 2179 * Return value: 2180 * hex value, or -1 if invalid 2181 */ 2182 2183 static int 2184 sbmac_parse_xdigit(char str) 2185 { 2186 int digit; 2187 2188 if ((str >= '0') && (str <= '9')) 2189 digit = str - '0'; 2190 else if ((str >= 'a') && (str <= 'f')) 2191 digit = str - 'a' + 10; 2192 else if ((str >= 'A') && (str <= 'F')) 2193 digit = str - 'A' + 10; 2194 else 2195 digit = -1; 2196 2197 return digit; 2198 } 2199 2200 /* 2201 * SBMAC_PARSE_HWADDR(str, hwaddr) 2202 * 2203 * Convert a string in the form xx:xx:xx:xx:xx:xx into a 6-byte 2204 * Ethernet address. 2205 * 2206 * Input parameters: 2207 * str - string 2208 * hwaddr - pointer to hardware address 2209 * 2210 * Return value: 2211 * 0 if ok, else -1 2212 */ 2213 2214 static int 2215 sbmac_parse_hwaddr(const char *str, u_char *hwaddr) 2216 { 2217 int digit1, digit2; 2218 int idx = 6; 2219 2220 while (*str && (idx > 0)) { 2221 digit1 = sbmac_parse_xdigit(*str); 2222 if (digit1 < 0) 2223 return -1; 2224 str++; 2225 if (!*str) 2226 return -1; 2227 2228 if ((*str == ':') || (*str == '-')) { 2229 digit2 = digit1; 2230 digit1 = 0; 2231 } else { 2232 digit2 = sbmac_parse_xdigit(*str); 2233 if (digit2 < 0) 2234 return -1; 2235 str++; 2236 } 2237 2238 *hwaddr++ = (digit1 << 4) | digit2; 2239 idx--; 2240 2241 if (*str == '-') 2242 str++; 2243 if (*str == ':') 2244 str++; 2245 } 2246 return 0; 2247 } 2248 2249 /* 2250 * SBMAC_ATTACH(parent, self, aux) 2251 * 2252 * Attach routine - init hardware and hook ourselves into NetBSD. 2253 * 2254 * Input parameters: 2255 * parent - parent bus device 2256 * self - our softc 2257 * aux - attach data 2258 * 2259 * Return value: 2260 * nothing 2261 */ 2262 2263 static void 2264 sbmac_attach(struct device *parent, struct device *self, void *aux) 2265 { 2266 struct ifnet *ifp; 2267 struct sbmac_softc *sc; 2268 struct sbobio_attach_args *sap = aux; 2269 u_char *eaddr; 2270 static int unit = 0; /* XXX */ 2271 uint64_t ea_reg; 2272 int idx; 2273 2274 sc = (struct sbmac_softc *)self; 2275 2276 /* Determine controller base address */ 2277 2278 sc->sbm_base = sap->sa_locs.sa_addr; 2279 2280 eaddr = sc->sbm_hwaddr; 2281 2282 /* 2283 * Initialize context (get pointers to registers and stuff), then 2284 * allocate the memory for the descriptor tables. 2285 */ 2286 2287 sbmac_initctx(sc); 2288 2289 callout_init(&(sc->sc_tick_ch), 0); 2290 2291 /* 2292 * Read the ethernet address. The firwmare left this programmed 2293 * for us in the ethernet address register for each mac. 2294 */ 2295 2296 ea_reg = SBMAC_READCSR(PKSEG1(sc->sbm_base + R_MAC_ETHERNET_ADDR)); 2297 for (idx = 0; idx < 6; idx++) { 2298 eaddr[idx] = (uint8_t) (ea_reg & 0xFF); 2299 ea_reg >>= 8; 2300 } 2301 2302 #define SBMAC_DEFAULT_HWADDR "40:00:00:00:01:00" 2303 if (eaddr[0] == 0 && eaddr[1] == 0 && eaddr[2] == 0 && 2304 eaddr[3] == 0 && eaddr[4] == 0 && eaddr[5] == 0) { 2305 sbmac_parse_hwaddr(SBMAC_DEFAULT_HWADDR, eaddr); 2306 eaddr[5] = unit; 2307 } 2308 2309 #ifdef SBMAC_ETH0_HWADDR 2310 if (unit == 0) 2311 sbmac_parse_hwaddr(SBMAC_ETH0_HWADDR, eaddr); 2312 #endif 2313 #ifdef SBMAC_ETH1_HWADDR 2314 if (unit == 1) 2315 sbmac_parse_hwaddr(SBMAC_ETH1_HWADDR, eaddr); 2316 #endif 2317 #ifdef SBMAC_ETH2_HWADDR 2318 if (unit == 2) 2319 sbmac_parse_hwaddr(SBMAC_ETH2_HWADDR, eaddr); 2320 #endif 2321 unit++; 2322 2323 /* 2324 * Display Ethernet address (this is called during the config process 2325 * so we need to finish off the config message that was being displayed) 2326 */ 2327 printf(": Ethernet%s\n", 2328 sc->sbm_pass3_dma ? ", using unaligned tx DMA" : ""); 2329 printf("%s: Ethernet address: %s\n", self->dv_xname, 2330 ether_sprintf(eaddr)); 2331 2332 2333 /* 2334 * Set up ifnet structure 2335 */ 2336 2337 ifp = &sc->sc_ethercom.ec_if; 2338 ifp->if_softc = sc; 2339 memcpy(ifp->if_xname, sc->sc_dev.dv_xname, IFNAMSIZ); 2340 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST | 2341 IFF_NOTRAILERS; 2342 ifp->if_ioctl = sbmac_ioctl; 2343 ifp->if_start = sbmac_start; 2344 ifp->if_watchdog = sbmac_watchdog; 2345 ifp->if_snd.ifq_maxlen = SBMAC_MAX_TXDESCR - 1; 2346 2347 /* 2348 * Set up ifmedia support. 2349 */ 2350 2351 /* 2352 * Initialize MII/media info. 2353 */ 2354 sc->sc_mii.mii_ifp = ifp; 2355 sc->sc_mii.mii_readreg = sbmac_mii_readreg; 2356 sc->sc_mii.mii_writereg = sbmac_mii_writereg; 2357 sc->sc_mii.mii_statchg = sbmac_mii_statchg; 2358 sc->sc_ethercom.ec_mii = &sc->sc_mii; 2359 ifmedia_init(&sc->sc_mii.mii_media, 0, ether_mediachange, 2360 ether_mediastatus); 2361 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 2362 MII_OFFSET_ANY, 0); 2363 2364 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 2365 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); 2366 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); 2367 } else { 2368 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 2369 } 2370 2371 2372 /* 2373 * map/route interrupt 2374 */ 2375 2376 sc->sbm_intrhand = cpu_intr_establish(sap->sa_locs.sa_intr[0], IPL_NET, 2377 sbmac_intr, sc); 2378 2379 /* 2380 * Call MI attach routines. 2381 */ 2382 if_attach(ifp); 2383 ether_ifattach(ifp, eaddr); 2384 } 2385