Commit 9bc4a1cc authored by David S. Miller's avatar David S. Miller

Merge branch '10GbE' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue

Jeff Kirsher says:

====================
10GbE Intel Wired LAN Driver Updates 2016-07-22

This series contains updates to ixgbe and ixgbevf only.

Emil fixes the NACK check in ixgbevf_set_uc_addr_vf() for instances where
the index is not equal to zero.  Fixes an issue where mac->ops.setup_fc
can be NULL for backplanes which can cause the driver to crash on load.

Don fixes the second parameter of the LED functions, which is the index to
the LED we are interested in affecting.  Fixed variable to store register
reads to unsigned integer.  Adds support for the new x553 hardware into
ixgbevf.  Fixed a missing rtnl lock around ixgbevf_reinit_locked().
Fixed an issue where in ixgbevf_reset_subtask() was not verifying that
the port has been removed.  Cleans up the initial crosstalk fix, since
the SFP that indicates the presence of a SFP+ module changes between
hardware types.

Babu Moger fixes typo in freeing IRQ, since the array subscript increments
after the execution of the statement.

Wei Yongjun adds the missing destroy_workqueue() before returning from
ixgbe_init_module() in the error handling case.

Tony adds range checking for setting the MTU from the VF, where the PF can
return a NACK but this was not passed on to the VF, so propagate the
results from the PF to the VF so errors can be reported.  Consolidates
mailbox read and write functions, since the recent changes to
ixgbevf_write_msg_read_ack(), other functions are performing the same
operations done here.

Colin Ian King removes a redundant check on ret_val, since ret_val has
not changed since the previous check.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents d3e6952c aac9e053
...@@ -804,8 +804,6 @@ struct ixgbe_adapter { ...@@ -804,8 +804,6 @@ struct ixgbe_adapter {
#define IXGBE_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */ #define IXGBE_RSS_KEY_SIZE 40 /* size of RSS Hash Key in bytes */
u32 rss_key[IXGBE_RSS_KEY_SIZE / sizeof(u32)]; u32 rss_key[IXGBE_RSS_KEY_SIZE / sizeof(u32)];
bool need_crosstalk_fix;
}; };
static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter) static inline u8 ixgbe_max_rss_indices(struct ixgbe_adapter *adapter)
......
...@@ -1813,9 +1813,6 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw) ...@@ -1813,9 +1813,6 @@ static s32 ixgbe_start_hw_82599(struct ixgbe_hw *hw)
/* We need to run link autotry after the driver loads */ /* We need to run link autotry after the driver loads */
hw->mac.autotry_restart = true; hw->mac.autotry_restart = true;
if (ret_val)
return ret_val;
return ixgbe_verify_fw_version_82599(hw); return ixgbe_verify_fw_version_82599(hw);
} }
......
...@@ -277,6 +277,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) ...@@ -277,6 +277,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
{ {
s32 ret_val; s32 ret_val;
u32 ctrl_ext; u32 ctrl_ext;
u16 device_caps;
/* Set the media type */ /* Set the media type */
hw->phy.media_type = hw->mac.ops.get_media_type(hw); hw->phy.media_type = hw->mac.ops.get_media_type(hw);
...@@ -301,6 +302,22 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) ...@@ -301,6 +302,22 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
if (ret_val) if (ret_val)
return ret_val; return ret_val;
/* Cashe bit indicating need for crosstalk fix */
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
hw->mac.ops.get_device_caps(hw, &device_caps);
if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR)
hw->need_crosstalk_fix = false;
else
hw->need_crosstalk_fix = true;
break;
default:
hw->need_crosstalk_fix = false;
break;
}
/* Clear adapter stopped flag */ /* Clear adapter stopped flag */
hw->adapter_stopped = false; hw->adapter_stopped = false;
...@@ -763,6 +780,9 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index) ...@@ -763,6 +780,9 @@ s32 ixgbe_led_on_generic(struct ixgbe_hw *hw, u32 index)
{ {
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
if (index > 3)
return IXGBE_ERR_PARAM;
/* To turn on the LED, set mode to ON. */ /* To turn on the LED, set mode to ON. */
led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index); led_reg |= IXGBE_LED_ON << IXGBE_LED_MODE_SHIFT(index);
...@@ -781,6 +801,9 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index) ...@@ -781,6 +801,9 @@ s32 ixgbe_led_off_generic(struct ixgbe_hw *hw, u32 index)
{ {
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
if (index > 3)
return IXGBE_ERR_PARAM;
/* To turn off the LED, set mode to OFF. */ /* To turn off the LED, set mode to OFF. */
led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index); led_reg |= IXGBE_LED_OFF << IXGBE_LED_MODE_SHIFT(index);
...@@ -2657,7 +2680,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw) ...@@ -2657,7 +2680,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw)
**/ **/
s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw) s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw)
{ {
int secrxreg; u32 secrxreg;
secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL); secrxreg = IXGBE_READ_REG(hw, IXGBE_SECRXCTRL);
secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS; secrxreg &= ~IXGBE_SECRXCTRL_RX_DIS;
...@@ -2698,6 +2721,9 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) ...@@ -2698,6 +2721,9 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
bool locked = false; bool locked = false;
s32 ret_val; s32 ret_val;
if (index > 3)
return IXGBE_ERR_PARAM;
/* /*
* Link must be up to auto-blink the LEDs; * Link must be up to auto-blink the LEDs;
* Force it if link is down. * Force it if link is down.
...@@ -2741,6 +2767,9 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) ...@@ -2741,6 +2767,9 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
bool locked = false; bool locked = false;
s32 ret_val; s32 ret_val;
if (index > 3)
return IXGBE_ERR_PARAM;
ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg); ret_val = hw->mac.ops.prot_autoc_read(hw, &locked, &autoc_reg);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
...@@ -3187,6 +3216,31 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw) ...@@ -3187,6 +3216,31 @@ s32 ixgbe_clear_vfta_generic(struct ixgbe_hw *hw)
return 0; return 0;
} }
/**
* ixgbe_need_crosstalk_fix - Determine if we need to do cross talk fix
* @hw: pointer to hardware structure
*
* Contains the logic to identify if we need to verify link for the
* crosstalk fix
**/
static bool ixgbe_need_crosstalk_fix(struct ixgbe_hw *hw)
{
/* Does FW say we need the fix */
if (!hw->need_crosstalk_fix)
return false;
/* Only consider SFP+ PHYs i.e. media type fiber */
switch (hw->mac.ops.get_media_type(hw)) {
case ixgbe_media_type_fiber:
case ixgbe_media_type_fiber_qsfp:
break;
default:
return false;
}
return true;
}
/** /**
* ixgbe_check_mac_link_generic - Determine link and speed status * ixgbe_check_mac_link_generic - Determine link and speed status
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -3202,6 +3256,35 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed, ...@@ -3202,6 +3256,35 @@ s32 ixgbe_check_mac_link_generic(struct ixgbe_hw *hw, ixgbe_link_speed *speed,
u32 links_reg, links_orig; u32 links_reg, links_orig;
u32 i; u32 i;
/* If Crosstalk fix enabled do the sanity check of making sure
* the SFP+ cage is full.
*/
if (ixgbe_need_crosstalk_fix(hw)) {
u32 sfp_cage_full;
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
IXGBE_ESDP_SDP2;
break;
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
IXGBE_ESDP_SDP0;
break;
default:
/* sanity check - No SFP+ devices here */
sfp_cage_full = false;
break;
}
if (!sfp_cage_full) {
*link_up = false;
*speed = IXGBE_LINK_SPEED_UNKNOWN;
return 0;
}
}
/* clear the old state */ /* clear the old state */
links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS); links_orig = IXGBE_READ_REG(hw, IXGBE_LINKS);
......
...@@ -2204,11 +2204,11 @@ static int ixgbe_set_phys_id(struct net_device *netdev, ...@@ -2204,11 +2204,11 @@ static int ixgbe_set_phys_id(struct net_device *netdev,
return 2; return 2;
case ETHTOOL_ID_ON: case ETHTOOL_ID_ON:
hw->mac.ops.led_on(hw, IXGBE_LED_ON); hw->mac.ops.led_on(hw, hw->bus.func);
break; break;
case ETHTOOL_ID_OFF: case ETHTOOL_ID_OFF:
hw->mac.ops.led_off(hw, IXGBE_LED_ON); hw->mac.ops.led_off(hw, hw->bus.func);
break; break;
case ETHTOOL_ID_INACTIVE: case ETHTOOL_ID_INACTIVE:
......
...@@ -3084,7 +3084,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter) ...@@ -3084,7 +3084,7 @@ static void ixgbe_free_irq(struct ixgbe_adapter *adapter)
free_irq(entry->vector, q_vector); free_irq(entry->vector, q_vector);
} }
free_irq(adapter->msix_entries[vector++].vector, adapter); free_irq(adapter->msix_entries[vector].vector, adapter);
} }
/** /**
...@@ -5625,7 +5625,6 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) ...@@ -5625,7 +5625,6 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
struct pci_dev *pdev = adapter->pdev; struct pci_dev *pdev = adapter->pdev;
unsigned int rss, fdir; unsigned int rss, fdir;
u32 fwsm; u32 fwsm;
u16 device_caps;
int i; int i;
/* PCI config space info */ /* PCI config space info */
...@@ -5771,22 +5770,6 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter) ...@@ -5771,22 +5770,6 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
adapter->tx_ring_count = IXGBE_DEFAULT_TXD; adapter->tx_ring_count = IXGBE_DEFAULT_TXD;
adapter->rx_ring_count = IXGBE_DEFAULT_RXD; adapter->rx_ring_count = IXGBE_DEFAULT_RXD;
/* Cache bit indicating need for crosstalk fix */
switch (hw->mac.type) {
case ixgbe_mac_82599EB:
case ixgbe_mac_X550EM_x:
case ixgbe_mac_x550em_a:
hw->mac.ops.get_device_caps(hw, &device_caps);
if (device_caps & IXGBE_DEVICE_CAPS_NO_CROSSTALK_WR)
adapter->need_crosstalk_fix = false;
else
adapter->need_crosstalk_fix = true;
break;
default:
adapter->need_crosstalk_fix = false;
break;
}
/* set default work limits */ /* set default work limits */
adapter->tx_work_limit = IXGBE_DEFAULT_TX_WORK; adapter->tx_work_limit = IXGBE_DEFAULT_TX_WORK;
...@@ -6707,18 +6690,6 @@ static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter) ...@@ -6707,18 +6690,6 @@ static void ixgbe_watchdog_update_link(struct ixgbe_adapter *adapter)
link_up = true; link_up = true;
} }
/* If Crosstalk fix enabled do the sanity check of making sure
* the SFP+ cage is empty.
*/
if (adapter->need_crosstalk_fix) {
u32 sfp_cage_full;
sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
IXGBE_ESDP_SDP2;
if (ixgbe_is_sfp(hw) && link_up && !sfp_cage_full)
link_up = false;
}
if (adapter->ixgbe_ieee_pfc) if (adapter->ixgbe_ieee_pfc)
pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en); pfc_en |= !!(adapter->ixgbe_ieee_pfc->pfc_en);
...@@ -7065,16 +7036,6 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter) ...@@ -7065,16 +7036,6 @@ static void ixgbe_sfp_detection_subtask(struct ixgbe_adapter *adapter)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
s32 err; s32 err;
/* If crosstalk fix enabled verify the SFP+ cage is full */
if (adapter->need_crosstalk_fix) {
u32 sfp_cage_full;
sfp_cage_full = IXGBE_READ_REG(hw, IXGBE_ESDP) &
IXGBE_ESDP_SDP2;
if (!sfp_cage_full)
return;
}
/* not searching for SFP so there is nothing to do here */ /* not searching for SFP so there is nothing to do here */
if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) && if (!(adapter->flags2 & IXGBE_FLAG2_SEARCH_FOR_SFP) &&
!(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET)) !(adapter->flags2 & IXGBE_FLAG2_SFP_NEEDS_RESET))
...@@ -10112,6 +10073,7 @@ static int __init ixgbe_init_module(void) ...@@ -10112,6 +10073,7 @@ static int __init ixgbe_init_module(void)
ret = pci_register_driver(&ixgbe_driver); ret = pci_register_driver(&ixgbe_driver);
if (ret) { if (ret) {
destroy_workqueue(ixgbe_wq);
ixgbe_dbg_exit(); ixgbe_dbg_exit();
return ret; return ret;
} }
......
...@@ -3525,6 +3525,7 @@ struct ixgbe_hw { ...@@ -3525,6 +3525,7 @@ struct ixgbe_hw {
bool force_full_reset; bool force_full_reset;
bool allow_unsupported_sfp; bool allow_unsupported_sfp;
bool wol_enabled; bool wol_enabled;
bool need_crosstalk_fix;
}; };
struct ixgbe_info { struct ixgbe_info {
......
...@@ -1618,6 +1618,8 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) ...@@ -1618,6 +1618,8 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
{ {
struct ixgbe_mac_info *mac = &hw->mac; struct ixgbe_mac_info *mac = &hw->mac;
mac->ops.setup_fc = ixgbe_setup_fc_x550em;
switch (mac->ops.get_media_type(hw)) { switch (mac->ops.get_media_type(hw)) {
case ixgbe_media_type_fiber: case ixgbe_media_type_fiber:
/* CS4227 does not support autoneg, so disable the laser control /* CS4227 does not support autoneg, so disable the laser control
...@@ -1627,7 +1629,6 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) ...@@ -1627,7 +1629,6 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
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_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;
switch (hw->device_id) { switch (hw->device_id) {
case IXGBE_DEV_ID_X550EM_A_SFP_N: case IXGBE_DEV_ID_X550EM_A_SFP_N:
mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_n; mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_n;
...@@ -1655,7 +1656,6 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) ...@@ -1655,7 +1656,6 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
mac->ops.setup_link = ixgbe_setup_sgmii; mac->ops.setup_link = ixgbe_setup_sgmii;
break; break;
default: default:
mac->ops.setup_fc = ixgbe_setup_fc_x550em;
break; break;
} }
} }
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
#define IXGBE_DEV_ID_X540_VF 0x1515 #define IXGBE_DEV_ID_X540_VF 0x1515
#define IXGBE_DEV_ID_X550_VF 0x1565 #define IXGBE_DEV_ID_X550_VF 0x1565
#define IXGBE_DEV_ID_X550EM_X_VF 0x15A8 #define IXGBE_DEV_ID_X550EM_X_VF 0x15A8
#define IXGBE_DEV_ID_X550EM_A_VF 0x15C5
#define IXGBE_DEV_ID_82599_VF_HV 0x152E #define IXGBE_DEV_ID_82599_VF_HV 0x152E
#define IXGBE_DEV_ID_X540_VF_HV 0x1530 #define IXGBE_DEV_ID_X540_VF_HV 0x1530
......
...@@ -457,6 +457,7 @@ enum ixgbevf_boards { ...@@ -457,6 +457,7 @@ enum ixgbevf_boards {
board_X550_vf_hv, board_X550_vf_hv,
board_X550EM_x_vf, board_X550EM_x_vf,
board_X550EM_x_vf_hv, board_X550EM_x_vf_hv,
board_x550em_a_vf,
}; };
enum ixgbevf_xcast_modes { enum ixgbevf_xcast_modes {
...@@ -470,6 +471,7 @@ extern const struct ixgbevf_info ixgbevf_X540_vf_info; ...@@ -470,6 +471,7 @@ extern const struct ixgbevf_info ixgbevf_X540_vf_info;
extern const struct ixgbevf_info ixgbevf_X550_vf_info; extern const struct ixgbevf_info ixgbevf_X550_vf_info;
extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info; extern const struct ixgbevf_info ixgbevf_X550EM_x_vf_info;
extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops; extern const struct ixgbe_mbx_operations ixgbevf_mbx_ops;
extern const struct ixgbevf_info ixgbevf_x550em_a_vf_info;
extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info; extern const struct ixgbevf_info ixgbevf_82599_vf_hv_info;
extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info; extern const struct ixgbevf_info ixgbevf_X540_vf_hv_info;
......
...@@ -56,7 +56,7 @@ const char ixgbevf_driver_name[] = "ixgbevf"; ...@@ -56,7 +56,7 @@ const char ixgbevf_driver_name[] = "ixgbevf";
static const char ixgbevf_driver_string[] = static const char ixgbevf_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver"; "Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver";
#define DRV_VERSION "2.12.1-k" #define DRV_VERSION "3.2.2-k"
const char ixgbevf_driver_version[] = DRV_VERSION; const char ixgbevf_driver_version[] = DRV_VERSION;
static char ixgbevf_copyright[] = static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation."; "Copyright (c) 2009 - 2015 Intel Corporation.";
...@@ -70,6 +70,7 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = { ...@@ -70,6 +70,7 @@ static const struct ixgbevf_info *ixgbevf_info_tbl[] = {
[board_X550_vf_hv] = &ixgbevf_X550_vf_hv_info, [board_X550_vf_hv] = &ixgbevf_X550_vf_hv_info,
[board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info, [board_X550EM_x_vf] = &ixgbevf_X550EM_x_vf_info,
[board_X550EM_x_vf_hv] = &ixgbevf_X550EM_x_vf_hv_info, [board_X550EM_x_vf_hv] = &ixgbevf_X550EM_x_vf_hv_info,
[board_x550em_a_vf] = &ixgbevf_x550em_a_vf_info,
}; };
/* ixgbevf_pci_tbl - PCI Device ID Table /* ixgbevf_pci_tbl - PCI Device ID Table
...@@ -89,6 +90,7 @@ static const struct pci_device_id ixgbevf_pci_tbl[] = { ...@@ -89,6 +90,7 @@ static const struct pci_device_id ixgbevf_pci_tbl[] = {
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550_VF_HV), board_X550_vf_hv },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf }, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF), board_X550EM_x_vf },
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv}, {PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_X_VF_HV), board_X550EM_x_vf_hv},
{PCI_VDEVICE(INTEL, IXGBE_DEV_ID_X550EM_A_VF), board_x550em_a_vf },
/* required last entry */ /* required last entry */
{0, } {0, }
}; };
...@@ -1800,16 +1802,19 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter, ...@@ -1800,16 +1802,19 @@ static void ixgbevf_configure_rx_ring(struct ixgbevf_adapter *adapter,
**/ **/
static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter) static void ixgbevf_configure_rx(struct ixgbevf_adapter *adapter)
{ {
int i;
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
struct net_device *netdev = adapter->netdev; struct net_device *netdev = adapter->netdev;
int i, ret;
ixgbevf_setup_psrtype(adapter); ixgbevf_setup_psrtype(adapter);
if (hw->mac.type >= ixgbe_mac_X550_vf) if (hw->mac.type >= ixgbe_mac_X550_vf)
ixgbevf_setup_vfmrqc(adapter); ixgbevf_setup_vfmrqc(adapter);
/* notify the PF of our intent to use this size of frame */ /* notify the PF of our intent to use this size of frame */
hw->mac.ops.set_rlpml(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN); ret = hw->mac.ops.set_rlpml(hw, netdev->mtu + ETH_HLEN + ETH_FCS_LEN);
if (ret)
dev_err(&adapter->pdev->dev,
"Failed to set MTU at %d\n", netdev->mtu);
/* Setup the HW Rx Head and Tail Descriptor Pointers and /* Setup the HW Rx Head and Tail Descriptor Pointers and
* the Base and Length of the Rx Descriptor Ring * the Base and Length of the Rx Descriptor Ring
...@@ -2772,12 +2777,15 @@ static void ixgbevf_reset_subtask(struct ixgbevf_adapter *adapter) ...@@ -2772,12 +2777,15 @@ static void ixgbevf_reset_subtask(struct ixgbevf_adapter *adapter)
/* If we're already down or resetting, just bail */ /* If we're already down or resetting, just bail */
if (test_bit(__IXGBEVF_DOWN, &adapter->state) || if (test_bit(__IXGBEVF_DOWN, &adapter->state) ||
test_bit(__IXGBEVF_REMOVING, &adapter->state) ||
test_bit(__IXGBEVF_RESETTING, &adapter->state)) test_bit(__IXGBEVF_RESETTING, &adapter->state))
return; return;
adapter->tx_timeout_count++; adapter->tx_timeout_count++;
rtnl_lock();
ixgbevf_reinit_locked(adapter); ixgbevf_reinit_locked(adapter);
rtnl_unlock();
} }
/** /**
...@@ -3732,6 +3740,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -3732,6 +3740,7 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN; int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE; int max_possible_frame = MAXIMUM_ETHERNET_VLAN_SIZE;
int ret;
switch (adapter->hw.api_version) { switch (adapter->hw.api_version) {
case ixgbe_mbox_api_11: case ixgbe_mbox_api_11:
...@@ -3748,14 +3757,17 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu) ...@@ -3748,14 +3757,17 @@ static int ixgbevf_change_mtu(struct net_device *netdev, int new_mtu)
if ((new_mtu < 68) || (max_frame > max_possible_frame)) if ((new_mtu < 68) || (max_frame > max_possible_frame))
return -EINVAL; return -EINVAL;
/* notify the PF of our intent to use this size of frame */
ret = hw->mac.ops.set_rlpml(hw, max_frame);
if (ret)
return -EINVAL;
hw_dbg(hw, "changing MTU from %d to %d\n", hw_dbg(hw, "changing MTU from %d to %d\n",
netdev->mtu, new_mtu); netdev->mtu, new_mtu);
/* must set new MTU before calling down or up */ /* must set new MTU before calling down or up */
netdev->mtu = new_mtu; netdev->mtu = new_mtu;
/* notify the PF of our intent to use this size of frame */
hw->mac.ops.set_rlpml(hw, max_frame);
return 0; return 0;
} }
......
...@@ -33,6 +33,18 @@ ...@@ -33,6 +33,18 @@
*/ */
#define IXGBE_HV_RESET_OFFSET 0x201 #define IXGBE_HV_RESET_OFFSET 0x201
static inline s32 ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw, u32 *msg,
u32 *retmsg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 retval = mbx->ops.write_posted(hw, msg, size);
if (retval)
return retval;
return mbx->ops.read_posted(hw, retmsg, size);
}
/** /**
* ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx * ixgbevf_start_hw_vf - Prepare hardware for Tx/Rx
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -255,8 +267,7 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr) ...@@ -255,8 +267,7 @@ static s32 ixgbevf_get_mac_addr_vf(struct ixgbe_hw *hw, u8 *mac_addr)
static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx; u32 msgbuf[3], msgbuf_chk;
u32 msgbuf[3];
u8 *msg_addr = (u8 *)(&msgbuf[1]); u8 *msg_addr = (u8 *)(&msgbuf[1]);
s32 ret_val; s32 ret_val;
...@@ -268,19 +279,18 @@ static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr) ...@@ -268,19 +279,18 @@ static s32 ixgbevf_set_uc_addr_vf(struct ixgbe_hw *hw, u32 index, u8 *addr)
*/ */
msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT; msgbuf[0] |= index << IXGBE_VT_MSGINFO_SHIFT;
msgbuf[0] |= IXGBE_VF_SET_MACVLAN; msgbuf[0] |= IXGBE_VF_SET_MACVLAN;
msgbuf_chk = msgbuf[0];
if (addr) if (addr)
ether_addr_copy(msg_addr, addr); ether_addr_copy(msg_addr, addr);
ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
if (!ret_val) ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 3);
ret_val = mbx->ops.read_posted(hw, msgbuf, 3); if (!ret_val) {
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; if (msgbuf[0] == (msgbuf_chk | IXGBE_VT_MSGTYPE_NACK))
return -ENOMEM;
if (!ret_val) }
if (msgbuf[0] ==
(IXGBE_VF_SET_MACVLAN | IXGBE_VT_MSGTYPE_NACK))
ret_val = -ENOMEM;
return ret_val; return ret_val;
} }
...@@ -423,7 +433,6 @@ int ixgbevf_get_rss_key_locked(struct ixgbe_hw *hw, u8 *rss_key) ...@@ -423,7 +433,6 @@ int ixgbevf_get_rss_key_locked(struct ixgbe_hw *hw, u8 *rss_key)
static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
u32 vmdq) u32 vmdq)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 msgbuf[3]; u32 msgbuf[3];
u8 *msg_addr = (u8 *)(&msgbuf[1]); u8 *msg_addr = (u8 *)(&msgbuf[1]);
s32 ret_val; s32 ret_val;
...@@ -431,10 +440,8 @@ static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, ...@@ -431,10 +440,8 @@ static s32 ixgbevf_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
memset(msgbuf, 0, sizeof(msgbuf)); memset(msgbuf, 0, sizeof(msgbuf));
msgbuf[0] = IXGBE_VF_SET_MAC_ADDR; msgbuf[0] = IXGBE_VF_SET_MAC_ADDR;
ether_addr_copy(msg_addr, addr); ether_addr_copy(msg_addr, addr);
ret_val = mbx->ops.write_posted(hw, msgbuf, 3);
if (!ret_val) ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
ret_val = mbx->ops.read_posted(hw, msgbuf, 3);
msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS; msgbuf[0] &= ~IXGBE_VT_MSGTYPE_CTS;
...@@ -468,17 +475,6 @@ static s32 ixgbevf_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr, ...@@ -468,17 +475,6 @@ static s32 ixgbevf_hv_set_rar_vf(struct ixgbe_hw *hw, u32 index, u8 *addr,
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
static void ixgbevf_write_msg_read_ack(struct ixgbe_hw *hw,
u32 *msg, u16 size)
{
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 retmsg[IXGBE_VFMAILBOX_SIZE];
s32 retval = mbx->ops.write_posted(hw, msg, size);
if (!retval)
mbx->ops.read_posted(hw, retmsg, size);
}
/** /**
* ixgbevf_update_mc_addr_list_vf - Update Multicast addresses * ixgbevf_update_mc_addr_list_vf - Update Multicast addresses
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
...@@ -519,7 +515,7 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, ...@@ -519,7 +515,7 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr); vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr);
} }
ixgbevf_write_msg_read_ack(hw, msgbuf, IXGBE_VFMAILBOX_SIZE); ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, IXGBE_VFMAILBOX_SIZE);
return 0; return 0;
} }
...@@ -542,7 +538,6 @@ static s32 ixgbevf_hv_update_mc_addr_list_vf(struct ixgbe_hw *hw, ...@@ -542,7 +538,6 @@ static s32 ixgbevf_hv_update_mc_addr_list_vf(struct ixgbe_hw *hw,
**/ **/
static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 msgbuf[2]; u32 msgbuf[2];
s32 err; s32 err;
...@@ -556,11 +551,7 @@ static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) ...@@ -556,11 +551,7 @@ static s32 ixgbevf_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE; msgbuf[0] = IXGBE_VF_UPDATE_XCAST_MODE;
msgbuf[1] = xcast_mode; msgbuf[1] = xcast_mode;
err = mbx->ops.write_posted(hw, msgbuf, 2); err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
if (err)
return err;
err = mbx->ops.read_posted(hw, msgbuf, 2);
if (err) if (err)
return err; return err;
...@@ -589,7 +580,6 @@ static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode) ...@@ -589,7 +580,6 @@ static s32 ixgbevf_hv_update_xcast_mode(struct ixgbe_hw *hw, int xcast_mode)
static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
bool vlan_on) bool vlan_on)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx;
u32 msgbuf[2]; u32 msgbuf[2];
s32 err; s32 err;
...@@ -598,11 +588,7 @@ static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind, ...@@ -598,11 +588,7 @@ static s32 ixgbevf_set_vfta_vf(struct ixgbe_hw *hw, u32 vlan, u32 vind,
/* Setting the 8 bit field MSG INFO to TRUE indicates "add" */ /* Setting the 8 bit field MSG INFO to TRUE indicates "add" */
msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT; msgbuf[0] |= vlan_on << IXGBE_VT_MSGINFO_SHIFT;
err = mbx->ops.write_posted(hw, msgbuf, 2); err = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
if (err)
goto mbx_err;
err = mbx->ops.read_posted(hw, msgbuf, 2);
if (err) if (err)
goto mbx_err; goto mbx_err;
...@@ -797,13 +783,22 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw, ...@@ -797,13 +783,22 @@ static s32 ixgbevf_hv_check_mac_link_vf(struct ixgbe_hw *hw,
* @hw: pointer to the HW structure * @hw: pointer to the HW structure
* @max_size: value to assign to max frame size * @max_size: value to assign to max frame size
**/ **/
static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) static s32 ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
{ {
u32 msgbuf[2]; u32 msgbuf[2];
s32 ret_val;
msgbuf[0] = IXGBE_VF_SET_LPE; msgbuf[0] = IXGBE_VF_SET_LPE;
msgbuf[1] = max_size; msgbuf[1] = max_size;
ixgbevf_write_msg_read_ack(hw, msgbuf, 2);
ret_val = ixgbevf_write_msg_read_ack(hw, msgbuf, msgbuf, 2);
if (ret_val)
return ret_val;
if ((msgbuf[0] & IXGBE_VF_SET_LPE) &&
(msgbuf[0] & IXGBE_VT_MSGTYPE_NACK))
return IXGBE_ERR_MBX;
return 0;
} }
/** /**
...@@ -812,7 +807,7 @@ static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) ...@@ -812,7 +807,7 @@ static void ixgbevf_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
* @max_size: value to assign to max frame size * @max_size: value to assign to max frame size
* Hyper-V variant. * Hyper-V variant.
**/ **/
static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) static s32 ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
{ {
u32 reg; u32 reg;
...@@ -823,6 +818,8 @@ static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size) ...@@ -823,6 +818,8 @@ static void ixgbevf_hv_set_rlpml_vf(struct ixgbe_hw *hw, u16 max_size)
/* CRC == 4 */ /* CRC == 4 */
reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN); reg |= ((max_size + 4) | IXGBE_RXDCTL_RLPML_EN);
IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg); IXGBE_WRITE_REG(hw, IXGBE_VFRXDCTL(0), reg);
return 0;
} }
/** /**
...@@ -839,11 +836,8 @@ static int ixgbevf_negotiate_api_version_vf(struct ixgbe_hw *hw, int api) ...@@ -839,11 +836,8 @@ static int ixgbevf_negotiate_api_version_vf(struct ixgbe_hw *hw, int api)
msg[0] = IXGBE_VF_API_NEGOTIATE; msg[0] = IXGBE_VF_API_NEGOTIATE;
msg[1] = api; msg[1] = api;
msg[2] = 0; msg[2] = 0;
err = hw->mbx.ops.write_posted(hw, msg, 3);
if (!err)
err = hw->mbx.ops.read_posted(hw, msg, 3);
err = ixgbevf_write_msg_read_ack(hw, msg, msg, 3);
if (!err) { if (!err) {
msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
...@@ -892,11 +886,8 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs, ...@@ -892,11 +886,8 @@ int ixgbevf_get_queues(struct ixgbe_hw *hw, unsigned int *num_tcs,
/* Fetch queue configuration from the PF */ /* Fetch queue configuration from the PF */
msg[0] = IXGBE_VF_GET_QUEUE; msg[0] = IXGBE_VF_GET_QUEUE;
msg[1] = msg[2] = msg[3] = msg[4] = 0; msg[1] = msg[2] = msg[3] = msg[4] = 0;
err = hw->mbx.ops.write_posted(hw, msg, 5);
if (!err)
err = hw->mbx.ops.read_posted(hw, msg, 5);
err = ixgbevf_write_msg_read_ack(hw, msg, msg, 5);
if (!err) { if (!err) {
msg[0] &= ~IXGBE_VT_MSGTYPE_CTS; msg[0] &= ~IXGBE_VT_MSGTYPE_CTS;
...@@ -1005,3 +996,8 @@ const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info = { ...@@ -1005,3 +996,8 @@ const struct ixgbevf_info ixgbevf_X550EM_x_vf_hv_info = {
.mac = ixgbe_mac_X550EM_x_vf, .mac = ixgbe_mac_X550EM_x_vf,
.mac_ops = &ixgbevf_hv_mac_ops, .mac_ops = &ixgbevf_hv_mac_ops,
}; };
const struct ixgbevf_info ixgbevf_x550em_a_vf_info = {
.mac = ixgbe_mac_x550em_a_vf,
.mac_ops = &ixgbevf_mac_ops,
};
...@@ -69,7 +69,7 @@ struct ixgbe_mac_operations { ...@@ -69,7 +69,7 @@ struct ixgbe_mac_operations {
s32 (*disable_mc)(struct ixgbe_hw *); s32 (*disable_mc)(struct ixgbe_hw *);
s32 (*clear_vfta)(struct ixgbe_hw *); s32 (*clear_vfta)(struct ixgbe_hw *);
s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool); s32 (*set_vfta)(struct ixgbe_hw *, u32, u32, bool);
void (*set_rlpml)(struct ixgbe_hw *, u16); s32 (*set_rlpml)(struct ixgbe_hw *, u16);
}; };
enum ixgbe_mac_type { enum ixgbe_mac_type {
...@@ -78,6 +78,7 @@ enum ixgbe_mac_type { ...@@ -78,6 +78,7 @@ enum ixgbe_mac_type {
ixgbe_mac_X540_vf, ixgbe_mac_X540_vf,
ixgbe_mac_X550_vf, ixgbe_mac_X550_vf,
ixgbe_mac_X550EM_x_vf, ixgbe_mac_X550EM_x_vf,
ixgbe_mac_x550em_a_vf,
ixgbe_num_macs ixgbe_num_macs
}; };
......
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