1 /* $OpenBSD: if_mvneta.c,v 1.32 2024/03/21 23:12:33 patrick Exp $ */ 2 /* $NetBSD: if_mvneta.c,v 1.41 2015/04/15 10:15:40 hsuenaga Exp $ */ 3 /* 4 * Copyright (c) 2007, 2008, 2013 KIYOHARA Takashi 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 19 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 25 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 * POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "bpfilter.h" 30 #include "kstat.h" 31 32 #include <sys/param.h> 33 #include <sys/device.h> 34 #include <sys/systm.h> 35 #include <sys/endian.h> 36 #include <sys/errno.h> 37 #include <sys/kernel.h> 38 #include <sys/mutex.h> 39 #include <sys/socket.h> 40 #include <sys/sockio.h> 41 #include <uvm/uvm_extern.h> 42 #include <sys/mbuf.h> 43 #include <sys/kstat.h> 44 45 #include <machine/bus.h> 46 #include <machine/cpufunc.h> 47 #include <machine/fdt.h> 48 49 #include <dev/ofw/openfirm.h> 50 #include <dev/ofw/ofw_clock.h> 51 #include <dev/ofw/ofw_misc.h> 52 #include <dev/ofw/ofw_pinctrl.h> 53 #include <dev/ofw/fdt.h> 54 55 #include <dev/fdt/if_mvnetareg.h> 56 57 #ifdef __armv7__ 58 #include <armv7/marvell/mvmbusvar.h> 59 #endif 60 61 #include <net/if.h> 62 #include <net/if_media.h> 63 #include <net/if_types.h> 64 65 #include <netinet/in.h> 66 #include <netinet/if_ether.h> 67 68 #include <dev/mii/mii.h> 69 #include <dev/mii/miivar.h> 70 71 #if NBPFILTER > 0 72 #include <net/bpf.h> 73 #endif 74 75 #ifdef MVNETA_DEBUG 76 #define DPRINTF(x) if (mvneta_debug) printf x 77 #define DPRINTFN(n,x) if (mvneta_debug >= (n)) printf x 78 int mvneta_debug = MVNETA_DEBUG; 79 #else 80 #define DPRINTF(x) 81 #define DPRINTFN(n,x) 82 #endif 83 84 #define MVNETA_READ(sc, reg) \ 85 bus_space_read_4((sc)->sc_iot, (sc)->sc_ioh, (reg)) 86 #define MVNETA_WRITE(sc, reg, val) \ 87 bus_space_write_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val)) 88 #define MVNETA_READ_FILTER(sc, reg, val, c) \ 89 bus_space_read_region_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val), (c)) 90 #define MVNETA_WRITE_FILTER(sc, reg, val, c) \ 91 bus_space_write_region_4((sc)->sc_iot, (sc)->sc_ioh, (reg), (val), (c)) 92 93 #define MVNETA_LINKUP_READ(sc) \ 94 MVNETA_READ(sc, MVNETA_PS0) 95 #define MVNETA_IS_LINKUP(sc) (MVNETA_LINKUP_READ(sc) & MVNETA_PS0_LINKUP) 96 97 #define MVNETA_TX_RING_CNT 256 98 #define MVNETA_TX_RING_MSK (MVNETA_TX_RING_CNT - 1) 99 #define MVNETA_TX_RING_NEXT(x) (((x) + 1) & MVNETA_TX_RING_MSK) 100 #define MVNETA_TX_QUEUE_CNT 1 101 #define MVNETA_RX_RING_CNT 256 102 #define MVNETA_RX_RING_MSK (MVNETA_RX_RING_CNT - 1) 103 #define MVNETA_RX_RING_NEXT(x) (((x) + 1) & MVNETA_RX_RING_MSK) 104 #define MVNETA_RX_QUEUE_CNT 1 105 106 CTASSERT(MVNETA_TX_RING_CNT > 1 && MVNETA_TX_RING_NEXT(MVNETA_TX_RING_CNT) == 107 (MVNETA_TX_RING_CNT + 1) % MVNETA_TX_RING_CNT); 108 CTASSERT(MVNETA_RX_RING_CNT > 1 && MVNETA_RX_RING_NEXT(MVNETA_RX_RING_CNT) == 109 (MVNETA_RX_RING_CNT + 1) % MVNETA_RX_RING_CNT); 110 111 #define MVNETA_NTXSEG 30 112 113 struct mvneta_dmamem { 114 bus_dmamap_t mdm_map; 115 bus_dma_segment_t mdm_seg; 116 size_t mdm_size; 117 caddr_t mdm_kva; 118 }; 119 #define MVNETA_DMA_MAP(_mdm) ((_mdm)->mdm_map) 120 #define MVNETA_DMA_LEN(_mdm) ((_mdm)->mdm_size) 121 #define MVNETA_DMA_DVA(_mdm) ((_mdm)->mdm_map->dm_segs[0].ds_addr) 122 #define MVNETA_DMA_KVA(_mdm) ((void *)(_mdm)->mdm_kva) 123 124 struct mvneta_buf { 125 bus_dmamap_t tb_map; 126 struct mbuf *tb_m; 127 }; 128 129 struct mvneta_softc { 130 struct device sc_dev; 131 struct mii_bus *sc_mdio; 132 133 bus_space_tag_t sc_iot; 134 bus_space_handle_t sc_ioh; 135 bus_dma_tag_t sc_dmat; 136 void *sc_ih; 137 138 uint64_t sc_clk_freq; 139 140 struct arpcom sc_ac; 141 #define sc_enaddr sc_ac.ac_enaddr 142 struct mii_data sc_mii; 143 #define sc_media sc_mii.mii_media 144 145 struct timeout sc_tick_ch; 146 147 struct mvneta_dmamem *sc_txring; 148 struct mvneta_buf *sc_txbuf; 149 struct mvneta_tx_desc *sc_txdesc; 150 unsigned int sc_tx_prod; /* next free tx desc */ 151 unsigned int sc_tx_cons; /* first tx desc sent */ 152 153 struct mvneta_dmamem *sc_rxring; 154 struct mvneta_buf *sc_rxbuf; 155 struct mvneta_rx_desc *sc_rxdesc; 156 unsigned int sc_rx_prod; /* next rx desc to fill */ 157 unsigned int sc_rx_cons; /* next rx desc recvd */ 158 struct if_rxring sc_rx_ring; 159 160 enum { 161 PHY_MODE_QSGMII, 162 PHY_MODE_SGMII, 163 PHY_MODE_RGMII, 164 PHY_MODE_RGMII_ID, 165 PHY_MODE_1000BASEX, 166 PHY_MODE_2500BASEX, 167 } sc_phy_mode; 168 int sc_fixed_link; 169 int sc_inband_status; 170 int sc_phy; 171 int sc_phyloc; 172 int sc_link; 173 int sc_sfp; 174 int sc_node; 175 176 struct if_device sc_ifd; 177 178 #if NKSTAT > 0 179 struct mutex sc_kstat_lock; 180 struct timeout sc_kstat_tick; 181 struct kstat *sc_kstat; 182 #endif 183 }; 184 185 186 int mvneta_miibus_readreg(struct device *, int, int); 187 void mvneta_miibus_writereg(struct device *, int, int, int); 188 void mvneta_miibus_statchg(struct device *); 189 190 void mvneta_wininit(struct mvneta_softc *); 191 192 /* Gigabit Ethernet Port part functions */ 193 int mvneta_match(struct device *, void *, void *); 194 void mvneta_attach(struct device *, struct device *, void *); 195 void mvneta_attach_deferred(struct device *); 196 197 void mvneta_tick(void *); 198 int mvneta_intr(void *); 199 200 void mvneta_start(struct ifqueue *); 201 int mvneta_ioctl(struct ifnet *, u_long, caddr_t); 202 void mvneta_inband_statchg(struct mvneta_softc *); 203 void mvneta_port_change(struct mvneta_softc *); 204 void mvneta_port_up(struct mvneta_softc *); 205 int mvneta_up(struct mvneta_softc *); 206 void mvneta_down(struct mvneta_softc *); 207 void mvneta_watchdog(struct ifnet *); 208 209 int mvneta_mediachange(struct ifnet *); 210 void mvneta_mediastatus(struct ifnet *, struct ifmediareq *); 211 212 void mvneta_rx_proc(struct mvneta_softc *); 213 void mvneta_tx_proc(struct mvneta_softc *); 214 uint8_t mvneta_crc8(const uint8_t *, size_t); 215 void mvneta_iff(struct mvneta_softc *); 216 217 struct mvneta_dmamem *mvneta_dmamem_alloc(struct mvneta_softc *, 218 bus_size_t, bus_size_t); 219 void mvneta_dmamem_free(struct mvneta_softc *, struct mvneta_dmamem *); 220 void mvneta_fill_rx_ring(struct mvneta_softc *); 221 222 #if NKSTAT > 0 223 void mvneta_kstat_attach(struct mvneta_softc *); 224 #endif 225 226 static struct rwlock mvneta_sff_lock = RWLOCK_INITIALIZER("mvnetasff"); 227 228 struct cfdriver mvneta_cd = { 229 NULL, "mvneta", DV_IFNET 230 }; 231 232 const struct cfattach mvneta_ca = { 233 sizeof (struct mvneta_softc), mvneta_match, mvneta_attach, 234 }; 235 236 int 237 mvneta_miibus_readreg(struct device *dev, int phy, int reg) 238 { 239 struct mvneta_softc *sc = (struct mvneta_softc *) dev; 240 return sc->sc_mdio->md_readreg(sc->sc_mdio->md_cookie, phy, reg); 241 } 242 243 void 244 mvneta_miibus_writereg(struct device *dev, int phy, int reg, int val) 245 { 246 struct mvneta_softc *sc = (struct mvneta_softc *) dev; 247 return sc->sc_mdio->md_writereg(sc->sc_mdio->md_cookie, phy, reg, val); 248 } 249 250 void 251 mvneta_miibus_statchg(struct device *self) 252 { 253 struct mvneta_softc *sc = (struct mvneta_softc *)self; 254 255 if (sc->sc_mii.mii_media_status & IFM_ACTIVE) { 256 uint32_t panc = MVNETA_READ(sc, MVNETA_PANC); 257 258 panc &= ~(MVNETA_PANC_SETMIISPEED | 259 MVNETA_PANC_SETGMIISPEED | 260 MVNETA_PANC_SETFULLDX); 261 262 switch (IFM_SUBTYPE(sc->sc_mii.mii_media_active)) { 263 case IFM_1000_SX: 264 case IFM_1000_LX: 265 case IFM_1000_CX: 266 case IFM_1000_T: 267 panc |= MVNETA_PANC_SETGMIISPEED; 268 break; 269 case IFM_100_TX: 270 panc |= MVNETA_PANC_SETMIISPEED; 271 break; 272 case IFM_10_T: 273 break; 274 } 275 276 if ((sc->sc_mii.mii_media_active & IFM_GMASK) == IFM_FDX) 277 panc |= MVNETA_PANC_SETFULLDX; 278 279 MVNETA_WRITE(sc, MVNETA_PANC, panc); 280 } 281 282 mvneta_port_change(sc); 283 } 284 285 void 286 mvneta_inband_statchg(struct mvneta_softc *sc) 287 { 288 uint64_t subtype = IFM_SUBTYPE(sc->sc_mii.mii_media_active); 289 uint32_t reg; 290 291 sc->sc_mii.mii_media_status = IFM_AVALID; 292 sc->sc_mii.mii_media_active = IFM_ETHER; 293 294 reg = MVNETA_READ(sc, MVNETA_PS0); 295 if (reg & MVNETA_PS0_LINKUP) 296 sc->sc_mii.mii_media_status |= IFM_ACTIVE; 297 if (sc->sc_phy_mode == PHY_MODE_2500BASEX) 298 sc->sc_mii.mii_media_active |= subtype; 299 else if (sc->sc_phy_mode == PHY_MODE_1000BASEX) 300 sc->sc_mii.mii_media_active |= subtype; 301 else if (reg & MVNETA_PS0_GMIISPEED) 302 sc->sc_mii.mii_media_active |= IFM_1000_T; 303 else if (reg & MVNETA_PS0_MIISPEED) 304 sc->sc_mii.mii_media_active |= IFM_100_TX; 305 else 306 sc->sc_mii.mii_media_active |= IFM_10_T; 307 if (reg & MVNETA_PS0_FULLDX) 308 sc->sc_mii.mii_media_active |= IFM_FDX; 309 310 mvneta_port_change(sc); 311 } 312 313 void 314 mvneta_enaddr_write(struct mvneta_softc *sc) 315 { 316 uint32_t maddrh, maddrl; 317 maddrh = sc->sc_enaddr[0] << 24; 318 maddrh |= sc->sc_enaddr[1] << 16; 319 maddrh |= sc->sc_enaddr[2] << 8; 320 maddrh |= sc->sc_enaddr[3]; 321 maddrl = sc->sc_enaddr[4] << 8; 322 maddrl |= sc->sc_enaddr[5]; 323 MVNETA_WRITE(sc, MVNETA_MACAH, maddrh); 324 MVNETA_WRITE(sc, MVNETA_MACAL, maddrl); 325 } 326 327 void 328 mvneta_wininit(struct mvneta_softc *sc) 329 { 330 uint32_t en; 331 int i; 332 333 #ifdef __armv7__ 334 if (mvmbus_dram_info == NULL) 335 panic("%s: mbus dram information not set up", 336 sc->sc_dev.dv_xname); 337 #endif 338 339 for (i = 0; i < MVNETA_NWINDOW; i++) { 340 MVNETA_WRITE(sc, MVNETA_BASEADDR(i), 0); 341 MVNETA_WRITE(sc, MVNETA_S(i), 0); 342 343 if (i < MVNETA_NREMAP) 344 MVNETA_WRITE(sc, MVNETA_HA(i), 0); 345 } 346 347 en = MVNETA_BARE_EN_MASK; 348 349 #ifdef __armv7__ 350 for (i = 0; i < mvmbus_dram_info->numcs; i++) { 351 struct mbus_dram_window *win = &mvmbus_dram_info->cs[i]; 352 353 MVNETA_WRITE(sc, MVNETA_BASEADDR(i), 354 MVNETA_BASEADDR_TARGET(mvmbus_dram_info->targetid) | 355 MVNETA_BASEADDR_ATTR(win->attr) | 356 MVNETA_BASEADDR_BASE(win->base)); 357 MVNETA_WRITE(sc, MVNETA_S(i), MVNETA_S_SIZE(win->size)); 358 359 en &= ~(1 << i); 360 } 361 #else 362 MVNETA_WRITE(sc, MVNETA_S(0), MVNETA_S_SIZE(0)); 363 en &= ~(1 << 0); 364 #endif 365 366 MVNETA_WRITE(sc, MVNETA_BARE, en); 367 } 368 369 #define COMPHY_SIP_POWER_ON 0x82000001 370 #define COMPHY_SIP_POWER_OFF 0x82000002 371 #define COMPHY_SPEED(x) ((x) << 2) 372 #define COMPHY_SPEED_1_25G 0 /* SGMII 1G */ 373 #define COMPHY_SPEED_2_5G 1 374 #define COMPHY_SPEED_3_125G 2 /* SGMII 2.5G */ 375 #define COMPHY_SPEED_5G 3 376 #define COMPHY_SPEED_5_15625G 4 /* XFI 5G */ 377 #define COMPHY_SPEED_6G 5 378 #define COMPHY_SPEED_10_3125G 6 /* XFI 10G */ 379 #define COMPHY_UNIT(x) ((x) << 8) 380 #define COMPHY_MODE(x) ((x) << 12) 381 #define COMPHY_MODE_SATA 1 382 #define COMPHY_MODE_SGMII 2 /* SGMII 1G */ 383 #define COMPHY_MODE_HS_SGMII 3 /* SGMII 2.5G */ 384 #define COMPHY_MODE_USB3H 4 385 #define COMPHY_MODE_USB3D 5 386 #define COMPHY_MODE_PCIE 6 387 #define COMPHY_MODE_RXAUI 7 388 #define COMPHY_MODE_XFI 8 389 #define COMPHY_MODE_SFI 9 390 #define COMPHY_MODE_USB3 10 391 392 void 393 mvneta_comphy_init(struct mvneta_softc *sc) 394 { 395 int node, phys[2], lane, unit; 396 uint32_t mode; 397 398 if (OF_getpropintarray(sc->sc_node, "phys", phys, sizeof(phys)) != 399 sizeof(phys)) 400 return; 401 node = OF_getnodebyphandle(phys[0]); 402 if (!node) 403 return; 404 405 lane = OF_getpropint(node, "reg", 0); 406 unit = phys[1]; 407 408 switch (sc->sc_phy_mode) { 409 case PHY_MODE_1000BASEX: 410 case PHY_MODE_SGMII: 411 mode = COMPHY_MODE(COMPHY_MODE_SGMII) | 412 COMPHY_SPEED(COMPHY_SPEED_1_25G) | 413 COMPHY_UNIT(unit); 414 break; 415 case PHY_MODE_2500BASEX: 416 mode = COMPHY_MODE(COMPHY_MODE_HS_SGMII) | 417 COMPHY_SPEED(COMPHY_SPEED_3_125G) | 418 COMPHY_UNIT(unit); 419 break; 420 default: 421 return; 422 } 423 424 smc_call(COMPHY_SIP_POWER_ON, lane, mode, 0); 425 } 426 427 int 428 mvneta_match(struct device *parent, void *cfdata, void *aux) 429 { 430 struct fdt_attach_args *faa = aux; 431 432 return OF_is_compatible(faa->fa_node, "marvell,armada-370-neta") || 433 OF_is_compatible(faa->fa_node, "marvell,armada-3700-neta"); 434 } 435 436 void 437 mvneta_attach(struct device *parent, struct device *self, void *aux) 438 { 439 struct mvneta_softc *sc = (struct mvneta_softc *) self; 440 struct fdt_attach_args *faa = aux; 441 uint32_t ctl0, ctl2, ctl4, panc; 442 struct ifnet *ifp; 443 int i, len, node; 444 char *phy_mode; 445 char *managed; 446 447 sc->sc_iot = faa->fa_iot; 448 timeout_set(&sc->sc_tick_ch, mvneta_tick, sc); 449 if (bus_space_map(sc->sc_iot, faa->fa_reg[0].addr, 450 faa->fa_reg[0].size, 0, &sc->sc_ioh)) { 451 printf("%s: cannot map registers\n", self->dv_xname); 452 return; 453 } 454 sc->sc_dmat = faa->fa_dmat; 455 sc->sc_node = faa->fa_node; 456 457 clock_enable(faa->fa_node, NULL); 458 sc->sc_clk_freq = clock_get_frequency_idx(faa->fa_node, 0); 459 460 pinctrl_byname(faa->fa_node, "default"); 461 462 len = OF_getproplen(faa->fa_node, "phy-mode"); 463 if (len <= 0) { 464 printf(": cannot extract phy-mode\n"); 465 return; 466 } 467 468 phy_mode = malloc(len, M_TEMP, M_WAITOK); 469 OF_getprop(faa->fa_node, "phy-mode", phy_mode, len); 470 if (!strncmp(phy_mode, "qsgmii", strlen("qsgmii"))) 471 sc->sc_phy_mode = PHY_MODE_QSGMII; 472 else if (!strncmp(phy_mode, "sgmii", strlen("sgmii"))) 473 sc->sc_phy_mode = PHY_MODE_SGMII; 474 else if (!strncmp(phy_mode, "rgmii-id", strlen("rgmii-id"))) 475 sc->sc_phy_mode = PHY_MODE_RGMII_ID; 476 else if (!strncmp(phy_mode, "rgmii", strlen("rgmii"))) 477 sc->sc_phy_mode = PHY_MODE_RGMII; 478 else if (!strncmp(phy_mode, "1000base-x", strlen("1000base-x"))) 479 sc->sc_phy_mode = PHY_MODE_1000BASEX; 480 else if (!strncmp(phy_mode, "2500base-x", strlen("2500base-x"))) 481 sc->sc_phy_mode = PHY_MODE_2500BASEX; 482 else { 483 printf(": cannot use phy-mode %s\n", phy_mode); 484 return; 485 } 486 free(phy_mode, M_TEMP, len); 487 488 /* TODO: check child's name to be "fixed-link" */ 489 if (OF_getproplen(faa->fa_node, "fixed-link") >= 0 || 490 OF_child(faa->fa_node)) 491 sc->sc_fixed_link = 1; 492 493 if ((len = OF_getproplen(faa->fa_node, "managed")) >= 0) { 494 managed = malloc(len, M_TEMP, M_WAITOK); 495 OF_getprop(faa->fa_node, "managed", managed, len); 496 if (!strncmp(managed, "in-band-status", 497 strlen("in-band-status"))) { 498 sc->sc_fixed_link = 1; 499 sc->sc_inband_status = 1; 500 } 501 free(managed, M_TEMP, len); 502 } 503 504 if (!sc->sc_fixed_link) { 505 sc->sc_phy = OF_getpropint(faa->fa_node, "phy-handle", 0); 506 if (!sc->sc_phy) 507 sc->sc_phy = OF_getpropint(faa->fa_node, "phy", 0); 508 node = OF_getnodebyphandle(sc->sc_phy); 509 if (!node) { 510 printf(": cannot find phy in fdt\n"); 511 return; 512 } 513 514 if ((sc->sc_phyloc = OF_getpropint(node, "reg", -1)) == -1) { 515 printf(": cannot extract phy addr\n"); 516 return; 517 } 518 } 519 520 mvneta_wininit(sc); 521 522 if (OF_getproplen(faa->fa_node, "local-mac-address") == 523 ETHER_ADDR_LEN) { 524 OF_getprop(faa->fa_node, "local-mac-address", 525 sc->sc_enaddr, ETHER_ADDR_LEN); 526 mvneta_enaddr_write(sc); 527 } else { 528 uint32_t maddrh, maddrl; 529 maddrh = MVNETA_READ(sc, MVNETA_MACAH); 530 maddrl = MVNETA_READ(sc, MVNETA_MACAL); 531 if (maddrh || maddrl) { 532 sc->sc_enaddr[0] = maddrh >> 24; 533 sc->sc_enaddr[1] = maddrh >> 16; 534 sc->sc_enaddr[2] = maddrh >> 8; 535 sc->sc_enaddr[3] = maddrh >> 0; 536 sc->sc_enaddr[4] = maddrl >> 8; 537 sc->sc_enaddr[5] = maddrl >> 0; 538 } else 539 ether_fakeaddr(&sc->sc_ac.ac_if); 540 } 541 542 sc->sc_sfp = OF_getpropint(faa->fa_node, "sfp", 0); 543 544 printf(": address %s\n", ether_sprintf(sc->sc_enaddr)); 545 546 /* disable port */ 547 MVNETA_WRITE(sc, MVNETA_PMACC0, 548 MVNETA_READ(sc, MVNETA_PMACC0) & ~MVNETA_PMACC0_PORTEN); 549 delay(200); 550 551 /* clear all cause registers */ 552 MVNETA_WRITE(sc, MVNETA_PRXTXTIC, 0); 553 MVNETA_WRITE(sc, MVNETA_PRXTXIC, 0); 554 MVNETA_WRITE(sc, MVNETA_PMIC, 0); 555 556 /* mask all interrupts */ 557 MVNETA_WRITE(sc, MVNETA_PRXTXTIM, MVNETA_PRXTXTI_PMISCICSUMMARY); 558 MVNETA_WRITE(sc, MVNETA_PRXTXIM, 0); 559 MVNETA_WRITE(sc, MVNETA_PMIM, MVNETA_PMI_PHYSTATUSCHNG | 560 MVNETA_PMI_LINKCHANGE | MVNETA_PMI_PSCSYNCCHNG); 561 MVNETA_WRITE(sc, MVNETA_PIE, 0); 562 563 /* enable MBUS Retry bit16 */ 564 MVNETA_WRITE(sc, MVNETA_ERETRY, 0x20); 565 566 /* enable access for CPU0 */ 567 MVNETA_WRITE(sc, MVNETA_PCP2Q(0), 568 MVNETA_PCP2Q_RXQAE_ALL | MVNETA_PCP2Q_TXQAE_ALL); 569 570 /* reset RX and TX DMAs */ 571 MVNETA_WRITE(sc, MVNETA_PRXINIT, MVNETA_PRXINIT_RXDMAINIT); 572 MVNETA_WRITE(sc, MVNETA_PTXINIT, MVNETA_PTXINIT_TXDMAINIT); 573 574 /* disable legacy WRR, disable EJP, release from reset */ 575 MVNETA_WRITE(sc, MVNETA_TQC_1, 0); 576 for (i = 0; i < MVNETA_TX_QUEUE_CNT; i++) { 577 MVNETA_WRITE(sc, MVNETA_TQTBCOUNT(i), 0); 578 MVNETA_WRITE(sc, MVNETA_TQTBCONFIG(i), 0); 579 } 580 581 MVNETA_WRITE(sc, MVNETA_PRXINIT, 0); 582 MVNETA_WRITE(sc, MVNETA_PTXINIT, 0); 583 584 /* set port acceleration mode */ 585 MVNETA_WRITE(sc, MVNETA_PACC, MVGVE_PACC_ACCELERATIONMODE_EDM); 586 587 MVNETA_WRITE(sc, MVNETA_PXC, MVNETA_PXC_AMNOTXES | MVNETA_PXC_RXCS); 588 MVNETA_WRITE(sc, MVNETA_PXCX, 0); 589 MVNETA_WRITE(sc, MVNETA_PMFS, 64); 590 591 /* Set SDC register except IPGINT bits */ 592 MVNETA_WRITE(sc, MVNETA_SDC, 593 MVNETA_SDC_RXBSZ_16_64BITWORDS | 594 MVNETA_SDC_BLMR | /* Big/Little Endian Receive Mode: No swap */ 595 MVNETA_SDC_BLMT | /* Big/Little Endian Transmit Mode: No swap */ 596 MVNETA_SDC_TXBSZ_16_64BITWORDS); 597 598 /* XXX: Disable PHY polling in hardware */ 599 MVNETA_WRITE(sc, MVNETA_EUC, 600 MVNETA_READ(sc, MVNETA_EUC) & ~MVNETA_EUC_POLLING); 601 602 /* clear uni-/multicast tables */ 603 uint32_t dfut[MVNETA_NDFUT], dfsmt[MVNETA_NDFSMT], dfomt[MVNETA_NDFOMT]; 604 memset(dfut, 0, sizeof(dfut)); 605 memset(dfsmt, 0, sizeof(dfut)); 606 memset(dfomt, 0, sizeof(dfut)); 607 MVNETA_WRITE_FILTER(sc, MVNETA_DFUT, dfut, MVNETA_NDFUT); 608 MVNETA_WRITE_FILTER(sc, MVNETA_DFSMT, dfut, MVNETA_NDFSMT); 609 MVNETA_WRITE_FILTER(sc, MVNETA_DFOMT, dfut, MVNETA_NDFOMT); 610 611 MVNETA_WRITE(sc, MVNETA_PIE, 612 MVNETA_PIE_RXPKTINTRPTENB_ALL | MVNETA_PIE_TXPKTINTRPTENB_ALL); 613 614 MVNETA_WRITE(sc, MVNETA_EUIC, 0); 615 616 /* Setup phy. */ 617 ctl0 = MVNETA_READ(sc, MVNETA_PMACC0); 618 ctl2 = MVNETA_READ(sc, MVNETA_PMACC2); 619 ctl4 = MVNETA_READ(sc, MVNETA_PMACC4); 620 panc = MVNETA_READ(sc, MVNETA_PANC); 621 622 /* Force link down to change in-band settings. */ 623 panc &= ~MVNETA_PANC_FORCELINKPASS; 624 panc |= MVNETA_PANC_FORCELINKFAIL; 625 MVNETA_WRITE(sc, MVNETA_PANC, panc); 626 627 mvneta_comphy_init(sc); 628 629 ctl0 &= ~MVNETA_PMACC0_PORTTYPE; 630 ctl2 &= ~(MVNETA_PMACC2_PORTMACRESET | MVNETA_PMACC2_INBANDAN); 631 ctl4 &= ~(MVNETA_PMACC4_SHORT_PREAMBLE); 632 panc &= ~(MVNETA_PANC_INBANDANEN | MVNETA_PANC_INBANDRESTARTAN | 633 MVNETA_PANC_SETMIISPEED | MVNETA_PANC_SETGMIISPEED | 634 MVNETA_PANC_ANSPEEDEN | MVNETA_PANC_SETFCEN | 635 MVNETA_PANC_PAUSEADV | MVNETA_PANC_ANFCEN | 636 MVNETA_PANC_SETFULLDX | MVNETA_PANC_ANDUPLEXEN); 637 638 ctl2 |= MVNETA_PMACC2_RGMIIEN; 639 switch (sc->sc_phy_mode) { 640 case PHY_MODE_QSGMII: 641 MVNETA_WRITE(sc, MVNETA_SERDESCFG, 642 MVNETA_SERDESCFG_QSGMII_PROTO); 643 ctl2 |= MVNETA_PMACC2_PCSEN; 644 break; 645 case PHY_MODE_SGMII: 646 MVNETA_WRITE(sc, MVNETA_SERDESCFG, 647 MVNETA_SERDESCFG_SGMII_PROTO); 648 ctl2 |= MVNETA_PMACC2_PCSEN; 649 break; 650 case PHY_MODE_1000BASEX: 651 MVNETA_WRITE(sc, MVNETA_SERDESCFG, 652 MVNETA_SERDESCFG_SGMII_PROTO); 653 ctl2 |= MVNETA_PMACC2_PCSEN; 654 break; 655 case PHY_MODE_2500BASEX: 656 MVNETA_WRITE(sc, MVNETA_SERDESCFG, 657 MVNETA_SERDESCFG_HSGMII_PROTO); 658 ctl2 |= MVNETA_PMACC2_PCSEN; 659 ctl4 |= MVNETA_PMACC4_SHORT_PREAMBLE; 660 break; 661 default: 662 break; 663 } 664 665 /* Use Auto-Negotiation for Inband Status only */ 666 if (sc->sc_inband_status) { 667 panc &= ~(MVNETA_PANC_FORCELINKFAIL | 668 MVNETA_PANC_FORCELINKPASS); 669 /* TODO: read mode from SFP */ 670 if (1) { 671 /* 802.3z */ 672 ctl0 |= MVNETA_PMACC0_PORTTYPE; 673 panc |= (MVNETA_PANC_INBANDANEN | 674 MVNETA_PANC_SETGMIISPEED | 675 MVNETA_PANC_SETFULLDX); 676 } else { 677 /* SGMII */ 678 ctl2 |= MVNETA_PMACC2_INBANDAN; 679 panc |= (MVNETA_PANC_INBANDANEN | 680 MVNETA_PANC_ANSPEEDEN | 681 MVNETA_PANC_ANDUPLEXEN); 682 } 683 MVNETA_WRITE(sc, MVNETA_OMSCD, 684 MVNETA_READ(sc, MVNETA_OMSCD) | MVNETA_OMSCD_1MS_CLOCK_ENABLE); 685 } else { 686 MVNETA_WRITE(sc, MVNETA_OMSCD, 687 MVNETA_READ(sc, MVNETA_OMSCD) & ~MVNETA_OMSCD_1MS_CLOCK_ENABLE); 688 } 689 690 MVNETA_WRITE(sc, MVNETA_PMACC0, ctl0); 691 MVNETA_WRITE(sc, MVNETA_PMACC2, ctl2); 692 MVNETA_WRITE(sc, MVNETA_PMACC4, ctl4); 693 MVNETA_WRITE(sc, MVNETA_PANC, panc); 694 695 /* Port reset */ 696 while (MVNETA_READ(sc, MVNETA_PMACC2) & MVNETA_PMACC2_PORTMACRESET) 697 ; 698 699 sc->sc_ih = fdt_intr_establish(faa->fa_node, IPL_NET | IPL_MPSAFE, 700 mvneta_intr, sc, sc->sc_dev.dv_xname); 701 702 ifp = &sc->sc_ac.ac_if; 703 ifp->if_softc = sc; 704 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; 705 ifp->if_xflags = IFXF_MPSAFE; 706 ifp->if_qstart = mvneta_start; 707 ifp->if_ioctl = mvneta_ioctl; 708 ifp->if_watchdog = mvneta_watchdog; 709 ifp->if_capabilities = IFCAP_VLAN_MTU; 710 711 #if notyet 712 /* 713 * We can do IPv4/TCPv4/UDPv4 checksums in hardware. 714 */ 715 ifp->if_capabilities |= IFCAP_CSUM_IPv4 | IFCAP_CSUM_TCPv4 | 716 IFCAP_CSUM_UDPv4; 717 718 ifp->if_capabilities |= IFCAP_VLAN_HWTAGGING; 719 /* 720 * But, IPv6 packets in the stream can cause incorrect TCPv4 Tx sums. 721 */ 722 ifp->if_capabilities &= ~IFCAP_CSUM_TCPv4; 723 #endif 724 725 ifq_init_maxlen(&ifp->if_snd, max(MVNETA_TX_RING_CNT - 1, IFQ_MAXLEN)); 726 strlcpy(ifp->if_xname, sc->sc_dev.dv_xname, sizeof(ifp->if_xname)); 727 728 /* 729 * Do MII setup. 730 */ 731 sc->sc_mii.mii_ifp = ifp; 732 sc->sc_mii.mii_readreg = mvneta_miibus_readreg; 733 sc->sc_mii.mii_writereg = mvneta_miibus_writereg; 734 sc->sc_mii.mii_statchg = mvneta_miibus_statchg; 735 736 ifmedia_init(&sc->sc_mii.mii_media, 0, 737 mvneta_mediachange, mvneta_mediastatus); 738 739 config_defer(self, mvneta_attach_deferred); 740 } 741 742 void 743 mvneta_attach_deferred(struct device *self) 744 { 745 struct mvneta_softc *sc = (struct mvneta_softc *) self; 746 struct ifnet *ifp = &sc->sc_ac.ac_if; 747 int mii_flags = 0; 748 749 if (!sc->sc_fixed_link) { 750 sc->sc_mdio = mii_byphandle(sc->sc_phy); 751 if (sc->sc_mdio == NULL) { 752 printf("%s: mdio bus not yet attached\n", self->dv_xname); 753 return; 754 } 755 756 switch (sc->sc_phy_mode) { 757 case PHY_MODE_1000BASEX: 758 mii_flags |= MIIF_IS_1000X; 759 break; 760 case PHY_MODE_SGMII: 761 mii_flags |= MIIF_SGMII; 762 break; 763 case PHY_MODE_RGMII_ID: 764 mii_flags |= MIIF_RXID | MIIF_TXID; 765 break; 766 default: 767 break; 768 } 769 770 mii_attach(self, &sc->sc_mii, 0xffffffff, sc->sc_phyloc, 771 MII_OFFSET_ANY, mii_flags); 772 if (LIST_FIRST(&sc->sc_mii.mii_phys) == NULL) { 773 printf("%s: no PHY found!\n", self->dv_xname); 774 ifmedia_add(&sc->sc_mii.mii_media, 775 IFM_ETHER|IFM_MANUAL, 0, NULL); 776 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_MANUAL); 777 } else 778 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 779 } else { 780 ifmedia_add(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO, 0, NULL); 781 ifmedia_set(&sc->sc_mii.mii_media, IFM_ETHER|IFM_AUTO); 782 783 if (sc->sc_inband_status) { 784 switch (sc->sc_phy_mode) { 785 case PHY_MODE_1000BASEX: 786 sc->sc_mii.mii_media_active = 787 IFM_ETHER|IFM_1000_KX|IFM_FDX; 788 break; 789 case PHY_MODE_2500BASEX: 790 sc->sc_mii.mii_media_active = 791 IFM_ETHER|IFM_2500_KX|IFM_FDX; 792 break; 793 default: 794 break; 795 } 796 mvneta_inband_statchg(sc); 797 } else { 798 sc->sc_mii.mii_media_status = IFM_AVALID|IFM_ACTIVE; 799 sc->sc_mii.mii_media_active = IFM_ETHER|IFM_1000_T|IFM_FDX; 800 mvneta_miibus_statchg(self); 801 } 802 803 ifp->if_baudrate = ifmedia_baudrate(sc->sc_mii.mii_media_active); 804 ifp->if_link_state = LINK_STATE_FULL_DUPLEX; 805 } 806 807 /* 808 * Call MI attach routines. 809 */ 810 if_attach(ifp); 811 ether_ifattach(ifp); 812 813 sc->sc_ifd.if_node = sc->sc_node; 814 sc->sc_ifd.if_ifp = ifp; 815 if_register(&sc->sc_ifd); 816 817 #if NKSTAT > 0 818 mvneta_kstat_attach(sc); 819 #endif 820 } 821 822 void 823 mvneta_tick(void *arg) 824 { 825 struct mvneta_softc *sc = arg; 826 struct mii_data *mii = &sc->sc_mii; 827 int s; 828 829 s = splnet(); 830 mii_tick(mii); 831 splx(s); 832 833 timeout_add_sec(&sc->sc_tick_ch, 1); 834 } 835 836 int 837 mvneta_intr(void *arg) 838 { 839 struct mvneta_softc *sc = arg; 840 struct ifnet *ifp = &sc->sc_ac.ac_if; 841 uint32_t ic, misc; 842 843 ic = MVNETA_READ(sc, MVNETA_PRXTXTIC); 844 845 if (ic & MVNETA_PRXTXTI_PMISCICSUMMARY) { 846 KERNEL_LOCK(); 847 misc = MVNETA_READ(sc, MVNETA_PMIC); 848 MVNETA_WRITE(sc, MVNETA_PMIC, 0); 849 if (sc->sc_inband_status && (misc & 850 (MVNETA_PMI_PHYSTATUSCHNG | 851 MVNETA_PMI_LINKCHANGE | 852 MVNETA_PMI_PSCSYNCCHNG))) { 853 mvneta_inband_statchg(sc); 854 } 855 KERNEL_UNLOCK(); 856 } 857 858 if (!ISSET(ifp->if_flags, IFF_RUNNING)) 859 return 1; 860 861 if (ic & MVNETA_PRXTXTI_TBTCQ(0)) 862 mvneta_tx_proc(sc); 863 864 if (ISSET(ic, MVNETA_PRXTXTI_RBICTAPQ(0) | MVNETA_PRXTXTI_RDTAQ(0))) 865 mvneta_rx_proc(sc); 866 867 return 1; 868 } 869 870 static inline int 871 mvneta_load_mbuf(struct mvneta_softc *sc, bus_dmamap_t map, struct mbuf *m) 872 { 873 int error; 874 875 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, 876 BUS_DMA_STREAMING | BUS_DMA_NOWAIT); 877 switch (error) { 878 case EFBIG: 879 error = m_defrag(m, M_DONTWAIT); 880 if (error != 0) 881 break; 882 883 error = bus_dmamap_load_mbuf(sc->sc_dmat, map, m, 884 BUS_DMA_STREAMING | BUS_DMA_NOWAIT); 885 if (error != 0) 886 break; 887 888 /* FALLTHROUGH */ 889 case 0: 890 return (0); 891 892 default: 893 break; 894 } 895 896 return (error); 897 } 898 899 static inline void 900 mvneta_encap(struct mvneta_softc *sc, bus_dmamap_t map, struct mbuf *m, 901 unsigned int prod) 902 { 903 struct mvneta_tx_desc *txd; 904 uint32_t cmdsts; 905 unsigned int i; 906 907 cmdsts = MVNETA_TX_FIRST_DESC | MVNETA_TX_ZERO_PADDING | 908 MVNETA_TX_L4_CSUM_NOT; 909 #if notyet 910 int m_csumflags; 911 if (m_csumflags & M_CSUM_IPv4) 912 cmdsts |= MVNETA_TX_GENERATE_IP_CHKSUM; 913 if (m_csumflags & M_CSUM_TCPv4) 914 cmdsts |= 915 MVNETA_TX_GENERATE_L4_CHKSUM | MVNETA_TX_L4_TYPE_TCP; 916 if (m_csumflags & M_CSUM_UDPv4) 917 cmdsts |= 918 MVNETA_TX_GENERATE_L4_CHKSUM | MVNETA_TX_L4_TYPE_UDP; 919 if (m_csumflags & (M_CSUM_IPv4 | M_CSUM_TCPv4 | M_CSUM_UDPv4)) { 920 const int iphdr_unitlen = sizeof(struct ip) / sizeof(uint32_t); 921 922 cmdsts |= MVNETA_TX_IP_NO_FRAG | 923 MVNETA_TX_IP_HEADER_LEN(iphdr_unitlen); /* unit is 4B */ 924 } 925 #endif 926 927 for (i = 0; i < map->dm_nsegs; i++) { 928 txd = &sc->sc_txdesc[prod]; 929 txd->bytecnt = map->dm_segs[i].ds_len; 930 txd->l4ichk = 0; 931 txd->cmdsts = cmdsts; 932 txd->nextdescptr = 0; 933 txd->bufptr = map->dm_segs[i].ds_addr; 934 txd->_padding[0] = 0; 935 txd->_padding[1] = 0; 936 txd->_padding[2] = 0; 937 txd->_padding[3] = 0; 938 939 prod = MVNETA_TX_RING_NEXT(prod); 940 cmdsts = 0; 941 } 942 txd->cmdsts |= MVNETA_TX_LAST_DESC; 943 } 944 945 static inline void 946 mvneta_sync_txring(struct mvneta_softc *sc, int ops) 947 { 948 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_txring), 0, 949 MVNETA_DMA_LEN(sc->sc_txring), ops); 950 } 951 952 void 953 mvneta_start(struct ifqueue *ifq) 954 { 955 struct ifnet *ifp = ifq->ifq_if; 956 struct mvneta_softc *sc = ifp->if_softc; 957 unsigned int prod, nprod, free, used = 0, nused; 958 struct mbuf *m; 959 bus_dmamap_t map; 960 961 /* If Link is DOWN, can't start TX */ 962 if (!MVNETA_IS_LINKUP(sc)) { 963 ifq_purge(ifq); 964 return; 965 } 966 967 mvneta_sync_txring(sc, BUS_DMASYNC_POSTWRITE); 968 969 prod = sc->sc_tx_prod; 970 free = MVNETA_TX_RING_CNT - (prod - sc->sc_tx_cons); 971 972 for (;;) { 973 if (free < MVNETA_NTXSEG - 1) { 974 ifq_set_oactive(ifq); 975 break; 976 } 977 978 m = ifq_dequeue(ifq); 979 if (m == NULL) 980 break; 981 982 map = sc->sc_txbuf[prod].tb_map; 983 if (mvneta_load_mbuf(sc, map, m) != 0) { 984 m_freem(m); 985 ifp->if_oerrors++; /* XXX atomic */ 986 continue; 987 } 988 989 #if NBPFILTER > 0 990 if (ifp->if_bpf) 991 bpf_mtap(ifp->if_bpf, m, BPF_DIRECTION_OUT); 992 #endif 993 994 bus_dmamap_sync(sc->sc_dmat, map, 0, map->dm_mapsize, 995 BUS_DMASYNC_PREWRITE); 996 997 mvneta_encap(sc, map, m, prod); 998 999 if (map->dm_nsegs > 1) { 1000 nprod = (prod + (map->dm_nsegs - 1)) % 1001 MVNETA_TX_RING_CNT; 1002 sc->sc_txbuf[prod].tb_map = sc->sc_txbuf[nprod].tb_map; 1003 prod = nprod; 1004 sc->sc_txbuf[prod].tb_map = map; 1005 } 1006 sc->sc_txbuf[prod].tb_m = m; 1007 prod = MVNETA_TX_RING_NEXT(prod); 1008 1009 free -= map->dm_nsegs; 1010 1011 nused = used + map->dm_nsegs; 1012 if (nused > MVNETA_PTXSU_MAX) { 1013 mvneta_sync_txring(sc, 1014 BUS_DMASYNC_PREWRITE|BUS_DMASYNC_POSTWRITE); 1015 MVNETA_WRITE(sc, MVNETA_PTXSU(0), 1016 MVNETA_PTXSU_NOWD(used)); 1017 used = map->dm_nsegs; 1018 } else 1019 used = nused; 1020 } 1021 1022 mvneta_sync_txring(sc, BUS_DMASYNC_PREWRITE); 1023 1024 sc->sc_tx_prod = prod; 1025 if (used) 1026 MVNETA_WRITE(sc, MVNETA_PTXSU(0), MVNETA_PTXSU_NOWD(used)); 1027 } 1028 1029 int 1030 mvneta_ioctl(struct ifnet *ifp, u_long cmd, caddr_t addr) 1031 { 1032 struct mvneta_softc *sc = ifp->if_softc; 1033 struct ifreq *ifr = (struct ifreq *)addr; 1034 int s, error = 0; 1035 1036 s = splnet(); 1037 1038 switch (cmd) { 1039 case SIOCSIFADDR: 1040 ifp->if_flags |= IFF_UP; 1041 /* FALLTHROUGH */ 1042 case SIOCSIFFLAGS: 1043 if (ifp->if_flags & IFF_UP) { 1044 if (ifp->if_flags & IFF_RUNNING) 1045 error = ENETRESET; 1046 else 1047 mvneta_up(sc); 1048 } else { 1049 if (ifp->if_flags & IFF_RUNNING) 1050 mvneta_down(sc); 1051 } 1052 break; 1053 case SIOCGIFMEDIA: 1054 case SIOCSIFMEDIA: 1055 DPRINTFN(2, ("mvneta_ioctl MEDIA\n")); 1056 error = ifmedia_ioctl(ifp, ifr, &sc->sc_media, cmd); 1057 break; 1058 case SIOCGIFRXR: 1059 error = if_rxr_ioctl((struct if_rxrinfo *)ifr->ifr_data, 1060 NULL, MCLBYTES, &sc->sc_rx_ring); 1061 break; 1062 case SIOCGIFSFFPAGE: 1063 error = rw_enter(&mvneta_sff_lock, RW_WRITE|RW_INTR); 1064 if (error != 0) 1065 break; 1066 1067 error = sfp_get_sffpage(sc->sc_sfp, (struct if_sffpage *)addr); 1068 rw_exit(&mvneta_sff_lock); 1069 break; 1070 default: 1071 DPRINTFN(2, ("mvneta_ioctl ETHER\n")); 1072 error = ether_ioctl(ifp, &sc->sc_ac, cmd, addr); 1073 break; 1074 } 1075 1076 if (error == ENETRESET) { 1077 if (ifp->if_flags & IFF_RUNNING) 1078 mvneta_iff(sc); 1079 error = 0; 1080 } 1081 1082 splx(s); 1083 1084 return error; 1085 } 1086 1087 void 1088 mvneta_port_change(struct mvneta_softc *sc) 1089 { 1090 if (!!(sc->sc_mii.mii_media_status & IFM_ACTIVE) != sc->sc_link) { 1091 sc->sc_link = !sc->sc_link; 1092 1093 if (sc->sc_link) { 1094 if (!sc->sc_inband_status) { 1095 uint32_t panc = MVNETA_READ(sc, MVNETA_PANC); 1096 panc &= ~MVNETA_PANC_FORCELINKFAIL; 1097 panc |= MVNETA_PANC_FORCELINKPASS; 1098 MVNETA_WRITE(sc, MVNETA_PANC, panc); 1099 } 1100 mvneta_port_up(sc); 1101 } else { 1102 if (!sc->sc_inband_status) { 1103 uint32_t panc = MVNETA_READ(sc, MVNETA_PANC); 1104 panc &= ~MVNETA_PANC_FORCELINKPASS; 1105 panc |= MVNETA_PANC_FORCELINKFAIL; 1106 MVNETA_WRITE(sc, MVNETA_PANC, panc); 1107 } 1108 } 1109 } 1110 } 1111 1112 void 1113 mvneta_port_up(struct mvneta_softc *sc) 1114 { 1115 /* Enable port RX/TX. */ 1116 MVNETA_WRITE(sc, MVNETA_RQC, MVNETA_RQC_ENQ(0)); 1117 MVNETA_WRITE(sc, MVNETA_TQC, MVNETA_TQC_ENQ(0)); 1118 } 1119 1120 int 1121 mvneta_up(struct mvneta_softc *sc) 1122 { 1123 struct ifnet *ifp = &sc->sc_ac.ac_if; 1124 struct mvneta_buf *txb, *rxb; 1125 int i; 1126 1127 DPRINTFN(2, ("mvneta_up\n")); 1128 1129 /* Allocate Tx descriptor ring. */ 1130 sc->sc_txring = mvneta_dmamem_alloc(sc, 1131 MVNETA_TX_RING_CNT * sizeof(struct mvneta_tx_desc), 32); 1132 sc->sc_txdesc = MVNETA_DMA_KVA(sc->sc_txring); 1133 1134 sc->sc_txbuf = malloc(sizeof(struct mvneta_buf) * MVNETA_TX_RING_CNT, 1135 M_DEVBUF, M_WAITOK); 1136 1137 for (i = 0; i < MVNETA_TX_RING_CNT; i++) { 1138 txb = &sc->sc_txbuf[i]; 1139 bus_dmamap_create(sc->sc_dmat, MCLBYTES, MVNETA_NTXSEG, 1140 MCLBYTES, 0, BUS_DMA_WAITOK, &txb->tb_map); 1141 txb->tb_m = NULL; 1142 } 1143 1144 sc->sc_tx_prod = sc->sc_tx_cons = 0; 1145 1146 /* Allocate Rx descriptor ring. */ 1147 sc->sc_rxring = mvneta_dmamem_alloc(sc, 1148 MVNETA_RX_RING_CNT * sizeof(struct mvneta_rx_desc), 32); 1149 sc->sc_rxdesc = MVNETA_DMA_KVA(sc->sc_rxring); 1150 1151 sc->sc_rxbuf = malloc(sizeof(struct mvneta_buf) * MVNETA_RX_RING_CNT, 1152 M_DEVBUF, M_WAITOK); 1153 1154 for (i = 0; i < MVNETA_RX_RING_CNT; i++) { 1155 rxb = &sc->sc_rxbuf[i]; 1156 bus_dmamap_create(sc->sc_dmat, MCLBYTES, 1, 1157 MCLBYTES, 0, BUS_DMA_WAITOK, &rxb->tb_map); 1158 rxb->tb_m = NULL; 1159 } 1160 1161 /* Set Rx descriptor ring data. */ 1162 MVNETA_WRITE(sc, MVNETA_PRXDQA(0), MVNETA_DMA_DVA(sc->sc_rxring)); 1163 MVNETA_WRITE(sc, MVNETA_PRXDQS(0), MVNETA_RX_RING_CNT | 1164 ((MCLBYTES >> 3) << 19)); 1165 1166 if (sc->sc_clk_freq != 0) { 1167 /* 1168 * Use the Non Occupied Descriptors Threshold to 1169 * interrupt when the descriptors granted by rxr are 1170 * used up, otherwise wait until the RX Interrupt 1171 * Time Threshold is reached. 1172 */ 1173 MVNETA_WRITE(sc, MVNETA_PRXDQTH(0), 1174 MVNETA_PRXDQTH_ODT(MVNETA_RX_RING_CNT) | 1175 MVNETA_PRXDQTH_NODT(2)); 1176 MVNETA_WRITE(sc, MVNETA_PRXITTH(0), sc->sc_clk_freq / 4000); 1177 } else { 1178 /* Time based moderation is hard without a clock */ 1179 MVNETA_WRITE(sc, MVNETA_PRXDQTH(0), 0); 1180 MVNETA_WRITE(sc, MVNETA_PRXITTH(0), 0); 1181 } 1182 1183 MVNETA_WRITE(sc, MVNETA_PRXC(0), 0); 1184 1185 /* Set Tx queue bandwidth. */ 1186 MVNETA_WRITE(sc, MVNETA_TQTBCOUNT(0), 0x03ffffff); 1187 MVNETA_WRITE(sc, MVNETA_TQTBCONFIG(0), 0x03ffffff); 1188 1189 /* Set Tx descriptor ring data. */ 1190 MVNETA_WRITE(sc, MVNETA_PTXDQA(0), MVNETA_DMA_DVA(sc->sc_txring)); 1191 MVNETA_WRITE(sc, MVNETA_PTXDQS(0), 1192 MVNETA_PTXDQS_DQS(MVNETA_TX_RING_CNT) | 1193 MVNETA_PTXDQS_TBT(MIN(MVNETA_TX_RING_CNT / 2, ifp->if_txmit))); 1194 1195 sc->sc_rx_prod = sc->sc_rx_cons = 0; 1196 1197 if_rxr_init(&sc->sc_rx_ring, 2, MVNETA_RX_RING_CNT); 1198 mvneta_fill_rx_ring(sc); 1199 1200 /* TODO: correct frame size */ 1201 MVNETA_WRITE(sc, MVNETA_PMACC0, 1202 (MVNETA_READ(sc, MVNETA_PMACC0) & MVNETA_PMACC0_PORTTYPE) | 1203 MVNETA_PMACC0_FRAMESIZELIMIT(MCLBYTES - MVNETA_HWHEADER_SIZE)); 1204 1205 /* set max MTU */ 1206 MVNETA_WRITE(sc, MVNETA_TXMTU, MVNETA_TXMTU_MAX); 1207 MVNETA_WRITE(sc, MVNETA_TXTKSIZE, 0xffffffff); 1208 MVNETA_WRITE(sc, MVNETA_TXQTKSIZE(0), 0x7fffffff); 1209 1210 /* enable port */ 1211 MVNETA_WRITE(sc, MVNETA_PMACC0, 1212 MVNETA_READ(sc, MVNETA_PMACC0) | MVNETA_PMACC0_PORTEN); 1213 1214 mvneta_enaddr_write(sc); 1215 1216 /* Program promiscuous mode and multicast filters. */ 1217 mvneta_iff(sc); 1218 1219 if (!sc->sc_fixed_link) 1220 mii_mediachg(&sc->sc_mii); 1221 1222 if (sc->sc_link) 1223 mvneta_port_up(sc); 1224 1225 /* Enable interrupt masks */ 1226 MVNETA_WRITE(sc, MVNETA_PRXTXTIM, MVNETA_PRXTXTI_RBICTAPQ(0) | 1227 MVNETA_PRXTXTI_TBTCQ(0) | MVNETA_PRXTXTI_RDTAQ(0) | 1228 MVNETA_PRXTXTI_PMISCICSUMMARY); 1229 MVNETA_WRITE(sc, MVNETA_PMIM, MVNETA_PMI_PHYSTATUSCHNG | 1230 MVNETA_PMI_LINKCHANGE | MVNETA_PMI_PSCSYNCCHNG); 1231 1232 timeout_add_sec(&sc->sc_tick_ch, 1); 1233 1234 ifp->if_flags |= IFF_RUNNING; 1235 ifq_clr_oactive(&ifp->if_snd); 1236 1237 return 0; 1238 } 1239 1240 void 1241 mvneta_down(struct mvneta_softc *sc) 1242 { 1243 struct ifnet *ifp = &sc->sc_ac.ac_if; 1244 uint32_t reg, txinprog, txfifoemp; 1245 struct mvneta_buf *txb, *rxb; 1246 int i, cnt; 1247 1248 DPRINTFN(2, ("mvneta_down\n")); 1249 1250 timeout_del(&sc->sc_tick_ch); 1251 ifp->if_flags &= ~IFF_RUNNING; 1252 intr_barrier(sc->sc_ih); 1253 1254 /* Stop Rx port activity. Check port Rx activity. */ 1255 reg = MVNETA_READ(sc, MVNETA_RQC); 1256 if (reg & MVNETA_RQC_ENQ_MASK) 1257 /* Issue stop command for active channels only */ 1258 MVNETA_WRITE(sc, MVNETA_RQC, MVNETA_RQC_DISQ_DISABLE(reg)); 1259 1260 /* Stop Tx port activity. Check port Tx activity. */ 1261 if (MVNETA_READ(sc, MVNETA_TQC) & MVNETA_TQC_ENQ(0)) 1262 MVNETA_WRITE(sc, MVNETA_TQC, MVNETA_TQC_DISQ(0)); 1263 1264 txinprog = MVNETA_PS_TXINPROG_(0); 1265 txfifoemp = MVNETA_PS_TXFIFOEMP_(0); 1266 1267 #define RX_DISABLE_TIMEOUT 0x1000000 1268 #define TX_FIFO_EMPTY_TIMEOUT 0x1000000 1269 /* Wait for all Rx activity to terminate. */ 1270 cnt = 0; 1271 do { 1272 if (cnt >= RX_DISABLE_TIMEOUT) { 1273 printf("%s: timeout for RX stopped. rqc 0x%x\n", 1274 sc->sc_dev.dv_xname, reg); 1275 break; 1276 } 1277 cnt++; 1278 1279 /* 1280 * Check Receive Queue Command register that all Rx queues 1281 * are stopped 1282 */ 1283 reg = MVNETA_READ(sc, MVNETA_RQC); 1284 } while (reg & 0xff); 1285 1286 /* Double check to verify that TX FIFO is empty */ 1287 cnt = 0; 1288 while (1) { 1289 do { 1290 if (cnt >= TX_FIFO_EMPTY_TIMEOUT) { 1291 printf("%s: timeout for TX FIFO empty. status " 1292 "0x%x\n", sc->sc_dev.dv_xname, reg); 1293 break; 1294 } 1295 cnt++; 1296 1297 reg = MVNETA_READ(sc, MVNETA_PS); 1298 } while (!(reg & txfifoemp) || reg & txinprog); 1299 1300 if (cnt >= TX_FIFO_EMPTY_TIMEOUT) 1301 break; 1302 1303 /* Double check */ 1304 reg = MVNETA_READ(sc, MVNETA_PS); 1305 if (reg & txfifoemp && !(reg & txinprog)) 1306 break; 1307 else 1308 printf("%s: TX FIFO empty double check failed." 1309 " %d loops, status 0x%x\n", sc->sc_dev.dv_xname, 1310 cnt, reg); 1311 } 1312 1313 delay(200); 1314 1315 /* disable port */ 1316 MVNETA_WRITE(sc, MVNETA_PMACC0, 1317 MVNETA_READ(sc, MVNETA_PMACC0) & ~MVNETA_PMACC0_PORTEN); 1318 delay(200); 1319 1320 /* mask all interrupts */ 1321 MVNETA_WRITE(sc, MVNETA_PRXTXTIM, MVNETA_PRXTXTI_PMISCICSUMMARY); 1322 MVNETA_WRITE(sc, MVNETA_PRXTXIM, 0); 1323 1324 /* clear all cause registers */ 1325 MVNETA_WRITE(sc, MVNETA_PRXTXTIC, 0); 1326 MVNETA_WRITE(sc, MVNETA_PRXTXIC, 0); 1327 1328 /* Free RX and TX mbufs still in the queues. */ 1329 for (i = 0; i < MVNETA_TX_RING_CNT; i++) { 1330 txb = &sc->sc_txbuf[i]; 1331 if (txb->tb_m) { 1332 bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0, 1333 txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1334 bus_dmamap_unload(sc->sc_dmat, txb->tb_map); 1335 m_freem(txb->tb_m); 1336 } 1337 bus_dmamap_destroy(sc->sc_dmat, txb->tb_map); 1338 } 1339 1340 mvneta_dmamem_free(sc, sc->sc_txring); 1341 free(sc->sc_txbuf, M_DEVBUF, 0); 1342 1343 for (i = 0; i < MVNETA_RX_RING_CNT; i++) { 1344 rxb = &sc->sc_rxbuf[i]; 1345 if (rxb->tb_m) { 1346 bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0, 1347 rxb->tb_map->dm_mapsize, BUS_DMASYNC_POSTREAD); 1348 bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); 1349 m_freem(rxb->tb_m); 1350 } 1351 bus_dmamap_destroy(sc->sc_dmat, rxb->tb_map); 1352 } 1353 1354 mvneta_dmamem_free(sc, sc->sc_rxring); 1355 free(sc->sc_rxbuf, M_DEVBUF, 0); 1356 1357 /* reset RX and TX DMAs */ 1358 MVNETA_WRITE(sc, MVNETA_PRXINIT, MVNETA_PRXINIT_RXDMAINIT); 1359 MVNETA_WRITE(sc, MVNETA_PTXINIT, MVNETA_PTXINIT_TXDMAINIT); 1360 MVNETA_WRITE(sc, MVNETA_PRXINIT, 0); 1361 MVNETA_WRITE(sc, MVNETA_PTXINIT, 0); 1362 1363 ifq_clr_oactive(&ifp->if_snd); 1364 } 1365 1366 void 1367 mvneta_watchdog(struct ifnet *ifp) 1368 { 1369 struct mvneta_softc *sc = ifp->if_softc; 1370 1371 /* 1372 * Reclaim first as there is a possibility of losing Tx completion 1373 * interrupts. 1374 */ 1375 mvneta_tx_proc(sc); 1376 if (sc->sc_tx_prod != sc->sc_tx_cons) { 1377 printf("%s: watchdog timeout\n", sc->sc_dev.dv_xname); 1378 1379 ifp->if_oerrors++; 1380 } 1381 } 1382 1383 /* 1384 * Set media options. 1385 */ 1386 int 1387 mvneta_mediachange(struct ifnet *ifp) 1388 { 1389 struct mvneta_softc *sc = ifp->if_softc; 1390 1391 if (LIST_FIRST(&sc->sc_mii.mii_phys)) 1392 mii_mediachg(&sc->sc_mii); 1393 1394 return (0); 1395 } 1396 1397 /* 1398 * Report current media status. 1399 */ 1400 void 1401 mvneta_mediastatus(struct ifnet *ifp, struct ifmediareq *ifmr) 1402 { 1403 struct mvneta_softc *sc = ifp->if_softc; 1404 1405 if (LIST_FIRST(&sc->sc_mii.mii_phys)) { 1406 mii_pollstat(&sc->sc_mii); 1407 ifmr->ifm_active = sc->sc_mii.mii_media_active; 1408 ifmr->ifm_status = sc->sc_mii.mii_media_status; 1409 } 1410 1411 if (sc->sc_fixed_link) { 1412 ifmr->ifm_active = sc->sc_mii.mii_media_active; 1413 ifmr->ifm_status = sc->sc_mii.mii_media_status; 1414 } 1415 } 1416 1417 void 1418 mvneta_rx_proc(struct mvneta_softc *sc) 1419 { 1420 struct ifnet *ifp = &sc->sc_ac.ac_if; 1421 struct mvneta_rx_desc *rxd; 1422 struct mvneta_buf *rxb; 1423 struct mbuf_list ml = MBUF_LIST_INITIALIZER(); 1424 struct mbuf *m; 1425 uint32_t rxstat; 1426 unsigned int i, done, cons; 1427 1428 done = MVNETA_PRXS_ODC(MVNETA_READ(sc, MVNETA_PRXS(0))); 1429 if (done == 0) 1430 return; 1431 1432 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_rxring), 1433 0, MVNETA_DMA_LEN(sc->sc_rxring), BUS_DMASYNC_POSTREAD); 1434 1435 cons = sc->sc_rx_cons; 1436 1437 for (i = 0; i < done; i++) { 1438 rxd = &sc->sc_rxdesc[cons]; 1439 rxb = &sc->sc_rxbuf[cons]; 1440 1441 m = rxb->tb_m; 1442 rxb->tb_m = NULL; 1443 1444 bus_dmamap_sync(sc->sc_dmat, rxb->tb_map, 0, 1445 m->m_pkthdr.len, BUS_DMASYNC_POSTREAD); 1446 bus_dmamap_unload(sc->sc_dmat, rxb->tb_map); 1447 1448 rxstat = rxd->cmdsts; 1449 if (rxstat & MVNETA_ERROR_SUMMARY) { 1450 #if 0 1451 int err = rxstat & MVNETA_RX_ERROR_CODE_MASK; 1452 1453 if (err == MVNETA_RX_CRC_ERROR) 1454 ifp->if_ierrors++; 1455 if (err == MVNETA_RX_OVERRUN_ERROR) 1456 ifp->if_ierrors++; 1457 if (err == MVNETA_RX_MAX_FRAME_LEN_ERROR) 1458 ifp->if_ierrors++; 1459 if (err == MVNETA_RX_RESOURCE_ERROR) 1460 ifp->if_ierrors++; 1461 #else 1462 ifp->if_ierrors++; 1463 #endif 1464 m_freem(m); 1465 } else { 1466 m->m_pkthdr.len = m->m_len = rxd->bytecnt; 1467 m_adj(m, MVNETA_HWHEADER_SIZE); 1468 1469 ml_enqueue(&ml, m); 1470 } 1471 1472 #if notyet 1473 if (rxstat & MVNETA_RX_IP_FRAME_TYPE) { 1474 int flgs = 0; 1475 1476 /* Check IPv4 header checksum */ 1477 flgs |= M_CSUM_IPv4; 1478 if (!(rxstat & MVNETA_RX_IP_HEADER_OK)) 1479 flgs |= M_CSUM_IPv4_BAD; 1480 else if ((bufsize & MVNETA_RX_IP_FRAGMENT) == 0) { 1481 /* 1482 * Check TCPv4/UDPv4 checksum for 1483 * non-fragmented packet only. 1484 * 1485 * It seemd that sometimes 1486 * MVNETA_RX_L4_CHECKSUM_OK bit was set to 0 1487 * even if the checksum is correct and the 1488 * packet was not fragmented. So we don't set 1489 * M_CSUM_TCP_UDP_BAD even if csum bit is 0. 1490 */ 1491 1492 if (((rxstat & MVNETA_RX_L4_TYPE_MASK) == 1493 MVNETA_RX_L4_TYPE_TCP) && 1494 ((rxstat & MVNETA_RX_L4_CHECKSUM_OK) != 0)) 1495 flgs |= M_CSUM_TCPv4; 1496 else if (((rxstat & MVNETA_RX_L4_TYPE_MASK) == 1497 MVNETA_RX_L4_TYPE_UDP) && 1498 ((rxstat & MVNETA_RX_L4_CHECKSUM_OK) != 0)) 1499 flgs |= M_CSUM_UDPv4; 1500 } 1501 m->m_pkthdr.csum_flags = flgs; 1502 } 1503 #endif 1504 1505 if_rxr_put(&sc->sc_rx_ring, 1); 1506 1507 cons = MVNETA_RX_RING_NEXT(cons); 1508 1509 if (i == MVNETA_PRXSU_MAX) { 1510 MVNETA_WRITE(sc, MVNETA_PRXSU(0), 1511 MVNETA_PRXSU_NOPD(MVNETA_PRXSU_MAX)); 1512 1513 /* tweaking the iterator inside the loop is fun */ 1514 done -= MVNETA_PRXSU_MAX; 1515 i = 0; 1516 } 1517 } 1518 1519 sc->sc_rx_cons = cons; 1520 1521 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_rxring), 1522 0, MVNETA_DMA_LEN(sc->sc_rxring), BUS_DMASYNC_PREREAD); 1523 1524 if (i > 0) { 1525 MVNETA_WRITE(sc, MVNETA_PRXSU(0), 1526 MVNETA_PRXSU_NOPD(i)); 1527 } 1528 1529 if (ifiq_input(&ifp->if_rcv, &ml)) 1530 if_rxr_livelocked(&sc->sc_rx_ring); 1531 1532 mvneta_fill_rx_ring(sc); 1533 } 1534 1535 void 1536 mvneta_tx_proc(struct mvneta_softc *sc) 1537 { 1538 struct ifnet *ifp = &sc->sc_ac.ac_if; 1539 struct ifqueue *ifq = &ifp->if_snd; 1540 struct mvneta_tx_desc *txd; 1541 struct mvneta_buf *txb; 1542 unsigned int i, cons, done; 1543 1544 if (!(ifp->if_flags & IFF_RUNNING)) 1545 return; 1546 1547 done = MVNETA_PTXS_TBC(MVNETA_READ(sc, MVNETA_PTXS(0))); 1548 if (done == 0) 1549 return; 1550 1551 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_txring), 0, 1552 MVNETA_DMA_LEN(sc->sc_txring), 1553 BUS_DMASYNC_POSTREAD); 1554 1555 cons = sc->sc_tx_cons; 1556 1557 for (i = 0; i < done; i++) { 1558 txd = &sc->sc_txdesc[cons]; 1559 txb = &sc->sc_txbuf[cons]; 1560 1561 if (txb->tb_m) { 1562 bus_dmamap_sync(sc->sc_dmat, txb->tb_map, 0, 1563 txb->tb_map->dm_mapsize, BUS_DMASYNC_POSTWRITE); 1564 bus_dmamap_unload(sc->sc_dmat, txb->tb_map); 1565 1566 m_freem(txb->tb_m); 1567 txb->tb_m = NULL; 1568 } 1569 1570 if (txd->cmdsts & MVNETA_ERROR_SUMMARY) { 1571 int err = txd->cmdsts & MVNETA_TX_ERROR_CODE_MASK; 1572 1573 if (err == MVNETA_TX_LATE_COLLISION_ERROR) 1574 ifp->if_collisions++; 1575 if (err == MVNETA_TX_UNDERRUN_ERROR) 1576 ifp->if_oerrors++; 1577 if (err == MVNETA_TX_EXCESSIVE_COLLISION_ERRO) 1578 ifp->if_collisions++; 1579 } 1580 1581 cons = MVNETA_TX_RING_NEXT(cons); 1582 1583 if (i == MVNETA_PTXSU_MAX) { 1584 MVNETA_WRITE(sc, MVNETA_PTXSU(0), 1585 MVNETA_PTXSU_NORB(MVNETA_PTXSU_MAX)); 1586 1587 /* tweaking the iterator inside the loop is fun */ 1588 done -= MVNETA_PTXSU_MAX; 1589 i = 0; 1590 } 1591 } 1592 1593 sc->sc_tx_cons = cons; 1594 1595 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_txring), 0, 1596 MVNETA_DMA_LEN(sc->sc_txring), 1597 BUS_DMASYNC_PREREAD); 1598 1599 if (i > 0) { 1600 MVNETA_WRITE(sc, MVNETA_PTXSU(0), 1601 MVNETA_PTXSU_NORB(i)); 1602 } 1603 if (ifq_is_oactive(ifq)) 1604 ifq_restart(ifq); 1605 } 1606 1607 uint8_t 1608 mvneta_crc8(const uint8_t *data, size_t size) 1609 { 1610 int bit; 1611 uint8_t byte; 1612 uint8_t crc = 0; 1613 const uint8_t poly = 0x07; 1614 1615 while(size--) 1616 for (byte = *data++, bit = NBBY-1; bit >= 0; bit--) 1617 crc = (crc << 1) ^ ((((crc >> 7) ^ (byte >> bit)) & 1) ? poly : 0); 1618 1619 return crc; 1620 } 1621 1622 CTASSERT(MVNETA_NDFSMT == MVNETA_NDFOMT); 1623 1624 void 1625 mvneta_iff(struct mvneta_softc *sc) 1626 { 1627 struct arpcom *ac = &sc->sc_ac; 1628 struct ifnet *ifp = &sc->sc_ac.ac_if; 1629 struct ether_multi *enm; 1630 struct ether_multistep step; 1631 uint32_t dfut[MVNETA_NDFUT], dfsmt[MVNETA_NDFSMT], dfomt[MVNETA_NDFOMT]; 1632 uint32_t pxc; 1633 int i; 1634 const uint8_t special[ETHER_ADDR_LEN] = {0x01,0x00,0x5e,0x00,0x00,0x00}; 1635 1636 pxc = MVNETA_READ(sc, MVNETA_PXC); 1637 pxc &= ~(MVNETA_PXC_RB | MVNETA_PXC_RBIP | MVNETA_PXC_RBARP | MVNETA_PXC_UPM); 1638 ifp->if_flags &= ~IFF_ALLMULTI; 1639 memset(dfut, 0, sizeof(dfut)); 1640 memset(dfsmt, 0, sizeof(dfsmt)); 1641 memset(dfomt, 0, sizeof(dfomt)); 1642 1643 if (ifp->if_flags & IFF_PROMISC || ac->ac_multirangecnt > 0) { 1644 ifp->if_flags |= IFF_ALLMULTI; 1645 if (ifp->if_flags & IFF_PROMISC) 1646 pxc |= MVNETA_PXC_UPM; 1647 for (i = 0; i < MVNETA_NDFSMT; i++) { 1648 dfsmt[i] = dfomt[i] = 1649 MVNETA_DF(0, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS) | 1650 MVNETA_DF(1, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS) | 1651 MVNETA_DF(2, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS) | 1652 MVNETA_DF(3, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS); 1653 } 1654 } else { 1655 ETHER_FIRST_MULTI(step, ac, enm); 1656 while (enm != NULL) { 1657 /* chip handles some IPv4 multicast specially */ 1658 if (memcmp(enm->enm_addrlo, special, 5) == 0) { 1659 i = enm->enm_addrlo[5]; 1660 dfsmt[i>>2] |= 1661 MVNETA_DF(i&3, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS); 1662 } else { 1663 i = mvneta_crc8(enm->enm_addrlo, ETHER_ADDR_LEN); 1664 dfomt[i>>2] |= 1665 MVNETA_DF(i&3, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS); 1666 } 1667 1668 ETHER_NEXT_MULTI(step, enm); 1669 } 1670 } 1671 1672 MVNETA_WRITE(sc, MVNETA_PXC, pxc); 1673 1674 /* Set Destination Address Filter Unicast Table */ 1675 i = sc->sc_enaddr[5] & 0xf; /* last nibble */ 1676 dfut[i>>2] = MVNETA_DF(i&3, MVNETA_DF_QUEUE(0) | MVNETA_DF_PASS); 1677 MVNETA_WRITE_FILTER(sc, MVNETA_DFUT, dfut, MVNETA_NDFUT); 1678 1679 /* Set Destination Address Filter Multicast Tables */ 1680 MVNETA_WRITE_FILTER(sc, MVNETA_DFSMT, dfsmt, MVNETA_NDFSMT); 1681 MVNETA_WRITE_FILTER(sc, MVNETA_DFOMT, dfomt, MVNETA_NDFOMT); 1682 } 1683 1684 struct mvneta_dmamem * 1685 mvneta_dmamem_alloc(struct mvneta_softc *sc, bus_size_t size, bus_size_t align) 1686 { 1687 struct mvneta_dmamem *mdm; 1688 int nsegs; 1689 1690 mdm = malloc(sizeof(*mdm), M_DEVBUF, M_WAITOK | M_ZERO); 1691 mdm->mdm_size = size; 1692 1693 if (bus_dmamap_create(sc->sc_dmat, size, 1, size, 0, 1694 BUS_DMA_WAITOK | BUS_DMA_ALLOCNOW, &mdm->mdm_map) != 0) 1695 goto mdmfree; 1696 1697 if (bus_dmamem_alloc(sc->sc_dmat, size, align, 0, &mdm->mdm_seg, 1, 1698 &nsegs, BUS_DMA_WAITOK) != 0) 1699 goto destroy; 1700 1701 if (bus_dmamem_map(sc->sc_dmat, &mdm->mdm_seg, nsegs, size, 1702 &mdm->mdm_kva, BUS_DMA_WAITOK|BUS_DMA_COHERENT) != 0) 1703 goto free; 1704 1705 if (bus_dmamap_load(sc->sc_dmat, mdm->mdm_map, mdm->mdm_kva, size, 1706 NULL, BUS_DMA_WAITOK) != 0) 1707 goto unmap; 1708 1709 bzero(mdm->mdm_kva, size); 1710 1711 return (mdm); 1712 1713 unmap: 1714 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, size); 1715 free: 1716 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1); 1717 destroy: 1718 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map); 1719 mdmfree: 1720 free(mdm, M_DEVBUF, 0); 1721 1722 return (NULL); 1723 } 1724 1725 void 1726 mvneta_dmamem_free(struct mvneta_softc *sc, struct mvneta_dmamem *mdm) 1727 { 1728 bus_dmamem_unmap(sc->sc_dmat, mdm->mdm_kva, mdm->mdm_size); 1729 bus_dmamem_free(sc->sc_dmat, &mdm->mdm_seg, 1); 1730 bus_dmamap_destroy(sc->sc_dmat, mdm->mdm_map); 1731 free(mdm, M_DEVBUF, 0); 1732 } 1733 1734 static inline struct mbuf * 1735 mvneta_alloc_mbuf(struct mvneta_softc *sc, bus_dmamap_t map) 1736 { 1737 struct mbuf *m = NULL; 1738 1739 m = MCLGETL(NULL, M_DONTWAIT, MCLBYTES); 1740 if (m == NULL) 1741 return (NULL); 1742 m->m_len = m->m_pkthdr.len = MCLBYTES; 1743 1744 if (bus_dmamap_load_mbuf(sc->sc_dmat, map, m, BUS_DMA_NOWAIT) != 0) { 1745 printf("%s: could not load mbuf DMA map", sc->sc_dev.dv_xname); 1746 m_freem(m); 1747 return (NULL); 1748 } 1749 1750 bus_dmamap_sync(sc->sc_dmat, map, 0, 1751 m->m_pkthdr.len, BUS_DMASYNC_PREREAD); 1752 1753 return (m); 1754 } 1755 1756 void 1757 mvneta_fill_rx_ring(struct mvneta_softc *sc) 1758 { 1759 struct mvneta_rx_desc *rxd; 1760 struct mvneta_buf *rxb; 1761 unsigned int slots, used = 0; 1762 unsigned int prod; 1763 1764 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_rxring), 1765 0, MVNETA_DMA_LEN(sc->sc_rxring), BUS_DMASYNC_POSTWRITE); 1766 1767 prod = sc->sc_rx_prod; 1768 1769 for (slots = if_rxr_get(&sc->sc_rx_ring, MVNETA_PRXSU_MAX); 1770 slots > 0; slots--) { 1771 rxb = &sc->sc_rxbuf[prod]; 1772 rxb->tb_m = mvneta_alloc_mbuf(sc, rxb->tb_map); 1773 if (rxb->tb_m == NULL) 1774 break; 1775 1776 rxd = &sc->sc_rxdesc[prod]; 1777 rxd->cmdsts = 0; 1778 rxd->bufsize = 0; 1779 rxd->bytecnt = 0; 1780 rxd->bufptr = rxb->tb_map->dm_segs[0].ds_addr; 1781 rxd->nextdescptr = 0; 1782 rxd->_padding[0] = 0; 1783 rxd->_padding[1] = 0; 1784 rxd->_padding[2] = 0; 1785 rxd->_padding[3] = 0; 1786 1787 prod = MVNETA_RX_RING_NEXT(prod); 1788 used++; 1789 } 1790 if_rxr_put(&sc->sc_rx_ring, slots); 1791 1792 sc->sc_rx_prod = prod; 1793 1794 bus_dmamap_sync(sc->sc_dmat, MVNETA_DMA_MAP(sc->sc_rxring), 1795 0, MVNETA_DMA_LEN(sc->sc_rxring), BUS_DMASYNC_PREWRITE); 1796 1797 if (used > 0) 1798 MVNETA_WRITE(sc, MVNETA_PRXSU(0), MVNETA_PRXSU_NOND(used)); 1799 } 1800 1801 #if NKSTAT > 0 1802 1803 /* this is used to sort and look up the array of kstats quickly */ 1804 enum mvneta_stat { 1805 mvneta_stat_good_octets_received, 1806 mvneta_stat_bad_octets_received, 1807 mvneta_stat_good_frames_received, 1808 mvneta_stat_mac_trans_error, 1809 mvneta_stat_bad_frames_received, 1810 mvneta_stat_broadcast_frames_received, 1811 mvneta_stat_multicast_frames_received, 1812 mvneta_stat_frames_64_octets, 1813 mvneta_stat_frames_65_to_127_octets, 1814 mvneta_stat_frames_128_to_255_octets, 1815 mvneta_stat_frames_256_to_511_octets, 1816 mvneta_stat_frames_512_to_1023_octets, 1817 mvneta_stat_frames_1024_to_max_octets, 1818 mvneta_stat_good_octets_sent, 1819 mvneta_stat_good_frames_sent, 1820 mvneta_stat_excessive_collision, 1821 mvneta_stat_multicast_frames_sent, 1822 mvneta_stat_broadcast_frames_sent, 1823 mvneta_stat_unrecog_mac_control_received, 1824 mvneta_stat_good_fc_received, 1825 mvneta_stat_bad_fc_received, 1826 mvneta_stat_undersize, 1827 mvneta_stat_fc_sent, 1828 mvneta_stat_fragments, 1829 mvneta_stat_oversize, 1830 mvneta_stat_jabber, 1831 mvneta_stat_mac_rcv_error, 1832 mvneta_stat_bad_crc, 1833 mvneta_stat_collisions, 1834 mvneta_stat_late_collisions, 1835 1836 mvneta_stat_port_discard, 1837 mvneta_stat_port_overrun, 1838 1839 mvnet_stat_count 1840 }; 1841 1842 struct mvneta_counter { 1843 const char *name; 1844 enum kstat_kv_unit unit; 1845 bus_size_t reg; 1846 }; 1847 1848 static const struct mvneta_counter mvneta_counters[] = { 1849 [mvneta_stat_good_octets_received] = 1850 { "rx good", KSTAT_KV_U_BYTES, 0x0 /* 64bit */ }, 1851 [mvneta_stat_bad_octets_received] = 1852 { "rx bad", KSTAT_KV_U_BYTES, 0x3008 }, 1853 [mvneta_stat_good_frames_received] = 1854 { "rx good", KSTAT_KV_U_PACKETS, 0x3010 }, 1855 [mvneta_stat_mac_trans_error] = 1856 { "tx mac error", KSTAT_KV_U_PACKETS, 0x300c }, 1857 [mvneta_stat_bad_frames_received] = 1858 { "rx bad", KSTAT_KV_U_PACKETS, 0x3014 }, 1859 [mvneta_stat_broadcast_frames_received] = 1860 { "rx bcast", KSTAT_KV_U_PACKETS, 0x3018 }, 1861 [mvneta_stat_multicast_frames_received] = 1862 { "rx mcast", KSTAT_KV_U_PACKETS, 0x301c }, 1863 [mvneta_stat_frames_64_octets] = 1864 { "64B", KSTAT_KV_U_PACKETS, 0x3020 }, 1865 [mvneta_stat_frames_65_to_127_octets] = 1866 { "65-127B", KSTAT_KV_U_PACKETS, 0x3024 }, 1867 [mvneta_stat_frames_128_to_255_octets] = 1868 { "128-255B", KSTAT_KV_U_PACKETS, 0x3028 }, 1869 [mvneta_stat_frames_256_to_511_octets] = 1870 { "256-511B", KSTAT_KV_U_PACKETS, 0x302c }, 1871 [mvneta_stat_frames_512_to_1023_octets] = 1872 { "512-1023B", KSTAT_KV_U_PACKETS, 0x3030 }, 1873 [mvneta_stat_frames_1024_to_max_octets] = 1874 { "1024-maxB", KSTAT_KV_U_PACKETS, 0x3034 }, 1875 [mvneta_stat_good_octets_sent] = 1876 { "tx good", KSTAT_KV_U_BYTES, 0x0 /* 64bit */ }, 1877 [mvneta_stat_good_frames_sent] = 1878 { "tx good", KSTAT_KV_U_PACKETS, 0x3040 }, 1879 [mvneta_stat_excessive_collision] = 1880 { "tx excess coll", KSTAT_KV_U_PACKETS, 0x3044 }, 1881 [mvneta_stat_multicast_frames_sent] = 1882 { "tx mcast", KSTAT_KV_U_PACKETS, 0x3048 }, 1883 [mvneta_stat_broadcast_frames_sent] = 1884 { "tx bcast", KSTAT_KV_U_PACKETS, 0x304c }, 1885 [mvneta_stat_unrecog_mac_control_received] = 1886 { "rx unknown fc", KSTAT_KV_U_PACKETS, 0x3050 }, 1887 [mvneta_stat_good_fc_received] = 1888 { "rx fc good", KSTAT_KV_U_PACKETS, 0x3058 }, 1889 [mvneta_stat_bad_fc_received] = 1890 { "rx fc bad", KSTAT_KV_U_PACKETS, 0x305c }, 1891 [mvneta_stat_undersize] = 1892 { "rx undersize", KSTAT_KV_U_PACKETS, 0x3060 }, 1893 [mvneta_stat_fc_sent] = 1894 { "tx fc", KSTAT_KV_U_PACKETS, 0x3054 }, 1895 [mvneta_stat_fragments] = 1896 { "rx fragments", KSTAT_KV_U_NONE, 0x3064 }, 1897 [mvneta_stat_oversize] = 1898 { "rx oversize", KSTAT_KV_U_PACKETS, 0x3068 }, 1899 [mvneta_stat_jabber] = 1900 { "rx jabber", KSTAT_KV_U_PACKETS, 0x306c }, 1901 [mvneta_stat_mac_rcv_error] = 1902 { "rx mac errors", KSTAT_KV_U_PACKETS, 0x3070 }, 1903 [mvneta_stat_bad_crc] = 1904 { "rx bad crc", KSTAT_KV_U_PACKETS, 0x3074 }, 1905 [mvneta_stat_collisions] = 1906 { "rx colls", KSTAT_KV_U_PACKETS, 0x3078 }, 1907 [mvneta_stat_late_collisions] = 1908 { "rx late colls", KSTAT_KV_U_PACKETS, 0x307c }, 1909 1910 [mvneta_stat_port_discard] = 1911 { "rx discard", KSTAT_KV_U_PACKETS, MVNETA_PXDFC }, 1912 [mvneta_stat_port_overrun] = 1913 { "rx overrun", KSTAT_KV_U_PACKETS, MVNETA_POFC }, 1914 }; 1915 1916 CTASSERT(nitems(mvneta_counters) == mvnet_stat_count); 1917 1918 int 1919 mvneta_kstat_read(struct kstat *ks) 1920 { 1921 struct mvneta_softc *sc = ks->ks_softc; 1922 struct kstat_kv *kvs = ks->ks_data; 1923 unsigned int i; 1924 uint32_t hi, lo; 1925 1926 for (i = 0; i < nitems(mvneta_counters); i++) { 1927 const struct mvneta_counter *c = &mvneta_counters[i]; 1928 if (c->reg == 0) 1929 continue; 1930 1931 kstat_kv_u64(&kvs[i]) += (uint64_t)MVNETA_READ(sc, c->reg); 1932 } 1933 1934 /* handle the exceptions */ 1935 1936 lo = MVNETA_READ(sc, 0x3000); 1937 hi = MVNETA_READ(sc, 0x3004); 1938 kstat_kv_u64(&kvs[mvneta_stat_good_octets_received]) += 1939 (uint64_t)hi << 32 | (uint64_t)lo; 1940 1941 lo = MVNETA_READ(sc, 0x3038); 1942 hi = MVNETA_READ(sc, 0x303c); 1943 kstat_kv_u64(&kvs[mvneta_stat_good_octets_sent]) += 1944 (uint64_t)hi << 32 | (uint64_t)lo; 1945 1946 nanouptime(&ks->ks_updated); 1947 1948 return (0); 1949 } 1950 1951 void 1952 mvneta_kstat_tick(void *arg) 1953 { 1954 struct mvneta_softc *sc = arg; 1955 1956 timeout_add_sec(&sc->sc_kstat_tick, 37); 1957 1958 if (mtx_enter_try(&sc->sc_kstat_lock)) { 1959 mvneta_kstat_read(sc->sc_kstat); 1960 mtx_leave(&sc->sc_kstat_lock); 1961 } 1962 } 1963 1964 void 1965 mvneta_kstat_attach(struct mvneta_softc *sc) 1966 { 1967 struct kstat *ks; 1968 struct kstat_kv *kvs; 1969 unsigned int i; 1970 1971 mtx_init(&sc->sc_kstat_lock, IPL_SOFTCLOCK); 1972 timeout_set(&sc->sc_kstat_tick, mvneta_kstat_tick, sc); 1973 1974 ks = kstat_create(sc->sc_dev.dv_xname, 0, "mvneta-stats", 0, 1975 KSTAT_T_KV, 0); 1976 if (ks == NULL) 1977 return; 1978 1979 kvs = mallocarray(nitems(mvneta_counters), sizeof(*kvs), 1980 M_DEVBUF, M_WAITOK|M_ZERO); 1981 for (i = 0; i < nitems(mvneta_counters); i++) { 1982 const struct mvneta_counter *c = &mvneta_counters[i]; 1983 kstat_kv_unit_init(&kvs[i], c->name, 1984 KSTAT_KV_T_COUNTER64, c->unit); 1985 } 1986 1987 ks->ks_softc = sc; 1988 ks->ks_data = kvs; 1989 ks->ks_datalen = nitems(mvneta_counters) * sizeof(*kvs); 1990 ks->ks_read = mvneta_kstat_read; 1991 kstat_set_mutex(ks, &sc->sc_kstat_lock); 1992 1993 kstat_install(ks); 1994 1995 sc->sc_kstat = ks; 1996 1997 timeout_add_sec(&sc->sc_kstat_tick, 37); 1998 } 1999 2000 #endif 2001