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