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