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