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:
Коммит
810b6d7638
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
||||
/*
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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];
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
Загрузка…
Ссылка в новой задаче