Commit 810b6d76 authored by David S. Miller's avatar David S. Miller

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-next

Jeff Kirsher says:

====================
This series contains updates to ixgbe, ixgbevf, igbvf, igb and
networking core (bridge).  Most notably is the addition of support
for local link multicast addresses in SR-IOV mode to the networking
core.

Also note, the ixgbe patch "ixgbe: Add support for pipeline reset" and
"ixgbe: Fix return value from macvlan filter function" is revised based
on community feedback.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents f7b4fb22 ac61d515
...@@ -636,6 +636,7 @@ ...@@ -636,6 +636,7 @@
/* NVM Word Offsets */ /* NVM Word Offsets */
#define NVM_COMPAT 0x0003 #define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */ #define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */
#define NVM_VERSION 0x0005
#define NVM_INIT_CONTROL2_REG 0x000F #define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014 #define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_CONTROL3_PORT_A 0x0024 #define NVM_INIT_CONTROL3_PORT_A 0x0024
...@@ -653,6 +654,19 @@ ...@@ -653,6 +654,19 @@
#define NVM_LED_1_CFG 0x001C #define NVM_LED_1_CFG 0x001C
#define NVM_LED_0_2_CFG 0x001F #define NVM_LED_0_2_CFG 0x001F
/* NVM version defines */
#define NVM_ETRACK_WORD 0x0042
#define NVM_COMB_VER_OFF 0x0083
#define NVM_COMB_VER_PTR 0x003d
#define NVM_MAJOR_MASK 0xF000
#define NVM_MINOR_MASK 0x0FF0
#define NVM_BUILD_MASK 0x000F
#define NVM_COMB_VER_MASK 0x00FF
#define NVM_MAJOR_SHIFT 12
#define NVM_MINOR_SHIFT 4
#define NVM_COMB_VER_SHFT 8
#define NVM_VER_INVALID 0xFFFF
#define NVM_ETRACK_SHIFT 16
#define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */ #define E1000_NVM_CFG_DONE_PORT_0 0x040000 /* MNG config cycle done */
#define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */ #define E1000_NVM_CFG_DONE_PORT_1 0x080000 /* ...for second port */
......
...@@ -1391,6 +1391,10 @@ s32 igb_validate_mdi_setting(struct e1000_hw *hw) ...@@ -1391,6 +1391,10 @@ s32 igb_validate_mdi_setting(struct e1000_hw *hw)
{ {
s32 ret_val = 0; s32 ret_val = 0;
/* All MDI settings are supported on 82580 and newer. */
if (hw->mac.type >= e1000_82580)
goto out;
if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) { if (!hw->mac.autoneg && (hw->phy.mdix == 0 || hw->phy.mdix == 3)) {
hw_dbg("Invalid MDI setting detected\n"); hw_dbg("Invalid MDI setting detected\n");
hw->phy.mdix = 1; hw->phy.mdix = 1;
......
...@@ -710,3 +710,73 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw) ...@@ -710,3 +710,73 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
out: out:
return ret_val; return ret_val;
} }
/**
* igb_get_fw_version - Get firmware version information
* @hw: pointer to the HW structure
* @fw_vers: pointer to output structure
*
* unsupported MAC types will return all 0 version structure
**/
void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers)
{
u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset;
u16 fw_version;
memset(fw_vers, 0, sizeof(struct e1000_fw_version));
switch (hw->mac.type) {
case e1000_i211:
return;
case e1000_82575:
case e1000_82576:
case e1000_82580:
case e1000_i350:
case e1000_i210:
break;
default:
return;
}
/* basic eeprom version numbers */
hw->nvm.ops.read(hw, NVM_VERSION, 1, &fw_version);
fw_vers->eep_major = (fw_version & NVM_MAJOR_MASK) >> NVM_MAJOR_SHIFT;
fw_vers->eep_minor = (fw_version & NVM_MINOR_MASK);
/* etrack id */
hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verl);
hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verh);
fw_vers->etrack_id = (eeprom_verh << NVM_ETRACK_SHIFT) | eeprom_verl;
switch (hw->mac.type) {
case e1000_i210:
case e1000_i350:
/* find combo image version */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
if ((comb_offset != 0x0) && (comb_offset != NVM_VER_INVALID)) {
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
+ 1), 1, &comb_verh);
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
1, &comb_verl);
/* get Option Rom version if it exists and is valid */
if ((comb_verh && comb_verl) &&
((comb_verh != NVM_VER_INVALID) &&
(comb_verl != NVM_VER_INVALID))) {
fw_vers->or_valid = true;
fw_vers->or_major =
comb_verl >> NVM_COMB_VER_SHFT;
fw_vers->or_build =
((comb_verl << NVM_COMB_VER_SHFT)
| (comb_verh >> NVM_COMB_VER_SHFT));
fw_vers->or_patch =
comb_verh & NVM_COMB_VER_MASK;
}
}
break;
default:
break;
}
return;
}
...@@ -40,4 +40,20 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data); ...@@ -40,4 +40,20 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_validate_nvm_checksum(struct e1000_hw *hw); s32 igb_validate_nvm_checksum(struct e1000_hw *hw);
s32 igb_update_nvm_checksum(struct e1000_hw *hw); s32 igb_update_nvm_checksum(struct e1000_hw *hw);
struct e1000_fw_version {
u32 etrack_id;
u16 eep_major;
u16 eep_minor;
u8 invm_major;
u8 invm_minor;
u8 invm_img_type;
bool or_valid;
u16 or_major;
u16 or_build;
u16 or_patch;
};
void igb_get_fw_version(struct e1000_hw *hw, struct e1000_fw_version *fw_vers);
#endif #endif
...@@ -1207,20 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw) ...@@ -1207,20 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
u16 phy_data; u16 phy_data;
bool link; bool link;
/* /* I210 and I211 devices support Auto-Crossover in forced operation. */
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI if (phy->type != e1000_phy_i210) {
* forced whenever speed and duplex are forced. /*
*/ * Clear Auto-Crossover to force MDI manually. M88E1000
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data); * requires MDI forced whenever speed and duplex are forced.
if (ret_val) */
goto out; ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL,
&phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE; phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data); ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
if (ret_val) phy_data);
goto out; if (ret_val)
goto out;
hw_dbg("M88E1000 PSCR: %X\n", phy_data); hw_dbg("M88E1000 PSCR: %X\n", phy_data);
}
ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data); ret_val = phy->ops.read_reg(hw, PHY_CONTROL, &phy_data);
if (ret_val) if (ret_val)
......
...@@ -1785,58 +1785,34 @@ static const struct net_device_ops igb_netdev_ops = { ...@@ -1785,58 +1785,34 @@ static const struct net_device_ops igb_netdev_ops = {
void igb_set_fw_version(struct igb_adapter *adapter) void igb_set_fw_version(struct igb_adapter *adapter)
{ {
struct e1000_hw *hw = &adapter->hw; struct e1000_hw *hw = &adapter->hw;
u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset; struct e1000_fw_version fw;
u16 major, build, patch, fw_version;
u32 etrack_id; igb_get_fw_version(hw, &fw);
hw->nvm.ops.read(hw, 5, 1, &fw_version); switch (hw->mac.type) {
if (adapter->hw.mac.type != e1000_i211) { case e1000_i211:
hw->nvm.ops.read(hw, NVM_ETRACK_WORD, 1, &eeprom_verh);
hw->nvm.ops.read(hw, (NVM_ETRACK_WORD + 1), 1, &eeprom_verl);
etrack_id = (eeprom_verh << IGB_ETRACK_SHIFT) | eeprom_verl;
/* combo image version needs to be found */
hw->nvm.ops.read(hw, NVM_COMB_VER_PTR, 1, &comb_offset);
if ((comb_offset != 0x0) &&
(comb_offset != IGB_NVM_VER_INVALID)) {
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset
+ 1), 1, &comb_verh);
hw->nvm.ops.read(hw, (NVM_COMB_VER_OFF + comb_offset),
1, &comb_verl);
/* Only display Option Rom if it exists and is valid */
if ((comb_verh && comb_verl) &&
((comb_verh != IGB_NVM_VER_INVALID) &&
(comb_verl != IGB_NVM_VER_INVALID))) {
major = comb_verl >> IGB_COMB_VER_SHFT;
build = (comb_verl << IGB_COMB_VER_SHFT) |
(comb_verh >> IGB_COMB_VER_SHFT);
patch = comb_verh & IGB_COMB_VER_MASK;
snprintf(adapter->fw_version,
sizeof(adapter->fw_version),
"%d.%d%d, 0x%08x, %d.%d.%d",
(fw_version & IGB_MAJOR_MASK) >>
IGB_MAJOR_SHIFT,
(fw_version & IGB_MINOR_MASK) >>
IGB_MINOR_SHIFT,
(fw_version & IGB_BUILD_MASK),
etrack_id, major, build, patch);
goto out;
}
}
snprintf(adapter->fw_version, sizeof(adapter->fw_version),
"%d.%d%d, 0x%08x",
(fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT,
(fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT,
(fw_version & IGB_BUILD_MASK), etrack_id);
} else {
snprintf(adapter->fw_version, sizeof(adapter->fw_version), snprintf(adapter->fw_version, sizeof(adapter->fw_version),
"%d.%d%d", "%2d.%2d-%d",
(fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT, fw.invm_major, fw.invm_minor, fw.invm_img_type);
(fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT, break;
(fw_version & IGB_BUILD_MASK));
default:
/* if option is rom valid, display its version too */
if (fw.or_valid) {
snprintf(adapter->fw_version,
sizeof(adapter->fw_version),
"%d.%d, 0x%08x, %d.%d.%d",
fw.eep_major, fw.eep_minor, fw.etrack_id,
fw.or_major, fw.or_build, fw.or_patch);
/* no option rom */
} else {
snprintf(adapter->fw_version,
sizeof(adapter->fw_version),
"%d.%d, 0x%08x",
fw.eep_major, fw.eep_minor, fw.etrack_id);
}
break;
} }
out:
return; return;
} }
......
...@@ -455,7 +455,7 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector, ...@@ -455,7 +455,7 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
unsigned char *va, unsigned char *va,
struct sk_buff *skb) struct sk_buff *skb)
{ {
u64 *regval = (u64 *)va; __le64 *regval = (__le64 *)va;
/* /*
* The timestamp is recorded in little endian format. * The timestamp is recorded in little endian format.
......
...@@ -184,6 +184,13 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring, ...@@ -184,6 +184,13 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
buffer_info->page_offset, buffer_info->page_offset,
PAGE_SIZE / 2, PAGE_SIZE / 2,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
if (dma_mapping_error(&pdev->dev,
buffer_info->page_dma)) {
__free_page(buffer_info->page);
buffer_info->page = NULL;
dev_err(&pdev->dev, "RX DMA map failed\n");
break;
}
} }
if (!buffer_info->skb) { if (!buffer_info->skb) {
...@@ -197,6 +204,12 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring, ...@@ -197,6 +204,12 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
buffer_info->dma = dma_map_single(&pdev->dev, skb->data, buffer_info->dma = dma_map_single(&pdev->dev, skb->data,
bufsz, bufsz,
DMA_FROM_DEVICE); DMA_FROM_DEVICE);
if (dma_mapping_error(&pdev->dev, buffer_info->dma)) {
dev_kfree_skb(buffer_info->skb);
buffer_info->skb = NULL;
dev_err(&pdev->dev, "RX DMA map failed\n");
goto no_buffers;
}
} }
/* Refresh the desc even if buffer_addrs didn't change because /* Refresh the desc even if buffer_addrs didn't change because
* each write-back erases this info. */ * each write-back erases this info. */
......
...@@ -693,6 +693,7 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw, ...@@ -693,6 +693,7 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
u16 soft_id); u16 soft_id);
extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input, extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
union ixgbe_atr_input *mask); union ixgbe_atr_input *mask);
extern bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
extern void ixgbe_set_rx_mode(struct net_device *netdev); extern void ixgbe_set_rx_mode(struct net_device *netdev);
#ifdef CONFIG_IXGBE_DCB #ifdef CONFIG_IXGBE_DCB
extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter); extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);
......
...@@ -62,7 +62,6 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw, ...@@ -62,7 +62,6 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
bool autoneg, bool autoneg,
bool autoneg_wait_to_complete); bool autoneg_wait_to_complete);
static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw); static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw);
static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw);
static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
{ {
...@@ -99,9 +98,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw) ...@@ -99,9 +98,8 @@ static void ixgbe_init_mac_link_ops_82599(struct ixgbe_hw *hw)
static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
{ {
s32 ret_val = 0; s32 ret_val = 0;
u32 reg_anlp1 = 0;
u32 i = 0;
u16 list_offset, data_offset, data_value; u16 list_offset, data_offset, data_value;
bool got_lock = false;
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) { if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
ixgbe_init_mac_link_ops_82599(hw); ixgbe_init_mac_link_ops_82599(hw);
...@@ -137,28 +135,36 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw) ...@@ -137,28 +135,36 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
usleep_range(hw->eeprom.semaphore_delay * 1000, usleep_range(hw->eeprom.semaphore_delay * 1000,
hw->eeprom.semaphore_delay * 2000); hw->eeprom.semaphore_delay * 2000);
/* Now restart DSP by setting Restart_AN and clearing LMS */ /* Need SW/FW semaphore around AUTOC writes if LESM on,
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw, * likewise reset_pipeline requires lock as it also writes
IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) | * AUTOC.
IXGBE_AUTOC_AN_RESTART)); */
if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
/* Wait for AN to leave state 0 */ ret_val = hw->mac.ops.acquire_swfw_sync(hw,
for (i = 0; i < 10; i++) { IXGBE_GSSR_MAC_CSR_SM);
usleep_range(4000, 8000); if (ret_val)
reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1); goto setup_sfp_out;
if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
break; got_lock = true;
}
/* Restart DSP and set SFI mode */
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL));
ret_val = ixgbe_reset_pipeline_82599(hw);
if (got_lock) {
hw->mac.ops.release_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
got_lock = false;
} }
if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
hw_dbg(hw, "sfp module setup not complete\n"); if (ret_val) {
hw_dbg(hw, " sfp module setup not complete\n");
ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE; ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
goto setup_sfp_out; goto setup_sfp_out;
} }
/* Restart DSP by setting Restart_AN and return to SFI mode */
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (IXGBE_READ_REG(hw,
IXGBE_AUTOC) | IXGBE_AUTOC_LMS_10G_SERIAL |
IXGBE_AUTOC_AN_RESTART));
} }
setup_sfp_out: setup_sfp_out:
...@@ -394,14 +400,26 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, ...@@ -394,14 +400,26 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
u32 links_reg; u32 links_reg;
u32 i; u32 i;
s32 status = 0; s32 status = 0;
bool got_lock = false;
if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
status = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (status)
goto out;
got_lock = true;
}
/* Restart link */ /* Restart link */
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); ixgbe_reset_pipeline_82599(hw);
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); if (got_lock)
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
/* Only poll for autoneg to complete if specified to do so */ /* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) { if (autoneg_wait_to_complete) {
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) == if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
IXGBE_AUTOC_LMS_KX4_KX_KR || IXGBE_AUTOC_LMS_KX4_KX_KR ||
(autoc_reg & IXGBE_AUTOC_LMS_MASK) == (autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
...@@ -425,6 +443,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw, ...@@ -425,6 +443,7 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
/* Add delay to filter out noises during initial link setup */ /* Add delay to filter out noises during initial link setup */
msleep(50); msleep(50);
out:
return status; return status;
} }
...@@ -779,6 +798,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ...@@ -779,6 +798,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
u32 links_reg; u32 links_reg;
u32 i; u32 i;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN; ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
bool got_lock = false;
/* Check to see if speed passed in is supported. */ /* Check to see if speed passed in is supported. */
status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities, status = hw->mac.ops.get_link_capabilities(hw, &link_capabilities,
...@@ -836,9 +856,26 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw, ...@@ -836,9 +856,26 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
} }
if (autoc != start_autoc) { if (autoc != start_autoc) {
/* Need SW/FW semaphore around AUTOC writes if LESM is on,
* likewise reset_pipeline requires us to hold this lock as
* it also writes to AUTOC.
*/
if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
status = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (status != 0)
goto out;
got_lock = true;
}
/* Restart link */ /* Restart link */
autoc |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc); IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc);
ixgbe_reset_pipeline_82599(hw);
if (got_lock)
hw->mac.ops.release_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
/* Only poll for autoneg to complete if specified to do so */ /* Only poll for autoneg to complete if specified to do so */
if (autoneg_wait_to_complete) { if (autoneg_wait_to_complete) {
...@@ -994,9 +1031,28 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw) ...@@ -994,9 +1031,28 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
hw->mac.orig_autoc2 = autoc2; hw->mac.orig_autoc2 = autoc2;
hw->mac.orig_link_settings_stored = true; hw->mac.orig_link_settings_stored = true;
} else { } else {
if (autoc != hw->mac.orig_autoc) if (autoc != hw->mac.orig_autoc) {
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc | /* Need SW/FW semaphore around AUTOC writes if LESM is
IXGBE_AUTOC_AN_RESTART)); * on, likewise reset_pipeline requires us to hold
* this lock as it also writes to AUTOC.
*/
bool got_lock = false;
if (ixgbe_verify_lesm_fw_enabled_82599(hw)) {
status = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (status)
goto reset_hw_out;
got_lock = true;
}
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, hw->mac.orig_autoc);
ixgbe_reset_pipeline_82599(hw);
if (got_lock)
hw->mac.ops.release_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
}
if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) != if ((autoc2 & IXGBE_AUTOC2_UPPER_MASK) !=
(hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) { (hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
...@@ -1983,7 +2039,7 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw) ...@@ -1983,7 +2039,7 @@ static s32 ixgbe_verify_fw_version_82599(struct ixgbe_hw *hw)
* Returns true if the LESM FW module is present and enabled. Otherwise * Returns true if the LESM FW module is present and enabled. Otherwise
* returns false. Smart Speed must be disabled if LESM FW module is enabled. * returns false. Smart Speed must be disabled if LESM FW module is enabled.
**/ **/
static bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw) bool ixgbe_verify_lesm_fw_enabled_82599(struct ixgbe_hw *hw)
{ {
bool lesm_enabled = false; bool lesm_enabled = false;
u16 fw_offset, fw_lesm_param_offset, fw_lesm_state; u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;
......
...@@ -90,6 +90,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw) ...@@ -90,6 +90,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
s32 ret_val = 0; s32 ret_val = 0;
u32 reg = 0, reg_bp = 0; u32 reg = 0, reg_bp = 0;
u16 reg_cu = 0; u16 reg_cu = 0;
bool got_lock = false;
/* /*
* Validate the requested mode. Strict IEEE mode does not allow * Validate the requested mode. Strict IEEE mode does not allow
...@@ -210,8 +211,29 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw) ...@@ -210,8 +211,29 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
* *
*/ */
if (hw->phy.media_type == ixgbe_media_type_backplane) { if (hw->phy.media_type == ixgbe_media_type_backplane) {
reg_bp |= IXGBE_AUTOC_AN_RESTART; /* Need the SW/FW semaphore around AUTOC writes if 82599 and
* LESM is on, likewise reset_pipeline requries the lock as
* it also writes AUTOC.
*/
if ((hw->mac.type == ixgbe_mac_82599EB) &&
ixgbe_verify_lesm_fw_enabled_82599(hw)) {
ret_val = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (ret_val)
goto out;
got_lock = true;
}
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp); IXGBE_WRITE_REG(hw, IXGBE_AUTOC, reg_bp);
if (hw->mac.type == ixgbe_mac_82599EB)
ixgbe_reset_pipeline_82599(hw);
if (got_lock)
hw->mac.ops.release_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
} else if ((hw->phy.media_type == ixgbe_media_type_copper) && } else if ((hw->phy.media_type == ixgbe_media_type_copper) &&
(ixgbe_device_supports_autoneg_fc(hw) == 0)) { (ixgbe_device_supports_autoneg_fc(hw) == 0)) {
hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE, hw->phy.ops.write_reg(hw, MDIO_AN_ADVERTISE,
...@@ -2616,6 +2638,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) ...@@ -2616,6 +2638,7 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
bool link_up = false; bool link_up = false;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
s32 ret_val = 0;
/* /*
* Link must be up to auto-blink the LEDs; * Link must be up to auto-blink the LEDs;
...@@ -2624,10 +2647,28 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) ...@@ -2624,10 +2647,28 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
hw->mac.ops.check_link(hw, &speed, &link_up, false); hw->mac.ops.check_link(hw, &speed, &link_up, false);
if (!link_up) { if (!link_up) {
/* Need the SW/FW semaphore around AUTOC writes if 82599 and
* LESM is on.
*/
bool got_lock = false;
if ((hw->mac.type == ixgbe_mac_82599EB) &&
ixgbe_verify_lesm_fw_enabled_82599(hw)) {
ret_val = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (ret_val)
goto out;
got_lock = true;
}
autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_AN_RESTART;
autoc_reg |= IXGBE_AUTOC_FLU; autoc_reg |= IXGBE_AUTOC_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
if (got_lock)
hw->mac.ops.release_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
usleep_range(10000, 20000); usleep_range(10000, 20000);
} }
...@@ -2636,7 +2677,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index) ...@@ -2636,7 +2677,8 @@ s32 ixgbe_blink_led_start_generic(struct ixgbe_hw *hw, u32 index)
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
return 0; out:
return ret_val;
} }
/** /**
...@@ -2648,18 +2690,40 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index) ...@@ -2648,18 +2690,40 @@ s32 ixgbe_blink_led_stop_generic(struct ixgbe_hw *hw, u32 index)
{ {
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC); u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL); u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
s32 ret_val = 0;
bool got_lock = false;
/* Need the SW/FW semaphore around AUTOC writes if 82599 and
* LESM is on.
*/
if ((hw->mac.type == ixgbe_mac_82599EB) &&
ixgbe_verify_lesm_fw_enabled_82599(hw)) {
ret_val = hw->mac.ops.acquire_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
if (ret_val)
goto out;
got_lock = true;
}
autoc_reg &= ~IXGBE_AUTOC_FLU; autoc_reg &= ~IXGBE_AUTOC_FLU;
autoc_reg |= IXGBE_AUTOC_AN_RESTART; autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg); IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
if (hw->mac.type == ixgbe_mac_82599EB)
ixgbe_reset_pipeline_82599(hw);
if (got_lock)
hw->mac.ops.release_swfw_sync(hw, IXGBE_GSSR_MAC_CSR_SM);
led_reg &= ~IXGBE_LED_MODE_MASK(index); led_reg &= ~IXGBE_LED_MODE_MASK(index);
led_reg &= ~IXGBE_LED_BLINK(index); led_reg &= ~IXGBE_LED_BLINK(index);
led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index); led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg); IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
return 0; out:
return ret_val;
} }
/** /**
......
...@@ -356,13 +356,37 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) ...@@ -356,13 +356,37 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Transmit Descriptor Formats /* Transmit Descriptor Formats
* *
* Advanced Transmit Descriptor * 82598 Advanced Transmit Descriptor
* +--------------------------------------------------------------+ * +--------------------------------------------------------------+
* 0 | Buffer Address [63:0] | * 0 | Buffer Address [63:0] |
* +--------------------------------------------------------------+ * +--------------------------------------------------------------+
* 8 | PAYLEN | PORTS | IDX | STA | DCMD |DTYP | RSV | DTALEN | * 8 | PAYLEN | POPTS | IDX | STA | DCMD |DTYP | RSV | DTALEN |
* +--------------------------------------------------------------+ * +--------------------------------------------------------------+
* 63 46 45 40 39 36 35 32 31 24 23 20 19 0 * 63 46 45 40 39 36 35 32 31 24 23 20 19 0
*
* 82598 Advanced Transmit Descriptor (Write-Back Format)
* +--------------------------------------------------------------+
* 0 | RSV [63:0] |
* +--------------------------------------------------------------+
* 8 | RSV | STA | NXTSEQ |
* +--------------------------------------------------------------+
* 63 36 35 32 31 0
*
* 82599+ Advanced Transmit Descriptor
* +--------------------------------------------------------------+
* 0 | Buffer Address [63:0] |
* +--------------------------------------------------------------+
* 8 |PAYLEN |POPTS|CC|IDX |STA |DCMD |DTYP |MAC |RSV |DTALEN |
* +--------------------------------------------------------------+
* 63 46 45 40 39 38 36 35 32 31 24 23 20 19 18 17 16 15 0
*
* 82599+ Advanced Transmit Descriptor (Write-Back Format)
* +--------------------------------------------------------------+
* 0 | RSV [63:0] |
* +--------------------------------------------------------------+
* 8 | RSV | STA | RSV |
* +--------------------------------------------------------------+
* 63 36 35 32 31 0
*/ */
for (n = 0; n < adapter->num_tx_queues; n++) { for (n = 0; n < adapter->num_tx_queues; n++) {
...@@ -423,7 +447,9 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) ...@@ -423,7 +447,9 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
dev_info(&adapter->pdev->dev, "RX Rings Dump\n"); dev_info(&adapter->pdev->dev, "RX Rings Dump\n");
/* Advanced Receive Descriptor (Read) Format /* Receive Descriptor Formats
*
* 82598 Advanced Receive Descriptor (Read) Format
* 63 1 0 * 63 1 0
* +-----------------------------------------------------+ * +-----------------------------------------------------+
* 0 | Packet Buffer Address [63:1] |A0/NSE| * 0 | Packet Buffer Address [63:1] |A0/NSE|
...@@ -432,17 +458,40 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter) ...@@ -432,17 +458,40 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
* +-----------------------------------------------------+ * +-----------------------------------------------------+
* *
* *
* Advanced Receive Descriptor (Write-Back) Format * 82598 Advanced Receive Descriptor (Write-Back) Format
* *
* 63 48 47 32 31 30 21 20 16 15 4 3 0 * 63 48 47 32 31 30 21 20 16 15 4 3 0
* +------------------------------------------------------+ * +------------------------------------------------------+
* 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS | * 0 | RSS Hash / |SPH| HDR_LEN | RSV |Packet| RSS |
* | Checksum Ident | | | | Type | Type | * | Packet | IP | | | | Type | Type |
* | Checksum | Ident | | | | | |
* +------------------------------------------------------+ * +------------------------------------------------------+
* 8 | VLAN Tag | Length | Extended Error | Extended Status | * 8 | VLAN Tag | Length | Extended Error | Extended Status |
* +------------------------------------------------------+ * +------------------------------------------------------+
* 63 48 47 32 31 20 19 0 * 63 48 47 32 31 20 19 0
*
* 82599+ Advanced Receive Descriptor (Read) Format
* 63 1 0
* +-----------------------------------------------------+
* 0 | Packet Buffer Address [63:1] |A0/NSE|
* +----------------------------------------------+------+
* 8 | Header Buffer Address [63:1] | DD |
* +-----------------------------------------------------+
*
*
* 82599+ Advanced Receive Descriptor (Write-Back) Format
*
* 63 48 47 32 31 30 21 20 17 16 4 3 0
* +------------------------------------------------------+
* 0 |RSS / Frag Checksum|SPH| HDR_LEN |RSC- |Packet| RSS |
* |/ RTT / PCoE_PARAM | | | CNT | Type | Type |
* |/ Flow Dir Flt ID | | | | | |
* +------------------------------------------------------+
* 8 | VLAN Tag | Length |Extended Error| Xtnd Status/NEXTP |
* +------------------------------------------------------+
* 63 48 47 32 31 20 19 0
*/ */
for (n = 0; n < adapter->num_rx_queues; n++) { for (n = 0; n < adapter->num_rx_queues; n++) {
rx_ring = adapter->rx_ring[n]; rx_ring = adapter->rx_ring[n];
pr_info("------------------------------------\n"); pr_info("------------------------------------\n");
...@@ -1795,7 +1844,7 @@ static struct sk_buff *ixgbe_fetch_rx_buffer(struct ixgbe_ring *rx_ring, ...@@ -1795,7 +1844,7 @@ static struct sk_buff *ixgbe_fetch_rx_buffer(struct ixgbe_ring *rx_ring,
**/ **/
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring, struct ixgbe_ring *rx_ring,
int budget) const int budget)
{ {
unsigned int total_rx_bytes = 0, total_rx_packets = 0; unsigned int total_rx_bytes = 0, total_rx_packets = 0;
#ifdef IXGBE_FCOE #ifdef IXGBE_FCOE
...@@ -1846,7 +1895,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, ...@@ -1846,7 +1895,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
/* probably a little skewed due to removing CRC */ /* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len; total_rx_bytes += skb->len;
total_rx_packets++;
/* populate checksum, timestamp, VLAN, and protocol */ /* populate checksum, timestamp, VLAN, and protocol */
ixgbe_process_skb_fields(rx_ring, rx_desc, skb); ixgbe_process_skb_fields(rx_ring, rx_desc, skb);
...@@ -1879,8 +1927,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, ...@@ -1879,8 +1927,8 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
ixgbe_rx_skb(q_vector, skb); ixgbe_rx_skb(q_vector, skb);
/* update budget accounting */ /* update budget accounting */
budget--; total_rx_packets++;
} while (likely(budget)); } while (likely(total_rx_packets < budget));
u64_stats_update_begin(&rx_ring->syncp); u64_stats_update_begin(&rx_ring->syncp);
rx_ring->stats.packets += total_rx_packets; rx_ring->stats.packets += total_rx_packets;
...@@ -1892,7 +1940,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector, ...@@ -1892,7 +1940,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (cleaned_count) if (cleaned_count)
ixgbe_alloc_rx_buffers(rx_ring, cleaned_count); ixgbe_alloc_rx_buffers(rx_ring, cleaned_count);
return !!budget; return (total_rx_packets < budget);
} }
/** /**
...@@ -4085,11 +4133,8 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter) ...@@ -4085,11 +4133,8 @@ static void ixgbe_up_complete(struct ixgbe_adapter *adapter)
else else
ixgbe_configure_msi_and_legacy(adapter); ixgbe_configure_msi_and_legacy(adapter);
/* enable the optics for both mult-speed fiber and 82599 SFP+ fiber */ /* enable the optics for 82599 SFP+ fiber */
if (hw->mac.ops.enable_tx_laser && if (hw->mac.ops.enable_tx_laser)
((hw->phy.multispeed_fiber) ||
((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
(hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.enable_tx_laser(hw); hw->mac.ops.enable_tx_laser(hw);
clear_bit(__IXGBE_DOWN, &adapter->state); clear_bit(__IXGBE_DOWN, &adapter->state);
...@@ -4411,11 +4456,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter) ...@@ -4411,11 +4456,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
if (!pci_channel_offline(adapter->pdev)) if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter); ixgbe_reset(adapter);
/* power down the optics for multispeed fiber and 82599 SFP+ fiber */ /* power down the optics for 82599 SFP+ fiber */
if (hw->mac.ops.disable_tx_laser && if (hw->mac.ops.disable_tx_laser)
((hw->phy.multispeed_fiber) ||
((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
(hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.disable_tx_laser(hw); hw->mac.ops.disable_tx_laser(hw);
ixgbe_clean_all_tx_rings(adapter); ixgbe_clean_all_tx_rings(adapter);
...@@ -5048,14 +5090,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake) ...@@ -5048,14 +5090,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
if (wufc) { if (wufc) {
ixgbe_set_rx_mode(netdev); ixgbe_set_rx_mode(netdev);
/* /* enable the optics for 82599 SFP+ fiber as we can WoL */
* enable the optics for both mult-speed fiber and if (hw->mac.ops.enable_tx_laser)
* 82599 SFP+ fiber as we can WoL.
*/
if (hw->mac.ops.enable_tx_laser &&
(hw->phy.multispeed_fiber ||
(hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber &&
hw->mac.type == ixgbe_mac_82599EB)))
hw->mac.ops.enable_tx_laser(hw); hw->mac.ops.enable_tx_laser(hw);
/* turn on all-multi mode if wake on multicast is enabled */ /* turn on all-multi mode if wake on multicast is enabled */
...@@ -6965,7 +7001,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[], ...@@ -6965,7 +7001,7 @@ static int ixgbe_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
return -EINVAL; return -EINVAL;
} }
if (is_unicast_ether_addr(addr)) { if (is_unicast_ether_addr(addr) || is_link_local(addr)) {
u32 rar_uc_entries = IXGBE_MAX_PF_MACVLANS; u32 rar_uc_entries = IXGBE_MAX_PF_MACVLANS;
if (netdev_uc_count(dev) < rar_uc_entries) if (netdev_uc_count(dev) < rar_uc_entries)
...@@ -7521,11 +7557,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev, ...@@ -7521,11 +7557,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err) if (err)
goto err_register; goto err_register;
/* power down the optics for multispeed fiber and 82599 SFP+ fiber */ /* power down the optics for 82599 SFP+ fiber */
if (hw->mac.ops.disable_tx_laser && if (hw->mac.ops.disable_tx_laser)
((hw->phy.multispeed_fiber) ||
((hw->mac.ops.get_media_type(hw) == ixgbe_media_type_fiber) &&
(hw->mac.type == ixgbe_mac_82599EB))))
hw->mac.ops.disable_tx_laser(hw); hw->mac.ops.disable_tx_laser(hw);
/* carrier off reporting is important to ethtool even BEFORE open */ /* carrier off reporting is important to ethtool even BEFORE open */
......
...@@ -554,12 +554,14 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector, ...@@ -554,12 +554,14 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
adapter = q_vector->adapter; adapter = q_vector->adapter;
hw = &adapter->hw; hw = &adapter->hw;
if (likely(!ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter)))
return;
tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL); tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
/* Check if we have a valid timestamp and make sure the skb should /* Check if we have a valid timestamp and make sure the skb should
* have been timestamped */ * have been timestamped */
if (likely(!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID) || if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
!ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter)))
return; return;
/* /*
......
...@@ -678,7 +678,7 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter, ...@@ -678,7 +678,7 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
return -1; return -1;
} }
return ixgbe_set_vf_mac(adapter, vf, new_mac); return ixgbe_set_vf_mac(adapter, vf, new_mac) < 0;
} }
static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter, static int ixgbe_set_vf_vlan_msg(struct ixgbe_adapter *adapter,
...@@ -745,7 +745,8 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter, ...@@ -745,7 +745,8 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
e_warn(drv, e_warn(drv,
"VF %d has requested a MACVLAN filter but there is no space for it\n", "VF %d has requested a MACVLAN filter but there is no space for it\n",
vf); vf);
return err;
return err < 0;
} }
static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter, static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,
......
...@@ -2978,6 +2978,11 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev) ...@@ -2978,6 +2978,11 @@ static int ixgbevf_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
#if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD #if PAGE_SIZE > IXGBE_MAX_DATA_PER_TXD
unsigned short f; unsigned short f;
#endif #endif
u8 *dst_mac = skb_header_pointer(skb, 0, 0, NULL);
if (!dst_mac || is_link_local(dst_mac)) {
dev_kfree_skb(skb);
return NETDEV_TX_OK;
}
tx_ring = &adapter->tx_ring[r_idx]; tx_ring = &adapter->tx_ring[r_idx];
......
...@@ -331,6 +331,9 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw, ...@@ -331,6 +331,9 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
netdev_for_each_mc_addr(ha, netdev) { netdev_for_each_mc_addr(ha, netdev) {
if (i == cnt) if (i == cnt)
break; break;
if (is_link_local(ha->addr))
continue;
vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr); vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr);
} }
......
...@@ -51,6 +51,25 @@ extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs, ...@@ -51,6 +51,25 @@ extern struct net_device *alloc_etherdev_mqs(int sizeof_priv, unsigned int txqs,
#define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1) #define alloc_etherdev(sizeof_priv) alloc_etherdev_mq(sizeof_priv, 1)
#define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count) #define alloc_etherdev_mq(sizeof_priv, count) alloc_etherdev_mqs(sizeof_priv, count, count)
/* Reserved Ethernet Addresses per IEEE 802.1Q */
static const u8 br_reserved_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
/**
* is_link_local - Determine if given Eth addr is a link local mcast address.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if address is link local reserved addr (01:80:c2:00:00:0X) per
* IEEE 802.1Q 8.6.3 Frame filtering.
*/
static inline int is_link_local(const unsigned char *dest)
{
__be16 *a = (__be16 *)dest;
static const __be16 *b = (const __be16 *)br_reserved_address;
static const __be16 m = cpu_to_be16(0xfff0);
return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
}
/** /**
* is_zero_ether_addr - Determine if give Ethernet address is all zeros. * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
* @addr: Pointer to a six-byte array containing the Ethernet address * @addr: Pointer to a six-byte array containing the Ethernet address
......
...@@ -358,7 +358,7 @@ void br_dev_setup(struct net_device *dev) ...@@ -358,7 +358,7 @@ void br_dev_setup(struct net_device *dev)
br->bridge_id.prio[0] = 0x80; br->bridge_id.prio[0] = 0x80;
br->bridge_id.prio[1] = 0x00; br->bridge_id.prio[1] = 0x00;
memcpy(br->group_addr, br_group_address, ETH_ALEN); memcpy(br->group_addr, br_reserved_address, ETH_ALEN);
br->stp_enabled = BR_NO_STP; br->stp_enabled = BR_NO_STP;
br->group_fwd_mask = BR_GROUPFWD_DEFAULT; br->group_fwd_mask = BR_GROUPFWD_DEFAULT;
......
...@@ -19,9 +19,6 @@ ...@@ -19,9 +19,6 @@
#include <linux/export.h> #include <linux/export.h>
#include "br_private.h" #include "br_private.h"
/* Bridge group multicast address 802.1d (pg 51). */
const u8 br_group_address[ETH_ALEN] = { 0x01, 0x80, 0xc2, 0x00, 0x00, 0x00 };
/* Hook for brouter */ /* Hook for brouter */
br_should_route_hook_t __rcu *br_should_route_hook __read_mostly; br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
EXPORT_SYMBOL(br_should_route_hook); EXPORT_SYMBOL(br_should_route_hook);
...@@ -127,18 +124,6 @@ static int br_handle_local_finish(struct sk_buff *skb) ...@@ -127,18 +124,6 @@ static int br_handle_local_finish(struct sk_buff *skb)
return 0; /* process further */ return 0; /* process further */
} }
/* Does address match the link local multicast address.
* 01:80:c2:00:00:0X
*/
static inline int is_link_local(const unsigned char *dest)
{
__be16 *a = (__be16 *)dest;
static const __be16 *b = (const __be16 *)br_group_address;
static const __be16 m = cpu_to_be16(0xfff0);
return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | ((a[2] ^ b[2]) & m)) == 0;
}
/* /*
* Return NULL if skb is handled * Return NULL if skb is handled
* note: already called with rcu_read_lock * note: already called with rcu_read_lock
......
...@@ -290,7 +290,6 @@ struct br_input_skb_cb { ...@@ -290,7 +290,6 @@ struct br_input_skb_cb {
pr_debug("%s: " format, (br)->dev->name, ##args) pr_debug("%s: " format, (br)->dev->name, ##args)
extern struct notifier_block br_device_notifier; extern struct notifier_block br_device_notifier;
extern const u8 br_group_address[ETH_ALEN];
/* called under bridge lock */ /* called under bridge lock */
static inline int br_is_root_bridge(const struct net_bridge *br) static inline int br_is_root_bridge(const struct net_bridge *br)
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <linux/capability.h> #include <linux/capability.h>
#include <linux/kernel.h> #include <linux/kernel.h>
#include <linux/netdevice.h> #include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_bridge.h> #include <linux/if_bridge.h>
#include <linux/rtnetlink.h> #include <linux/rtnetlink.h>
#include <linux/spinlock.h> #include <linux/spinlock.h>
...@@ -310,7 +311,7 @@ static ssize_t store_group_addr(struct device *d, ...@@ -310,7 +311,7 @@ static ssize_t store_group_addr(struct device *d,
/* Must be 01:80:c2:00:00:0X */ /* Must be 01:80:c2:00:00:0X */
for (i = 0; i < 5; i++) for (i = 0; i < 5; i++)
if (new_addr[i] != br_group_address[i]) if (new_addr[i] != br_reserved_address[i])
return -EINVAL; return -EINVAL;
if (new_addr[5] & ~0xf) if (new_addr[5] & ~0xf)
......
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