Skip to content

Commit

Permalink
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/gi…
Browse files Browse the repository at this point in the history
…t/jkirsher/next-queue

Jeff Kirsher says:

====================
Intel Wired LAN Driver Updates 2015-10-23

This series contains updates to i40e, i40evf, if_link, ixgbe and ixgbevf.

Anjali adds a workaround to drop any flow control frames from being
transmitted from any VSI, so that a malicious VF cannot send flow control
or PFC packets out on the wire.  Also fixed a bug in debugfs by grabbing
the filter list lock before adding or deleting a filter.

Akeem fixes an issue where we were unconditionally returning VEB bridge
mode before allowing LB in the add VSI routine, resolve by checking if
the bridge is actually in VEB mode first.

Mitch fixed an issue where the incorrect structure was being used for
VLAN filter list, which meant the VLAN filter list did not get
processed correctly and VLAN filters would not be re-enabled after any
kind of reset.

Helin fixed a problem of possibly getting inconsistent flow control
status after a PF reset.  The issue was requested_mode was being set
with a default value during probe, but the hardware state could be a
different value from this mode.

Carolyn fixed a problem where the driver output of the OEM version
string varied from the other tools.

Jean Sacren fixes up kernel documentation by fixing function header
comments to match actual variables used in the functions.  Also
cleaned up variable initialization, when the variable would be
over-written immediately.

Hiroshi Shimanoto provides three patches to add "trusted" VF by adding
netlink directives and an NDO entry.  Then implement these new controls
in ixgbe and ixgbevf.  This series has gone through several iterations
to address all the suggested community changes and concerns.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Oct 23, 2015
2 parents e74f510 + 8443c1a commit bf79586
Show file tree
Hide file tree
Showing 25 changed files with 318 additions and 59 deletions.
17 changes: 13 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,10 @@
#define I40E_NVM_VERSION_LO_MASK (0xff << I40E_NVM_VERSION_LO_SHIFT)
#define I40E_NVM_VERSION_HI_SHIFT 12
#define I40E_NVM_VERSION_HI_MASK (0xf << I40E_NVM_VERSION_HI_SHIFT)
#define I40E_OEM_VER_BUILD_MASK 0xff00
#define I40E_OEM_VER_BUILD_MASK 0xffff
#define I40E_OEM_VER_PATCH_MASK 0xff
#define I40E_OEM_VER_BUILD_SHIFT 8
#define I40E_OEM_VER_SHIFT 24

/* The values in here are decimal coded as hex as is the case in the NVM map*/
#define I40E_CURRENT_NVM_VERSION_HI 0x2
Expand Down Expand Up @@ -594,16 +596,23 @@ struct i40e_device {
static inline char *i40e_nvm_version_str(struct i40e_hw *hw)
{
static char buf[32];
u32 full_ver;
u8 ver, patch;
u16 build;

full_ver = hw->nvm.oem_ver;
ver = (u8)(full_ver >> I40E_OEM_VER_SHIFT);
build = (u16)((full_ver >> I40E_OEM_VER_BUILD_SHIFT)
& I40E_OEM_VER_BUILD_MASK);
patch = (u8)(full_ver & I40E_OEM_VER_PATCH_MASK);

snprintf(buf, sizeof(buf),
"%x.%02x 0x%x %d.%d.%d",
(hw->nvm.version & I40E_NVM_VERSION_HI_MASK) >>
I40E_NVM_VERSION_HI_SHIFT,
(hw->nvm.version & I40E_NVM_VERSION_LO_MASK) >>
I40E_NVM_VERSION_LO_SHIFT,
hw->nvm.eetrack, (hw->nvm.oem_ver >> 24),
(hw->nvm.oem_ver & I40E_OEM_VER_BUILD_MASK) >> 8,
hw->nvm.oem_ver & I40E_OEM_VER_PATCH_MASK);
hw->nvm.eetrack, ver, build, patch);

return buf;
}
Expand Down
44 changes: 26 additions & 18 deletions drivers/net/ethernet/intel/i40e/i40e_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,25 +331,11 @@ void i40e_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
len = buf_len;
/* write the full 16-byte chunks */
for (i = 0; i < (len - 16); i += 16)
i40e_debug(hw, mask,
"\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, buf[i], buf[i + 1], buf[i + 2],
buf[i + 3], buf[i + 4], buf[i + 5],
buf[i + 6], buf[i + 7], buf[i + 8],
buf[i + 9], buf[i + 10], buf[i + 11],
buf[i + 12], buf[i + 13], buf[i + 14],
buf[i + 15]);
i40e_debug(hw, mask, "\t0x%04X %16ph\n", i, buf + i);
/* write whatever's left over without overrunning the buffer */
if (i < len) {
char d_buf[80];
int j = 0;

memset(d_buf, 0, sizeof(d_buf));
j += sprintf(d_buf, "\t0x%04X ", i);
while (i < len)
j += sprintf(&d_buf[j], " %02X", buf[i++]);
i40e_debug(hw, mask, "%s\n", d_buf);
}
if (i < len)
i40e_debug(hw, mask, "\t0x%04X %*ph\n",
i, len - i, buf + i);
}
}

Expand Down Expand Up @@ -3828,6 +3814,28 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
return status;
}

/**
* i40e_add_filter_to_drop_tx_flow_control_frames- filter to drop flow control
* @hw: pointer to the hw struct
* @seid: VSI seid to add ethertype filter from
**/
#define I40E_FLOW_CONTROL_ETHTYPE 0x8808
void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
u16 seid)
{
u16 flag = I40E_AQC_ADD_CONTROL_PACKET_FLAGS_IGNORE_MAC |
I40E_AQC_ADD_CONTROL_PACKET_FLAGS_DROP |
I40E_AQC_ADD_CONTROL_PACKET_FLAGS_TX;
u16 ethtype = I40E_FLOW_CONTROL_ETHTYPE;
i40e_status status;

status = i40e_aq_add_rem_control_packet_filter(hw, NULL, ethtype, flag,
seid, 0, true, NULL,
NULL);
if (status)
hw_dbg(hw, "Ethtype Filter Add failed: Error pruning Tx flow control frames\n");
}

/**
* i40e_aq_alternate_read
* @hw: pointer to the hardware structure
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_debugfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -1137,7 +1137,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
goto command_write_done;
}

spin_lock_bh(&vsi->mac_filter_list_lock);
f = i40e_add_filter(vsi, ma, vlan, false, false);
spin_unlock_bh(&vsi->mac_filter_list_lock);
ret = i40e_sync_vsi_filters(vsi, true);
if (f && !ret)
dev_info(&pf->pdev->dev,
Expand Down Expand Up @@ -1174,7 +1176,9 @@ static ssize_t i40e_dbg_command_write(struct file *filp,
goto command_write_done;
}

spin_lock_bh(&vsi->mac_filter_list_lock);
i40e_del_filter(vsi, ma, vlan, false, false);
spin_unlock_bh(&vsi->mac_filter_list_lock);
ret = i40e_sync_vsi_filters(vsi, true);
if (!ret)
dev_info(&pf->pdev->dev,
Expand Down
56 changes: 52 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ static const char i40e_driver_string[] =

#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 3
#define DRV_VERSION_BUILD 38
#define DRV_VERSION_BUILD 46
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
Expand Down Expand Up @@ -6837,6 +6837,15 @@ static void i40e_reset_and_rebuild(struct i40e_pf *pf, bool reinit)
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
ret = i40e_setup_misc_vector(pf);

/* Add a filter to drop all Flow control frames from any VSI from being
* transmitted. By doing so we stop a malicious VF from sending out
* PAUSE or PFC frames and potentially controlling traffic for other
* PF/VF VSIs.
* The FW can still send Flow control frames if enabled.
*/
i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
pf->main_vsi_seid);

/* restart the VSIs that were rebuilt and running before the reset */
i40e_pf_unquiesce_all_vsi(pf);

Expand Down Expand Up @@ -8732,12 +8741,22 @@ int i40e_is_vsi_uplink_mode_veb(struct i40e_vsi *vsi)
return 1;

veb = pf->veb[vsi->veb_idx];
if (!veb) {
dev_info(&pf->pdev->dev,
"There is no veb associated with the bridge\n");
return -ENOENT;
}

/* Uplink is a bridge in VEPA mode */
if (veb && (veb->bridge_mode & BRIDGE_MODE_VEPA))
if (veb->bridge_mode & BRIDGE_MODE_VEPA) {
return 0;
} else {
/* Uplink is a bridge in VEB mode */
return 1;
}

/* Uplink is a bridge in VEB mode */
return 1;
/* VEPA is now default bridge, so return 0 */
return 0;
}

/**
Expand Down Expand Up @@ -10164,6 +10183,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
int err;
u32 len;
u32 i;
u8 set_fc_aq_fail;

err = pci_enable_device_mem(pdev);
if (err)
Expand Down Expand Up @@ -10428,6 +10448,25 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err);
goto err_vsis;
}

/* Make sure flow control is set according to current settings */
err = i40e_set_fc(hw, &set_fc_aq_fail, true);
if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_GET)
dev_dbg(&pf->pdev->dev,
"Set fc with err %s aq_err %s on get_phy_cap\n",
i40e_stat_str(hw, err),
i40e_aq_str(hw, hw->aq.asq_last_status));
if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_SET)
dev_dbg(&pf->pdev->dev,
"Set fc with err %s aq_err %s on set_phy_config\n",
i40e_stat_str(hw, err),
i40e_aq_str(hw, hw->aq.asq_last_status));
if (set_fc_aq_fail & I40E_SET_FC_AQ_FAIL_UPDATE)
dev_dbg(&pf->pdev->dev,
"Set fc with err %s aq_err %s on get_link_info\n",
i40e_stat_str(hw, err),
i40e_aq_str(hw, hw->aq.asq_last_status));

/* if FDIR VSI was set up, start it now */
for (i = 0; i < pf->num_alloc_vsi; i++) {
if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) {
Expand Down Expand Up @@ -10585,6 +10624,15 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
i40e_aq_str(&pf->hw, pf->hw.aq.asq_last_status));
pf->hw.phy.phy_types = le32_to_cpu(abilities.phy_type);

/* Add a filter to drop all Flow control frames from any VSI from being
* transmitted. By doing so we stop a malicious VF from sending out
* PAUSE or PFC frames and potentially controlling traffic for other
* PF/VF VSIs.
* The FW can still send Flow control frames if enabled.
*/
i40e_add_filter_to_drop_tx_flow_control_frames(&pf->hw,
pf->main_vsi_seid);

/* print a string summarizing features */
i40e_print_features(pf);

Expand Down
9 changes: 5 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_nvm.c
Original file line number Diff line number Diff line change
Expand Up @@ -484,7 +484,7 @@ static i40e_status i40e_write_nvm_aq(struct i40e_hw *hw, u8 module_pointer,
static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
u16 *checksum)
{
i40e_status ret_code = 0;
i40e_status ret_code;
struct i40e_virt_mem vmem;
u16 pcie_alt_module = 0;
u16 checksum_local = 0;
Expand Down Expand Up @@ -564,15 +564,16 @@ static i40e_status i40e_calc_nvm_checksum(struct i40e_hw *hw,
**/
i40e_status i40e_update_nvm_checksum(struct i40e_hw *hw)
{
i40e_status ret_code = 0;
i40e_status ret_code;
u16 checksum;
__le16 le_sum;

ret_code = i40e_calc_nvm_checksum(hw, &checksum);
le_sum = cpu_to_le16(checksum);
if (!ret_code)
if (!ret_code) {
le_sum = cpu_to_le16(checksum);
ret_code = i40e_write_nvm_aq(hw, 0x00, I40E_SR_SW_CHECKSUM_WORD,
1, &le_sum, true);
}

return ret_code;
}
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_prototype.h
Original file line number Diff line number Diff line change
Expand Up @@ -322,4 +322,6 @@ i40e_status i40e_aq_debug_dump(struct i40e_hw *hw, u8 cluster_id,
void *buff, u16 *ret_buff_size,
u8 *ret_next_table, u32 *ret_next_index,
struct i40e_asq_cmd_details *cmd_details);
void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
u16 vsi_seid);
#endif /* _I40E_PROTOTYPE_H_ */
3 changes: 3 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_txrx.c
Original file line number Diff line number Diff line change
Expand Up @@ -2187,6 +2187,7 @@ static inline int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
* @tx_ring: ptr to the ring to send
* @skb: ptr to the skb we're sending
* @hdr_len: ptr to the size of the packet header
* @cd_type_cmd_tso_mss: ptr to u64 object
* @cd_tunneling: ptr to context descriptor bits
*
* Returns 0 if no TSO can happen, 1 if tso is going, or error
Expand Down Expand Up @@ -2246,6 +2247,7 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
* @tx_ring: ptr to the ring to send
* @skb: ptr to the skb we're sending
* @tx_flags: the collected send information
* @cd_type_cmd_tso_mss: ptr to u64 object
*
* Returns 0 if no Tx timestamp can happen and 1 if the timestamp will happen
**/
Expand Down Expand Up @@ -2288,6 +2290,7 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,
* @tx_flags: pointer to Tx flags currently set
* @td_cmd: Tx descriptor command bits to set
* @td_offset: Tx descriptor header offsets to set
* @tx_ring: Tx descriptor ring
* @cd_tunneling: ptr to context desc bits
**/
static void i40e_tx_enable_csum(struct sk_buff *skb, u32 *tx_flags,
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -944,6 +944,7 @@ int i40e_alloc_vfs(struct i40e_pf *pf, u16 num_alloc_vfs)
if (pci_num_vf(pf->pdev) != num_alloc_vfs) {
ret = pci_enable_sriov(pf->pdev, num_alloc_vfs);
if (ret) {
pf->flags &= ~I40E_FLAG_VEB_MODE_ENABLED;
pf->num_alloc_vfs = 0;
goto err_iov;
}
Expand Down
22 changes: 4 additions & 18 deletions drivers/net/ethernet/intel/i40evf/i40e_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -331,25 +331,11 @@ void i40evf_debug_aq(struct i40e_hw *hw, enum i40e_debug_mask mask, void *desc,
len = buf_len;
/* write the full 16-byte chunks */
for (i = 0; i < (len - 16); i += 16)
i40e_debug(hw, mask,
"\t0x%04X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X %02X\n",
i, buf[i], buf[i + 1], buf[i + 2],
buf[i + 3], buf[i + 4], buf[i + 5],
buf[i + 6], buf[i + 7], buf[i + 8],
buf[i + 9], buf[i + 10], buf[i + 11],
buf[i + 12], buf[i + 13], buf[i + 14],
buf[i + 15]);
i40e_debug(hw, mask, "\t0x%04X %16ph\n", i, buf + i);
/* write whatever's left over without overrunning the buffer */
if (i < len) {
char d_buf[80];
int j = 0;

memset(d_buf, 0, sizeof(d_buf));
j += sprintf(d_buf, "\t0x%04X ", i);
while (i < len)
j += sprintf(&d_buf[j], " %02X", buf[i++]);
i40e_debug(hw, mask, "%s\n", d_buf);
}
if (i < len)
i40e_debug(hw, mask, "\t0x%04X %*ph\n",
i, len - i, buf + i);
}
}

Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40evf/i40e_prototype.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,6 @@ i40e_status i40e_aq_add_rem_control_packet_filter(struct i40e_hw *hw,
u16 vsi_seid, u16 queue, bool is_add,
struct i40e_control_filter_stats *stats,
struct i40e_asq_cmd_details *cmd_details);
void i40e_add_filter_to_drop_tx_flow_control_frames(struct i40e_hw *hw,
u16 vsi_seid);
#endif /* _I40E_PROTOTYPE_H_ */
17 changes: 9 additions & 8 deletions drivers/net/ethernet/intel/i40evf/i40evf_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] =
"Intel(R) XL710/X710 Virtual Function Network Driver";

#define DRV_VERSION "1.3.25"
#define DRV_VERSION "1.3.33"
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2015 Intel Corporation.";
Expand Down Expand Up @@ -282,6 +282,7 @@ static void i40evf_fire_sw_int(struct i40evf_adapter *adapter, u32 mask)
/**
* i40evf_irq_enable - Enable default interrupt generation settings
* @adapter: board private structure
* @flush: boolean value whether to run rd32()
**/
void i40evf_irq_enable(struct i40evf_adapter *adapter, bool flush)
{
Expand All @@ -305,15 +306,14 @@ static irqreturn_t i40evf_msix_aq(int irq, void *data)
struct i40evf_adapter *adapter = netdev_priv(netdev);
struct i40e_hw *hw = &adapter->hw;
u32 val;
u32 ena_mask;

/* handle non-queue interrupts */
val = rd32(hw, I40E_VFINT_ICR01);
ena_mask = rd32(hw, I40E_VFINT_ICR0_ENA1);
rd32(hw, I40E_VFINT_ICR01);
rd32(hw, I40E_VFINT_ICR0_ENA1);


val = rd32(hw, I40E_VFINT_DYN_CTL01);
val = val | I40E_VFINT_DYN_CTL01_CLEARPBA_MASK;
val = rd32(hw, I40E_VFINT_DYN_CTL01) |
I40E_VFINT_DYN_CTL01_CLEARPBA_MASK;
wr32(hw, I40E_VFINT_DYN_CTL01, val);

/* schedule work on the private workqueue */
Expand Down Expand Up @@ -1609,6 +1609,7 @@ static void i40evf_reset_task(struct work_struct *work)
reset_task);
struct net_device *netdev = adapter->netdev;
struct i40e_hw *hw = &adapter->hw;
struct i40evf_vlan_filter *vlf;
struct i40evf_mac_filter *f;
u32 reg_val;
int i = 0, err;
Expand Down Expand Up @@ -1732,8 +1733,8 @@ static void i40evf_reset_task(struct work_struct *work)
f->add = true;
}
/* re-add all VLAN filters */
list_for_each_entry(f, &adapter->vlan_filter_list, list) {
f->add = true;
list_for_each_entry(vlf, &adapter->vlan_filter_list, list) {
vlf->add = true;
}
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_MAC_FILTER;
adapter->aq_required |= I40EVF_FLAG_AQ_ADD_VLAN_FILTER;
Expand Down
8 changes: 8 additions & 0 deletions drivers/net/ethernet/intel/ixgbe/ixgbe.h
Original file line number Diff line number Diff line change
Expand Up @@ -152,9 +152,17 @@ struct vf_data_storage {
u16 vlan_count;
u8 spoofchk_enabled;
bool rss_query_enabled;
u8 trusted;
int xcast_mode;
unsigned int vf_api;
};

enum ixgbevf_xcast_modes {
IXGBEVF_XCAST_MODE_NONE = 0,
IXGBEVF_XCAST_MODE_MULTI,
IXGBEVF_XCAST_MODE_ALLMULTI,
};

struct vf_macvlans {
struct list_head l;
int vf;
Expand Down
Loading

0 comments on commit bf79586

Please sign in to comment.