i40e: Add support for 'ethtool -m'
This patch adds support for 'ethtool -m' command which displays information about (Q)SFP+ module plugged into NIC's cage. Signed-off-by: Filip Sadowski <filip.sadowski@intel.com> Tested-by: Andrew Bowers <andrewx.bowers@intel.com> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Esse commit está contido em:
@@ -244,6 +244,8 @@ enum i40e_admin_queue_opc {
|
||||
i40e_aqc_opc_set_phy_debug = 0x0622,
|
||||
i40e_aqc_opc_upload_ext_phy_fm = 0x0625,
|
||||
i40e_aqc_opc_run_phy_activity = 0x0626,
|
||||
i40e_aqc_opc_set_phy_register = 0x0628,
|
||||
i40e_aqc_opc_get_phy_register = 0x0629,
|
||||
|
||||
/* NVM commands */
|
||||
i40e_aqc_opc_nvm_read = 0x0701,
|
||||
@@ -2046,6 +2048,22 @@ struct i40e_aqc_run_phy_activity {
|
||||
|
||||
I40E_CHECK_CMD_LENGTH(i40e_aqc_run_phy_activity);
|
||||
|
||||
/* Set PHY Register command (0x0628) */
|
||||
/* Get PHY Register command (0x0629) */
|
||||
struct i40e_aqc_phy_register_access {
|
||||
u8 phy_interface;
|
||||
#define I40E_AQ_PHY_REG_ACCESS_INTERNAL 0
|
||||
#define I40E_AQ_PHY_REG_ACCESS_EXTERNAL 1
|
||||
#define I40E_AQ_PHY_REG_ACCESS_EXTERNAL_MODULE 2
|
||||
u8 dev_address;
|
||||
u8 reserved1[2];
|
||||
__le32 reg_address;
|
||||
__le32 reg_value;
|
||||
u8 reserved2[4];
|
||||
};
|
||||
|
||||
I40E_CHECK_CMD_LENGTH(i40e_aqc_phy_register_access);
|
||||
|
||||
/* NVM Read command (indirect 0x0701)
|
||||
* NVM Erase commands (direct 0x0702)
|
||||
* NVM Update commands (indirect 0x0703)
|
||||
|
@@ -1041,6 +1041,75 @@ do_retry:
|
||||
wr32(hw, reg_addr, reg_val);
|
||||
}
|
||||
|
||||
/**
|
||||
* i40evf_aq_set_phy_register
|
||||
* @hw: pointer to the hw struct
|
||||
* @phy_select: select which phy should be accessed
|
||||
* @dev_addr: PHY device address
|
||||
* @reg_addr: PHY register address
|
||||
* @reg_val: new register value
|
||||
* @cmd_details: pointer to command details structure or NULL
|
||||
*
|
||||
* Reset the external PHY.
|
||||
**/
|
||||
i40e_status i40evf_aq_set_phy_register(struct i40e_hw *hw,
|
||||
u8 phy_select, u8 dev_addr,
|
||||
u32 reg_addr, u32 reg_val,
|
||||
struct i40e_asq_cmd_details *cmd_details)
|
||||
{
|
||||
struct i40e_aq_desc desc;
|
||||
struct i40e_aqc_phy_register_access *cmd =
|
||||
(struct i40e_aqc_phy_register_access *)&desc.params.raw;
|
||||
i40e_status status;
|
||||
|
||||
i40evf_fill_default_direct_cmd_desc(&desc,
|
||||
i40e_aqc_opc_set_phy_register);
|
||||
|
||||
cmd->phy_interface = phy_select;
|
||||
cmd->dev_address = dev_addr;
|
||||
cmd->reg_address = cpu_to_le32(reg_addr);
|
||||
cmd->reg_value = cpu_to_le32(reg_val);
|
||||
|
||||
status = i40evf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40evf_aq_get_phy_register
|
||||
* @hw: pointer to the hw struct
|
||||
* @phy_select: select which phy should be accessed
|
||||
* @dev_addr: PHY device address
|
||||
* @reg_addr: PHY register address
|
||||
* @reg_val: read register value
|
||||
* @cmd_details: pointer to command details structure or NULL
|
||||
*
|
||||
* Reset the external PHY.
|
||||
**/
|
||||
i40e_status i40evf_aq_get_phy_register(struct i40e_hw *hw,
|
||||
u8 phy_select, u8 dev_addr,
|
||||
u32 reg_addr, u32 *reg_val,
|
||||
struct i40e_asq_cmd_details *cmd_details)
|
||||
{
|
||||
struct i40e_aq_desc desc;
|
||||
struct i40e_aqc_phy_register_access *cmd =
|
||||
(struct i40e_aqc_phy_register_access *)&desc.params.raw;
|
||||
i40e_status status;
|
||||
|
||||
i40evf_fill_default_direct_cmd_desc(&desc,
|
||||
i40e_aqc_opc_get_phy_register);
|
||||
|
||||
cmd->phy_interface = phy_select;
|
||||
cmd->dev_address = dev_addr;
|
||||
cmd->reg_address = cpu_to_le32(reg_addr);
|
||||
|
||||
status = i40evf_asq_send_command(hw, &desc, NULL, 0, cmd_details);
|
||||
if (!status)
|
||||
*reg_val = le32_to_cpu(cmd->reg_value);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/**
|
||||
* i40e_aq_send_msg_to_pf
|
||||
* @hw: pointer to the hardware structure
|
||||
|
@@ -111,6 +111,15 @@ i40e_status i40evf_aq_rx_ctl_write_register(struct i40e_hw *hw,
|
||||
u32 reg_addr, u32 reg_val,
|
||||
struct i40e_asq_cmd_details *cmd_details);
|
||||
void i40evf_write_rx_ctl(struct i40e_hw *hw, u32 reg_addr, u32 reg_val);
|
||||
i40e_status i40e_aq_set_phy_register(struct i40e_hw *hw,
|
||||
u8 phy_select, u8 dev_addr,
|
||||
u32 reg_addr, u32 reg_val,
|
||||
struct i40e_asq_cmd_details *cmd_details);
|
||||
i40e_status i40e_aq_get_phy_register(struct i40e_hw *hw,
|
||||
u8 phy_select, u8 dev_addr,
|
||||
u32 reg_addr, u32 *reg_val,
|
||||
struct i40e_asq_cmd_details *cmd_details);
|
||||
|
||||
i40e_status i40e_read_phy_register(struct i40e_hw *hw, u8 page,
|
||||
u16 reg, u8 phy_addr, u16 *value);
|
||||
i40e_status i40e_write_phy_register(struct i40e_hw *hw, u8 page,
|
||||
|
@@ -401,6 +401,18 @@ struct i40e_nvm_access {
|
||||
u8 data[1];
|
||||
};
|
||||
|
||||
/* (Q)SFP module access definitions */
|
||||
#define I40E_I2C_EEPROM_DEV_ADDR 0xA0
|
||||
#define I40E_I2C_EEPROM_DEV_ADDR2 0xA2
|
||||
#define I40E_MODULE_TYPE_ADDR 0x00
|
||||
#define I40E_MODULE_REVISION_ADDR 0x01
|
||||
#define I40E_MODULE_SFF_8472_COMP 0x5E
|
||||
#define I40E_MODULE_SFF_8472_SWAP 0x5C
|
||||
#define I40E_MODULE_SFF_ADDR_MODE 0x04
|
||||
#define I40E_MODULE_TYPE_QSFP_PLUS 0x0D
|
||||
#define I40E_MODULE_TYPE_QSFP28 0x11
|
||||
#define I40E_MODULE_QSFP_MAX_LEN 640
|
||||
|
||||
/* PCI bus types */
|
||||
enum i40e_bus_type {
|
||||
i40e_bus_type_unknown = 0,
|
||||
|
Referência em uma nova issue
Block a user