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