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