Ejemplo n.º 1
0
static int xfp_phy_init(struct efx_nic *efx)
{
	struct xfp_phy_data *phy_data;
	u32 devid = mdio_clause45_read_id(efx, MDIO_MMD_PHYXS);
	int rc;

	phy_data = kzalloc(sizeof(struct xfp_phy_data), GFP_KERNEL);
	if (!phy_data)
		return -ENOMEM;
	efx->phy_data = phy_data;

	EFX_INFO(efx, "XFP: PHY ID reg %x (OUI %x model %x revision"
		 " %x)\n", devid, MDIO_ID_OUI(devid), MDIO_ID_MODEL(devid),
		 MDIO_ID_REV(devid));

	phy_data->phy_mode = efx->phy_mode;

	rc = xfp_reset_phy(efx);

	EFX_INFO(efx, "XFP: PHY init %s.\n",
		 rc ? "failed" : "successful");
	if (rc < 0)
		goto fail;

	return 0;

 fail:
	kfree(efx->phy_data);
	efx->phy_data = NULL;
	return rc;
}
Ejemplo n.º 2
0
/* Initialisation entry point for this PHY driver */
static int txc43128_phy_init(struct efx_nic *efx)
{
	u32 devid;
	int rc;

	devid = efx_mdio_read_id(efx, MDIO_MMD_PHYXS);
	EFX_INFO(efx, ""TXCNAME ": PHY ID reg %x (OUI %06x model %02x "
		 "revision %x)\n", devid, efx_mdio_id_oui(devid),
		 efx_mdio_id_model(devid), efx_mdio_id_rev(devid));

	EFX_INFO(efx, ""TXCNAME ": Silicon ID %x\n",
		 efx_mdio_read(efx, MDIO_MMD_PHYXS, TXC_GLRGS_SLID) &
		 TXC_GLRGS_SLID_MASK);

	rc = txc_reset_phy(efx);
	if (rc < 0)
		return rc;

	rc = txc_bist(efx);
	if (rc < 0)
		return rc;

	txc_apply_defaults(efx);

	return 0;
}
Ejemplo n.º 3
0
static void sfn4111t_fini(struct efx_nic *efx)
{
	EFX_INFO(efx, "%s\n", __func__);

	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
	i2c_unregister_device(falcon_board(efx)->hwmon_client);
}
Ejemplo n.º 4
0
static void sfe4001_fini(struct efx_nic *efx)
{
	struct falcon_board *board = falcon_board(efx);

	EFX_INFO(efx, "%s\n", __func__);

	device_remove_file(&efx->pci_dev->dev, &dev_attr_phy_flash_cfg);
	sfe4001_poweroff(efx);
	i2c_unregister_device(board->ioexp_client);
	i2c_unregister_device(board->hwmon_client);
}
Ejemplo n.º 5
0
/* This board uses an I2C expander to provider power to the PHY, which needs to
 * be turned on before the PHY can be used.
 * Context: Process context, rtnl lock held
 */
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.º 6
0
static void txc_reset_logic_mmd(struct efx_nic *efx, int mmd)
{
	int val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD);
	int tries = 50;
	val |= (1 << TXC_GLCMD_LMTSWRST_LBN);
	efx_mdio_write(efx, mmd, TXC_GLRGS_GLCMD, val);
	while (tries--) {
		val = efx_mdio_read(efx, mmd, TXC_GLRGS_GLCMD);
		if (!(val & (1 << TXC_GLCMD_LMTSWRST_LBN)))
			break;
		udelay(1);
	}
	if (!tries)
		EFX_INFO(efx, TXCNAME " Logic reset timed out!\n");
}
Ejemplo n.º 7
0
Archivo: boards.c Proyecto: 274914765/C
int efx_set_board_info(struct efx_nic *efx, u16 revision_info)
{
    int rc = 0;
    struct efx_board_data *data;

    if (BOARD_TYPE(revision_info) >= EFX_BOARD_MAX) {
        EFX_ERR(efx, "squashing unknown board type %d\n",
            BOARD_TYPE(revision_info));
        revision_info = 0;
    }

    if (BOARD_TYPE(revision_info) == 0) {
        efx->board_info.major = 0;
        efx->board_info.minor = 0;
        /* For early boards that don't have revision info. there is
         * only 1 board for each PHY type, so we can work it out, with
         * the exception of the PHY-less boards. */
        switch (efx->phy_type) {
        case PHY_TYPE_10XPRESS:
            efx->board_info.type = EFX_BOARD_SFE4001;
            break;
        case PHY_TYPE_XFP:
            efx->board_info.type = EFX_BOARD_SFE4002;
            break;
        default:
            efx->board_info.type = 0;
            break;
        }
    } else {
        efx->board_info.type = BOARD_TYPE(revision_info);
        efx->board_info.major = BOARD_MAJOR(revision_info);
        efx->board_info.minor = BOARD_MINOR(revision_info);
    }

    data = &board_data[efx->board_info.type];

    /* Report the board model number or generic type for recognisable
     * boards. */
    if (efx->board_info.type != 0)
        EFX_INFO(efx, "board is %s rev %c%d\n",
             (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
             ? data->ref_model : data->gen_type,
             'A' + efx->board_info.major, efx->board_info.minor);

    efx->board_info.init = data->init;

    return rc;
}
Ejemplo n.º 8
0
static bool falcon_xgmii_status(struct efx_nic *efx)
{
	efx_oword_t reg;

	if (falcon_rev(efx) < FALCON_REV_B0)
		return true;

	/* The ISR latches, so clear it and re-read */
	falcon_read(efx, &reg, XM_MGT_INT_REG_B0);
	falcon_read(efx, &reg, XM_MGT_INT_REG_B0);

	if (EFX_OWORD_FIELD(reg, XM_LCLFLT) ||
	    EFX_OWORD_FIELD(reg, XM_RMTFLT)) {
		EFX_INFO(efx, "MGT_INT: "EFX_DWORD_FMT"\n", EFX_DWORD_VAL(reg));
		return false;
	}

	return true;
}
Ejemplo n.º 9
0
void falcon_probe_board(struct efx_nic *efx, u16 revision_info)
{
	struct falcon_board *board = falcon_board(efx);
	u8 type_id = FALCON_BOARD_TYPE(revision_info);
	int i;

	board->major = FALCON_BOARD_MAJOR(revision_info);
	board->minor = FALCON_BOARD_MINOR(revision_info);

	for (i = 0; i < ARRAY_SIZE(board_types); i++)
		if (board_types[i].id == type_id)
			board->type = &board_types[i];

	if (board->type) {
		EFX_INFO(efx, "board is %s rev %c%d\n",
			 (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
			 ? board->type->ref_model : board->type->gen_type,
			 'A' + board->major, board->minor);
	} else {
		EFX_ERR(efx, "unknown board type %d\n", type_id);
		board->type = &falcon_dummy_board;
	}
}
Ejemplo n.º 10
0
void efx_set_board_info(struct efx_nic *efx, u16 revision_info)
{
	struct efx_board_data *data = NULL;
	int i;

	efx->board_info.type = BOARD_TYPE(revision_info);
	efx->board_info.major = BOARD_MAJOR(revision_info);
	efx->board_info.minor = BOARD_MINOR(revision_info);

	for (i = 0; i < ARRAY_SIZE(board_data); i++)
		if (board_data[i].type == efx->board_info.type)
			data = &board_data[i];

	if (data) {
		EFX_INFO(efx, "board is %s rev %c%d\n",
			 (efx->pci_dev->subsystem_vendor == EFX_VENDID_SFC)
			 ? data->ref_model : data->gen_type,
			 'A' + efx->board_info.major, efx->board_info.minor);
		efx->board_info.init = data->init;
	} else {
		EFX_ERR(efx, "unknown board type %d\n", efx->board_info.type);
	}
}
Ejemplo n.º 11
0
static int sfe4001_poweron(struct efx_nic *efx)
{
	struct i2c_client *ioexp_client = falcon_board(efx)->ioexp_client;
	struct i2c_client *hwmon_client = falcon_board(efx)->hwmon_client;
	unsigned int i, j;
	int rc;
	u8 out;

	/* Clear any previous over-temperature alert */
	rc = i2c_smbus_read_byte_data(hwmon_client, MAX664X_REG_RSL);
	if (rc < 0)
		return rc;

	/* Enable port 0 and port 1 outputs on IO expander */
	rc = i2c_smbus_write_byte_data(ioexp_client, P0_CONFIG, 0x00);
	if (rc)
		return rc;
	rc = i2c_smbus_write_byte_data(ioexp_client, P1_CONFIG,
				       0xff & ~(1 << P1_SPARE_LBN));
	if (rc)
		goto fail_on;

	/* If PHY power is on, turn it all off and wait 1 second to
	 * ensure a full reset.
	 */
	rc = i2c_smbus_read_byte_data(ioexp_client, P0_OUT);
	if (rc < 0)
		goto fail_on;
	out = 0xff & ~((0 << P0_EN_1V2_LBN) | (0 << P0_EN_2V5_LBN) |
		       (0 << P0_EN_3V3X_LBN) | (0 << P0_EN_5V_LBN) |
		       (0 << P0_EN_1V0X_LBN));
	if (rc != out) {
		EFX_INFO(efx, "power-cycling PHY\n");
		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
		if (rc)
			goto fail_on;
		schedule_timeout_uninterruptible(HZ);
	}

	for (i = 0; i < 20; ++i) {
		/* Turn on 1.2V, 2.5V, 3.3V and 5V power rails */
		out = 0xff & ~((1 << P0_EN_1V2_LBN) | (1 << P0_EN_2V5_LBN) |
			       (1 << P0_EN_3V3X_LBN) | (1 << P0_EN_5V_LBN) |
			       (1 << P0_X_TRST_LBN));
		if (efx->phy_mode & PHY_MODE_SPECIAL)
			out |= 1 << P0_EN_3V3X_LBN;

		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
		if (rc)
			goto fail_on;
		msleep(10);

		/* Turn on 1V power rail */
		out &= ~(1 << P0_EN_1V0X_LBN);
		rc = i2c_smbus_write_byte_data(ioexp_client, P0_OUT, out);
		if (rc)
			goto fail_on;

		EFX_INFO(efx, "waiting for DSP boot (attempt %d)...\n", i);

		/* In flash config mode, DSP does not turn on AFE, so
		 * just wait 1 second.
		 */
		if (efx->phy_mode & PHY_MODE_SPECIAL) {
			schedule_timeout_uninterruptible(HZ);
			return 0;
		}

		for (j = 0; j < 10; ++j) {
			msleep(100);

			/* Check DSP has asserted AFE power line */
			rc = i2c_smbus_read_byte_data(ioexp_client, P1_IN);
			if (rc < 0)
				goto fail_on;
			if (rc & (1 << P1_AFE_PWD_LBN))
				return 0;
		}
	}

	EFX_INFO(efx, "timed out waiting for DSP boot\n");
	rc = -ETIMEDOUT;
fail_on:
	sfe4001_poweroff(efx);
	return rc;
}
Ejemplo n.º 12
0
/* Run a single BIST on one MMD*/
static int txc_bist_one(struct efx_nic *efx, int mmd, int test)
{
	int ctrl, bctl;
	int lane;
	int rc = 0;

	EFX_INFO(efx, "" TXCNAME ": running BIST on %s MMD\n",
		 efx_mdio_mmd_name(mmd));

	/* Set PMA to test into loopback using Mt Diablo reg as per app note */
	ctrl = efx_mdio_read(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL);
	ctrl |= (1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN);
	efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl);

	/* The BIST app. note lists these  as 3 distinct steps. */
	/* Set the BIST type */
	bctl = (test << TXC_BIST_CTRL_TYPE_LBN);
	efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl);

	/* Set the BSTEN bit in the BIST Control register to enable */
	bctl |= (1 << TXC_BIST_CTRL_ENAB_LBN);
	efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl);

	/* Set the BSTRT bit in the BIST Control register */
	efx_mdio_write(efx, mmd, TXC_BIST_CTL,
		       bctl | (1 << TXC_BIST_CTRL_STRT_LBN));

	/* Wait. */
	udelay(TXC_BIST_DURATION);

	/* Set the BSTOP bit in the BIST Control register */
	bctl |= (1 << TXC_BIST_CTRL_STOP_LBN);
	efx_mdio_write(efx, mmd, TXC_BIST_CTL, bctl);

	/* The STOP bit should go off when things have stopped */
	while (bctl & (1 << TXC_BIST_CTRL_STOP_LBN))
		bctl = efx_mdio_read(efx, mmd, TXC_BIST_CTL);

	/* Check all the error counts are 0 and all the frame counts are
	   non-zero */
	for (lane = 0; lane < 4; lane++) {
		int count = efx_mdio_read(efx, mmd, TXC_BIST_RX0ERRCNT + lane);
		if (count != 0) {
			EFX_ERR(efx, ""TXCNAME": BIST error. "
				"Lane %d had %d errs\n", lane, count);
			rc = -EIO;
		}
		count = efx_mdio_read(efx, mmd, TXC_BIST_RX0FRMCNT + lane);
		if (count == 0) {
			EFX_ERR(efx, ""TXCNAME": BIST error. "
				"Lane %d got 0 frames\n", lane);
			rc = -EIO;
		}
	}

	if (rc == 0)
		EFX_INFO(efx, ""TXCNAME": BIST pass\n");

	/* Disable BIST */
	efx_mdio_write(efx, mmd, TXC_BIST_CTL, 0);

	/* Turn off loopback */
	ctrl &= ~(1 << TXC_MTDIABLO_CTRL_PMA_LOOP_LBN);
	efx_mdio_write(efx, MDIO_MMD_PCS, TXC_MTDIABLO_CTRL, ctrl);

	return rc;
}