1 /* $OpenBSD: if_dwxe.c,v 1.24 2024/02/27 10:47:20 kettenis Exp $ */ 2 /* 3 * Copyright (c) 2008 Mark Kettenis 4 * Copyright (c) 2017 Patrick Wildt <patrick@blueri.se> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 /* 20 * Driver for the ethernet controller on the Allwinner H3/A64 SoCs. 21 */ 22 23 #include "bpfilter.h" 24 25 #include <sys/param.h> 26 #include <sys/systm.h> 27 #include <sys/device.h> 28 #include <sys/kernel.h> 29 #include <sys/malloc.h> 30 #include <sys/mbuf.h> 31 #include <sys/queue.h> 32 #include <sys/socket.h> 33 #include <sys/sockio.h> 34 #include <sys/timeout.h> 35 36 #include <machine/bus.h> 37 #include <machine/fdt.h> 38 39 #include <net/if.h> 40 #include <net/if_media.h> 41 42 #include <dev/ofw/openfirm.h> 43 #include <dev/ofw/ofw_clock.h> 44 #include <dev/ofw/ofw_misc.h> 45 #include <dev/ofw/ofw_pinctrl.h> 46 #include <dev/ofw/ofw_regulator.h> 47 #include <dev/ofw/fdt.h> 48 49 #include <dev/mii/mii.h> 50 #include <dev/mii/miivar.h> 51 52 #if NBPFILTER > 0 53 #include <net/bpf.h> 54 #endif 55 56 #include <netinet/in.h> 57 #include <netinet/if_ether.h> 58 59 /* 60 * DWXE registers. 61 */ 62 63 #define DWXE_BASIC_CTL0 0x00 64 #define DWXE_BASIC_CTL0_DUPLEX (1 << 0) 65 #define DWXE_BASIC_CTL0_LOOPBACK (1 << 1) 66 #define DWXE_BASIC_CTL0_SPEED_1000 (0 << 2) 67 #define DWXE_BASIC_CTL0_SPEED_10 (2 << 2) 68 #define DWXE_BASIC_CTL0_SPEED_100 (3 << 2) 69 #define DWXE_BASIC_CTL0_SPEED_MASK (3 << 2) 70 #define DWXE_BASIC_CTL1 0x04 71 #define DWXE_BASIC_CTL1_SOFT_RST (1 << 0) 72 #define DWXE_BASIC_CTL1_RX_TX_PRI (1 << 1) 73 #define DWXE_BASIC_CTL1_BURST_LEN_MASK (0x3f << 24) 74 #define DWXE_BASIC_CTL1_BURST_LEN(x) ((x) << 24) 75 #define DWXE_INT_STA 0x08 76 #define DWXE_INT_STA_TX_INT (1 << 0) 77 #define DWXE_INT_STA_TX_DMA_STOP_INT (1 << 1) 78 #define DWXE_INT_STA_TX_BUF_UA_INT (1 << 2) 79 #define DWXE_INT_STA_TX_TIMEOUT_INT (1 << 3) 80 #define DWXE_INT_STA_TX_UNDERFLOW_INT (1 << 4) 81 #define DWXE_INT_STA_TX_EARLY_INT (1 << 5) 82 #define DWXE_INT_STA_RX_INT (1 << 8) 83 #define DWXE_INT_STA_RX_BUF_UA_INT (1 << 9) 84 #define DWXE_INT_STA_RX_DMA_STOP_INT (1 << 10) 85 #define DWXE_INT_STA_RX_TIMEOUT_INT (1 << 11) 86 #define DWXE_INT_STA_RX_OVERFLOW_INT (1 << 12) 87 #define DWXE_INT_STA_RX_EARLY_INT (1 << 13) 88 #define DWXE_INT_STA_RGMII_STA_INT (1 << 16) 89 #define DWXE_INT_EN 0x0C 90 #define DWXE_INT_EN_TX_INT (1 << 0) 91 #define DWXE_INT_EN_TX_DMA_STOP_INT (1 << 1) 92 #define DWXE_INT_EN_TX_BUF_UA_INT (1 << 2) 93 #define DWXE_INT_EN_TX_TIMEOUT_INT (1 << 3) 94 #define DWXE_INT_EN_TX_UNDERFLOW_INT (1 << 4) 95 #define DWXE_INT_EN_TX_EARLY_INT (1 << 5) 96 #define DWXE_INT_EN_RX_INT (1 << 8) 97 #define DWXE_INT_EN_RX_BUF_UA_INT (1 << 9) 98 #define DWXE_INT_EN_RX_DMA_STOP_INT (1 << 10) 99 #define DWXE_INT_EN_RX_TIMEOUT_INT (1 << 11) 100 #define DWXE_INT_EN_RX_OVERFLOW_INT (1 << 12) 101 #define DWXE_INT_EN_RX_EARLY_INT (1 << 13) 102 #define DWXE_INT_EN_RGMII_EN_INT (1 << 16) 103 #define DWXE_TX_CTL0 0x10 104 #define DWXE_TX_CTL0_TX_TRANSMITTER_EN (1U << 31) 105 #define DWXE_TX_CTL1 0x14 106 #define DWXE_TX_CTL1_TX_FIFO_FLUSH (1 << 0) 107 #define DWXE_TX_CTL1_TX_MD (1 << 1) 108 #define DWXE_TX_CTL1_TX_NEXT_FRM (1 << 2) 109 #define DWXE_TX_CTL1_TX_TH_MASK (0x3 << 8) 110 #define DWXE_TX_CTL1_TX_TH_64 0 111 #define DWXE_TX_CTL1_TX_TH_128 (0x1 << 8) 112 #define DWXE_TX_CTL1_TX_TH_192 (0x2 << 8) 113 #define DWXE_TX_CTL1_TX_TH_256 (0x3 << 8) 114 #define DWXE_TX_CTL1_TX_DMA_EN (1 << 30) 115 #define DWXE_TX_CTL1_TX_DMA_START (1U << 31) 116 #define DWXE_TX_FLOW_CTL 0x1C 117 #define DWXE_TX_FLOW_CTL_EN (1 << 0) 118 #define DWXE_TX_DESC_LIST 0x20 119 #define DWXE_RX_CTL0 0x24 120 #define DWXE_RX_CTL0_RX_FLOW_CTL_EN (1 << 16) 121 #define DWXE_RX_CTL0_RX_DO_CRC (1 << 27) 122 #define DWXE_RX_CTL0_RX_RECEIVER_EN (1U << 31) 123 #define DWXE_RX_CTL1 0x28 124 #define DWXE_RX_CTL1_RX_MD (1 << 1) 125 #define DWXE_RX_CTL1_RX_TH_MASK (0x3 << 4) 126 #define DWXE_RX_CTL1_RX_TH_32 (0x0 << 4) 127 #define DWXE_RX_CTL1_RX_TH_64 (0x1 << 4) 128 #define DWXE_RX_CTL1_RX_TH_96 (0x2 << 4) 129 #define DWXE_RX_CTL1_RX_TH_128 (0x3 << 4) 130 #define DWXE_RX_CTL1_RX_DMA_EN (1 << 30) 131 #define DWXE_RX_CTL1_RX_DMA_START (1U << 31) 132 #define DWXE_RX_DESC_LIST 0x34 133 #define DWXE_RX_FRM_FLT 0x38 134 #define DWXE_RX_FRM_FLT_RX_ALL (1 << 0) 135 #define DWXE_RX_FRM_FLT_HASH_UNICAST (1 << 8) 136 #define DWXE_RX_FRM_FLT_HASH_MULTICAST (1 << 9) 137 #define DWXE_RX_FRM_FLT_CTL (1 << 13) 138 #define DWXE_RX_FRM_FLT_RX_ALL_MULTICAST (1 << 16) 139 #define DWXE_RX_FRM_FLT_DIS_BROADCAST (1 << 17) 140 #define DWXE_RX_FRM_FLT_DIS_ADDR_FILTER (1U << 31) 141 #define DWXE_RX_HASH0 0x40 142 #define DWXE_RX_HASH1 0x44 143 #define DWXE_MDIO_CMD 0x48 144 #define DWXE_MDIO_CMD_MII_BUSY (1 << 0) 145 #define DWXE_MDIO_CMD_MII_WRITE (1 << 1) 146 #define DWXE_MDIO_CMD_PHY_REG_SHIFT 4 147 #define DWXE_MDIO_CMD_PHY_ADDR_SHIFT 12 148 #define DWXE_MDIO_CMD_MDC_DIV_RATIO_M_SHIFT 20 149 #define DWXE_MDIO_CMD_MDC_DIV_RATIO_M_MASK 0x7 150 #define DWXE_MDIO_CMD_MDC_DIV_RATIO_M_16 0 151 #define DWXE_MDIO_CMD_MDC_DIV_RATIO_M_32 1 152 #define DWXE_MDIO_CMD_MDC_DIV_RATIO_M_64 2 153 #define DWXE_MDIO_CMD_MDC_DIV_RATIO_M_128 3 154 #define DWXE_MDIO_DATA 0x4C 155 #define DWXE_MACADDR_HI 0x50 156 #define DWXE_MACADDR_LO 0x54 157 #define DWXE_TX_DMA_STA 0xB0 158 #define DWXE_TX_CUR_DESC 0xB4 159 #define DWXE_TX_CUR_BUF 0xB8 160 #define DWXE_RX_DMA_STA 0xC0 161 #define DWXE_RX_CUR_DESC 0xC4 162 #define DWXE_RX_CUR_BUF 0xC8 163 164 /* 165 * DWXE descriptors. 166 */ 167 168 struct dwxe_desc { 169 uint32_t sd_status; 170 uint32_t sd_len; 171 uint32_t sd_addr; 172 uint32_t sd_next; 173 }; 174 175 /* Tx status bits. */ 176 #define DWXE_TX_DEFER (1 << 0) 177 #define DWXE_TX_UNDERFLOW_ERR (1 << 1) 178 #define DWXE_TX_DEFER_ERR (1 << 2) 179 #define DWXE_TX_COL_CNT_MASK (0xf << 3) 180 #define DWXE_TX_COL_CNT_SHIFT 3 181 #define DWXE_TX_COL_ERR_1 (1 << 8) 182 #define DWXE_TX_COL_ERR_0 (1 << 9) 183 #define DWXE_TX_CRS_ERR (1 << 10) 184 #define DWXE_TX_PAYLOAD_ERR (1 << 12) 185 #define DWXE_TX_LENGTH_ERR (1 << 14) 186 #define DWXE_TX_HEADER_ERR (1 << 16) 187 #define DWXE_TX_DESC_CTL (1U << 31) 188 189 /* Rx status bits */ 190 #define DWXE_RX_PAYLOAD_ERR (1 << 0) 191 #define DWXE_RX_CRC_ERR (1 << 1) 192 #define DWXE_RX_PHY_ERR (1 << 3) 193 #define DWXE_RX_LENGTH_ERR (1 << 4) 194 #define DWXE_RX_FRM_TYPE (1 << 5) 195 #define DWXE_RX_COL_ERR (1 << 6) 196 #define DWXE_RX_HEADER_ERR (1 << 7) 197 #define DWXE_RX_LAST_DESC (1 << 8) 198 #define DWXE_RX_FIR_DESC (1 << 9) 199 #define DWXE_RX_OVERFLOW_ERR (1 << 11) 200 #define DWXE_RX_SAF_FAIL (1 << 13) 201 #define DWXE_RX_NO_ENOUGH_BUF_ERR (1 << 14) 202 #define DWXE_RX_FRM_LEN_MASK 0x3fff 203 #define DWXE_RX_FRM_LEN_SHIFT 16 204 #define DWXE_RX_DAF_FAIL (1 << 30) 205 #define DWXE_RX_DESC_CTL (1U << 31) 206 207 /* Tx size bits */ 208 #define DWXE_TX_BUF_SIZE (0xfff << 0) 209 #define DWXE_TX_CRC_CTL (1 << 26) 210 #define DWXE_TX_CHECKSUM_CTL_MASK (0x3 << 27) 211 #define DWXE_TX_CHECKSUM_CTL_IP (1 << 27) 212 #define DWXE_TX_CHECKSUM_CTL_NO_PSE (2 << 27) 213 #define DWXE_TX_CHECKSUM_CTL_FULL (3 << 27) 214 #define DWXE_TX_FIR_DESC (1 << 29) 215 #define DWXE_TX_LAST_DESC (1 << 30) 216 #define DWXE_TX_INT_CTL (1U << 31) 217 218 /* Rx size bits */ 219 #define DWXE_RX_BUF_SIZE (0xfff << 0) 220 #define DWXE_RX_INT_CTL (1U << 31) 221 222 /* EMAC syscon bits */ 223 #define SYSCON_EMAC 0x30 224 #define SYSCON_ETCS_MASK (0x3 << 0) 225 #define SYSCON_ETCS_MII (0 << 0) 226 #define SYSCON_ETCS_EXT_GMII (1 << 0) 227 #define SYSCON_ETCS_INT_GMII (2 << 0) 228 #define SYSCON_EPIT (1 << 2) /* 1: RGMII, 0: MII */ 229 #define SYSCON_ERXDC_MASK (0xf << 5) 230 #define SYSCON_ERXDC_SHIFT 5 231 #define SYSCON_ETXDC_MASK (0x7 << 10) 232 #define SYSCON_ETXDC_SHIFT 10 233 #define SYSCON_RMII_EN (1 << 13) /* 1: enable RMII (overrides EPIT) */ 234 #define SYSCON_H3_EPHY_SELECT (1 << 15) /* 1: internal PHY, 0: external PHY */ 235 #define SYSCON_H3_EPHY_SHUTDOWN (1 << 16) /* 1: shutdown, 0: power up */ 236 #define SYSCON_H3_EPHY_LED_POL (1 << 17) /* 1: active low, 0: active high */ 237 #define SYSCON_H3_EPHY_CLK_SEL (1 << 18) /* 1: 24MHz, 0: 25MHz */ 238 #define SYSCON_H3_EPHY_ADDR_MASK (0x1f << 20) 239 #define SYSCON_H3_EPHY_ADDR_SHIFT 20 240 241 /* GMAC syscon bits (Allwinner R40) */ 242 #define SYSCON_GMAC 0x00 243 #define SYSCON_GTCS_MASK SYSCON_ETCS_MASK 244 #define SYSCON_GTCS_MII SYSCON_ETCS_MII 245 #define SYSCON_GTCS_EXT_GMII SYSCON_ETCS_EXT_GMII 246 #define SYSCON_GTCS_INT_GMII SYSCON_ETCS_INT_GMII 247 #define SYSCON_GPIT SYSCON_EPIT 248 #define SYSCON_GRXDC_MASK (0x7 << 5) 249 #define SYSCON_GRXDC_SHIFT 5 250 251 struct dwxe_buf { 252 bus_dmamap_t tb_map; 253 struct mbuf *tb_m; 254 }; 255 256 #define DWXE_NTXDESC 256 257 #define DWXE_NTXSEGS 16 258 259 #define DWXE_NRXDESC 256 260 261 struct dwxe_dmamem { 262 bus_dmamap_t tdm_map; 263 bus_dma_segment_t tdm_seg; 264 size_t tdm_size; 265 caddr_t tdm_kva; 266 }; 267 #define DWXE_DMA_MAP(_tdm) ((_tdm)->tdm_map) 268 #define DWXE_DMA_LEN(_tdm) ((_tdm)->tdm_size) 269 #define DWXE_DMA_DVA(_tdm) ((_tdm)->tdm_map->dm_segs[0].ds_addr) 270 #define DWXE_DMA_KVA(_tdm) ((void *)(_tdm)->tdm_kva) 271 272 struct dwxe_softc { 273 struct device sc_dev; 274 int sc_node; 275 bus_space_tag_t sc_iot; 276 bus_space_handle_t sc_ioh; 277 bus_dma_tag_t sc_dmat; 278 void *sc_ih; 279 280 struct arpcom sc_ac; 281 #define sc_lladdr sc_ac.ac_enaddr 282 struct mii_data sc_mii; 283 #define sc_media sc_mii.mii_media 284 int sc_link; 285 int sc_phyloc; 286 287 struct dwxe_dmamem *sc_txring; 288 struct dwxe_buf *sc_txbuf; 289 struct dwxe_desc *sc_txdesc; 290 int sc_tx_prod; 291 int sc_tx_cons; 292 293 struct dwxe_dmamem *sc_rxring; 294 struct dwxe_buf *sc_rxbuf; 295 struct dwxe_desc *sc_rxdesc; 296 int sc_rx_prod; 297 struct if_rxring sc_rx_ring; 298 int sc_rx_cons; 299 300 struct timeout sc_tick; 301 struct timeout sc_rxto; 302 303 uint32_t sc_clk; 304 }; 305 306 #define DEVNAME(_s) ((_s)->sc_dev.dv_xname) 307 308 int dwxe_match(struct device *, void *, void *); 309 void dwxe_attach(struct device *, struct device *, void *); 310 int dwxe_activate(struct device *, int); 311 void dwxe_init(struct dwxe_softc *sc); 312 void dwxe_phy_setup_emac(struct dwxe_softc *); 313 void dwxe_phy_setup_gmac(struct dwxe_softc *); 314 315 const struct cfattach dwxe_ca = { 316 sizeof(struct dwxe_softc), dwxe_match, dwxe_attach, 317 NULL, dwxe_activate 318 }; 319 320 struct cfdriver dwxe_cd = { 321 NULL, "dwxe", DV_IFNET 322 }; 323 324 uint32_t dwxe_read(struct dwxe_softc *, bus_addr_t); 325 void dwxe_write(struct dwxe_softc *, bus_addr_t, uint32_t); 326 327 int dwxe_ioctl(struct ifnet *, u_long, caddr_t); 328 void dwxe_start(struct ifqueue *); 329 void dwxe_watchdog(struct ifnet *); 330 331 int dwxe_media_change(struct ifnet *); 332 void dwxe_media_status(struct ifnet *, struct ifmediareq *); 333 334 int dwxe_mii_readreg(struct device *, int, int); 335 void dwxe_mii_writereg(struct device *, int, int, int); 336 void dwxe_mii_statchg(struct device *); 337 338 void dwxe_lladdr_read(struct dwxe_softc *, uint8_t *); 339 void dwxe_lladdr_write(struct dwxe_softc *); 340 341 void dwxe_tick(void *); 342 void dwxe_rxtick(void *); 343 344 int dwxe_intr(void *); 345 void dwxe_tx_proc(struct dwxe_softc *); 346 void dwxe_rx_proc(struct dwxe_softc *); 347 348 void dwxe_up(struct dwxe_softc *); 349 void dwxe_down(struct dwxe_softc *); 350 void dwxe_iff(struct dwxe_softc *); 351 int dwxe_encap(struct dwxe_softc *, struct mbuf *, int *, int *); 352 353 void dwxe_reset(struct dwxe_softc *); 354 void dwxe_stop_dma(struct dwxe_softc *); 355 356 struct dwxe_dmamem * 357 dwxe_dmamem_alloc(struct dwxe_softc *, bus_size_t, bus_size_t); 358 void dwxe_dmamem_free(struct dwxe_softc *, struct dwxe_dmamem *); 359 struct mbuf *dwxe_alloc_mbuf(struct dwxe_softc *, bus_dmamap_t); 360 void dwxe_fill_rx_ring(struct dwxe_softc *); 361 362 int 363 dwxe_match(struct device *parent, void *cfdata, void *aux) 364 { 365 struct fdt_attach_args *faa = aux; 366 367 return OF_is_compatible(faa->fa_node, "allwinner,sun8i-h3-emac") || 368 OF_is_compatible(faa->fa_node, "allwinner,sun8i-r40-gmac") || 369 OF_is_compatible(faa->fa_node, "allwinner,sun50i-a64-emac"); 370 } 371 372 void 373 dwxe_attach(struct device *parent, struct device *self, void *aux) 374 { 375 struct dwxe_softc *sc = (void *)self; 376 struct fdt_attach_args *faa = aux; 377 char phy_mode[16] = { 0 }; 378 struct ifnet *ifp; 379 uint32_t phy; 380 int mii_flags = 0; 381 int node; 382 383 sc->sc_node = faa->fa_node; 384 sc->sc_iot = faa->fa_iot; 385 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 386 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 387 printf("%s: cannot map registers\n", self->dv_xname); 388 return; 389 } 390 sc->sc_dmat = faa->fa_dmat; 391 392 OF_getprop(faa->fa_node, "phy-mode", phy_mode, sizeof(phy_mode)); 393 if (strcmp(phy_mode, "rgmii") == 0) 394 mii_flags |= MIIF_SETDELAY; 395 else if (strcmp(phy_mode, "rgmii-rxid") == 0) 396 mii_flags |= MIIF_SETDELAY | MIIF_RXID; 397 else if (strcmp(phy_mode, "rgmii-txid") == 0) 398 mii_flags |= MIIF_SETDELAY | MIIF_TXID; 399 else if (strcmp(phy_mode, "rgmii-id") == 0) 400 mii_flags |= MIIF_SETDELAY | MIIF_RXID | MIIF_TXID; 401 402 /* Lookup PHY. */ 403 phy = OF_getpropint(faa->fa_node, "phy-handle", 0); 404 node = OF_getnodebyphandle(phy); 405 if (node) 406 sc->sc_phyloc = OF_getpropint(node, "reg", MII_PHY_ANY); 407 else 408 sc->sc_phyloc = MII_PHY_ANY; 409 sc->sc_mii.mii_node = node; 410 411 sc->sc_clk = clock_get_frequency(faa->fa_node, "stmmaceth"); 412 if (sc->sc_clk > 160000000) 413 sc->sc_clk = DWXE_MDIO_CMD_MDC_DIV_RATIO_M_128; 414 else if (sc->sc_clk > 80000000) 415 sc->sc_clk = DWXE_MDIO_CMD_MDC_DIV_RATIO_M_64; 416 else if (sc->sc_clk > 40000000) 417 sc->sc_clk = DWXE_MDIO_CMD_MDC_DIV_RATIO_M_32; 418 else 419 sc->sc_clk = DWXE_MDIO_CMD_MDC_DIV_RATIO_M_16; 420 421 if (OF_getprop(faa->fa_node, "local-mac-address", 422 &sc->sc_lladdr, ETHER_ADDR_LEN) != ETHER_ADDR_LEN) 423 dwxe_lladdr_read(sc, sc->sc_lladdr); 424 printf(": address %s\n", ether_sprintf(sc->sc_lladdr)); 425 426 dwxe_init(sc); 427 428 timeout_set(&sc->sc_tick, dwxe_tick, sc); 429 timeout_set(&sc->sc_rxto, dwxe_rxtick, sc); 430 431 ifp = &sc->sc_ac.ac_if; 432 ifp->if_softc = sc; 433 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 434 ifp->if_xflags = IFXF_MPSAFE; 435 ifp->if_ioctl = dwxe_ioctl; 436 ifp->if_qstart = dwxe_start; 437 ifp->if_watchdog = dwxe_watchdog; 438 ifq_init_maxlen(&ifp->if_snd, DWXE_NTXDESC - 1); 439 bcopy(sc->sc_dev.dv_xname, ifp->if_xname, IFNAMSIZ); 440 441 ifp->if_capabilities = IFCAP_VLAN_MTU; 442 443 sc->sc_mii.mii_ifp = ifp; 444 sc->sc_mii.mii_readreg = dwxe_mii_readreg; 445 sc->sc_mii.mii_writereg = dwxe_mii_writereg; 446 sc->sc_mii.mii_statchg = dwxe_mii_statchg; 447 448 ifmedia_init(&sc->sc_media, 0, dwxe_media_change, dwxe_media_status); 449 450 mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc, 451 MII_OFFSET_ANY, MIIF_NOISOLATE | mii_flags); 452 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 453 printf("%s: no PHY found!\n", sc->sc_dev.dv_xname); 454 ifmedia_add(&sc->sc_media, IFM_ETHER|IFM_MANUAL, 0, NULL); 455 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_MANUAL); 456 } else 457 ifmedia_set(&sc->sc_media, IFM_ETHER|IFM_AUTO); 458 459 if_attach(ifp); 460 ether_ifattach(ifp); 461 462 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_NET | IPL_MPSAFE, 463 dwxe_intr, sc, sc->sc_dev.dv_xname); 464 if (sc->sc_ih == NULL) 465 printf("%s: can't establish interrupt\n", sc->sc_dev.dv_xname); 466 } 467 468 int 469 dwxe_activate(struct device *self, int act) 470 { 471 struct dwxe_softc *sc = (struct dwxe_softc *)self; 472 struct ifnet *ifp = &sc->sc_ac.ac_if; 473 474 switch (act) { 475 case DVACT_SUSPEND: 476 if (ifp->if_flags & IFF_RUNNING) 477 dwxe_down(sc); 478 break; 479 case DVACT_RESUME: 480 dwxe_init(sc); 481 if (ifp->if_flags & IFF_UP) 482 dwxe_up(sc); 483 break; 484 } 485 486 return 0; 487 } 488 489 void 490 dwxe_init(struct dwxe_softc *sc) 491 { 492 uint32_t phy_supply; 493 494 pinctrl_byname(sc->sc_node, "default"); 495 496 /* Enable clock. */ 497 clock_enable(sc->sc_node, "stmmaceth"); 498 reset_deassert(sc->sc_node, "stmmaceth"); 499 delay(5000); 500 501 /* Power up PHY. */ 502 phy_supply = OF_getpropint(sc->sc_node, "phy-supply", 0); 503 if (phy_supply) 504 regulator_enable(phy_supply); 505 506 /* Do hardware specific initializations. */ 507 if (OF_is_compatible(sc->sc_node, "allwinner,sun8i-r40-gmac")) 508 dwxe_phy_setup_gmac(sc); 509 else 510 dwxe_phy_setup_emac(sc); 511 512 dwxe_reset(sc); 513 } 514 515 void 516 dwxe_phy_setup_emac(struct dwxe_softc *sc) 517 { 518 struct regmap *rm; 519 uint32_t syscon; 520 uint32_t tx_delay, rx_delay; 521 char *phy_mode; 522 int len; 523 524 rm = regmap_byphandle(OF_getpropint(sc->sc_node, "syscon", 0)); 525 if (rm == NULL) 526 return; 527 528 syscon = regmap_read_4(rm, SYSCON_EMAC); 529 syscon &= ~(SYSCON_ETCS_MASK|SYSCON_EPIT|SYSCON_RMII_EN); 530 syscon &= ~(SYSCON_ETXDC_MASK | SYSCON_ERXDC_MASK); 531 syscon &= ~SYSCON_H3_EPHY_SELECT; 532 533 if ((len = OF_getproplen(sc->sc_node, "phy-mode")) <= 0) 534 return; 535 phy_mode = malloc(len, M_TEMP, M_WAITOK); 536 OF_getprop(sc->sc_node, "phy-mode", phy_mode, len); 537 if (!strncmp(phy_mode, "rgmii", strlen("rgmii"))) 538 syscon |= SYSCON_EPIT | SYSCON_ETCS_INT_GMII; 539 else if (!strncmp(phy_mode, "rmii", strlen("rmii"))) 540 syscon |= SYSCON_EPIT | SYSCON_ETCS_EXT_GMII; 541 else if (!strncmp(phy_mode, "mii", strlen("mii")) && 542 OF_is_compatible(sc->sc_node, "allwinner,sun8i-h3-emac")) { 543 syscon &= ~SYSCON_H3_EPHY_SHUTDOWN; 544 syscon |= SYSCON_H3_EPHY_SELECT | SYSCON_H3_EPHY_CLK_SEL; 545 if (OF_getproplen(sc->sc_node, "allwinner,leds-active-low") == 0) 546 syscon |= SYSCON_H3_EPHY_LED_POL; 547 else 548 syscon &= ~SYSCON_H3_EPHY_LED_POL; 549 syscon &= ~SYSCON_H3_EPHY_ADDR_MASK; 550 syscon |= (sc->sc_phyloc << SYSCON_H3_EPHY_ADDR_SHIFT); 551 } 552 free(phy_mode, M_TEMP, len); 553 554 tx_delay = OF_getpropint(sc->sc_node, "allwinner,tx-delay-ps", 0); 555 rx_delay = OF_getpropint(sc->sc_node, "allwinner,rx-delay-ps", 0); 556 syscon |= ((tx_delay / 100) << SYSCON_ETXDC_SHIFT) & SYSCON_ETXDC_MASK; 557 syscon |= ((rx_delay / 100) << SYSCON_ERXDC_SHIFT) & SYSCON_ERXDC_MASK; 558 559 regmap_write_4(rm, SYSCON_EMAC, syscon); 560 } 561 562 void 563 dwxe_phy_setup_gmac(struct dwxe_softc *sc) 564 { 565 struct regmap *rm; 566 uint32_t syscon; 567 uint32_t rx_delay; 568 char *phy_mode; 569 int len; 570 571 rm = regmap_byphandle(OF_getpropint(sc->sc_node, "syscon", 0)); 572 if (rm == NULL) 573 return; 574 575 syscon = regmap_read_4(rm, SYSCON_GMAC); 576 syscon &= ~(SYSCON_GTCS_MASK|SYSCON_GPIT|SYSCON_ERXDC_MASK); 577 578 if ((len = OF_getproplen(sc->sc_node, "phy-mode")) <= 0) 579 return; 580 phy_mode = malloc(len, M_TEMP, M_WAITOK); 581 OF_getprop(sc->sc_node, "phy-mode", phy_mode, len); 582 if (!strncmp(phy_mode, "rgmii", strlen("rgmii"))) 583 syscon |= SYSCON_GPIT | SYSCON_GTCS_INT_GMII; 584 else if (!strncmp(phy_mode, "rmii", strlen("rmii"))) 585 syscon |= SYSCON_GPIT | SYSCON_GTCS_EXT_GMII; 586 free(phy_mode, M_TEMP, len); 587 588 rx_delay = OF_getpropint(sc->sc_node, "allwinner,rx-delay-ps", 0); 589 syscon |= ((rx_delay / 100) << SYSCON_ERXDC_SHIFT) & SYSCON_ERXDC_MASK; 590 591 regmap_write_4(rm, SYSCON_GMAC, syscon); 592 } 593 594 uint32_t 595 dwxe_read(struct dwxe_softc *sc, bus_addr_t addr) 596 { 597 return bus_space_read_4(sc->sc_iot, sc->sc_ioh, addr); 598 } 599 600 void 601 dwxe_write(struct dwxe_softc *sc, bus_addr_t addr, uint32_t data) 602 { 603 bus_space_write_4(sc->sc_iot, sc->sc_ioh, addr, data); 604 } 605 606 void 607 dwxe_lladdr_read(struct dwxe_softc *sc, uint8_t *lladdr) 608 { 609 uint32_t machi, maclo; 610 611 machi = dwxe_read(sc, DWXE_MACADDR_HI); 612 maclo = dwxe_read(sc, DWXE_MACADDR_LO); 613 614 lladdr[0] = (maclo >> 0) & 0xff; 615 lladdr[1] = (maclo >> 8) & 0xff; 616 lladdr[2] = (maclo >> 16) & 0xff; 617 lladdr[3] = (maclo >> 24) & 0xff; 618 lladdr[4] = (machi >> 0) & 0xff; 619 lladdr[5] = (machi >> 8) & 0xff; 620 } 621 622 void 623 dwxe_lladdr_write(struct dwxe_softc *sc) 624 { 625 dwxe_write(sc, DWXE_MACADDR_HI, 626 sc->sc_lladdr[5] << 8 | sc->sc_lladdr[4] << 0); 627 dwxe_write(sc, DWXE_MACADDR_LO, 628 sc->sc_lladdr[3] << 24 | sc->sc_lladdr[2] << 16 | 629 sc->sc_lladdr[1] << 8 | sc->sc_lladdr[0] << 0); 630 } 631 632 void 633 dwxe_start(struct ifqueue *ifq) 634 { 635 struct ifnet *ifp = ifq->ifq_if; 636 struct dwxe_softc *sc = ifp->if_softc; 637 struct mbuf *m; 638 int error, idx, left, used; 639 640 if (!(ifp->if_flags & IFF_RUNNING)) 641 return; 642 if (ifq_is_oactive(&ifp->if_snd)) 643 return; 644 if (ifq_empty(&ifp->if_snd)) 645 return; 646 if (!sc->sc_link) 647 return; 648 649 idx = sc->sc_tx_prod; 650 left = sc->sc_tx_cons; 651 if (left <= idx) 652 left += DWXE_NTXDESC; 653 left -= idx; 654 used = 0; 655 656 for (;;) { 657 if (used + DWXE_NTXSEGS + 1 > left) { 658 ifq_set_oactive(ifq); 659 break; 660 } 661 662 m = ifq_dequeue(ifq); 663 if (m == NULL) 664 break; 665 666 error = dwxe_encap(sc, m, &idx, &used); 667 if (error == EFBIG) { 668 m_freem(m); /* give up: drop it */ 669 ifp->if_oerrors++; 670 continue; 671 } 672 673 #if NBPFILTER > 0 674 if (ifp->if_bpf) 675 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 676 #endif 677 } 678 679 if (sc->sc_tx_prod != idx) { 680 sc->sc_tx_prod = idx; 681 682 /* Set a timeout in case the chip goes out to lunch. */ 683 ifp->if_timer = 5; 684 685 dwxe_write(sc, DWXE_TX_CTL1, dwxe_read(sc, 686 DWXE_TX_CTL1) | DWXE_TX_CTL1_TX_DMA_START); 687 } 688 } 689 690 int 691 dwxe_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) 692 { 693 struct dwxe_softc *sc = ifp->if_softc; 694 struct ifreq *ifr = (struct ifreq *)addr; 695 int error = 0, s; 696 697 s = splnet(); 698 699 switch (cmd) { 700 case SIOCSIFADDR: 701 ifp->if_flags |= IFF_UP; 702 /* FALLTHROUGH */ 703 case SIOCSIFFLAGS: 704 if (ifp->if_flags & IFF_UP) { 705 if (ifp->if_flags & IFF_RUNNING) 706 error = ENETRESET; 707 else 708 dwxe_up(sc); 709 } else { 710 if (ifp->if_flags & IFF_RUNNING) 711 dwxe_down(sc); 712 } 713 break; 714 715 case SIOCGIFMEDIA: 716 case SIOCSIFMEDIA: 717 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 718 break; 719 720 case SIOCGIFRXR: 721 error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data, 722 NULL, MCLBYTES, &sc->sc_rx_ring); 723 break; 724 725 default: 726 error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr); 727 break; 728 } 729 730 if (error == ENETRESET) { 731 if (ifp->if_flags & IFF_RUNNING) 732 dwxe_iff(sc); 733 error = 0; 734 } 735 736 splx(s); 737 return (error); 738 } 739 740 void 741 dwxe_watchdog(struct ifnet *ifp) 742 { 743 printf("%s\n", __func__); 744 } 745 746 int 747 dwxe_media_change(struct ifnet *ifp) 748 { 749 struct dwxe_softc *sc = ifp->if_softc; 750 751 if (LIST_FIRST(&sc->sc_mii.mii_phys)) 752 mii_mediachg(&sc->sc_mii); 753 754 return (0); 755 } 756 757 void 758 dwxe_media_status(struct ifnet *ifp, struct ifmediareq *ifmr) 759 { 760 struct dwxe_softc *sc = ifp->if_softc; 761 762 if (LIST_FIRST(&sc->sc_mii.mii_phys)) { 763 mii_pollstat(&sc->sc_mii); 764 ifmr->ifm_active = sc->sc_mii.mii_media_active; 765 ifmr->ifm_status = sc->sc_mii.mii_media_status; 766 } 767 } 768 769 int 770 dwxe_mii_readreg(struct device *self, int phy, int reg) 771 { 772 struct dwxe_softc *sc = (void *)self; 773 int n; 774 775 dwxe_write(sc, DWXE_MDIO_CMD, 776 sc->sc_clk << DWXE_MDIO_CMD_MDC_DIV_RATIO_M_SHIFT | 777 phy << DWXE_MDIO_CMD_PHY_ADDR_SHIFT | 778 reg << DWXE_MDIO_CMD_PHY_REG_SHIFT | 779 DWXE_MDIO_CMD_MII_BUSY); 780 for (n = 0; n < 1000; n++) { 781 if ((dwxe_read(sc, DWXE_MDIO_CMD) & 782 DWXE_MDIO_CMD_MII_BUSY) == 0) 783 return dwxe_read(sc, DWXE_MDIO_DATA); 784 delay(10); 785 } 786 787 printf("%s: mii_read timeout\n", sc->sc_dev.dv_xname); 788 return (0); 789 } 790 791 void 792 dwxe_mii_writereg(struct device *self, int phy, int reg, int val) 793 { 794 struct dwxe_softc *sc = (void *)self; 795 int n; 796 797 dwxe_write(sc, DWXE_MDIO_DATA, val); 798 dwxe_write(sc, DWXE_MDIO_CMD, 799 sc->sc_clk << DWXE_MDIO_CMD_MDC_DIV_RATIO_M_SHIFT | 800 phy << DWXE_MDIO_CMD_PHY_ADDR_SHIFT | 801 reg << DWXE_MDIO_CMD_PHY_REG_SHIFT | 802 DWXE_MDIO_CMD_MII_WRITE | 803 DWXE_MDIO_CMD_MII_BUSY); 804 for (n = 0; n < 1000; n++) { 805 if ((dwxe_read(sc, DWXE_MDIO_CMD) & 806 DWXE_MDIO_CMD_MII_BUSY) == 0) 807 return; 808 delay(10); 809 } 810 811 printf("%s: mii_write timeout\n", sc->sc_dev.dv_xname); 812 } 813 814 void 815 dwxe_mii_statchg(struct device *self) 816 { 817 struct dwxe_softc *sc = (void *)self; 818 uint32_t basicctrl; 819 820 basicctrl = dwxe_read(sc, DWXE_BASIC_CTL0); 821 basicctrl &= ~DWXE_BASIC_CTL0_SPEED_MASK; 822 823 switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { 824 case IFM_1000_SX: 825 case IFM_1000_LX: 826 case IFM_1000_CX: 827 case IFM_1000_T: 828 basicctrl |= DWXE_BASIC_CTL0_SPEED_1000; 829 sc->sc_link = 1; 830 break; 831 case IFM_100_TX: 832 basicctrl |= DWXE_BASIC_CTL0_SPEED_100; 833 sc->sc_link = 1; 834 break; 835 case IFM_10_T: 836 basicctrl |= DWXE_BASIC_CTL0_SPEED_10; 837 sc->sc_link = 1; 838 break; 839 default: 840 sc->sc_link = 0; 841 return; 842 } 843 844 if (sc->sc_link == 0) 845 return; 846 847 basicctrl &= ~DWXE_BASIC_CTL0_DUPLEX; 848 if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) 849 basicctrl |= DWXE_BASIC_CTL0_DUPLEX; 850 851 /* XXX: RX/TX flow control? */ 852 853 dwxe_write(sc, DWXE_BASIC_CTL0, basicctrl); 854 } 855 856 void 857 dwxe_tick(void *arg) 858 { 859 struct dwxe_softc *sc = arg; 860 int s; 861 862 s = splnet(); 863 mii_tick(&sc->sc_mii); 864 splx(s); 865 866 timeout_add_sec(&sc->sc_tick, 1); 867 } 868 869 void 870 dwxe_rxtick(void *arg) 871 { 872 struct dwxe_softc *sc = arg; 873 uint32_t ctl; 874 int s; 875 876 s = splnet(); 877 878 ctl = dwxe_read(sc, DWXE_RX_CTL1); 879 dwxe_write(sc, DWXE_RX_CTL1, ctl & ~DWXE_RX_CTL1_RX_DMA_EN); 880 881 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_rxring), 882 0, DWXE_DMA_LEN(sc->sc_rxring), 883 BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE); 884 885 dwxe_write(sc, DWXE_RX_DESC_LIST, 0); 886 887 sc->sc_rx_prod = sc->sc_rx_cons = 0; 888 dwxe_fill_rx_ring(sc); 889 890 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_rxring), 891 0, DWXE_DMA_LEN(sc->sc_rxring), 892 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 893 894 dwxe_write(sc, DWXE_RX_DESC_LIST, DWXE_DMA_DVA(sc->sc_rxring)); 895 dwxe_write(sc, DWXE_RX_CTL1, ctl); 896 897 splx(s); 898 } 899 900 int 901 dwxe_intr(void *arg) 902 { 903 struct dwxe_softc *sc = arg; 904 uint32_t reg; 905 906 reg = dwxe_read(sc, DWXE_INT_STA); 907 dwxe_write(sc, DWXE_INT_STA, reg); 908 909 if (reg & DWXE_INT_STA_RX_INT) 910 dwxe_rx_proc(sc); 911 912 if (reg & DWXE_INT_STA_TX_INT || 913 reg & DWXE_INT_STA_TX_BUF_UA_INT) 914 dwxe_tx_proc(sc); 915 916 return (1); 917 } 918 919 void 920 dwxe_tx_proc(struct dwxe_softc *sc) 921 { 922 struct ifnet *ifp = &sc->sc_ac.ac_if; 923 struct dwxe_desc *txd; 924 struct dwxe_buf *txb; 925 int idx, txfree; 926 927 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_txring), 0, 928 DWXE_DMA_LEN(sc->sc_txring), 929 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 930 931 txfree = 0; 932 while (sc->sc_tx_cons != sc->sc_tx_prod) { 933 idx = sc->sc_tx_cons; 934 KASSERT(idx < DWXE_NTXDESC); 935 936 txd = &sc->sc_txdesc[idx]; 937 if (txd->sd_status & DWXE_TX_DESC_CTL) 938 break; 939 940 txb = &sc->sc_txbuf[idx]; 941 if (txb->tb_m) { 942 bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0, 943 txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 944 bus_dmamap_unload(sc->sc_dmat, txb->tb_map); 945 946 m_freem(txb->tb_m); 947 txb->tb_m = NULL; 948 } 949 950 txfree++; 951 952 if (sc->sc_tx_cons == (DWXE_NTXDESC - 1)) 953 sc->sc_tx_cons = 0; 954 else 955 sc->sc_tx_cons++; 956 957 txd->sd_status = 0; 958 } 959 960 if (sc->sc_tx_cons == sc->sc_tx_prod) 961 ifp->if_timer = 0; 962 963 if (txfree) { 964 if (ifq_is_oactive(&ifp->if_snd)) 965 ifq_restart(&ifp->if_snd); 966 } 967 } 968 969 void 970 dwxe_rx_proc(struct dwxe_softc *sc) 971 { 972 struct ifnet *ifp = &sc->sc_ac.ac_if; 973 struct dwxe_desc *rxd; 974 struct dwxe_buf *rxb; 975 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 976 struct mbuf *m; 977 int idx, len, cnt, put; 978 979 if ((ifp->if_flags & IFF_RUNNING) == 0) 980 return; 981 982 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_rxring), 0, 983 DWXE_DMA_LEN(sc->sc_rxring), 984 BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE); 985 986 cnt = if_rxr_inuse(&sc->sc_rx_ring); 987 put = 0; 988 while (put < cnt) { 989 idx = sc->sc_rx_cons; 990 KASSERT(idx < DWXE_NRXDESC); 991 992 rxd = &sc->sc_rxdesc[idx]; 993 if (rxd->sd_status & DWXE_RX_DESC_CTL) 994 break; 995 996 len = (rxd->sd_status >> DWXE_RX_FRM_LEN_SHIFT) 997 & DWXE_RX_FRM_LEN_MASK; 998 rxb = &sc->sc_rxbuf[idx]; 999 KASSERT(rxb->tb_m); 1000 1001 bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0, 1002 len, BUS_DMASYNC_POSTREAD); 1003 bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); 1004 1005 /* Strip off CRC. */ 1006 len -= ETHER_CRC_LEN; 1007 KASSERT(len > 0); 1008 1009 m = rxb->tb_m; 1010 rxb->tb_m = NULL; 1011 m->m_pkthdr.len = m->m_len = len; 1012 1013 ml_enqueue(&ml, m); 1014 1015 put++; 1016 if (sc->sc_rx_cons == (DWXE_NRXDESC - 1)) 1017 sc->sc_rx_cons = 0; 1018 else 1019 sc->sc_rx_cons++; 1020 } 1021 1022 if_rxr_put(&sc->sc_rx_ring, put); 1023 if (ifiq_input(&ifp->if_rcv, &ml)) 1024 if_rxr_livelocked(&sc->sc_rx_ring); 1025 1026 dwxe_fill_rx_ring(sc); 1027 1028 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_rxring), 0, 1029 DWXE_DMA_LEN(sc->sc_rxring), 1030 BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE); 1031 } 1032 1033 void 1034 dwxe_up(struct dwxe_softc *sc) 1035 { 1036 struct ifnet *ifp = &sc->sc_ac.ac_if; 1037 struct dwxe_buf *txb, *rxb; 1038 int i; 1039 1040 /* Allocate Tx descriptor ring. */ 1041 sc->sc_txring = dwxe_dmamem_alloc(sc, 1042 DWXE_NTXDESC * sizeof(struct dwxe_desc), 8); 1043 sc->sc_txdesc = DWXE_DMA_KVA(sc->sc_txring); 1044 1045 sc->sc_txbuf = malloc(sizeof(struct dwxe_buf) * DWXE_NTXDESC, 1046 M_DEVBUF, M_WAITOK); 1047 for (i = 0; i < DWXE_NTXDESC; i++) { 1048 txb = &sc->sc_txbuf[i]; 1049 bus_dmamap_create(sc->sc_dmat, MCLBYTES, DWXE_NTXSEGS, 1050 MCLBYTES, 0, BUS_DMA_WAITOK, &txb->tb_map); 1051 txb->tb_m = NULL; 1052 1053 sc->sc_txdesc[i].sd_next = 1054 DWXE_DMA_DVA(sc->sc_txring) + 1055 ((i+1) % DWXE_NTXDESC) * sizeof(struct dwxe_desc); 1056 } 1057 1058 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_txring), 1059 0, DWXE_DMA_LEN(sc->sc_txring), BUS_DMASYNC_PREWRITE); 1060 1061 sc->sc_tx_prod = sc->sc_tx_cons = 0; 1062 1063 dwxe_write(sc, DWXE_TX_DESC_LIST, DWXE_DMA_DVA(sc->sc_txring)); 1064 1065 /* Allocate descriptor ring. */ 1066 sc->sc_rxring = dwxe_dmamem_alloc(sc, 1067 DWXE_NRXDESC * sizeof(struct dwxe_desc), 8); 1068 sc->sc_rxdesc = DWXE_DMA_KVA(sc->sc_rxring); 1069 1070 sc->sc_rxbuf = malloc(sizeof(struct dwxe_buf) * DWXE_NRXDESC, 1071 M_DEVBUF, M_WAITOK); 1072 1073 for (i = 0; i < DWXE_NRXDESC; i++) { 1074 rxb = &sc->sc_rxbuf[i]; 1075 bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 1076 MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->tb_map); 1077 rxb->tb_m = NULL; 1078 1079 sc->sc_rxdesc[i].sd_next = 1080 DWXE_DMA_DVA(sc->sc_rxring) + 1081 ((i+1) % DWXE_NRXDESC) * sizeof(struct dwxe_desc); 1082 } 1083 1084 if_rxr_init(&sc->sc_rx_ring, 2, DWXE_NRXDESC); 1085 1086 sc->sc_rx_prod = sc->sc_rx_cons = 0; 1087 dwxe_fill_rx_ring(sc); 1088 1089 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_rxring), 1090 0, DWXE_DMA_LEN(sc->sc_rxring), 1091 BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE); 1092 1093 dwxe_write(sc, DWXE_RX_DESC_LIST, DWXE_DMA_DVA(sc->sc_rxring)); 1094 1095 dwxe_lladdr_write(sc); 1096 1097 //dwxe_write(sc, DWXE_BASIC_CTL1, DWXE_BASIC_CTL1_SOFT_RST); 1098 1099 /* Configure media. */ 1100 if (LIST_FIRST(&sc->sc_mii.mii_phys)) 1101 mii_mediachg(&sc->sc_mii); 1102 1103 /* Program promiscuous mode and multicast filters. */ 1104 dwxe_iff(sc); 1105 1106 ifp->if_flags |= IFF_RUNNING; 1107 ifq_clr_oactive(&ifp->if_snd); 1108 1109 dwxe_write(sc, DWXE_INT_EN, DWXE_INT_EN_RX_INT | 1110 DWXE_INT_EN_TX_INT | DWXE_INT_EN_TX_BUF_UA_INT); 1111 1112 dwxe_write(sc, DWXE_TX_CTL1, dwxe_read(sc, DWXE_TX_CTL1) | 1113 DWXE_TX_CTL1_TX_MD | DWXE_TX_CTL1_TX_NEXT_FRM | 1114 DWXE_TX_CTL1_TX_DMA_EN); 1115 dwxe_write(sc, DWXE_RX_CTL1, dwxe_read(sc, DWXE_RX_CTL1) | 1116 DWXE_RX_CTL1_RX_MD | DWXE_RX_CTL1_RX_DMA_EN); 1117 1118 dwxe_write(sc, DWXE_TX_CTL0, dwxe_read(sc, DWXE_TX_CTL0) | 1119 DWXE_TX_CTL0_TX_TRANSMITTER_EN); 1120 dwxe_write(sc, DWXE_RX_CTL0, dwxe_read(sc, DWXE_RX_CTL0) | 1121 DWXE_RX_CTL0_RX_RECEIVER_EN | DWXE_RX_CTL0_RX_DO_CRC); 1122 1123 timeout_add_sec(&sc->sc_tick, 1); 1124 } 1125 1126 void 1127 dwxe_down(struct dwxe_softc *sc) 1128 { 1129 struct ifnet *ifp = &sc->sc_ac.ac_if; 1130 struct dwxe_buf *txb, *rxb; 1131 uint32_t dmactrl; 1132 int i; 1133 1134 timeout_del(&sc->sc_rxto); 1135 timeout_del(&sc->sc_tick); 1136 1137 ifp->if_flags &= ~IFF_RUNNING; 1138 ifq_clr_oactive(&ifp->if_snd); 1139 ifp->if_timer = 0; 1140 1141 dwxe_stop_dma(sc); 1142 1143 dwxe_write(sc, DWXE_TX_CTL0, dwxe_read(sc, 1144 DWXE_TX_CTL0) & ~DWXE_TX_CTL0_TX_TRANSMITTER_EN); 1145 1146 dwxe_write(sc, DWXE_RX_CTL0, dwxe_read(sc, 1147 DWXE_RX_CTL0) & ~DWXE_RX_CTL0_RX_RECEIVER_EN); 1148 1149 dmactrl = dwxe_read(sc, DWXE_TX_CTL1); 1150 dmactrl &= ~DWXE_TX_CTL1_TX_DMA_EN; 1151 dwxe_write(sc, DWXE_TX_CTL1, dmactrl); 1152 1153 dmactrl = dwxe_read(sc, DWXE_RX_CTL1); 1154 dmactrl &= ~DWXE_RX_CTL1_RX_DMA_EN; 1155 dwxe_write(sc, DWXE_RX_CTL1, dmactrl); 1156 1157 dwxe_write(sc, DWXE_INT_EN, 0); 1158 1159 intr_barrier(sc->sc_ih); 1160 ifq_barrier(&ifp->if_snd); 1161 1162 for (i = 0; i < DWXE_NTXDESC; i++) { 1163 txb = &sc->sc_txbuf[i]; 1164 if (txb->tb_m) { 1165 bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0, 1166 txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1167 bus_dmamap_unload(sc->sc_dmat, txb->tb_map); 1168 m_freem(txb->tb_m); 1169 } 1170 bus_dmamap_destroy(sc->sc_dmat, txb->tb_map); 1171 } 1172 1173 dwxe_dmamem_free(sc, sc->sc_txring); 1174 free(sc->sc_txbuf, M_DEVBUF, 0); 1175 1176 for (i = 0; i < DWXE_NRXDESC; i++) { 1177 rxb = &sc->sc_rxbuf[i]; 1178 if (rxb->tb_m) { 1179 bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0, 1180 rxb->tb_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1181 bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); 1182 m_freem(rxb->tb_m); 1183 } 1184 bus_dmamap_destroy(sc->sc_dmat, rxb->tb_map); 1185 } 1186 1187 dwxe_dmamem_free(sc, sc->sc_rxring); 1188 free(sc->sc_rxbuf, M_DEVBUF, 0); 1189 } 1190 1191 /* Bit Reversal - http://aggregate.org/MAGIC/#Bit%20Reversal */ 1192 static uint32_t 1193 bitrev32(uint32_t x) 1194 { 1195 x = (((x & 0xaaaaaaaa) >> 1) | ((x & 0x55555555) << 1)); 1196 x = (((x & 0xcccccccc) >> 2) | ((x & 0x33333333) << 2)); 1197 x = (((x & 0xf0f0f0f0) >> 4) | ((x & 0x0f0f0f0f) << 4)); 1198 x = (((x & 0xff00ff00) >> 8) | ((x & 0x00ff00ff) << 8)); 1199 1200 return (x >> 16) | (x << 16); 1201 } 1202 1203 void 1204 dwxe_iff(struct dwxe_softc *sc) 1205 { 1206 struct arpcom *ac = &sc->sc_ac; 1207 struct ifnet *ifp = &sc->sc_ac.ac_if; 1208 struct ether_multi *enm; 1209 struct ether_multistep step; 1210 uint32_t crc, hash[2], hashbit, hashreg; 1211 uint32_t reg; 1212 1213 reg = 0; 1214 1215 ifp->if_flags &= ~IFF_ALLMULTI; 1216 bzero(hash, sizeof(hash)); 1217 if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { 1218 ifp->if_flags |= IFF_ALLMULTI; 1219 reg |= DWXE_RX_FRM_FLT_RX_ALL_MULTICAST; 1220 if (ifp->if_flags & IFF_PROMISC) 1221 reg |= DWXE_RX_FRM_FLT_DIS_ADDR_FILTER; 1222 } else { 1223 reg |= DWXE_RX_FRM_FLT_HASH_MULTICAST; 1224 ETHER_FIRST_MULTI(step, ac, enm); 1225 while (enm != NULL) { 1226 crc = ether_crc32_le(enm->enm_addrlo, 1227 ETHER_ADDR_LEN) & 0x7f; 1228 1229 crc = bitrev32(~crc) >> 26; 1230 hashreg = (crc >> 5); 1231 hashbit = (crc & 0x1f); 1232 hash[hashreg] |= (1 << hashbit); 1233 1234 ETHER_NEXT_MULTI(step, enm); 1235 } 1236 } 1237 1238 dwxe_lladdr_write(sc); 1239 1240 dwxe_write(sc, DWXE_RX_HASH0, hash[1]); 1241 dwxe_write(sc, DWXE_RX_HASH1, hash[0]); 1242 1243 dwxe_write(sc, DWXE_RX_FRM_FLT, reg); 1244 } 1245 1246 int 1247 dwxe_encap(struct dwxe_softc *sc, struct mbuf *m, int *idx, int *used) 1248 { 1249 struct dwxe_desc *txd, *txd_start; 1250 bus_dmamap_t map; 1251 int cur, frag, i; 1252 1253 cur = frag = *idx; 1254 map = sc->sc_txbuf[cur].tb_map; 1255 1256 if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) { 1257 if (m_defrag(m, M_DONTWAIT)) 1258 return (EFBIG); 1259 if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT)) 1260 return (EFBIG); 1261 } 1262 1263 /* Sync the DMA map. */ 1264 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 1265 BUS_DMASYNC_PREWRITE); 1266 1267 txd = txd_start = &sc->sc_txdesc[frag]; 1268 for (i = 0; i < map->dm_nsegs; i++) { 1269 txd->sd_addr = map->dm_segs[i].ds_addr; 1270 txd->sd_len = map->dm_segs[i].ds_len; 1271 if (i == 0) 1272 txd->sd_len |= DWXE_TX_FIR_DESC; 1273 if (i == (map->dm_nsegs - 1)) 1274 txd->sd_len |= DWXE_TX_LAST_DESC | DWXE_TX_INT_CTL; 1275 if (i != 0) 1276 txd->sd_status = DWXE_TX_DESC_CTL; 1277 1278 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_txring), 1279 frag * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE); 1280 1281 cur = frag; 1282 if (frag == (DWXE_NTXDESC - 1)) { 1283 txd = &sc->sc_txdesc[0]; 1284 frag = 0; 1285 } else { 1286 txd++; 1287 frag++; 1288 } 1289 KASSERT(frag != sc->sc_tx_cons); 1290 } 1291 1292 txd_start->sd_status = DWXE_TX_DESC_CTL; 1293 bus_dmamap_sync(sc->sc_dmat, DWXE_DMA_MAP(sc->sc_txring), 1294 *idx * sizeof(*txd), sizeof(*txd), BUS_DMASYNC_PREWRITE); 1295 1296 KASSERT(sc->sc_txbuf[cur].tb_m == NULL); 1297 sc->sc_txbuf[*idx].tb_map = sc->sc_txbuf[cur].tb_map; 1298 sc->sc_txbuf[cur].tb_map = map; 1299 sc->sc_txbuf[cur].tb_m = m; 1300 1301 *idx = frag; 1302 *used += map->dm_nsegs; 1303 1304 return (0); 1305 } 1306 1307 void 1308 dwxe_reset(struct dwxe_softc *sc) 1309 { 1310 int n; 1311 1312 dwxe_stop_dma(sc); 1313 1314 dwxe_write(sc, DWXE_BASIC_CTL1, DWXE_BASIC_CTL1_SOFT_RST); 1315 1316 for (n = 0; n < 1000; n++) { 1317 if ((dwxe_read(sc, DWXE_BASIC_CTL1) & 1318 DWXE_BASIC_CTL1_SOFT_RST) == 0) 1319 return; 1320 delay(10); 1321 } 1322 1323 printf("%s: reset timeout\n", sc->sc_dev.dv_xname); 1324 } 1325 1326 void 1327 dwxe_stop_dma(struct dwxe_softc *sc) 1328 { 1329 uint32_t dmactrl; 1330 1331 /* Stop DMA. */ 1332 dmactrl = dwxe_read(sc, DWXE_TX_CTL1); 1333 dmactrl &= ~DWXE_TX_CTL1_TX_DMA_EN; 1334 dmactrl |= DWXE_TX_CTL1_TX_FIFO_FLUSH; 1335 dwxe_write(sc, DWXE_TX_CTL1, dmactrl); 1336 } 1337 1338 struct dwxe_dmamem * 1339 dwxe_dmamem_alloc(struct dwxe_softc *sc, bus_size_t size, bus_size_t align) 1340 { 1341 struct dwxe_dmamem *tdm; 1342 int nsegs; 1343 1344 tdm = malloc(sizeof(*tdm), M_DEVBUF, M_WAITOK | M_ZERO); 1345 tdm->tdm_size = size; 1346 1347 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 1348 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &tdm->tdm_map) != 0) 1349 goto tdmfree; 1350 1351 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &tdm->tdm_seg, 1, 1352 &nsegs, BUS_DMA_WAITOK) != 0) 1353 goto destroy; 1354 1355 if (bus_dmamem_map(sc->sc_dmat, &tdm->tdm_seg, nsegs, size, 1356 &tdm->tdm_kva, BUS_DMA_WAITOK | BUS_DMA_COHERENT) != 0) 1357 goto free; 1358 1359 if (bus_dmamap_load(sc->sc_dmat, tdm->tdm_map, tdm->tdm_kva, size, 1360 NULL, BUS_DMA_WAITOK) != 0) 1361 goto unmap; 1362 1363 bzero(tdm->tdm_kva, size); 1364 1365 return (tdm); 1366 1367 unmap: 1368 bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, size); 1369 free: 1370 bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1); 1371 destroy: 1372 bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map); 1373 tdmfree: 1374 free(tdm, M_DEVBUF, 0); 1375 1376 return (NULL); 1377 } 1378 1379 void 1380 dwxe_dmamem_free(struct dwxe_softc *sc, struct dwxe_dmamem *tdm) 1381 { 1382 bus_dmamem_unmap(sc->sc_dmat, tdm->tdm_kva, tdm->tdm_size); 1383 bus_dmamem_free(sc->sc_dmat, &tdm->tdm_seg, 1); 1384 bus_dmamap_destroy(sc->sc_dmat, tdm->tdm_map); 1385 free(tdm, M_DEVBUF, 0); 1386 } 1387 1388 struct mbuf * 1389 dwxe_alloc_mbuf(struct dwxe_softc *sc, bus_dmamap_t map) 1390 { 1391 struct mbuf *m = NULL; 1392 1393 m = MCLGETL(NULL, M_DONTWAIT, MCLBYTES); 1394 if (!m) 1395 return (NULL); 1396 m->m_len = m->m_pkthdr.len = MCLBYTES; 1397 m_adj(m, ETHER_ALIGN); 1398 1399 if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) { 1400 printf("%s: could not load mbuf DMA map", DEVNAME(sc)); 1401 m_freem(m); 1402 return (NULL); 1403 } 1404 1405 bus_dmamap_sync(sc->sc_dmat, map, 0, 1406 m->m_pkthdr.len, BUS_DMASYNC_PREREAD); 1407 1408 return (m); 1409 } 1410 1411 void 1412 dwxe_fill_rx_ring(struct dwxe_softc *sc) 1413 { 1414 struct dwxe_desc *rxd; 1415 struct dwxe_buf *rxb; 1416 u_int slots; 1417 1418 for (slots = if_rxr_get(&sc->sc_rx_ring, DWXE_NRXDESC); 1419 slots > 0; slots--) { 1420 rxb = &sc->sc_rxbuf[sc->sc_rx_prod]; 1421 rxb->tb_m = dwxe_alloc_mbuf(sc, rxb->tb_map); 1422 if (rxb->tb_m == NULL) 1423 break; 1424 1425 rxd = &sc->sc_rxdesc[sc->sc_rx_prod]; 1426 rxd->sd_len = rxb->tb_map->dm_segs[0].ds_len - 1; 1427 rxd->sd_addr = rxb->tb_map->dm_segs[0].ds_addr; 1428 rxd->sd_status = DWXE_RX_DESC_CTL; 1429 1430 if (sc->sc_rx_prod == (DWXE_NRXDESC - 1)) 1431 sc->sc_rx_prod = 0; 1432 else 1433 sc->sc_rx_prod++; 1434 } 1435 if_rxr_put(&sc->sc_rx_ring, slots); 1436 1437 if (if_rxr_inuse(&sc->sc_rx_ring) == 0) 1438 timeout_add(&sc->sc_rxto, 1); 1439 } 1440