1 /* $NetBSD: ixp425_if_npe.c,v 1.19 2010/04/05 07:19:29 joerg Exp $ */ 2 3 /*- 4 * Copyright (c) 2006 Sam Leffler. All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 #if 0 29 __FBSDID("$FreeBSD: src/sys/arm/xscale/ixp425/if_npe.c,v 1.1 2006/11/19 23:55:23 sam Exp $"); 30 #endif 31 __KERNEL_RCSID(0, "$NetBSD: ixp425_if_npe.c,v 1.19 2010/04/05 07:19:29 joerg Exp $"); 32 33 /* 34 * Intel XScale NPE Ethernet driver. 35 * 36 * This driver handles the two ports present on the IXP425. 37 * Packet processing is done by the Network Processing Engines 38 * (NPE's) that work together with a MAC and PHY. The MAC 39 * is also mapped to the XScale cpu; the PHY is accessed via 40 * the MAC. NPE-XScale communication happens through h/w 41 * queues managed by the Q Manager block. 42 * 43 * The code here replaces the ethAcc, ethMii, and ethDB classes 44 * in the Intel Access Library (IAL) and the OS-specific driver. 45 * 46 * XXX add vlan support 47 * XXX NPE-C port doesn't work yet 48 */ 49 50 #include "rnd.h" 51 52 #include <sys/param.h> 53 #include <sys/systm.h> 54 #include <sys/kernel.h> 55 #include <sys/device.h> 56 #include <sys/callout.h> 57 #include <sys/mbuf.h> 58 #include <sys/malloc.h> 59 #include <sys/socket.h> 60 #include <sys/endian.h> 61 #include <sys/ioctl.h> 62 #include <sys/syslog.h> 63 64 #include <machine/bus.h> 65 66 #include <net/if.h> 67 #include <net/if_dl.h> 68 #include <net/if_media.h> 69 #include <net/if_ether.h> 70 71 #include <net/bpf.h> 72 73 #if NRND > 0 74 #include <sys/rnd.h> 75 #endif 76 77 #include <arm/xscale/ixp425reg.h> 78 #include <arm/xscale/ixp425var.h> 79 #include <arm/xscale/ixp425_qmgr.h> 80 #include <arm/xscale/ixp425_npevar.h> 81 #include <arm/xscale/ixp425_if_npereg.h> 82 83 #include <dev/mii/miivar.h> 84 85 #include "locators.h" 86 87 struct npebuf { 88 struct npebuf *ix_next; /* chain to next buffer */ 89 void *ix_m; /* backpointer to mbuf */ 90 bus_dmamap_t ix_map; /* bus dma map for associated data */ 91 struct npehwbuf *ix_hw; /* associated h/w block */ 92 uint32_t ix_neaddr; /* phys address of ix_hw */ 93 }; 94 95 struct npedma { 96 const char* name; 97 int nbuf; /* # npebuf's allocated */ 98 bus_dmamap_t m_map; 99 struct npehwbuf *hwbuf; /* NPE h/w buffers */ 100 bus_dmamap_t buf_map; 101 bus_addr_t buf_phys; /* phys addr of buffers */ 102 struct npebuf *buf; /* s/w buffers (1-1 w/ h/w) */ 103 }; 104 105 struct npe_softc { 106 struct device sc_dev; 107 struct ethercom sc_ethercom; 108 uint8_t sc_enaddr[ETHER_ADDR_LEN]; 109 struct mii_data sc_mii; 110 bus_space_tag_t sc_iot; 111 bus_dma_tag_t sc_dt; 112 bus_space_handle_t sc_ioh; /* MAC register window */ 113 bus_space_handle_t sc_miih; /* MII register window */ 114 struct ixpnpe_softc *sc_npe; /* NPE support */ 115 int sc_unit; 116 int sc_phy; 117 struct callout sc_tick_ch; /* Tick callout */ 118 struct npedma txdma; 119 struct npebuf *tx_free; /* list of free tx buffers */ 120 struct npedma rxdma; 121 int rx_qid; /* rx qid */ 122 int rx_freeqid; /* rx free buffers qid */ 123 int tx_qid; /* tx qid */ 124 int tx_doneqid; /* tx completed qid */ 125 struct npestats *sc_stats; 126 bus_dmamap_t sc_stats_map; 127 bus_addr_t sc_stats_phys; /* phys addr of sc_stats */ 128 int sc_if_flags; /* keep last if_flags */ 129 #if NRND > 0 130 rndsource_element_t rnd_source; /* random source */ 131 #endif 132 }; 133 134 /* 135 * Per-unit static configuration for IXP425. The tx and 136 * rx free Q id's are fixed by the NPE microcode. The 137 * rx Q id's are programmed to be separate to simplify 138 * multi-port processing. It may be better to handle 139 * all traffic through one Q (as done by the Intel drivers). 140 * 141 * Note that the PHY's are accessible only from MAC A 142 * on the IXP425. This and other platform-specific 143 * assumptions probably need to be handled through hints. 144 */ 145 static const struct { 146 const char *desc; /* device description */ 147 int npeid; /* NPE assignment */ 148 int macport; /* Port number of the MAC */ 149 uint32_t imageid; /* NPE firmware image id */ 150 uint32_t regbase; 151 int regsize; 152 uint32_t miibase; 153 int miisize; 154 uint8_t rx_qid; 155 uint8_t rx_freeqid; 156 uint8_t tx_qid; 157 uint8_t tx_doneqid; 158 } npeconfig[NPE_PORTS_MAX] = { 159 { .desc = "IXP NPE-B", 160 .npeid = NPE_B, 161 .macport = 0x10, 162 .imageid = IXP425_NPE_B_IMAGEID, 163 .regbase = IXP425_MAC_A_HWBASE, 164 .regsize = IXP425_MAC_A_SIZE, 165 .miibase = IXP425_MAC_A_HWBASE, 166 .miisize = IXP425_MAC_A_SIZE, 167 .rx_qid = 4, 168 .rx_freeqid = 27, 169 .tx_qid = 24, 170 .tx_doneqid = 31 171 }, 172 { .desc = "IXP NPE-C", 173 .npeid = NPE_C, 174 .macport = 0x20, 175 .imageid = IXP425_NPE_C_IMAGEID, 176 .regbase = IXP425_MAC_B_HWBASE, 177 .regsize = IXP425_MAC_B_SIZE, 178 .miibase = IXP425_MAC_A_HWBASE, 179 .miisize = IXP425_MAC_A_SIZE, 180 .rx_qid = 12, 181 .rx_freeqid = 28, 182 .tx_qid = 25, 183 .tx_doneqid = 31 184 }, 185 }; 186 static struct npe_softc *npes[NPE_MAX]; /* NB: indexed by npeid */ 187 188 static __inline uint32_t 189 RD4(struct npe_softc *sc, bus_size_t off) 190 { 191 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, off); 192 } 193 194 static __inline void 195 WR4(struct npe_softc *sc, bus_size_t off, uint32_t val) 196 { 197 bus_space_write_4(sc->sc_iot, sc->sc_ioh, off, val); 198 } 199 200 static int npe_activate(struct npe_softc *); 201 #if 0 202 static void npe_deactivate(struct npe_softc *); 203 #endif 204 static void npe_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr); 205 static void npe_setmac(struct npe_softc *sc, const u_char *eaddr); 206 static void npe_getmac(struct npe_softc *sc); 207 static void npe_txdone(int qid, void *arg); 208 static int npe_rxbuf_init(struct npe_softc *, struct npebuf *, 209 struct mbuf *); 210 static void npe_rxdone(int qid, void *arg); 211 static void npeinit_macreg(struct npe_softc *); 212 static int npeinit(struct ifnet *); 213 static void npeinit_resetcb(void *); 214 static void npeinit_locked(void *); 215 static void npestart(struct ifnet *); 216 static void npestop(struct ifnet *, int); 217 static void npewatchdog(struct ifnet *); 218 static int npeioctl(struct ifnet * ifp, u_long, void *); 219 220 static int npe_setrxqosentry(struct npe_softc *, int classix, 221 int trafclass, int qid); 222 static int npe_updatestats(struct npe_softc *); 223 #if 0 224 static int npe_getstats(struct npe_softc *); 225 static uint32_t npe_getimageid(struct npe_softc *); 226 static int npe_setloopback(struct npe_softc *, int ena); 227 #endif 228 229 static int npe_miibus_readreg(struct device *, int, int); 230 static void npe_miibus_writereg(struct device *, int, int, int); 231 static void npe_miibus_statchg(struct device *); 232 233 static int npe_debug; 234 #define DPRINTF(sc, fmt, ...) do { \ 235 if (npe_debug) printf(fmt, __VA_ARGS__); \ 236 } while (0) 237 #define DPRINTFn(n, sc, fmt, ...) do { \ 238 if (npe_debug >= n) printf(fmt, __VA_ARGS__); \ 239 } while (0) 240 241 #define NPE_TXBUF 128 242 #define NPE_RXBUF 64 243 244 #ifndef ETHER_ALIGN 245 #define ETHER_ALIGN 2 /* XXX: Ditch this */ 246 #endif 247 248 #define MAC2UINT64(addr) (((uint64_t)addr[0] << 40) \ 249 + ((uint64_t)addr[1] << 32) \ 250 + ((uint64_t)addr[2] << 24) \ 251 + ((uint64_t)addr[3] << 16) \ 252 + ((uint64_t)addr[4] << 8) \ 253 + (uint64_t)addr[5]) 254 255 /* NB: all tx done processing goes through one queue */ 256 static int tx_doneqid = -1; 257 258 void (*npe_getmac_md)(int, uint8_t *); 259 260 static int npe_match(struct device *, struct cfdata *, void *); 261 static void npe_attach(struct device *, struct device *, void *); 262 263 CFATTACH_DECL(npe, sizeof(struct npe_softc), 264 npe_match, npe_attach, NULL, NULL); 265 266 static int 267 npe_match(struct device *parent, struct cfdata *cf, void *arg) 268 { 269 struct ixpnpe_attach_args *na = arg; 270 271 return (na->na_unit == NPE_B || na->na_unit == NPE_C); 272 } 273 274 static void 275 npe_attach(struct device *parent, struct device *self, void *arg) 276 { 277 struct npe_softc *sc = (void *)self; 278 struct ixpnpe_attach_args *na = arg; 279 struct ixpnpe_softc *isc = (struct ixpnpe_softc *)parent; 280 struct ifnet *ifp; 281 282 aprint_naive("\n"); 283 aprint_normal(": Ethernet co-processor\n"); 284 285 sc->sc_iot = na->na_iot; 286 sc->sc_dt = na->na_dt; 287 sc->sc_npe = na->na_npe; 288 sc->sc_unit = (na->na_unit == NPE_B) ? 0 : 1; 289 sc->sc_phy = na->na_phy; 290 291 memset(&sc->sc_ethercom, 0, sizeof(sc->sc_ethercom)); 292 memset(&sc->sc_mii, 0, sizeof(sc->sc_mii)); 293 294 callout_init(&sc->sc_tick_ch, 0); 295 296 if (npe_activate(sc)) { 297 aprint_error("%s: Failed to activate NPE (missing " 298 "microcode?)\n", sc->sc_dev.dv_xname); 299 return; 300 } 301 302 npe_getmac(sc); 303 npeinit_macreg(sc); 304 305 aprint_normal("%s: Ethernet address %s\n", sc->sc_dev.dv_xname, 306 ether_sprintf(sc->sc_enaddr)); 307 308 ifp = &sc->sc_ethercom.ec_if; 309 sc->sc_mii.mii_ifp = ifp; 310 sc->sc_mii.mii_readreg = npe_miibus_readreg; 311 sc->sc_mii.mii_writereg = npe_miibus_writereg; 312 sc->sc_mii.mii_statchg = npe_miibus_statchg; 313 sc->sc_ethercom.ec_mii = &sc->sc_mii; 314 315 ifmedia_init(&sc->sc_mii.mii_media, IFM_IMASK, ether_mediachange, 316 npe_ifmedia_status); 317 318 mii_attach(&sc->sc_dev, &sc->sc_mii, 0xffffffff, MII_PHY_ANY, 319 MII_OFFSET_ANY, MIIF_DOPAUSE); 320 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 321 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE, 0, NULL); 322 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_NONE); 323 } else 324 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 325 326 ifp->if_softc = sc; 327 strcpy(ifp->if_xname, sc->sc_dev.dv_xname); 328 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 329 ifp->if_start = npestart; 330 ifp->if_ioctl = npeioctl; 331 ifp->if_watchdog = npewatchdog; 332 ifp->if_init = npeinit; 333 ifp->if_stop = npestop; 334 IFQ_SET_READY(&ifp->if_snd); 335 336 /* VLAN capable */ 337 sc->sc_ethercom.ec_capabilities |= ETHERCAP_VLAN_MTU; 338 339 if_attach(ifp); 340 ether_ifattach(ifp, sc->sc_enaddr); 341 #if NRND > 0 342 rnd_attach_source(&sc->rnd_source, sc->sc_dev.dv_xname, 343 RND_TYPE_NET, 0); 344 #endif 345 346 /* callback function to reset MAC */ 347 isc->macresetcbfunc = npeinit_resetcb; 348 isc->macresetcbarg = sc; 349 } 350 351 /* 352 * Compute and install the multicast filter. 353 */ 354 static void 355 npe_setmcast(struct npe_softc *sc) 356 { 357 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 358 uint8_t mask[ETHER_ADDR_LEN], addr[ETHER_ADDR_LEN]; 359 uint32_t reg; 360 uint32_t msg[2]; 361 int i; 362 363 /* Always use filter. Is here a correct position? */ 364 reg = RD4(sc, NPE_MAC_RX_CNTRL1); 365 WR4(sc, NPE_MAC_RX_CNTRL1, reg | NPE_RX_CNTRL1_ADDR_FLTR_EN); 366 367 if (ifp->if_flags & IFF_PROMISC) { 368 memset(mask, 0, ETHER_ADDR_LEN); 369 memset(addr, 0, ETHER_ADDR_LEN); 370 } else if (ifp->if_flags & IFF_ALLMULTI) { 371 static const uint8_t allmulti[ETHER_ADDR_LEN] = 372 { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00 }; 373 all_multi: 374 memcpy(mask, allmulti, ETHER_ADDR_LEN); 375 memcpy(addr, allmulti, ETHER_ADDR_LEN); 376 } else { 377 uint8_t clr[ETHER_ADDR_LEN], set[ETHER_ADDR_LEN]; 378 struct ether_multistep step; 379 struct ether_multi *enm; 380 381 memset(clr, 0, ETHER_ADDR_LEN); 382 memset(set, 0xff, ETHER_ADDR_LEN); 383 384 ETHER_FIRST_MULTI(step, &sc->sc_ethercom, enm); 385 while (enm != NULL) { 386 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, ETHER_ADDR_LEN)) { 387 ifp->if_flags |= IFF_ALLMULTI; 388 goto all_multi; 389 } 390 391 for (i = 0; i < ETHER_ADDR_LEN; i++) { 392 clr[i] |= enm->enm_addrlo[i]; 393 set[i] &= enm->enm_addrlo[i]; 394 } 395 396 ETHER_NEXT_MULTI(step, enm); 397 } 398 399 for (i = 0; i < ETHER_ADDR_LEN; i++) { 400 mask[i] = set[i] | ~clr[i]; 401 addr[i] = set[i]; 402 } 403 } 404 405 /* 406 * Write the mask and address registers. 407 */ 408 for (i = 0; i < ETHER_ADDR_LEN; i++) { 409 WR4(sc, NPE_MAC_ADDR_MASK(i), mask[i]); 410 WR4(sc, NPE_MAC_ADDR(i), addr[i]); 411 } 412 413 msg[0] = NPE_ADDRESSFILTERCONFIG << NPE_MAC_MSGID_SHL 414 | (npeconfig[sc->sc_unit].macport << NPE_MAC_PORTID_SHL); 415 msg[1] = ((ifp->if_flags & IFF_PROMISC) ? 1 : 0) << 24 416 | ((RD4(sc, NPE_MAC_UNI_ADDR_6) & 0xff) << 16) 417 | (addr[5] << 8) | mask[5]; 418 ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg); 419 } 420 421 static int 422 npe_dma_setup(struct npe_softc *sc, struct npedma *dma, 423 const char *name, int nbuf, int maxseg) 424 { 425 bus_dma_segment_t seg; 426 int rseg, error, i; 427 void *hwbuf; 428 size_t size; 429 430 memset(dma, 0, sizeof(*dma)); 431 432 dma->name = name; 433 dma->nbuf = nbuf; 434 435 size = nbuf * sizeof(struct npehwbuf); 436 437 /* XXX COHERENT for now */ 438 error = bus_dmamem_alloc(sc->sc_dt, size, sizeof(uint32_t), 0, &seg, 439 1, &rseg, BUS_DMA_NOWAIT); 440 if (error) { 441 printf("%s: unable to allocate memory for %s h/w buffers, " 442 "error %u\n", sc->sc_dev.dv_xname, dma->name, error); 443 } 444 445 error = bus_dmamem_map(sc->sc_dt, &seg, 1, size, &hwbuf, 446 BUS_DMA_NOWAIT | BUS_DMA_COHERENT | BUS_DMA_NOCACHE); 447 if (error) { 448 printf("%s: unable to map memory for %s h/w buffers, " 449 "error %u\n", sc->sc_dev.dv_xname, dma->name, error); 450 free_dmamem: 451 bus_dmamem_free(sc->sc_dt, &seg, rseg); 452 return error; 453 } 454 dma->hwbuf = (void *)hwbuf; 455 456 error = bus_dmamap_create(sc->sc_dt, size, 1, size, 0, 457 BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, &dma->buf_map); 458 if (error) { 459 printf("%s: unable to create map for %s h/w buffers, " 460 "error %u\n", sc->sc_dev.dv_xname, dma->name, error); 461 unmap_dmamem: 462 dma->hwbuf = NULL; 463 bus_dmamem_unmap(sc->sc_dt, hwbuf, size); 464 goto free_dmamem; 465 } 466 467 error = bus_dmamap_load(sc->sc_dt, dma->buf_map, hwbuf, size, NULL, 468 BUS_DMA_NOWAIT); 469 if (error) { 470 printf("%s: unable to load map for %s h/w buffers, " 471 "error %u\n", sc->sc_dev.dv_xname, dma->name, error); 472 destroy_dmamap: 473 bus_dmamap_destroy(sc->sc_dt, dma->buf_map); 474 goto unmap_dmamem; 475 } 476 477 /* XXX M_TEMP */ 478 dma->buf = malloc(nbuf * sizeof(struct npebuf), M_TEMP, M_NOWAIT | M_ZERO); 479 if (dma->buf == NULL) { 480 printf("%s: unable to allocate memory for %s s/w buffers\n", 481 sc->sc_dev.dv_xname, dma->name); 482 bus_dmamap_unload(sc->sc_dt, dma->buf_map); 483 error = ENOMEM; 484 goto destroy_dmamap; 485 } 486 487 dma->buf_phys = dma->buf_map->dm_segs[0].ds_addr; 488 for (i = 0; i < dma->nbuf; i++) { 489 struct npebuf *npe = &dma->buf[i]; 490 struct npehwbuf *hw = &dma->hwbuf[i]; 491 492 /* calculate offset to shared area */ 493 npe->ix_neaddr = dma->buf_phys + 494 ((uintptr_t)hw - (uintptr_t)dma->hwbuf); 495 KASSERT((npe->ix_neaddr & 0x1f) == 0); 496 error = bus_dmamap_create(sc->sc_dt, MCLBYTES, maxseg, 497 MCLBYTES, 0, 0, &npe->ix_map); 498 if (error != 0) { 499 printf("%s: unable to create dmamap for %s buffer %u, " 500 "error %u\n", sc->sc_dev.dv_xname, dma->name, i, 501 error); 502 /* XXXSCW: Free up maps... */ 503 return error; 504 } 505 npe->ix_hw = hw; 506 } 507 bus_dmamap_sync(sc->sc_dt, dma->buf_map, 0, dma->buf_map->dm_mapsize, 508 BUS_DMASYNC_PREWRITE); 509 return 0; 510 } 511 512 #if 0 513 static void 514 npe_dma_destroy(struct npe_softc *sc, struct npedma *dma) 515 { 516 int i; 517 518 /* XXXSCW: Clean this up */ 519 520 if (dma->hwbuf != NULL) { 521 for (i = 0; i < dma->nbuf; i++) { 522 struct npebuf *npe = &dma->buf[i]; 523 bus_dmamap_destroy(sc->sc_dt, npe->ix_map); 524 } 525 bus_dmamap_unload(sc->sc_dt, dma->buf_map); 526 bus_dmamem_free(sc->sc_dt, (void *)dma->hwbuf, dma->buf_map); 527 bus_dmamap_destroy(sc->sc_dt, dma->buf_map); 528 } 529 if (dma->buf != NULL) 530 free(dma->buf, M_TEMP); 531 memset(dma, 0, sizeof(*dma)); 532 } 533 #endif 534 535 static int 536 npe_activate(struct npe_softc *sc) 537 { 538 bus_dma_segment_t seg; 539 int unit = sc->sc_unit; 540 int error, i, rseg; 541 void *statbuf; 542 543 /* load NPE firmware and start it running */ 544 error = ixpnpe_init(sc->sc_npe, "npe_fw", npeconfig[unit].imageid); 545 if (error != 0) 546 return error; 547 548 if (bus_space_map(sc->sc_iot, npeconfig[unit].regbase, 549 npeconfig[unit].regsize, 0, &sc->sc_ioh)) { 550 printf("%s: Cannot map registers 0x%x:0x%x\n", 551 sc->sc_dev.dv_xname, npeconfig[unit].regbase, 552 npeconfig[unit].regsize); 553 return ENOMEM; 554 } 555 556 if (npeconfig[unit].miibase != npeconfig[unit].regbase) { 557 /* 558 * The PHY's are only accessible from one MAC (it appears) 559 * so for other MAC's setup an additional mapping for 560 * frobbing the PHY registers. 561 */ 562 if (bus_space_map(sc->sc_iot, npeconfig[unit].miibase, 563 npeconfig[unit].miisize, 0, &sc->sc_miih)) { 564 printf("%s: Cannot map MII registers 0x%x:0x%x\n", 565 sc->sc_dev.dv_xname, npeconfig[unit].miibase, 566 npeconfig[unit].miisize); 567 return ENOMEM; 568 } 569 } else 570 sc->sc_miih = sc->sc_ioh; 571 error = npe_dma_setup(sc, &sc->txdma, "tx", NPE_TXBUF, NPE_MAXSEG); 572 if (error != 0) 573 return error; 574 error = npe_dma_setup(sc, &sc->rxdma, "rx", NPE_RXBUF, 1); 575 if (error != 0) 576 return error; 577 578 /* setup statistics block */ 579 error = bus_dmamem_alloc(sc->sc_dt, sizeof(struct npestats), 580 sizeof(uint32_t), 0, &seg, 1, &rseg, BUS_DMA_NOWAIT); 581 if (error) { 582 printf("%s: unable to allocate memory for stats block, " 583 "error %u\n", sc->sc_dev.dv_xname, error); 584 return error; 585 } 586 587 error = bus_dmamem_map(sc->sc_dt, &seg, 1, sizeof(struct npestats), 588 &statbuf, BUS_DMA_NOWAIT); 589 if (error) { 590 printf("%s: unable to map memory for stats block, " 591 "error %u\n", sc->sc_dev.dv_xname, error); 592 return error; 593 } 594 sc->sc_stats = (void *)statbuf; 595 596 error = bus_dmamap_create(sc->sc_dt, sizeof(struct npestats), 1, 597 sizeof(struct npestats), 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW, 598 &sc->sc_stats_map); 599 if (error) { 600 printf("%s: unable to create map for stats block, " 601 "error %u\n", sc->sc_dev.dv_xname, error); 602 return error; 603 } 604 605 if (bus_dmamap_load(sc->sc_dt, sc->sc_stats_map, sc->sc_stats, 606 sizeof(struct npestats), NULL, BUS_DMA_NOWAIT) != 0) { 607 printf("%s: unable to load memory for stats block, error %u\n", 608 sc->sc_dev.dv_xname, error); 609 return error; 610 } 611 sc->sc_stats_phys = sc->sc_stats_map->dm_segs[0].ds_addr; 612 613 /* XXX disable half-bridge LEARNING+FILTERING feature */ 614 615 /* 616 * Setup h/w rx/tx queues. There are four q's: 617 * rx inbound q of rx'd frames 618 * rx_free pool of ixpbuf's for receiving frames 619 * tx outbound q of frames to send 620 * tx_done q of tx frames that have been processed 621 * 622 * The NPE handles the actual tx/rx process and the q manager 623 * handles the queues. The driver just writes entries to the 624 * q manager mailbox's and gets callbacks when there are rx'd 625 * frames to process or tx'd frames to reap. These callbacks 626 * are controlled by the q configurations; e.g. we get a 627 * callback when tx_done has 2 or more frames to process and 628 * when the rx q has at least one frame. These setings can 629 * changed at the time the q is configured. 630 */ 631 sc->rx_qid = npeconfig[unit].rx_qid; 632 ixpqmgr_qconfig(sc->rx_qid, NPE_RXBUF, 0, 1, 633 IX_QMGR_Q_SOURCE_ID_NOT_E, npe_rxdone, sc); 634 sc->rx_freeqid = npeconfig[unit].rx_freeqid; 635 ixpqmgr_qconfig(sc->rx_freeqid, NPE_RXBUF, 0, NPE_RXBUF/2, 0, NULL, sc); 636 /* tell the NPE to direct all traffic to rx_qid */ 637 #if 0 638 for (i = 0; i < 8; i++) 639 #else 640 printf("%s: remember to fix rx q setup\n", sc->sc_dev.dv_xname); 641 for (i = 0; i < 4; i++) 642 #endif 643 npe_setrxqosentry(sc, i, 0, sc->rx_qid); 644 645 sc->tx_qid = npeconfig[unit].tx_qid; 646 sc->tx_doneqid = npeconfig[unit].tx_doneqid; 647 ixpqmgr_qconfig(sc->tx_qid, NPE_TXBUF, 0, NPE_TXBUF, 0, NULL, sc); 648 if (tx_doneqid == -1) { 649 ixpqmgr_qconfig(sc->tx_doneqid, NPE_TXBUF, 0, 2, 650 IX_QMGR_Q_SOURCE_ID_NOT_E, npe_txdone, sc); 651 tx_doneqid = sc->tx_doneqid; 652 } 653 654 KASSERT(npes[npeconfig[unit].npeid] == NULL); 655 npes[npeconfig[unit].npeid] = sc; 656 657 return 0; 658 } 659 660 #if 0 661 static void 662 npe_deactivate(struct npe_softc *sc); 663 { 664 int unit = sc->sc_unit; 665 666 npes[npeconfig[unit].npeid] = NULL; 667 668 /* XXX disable q's */ 669 if (sc->sc_npe != NULL) 670 ixpnpe_stop(sc->sc_npe); 671 if (sc->sc_stats != NULL) { 672 bus_dmamap_unload(sc->sc_stats_tag, sc->sc_stats_map); 673 bus_dmamem_free(sc->sc_stats_tag, sc->sc_stats, 674 sc->sc_stats_map); 675 bus_dmamap_destroy(sc->sc_stats_tag, sc->sc_stats_map); 676 } 677 if (sc->sc_stats_tag != NULL) 678 bus_dma_tag_destroy(sc->sc_stats_tag); 679 npe_dma_destroy(sc, &sc->txdma); 680 npe_dma_destroy(sc, &sc->rxdma); 681 bus_generic_detach(sc->sc_dev); 682 if (sc->sc_mii) 683 device_delete_child(sc->sc_dev, sc->sc_mii); 684 #if 0 685 /* XXX sc_ioh and sc_miih */ 686 if (sc->mem_res) 687 bus_release_resource(dev, SYS_RES_IOPORT, 688 rman_get_rid(sc->mem_res), sc->mem_res); 689 sc->mem_res = 0; 690 #endif 691 } 692 #endif 693 694 /* 695 * Notify the world which media we're using. 696 */ 697 static void 698 npe_ifmedia_status(struct ifnet *ifp, struct ifmediareq *ifmr) 699 { 700 struct npe_softc *sc = ifp->if_softc; 701 702 mii_pollstat(&sc->sc_mii); 703 704 ifmr->ifm_active = sc->sc_mii.mii_media_active; 705 ifmr->ifm_status = sc->sc_mii.mii_media_status; 706 } 707 708 static void 709 npe_addstats(struct npe_softc *sc) 710 { 711 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 712 struct npestats *ns = sc->sc_stats; 713 714 ifp->if_oerrors += 715 be32toh(ns->dot3StatsInternalMacTransmitErrors) 716 + be32toh(ns->dot3StatsCarrierSenseErrors) 717 + be32toh(ns->TxVLANIdFilterDiscards) 718 ; 719 ifp->if_ierrors += be32toh(ns->dot3StatsFCSErrors) 720 + be32toh(ns->dot3StatsInternalMacReceiveErrors) 721 + be32toh(ns->RxOverrunDiscards) 722 + be32toh(ns->RxUnderflowEntryDiscards) 723 ; 724 ifp->if_collisions += 725 be32toh(ns->dot3StatsSingleCollisionFrames) 726 + be32toh(ns->dot3StatsMultipleCollisionFrames) 727 ; 728 } 729 730 static void 731 npe_tick(void *xsc) 732 { 733 #define ACK (NPE_RESETSTATS << NPE_MAC_MSGID_SHL) 734 struct npe_softc *sc = xsc; 735 uint32_t msg[2]; 736 737 /* 738 * NB: to avoid sleeping with the softc lock held we 739 * split the NPE msg processing into two parts. The 740 * request for statistics is sent w/o waiting for a 741 * reply and then on the next tick we retrieve the 742 * results. This works because npe_tick is the only 743 * code that talks via the mailbox's (except at setup). 744 * This likely can be handled better. 745 */ 746 if (ixpnpe_recvmsg(sc->sc_npe, msg) == 0 && msg[0] == ACK) { 747 bus_dmamap_sync(sc->sc_dt, sc->sc_stats_map, 0, 748 sizeof(struct npestats), BUS_DMASYNC_POSTREAD); 749 npe_addstats(sc); 750 } 751 npe_updatestats(sc); 752 mii_tick(&sc->sc_mii); 753 754 /* schedule next poll */ 755 callout_reset(&sc->sc_tick_ch, hz, npe_tick, sc); 756 #undef ACK 757 } 758 759 static void 760 npe_setmac(struct npe_softc *sc, const u_char *eaddr) 761 { 762 763 WR4(sc, NPE_MAC_UNI_ADDR_1, eaddr[0]); 764 WR4(sc, NPE_MAC_UNI_ADDR_2, eaddr[1]); 765 WR4(sc, NPE_MAC_UNI_ADDR_3, eaddr[2]); 766 WR4(sc, NPE_MAC_UNI_ADDR_4, eaddr[3]); 767 WR4(sc, NPE_MAC_UNI_ADDR_5, eaddr[4]); 768 WR4(sc, NPE_MAC_UNI_ADDR_6, eaddr[5]); 769 } 770 771 static void 772 npe_getmac(struct npe_softc *sc) 773 { 774 uint8_t *eaddr = sc->sc_enaddr; 775 776 if (npe_getmac_md != NULL) { 777 (*npe_getmac_md)(sc->sc_dev.dv_unit, eaddr); 778 } else { 779 /* 780 * Some system's unicast address appears to be loaded from 781 * EEPROM on reset 782 */ 783 eaddr[0] = RD4(sc, NPE_MAC_UNI_ADDR_1) & 0xff; 784 eaddr[1] = RD4(sc, NPE_MAC_UNI_ADDR_2) & 0xff; 785 eaddr[2] = RD4(sc, NPE_MAC_UNI_ADDR_3) & 0xff; 786 eaddr[3] = RD4(sc, NPE_MAC_UNI_ADDR_4) & 0xff; 787 eaddr[4] = RD4(sc, NPE_MAC_UNI_ADDR_5) & 0xff; 788 eaddr[5] = RD4(sc, NPE_MAC_UNI_ADDR_6) & 0xff; 789 } 790 } 791 792 struct txdone { 793 struct npebuf *head; 794 struct npebuf **tail; 795 int count; 796 }; 797 798 static __inline void 799 npe_txdone_finish(struct npe_softc *sc, const struct txdone *td) 800 { 801 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 802 803 *td->tail = sc->tx_free; 804 sc->tx_free = td->head; 805 /* 806 * We're no longer busy, so clear the busy flag and call the 807 * start routine to xmit more packets. 808 */ 809 ifp->if_opackets += td->count; 810 ifp->if_flags &= ~IFF_OACTIVE; 811 ifp->if_timer = 0; 812 npestart(ifp); 813 } 814 815 /* 816 * Q manager callback on tx done queue. Reap mbufs 817 * and return tx buffers to the free list. Finally 818 * restart output. Note the microcode has only one 819 * txdone q wired into it so we must use the NPE ID 820 * returned with each npehwbuf to decide where to 821 * send buffers. 822 */ 823 static void 824 npe_txdone(int qid, void *arg) 825 { 826 #define P2V(a, dma) \ 827 &(dma)->buf[((a) - (dma)->buf_phys) / sizeof(struct npehwbuf)] 828 struct npe_softc *sc; 829 struct npebuf *npe; 830 struct txdone *td, q[NPE_MAX]; 831 uint32_t entry; 832 833 /* XXX no NPE-A support */ 834 q[NPE_B].tail = &q[NPE_B].head; q[NPE_B].count = 0; 835 q[NPE_C].tail = &q[NPE_C].head; q[NPE_C].count = 0; 836 /* XXX max # at a time? */ 837 while (ixpqmgr_qread(qid, &entry) == 0) { 838 sc = npes[NPE_QM_Q_NPE(entry)]; 839 DPRINTF(sc, "%s: entry 0x%x NPE %u port %u\n", 840 __func__, entry, NPE_QM_Q_NPE(entry), NPE_QM_Q_PORT(entry)); 841 #if NRND > 0 842 if (RND_ENABLED(&sc->rnd_source)) 843 rnd_add_uint32(&sc->rnd_source, entry); 844 #endif 845 846 npe = P2V(NPE_QM_Q_ADDR(entry), &sc->txdma); 847 m_freem(npe->ix_m); 848 npe->ix_m = NULL; 849 850 td = &q[NPE_QM_Q_NPE(entry)]; 851 *td->tail = npe; 852 td->tail = &npe->ix_next; 853 td->count++; 854 } 855 856 if (q[NPE_B].count) 857 npe_txdone_finish(npes[NPE_B], &q[NPE_B]); 858 if (q[NPE_C].count) 859 npe_txdone_finish(npes[NPE_C], &q[NPE_C]); 860 #undef P2V 861 } 862 863 static __inline struct mbuf * 864 npe_getcl(void) 865 { 866 struct mbuf *m; 867 868 MGETHDR(m, M_DONTWAIT, MT_DATA); 869 if (m != NULL) { 870 MCLGET(m, M_DONTWAIT); 871 if ((m->m_flags & M_EXT) == 0) { 872 m_freem(m); 873 m = NULL; 874 } 875 } 876 return (m); 877 } 878 879 static int 880 npe_rxbuf_init(struct npe_softc *sc, struct npebuf *npe, struct mbuf *m) 881 { 882 struct npehwbuf *hw; 883 int error; 884 885 if (m == NULL) { 886 m = npe_getcl(); 887 if (m == NULL) 888 return ENOBUFS; 889 } 890 KASSERT(m->m_ext.ext_size >= (NPE_FRAME_SIZE_DEFAULT + ETHER_ALIGN)); 891 m->m_pkthdr.len = m->m_len = NPE_FRAME_SIZE_DEFAULT; 892 /* backload payload and align ip hdr */ 893 m->m_data = m->m_ext.ext_buf + (m->m_ext.ext_size 894 - (NPE_FRAME_SIZE_DEFAULT + ETHER_ALIGN)); 895 error = bus_dmamap_load_mbuf(sc->sc_dt, npe->ix_map, m, 896 BUS_DMA_READ|BUS_DMA_NOWAIT); 897 if (error != 0) { 898 m_freem(m); 899 return error; 900 } 901 hw = npe->ix_hw; 902 hw->ix_ne[0].data = htobe32(npe->ix_map->dm_segs[0].ds_addr); 903 /* NB: NPE requires length be a multiple of 64 */ 904 /* NB: buffer length is shifted in word */ 905 hw->ix_ne[0].len = htobe32(npe->ix_map->dm_segs[0].ds_len << 16); 906 hw->ix_ne[0].next = 0; 907 npe->ix_m = m; 908 /* Flush the memory in the mbuf */ 909 bus_dmamap_sync(sc->sc_dt, npe->ix_map, 0, npe->ix_map->dm_mapsize, 910 BUS_DMASYNC_PREREAD); 911 return 0; 912 } 913 914 /* 915 * RX q processing for a specific NPE. Claim entries 916 * from the hardware queue and pass the frames up the 917 * stack. Pass the rx buffers to the free list. 918 */ 919 static void 920 npe_rxdone(int qid, void *arg) 921 { 922 #define P2V(a, dma) \ 923 &(dma)->buf[((a) - (dma)->buf_phys) / sizeof(struct npehwbuf)] 924 struct npe_softc *sc = arg; 925 struct npedma *dma = &sc->rxdma; 926 uint32_t entry; 927 928 while (ixpqmgr_qread(qid, &entry) == 0) { 929 struct npebuf *npe = P2V(NPE_QM_Q_ADDR(entry), dma); 930 struct mbuf *m; 931 932 DPRINTF(sc, "%s: entry 0x%x neaddr 0x%x ne_len 0x%x\n", 933 __func__, entry, npe->ix_neaddr, npe->ix_hw->ix_ne[0].len); 934 #if NRND > 0 935 if (RND_ENABLED(&sc->rnd_source)) 936 rnd_add_uint32(&sc->rnd_source, entry); 937 #endif 938 /* 939 * Allocate a new mbuf to replenish the rx buffer. 940 * If doing so fails we drop the rx'd frame so we 941 * can reuse the previous mbuf. When we're able to 942 * allocate a new mbuf dispatch the mbuf w/ rx'd 943 * data up the stack and replace it with the newly 944 * allocated one. 945 */ 946 m = npe_getcl(); 947 if (m != NULL) { 948 struct mbuf *mrx = npe->ix_m; 949 struct npehwbuf *hw = npe->ix_hw; 950 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 951 952 /* Flush mbuf memory for rx'd data */ 953 bus_dmamap_sync(sc->sc_dt, npe->ix_map, 0, 954 npe->ix_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 955 956 /* XXX flush hw buffer; works now 'cuz coherent */ 957 /* set m_len etc. per rx frame size */ 958 mrx->m_len = be32toh(hw->ix_ne[0].len) & 0xffff; 959 mrx->m_pkthdr.len = mrx->m_len; 960 mrx->m_pkthdr.rcvif = ifp; 961 /* Don't add M_HASFCS. See below */ 962 963 #if 1 964 if (mrx->m_pkthdr.len < sizeof(struct ether_header)) { 965 log(LOG_INFO, "%s: too short frame (len=%d)\n", 966 sc->sc_dev.dv_xname, mrx->m_pkthdr.len); 967 /* Back out "newly allocated" mbuf. */ 968 m_freem(m); 969 ifp->if_ierrors++; 970 goto fail; 971 } 972 if ((ifp->if_flags & IFF_PROMISC) == 0) { 973 struct ether_header *eh; 974 975 /* 976 * Workaround for "Non-Intel XScale Technology 977 * Eratta" No. 29. AA:BB:CC:DD:EE:xF's packet 978 * matches the filter (both unicast and 979 * multicast). 980 */ 981 eh = mtod(mrx, struct ether_header *); 982 if (ETHER_IS_MULTICAST(eh->ether_dhost) == 0) { 983 /* unicast */ 984 985 if (sc->sc_enaddr[5] != eh->ether_dhost[5]) { 986 /* discard it */ 987 #if 0 988 printf("discard it\n"); 989 #endif 990 /* 991 * Back out "newly allocated" 992 * mbuf. 993 */ 994 m_freem(m); 995 goto fail; 996 } 997 } else if (memcmp(eh->ether_dhost, 998 etherbroadcastaddr, 6) == 0) { 999 /* Always accept broadcast packet*/ 1000 } else { 1001 struct ethercom *ec = &sc->sc_ethercom; 1002 struct ether_multi *enm; 1003 struct ether_multistep step; 1004 int match = 0; 1005 1006 /* multicast */ 1007 1008 ETHER_FIRST_MULTI(step, ec, enm); 1009 while (enm != NULL) { 1010 uint64_t lowint, highint, dest; 1011 1012 lowint = MAC2UINT64(enm->enm_addrlo); 1013 highint = MAC2UINT64(enm->enm_addrhi); 1014 dest = MAC2UINT64(eh->ether_dhost); 1015 #if 0 1016 printf("%llx\n", lowint); 1017 printf("%llx\n", dest); 1018 printf("%llx\n", highint); 1019 #endif 1020 if ((lowint <= dest) && (dest <= highint)) { 1021 match = 1; 1022 break; 1023 } 1024 ETHER_NEXT_MULTI(step, enm); 1025 } 1026 if (match == 0) { 1027 /* discard it */ 1028 #if 0 1029 printf("discard it(M)\n"); 1030 #endif 1031 /* 1032 * Back out "newly allocated" 1033 * mbuf. 1034 */ 1035 m_freem(m); 1036 goto fail; 1037 } 1038 } 1039 } 1040 if (mrx->m_pkthdr.len > NPE_FRAME_SIZE_DEFAULT) { 1041 log(LOG_INFO, "%s: oversized frame (len=%d)\n", 1042 sc->sc_dev.dv_xname, mrx->m_pkthdr.len); 1043 /* Back out "newly allocated" mbuf. */ 1044 m_freem(m); 1045 ifp->if_ierrors++; 1046 goto fail; 1047 } 1048 #endif 1049 1050 /* 1051 * Trim FCS! 1052 * NPE always adds the FCS by this driver's setting, 1053 * so we always trim it here and not add M_HASFCS. 1054 */ 1055 m_adj(mrx, -ETHER_CRC_LEN); 1056 1057 ifp->if_ipackets++; 1058 /* 1059 * Tap off here if there is a bpf listener. 1060 */ 1061 bpf_mtap(ifp, mrx); 1062 ifp->if_input(ifp, mrx); 1063 } else { 1064 fail: 1065 /* discard frame and re-use mbuf */ 1066 m = npe->ix_m; 1067 } 1068 if (npe_rxbuf_init(sc, npe, m) == 0) { 1069 /* return npe buf to rx free list */ 1070 ixpqmgr_qwrite(sc->rx_freeqid, npe->ix_neaddr); 1071 } else { 1072 /* XXX should not happen */ 1073 } 1074 } 1075 #undef P2V 1076 } 1077 1078 static void 1079 npe_startxmit(struct npe_softc *sc) 1080 { 1081 struct npedma *dma = &sc->txdma; 1082 int i; 1083 1084 sc->tx_free = NULL; 1085 for (i = 0; i < dma->nbuf; i++) { 1086 struct npebuf *npe = &dma->buf[i]; 1087 if (npe->ix_m != NULL) { 1088 /* NB: should not happen */ 1089 printf("%s: %s: free mbuf at entry %u\n", 1090 sc->sc_dev.dv_xname, __func__, i); 1091 m_freem(npe->ix_m); 1092 } 1093 npe->ix_m = NULL; 1094 npe->ix_next = sc->tx_free; 1095 sc->tx_free = npe; 1096 } 1097 } 1098 1099 static void 1100 npe_startrecv(struct npe_softc *sc) 1101 { 1102 struct npedma *dma = &sc->rxdma; 1103 struct npebuf *npe; 1104 int i; 1105 1106 for (i = 0; i < dma->nbuf; i++) { 1107 npe = &dma->buf[i]; 1108 npe_rxbuf_init(sc, npe, npe->ix_m); 1109 /* set npe buf on rx free list */ 1110 ixpqmgr_qwrite(sc->rx_freeqid, npe->ix_neaddr); 1111 } 1112 } 1113 1114 static void 1115 npeinit_macreg(struct npe_softc *sc) 1116 { 1117 1118 /* 1119 * Reset MAC core. 1120 */ 1121 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET); 1122 DELAY(NPE_MAC_RESET_DELAY); 1123 /* configure MAC to generate MDC clock */ 1124 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN); 1125 1126 /* disable transmitter and reciver in the MAC */ 1127 WR4(sc, NPE_MAC_RX_CNTRL1, 1128 RD4(sc, NPE_MAC_RX_CNTRL1) &~ NPE_RX_CNTRL1_RX_EN); 1129 WR4(sc, NPE_MAC_TX_CNTRL1, 1130 RD4(sc, NPE_MAC_TX_CNTRL1) &~ NPE_TX_CNTRL1_TX_EN); 1131 1132 /* 1133 * Set the MAC core registers. 1134 */ 1135 WR4(sc, NPE_MAC_INT_CLK_THRESH, 0x1); /* clock ratio: for ipx4xx */ 1136 WR4(sc, NPE_MAC_TX_CNTRL2, 0xf); /* max retries */ 1137 WR4(sc, NPE_MAC_RANDOM_SEED, 0x8); /* LFSR back-off seed */ 1138 /* thresholds determined by NPE firmware FS */ 1139 WR4(sc, NPE_MAC_THRESH_P_EMPTY, 0x12); 1140 WR4(sc, NPE_MAC_THRESH_P_FULL, 0x30); 1141 WR4(sc, NPE_MAC_BUF_SIZE_TX, NPE_MAC_BUF_SIZE_TX_DEFAULT); 1142 /* tx fifo threshold (bytes) */ 1143 WR4(sc, NPE_MAC_TX_DEFER, 0x15); /* for single deferral */ 1144 WR4(sc, NPE_MAC_RX_DEFER, 0x16); /* deferral on inter-frame gap*/ 1145 WR4(sc, NPE_MAC_TX_TWO_DEFER_1, 0x8); /* for 2-part deferral */ 1146 WR4(sc, NPE_MAC_TX_TWO_DEFER_2, 0x7); /* for 2-part deferral */ 1147 WR4(sc, NPE_MAC_SLOT_TIME, NPE_MAC_SLOT_TIME_MII_DEFAULT); 1148 /* assumes MII mode */ 1149 WR4(sc, NPE_MAC_TX_CNTRL1, 1150 NPE_TX_CNTRL1_RETRY /* retry failed xmits */ 1151 | NPE_TX_CNTRL1_FCS_EN /* append FCS */ 1152 | NPE_TX_CNTRL1_2DEFER /* 2-part deferal */ 1153 | NPE_TX_CNTRL1_PAD_EN); /* pad runt frames */ 1154 /* XXX pad strip? */ 1155 WR4(sc, NPE_MAC_RX_CNTRL1, 1156 NPE_RX_CNTRL1_CRC_EN /* include CRC/FCS */ 1157 | NPE_RX_CNTRL1_PAUSE_EN); /* ena pause frame handling */ 1158 WR4(sc, NPE_MAC_RX_CNTRL2, 0); 1159 } 1160 1161 static void 1162 npeinit_resetcb(void *xsc) 1163 { 1164 struct npe_softc *sc = xsc; 1165 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1166 uint32_t msg[2]; 1167 1168 ifp->if_oerrors++; 1169 npeinit_locked(sc); 1170 1171 msg[0] = NPE_NOTIFYMACRECOVERYDONE << NPE_MAC_MSGID_SHL 1172 | (npeconfig[sc->sc_unit].macport << NPE_MAC_PORTID_SHL); 1173 msg[1] = 0; 1174 ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg); 1175 } 1176 1177 /* 1178 * Reset and initialize the chip 1179 */ 1180 static void 1181 npeinit_locked(void *xsc) 1182 { 1183 struct npe_softc *sc = xsc; 1184 struct ifnet *ifp = &sc->sc_ethercom.ec_if; 1185 1186 /* Cancel any pending I/O. */ 1187 npestop(ifp, 0); 1188 1189 /* Reset the chip to a known state. */ 1190 npeinit_macreg(sc); 1191 npe_setmac(sc, CLLADDR(ifp->if_sadl)); 1192 ether_mediachange(ifp); 1193 npe_setmcast(sc); 1194 1195 npe_startxmit(sc); 1196 npe_startrecv(sc); 1197 1198 ifp->if_flags |= IFF_RUNNING; 1199 ifp->if_flags &= ~IFF_OACTIVE; 1200 ifp->if_timer = 0; /* just in case */ 1201 1202 /* enable transmitter and reciver in the MAC */ 1203 WR4(sc, NPE_MAC_RX_CNTRL1, 1204 RD4(sc, NPE_MAC_RX_CNTRL1) | NPE_RX_CNTRL1_RX_EN); 1205 WR4(sc, NPE_MAC_TX_CNTRL1, 1206 RD4(sc, NPE_MAC_TX_CNTRL1) | NPE_TX_CNTRL1_TX_EN); 1207 1208 callout_reset(&sc->sc_tick_ch, hz, npe_tick, sc); 1209 } 1210 1211 static int 1212 npeinit(struct ifnet *ifp) 1213 { 1214 struct npe_softc *sc = ifp->if_softc; 1215 int s; 1216 1217 s = splnet(); 1218 npeinit_locked(sc); 1219 splx(s); 1220 1221 return (0); 1222 } 1223 1224 /* 1225 * Defragment an mbuf chain, returning at most maxfrags separate 1226 * mbufs+clusters. If this is not possible NULL is returned and 1227 * the original mbuf chain is left in it's present (potentially 1228 * modified) state. We use two techniques: collapsing consecutive 1229 * mbufs and replacing consecutive mbufs by a cluster. 1230 */ 1231 static __inline struct mbuf * 1232 npe_defrag(struct mbuf *m0) 1233 { 1234 struct mbuf *m; 1235 1236 MGETHDR(m, M_DONTWAIT, MT_DATA); 1237 if (m == NULL) 1238 return (NULL); 1239 M_COPY_PKTHDR(m, m0); 1240 1241 if ((m->m_len = m0->m_pkthdr.len) > MHLEN) { 1242 MCLGET(m, M_DONTWAIT); 1243 if ((m->m_flags & M_EXT) == 0) { 1244 m_freem(m); 1245 return (NULL); 1246 } 1247 } 1248 1249 m_copydata(m0, 0, m0->m_pkthdr.len, mtod(m, void *)); 1250 m_freem(m0); 1251 1252 return (m); 1253 } 1254 1255 /* 1256 * Dequeue packets and place on the h/w transmit queue. 1257 */ 1258 static void 1259 npestart(struct ifnet *ifp) 1260 { 1261 struct npe_softc *sc = ifp->if_softc; 1262 struct npebuf *npe; 1263 struct npehwbuf *hw; 1264 struct mbuf *m, *n; 1265 bus_dma_segment_t *segs; 1266 int nseg, len, error, i; 1267 uint32_t next; 1268 1269 if ((ifp->if_flags & (IFF_RUNNING|IFF_OACTIVE)) != IFF_RUNNING) 1270 return; 1271 1272 while (sc->tx_free != NULL) { 1273 IFQ_DEQUEUE(&ifp->if_snd, m); 1274 if (m == NULL) 1275 break; 1276 npe = sc->tx_free; 1277 error = bus_dmamap_load_mbuf(sc->sc_dt, npe->ix_map, m, 1278 BUS_DMA_WRITE|BUS_DMA_NOWAIT); 1279 if (error == EFBIG) { 1280 n = npe_defrag(m); 1281 if (n == NULL) { 1282 printf("%s: %s: too many fragments\n", 1283 sc->sc_dev.dv_xname, __func__); 1284 m_freem(m); 1285 return; /* XXX? */ 1286 } 1287 m = n; 1288 error = bus_dmamap_load_mbuf(sc->sc_dt, npe->ix_map, 1289 m, BUS_DMA_WRITE|BUS_DMA_NOWAIT); 1290 } 1291 if (error != 0) { 1292 printf("%s: %s: error %u\n", 1293 sc->sc_dev.dv_xname, __func__, error); 1294 m_freem(m); 1295 return; /* XXX? */ 1296 } 1297 sc->tx_free = npe->ix_next; 1298 1299 /* 1300 * Tap off here if there is a bpf listener. 1301 */ 1302 bpf_mtap(ifp, m); 1303 1304 bus_dmamap_sync(sc->sc_dt, npe->ix_map, 0, 1305 npe->ix_map->dm_mapsize, BUS_DMASYNC_PREWRITE); 1306 1307 npe->ix_m = m; 1308 hw = npe->ix_hw; 1309 len = m->m_pkthdr.len; 1310 nseg = npe->ix_map->dm_nsegs; 1311 segs = npe->ix_map->dm_segs; 1312 next = npe->ix_neaddr + sizeof(hw->ix_ne[0]); 1313 for (i = 0; i < nseg; i++) { 1314 hw->ix_ne[i].data = htobe32(segs[i].ds_addr); 1315 hw->ix_ne[i].len = htobe32((segs[i].ds_len<<16) | len); 1316 hw->ix_ne[i].next = htobe32(next); 1317 1318 len = 0; /* zero for segments > 1 */ 1319 next += sizeof(hw->ix_ne[0]); 1320 } 1321 hw->ix_ne[i-1].next = 0; /* zero last in chain */ 1322 /* XXX flush descriptor instead of using uncached memory */ 1323 1324 DPRINTF(sc, "%s: qwrite(%u, 0x%x) ne_data %x ne_len 0x%x\n", 1325 __func__, sc->tx_qid, npe->ix_neaddr, 1326 hw->ix_ne[0].data, hw->ix_ne[0].len); 1327 /* stick it on the tx q */ 1328 /* XXX add vlan priority */ 1329 ixpqmgr_qwrite(sc->tx_qid, npe->ix_neaddr); 1330 1331 ifp->if_timer = 5; 1332 } 1333 if (sc->tx_free == NULL) 1334 ifp->if_flags |= IFF_OACTIVE; 1335 } 1336 1337 static void 1338 npe_stopxmit(struct npe_softc *sc) 1339 { 1340 struct npedma *dma = &sc->txdma; 1341 int i; 1342 1343 /* XXX qmgr */ 1344 for (i = 0; i < dma->nbuf; i++) { 1345 struct npebuf *npe = &dma->buf[i]; 1346 1347 if (npe->ix_m != NULL) { 1348 bus_dmamap_unload(sc->sc_dt, npe->ix_map); 1349 m_freem(npe->ix_m); 1350 npe->ix_m = NULL; 1351 } 1352 } 1353 } 1354 1355 static void 1356 npe_stoprecv(struct npe_softc *sc) 1357 { 1358 struct npedma *dma = &sc->rxdma; 1359 int i; 1360 1361 /* XXX qmgr */ 1362 for (i = 0; i < dma->nbuf; i++) { 1363 struct npebuf *npe = &dma->buf[i]; 1364 1365 if (npe->ix_m != NULL) { 1366 bus_dmamap_unload(sc->sc_dt, npe->ix_map); 1367 m_freem(npe->ix_m); 1368 npe->ix_m = NULL; 1369 } 1370 } 1371 } 1372 1373 /* 1374 * Turn off interrupts, and stop the nic. 1375 */ 1376 void 1377 npestop(struct ifnet *ifp, int disable) 1378 { 1379 struct npe_softc *sc = ifp->if_softc; 1380 1381 /* disable transmitter and reciver in the MAC */ 1382 WR4(sc, NPE_MAC_RX_CNTRL1, 1383 RD4(sc, NPE_MAC_RX_CNTRL1) &~ NPE_RX_CNTRL1_RX_EN); 1384 WR4(sc, NPE_MAC_TX_CNTRL1, 1385 RD4(sc, NPE_MAC_TX_CNTRL1) &~ NPE_TX_CNTRL1_TX_EN); 1386 1387 callout_stop(&sc->sc_tick_ch); 1388 1389 npe_stopxmit(sc); 1390 npe_stoprecv(sc); 1391 /* XXX go into loopback & drain q's? */ 1392 /* XXX but beware of disabling tx above */ 1393 1394 /* 1395 * The MAC core rx/tx disable may leave the MAC hardware in an 1396 * unpredictable state. A hw reset is executed before resetting 1397 * all the MAC parameters to a known value. 1398 */ 1399 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_RESET); 1400 DELAY(NPE_MAC_RESET_DELAY); 1401 WR4(sc, NPE_MAC_INT_CLK_THRESH, NPE_MAC_INT_CLK_THRESH_DEFAULT); 1402 WR4(sc, NPE_MAC_CORE_CNTRL, NPE_CORE_MDC_EN); 1403 1404 ifp->if_timer = 0; 1405 ifp->if_flags &= ~(IFF_RUNNING | IFF_OACTIVE); 1406 } 1407 1408 void 1409 npewatchdog(struct ifnet *ifp) 1410 { 1411 struct npe_softc *sc = ifp->if_softc; 1412 int s; 1413 1414 printf("%s: device timeout\n", sc->sc_dev.dv_xname); 1415 s = splnet(); 1416 ifp->if_oerrors++; 1417 npeinit_locked(sc); 1418 splx(s); 1419 } 1420 1421 static int 1422 npeioctl(struct ifnet *ifp, u_long cmd, void *data) 1423 { 1424 struct npe_softc *sc = ifp->if_softc; 1425 struct ifreq *ifr = (struct ifreq *) data; 1426 int s, error = 0; 1427 1428 s = splnet(); 1429 1430 switch (cmd) { 1431 case SIOCSIFMEDIA: 1432 case SIOCGIFMEDIA: 1433 #if 0 /* not yet */ 1434 /* Flow control requires full-duplex mode. */ 1435 if (IFM_SUBTYPE(ifr->ifr_media) == IFM_AUTO || 1436 (ifr->ifr_media & IFM_FDX) == 0) 1437 ifr->ifr_media &= ~IFM_ETH_FMASK; 1438 if (IFM_SUBTYPE(ifr->ifr_media) != IFM_AUTO) { 1439 if ((ifr->ifr_media & IFM_ETH_FMASK) == IFM_FLOW) { 1440 /* We can do both TXPAUSE and RXPAUSE. */ 1441 ifr->ifr_media |= 1442 IFM_ETH_TXPAUSE | IFM_ETH_RXPAUSE; 1443 } 1444 sc->sc_flowflags = ifr->ifr_media & IFM_ETH_FMASK; 1445 } 1446 #endif 1447 error = ifmedia_ioctl(ifp, ifr, &sc->sc_mii.mii_media, cmd); 1448 break; 1449 case SIOCSIFFLAGS: 1450 if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_RUNNING) { 1451 /* 1452 * If interface is marked down and it is running, 1453 * then stop and disable it. 1454 */ 1455 (*ifp->if_stop)(ifp, 1); 1456 } else if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) == IFF_UP) { 1457 /* 1458 * If interface is marked up and it is stopped, then 1459 * start it. 1460 */ 1461 error = (*ifp->if_init)(ifp); 1462 } else if ((ifp->if_flags & IFF_UP) != 0) { 1463 int diff; 1464 1465 /* Up (AND RUNNING). */ 1466 1467 diff = (ifp->if_flags ^ sc->sc_if_flags) 1468 & (IFF_PROMISC|IFF_ALLMULTI); 1469 if ((diff & (IFF_PROMISC|IFF_ALLMULTI)) != 0) { 1470 /* 1471 * If the difference bettween last flag and 1472 * new flag only IFF_PROMISC or IFF_ALLMULTI, 1473 * set multicast filter only (don't reset to 1474 * prevent link down). 1475 */ 1476 npe_setmcast(sc); 1477 } else { 1478 /* 1479 * Reset the interface to pick up changes in 1480 * any other flags that affect the hardware 1481 * state. 1482 */ 1483 error = (*ifp->if_init)(ifp); 1484 } 1485 } 1486 sc->sc_if_flags = ifp->if_flags; 1487 break; 1488 default: 1489 error = ether_ioctl(ifp, cmd, data); 1490 if (error == ENETRESET) { 1491 /* 1492 * Multicast list has changed; set the hardware filter 1493 * accordingly. 1494 */ 1495 npe_setmcast(sc); 1496 error = 0; 1497 } 1498 } 1499 1500 npestart(ifp); 1501 1502 splx(s); 1503 return error; 1504 } 1505 1506 /* 1507 * Setup a traffic class -> rx queue mapping. 1508 */ 1509 static int 1510 npe_setrxqosentry(struct npe_softc *sc, int classix, int trafclass, int qid) 1511 { 1512 int npeid = npeconfig[sc->sc_unit].npeid; 1513 uint32_t msg[2]; 1514 1515 msg[0] = (NPE_SETRXQOSENTRY << NPE_MAC_MSGID_SHL) | (npeid << 20) 1516 | classix; 1517 msg[1] = (trafclass << 24) | (1 << 23) | (qid << 16) | (qid << 4); 1518 return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg); 1519 } 1520 1521 /* 1522 * Update and reset the statistics in the NPE. 1523 */ 1524 static int 1525 npe_updatestats(struct npe_softc *sc) 1526 { 1527 uint32_t msg[2]; 1528 1529 msg[0] = NPE_RESETSTATS << NPE_MAC_MSGID_SHL; 1530 msg[1] = sc->sc_stats_phys; /* physical address of stat block */ 1531 return ixpnpe_sendmsg(sc->sc_npe, msg); /* NB: no recv */ 1532 } 1533 1534 #if 0 1535 /* 1536 * Get the current statistics block. 1537 */ 1538 static int 1539 npe_getstats(struct npe_softc *sc) 1540 { 1541 uint32_t msg[2]; 1542 1543 msg[0] = NPE_GETSTATS << NPE_MAC_MSGID_SHL; 1544 msg[1] = sc->sc_stats_phys; /* physical address of stat block */ 1545 return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg); 1546 } 1547 1548 /* 1549 * Query the image id of the loaded firmware. 1550 */ 1551 static uint32_t 1552 npe_getimageid(struct npe_softc *sc) 1553 { 1554 uint32_t msg[2]; 1555 1556 msg[0] = NPE_GETSTATUS << NPE_MAC_MSGID_SHL; 1557 msg[1] = 0; 1558 return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg) == 0 ? msg[1] : 0; 1559 } 1560 1561 /* 1562 * Enable/disable loopback. 1563 */ 1564 static int 1565 npe_setloopback(struct npe_softc *sc, int ena) 1566 { 1567 uint32_t msg[2]; 1568 1569 msg[0] = (NPE_SETLOOPBACK << NPE_MAC_MSGID_SHL) | (ena != 0); 1570 msg[1] = 0; 1571 return ixpnpe_sendandrecvmsg(sc->sc_npe, msg, msg); 1572 } 1573 #endif 1574 1575 /* 1576 * MII bus support routines. 1577 * 1578 * NB: ixp425 has one PHY per NPE 1579 */ 1580 static uint32_t 1581 npe_mii_mdio_read(struct npe_softc *sc, int reg) 1582 { 1583 #define MII_RD4(sc, reg) bus_space_read_4(sc->sc_iot, sc->sc_miih, reg) 1584 uint32_t v; 1585 1586 /* NB: registers are known to be sequential */ 1587 v = (MII_RD4(sc, reg+0) & 0xff) << 0; 1588 v |= (MII_RD4(sc, reg+4) & 0xff) << 8; 1589 v |= (MII_RD4(sc, reg+8) & 0xff) << 16; 1590 v |= (MII_RD4(sc, reg+12) & 0xff) << 24; 1591 return v; 1592 #undef MII_RD4 1593 } 1594 1595 static void 1596 npe_mii_mdio_write(struct npe_softc *sc, int reg, uint32_t cmd) 1597 { 1598 #define MII_WR4(sc, reg, v) \ 1599 bus_space_write_4(sc->sc_iot, sc->sc_miih, reg, v) 1600 1601 /* NB: registers are known to be sequential */ 1602 MII_WR4(sc, reg+0, cmd & 0xff); 1603 MII_WR4(sc, reg+4, (cmd >> 8) & 0xff); 1604 MII_WR4(sc, reg+8, (cmd >> 16) & 0xff); 1605 MII_WR4(sc, reg+12, (cmd >> 24) & 0xff); 1606 #undef MII_WR4 1607 } 1608 1609 static int 1610 npe_mii_mdio_wait(struct npe_softc *sc) 1611 { 1612 #define MAXTRIES 100 /* XXX */ 1613 uint32_t v; 1614 int i; 1615 1616 for (i = 0; i < MAXTRIES; i++) { 1617 v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_CMD); 1618 if ((v & NPE_MII_GO) == 0) 1619 return 1; 1620 } 1621 return 0; /* NB: timeout */ 1622 #undef MAXTRIES 1623 } 1624 1625 static int 1626 npe_miibus_readreg(struct device *self, int phy, int reg) 1627 { 1628 struct npe_softc *sc = (void *)self; 1629 uint32_t v; 1630 1631 if (sc->sc_phy > IXPNPECF_PHY_DEFAULT && phy != sc->sc_phy) 1632 return 0xffff; 1633 v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) 1634 | NPE_MII_GO; 1635 npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v); 1636 if (npe_mii_mdio_wait(sc)) 1637 v = npe_mii_mdio_read(sc, NPE_MAC_MDIO_STS); 1638 else 1639 v = 0xffff | NPE_MII_READ_FAIL; 1640 return (v & NPE_MII_READ_FAIL) ? 0xffff : (v & 0xffff); 1641 #undef MAXTRIES 1642 } 1643 1644 static void 1645 npe_miibus_writereg(struct device *self, int phy, int reg, int data) 1646 { 1647 struct npe_softc *sc = (void *)self; 1648 uint32_t v; 1649 1650 if (sc->sc_phy > IXPNPECF_PHY_DEFAULT && phy != sc->sc_phy) 1651 return; 1652 v = (phy << NPE_MII_ADDR_SHL) | (reg << NPE_MII_REG_SHL) 1653 | data | NPE_MII_WRITE 1654 | NPE_MII_GO; 1655 npe_mii_mdio_write(sc, NPE_MAC_MDIO_CMD, v); 1656 /* XXX complain about timeout */ 1657 (void) npe_mii_mdio_wait(sc); 1658 } 1659 1660 static void 1661 npe_miibus_statchg(struct device *self) 1662 { 1663 struct npe_softc *sc = (void *)self; 1664 uint32_t tx1, rx1; 1665 uint32_t randoff; 1666 1667 /* sync MAC duplex state */ 1668 tx1 = RD4(sc, NPE_MAC_TX_CNTRL1); 1669 rx1 = RD4(sc, NPE_MAC_RX_CNTRL1); 1670 if (sc->sc_mii.mii_media_active & IFM_FDX) { 1671 WR4(sc, NPE_MAC_SLOT_TIME, NPE_MAC_SLOT_TIME_MII_DEFAULT); 1672 tx1 &= ~NPE_TX_CNTRL1_DUPLEX; 1673 rx1 |= NPE_RX_CNTRL1_PAUSE_EN; 1674 } else { 1675 struct timeval now; 1676 getmicrotime(&now); 1677 randoff = (RD4(sc, NPE_MAC_UNI_ADDR_6) ^ now.tv_usec) 1678 & 0x7f; 1679 WR4(sc, NPE_MAC_SLOT_TIME, NPE_MAC_SLOT_TIME_MII_DEFAULT 1680 + randoff); 1681 tx1 |= NPE_TX_CNTRL1_DUPLEX; 1682 rx1 &= ~NPE_RX_CNTRL1_PAUSE_EN; 1683 } 1684 WR4(sc, NPE_MAC_RX_CNTRL1, rx1); 1685 WR4(sc, NPE_MAC_TX_CNTRL1, tx1); 1686 } 1687