ixgbe: Report driver version to firmware for x550 devices

Some x550 devices require the driver version reported to its firmware; this
patch sends the driver version string to the firmware through the host
interface command for x550 devices.

Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
This commit is contained in:
Tony Nguyen 2016-10-26 16:25:18 -07:00 committed by Jeff Kirsher
parent 1fe954b209
commit cb8e051446
5 changed files with 80 additions and 7 deletions

View File

@ -3578,7 +3578,7 @@ void ixgbe_set_rxpba_generic(struct ixgbe_hw *hw,
* Calculates the checksum for some buffer on a specified length. The
* checksum calculated is returned.
**/
static u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
u8 ixgbe_calculate_checksum(u8 *buffer, u32 length)
{
u32 i;
u8 sum = 0;
@ -3722,6 +3722,8 @@ rel_out:
* @min: driver version minor number
* @build: driver version build number
* @sub: driver version sub build number
* @len: length of driver_ver string
* @driver_ver: driver string
*
* Sends driver version number to firmware through the manageability
* block. On success return 0
@ -3729,7 +3731,8 @@ rel_out:
* semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
**/
s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
u8 build, u8 sub)
u8 build, u8 sub, __always_unused u16 len,
__always_unused const char *driver_ver)
{
struct ixgbe_hic_drv_info fw_cmd;
int i;

View File

@ -111,7 +111,8 @@ void ixgbe_set_mac_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
void ixgbe_set_vlan_anti_spoofing(struct ixgbe_hw *hw, bool enable, int vf);
s32 ixgbe_get_device_caps_generic(struct ixgbe_hw *hw, u16 *device_caps);
s32 ixgbe_set_fw_drv_ver_generic(struct ixgbe_hw *hw, u8 maj, u8 min,
u8 build, u8 ver);
u8 build, u8 ver, u16 len, const char *str);
u8 ixgbe_calculate_checksum(u8 *buffer, u32 length);
s32 ixgbe_host_interface_command(struct ixgbe_hw *hw, void *, u32 length,
u32 timeout, bool return_data);
void ixgbe_clear_tx_pending(struct ixgbe_hw *hw);

View File

@ -9833,8 +9833,9 @@ skip_sriov:
* since os does not support feature
*/
if (hw->mac.ops.set_fw_drv_ver)
hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF,
0xFF);
hw->mac.ops.set_fw_drv_ver(hw, 0xFF, 0xFF, 0xFF, 0xFF,
sizeof(ixgbe_driver_version) - 1,
ixgbe_driver_version);
/* add san mac addr to netdev */
ixgbe_add_sanmac_netdev(netdev);

View File

@ -2619,6 +2619,7 @@ enum ixgbe_fdir_pballoc_type {
#define FW_CEM_UNUSED_VER 0x0
#define FW_CEM_MAX_RETRIES 3
#define FW_CEM_RESP_STATUS_SUCCESS 0x1
#define FW_CEM_DRIVER_VERSION_SIZE 39 /* +9 would send 48 bytes to fw */
#define FW_READ_SHADOW_RAM_CMD 0x31
#define FW_READ_SHADOW_RAM_LEN 0x6
#define FW_WRITE_SHADOW_RAM_CMD 0x33
@ -2686,6 +2687,16 @@ struct ixgbe_hic_drv_info {
u16 pad2; /* end spacing to ensure length is mult. of dword2 */
};
struct ixgbe_hic_drv_info2 {
struct ixgbe_hic_hdr hdr;
u8 port_num;
u8 ver_sub;
u8 ver_build;
u8 ver_min;
u8 ver_maj;
char driver_string[FW_CEM_DRIVER_VERSION_SIZE];
};
/* These need to be dword aligned */
struct ixgbe_hic_read_shadow_ram {
union ixgbe_hic_hdr2 hdr;
@ -3362,7 +3373,8 @@ struct ixgbe_mac_operations {
void (*fc_autoneg)(struct ixgbe_hw *);
/* Manageability interface */
s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8);
s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8, u16,
const char *);
s32 (*get_thermal_sensor_data)(struct ixgbe_hw *);
s32 (*init_thermal_sensor_thresh)(struct ixgbe_hw *hw);
void (*disable_rx)(struct ixgbe_hw *hw);

View File

@ -2354,6 +2354,62 @@ static s32 ixgbe_led_off_t_x550em(struct ixgbe_hw *hw, u32 led_idx)
return 0;
}
/**
* ixgbe_set_fw_drv_ver_x550 - Sends driver version to firmware
* @hw: pointer to the HW structure
* @maj: driver version major number
* @min: driver version minor number
* @build: driver version build number
* @sub: driver version sub build number
* @len: length of driver_ver string
* @driver_ver: driver string
*
* Sends driver version number to firmware through the manageability
* block. On success return 0
* else returns IXGBE_ERR_SWFW_SYNC when encountering an error acquiring
* semaphore or IXGBE_ERR_HOST_INTERFACE_COMMAND when command fails.
**/
static s32 ixgbe_set_fw_drv_ver_x550(struct ixgbe_hw *hw, u8 maj, u8 min,
u8 build, u8 sub, u16 len,
const char *driver_ver)
{
struct ixgbe_hic_drv_info2 fw_cmd;
s32 ret_val;
int i;
if (!len || !driver_ver || (len > sizeof(fw_cmd.driver_string)))
return IXGBE_ERR_INVALID_ARGUMENT;
fw_cmd.hdr.cmd = FW_CEM_CMD_DRIVER_INFO;
fw_cmd.hdr.buf_len = FW_CEM_CMD_DRIVER_INFO_LEN + len;
fw_cmd.hdr.cmd_or_resp.cmd_resv = FW_CEM_CMD_RESERVED;
fw_cmd.port_num = (u8)hw->bus.func;
fw_cmd.ver_maj = maj;
fw_cmd.ver_min = min;
fw_cmd.ver_build = build;
fw_cmd.ver_sub = sub;
fw_cmd.hdr.checksum = 0;
memcpy(fw_cmd.driver_string, driver_ver, len);
fw_cmd.hdr.checksum = ixgbe_calculate_checksum((u8 *)&fw_cmd,
(FW_CEM_HDR_LEN + fw_cmd.hdr.buf_len));
for (i = 0; i <= FW_CEM_MAX_RETRIES; i++) {
ret_val = ixgbe_host_interface_command(hw, (u32 *)&fw_cmd,
sizeof(fw_cmd),
IXGBE_HI_COMMAND_TIMEOUT,
true);
if (ret_val)
continue;
if (fw_cmd.hdr.cmd_or_resp.ret_status !=
FW_CEM_RESP_STATUS_SUCCESS)
return IXGBE_ERR_HOST_INTERFACE_COMMAND;
return 0;
}
return ret_val;
}
/** ixgbe_get_lcd_x550em - Determine lowest common denominator
* @hw: pointer to hardware structure
* @lcd_speed: pointer to lowest common link speed
@ -3273,7 +3329,7 @@ static s32 ixgbe_write_phy_reg_x550a(struct ixgbe_hw *hw, u32 reg_addr,
.clear_vfta = &ixgbe_clear_vfta_generic, \
.set_vfta = &ixgbe_set_vfta_generic, \
.fc_enable = &ixgbe_fc_enable_generic, \
.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, \
.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_x550, \
.init_uta_tables = &ixgbe_init_uta_tables_generic, \
.set_mac_anti_spoofing = &ixgbe_set_mac_anti_spoofing, \
.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, \