1 /* $NetBSD: dwc_gmac.c,v 1.95 2024/09/07 06:17:37 andvar 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.95 2024/09/07 06:17:37 andvar 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 if (data->rd_m->m_len > AWGE_MAX_PACKET) { 525 data->rd_m->m_len = data->rd_m->m_pkthdr.len 526 = AWGE_MAX_PACKET; 527 } 528 529 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, 530 data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT); 531 if (error != 0) { 532 aprint_error_dev(sc->sc_dev, 533 "could not load rx buf DMA map #%d", i); 534 goto fail; 535 } 536 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 537 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 538 physaddr = data->rd_map->dm_segs[0].ds_addr; 539 540 desc = &sc->sc_rxq.r_desc[i]; 541 desc->ddesc_data = htole32(physaddr); 542 next = RX_NEXT(i); 543 desc->ddesc_next = htole32(ring->r_physaddr 544 + next * sizeof(*desc)); 545 sc->sc_descm->rx_init_flags(desc); 546 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 547 sc->sc_descm->rx_set_owned_by_dev(desc); 548 } 549 550 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 551 RX_DESC_OFFSET(0), 552 AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 553 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 554 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 555 ring->r_physaddr); 556 557 return 0; 558 559 fail: 560 dwc_gmac_free_rx_ring(sc, ring); 561 return error; 562 } 563 564 static void 565 dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, 566 struct dwc_gmac_rx_ring *ring) 567 { 568 struct dwc_gmac_dev_dmadesc *desc; 569 struct dwc_gmac_rx_data *data; 570 int i; 571 572 mutex_enter(&ring->r_mtx); 573 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 574 desc = &sc->sc_rxq.r_desc[i]; 575 data = &sc->sc_rxq.r_data[i]; 576 sc->sc_descm->rx_init_flags(desc); 577 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 578 sc->sc_descm->rx_set_owned_by_dev(desc); 579 } 580 581 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 582 AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 583 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 584 585 ring->r_cur = ring->r_next = 0; 586 /* reset DMA address to start of ring */ 587 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 588 sc->sc_rxq.r_physaddr); 589 mutex_exit(&ring->r_mtx); 590 } 591 592 static int 593 dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc) 594 { 595 const size_t ringsize = AWGE_TOTAL_RING_COUNT * 596 sizeof(struct dwc_gmac_dev_dmadesc); 597 int error, nsegs; 598 void *rings; 599 600 error = bus_dmamap_create(sc->sc_dmat, ringsize, 1, ringsize, 0, 601 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map); 602 if (error != 0) { 603 aprint_error_dev(sc->sc_dev, 604 "could not create desc DMA map\n"); 605 sc->sc_dma_ring_map = NULL; 606 goto fail; 607 } 608 609 error = bus_dmamem_alloc(sc->sc_dmat, ringsize, PAGE_SIZE, 0, 610 &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT |BUS_DMA_COHERENT); 611 if (error != 0) { 612 aprint_error_dev(sc->sc_dev, 613 "could not map DMA memory\n"); 614 goto fail; 615 } 616 617 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs, 618 ringsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 619 if (error != 0) { 620 aprint_error_dev(sc->sc_dev, 621 "could not allocate DMA memory\n"); 622 goto fail; 623 } 624 625 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings, 626 ringsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 627 if (error != 0) { 628 aprint_error_dev(sc->sc_dev, 629 "could not load desc DMA map\n"); 630 goto fail; 631 } 632 633 /* give first AWGE_RX_RING_COUNT to the RX side */ 634 sc->sc_rxq.r_desc = rings; 635 sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr; 636 637 /* and next rings to the TX side */ 638 sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT; 639 sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr + 640 AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc); 641 642 return 0; 643 644 fail: 645 dwc_gmac_free_dma_rings(sc); 646 return error; 647 } 648 649 static void 650 dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc) 651 { 652 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 653 sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 654 bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map); 655 bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc, 656 AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc)); 657 bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1); 658 } 659 660 static void 661 dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring) 662 { 663 struct dwc_gmac_rx_data *data; 664 int i; 665 666 if (ring->r_desc == NULL) 667 return; 668 669 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 670 data = &ring->r_data[i]; 671 672 if (data->rd_map != NULL) { 673 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 674 AWGE_RX_RING_COUNT 675 * sizeof(struct dwc_gmac_dev_dmadesc), 676 BUS_DMASYNC_POSTREAD); 677 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 678 bus_dmamap_destroy(sc->sc_dmat, data->rd_map); 679 } 680 m_freem(data->rd_m); 681 } 682 } 683 684 static int 685 dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, 686 struct dwc_gmac_tx_ring *ring) 687 { 688 int i, error = 0; 689 690 ring->t_queued = 0; 691 ring->t_cur = ring->t_next = 0; 692 693 memset(ring->t_desc, 0, AWGE_TX_RING_COUNT * sizeof(*ring->t_desc)); 694 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 695 TX_DESC_OFFSET(0), 696 AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 697 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 698 699 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 700 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 701 AWGE_TX_RING_COUNT, MCLBYTES, 0, 702 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 703 &ring->t_data[i].td_map); 704 if (error != 0) { 705 aprint_error_dev(sc->sc_dev, 706 "could not create TX DMA map #%d\n", i); 707 ring->t_data[i].td_map = NULL; 708 goto fail; 709 } 710 ring->t_desc[i].ddesc_next = htole32( 711 ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc) 712 * TX_NEXT(i)); 713 } 714 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 715 TX_DESC_OFFSET(0), 716 AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 717 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 718 719 return 0; 720 721 fail: 722 dwc_gmac_free_tx_ring(sc, ring); 723 return error; 724 } 725 726 static void 727 dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops) 728 { 729 /* 'end' is pointing one descriptor beyond the last we want to sync */ 730 if (end > start) { 731 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 732 TX_DESC_OFFSET(start), 733 TX_DESC_OFFSET(end) - TX_DESC_OFFSET(start), 734 ops); 735 return; 736 } 737 /* sync from 'start' to end of ring */ 738 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 739 TX_DESC_OFFSET(start), 740 TX_DESC_OFFSET(AWGE_TX_RING_COUNT) - TX_DESC_OFFSET(start), 741 ops); 742 if (TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0) > 0) { 743 /* sync from start of ring to 'end' */ 744 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 745 TX_DESC_OFFSET(0), 746 TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0), 747 ops); 748 } 749 } 750 751 static void 752 dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, 753 struct dwc_gmac_tx_ring *ring) 754 { 755 int i; 756 757 mutex_enter(&ring->t_mtx); 758 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 759 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 760 761 if (data->td_m != NULL) { 762 bus_dmamap_sync(sc->sc_dmat, data->td_active, 763 0, data->td_active->dm_mapsize, 764 BUS_DMASYNC_POSTWRITE); 765 bus_dmamap_unload(sc->sc_dmat, data->td_active); 766 m_freem(data->td_m); 767 data->td_m = NULL; 768 } 769 } 770 771 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 772 TX_DESC_OFFSET(0), 773 AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 774 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 775 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 776 sc->sc_txq.t_physaddr); 777 778 ring->t_queued = 0; 779 ring->t_cur = ring->t_next = 0; 780 mutex_exit(&ring->t_mtx); 781 } 782 783 static void 784 dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, 785 struct dwc_gmac_tx_ring *ring) 786 { 787 int i; 788 789 /* unload the maps */ 790 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 791 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 792 793 if (data->td_m != NULL) { 794 bus_dmamap_sync(sc->sc_dmat, data->td_active, 795 0, data->td_map->dm_mapsize, 796 BUS_DMASYNC_POSTWRITE); 797 bus_dmamap_unload(sc->sc_dmat, data->td_active); 798 m_freem(data->td_m); 799 data->td_m = NULL; 800 } 801 } 802 803 /* and actually free them */ 804 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 805 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 806 807 bus_dmamap_destroy(sc->sc_dmat, data->td_map); 808 } 809 } 810 811 static void 812 dwc_gmac_miibus_statchg(struct ifnet *ifp) 813 { 814 struct dwc_gmac_softc * const sc = ifp->if_softc; 815 struct mii_data * const mii = &sc->sc_mii; 816 uint32_t conf, flow; 817 818 /* 819 * Set MII or GMII interface based on the speed 820 * negotiated by the PHY. 821 */ 822 conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF); 823 conf &= ~(AWIN_GMAC_MAC_CONF_FES100 | AWIN_GMAC_MAC_CONF_MIISEL 824 | AWIN_GMAC_MAC_CONF_FULLDPLX); 825 conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST 826 | AWIN_GMAC_MAC_CONF_DISABLERXOWN 827 | AWIN_GMAC_MAC_CONF_DISABLEJABBER 828 | AWIN_GMAC_MAC_CONF_RXENABLE 829 | AWIN_GMAC_MAC_CONF_TXENABLE; 830 switch (IFM_SUBTYPE(mii->mii_media_active)) { 831 case IFM_10_T: 832 conf |= AWIN_GMAC_MAC_CONF_MIISEL; 833 break; 834 case IFM_100_TX: 835 conf |= AWIN_GMAC_MAC_CONF_FES100 | 836 AWIN_GMAC_MAC_CONF_MIISEL; 837 break; 838 case IFM_1000_T: 839 break; 840 } 841 if (sc->sc_set_speed) 842 sc->sc_set_speed(sc, IFM_SUBTYPE(mii->mii_media_active)); 843 844 flow = 0; 845 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) { 846 conf |= AWIN_GMAC_MAC_CONF_FULLDPLX; 847 flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE); 848 } 849 if (mii->mii_media_active & IFM_ETH_TXPAUSE) { 850 flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE; 851 } 852 if (mii->mii_media_active & IFM_ETH_RXPAUSE) { 853 flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE; 854 } 855 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 856 AWIN_GMAC_MAC_FLOWCTRL, flow); 857 858 #ifdef DWC_GMAC_DEBUG 859 aprint_normal_dev(sc->sc_dev, 860 "setting MAC conf register: %08x\n", conf); 861 #endif 862 863 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 864 AWIN_GMAC_MAC_CONF, conf); 865 } 866 867 static int 868 dwc_gmac_init(struct ifnet *ifp) 869 { 870 struct dwc_gmac_softc * const sc = ifp->if_softc; 871 uint32_t ffilt; 872 873 ASSERT_SLEEPABLE(); 874 KASSERT(IFNET_LOCKED(ifp)); 875 KASSERT(ifp == &sc->sc_ec.ec_if); 876 877 dwc_gmac_stop(ifp, 0); 878 879 /* 880 * Configure DMA burst/transfer mode and RX/TX priorities. 881 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented. 882 */ 883 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 884 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL | 885 __SHIFTIN(2, GMAC_BUSMODE_RPBL) | 886 __SHIFTIN(2, GMAC_BUSMODE_PBL)); 887 888 /* 889 * Set up address filter 890 */ 891 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 892 if (ifp->if_flags & IFF_PROMISC) { 893 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 894 } else { 895 ffilt &= ~AWIN_GMAC_MAC_FFILT_PR; 896 } 897 if (ifp->if_flags & IFF_BROADCAST) { 898 ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF; 899 } else { 900 ffilt |= AWIN_GMAC_MAC_FFILT_DBF; 901 } 902 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 903 904 /* 905 * Set up multicast filter 906 */ 907 mutex_enter(sc->sc_mcast_lock); 908 dwc_gmac_setmulti(sc); 909 mutex_exit(sc->sc_mcast_lock); 910 911 /* 912 * Set up dma pointer for RX and TX ring 913 */ 914 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 915 sc->sc_rxq.r_physaddr); 916 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 917 sc->sc_txq.t_physaddr); 918 919 /* 920 * Start RX/TX part 921 */ 922 uint32_t opmode = GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART; 923 if ((sc->sc_flags & DWC_GMAC_FORCE_THRESH_DMA_MODE) == 0) { 924 opmode |= GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD; 925 } 926 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE, opmode); 927 #ifdef DWC_GMAC_DEBUG 928 aprint_normal_dev(sc->sc_dev, 929 "setting DMA opmode register: %08x\n", opmode); 930 #endif 931 932 ifp->if_flags |= IFF_RUNNING; 933 sc->sc_if_flags = ifp->if_flags; 934 935 mutex_enter(sc->sc_intr_lock); 936 sc->sc_stopping = false; 937 mutex_exit(sc->sc_intr_lock); 938 939 mutex_enter(&sc->sc_txq.t_mtx); 940 sc->sc_txbusy = false; 941 mutex_exit(&sc->sc_txq.t_mtx); 942 943 return 0; 944 } 945 946 static void 947 dwc_gmac_start(struct ifnet *ifp) 948 { 949 struct dwc_gmac_softc * const sc = ifp->if_softc; 950 KASSERT(if_is_mpsafe(ifp)); 951 952 mutex_enter(sc->sc_intr_lock); 953 if (!sc->sc_stopping) { 954 dwc_gmac_start_locked(ifp); 955 } 956 mutex_exit(sc->sc_intr_lock); 957 } 958 959 static void 960 dwc_gmac_start_locked(struct ifnet *ifp) 961 { 962 struct dwc_gmac_softc * const sc = ifp->if_softc; 963 int old = sc->sc_txq.t_queued; 964 int start = sc->sc_txq.t_cur; 965 struct mbuf *m0; 966 967 KASSERT(mutex_owned(sc->sc_intr_lock)); 968 969 mutex_enter(&sc->sc_txq.t_mtx); 970 if (sc->sc_txbusy) { 971 mutex_exit(&sc->sc_txq.t_mtx); 972 return; 973 } 974 975 for (;;) { 976 IFQ_POLL(&ifp->if_snd, m0); 977 if (m0 == NULL) 978 break; 979 if (dwc_gmac_queue(sc, m0) != 0) { 980 sc->sc_txbusy = true; 981 break; 982 } 983 IFQ_DEQUEUE(&ifp->if_snd, m0); 984 bpf_mtap(ifp, m0, BPF_D_OUT); 985 if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) { 986 sc->sc_txbusy = true; 987 break; 988 } 989 } 990 991 if (sc->sc_txq.t_queued != old) { 992 /* packets have been queued, kick it off */ 993 dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur, 994 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 995 996 #ifdef DWC_GMAC_DEBUG 997 dwc_dump_status(sc); 998 #endif 999 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1000 AWIN_GMAC_DMA_TXPOLL, ~0U); 1001 } 1002 mutex_exit(&sc->sc_txq.t_mtx); 1003 } 1004 1005 static void 1006 dwc_gmac_stop(struct ifnet *ifp, int disable) 1007 { 1008 struct dwc_gmac_softc * const sc = ifp->if_softc; 1009 1010 ASSERT_SLEEPABLE(); 1011 KASSERT(IFNET_LOCKED(ifp)); 1012 1013 ifp->if_flags &= ~IFF_RUNNING; 1014 1015 mutex_enter(sc->sc_mcast_lock); 1016 sc->sc_if_flags = ifp->if_flags; 1017 mutex_exit(sc->sc_mcast_lock); 1018 1019 mutex_enter(sc->sc_intr_lock); 1020 sc->sc_stopping = true; 1021 mutex_exit(sc->sc_intr_lock); 1022 1023 mutex_enter(&sc->sc_txq.t_mtx); 1024 sc->sc_txbusy = false; 1025 mutex_exit(&sc->sc_txq.t_mtx); 1026 1027 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1028 AWIN_GMAC_DMA_OPMODE, 1029 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1030 AWIN_GMAC_DMA_OPMODE) 1031 & ~(GMAC_DMA_OP_TXSTART | GMAC_DMA_OP_RXSTART)); 1032 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1033 AWIN_GMAC_DMA_OPMODE, 1034 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1035 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX); 1036 1037 mii_down(&sc->sc_mii); 1038 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq); 1039 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); 1040 } 1041 1042 /* 1043 * Add m0 to the TX ring 1044 */ 1045 static int 1046 dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0) 1047 { 1048 struct dwc_gmac_dev_dmadesc *desc = NULL; 1049 struct dwc_gmac_tx_data *data = NULL; 1050 bus_dmamap_t map; 1051 int error, i, first; 1052 1053 #ifdef DWC_GMAC_DEBUG 1054 aprint_normal_dev(sc->sc_dev, 1055 "dwc_gmac_queue: adding mbuf chain %p\n", m0); 1056 #endif 1057 1058 first = sc->sc_txq.t_cur; 1059 map = sc->sc_txq.t_data[first].td_map; 1060 1061 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0, 1062 BUS_DMA_WRITE | BUS_DMA_NOWAIT); 1063 if (error != 0) { 1064 aprint_error_dev(sc->sc_dev, "could not map mbuf " 1065 "(len: %d, error %d)\n", m0->m_pkthdr.len, error); 1066 return error; 1067 } 1068 1069 if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) { 1070 bus_dmamap_unload(sc->sc_dmat, map); 1071 return ENOBUFS; 1072 } 1073 1074 for (i = 0; i < map->dm_nsegs; i++) { 1075 data = &sc->sc_txq.t_data[sc->sc_txq.t_cur]; 1076 desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur]; 1077 1078 desc->ddesc_data = htole32(map->dm_segs[i].ds_addr); 1079 1080 #ifdef DWC_GMAC_DEBUG 1081 aprint_normal_dev(sc->sc_dev, "enqueuing desc #%d data %08lx " 1082 "len %lu\n", sc->sc_txq.t_cur, 1083 (unsigned long)map->dm_segs[i].ds_addr, 1084 (unsigned long)map->dm_segs[i].ds_len); 1085 #endif 1086 1087 sc->sc_descm->tx_init_flags(desc); 1088 sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len); 1089 1090 if (i == 0) 1091 sc->sc_descm->tx_set_first_frag(desc); 1092 1093 /* 1094 * Defer passing ownership of the first descriptor 1095 * until we are done. 1096 */ 1097 if (i != 0) 1098 sc->sc_descm->tx_set_owned_by_dev(desc); 1099 1100 sc->sc_txq.t_queued++; 1101 sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur); 1102 } 1103 1104 sc->sc_descm->tx_set_last_frag(desc); 1105 1106 data->td_m = m0; 1107 data->td_active = map; 1108 1109 /* sync the packet buffer */ 1110 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 1111 BUS_DMASYNC_PREWRITE); 1112 1113 /* sync the new descriptors - ownership not transferred yet */ 1114 dwc_gmac_txdesc_sync(sc, first, sc->sc_txq.t_cur, 1115 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1116 1117 /* Pass first to device */ 1118 sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]); 1119 1120 return 0; 1121 } 1122 1123 /* 1124 * If the interface is up and running, only modify the receive 1125 * filter when setting promiscuous or debug mode. Otherwise fall 1126 * through to ether_ioctl, which will reset the chip. 1127 */ 1128 static int 1129 dwc_gmac_ifflags_cb(struct ethercom *ec) 1130 { 1131 struct ifnet * const ifp = &ec->ec_if; 1132 struct dwc_gmac_softc * const sc = ifp->if_softc; 1133 int ret = 0; 1134 1135 KASSERT(IFNET_LOCKED(ifp)); 1136 mutex_enter(sc->sc_mcast_lock); 1137 1138 u_short change = ifp->if_flags ^ sc->sc_if_flags; 1139 sc->sc_if_flags = ifp->if_flags; 1140 1141 if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) { 1142 ret = ENETRESET; 1143 } else if ((change & IFF_PROMISC) != 0) { 1144 dwc_gmac_setmulti(sc); 1145 } 1146 1147 mutex_exit(sc->sc_mcast_lock); 1148 1149 return ret; 1150 } 1151 1152 static int 1153 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1154 { 1155 struct dwc_gmac_softc * const sc = ifp->if_softc; 1156 int error = 0; 1157 1158 switch (cmd) { 1159 case SIOCADDMULTI: 1160 case SIOCDELMULTI: 1161 break; 1162 default: 1163 KASSERT(IFNET_LOCKED(ifp)); 1164 } 1165 1166 const int s = splnet(); 1167 error = ether_ioctl(ifp, cmd, data); 1168 splx(s); 1169 1170 if (error == ENETRESET) { 1171 error = 0; 1172 if (cmd == SIOCADDMULTI || cmd == SIOCDELMULTI) { 1173 mutex_enter(sc->sc_mcast_lock); 1174 if (sc->sc_if_flags & IFF_RUNNING) { 1175 /* 1176 * Multicast list has changed; set the hardware 1177 * filter accordingly. 1178 */ 1179 dwc_gmac_setmulti(sc); 1180 } 1181 mutex_exit(sc->sc_mcast_lock); 1182 } 1183 } 1184 1185 return error; 1186 } 1187 1188 static void 1189 dwc_gmac_tx_intr(struct dwc_gmac_softc *sc) 1190 { 1191 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1192 struct dwc_gmac_tx_data *data; 1193 struct dwc_gmac_dev_dmadesc *desc; 1194 int i, nsegs; 1195 1196 mutex_enter(&sc->sc_txq.t_mtx); 1197 1198 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) { 1199 #ifdef DWC_GMAC_DEBUG 1200 aprint_normal_dev(sc->sc_dev, 1201 "%s: checking desc #%d (t_queued: %d)\n", __func__, 1202 i, sc->sc_txq.t_queued); 1203 #endif 1204 1205 /* 1206 * i + 1 does not need to be a valid descriptor, 1207 * this is just a special notion to just sync 1208 * a single tx descriptor (i) 1209 */ 1210 dwc_gmac_txdesc_sync(sc, i, i + 1, 1211 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1212 1213 desc = &sc->sc_txq.t_desc[i]; 1214 if (sc->sc_descm->tx_is_owned_by_dev(desc)) 1215 break; 1216 1217 data = &sc->sc_txq.t_data[i]; 1218 if (data->td_m == NULL) 1219 continue; 1220 1221 if_statinc(ifp, if_opackets); 1222 nsegs = data->td_active->dm_nsegs; 1223 bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, 1224 data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1225 bus_dmamap_unload(sc->sc_dmat, data->td_active); 1226 1227 #ifdef DWC_GMAC_DEBUG 1228 aprint_normal_dev(sc->sc_dev, 1229 "%s: done with packet at desc #%d, freeing mbuf %p\n", 1230 __func__, i, data->td_m); 1231 #endif 1232 1233 m_freem(data->td_m); 1234 data->td_m = NULL; 1235 1236 sc->sc_txq.t_queued -= nsegs; 1237 } 1238 1239 sc->sc_txq.t_next = i; 1240 1241 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) { 1242 sc->sc_txbusy = false; 1243 } 1244 mutex_exit(&sc->sc_txq.t_mtx); 1245 } 1246 1247 static void 1248 dwc_gmac_rx_intr(struct dwc_gmac_softc *sc) 1249 { 1250 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1251 struct dwc_gmac_dev_dmadesc *desc; 1252 struct dwc_gmac_rx_data *data; 1253 bus_addr_t physaddr; 1254 struct mbuf *m, *mnew; 1255 int i, len, error; 1256 1257 mutex_enter(&sc->sc_rxq.r_mtx); 1258 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { 1259 #ifdef DWC_GMAC_DEBUG 1260 aprint_normal_dev(sc->sc_dev, "%s: checking desc #%d\n", 1261 __func__, i); 1262 #endif 1263 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1264 RX_DESC_OFFSET(i), sizeof(*desc), 1265 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1266 desc = &sc->sc_rxq.r_desc[i]; 1267 data = &sc->sc_rxq.r_data[i]; 1268 1269 if (sc->sc_descm->rx_is_owned_by_dev(desc)) 1270 break; 1271 1272 if (sc->sc_descm->rx_has_error(desc)) { 1273 #ifdef DWC_GMAC_DEBUG 1274 aprint_normal_dev(sc->sc_dev, 1275 "%s: RX error: status %08x, skipping\n", 1276 __func__, le32toh(desc->ddesc_status0)); 1277 #endif 1278 if_statinc(ifp, if_ierrors); 1279 goto skip; 1280 } 1281 1282 len = sc->sc_descm->rx_get_len(desc); 1283 1284 #ifdef DWC_GMAC_DEBUG 1285 aprint_normal_dev(sc->sc_dev, 1286 "%s: device is done with descriptor #%d, len: %d\n", 1287 __func__, i, len); 1288 #endif 1289 1290 /* 1291 * Try to get a new mbuf before passing this one 1292 * up, if that fails, drop the packet and reuse 1293 * the existing one. 1294 */ 1295 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1296 if (mnew == NULL) { 1297 if_statinc(ifp, if_ierrors); 1298 goto skip; 1299 } 1300 MCLGET(mnew, M_DONTWAIT); 1301 if ((mnew->m_flags & M_EXT) == 0) { 1302 m_freem(mnew); 1303 if_statinc(ifp, if_ierrors); 1304 goto skip; 1305 } 1306 mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size; 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_TXCHAIN); 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" "collison\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