Commit 43e2dfb2 authored by David S. Miller's avatar David S. Miller

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

Jeff Kirsher says:

====================
10GbE Intel Wired LAN Driver Updates 2016-04-04

This series contains updates to ixgbe and ixgbevf.

Pavel Tikhomirov fixes a typo where we were incrementing transmit stats
instead of receive stats on the receive side.

Emil updates the ixgbevf driver to use bit operations for setting and
checking the adapter state.

Chas Williams adds the new NDO trust feature check so that the VF guest
has the ability to set the unicast address of the interface, if it is a
trusted VF.

Alex cleans up the driver to that the only time we add a PF entry to the
VLVF is either for VLAN 0 or if the PF has requested a VLAN that a VF
is already using.  Also adds support for generic transmit checksums,
giving the added advantage is that we can support inner checksum offloads
for tunnels and MPLS while still being able to transparently insert
VLAN tags.  Lastly, changed ixgbe so that we can use the ethtool
rx-vlan-filter flag to toggle receive VLAN filtering on and off.

Mark cleans up the ixgbe driver by making all op structures that do not
change constants.  Also fixed flow control for Xeon D KR backplanes, since
we cannot use auto-negotiation to determine the mode, we have to use
whatever the user configured.

Sowmini Varadhan updates ixgbe to use eth_platform_get_mac_address()
instead of the arch specific solution that was added by a previous
commit.

Don fixed an issue where it was possible that a system reset could occur
when we were holding the SWFW semaphore lock, which the next time the
driver loaded would see it incorrectly as locked.

v2: updated patch 8 of the series to include a minor flags issue where
    we had lost NETIF_F_HW_TC and we were setting NETIF_F_SCTP_CRC in
    two different areas, when we only needed/wanted it in one spot.
====================
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parents 6e338048 0c5a6166
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -456,7 +456,7 @@ static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector) ...@@ -456,7 +456,7 @@ static inline bool ixgbe_qv_lock_poll(struct ixgbe_q_vector *q_vector)
IXGBE_QV_STATE_POLL); IXGBE_QV_STATE_POLL);
#ifdef BP_EXTENDED_STATS #ifdef BP_EXTENDED_STATS
if (rc != IXGBE_QV_STATE_IDLE) if (rc != IXGBE_QV_STATE_IDLE)
q_vector->tx.ring->stats.yields++; q_vector->rx.ring->stats.yields++;
#endif #endif
return rc == IXGBE_QV_STATE_IDLE; return rc == IXGBE_QV_STATE_IDLE;
} }
...@@ -862,11 +862,11 @@ enum ixgbe_boards { ...@@ -862,11 +862,11 @@ enum ixgbe_boards {
board_X550EM_x, board_X550EM_x,
}; };
extern struct ixgbe_info ixgbe_82598_info; extern const struct ixgbe_info ixgbe_82598_info;
extern struct ixgbe_info ixgbe_82599_info; extern const struct ixgbe_info ixgbe_82599_info;
extern struct ixgbe_info ixgbe_X540_info; extern const struct ixgbe_info ixgbe_X540_info;
extern struct ixgbe_info ixgbe_X550_info; extern const struct ixgbe_info ixgbe_X550_info;
extern struct ixgbe_info ixgbe_X550EM_x_info; extern const struct ixgbe_info ixgbe_X550EM_x_info;
#ifdef CONFIG_IXGBE_DCB #ifdef CONFIG_IXGBE_DCB
extern const struct dcbnl_rtnl_ops dcbnl_ops; extern const struct dcbnl_rtnl_ops dcbnl_ops;
#endif #endif
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2015 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -1160,7 +1160,7 @@ static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb, ...@@ -1160,7 +1160,7 @@ static void ixgbe_set_rxpba_82598(struct ixgbe_hw *hw, int num_pb,
IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB); IXGBE_WRITE_REG(hw, IXGBE_TXPBSIZE(i), IXGBE_TXPBSIZE_40KB);
} }
static struct ixgbe_mac_operations mac_ops_82598 = { static const struct ixgbe_mac_operations mac_ops_82598 = {
.init_hw = &ixgbe_init_hw_generic, .init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82598, .reset_hw = &ixgbe_reset_hw_82598,
.start_hw = &ixgbe_start_hw_82598, .start_hw = &ixgbe_start_hw_82598,
...@@ -1192,9 +1192,11 @@ static struct ixgbe_mac_operations mac_ops_82598 = { ...@@ -1192,9 +1192,11 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.clear_vfta = &ixgbe_clear_vfta_82598, .clear_vfta = &ixgbe_clear_vfta_82598,
.set_vfta = &ixgbe_set_vfta_82598, .set_vfta = &ixgbe_set_vfta_82598,
.fc_enable = &ixgbe_fc_enable_82598, .fc_enable = &ixgbe_fc_enable_82598,
.setup_fc = ixgbe_setup_fc_generic,
.set_fw_drv_ver = NULL, .set_fw_drv_ver = NULL,
.acquire_swfw_sync = &ixgbe_acquire_swfw_sync, .acquire_swfw_sync = &ixgbe_acquire_swfw_sync,
.release_swfw_sync = &ixgbe_release_swfw_sync, .release_swfw_sync = &ixgbe_release_swfw_sync,
.init_swfw_sync = NULL,
.get_thermal_sensor_data = NULL, .get_thermal_sensor_data = NULL,
.init_thermal_sensor_thresh = NULL, .init_thermal_sensor_thresh = NULL,
.prot_autoc_read = &prot_autoc_read_generic, .prot_autoc_read = &prot_autoc_read_generic,
...@@ -1203,7 +1205,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = { ...@@ -1203,7 +1205,7 @@ static struct ixgbe_mac_operations mac_ops_82598 = {
.disable_rx = &ixgbe_disable_rx_generic, .disable_rx = &ixgbe_disable_rx_generic,
}; };
static struct ixgbe_eeprom_operations eeprom_ops_82598 = { static const struct ixgbe_eeprom_operations eeprom_ops_82598 = {
.init_params = &ixgbe_init_eeprom_params_generic, .init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eerd_generic, .read = &ixgbe_read_eerd_generic,
.write = &ixgbe_write_eeprom_generic, .write = &ixgbe_write_eeprom_generic,
...@@ -1214,7 +1216,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = { ...@@ -1214,7 +1216,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82598 = {
.update_checksum = &ixgbe_update_eeprom_checksum_generic, .update_checksum = &ixgbe_update_eeprom_checksum_generic,
}; };
static struct ixgbe_phy_operations phy_ops_82598 = { static const struct ixgbe_phy_operations phy_ops_82598 = {
.identify = &ixgbe_identify_phy_generic, .identify = &ixgbe_identify_phy_generic,
.identify_sfp = &ixgbe_identify_module_generic, .identify_sfp = &ixgbe_identify_module_generic,
.init = &ixgbe_init_phy_ops_82598, .init = &ixgbe_init_phy_ops_82598,
...@@ -1230,7 +1232,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = { ...@@ -1230,7 +1232,7 @@ static struct ixgbe_phy_operations phy_ops_82598 = {
.check_overtemp = &ixgbe_tn_check_overtemp, .check_overtemp = &ixgbe_tn_check_overtemp,
}; };
struct ixgbe_info ixgbe_82598_info = { const struct ixgbe_info ixgbe_82598_info = {
.mac = ixgbe_mac_82598EB, .mac = ixgbe_mac_82598EB,
.get_invariants = &ixgbe_get_invariants_82598, .get_invariants = &ixgbe_get_invariants_82598,
.mac_ops = &mac_ops_82598, .mac_ops = &mac_ops_82598,
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2015 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -2181,7 +2181,7 @@ static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset, ...@@ -2181,7 +2181,7 @@ static s32 ixgbe_write_i2c_byte_82599(struct ixgbe_hw *hw, u8 byte_offset,
return status; return status;
} }
static struct ixgbe_mac_operations mac_ops_82599 = { static const struct ixgbe_mac_operations mac_ops_82599 = {
.init_hw = &ixgbe_init_hw_generic, .init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_82599, .reset_hw = &ixgbe_reset_hw_82599,
.start_hw = &ixgbe_start_hw_82599, .start_hw = &ixgbe_start_hw_82599,
...@@ -2220,6 +2220,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { ...@@ -2220,6 +2220,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.clear_vfta = &ixgbe_clear_vfta_generic, .clear_vfta = &ixgbe_clear_vfta_generic,
.set_vfta = &ixgbe_set_vfta_generic, .set_vfta = &ixgbe_set_vfta_generic,
.fc_enable = &ixgbe_fc_enable_generic, .fc_enable = &ixgbe_fc_enable_generic,
.setup_fc = ixgbe_setup_fc_generic,
.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic,
.init_uta_tables = &ixgbe_init_uta_tables_generic, .init_uta_tables = &ixgbe_init_uta_tables_generic,
.setup_sfp = &ixgbe_setup_sfp_modules_82599, .setup_sfp = &ixgbe_setup_sfp_modules_82599,
...@@ -2227,6 +2228,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { ...@@ -2227,6 +2228,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing,
.acquire_swfw_sync = &ixgbe_acquire_swfw_sync, .acquire_swfw_sync = &ixgbe_acquire_swfw_sync,
.release_swfw_sync = &ixgbe_release_swfw_sync, .release_swfw_sync = &ixgbe_release_swfw_sync,
.init_swfw_sync = NULL,
.get_thermal_sensor_data = &ixgbe_get_thermal_sensor_data_generic, .get_thermal_sensor_data = &ixgbe_get_thermal_sensor_data_generic,
.init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic, .init_thermal_sensor_thresh = &ixgbe_init_thermal_sensor_thresh_generic,
.prot_autoc_read = &prot_autoc_read_82599, .prot_autoc_read = &prot_autoc_read_82599,
...@@ -2235,7 +2237,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = { ...@@ -2235,7 +2237,7 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
.disable_rx = &ixgbe_disable_rx_generic, .disable_rx = &ixgbe_disable_rx_generic,
}; };
static struct ixgbe_eeprom_operations eeprom_ops_82599 = { static const struct ixgbe_eeprom_operations eeprom_ops_82599 = {
.init_params = &ixgbe_init_eeprom_params_generic, .init_params = &ixgbe_init_eeprom_params_generic,
.read = &ixgbe_read_eeprom_82599, .read = &ixgbe_read_eeprom_82599,
.read_buffer = &ixgbe_read_eeprom_buffer_82599, .read_buffer = &ixgbe_read_eeprom_buffer_82599,
...@@ -2246,7 +2248,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = { ...@@ -2246,7 +2248,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
.update_checksum = &ixgbe_update_eeprom_checksum_generic, .update_checksum = &ixgbe_update_eeprom_checksum_generic,
}; };
static struct ixgbe_phy_operations phy_ops_82599 = { static const struct ixgbe_phy_operations phy_ops_82599 = {
.identify = &ixgbe_identify_phy_82599, .identify = &ixgbe_identify_phy_82599,
.identify_sfp = &ixgbe_identify_module_generic, .identify_sfp = &ixgbe_identify_module_generic,
.init = &ixgbe_init_phy_ops_82599, .init = &ixgbe_init_phy_ops_82599,
...@@ -2263,7 +2265,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = { ...@@ -2263,7 +2265,7 @@ static struct ixgbe_phy_operations phy_ops_82599 = {
.check_overtemp = &ixgbe_tn_check_overtemp, .check_overtemp = &ixgbe_tn_check_overtemp,
}; };
struct ixgbe_info ixgbe_82599_info = { const struct ixgbe_info ixgbe_82599_info = {
.mac = ixgbe_mac_82599EB, .mac = ixgbe_mac_82599EB,
.get_invariants = &ixgbe_get_invariants_82599, .get_invariants = &ixgbe_get_invariants_82599,
.mac_ops = &mac_ops_82599, .mac_ops = &mac_ops_82599,
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2015 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -111,12 +111,12 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw) ...@@ -111,12 +111,12 @@ bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw)
} }
/** /**
* ixgbe_setup_fc - Set up flow control * ixgbe_setup_fc_generic - Set up flow control
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
* *
* Called at init time to set up flow control. * Called at init time to set up flow control.
**/ **/
static s32 ixgbe_setup_fc(struct ixgbe_hw *hw) s32 ixgbe_setup_fc_generic(struct ixgbe_hw *hw)
{ {
s32 ret_val = 0; s32 ret_val = 0;
u32 reg = 0, reg_bp = 0; u32 reg = 0, reg_bp = 0;
...@@ -296,7 +296,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw) ...@@ -296,7 +296,7 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
/* Setup flow control */ /* Setup flow control */
ret_val = ixgbe_setup_fc(hw); ret_val = hw->mac.ops.setup_fc(hw);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -81,6 +81,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw); ...@@ -81,6 +81,7 @@ s32 ixgbe_disable_rx_buff_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw); s32 ixgbe_enable_rx_buff_generic(struct ixgbe_hw *hw);
s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval); s32 ixgbe_enable_rx_dma_generic(struct ixgbe_hw *hw, u32 regval);
s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw); s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw);
s32 ixgbe_setup_fc_generic(struct ixgbe_hw *);
bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw); bool ixgbe_device_supports_autoneg_fc(struct ixgbe_hw *hw);
void ixgbe_fc_autoneg(struct ixgbe_hw *hw); void ixgbe_fc_autoneg(struct ixgbe_hw *hw);
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2015 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -54,15 +54,6 @@ ...@@ -54,15 +54,6 @@
#include <net/pkt_cls.h> #include <net/pkt_cls.h>
#include <net/tc_act/tc_gact.h> #include <net/tc_act/tc_gact.h>
#ifdef CONFIG_OF
#include <linux/of_net.h>
#endif
#ifdef CONFIG_SPARC
#include <asm/idprom.h>
#include <asm/prom.h>
#endif
#include "ixgbe.h" #include "ixgbe.h"
#include "ixgbe_common.h" #include "ixgbe_common.h"
#include "ixgbe_dcb_82599.h" #include "ixgbe_dcb_82599.h"
...@@ -1086,6 +1077,36 @@ static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter) ...@@ -1086,6 +1077,36 @@ static void ixgbe_tx_timeout_reset(struct ixgbe_adapter *adapter)
} }
} }
/**
* ixgbe_tx_maxrate - callback to set the maximum per-queue bitrate
**/
static int ixgbe_tx_maxrate(struct net_device *netdev,
int queue_index, u32 maxrate)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
u32 bcnrc_val = ixgbe_link_mbps(adapter);
if (!maxrate)
return 0;
/* Calculate the rate factor values to set */
bcnrc_val <<= IXGBE_RTTBCNRC_RF_INT_SHIFT;
bcnrc_val /= maxrate;
/* clear everything but the rate factor */
bcnrc_val &= IXGBE_RTTBCNRC_RF_INT_MASK |
IXGBE_RTTBCNRC_RF_DEC_MASK;
/* enable the rate scheduler */
bcnrc_val |= IXGBE_RTTBCNRC_RS_ENA;
IXGBE_WRITE_REG(hw, IXGBE_RTTDQSEL, queue_index);
IXGBE_WRITE_REG(hw, IXGBE_RTTBCNRC, bcnrc_val);
return 0;
}
/** /**
* ixgbe_clean_tx_irq - Reclaim resources after transmit completes * ixgbe_clean_tx_irq - Reclaim resources after transmit completes
* @q_vector: structure containing interrupt and ring information * @q_vector: structure containing interrupt and ring information
...@@ -3908,7 +3929,9 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev, ...@@ -3908,7 +3929,9 @@ static int ixgbe_vlan_rx_add_vid(struct net_device *netdev,
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
/* add VID to filter table */ /* add VID to filter table */
hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, true); if (!vid || !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
hw->mac.ops.set_vfta(&adapter->hw, vid, VMDQ_P(0), true, !!vid);
set_bit(vid, adapter->active_vlans); set_bit(vid, adapter->active_vlans);
return 0; return 0;
...@@ -3965,9 +3988,7 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev, ...@@ -3965,9 +3988,7 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
/* remove VID from filter table */ /* remove VID from filter table */
if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) if (vid && !(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
ixgbe_update_pf_promisc_vlvf(adapter, vid);
else
hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true); hw->mac.ops.set_vfta(hw, vid, VMDQ_P(0), false, true);
clear_bit(vid, adapter->active_vlans); clear_bit(vid, adapter->active_vlans);
...@@ -4172,11 +4193,11 @@ static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter) ...@@ -4172,11 +4193,11 @@ static void ixgbe_vlan_promisc_disable(struct ixgbe_adapter *adapter)
static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter) static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
{ {
u16 vid; u16 vid = 1;
ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0); ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), 0);
for_each_set_bit(vid, adapter->active_vlans, VLAN_N_VID) for_each_set_bit_from(vid, adapter->active_vlans, VLAN_N_VID)
ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid); ixgbe_vlan_rx_add_vid(adapter->netdev, htons(ETH_P_8021Q), vid);
} }
...@@ -4426,6 +4447,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4426,6 +4447,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev); struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE; u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
netdev_features_t features = netdev->features;
int count; int count;
/* Check for Promiscuous and All Multicast modes */ /* Check for Promiscuous and All Multicast modes */
...@@ -4443,14 +4465,13 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4443,14 +4465,13 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
hw->addr_ctrl.user_set_promisc = true; hw->addr_ctrl.user_set_promisc = true;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE); fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
vmolr |= IXGBE_VMOLR_MPE; vmolr |= IXGBE_VMOLR_MPE;
ixgbe_vlan_promisc_enable(adapter); features &= ~NETIF_F_HW_VLAN_CTAG_FILTER;
} else { } else {
if (netdev->flags & IFF_ALLMULTI) { if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE; fctrl |= IXGBE_FCTRL_MPE;
vmolr |= IXGBE_VMOLR_MPE; vmolr |= IXGBE_VMOLR_MPE;
} }
hw->addr_ctrl.user_set_promisc = false; hw->addr_ctrl.user_set_promisc = false;
ixgbe_vlan_promisc_disable(adapter);
} }
/* /*
...@@ -4483,7 +4504,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4483,7 +4504,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
} }
/* This is useful for sniffing bad packets. */ /* This is useful for sniffing bad packets. */
if (adapter->netdev->features & NETIF_F_RXALL) { if (features & NETIF_F_RXALL) {
/* UPE and MPE will be handled by normal PROMISC logic /* UPE and MPE will be handled by normal PROMISC logic
* in e1000e_set_rx_mode */ * in e1000e_set_rx_mode */
fctrl |= (IXGBE_FCTRL_SBP | /* Receive bad packets */ fctrl |= (IXGBE_FCTRL_SBP | /* Receive bad packets */
...@@ -4496,10 +4517,15 @@ void ixgbe_set_rx_mode(struct net_device *netdev) ...@@ -4496,10 +4517,15 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl); IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX) if (features & NETIF_F_HW_VLAN_CTAG_RX)
ixgbe_vlan_strip_enable(adapter); ixgbe_vlan_strip_enable(adapter);
else else
ixgbe_vlan_strip_disable(adapter); ixgbe_vlan_strip_disable(adapter);
if (features & NETIF_F_HW_VLAN_CTAG_FILTER)
ixgbe_vlan_promisc_disable(adapter);
else
ixgbe_vlan_promisc_enable(adapter);
} }
static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter) static void ixgbe_napi_enable_all(struct ixgbe_adapter *adapter)
...@@ -7211,103 +7237,61 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring, ...@@ -7211,103 +7237,61 @@ static int ixgbe_tso(struct ixgbe_ring *tx_ring,
return 1; return 1;
} }
static inline bool ixgbe_ipv6_csum_is_sctp(struct sk_buff *skb)
{
unsigned int offset = 0;
ipv6_find_hdr(skb, &offset, IPPROTO_SCTP, NULL, NULL);
return offset == skb_checksum_start_offset(skb);
}
static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring, static void ixgbe_tx_csum(struct ixgbe_ring *tx_ring,
struct ixgbe_tx_buffer *first) struct ixgbe_tx_buffer *first)
{ {
struct sk_buff *skb = first->skb; struct sk_buff *skb = first->skb;
u32 vlan_macip_lens = 0; u32 vlan_macip_lens = 0;
u32 mss_l4len_idx = 0;
u32 type_tucmd = 0; u32 type_tucmd = 0;
if (skb->ip_summed != CHECKSUM_PARTIAL) { if (skb->ip_summed != CHECKSUM_PARTIAL) {
if (!(first->tx_flags & IXGBE_TX_FLAGS_HW_VLAN) && csum_failed:
!(first->tx_flags & IXGBE_TX_FLAGS_CC)) if (!(first->tx_flags & (IXGBE_TX_FLAGS_HW_VLAN |
IXGBE_TX_FLAGS_CC)))
return; return;
vlan_macip_lens = skb_network_offset(skb) << goto no_csum;
IXGBE_ADVTXD_MACLEN_SHIFT; }
} else {
u8 l4_hdr = 0;
union {
struct iphdr *ipv4;
struct ipv6hdr *ipv6;
u8 *raw;
} network_hdr;
union {
struct tcphdr *tcphdr;
u8 *raw;
} transport_hdr;
__be16 frag_off;
if (skb->encapsulation) {
network_hdr.raw = skb_inner_network_header(skb);
transport_hdr.raw = skb_inner_transport_header(skb);
vlan_macip_lens = skb_inner_network_offset(skb) <<
IXGBE_ADVTXD_MACLEN_SHIFT;
} else {
network_hdr.raw = skb_network_header(skb);
transport_hdr.raw = skb_transport_header(skb);
vlan_macip_lens = skb_network_offset(skb) <<
IXGBE_ADVTXD_MACLEN_SHIFT;
}
/* use first 4 bits to determine IP version */
switch (network_hdr.ipv4->version) {
case IPVERSION:
vlan_macip_lens |= transport_hdr.raw - network_hdr.raw;
type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
l4_hdr = network_hdr.ipv4->protocol;
break;
case 6:
vlan_macip_lens |= transport_hdr.raw - network_hdr.raw;
l4_hdr = network_hdr.ipv6->nexthdr;
if (likely((transport_hdr.raw - network_hdr.raw) ==
sizeof(struct ipv6hdr)))
break;
ipv6_skip_exthdr(skb, network_hdr.raw - skb->data +
sizeof(struct ipv6hdr),
&l4_hdr, &frag_off);
if (unlikely(frag_off))
l4_hdr = NEXTHDR_FRAGMENT;
break;
default:
break;
}
switch (l4_hdr) { switch (skb->csum_offset) {
case IPPROTO_TCP: case offsetof(struct tcphdr, check):
type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_TCP; type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
mss_l4len_idx = (transport_hdr.tcphdr->doff * 4) << /* fall through */
IXGBE_ADVTXD_L4LEN_SHIFT; case offsetof(struct udphdr, check):
break; break;
case IPPROTO_SCTP: case offsetof(struct sctphdr, checksum):
type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; /* validate that this is actually an SCTP request */
mss_l4len_idx = sizeof(struct sctphdr) << if (((first->protocol == htons(ETH_P_IP)) &&
IXGBE_ADVTXD_L4LEN_SHIFT; (ip_hdr(skb)->protocol == IPPROTO_SCTP)) ||
break; ((first->protocol == htons(ETH_P_IPV6)) &&
case IPPROTO_UDP: ixgbe_ipv6_csum_is_sctp(skb))) {
mss_l4len_idx = sizeof(struct udphdr) << type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_SCTP;
IXGBE_ADVTXD_L4LEN_SHIFT;
break; break;
default:
if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev,
"partial checksum, version=%d, l4 proto=%x\n",
network_hdr.ipv4->version, l4_hdr);
}
skb_checksum_help(skb);
goto no_csum;
} }
/* fall through */
/* update TX checksum flag */ default:
first->tx_flags |= IXGBE_TX_FLAGS_CSUM; skb_checksum_help(skb);
goto csum_failed;
} }
/* update TX checksum flag */
first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
vlan_macip_lens = skb_checksum_start_offset(skb) -
skb_network_offset(skb);
no_csum: no_csum:
/* vlan_macip_lens: MACLEN, VLAN tag */ /* vlan_macip_lens: MACLEN, VLAN tag */
vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, ixgbe_tx_ctxtdesc(tx_ring, vlan_macip_lens, 0, type_tucmd, 0);
type_tucmd, mss_l4len_idx);
} }
#define IXGBE_SET_FLAG(_input, _flag, _result) \ #define IXGBE_SET_FLAG(_input, _flag, _result) \
...@@ -8278,19 +8262,20 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter, ...@@ -8278,19 +8262,20 @@ static int ixgbe_configure_clsu32(struct ixgbe_adapter *adapter,
return -EINVAL; return -EINVAL;
for (i = 0; nexthdr[i].jump; i++) { for (i = 0; nexthdr[i].jump; i++) {
if (nexthdr->o != cls->knode.sel->offoff || if (nexthdr[i].o != cls->knode.sel->offoff ||
nexthdr->s != cls->knode.sel->offshift || nexthdr[i].s != cls->knode.sel->offshift ||
nexthdr->m != cls->knode.sel->offmask || nexthdr[i].m != cls->knode.sel->offmask ||
/* do not support multiple key jumps its just mad */ /* do not support multiple key jumps its just mad */
cls->knode.sel->nkeys > 1) cls->knode.sel->nkeys > 1)
return -EINVAL; return -EINVAL;
if (nexthdr->off != cls->knode.sel->keys[0].off || if (nexthdr[i].off == cls->knode.sel->keys[0].off &&
nexthdr->val != cls->knode.sel->keys[0].val || nexthdr[i].val == cls->knode.sel->keys[0].val &&
nexthdr->mask != cls->knode.sel->keys[0].mask) nexthdr[i].mask == cls->knode.sel->keys[0].mask) {
return -EINVAL; adapter->jump_tables[link_uhtid] =
nexthdr[i].jump;
adapter->jump_tables[link_uhtid] = nexthdr->jump; break;
}
} }
return 0; return 0;
} }
...@@ -8515,11 +8500,6 @@ static int ixgbe_set_features(struct net_device *netdev, ...@@ -8515,11 +8500,6 @@ static int ixgbe_set_features(struct net_device *netdev,
adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE; adapter->flags |= IXGBE_FLAG_FDIR_HASH_CAPABLE;
} }
if (features & NETIF_F_HW_VLAN_CTAG_RX)
ixgbe_vlan_strip_enable(adapter);
else
ixgbe_vlan_strip_disable(adapter);
if (changed & NETIF_F_RXALL) if (changed & NETIF_F_RXALL)
need_reset = true; need_reset = true;
...@@ -8536,6 +8516,9 @@ static int ixgbe_set_features(struct net_device *netdev, ...@@ -8536,6 +8516,9 @@ static int ixgbe_set_features(struct net_device *netdev,
if (need_reset) if (need_reset)
ixgbe_do_reset(netdev); ixgbe_do_reset(netdev);
else if (changed & (NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER))
ixgbe_set_rx_mode(netdev);
return 0; return 0;
} }
...@@ -8858,6 +8841,7 @@ static const struct net_device_ops ixgbe_netdev_ops = { ...@@ -8858,6 +8841,7 @@ static const struct net_device_ops ixgbe_netdev_ops = {
.ndo_set_mac_address = ixgbe_set_mac, .ndo_set_mac_address = ixgbe_set_mac,
.ndo_change_mtu = ixgbe_change_mtu, .ndo_change_mtu = ixgbe_change_mtu,
.ndo_tx_timeout = ixgbe_tx_timeout, .ndo_tx_timeout = ixgbe_tx_timeout,
.ndo_set_tx_maxrate = ixgbe_tx_maxrate,
.ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid, .ndo_vlan_rx_add_vid = ixgbe_vlan_rx_add_vid,
.ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid, .ndo_vlan_rx_kill_vid = ixgbe_vlan_rx_kill_vid,
.ndo_do_ioctl = ixgbe_ioctl, .ndo_do_ioctl = ixgbe_ioctl,
...@@ -9010,29 +8994,6 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id, ...@@ -9010,29 +8994,6 @@ int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
return is_wol_supported; return is_wol_supported;
} }
/**
* ixgbe_get_platform_mac_addr - Look up MAC address in Open Firmware / IDPROM
* @adapter: Pointer to adapter struct
*/
static void ixgbe_get_platform_mac_addr(struct ixgbe_adapter *adapter)
{
#ifdef CONFIG_OF
struct device_node *dp = pci_device_to_OF_node(adapter->pdev);
struct ixgbe_hw *hw = &adapter->hw;
const unsigned char *addr;
addr = of_get_mac_address(dp);
if (addr) {
ether_addr_copy(hw->mac.perm_addr, addr);
return;
}
#endif /* CONFIG_OF */
#ifdef CONFIG_SPARC
ether_addr_copy(hw->mac.perm_addr, idprom->id_ethaddr);
#endif /* CONFIG_SPARC */
}
/** /**
* ixgbe_probe - Device Initialization Routine * ixgbe_probe - Device Initialization Routine
* @pdev: PCI device information struct * @pdev: PCI device information struct
...@@ -9136,12 +9097,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -9136,12 +9097,12 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name)); strlcpy(netdev->name, pci_name(pdev), sizeof(netdev->name));
/* Setup hw api */ /* Setup hw api */
memcpy(&hw->mac.ops, ii->mac_ops, sizeof(hw->mac.ops)); hw->mac.ops = *ii->mac_ops;
hw->mac.type = ii->mac; hw->mac.type = ii->mac;
hw->mvals = ii->mvals; hw->mvals = ii->mvals;
/* EEPROM */ /* EEPROM */
memcpy(&hw->eeprom.ops, ii->eeprom_ops, sizeof(hw->eeprom.ops)); hw->eeprom.ops = *ii->eeprom_ops;
eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw)); eec = IXGBE_READ_REG(hw, IXGBE_EEC(hw));
if (ixgbe_removed(hw->hw_addr)) { if (ixgbe_removed(hw->hw_addr)) {
err = -EIO; err = -EIO;
...@@ -9152,7 +9113,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -9152,7 +9113,7 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic; hw->eeprom.ops.read = &ixgbe_read_eeprom_bit_bang_generic;
/* PHY */ /* PHY */
memcpy(&hw->phy.ops, ii->phy_ops, sizeof(hw->phy.ops)); hw->phy.ops = *ii->phy_ops;
hw->phy.sfp_type = ixgbe_sfp_type_unknown; hw->phy.sfp_type = ixgbe_sfp_type_unknown;
/* ixgbe_identify_phy_generic will set prtad and mmds properly */ /* ixgbe_identify_phy_generic will set prtad and mmds properly */
hw->phy.mdio.prtad = MDIO_PRTAD_NONE; hw->phy.mdio.prtad = MDIO_PRTAD_NONE;
...@@ -9169,6 +9130,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -9169,6 +9130,10 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) if (err)
goto err_sw_init; goto err_sw_init;
/* Make sure the SWFW semaphore is in a valid state */
if (hw->mac.ops.init_swfw_sync)
hw->mac.ops.init_swfw_sync(hw);
/* Make it possible the adapter to be woken up via WOL */ /* Make it possible the adapter to be woken up via WOL */
switch (adapter->hw.mac.type) { switch (adapter->hw.mac.type) {
case ixgbe_mac_82599EB: case ixgbe_mac_82599EB:
...@@ -9215,48 +9180,42 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -9215,48 +9180,42 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto skip_sriov; goto skip_sriov;
/* Mailbox */ /* Mailbox */
ixgbe_init_mbx_params_pf(hw); ixgbe_init_mbx_params_pf(hw);
memcpy(&hw->mbx.ops, ii->mbx_ops, sizeof(hw->mbx.ops)); hw->mbx.ops = ii->mbx_ops;
pci_sriov_set_totalvfs(pdev, IXGBE_MAX_VFS_DRV_LIMIT); pci_sriov_set_totalvfs(pdev, IXGBE_MAX_VFS_DRV_LIMIT);
ixgbe_enable_sriov(adapter); ixgbe_enable_sriov(adapter);
skip_sriov: skip_sriov:
#endif #endif
netdev->features = NETIF_F_SG | netdev->features = NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_TSO | NETIF_F_TSO |
NETIF_F_TSO6 | NETIF_F_TSO6 |
NETIF_F_RXHASH | NETIF_F_RXHASH |
NETIF_F_RXCSUM; NETIF_F_RXCSUM |
NETIF_F_HW_CSUM |
netdev->hw_features = netdev->features | NETIF_F_HW_L2FW_DOFFLOAD; NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
switch (adapter->hw.mac.type) { if (hw->mac.type >= ixgbe_mac_82599EB)
case ixgbe_mac_82599EB:
case ixgbe_mac_X540:
case ixgbe_mac_X550:
case ixgbe_mac_X550EM_x:
netdev->features |= NETIF_F_SCTP_CRC; netdev->features |= NETIF_F_SCTP_CRC;
netdev->hw_features |= NETIF_F_SCTP_CRC |
NETIF_F_NTUPLE |
NETIF_F_HW_TC;
break;
default:
break;
}
netdev->hw_features |= NETIF_F_RXALL; /* copy netdev features into list of user selectable features */
netdev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; netdev->hw_features |= netdev->features;
netdev->hw_features |= NETIF_F_RXALL |
NETIF_F_HW_L2FW_DOFFLOAD;
if (hw->mac.type >= ixgbe_mac_82599EB)
netdev->hw_features |= NETIF_F_NTUPLE |
NETIF_F_HW_TC;
netdev->vlan_features |= NETIF_F_TSO; netdev->vlan_features |= NETIF_F_SG |
netdev->vlan_features |= NETIF_F_TSO6; NETIF_F_TSO |
netdev->vlan_features |= NETIF_F_IP_CSUM; NETIF_F_TSO6 |
netdev->vlan_features |= NETIF_F_IPV6_CSUM; NETIF_F_HW_CSUM |
netdev->vlan_features |= NETIF_F_SG; NETIF_F_SCTP_CRC;
netdev->hw_enc_features |= NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM; netdev->mpls_features |= NETIF_F_HW_CSUM;
netdev->hw_enc_features |= NETIF_F_HW_CSUM;
netdev->priv_flags |= IFF_UNICAST_FLT; netdev->priv_flags |= IFF_UNICAST_FLT;
netdev->priv_flags |= IFF_SUPP_NOFCS; netdev->priv_flags |= IFF_SUPP_NOFCS;
...@@ -9304,7 +9263,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -9304,7 +9263,8 @@ static int ixgbe_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_sw_init; goto err_sw_init;
} }
ixgbe_get_platform_mac_addr(adapter); eth_platform_get_mac_address(&adapter->pdev->dev,
adapter->hw.mac.perm_addr);
memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len); memcpy(netdev->dev_addr, hw->mac.perm_addr, netdev->addr_len);
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -48,10 +48,10 @@ s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) ...@@ -48,10 +48,10 @@ s32 ixgbe_read_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
if (size > mbx->size) if (size > mbx->size)
size = mbx->size; size = mbx->size;
if (!mbx->ops.read) if (!mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
return mbx->ops.read(hw, msg, size, mbx_id); return mbx->ops->read(hw, msg, size, mbx_id);
} }
/** /**
...@@ -70,10 +70,10 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id) ...@@ -70,10 +70,10 @@ s32 ixgbe_write_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, u16 mbx_id)
if (size > mbx->size) if (size > mbx->size)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
if (!mbx->ops.write) if (!mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
return mbx->ops.write(hw, msg, size, mbx_id); return mbx->ops->write(hw, msg, size, mbx_id);
} }
/** /**
...@@ -87,10 +87,10 @@ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id) ...@@ -87,10 +87,10 @@ s32 ixgbe_check_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mbx_info *mbx = &hw->mbx;
if (!mbx->ops.check_for_msg) if (!mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
return mbx->ops.check_for_msg(hw, mbx_id); return mbx->ops->check_for_msg(hw, mbx_id);
} }
/** /**
...@@ -104,10 +104,10 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id) ...@@ -104,10 +104,10 @@ s32 ixgbe_check_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mbx_info *mbx = &hw->mbx;
if (!mbx->ops.check_for_ack) if (!mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
return mbx->ops.check_for_ack(hw, mbx_id); return mbx->ops->check_for_ack(hw, mbx_id);
} }
/** /**
...@@ -121,10 +121,10 @@ s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id) ...@@ -121,10 +121,10 @@ s32 ixgbe_check_for_rst(struct ixgbe_hw *hw, u16 mbx_id)
{ {
struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mbx_info *mbx = &hw->mbx;
if (!mbx->ops.check_for_rst) if (!mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
return mbx->ops.check_for_rst(hw, mbx_id); return mbx->ops->check_for_rst(hw, mbx_id);
} }
/** /**
...@@ -139,10 +139,10 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id) ...@@ -139,10 +139,10 @@ static s32 ixgbe_poll_for_msg(struct ixgbe_hw *hw, u16 mbx_id)
struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout; int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_msg) if (!countdown || !mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
while (mbx->ops.check_for_msg(hw, mbx_id)) { while (mbx->ops->check_for_msg(hw, mbx_id)) {
countdown--; countdown--;
if (!countdown) if (!countdown)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
...@@ -164,10 +164,10 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id) ...@@ -164,10 +164,10 @@ static s32 ixgbe_poll_for_ack(struct ixgbe_hw *hw, u16 mbx_id)
struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mbx_info *mbx = &hw->mbx;
int countdown = mbx->timeout; int countdown = mbx->timeout;
if (!countdown || !mbx->ops.check_for_ack) if (!countdown || !mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
while (mbx->ops.check_for_ack(hw, mbx_id)) { while (mbx->ops->check_for_ack(hw, mbx_id)) {
countdown--; countdown--;
if (!countdown) if (!countdown)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
...@@ -193,7 +193,7 @@ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, ...@@ -193,7 +193,7 @@ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
struct ixgbe_mbx_info *mbx = &hw->mbx; struct ixgbe_mbx_info *mbx = &hw->mbx;
s32 ret_val; s32 ret_val;
if (!mbx->ops.read) if (!mbx->ops)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
ret_val = ixgbe_poll_for_msg(hw, mbx_id); ret_val = ixgbe_poll_for_msg(hw, mbx_id);
...@@ -201,7 +201,7 @@ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, ...@@ -201,7 +201,7 @@ static s32 ixgbe_read_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
return ret_val; return ret_val;
/* if ack received read message */ /* if ack received read message */
return mbx->ops.read(hw, msg, size, mbx_id); return mbx->ops->read(hw, msg, size, mbx_id);
} }
/** /**
...@@ -221,11 +221,11 @@ static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size, ...@@ -221,11 +221,11 @@ static s32 ixgbe_write_posted_mbx(struct ixgbe_hw *hw, u32 *msg, u16 size,
s32 ret_val; s32 ret_val;
/* exit if either we can't write or there isn't a defined timeout */ /* exit if either we can't write or there isn't a defined timeout */
if (!mbx->ops.write || !mbx->timeout) if (!mbx->ops || !mbx->timeout)
return IXGBE_ERR_MBX; return IXGBE_ERR_MBX;
/* send msg */ /* send msg */
ret_val = mbx->ops.write(hw, msg, size, mbx_id); ret_val = mbx->ops->write(hw, msg, size, mbx_id);
if (ret_val) if (ret_val)
return ret_val; return ret_val;
...@@ -446,7 +446,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw) ...@@ -446,7 +446,7 @@ void ixgbe_init_mbx_params_pf(struct ixgbe_hw *hw)
} }
#endif /* CONFIG_PCI_IOV */ #endif /* CONFIG_PCI_IOV */
struct ixgbe_mbx_operations mbx_ops_generic = { const struct ixgbe_mbx_operations mbx_ops_generic = {
.read = ixgbe_read_mbx_pf, .read = ixgbe_read_mbx_pf,
.write = ixgbe_write_mbx_pf, .write = ixgbe_write_mbx_pf,
.read_posted = ixgbe_read_posted_mbx, .read_posted = ixgbe_read_posted_mbx,
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2013 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -123,6 +123,6 @@ s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16); ...@@ -123,6 +123,6 @@ s32 ixgbe_check_for_rst(struct ixgbe_hw *, u16);
void ixgbe_init_mbx_params_pf(struct ixgbe_hw *); void ixgbe_init_mbx_params_pf(struct ixgbe_hw *);
#endif /* CONFIG_PCI_IOV */ #endif /* CONFIG_PCI_IOV */
extern struct ixgbe_mbx_operations mbx_ops_generic; extern const struct ixgbe_mbx_operations mbx_ops_generic;
#endif /* _IXGBE_MBX_H_ */ #endif /* _IXGBE_MBX_H_ */
...@@ -82,6 +82,12 @@ static struct ixgbe_mat_field ixgbe_tcp_fields[] = { ...@@ -82,6 +82,12 @@ static struct ixgbe_mat_field ixgbe_tcp_fields[] = {
{ .val = NULL } /* terminal node */ { .val = NULL } /* terminal node */
}; };
static struct ixgbe_mat_field ixgbe_udp_fields[] = {
{.off = 0, .val = ixgbe_mat_prgm_ports,
.type = IXGBE_ATR_FLOW_TYPE_UDPV4},
{ .val = NULL } /* terminal node */
};
struct ixgbe_nexthdr { struct ixgbe_nexthdr {
/* offset, shift, and mask of position to next header */ /* offset, shift, and mask of position to next header */
unsigned int o; unsigned int o;
...@@ -98,6 +104,8 @@ struct ixgbe_nexthdr { ...@@ -98,6 +104,8 @@ struct ixgbe_nexthdr {
static struct ixgbe_nexthdr ixgbe_ipv4_jumps[] = { static struct ixgbe_nexthdr ixgbe_ipv4_jumps[] = {
{ .o = 0, .s = 6, .m = 0xf, { .o = 0, .s = 6, .m = 0xf,
.off = 8, .val = 0x600, .mask = 0xff00, .jump = ixgbe_tcp_fields}, .off = 8, .val = 0x600, .mask = 0xff00, .jump = ixgbe_tcp_fields},
{ .o = 0, .s = 6, .m = 0xf,
.off = 8, .val = 0x1100, .mask = 0xff00, .jump = ixgbe_udp_fields},
{ .jump = NULL } /* terminal node */ { .jump = NULL } /* terminal node */
}; };
#endif /* _IXGBE_MODEL_H_ */ #endif /* _IXGBE_MODEL_H_ */
...@@ -589,40 +589,40 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf) ...@@ -589,40 +589,40 @@ static void ixgbe_clear_vmvir(struct ixgbe_adapter *adapter, u32 vf)
static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf) static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
{ {
struct ixgbe_hw *hw = &adapter->hw; struct ixgbe_hw *hw = &adapter->hw;
u32 i; u32 vlvfb_mask, pool_mask, i;
/* create mask for VF and other pools */
pool_mask = ~(1 << (VMDQ_P(0) % 32));
vlvfb_mask = 1 << (vf % 32);
/* post increment loop, covers VLVF_ENTRIES - 1 to 0 */ /* post increment loop, covers VLVF_ENTRIES - 1 to 0 */
for (i = IXGBE_VLVF_ENTRIES; i--;) { for (i = IXGBE_VLVF_ENTRIES; i--;) {
u32 bits[2], vlvfb, vid, vfta, vlvf; u32 bits[2], vlvfb, vid, vfta, vlvf;
u32 word = i * 2 + vf / 32; u32 word = i * 2 + vf / 32;
u32 mask = 1 << (vf % 32); u32 mask;
vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word)); vlvfb = IXGBE_READ_REG(hw, IXGBE_VLVFB(word));
/* if our bit isn't set we can skip it */ /* if our bit isn't set we can skip it */
if (!(vlvfb & mask)) if (!(vlvfb & vlvfb_mask))
continue; continue;
/* clear our bit from vlvfb */ /* clear our bit from vlvfb */
vlvfb ^= mask; vlvfb ^= vlvfb_mask;
/* create 64b mask to chedk to see if we should clear VLVF */ /* create 64b mask to chedk to see if we should clear VLVF */
bits[word % 2] = vlvfb; bits[word % 2] = vlvfb;
bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1)); bits[~word % 2] = IXGBE_READ_REG(hw, IXGBE_VLVFB(word ^ 1));
/* if promisc is enabled, PF will be present, leave VFTA */
if (adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC) {
bits[VMDQ_P(0) / 32] &= ~(1 << (VMDQ_P(0) % 32));
if (bits[0] || bits[1])
goto update_vlvfb;
goto update_vlvf;
}
/* if other pools are present, just remove ourselves */ /* if other pools are present, just remove ourselves */
if (bits[0] || bits[1]) if (bits[(VMDQ_P(0) / 32) ^ 1] ||
(bits[VMDQ_P(0) / 32] & pool_mask))
goto update_vlvfb; goto update_vlvfb;
/* if PF is present, leave VFTA */
if (bits[0] || bits[1])
goto update_vlvf;
/* if we cannot determine VLAN just remove ourselves */ /* if we cannot determine VLAN just remove ourselves */
vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i)); vlvf = IXGBE_READ_REG(hw, IXGBE_VLVF(i));
if (!vlvf) if (!vlvf)
...@@ -638,6 +638,9 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf) ...@@ -638,6 +638,9 @@ static void ixgbe_clear_vf_vlans(struct ixgbe_adapter *adapter, u32 vf)
update_vlvf: update_vlvf:
/* clear POOL selection enable */ /* clear POOL selection enable */
IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0); IXGBE_WRITE_REG(hw, IXGBE_VLVF(i), 0);
if (!(adapter->flags2 & IXGBE_FLAG2_VLAN_PROMISC))
vlvfb = 0;
update_vlvfb: update_vlvfb:
/* clear pool bits */ /* clear pool bits */
IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb); IXGBE_WRITE_REG(hw, IXGBE_VLVFB(word), vlvfb);
...@@ -887,7 +890,7 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter, ...@@ -887,7 +890,7 @@ static int ixgbe_set_vf_mac_addr(struct ixgbe_adapter *adapter,
return -1; return -1;
} }
if (adapter->vfinfo[vf].pf_set_mac && if (adapter->vfinfo[vf].pf_set_mac && !adapter->vfinfo[vf].trusted &&
!ether_addr_equal(adapter->vfinfo[vf].vf_mac_addresses, new_mac)) { !ether_addr_equal(adapter->vfinfo[vf].vf_mac_addresses, new_mac)) {
e_warn(drv, e_warn(drv,
"VF %d attempted to override administratively set MAC address\n" "VF %d attempted to override administratively set MAC address\n"
...@@ -1395,7 +1398,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos) ...@@ -1395,7 +1398,7 @@ int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int vf, u16 vlan, u8 qos)
return err; return err;
} }
static int ixgbe_link_mbps(struct ixgbe_adapter *adapter) int ixgbe_link_mbps(struct ixgbe_adapter *adapter)
{ {
switch (adapter->link_speed) { switch (adapter->link_speed) {
case IXGBE_LINK_SPEED_100_FULL: case IXGBE_LINK_SPEED_100_FULL:
......
...@@ -44,6 +44,7 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter); ...@@ -44,6 +44,7 @@ void ixgbe_ping_all_vfs(struct ixgbe_adapter *adapter);
int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac); int ixgbe_ndo_set_vf_mac(struct net_device *netdev, int queue, u8 *mac);
int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan, int ixgbe_ndo_set_vf_vlan(struct net_device *netdev, int queue, u16 vlan,
u8 qos); u8 qos);
int ixgbe_link_mbps(struct ixgbe_adapter *adapter);
int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate, int ixgbe_ndo_set_vf_bw(struct net_device *netdev, int vf, int min_tx_rate,
int max_tx_rate); int max_tx_rate);
int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting); int ixgbe_ndo_set_vf_spoofchk(struct net_device *netdev, int vf, bool setting);
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2015 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -3266,6 +3266,7 @@ struct ixgbe_mac_operations { ...@@ -3266,6 +3266,7 @@ struct ixgbe_mac_operations {
s32 (*enable_rx_dma)(struct ixgbe_hw *, u32); s32 (*enable_rx_dma)(struct ixgbe_hw *, u32);
s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32); s32 (*acquire_swfw_sync)(struct ixgbe_hw *, u32);
void (*release_swfw_sync)(struct ixgbe_hw *, u32); void (*release_swfw_sync)(struct ixgbe_hw *, u32);
void (*init_swfw_sync)(struct ixgbe_hw *);
s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *); s32 (*prot_autoc_read)(struct ixgbe_hw *, bool *, u32 *);
s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool); s32 (*prot_autoc_write)(struct ixgbe_hw *, u32, bool);
...@@ -3308,6 +3309,7 @@ struct ixgbe_mac_operations { ...@@ -3308,6 +3309,7 @@ struct ixgbe_mac_operations {
/* Flow Control */ /* Flow Control */
s32 (*fc_enable)(struct ixgbe_hw *); s32 (*fc_enable)(struct ixgbe_hw *);
s32 (*setup_fc)(struct ixgbe_hw *);
/* Manageability interface */ /* Manageability interface */
s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8); s32 (*set_fw_drv_ver)(struct ixgbe_hw *, u8, u8, u8, u8);
...@@ -3442,7 +3444,7 @@ struct ixgbe_mbx_stats { ...@@ -3442,7 +3444,7 @@ struct ixgbe_mbx_stats {
}; };
struct ixgbe_mbx_info { struct ixgbe_mbx_info {
struct ixgbe_mbx_operations ops; const struct ixgbe_mbx_operations *ops;
struct ixgbe_mbx_stats stats; struct ixgbe_mbx_stats stats;
u32 timeout; u32 timeout;
u32 usec_delay; u32 usec_delay;
...@@ -3475,10 +3477,10 @@ struct ixgbe_hw { ...@@ -3475,10 +3477,10 @@ struct ixgbe_hw {
struct ixgbe_info { struct ixgbe_info {
enum ixgbe_mac_type mac; enum ixgbe_mac_type mac;
s32 (*get_invariants)(struct ixgbe_hw *); s32 (*get_invariants)(struct ixgbe_hw *);
struct ixgbe_mac_operations *mac_ops; const struct ixgbe_mac_operations *mac_ops;
struct ixgbe_eeprom_operations *eeprom_ops; const struct ixgbe_eeprom_operations *eeprom_ops;
struct ixgbe_phy_operations *phy_ops; const struct ixgbe_phy_operations *phy_ops;
struct ixgbe_mbx_operations *mbx_ops; const struct ixgbe_mbx_operations *mbx_ops;
const u32 *mvals; const u32 *mvals;
}; };
...@@ -3525,6 +3527,7 @@ struct ixgbe_info { ...@@ -3525,6 +3527,7 @@ struct ixgbe_info {
#define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010) #define IXGBE_KRM_PORT_CAR_GEN_CTRL(P) ((P) ? 0x8010 : 0x4010)
#define IXGBE_KRM_LINK_CTRL_1(P) ((P) ? 0x820C : 0x420C) #define IXGBE_KRM_LINK_CTRL_1(P) ((P) ? 0x820C : 0x420C)
#define IXGBE_KRM_AN_CNTL_1(P) ((P) ? 0x822C : 0x422C)
#define IXGBE_KRM_DSP_TXFFE_STATE_4(P) ((P) ? 0x8634 : 0x4634) #define IXGBE_KRM_DSP_TXFFE_STATE_4(P) ((P) ? 0x8634 : 0x4634)
#define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P) ? 0x8638 : 0x4638) #define IXGBE_KRM_DSP_TXFFE_STATE_5(P) ((P) ? 0x8638 : 0x4638)
#define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P) ((P) ? 0x8B00 : 0x4B00) #define IXGBE_KRM_RX_TRN_LINKUP_CTRL(P) ((P) ? 0x8B00 : 0x4B00)
...@@ -3547,6 +3550,9 @@ struct ixgbe_info { ...@@ -3547,6 +3550,9 @@ struct ixgbe_info {
#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE (1 << 29) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_ENABLE (1 << 29)
#define IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART (1 << 31) #define IXGBE_KRM_LINK_CTRL_1_TETH_AN_RESTART (1 << 31)
#define IXGBE_KRM_AN_CNTL_1_SYM_PAUSE (1 << 28)
#define IXGBE_KRM_AN_CNTL_1_ASM_PAUSE (1 << 29)
#define IXGBE_KRM_DSP_TXFFE_STATE_C0_EN (1 << 6) #define IXGBE_KRM_DSP_TXFFE_STATE_C0_EN (1 << 6)
#define IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN (1 << 15) #define IXGBE_KRM_DSP_TXFFE_STATE_CP1_CN1_EN (1 << 15)
#define IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN (1 << 16) #define IXGBE_KRM_DSP_TXFFE_STATE_CO_ADAPT_EN (1 << 16)
......
/******************************************************************************* /*******************************************************************************
Intel 10 Gigabit PCI Express Linux driver Intel 10 Gigabit PCI Express Linux driver
Copyright(c) 1999 - 2014 Intel Corporation. Copyright(c) 1999 - 2016 Intel Corporation.
This program is free software; you can redistribute it and/or modify it This program is free software; you can redistribute it and/or modify it
under the terms and conditions of the GNU General Public License, under the terms and conditions of the GNU General Public License,
...@@ -746,6 +746,25 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw) ...@@ -746,6 +746,25 @@ static void ixgbe_release_swfw_sync_semaphore(struct ixgbe_hw *hw)
IXGBE_WRITE_FLUSH(hw); IXGBE_WRITE_FLUSH(hw);
} }
/**
* ixgbe_init_swfw_sync_X540 - Release hardware semaphore
* @hw: pointer to hardware structure
*
* This function reset hardware semaphore bits for a semaphore that may
* have be left locked due to a catastrophic failure.
**/
void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw)
{
/* First try to grab the semaphore but we don't need to bother
* looking to see whether we got the lock or not since we do
* the same thing regardless of whether we got the lock or not.
* We got the lock - we release it.
* We timeout trying to get the lock - we force its release.
*/
ixgbe_get_swfw_sync_semaphore(hw);
ixgbe_release_swfw_sync_semaphore(hw);
}
/** /**
* ixgbe_blink_led_start_X540 - Blink LED based on index. * ixgbe_blink_led_start_X540 - Blink LED based on index.
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
...@@ -810,7 +829,7 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index) ...@@ -810,7 +829,7 @@ s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index)
return 0; return 0;
} }
static struct ixgbe_mac_operations mac_ops_X540 = { static const struct ixgbe_mac_operations mac_ops_X540 = {
.init_hw = &ixgbe_init_hw_generic, .init_hw = &ixgbe_init_hw_generic,
.reset_hw = &ixgbe_reset_hw_X540, .reset_hw = &ixgbe_reset_hw_X540,
.start_hw = &ixgbe_start_hw_X540, .start_hw = &ixgbe_start_hw_X540,
...@@ -846,6 +865,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = { ...@@ -846,6 +865,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.clear_vfta = &ixgbe_clear_vfta_generic, .clear_vfta = &ixgbe_clear_vfta_generic,
.set_vfta = &ixgbe_set_vfta_generic, .set_vfta = &ixgbe_set_vfta_generic,
.fc_enable = &ixgbe_fc_enable_generic, .fc_enable = &ixgbe_fc_enable_generic,
.setup_fc = ixgbe_setup_fc_generic,
.set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic, .set_fw_drv_ver = &ixgbe_set_fw_drv_ver_generic,
.init_uta_tables = &ixgbe_init_uta_tables_generic, .init_uta_tables = &ixgbe_init_uta_tables_generic,
.setup_sfp = NULL, .setup_sfp = NULL,
...@@ -853,6 +873,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = { ...@@ -853,6 +873,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing, .set_vlan_anti_spoofing = &ixgbe_set_vlan_anti_spoofing,
.acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540, .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540,
.release_swfw_sync = &ixgbe_release_swfw_sync_X540, .release_swfw_sync = &ixgbe_release_swfw_sync_X540,
.init_swfw_sync = &ixgbe_init_swfw_sync_X540,
.disable_rx_buff = &ixgbe_disable_rx_buff_generic, .disable_rx_buff = &ixgbe_disable_rx_buff_generic,
.enable_rx_buff = &ixgbe_enable_rx_buff_generic, .enable_rx_buff = &ixgbe_enable_rx_buff_generic,
.get_thermal_sensor_data = NULL, .get_thermal_sensor_data = NULL,
...@@ -863,7 +884,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = { ...@@ -863,7 +884,7 @@ static struct ixgbe_mac_operations mac_ops_X540 = {
.disable_rx = &ixgbe_disable_rx_generic, .disable_rx = &ixgbe_disable_rx_generic,
}; };
static struct ixgbe_eeprom_operations eeprom_ops_X540 = { static const struct ixgbe_eeprom_operations eeprom_ops_X540 = {
.init_params = &ixgbe_init_eeprom_params_X540, .init_params = &ixgbe_init_eeprom_params_X540,
.read = &ixgbe_read_eerd_X540, .read = &ixgbe_read_eerd_X540,
.read_buffer = &ixgbe_read_eerd_buffer_X540, .read_buffer = &ixgbe_read_eerd_buffer_X540,
...@@ -874,7 +895,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_X540 = { ...@@ -874,7 +895,7 @@ static struct ixgbe_eeprom_operations eeprom_ops_X540 = {
.update_checksum = &ixgbe_update_eeprom_checksum_X540, .update_checksum = &ixgbe_update_eeprom_checksum_X540,
}; };
static struct ixgbe_phy_operations phy_ops_X540 = { static const struct ixgbe_phy_operations phy_ops_X540 = {
.identify = &ixgbe_identify_phy_generic, .identify = &ixgbe_identify_phy_generic,
.identify_sfp = &ixgbe_identify_sfp_module_generic, .identify_sfp = &ixgbe_identify_sfp_module_generic,
.init = NULL, .init = NULL,
...@@ -897,7 +918,7 @@ static const u32 ixgbe_mvals_X540[IXGBE_MVALS_IDX_LIMIT] = { ...@@ -897,7 +918,7 @@ static const u32 ixgbe_mvals_X540[IXGBE_MVALS_IDX_LIMIT] = {
IXGBE_MVALS_INIT(X540) IXGBE_MVALS_INIT(X540)
}; };
struct ixgbe_info ixgbe_X540_info = { const struct ixgbe_info ixgbe_X540_info = {
.mac = ixgbe_mac_X540, .mac = ixgbe_mac_X540,
.get_invariants = &ixgbe_get_invariants_X540, .get_invariants = &ixgbe_get_invariants_X540,
.mac_ops = &mac_ops_X540, .mac_ops = &mac_ops_X540,
......
...@@ -36,4 +36,5 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index); ...@@ -36,4 +36,5 @@ s32 ixgbe_blink_led_start_X540(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index); s32 ixgbe_blink_led_stop_X540(struct ixgbe_hw *hw, u32 index);
s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); s32 ixgbe_acquire_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask); void ixgbe_release_swfw_sync_X540(struct ixgbe_hw *hw, u32 mask);
void ixgbe_init_swfw_sync_X540(struct ixgbe_hw *hw);
s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw); s32 ixgbe_init_eeprom_params_X540(struct ixgbe_hw *hw);
/******************************************************************************* /*******************************************************************************
* *
* Intel 10 Gigabit PCI Express Linux driver * Intel 10 Gigabit PCI Express Linux driver
* Copyright(c) 1999 - 2015 Intel Corporation. * Copyright(c) 1999 - 2016 Intel Corporation.
* *
* This program is free software; you can redistribute it and/or modify it * This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License, * under the terms and conditions of the GNU General Public License,
...@@ -27,6 +27,7 @@ ...@@ -27,6 +27,7 @@
#include "ixgbe_phy.h" #include "ixgbe_phy.h"
static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed); static s32 ixgbe_setup_kr_speed_x550em(struct ixgbe_hw *, ixgbe_link_speed);
static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *);
static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw) static s32 ixgbe_get_invariants_X550_x(struct ixgbe_hw *hw)
{ {
...@@ -1342,15 +1343,18 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw) ...@@ -1342,15 +1343,18 @@ static void ixgbe_init_mac_link_ops_X550em(struct ixgbe_hw *hw)
mac->ops.enable_tx_laser = NULL; mac->ops.enable_tx_laser = NULL;
mac->ops.flap_tx_laser = NULL; mac->ops.flap_tx_laser = NULL;
mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber; mac->ops.setup_link = ixgbe_setup_mac_link_multispeed_fiber;
mac->ops.setup_fc = ixgbe_setup_fc_x550em;
mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em; mac->ops.setup_mac_link = ixgbe_setup_mac_link_sfp_x550em;
mac->ops.set_rate_select_speed = mac->ops.set_rate_select_speed =
ixgbe_set_soft_rate_select_speed; ixgbe_set_soft_rate_select_speed;
break; break;
case ixgbe_media_type_copper: case ixgbe_media_type_copper:
mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em; mac->ops.setup_link = ixgbe_setup_mac_link_t_X550em;
mac->ops.setup_fc = ixgbe_setup_fc_generic;
mac->ops.check_link = ixgbe_check_link_t_X550em; mac->ops.check_link = ixgbe_check_link_t_X550em;
break; break;
default: default:
mac->ops.setup_fc = ixgbe_setup_fc_x550em;
break; break;
} }
} }
...@@ -1842,6 +1846,82 @@ static s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw, ...@@ -1842,6 +1846,82 @@ static s32 ixgbe_get_lcd_t_x550em(struct ixgbe_hw *hw,
return status; return status;
} }
/**
* ixgbe_setup_fc_x550em - Set up flow control
* @hw: pointer to hardware structure
*/
static s32 ixgbe_setup_fc_x550em(struct ixgbe_hw *hw)
{
bool pause, asm_dir;
u32 reg_val;
s32 rc;
/* Validate the requested mode */
if (hw->fc.strict_ieee && hw->fc.requested_mode == ixgbe_fc_rx_pause) {
hw_err(hw, "ixgbe_fc_rx_pause not valid in strict IEEE mode\n");
return IXGBE_ERR_INVALID_LINK_SETTINGS;
}
/* 10gig parts do not have a word in the EEPROM to determine the
* default flow control setting, so we explicitly set it to full.
*/
if (hw->fc.requested_mode == ixgbe_fc_default)
hw->fc.requested_mode = ixgbe_fc_full;
/* Determine PAUSE and ASM_DIR bits. */
switch (hw->fc.requested_mode) {
case ixgbe_fc_none:
pause = false;
asm_dir = false;
break;
case ixgbe_fc_tx_pause:
pause = false;
asm_dir = true;
break;
case ixgbe_fc_rx_pause:
/* Rx Flow control is enabled and Tx Flow control is
* disabled by software override. Since there really
* isn't a way to advertise that we are capable of RX
* Pause ONLY, we will advertise that we support both
* symmetric and asymmetric Rx PAUSE, as such we fall
* through to the fc_full statement. Later, we will
* disable the adapter's ability to send PAUSE frames.
*/
/* Fallthrough */
case ixgbe_fc_full:
pause = true;
asm_dir = true;
break;
default:
hw_err(hw, "Flow control param set incorrectly\n");
return IXGBE_ERR_CONFIG;
}
if (hw->device_id != IXGBE_DEV_ID_X550EM_X_KR)
return 0;
rc = ixgbe_read_iosf_sb_reg_x550(hw,
IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
IXGBE_SB_IOSF_TARGET_KR_PHY, &reg_val);
if (rc)
return rc;
reg_val &= ~(IXGBE_KRM_AN_CNTL_1_SYM_PAUSE |
IXGBE_KRM_AN_CNTL_1_ASM_PAUSE);
if (pause)
reg_val |= IXGBE_KRM_AN_CNTL_1_SYM_PAUSE;
if (asm_dir)
reg_val |= IXGBE_KRM_AN_CNTL_1_ASM_PAUSE;
rc = ixgbe_write_iosf_sb_reg_x550(hw,
IXGBE_KRM_AN_CNTL_1(hw->bus.lan_id),
IXGBE_SB_IOSF_TARGET_KR_PHY, reg_val);
/* This device does not fully support AN. */
hw->fc.disable_fc_autoneg = true;
return rc;
}
/** ixgbe_enter_lplu_x550em - Transition to low power states /** ixgbe_enter_lplu_x550em - Transition to low power states
* @hw: pointer to hardware structure * @hw: pointer to hardware structure
* *
...@@ -2337,12 +2417,10 @@ static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask) ...@@ -2337,12 +2417,10 @@ static void ixgbe_release_swfw_sync_X550em(struct ixgbe_hw *hw, u32 mask)
.enable_rx_buff = &ixgbe_enable_rx_buff_generic, \ .enable_rx_buff = &ixgbe_enable_rx_buff_generic, \
.get_thermal_sensor_data = NULL, \ .get_thermal_sensor_data = NULL, \
.init_thermal_sensor_thresh = NULL, \ .init_thermal_sensor_thresh = NULL, \
.prot_autoc_read = &prot_autoc_read_generic, \
.prot_autoc_write = &prot_autoc_write_generic, \
.enable_rx = &ixgbe_enable_rx_generic, \ .enable_rx = &ixgbe_enable_rx_generic, \
.disable_rx = &ixgbe_disable_rx_x550, \ .disable_rx = &ixgbe_disable_rx_x550, \
static struct ixgbe_mac_operations mac_ops_X550 = { static const struct ixgbe_mac_operations mac_ops_X550 = {
X550_COMMON_MAC X550_COMMON_MAC
.reset_hw = &ixgbe_reset_hw_X540, .reset_hw = &ixgbe_reset_hw_X540,
.get_media_type = &ixgbe_get_media_type_X540, .get_media_type = &ixgbe_get_media_type_X540,
...@@ -2354,9 +2432,13 @@ static struct ixgbe_mac_operations mac_ops_X550 = { ...@@ -2354,9 +2432,13 @@ static struct ixgbe_mac_operations mac_ops_X550 = {
.setup_sfp = NULL, .setup_sfp = NULL,
.acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540, .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X540,
.release_swfw_sync = &ixgbe_release_swfw_sync_X540, .release_swfw_sync = &ixgbe_release_swfw_sync_X540,
.init_swfw_sync = &ixgbe_init_swfw_sync_X540,
.prot_autoc_read = prot_autoc_read_generic,
.prot_autoc_write = prot_autoc_write_generic,
.setup_fc = ixgbe_setup_fc_generic,
}; };
static struct ixgbe_mac_operations mac_ops_X550EM_x = { static const struct ixgbe_mac_operations mac_ops_X550EM_x = {
X550_COMMON_MAC X550_COMMON_MAC
.reset_hw = &ixgbe_reset_hw_X550em, .reset_hw = &ixgbe_reset_hw_X550em,
.get_media_type = &ixgbe_get_media_type_X550em, .get_media_type = &ixgbe_get_media_type_X550em,
...@@ -2368,6 +2450,8 @@ static struct ixgbe_mac_operations mac_ops_X550EM_x = { ...@@ -2368,6 +2450,8 @@ static struct ixgbe_mac_operations mac_ops_X550EM_x = {
.setup_sfp = ixgbe_setup_sfp_modules_X550em, .setup_sfp = ixgbe_setup_sfp_modules_X550em,
.acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X550em, .acquire_swfw_sync = &ixgbe_acquire_swfw_sync_X550em,
.release_swfw_sync = &ixgbe_release_swfw_sync_X550em, .release_swfw_sync = &ixgbe_release_swfw_sync_X550em,
.init_swfw_sync = &ixgbe_init_swfw_sync_X540,
.setup_fc = NULL, /* defined later */
}; };
#define X550_COMMON_EEP \ #define X550_COMMON_EEP \
...@@ -2379,12 +2463,12 @@ static struct ixgbe_mac_operations mac_ops_X550EM_x = { ...@@ -2379,12 +2463,12 @@ static struct ixgbe_mac_operations mac_ops_X550EM_x = {
.update_checksum = &ixgbe_update_eeprom_checksum_X550, \ .update_checksum = &ixgbe_update_eeprom_checksum_X550, \
.calc_checksum = &ixgbe_calc_eeprom_checksum_X550, \ .calc_checksum = &ixgbe_calc_eeprom_checksum_X550, \
static struct ixgbe_eeprom_operations eeprom_ops_X550 = { static const struct ixgbe_eeprom_operations eeprom_ops_X550 = {
X550_COMMON_EEP X550_COMMON_EEP
.init_params = &ixgbe_init_eeprom_params_X550, .init_params = &ixgbe_init_eeprom_params_X550,
}; };
static struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = { static const struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
X550_COMMON_EEP X550_COMMON_EEP
.init_params = &ixgbe_init_eeprom_params_X540, .init_params = &ixgbe_init_eeprom_params_X540,
}; };
...@@ -2405,13 +2489,13 @@ static struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = { ...@@ -2405,13 +2489,13 @@ static struct ixgbe_eeprom_operations eeprom_ops_X550EM_x = {
.check_overtemp = &ixgbe_tn_check_overtemp, \ .check_overtemp = &ixgbe_tn_check_overtemp, \
.get_firmware_version = &ixgbe_get_phy_firmware_version_generic, .get_firmware_version = &ixgbe_get_phy_firmware_version_generic,
static struct ixgbe_phy_operations phy_ops_X550 = { static const struct ixgbe_phy_operations phy_ops_X550 = {
X550_COMMON_PHY X550_COMMON_PHY
.init = NULL, .init = NULL,
.identify = &ixgbe_identify_phy_generic, .identify = &ixgbe_identify_phy_generic,
}; };
static struct ixgbe_phy_operations phy_ops_X550EM_x = { static const struct ixgbe_phy_operations phy_ops_X550EM_x = {
X550_COMMON_PHY X550_COMMON_PHY
.init = &ixgbe_init_phy_ops_X550em, .init = &ixgbe_init_phy_ops_X550em,
.identify = &ixgbe_identify_phy_x550em, .identify = &ixgbe_identify_phy_x550em,
...@@ -2430,7 +2514,7 @@ static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = { ...@@ -2430,7 +2514,7 @@ static const u32 ixgbe_mvals_X550EM_x[IXGBE_MVALS_IDX_LIMIT] = {
IXGBE_MVALS_INIT(X550EM_x) IXGBE_MVALS_INIT(X550EM_x)
}; };
struct ixgbe_info ixgbe_X550_info = { const struct ixgbe_info ixgbe_X550_info = {
.mac = ixgbe_mac_X550, .mac = ixgbe_mac_X550,
.get_invariants = &ixgbe_get_invariants_X540, .get_invariants = &ixgbe_get_invariants_X540,
.mac_ops = &mac_ops_X550, .mac_ops = &mac_ops_X550,
...@@ -2440,7 +2524,7 @@ struct ixgbe_info ixgbe_X550_info = { ...@@ -2440,7 +2524,7 @@ struct ixgbe_info ixgbe_X550_info = {
.mvals = ixgbe_mvals_X550, .mvals = ixgbe_mvals_X550,
}; };
struct ixgbe_info ixgbe_X550EM_x_info = { const struct ixgbe_info ixgbe_X550EM_x_info = {
.mac = ixgbe_mac_X550EM_x, .mac = ixgbe_mac_X550EM_x,
.get_invariants = &ixgbe_get_invariants_X550_x, .get_invariants = &ixgbe_get_invariants_X550_x,
.mac_ops = &mac_ops_X550EM_x, .mac_ops = &mac_ops_X550EM_x,
......
...@@ -403,13 +403,6 @@ struct ixgbevf_adapter { ...@@ -403,13 +403,6 @@ struct ixgbevf_adapter {
u32 alloc_rx_page_failed; u32 alloc_rx_page_failed;
u32 alloc_rx_buff_failed; u32 alloc_rx_buff_failed;
/* Some features need tri-state capability,
* thus the additional *_CAPABLE flags.
*/
u32 flags;
#define IXGBEVF_FLAG_RESET_REQUESTED (u32)(1)
#define IXGBEVF_FLAG_QUEUE_RESET_REQUESTED (u32)(1 << 2)
struct msix_entry *msix_entries; struct msix_entry *msix_entries;
/* OS defined structs */ /* OS defined structs */
...@@ -461,6 +454,8 @@ enum ixbgevf_state_t { ...@@ -461,6 +454,8 @@ enum ixbgevf_state_t {
__IXGBEVF_REMOVING, __IXGBEVF_REMOVING,
__IXGBEVF_SERVICE_SCHED, __IXGBEVF_SERVICE_SCHED,
__IXGBEVF_SERVICE_INITED, __IXGBEVF_SERVICE_INITED,
__IXGBEVF_RESET_REQUESTED,
__IXGBEVF_QUEUE_RESET_REQUESTED,
}; };
enum ixgbevf_boards { enum ixgbevf_boards {
......
...@@ -268,7 +268,7 @@ static void ixgbevf_tx_timeout_reset(struct ixgbevf_adapter *adapter) ...@@ -268,7 +268,7 @@ static void ixgbevf_tx_timeout_reset(struct ixgbevf_adapter *adapter)
{ {
/* Do the reset outside of interrupt context */ /* Do the reset outside of interrupt context */
if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) { if (!test_bit(__IXGBEVF_DOWN, &adapter->state)) {
adapter->flags |= IXGBEVF_FLAG_RESET_REQUESTED; set_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state);
ixgbevf_service_event_schedule(adapter); ixgbevf_service_event_schedule(adapter);
} }
} }
...@@ -1984,7 +1984,7 @@ static int ixgbevf_configure_dcb(struct ixgbevf_adapter *adapter) ...@@ -1984,7 +1984,7 @@ static int ixgbevf_configure_dcb(struct ixgbevf_adapter *adapter)
hw->mbx.timeout = 0; hw->mbx.timeout = 0;
/* wait for watchdog to come around and bail us out */ /* wait for watchdog to come around and bail us out */
adapter->flags |= IXGBEVF_FLAG_QUEUE_RESET_REQUESTED; set_bit(__IXGBEVF_QUEUE_RESET_REQUESTED, &adapter->state);
} }
return 0; return 0;
...@@ -2749,11 +2749,9 @@ static void ixgbevf_service_timer(unsigned long data) ...@@ -2749,11 +2749,9 @@ static void ixgbevf_service_timer(unsigned long data)
static void ixgbevf_reset_subtask(struct ixgbevf_adapter *adapter) static void ixgbevf_reset_subtask(struct ixgbevf_adapter *adapter)
{ {
if (!(adapter->flags & IXGBEVF_FLAG_RESET_REQUESTED)) if (!test_and_clear_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state))
return; return;
adapter->flags &= ~IXGBEVF_FLAG_RESET_REQUESTED;
/* If we're already down or resetting, just bail */ /* If we're already down or resetting, just bail */
if (test_bit(__IXGBEVF_DOWN, &adapter->state) || if (test_bit(__IXGBEVF_DOWN, &adapter->state) ||
test_bit(__IXGBEVF_RESETTING, &adapter->state)) test_bit(__IXGBEVF_RESETTING, &adapter->state))
...@@ -2821,7 +2819,7 @@ static void ixgbevf_watchdog_update_link(struct ixgbevf_adapter *adapter) ...@@ -2821,7 +2819,7 @@ static void ixgbevf_watchdog_update_link(struct ixgbevf_adapter *adapter)
/* if check for link returns error we will need to reset */ /* if check for link returns error we will need to reset */
if (err && time_after(jiffies, adapter->last_reset + (10 * HZ))) { if (err && time_after(jiffies, adapter->last_reset + (10 * HZ))) {
adapter->flags |= IXGBEVF_FLAG_RESET_REQUESTED; set_bit(__IXGBEVF_RESET_REQUESTED, &adapter->state);
link_up = false; link_up = false;
} }
...@@ -3222,11 +3220,10 @@ static void ixgbevf_queue_reset_subtask(struct ixgbevf_adapter *adapter) ...@@ -3222,11 +3220,10 @@ static void ixgbevf_queue_reset_subtask(struct ixgbevf_adapter *adapter)
{ {
struct net_device *dev = adapter->netdev; struct net_device *dev = adapter->netdev;
if (!(adapter->flags & IXGBEVF_FLAG_QUEUE_RESET_REQUESTED)) if (!test_and_clear_bit(__IXGBEVF_QUEUE_RESET_REQUESTED,
&adapter->state))
return; return;
adapter->flags &= ~IXGBEVF_FLAG_QUEUE_RESET_REQUESTED;
/* if interface is down do nothing */ /* if interface is down do nothing */
if (test_bit(__IXGBEVF_DOWN, &adapter->state) || if (test_bit(__IXGBEVF_DOWN, &adapter->state) ||
test_bit(__IXGBEVF_RESETTING, &adapter->state)) test_bit(__IXGBEVF_RESETTING, &adapter->state))
...@@ -3337,76 +3334,55 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring, ...@@ -3337,76 +3334,55 @@ static int ixgbevf_tso(struct ixgbevf_ring *tx_ring,
return 1; return 1;
} }
static inline bool ixgbevf_ipv6_csum_is_sctp(struct sk_buff *skb)
{
unsigned int offset = 0;
ipv6_find_hdr(skb, &offset, IPPROTO_SCTP, NULL, NULL);
return offset == skb_checksum_start_offset(skb);
}
static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring, static void ixgbevf_tx_csum(struct ixgbevf_ring *tx_ring,
struct ixgbevf_tx_buffer *first) struct ixgbevf_tx_buffer *first)
{ {
struct sk_buff *skb = first->skb; struct sk_buff *skb = first->skb;
u32 vlan_macip_lens = 0; u32 vlan_macip_lens = 0;
u32 mss_l4len_idx = 0;
u32 type_tucmd = 0; u32 type_tucmd = 0;
if (skb->ip_summed == CHECKSUM_PARTIAL) { if (skb->ip_summed != CHECKSUM_PARTIAL)
u8 l4_hdr = 0; goto no_csum;
__be16 frag_off;
switch (first->protocol) {
case htons(ETH_P_IP):
vlan_macip_lens |= skb_network_header_len(skb);
type_tucmd |= IXGBE_ADVTXD_TUCMD_IPV4;
l4_hdr = ip_hdr(skb)->protocol;
break;
case htons(ETH_P_IPV6):
vlan_macip_lens |= skb_network_header_len(skb);
l4_hdr = ipv6_hdr(skb)->nexthdr;
if (likely(skb_network_header_len(skb) ==
sizeof(struct ipv6hdr)))
break;
ipv6_skip_exthdr(skb, skb_network_offset(skb) +
sizeof(struct ipv6hdr),
&l4_hdr, &frag_off);
if (unlikely(frag_off))
l4_hdr = NEXTHDR_FRAGMENT;
break;
default:
break;
}
switch (l4_hdr) { switch (skb->csum_offset) {
case IPPROTO_TCP: case offsetof(struct tcphdr, check):
type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_TCP; type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_TCP;
mss_l4len_idx = tcp_hdrlen(skb) << /* fall through */
IXGBE_ADVTXD_L4LEN_SHIFT; case offsetof(struct udphdr, check):
break; break;
case IPPROTO_SCTP: case offsetof(struct sctphdr, checksum):
type_tucmd |= IXGBE_ADVTXD_TUCMD_L4T_SCTP; /* validate that this is actually an SCTP request */
mss_l4len_idx = sizeof(struct sctphdr) << if (((first->protocol == htons(ETH_P_IP)) &&
IXGBE_ADVTXD_L4LEN_SHIFT; (ip_hdr(skb)->protocol == IPPROTO_SCTP)) ||
break; ((first->protocol == htons(ETH_P_IPV6)) &&
case IPPROTO_UDP: ixgbevf_ipv6_csum_is_sctp(skb))) {
mss_l4len_idx = sizeof(struct udphdr) << type_tucmd = IXGBE_ADVTXD_TUCMD_L4T_SCTP;
IXGBE_ADVTXD_L4LEN_SHIFT;
break; break;
default:
if (unlikely(net_ratelimit())) {
dev_warn(tx_ring->dev,
"partial checksum, l3 proto=%x, l4 proto=%x\n",
first->protocol, l4_hdr);
}
skb_checksum_help(skb);
goto no_csum;
} }
/* fall through */
/* update TX checksum flag */ default:
first->tx_flags |= IXGBE_TX_FLAGS_CSUM; skb_checksum_help(skb);
goto no_csum;
} }
/* update TX checksum flag */
first->tx_flags |= IXGBE_TX_FLAGS_CSUM;
vlan_macip_lens = skb_checksum_start_offset(skb) -
skb_network_offset(skb);
no_csum: no_csum:
/* vlan_macip_lens: MACLEN, VLAN tag */ /* vlan_macip_lens: MACLEN, VLAN tag */
vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT; vlan_macip_lens |= skb_network_offset(skb) << IXGBE_ADVTXD_MACLEN_SHIFT;
vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK; vlan_macip_lens |= first->tx_flags & IXGBE_TX_FLAGS_VLAN_MASK;
ixgbevf_tx_ctxtdesc(tx_ring, vlan_macip_lens, ixgbevf_tx_ctxtdesc(tx_ring, vlan_macip_lens, type_tucmd, 0);
type_tucmd, mss_l4len_idx);
} }
static __le32 ixgbevf_tx_cmd_type(u32 tx_flags) static __le32 ixgbevf_tx_cmd_type(u32 tx_flags)
...@@ -4013,22 +3989,25 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -4013,22 +3989,25 @@ static int ixgbevf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
} }
netdev->hw_features = NETIF_F_SG | netdev->hw_features = NETIF_F_SG |
NETIF_F_IP_CSUM |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO | NETIF_F_TSO |
NETIF_F_TSO6 | NETIF_F_TSO6 |
NETIF_F_RXCSUM; NETIF_F_RXCSUM |
NETIF_F_HW_CSUM |
NETIF_F_SCTP_CRC;
netdev->features = netdev->hw_features | netdev->features = netdev->hw_features |
NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX | NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER; NETIF_F_HW_VLAN_CTAG_FILTER;
netdev->vlan_features |= NETIF_F_TSO | netdev->vlan_features |= NETIF_F_SG |
NETIF_F_TSO |
NETIF_F_TSO6 | NETIF_F_TSO6 |
NETIF_F_IP_CSUM | NETIF_F_HW_CSUM |
NETIF_F_IPV6_CSUM | NETIF_F_SCTP_CRC;
NETIF_F_SG;
netdev->mpls_features |= NETIF_F_HW_CSUM;
netdev->hw_enc_features |= NETIF_F_HW_CSUM;
if (pci_using_dac) if (pci_using_dac)
netdev->features |= NETIF_F_HIGHDMA; netdev->features |= NETIF_F_HIGHDMA;
......
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