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