1 /* $NetBSD: dwc_gmac.c,v 1.34 2015/08/21 20:12:29 jmcneill Exp $ */ 2 3 /*- 4 * Copyright (c) 2013, 2014 The NetBSD Foundation, Inc. 5 * All rights reserved. 6 * 7 * This code is derived from software contributed to The NetBSD Foundation 8 * by Matt Thomas of 3am Software Foundry and Martin Husemann. 9 * 10 * Redistribution and use in source and binary forms, with or without 11 * modification, are permitted provided that the following conditions 12 * are met: 13 * 1. Redistributions of source code must retain the above copyright 14 * notice, this list of conditions and the following disclaimer. 15 * 2. Redistributions in binary form must reproduce the above copyright 16 * notice, this list of conditions and the following disclaimer in the 17 * documentation and/or other materials provided with the distribution. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 /* 33 * This driver supports the Synopsis Designware GMAC core, as found 34 * on Allwinner A20 cores and others. 35 * 36 * Real documentation seems to not be available, the marketing product 37 * documents could be found here: 38 * 39 * http://www.synopsys.com/dw/ipdir.php?ds=dwc_ether_mac10_100_1000_unive 40 */ 41 42 #include <sys/cdefs.h> 43 44 __KERNEL_RCSID(1, "$NetBSD: dwc_gmac.c,v 1.34 2015/08/21 20:12:29 jmcneill Exp $"); 45 46 /* #define DWC_GMAC_DEBUG 1 */ 47 48 #include "opt_inet.h" 49 50 #include <sys/param.h> 51 #include <sys/bus.h> 52 #include <sys/device.h> 53 #include <sys/intr.h> 54 #include <sys/systm.h> 55 #include <sys/sockio.h> 56 #include <sys/cprng.h> 57 58 #include <net/if.h> 59 #include <net/if_ether.h> 60 #include <net/if_media.h> 61 #include <net/bpf.h> 62 #ifdef INET 63 #include <netinet/if_inarp.h> 64 #endif 65 66 #include <dev/mii/miivar.h> 67 68 #include <dev/ic/dwc_gmac_reg.h> 69 #include <dev/ic/dwc_gmac_var.h> 70 71 static int dwc_gmac_miibus_read_reg(device_t, int, int); 72 static void dwc_gmac_miibus_write_reg(device_t, int, int, int); 73 static void dwc_gmac_miibus_statchg(struct ifnet *); 74 75 static int dwc_gmac_reset(struct dwc_gmac_softc *sc); 76 static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, 77 uint8_t enaddr[ETHER_ADDR_LEN]); 78 static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc); 79 static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc); 80 static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 81 static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 82 static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 83 static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 84 static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 85 static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 86 static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops); 87 static int dwc_gmac_init(struct ifnet *ifp); 88 static void dwc_gmac_stop(struct ifnet *ifp, int disable); 89 static void dwc_gmac_start(struct ifnet *ifp); 90 static int dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0); 91 static int dwc_gmac_ioctl(struct ifnet *, u_long, void *); 92 static void dwc_gmac_tx_intr(struct dwc_gmac_softc *sc); 93 static void dwc_gmac_rx_intr(struct dwc_gmac_softc *sc); 94 static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc); 95 static int dwc_gmac_ifflags_cb(struct ethercom *); 96 static uint32_t bitrev32(uint32_t x); 97 98 #define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \ 99 *sizeof(struct dwc_gmac_dev_dmadesc)) 100 #define TX_NEXT(N) (((N)+1) & (AWGE_TX_RING_COUNT-1)) 101 102 #define RX_DESC_OFFSET(N) ((N)*sizeof(struct dwc_gmac_dev_dmadesc)) 103 #define RX_NEXT(N) (((N)+1) & (AWGE_RX_RING_COUNT-1)) 104 105 106 107 #define GMAC_DEF_DMA_INT_MASK (GMAC_DMA_INT_TIE|GMAC_DMA_INT_RIE| \ 108 GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE| \ 109 GMAC_DMA_INT_FBE|GMAC_DMA_INT_UNE) 110 111 #define GMAC_DMA_INT_ERRORS (GMAC_DMA_INT_AIE|GMAC_DMA_INT_ERE| \ 112 GMAC_DMA_INT_FBE| \ 113 GMAC_DMA_INT_RWE|GMAC_DMA_INT_RUE| \ 114 GMAC_DMA_INT_UNE|GMAC_DMA_INT_OVE| \ 115 GMAC_DMA_INT_TJE) 116 117 #define AWIN_DEF_MAC_INTRMASK \ 118 (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \ 119 AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII) 120 121 122 #ifdef DWC_GMAC_DEBUG 123 static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc); 124 static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc); 125 static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc); 126 static void dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg); 127 static void dwc_dump_status(struct dwc_gmac_softc *sc); 128 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt); 129 #endif 130 131 void 132 dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk) 133 { 134 uint8_t enaddr[ETHER_ADDR_LEN]; 135 uint32_t maclo, machi; 136 struct mii_data * const mii = &sc->sc_mii; 137 struct ifnet * const ifp = &sc->sc_ec.ec_if; 138 prop_dictionary_t dict; 139 int s; 140 141 mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET); 142 sc->sc_mii_clk = mii_clk & 7; 143 144 dict = device_properties(sc->sc_dev); 145 prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL; 146 if (ea != NULL) { 147 /* 148 * If the MAC address is overriden by a device property, 149 * use that. 150 */ 151 KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); 152 KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); 153 memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN); 154 } else { 155 /* 156 * If we did not get an externaly configure address, 157 * try to read one from the current filter setup, 158 * before resetting the chip. 159 */ 160 maclo = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 161 AWIN_GMAC_MAC_ADDR0LO); 162 machi = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 163 AWIN_GMAC_MAC_ADDR0HI); 164 165 if (maclo == 0xffffffff && (machi & 0xffff) == 0xffff) { 166 /* fake MAC address */ 167 maclo = 0x00f2 | (cprng_strong32() << 16); 168 machi = cprng_strong32(); 169 } 170 171 enaddr[0] = maclo & 0x0ff; 172 enaddr[1] = (maclo >> 8) & 0x0ff; 173 enaddr[2] = (maclo >> 16) & 0x0ff; 174 enaddr[3] = (maclo >> 24) & 0x0ff; 175 enaddr[4] = machi & 0x0ff; 176 enaddr[5] = (machi >> 8) & 0x0ff; 177 } 178 179 /* 180 * Init chip and do initial setup 181 */ 182 if (dwc_gmac_reset(sc) != 0) 183 return; /* not much to cleanup, haven't attached yet */ 184 dwc_gmac_write_hwaddr(sc, enaddr); 185 aprint_normal_dev(sc->sc_dev, "Ethernet address: %s\n", 186 ether_sprintf(enaddr)); 187 188 /* 189 * Allocate Tx and Rx rings 190 */ 191 if (dwc_gmac_alloc_dma_rings(sc) != 0) { 192 aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n"); 193 goto fail; 194 } 195 196 if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) { 197 aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n"); 198 goto fail; 199 } 200 201 mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET); 202 if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) { 203 aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n"); 204 goto fail; 205 } 206 207 /* 208 * Prepare interface data 209 */ 210 ifp->if_softc = sc; 211 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 212 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 213 ifp->if_ioctl = dwc_gmac_ioctl; 214 ifp->if_start = dwc_gmac_start; 215 ifp->if_init = dwc_gmac_init; 216 ifp->if_stop = dwc_gmac_stop; 217 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 218 IFQ_SET_READY(&ifp->if_snd); 219 220 /* 221 * Attach MII subdevices 222 */ 223 sc->sc_ec.ec_mii = &sc->sc_mii; 224 ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); 225 mii->mii_ifp = ifp; 226 mii->mii_readreg = dwc_gmac_miibus_read_reg; 227 mii->mii_writereg = dwc_gmac_miibus_write_reg; 228 mii->mii_statchg = dwc_gmac_miibus_statchg; 229 mii_attach(sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 230 MIIF_DOPAUSE); 231 232 if (LIST_EMPTY(&mii->mii_phys)) { 233 aprint_error_dev(sc->sc_dev, "no PHY found!\n"); 234 ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_MANUAL, 0, NULL); 235 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_MANUAL); 236 } else { 237 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); 238 } 239 240 /* 241 * We can support 802.1Q VLAN-sized frames. 242 */ 243 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 244 245 /* 246 * Ready, attach interface 247 */ 248 if_attach(ifp); 249 ether_ifattach(ifp, enaddr); 250 ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb); 251 252 /* 253 * Enable interrupts 254 */ 255 s = splnet(); 256 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK, 257 AWIN_DEF_MAC_INTRMASK); 258 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE, 259 GMAC_DEF_DMA_INT_MASK); 260 splx(s); 261 262 return; 263 264 fail: 265 dwc_gmac_free_rx_ring(sc, &sc->sc_rxq); 266 dwc_gmac_free_tx_ring(sc, &sc->sc_txq); 267 } 268 269 270 271 static int 272 dwc_gmac_reset(struct dwc_gmac_softc *sc) 273 { 274 size_t cnt; 275 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 276 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) | GMAC_BUSMODE_RESET); 277 for (cnt = 0; cnt < 3000; cnt++) { 278 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) 279 & GMAC_BUSMODE_RESET) == 0) 280 return 0; 281 delay(10); 282 } 283 284 aprint_error_dev(sc->sc_dev, "reset timed out\n"); 285 return EIO; 286 } 287 288 static void 289 dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, 290 uint8_t enaddr[ETHER_ADDR_LEN]) 291 { 292 uint32_t lo, hi; 293 294 lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16) 295 | (enaddr[3] << 24); 296 hi = enaddr[4] | (enaddr[5] << 8); 297 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo); 298 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi); 299 } 300 301 static int 302 dwc_gmac_miibus_read_reg(device_t self, int phy, int reg) 303 { 304 struct dwc_gmac_softc * const sc = device_private(self); 305 uint16_t mii; 306 size_t cnt; 307 int rv = 0; 308 309 mii = __SHIFTIN(phy,GMAC_MII_PHY_MASK) 310 | __SHIFTIN(reg,GMAC_MII_REG_MASK) 311 | __SHIFTIN(sc->sc_mii_clk,GMAC_MII_CLKMASK) 312 | GMAC_MII_BUSY; 313 314 mutex_enter(&sc->sc_mdio_lock); 315 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii); 316 317 for (cnt = 0; cnt < 1000; cnt++) { 318 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 319 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) { 320 rv = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 321 AWIN_GMAC_MAC_MIIDATA); 322 break; 323 } 324 delay(10); 325 } 326 327 mutex_exit(&sc->sc_mdio_lock); 328 329 return rv; 330 } 331 332 static void 333 dwc_gmac_miibus_write_reg(device_t self, int phy, int reg, int val) 334 { 335 struct dwc_gmac_softc * const sc = device_private(self); 336 uint16_t mii; 337 size_t cnt; 338 339 mii = __SHIFTIN(phy,GMAC_MII_PHY_MASK) 340 | __SHIFTIN(reg,GMAC_MII_REG_MASK) 341 | __SHIFTIN(sc->sc_mii_clk,GMAC_MII_CLKMASK) 342 | GMAC_MII_BUSY | GMAC_MII_WRITE; 343 344 mutex_enter(&sc->sc_mdio_lock); 345 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIDATA, val); 346 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii); 347 348 for (cnt = 0; cnt < 1000; cnt++) { 349 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 350 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) 351 break; 352 delay(10); 353 } 354 355 mutex_exit(&sc->sc_mdio_lock); 356 } 357 358 static int 359 dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, 360 struct dwc_gmac_rx_ring *ring) 361 { 362 struct dwc_gmac_rx_data *data; 363 bus_addr_t physaddr; 364 const size_t descsize = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc); 365 int error, i, next; 366 367 ring->r_cur = ring->r_next = 0; 368 memset(ring->r_desc, 0, descsize); 369 370 /* 371 * Pre-allocate Rx buffers and populate Rx ring. 372 */ 373 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 374 struct dwc_gmac_dev_dmadesc *desc; 375 376 data = &sc->sc_rxq.r_data[i]; 377 378 MGETHDR(data->rd_m, M_DONTWAIT, MT_DATA); 379 if (data->rd_m == NULL) { 380 aprint_error_dev(sc->sc_dev, 381 "could not allocate rx mbuf #%d\n", i); 382 error = ENOMEM; 383 goto fail; 384 } 385 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 386 MCLBYTES, 0, BUS_DMA_NOWAIT, &data->rd_map); 387 if (error != 0) { 388 aprint_error_dev(sc->sc_dev, 389 "could not create DMA map\n"); 390 data->rd_map = NULL; 391 goto fail; 392 } 393 MCLGET(data->rd_m, M_DONTWAIT); 394 if (!(data->rd_m->m_flags & M_EXT)) { 395 aprint_error_dev(sc->sc_dev, 396 "could not allocate mbuf cluster #%d\n", i); 397 error = ENOMEM; 398 goto fail; 399 } 400 401 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 402 mtod(data->rd_m, void *), MCLBYTES, NULL, 403 BUS_DMA_READ | BUS_DMA_NOWAIT); 404 if (error != 0) { 405 aprint_error_dev(sc->sc_dev, 406 "could not load rx buf DMA map #%d", i); 407 goto fail; 408 } 409 physaddr = data->rd_map->dm_segs[0].ds_addr; 410 411 desc = &sc->sc_rxq.r_desc[i]; 412 desc->ddesc_data = htole32(physaddr); 413 next = RX_NEXT(i); 414 desc->ddesc_next = htole32(ring->r_physaddr 415 + next * sizeof(*desc)); 416 desc->ddesc_cntl = htole32( 417 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 418 DDESC_CNTL_RXCHAIN); 419 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 420 } 421 422 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 423 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 424 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 425 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 426 ring->r_physaddr); 427 428 return 0; 429 430 fail: 431 dwc_gmac_free_rx_ring(sc, ring); 432 return error; 433 } 434 435 static void 436 dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, 437 struct dwc_gmac_rx_ring *ring) 438 { 439 struct dwc_gmac_dev_dmadesc *desc; 440 int i; 441 442 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 443 desc = &sc->sc_rxq.r_desc[i]; 444 desc->ddesc_cntl = htole32( 445 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 446 DDESC_CNTL_RXCHAIN); 447 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 448 } 449 450 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 451 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 452 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 453 454 ring->r_cur = ring->r_next = 0; 455 /* reset DMA address to start of ring */ 456 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 457 sc->sc_rxq.r_physaddr); 458 } 459 460 static int 461 dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc) 462 { 463 const size_t descsize = AWGE_TOTAL_RING_COUNT * 464 sizeof(struct dwc_gmac_dev_dmadesc); 465 int error, nsegs; 466 void *rings; 467 468 error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0, 469 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map); 470 if (error != 0) { 471 aprint_error_dev(sc->sc_dev, 472 "could not create desc DMA map\n"); 473 sc->sc_dma_ring_map = NULL; 474 goto fail; 475 } 476 477 error = bus_dmamem_alloc(sc->sc_dmat, descsize, PAGE_SIZE, 0, 478 &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 479 if (error != 0) { 480 aprint_error_dev(sc->sc_dev, 481 "could not map DMA memory\n"); 482 goto fail; 483 } 484 485 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs, 486 descsize, &rings, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 487 if (error != 0) { 488 aprint_error_dev(sc->sc_dev, 489 "could not allocate DMA memory\n"); 490 goto fail; 491 } 492 493 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings, 494 descsize, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 495 if (error != 0) { 496 aprint_error_dev(sc->sc_dev, 497 "could not load desc DMA map\n"); 498 goto fail; 499 } 500 501 /* give first AWGE_RX_RING_COUNT to the RX side */ 502 sc->sc_rxq.r_desc = rings; 503 sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr; 504 505 /* and next rings to the TX side */ 506 sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT; 507 sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr + 508 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc); 509 510 return 0; 511 512 fail: 513 dwc_gmac_free_dma_rings(sc); 514 return error; 515 } 516 517 static void 518 dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc) 519 { 520 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 521 sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 522 bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map); 523 bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc, 524 AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc)); 525 bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1); 526 } 527 528 static void 529 dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring) 530 { 531 struct dwc_gmac_rx_data *data; 532 int i; 533 534 if (ring->r_desc == NULL) 535 return; 536 537 538 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 539 data = &ring->r_data[i]; 540 541 if (data->rd_map != NULL) { 542 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 543 AWGE_RX_RING_COUNT 544 *sizeof(struct dwc_gmac_dev_dmadesc), 545 BUS_DMASYNC_POSTREAD); 546 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 547 bus_dmamap_destroy(sc->sc_dmat, data->rd_map); 548 } 549 if (data->rd_m != NULL) 550 m_freem(data->rd_m); 551 } 552 } 553 554 static int 555 dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, 556 struct dwc_gmac_tx_ring *ring) 557 { 558 int i, error = 0; 559 560 ring->t_queued = 0; 561 ring->t_cur = ring->t_next = 0; 562 563 memset(ring->t_desc, 0, AWGE_TX_RING_COUNT*sizeof(*ring->t_desc)); 564 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 565 TX_DESC_OFFSET(0), 566 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 567 BUS_DMASYNC_POSTWRITE); 568 569 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 570 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 571 AWGE_TX_RING_COUNT, MCLBYTES, 0, 572 BUS_DMA_NOWAIT|BUS_DMA_COHERENT, 573 &ring->t_data[i].td_map); 574 if (error != 0) { 575 aprint_error_dev(sc->sc_dev, 576 "could not create TX DMA map #%d\n", i); 577 ring->t_data[i].td_map = NULL; 578 goto fail; 579 } 580 ring->t_desc[i].ddesc_next = htole32( 581 ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc) 582 *TX_NEXT(i)); 583 } 584 585 return 0; 586 587 fail: 588 dwc_gmac_free_tx_ring(sc, ring); 589 return error; 590 } 591 592 static void 593 dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops) 594 { 595 /* 'end' is pointing one descriptor beyound the last we want to sync */ 596 if (end > start) { 597 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 598 TX_DESC_OFFSET(start), 599 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(start), 600 ops); 601 return; 602 } 603 /* sync from 'start' to end of ring */ 604 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 605 TX_DESC_OFFSET(start), 606 TX_DESC_OFFSET(AWGE_TX_RING_COUNT)-TX_DESC_OFFSET(start), 607 ops); 608 /* sync from start of ring to 'end' */ 609 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 610 TX_DESC_OFFSET(0), 611 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0), 612 ops); 613 } 614 615 static void 616 dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, 617 struct dwc_gmac_tx_ring *ring) 618 { 619 int i; 620 621 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 622 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 623 624 if (data->td_m != NULL) { 625 bus_dmamap_sync(sc->sc_dmat, data->td_active, 626 0, data->td_active->dm_mapsize, 627 BUS_DMASYNC_POSTWRITE); 628 bus_dmamap_unload(sc->sc_dmat, data->td_active); 629 m_freem(data->td_m); 630 data->td_m = NULL; 631 } 632 } 633 634 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 635 TX_DESC_OFFSET(0), 636 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 637 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 638 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 639 sc->sc_txq.t_physaddr); 640 641 ring->t_queued = 0; 642 ring->t_cur = ring->t_next = 0; 643 } 644 645 static void 646 dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, 647 struct dwc_gmac_tx_ring *ring) 648 { 649 int i; 650 651 /* unload the maps */ 652 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 653 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 654 655 if (data->td_m != NULL) { 656 bus_dmamap_sync(sc->sc_dmat, data->td_active, 657 0, data->td_map->dm_mapsize, 658 BUS_DMASYNC_POSTWRITE); 659 bus_dmamap_unload(sc->sc_dmat, data->td_active); 660 m_freem(data->td_m); 661 data->td_m = NULL; 662 } 663 } 664 665 /* and actually free them */ 666 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 667 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 668 669 bus_dmamap_destroy(sc->sc_dmat, data->td_map); 670 } 671 } 672 673 static void 674 dwc_gmac_miibus_statchg(struct ifnet *ifp) 675 { 676 struct dwc_gmac_softc * const sc = ifp->if_softc; 677 struct mii_data * const mii = &sc->sc_mii; 678 uint32_t conf, flow; 679 680 /* 681 * Set MII or GMII interface based on the speed 682 * negotiated by the PHY. 683 */ 684 conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF); 685 conf &= ~(AWIN_GMAC_MAC_CONF_FES100|AWIN_GMAC_MAC_CONF_MIISEL 686 |AWIN_GMAC_MAC_CONF_FULLDPLX); 687 conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST 688 | AWIN_GMAC_MAC_CONF_DISABLERXOWN 689 | AWIN_GMAC_MAC_CONF_DISABLEJABBER 690 | AWIN_GMAC_MAC_CONF_ACS 691 | AWIN_GMAC_MAC_CONF_RXENABLE 692 | AWIN_GMAC_MAC_CONF_TXENABLE; 693 switch (IFM_SUBTYPE(mii->mii_media_active)) { 694 case IFM_10_T: 695 conf |= AWIN_GMAC_MAC_CONF_MIISEL; 696 break; 697 case IFM_100_TX: 698 conf |= AWIN_GMAC_MAC_CONF_FES100 | 699 AWIN_GMAC_MAC_CONF_MIISEL; 700 break; 701 case IFM_1000_T: 702 break; 703 } 704 705 flow = 0; 706 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) { 707 conf |= AWIN_GMAC_MAC_CONF_FULLDPLX; 708 flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE); 709 } 710 if (mii->mii_media_active & IFM_ETH_TXPAUSE) { 711 flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE; 712 } 713 if (mii->mii_media_active & IFM_ETH_RXPAUSE) { 714 flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE; 715 } 716 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 717 AWIN_GMAC_MAC_FLOWCTRL, flow); 718 719 #ifdef DWC_GMAC_DEBUG 720 aprint_normal_dev(sc->sc_dev, 721 "setting MAC conf register: %08x\n", conf); 722 #endif 723 724 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 725 AWIN_GMAC_MAC_CONF, conf); 726 } 727 728 static int 729 dwc_gmac_init(struct ifnet *ifp) 730 { 731 struct dwc_gmac_softc *sc = ifp->if_softc; 732 uint32_t ffilt; 733 734 if (ifp->if_flags & IFF_RUNNING) 735 return 0; 736 737 dwc_gmac_stop(ifp, 0); 738 739 /* 740 * Configure DMA burst/transfer mode and RX/TX priorities. 741 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented. 742 */ 743 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 744 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL | 745 __SHIFTIN(2, GMAC_BUSMODE_RPBL) | 746 __SHIFTIN(2, GMAC_BUSMODE_PBL)); 747 748 /* 749 * Set up address filter 750 */ 751 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 752 if (ifp->if_flags & IFF_PROMISC) { 753 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 754 } else { 755 ffilt &= ~AWIN_GMAC_MAC_FFILT_PR; 756 } 757 if (ifp->if_flags & IFF_BROADCAST) { 758 ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF; 759 } else { 760 ffilt |= AWIN_GMAC_MAC_FFILT_DBF; 761 } 762 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 763 764 /* 765 * Set up multicast filter 766 */ 767 dwc_gmac_setmulti(sc); 768 769 /* 770 * Set up dma pointer for RX and TX ring 771 */ 772 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 773 sc->sc_rxq.r_physaddr); 774 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 775 sc->sc_txq.t_physaddr); 776 777 /* 778 * Start RX/TX part 779 */ 780 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 781 AWIN_GMAC_DMA_OPMODE, GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART | 782 GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD); 783 784 ifp->if_flags |= IFF_RUNNING; 785 ifp->if_flags &= ~IFF_OACTIVE; 786 787 return 0; 788 } 789 790 static void 791 dwc_gmac_start(struct ifnet *ifp) 792 { 793 struct dwc_gmac_softc *sc = ifp->if_softc; 794 int old = sc->sc_txq.t_queued; 795 int start = sc->sc_txq.t_cur; 796 struct mbuf *m0; 797 798 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 799 return; 800 801 for (;;) { 802 IFQ_POLL(&ifp->if_snd, m0); 803 if (m0 == NULL) 804 break; 805 if (dwc_gmac_queue(sc, m0) != 0) { 806 ifp->if_flags |= IFF_OACTIVE; 807 break; 808 } 809 IFQ_DEQUEUE(&ifp->if_snd, m0); 810 bpf_mtap(ifp, m0); 811 if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) { 812 ifp->if_flags |= IFF_OACTIVE; 813 break; 814 } 815 } 816 817 if (sc->sc_txq.t_queued != old) { 818 /* packets have been queued, kick it off */ 819 dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur, 820 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 821 822 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 823 AWIN_GMAC_DMA_TXPOLL, ~0U); 824 #ifdef DWC_GMAC_DEBUG 825 dwc_dump_status(sc); 826 #endif 827 } 828 } 829 830 static void 831 dwc_gmac_stop(struct ifnet *ifp, int disable) 832 { 833 struct dwc_gmac_softc *sc = ifp->if_softc; 834 835 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 836 AWIN_GMAC_DMA_OPMODE, 837 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 838 AWIN_GMAC_DMA_OPMODE) 839 & ~(GMAC_DMA_OP_TXSTART|GMAC_DMA_OP_RXSTART)); 840 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 841 AWIN_GMAC_DMA_OPMODE, 842 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 843 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX); 844 845 mii_down(&sc->sc_mii); 846 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq); 847 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); 848 } 849 850 /* 851 * Add m0 to the TX ring 852 */ 853 static int 854 dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0) 855 { 856 struct dwc_gmac_dev_dmadesc *desc = NULL; 857 struct dwc_gmac_tx_data *data = NULL; 858 bus_dmamap_t map; 859 uint32_t flags, len, status; 860 int error, i, first; 861 862 #ifdef DWC_GMAC_DEBUG 863 aprint_normal_dev(sc->sc_dev, 864 "dwc_gmac_queue: adding mbuf chain %p\n", m0); 865 #endif 866 867 first = sc->sc_txq.t_cur; 868 map = sc->sc_txq.t_data[first].td_map; 869 870 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0, 871 BUS_DMA_WRITE|BUS_DMA_NOWAIT); 872 if (error != 0) { 873 aprint_error_dev(sc->sc_dev, "could not map mbuf " 874 "(len: %d, error %d)\n", m0->m_pkthdr.len, error); 875 return error; 876 } 877 878 if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) { 879 bus_dmamap_unload(sc->sc_dmat, map); 880 return ENOBUFS; 881 } 882 883 flags = DDESC_CNTL_TXFIRST|DDESC_CNTL_TXCHAIN; 884 status = 0; 885 for (i = 0; i < map->dm_nsegs; i++) { 886 data = &sc->sc_txq.t_data[sc->sc_txq.t_cur]; 887 desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur]; 888 889 desc->ddesc_data = htole32(map->dm_segs[i].ds_addr); 890 len = __SHIFTIN(map->dm_segs[i].ds_len, DDESC_CNTL_SIZE1MASK); 891 892 #ifdef DWC_GMAC_DEBUG 893 aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx " 894 "len %lu (flags: %08x, len: %08x)\n", sc->sc_txq.t_cur, 895 (unsigned long)map->dm_segs[i].ds_addr, 896 (unsigned long)map->dm_segs[i].ds_len, 897 flags, len); 898 #endif 899 900 desc->ddesc_cntl = htole32(len|flags); 901 flags &= ~DDESC_CNTL_TXFIRST; 902 903 /* 904 * Defer passing ownership of the first descriptor 905 * until we are done. 906 */ 907 desc->ddesc_status = htole32(status); 908 status |= DDESC_STATUS_OWNEDBYDEV; 909 910 sc->sc_txq.t_queued++; 911 sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur); 912 } 913 914 desc->ddesc_cntl |= htole32(DDESC_CNTL_TXLAST|DDESC_CNTL_TXINT); 915 916 data->td_m = m0; 917 data->td_active = map; 918 919 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 920 BUS_DMASYNC_PREWRITE); 921 922 /* Pass first to device */ 923 sc->sc_txq.t_desc[first].ddesc_status = 924 htole32(DDESC_STATUS_OWNEDBYDEV); 925 926 return 0; 927 } 928 929 /* 930 * If the interface is up and running, only modify the receive 931 * filter when setting promiscuous or debug mode. Otherwise fall 932 * through to ether_ioctl, which will reset the chip. 933 */ 934 static int 935 dwc_gmac_ifflags_cb(struct ethercom *ec) 936 { 937 struct ifnet *ifp = &ec->ec_if; 938 struct dwc_gmac_softc *sc = ifp->if_softc; 939 int change = ifp->if_flags ^ sc->sc_if_flags; 940 941 if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0) 942 return ENETRESET; 943 if ((change & IFF_PROMISC) != 0) 944 dwc_gmac_setmulti(sc); 945 return 0; 946 } 947 948 static int 949 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 950 { 951 struct dwc_gmac_softc *sc = ifp->if_softc; 952 int s, error = 0; 953 954 s = splnet(); 955 956 if ((error = ether_ioctl(ifp, cmd, data)) == ENETRESET) { 957 error = 0; 958 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 959 ; 960 else if (ifp->if_flags & IFF_RUNNING) { 961 /* 962 * Multicast list has changed; set the hardware filter 963 * accordingly. 964 */ 965 dwc_gmac_setmulti(sc); 966 } 967 } 968 969 /* Try to get things going again */ 970 if (ifp->if_flags & IFF_UP) 971 dwc_gmac_start(ifp); 972 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 973 splx(s); 974 return error; 975 } 976 977 static void 978 dwc_gmac_tx_intr(struct dwc_gmac_softc *sc) 979 { 980 struct ifnet *ifp = &sc->sc_ec.ec_if; 981 struct dwc_gmac_tx_data *data; 982 struct dwc_gmac_dev_dmadesc *desc; 983 uint32_t status; 984 int i, nsegs; 985 986 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) { 987 #ifdef DWC_GMAC_DEBUG 988 aprint_normal_dev(sc->sc_dev, 989 "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n", 990 i, sc->sc_txq.t_queued); 991 #endif 992 993 /* 994 * i+1 does not need to be a valid descriptor, 995 * this is just a special notion to just sync 996 * a single tx descriptor (i) 997 */ 998 dwc_gmac_txdesc_sync(sc, i, i+1, 999 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1000 1001 desc = &sc->sc_txq.t_desc[i]; 1002 status = le32toh(desc->ddesc_status); 1003 if (status & DDESC_STATUS_OWNEDBYDEV) 1004 break; 1005 1006 data = &sc->sc_txq.t_data[i]; 1007 if (data->td_m == NULL) 1008 continue; 1009 1010 ifp->if_opackets++; 1011 nsegs = data->td_active->dm_nsegs; 1012 bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, 1013 data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1014 bus_dmamap_unload(sc->sc_dmat, data->td_active); 1015 1016 #ifdef DWC_GMAC_DEBUG 1017 aprint_normal_dev(sc->sc_dev, 1018 "dwc_gmac_tx_intr: done with packet at desc #%d, " 1019 "freeing mbuf %p\n", i, data->td_m); 1020 #endif 1021 1022 m_freem(data->td_m); 1023 data->td_m = NULL; 1024 1025 sc->sc_txq.t_queued -= nsegs; 1026 } 1027 1028 sc->sc_txq.t_next = i; 1029 1030 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) { 1031 ifp->if_flags &= ~IFF_OACTIVE; 1032 } 1033 } 1034 1035 static void 1036 dwc_gmac_rx_intr(struct dwc_gmac_softc *sc) 1037 { 1038 struct ifnet *ifp = &sc->sc_ec.ec_if; 1039 struct dwc_gmac_dev_dmadesc *desc; 1040 struct dwc_gmac_rx_data *data; 1041 bus_addr_t physaddr; 1042 uint32_t status; 1043 struct mbuf *m, *mnew; 1044 int i, len, error; 1045 1046 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { 1047 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1048 RX_DESC_OFFSET(i), sizeof(*desc), 1049 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1050 desc = &sc->sc_rxq.r_desc[i]; 1051 data = &sc->sc_rxq.r_data[i]; 1052 1053 status = le32toh(desc->ddesc_status); 1054 if (status & DDESC_STATUS_OWNEDBYDEV) 1055 break; 1056 1057 if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) { 1058 #ifdef DWC_GMAC_DEBUG 1059 aprint_normal_dev(sc->sc_dev, 1060 "RX error: descriptor status %08x, skipping\n", 1061 status); 1062 #endif 1063 ifp->if_ierrors++; 1064 goto skip; 1065 } 1066 1067 len = __SHIFTOUT(status, DDESC_STATUS_FRMLENMSK); 1068 1069 #ifdef DWC_GMAC_DEBUG 1070 aprint_normal_dev(sc->sc_dev, 1071 "rx int: device is done with descriptor #%d, len: %d\n", 1072 i, len); 1073 #endif 1074 1075 /* 1076 * Try to get a new mbuf before passing this one 1077 * up, if that fails, drop the packet and reuse 1078 * the existing one. 1079 */ 1080 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1081 if (mnew == NULL) { 1082 ifp->if_ierrors++; 1083 goto skip; 1084 } 1085 MCLGET(mnew, M_DONTWAIT); 1086 if ((mnew->m_flags & M_EXT) == 0) { 1087 m_freem(mnew); 1088 ifp->if_ierrors++; 1089 goto skip; 1090 } 1091 1092 /* unload old DMA map */ 1093 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1094 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1095 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 1096 1097 /* and reload with new mbuf */ 1098 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 1099 mtod(mnew, void*), MCLBYTES, NULL, 1100 BUS_DMA_READ | BUS_DMA_NOWAIT); 1101 if (error != 0) { 1102 m_freem(mnew); 1103 /* try to reload old mbuf */ 1104 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 1105 mtod(data->rd_m, void*), MCLBYTES, NULL, 1106 BUS_DMA_READ | BUS_DMA_NOWAIT); 1107 if (error != 0) { 1108 panic("%s: could not load old rx mbuf", 1109 device_xname(sc->sc_dev)); 1110 } 1111 ifp->if_ierrors++; 1112 goto skip; 1113 } 1114 physaddr = data->rd_map->dm_segs[0].ds_addr; 1115 1116 /* 1117 * New mbuf loaded, update RX ring and continue 1118 */ 1119 m = data->rd_m; 1120 data->rd_m = mnew; 1121 desc->ddesc_data = htole32(physaddr); 1122 1123 /* finalize mbuf */ 1124 m->m_pkthdr.len = m->m_len = len; 1125 m->m_pkthdr.rcvif = ifp; 1126 m->m_flags |= M_HASFCS; 1127 1128 bpf_mtap(ifp, m); 1129 ifp->if_ipackets++; 1130 (*ifp->if_input)(ifp, m); 1131 1132 skip: 1133 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1134 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1135 desc->ddesc_cntl = htole32( 1136 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 1137 DDESC_CNTL_RXCHAIN); 1138 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 1139 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1140 RX_DESC_OFFSET(i), sizeof(*desc), 1141 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1142 } 1143 1144 /* update RX pointer */ 1145 sc->sc_rxq.r_cur = i; 1146 1147 } 1148 1149 /* 1150 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal 1151 */ 1152 static uint32_t 1153 bitrev32(uint32_t x) 1154 { 1155 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); 1156 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); 1157 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); 1158 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); 1159 1160 return (x >> 16) | (x << 16); 1161 } 1162 1163 static void 1164 dwc_gmac_setmulti(struct dwc_gmac_softc *sc) 1165 { 1166 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1167 struct ether_multi *enm; 1168 struct ether_multistep step; 1169 uint32_t hashes[2] = { 0, 0 }; 1170 uint32_t ffilt, h; 1171 int mcnt, s; 1172 1173 s = splnet(); 1174 1175 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 1176 1177 if (ifp->if_flags & IFF_PROMISC) { 1178 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 1179 goto special_filter; 1180 } 1181 1182 ifp->if_flags &= ~IFF_ALLMULTI; 1183 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM|AWIN_GMAC_MAC_FFILT_PR); 1184 1185 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0); 1186 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0); 1187 1188 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); 1189 mcnt = 0; 1190 while (enm != NULL) { 1191 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1192 ETHER_ADDR_LEN) != 0) { 1193 ffilt |= AWIN_GMAC_MAC_FFILT_PM; 1194 ifp->if_flags |= IFF_ALLMULTI; 1195 goto special_filter; 1196 } 1197 1198 h = bitrev32( 1199 ~ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) 1200 ) >> 26; 1201 hashes[h >> 5] |= (1 << (h & 0x1f)); 1202 1203 mcnt++; 1204 ETHER_NEXT_MULTI(step, enm); 1205 } 1206 1207 if (mcnt) 1208 ffilt |= AWIN_GMAC_MAC_FFILT_HMC; 1209 else 1210 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC; 1211 1212 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 1213 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1214 hashes[0]); 1215 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1216 hashes[1]); 1217 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1218 1219 splx(s); 1220 1221 #ifdef DWC_GMAC_DEBUG 1222 dwc_gmac_dump_ffilt(sc, ffilt); 1223 #endif 1224 return; 1225 1226 special_filter: 1227 #ifdef DWC_GMAC_DEBUG 1228 dwc_gmac_dump_ffilt(sc, ffilt); 1229 #endif 1230 /* no MAC hashes, ALLMULTI or PROMISC */ 1231 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, 1232 ffilt); 1233 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1234 0xffffffff); 1235 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1236 0xffffffff); 1237 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1238 splx(s); 1239 } 1240 1241 int 1242 dwc_gmac_intr(struct dwc_gmac_softc *sc) 1243 { 1244 uint32_t status, dma_status; 1245 int rv = 0; 1246 1247 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR); 1248 if (status & AWIN_GMAC_MII_IRQ) { 1249 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1250 AWIN_GMAC_MII_STATUS); 1251 rv = 1; 1252 mii_pollstat(&sc->sc_mii); 1253 } 1254 1255 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1256 AWIN_GMAC_DMA_STATUS); 1257 1258 if (dma_status & (GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE)) 1259 rv = 1; 1260 1261 if (dma_status & GMAC_DMA_INT_TIE) 1262 dwc_gmac_tx_intr(sc); 1263 1264 if (dma_status & GMAC_DMA_INT_RIE) 1265 dwc_gmac_rx_intr(sc); 1266 1267 /* 1268 * Check error conditions 1269 */ 1270 if (dma_status & GMAC_DMA_INT_ERRORS) { 1271 sc->sc_ec.ec_if.if_oerrors++; 1272 #ifdef DWC_GMAC_DEBUG 1273 dwc_dump_and_abort(sc, "interrupt error condition"); 1274 #endif 1275 } 1276 1277 /* ack interrupt */ 1278 if (dma_status) 1279 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1280 AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK); 1281 1282 /* 1283 * Get more packets 1284 */ 1285 if (rv) 1286 sc->sc_ec.ec_if.if_start(&sc->sc_ec.ec_if); 1287 1288 return rv; 1289 } 1290 1291 #ifdef DWC_GMAC_DEBUG 1292 static void 1293 dwc_gmac_dump_dma(struct dwc_gmac_softc *sc) 1294 { 1295 aprint_normal_dev(sc->sc_dev, "busmode: %08x\n", 1296 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)); 1297 aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n", 1298 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL)); 1299 aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n", 1300 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL)); 1301 aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n", 1302 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR)); 1303 aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n", 1304 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR)); 1305 aprint_normal_dev(sc->sc_dev, "status: %08x\n", 1306 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS)); 1307 aprint_normal_dev(sc->sc_dev, "op mode: %08x\n", 1308 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE)); 1309 aprint_normal_dev(sc->sc_dev, "int enable: %08x\n", 1310 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE)); 1311 aprint_normal_dev(sc->sc_dev, "cur tx: %08x\n", 1312 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC)); 1313 aprint_normal_dev(sc->sc_dev, "cur rx: %08x\n", 1314 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC)); 1315 aprint_normal_dev(sc->sc_dev, "cur tx buffer: %08x\n", 1316 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR)); 1317 aprint_normal_dev(sc->sc_dev, "cur rx buffer: %08x\n", 1318 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR)); 1319 } 1320 1321 static void 1322 dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc) 1323 { 1324 int i; 1325 1326 aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n", 1327 sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued); 1328 aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n"); 1329 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 1330 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i]; 1331 aprint_normal("#%d (%08lx): status: %08x cntl: %08x " 1332 "data: %08x next: %08x\n", 1333 i, sc->sc_txq.t_physaddr + 1334 i*sizeof(struct dwc_gmac_dev_dmadesc), 1335 le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl), 1336 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1337 } 1338 } 1339 1340 static void 1341 dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc) 1342 { 1343 int i; 1344 1345 aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n", 1346 sc->sc_rxq.r_cur, sc->sc_rxq.r_next); 1347 aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n"); 1348 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 1349 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i]; 1350 aprint_normal("#%d (%08lx): status: %08x cntl: %08x " 1351 "data: %08x next: %08x\n", 1352 i, sc->sc_rxq.r_physaddr + 1353 i*sizeof(struct dwc_gmac_dev_dmadesc), 1354 le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl), 1355 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1356 } 1357 } 1358 1359 static void 1360 dwc_dump_status(struct dwc_gmac_softc *sc) 1361 { 1362 uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1363 AWIN_GMAC_MAC_INTR); 1364 uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1365 AWIN_GMAC_DMA_STATUS); 1366 char buf[200]; 1367 1368 /* print interrupt state */ 1369 snprintb(buf, sizeof(buf), "\177\20" 1370 "b\x10""NI\0" 1371 "b\x0f""AI\0" 1372 "b\x0e""ER\0" 1373 "b\x0d""FB\0" 1374 "b\x0a""ET\0" 1375 "b\x09""RW\0" 1376 "b\x08""RS\0" 1377 "b\x07""RU\0" 1378 "b\x06""RI\0" 1379 "b\x05""UN\0" 1380 "b\x04""OV\0" 1381 "b\x03""TJ\0" 1382 "b\x02""TU\0" 1383 "b\x01""TS\0" 1384 "b\x00""TI\0" 1385 "\0", dma_status); 1386 aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n", 1387 status, buf); 1388 } 1389 1390 static void 1391 dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg) 1392 { 1393 dwc_dump_status(sc); 1394 dwc_gmac_dump_ffilt(sc, 1395 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT)); 1396 dwc_gmac_dump_dma(sc); 1397 dwc_gmac_dump_tx_desc(sc); 1398 dwc_gmac_dump_rx_desc(sc); 1399 1400 panic("%s", msg); 1401 } 1402 1403 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt) 1404 { 1405 char buf[200]; 1406 1407 /* print filter setup */ 1408 snprintb(buf, sizeof(buf), "\177\20" 1409 "b\x1f""RA\0" 1410 "b\x0a""HPF\0" 1411 "b\x09""SAF\0" 1412 "b\x08""SAIF\0" 1413 "b\x05""DBF\0" 1414 "b\x04""PM\0" 1415 "b\x03""DAIF\0" 1416 "b\x02""HMC\0" 1417 "b\x01""HUC\0" 1418 "b\x00""PR\0" 1419 "\0", ffilt); 1420 aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf); 1421 } 1422 #endif 1423