Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ceb5f13b authored by Carolyn Wyborny's avatar Carolyn Wyborny Committed by Jeff Kirsher
Browse files

igb: Add support for i354 devices



This patch adds base support for new i354 devices.  Loopback test is
unsupported for this release.

Signed-off-by: default avatarCarolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 70ea4783
Loading
Loading
Loading
Loading
+119 −3
Original line number Original line Diff line number Diff line
@@ -100,6 +100,7 @@ static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw)
		break;
		break;
	case e1000_82580:
	case e1000_82580:
	case e1000_i350:
	case e1000_i350:
	case e1000_i354:
	case e1000_i210:
	case e1000_i210:
	case e1000_i211:
	case e1000_i211:
		reg = rd32(E1000_MDICNFG);
		reg = rd32(E1000_MDICNFG);
@@ -149,6 +150,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
		switch (hw->mac.type) {
		switch (hw->mac.type) {
		case e1000_82580:
		case e1000_82580:
		case e1000_i350:
		case e1000_i350:
		case e1000_i354:
			phy->ops.read_reg = igb_read_phy_reg_82580;
			phy->ops.read_reg = igb_read_phy_reg_82580;
			phy->ops.write_reg = igb_write_phy_reg_82580;
			phy->ops.write_reg = igb_write_phy_reg_82580;
			break;
			break;
@@ -174,13 +176,14 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)


	/* Verify phy id and set remaining function pointers */
	/* Verify phy id and set remaining function pointers */
	switch (phy->id) {
	switch (phy->id) {
	case M88E1545_E_PHY_ID:
	case I347AT4_E_PHY_ID:
	case I347AT4_E_PHY_ID:
	case M88E1112_E_PHY_ID:
	case M88E1112_E_PHY_ID:
	case M88E1111_I_PHY_ID:
	case M88E1111_I_PHY_ID:
		phy->type		= e1000_phy_m88;
		phy->type		= e1000_phy_m88;
		phy->ops.check_polarity	= igb_check_polarity_m88;
		phy->ops.get_phy_info	= igb_get_phy_info_m88;
		phy->ops.get_phy_info	= igb_get_phy_info_m88;
		if (phy->id == I347AT4_E_PHY_ID ||
		if (phy->id != M88E1111_I_PHY_ID)
		    phy->id == M88E1112_E_PHY_ID)
			phy->ops.get_cable_length =
			phy->ops.get_cable_length =
					 igb_get_cable_length_m88_gen2;
					 igb_get_cable_length_m88_gen2;
		else
		else
@@ -287,6 +290,7 @@ static s32 igb_init_nvm_params_82575(struct e1000_hw *hw)
			nvm->ops.read = igb_read_nvm_spi;
			nvm->ops.read = igb_read_nvm_spi;
		nvm->ops.write = igb_write_nvm_spi;
		nvm->ops.write = igb_write_nvm_spi;
		break;
		break;
	case e1000_i354:
	case e1000_i350:
	case e1000_i350:
		nvm->ops.validate = igb_validate_nvm_checksum_i350;
		nvm->ops.validate = igb_validate_nvm_checksum_i350;
		nvm->ops.update = igb_update_nvm_checksum_i350;
		nvm->ops.update = igb_update_nvm_checksum_i350;
@@ -352,6 +356,7 @@ static s32 igb_init_mac_params_82575(struct e1000_hw *hw)
		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
		mac->rar_entry_count = E1000_RAR_ENTRIES_82580;
		break;
		break;
	case e1000_i350:
	case e1000_i350:
	case e1000_i354:
		mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
		mac->rar_entry_count = E1000_RAR_ENTRIES_I350;
		break;
		break;
	default:
	default:
@@ -445,6 +450,11 @@ static s32 igb_get_invariants_82575(struct e1000_hw *hw)
	case E1000_DEV_ID_I211_COPPER:
	case E1000_DEV_ID_I211_COPPER:
		mac->type = e1000_i211;
		mac->type = e1000_i211;
		break;
		break;
	case E1000_DEV_ID_I354_BACKPLANE_1GBPS:
	case E1000_DEV_ID_I354_SGMII:
	case E1000_DEV_ID_I354_BACKPLANE_2_5GBPS:
		mac->type = e1000_i354;
		break;
	default:
	default:
		return -E1000_ERR_MAC_INIT;
		return -E1000_ERR_MAC_INIT;
		break;
		break;
@@ -642,6 +652,7 @@ static s32 igb_get_phy_id_82575(struct e1000_hw *hw)
			break;
			break;
		case e1000_82580:
		case e1000_82580:
		case e1000_i350:
		case e1000_i350:
		case e1000_i354:
		case e1000_i210:
		case e1000_i210:
		case e1000_i211:
		case e1000_i211:
			mdic = rd32(E1000_MDICNFG);
			mdic = rd32(E1000_MDICNFG);
@@ -1272,7 +1283,7 @@ static s32 igb_init_hw_82575(struct e1000_hw *hw)


	/* Disabling VLAN filtering */
	/* Disabling VLAN filtering */
	hw_dbg("Initializing the IEEE VLAN\n");
	hw_dbg("Initializing the IEEE VLAN\n");
	if (hw->mac.type == e1000_i350)
	if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
		igb_clear_vfta_i350(hw);
		igb_clear_vfta_i350(hw);
	else
	else
		igb_clear_vfta(hw);
		igb_clear_vfta(hw);
@@ -1348,6 +1359,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
		switch (hw->phy.id) {
		switch (hw->phy.id) {
		case I347AT4_E_PHY_ID:
		case I347AT4_E_PHY_ID:
		case M88E1112_E_PHY_ID:
		case M88E1112_E_PHY_ID:
		case M88E1545_E_PHY_ID:
		case I210_I_PHY_ID:
		case I210_I_PHY_ID:
			ret_val = igb_copper_link_setup_m88_gen2(hw);
			ret_val = igb_copper_link_setup_m88_gen2(hw);
			break;
			break;
@@ -1804,6 +1816,7 @@ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
		reg_offset = E1000_DTXSWC;
		reg_offset = E1000_DTXSWC;
		break;
		break;
	case e1000_i350:
	case e1000_i350:
	case e1000_i354:
		reg_offset = E1000_TXSWC;
		reg_offset = E1000_TXSWC;
		break;
		break;
	default:
	default:
@@ -1845,6 +1858,7 @@ void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
			dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
		wr32(E1000_DTXSWC, dtxswc);
		wr32(E1000_DTXSWC, dtxswc);
		break;
		break;
	case e1000_i354:
	case e1000_i350:
	case e1000_i350:
		dtxswc = rd32(E1000_TXSWC);
		dtxswc = rd32(E1000_TXSWC);
		if (enable)
		if (enable)
@@ -2365,6 +2379,108 @@ s32 igb_set_eee_i350(struct e1000_hw *hw)
	return ret_val;
	return ret_val;
}
}


/**
 *  igb_set_eee_i354 - Enable/disable EEE support
 *  @hw: pointer to the HW structure
 *
 *  Enable/disable EEE legacy mode based on setting in dev_spec structure.
 *
 **/
s32 igb_set_eee_i354(struct e1000_hw *hw)
{
	struct e1000_phy_info *phy = &hw->phy;
	s32 ret_val = 0;
	u16 phy_data;

	if ((hw->phy.media_type != e1000_media_type_copper) ||
	    (phy->id != M88E1545_E_PHY_ID))
		goto out;

	if (!hw->dev_spec._82575.eee_disable) {
		/* Switch to PHY page 18. */
		ret_val = phy->ops.write_reg(hw, E1000_M88E1545_PAGE_ADDR, 18);
		if (ret_val)
			goto out;

		ret_val = phy->ops.read_reg(hw, E1000_M88E1545_EEE_CTRL_1,
					    &phy_data);
		if (ret_val)
			goto out;

		phy_data |= E1000_M88E1545_EEE_CTRL_1_MS;
		ret_val = phy->ops.write_reg(hw, E1000_M88E1545_EEE_CTRL_1,
					     phy_data);
		if (ret_val)
			goto out;

		/* Return the PHY to page 0. */
		ret_val = phy->ops.write_reg(hw, E1000_M88E1545_PAGE_ADDR, 0);
		if (ret_val)
			goto out;

		/* Turn on EEE advertisement. */
		ret_val = igb_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
					     E1000_EEE_ADV_DEV_I354,
					     &phy_data);
		if (ret_val)
			goto out;

		phy_data |= E1000_EEE_ADV_100_SUPPORTED |
			    E1000_EEE_ADV_1000_SUPPORTED;
		ret_val = igb_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
						E1000_EEE_ADV_DEV_I354,
						phy_data);
	} else {
		/* Turn off EEE advertisement. */
		ret_val = igb_read_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
					     E1000_EEE_ADV_DEV_I354,
					     &phy_data);
		if (ret_val)
			goto out;

		phy_data &= ~(E1000_EEE_ADV_100_SUPPORTED |
			      E1000_EEE_ADV_1000_SUPPORTED);
		ret_val = igb_write_xmdio_reg(hw, E1000_EEE_ADV_ADDR_I354,
					      E1000_EEE_ADV_DEV_I354,
					      phy_data);
	}

out:
	return ret_val;
}

/**
 *  igb_get_eee_status_i354 - Get EEE status
 *  @hw: pointer to the HW structure
 *  @status: EEE status
 *
 *  Get EEE status by guessing based on whether Tx or Rx LPI indications have
 *  been received.
 **/
s32 igb_get_eee_status_i354(struct e1000_hw *hw, bool *status)
{
	struct e1000_phy_info *phy = &hw->phy;
	s32 ret_val = 0;
	u16 phy_data;

	/* Check if EEE is supported on this device. */
	if ((hw->phy.media_type != e1000_media_type_copper) ||
	    (phy->id != M88E1545_E_PHY_ID))
		goto out;

	ret_val = igb_read_xmdio_reg(hw, E1000_PCS_STATUS_ADDR_I354,
				     E1000_PCS_STATUS_DEV_I354,
				     &phy_data);
	if (ret_val)
		goto out;

	*status = phy_data & (E1000_PCS_STATUS_TX_LPI_RCVD |
			      E1000_PCS_STATUS_RX_LPI_RCVD) ? true : false;

out:
	return ret_val;
}

static const u8 e1000_emc_temp_data[4] = {
static const u8 e1000_emc_temp_data[4] = {
	E1000_EMC_INTERNAL_DATA,
	E1000_EMC_INTERNAL_DATA,
	E1000_EMC_DIODE1_DATA,
	E1000_EMC_DIODE1_DATA,
+1 −0
Original line number Original line Diff line number Diff line
@@ -265,6 +265,7 @@ void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
u16 igb_rxpbs_adjust_82580(u32 data);
u16 igb_rxpbs_adjust_82580(u32 data);
s32 igb_read_emi_reg(struct e1000_hw *, u16 addr, u16 *data);
s32 igb_read_emi_reg(struct e1000_hw *, u16 addr, u16 *data);
s32 igb_set_eee_i350(struct e1000_hw *);
s32 igb_set_eee_i350(struct e1000_hw *);
s32 igb_set_eee_i354(struct e1000_hw *);
s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *);
s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *);
s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw);
s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw);


+16 −0
Original line number Original line Diff line number Diff line
@@ -236,11 +236,14 @@
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
/* BMC external code execution disabled */
/* BMC external code execution disabled */


#define E1000_STATUS_2P5_SKU		0x00001000 /* Val of 2.5GBE SKU strap */
#define E1000_STATUS_2P5_SKU_OVER	0x00002000 /* Val of 2.5GBE SKU Over */
/* Constants used to intrepret the masked PCI-X bus speed. */
/* Constants used to intrepret the masked PCI-X bus speed. */


#define SPEED_10    10
#define SPEED_10    10
#define SPEED_100   100
#define SPEED_100   100
#define SPEED_1000  1000
#define SPEED_1000  1000
#define SPEED_2500  2500
#define HALF_DUPLEX 1
#define HALF_DUPLEX 1
#define FULL_DUPLEX 2
#define FULL_DUPLEX 2


@@ -768,6 +771,7 @@
#define I350_I_PHY_ID        0x015403B0
#define I350_I_PHY_ID        0x015403B0
#define M88_VENDOR           0x0141
#define M88_VENDOR           0x0141
#define I210_I_PHY_ID        0x01410C00
#define I210_I_PHY_ID        0x01410C00
#define M88E1545_E_PHY_ID    0x01410EA0


/* M88E1000 Specific Registers */
/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
#define M88E1000_PHY_SPEC_CTRL     0x10  /* PHY Specific Control Register */
@@ -889,6 +893,18 @@
#define E1000_EEE_LP_ADV_DEV_I210    7           /* EEE LP Adv Device */
#define E1000_EEE_LP_ADV_DEV_I210    7           /* EEE LP Adv Device */
#define E1000_EEE_LP_ADV_ADDR_I210   61          /* EEE LP Adv Register */
#define E1000_EEE_LP_ADV_ADDR_I210   61          /* EEE LP Adv Register */
#define E1000_MMDAC_FUNC_DATA        0x4000      /* Data, no post increment */
#define E1000_MMDAC_FUNC_DATA        0x4000      /* Data, no post increment */
#define E1000_M88E1545_PAGE_ADDR	0x16       /* Page Offset Register */
#define E1000_M88E1545_EEE_CTRL_1	0x0
#define E1000_M88E1545_EEE_CTRL_1_MS	0x0001     /* EEE Master/Slave */
#define E1000_EEE_ADV_DEV_I354		7
#define E1000_EEE_ADV_ADDR_I354		60
#define E1000_EEE_ADV_100_SUPPORTED	(1 << 1)   /* 100BaseTx EEE Supported */
#define E1000_EEE_ADV_1000_SUPPORTED	(1 << 2)   /* 1000BaseT EEE Supported */
#define E1000_PCS_STATUS_DEV_I354	3
#define E1000_PCS_STATUS_ADDR_I354	1
#define E1000_PCS_STATUS_TX_LPI_IND	0x0200     /* Tx in LPI state */
#define E1000_PCS_STATUS_RX_LPI_RCVD	0x0400
#define E1000_PCS_STATUS_TX_LPI_RCVD	0x0800


/* SerDes Control */
/* SerDes Control */
#define E1000_GEN_CTL_READY             0x80000000
#define E1000_GEN_CTL_READY             0x80000000
+4 −0
Original line number Original line Diff line number Diff line
@@ -70,6 +70,9 @@ struct e1000_hw;
#define E1000_DEV_ID_I210_SERDES		0x1537
#define E1000_DEV_ID_I210_SERDES		0x1537
#define E1000_DEV_ID_I210_SGMII			0x1538
#define E1000_DEV_ID_I210_SGMII			0x1538
#define E1000_DEV_ID_I211_COPPER		0x1539
#define E1000_DEV_ID_I211_COPPER		0x1539
#define E1000_DEV_ID_I354_BACKPLANE_1GBPS	0x1F40
#define E1000_DEV_ID_I354_SGMII			0x1F41
#define E1000_DEV_ID_I354_BACKPLANE_2_5GBPS	0x1F45


#define E1000_REVISION_2 2
#define E1000_REVISION_2 2
#define E1000_REVISION_4 4
#define E1000_REVISION_4 4
@@ -90,6 +93,7 @@ enum e1000_mac_type {
	e1000_82576,
	e1000_82576,
	e1000_82580,
	e1000_82580,
	e1000_i350,
	e1000_i350,
	e1000_i354,
	e1000_i210,
	e1000_i210,
	e1000_i211,
	e1000_i211,
	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
	e1000_num_macs  /* List is 1-based, so subtract 1 for true count. */
+12 −1
Original line number Original line Diff line number Diff line
@@ -214,7 +214,7 @@ s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
		else
		else
			vfta &= ~mask;
			vfta &= ~mask;
	}
	}
	if (hw->mac.type == e1000_i350)
	if ((hw->mac.type == e1000_i350) || (hw->mac.type == e1000_i354))
		igb_write_vfta_i350(hw, index, vfta);
		igb_write_vfta_i350(hw, index, vfta);
	else
	else
		igb_write_vfta(hw, index, vfta);
		igb_write_vfta(hw, index, vfta);
@@ -1171,6 +1171,17 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
		hw_dbg("Half Duplex\n");
		hw_dbg("Half Duplex\n");
	}
	}


	/* Check if it is an I354 2.5Gb backplane connection. */
	if (hw->mac.type == e1000_i354) {
		if ((status & E1000_STATUS_2P5_SKU) &&
		    !(status & E1000_STATUS_2P5_SKU_OVER)) {
			*speed = SPEED_2500;
			*duplex = FULL_DUPLEX;
			hw_dbg("2500 Mbs, ");
			hw_dbg("Full Duplex\n");
		}
	}

	return 0;
	return 0;
}
}


Loading