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