From 03e47472e4b5d434e97d43f2366acf7e069ecd8f Mon Sep 17 00:00:00 2001 From: jmallett Date: Tue, 30 Nov 2010 07:14:05 +0000 Subject: Run all poll requests through a single function that can either do the generic link state polling or media-specific ones, while avoidiing changing link state on interfaces that use miibus; this substantially speeds up link time on interface (re)initialization. --- sys/mips/cavium/octe/ethernet-common.c | 29 +++++++++++++++++++- sys/mips/cavium/octe/ethernet-common.h | 2 -- sys/mips/cavium/octe/ethernet-rgmii.c | 48 +++++----------------------------- sys/mips/cavium/octe/ethernet-sgmii.c | 2 -- sys/mips/cavium/octe/ethernet-xaui.c | 4 +-- sys/mips/cavium/octe/ethernet.c | 17 ++++-------- sys/mips/cavium/octe/octe.c | 4 +-- 7 files changed, 43 insertions(+), 63 deletions(-) diff --git a/sys/mips/cavium/octe/ethernet-common.c b/sys/mips/cavium/octe/ethernet-common.c index 3526e80..aa66b8f 100644 --- a/sys/mips/cavium/octe/ethernet-common.c +++ b/sys/mips/cavium/octe/ethernet-common.c @@ -188,7 +188,10 @@ int cvm_oct_common_open(struct ifnet *ifp) gmx_cfg.s.en = 1; cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - if (!octeon_is_simulation()) { + /* + * Set the link state unless we are using MII. + */ + if (!octeon_is_simulation() && priv->miibus == NULL) { link_info = cvmx_helper_link_get(priv->port); if (!link_info.s.link_up) if_link_state_change(ifp, LINK_STATE_DOWN); @@ -224,6 +227,30 @@ void cvm_oct_common_poll(struct ifnet *ifp) cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; cvmx_helper_link_info_t link_info; + /* + * If this is a simulation, do nothing. + */ + if (octeon_is_simulation()) + return; + + /* + * If there is a device-specific poll method, use it. + */ + if (priv->poll != NULL) { + priv->poll(ifp); + return; + } + + /* + * If an MII bus is attached, don't use the Simple Executive's link + * state routines. + */ + if (priv->miibus != NULL) + return; + + /* + * Use the Simple Executive's link state routines. + */ link_info = cvmx_helper_link_get(priv->port); if (link_info.u64 == priv->link_info) return; diff --git a/sys/mips/cavium/octe/ethernet-common.h b/sys/mips/cavium/octe/ethernet-common.h index 2fd2f83..7c0eea7 100644 --- a/sys/mips/cavium/octe/ethernet-common.h +++ b/sys/mips/cavium/octe/ethernet-common.h @@ -48,8 +48,6 @@ void cvm_oct_cleanup_module(void); int cvm_oct_rgmii_init(struct ifnet *ifp); void cvm_oct_rgmii_uninit(struct ifnet *ifp); int cvm_oct_sgmii_init(struct ifnet *ifp); -void cvm_oct_sgmii_uninit(struct ifnet *ifp); int cvm_oct_spi_init(struct ifnet *ifp); void cvm_oct_spi_uninit(struct ifnet *ifp); int cvm_oct_xaui_init(struct ifnet *ifp); -void cvm_oct_xaui_uninit(struct ifnet *ifp); diff --git a/sys/mips/cavium/octe/ethernet-rgmii.c b/sys/mips/cavium/octe/ethernet-rgmii.c index ac55de8..4273a6f 100644 --- a/sys/mips/cavium/octe/ethernet-rgmii.c +++ b/sys/mips/cavium/octe/ethernet-rgmii.c @@ -134,9 +134,11 @@ static void cvm_oct_rgmii_poll(struct ifnet *ifp) cvmx_write_csr(CVMX_GMXX_RXX_INT_REG(index, interface), gmxx_rxx_int_reg.u64); } - link_info = cvmx_helper_link_autoconf(priv->port); - priv->link_info = link_info.u64; - priv->need_link_update = 1; + if (priv->miibus == NULL) { + link_info = cvmx_helper_link_autoconf(priv->port); + priv->link_info = link_info.u64; + priv->need_link_update = 1; + } mtx_unlock_spin(&global_register_lock); } @@ -206,42 +208,6 @@ static int cvm_oct_rgmii_rml_interrupt(void *dev_id) } -static int cvm_oct_rgmii_open(struct ifnet *ifp) -{ - cvmx_gmxx_prtx_cfg_t gmx_cfg; - cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - cvmx_helper_link_info_t link_info; - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 1; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - - if (!octeon_is_simulation()) { - link_info = cvmx_helper_link_get(priv->port); - if (!link_info.s.link_up) - if_link_state_change(ifp, LINK_STATE_DOWN); - else - if_link_state_change(ifp, LINK_STATE_UP); - } - - return 0; -} - -static int cvm_oct_rgmii_stop(struct ifnet *ifp) -{ - cvmx_gmxx_prtx_cfg_t gmx_cfg; - cvm_oct_private_t *priv = (cvm_oct_private_t *)ifp->if_softc; - int interface = INTERFACE(priv->port); - int index = INDEX(priv->port); - - gmx_cfg.u64 = cvmx_read_csr(CVMX_GMXX_PRTX_CFG(index, interface)); - gmx_cfg.s.en = 0; - cvmx_write_csr(CVMX_GMXX_PRTX_CFG(index, interface), gmx_cfg.u64); - return 0; -} - int cvm_oct_rgmii_init(struct ifnet *ifp) { struct octebus_softc *sc; @@ -250,8 +216,8 @@ int cvm_oct_rgmii_init(struct ifnet *ifp) int rid; cvm_oct_common_init(ifp); - priv->open = cvm_oct_rgmii_open; - priv->stop = cvm_oct_rgmii_stop; + priv->open = cvm_oct_common_open; + priv->stop = cvm_oct_common_stop; priv->stop(ifp); /* Due to GMX errata in CN3XXX series chips, it is necessary to take the diff --git a/sys/mips/cavium/octe/ethernet-sgmii.c b/sys/mips/cavium/octe/ethernet-sgmii.c index 5f9210a..834df45 100644 --- a/sys/mips/cavium/octe/ethernet-sgmii.c +++ b/sys/mips/cavium/octe/ethernet-sgmii.c @@ -53,8 +53,6 @@ int cvm_oct_sgmii_init(struct ifnet *ifp) priv->open = cvm_oct_common_open; priv->stop = cvm_oct_common_stop; priv->stop(ifp); - if (!octeon_is_simulation()) - priv->poll = cvm_oct_common_poll; /* FIXME: Need autoneg logic */ return 0; diff --git a/sys/mips/cavium/octe/ethernet-xaui.c b/sys/mips/cavium/octe/ethernet-xaui.c index 6ac1f0c..212cd2e 100644 --- a/sys/mips/cavium/octe/ethernet-xaui.c +++ b/sys/mips/cavium/octe/ethernet-xaui.c @@ -53,8 +53,6 @@ int cvm_oct_xaui_init(struct ifnet *ifp) priv->open = cvm_oct_common_open; priv->stop = cvm_oct_common_stop; priv->stop(ifp); - if (!octeon_is_simulation()) - priv->poll = cvm_oct_common_poll; - return 0; + return 0; } diff --git a/sys/mips/cavium/octe/ethernet.c b/sys/mips/cavium/octe/ethernet.c index 812fc01..2717d2c 100644 --- a/sys/mips/cavium/octe/ethernet.c +++ b/sys/mips/cavium/octe/ethernet.c @@ -136,18 +136,11 @@ static void cvm_do_timer(void *arg) int queues_per_port; int qos; cvm_oct_private_t *priv = (cvm_oct_private_t *)cvm_oct_device[port]->if_softc; - if (priv->poll) - { - /* skip polling if we don't get the lock */ - if (MDIO_TRYLOCK()) { - priv->poll(cvm_oct_device[port]); - MDIO_UNLOCK(); - - if (priv->need_link_update) { - updated++; - taskqueue_enqueue(cvm_oct_link_taskq, &priv->link_task); - } - } + + cvm_oct_common_poll(priv->ifp); + if (priv->need_link_update) { + updated++; + taskqueue_enqueue(cvm_oct_link_taskq, &priv->link_task); } queues_per_port = cvmx_pko_get_num_queues(port); diff --git a/sys/mips/cavium/octe/octe.c b/sys/mips/cavium/octe/octe.c index eba39c3..9f275d1 100644 --- a/sys/mips/cavium/octe/octe.c +++ b/sys/mips/cavium/octe/octe.c @@ -281,8 +281,8 @@ octe_init(void *arg) cvm_oct_common_set_mac_address(ifp, IF_LLADDR(ifp)); - if (priv->poll != NULL) - priv->poll(ifp); + cvm_oct_common_poll(ifp); + if (priv->miibus != NULL) mii_mediachg(device_get_softc(priv->miibus)); -- cgit v1.1