1 /* $NetBSD: dwc_gmac.c,v 1.90 2024/07/14 09:38:41 skrll 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.90 2024/07/14 09:38:41 skrll 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 rxringsz = 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, rxringsz); 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, 541 RX_DESC_OFFSET(0), 542 AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 543 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 544 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 545 ring->r_physaddr); 546 547 return 0; 548 549 fail: 550 dwc_gmac_free_rx_ring(sc, ring); 551 return error; 552 } 553 554 static void 555 dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, 556 struct dwc_gmac_rx_ring *ring) 557 { 558 struct dwc_gmac_dev_dmadesc *desc; 559 struct dwc_gmac_rx_data *data; 560 int i; 561 562 mutex_enter(&ring->r_mtx); 563 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 564 desc = &sc->sc_rxq.r_desc[i]; 565 data = &sc->sc_rxq.r_data[i]; 566 sc->sc_descm->rx_init_flags(desc); 567 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 568 sc->sc_descm->rx_set_owned_by_dev(desc); 569 } 570 571 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 572 AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 573 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 574 575 ring->r_cur = ring->r_next = 0; 576 /* reset DMA address to start of ring */ 577 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 578 sc->sc_rxq.r_physaddr); 579 mutex_exit(&ring->r_mtx); 580 } 581 582 static int 583 dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc) 584 { 585 const size_t ringsize = AWGE_TOTAL_RING_COUNT * 586 sizeof(struct dwc_gmac_dev_dmadesc); 587 int error, nsegs; 588 void *rings; 589 590 error = bus_dmamap_create(sc->sc_dmat, ringsize, 1, ringsize, 0, 591 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map); 592 if (error != 0) { 593 aprint_error_dev(sc->sc_dev, 594 "could not create desc DMA map\n"); 595 sc->sc_dma_ring_map = NULL; 596 goto fail; 597 } 598 599 error = bus_dmamem_alloc(sc->sc_dmat, ringsize, PAGE_SIZE, 0, 600 &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT |BUS_DMA_COHERENT); 601 if (error != 0) { 602 aprint_error_dev(sc->sc_dev, 603 "could not map DMA memory\n"); 604 goto fail; 605 } 606 607 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs, 608 ringsize, &rings, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 609 if (error != 0) { 610 aprint_error_dev(sc->sc_dev, 611 "could not allocate DMA memory\n"); 612 goto fail; 613 } 614 615 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings, 616 ringsize, NULL, BUS_DMA_NOWAIT | BUS_DMA_COHERENT); 617 if (error != 0) { 618 aprint_error_dev(sc->sc_dev, 619 "could not load desc DMA map\n"); 620 goto fail; 621 } 622 623 /* give first AWGE_RX_RING_COUNT to the RX side */ 624 sc->sc_rxq.r_desc = rings; 625 sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr; 626 627 /* and next rings to the TX side */ 628 sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT; 629 sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr + 630 AWGE_RX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc); 631 632 return 0; 633 634 fail: 635 dwc_gmac_free_dma_rings(sc); 636 return error; 637 } 638 639 static void 640 dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc) 641 { 642 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 643 sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 644 bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map); 645 bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc, 646 AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc)); 647 bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1); 648 } 649 650 static void 651 dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring) 652 { 653 struct dwc_gmac_rx_data *data; 654 int i; 655 656 if (ring->r_desc == NULL) 657 return; 658 659 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 660 data = &ring->r_data[i]; 661 662 if (data->rd_map != NULL) { 663 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 664 AWGE_RX_RING_COUNT 665 * sizeof(struct dwc_gmac_dev_dmadesc), 666 BUS_DMASYNC_POSTREAD); 667 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 668 bus_dmamap_destroy(sc->sc_dmat, data->rd_map); 669 } 670 m_freem(data->rd_m); 671 } 672 } 673 674 static int 675 dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, 676 struct dwc_gmac_tx_ring *ring) 677 { 678 int i, error = 0; 679 680 ring->t_queued = 0; 681 ring->t_cur = ring->t_next = 0; 682 683 memset(ring->t_desc, 0, AWGE_TX_RING_COUNT * sizeof(*ring->t_desc)); 684 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 685 TX_DESC_OFFSET(0), 686 AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 687 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 688 689 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 690 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 691 AWGE_TX_RING_COUNT, MCLBYTES, 0, 692 BUS_DMA_NOWAIT | BUS_DMA_COHERENT, 693 &ring->t_data[i].td_map); 694 if (error != 0) { 695 aprint_error_dev(sc->sc_dev, 696 "could not create TX DMA map #%d\n", i); 697 ring->t_data[i].td_map = NULL; 698 goto fail; 699 } 700 ring->t_desc[i].ddesc_next = htole32( 701 ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc) 702 * TX_NEXT(i)); 703 } 704 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 705 TX_DESC_OFFSET(0), 706 AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 707 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 708 709 return 0; 710 711 fail: 712 dwc_gmac_free_tx_ring(sc, ring); 713 return error; 714 } 715 716 static void 717 dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops) 718 { 719 /* 'end' is pointing one descriptor beyond the last we want to sync */ 720 if (end > start) { 721 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 722 TX_DESC_OFFSET(start), 723 TX_DESC_OFFSET(end) - TX_DESC_OFFSET(start), 724 ops); 725 return; 726 } 727 /* sync from 'start' to end of ring */ 728 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 729 TX_DESC_OFFSET(start), 730 TX_DESC_OFFSET(AWGE_TX_RING_COUNT) - TX_DESC_OFFSET(start), 731 ops); 732 if (TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0) > 0) { 733 /* sync from start of ring to 'end' */ 734 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 735 TX_DESC_OFFSET(0), 736 TX_DESC_OFFSET(end) - TX_DESC_OFFSET(0), 737 ops); 738 } 739 } 740 741 static void 742 dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, 743 struct dwc_gmac_tx_ring *ring) 744 { 745 int i; 746 747 mutex_enter(&ring->t_mtx); 748 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 749 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 750 751 if (data->td_m != NULL) { 752 bus_dmamap_sync(sc->sc_dmat, data->td_active, 753 0, data->td_active->dm_mapsize, 754 BUS_DMASYNC_POSTWRITE); 755 bus_dmamap_unload(sc->sc_dmat, data->td_active); 756 m_freem(data->td_m); 757 data->td_m = NULL; 758 } 759 } 760 761 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 762 TX_DESC_OFFSET(0), 763 AWGE_TX_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc), 764 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 765 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 766 sc->sc_txq.t_physaddr); 767 768 ring->t_queued = 0; 769 ring->t_cur = ring->t_next = 0; 770 mutex_exit(&ring->t_mtx); 771 } 772 773 static void 774 dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, 775 struct dwc_gmac_tx_ring *ring) 776 { 777 int i; 778 779 /* unload the maps */ 780 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 781 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 782 783 if (data->td_m != NULL) { 784 bus_dmamap_sync(sc->sc_dmat, data->td_active, 785 0, data->td_map->dm_mapsize, 786 BUS_DMASYNC_POSTWRITE); 787 bus_dmamap_unload(sc->sc_dmat, data->td_active); 788 m_freem(data->td_m); 789 data->td_m = NULL; 790 } 791 } 792 793 /* and actually free them */ 794 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 795 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 796 797 bus_dmamap_destroy(sc->sc_dmat, data->td_map); 798 } 799 } 800 801 static void 802 dwc_gmac_miibus_statchg(struct ifnet *ifp) 803 { 804 struct dwc_gmac_softc * const sc = ifp->if_softc; 805 struct mii_data * const mii = &sc->sc_mii; 806 uint32_t conf, flow; 807 808 /* 809 * Set MII or GMII interface based on the speed 810 * negotiated by the PHY. 811 */ 812 conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF); 813 conf &= ~(AWIN_GMAC_MAC_CONF_FES100 | AWIN_GMAC_MAC_CONF_MIISEL 814 | AWIN_GMAC_MAC_CONF_FULLDPLX); 815 conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST 816 | AWIN_GMAC_MAC_CONF_DISABLERXOWN 817 | AWIN_GMAC_MAC_CONF_DISABLEJABBER 818 | AWIN_GMAC_MAC_CONF_RXENABLE 819 | AWIN_GMAC_MAC_CONF_TXENABLE; 820 switch (IFM_SUBTYPE(mii->mii_media_active)) { 821 case IFM_10_T: 822 conf |= AWIN_GMAC_MAC_CONF_MIISEL; 823 break; 824 case IFM_100_TX: 825 conf |= AWIN_GMAC_MAC_CONF_FES100 | 826 AWIN_GMAC_MAC_CONF_MIISEL; 827 break; 828 case IFM_1000_T: 829 break; 830 } 831 if (sc->sc_set_speed) 832 sc->sc_set_speed(sc, IFM_SUBTYPE(mii->mii_media_active)); 833 834 flow = 0; 835 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) { 836 conf |= AWIN_GMAC_MAC_CONF_FULLDPLX; 837 flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE); 838 } 839 if (mii->mii_media_active & IFM_ETH_TXPAUSE) { 840 flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE; 841 } 842 if (mii->mii_media_active & IFM_ETH_RXPAUSE) { 843 flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE; 844 } 845 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 846 AWIN_GMAC_MAC_FLOWCTRL, flow); 847 848 #ifdef DWC_GMAC_DEBUG 849 aprint_normal_dev(sc->sc_dev, 850 "setting MAC conf register: %08x\n", conf); 851 #endif 852 853 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 854 AWIN_GMAC_MAC_CONF, conf); 855 } 856 857 static int 858 dwc_gmac_init(struct ifnet *ifp) 859 { 860 struct dwc_gmac_softc *sc = ifp->if_softc; 861 862 mutex_enter(sc->sc_lock); 863 int ret = dwc_gmac_init_locked(ifp); 864 mutex_exit(sc->sc_lock); 865 866 return ret; 867 } 868 869 static int 870 dwc_gmac_init_locked(struct ifnet *ifp) 871 { 872 struct dwc_gmac_softc *sc = ifp->if_softc; 873 uint32_t ffilt; 874 875 if (ifp->if_flags & IFF_RUNNING) 876 return 0; 877 878 dwc_gmac_stop_locked(ifp, 0); 879 880 /* 881 * Configure DMA burst/transfer mode and RX/TX priorities. 882 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented. 883 */ 884 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 885 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL | 886 __SHIFTIN(2, GMAC_BUSMODE_RPBL) | 887 __SHIFTIN(2, GMAC_BUSMODE_PBL)); 888 889 /* 890 * Set up address filter 891 */ 892 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 893 if (ifp->if_flags & IFF_PROMISC) { 894 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 895 } else { 896 ffilt &= ~AWIN_GMAC_MAC_FFILT_PR; 897 } 898 if (ifp->if_flags & IFF_BROADCAST) { 899 ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF; 900 } else { 901 ffilt |= AWIN_GMAC_MAC_FFILT_DBF; 902 } 903 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 904 905 /* 906 * Set up multicast filter 907 */ 908 dwc_gmac_setmulti(sc); 909 910 /* 911 * Set up dma pointer for RX and TX ring 912 */ 913 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 914 sc->sc_rxq.r_physaddr); 915 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 916 sc->sc_txq.t_physaddr); 917 918 /* 919 * Start RX/TX part 920 */ 921 uint32_t opmode = GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART; 922 if ((sc->sc_flags & DWC_GMAC_FORCE_THRESH_DMA_MODE) == 0) { 923 opmode |= GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD; 924 } 925 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE, opmode); 926 #ifdef DWC_GMAC_DEBUG 927 aprint_normal_dev(sc->sc_dev, 928 "setting DMA opmode register: %08x\n", opmode); 929 #endif 930 931 sc->sc_stopping = false; 932 933 ifp->if_flags |= IFF_RUNNING; 934 sc->sc_txbusy = false; 935 936 return 0; 937 } 938 939 static void 940 dwc_gmac_start(struct ifnet *ifp) 941 { 942 struct dwc_gmac_softc *sc = ifp->if_softc; 943 #ifdef DWCGMAC_MPSAFE 944 KASSERT(if_is_mpsafe(ifp)); 945 #endif 946 947 mutex_enter(sc->sc_lock); 948 if (!sc->sc_stopping) { 949 mutex_enter(&sc->sc_txq.t_mtx); 950 dwc_gmac_start_locked(ifp); 951 mutex_exit(&sc->sc_txq.t_mtx); 952 } 953 mutex_exit(sc->sc_lock); 954 } 955 956 static void 957 dwc_gmac_start_locked(struct ifnet *ifp) 958 { 959 struct dwc_gmac_softc *sc = ifp->if_softc; 960 int old = sc->sc_txq.t_queued; 961 int start = sc->sc_txq.t_cur; 962 struct mbuf *m0; 963 964 if ((ifp->if_flags & IFF_RUNNING) == 0) 965 return; 966 if (sc->sc_txbusy) 967 return; 968 969 for (;;) { 970 IFQ_POLL(&ifp->if_snd, m0); 971 if (m0 == NULL) 972 break; 973 if (dwc_gmac_queue(sc, m0) != 0) { 974 sc->sc_txbusy = true; 975 break; 976 } 977 IFQ_DEQUEUE(&ifp->if_snd, m0); 978 bpf_mtap(ifp, m0, BPF_D_OUT); 979 if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) { 980 sc->sc_txbusy = true; 981 break; 982 } 983 } 984 985 if (sc->sc_txq.t_queued != old) { 986 /* packets have been queued, kick it off */ 987 dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur, 988 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 989 990 #ifdef DWC_GMAC_DEBUG 991 dwc_dump_status(sc); 992 #endif 993 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 994 AWIN_GMAC_DMA_TXPOLL, ~0U); 995 } 996 } 997 998 static void 999 dwc_gmac_stop(struct ifnet *ifp, int disable) 1000 { 1001 struct dwc_gmac_softc *sc = ifp->if_softc; 1002 1003 mutex_enter(sc->sc_lock); 1004 dwc_gmac_stop_locked(ifp, disable); 1005 mutex_exit(sc->sc_lock); 1006 } 1007 1008 static void 1009 dwc_gmac_stop_locked(struct ifnet *ifp, int disable) 1010 { 1011 struct dwc_gmac_softc *sc = ifp->if_softc; 1012 1013 sc->sc_stopping = true; 1014 1015 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1016 AWIN_GMAC_DMA_OPMODE, 1017 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1018 AWIN_GMAC_DMA_OPMODE) 1019 & ~(GMAC_DMA_OP_TXSTART | GMAC_DMA_OP_RXSTART)); 1020 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1021 AWIN_GMAC_DMA_OPMODE, 1022 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1023 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX); 1024 1025 mii_down(&sc->sc_mii); 1026 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq); 1027 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); 1028 1029 ifp->if_flags &= ~IFF_RUNNING; 1030 sc->sc_txbusy = false; 1031 } 1032 1033 /* 1034 * Add m0 to the TX ring 1035 */ 1036 static int 1037 dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0) 1038 { 1039 struct dwc_gmac_dev_dmadesc *desc = NULL; 1040 struct dwc_gmac_tx_data *data = NULL; 1041 bus_dmamap_t map; 1042 int error, i, first; 1043 1044 #ifdef DWC_GMAC_DEBUG 1045 aprint_normal_dev(sc->sc_dev, 1046 "dwc_gmac_queue: adding mbuf chain %p\n", m0); 1047 #endif 1048 1049 first = sc->sc_txq.t_cur; 1050 map = sc->sc_txq.t_data[first].td_map; 1051 1052 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0, 1053 BUS_DMA_WRITE | BUS_DMA_NOWAIT); 1054 if (error != 0) { 1055 aprint_error_dev(sc->sc_dev, "could not map mbuf " 1056 "(len: %d, error %d)\n", m0->m_pkthdr.len, error); 1057 return error; 1058 } 1059 1060 if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) { 1061 bus_dmamap_unload(sc->sc_dmat, map); 1062 return ENOBUFS; 1063 } 1064 1065 for (i = 0; i < map->dm_nsegs; i++) { 1066 data = &sc->sc_txq.t_data[sc->sc_txq.t_cur]; 1067 desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur]; 1068 1069 desc->ddesc_data = htole32(map->dm_segs[i].ds_addr); 1070 1071 #ifdef DWC_GMAC_DEBUG 1072 aprint_normal_dev(sc->sc_dev, "enqueuing desc #%d data %08lx " 1073 "len %lu\n", sc->sc_txq.t_cur, 1074 (unsigned long)map->dm_segs[i].ds_addr, 1075 (unsigned long)map->dm_segs[i].ds_len); 1076 #endif 1077 1078 sc->sc_descm->tx_init_flags(desc); 1079 sc->sc_descm->tx_set_len(desc, map->dm_segs[i].ds_len); 1080 1081 if (i == 0) 1082 sc->sc_descm->tx_set_first_frag(desc); 1083 1084 /* 1085 * Defer passing ownership of the first descriptor 1086 * until we are done. 1087 */ 1088 if (i != 0) 1089 sc->sc_descm->tx_set_owned_by_dev(desc); 1090 1091 sc->sc_txq.t_queued++; 1092 sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur); 1093 } 1094 1095 sc->sc_descm->tx_set_last_frag(desc); 1096 1097 data->td_m = m0; 1098 data->td_active = map; 1099 1100 /* sync the packet buffer */ 1101 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 1102 BUS_DMASYNC_PREWRITE); 1103 1104 /* sync the new descriptors - ownership not transferred yet */ 1105 dwc_gmac_txdesc_sync(sc, first, sc->sc_txq.t_cur, 1106 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1107 1108 /* Pass first to device */ 1109 sc->sc_descm->tx_set_owned_by_dev(&sc->sc_txq.t_desc[first]); 1110 1111 return 0; 1112 } 1113 1114 /* 1115 * If the interface is up and running, only modify the receive 1116 * filter when setting promiscuous or debug mode. Otherwise fall 1117 * through to ether_ioctl, which will reset the chip. 1118 */ 1119 static int 1120 dwc_gmac_ifflags_cb(struct ethercom *ec) 1121 { 1122 struct ifnet *ifp = &ec->ec_if; 1123 struct dwc_gmac_softc *sc = ifp->if_softc; 1124 int ret = 0; 1125 1126 mutex_enter(sc->sc_lock); 1127 u_short change = ifp->if_flags ^ sc->sc_if_flags; 1128 sc->sc_if_flags = ifp->if_flags; 1129 1130 if ((change & ~(IFF_CANTCHANGE | IFF_DEBUG)) != 0) { 1131 ret = ENETRESET; 1132 goto out; 1133 } 1134 if ((change & IFF_PROMISC) != 0) { 1135 dwc_gmac_setmulti(sc); 1136 } 1137 out: 1138 mutex_exit(sc->sc_lock); 1139 1140 return ret; 1141 } 1142 1143 static int 1144 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1145 { 1146 struct dwc_gmac_softc *sc = ifp->if_softc; 1147 int error = 0; 1148 1149 int s = splnet(); 1150 error = ether_ioctl(ifp, cmd, data); 1151 1152 #ifdef DWCGMAC_MPSAFE 1153 splx(s); 1154 #endif 1155 1156 if (error == ENETRESET) { 1157 error = 0; 1158 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 1159 ; 1160 else if (ifp->if_flags & IFF_RUNNING) { 1161 /* 1162 * Multicast list has changed; set the hardware filter 1163 * accordingly. 1164 */ 1165 mutex_enter(sc->sc_lock); 1166 dwc_gmac_setmulti(sc); 1167 mutex_exit(sc->sc_lock); 1168 } 1169 } 1170 1171 /* Try to get things going again */ 1172 if (ifp->if_flags & IFF_UP) 1173 dwc_gmac_start(ifp); 1174 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1175 1176 #ifndef DWCGMAC_MPSAFE 1177 splx(s); 1178 #endif 1179 1180 return error; 1181 } 1182 1183 static void 1184 dwc_gmac_tx_intr(struct dwc_gmac_softc *sc) 1185 { 1186 struct ifnet *ifp = &sc->sc_ec.ec_if; 1187 struct dwc_gmac_tx_data *data; 1188 struct dwc_gmac_dev_dmadesc *desc; 1189 int i, nsegs; 1190 1191 mutex_enter(&sc->sc_txq.t_mtx); 1192 1193 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) { 1194 #ifdef DWC_GMAC_DEBUG 1195 aprint_normal_dev(sc->sc_dev, 1196 "%s: checking desc #%d (t_queued: %d)\n", __func__, 1197 i, sc->sc_txq.t_queued); 1198 #endif 1199 1200 /* 1201 * i + 1 does not need to be a valid descriptor, 1202 * this is just a special notion to just sync 1203 * a single tx descriptor (i) 1204 */ 1205 dwc_gmac_txdesc_sync(sc, i, i + 1, 1206 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1207 1208 desc = &sc->sc_txq.t_desc[i]; 1209 if (sc->sc_descm->tx_is_owned_by_dev(desc)) 1210 break; 1211 1212 data = &sc->sc_txq.t_data[i]; 1213 if (data->td_m == NULL) 1214 continue; 1215 1216 if_statinc(ifp, if_opackets); 1217 nsegs = data->td_active->dm_nsegs; 1218 bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, 1219 data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1220 bus_dmamap_unload(sc->sc_dmat, data->td_active); 1221 1222 #ifdef DWC_GMAC_DEBUG 1223 aprint_normal_dev(sc->sc_dev, 1224 "%s: done with packet at desc #%d, freeing mbuf %p\n", 1225 __func__, i, data->td_m); 1226 #endif 1227 1228 m_freem(data->td_m); 1229 data->td_m = NULL; 1230 1231 sc->sc_txq.t_queued -= nsegs; 1232 } 1233 1234 sc->sc_txq.t_next = i; 1235 1236 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) { 1237 sc->sc_txbusy = false; 1238 } 1239 mutex_exit(&sc->sc_txq.t_mtx); 1240 } 1241 1242 static void 1243 dwc_gmac_rx_intr(struct dwc_gmac_softc *sc) 1244 { 1245 struct ifnet *ifp = &sc->sc_ec.ec_if; 1246 struct dwc_gmac_dev_dmadesc *desc; 1247 struct dwc_gmac_rx_data *data; 1248 bus_addr_t physaddr; 1249 struct mbuf *m, *mnew; 1250 int i, len, error; 1251 1252 mutex_enter(&sc->sc_rxq.r_mtx); 1253 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { 1254 #ifdef DWC_GMAC_DEBUG 1255 aprint_normal_dev(sc->sc_dev, "%s: checking desc #%d\n", 1256 __func__, i); 1257 #endif 1258 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1259 RX_DESC_OFFSET(i), sizeof(*desc), 1260 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1261 desc = &sc->sc_rxq.r_desc[i]; 1262 data = &sc->sc_rxq.r_data[i]; 1263 1264 if (sc->sc_descm->rx_is_owned_by_dev(desc)) 1265 break; 1266 1267 if (sc->sc_descm->rx_has_error(desc)) { 1268 #ifdef DWC_GMAC_DEBUG 1269 aprint_normal_dev(sc->sc_dev, 1270 "%s: RX error: status %08x, skipping\n", 1271 __func__, le32toh(desc->ddesc_status0)); 1272 #endif 1273 if_statinc(ifp, if_ierrors); 1274 goto skip; 1275 } 1276 1277 len = sc->sc_descm->rx_get_len(desc); 1278 1279 #ifdef DWC_GMAC_DEBUG 1280 aprint_normal_dev(sc->sc_dev, 1281 "%s: device is done with descriptor #%d, len: %d\n", 1282 __func__, i, len); 1283 #endif 1284 1285 /* 1286 * Try to get a new mbuf before passing this one 1287 * up, if that fails, drop the packet and reuse 1288 * the existing one. 1289 */ 1290 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1291 if (mnew == NULL) { 1292 if_statinc(ifp, if_ierrors); 1293 goto skip; 1294 } 1295 MCLGET(mnew, M_DONTWAIT); 1296 if ((mnew->m_flags & M_EXT) == 0) { 1297 m_freem(mnew); 1298 if_statinc(ifp, if_ierrors); 1299 goto skip; 1300 } 1301 mnew->m_len = mnew->m_pkthdr.len = mnew->m_ext.ext_size; 1302 if (mnew->m_len > AWGE_MAX_PACKET) { 1303 mnew->m_len = mnew->m_pkthdr.len = AWGE_MAX_PACKET; 1304 } 1305 1306 /* unload old DMA map */ 1307 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1308 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1309 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 1310 1311 /* and reload with new mbuf */ 1312 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, 1313 mnew, BUS_DMA_READ | BUS_DMA_NOWAIT); 1314 if (error != 0) { 1315 m_freem(mnew); 1316 /* try to reload old mbuf */ 1317 error = bus_dmamap_load_mbuf(sc->sc_dmat, data->rd_map, 1318 data->rd_m, BUS_DMA_READ | BUS_DMA_NOWAIT); 1319 if (error != 0) { 1320 panic("%s: could not load old rx mbuf", 1321 device_xname(sc->sc_dev)); 1322 } 1323 if_statinc(ifp, if_ierrors); 1324 goto skip; 1325 } 1326 physaddr = data->rd_map->dm_segs[0].ds_addr; 1327 1328 #ifdef DWC_GMAC_DEBUG 1329 aprint_normal_dev(sc->sc_dev, 1330 "%s: receiving packet at desc #%d, using mbuf %p\n", 1331 __func__, i, data->rd_m); 1332 #endif 1333 /* 1334 * New mbuf loaded, update RX ring and continue 1335 */ 1336 m = data->rd_m; 1337 data->rd_m = mnew; 1338 desc->ddesc_data = htole32(physaddr); 1339 1340 /* finalize mbuf */ 1341 m->m_pkthdr.len = m->m_len = len; 1342 m_set_rcvif(m, ifp); 1343 m->m_flags |= M_HASFCS; 1344 1345 if_percpuq_enqueue(sc->sc_ipq, m); 1346 1347 skip: 1348 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1349 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1350 1351 sc->sc_descm->rx_init_flags(desc); 1352 sc->sc_descm->rx_set_len(desc, data->rd_m->m_len); 1353 1354 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1355 RX_DESC_OFFSET(i), sizeof(*desc), 1356 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1357 1358 sc->sc_descm->rx_set_owned_by_dev(desc); 1359 1360 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1361 RX_DESC_OFFSET(i), sizeof(*desc), 1362 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1363 } 1364 1365 /* update RX pointer */ 1366 sc->sc_rxq.r_cur = i; 1367 1368 mutex_exit(&sc->sc_rxq.r_mtx); 1369 } 1370 1371 static void 1372 dwc_gmac_setmulti(struct dwc_gmac_softc *sc) 1373 { 1374 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1375 struct ether_multi *enm; 1376 struct ether_multistep step; 1377 struct ethercom *ec = &sc->sc_ec; 1378 uint32_t hashes[2] = { 0, 0 }; 1379 uint32_t ffilt, h; 1380 int mcnt; 1381 1382 KASSERT(mutex_owned(sc->sc_lock)); 1383 1384 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 1385 1386 if (ifp->if_flags & IFF_PROMISC) { 1387 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 1388 goto special_filter; 1389 } 1390 1391 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM | AWIN_GMAC_MAC_FFILT_PR); 1392 1393 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0); 1394 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0); 1395 1396 ETHER_LOCK(ec); 1397 ec->ec_flags &= ~ETHER_F_ALLMULTI; 1398 ETHER_FIRST_MULTI(step, ec, enm); 1399 mcnt = 0; 1400 while (enm != NULL) { 1401 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1402 ETHER_ADDR_LEN) != 0) { 1403 ffilt |= AWIN_GMAC_MAC_FFILT_PM; 1404 ec->ec_flags |= ETHER_F_ALLMULTI; 1405 ETHER_UNLOCK(ec); 1406 goto special_filter; 1407 } 1408 1409 h = ~ether_crc32_be(enm->enm_addrlo, ETHER_ADDR_LEN) >> 26; 1410 hashes[h >> 5] |= (1 << (h & 0x1f)); 1411 1412 mcnt++; 1413 ETHER_NEXT_MULTI(step, enm); 1414 } 1415 ETHER_UNLOCK(ec); 1416 1417 if (mcnt) 1418 ffilt |= AWIN_GMAC_MAC_FFILT_HMC; 1419 else 1420 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC; 1421 1422 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 1423 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1424 hashes[0]); 1425 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1426 hashes[1]); 1427 sc->sc_if_flags = ifp->if_flags; 1428 1429 #ifdef DWC_GMAC_DEBUG 1430 dwc_gmac_dump_ffilt(sc, ffilt); 1431 #endif 1432 return; 1433 1434 special_filter: 1435 #ifdef DWC_GMAC_DEBUG 1436 dwc_gmac_dump_ffilt(sc, ffilt); 1437 #endif 1438 /* no MAC hashes, ALLMULTI or PROMISC */ 1439 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, 1440 ffilt); 1441 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1442 0xffffffff); 1443 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1444 0xffffffff); 1445 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1446 } 1447 1448 int 1449 dwc_gmac_intr(struct dwc_gmac_softc *sc) 1450 { 1451 uint32_t status, dma_status; 1452 int rv = 0; 1453 1454 if (sc->sc_stopping) 1455 return 0; 1456 1457 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR); 1458 if (status & AWIN_GMAC_MII_IRQ) { 1459 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1460 AWIN_GMAC_MII_STATUS); 1461 rv = 1; 1462 mii_pollstat(&sc->sc_mii); 1463 } 1464 1465 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1466 AWIN_GMAC_DMA_STATUS); 1467 1468 if (dma_status & (GMAC_DMA_INT_NIE | GMAC_DMA_INT_AIE)) 1469 rv = 1; 1470 1471 if (dma_status & GMAC_DMA_INT_TIE) 1472 dwc_gmac_tx_intr(sc); 1473 1474 if (dma_status & GMAC_DMA_INT_RIE) 1475 dwc_gmac_rx_intr(sc); 1476 1477 /* 1478 * Check error conditions 1479 */ 1480 if (dma_status & GMAC_DMA_INT_ERRORS) { 1481 if_statinc(&sc->sc_ec.ec_if, if_oerrors); 1482 #ifdef DWC_GMAC_DEBUG 1483 dwc_dump_and_abort(sc, "interrupt error condition"); 1484 #endif 1485 } 1486 1487 rnd_add_uint32(&sc->rnd_source, dma_status); 1488 1489 /* ack interrupt */ 1490 if (dma_status) 1491 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1492 AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK); 1493 1494 /* 1495 * Get more packets 1496 */ 1497 if (rv) 1498 if_schedule_deferred_start(&sc->sc_ec.ec_if); 1499 1500 return rv; 1501 } 1502 1503 static void 1504 dwc_gmac_desc_set_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) 1505 { 1506 1507 desc->ddesc_status0 |= htole32(DDESC_STATUS_OWNEDBYDEV); 1508 } 1509 1510 static int 1511 dwc_gmac_desc_is_owned_by_dev(struct dwc_gmac_dev_dmadesc *desc) 1512 { 1513 1514 return !!(le32toh(desc->ddesc_status0) & DDESC_STATUS_OWNEDBYDEV); 1515 } 1516 1517 static void 1518 dwc_gmac_desc_std_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) 1519 { 1520 uint32_t cntl = le32toh(desc->ddesc_cntl1); 1521 1522 desc->ddesc_cntl1 = htole32((cntl & ~DDESC_CNTL_SIZE1MASK) | 1523 __SHIFTIN(len, DDESC_CNTL_SIZE1MASK)); 1524 } 1525 1526 static uint32_t 1527 dwc_gmac_desc_std_get_len(struct dwc_gmac_dev_dmadesc *desc) 1528 { 1529 1530 return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_STATUS_FRMLENMSK); 1531 } 1532 1533 static void 1534 dwc_gmac_desc_std_tx_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 void 1542 dwc_gmac_desc_std_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc) 1543 { 1544 uint32_t cntl = le32toh(desc->ddesc_cntl1); 1545 1546 desc->ddesc_cntl1 = htole32(cntl | DDESC_CNTL_TXFIRST); 1547 } 1548 1549 static void 1550 dwc_gmac_desc_std_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc) 1551 { 1552 uint32_t cntl = le32toh(desc->ddesc_cntl1); 1553 1554 desc->ddesc_cntl1 = htole32(cntl | 1555 DDESC_CNTL_TXLAST | DDESC_CNTL_TXINT); 1556 } 1557 1558 static void 1559 dwc_gmac_desc_std_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1560 { 1561 1562 desc->ddesc_status0 = 0; 1563 desc->ddesc_cntl1 = htole32(DDESC_CNTL_TXCHAIN); 1564 } 1565 1566 static int 1567 dwc_gmac_desc_std_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) { 1568 return !!(le32toh(desc->ddesc_status0) & 1569 (DDESC_STATUS_RXERROR | DDESC_STATUS_RXTRUNCATED)); 1570 } 1571 1572 static void 1573 dwc_gmac_desc_enh_set_len(struct dwc_gmac_dev_dmadesc *desc, int len) 1574 { 1575 uint32_t tdes1 = le32toh(desc->ddesc_cntl1); 1576 1577 desc->ddesc_cntl1 = htole32((tdes1 & ~DDESC_DES1_SIZE1MASK) | 1578 __SHIFTIN(len, DDESC_DES1_SIZE1MASK)); 1579 } 1580 1581 static uint32_t 1582 dwc_gmac_desc_enh_get_len(struct dwc_gmac_dev_dmadesc *desc) 1583 { 1584 1585 return __SHIFTOUT(le32toh(desc->ddesc_status0), DDESC_RDES0_FL); 1586 } 1587 1588 static void 1589 dwc_gmac_desc_enh_tx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1590 { 1591 1592 desc->ddesc_status0 = htole32(DDESC_TDES0_TCH); 1593 desc->ddesc_cntl1 = 0; 1594 } 1595 1596 static void 1597 dwc_gmac_desc_enh_tx_set_first_frag(struct dwc_gmac_dev_dmadesc *desc) 1598 { 1599 uint32_t tdes0 = le32toh(desc->ddesc_status0); 1600 1601 desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_FS); 1602 } 1603 1604 static void 1605 dwc_gmac_desc_enh_tx_set_last_frag(struct dwc_gmac_dev_dmadesc *desc) 1606 { 1607 uint32_t tdes0 = le32toh(desc->ddesc_status0); 1608 1609 desc->ddesc_status0 = htole32(tdes0 | DDESC_TDES0_LS | DDESC_TDES0_IC); 1610 } 1611 1612 static void 1613 dwc_gmac_desc_enh_rx_init_flags(struct dwc_gmac_dev_dmadesc *desc) 1614 { 1615 1616 desc->ddesc_status0 = 0; 1617 desc->ddesc_cntl1 = htole32(DDESC_RDES1_RCH); 1618 } 1619 1620 static int 1621 dwc_gmac_desc_enh_rx_has_error(struct dwc_gmac_dev_dmadesc *desc) 1622 { 1623 1624 return !!(le32toh(desc->ddesc_status0) & 1625 (DDESC_RDES0_ES | DDESC_RDES0_LE)); 1626 } 1627 1628 #ifdef DWC_GMAC_DEBUG 1629 static void 1630 dwc_gmac_dump_dma(struct dwc_gmac_softc *sc) 1631 { 1632 aprint_normal_dev(sc->sc_dev, "busmode: %08x\n", 1633 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)); 1634 aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n", 1635 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL)); 1636 aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n", 1637 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL)); 1638 aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n", 1639 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR)); 1640 aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n", 1641 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR)); 1642 aprint_normal_dev(sc->sc_dev, " status: %08x\n", 1643 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS)); 1644 aprint_normal_dev(sc->sc_dev, "op mode: %08x\n", 1645 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE)); 1646 aprint_normal_dev(sc->sc_dev, "int en.: %08x\n", 1647 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE)); 1648 aprint_normal_dev(sc->sc_dev, " cur tx: %08x\n", 1649 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC)); 1650 aprint_normal_dev(sc->sc_dev, " cur rx: %08x\n", 1651 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC)); 1652 aprint_normal_dev(sc->sc_dev, "cur txb: %08x\n", 1653 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR)); 1654 aprint_normal_dev(sc->sc_dev, "cur rxb: %08x\n", 1655 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR)); 1656 } 1657 1658 static void 1659 dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc) 1660 { 1661 const size_t descsz = sizeof(struct dwc_gmac_dev_dmadesc); 1662 1663 aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n", 1664 sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued); 1665 aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n"); 1666 1667 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1668 TX_DESC_OFFSET(0), AWGE_TX_RING_COUNT * descsz, 1669 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1670 1671 for (size_t i = 0; i < AWGE_TX_RING_COUNT; i++) { 1672 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i]; 1673 aprint_normal("#%3zu (%08lx): status: %08x cntl: %08x " 1674 "data: %08x next: %08x\n", 1675 i, sc->sc_txq.t_physaddr + i * descsz, 1676 le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1), 1677 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1678 } 1679 } 1680 1681 static void 1682 dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc) 1683 { 1684 const size_t descsz = sizeof(struct dwc_gmac_dev_dmadesc); 1685 1686 aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n", 1687 sc->sc_rxq.r_cur, sc->sc_rxq.r_next); 1688 aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n"); 1689 1690 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1691 RX_DESC_OFFSET(0), AWGE_RX_RING_COUNT * descsz, 1692 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 1693 1694 for (size_t i = 0; i < AWGE_RX_RING_COUNT; i++) { 1695 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i]; 1696 char buf[200]; 1697 1698 if (!sc->sc_descm->rx_is_owned_by_dev(desc)) { 1699 /* print interrupt state */ 1700 snprintb(buf, sizeof(buf), 1701 "\177\20" 1702 "b\x1e" "daff\0" 1703 "f\x10\xe" "frlen\0" 1704 "b\x0f" "error\0" 1705 "b\x0e" "rxtrunc\0" /* descriptor error? */ 1706 "b\x0d" "saff\0" 1707 "b\x0c" "giantframe\0" /* length error? */ 1708 "b\x0b" "damaged\0" 1709 "b\x0a" "vlan\0" 1710 "b\x09" "first\0" 1711 "b\x08" "last\0" 1712 "b\x07" "giant\0" 1713 "b\x06" "collison\0" 1714 "b\x05" "ether\0" 1715 "b\x04" "watchdog\0" 1716 "b\x03" "miierror\0" 1717 "b\x02" "dribbling\0" 1718 "b\x01" "crc\0" 1719 "\0", le32toh(desc->ddesc_status0)); 1720 } 1721 1722 aprint_normal("#%3zu (%08lx): status: %08x cntl: %08x " 1723 "data: %08x next: %08x %s\n", 1724 i, sc->sc_rxq.r_physaddr + i * descsz, 1725 le32toh(desc->ddesc_status0), le32toh(desc->ddesc_cntl1), 1726 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next), 1727 sc->sc_descm->rx_is_owned_by_dev(desc) ? "" : buf); 1728 } 1729 } 1730 1731 static void 1732 dwc_dump_status(struct dwc_gmac_softc *sc) 1733 { 1734 uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1735 AWIN_GMAC_MAC_INTR); 1736 uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1737 AWIN_GMAC_DMA_STATUS); 1738 char buf[200]; 1739 1740 /* print interrupt state */ 1741 snprintb(buf, sizeof(buf), 1742 "\177\20" 1743 "b\x1c" "GPI\0" 1744 "b\x1b" "GMC\0" 1745 "b\x1a" "GLI\0" 1746 "f\x17\x3" "EB\0" 1747 "f\x14\x3" "TPS\0" 1748 "f\x11\x3" "RPS\0" 1749 "b\x10" "NI\0" 1750 "b\x0f" "AI\0" 1751 "b\x0e" "ER\0" 1752 "b\x0d" "FB\0" 1753 "b\x0a" "ET\0" 1754 "b\x09" "RW\0" 1755 "b\x08" "RS\0" 1756 "b\x07" "RU\0" 1757 "b\x06" "RI\0" 1758 "b\x05" "UN\0" 1759 "b\x04" "OV\0" 1760 "b\x03" "TJ\0" 1761 "b\x02" "TU\0" 1762 "b\x01" "TS\0" 1763 "b\x00" "TI\0" 1764 "\0", dma_status); 1765 aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n", 1766 status, buf); 1767 } 1768 1769 static void 1770 dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg) 1771 { 1772 dwc_dump_status(sc); 1773 dwc_gmac_dump_ffilt(sc, 1774 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT)); 1775 dwc_gmac_dump_dma(sc); 1776 dwc_gmac_dump_tx_desc(sc); 1777 dwc_gmac_dump_rx_desc(sc); 1778 1779 panic("%s", msg); 1780 } 1781 1782 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt) 1783 { 1784 char buf[200]; 1785 1786 /* print filter setup */ 1787 snprintb(buf, sizeof(buf), "\177\20" 1788 "b\x1f""RA\0" 1789 "b\x0a""HPF\0" 1790 "b\x09""SAF\0" 1791 "b\x08""SAIF\0" 1792 "b\x05""DBF\0" 1793 "b\x04""PM\0" 1794 "b\x03""DAIF\0" 1795 "b\x02""HMC\0" 1796 "b\x01""HUC\0" 1797 "b\x00""PR\0" 1798 "\0", ffilt); 1799 aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf); 1800 } 1801 #endif 1802