static int falcon_reconfigure_port(struct efx_nic *efx) { int rc; WARN_ON(efx_nic_rev(efx) > EFX_REV_FALCON_B0); /* Poll the PHY link state *before* reconfiguring it. This means we * will pick up the correct speed (in loopback) to select the correct * MAC. */ if (LOOPBACK_INTERNAL(efx)) falcon_loopback_link_poll(efx); else efx->phy_op->poll(efx); falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); efx->phy_op->reconfigure(efx); rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); /* Synchronise efx->link_state with the kernel */ efx_link_status_changed(efx); return 0; }
static int falcon_reconfigure_port(struct efx_nic *efx) { int rc; WARN_ON(efx_nic_rev(efx) > EFX_REV_FALCON_B0); if (LOOPBACK_INTERNAL(efx)) falcon_loopback_link_poll(efx); else efx->phy_op->poll(efx); falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); efx->phy_op->reconfigure(efx); rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); efx_link_status_changed(efx); return 0; }
/* Perform a "special software reset" on the PHY. The caller is * responsible for saving and restoring the PHY hardware registers * properly, and masking/unmasking LASI */ static int tenxpress_special_reset(struct efx_nic *efx) { int rc, reg; /* The XGMAC clock is driven from the SFX7101 312MHz clock, so * a special software reset can glitch the XGMAC sufficiently for stats * requests to fail. */ falcon_stop_nic_stats(efx); /* Initiate reset */ reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); reg |= (1 << PMA_PMD_EXT_SSR_LBN); efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); mdelay(200); /* Wait for the blocks to come out of reset */ rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) goto out; /* Try and reconfigure the device */ rc = tenxpress_init(efx); if (rc < 0) goto out; /* Wait for the XGXS state machine to churn */ mdelay(10); out: falcon_start_nic_stats(efx); return rc; }
static ssize_t set_phy_flash_cfg(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) { struct efx_nic *efx = pci_get_drvdata(to_pci_dev(dev)); enum efx_phy_mode old_mode, new_mode; int err; rtnl_lock(); old_mode = efx->phy_mode; if (count == 0 || *buf == '0') new_mode = old_mode & ~PHY_MODE_SPECIAL; else new_mode = PHY_MODE_SPECIAL; if (old_mode == new_mode) { err = 0; } else if (efx->state != STATE_RUNNING || netif_running(efx->net_dev)) { err = -EBUSY; } else { /* Reset the PHY, reconfigure the MAC and enable/disable * MAC stats accordingly. */ efx->phy_mode = new_mode; if (new_mode & PHY_MODE_SPECIAL) falcon_stop_nic_stats(efx); err = sfe4001_poweron(efx); if (!err) err = efx_reconfigure_port(efx); if (!(new_mode & PHY_MODE_SPECIAL)) falcon_start_nic_stats(efx); } rtnl_unlock(); return err ? err : count; }
static int tenxpress_special_reset(struct efx_nic *efx) { int rc, reg; falcon_stop_nic_stats(efx); reg = efx_mdio_read(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG); reg |= (1 << PMA_PMD_EXT_SSR_LBN); efx_mdio_write(efx, MDIO_MMD_PMAPMD, PMA_PMD_XCONTROL_REG, reg); mdelay(200); rc = efx_mdio_wait_reset_mmds(efx, TENXPRESS_REQUIRED_DEVS); if (rc < 0) goto out; rc = tenxpress_init(efx); if (rc < 0) goto out; mdelay(10); out: falcon_start_nic_stats(efx); return rc; }
static void falcon_monitor(struct efx_nic *efx) { bool link_changed; int rc; BUG_ON(!mutex_is_locked(&efx->mac_lock)); rc = falcon_board(efx)->type->monitor(efx); if (rc) { netif_err(efx, hw, efx->net_dev, "Board sensor %s; shutting down PHY\n", (rc == -ERANGE) ? "reported fault" : "failed"); efx->phy_mode |= PHY_MODE_LOW_POWER; rc = __efx_reconfigure_port(efx); WARN_ON(rc); } if (LOOPBACK_INTERNAL(efx)) link_changed = falcon_loopback_link_poll(efx); else link_changed = efx->phy_op->poll(efx); if (link_changed) { falcon_stop_nic_stats(efx); falcon_deconfigure_mac_wrapper(efx); falcon_reset_macs(efx); rc = falcon_reconfigure_xmac(efx); BUG_ON(rc); falcon_start_nic_stats(efx); efx_link_status_changed(efx); } falcon_poll_xmac(efx); }
/* Try to bring up the Falcon side of the Falcon-Phy XAUI link */ static bool falcon_xmac_link_ok_retry(struct efx_nic *efx, int tries) { bool mac_up = falcon_xmac_link_ok(efx); if (LOOPBACK_MASK(efx) & LOOPBACKS_EXTERNAL(efx) & LOOPBACKS_WS || efx_phy_mode_disabled(efx->phy_mode)) /* XAUI link is expected to be down */ return mac_up; falcon_stop_nic_stats(efx); while (!mac_up && tries) { EFX_LOG(efx, "bashing xaui\n"); falcon_reset_xaui(efx); udelay(200); mac_up = falcon_xmac_link_ok(efx); --tries; } falcon_start_nic_stats(efx); return mac_up; }