net/ixgbe/base: add link MAC setup for X550a SFP+
This patch updates ixgbe_setup_mac_link_sfp_x550a for X550 SFP+. ixgbe_set_lan_id_multi_port_pcie has been updated to set the MAC instance(0/1) which is needed when configuring the external PHY, since X550a has two instances of MGPK. The MAC instance is read from the EEPROM. Signed-off-by: Beilei Xing <beilei.xing@intel.com>
This commit is contained in:
parent
eb540e47c6
commit
fc0559bdb5
@ -1020,13 +1020,15 @@ s32 ixgbe_get_bus_info_generic(struct ixgbe_hw *hw)
|
||||
* ixgbe_set_lan_id_multi_port_pcie - Set LAN id for PCIe multiple port devices
|
||||
* @hw: pointer to the HW structure
|
||||
*
|
||||
* Determines the LAN function id by reading memory-mapped registers
|
||||
* and swaps the port value if requested.
|
||||
* Determines the LAN function id by reading memory-mapped registers and swaps
|
||||
* the port value if requested, and set MAC instance for devices that share
|
||||
* CS4227.
|
||||
**/
|
||||
void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
|
||||
{
|
||||
struct ixgbe_bus_info *bus = &hw->bus;
|
||||
u32 reg;
|
||||
u16 ee_ctrl_4;
|
||||
|
||||
DEBUGFUNC("ixgbe_set_lan_id_multi_port_pcie");
|
||||
|
||||
@ -1038,6 +1040,13 @@ void ixgbe_set_lan_id_multi_port_pcie(struct ixgbe_hw *hw)
|
||||
reg = IXGBE_READ_REG(hw, IXGBE_FACTPS_BY_MAC(hw));
|
||||
if (reg & IXGBE_FACTPS_LFS)
|
||||
bus->func ^= 0x1;
|
||||
|
||||
/* Get MAC instance from EEPROM for configuring CS4227 */
|
||||
if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP) {
|
||||
hw->eeprom.ops.read(hw, IXGBE_EEPROM_CTRL_4, &ee_ctrl_4);
|
||||
bus->instance_id = (ee_ctrl_4 & IXGBE_EE_CTRL_4_INST_ID) >>
|
||||
IXGBE_EE_CTRL_4_INST_ID_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -89,8 +89,11 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#define IXGBE_CS4227 0xBE /* CS4227 address */
|
||||
#define IXGBE_CS4227_GLOBAL_ID_LSB 0
|
||||
#define IXGBE_CS4227_GLOBAL_ID_MSB 1
|
||||
#define IXGBE_CS4227_SCRATCH 2
|
||||
#define IXGBE_CS4227_GLOBAL_ID_VALUE 0x03E5
|
||||
#define IXGBE_CS4223_PHY_ID 0x7003/* Quad port */
|
||||
#define IXGBE_CS4227_PHY_ID 0x3003/* Dual port */
|
||||
#define IXGBE_CS4227_RESET_PENDING 0x1357
|
||||
#define IXGBE_CS4227_RESET_COMPLETE 0x5AA5
|
||||
#define IXGBE_CS4227_RETRIES 15
|
||||
|
@ -1472,6 +1472,7 @@ struct ixgbe_dmac_config {
|
||||
#define IXGBE_CORECTL_WRITE_CMD 0x00010000
|
||||
|
||||
/* Device Type definitions for new protocol MDIO commands */
|
||||
#define IXGBE_MDIO_ZERO_DEV_TYPE 0x0
|
||||
#define IXGBE_MDIO_PMA_PMD_DEV_TYPE 0x1
|
||||
#define IXGBE_MDIO_PCS_DEV_TYPE 0x3
|
||||
#define IXGBE_MDIO_PHY_XS_DEV_TYPE 0x4
|
||||
@ -2247,6 +2248,9 @@ enum {
|
||||
#define IXGBE_PBANUM_PTR_GUARD 0xFAFA
|
||||
#define IXGBE_EEPROM_CHECKSUM 0x3F
|
||||
#define IXGBE_EEPROM_SUM 0xBABA
|
||||
#define IXGBE_EEPROM_CTRL_4 0x45
|
||||
#define IXGBE_EE_CTRL_4_INST_ID 0x10
|
||||
#define IXGBE_EE_CTRL_4_INST_ID_SHIFT 4
|
||||
#define IXGBE_PCIE_ANALOG_PTR 0x03
|
||||
#define IXGBE_ATLAS0_CONFIG_PTR 0x04
|
||||
#define IXGBE_PHY_PTR 0x04
|
||||
@ -3630,6 +3634,7 @@ struct ixgbe_bus_info {
|
||||
|
||||
u16 func;
|
||||
u16 lan_id;
|
||||
u16 instance_id;
|
||||
};
|
||||
|
||||
/* Flow control parameters */
|
||||
@ -4130,5 +4135,8 @@ struct ixgbe_hw {
|
||||
|
||||
#define IXGBE_NW_MNG_IF_SEL 0x00011178
|
||||
#define IXGBE_NW_MNG_IF_SEL_INT_PHY_MODE (1 << 24)
|
||||
#define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT 3
|
||||
#define IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD \
|
||||
(0x1F << IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT)
|
||||
|
||||
#endif /* _IXGBE_TYPE_H_ */
|
||||
|
@ -1551,7 +1551,8 @@ void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
|
||||
mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
|
||||
mac->ops.set_rate_select_speed =
|
||||
ixgbe_set_soft_rate_select_speed;
|
||||
if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N)
|
||||
if ((hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) ||
|
||||
(hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP))
|
||||
mac->ops.setup_mac_link =
|
||||
ixgbe_setup_mac_link_sfp_x550a;
|
||||
else
|
||||
@ -2207,8 +2208,9 @@ s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
|
||||
bool autoneg_wait_to_complete)
|
||||
{
|
||||
s32 ret_val;
|
||||
u32 reg_val;
|
||||
u16 reg_phy_ext;
|
||||
bool setup_linear = false;
|
||||
u32 reg_slice, reg_phy_int, slice_offset;
|
||||
|
||||
UNREFERENCED_1PARAMETER(autoneg_wait_to_complete);
|
||||
|
||||
@ -2224,32 +2226,73 @@ s32 ixgbe_setup_mac_link_sfp_x550a(struct ixgbe_hw *hw,
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
return ret_val;
|
||||
|
||||
/* Configure internal PHY for native SFI */
|
||||
ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
|
||||
IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
|
||||
IXGBE_SB_IOSF_TARGET_KR_PHY, ®_val);
|
||||
if (hw->device_id == IXGBE_DEV_ID_X550EM_A_SFP_N) {
|
||||
/* Configure internal PHY for native SFI */
|
||||
ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
|
||||
IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
|
||||
IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int);
|
||||
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
return ret_val;
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
return ret_val;
|
||||
|
||||
if (setup_linear) {
|
||||
reg_val &= ~IXGBE_KRM_AN_CNTL_8_LIMITING;
|
||||
reg_val |= IXGBE_KRM_AN_CNTL_8_LINEAR;
|
||||
if (setup_linear) {
|
||||
reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LIMITING;
|
||||
reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LINEAR;
|
||||
} else {
|
||||
reg_phy_int |= IXGBE_KRM_AN_CNTL_8_LIMITING;
|
||||
reg_phy_int &= ~IXGBE_KRM_AN_CNTL_8_LINEAR;
|
||||
}
|
||||
|
||||
ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
|
||||
IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
|
||||
IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
|
||||
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
return ret_val;
|
||||
|
||||
/* Setup XFI/SFI internal link. */
|
||||
ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
|
||||
} else {
|
||||
reg_val |= IXGBE_KRM_AN_CNTL_8_LIMITING;
|
||||
reg_val &= ~IXGBE_KRM_AN_CNTL_8_LINEAR;
|
||||
/* Configure internal PHY for KR/KX. */
|
||||
ixgbe_setup_kr_speed_x550em(hw, speed);
|
||||
|
||||
/* Get CS4227 MDIO address */
|
||||
hw->phy.addr =
|
||||
(hw->phy.nw_mng_if_sel &
|
||||
IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD)
|
||||
>> IXGBE_NW_MNG_IF_SEL_MDIO_PHY_ADD_SHIFT;
|
||||
|
||||
if (hw->phy.addr == 0x0 || hw->phy.addr == 0xFFFF) {
|
||||
/* Find Address */
|
||||
DEBUGOUT("Invalid NW_MNG_IF_SEL.MDIO_PHY_ADD value\n");
|
||||
return IXGBE_ERR_PHY_ADDR_INVALID;
|
||||
}
|
||||
|
||||
/* Get external PHY device id */
|
||||
ret_val = hw->phy.ops.read_reg(hw, IXGBE_CS4227_GLOBAL_ID_MSB,
|
||||
IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
|
||||
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
return ret_val;
|
||||
|
||||
/* When configuring quad port CS4223, the MAC instance is part
|
||||
* of the slice offset.
|
||||
*/
|
||||
if (reg_phy_ext == IXGBE_CS4223_PHY_ID)
|
||||
slice_offset = (hw->bus.lan_id +
|
||||
(hw->bus.instance_id << 1)) << 12;
|
||||
else
|
||||
slice_offset = hw->bus.lan_id << 12;
|
||||
|
||||
/* Configure CS4227/CS4223 LINE side to proper mode. */
|
||||
reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
|
||||
if (setup_linear)
|
||||
reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 0x1;
|
||||
else
|
||||
reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 0x1;
|
||||
ret_val = hw->phy.ops.write_reg(hw, reg_slice,
|
||||
IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
|
||||
}
|
||||
|
||||
ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
|
||||
IXGBE_KRM_AN_CNTL_8(hw->bus.lan_id),
|
||||
IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
|
||||
|
||||
if (ret_val != IXGBE_SUCCESS)
|
||||
return ret_val;
|
||||
|
||||
/* Setup XFI/SFI internal link. */
|
||||
ret_val = ixgbe_setup_ixfi_x550em(hw, &speed);
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user