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