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: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2012-10-31 14:25:33 -04:00
commit 810b6d7638
21 changed files with 415 additions and 148 deletions

View File

@ -636,6 +636,7 @@
/* NVM Word Offsets */
#define NVM_COMPAT 0x0003
#define NVM_ID_LED_SETTINGS 0x0004 /* SERDES output amplitude */
#define NVM_VERSION 0x0005
#define NVM_INIT_CONTROL2_REG 0x000F
#define NVM_INIT_CONTROL3_PORT_B 0x0014
#define NVM_INIT_CONTROL3_PORT_A 0x0024
@ -653,6 +654,19 @@
#define NVM_LED_1_CFG 0x001C
#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_1 0x080000 /* ...for second port */

View File

@ -1391,6 +1391,10 @@ s32 igb_validate_mdi_setting(struct e1000_hw *hw)
{
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)) {
hw_dbg("Invalid MDI setting detected\n");
hw->phy.mdix = 1;

View File

@ -710,3 +710,73 @@ s32 igb_update_nvm_checksum(struct e1000_hw *hw)
out:
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;
}

View File

@ -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_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

View File

@ -1207,20 +1207,25 @@ s32 igb_phy_force_speed_duplex_m88(struct e1000_hw *hw)
u16 phy_data;
bool link;
/*
* Clear Auto-Crossover to force MDI manually. M88E1000 requires MDI
* forced whenever speed and duplex are forced.
*/
ret_val = phy->ops.read_reg(hw, M88E1000_PHY_SPEC_CTRL, &phy_data);
if (ret_val)
goto out;
/* I210 and I211 devices support Auto-Crossover in forced operation. */
if (phy->type != e1000_phy_i210) {
/*
* Clear Auto-Crossover to force MDI manually. M88E1000
* requires MDI forced whenever speed and duplex are forced.
*/
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;
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL, phy_data);
if (ret_val)
goto out;
phy_data &= ~M88E1000_PSCR_AUTO_X_MODE;
ret_val = phy->ops.write_reg(hw, M88E1000_PHY_SPEC_CTRL,
phy_data);
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);
if (ret_val)

View File

@ -1785,58 +1785,34 @@ static const struct net_device_ops igb_netdev_ops = {
void igb_set_fw_version(struct igb_adapter *adapter)
{
struct e1000_hw *hw = &adapter->hw;
u16 eeprom_verh, eeprom_verl, comb_verh, comb_verl, comb_offset;
u16 major, build, patch, fw_version;
u32 etrack_id;
struct e1000_fw_version fw;
hw->nvm.ops.read(hw, 5, 1, &fw_version);
if (adapter->hw.mac.type != 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;
igb_get_fw_version(hw, &fw);
/* 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);
switch (hw->mac.type) {
case e1000_i211:
snprintf(adapter->fw_version, sizeof(adapter->fw_version),
"%2d.%2d-%d",
fw.invm_major, fw.invm_minor, fw.invm_img_type);
break;
/* 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;
}
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);
}
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),
"%d.%d%d",
(fw_version & IGB_MAJOR_MASK) >> IGB_MAJOR_SHIFT,
(fw_version & IGB_MINOR_MASK) >> IGB_MINOR_SHIFT,
(fw_version & IGB_BUILD_MASK));
break;
}
out:
return;
}

View File

@ -455,7 +455,7 @@ void igb_ptp_rx_pktstamp(struct igb_q_vector *q_vector,
unsigned char *va,
struct sk_buff *skb)
{
u64 *regval = (u64 *)va;
__le64 *regval = (__le64 *)va;
/*
* The timestamp is recorded in little endian format.

View File

@ -184,6 +184,13 @@ static void igbvf_alloc_rx_buffers(struct igbvf_ring *rx_ring,
buffer_info->page_offset,
PAGE_SIZE / 2,
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) {
@ -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,
bufsz,
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
* each write-back erases this info. */

View File

@ -693,6 +693,7 @@ extern s32 ixgbe_fdir_erase_perfect_filter_82599(struct ixgbe_hw *hw,
u16 soft_id);
extern void ixgbe_atr_compute_perfect_hash_82599(union ixgbe_atr_input *input,
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);
#ifdef CONFIG_IXGBE_DCB
extern void ixgbe_set_rx_drop_en(struct ixgbe_adapter *adapter);

View File

@ -62,7 +62,6 @@ static s32 ixgbe_setup_copper_link_82599(struct ixgbe_hw *hw,
bool autoneg,
bool autoneg_wait_to_complete);
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)
{
@ -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)
{
s32 ret_val = 0;
u32 reg_anlp1 = 0;
u32 i = 0;
u16 list_offset, data_offset, data_value;
bool got_lock = false;
if (hw->phy.sfp_type != ixgbe_sfp_type_unknown) {
ixgbe_init_mac_link_ops_82599(hw);
@ -137,28 +135,36 @@ static s32 ixgbe_setup_sfp_modules_82599(struct ixgbe_hw *hw)
usleep_range(hw->eeprom.semaphore_delay * 1000,
hw->eeprom.semaphore_delay * 2000);
/* Now restart DSP by setting Restart_AN and clearing LMS */
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, ((IXGBE_READ_REG(hw,
IXGBE_AUTOC) & ~IXGBE_AUTOC_LMS_MASK) |
IXGBE_AUTOC_AN_RESTART));
/* Need SW/FW semaphore around AUTOC writes if LESM on,
* likewise reset_pipeline requires lock as it also writes
* AUTOC.
*/
if (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 setup_sfp_out;
/* Wait for AN to leave state 0 */
for (i = 0; i < 10; i++) {
usleep_range(4000, 8000);
reg_anlp1 = IXGBE_READ_REG(hw, IXGBE_ANLP1);
if (reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)
break;
got_lock = true;
}
if (!(reg_anlp1 & IXGBE_ANLP1_AN_STATE_MASK)) {
hw_dbg(hw, "sfp module setup not complete\n");
/* 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 (ret_val) {
hw_dbg(hw, " sfp module setup not complete\n");
ret_val = IXGBE_ERR_SFP_SETUP_NOT_COMPLETE;
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:
@ -394,14 +400,26 @@ static s32 ixgbe_start_mac_link_82599(struct ixgbe_hw *hw,
u32 links_reg;
u32 i;
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 */
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
autoc_reg |= IXGBE_AUTOC_AN_RESTART;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
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 */
if (autoneg_wait_to_complete) {
autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
if ((autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
IXGBE_AUTOC_LMS_KX4_KX_KR ||
(autoc_reg & IXGBE_AUTOC_LMS_MASK) ==
@ -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 */
msleep(50);
out:
return status;
}
@ -779,6 +798,7 @@ static s32 ixgbe_setup_mac_link_82599(struct ixgbe_hw *hw,
u32 links_reg;
u32 i;
ixgbe_link_speed link_capabilities = IXGBE_LINK_SPEED_UNKNOWN;
bool got_lock = false;
/* Check to see if speed passed in is supported. */
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,
}
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 */
autoc |= IXGBE_AUTOC_AN_RESTART;
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 */
if (autoneg_wait_to_complete) {
@ -994,9 +1031,28 @@ mac_reset_top:
hw->mac.orig_autoc2 = autoc2;
hw->mac.orig_link_settings_stored = true;
} else {
if (autoc != hw->mac.orig_autoc)
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, (hw->mac.orig_autoc |
IXGBE_AUTOC_AN_RESTART));
if (autoc != hw->mac.orig_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.
*/
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) !=
(hw->mac.orig_autoc2 & IXGBE_AUTOC2_UPPER_MASK)) {
@ -1983,7 +2039,7 @@ fw_version_out:
* 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.
**/
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;
u16 fw_offset, fw_lesm_param_offset, fw_lesm_state;

View File

@ -90,6 +90,7 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
s32 ret_val = 0;
u32 reg = 0, reg_bp = 0;
u16 reg_cu = 0;
bool got_lock = false;
/*
* Validate the requested mode. Strict IEEE mode does not allow
@ -210,8 +211,29 @@ static s32 ixgbe_setup_fc(struct ixgbe_hw *hw)
*
*/
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);
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) &&
(ixgbe_device_supports_autoneg_fc(hw) == 0)) {
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)
bool link_up = false;
u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
u32 led_reg = IXGBE_READ_REG(hw, IXGBE_LEDCTL);
s32 ret_val = 0;
/*
* 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)
hw->mac.ops.check_link(hw, &speed, &link_up, false);
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_FLU;
IXGBE_WRITE_REG(hw, IXGBE_AUTOC, autoc_reg);
IXGBE_WRITE_FLUSH(hw);
if (got_lock)
hw->mac.ops.release_swfw_sync(hw,
IXGBE_GSSR_MAC_CSR_SM);
usleep_range(10000, 20000);
}
@ -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_FLUSH(hw);
return 0;
out:
return ret_val;
}
/**
@ -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 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_AN_RESTART;
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_BLINK(index);
led_reg |= IXGBE_LED_LINK_ACTIVE << IXGBE_LED_MODE_SHIFT(index);
IXGBE_WRITE_REG(hw, IXGBE_LEDCTL, led_reg);
IXGBE_WRITE_FLUSH(hw);
return 0;
out:
return ret_val;
}
/**

View File

@ -356,13 +356,37 @@ static void ixgbe_dump(struct ixgbe_adapter *adapter)
/* Transmit Descriptor Formats
*
* Advanced Transmit Descriptor
* 82598 Advanced Transmit Descriptor
* +--------------------------------------------------------------+
* 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
*
* 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++) {
@ -423,7 +447,9 @@ rx_ring_summary:
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
* +-----------------------------------------------------+
* 0 | Packet Buffer Address [63:1] |A0/NSE|
@ -432,17 +458,40 @@ rx_ring_summary:
* +-----------------------------------------------------+
*
*
* 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
* +------------------------------------------------------+
* 0 | Packet IP |SPH| HDR_LEN | RSV|Packet| RSS |
* | Checksum Ident | | | | Type | Type |
* 0 | RSS Hash / |SPH| HDR_LEN | RSV |Packet| RSS |
* | Packet | IP | | | | Type | Type |
* | Checksum | Ident | | | | | |
* +------------------------------------------------------+
* 8 | VLAN Tag | Length | Extended Error | Extended Status |
* +------------------------------------------------------+
* 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++) {
rx_ring = adapter->rx_ring[n];
pr_info("------------------------------------\n");
@ -1795,7 +1844,7 @@ dma_sync:
**/
static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
struct ixgbe_ring *rx_ring,
int budget)
const int budget)
{
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
#ifdef IXGBE_FCOE
@ -1846,7 +1895,6 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
/* probably a little skewed due to removing CRC */
total_rx_bytes += skb->len;
total_rx_packets++;
/* populate checksum, timestamp, VLAN, and protocol */
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,
ixgbe_rx_skb(q_vector, skb);
/* update budget accounting */
budget--;
} while (likely(budget));
total_rx_packets++;
} while (likely(total_rx_packets < budget));
u64_stats_update_begin(&rx_ring->syncp);
rx_ring->stats.packets += total_rx_packets;
@ -1892,7 +1940,7 @@ static bool ixgbe_clean_rx_irq(struct ixgbe_q_vector *q_vector,
if (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)
else
ixgbe_configure_msi_and_legacy(adapter);
/* enable the optics for both mult-speed fiber and 82599 SFP+ fiber */
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))))
/* enable the optics for 82599 SFP+ fiber */
if (hw->mac.ops.enable_tx_laser)
hw->mac.ops.enable_tx_laser(hw);
clear_bit(__IXGBE_DOWN, &adapter->state);
@ -4411,11 +4456,8 @@ void ixgbe_down(struct ixgbe_adapter *adapter)
if (!pci_channel_offline(adapter->pdev))
ixgbe_reset(adapter);
/* power down the optics for multispeed fiber and 82599 SFP+ fiber */
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))))
/* power down the optics for 82599 SFP+ fiber */
if (hw->mac.ops.disable_tx_laser)
hw->mac.ops.disable_tx_laser(hw);
ixgbe_clean_all_tx_rings(adapter);
@ -5048,14 +5090,8 @@ static int __ixgbe_shutdown(struct pci_dev *pdev, bool *enable_wake)
if (wufc) {
ixgbe_set_rx_mode(netdev);
/*
* enable the optics for both mult-speed fiber and
* 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)))
/* enable the optics for 82599 SFP+ fiber as we can WoL */
if (hw->mac.ops.enable_tx_laser)
hw->mac.ops.enable_tx_laser(hw);
/* 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[],
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;
if (netdev_uc_count(dev) < rar_uc_entries)
@ -7521,11 +7557,8 @@ static int __devinit ixgbe_probe(struct pci_dev *pdev,
if (err)
goto err_register;
/* power down the optics for multispeed fiber and 82599 SFP+ fiber */
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))))
/* power down the optics for 82599 SFP+ fiber */
if (hw->mac.ops.disable_tx_laser)
hw->mac.ops.disable_tx_laser(hw);
/* carrier off reporting is important to ethtool even BEFORE open */

View File

@ -554,12 +554,14 @@ void ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
adapter = q_vector->adapter;
hw = &adapter->hw;
if (likely(!ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter)))
return;
tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
/* Check if we have a valid timestamp and make sure the skb should
* have been timestamped */
if (likely(!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID) ||
!ixgbe_ptp_match(skb, adapter->rx_hwtstamp_filter)))
if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
return;
/*

View File

@ -678,7 +678,7 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
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,
@ -745,7 +745,8 @@ static int ixgbe_set_vf_macvlan_msg(struct ixgbe_adapter *adapter,
e_warn(drv,
"VF %d has requested a MACVLAN filter but there is no space for it\n",
vf);
return err;
return err < 0;
}
static int ixgbe_negotiate_vf_api(struct ixgbe_adapter *adapter,

View File

@ -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
unsigned short f;
#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];

View File

@ -331,6 +331,9 @@ static s32 ixgbevf_update_mc_addr_list_vf(struct ixgbe_hw *hw,
netdev_for_each_mc_addr(ha, netdev) {
if (i == cnt)
break;
if (is_link_local(ha->addr))
continue;
vector_list[i++] = ixgbevf_mta_vector(hw, ha->addr);
}

View File

@ -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_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.
* @addr: Pointer to a six-byte array containing the Ethernet address

View File

@ -358,7 +358,7 @@ void br_dev_setup(struct net_device *dev)
br->bridge_id.prio[0] = 0x80;
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->group_fwd_mask = BR_GROUPFWD_DEFAULT;

View File

@ -19,9 +19,6 @@
#include <linux/export.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 */
br_should_route_hook_t __rcu *br_should_route_hook __read_mostly;
EXPORT_SYMBOL(br_should_route_hook);
@ -127,18 +124,6 @@ static int br_handle_local_finish(struct sk_buff *skb)
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
* note: already called with rcu_read_lock

View File

@ -290,7 +290,6 @@ struct br_input_skb_cb {
pr_debug("%s: " format, (br)->dev->name, ##args)
extern struct notifier_block br_device_notifier;
extern const u8 br_group_address[ETH_ALEN];
/* called under bridge lock */
static inline int br_is_root_bridge(const struct net_bridge *br)

View File

@ -14,6 +14,7 @@
#include <linux/capability.h>
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_bridge.h>
#include <linux/rtnetlink.h>
#include <linux/spinlock.h>
@ -310,7 +311,7 @@ static ssize_t store_group_addr(struct device *d,
/* Must be 01:80:c2:00:00:0X */
for (i = 0; i < 5; i++)
if (new_addr[i] != br_group_address[i])
if (new_addr[i] != br_reserved_address[i])
return -EINVAL;
if (new_addr[5] & ~0xf)