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.
This commit is contained in:
Juli Mallett 2010-11-30 07:14:05 +00:00
parent 5cb51b647c
commit 074a0a8d57
7 changed files with 42 additions and 62 deletions

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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;

View File

@ -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;
}

View File

@ -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);

View File

@ -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));