Ejemplo n.º 1
0
static int sfe4001_init(struct efx_nic *efx)
{
    struct falcon_board *board = falcon_board(efx);
    int rc;

#if defined(CONFIG_SENSORS_LM90) || defined(CONFIG_SENSORS_LM90_MODULE)
    board->hwmon_client =
        i2c_new_device(&board->i2c_adap, &sfe4001_hwmon_info);
#else
    board->hwmon_client =
        i2c_new_dummy(&board->i2c_adap, sfe4001_hwmon_info.addr);
#endif
    if (!board->hwmon_client)
        return -EIO;

    /* Raise board/PHY high limit from 85 to 90 degrees Celsius */
    rc = i2c_smbus_write_byte_data(board->hwmon_client,
                                   MAX664X_REG_WLHO, 90);
    if (rc)
        goto fail_hwmon;

    board->ioexp_client = i2c_new_dummy(&board->i2c_adap, PCA9539);
    if (!board->ioexp_client) {
        rc = -EIO;
        goto fail_hwmon;
    }

    if (efx->phy_mode & PHY_MODE_SPECIAL) {
        /* PHY won't generate a 156.25 MHz clock and MAC stats fetch
         * will fail. */
        falcon_stop_nic_stats(efx);
    }
    rc = sfe4001_poweron(efx);
    if (rc)
        goto fail_ioexp;

    rc = device_create_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
    if (rc)
        goto fail_on;

    EFX_INFO(efx, "PHY is powered on\n");
    return 0;

fail_on:
    sfe4001_poweroff(efx);
fail_ioexp:
    i2c_unregister_device(board->ioexp_client);
fail_hwmon:
    i2c_unregister_device(board->hwmon_client);
    return rc;
}
Ejemplo n.º 2
0
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);
		if (falcon_board(efx)->type->id == FALCON_BOARD_SFE4001)
			err = sfe4001_poweron(efx);
		else
			err = sfn4111t_reset(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;
}
Ejemplo n.º 3
0
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;
}