ixl(4): Add support for X710-T*L devices

Add support for new devices which are capable of 2.5 and 5G speeds, as well as
Energy Efficient Ethernet (EEE):

- introduce new device ids
- add ability to select 2.5 and 5G speeds on devices which support it
- add sysctls to enable EEE and read related statistics

Submitted by:	Krzysztof Galazka <krzysztof.galazka@intel.com>
Reviewed by:	#IntelNetworking
MFC after:	3 days
Sponsored by:	Intel Corporation
Differential Revision:	https://reviews.freebsd.org/D25549
This commit is contained in:
Eric Joyner 2020-09-01 23:16:38 +00:00
parent b4a5336039
commit 2984a8dd7c
9 changed files with 537 additions and 16 deletions

View File

@ -1940,6 +1940,8 @@ enum i40e_aq_phy_type {
I40E_PHY_TYPE_25GBASE_LR = 0x22,
I40E_PHY_TYPE_25GBASE_AOC = 0x23,
I40E_PHY_TYPE_25GBASE_ACC = 0x24,
I40E_PHY_TYPE_2_5GBASE_T = 0x30,
I40E_PHY_TYPE_5GBASE_T = 0x31,
I40E_PHY_TYPE_MAX,
I40E_PHY_TYPE_NOT_SUPPORTED_HIGH_TEMP = 0xFD,
I40E_PHY_TYPE_EMPTY = 0xFE,
@ -1981,19 +1983,25 @@ enum i40e_aq_phy_type {
BIT_ULL(I40E_PHY_TYPE_25GBASE_SR) | \
BIT_ULL(I40E_PHY_TYPE_25GBASE_LR) | \
BIT_ULL(I40E_PHY_TYPE_25GBASE_AOC) | \
BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC))
BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC) | \
BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T) | \
BIT_ULL(I40E_PHY_TYPE_5GBASE_T))
#define I40E_LINK_SPEED_2_5GB_SHIFT 0x0
#define I40E_LINK_SPEED_100MB_SHIFT 0x1
#define I40E_LINK_SPEED_1000MB_SHIFT 0x2
#define I40E_LINK_SPEED_10GB_SHIFT 0x3
#define I40E_LINK_SPEED_40GB_SHIFT 0x4
#define I40E_LINK_SPEED_20GB_SHIFT 0x5
#define I40E_LINK_SPEED_25GB_SHIFT 0x6
#define I40E_LINK_SPEED_5GB_SHIFT 0x7
enum i40e_aq_link_speed {
I40E_LINK_SPEED_UNKNOWN = 0,
I40E_LINK_SPEED_100MB = (1 << I40E_LINK_SPEED_100MB_SHIFT),
I40E_LINK_SPEED_1GB = (1 << I40E_LINK_SPEED_1000MB_SHIFT),
I40E_LINK_SPEED_2_5GB = (1 << I40E_LINK_SPEED_2_5GB_SHIFT),
I40E_LINK_SPEED_5GB = (1 << I40E_LINK_SPEED_5GB_SHIFT),
I40E_LINK_SPEED_10GB = (1 << I40E_LINK_SPEED_10GB_SHIFT),
I40E_LINK_SPEED_40GB = (1 << I40E_LINK_SPEED_40GB_SHIFT),
I40E_LINK_SPEED_20GB = (1 << I40E_LINK_SPEED_20GB_SHIFT),
@ -2030,6 +2038,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_EEE_1000BASE_KX 0x0010
#define I40E_AQ_EEE_10GBASE_KX4 0x0020
#define I40E_AQ_EEE_10GBASE_KR 0x0040
#define I40E_AQ_EEE_2_5GBASE_T 0x0100
#define I40E_AQ_EEE_5GBASE_T 0x0200
__le32 eeer_val;
u8 d3_lpan;
#define I40E_AQ_SET_PHY_D3_LPAN_ENA 0x01
@ -2040,6 +2050,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_TYPE_EXT_25G_LR 0x08
#define I40E_AQ_PHY_TYPE_EXT_25G_AOC 0x10
#define I40E_AQ_PHY_TYPE_EXT_25G_ACC 0x20
#define I40E_AQ_PHY_TYPE_EXT_2_5GBASE_T 0x40
#define I40E_AQ_PHY_TYPE_EXT_5GBASE_T 0x80
u8 fec_cfg_curr_mod_ext_info;
#define I40E_AQ_ENABLE_FEC_KR 0x01
#define I40E_AQ_ENABLE_FEC_RS 0x02
@ -2282,15 +2294,32 @@ enum i40e_aq_phy_reg_type {
I40E_AQC_PHY_REG_EXERNAL_MODULE = 0x3
};
#pragma pack(1)
/* Run PHY Activity (0x0626) */
struct i40e_aqc_run_phy_activity {
__le16 activity_id;
u8 flags;
u8 reserved1;
__le32 control;
__le32 data;
u8 reserved2[4];
u8 cmd_flags;
__le16 activity_id;
#define I40E_AQ_RUN_PHY_ACT_ID_USR_DFND 0x10
u8 reserved;
union {
struct {
__le32 dnl_opcode;
#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR 0x801a
#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT 0x801b
#define I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR 0x1801b
__le32 data;
u8 reserved2[4];
} cmd;
struct {
__le32 cmd_status;
#define I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC 0x4
#define I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK 0xFFFF
__le32 data0;
__le32 data1;
} resp;
} params;
};
#pragma pack()
I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);

View File

@ -62,6 +62,10 @@ enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw)
case I40E_DEV_ID_QSFP_C:
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_10G_BASE_T_BC:
case I40E_DEV_ID_10G_B:
case I40E_DEV_ID_10G_SFP:
case I40E_DEV_ID_5G_BASE_T_BC:
case I40E_DEV_ID_20G_KR2:
case I40E_DEV_ID_20G_KR2_A:
case I40E_DEV_ID_25G_B:
@ -1251,6 +1255,8 @@ static enum i40e_media_type i40e_get_media_type(struct i40e_hw *hw)
break;
case I40E_PHY_TYPE_100BASE_TX:
case I40E_PHY_TYPE_1000BASE_T:
case I40E_PHY_TYPE_2_5GBASE_T:
case I40E_PHY_TYPE_5GBASE_T:
case I40E_PHY_TYPE_10GBASE_T:
media = I40E_MEDIA_TYPE_BASET;
break;
@ -1516,7 +1522,8 @@ static u32 i40e_led_is_mine(struct i40e_hw *hw, int idx)
u32 gpio_val = 0;
u32 port;
if (!hw->func_caps.led[idx])
if (!I40E_IS_X710TL_DEVICE(hw->device_id) &&
!hw->func_caps.led[idx])
return 0;
gpio_val = rd32(hw, I40E_GLGEN_GPIO_CTL(idx));
port = (gpio_val & I40E_GLGEN_GPIO_CTL_PRT_NUM_MASK) >>
@ -1635,6 +1642,19 @@ void i40e_led_set(struct i40e_hw *hw, u32 mode, bool blink)
break;
}
if (I40E_IS_X710TL_DEVICE(hw->device_id)) {
u32 pin_func = 0;
if (mode & I40E_FW_LED)
pin_func = I40E_PIN_FUNC_SDP;
else
pin_func = I40E_PIN_FUNC_LED;
gpio_val &= ~I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK;
gpio_val |= ((pin_func <<
I40E_GLGEN_GPIO_CTL_PIN_FUNC_SHIFT) &
I40E_GLGEN_GPIO_CTL_PIN_FUNC_MASK);
}
gpio_val &= ~I40E_GLGEN_GPIO_CTL_LED_MODE_MASK;
/* this & is a bit of paranoia, but serves as a range check */
gpio_val |= ((mode << I40E_GLGEN_GPIO_CTL_LED_MODE_SHIFT) &
@ -6230,6 +6250,71 @@ enum i40e_status_code i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
return status;
}
/**
* i40e_enable_eee
* @hw: pointer to the hardware structure
* @enable: state of Energy Efficient Ethernet mode to be set
*
* Enables or disables Energy Efficient Ethernet (EEE) mode
* accordingly to @enable parameter.
**/
enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable)
{
struct i40e_aq_get_phy_abilities_resp abilities;
struct i40e_aq_set_phy_config config;
enum i40e_status_code status;
__le16 eee_capability;
/* Get initial PHY capabilities */
status = i40e_aq_get_phy_capabilities(hw, FALSE, TRUE, &abilities,
NULL);
if (status)
goto err;
/* Check whether NIC configuration is compatible with Energy Efficient
* Ethernet (EEE) mode.
*/
if (abilities.eee_capability == 0) {
status = I40E_ERR_CONFIG;
goto err;
}
/* Cache initial EEE capability */
eee_capability = abilities.eee_capability;
/* Get current configuration */
status = i40e_aq_get_phy_capabilities(hw, FALSE, false, &abilities,
NULL);
if (status)
goto err;
/* Cache current configuration */
config.phy_type = abilities.phy_type;
config.phy_type_ext = abilities.phy_type_ext;
config.link_speed = abilities.link_speed;
config.abilities = abilities.abilities |
I40E_AQ_PHY_ENABLE_ATOMIC_LINK;
config.eeer = abilities.eeer_val;
config.low_power_ctrl = abilities.d3_lpan;
config.fec_config = abilities.fec_cfg_curr_mod_ext_info &
I40E_AQ_PHY_FEC_CONFIG_MASK;
/* Set desired EEE state */
if (enable) {
config.eee_capability = eee_capability;
config.eeer |= I40E_PRTPM_EEER_TX_LPI_EN_MASK;
} else {
config.eee_capability = 0;
config.eeer &= ~I40E_PRTPM_EEER_TX_LPI_EN_MASK;
}
/* Save modified config */
status = i40e_aq_set_phy_config(hw, &config, NULL);
err:
return status;
}
/**
* i40e_read_bw_from_alt_ram
* @hw: pointer to the hardware structure
@ -6550,6 +6635,8 @@ enum i40e_status_code i40e_write_phy_register(struct i40e_hw *hw,
break;
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_10G_BASE_T_BC:
case I40E_DEV_ID_5G_BASE_T_BC:
case I40E_DEV_ID_10G_BASE_T_X722:
case I40E_DEV_ID_25G_B:
case I40E_DEV_ID_25G_SFP28:
@ -6586,6 +6673,8 @@ enum i40e_status_code i40e_read_phy_register(struct i40e_hw *hw,
break;
case I40E_DEV_ID_10G_BASE_T:
case I40E_DEV_ID_10G_BASE_T4:
case I40E_DEV_ID_10G_BASE_T_BC:
case I40E_DEV_ID_5G_BASE_T_BC:
case I40E_DEV_ID_10G_BASE_T_X722:
case I40E_DEV_ID_25G_B:
case I40E_DEV_ID_25G_SFP28:
@ -6841,6 +6930,196 @@ restore_config:
return status;
}
/**
* i40e_get_phy_lpi_status - read LPI status from PHY or MAC register
* @hw: pointer to the hw struct
* @stat: pointer to structure with status of rx and tx lpi
*
* Read LPI state directly from external PHY register or from MAC
* register, depending on device ID and current link speed.
*/
enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
struct i40e_hw_port_stats *stat)
{
enum i40e_status_code ret = I40E_SUCCESS;
u32 val;
stat->rx_lpi_status = 0;
stat->tx_lpi_status = 0;
if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
(hw->phy.link_info.link_speed == I40E_LINK_SPEED_2_5GB ||
hw->phy.link_info.link_speed == I40E_LINK_SPEED_5GB)) {
ret = i40e_aq_get_phy_register(hw,
I40E_AQ_PHY_REG_ACCESS_EXTERNAL,
I40E_BCM_PHY_PCS_STATUS1_PAGE,
TRUE,
I40E_BCM_PHY_PCS_STATUS1_REG,
&val, NULL);
if (ret != I40E_SUCCESS)
return ret;
stat->rx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_RX_LPI);
stat->tx_lpi_status = !!(val & I40E_BCM_PHY_PCS_STATUS1_TX_LPI);
return ret;
}
val = rd32(hw, I40E_PRTPM_EEE_STAT);
stat->rx_lpi_status = (val & I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_MASK) >>
I40E_PRTPM_EEE_STAT_RX_LPI_STATUS_SHIFT;
stat->tx_lpi_status = (val & I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_MASK) >>
I40E_PRTPM_EEE_STAT_TX_LPI_STATUS_SHIFT;
return ret;
}
/**
* i40e_get_lpi_counters - read LPI counters from EEE statistics
* @hw: pointer to the hw struct
* @tx_counter: pointer to memory for TX LPI counter
* @rx_counter: pointer to memory for RX LPI counter
* @is_clear: returns TRUE if counters are clear after read
*
* Read Low Power Idle (LPI) mode counters from Energy Efficient
* Ethernet (EEE) statistics.
**/
enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw,
u32 *tx_counter, u32 *rx_counter,
bool *is_clear)
{
/* only X710-T*L requires special handling of counters
* for other devices we just read the MAC registers
*/
if ((hw->device_id == I40E_DEV_ID_10G_BASE_T_BC ||
hw->device_id == I40E_DEV_ID_5G_BASE_T_BC) &&
hw->phy.link_info.link_speed != I40E_LINK_SPEED_1GB) {
enum i40e_status_code retval;
u32 cmd_status;
*is_clear = FALSE;
retval = i40e_aq_run_phy_activity(hw,
I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT,
&cmd_status, tx_counter, rx_counter, NULL);
if (!retval && cmd_status != I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
retval = I40E_ERR_ADMIN_QUEUE_ERROR;
return retval;
}
*is_clear = TRUE;
*tx_counter = rd32(hw, I40E_PRTPM_TLPIC);
*rx_counter = rd32(hw, I40E_PRTPM_RLPIC);
return I40E_SUCCESS;
}
/**
* i40e_get_lpi_duration - read LPI time duration from EEE statistics
* @hw: pointer to the hw struct
* @stat: pointer to structure with status of rx and tx lpi
* @tx_duration: pointer to memory for TX LPI time duration
* @rx_duration: pointer to memory for RX LPI time duration
*
* Read Low Power Idle (LPI) mode time duration from Energy Efficient
* Ethernet (EEE) statistics.
*/
enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
struct i40e_hw_port_stats *stat,
u64 *tx_duration, u64 *rx_duration)
{
u32 tx_time_dur, rx_time_dur;
enum i40e_status_code retval;
u32 cmd_status;
if (hw->device_id != I40E_DEV_ID_10G_BASE_T_BC &&
hw->device_id != I40E_DEV_ID_5G_BASE_T_BC)
return I40E_ERR_NOT_IMPLEMENTED;
retval = i40e_aq_run_phy_activity
(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_DUR,
&cmd_status, &tx_time_dur, &rx_time_dur, NULL);
if (retval)
return retval;
if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
return I40E_ERR_ADMIN_QUEUE_ERROR;
if (hw->phy.link_info.link_speed == I40E_LINK_SPEED_1GB &&
!tx_time_dur && !rx_time_dur &&
stat->tx_lpi_status && stat->rx_lpi_status) {
retval = i40e_aq_run_phy_activity
(hw, I40E_AQ_RUN_PHY_ACT_ID_USR_DFND,
I40E_AQ_RUN_PHY_ACT_DNL_OPCODE_GET_EEE_STAT_DUR,
&cmd_status,
&tx_time_dur, &rx_time_dur, NULL);
if (retval)
return retval;
if ((cmd_status & I40E_AQ_RUN_PHY_ACT_CMD_STAT_MASK) !=
I40E_AQ_RUN_PHY_ACT_CMD_STAT_SUCC)
return I40E_ERR_ADMIN_QUEUE_ERROR;
tx_time_dur = 0;
rx_time_dur = 0;
}
*tx_duration = tx_time_dur;
*rx_duration = rx_time_dur;
return retval;
}
/**
* i40e_lpi_stat_update - update LPI counters with values relative to offset
* @hw: pointer to the hw struct
* @offset_loaded: flag indicating need of writing current value to offset
* @tx_offset: pointer to offset of TX LPI counter
* @tx_stat: pointer to value of TX LPI counter
* @rx_offset: pointer to offset of RX LPI counter
* @rx_stat: pointer to value of RX LPI counter
*
* Update Low Power Idle (LPI) mode counters while having regard to passed
* offsets.
**/
enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
bool offset_loaded, u64 *tx_offset,
u64 *tx_stat, u64 *rx_offset,
u64 *rx_stat)
{
enum i40e_status_code retval;
u32 tx_counter, rx_counter;
bool is_clear;
retval = i40e_get_lpi_counters(hw, &tx_counter, &rx_counter, &is_clear);
if (retval)
goto err;
if (is_clear) {
*tx_stat += tx_counter;
*rx_stat += rx_counter;
} else {
if (!offset_loaded) {
*tx_offset = tx_counter;
*rx_offset = rx_counter;
}
*tx_stat = (tx_counter >= *tx_offset) ?
(u32)(tx_counter - *tx_offset) :
(u32)((tx_counter + BIT_ULL(32)) - *tx_offset);
*rx_stat = (rx_counter >= *rx_offset) ?
(u32)(rx_counter - *rx_offset) :
(u32)((rx_counter + BIT_ULL(32)) - *rx_offset);
}
err:
return retval;
}
/**
* i40e_aq_rx_ctl_read_register - use FW to read from an Rx control register
* @hw: pointer to the hw struct
@ -7084,6 +7363,52 @@ i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
return status;
}
/**
* i40e_aq_run_phy_activity
* @hw: pointer to the hw struct
* @activity_id: ID of DNL activity to run
* @dnl_opcode: opcode passed to DNL script
* @cmd_status: pointer to memory to write return value of DNL script
* @data0: pointer to memory for first 4 bytes of data returned by DNL script
* @data1: pointer to memory for last 4 bytes of data returned by DNL script
* @cmd_details: pointer to command details structure or NULL
*
* Run DNL admin command.
**/
enum i40e_status_code
i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 dnl_opcode,
u32 *cmd_status, u32 *data0, u32 *data1,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aqc_run_phy_activity *cmd;
enum i40e_status_code retval;
struct i40e_aq_desc desc;
cmd = (struct i40e_aqc_run_phy_activity *)&desc.params.raw;
if (!cmd_status || !data0 || !data1) {
retval = I40E_ERR_PARAM;
goto err;
}
i40e_fill_default_direct_cmd_desc(&desc,
i40e_aqc_opc_run_phy_activity);
cmd->activity_id = CPU_TO_LE16(activity_id);
cmd->params.cmd.dnl_opcode = CPU_TO_LE32(dnl_opcode);
retval = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
if (retval)
goto err;
*cmd_status = LE32_TO_CPU(cmd->params.resp.cmd_status);
*data0 = LE32_TO_CPU(cmd->params.resp.data0);
*data1 = LE32_TO_CPU(cmd->params.resp.data1);
err:
return retval;
}
/**
* i40e_aq_send_msg_to_pf
* @hw: pointer to the hardware structure

View File

@ -54,6 +54,13 @@
#define I40E_DEV_ID_10G_BASE_T4 0x1589
#define I40E_DEV_ID_25G_B 0x158A
#define I40E_DEV_ID_25G_SFP28 0x158B
#define I40E_DEV_ID_10G_BASE_T_BC 0x15FF
#define I40E_DEV_ID_10G_B 0x104F
#define I40E_DEV_ID_10G_SFP 0x104E
#define I40E_DEV_ID_5G_BASE_T_BC 0x101F
#define I40E_IS_X710TL_DEVICE(d) \
(((d) == I40E_DEV_ID_10G_BASE_T_BC) || \
((d) == I40E_DEV_ID_5G_BASE_T_BC))
#define I40E_DEV_ID_VF 0x154C
#define I40E_DEV_ID_VF_HV 0x1571
#define I40E_DEV_ID_ADAPTIVE_VF 0x1889

View File

@ -104,6 +104,17 @@ enum i40e_status_code i40e_led_get_reg(struct i40e_hw *hw, u16 led_addr,
u32 *reg_val);
enum i40e_status_code i40e_led_set_reg(struct i40e_hw *hw, u16 led_addr,
u32 reg_val);
enum i40e_status_code i40e_get_phy_lpi_status(struct i40e_hw *hw,
struct i40e_hw_port_stats *stats);
enum i40e_status_code i40e_get_lpi_counters(struct i40e_hw *hw, u32 *tx_counter,
u32 *rx_counter, bool *is_clear);
enum i40e_status_code i40e_lpi_stat_update(struct i40e_hw *hw,
bool offset_loaded, u64 *tx_offset,
u64 *tx_stat, u64 *rx_offset,
u64 *rx_stat);
enum i40e_status_code i40e_get_lpi_duration(struct i40e_hw *hw,
struct i40e_hw_port_stats *stat,
u64 *tx_duration, u64 *rx_duration);
/* admin send queue commands */
enum i40e_status_code i40e_aq_get_firmware_version(struct i40e_hw *hw,
@ -479,6 +490,7 @@ void i40e_nvmupd_check_wait_event(struct i40e_hw *hw, u16 opcode,
struct i40e_aq_desc *desc);
void i40e_nvmupd_clear_wait_state(struct i40e_hw *hw);
void i40e_set_pci_config_data(struct i40e_hw *hw, u16 link_status);
enum i40e_status_code i40e_enable_eee(struct i40e_hw *hw, bool enable);
enum i40e_status_code i40e_set_mac_type(struct i40e_hw *hw);
@ -506,6 +518,10 @@ i40e_virtchnl_link_speed(enum i40e_aq_link_speed link_speed)
return VIRTCHNL_LINK_SPEED_100MB;
case I40E_LINK_SPEED_1GB:
return VIRTCHNL_LINK_SPEED_1GB;
case I40E_LINK_SPEED_2_5GB:
return VIRTCHNL_LINK_SPEED_2_5GB;
case I40E_LINK_SPEED_5GB:
return VIRTCHNL_LINK_SPEED_5GB;
case I40E_LINK_SPEED_10GB:
return VIRTCHNL_LINK_SPEED_10GB;
case I40E_LINK_SPEED_40GB:
@ -576,6 +592,11 @@ i40e_aq_get_phy_register_ext(struct i40e_hw *hw,
#define i40e_aq_get_phy_register(hw, ps, da, pc, ra, rv, cd) \
i40e_aq_get_phy_register_ext(hw, ps, da, pc, FALSE, 0, ra, rv, cd)
enum i40e_status_code
i40e_aq_run_phy_activity(struct i40e_hw *hw, u16 activity_id, u32 opcode,
u32 *cmd_status, u32 *data0, u32 *data1,
struct i40e_asq_cmd_details *cmd_details);
enum i40e_status_code i40e_aq_set_arp_proxy_config(struct i40e_hw *hw,
struct i40e_aqc_arp_proxy_data *proxy_config,
struct i40e_asq_cmd_details *cmd_details);

View File

@ -347,6 +347,12 @@ struct i40e_phy_info {
I40E_PHY_TYPE_OFFSET)
#define I40E_CAP_PHY_TYPE_25GBASE_ACC BIT_ULL(I40E_PHY_TYPE_25GBASE_ACC + \
I40E_PHY_TYPE_OFFSET)
/* Offset for 2.5G/5G PHY Types value to bit number conversion */
#define I40E_PHY_TYPE_OFFSET2 (-10)
#define I40E_CAP_PHY_TYPE_2_5GBASE_T BIT_ULL(I40E_PHY_TYPE_2_5GBASE_T + \
I40E_PHY_TYPE_OFFSET2)
#define I40E_CAP_PHY_TYPE_5GBASE_T BIT_ULL(I40E_PHY_TYPE_5GBASE_T + \
I40E_PHY_TYPE_OFFSET2)
#define I40E_HW_CAP_MAX_GPIO 30
#define I40E_HW_CAP_MDIO_PORT_MODE_MDIO 0
#define I40E_HW_CAP_MDIO_PORT_MODE_I2C 1
@ -1490,6 +1496,8 @@ struct i40e_hw_port_stats {
u32 rx_lpi_status;
u64 tx_lpi_count; /* etlpic */
u64 rx_lpi_count; /* erlpic */
u64 tx_lpi_duration;
u64 rx_lpi_duration;
};
/* Checksum and Shadow RAM pointers */
@ -1542,6 +1550,7 @@ struct i40e_hw_port_stats {
#define I40E_SR_FEATURE_CONFIGURATION_PTR 0x49
#define I40E_SR_CONFIGURATION_METADATA_PTR 0x4D
#define I40E_SR_IMMEDIATE_VALUES_PTR 0x4E
#define I40E_SR_5TH_FREE_PROVISION_AREA_PTR 0x50
/* Auxiliary field, mask and shift definition for Shadow RAM and NVM Flash */
#define I40E_SR_VPD_MODULE_MAX_SIZE 1024
@ -1728,4 +1737,9 @@ struct i40e_lldp_variables {
#define I40E_FLEX_56_MASK (0x1ULL << I40E_FLEX_56_SHIFT)
#define I40E_FLEX_57_SHIFT 6
#define I40E_FLEX_57_MASK (0x1ULL << I40E_FLEX_57_SHIFT)
#define I40E_BCM_PHY_PCS_STATUS1_PAGE 0x3
#define I40E_BCM_PHY_PCS_STATUS1_REG 0x0001
#define I40E_BCM_PHY_PCS_STATUS1_RX_LPI BIT(8)
#define I40E_BCM_PHY_PCS_STATUS1_TX_LPI BIT(9)
#endif /* _I40E_TYPE_H_ */

View File

@ -48,7 +48,7 @@
* Driver version
*********************************************************************/
#define IXL_DRIVER_VERSION_MAJOR 2
#define IXL_DRIVER_VERSION_MINOR 2
#define IXL_DRIVER_VERSION_MINOR 3
#define IXL_DRIVER_VERSION_BUILD 0
#define IXL_DRIVER_VERSION_STRING \
@ -82,6 +82,10 @@ static pci_vendor_info_t ixl_vendor_info_array[] =
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_SFP_I_X722, "Intel(R) Ethernet Connection X722 for 10GbE SFP+"),
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_B, "Intel(R) Ethernet Controller XXV710 for 25GbE backplane"),
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_25G_SFP28, "Intel(R) Ethernet Controller XXV710 for 25GbE SFP28"),
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_BASE_T_BC, "Intel(R) Ethernet Controller X710 for 10GBASE-T"),
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_SFP, "Intel(R) Ethernet Controller X710 for 10GbE SFP+"),
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_10G_B, "Intel(R) Ethernet Controller X710 for 10GbE backplane"),
PVIDV(I40E_INTEL_VENDOR_ID, I40E_DEV_ID_5G_BASE_T_BC, "Intel(R) Ethernet Controller V710 for 5GBASE-T"),
/* required last entry */
PVID_END
};
@ -599,6 +603,12 @@ ixl_if_attach_pre(if_ctx_t ctx)
pf->state |= IXL_PF_STATE_FW_LLDP_DISABLED;
}
/* Try enabling Energy Efficient Ethernet (EEE) mode */
if (i40e_enable_eee(hw, true) == I40E_SUCCESS)
atomic_set_32(&pf->state, IXL_PF_STATE_EEE_ENABLED);
else
atomic_clear_32(&pf->state, IXL_PF_STATE_EEE_ENABLED);
/* Get MAC addresses from hardware */
i40e_get_mac_addr(hw, hw->mac.addr);
error = i40e_validate_mac_addr(hw->mac.addr);
@ -1491,6 +1501,14 @@ ixl_if_media_status(if_ctx_t ctx, struct ifmediareq *ifmr)
case I40E_PHY_TYPE_1000BASE_T_OPTICAL:
ifmr->ifm_active |= IFM_1000_T;
break;
/* 2.5 G */
case I40E_PHY_TYPE_2_5GBASE_T:
ifmr->ifm_active |= IFM_2500_T;
break;
/* 5 G */
case I40E_PHY_TYPE_5GBASE_T:
ifmr->ifm_active |= IFM_5000_T;
break;
/* 10 G */
case I40E_PHY_TYPE_10GBASE_SFPP_CU:
ifmr->ifm_active |= IFM_10G_TWINAX;

View File

@ -87,6 +87,7 @@ enum ixl_pf_state {
IXL_PF_STATE_GLOB_RESET_REQ = (1 << 7),
IXL_PF_STATE_EMP_RESET_REQ = (1 << 8),
IXL_PF_STATE_FW_LLDP_DISABLED = (1 << 9),
IXL_PF_STATE_EEE_ENABLED = (1 << 10),
};
#define IXL_PF_IN_RECOVERY_MODE(pf) \
@ -191,7 +192,9 @@ struct ixl_pf {
"\t 0x4 - advertise 10G\n" \
"\t 0x8 - advertise 20G\n" \
"\t0x10 - advertise 25G\n" \
"\t0x20 - advertise 40G\n\n" \
"\t0x20 - advertise 40G\n" \
"\t0x40 - advertise 2.5G\n" \
"\t0x80 - advertise 5G\n\n" \
"Set to 0 to disable link.\n" \
"Use \"sysctl -x\" to view flags properly."
@ -203,7 +206,9 @@ struct ixl_pf {
"\t 0x4 - 10G\n" \
"\t 0x8 - 20G\n" \
"\t0x10 - 25G\n" \
"\t0x20 - 40G\n\n" \
"\t0x20 - 40G\n" \
"\t0x40 - 2.5G\n" \
"\t0x80 - 5G\n\n" \
"Use \"sysctl -x\" to view flags properly."
#define IXL_SYSCTL_HELP_FC \

View File

@ -61,6 +61,8 @@ static int ixl_sysctl_unallocated_queues(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_pf_tx_itr(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_pf_rx_itr(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_eee_enable(SYSCTL_HANDLER_ARGS);
/* Debug Sysctls */
static int ixl_sysctl_link_status(SYSCTL_HANDLER_ARGS);
static int ixl_sysctl_phy_abilities(SYSCTL_HANDLER_ARGS);
@ -620,6 +622,12 @@ ixl_add_ifmedia(struct ifmedia *media, u64 phy_types)
if (phy_types & (I40E_CAP_PHY_TYPE_1000BASE_LX))
ifmedia_add(media, IFM_ETHER | IFM_1000_LX, 0, NULL);
if (phy_types & (I40E_CAP_PHY_TYPE_2_5GBASE_T))
ifmedia_add(media, IFM_ETHER | IFM_2500_T, 0, NULL);
if (phy_types & (I40E_CAP_PHY_TYPE_5GBASE_T))
ifmedia_add(media, IFM_ETHER | IFM_5000_T, 0, NULL);
if (phy_types & (I40E_CAP_PHY_TYPE_XAUI) ||
phy_types & (I40E_CAP_PHY_TYPE_XFI) ||
phy_types & (I40E_CAP_PHY_TYPE_10GBASE_SFPP_CU))
@ -1891,6 +1899,13 @@ ixl_update_stats_counters(struct ixl_pf *pf)
ixl_stat_update32(hw, I40E_GLPRT_RJC(hw->port),
pf->stat_offsets_loaded,
&osd->rx_jabber, &nsd->rx_jabber);
/* EEE */
i40e_get_phy_lpi_status(hw, nsd);
i40e_lpi_stat_update(hw, pf->stat_offsets_loaded,
&osd->tx_lpi_count, &nsd->tx_lpi_count,
&osd->rx_lpi_count, &nsd->rx_lpi_count);
pf->stat_offsets_loaded = true;
/* End hw stats */
@ -2154,6 +2169,8 @@ ixl_add_device_sysctls(struct ixl_pf *pf)
struct sysctl_oid *fec_node;
struct sysctl_oid_list *fec_list;
struct sysctl_oid *eee_node;
struct sysctl_oid_list *eee_list;
/* Set up sysctls */
SYSCTL_ADD_PROC(ctx, ctx_list,
@ -2246,6 +2263,32 @@ ixl_add_device_sysctls(struct ixl_pf *pf)
OID_AUTO, "fw_lldp", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_NEEDGIANT,
pf, 0, ixl_sysctl_fw_lldp, "I", IXL_SYSCTL_HELP_FW_LLDP);
eee_node = SYSCTL_ADD_NODE(ctx, ctx_list,
OID_AUTO, "eee", CTLFLAG_RD | CTLFLAG_MPSAFE, NULL,
"Energy Efficient Ethernet (EEE) Sysctls");
eee_list = SYSCTL_CHILDREN(eee_node);
SYSCTL_ADD_PROC(ctx, eee_list,
OID_AUTO, "enable", CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE,
pf, 0, ixl_sysctl_eee_enable, "I",
"Enable Energy Efficient Ethernet (EEE)");
SYSCTL_ADD_UINT(ctx, eee_list, OID_AUTO, "tx_lpi_status",
CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.tx_lpi_status, 0,
"TX LPI status");
SYSCTL_ADD_UINT(ctx, eee_list, OID_AUTO, "rx_lpi_status",
CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.rx_lpi_status, 0,
"RX LPI status");
SYSCTL_ADD_UQUAD(ctx, eee_list, OID_AUTO, "tx_lpi_count",
CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.tx_lpi_count,
"TX LPI count");
SYSCTL_ADD_UQUAD(ctx, eee_list, OID_AUTO, "rx_lpi_count",
CTLFLAG_RD | CTLFLAG_MPSAFE, &pf->stats.rx_lpi_count,
"RX LPI count");
/* Add sysctls meant to print debug information, but don't list them
* in "sysctl -a" output. */
debug_node = SYSCTL_ADD_NODE(ctx, ctx_list,
@ -2375,6 +2418,8 @@ ixl_link_speed_string(enum i40e_aq_link_speed link_speed)
"40 Gbps",
"20 Gbps",
"25 Gbps",
"2.5 Gbps",
"5 Gbps"
};
int index;
@ -2397,6 +2442,12 @@ ixl_link_speed_string(enum i40e_aq_link_speed link_speed)
case I40E_LINK_SPEED_25GB:
index = 6;
break;
case I40E_LINK_SPEED_2_5GB:
index = 7;
break;
case I40E_LINK_SPEED_5GB:
index = 8;
break;
case I40E_LINK_SPEED_UNKNOWN:
default:
index = 0;
@ -2430,14 +2481,16 @@ ixl_sysctl_current_speed(SYSCTL_HANDLER_ARGS)
static u8
ixl_convert_sysctl_aq_link_speed(u8 speeds, bool to_aq)
{
#define SPEED_MAP_SIZE 6
#define SPEED_MAP_SIZE 8
static u16 speedmap[SPEED_MAP_SIZE] = {
(I40E_LINK_SPEED_100MB | (0x1 << 8)),
(I40E_LINK_SPEED_1GB | (0x2 << 8)),
(I40E_LINK_SPEED_10GB | (0x4 << 8)),
(I40E_LINK_SPEED_20GB | (0x8 << 8)),
(I40E_LINK_SPEED_25GB | (0x10 << 8)),
(I40E_LINK_SPEED_40GB | (0x20 << 8))
(I40E_LINK_SPEED_40GB | (0x20 << 8)),
(I40E_LINK_SPEED_2_5GB | (0x40 << 8)),
(I40E_LINK_SPEED_5GB | (0x80 << 8)),
};
u8 retval = 0;
@ -2509,6 +2562,8 @@ ixl_set_advertised_speeds(struct ixl_pf *pf, int speeds, bool from_aq)
** 0x8 - 20G
** 0x10 - 25G
** 0x20 - 40G
** 0x40 - 2.5G
** 0x80 - 5G
*/
static int
ixl_sysctl_supported_speeds(SYSCTL_HANDLER_ARGS)
@ -2528,6 +2583,8 @@ ixl_sysctl_supported_speeds(SYSCTL_HANDLER_ARGS)
** 0x8 - advertise 20G
** 0x10 - advertise 25G
** 0x20 - advertise 40G
** 0x40 - advertise 2.5G
** 0x80 - advertise 5G
**
** Set to 0 to disable link
*/
@ -2552,7 +2609,7 @@ ixl_sysctl_set_advertise(SYSCTL_HANDLER_ARGS)
}
/* Error out if bits outside of possible flag range are set */
if ((requested_ls & ~((u8)0x3F)) != 0) {
if ((requested_ls & ~((u8)0xFF)) != 0) {
device_printf(dev, "Input advertised speed out of range; "
"valid flags are: 0x%02x\n",
ixl_convert_sysctl_aq_link_speed(pf->supported_speeds, false));
@ -2591,6 +2648,10 @@ ixl_max_aq_speed_to_value(u8 link_speeds)
return IF_Gbps(20);
if (link_speeds & I40E_LINK_SPEED_10GB)
return IF_Gbps(10);
if (link_speeds & I40E_LINK_SPEED_5GB)
return IF_Gbps(5);
if (link_speeds & I40E_LINK_SPEED_2_5GB)
return IF_Mbps(2500);
if (link_speeds & I40E_LINK_SPEED_1GB)
return IF_Gbps(1);
if (link_speeds & I40E_LINK_SPEED_100MB)
@ -2875,8 +2936,8 @@ ixl_phy_type_string(u32 bit_pos, bool ext)
"25GBASE-LR",
"25GBASE-AOC",
"25GBASE-ACC",
"Reserved (6)",
"Reserved (7)"
"2.5GBASE-T",
"5GBASE-T"
};
if (ext && bit_pos > 7) return "Invalid_Ext";
@ -4103,6 +4164,43 @@ ixl_sysctl_fw_lldp(SYSCTL_HANDLER_ARGS)
return ixl_start_fw_lldp(pf);
}
static int
ixl_sysctl_eee_enable(SYSCTL_HANDLER_ARGS)
{
struct ixl_pf *pf = (struct ixl_pf *)arg1;
int state, new_state;
int sysctl_handle_status = 0;
enum i40e_status_code cmd_status;
/* Init states' values */
state = new_state = (!!(pf->state & IXL_PF_STATE_EEE_ENABLED));
/* Get requested mode */
sysctl_handle_status = sysctl_handle_int(oidp, &new_state, 0, req);
if ((sysctl_handle_status) || (req->newptr == NULL))
return (sysctl_handle_status);
/* Check if state has changed */
if (new_state == state)
return (0);
/* Set new state */
cmd_status = i40e_enable_eee(&pf->hw, (bool)(!!new_state));
/* Save new state or report error */
if (!cmd_status) {
if (new_state == 0)
atomic_clear_32(&pf->state, IXL_PF_STATE_EEE_ENABLED);
else
atomic_set_32(&pf->state, IXL_PF_STATE_EEE_ENABLED);
} else if (cmd_status == I40E_ERR_CONFIG)
return (EPERM);
else
return (EIO);
return (0);
}
int
ixl_attach_get_link_status(struct ixl_pf *pf)
{

View File

@ -77,12 +77,14 @@ enum virtchnl_status_code {
VIRTCHNL_STATUS_NOT_SUPPORTED = -64,
};
#define VIRTCHNL_LINK_SPEED_2_5GB_SHIFT 0x0
#define VIRTCHNL_LINK_SPEED_100MB_SHIFT 0x1
#define VIRTCHNL_LINK_SPEED_1000MB_SHIFT 0x2
#define VIRTCHNL_LINK_SPEED_10GB_SHIFT 0x3
#define VIRTCHNL_LINK_SPEED_40GB_SHIFT 0x4
#define VIRTCHNL_LINK_SPEED_20GB_SHIFT 0x5
#define VIRTCHNL_LINK_SPEED_25GB_SHIFT 0x6
#define VIRTCHNL_LINK_SPEED_5GB_SHIFT 0x7
enum virtchnl_link_speed {
VIRTCHNL_LINK_SPEED_UNKNOWN = 0,
@ -92,6 +94,8 @@ enum virtchnl_link_speed {
VIRTCHNL_LINK_SPEED_40GB = BIT(VIRTCHNL_LINK_SPEED_40GB_SHIFT),
VIRTCHNL_LINK_SPEED_20GB = BIT(VIRTCHNL_LINK_SPEED_20GB_SHIFT),
VIRTCHNL_LINK_SPEED_25GB = BIT(VIRTCHNL_LINK_SPEED_25GB_SHIFT),
VIRTCHNL_LINK_SPEED_2_5GB = BIT(VIRTCHNL_LINK_SPEED_2_5GB_SHIFT),
VIRTCHNL_LINK_SPEED_5GB = BIT(VIRTCHNL_LINK_SPEED_5GB_SHIFT),
};
/* for hsplit_0 field of Rx HMC context */