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

Jeff Kirsher says:

====================
40GbE Intel Wired LAN Driver Updates 2015-12-12

This series contains updates to i40e and i40evf only.

Jesse fixes some trivial static analyzer warnings where BIT() can be used
instead of BIT_ULL().

Mitch fixes the virtual channel interface which was using incorrect semantics
to remove MAC addresses and would leave incorrect filters active when using
VLANs.  Also fixes an issue that when VF's are created, the MAC address
defaults to all zeros, indicating to the VF driver that it should use a
random MAC address.  However, the PF driver was incorrectly adding this
zero MAC to the filter table, so check for a good address before adding
the default filter.  Adds a check to make sure that the Tx and Rx rings
actually exist before dereferencing them to free resources.  Re-classifies
several messages which are really for debugging purposes, especially since
the driver can fully recover from any of these.  Fixed up the VF version
strings to match the PF driver.

Anjali adds a virtchnl offload to support the expanded version of TCP/UDP
PCTYPES for RSS.

Shannon fixes i40e to clean the whole MAC filter list when resetting after
an intermediate add or delete push to the firmware.

v2: added blank line after variable declaration in patch 9 based on
    feedback from Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
David S. Miller 2015-12-13 02:22:50 -05:00
commit 91190237df
10 changed files with 156 additions and 41 deletions

View File

@ -776,6 +776,8 @@ int i40e_vsi_add_vlan(struct i40e_vsi *vsi, s16 vid);
int i40e_vsi_kill_vlan(struct i40e_vsi *vsi, s16 vid);
struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);
int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);
bool i40e_is_vsi_in_vlan(struct i40e_vsi *vsi);
struct i40e_mac_filter *i40e_find_mac(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev);

View File

@ -227,6 +227,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_nvm_update = 0x0703,
i40e_aqc_opc_nvm_config_read = 0x0704,
i40e_aqc_opc_nvm_config_write = 0x0705,
i40e_aqc_opc_oem_post_update = 0x0720,
/* virtualization commands */
i40e_aqc_opc_send_msg_to_pf = 0x0801,
@ -1891,6 +1892,26 @@ struct i40e_aqc_nvm_config_data_immediate_field {
I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field);
/* OEM Post Update (indirect 0x0720)
* no command data struct used
*/
struct i40e_aqc_nvm_oem_post_update {
#define I40E_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA 0x01
u8 sel_data;
u8 reserved[7];
};
I40E_CHECK_STRUCT_LEN(0x8, i40e_aqc_nvm_oem_post_update);
struct i40e_aqc_nvm_oem_post_update_buffer {
u8 str_len;
u8 dev_addr;
__le16 eeprom_addr;
u8 data[36];
};
I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
/* Send to PF command (indirect 0x0801) id is only used by PF
* Send to VF command (indirect 0x0802) id is only used by PF
* Send to Peer PF command (indirect 0x0803)

View File

@ -762,7 +762,7 @@ static void i40e_write_byte(u8 *hmc_bits,
/* prepare the bits and mask */
shift_width = ce_info->lsb % 8;
mask = BIT(ce_info->width) - 1;
mask = (u8)(BIT(ce_info->width) - 1);
src_byte = *from;
src_byte &= mask;

View File

@ -39,7 +39,7 @@ static const char i40e_driver_string[] =
#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 4
#define DRV_VERSION_BUILD 7
#define DRV_VERSION_BUILD 8
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
@ -1258,6 +1258,42 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
struct i40e_mac_filter, list);
}
/**
* i40e_del_mac_all_vlan - Remove a MAC filter from all VLANS
* @vsi: the VSI to be searched
* @macaddr: the mac address to be removed
* @is_vf: true if it is a VF
* @is_netdev: true if it is a netdev
*
* Removes a given MAC address from a VSI, regardless of VLAN
*
* Returns 0 for success, or error
**/
int i40e_del_mac_all_vlan(struct i40e_vsi *vsi, u8 *macaddr,
bool is_vf, bool is_netdev)
{
struct i40e_mac_filter *f = NULL;
int changed = 0;
WARN(!spin_is_locked(&vsi->mac_filter_list_lock),
"Missing mac_filter_list_lock\n");
list_for_each_entry(f, &vsi->mac_filter_list, list) {
if ((ether_addr_equal(macaddr, f->macaddr)) &&
(is_vf == f->is_vf) &&
(is_netdev == f->is_netdev)) {
f->counter--;
f->changed = true;
changed = 1;
}
}
if (changed) {
vsi->flags |= I40E_VSI_FLAG_FILTER_CHANGED;
vsi->back->flags |= I40E_FLAG_FILTER_SYNC;
return 0;
}
return -ENOENT;
}
/**
* i40e_rm_default_mac_filter - Remove the default MAC filter set by NVM
* @vsi: the PF Main VSI - inappropriate for any other VSI
@ -1531,7 +1567,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
if (enabled_tc && (vsi->back->flags & I40E_FLAG_DCB_ENABLED)) {
/* Find numtc from enabled TC bitmap */
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (enabled_tc & BIT_ULL(i)) /* TC is enabled */
if (enabled_tc & BIT(i)) /* TC is enabled */
numtc++;
}
if (!numtc) {
@ -1560,7 +1596,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
/* Setup queue offset/count for all TCs for given VSI */
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
/* See if the given TC is enabled for the given VSI */
if (vsi->tc_config.enabled_tc & BIT_ULL(i)) {
if (vsi->tc_config.enabled_tc & BIT(i)) {
/* TC is enabled */
int pow, num_qps;
@ -1880,11 +1916,13 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
/* Now process 'del_list' outside the lock */
if (!list_empty(&tmp_del_list)) {
int del_list_size;
filter_list_len = pf->hw.aq.asq_buf_size /
sizeof(struct i40e_aqc_remove_macvlan_element_data);
del_list = kcalloc(filter_list_len,
sizeof(struct i40e_aqc_remove_macvlan_element_data),
GFP_KERNEL);
del_list_size = filter_list_len *
sizeof(struct i40e_aqc_remove_macvlan_element_data);
del_list = kzalloc(del_list_size, GFP_KERNEL);
if (!del_list) {
i40e_cleanup_add_list(&tmp_add_list);
@ -1919,7 +1957,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
NULL);
aq_err = pf->hw.aq.asq_last_status;
num_del = 0;
memset(del_list, 0, sizeof(*del_list));
memset(del_list, 0, del_list_size);
if (aq_ret && aq_err != I40E_AQ_RC_ENOENT) {
retval = -EIO;
@ -1955,13 +1993,14 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
}
if (!list_empty(&tmp_add_list)) {
int add_list_size;
/* do all the adds now */
filter_list_len = pf->hw.aq.asq_buf_size /
sizeof(struct i40e_aqc_add_macvlan_element_data),
add_list = kcalloc(filter_list_len,
sizeof(struct i40e_aqc_add_macvlan_element_data),
GFP_KERNEL);
add_list_size = filter_list_len *
sizeof(struct i40e_aqc_add_macvlan_element_data);
add_list = kzalloc(add_list_size, GFP_KERNEL);
if (!add_list) {
/* Purge element from temporary lists */
i40e_cleanup_add_list(&tmp_add_list);
@ -2000,7 +2039,7 @@ int i40e_sync_vsi_filters(struct i40e_vsi *vsi)
if (aq_ret)
break;
memset(add_list, 0, sizeof(*add_list));
memset(add_list, 0, add_list_size);
}
/* Entries from tmp_add_list were cloned from MAC
* filter list, hence clean those cloned entries
@ -4433,7 +4472,7 @@ static u8 i40e_get_iscsi_tc_map(struct i40e_pf *pf)
if (app.selector == I40E_APP_SEL_TCPIP &&
app.protocolid == I40E_APP_PROTOID_ISCSI) {
tc = dcbcfg->etscfg.prioritytable[app.priority];
enabled_tc |= BIT_ULL(tc);
enabled_tc |= BIT(tc);
break;
}
}
@ -4517,7 +4556,7 @@ static u8 i40e_pf_get_num_tc(struct i40e_pf *pf)
/* At least have TC0 */
enabled_tc = (enabled_tc ? enabled_tc : 0x1);
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (enabled_tc & BIT_ULL(i))
if (enabled_tc & BIT(i))
num_tc++;
}
return num_tc;
@ -4539,7 +4578,7 @@ static u8 i40e_pf_get_default_tc(struct i40e_pf *pf)
/* Find the first enabled TC */
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (enabled_tc & BIT_ULL(i))
if (enabled_tc & BIT(i))
break;
}
@ -4699,7 +4738,7 @@ static void i40e_vsi_config_netdev_tc(struct i40e_vsi *vsi, u8 enabled_tc)
* will set the numtc for netdev as 2 that will be
* referenced by the netdev layer as TC 0 and 1.
*/
if (vsi->tc_config.enabled_tc & BIT_ULL(i))
if (vsi->tc_config.enabled_tc & BIT(i))
netdev_set_tc_queue(netdev,
vsi->tc_config.tc_info[i].netdev_tc,
vsi->tc_config.tc_info[i].qcount,
@ -4761,7 +4800,7 @@ static int i40e_vsi_config_tc(struct i40e_vsi *vsi, u8 enabled_tc)
/* Enable ETS TCs with equal BW Share for now across all VSIs */
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (enabled_tc & BIT_ULL(i))
if (enabled_tc & BIT(i))
bw_share[i] = 1;
}
@ -4835,7 +4874,7 @@ int i40e_veb_config_tc(struct i40e_veb *veb, u8 enabled_tc)
/* Enable ETS TCs with equal BW Share for now */
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
if (enabled_tc & BIT_ULL(i))
if (enabled_tc & BIT(i))
bw_data.tc_bw_share_credits[i] = 1;
}
@ -5232,7 +5271,7 @@ static int i40e_setup_tc(struct net_device *netdev, u8 tc)
/* Generate TC map for number of tc requested */
for (i = 0; i < tc; i++)
enabled_tc |= BIT_ULL(i);
enabled_tc |= BIT(i);
/* Requesting same TC configuration as already enabled */
if (enabled_tc == vsi->tc_config.enabled_tc)
@ -6096,23 +6135,23 @@ static void i40e_reset_subtask(struct i40e_pf *pf)
rtnl_lock();
if (test_bit(__I40E_REINIT_REQUESTED, &pf->state)) {
reset_flags |= BIT_ULL(__I40E_REINIT_REQUESTED);
reset_flags |= BIT(__I40E_REINIT_REQUESTED);
clear_bit(__I40E_REINIT_REQUESTED, &pf->state);
}
if (test_bit(__I40E_PF_RESET_REQUESTED, &pf->state)) {
reset_flags |= BIT_ULL(__I40E_PF_RESET_REQUESTED);
reset_flags |= BIT(__I40E_PF_RESET_REQUESTED);
clear_bit(__I40E_PF_RESET_REQUESTED, &pf->state);
}
if (test_bit(__I40E_CORE_RESET_REQUESTED, &pf->state)) {
reset_flags |= BIT_ULL(__I40E_CORE_RESET_REQUESTED);
reset_flags |= BIT(__I40E_CORE_RESET_REQUESTED);
clear_bit(__I40E_CORE_RESET_REQUESTED, &pf->state);
}
if (test_bit(__I40E_GLOBAL_RESET_REQUESTED, &pf->state)) {
reset_flags |= BIT_ULL(__I40E_GLOBAL_RESET_REQUESTED);
reset_flags |= BIT(__I40E_GLOBAL_RESET_REQUESTED);
clear_bit(__I40E_GLOBAL_RESET_REQUESTED, &pf->state);
}
if (test_bit(__I40E_DOWN_REQUESTED, &pf->state)) {
reset_flags |= BIT_ULL(__I40E_DOWN_REQUESTED);
reset_flags |= BIT(__I40E_DOWN_REQUESTED);
clear_bit(__I40E_DOWN_REQUESTED, &pf->state);
}
@ -6183,15 +6222,18 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
val = rd32(&pf->hw, pf->hw.aq.arq.len);
oldval = val;
if (val & I40E_PF_ARQLEN_ARQVFE_MASK) {
dev_info(&pf->pdev->dev, "ARQ VF Error detected\n");
if (hw->debug_mask & I40E_DEBUG_AQ)
dev_info(&pf->pdev->dev, "ARQ VF Error detected\n");
val &= ~I40E_PF_ARQLEN_ARQVFE_MASK;
}
if (val & I40E_PF_ARQLEN_ARQOVFL_MASK) {
dev_info(&pf->pdev->dev, "ARQ Overflow Error detected\n");
if (hw->debug_mask & I40E_DEBUG_AQ)
dev_info(&pf->pdev->dev, "ARQ Overflow Error detected\n");
val &= ~I40E_PF_ARQLEN_ARQOVFL_MASK;
}
if (val & I40E_PF_ARQLEN_ARQCRIT_MASK) {
dev_info(&pf->pdev->dev, "ARQ Critical Error detected\n");
if (hw->debug_mask & I40E_DEBUG_AQ)
dev_info(&pf->pdev->dev, "ARQ Critical Error detected\n");
val &= ~I40E_PF_ARQLEN_ARQCRIT_MASK;
}
if (oldval != val)
@ -6200,15 +6242,18 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
val = rd32(&pf->hw, pf->hw.aq.asq.len);
oldval = val;
if (val & I40E_PF_ATQLEN_ATQVFE_MASK) {
dev_info(&pf->pdev->dev, "ASQ VF Error detected\n");
if (pf->hw.debug_mask & I40E_DEBUG_AQ)
dev_info(&pf->pdev->dev, "ASQ VF Error detected\n");
val &= ~I40E_PF_ATQLEN_ATQVFE_MASK;
}
if (val & I40E_PF_ATQLEN_ATQOVFL_MASK) {
dev_info(&pf->pdev->dev, "ASQ Overflow Error detected\n");
if (pf->hw.debug_mask & I40E_DEBUG_AQ)
dev_info(&pf->pdev->dev, "ASQ Overflow Error detected\n");
val &= ~I40E_PF_ATQLEN_ATQOVFL_MASK;
}
if (val & I40E_PF_ATQLEN_ATQCRIT_MASK) {
dev_info(&pf->pdev->dev, "ASQ Critical Error detected\n");
if (pf->hw.debug_mask & I40E_DEBUG_AQ)
dev_info(&pf->pdev->dev, "ASQ Critical Error detected\n");
val &= ~I40E_PF_ATQLEN_ATQCRIT_MASK;
}
if (oldval != val)
@ -6259,6 +6304,7 @@ static void i40e_clean_adminq_subtask(struct i40e_pf *pf)
break;
case i40e_aqc_opc_nvm_erase:
case i40e_aqc_opc_nvm_update:
case i40e_aqc_opc_oem_post_update:
i40e_debug(&pf->hw, I40E_DEBUG_NVM, "ARQ NVM operation completed\n");
break;
default:
@ -10567,7 +10613,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
/* NVM bit on means WoL disabled for the port */
i40e_read_nvm_word(hw, I40E_SR_NVM_WAKE_ON_LAN, &wol_nvm_bits);
if ((1 << hw->port) & wol_nvm_bits || hw->partition_id != 1)
if (BIT (hw->port) & wol_nvm_bits || hw->partition_id != 1)
pf->wol_en = false;
else
pf->wol_en = true;

View File

@ -153,6 +153,7 @@ struct i40e_virtchnl_vsi_resource {
#define I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020
#define I40E_VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000
#define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000
#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000
struct i40e_virtchnl_vf_resource {
u16 num_vsis;

View File

@ -549,12 +549,15 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
i40e_vsi_add_pvid(vsi, vf->port_vlan_id);
spin_lock_bh(&vsi->mac_filter_list_lock);
f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
vf->port_vlan_id ? vf->port_vlan_id : -1,
true, false);
if (!f)
dev_info(&pf->pdev->dev,
"Could not allocate VF MAC addr\n");
if (is_valid_ether_addr(vf->default_lan_addr.addr)) {
f = i40e_add_filter(vsi, vf->default_lan_addr.addr,
vf->port_vlan_id ? vf->port_vlan_id : -1,
true, false);
if (!f)
dev_info(&pf->pdev->dev,
"Could not add MAC filter %pM for VF %d\n",
vf->default_lan_addr.addr, vf->vf_id);
}
f = i40e_add_filter(vsi, brdcast,
vf->port_vlan_id ? vf->port_vlan_id : -1,
true, false);
@ -1683,8 +1686,12 @@ static int i40e_vc_del_mac_addr_msg(struct i40e_vf *vf, u8 *msg, u16 msglen)
spin_lock_bh(&vsi->mac_filter_list_lock);
/* delete addresses from the list */
for (i = 0; i < al->num_elements; i++)
i40e_del_filter(vsi, al->list[i].addr,
I40E_VLAN_ANY, true, false);
if (i40e_del_mac_all_vlan(vsi, al->list[i].addr, true, false)) {
ret = I40E_ERR_INVALID_MAC_ADDR;
spin_unlock_bh(&vsi->mac_filter_list_lock);
goto error_param;
}
spin_unlock_bh(&vsi->mac_filter_list_lock);
/* program the updated filter list */

View File

@ -227,6 +227,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_nvm_update = 0x0703,
i40e_aqc_opc_nvm_config_read = 0x0704,
i40e_aqc_opc_nvm_config_write = 0x0705,
i40e_aqc_opc_oem_post_update = 0x0720,
/* virtualization commands */
i40e_aqc_opc_send_msg_to_pf = 0x0801,
@ -1888,6 +1889,26 @@ struct i40e_aqc_nvm_config_data_immediate_field {
I40E_CHECK_STRUCT_LEN(0xc, i40e_aqc_nvm_config_data_immediate_field);
/* OEM Post Update (indirect 0x0720)
* no command data struct used
*/
struct i40e_aqc_nvm_oem_post_update {
#define I40E_AQ_NVM_OEM_POST_UPDATE_EXTERNAL_DATA 0x01
u8 sel_data;
u8 reserved[7];
};
I40E_CHECK_STRUCT_LEN(0x8, i40e_aqc_nvm_oem_post_update);
struct i40e_aqc_nvm_oem_post_update_buffer {
u8 str_len;
u8 dev_addr;
__le16 eeprom_addr;
u8 data[36];
};
I40E_CHECK_STRUCT_LEN(0x28, i40e_aqc_nvm_oem_post_update_buffer);
/* Send to PF command (indirect 0x0801) id is only used by PF
* Send to VF command (indirect 0x0802) id is only used by PF
* Send to Peer PF command (indirect 0x0803)

View File

@ -153,6 +153,7 @@ struct i40e_virtchnl_vsi_resource {
#define I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR 0x00000020
#define I40E_VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000
#define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000
#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2 0x00040000
struct i40e_virtchnl_vf_resource {
u16 num_vsis;

View File

@ -34,7 +34,15 @@ char i40evf_driver_name[] = "i40evf";
static const char i40evf_driver_string[] =
"Intel(R) XL710/X710 Virtual Function Network Driver";
#define DRV_VERSION "1.4.3"
#define DRV_KERN "-k"
#define DRV_VERSION_MAJOR 1
#define DRV_VERSION_MINOR 4
#define DRV_VERSION_BUILD 4
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) \
DRV_KERN
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2015 Intel Corporation.";
@ -2034,6 +2042,9 @@ void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter)
{
int i;
if (!adapter->tx_rings)
return;
for (i = 0; i < adapter->num_active_queues; i++)
if (adapter->tx_rings[i].desc)
i40evf_free_tx_resources(&adapter->tx_rings[i]);
@ -2102,6 +2113,9 @@ void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter)
{
int i;
if (!adapter->rx_rings)
return;
for (i = 0; i < adapter->num_active_queues; i++)
if (adapter->rx_rings[i].desc)
i40evf_free_rx_resources(&adapter->rx_rings[i]);

View File

@ -157,7 +157,9 @@ int i40evf_send_vf_config_msg(struct i40evf_adapter *adapter)
I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ |
I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG |
I40E_VIRTCHNL_VF_OFFLOAD_VLAN |
I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR;
I40E_VIRTCHNL_VF_OFFLOAD_WB_ON_ITR |
I40E_VIRTCHNL_VF_OFFLOAD_RSS_PCTYPE_V2;
adapter->current_op = I40E_VIRTCHNL_OP_GET_VF_RESOURCES;
adapter->aq_required &= ~I40EVF_FLAG_AQ_GET_CONFIG;
if (PF_IS_V11(adapter))