Commit 49425dfc authored by Mark Rustad's avatar Mark Rustad Committed by Jeff Kirsher

ixgbe: Add support for x550em_a 10G MAC type

Add support for x550em_a 10G MAC type to the ixgbe driver. The new
MAC includes new firmware commands that need to be used to control
PHY and IOSF access, so that support is also added. The interface
supported is a native SFP+ interface.
Signed-off-by: default avatarMark Rustad <mark.d.rustad@intel.com>
Tested-by: default avatarAndrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: default avatarJeff Kirsher <jeffrey.t.kirsher@intel.com>
parent 9a5c27e6
...@@ -817,6 +817,7 @@ static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter) ...@@ -817,6 +817,7 @@ static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
return IXGBE_MAX_RSS_INDICES; return IXGBE_MAX_RSS_INDICES;
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
return IXGBE_MAX_RSS_INDICES_X550; return IXGBE_MAX_RSS_INDICES_X550;
default: default:
return 0; return 0;
...@@ -860,6 +861,7 @@ enum ixgbe_boards { ...@@ -860,6 +861,7 @@ enum ixgbe_boards {
board_X540, board_X540,
board_X550, board_X550,
board_X550EM_x, board_X550EM_x,
board_x550em_a,
}; };
extern const struct ixgbe_info ixgbe_82598_info; extern const struct ixgbe_info ixgbe_82598_info;
...@@ -867,6 +869,7 @@ extern const struct ixgbe_info ixgbe_82599_info; ...@@ -867,6 +869,7 @@ extern const struct ixgbe_info ixgbe_82599_info;
extern const struct ixgbe_info ixgbe_X540_info; extern const struct ixgbe_info ixgbe_X540_info;
extern const struct ixgbe_info ixgbe_X550_info; extern const struct ixgbe_info ixgbe_X550_info;
extern const struct ixgbe_info ixgbe_X550EM_x_info; extern const struct ixgbe_info ixgbe_X550EM_x_info;
extern const struct ixgbe_info ixgbe_x550em_a_info;
#ifdef CONFIG_IXGBE_DCB #ifdef CONFIG_IXGBE_DCB
extern const struct dcbnl_rtnl_ops dcbnl_ops; extern const struct dcbnl_rtnl_ops dcbnl_ops;
#endif #endif
......
...@@ -1633,6 +1633,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw, ...@@ -1633,6 +1633,7 @@ s32 ixgbe_fdir_set_input_mask_82599(struct ixgbe_hw *hw,
switch (hw->mac.type) { switch (hw->mac.type) {
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm); IXGBE_WRITE_REG(hw, IXGBE_FDIRSCTPM, ~fdirtcpm);
break; break;
default: default:
......
...@@ -2855,6 +2855,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw) ...@@ -2855,6 +2855,7 @@ u16 ixgbe_get_pcie_msix_count_generic(struct ixgbe_hw *hw)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS; pcie_offset = IXGBE_PCIE_MSIX_82599_CAPS;
max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599; max_msix_count = IXGBE_MAX_MSIX_VECTORS_82599;
break; break;
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -293,6 +293,7 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw, ...@@ -293,6 +293,7 @@ s32 ixgbe_dcb_hw_config(struct ixgbe_hw *hw,
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max, return ixgbe_dcb_hw_config_82599(hw, pfc_en, refill, max,
bwgid, ptype, prio_tc); bwgid, ptype, prio_tc);
default: default:
...@@ -311,6 +312,7 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc) ...@@ -311,6 +312,7 @@ s32 ixgbe_dcb_hw_pfc_config(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc); return ixgbe_dcb_config_pfc_82599(hw, pfc_en, prio_tc);
default: default:
break; break;
...@@ -368,6 +370,7 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw, ...@@ -368,6 +370,7 @@ s32 ixgbe_dcb_hw_ets_config(struct ixgbe_hw *hw,
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max, ixgbe_dcb_config_rx_arbiter_82599(hw, refill, max,
bwg_id, prio_type, prio_tc); bwg_id, prio_type, prio_tc);
ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max, ixgbe_dcb_config_tx_desc_arbiter_82599(hw, refill, max,
...@@ -398,6 +401,7 @@ void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map) ...@@ -398,6 +401,7 @@ void ixgbe_dcb_read_rtrup2tc(struct ixgbe_hw *hw, u8 *map)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
ixgbe_dcb_read_rtrup2tc_82599(hw, map); ixgbe_dcb_read_rtrup2tc_82599(hw, map);
break; break;
default: default:
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -547,6 +547,7 @@ static void ixgbe_get_regs(struct net_device *netdev, ...@@ -547,6 +547,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i)); regs_buff[35 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTL_82599(i));
regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i)); regs_buff[43 + i] = IXGBE_READ_REG(hw, IXGBE_FCRTH_82599(i));
break; break;
...@@ -660,6 +661,7 @@ static void ixgbe_get_regs(struct net_device *netdev, ...@@ -660,6 +661,7 @@ static void ixgbe_get_regs(struct net_device *netdev,
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_RTTDCS); regs_buff[830] = IXGBE_READ_REG(hw, IXGBE_RTTDCS);
regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RTRPCS); regs_buff[832] = IXGBE_READ_REG(hw, IXGBE_RTRPCS);
for (i = 0; i < 8; i++) for (i = 0; i < 8; i++)
...@@ -1443,6 +1445,7 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data) ...@@ -1443,6 +1445,7 @@ static int ixgbe_reg_test(struct ixgbe_adapter *adapter, u64 *data)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
toggle = 0x7FFFF30F; toggle = 0x7FFFF30F;
test = reg_test_82599; test = reg_test_82599;
break; break;
...@@ -1681,6 +1684,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter) ...@@ -1681,6 +1684,7 @@ static void ixgbe_free_desc_rings(struct ixgbe_adapter *adapter)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL); reg_ctl = IXGBE_READ_REG(hw, IXGBE_DMATXCTL);
reg_ctl &= ~IXGBE_DMATXCTL_TE; reg_ctl &= ~IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl); IXGBE_WRITE_REG(hw, IXGBE_DMATXCTL, reg_ctl);
...@@ -1720,6 +1724,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter) ...@@ -1720,6 +1724,7 @@ static int ixgbe_setup_desc_rings(struct ixgbe_adapter *adapter)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL); reg_data = IXGBE_READ_REG(&adapter->hw, IXGBE_DMATXCTL);
reg_data |= IXGBE_DMATXCTL_TE; reg_data |= IXGBE_DMATXCTL_TE;
IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data); IXGBE_WRITE_REG(&adapter->hw, IXGBE_DMATXCTL, reg_data);
...@@ -1780,6 +1785,7 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter) ...@@ -1780,6 +1785,7 @@ static int ixgbe_setup_loopback_test(struct ixgbe_adapter *adapter)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
reg_data = IXGBE_READ_REG(hw, IXGBE_MACC); reg_data = IXGBE_READ_REG(hw, IXGBE_MACC);
reg_data |= IXGBE_MACC_FLU; reg_data |= IXGBE_MACC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data); IXGBE_WRITE_REG(hw, IXGBE_MACC, reg_data);
...@@ -2991,6 +2997,7 @@ static int ixgbe_get_ts_info(struct net_device *dev, ...@@ -2991,6 +2997,7 @@ static int ixgbe_get_ts_info(struct net_device *dev,
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
info->so_timestamping = info->so_timestamping =
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -128,6 +128,7 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc, ...@@ -128,6 +128,7 @@ static void ixgbe_get_first_reg_idx(struct ixgbe_adapter *adapter, u8 tc,
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
if (num_tcs > 4) { if (num_tcs > 4) {
/* /*
* TCs : TC0/1 TC2/3 TC4-7 * TCs : TC0/1 TC2/3 TC4-7
......
...@@ -307,6 +307,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number) ...@@ -307,6 +307,7 @@ static s32 ixgbe_check_for_rst_pf(struct ixgbe_hw *hw, u16 vf_number)
case ixgbe_mac_X540: case ixgbe_mac_X540:
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset)); vflre = IXGBE_READ_REG(hw, IXGBE_VFLREC(reg_offset));
break; break;
default: default:
...@@ -430,6 +431,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) ...@@ -430,6 +431,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
if (hw->mac.type != ixgbe_mac_82599EB && if (hw->mac.type != ixgbe_mac_82599EB &&
hw->mac.type != ixgbe_mac_X550 && hw->mac.type != ixgbe_mac_X550 &&
hw->mac.type != ixgbe_mac_X550EM_x && hw->mac.type != ixgbe_mac_X550EM_x &&
hw->mac.type != ixgbe_mac_x550em_a &&
hw->mac.type != ixgbe_mac_X540) hw->mac.type != ixgbe_mac_X540)
return; return;
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2015 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -333,6 +333,7 @@ static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter, ...@@ -333,6 +333,7 @@ static void ixgbe_ptp_convert_to_hwtstamp(struct ixgbe_adapter *adapter,
*/ */
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
/* Upper 32 bits represent billions of cycles, lower 32 bits /* Upper 32 bits represent billions of cycles, lower 32 bits
* represent cycles. However, we use timespec64_to_ns for the * represent cycles. However, we use timespec64_to_ns for the
* correct math even though the units haven't been corrected * correct math even though the units haven't been corrected
...@@ -921,6 +922,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter, ...@@ -921,6 +922,7 @@ static int ixgbe_ptp_set_timestamp_mode(struct ixgbe_adapter *adapter,
switch (hw->mac.type) { switch (hw->mac.type) {
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
/* enable timestamping all packets only if at least some /* enable timestamping all packets only if at least some
* packets were requested. Otherwise, play nice and disable * packets were requested. Otherwise, play nice and disable
* timestamping * timestamping
...@@ -1083,6 +1085,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter) ...@@ -1083,6 +1085,7 @@ void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter)
cc.shift = 2; cc.shift = 2;
} }
/* fallthrough */ /* fallthrough */
case ixgbe_mac_x550em_a:
case ixgbe_mac_X550: case ixgbe_mac_X550:
cc.read = ixgbe_ptp_read_X550; cc.read = ixgbe_ptp_read_X550;
...@@ -1223,6 +1226,7 @@ static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter) ...@@ -1223,6 +1226,7 @@ static long ixgbe_ptp_create_clock(struct ixgbe_adapter *adapter)
break; break;
case ixgbe_mac_X550: case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x: case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name); snprintf(adapter->ptp_caps.name, 16, "%s", netdev->name);
adapter->ptp_caps.owner = THIS_MODULE; adapter->ptp_caps.owner = THIS_MODULE;
adapter->ptp_caps.max_adj = 30000000; adapter->ptp_caps.max_adj = 30000000;
......
...@@ -2627,6 +2627,20 @@ enum ixgbe_fdir_pballoc_type { ...@@ -2627,6 +2627,20 @@ enum ixgbe_fdir_pballoc_type {
#define FW_MAX_READ_BUFFER_SIZE 1024 #define FW_MAX_READ_BUFFER_SIZE 1024
#define FW_DISABLE_RXEN_CMD 0xDE #define FW_DISABLE_RXEN_CMD 0xDE
#define FW_DISABLE_RXEN_LEN 0x1 #define FW_DISABLE_RXEN_LEN 0x1
#define FW_PHY_MGMT_REQ_CMD 0x20
#define FW_PHY_TOKEN_REQ_CMD 0x0A
#define FW_PHY_TOKEN_REQ_LEN 2
#define FW_PHY_TOKEN_REQ 0
#define FW_PHY_TOKEN_REL 1
#define FW_PHY_TOKEN_OK 1
#define FW_PHY_TOKEN_RETRY 0x80
#define FW_PHY_TOKEN_DELAY 5 /* milliseconds */
#define FW_PHY_TOKEN_WAIT 5 /* seconds */
#define FW_PHY_TOKEN_RETRIES ((FW_PHY_TOKEN_WAIT * 1000) / FW_PHY_TOKEN_DELAY)
#define FW_INT_PHY_REQ_CMD 0xB
#define FW_INT_PHY_REQ_LEN 10
#define FW_INT_PHY_REQ_READ 0
#define FW_INT_PHY_REQ_WRITE 1
/* Host Interface Command Structures */ /* Host Interface Command Structures */
struct ixgbe_hic_hdr { struct ixgbe_hic_hdr {
...@@ -2695,6 +2709,28 @@ struct ixgbe_hic_disable_rxen { ...@@ -2695,6 +2709,28 @@ struct ixgbe_hic_disable_rxen {
u16 pad3; u16 pad3;
}; };
struct ixgbe_hic_phy_token_req {
struct ixgbe_hic_hdr hdr;
u8 port_number;
u8 command_type;
u16 pad;
};
struct ixgbe_hic_internal_phy_req {
struct ixgbe_hic_hdr hdr;
u8 port_number;
u8 command_type;
__be16 address;
u16 rsv1;
__be32 write_data;
u16 pad;
} __packed;
struct ixgbe_hic_internal_phy_resp {
struct ixgbe_hic_hdr hdr;
__be32 read_data;
};
/* Transmit Descriptor - Advanced */ /* Transmit Descriptor - Advanced */
union ixgbe_adv_tx_desc { union ixgbe_adv_tx_desc {
struct { struct {
...@@ -3528,6 +3564,8 @@ struct ixgbe_info { ...@@ -3528,6 +3564,8 @@ struct ixgbe_info {
#define IXGBE_ERR_INVALID_ARGUMENT -32 #define IXGBE_ERR_INVALID_ARGUMENT -32
#define IXGBE_ERR_HOST_INTERFACE_COMMAND -33 #define IXGBE_ERR_HOST_INTERFACE_COMMAND -33
#define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38 #define IXGBE_ERR_FDIR_CMD_INCOMPLETE -38
#define IXGBE_ERR_FW_RESP_INVALID -39
#define IXGBE_ERR_TOKEN_RETRY -40
#define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF #define IXGBE_NOT_IMPLEMENTED 0x7FFFFFFF
#define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4)) #define IXGBE_FUSES0_GROUP(_i) (0x11158 + ((_i) * 4))
......
...@@ -278,6 +278,8 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw) ...@@ -278,6 +278,8 @@ static s32 ixgbe_identify_phy_x550em(struct ixgbe_hw *hw)
hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM; hw->phy.phy_semaphore_mask = IXGBE_GSSR_SHARED_I2C_SM;
ixgbe_setup_mux_ctl(hw); ixgbe_setup_mux_ctl(hw);
ixgbe_check_cs4227(hw); ixgbe_check_cs4227(hw);
/* Fallthrough */
case IXGBE_DEV_ID_X550EM_A_SFP_N:
return ixgbe_identify_module_generic(hw); return ixgbe_identify_module_generic(hw);
case IXGBE_DEV_ID_X550EM_X_KX4: case IXGBE_DEV_ID_X550EM_X_KX4:
hw->phy.type = ixgbe_phy_x550em_kx4; hw->phy.type = ixgbe_phy_x550em_kx4;
...@@ -413,6 +415,121 @@ static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr, ...@@ -413,6 +415,121 @@ static s32 ixgbe_read_iosf_sb_reg_x550(struct ixgbe_hw *hw, u32 reg_addr,
return ret; return ret;
} }
/**
* ixgbe_get_phy_token - Get the token for shared PHY access
* @hw: Pointer to hardware structure
*/
static s32 ixgbe_get_phy_token(struct ixgbe_hw *hw)
{
struct ixgbe_hic_phy_token_req token_cmd;
s32 status;
token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
token_cmd.port_number = hw->bus.lan_id;
token_cmd.command_type = FW_PHY_TOKEN_REQ;
token_cmd.pad = 0;
status = ixgbe_host_interface_command(hw, &token_cmd, sizeof(token_cmd),
IXGBE_HI_COMMAND_TIMEOUT,
true);
if (status)
return status;
if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
return 0;
if (token_cmd.hdr.cmd_or_resp.ret_status != FW_PHY_TOKEN_RETRY)
return IXGBE_ERR_FW_RESP_INVALID;
return IXGBE_ERR_TOKEN_RETRY;
}
/**
* ixgbe_put_phy_token - Put the token for shared PHY access
* @hw: Pointer to hardware structure
*/
static s32 ixgbe_put_phy_token(struct ixgbe_hw *hw)
{
struct ixgbe_hic_phy_token_req token_cmd;
s32 status;
token_cmd.hdr.cmd = FW_PHY_TOKEN_REQ_CMD;
token_cmd.hdr.buf_len = FW_PHY_TOKEN_REQ_LEN;
token_cmd.hdr.cmd_or_resp.cmd_resv = 0;
token_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
token_cmd.port_number = hw->bus.lan_id;
token_cmd.command_type = FW_PHY_TOKEN_REL;
token_cmd.pad = 0;
status = ixgbe_host_interface_command(hw, &token_cmd, sizeof(token_cmd),
IXGBE_HI_COMMAND_TIMEOUT,
true);
if (status)
return status;
if (token_cmd.hdr.cmd_or_resp.ret_status == FW_PHY_TOKEN_OK)
return 0;
return IXGBE_ERR_FW_RESP_INVALID;
}
/**
* ixgbe_write_iosf_sb_reg_x550a - Write to IOSF PHY register
* @hw: pointer to hardware structure
* @reg_addr: 32 bit PHY register to write
* @device_type: 3 bit device type
* @data: Data to write to the register
**/
static s32 ixgbe_write_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
__always_unused u32 device_type,
u32 data)
{
struct ixgbe_hic_internal_phy_req write_cmd;
memset(&write_cmd, 0, sizeof(write_cmd));
write_cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
write_cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
write_cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
write_cmd.port_number = hw->bus.lan_id;
write_cmd.command_type = FW_INT_PHY_REQ_WRITE;
write_cmd.address = cpu_to_be16(reg_addr);
write_cmd.write_data = cpu_to_be32(data);
return ixgbe_host_interface_command(hw, &write_cmd, sizeof(write_cmd),
IXGBE_HI_COMMAND_TIMEOUT, false);
}
/**
* ixgbe_read_iosf_sb_reg_x550a - Read from IOSF PHY register
* @hw: pointer to hardware structure
* @reg_addr: 32 bit PHY register to write
* @device_type: 3 bit device type
* @data: Pointer to read data from the register
**/
static s32 ixgbe_read_iosf_sb_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
__always_unused u32 device_type,
u32 *data)
{
union {
struct ixgbe_hic_internal_phy_req cmd;
struct ixgbe_hic_internal_phy_resp rsp;
} hic;
s32 status;
memset(&hic, 0, sizeof(hic));
hic.cmd.hdr.cmd = FW_INT_PHY_REQ_CMD;
hic.cmd.hdr.buf_len = FW_INT_PHY_REQ_LEN;
hic.cmd.hdr.checksum = FW_DEFAULT_CHECKSUM;
hic.cmd.port_number = hw->bus.lan_id;
hic.cmd.command_type = FW_INT_PHY_REQ_READ;
hic.cmd.address = cpu_to_be16(reg_addr);
status = ixgbe_host_interface_command(hw, &hic.cmd, sizeof(hic.cmd),
IXGBE_HI_COMMAND_TIMEOUT, true);
/* Extract the register value from the response. */
*data = be32_to_cpu(hic.rsp.read_data);
return status;
}
/** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface /** ixgbe_read_ee_hostif_data_X550 - Read EEPROM word using a host interface
* command assuming that the semaphore is already obtained. * command assuming that the semaphore is already obtained.
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -1339,9 +1456,9 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) ...@@ -1339,9 +1456,9 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
mac->ops.disable_tx_laser = NULL; mac->ops.disable_tx_laser = NULL;
mac->ops.enable_tx_laser = NULL; mac->ops.enable_tx_laser = NULL;
mac->ops.flap_tx_laser = NULL; mac->ops.flap_tx_laser = NULL;
mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber; mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
mac->ops.setup_fc = ixgbe_setup_fc_x550em; mac->ops.setup_fc = ixgbe_setup_fc_x550em;
mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
mac->ops.set_rate_select_speed = mac->ops.set_rate_select_speed =
ixgbe_set_soft_rate_select_speed; ixgbe_set_soft_rate_select_speed;
break; break;
...@@ -1349,6 +1466,8 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) ...@@ -1349,6 +1466,8 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
mac->ops.setup_fc = ixgbe_setup_fc_generic; mac->ops.setup_fc = ixgbe_setup_fc_generic;
mac->ops.check_link = ixgbe_check_link_t_X550em; mac->ops.check_link = ixgbe_check_link_t_X550em;
return;
case ixgbe_media_type_backplane:
break; break;
default: default:
mac->ops.setup_fc = ixgbe_setup_fc_x550em; mac->ops.setup_fc = ixgbe_setup_fc_x550em;
...@@ -2107,11 +2226,12 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw) ...@@ -2107,11 +2226,12 @@ static enum ixgbe_media_type ixgbe_get_media_type_X550em(struct ixgbe_hw *hw)
media_type = ixgbe_media_type_backplane; media_type = ixgbe_media_type_backplane;
break; break;
case IXGBE_DEV_ID_X550EM_X_SFP: case IXGBE_DEV_ID_X550EM_X_SFP:
case IXGBE_DEV_ID_X550EM_A_SFP_N:
media_type = ixgbe_media_type_fiber; media_type = ixgbe_media_type_fiber;
break; break;
case IXGBE_DEV_ID_X550EM_X_1G_T: case IXGBE_DEV_ID_X550EM_X_1G_T:
case IXGBE_DEV_ID_X550EM_X_10G_T: case IXGBE_DEV_ID_X550EM_X_10G_T:
media_type = ixgbe_media_type_copper; media_type = ixgbe_media_type_copper;
break; break;
default: default:
media_type = ixgbe_media_type_unknown; media_type = ixgbe_media_type_unknown;
...@@ -2375,6 +2495,59 @@ static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask) ...@@ -2375,6 +2495,59 @@ static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
ixgbe_release_swfw_sync_X540(hw, mask); ixgbe_release_swfw_sync_X540(hw, mask);
} }
/**
* ixgbe_acquire_swfw_sync_x550em_a - Acquire SWFW semaphore
* @hw: pointer to hardware structure
* @mask: Mask to specify which semaphore to acquire
*
* Acquires the SWFW semaphore and get the shared PHY token as needed
*/
static s32 ixgbe_acquire_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask)
{
u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
int retries = FW_PHY_TOKEN_RETRIES;
s32 status;
while (--retries) {
status = 0;
if (hmask)
status = ixgbe_acquire_swfw_sync_X540(hw, hmask);
if (status)
return status;
if (!(mask & IXGBE_GSSR_TOKEN_SM))
return 0;
status = ixgbe_get_phy_token(hw);
if (!status)
return 0;
if (hmask)
ixgbe_release_swfw_sync_X540(hw, hmask);
if (status != IXGBE_ERR_TOKEN_RETRY)
return status;
udelay(FW_PHY_TOKEN_DELAY * 1000);
}
return status;
}
/**
* ixgbe_release_swfw_sync_x550em_a - Release SWFW semaphore
* @hw: pointer to hardware structure
* @mask: Mask to specify which semaphore to release
*
* Release the SWFW semaphore and puts the shared PHY token as needed
*/
static void ixgbe_release_swfw_sync_x550em_a(struct ixgbe_hw *hw, u32 mask)
{
u32 hmask = mask & ~IXGBE_GSSR_TOKEN_SM;
if (mask & IXGBE_GSSR_TOKEN_SM)
ixgbe_put_phy_token(hw);
if (hmask)
ixgbe_release_swfw_sync_X540(hw, hmask);
}
#define X550_COMMON_MAC \ #define X550_COMMON_MAC \
.init_hw = &ixgbe_init_hw_generic, \ .init_hw = &ixgbe_init_hw_generic, \
.start_hw = &ixgbe_start_hw_X540, \ .start_hw = &ixgbe_start_hw_X540, \
...@@ -2455,6 +2628,23 @@ static const struct ixgbe_mac_operations mac_ops_X550EM_x = { ...@@ -2455,6 +2628,23 @@ static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550, .write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550,
}; };
static struct ixgbe_mac_operations mac_ops_x550em_a = {
X550_COMMON_MAC
.reset_hw = ixgbe_reset_hw_X550em,
.get_media_type = ixgbe_get_media_type_X550em,
.get_san_mac_addr = NULL,
.get_wwn_prefix = NULL,
.setup_link = NULL, /* defined later */
.get_link_capabilities = ixgbe_get_link_capabilities_X550em,
.get_bus_info = ixgbe_get_bus_info_X550em,
.setup_sfp = ixgbe_setup_sfp_modules_X550em,
.acquire_swfw_sync = ixgbe_acquire_swfw_sync_x550em_a,
.release_swfw_sync = ixgbe_release_swfw_sync_x550em_a,
.setup_fc = ixgbe_setup_fc_generic,
.read_iosf_sb_reg = ixgbe_read_iosf_sb_reg_x550a,
.write_iosf_sb_reg = ixgbe_write_iosf_sb_reg_x550a,
};
#define X550_COMMON_EEP \ #define X550_COMMON_EEP \
.read = &ixgbe_read_ee_hostif_X550, \ .read = &ixgbe_read_ee_hostif_X550, \
.read_buffer = &ixgbe_read_ee_hostif_buffer_X550, \ .read_buffer = &ixgbe_read_ee_hostif_buffer_X550, \
...@@ -2515,6 +2705,10 @@ static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = { ...@@ -2515,6 +2705,10 @@ static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
IXGBE_MVALS_INIT(X550EM_x) IXGBE_MVALS_INIT(X550EM_x)
}; };
static const u32 ixgbe_mvals_x550em_a[IXGBE_MVALS_IDX_LIMIT] = {
IXGBE_MVALS_INIT(X550EM_a)
};
const struct ixgbe_info ixgbe_X550_info = { const struct ixgbe_info ixgbe_X550_info = {
.mac = ixgbe_mac_X550, .mac = ixgbe_mac_X550,
.get_invariants = &ixgbe_get_invariants_X540, .get_invariants = &ixgbe_get_invariants_X540,
...@@ -2534,3 +2728,13 @@ const struct ixgbe_info ixgbe_X550EM_x_info = { ...@@ -2534,3 +2728,13 @@ const struct ixgbe_info ixgbe_X550EM_x_info = {
.mbx_ops = &mbx_ops_generic, .mbx_ops = &mbx_ops_generic,
.mvals = ixgbe_mvals_X550EM_x, .mvals = ixgbe_mvals_X550EM_x,
}; };
const struct ixgbe_info ixgbe_x550em_a_info = {
.mac = ixgbe_mac_x550em_a,
.get_invariants = &ixgbe_get_invariants_X550_x,
.mac_ops = &mac_ops_x550em_a,
.eeprom_ops = &eeprom_ops_X550EM_x,
.phy_ops = &phy_ops_X550EM_x,
.mbx_ops = &mbx_ops_generic,
.mvals = ixgbe_mvals_x550em_a,
};
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment