Skip to content

Commit

Permalink
Merge branch '40GbE' of git://git.kernel.org/pub/scm/linux/kernel/git…
Browse files Browse the repository at this point in the history
…/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>
  • Loading branch information
David S. Miller committed Dec 13, 2015
2 parents 1d72135 + c9c9f1b commit 9119023
Show file tree
Hide file tree
Showing 10 changed files with 156 additions and 41 deletions.
2 changes: 2 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
21 changes: 21 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
106 changes: 76 additions & 30 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 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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
Expand All @@ -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;
}

Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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;
}

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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);
}

Expand Down Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 15 additions & 8 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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 */
Expand Down
Loading

0 comments on commit 9119023

Please sign in to comment.