Skip to content

Commit

Permalink
igb: Add support for i354 devices
Browse files Browse the repository at this point in the history
This patch adds base support for new i354 devices.  Loopback test is
unsupported for this release.

Signed-off-by: Carolyn Wyborny <carolyn.wyborny@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
  • Loading branch information
Carolyn Wyborny authored and Jeff Kirsher committed Apr 18, 2013
1 parent 70ea478 commit ceb5f13
Show file tree
Hide file tree
Showing 12 changed files with 251 additions and 36 deletions.
122 changes: 119 additions & 3 deletions drivers/net/ethernet/intel/igb/e1000_82575.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ static bool igb_sgmii_uses_mdio_82575(struct e1000_hw *hw)
break;
case e1000_82580:
case e1000_i350:
case e1000_i354:
case e1000_i210:
case e1000_i211:
reg = rd32(E1000_MDICNFG);
Expand Down Expand Up @@ -149,6 +150,7 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)
switch (hw->mac.type) {
case e1000_82580:
case e1000_i350:
case e1000_i354:
phy->ops.read_reg = igb_read_phy_reg_82580;
phy->ops.write_reg = igb_write_phy_reg_82580;
break;
Expand All @@ -174,13 +176,14 @@ static s32 igb_init_phy_params_82575(struct e1000_hw *hw)

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

/* Disabling VLAN filtering */
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);
else
igb_clear_vfta(hw);
Expand Down Expand Up @@ -1348,6 +1359,7 @@ static s32 igb_setup_copper_link_82575(struct e1000_hw *hw)
switch (hw->phy.id) {
case I347AT4_E_PHY_ID:
case M88E1112_E_PHY_ID:
case M88E1545_E_PHY_ID:
case I210_I_PHY_ID:
ret_val = igb_copper_link_setup_m88_gen2(hw);
break;
Expand Down Expand Up @@ -1804,6 +1816,7 @@ void igb_vmdq_set_anti_spoofing_pf(struct e1000_hw *hw, bool enable, int pf)
reg_offset = E1000_DTXSWC;
break;
case e1000_i350:
case e1000_i354:
reg_offset = E1000_TXSWC;
break;
default:
Expand Down Expand Up @@ -1845,6 +1858,7 @@ void igb_vmdq_set_loopback_pf(struct e1000_hw *hw, bool enable)
dtxswc &= ~E1000_DTXSWC_VMDQ_LOOPBACK_EN;
wr32(E1000_DTXSWC, dtxswc);
break;
case e1000_i354:
case e1000_i350:
dtxswc = rd32(E1000_TXSWC);
if (enable)
Expand Down Expand Up @@ -2365,6 +2379,108 @@ s32 igb_set_eee_i350(struct e1000_hw *hw)
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] = {
E1000_EMC_INTERNAL_DATA,
E1000_EMC_DIODE1_DATA,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/igb/e1000_82575.h
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,7 @@ void igb_vmdq_set_replication_pf(struct e1000_hw *, bool);
u16 igb_rxpbs_adjust_82580(u32 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_i354(struct e1000_hw *);
s32 igb_init_thermal_sensor_thresh_generic(struct e1000_hw *);
s32 igb_get_thermal_sensor_data_generic(struct e1000_hw *hw);

Expand Down
16 changes: 16 additions & 0 deletions drivers/net/ethernet/intel/igb/e1000_defines.h
Original file line number Diff line number Diff line change
Expand Up @@ -236,11 +236,14 @@
#define E1000_STATUS_GIO_MASTER_ENABLE 0x00080000
/* 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. */

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

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

/* M88E1000 Specific Registers */
#define M88E1000_PHY_SPEC_CTRL 0x10 /* PHY Specific Control Register */
Expand Down Expand Up @@ -889,6 +893,18 @@
#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_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 */
#define E1000_GEN_CTL_READY 0x80000000
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/igb/e1000_hw.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ struct e1000_hw;
#define E1000_DEV_ID_I210_SERDES 0x1537
#define E1000_DEV_ID_I210_SGMII 0x1538
#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_4 4
Expand All @@ -90,6 +93,7 @@ enum e1000_mac_type {
e1000_82576,
e1000_82580,
e1000_i350,
e1000_i354,
e1000_i210,
e1000_i211,
e1000_num_macs /* List is 1-based, so subtract 1 for true count. */
Expand Down
13 changes: 12 additions & 1 deletion drivers/net/ethernet/intel/igb/e1000_mac.c
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,7 @@ s32 igb_vfta_set(struct e1000_hw *hw, u32 vid, bool add)
else
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);
else
igb_write_vfta(hw, index, vfta);
Expand Down Expand Up @@ -1171,6 +1171,17 @@ s32 igb_get_speed_and_duplex_copper(struct e1000_hw *hw, u16 *speed,
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;
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/igb/e1000_nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -721,6 +721,7 @@ void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
case e1000_82575:
case e1000_82576:
case e1000_82580:
case e1000_i354:
case e1000_i350:
case e1000_i210:
break;
Expand All @@ -739,6 +740,7 @@ void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)

switch (hw->mac.type) {
case e1000_i210:
case e1000_i354:
case e1000_i350:
/* find combo image version */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/igb/e1000_phy.c
Original file line number Diff line number Diff line change
Expand Up @@ -1682,6 +1682,7 @@ s32 igb_get_cable_length_m88_gen2(struct e1000_hw *hw)
phy->max_cable_length = phy_data / (is_cm ? 100 : 1);
phy->cable_length = phy_data / (is_cm ? 100 : 1);
break;
case M88E1545_E_PHY_ID:
case I347AT4_E_PHY_ID:
/* Remember the original page select and set it to 7 */
ret_val = phy->ops.read_reg(hw, I347AT4_PAGE_SELECT,
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/igb/e1000_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#define E1000_TIPG 0x00410 /* TX Inter-packet gap -RW */
#define E1000_AIT 0x00458 /* Adaptive Interframe Spacing Throttle - RW */
#define E1000_LEDCTL 0x00E00 /* LED Control - RW */
#define E1000_LEDMUX 0x08130 /* LED MUX Control */
#define E1000_PBA 0x01000 /* Packet Buffer Allocation - RW */
#define E1000_PBS 0x01008 /* Packet Buffer Size */
#define E1000_EEMNGCTL 0x01010 /* MNG EEprom Control */
Expand All @@ -83,6 +84,9 @@
#define E1000_I2C_DATA_IN 0x00001000 /* I2C- Data In */
#define E1000_I2C_CLK_OE_N 0x00002000 /* I2C- Clock Output Enable */
#define E1000_I2C_CLK_IN 0x00004000 /* I2C- Clock In */
#define E1000_MPHY_ADDR_CTRL 0x0024 /* GbE MPHY Address Control */
#define E1000_MPHY_DATA 0x0E10 /* GBE MPHY Data */
#define E1000_MPHY_STAT 0x0E0C /* GBE MPHY Statistics */

/* IEEE 1588 TIMESYNCH */
#define E1000_TSYNCRXCTL 0x0B620 /* Rx Time Sync Control register - RW */
Expand Down
4 changes: 2 additions & 2 deletions drivers/net/ethernet/intel/igb/igb.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,9 +122,9 @@ struct vf_data_storage {
* descriptors until either it has this many to write back, or the
* ITR timer expires.
*/
#define IGB_RX_PTHRESH 8
#define IGB_RX_PTHRESH ((hw->mac.type == e1000_i354) ? 12 : 8)
#define IGB_RX_HTHRESH 8
#define IGB_TX_PTHRESH 8
#define IGB_TX_PTHRESH ((hw->mac.type == e1000_i354) ? 20 : 8)
#define IGB_TX_HTHRESH 1
#define IGB_RX_WTHRESH ((hw->mac.type == e1000_82576 && \
adapter->msix_entries) ? 1 : 4)
Expand Down
Loading

0 comments on commit ceb5f13

Please sign in to comment.