1 /* $NetBSD: dwc_gmac.c,v 1.45 2017/12/21 12:09:43 martin 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.45 2017/12/21 12:09:43 martin Exp $"); 45 46 /* #define DWC_GMAC_DEBUG 1 */ 47 48 #ifdef _KERNEL_OPT 49 #include "opt_inet.h" 50 #include "opt_net_mpsafe.h" 51 #endif 52 53 #include <sys/param.h> 54 #include <sys/bus.h> 55 #include <sys/device.h> 56 #include <sys/intr.h> 57 #include <sys/systm.h> 58 #include <sys/sockio.h> 59 #include <sys/cprng.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); 75 static void dwc_gmac_miibus_write_reg(device_t, int, int, int); 76 static void dwc_gmac_miibus_statchg(struct ifnet *); 77 78 static int dwc_gmac_reset(struct dwc_gmac_softc *sc); 79 static void dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, 80 uint8_t enaddr[ETHER_ADDR_LEN]); 81 static int dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc); 82 static void dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc); 83 static int dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 84 static void dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 85 static void dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *); 86 static int dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 87 static void dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 88 static void dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_tx_ring *); 89 static void dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops); 90 static int dwc_gmac_init(struct ifnet *ifp); 91 static int dwc_gmac_init_locked(struct ifnet *ifp); 92 static void dwc_gmac_stop(struct ifnet *ifp, int disable); 93 static void dwc_gmac_stop_locked(struct ifnet *ifp, int disable); 94 static void dwc_gmac_start(struct ifnet *ifp); 95 static void dwc_gmac_start_locked(struct ifnet *ifp); 96 static int dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0); 97 static int dwc_gmac_ioctl(struct ifnet *, u_long, void *); 98 static void dwc_gmac_tx_intr(struct dwc_gmac_softc *sc); 99 static void dwc_gmac_rx_intr(struct dwc_gmac_softc *sc); 100 static void dwc_gmac_setmulti(struct dwc_gmac_softc *sc); 101 static int dwc_gmac_ifflags_cb(struct ethercom *); 102 static uint32_t bitrev32(uint32_t x); 103 104 #define TX_DESC_OFFSET(N) ((AWGE_RX_RING_COUNT+(N)) \ 105 *sizeof(struct dwc_gmac_dev_dmadesc)) 106 #define TX_NEXT(N) (((N)+1) & (AWGE_TX_RING_COUNT-1)) 107 108 #define RX_DESC_OFFSET(N) ((N)*sizeof(struct dwc_gmac_dev_dmadesc)) 109 #define RX_NEXT(N) (((N)+1) & (AWGE_RX_RING_COUNT-1)) 110 111 112 113 #define GMAC_DEF_DMA_INT_MASK (GMAC_DMA_INT_TIE|GMAC_DMA_INT_RIE| \ 114 GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE| \ 115 GMAC_DMA_INT_FBE|GMAC_DMA_INT_UNE) 116 117 #define GMAC_DMA_INT_ERRORS (GMAC_DMA_INT_AIE|GMAC_DMA_INT_ERE| \ 118 GMAC_DMA_INT_FBE| \ 119 GMAC_DMA_INT_RWE|GMAC_DMA_INT_RUE| \ 120 GMAC_DMA_INT_UNE|GMAC_DMA_INT_OVE| \ 121 GMAC_DMA_INT_TJE) 122 123 #define AWIN_DEF_MAC_INTRMASK \ 124 (AWIN_GMAC_MAC_INT_TSI | AWIN_GMAC_MAC_INT_ANEG | \ 125 AWIN_GMAC_MAC_INT_LINKCHG | AWIN_GMAC_MAC_INT_RGSMII) 126 127 128 #ifdef DWC_GMAC_DEBUG 129 static void dwc_gmac_dump_dma(struct dwc_gmac_softc *sc); 130 static void dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc); 131 static void dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc); 132 static void dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg); 133 static void dwc_dump_status(struct dwc_gmac_softc *sc); 134 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt); 135 #endif 136 137 #ifdef NET_MPSAFE 138 #define DWCGMAC_MPSAFE 1 139 #endif 140 141 void 142 dwc_gmac_attach(struct dwc_gmac_softc *sc, uint32_t mii_clk) 143 { 144 uint8_t enaddr[ETHER_ADDR_LEN]; 145 uint32_t maclo, machi; 146 struct mii_data * const mii = &sc->sc_mii; 147 struct ifnet * const ifp = &sc->sc_ec.ec_if; 148 prop_dictionary_t dict; 149 int rv; 150 151 mutex_init(&sc->sc_mdio_lock, MUTEX_DEFAULT, IPL_NET); 152 sc->sc_mii_clk = mii_clk & 7; 153 154 dict = device_properties(sc->sc_dev); 155 prop_data_t ea = dict ? prop_dictionary_get(dict, "mac-address") : NULL; 156 if (ea != NULL) { 157 /* 158 * If the MAC address is overriden by a device property, 159 * use that. 160 */ 161 KASSERT(prop_object_type(ea) == PROP_TYPE_DATA); 162 KASSERT(prop_data_size(ea) == ETHER_ADDR_LEN); 163 memcpy(enaddr, prop_data_data_nocopy(ea), ETHER_ADDR_LEN); 164 } else { 165 /* 166 * If we did not get an externaly configure address, 167 * try to read one from the current filter setup, 168 * before resetting the chip. 169 */ 170 maclo = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 171 AWIN_GMAC_MAC_ADDR0LO); 172 machi = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 173 AWIN_GMAC_MAC_ADDR0HI); 174 175 if (maclo == 0xffffffff && (machi & 0xffff) == 0xffff) { 176 /* fake MAC address */ 177 maclo = 0x00f2 | (cprng_strong32() << 16); 178 machi = cprng_strong32(); 179 } 180 181 enaddr[0] = maclo & 0x0ff; 182 enaddr[1] = (maclo >> 8) & 0x0ff; 183 enaddr[2] = (maclo >> 16) & 0x0ff; 184 enaddr[3] = (maclo >> 24) & 0x0ff; 185 enaddr[4] = machi & 0x0ff; 186 enaddr[5] = (machi >> 8) & 0x0ff; 187 } 188 189 /* 190 * Init chip and do initial setup 191 */ 192 if (dwc_gmac_reset(sc) != 0) 193 return; /* not much to cleanup, haven't attached yet */ 194 dwc_gmac_write_hwaddr(sc, enaddr); 195 aprint_normal_dev(sc->sc_dev, "Ethernet address: %s\n", 196 ether_sprintf(enaddr)); 197 198 /* 199 * Allocate Tx and Rx rings 200 */ 201 if (dwc_gmac_alloc_dma_rings(sc) != 0) { 202 aprint_error_dev(sc->sc_dev, "could not allocate DMA rings\n"); 203 goto fail; 204 } 205 206 if (dwc_gmac_alloc_tx_ring(sc, &sc->sc_txq) != 0) { 207 aprint_error_dev(sc->sc_dev, "could not allocate Tx ring\n"); 208 goto fail; 209 } 210 211 if (dwc_gmac_alloc_rx_ring(sc, &sc->sc_rxq) != 0) { 212 aprint_error_dev(sc->sc_dev, "could not allocate Rx ring\n"); 213 goto fail; 214 } 215 216 sc->sc_lock = mutex_obj_alloc(MUTEX_DEFAULT, IPL_NET); 217 mutex_init(&sc->sc_txq.t_mtx, MUTEX_DEFAULT, IPL_NET); 218 mutex_init(&sc->sc_rxq.r_mtx, MUTEX_DEFAULT, IPL_NET); 219 220 /* 221 * Prepare interface data 222 */ 223 ifp->if_softc = sc; 224 strlcpy(ifp->if_xname, device_xname(sc->sc_dev), IFNAMSIZ); 225 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 226 #ifdef DWCGMAC_MPSAFE 227 ifp->if_extflags = IFEF_MPSAFE; 228 #endif 229 ifp->if_ioctl = dwc_gmac_ioctl; 230 ifp->if_start = dwc_gmac_start; 231 ifp->if_init = dwc_gmac_init; 232 ifp->if_stop = dwc_gmac_stop; 233 IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); 234 IFQ_SET_READY(&ifp->if_snd); 235 236 /* 237 * Attach MII subdevices 238 */ 239 sc->sc_ec.ec_mii = &sc->sc_mii; 240 ifmedia_init(&mii->mii_media, 0, ether_mediachange, ether_mediastatus); 241 mii->mii_ifp = ifp; 242 mii->mii_readreg = dwc_gmac_miibus_read_reg; 243 mii->mii_writereg = dwc_gmac_miibus_write_reg; 244 mii->mii_statchg = dwc_gmac_miibus_statchg; 245 mii_attach(sc->sc_dev, mii, 0xffffffff, MII_PHY_ANY, MII_OFFSET_ANY, 246 MIIF_DOPAUSE); 247 248 if (LIST_EMPTY(&mii->mii_phys)) { 249 aprint_error_dev(sc->sc_dev, "no PHY found!\n"); 250 ifmedia_add(&mii->mii_media, IFM_ETHER|IFM_MANUAL, 0, NULL); 251 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_MANUAL); 252 } else { 253 ifmedia_set(&mii->mii_media, IFM_ETHER|IFM_AUTO); 254 } 255 256 /* 257 * We can support 802.1Q VLAN-sized frames. 258 */ 259 sc->sc_ec.ec_capabilities |= ETHERCAP_VLAN_MTU; 260 261 /* 262 * Ready, attach interface 263 */ 264 /* Attach the interface. */ 265 rv = if_initialize(ifp); 266 if (rv != 0) 267 goto fail_2; 268 sc->sc_ipq = if_percpuq_create(&sc->sc_ec.ec_if); 269 if_deferred_start_init(ifp, NULL); 270 ether_ifattach(ifp, enaddr); 271 ether_set_ifflags_cb(&sc->sc_ec, dwc_gmac_ifflags_cb); 272 if_register(ifp); 273 274 /* 275 * Enable interrupts 276 */ 277 mutex_enter(sc->sc_lock); 278 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTMASK, 279 AWIN_DEF_MAC_INTRMASK); 280 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE, 281 GMAC_DEF_DMA_INT_MASK); 282 mutex_exit(sc->sc_lock); 283 284 return; 285 fail_2: 286 ifmedia_removeall(&mii->mii_media); 287 mii_detach(mii, MII_PHY_ANY, MII_OFFSET_ANY); 288 mutex_destroy(&sc->sc_txq.t_mtx); 289 mutex_destroy(&sc->sc_rxq.r_mtx); 290 mutex_obj_free(sc->sc_lock); 291 fail: 292 dwc_gmac_free_rx_ring(sc, &sc->sc_rxq); 293 dwc_gmac_free_tx_ring(sc, &sc->sc_txq); 294 dwc_gmac_free_dma_rings(sc); 295 mutex_destroy(&sc->sc_mdio_lock); 296 } 297 298 299 300 static int 301 dwc_gmac_reset(struct dwc_gmac_softc *sc) 302 { 303 size_t cnt; 304 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 305 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) | GMAC_BUSMODE_RESET); 306 for (cnt = 0; cnt < 3000; cnt++) { 307 if ((bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE) 308 & GMAC_BUSMODE_RESET) == 0) 309 return 0; 310 delay(10); 311 } 312 313 aprint_error_dev(sc->sc_dev, "reset timed out\n"); 314 return EIO; 315 } 316 317 static void 318 dwc_gmac_write_hwaddr(struct dwc_gmac_softc *sc, 319 uint8_t enaddr[ETHER_ADDR_LEN]) 320 { 321 uint32_t lo, hi; 322 323 lo = enaddr[0] | (enaddr[1] << 8) | (enaddr[2] << 16) 324 | (enaddr[3] << 24); 325 hi = enaddr[4] | (enaddr[5] << 8); 326 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0LO, lo); 327 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_ADDR0HI, hi); 328 } 329 330 static int 331 dwc_gmac_miibus_read_reg(device_t self, int phy, int reg) 332 { 333 struct dwc_gmac_softc * const sc = device_private(self); 334 uint16_t mii; 335 size_t cnt; 336 int rv = 0; 337 338 mii = __SHIFTIN(phy,GMAC_MII_PHY_MASK) 339 | __SHIFTIN(reg,GMAC_MII_REG_MASK) 340 | __SHIFTIN(sc->sc_mii_clk,GMAC_MII_CLKMASK) 341 | GMAC_MII_BUSY; 342 343 mutex_enter(&sc->sc_mdio_lock); 344 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii); 345 346 for (cnt = 0; cnt < 1000; cnt++) { 347 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 348 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) { 349 rv = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 350 AWIN_GMAC_MAC_MIIDATA); 351 break; 352 } 353 delay(10); 354 } 355 356 mutex_exit(&sc->sc_mdio_lock); 357 358 return rv; 359 } 360 361 static void 362 dwc_gmac_miibus_write_reg(device_t self, int phy, int reg, int val) 363 { 364 struct dwc_gmac_softc * const sc = device_private(self); 365 uint16_t mii; 366 size_t cnt; 367 368 mii = __SHIFTIN(phy,GMAC_MII_PHY_MASK) 369 | __SHIFTIN(reg,GMAC_MII_REG_MASK) 370 | __SHIFTIN(sc->sc_mii_clk,GMAC_MII_CLKMASK) 371 | GMAC_MII_BUSY | GMAC_MII_WRITE; 372 373 mutex_enter(&sc->sc_mdio_lock); 374 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIDATA, val); 375 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_MIIADDR, mii); 376 377 for (cnt = 0; cnt < 1000; cnt++) { 378 if (!(bus_space_read_4(sc->sc_bst, sc->sc_bsh, 379 AWIN_GMAC_MAC_MIIADDR) & GMAC_MII_BUSY)) 380 break; 381 delay(10); 382 } 383 384 mutex_exit(&sc->sc_mdio_lock); 385 } 386 387 static int 388 dwc_gmac_alloc_rx_ring(struct dwc_gmac_softc *sc, 389 struct dwc_gmac_rx_ring *ring) 390 { 391 struct dwc_gmac_rx_data *data; 392 bus_addr_t physaddr; 393 const size_t descsize = AWGE_RX_RING_COUNT * sizeof(*ring->r_desc); 394 int error, i, next; 395 396 ring->r_cur = ring->r_next = 0; 397 memset(ring->r_desc, 0, descsize); 398 399 /* 400 * Pre-allocate Rx buffers and populate Rx ring. 401 */ 402 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 403 struct dwc_gmac_dev_dmadesc *desc; 404 405 data = &sc->sc_rxq.r_data[i]; 406 407 MGETHDR(data->rd_m, M_DONTWAIT, MT_DATA); 408 if (data->rd_m == NULL) { 409 aprint_error_dev(sc->sc_dev, 410 "could not allocate rx mbuf #%d\n", i); 411 error = ENOMEM; 412 goto fail; 413 } 414 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 415 MCLBYTES, 0, BUS_DMA_NOWAIT, &data->rd_map); 416 if (error != 0) { 417 aprint_error_dev(sc->sc_dev, 418 "could not create DMA map\n"); 419 data->rd_map = NULL; 420 goto fail; 421 } 422 MCLGET(data->rd_m, M_DONTWAIT); 423 if (!(data->rd_m->m_flags & M_EXT)) { 424 aprint_error_dev(sc->sc_dev, 425 "could not allocate mbuf cluster #%d\n", i); 426 error = ENOMEM; 427 goto fail; 428 } 429 430 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 431 mtod(data->rd_m, void *), MCLBYTES, NULL, 432 BUS_DMA_READ | BUS_DMA_NOWAIT); 433 if (error != 0) { 434 aprint_error_dev(sc->sc_dev, 435 "could not load rx buf DMA map #%d", i); 436 goto fail; 437 } 438 physaddr = data->rd_map->dm_segs[0].ds_addr; 439 440 desc = &sc->sc_rxq.r_desc[i]; 441 desc->ddesc_data = htole32(physaddr); 442 next = RX_NEXT(i); 443 desc->ddesc_next = htole32(ring->r_physaddr 444 + next * sizeof(*desc)); 445 desc->ddesc_cntl = htole32( 446 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 447 DDESC_CNTL_RXCHAIN); 448 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 449 } 450 451 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 452 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 453 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_PREREAD); 454 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 455 ring->r_physaddr); 456 457 return 0; 458 459 fail: 460 dwc_gmac_free_rx_ring(sc, ring); 461 return error; 462 } 463 464 static void 465 dwc_gmac_reset_rx_ring(struct dwc_gmac_softc *sc, 466 struct dwc_gmac_rx_ring *ring) 467 { 468 struct dwc_gmac_dev_dmadesc *desc; 469 int i; 470 471 mutex_enter(&ring->r_mtx); 472 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 473 desc = &sc->sc_rxq.r_desc[i]; 474 desc->ddesc_cntl = htole32( 475 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 476 DDESC_CNTL_RXCHAIN); 477 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 478 } 479 480 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 481 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 482 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 483 484 ring->r_cur = ring->r_next = 0; 485 /* reset DMA address to start of ring */ 486 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 487 sc->sc_rxq.r_physaddr); 488 mutex_exit(&ring->r_mtx); 489 } 490 491 static int 492 dwc_gmac_alloc_dma_rings(struct dwc_gmac_softc *sc) 493 { 494 const size_t descsize = AWGE_TOTAL_RING_COUNT * 495 sizeof(struct dwc_gmac_dev_dmadesc); 496 int error, nsegs; 497 void *rings; 498 499 error = bus_dmamap_create(sc->sc_dmat, descsize, 1, descsize, 0, 500 BUS_DMA_NOWAIT, &sc->sc_dma_ring_map); 501 if (error != 0) { 502 aprint_error_dev(sc->sc_dev, 503 "could not create desc DMA map\n"); 504 sc->sc_dma_ring_map = NULL; 505 goto fail; 506 } 507 508 error = bus_dmamem_alloc(sc->sc_dmat, descsize, PAGE_SIZE, 0, 509 &sc->sc_dma_ring_seg, 1, &nsegs, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 510 if (error != 0) { 511 aprint_error_dev(sc->sc_dev, 512 "could not map DMA memory\n"); 513 goto fail; 514 } 515 516 error = bus_dmamem_map(sc->sc_dmat, &sc->sc_dma_ring_seg, nsegs, 517 descsize, &rings, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 518 if (error != 0) { 519 aprint_error_dev(sc->sc_dev, 520 "could not allocate DMA memory\n"); 521 goto fail; 522 } 523 524 error = bus_dmamap_load(sc->sc_dmat, sc->sc_dma_ring_map, rings, 525 descsize, NULL, BUS_DMA_NOWAIT|BUS_DMA_COHERENT); 526 if (error != 0) { 527 aprint_error_dev(sc->sc_dev, 528 "could not load desc DMA map\n"); 529 goto fail; 530 } 531 532 /* give first AWGE_RX_RING_COUNT to the RX side */ 533 sc->sc_rxq.r_desc = rings; 534 sc->sc_rxq.r_physaddr = sc->sc_dma_ring_map->dm_segs[0].ds_addr; 535 536 /* and next rings to the TX side */ 537 sc->sc_txq.t_desc = sc->sc_rxq.r_desc + AWGE_RX_RING_COUNT; 538 sc->sc_txq.t_physaddr = sc->sc_rxq.r_physaddr + 539 AWGE_RX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc); 540 541 return 0; 542 543 fail: 544 dwc_gmac_free_dma_rings(sc); 545 return error; 546 } 547 548 static void 549 dwc_gmac_free_dma_rings(struct dwc_gmac_softc *sc) 550 { 551 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 0, 552 sc->sc_dma_ring_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 553 bus_dmamap_unload(sc->sc_dmat, sc->sc_dma_ring_map); 554 bus_dmamem_unmap(sc->sc_dmat, sc->sc_rxq.r_desc, 555 AWGE_TOTAL_RING_COUNT * sizeof(struct dwc_gmac_dev_dmadesc)); 556 bus_dmamem_free(sc->sc_dmat, &sc->sc_dma_ring_seg, 1); 557 } 558 559 static void 560 dwc_gmac_free_rx_ring(struct dwc_gmac_softc *sc, struct dwc_gmac_rx_ring *ring) 561 { 562 struct dwc_gmac_rx_data *data; 563 int i; 564 565 if (ring->r_desc == NULL) 566 return; 567 568 569 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 570 data = &ring->r_data[i]; 571 572 if (data->rd_map != NULL) { 573 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 574 AWGE_RX_RING_COUNT 575 *sizeof(struct dwc_gmac_dev_dmadesc), 576 BUS_DMASYNC_POSTREAD); 577 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 578 bus_dmamap_destroy(sc->sc_dmat, data->rd_map); 579 } 580 if (data->rd_m != NULL) 581 m_freem(data->rd_m); 582 } 583 } 584 585 static int 586 dwc_gmac_alloc_tx_ring(struct dwc_gmac_softc *sc, 587 struct dwc_gmac_tx_ring *ring) 588 { 589 int i, error = 0; 590 591 ring->t_queued = 0; 592 ring->t_cur = ring->t_next = 0; 593 594 memset(ring->t_desc, 0, AWGE_TX_RING_COUNT*sizeof(*ring->t_desc)); 595 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 596 TX_DESC_OFFSET(0), 597 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 598 BUS_DMASYNC_POSTWRITE); 599 600 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 601 error = bus_dmamap_create(sc->sc_dmat, MCLBYTES, 602 AWGE_TX_RING_COUNT, MCLBYTES, 0, 603 BUS_DMA_NOWAIT|BUS_DMA_COHERENT, 604 &ring->t_data[i].td_map); 605 if (error != 0) { 606 aprint_error_dev(sc->sc_dev, 607 "could not create TX DMA map #%d\n", i); 608 ring->t_data[i].td_map = NULL; 609 goto fail; 610 } 611 ring->t_desc[i].ddesc_next = htole32( 612 ring->t_physaddr + sizeof(struct dwc_gmac_dev_dmadesc) 613 *TX_NEXT(i)); 614 } 615 616 return 0; 617 618 fail: 619 dwc_gmac_free_tx_ring(sc, ring); 620 return error; 621 } 622 623 static void 624 dwc_gmac_txdesc_sync(struct dwc_gmac_softc *sc, int start, int end, int ops) 625 { 626 /* 'end' is pointing one descriptor beyound the last we want to sync */ 627 if (end > start) { 628 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 629 TX_DESC_OFFSET(start), 630 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(start), 631 ops); 632 return; 633 } 634 /* sync from 'start' to end of ring */ 635 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 636 TX_DESC_OFFSET(start), 637 TX_DESC_OFFSET(AWGE_TX_RING_COUNT)-TX_DESC_OFFSET(start), 638 ops); 639 /* sync from start of ring to 'end' */ 640 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 641 TX_DESC_OFFSET(0), 642 TX_DESC_OFFSET(end)-TX_DESC_OFFSET(0), 643 ops); 644 } 645 646 static void 647 dwc_gmac_reset_tx_ring(struct dwc_gmac_softc *sc, 648 struct dwc_gmac_tx_ring *ring) 649 { 650 int i; 651 652 mutex_enter(&ring->t_mtx); 653 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 654 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 655 656 if (data->td_m != NULL) { 657 bus_dmamap_sync(sc->sc_dmat, data->td_active, 658 0, data->td_active->dm_mapsize, 659 BUS_DMASYNC_POSTWRITE); 660 bus_dmamap_unload(sc->sc_dmat, data->td_active); 661 m_freem(data->td_m); 662 data->td_m = NULL; 663 } 664 } 665 666 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 667 TX_DESC_OFFSET(0), 668 AWGE_TX_RING_COUNT*sizeof(struct dwc_gmac_dev_dmadesc), 669 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 670 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 671 sc->sc_txq.t_physaddr); 672 673 ring->t_queued = 0; 674 ring->t_cur = ring->t_next = 0; 675 mutex_exit(&ring->t_mtx); 676 } 677 678 static void 679 dwc_gmac_free_tx_ring(struct dwc_gmac_softc *sc, 680 struct dwc_gmac_tx_ring *ring) 681 { 682 int i; 683 684 /* unload the maps */ 685 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 686 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 687 688 if (data->td_m != NULL) { 689 bus_dmamap_sync(sc->sc_dmat, data->td_active, 690 0, data->td_map->dm_mapsize, 691 BUS_DMASYNC_POSTWRITE); 692 bus_dmamap_unload(sc->sc_dmat, data->td_active); 693 m_freem(data->td_m); 694 data->td_m = NULL; 695 } 696 } 697 698 /* and actually free them */ 699 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 700 struct dwc_gmac_tx_data *data = &ring->t_data[i]; 701 702 bus_dmamap_destroy(sc->sc_dmat, data->td_map); 703 } 704 } 705 706 static void 707 dwc_gmac_miibus_statchg(struct ifnet *ifp) 708 { 709 struct dwc_gmac_softc * const sc = ifp->if_softc; 710 struct mii_data * const mii = &sc->sc_mii; 711 uint32_t conf, flow; 712 713 /* 714 * Set MII or GMII interface based on the speed 715 * negotiated by the PHY. 716 */ 717 conf = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_CONF); 718 conf &= ~(AWIN_GMAC_MAC_CONF_FES100|AWIN_GMAC_MAC_CONF_MIISEL 719 |AWIN_GMAC_MAC_CONF_FULLDPLX); 720 conf |= AWIN_GMAC_MAC_CONF_FRAMEBURST 721 | AWIN_GMAC_MAC_CONF_DISABLERXOWN 722 | AWIN_GMAC_MAC_CONF_DISABLEJABBER 723 | AWIN_GMAC_MAC_CONF_ACS 724 | AWIN_GMAC_MAC_CONF_RXENABLE 725 | AWIN_GMAC_MAC_CONF_TXENABLE; 726 switch (IFM_SUBTYPE(mii->mii_media_active)) { 727 case IFM_10_T: 728 conf |= AWIN_GMAC_MAC_CONF_MIISEL; 729 break; 730 case IFM_100_TX: 731 conf |= AWIN_GMAC_MAC_CONF_FES100 | 732 AWIN_GMAC_MAC_CONF_MIISEL; 733 break; 734 case IFM_1000_T: 735 break; 736 } 737 738 flow = 0; 739 if (IFM_OPTIONS(mii->mii_media_active) & IFM_FDX) { 740 conf |= AWIN_GMAC_MAC_CONF_FULLDPLX; 741 flow |= __SHIFTIN(0x200, AWIN_GMAC_MAC_FLOWCTRL_PAUSE); 742 } 743 if (mii->mii_media_active & IFM_ETH_TXPAUSE) { 744 flow |= AWIN_GMAC_MAC_FLOWCTRL_TFE; 745 } 746 if (mii->mii_media_active & IFM_ETH_RXPAUSE) { 747 flow |= AWIN_GMAC_MAC_FLOWCTRL_RFE; 748 } 749 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 750 AWIN_GMAC_MAC_FLOWCTRL, flow); 751 752 #ifdef DWC_GMAC_DEBUG 753 aprint_normal_dev(sc->sc_dev, 754 "setting MAC conf register: %08x\n", conf); 755 #endif 756 757 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 758 AWIN_GMAC_MAC_CONF, conf); 759 } 760 761 static int 762 dwc_gmac_init(struct ifnet *ifp) 763 { 764 struct dwc_gmac_softc *sc = ifp->if_softc; 765 766 mutex_enter(sc->sc_lock); 767 int ret = dwc_gmac_init_locked(ifp); 768 mutex_exit(sc->sc_lock); 769 770 return ret; 771 } 772 773 static int 774 dwc_gmac_init_locked(struct ifnet *ifp) 775 { 776 struct dwc_gmac_softc *sc = ifp->if_softc; 777 uint32_t ffilt; 778 779 if (ifp->if_flags & IFF_RUNNING) 780 return 0; 781 782 dwc_gmac_stop_locked(ifp, 0); 783 784 /* 785 * Configure DMA burst/transfer mode and RX/TX priorities. 786 * XXX - the GMAC_BUSMODE_PRIORXTX bits are undocumented. 787 */ 788 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE, 789 GMAC_BUSMODE_FIXEDBURST | GMAC_BUSMODE_4PBL | 790 __SHIFTIN(2, GMAC_BUSMODE_RPBL) | 791 __SHIFTIN(2, GMAC_BUSMODE_PBL)); 792 793 /* 794 * Set up address filter 795 */ 796 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 797 if (ifp->if_flags & IFF_PROMISC) { 798 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 799 } else { 800 ffilt &= ~AWIN_GMAC_MAC_FFILT_PR; 801 } 802 if (ifp->if_flags & IFF_BROADCAST) { 803 ffilt &= ~AWIN_GMAC_MAC_FFILT_DBF; 804 } else { 805 ffilt |= AWIN_GMAC_MAC_FFILT_DBF; 806 } 807 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 808 809 /* 810 * Set up multicast filter 811 */ 812 dwc_gmac_setmulti(sc); 813 814 /* 815 * Set up dma pointer for RX and TX ring 816 */ 817 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR, 818 sc->sc_rxq.r_physaddr); 819 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR, 820 sc->sc_txq.t_physaddr); 821 822 /* 823 * Start RX/TX part 824 */ 825 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 826 AWIN_GMAC_DMA_OPMODE, GMAC_DMA_OP_RXSTART | GMAC_DMA_OP_TXSTART | 827 GMAC_DMA_OP_RXSTOREFORWARD | GMAC_DMA_OP_TXSTOREFORWARD); 828 829 sc->sc_stopping = false; 830 831 ifp->if_flags |= IFF_RUNNING; 832 ifp->if_flags &= ~IFF_OACTIVE; 833 834 return 0; 835 } 836 837 static void 838 dwc_gmac_start(struct ifnet *ifp) 839 { 840 struct dwc_gmac_softc *sc = ifp->if_softc; 841 #ifdef DWCGMAC_MPSAFE 842 KASSERT(if_is_mpsafe(ifp)); 843 #endif 844 845 mutex_enter(sc->sc_lock); 846 if (!sc->sc_stopping) { 847 mutex_enter(&sc->sc_txq.t_mtx); 848 dwc_gmac_start_locked(ifp); 849 mutex_exit(&sc->sc_txq.t_mtx); 850 } 851 mutex_exit(sc->sc_lock); 852 } 853 854 static void 855 dwc_gmac_start_locked(struct ifnet *ifp) 856 { 857 struct dwc_gmac_softc *sc = ifp->if_softc; 858 int old = sc->sc_txq.t_queued; 859 int start = sc->sc_txq.t_cur; 860 struct mbuf *m0; 861 862 if ((ifp->if_flags & (IFF_RUNNING | IFF_OACTIVE)) != IFF_RUNNING) 863 return; 864 865 for (;;) { 866 IFQ_POLL(&ifp->if_snd, m0); 867 if (m0 == NULL) 868 break; 869 if (dwc_gmac_queue(sc, m0) != 0) { 870 ifp->if_flags |= IFF_OACTIVE; 871 break; 872 } 873 IFQ_DEQUEUE(&ifp->if_snd, m0); 874 bpf_mtap(ifp, m0); 875 if (sc->sc_txq.t_queued == AWGE_TX_RING_COUNT) { 876 ifp->if_flags |= IFF_OACTIVE; 877 break; 878 } 879 } 880 881 if (sc->sc_txq.t_queued != old) { 882 /* packets have been queued, kick it off */ 883 dwc_gmac_txdesc_sync(sc, start, sc->sc_txq.t_cur, 884 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 885 886 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 887 AWIN_GMAC_DMA_TXPOLL, ~0U); 888 #ifdef DWC_GMAC_DEBUG 889 dwc_dump_status(sc); 890 #endif 891 } 892 } 893 894 static void 895 dwc_gmac_stop(struct ifnet *ifp, int disable) 896 { 897 struct dwc_gmac_softc *sc = ifp->if_softc; 898 899 mutex_enter(sc->sc_lock); 900 dwc_gmac_stop_locked(ifp, disable); 901 mutex_exit(sc->sc_lock); 902 } 903 904 static void 905 dwc_gmac_stop_locked(struct ifnet *ifp, int disable) 906 { 907 struct dwc_gmac_softc *sc = ifp->if_softc; 908 909 sc->sc_stopping = true; 910 911 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 912 AWIN_GMAC_DMA_OPMODE, 913 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 914 AWIN_GMAC_DMA_OPMODE) 915 & ~(GMAC_DMA_OP_TXSTART|GMAC_DMA_OP_RXSTART)); 916 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 917 AWIN_GMAC_DMA_OPMODE, 918 bus_space_read_4(sc->sc_bst, sc->sc_bsh, 919 AWIN_GMAC_DMA_OPMODE) | GMAC_DMA_OP_FLUSHTX); 920 921 mii_down(&sc->sc_mii); 922 dwc_gmac_reset_tx_ring(sc, &sc->sc_txq); 923 dwc_gmac_reset_rx_ring(sc, &sc->sc_rxq); 924 } 925 926 /* 927 * Add m0 to the TX ring 928 */ 929 static int 930 dwc_gmac_queue(struct dwc_gmac_softc *sc, struct mbuf *m0) 931 { 932 struct dwc_gmac_dev_dmadesc *desc = NULL; 933 struct dwc_gmac_tx_data *data = NULL; 934 bus_dmamap_t map; 935 uint32_t flags, len, status; 936 int error, i, first; 937 938 #ifdef DWC_GMAC_DEBUG 939 aprint_normal_dev(sc->sc_dev, 940 "dwc_gmac_queue: adding mbuf chain %p\n", m0); 941 #endif 942 943 first = sc->sc_txq.t_cur; 944 map = sc->sc_txq.t_data[first].td_map; 945 946 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m0, 947 BUS_DMA_WRITE|BUS_DMA_NOWAIT); 948 if (error != 0) { 949 aprint_error_dev(sc->sc_dev, "could not map mbuf " 950 "(len: %d, error %d)\n", m0->m_pkthdr.len, error); 951 return error; 952 } 953 954 if (sc->sc_txq.t_queued + map->dm_nsegs > AWGE_TX_RING_COUNT) { 955 bus_dmamap_unload(sc->sc_dmat, map); 956 return ENOBUFS; 957 } 958 959 flags = DDESC_CNTL_TXFIRST|DDESC_CNTL_TXCHAIN; 960 status = 0; 961 for (i = 0; i < map->dm_nsegs; i++) { 962 data = &sc->sc_txq.t_data[sc->sc_txq.t_cur]; 963 desc = &sc->sc_txq.t_desc[sc->sc_txq.t_cur]; 964 965 desc->ddesc_data = htole32(map->dm_segs[i].ds_addr); 966 len = __SHIFTIN(map->dm_segs[i].ds_len, DDESC_CNTL_SIZE1MASK); 967 968 #ifdef DWC_GMAC_DEBUG 969 aprint_normal_dev(sc->sc_dev, "enqueing desc #%d data %08lx " 970 "len %lu (flags: %08x, len: %08x)\n", sc->sc_txq.t_cur, 971 (unsigned long)map->dm_segs[i].ds_addr, 972 (unsigned long)map->dm_segs[i].ds_len, 973 flags, len); 974 #endif 975 976 desc->ddesc_cntl = htole32(len|flags); 977 flags &= ~DDESC_CNTL_TXFIRST; 978 979 /* 980 * Defer passing ownership of the first descriptor 981 * until we are done. 982 */ 983 desc->ddesc_status = htole32(status); 984 status |= DDESC_STATUS_OWNEDBYDEV; 985 986 sc->sc_txq.t_queued++; 987 sc->sc_txq.t_cur = TX_NEXT(sc->sc_txq.t_cur); 988 } 989 990 desc->ddesc_cntl |= htole32(DDESC_CNTL_TXLAST|DDESC_CNTL_TXINT); 991 992 data->td_m = m0; 993 data->td_active = map; 994 995 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 996 BUS_DMASYNC_PREWRITE); 997 998 /* Pass first to device */ 999 sc->sc_txq.t_desc[first].ddesc_status = 1000 htole32(DDESC_STATUS_OWNEDBYDEV); 1001 1002 return 0; 1003 } 1004 1005 /* 1006 * If the interface is up and running, only modify the receive 1007 * filter when setting promiscuous or debug mode. Otherwise fall 1008 * through to ether_ioctl, which will reset the chip. 1009 */ 1010 static int 1011 dwc_gmac_ifflags_cb(struct ethercom *ec) 1012 { 1013 struct ifnet *ifp = &ec->ec_if; 1014 struct dwc_gmac_softc *sc = ifp->if_softc; 1015 int ret = 0; 1016 1017 mutex_enter(sc->sc_lock); 1018 int change = ifp->if_flags ^ sc->sc_if_flags; 1019 sc->sc_if_flags = ifp->if_flags; 1020 1021 if ((change & ~(IFF_CANTCHANGE|IFF_DEBUG)) != 0) { 1022 ret = ENETRESET; 1023 goto out; 1024 } 1025 if ((change & IFF_PROMISC) != 0) { 1026 dwc_gmac_setmulti(sc); 1027 } 1028 out: 1029 mutex_exit(sc->sc_lock); 1030 1031 return ret; 1032 } 1033 1034 static int 1035 dwc_gmac_ioctl(struct ifnet *ifp, u_long cmd, void *data) 1036 { 1037 struct dwc_gmac_softc *sc = ifp->if_softc; 1038 int error = 0; 1039 1040 int s = splnet(); 1041 error = ether_ioctl(ifp, cmd, data); 1042 1043 #ifdef DWCGMAC_MPSAFE 1044 splx(s); 1045 #endif 1046 1047 if (error == ENETRESET) { 1048 error = 0; 1049 if (cmd != SIOCADDMULTI && cmd != SIOCDELMULTI) 1050 ; 1051 else if (ifp->if_flags & IFF_RUNNING) { 1052 /* 1053 * Multicast list has changed; set the hardware filter 1054 * accordingly. 1055 */ 1056 mutex_enter(sc->sc_lock); 1057 dwc_gmac_setmulti(sc); 1058 mutex_exit(sc->sc_lock); 1059 } 1060 } 1061 1062 /* Try to get things going again */ 1063 if (ifp->if_flags & IFF_UP) 1064 dwc_gmac_start(ifp); 1065 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1066 1067 #ifndef DWCGMAC_MPSAFE 1068 splx(s); 1069 #endif 1070 1071 return error; 1072 } 1073 1074 static void 1075 dwc_gmac_tx_intr(struct dwc_gmac_softc *sc) 1076 { 1077 struct ifnet *ifp = &sc->sc_ec.ec_if; 1078 struct dwc_gmac_tx_data *data; 1079 struct dwc_gmac_dev_dmadesc *desc; 1080 uint32_t status; 1081 int i, nsegs; 1082 1083 mutex_enter(&sc->sc_txq.t_mtx); 1084 1085 for (i = sc->sc_txq.t_next; sc->sc_txq.t_queued > 0; i = TX_NEXT(i)) { 1086 #ifdef DWC_GMAC_DEBUG 1087 aprint_normal_dev(sc->sc_dev, 1088 "dwc_gmac_tx_intr: checking desc #%d (t_queued: %d)\n", 1089 i, sc->sc_txq.t_queued); 1090 #endif 1091 1092 /* 1093 * i+1 does not need to be a valid descriptor, 1094 * this is just a special notion to just sync 1095 * a single tx descriptor (i) 1096 */ 1097 dwc_gmac_txdesc_sync(sc, i, i+1, 1098 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1099 1100 desc = &sc->sc_txq.t_desc[i]; 1101 status = le32toh(desc->ddesc_status); 1102 if (status & DDESC_STATUS_OWNEDBYDEV) 1103 break; 1104 1105 data = &sc->sc_txq.t_data[i]; 1106 if (data->td_m == NULL) 1107 continue; 1108 1109 ifp->if_opackets++; 1110 nsegs = data->td_active->dm_nsegs; 1111 bus_dmamap_sync(sc->sc_dmat, data->td_active, 0, 1112 data->td_active->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1113 bus_dmamap_unload(sc->sc_dmat, data->td_active); 1114 1115 #ifdef DWC_GMAC_DEBUG 1116 aprint_normal_dev(sc->sc_dev, 1117 "dwc_gmac_tx_intr: done with packet at desc #%d, " 1118 "freeing mbuf %p\n", i, data->td_m); 1119 #endif 1120 1121 m_freem(data->td_m); 1122 data->td_m = NULL; 1123 1124 sc->sc_txq.t_queued -= nsegs; 1125 } 1126 1127 sc->sc_txq.t_next = i; 1128 1129 if (sc->sc_txq.t_queued < AWGE_TX_RING_COUNT) { 1130 ifp->if_flags &= ~IFF_OACTIVE; 1131 } 1132 mutex_exit(&sc->sc_txq.t_mtx); 1133 } 1134 1135 static void 1136 dwc_gmac_rx_intr(struct dwc_gmac_softc *sc) 1137 { 1138 struct ifnet *ifp = &sc->sc_ec.ec_if; 1139 struct dwc_gmac_dev_dmadesc *desc; 1140 struct dwc_gmac_rx_data *data; 1141 bus_addr_t physaddr; 1142 uint32_t status; 1143 struct mbuf *m, *mnew; 1144 int i, len, error; 1145 1146 mutex_enter(&sc->sc_rxq.r_mtx); 1147 for (i = sc->sc_rxq.r_cur; ; i = RX_NEXT(i)) { 1148 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1149 RX_DESC_OFFSET(i), sizeof(*desc), 1150 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 1151 desc = &sc->sc_rxq.r_desc[i]; 1152 data = &sc->sc_rxq.r_data[i]; 1153 1154 status = le32toh(desc->ddesc_status); 1155 if (status & DDESC_STATUS_OWNEDBYDEV) 1156 break; 1157 1158 if (status & (DDESC_STATUS_RXERROR|DDESC_STATUS_RXTRUNCATED)) { 1159 #ifdef DWC_GMAC_DEBUG 1160 aprint_normal_dev(sc->sc_dev, 1161 "RX error: descriptor status %08x, skipping\n", 1162 status); 1163 #endif 1164 ifp->if_ierrors++; 1165 goto skip; 1166 } 1167 1168 len = __SHIFTOUT(status, DDESC_STATUS_FRMLENMSK); 1169 1170 #ifdef DWC_GMAC_DEBUG 1171 aprint_normal_dev(sc->sc_dev, 1172 "rx int: device is done with descriptor #%d, len: %d\n", 1173 i, len); 1174 #endif 1175 1176 /* 1177 * Try to get a new mbuf before passing this one 1178 * up, if that fails, drop the packet and reuse 1179 * the existing one. 1180 */ 1181 MGETHDR(mnew, M_DONTWAIT, MT_DATA); 1182 if (mnew == NULL) { 1183 ifp->if_ierrors++; 1184 goto skip; 1185 } 1186 MCLGET(mnew, M_DONTWAIT); 1187 if ((mnew->m_flags & M_EXT) == 0) { 1188 m_freem(mnew); 1189 ifp->if_ierrors++; 1190 goto skip; 1191 } 1192 1193 /* unload old DMA map */ 1194 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1195 data->rd_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1196 bus_dmamap_unload(sc->sc_dmat, data->rd_map); 1197 1198 /* and reload with new mbuf */ 1199 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 1200 mtod(mnew, void*), MCLBYTES, NULL, 1201 BUS_DMA_READ | BUS_DMA_NOWAIT); 1202 if (error != 0) { 1203 m_freem(mnew); 1204 /* try to reload old mbuf */ 1205 error = bus_dmamap_load(sc->sc_dmat, data->rd_map, 1206 mtod(data->rd_m, void*), MCLBYTES, NULL, 1207 BUS_DMA_READ | BUS_DMA_NOWAIT); 1208 if (error != 0) { 1209 panic("%s: could not load old rx mbuf", 1210 device_xname(sc->sc_dev)); 1211 } 1212 ifp->if_ierrors++; 1213 goto skip; 1214 } 1215 physaddr = data->rd_map->dm_segs[0].ds_addr; 1216 1217 /* 1218 * New mbuf loaded, update RX ring and continue 1219 */ 1220 m = data->rd_m; 1221 data->rd_m = mnew; 1222 desc->ddesc_data = htole32(physaddr); 1223 1224 /* finalize mbuf */ 1225 m->m_pkthdr.len = m->m_len = len; 1226 m_set_rcvif(m, ifp); 1227 m->m_flags |= M_HASFCS; 1228 1229 if_percpuq_enqueue(sc->sc_ipq, m); 1230 1231 skip: 1232 bus_dmamap_sync(sc->sc_dmat, data->rd_map, 0, 1233 data->rd_map->dm_mapsize, BUS_DMASYNC_PREREAD); 1234 desc->ddesc_cntl = htole32( 1235 __SHIFTIN(AWGE_MAX_PACKET,DDESC_CNTL_SIZE1MASK) | 1236 DDESC_CNTL_RXCHAIN); 1237 desc->ddesc_status = htole32(DDESC_STATUS_OWNEDBYDEV); 1238 bus_dmamap_sync(sc->sc_dmat, sc->sc_dma_ring_map, 1239 RX_DESC_OFFSET(i), sizeof(*desc), 1240 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1241 } 1242 1243 /* update RX pointer */ 1244 sc->sc_rxq.r_cur = i; 1245 1246 mutex_exit(&sc->sc_rxq.r_mtx); 1247 } 1248 1249 /* 1250 * Reverse order of bits - http://aggregate.org/MAGIC/#Bit%20Reversal 1251 */ 1252 static uint32_t 1253 bitrev32(uint32_t x) 1254 { 1255 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); 1256 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); 1257 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); 1258 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); 1259 1260 return (x >> 16) | (x << 16); 1261 } 1262 1263 static void 1264 dwc_gmac_setmulti(struct dwc_gmac_softc *sc) 1265 { 1266 struct ifnet * const ifp = &sc->sc_ec.ec_if; 1267 struct ether_multi *enm; 1268 struct ether_multistep step; 1269 uint32_t hashes[2] = { 0, 0 }; 1270 uint32_t ffilt, h; 1271 int mcnt; 1272 1273 KASSERT(mutex_owned(sc->sc_lock)); 1274 1275 ffilt = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT); 1276 1277 if (ifp->if_flags & IFF_PROMISC) { 1278 ffilt |= AWIN_GMAC_MAC_FFILT_PR; 1279 goto special_filter; 1280 } 1281 1282 ifp->if_flags &= ~IFF_ALLMULTI; 1283 ffilt &= ~(AWIN_GMAC_MAC_FFILT_PM|AWIN_GMAC_MAC_FFILT_PR); 1284 1285 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 0); 1286 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 0); 1287 1288 ETHER_FIRST_MULTI(step, &sc->sc_ec, enm); 1289 mcnt = 0; 1290 while (enm != NULL) { 1291 if (memcmp(enm->enm_addrlo, enm->enm_addrhi, 1292 ETHER_ADDR_LEN) != 0) { 1293 ffilt |= AWIN_GMAC_MAC_FFILT_PM; 1294 ifp->if_flags |= IFF_ALLMULTI; 1295 goto special_filter; 1296 } 1297 1298 h = bitrev32( 1299 ~ether_crc32_le(enm->enm_addrlo, ETHER_ADDR_LEN) 1300 ) >> 26; 1301 hashes[h >> 5] |= (1 << (h & 0x1f)); 1302 1303 mcnt++; 1304 ETHER_NEXT_MULTI(step, enm); 1305 } 1306 1307 if (mcnt) 1308 ffilt |= AWIN_GMAC_MAC_FFILT_HMC; 1309 else 1310 ffilt &= ~AWIN_GMAC_MAC_FFILT_HMC; 1311 1312 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, ffilt); 1313 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1314 hashes[0]); 1315 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1316 hashes[1]); 1317 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1318 1319 #ifdef DWC_GMAC_DEBUG 1320 dwc_gmac_dump_ffilt(sc, ffilt); 1321 #endif 1322 return; 1323 1324 special_filter: 1325 #ifdef DWC_GMAC_DEBUG 1326 dwc_gmac_dump_ffilt(sc, ffilt); 1327 #endif 1328 /* no MAC hashes, ALLMULTI or PROMISC */ 1329 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT, 1330 ffilt); 1331 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTLOW, 1332 0xffffffff); 1333 bus_space_write_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_HTHIGH, 1334 0xffffffff); 1335 sc->sc_if_flags = sc->sc_ec.ec_if.if_flags; 1336 } 1337 1338 int 1339 dwc_gmac_intr(struct dwc_gmac_softc *sc) 1340 { 1341 uint32_t status, dma_status; 1342 int rv = 0; 1343 1344 if (sc->sc_stopping) 1345 return 0; 1346 1347 status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_INTR); 1348 if (status & AWIN_GMAC_MII_IRQ) { 1349 (void)bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1350 AWIN_GMAC_MII_STATUS); 1351 rv = 1; 1352 mii_pollstat(&sc->sc_mii); 1353 } 1354 1355 dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1356 AWIN_GMAC_DMA_STATUS); 1357 1358 if (dma_status & (GMAC_DMA_INT_NIE|GMAC_DMA_INT_AIE)) 1359 rv = 1; 1360 1361 if (dma_status & GMAC_DMA_INT_TIE) 1362 dwc_gmac_tx_intr(sc); 1363 1364 if (dma_status & GMAC_DMA_INT_RIE) 1365 dwc_gmac_rx_intr(sc); 1366 1367 /* 1368 * Check error conditions 1369 */ 1370 if (dma_status & GMAC_DMA_INT_ERRORS) { 1371 sc->sc_ec.ec_if.if_oerrors++; 1372 #ifdef DWC_GMAC_DEBUG 1373 dwc_dump_and_abort(sc, "interrupt error condition"); 1374 #endif 1375 } 1376 1377 /* ack interrupt */ 1378 if (dma_status) 1379 bus_space_write_4(sc->sc_bst, sc->sc_bsh, 1380 AWIN_GMAC_DMA_STATUS, dma_status & GMAC_DMA_INT_MASK); 1381 1382 /* 1383 * Get more packets 1384 */ 1385 if (rv) 1386 if_schedule_deferred_start(&sc->sc_ec.ec_if); 1387 1388 return rv; 1389 } 1390 1391 #ifdef DWC_GMAC_DEBUG 1392 static void 1393 dwc_gmac_dump_dma(struct dwc_gmac_softc *sc) 1394 { 1395 aprint_normal_dev(sc->sc_dev, "busmode: %08x\n", 1396 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_BUSMODE)); 1397 aprint_normal_dev(sc->sc_dev, "tx poll: %08x\n", 1398 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TXPOLL)); 1399 aprint_normal_dev(sc->sc_dev, "rx poll: %08x\n", 1400 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RXPOLL)); 1401 aprint_normal_dev(sc->sc_dev, "rx descriptors: %08x\n", 1402 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_RX_ADDR)); 1403 aprint_normal_dev(sc->sc_dev, "tx descriptors: %08x\n", 1404 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_TX_ADDR)); 1405 aprint_normal_dev(sc->sc_dev, "status: %08x\n", 1406 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_STATUS)); 1407 aprint_normal_dev(sc->sc_dev, "op mode: %08x\n", 1408 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_OPMODE)); 1409 aprint_normal_dev(sc->sc_dev, "int enable: %08x\n", 1410 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_INTENABLE)); 1411 aprint_normal_dev(sc->sc_dev, "cur tx: %08x\n", 1412 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_DESC)); 1413 aprint_normal_dev(sc->sc_dev, "cur rx: %08x\n", 1414 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_DESC)); 1415 aprint_normal_dev(sc->sc_dev, "cur tx buffer: %08x\n", 1416 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_TX_BUFADDR)); 1417 aprint_normal_dev(sc->sc_dev, "cur rx buffer: %08x\n", 1418 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_DMA_CUR_RX_BUFADDR)); 1419 } 1420 1421 static void 1422 dwc_gmac_dump_tx_desc(struct dwc_gmac_softc *sc) 1423 { 1424 int i; 1425 1426 aprint_normal_dev(sc->sc_dev, "TX queue: cur=%d, next=%d, queued=%d\n", 1427 sc->sc_txq.t_cur, sc->sc_txq.t_next, sc->sc_txq.t_queued); 1428 aprint_normal_dev(sc->sc_dev, "TX DMA descriptors:\n"); 1429 for (i = 0; i < AWGE_TX_RING_COUNT; i++) { 1430 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_txq.t_desc[i]; 1431 aprint_normal("#%d (%08lx): status: %08x cntl: %08x " 1432 "data: %08x next: %08x\n", 1433 i, sc->sc_txq.t_physaddr + 1434 i*sizeof(struct dwc_gmac_dev_dmadesc), 1435 le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl), 1436 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1437 } 1438 } 1439 1440 static void 1441 dwc_gmac_dump_rx_desc(struct dwc_gmac_softc *sc) 1442 { 1443 int i; 1444 1445 aprint_normal_dev(sc->sc_dev, "RX queue: cur=%d, next=%d\n", 1446 sc->sc_rxq.r_cur, sc->sc_rxq.r_next); 1447 aprint_normal_dev(sc->sc_dev, "RX DMA descriptors:\n"); 1448 for (i = 0; i < AWGE_RX_RING_COUNT; i++) { 1449 struct dwc_gmac_dev_dmadesc *desc = &sc->sc_rxq.r_desc[i]; 1450 aprint_normal("#%d (%08lx): status: %08x cntl: %08x " 1451 "data: %08x next: %08x\n", 1452 i, sc->sc_rxq.r_physaddr + 1453 i*sizeof(struct dwc_gmac_dev_dmadesc), 1454 le32toh(desc->ddesc_status), le32toh(desc->ddesc_cntl), 1455 le32toh(desc->ddesc_data), le32toh(desc->ddesc_next)); 1456 } 1457 } 1458 1459 static void 1460 dwc_dump_status(struct dwc_gmac_softc *sc) 1461 { 1462 uint32_t status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1463 AWIN_GMAC_MAC_INTR); 1464 uint32_t dma_status = bus_space_read_4(sc->sc_bst, sc->sc_bsh, 1465 AWIN_GMAC_DMA_STATUS); 1466 char buf[200]; 1467 1468 /* print interrupt state */ 1469 snprintb(buf, sizeof(buf), "\177\20" 1470 "b\x10""NI\0" 1471 "b\x0f""AI\0" 1472 "b\x0e""ER\0" 1473 "b\x0d""FB\0" 1474 "b\x0a""ET\0" 1475 "b\x09""RW\0" 1476 "b\x08""RS\0" 1477 "b\x07""RU\0" 1478 "b\x06""RI\0" 1479 "b\x05""UN\0" 1480 "b\x04""OV\0" 1481 "b\x03""TJ\0" 1482 "b\x02""TU\0" 1483 "b\x01""TS\0" 1484 "b\x00""TI\0" 1485 "\0", dma_status); 1486 aprint_normal_dev(sc->sc_dev, "INTR status: %08x, DMA status: %s\n", 1487 status, buf); 1488 } 1489 1490 static void 1491 dwc_dump_and_abort(struct dwc_gmac_softc *sc, const char *msg) 1492 { 1493 dwc_dump_status(sc); 1494 dwc_gmac_dump_ffilt(sc, 1495 bus_space_read_4(sc->sc_bst, sc->sc_bsh, AWIN_GMAC_MAC_FFILT)); 1496 dwc_gmac_dump_dma(sc); 1497 dwc_gmac_dump_tx_desc(sc); 1498 dwc_gmac_dump_rx_desc(sc); 1499 1500 panic("%s", msg); 1501 } 1502 1503 static void dwc_gmac_dump_ffilt(struct dwc_gmac_softc *sc, uint32_t ffilt) 1504 { 1505 char buf[200]; 1506 1507 /* print filter setup */ 1508 snprintb(buf, sizeof(buf), "\177\20" 1509 "b\x1f""RA\0" 1510 "b\x0a""HPF\0" 1511 "b\x09""SAF\0" 1512 "b\x08""SAIF\0" 1513 "b\x05""DBF\0" 1514 "b\x04""PM\0" 1515 "b\x03""DAIF\0" 1516 "b\x02""HMC\0" 1517 "b\x01""HUC\0" 1518 "b\x00""PR\0" 1519 "\0", ffilt); 1520 aprint_normal_dev(sc->sc_dev, "FFILT: %s\n", buf); 1521 } 1522 #endif 1523