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-08-26

This series contains updates to i40e and i40evf only.

Anjali provides a fix for i40e where the part is not receiving multicast
or VLAN tagged packets when in promiscuous mode.  This can occur when a
software bridge is created on top of the device.  Fixed the legacy and MSI
interrupt mode in the driver, which was non-existent before since we
were assuming MSIX was the only mode that the driver ran in.  Fixed the
i40evf driver, where the wrong defines were getting used in the VF
driver.

Mitch fixes a sparse warning about comparing __le16 to u16 so use
le16_to_cpu() to resolve the warning.  Also fixed a dyslexic spelling
of invalid.

Shannon adds port.crc_errors to receive CRC error counter, since it
is a receive counter.

Catherine provides a fix to move the stopping of the service task and
flow director to i40e_shutdown() instead of i40e_suspend().

Greg fixes the ethtool offline diagnostic with netqueues, which just need
to be treated the same as virtual functions when someone wants to run the
ethtool offline diagnostic test.  Also fixed up code comments for the
i40e ethtool diagnostic test function.  Cleans up redundant and unneeded
messages, since the kernel notifies all VXLAN capable registered drivers,
so no need to log this.

Neerav adds the ability to update statistics per VEB per traffic class
and dump it via ethtool.

Jingjing adds support for virtual channel offload to support receive
polling mode in the VF driver.

v2: dropped patch which added helper functions into a header, feedback from
    David Miller was to make the functions constant to reduce the driver
    footprint, so remove the patch while Anjali works on making the requested
    changes.
====================

Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David S. Miller committed Aug 27, 2015
2 parents 0118e01 + bf41846 commit fe21882
Show file tree
Hide file tree
Showing 15 changed files with 188 additions and 3,166 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 @@ -442,6 +442,8 @@ struct i40e_veb {
bool stat_offsets_loaded;
struct i40e_eth_stats stats;
struct i40e_eth_stats stats_offsets;
struct i40e_veb_tc_stats tc_stats;
struct i40e_veb_tc_stats tc_stats_offsets;
};

/* struct that defines a VSI, associated with a dev */
Expand Down
4 changes: 4 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_dcb.c
Original file line number Diff line number Diff line change
Expand Up @@ -588,6 +588,8 @@ i40e_status i40e_get_dcb_config(struct i40e_hw *hw)
if (!ret) {
/* CEE mode */
hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
hw->local_dcbx_config.tlv_status =
le16_to_cpu(cee_v1_cfg.tlv_status);
i40e_cee_to_dcb_v1_config(&cee_v1_cfg,
&hw->local_dcbx_config);
}
Expand All @@ -597,6 +599,8 @@ i40e_status i40e_get_dcb_config(struct i40e_hw *hw)
if (!ret) {
/* CEE mode */
hw->local_dcbx_config.dcbx_mode = I40E_DCBX_MODE_CEE;
hw->local_dcbx_config.tlv_status =
le32_to_cpu(cee_cfg.tlv_status);
i40e_cee_to_dcb_config(&cee_cfg,
&hw->local_dcbx_config);
}
Expand Down
54 changes: 46 additions & 8 deletions drivers/net/ethernet/intel/i40e/i40e_ethtool.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ static struct i40e_stats i40e_gstrings_stats[] = {
I40E_PF_STAT("tx_errors", stats.eth.tx_errors),
I40E_PF_STAT("rx_dropped", stats.eth.rx_discards),
I40E_PF_STAT("tx_dropped_link_down", stats.tx_dropped_link_down),
I40E_PF_STAT("crc_errors", stats.crc_errors),
I40E_PF_STAT("rx_crc_errors", stats.crc_errors),
I40E_PF_STAT("illegal_bytes", stats.illegal_bytes),
I40E_PF_STAT("mac_local_faults", stats.mac_local_faults),
I40E_PF_STAT("mac_remote_faults", stats.mac_remote_faults),
Expand Down Expand Up @@ -197,7 +197,14 @@ static const struct i40e_stats i40e_gstrings_fcoe_stats[] = {
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_tx) + \
FIELD_SIZEOF(struct i40e_pf, stats.priority_xon_2_xoff)) \
/ sizeof(u64))
#define I40E_VEB_TC_STATS_LEN ( \
(FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_rx_packets) + \
FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_rx_bytes) + \
FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_tx_packets) + \
FIELD_SIZEOF(struct i40e_veb, tc_stats.tc_tx_bytes)) \
/ sizeof(u64))
#define I40E_VEB_STATS_LEN ARRAY_SIZE(i40e_gstrings_veb_stats)
#define I40E_VEB_STATS_TOTAL (I40E_VEB_STATS_LEN + I40E_VEB_TC_STATS_LEN)
#define I40E_PF_STATS_LEN(n) (I40E_GLOBAL_STATS_LEN + \
I40E_PFC_STATS_LEN + \
I40E_VSI_STATS_LEN((n)))
Expand Down Expand Up @@ -1257,7 +1264,7 @@ static int i40e_get_sset_count(struct net_device *netdev, int sset)
int len = I40E_PF_STATS_LEN(netdev);

if (pf->lan_veb != I40E_NO_VEB)
len += I40E_VEB_STATS_LEN;
len += I40E_VEB_STATS_TOTAL;
return len;
} else {
return I40E_VSI_STATS_LEN(netdev);
Expand Down Expand Up @@ -1408,6 +1415,20 @@ static void i40e_get_strings(struct net_device *netdev, u32 stringset,
i40e_gstrings_veb_stats[i].stat_string);
p += ETH_GSTRING_LEN;
}
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_tx_packets", i);
p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_tx_bytes", i);
p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_rx_packets", i);
p += ETH_GSTRING_LEN;
snprintf(p, ETH_GSTRING_LEN,
"veb.tc_%u_rx_bytes", i);
p += ETH_GSTRING_LEN;
}
}
for (i = 0; i < I40E_GLOBAL_STATS_LEN; i++) {
snprintf(p, ETH_GSTRING_LEN, "port.%s",
Expand Down Expand Up @@ -1559,6 +1580,21 @@ static inline bool i40e_active_vfs(struct i40e_pf *pf)
return false;
}

static inline bool i40e_active_vmdqs(struct i40e_pf *pf)
{
struct i40e_vsi **vsi = pf->vsi;
int i;

for (i = 0; i < pf->num_alloc_vsi; i++) {
if (!vsi[i])
continue;
if (vsi[i]->type == I40E_VSI_VMDQ2)
return true;
}

return false;
}

static void i40e_diag_test(struct net_device *netdev,
struct ethtool_test *eth_test, u64 *data)
{
Expand All @@ -1572,9 +1608,9 @@ static void i40e_diag_test(struct net_device *netdev,

set_bit(__I40E_TESTING, &pf->state);

if (i40e_active_vfs(pf)) {
if (i40e_active_vfs(pf) || i40e_active_vmdqs(pf)) {
dev_warn(&pf->pdev->dev,
"Please take active VFS offline and restart the adapter before running NIC diagnostics\n");
"Please take active VFs and Netqueues offline and restart the adapter before running NIC diagnostics\n");
data[I40E_ETH_TEST_REG] = 1;
data[I40E_ETH_TEST_EEPROM] = 1;
data[I40E_ETH_TEST_INTR] = 1;
Expand All @@ -1590,11 +1626,13 @@ static void i40e_diag_test(struct net_device *netdev,
/* indicate we're in test mode */
dev_close(netdev);
else
/* This reset does not affect link - if it is
* changed to a type of reset that does affect
* link then the following link test would have
* to be moved to before the reset
*/
i40e_do_reset(pf, BIT(__I40E_PF_RESET_REQUESTED));

/* Link test performed before hardware reset
* so autoneg doesn't interfere with test result
*/
if (i40e_link_test(netdev, &data[I40E_ETH_TEST_LINK]))
eth_test->flags |= ETH_TEST_FL_FAILED;

Expand Down Expand Up @@ -2508,7 +2546,7 @@ static int i40e_get_rxfh(struct net_device *netdev, u32 *indir, u8 *key,
* @indir: indirection table
* @key: hash key
*
* Returns -EINVAL if the table specifies an inavlid queue id, otherwise
* Returns -EINVAL if the table specifies an invalid queue id, otherwise
* returns 0 after programming the table.
**/
static int i40e_set_rxfh(struct net_device *netdev, const u32 *indir,
Expand Down
66 changes: 55 additions & 11 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 6
#define DRV_VERSION_BUILD 9
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
Expand Down Expand Up @@ -624,11 +624,15 @@ static void i40e_update_veb_stats(struct i40e_veb *veb)
struct i40e_hw *hw = &pf->hw;
struct i40e_eth_stats *oes;
struct i40e_eth_stats *es; /* device's eth stats */
int idx = 0;
struct i40e_veb_tc_stats *veb_oes;
struct i40e_veb_tc_stats *veb_es;
int i, idx = 0;

idx = veb->stats_idx;
es = &veb->stats;
oes = &veb->stats_offsets;
veb_es = &veb->tc_stats;
veb_oes = &veb->tc_stats_offsets;

/* Gather up the stats that the hw collects */
i40e_stat_update32(hw, I40E_GLSW_TDPC(idx),
Expand Down Expand Up @@ -664,6 +668,28 @@ static void i40e_update_veb_stats(struct i40e_veb *veb)
i40e_stat_update48(hw, I40E_GLSW_BPTCH(idx), I40E_GLSW_BPTCL(idx),
veb->stat_offsets_loaded,
&oes->tx_broadcast, &es->tx_broadcast);
for (i = 0; i < I40E_MAX_TRAFFIC_CLASS; i++) {
i40e_stat_update48(hw, I40E_GLVEBTC_RPCH(i, idx),
I40E_GLVEBTC_RPCL(i, idx),
veb->stat_offsets_loaded,
&veb_oes->tc_rx_packets[i],
&veb_es->tc_rx_packets[i]);
i40e_stat_update48(hw, I40E_GLVEBTC_RBCH(i, idx),
I40E_GLVEBTC_RBCL(i, idx),
veb->stat_offsets_loaded,
&veb_oes->tc_rx_bytes[i],
&veb_es->tc_rx_bytes[i]);
i40e_stat_update48(hw, I40E_GLVEBTC_TPCH(i, idx),
I40E_GLVEBTC_TPCL(i, idx),
veb->stat_offsets_loaded,
&veb_oes->tc_tx_packets[i],
&veb_es->tc_tx_packets[i]);
i40e_stat_update48(hw, I40E_GLVEBTC_TBCH(i, idx),
I40E_GLVEBTC_TBCL(i, idx),
veb->stat_offsets_loaded,
&veb_oes->tc_tx_bytes[i],
&veb_es->tc_tx_bytes[i]);
}
veb->stat_offsets_loaded = true;
}

Expand Down Expand Up @@ -1255,6 +1281,8 @@ struct i40e_mac_filter *i40e_put_mac_in_vlan(struct i40e_vsi *vsi, u8 *macaddr,
struct i40e_mac_filter *f;

list_for_each_entry(f, &vsi->mac_filter_list, list) {
if (vsi->info.pvid)
f->vlan = le16_to_cpu(vsi->info.pvid);
if (!i40e_find_filter(vsi, macaddr, f->vlan,
is_vf, is_netdev)) {
if (!i40e_add_filter(vsi, macaddr, f->vlan,
Expand Down Expand Up @@ -1548,7 +1576,10 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
* vectors available and so we need to lower the used
* q count.
*/
qcount = min_t(int, vsi->alloc_queue_pairs, pf->num_lan_msix);
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
qcount = min_t(int, vsi->alloc_queue_pairs, pf->num_lan_msix);
else
qcount = vsi->alloc_queue_pairs;
num_tc_qps = qcount / numtc;
num_tc_qps = min_t(int, num_tc_qps, i40e_pf_get_max_q_per_tc(pf));

Expand Down Expand Up @@ -1612,7 +1643,7 @@ static void i40e_vsi_setup_queue_map(struct i40e_vsi *vsi,
if ((vsi->type == I40E_VSI_MAIN) && (numtc == 1)) {
if (vsi->req_queue_pairs > 0)
vsi->num_queue_pairs = vsi->req_queue_pairs;
else
else if (pf->flags & I40E_FLAG_MSIX_ENABLED)
vsi->num_queue_pairs = pf->num_lan_msix;
}

Expand Down Expand Up @@ -3414,7 +3445,7 @@ static irqreturn_t i40e_fdir_clean_ring(int irq, void *data)
* @v_idx: vector index
* @qp_idx: queue pair index
**/
static void map_vector_to_qp(struct i40e_vsi *vsi, int v_idx, int qp_idx)
static void i40e_map_vector_to_qp(struct i40e_vsi *vsi, int v_idx, int qp_idx)
{
struct i40e_q_vector *q_vector = vsi->q_vectors[v_idx];
struct i40e_ring *tx_ring = vsi->tx_rings[qp_idx];
Expand Down Expand Up @@ -3468,7 +3499,7 @@ static void i40e_vsi_map_rings_to_vectors(struct i40e_vsi *vsi)
q_vector->tx.ring = NULL;

while (num_ringpairs--) {
map_vector_to_qp(vsi, v_start, qp_idx);
i40e_map_vector_to_qp(vsi, v_start, qp_idx);
qp_idx++;
qp_remaining--;
}
Expand Down Expand Up @@ -8037,8 +8068,6 @@ static void i40e_add_vxlan_port(struct net_device *netdev,
pf->vxlan_ports[next_idx] = port;
pf->pending_vxlan_bitmap |= BIT_ULL(next_idx);
pf->flags |= I40E_FLAG_VXLAN_FILTER_SYNC;

dev_info(&pf->pdev->dev, "adding vxlan port %d\n", ntohs(port));
}

/**
Expand Down Expand Up @@ -8796,6 +8825,11 @@ static int i40e_vsi_setup_vectors(struct i40e_vsi *vsi)
goto vector_setup_out;
}

/* In Legacy mode, we do not have to get any other vector since we
* piggyback on the misc/ICR0 for queue interrupts.
*/
if (!(pf->flags & I40E_FLAG_MSIX_ENABLED))
return ret;
if (vsi->num_q_vectors)
vsi->base_vector = i40e_get_lump(pf, pf->irq_pile,
vsi->num_q_vectors, vsi->idx);
Expand Down Expand Up @@ -10448,6 +10482,19 @@ static void i40e_shutdown(struct pci_dev *pdev)
wr32(hw, I40E_PFPM_APM, (pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
wr32(hw, I40E_PFPM_WUFC, (pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));

del_timer_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task);
i40e_fdir_teardown(pf);

rtnl_lock();
i40e_prep_for_reset(pf);
rtnl_unlock();

wr32(hw, I40E_PFPM_APM,
(pf->wol_en ? I40E_PFPM_APM_APME_MASK : 0));
wr32(hw, I40E_PFPM_WUFC,
(pf->wol_en ? I40E_PFPM_WUFC_MAG_MASK : 0));

i40e_clear_interrupt_scheme(pf);

if (system_state == SYSTEM_POWER_OFF) {
Expand All @@ -10468,9 +10515,6 @@ static int i40e_suspend(struct pci_dev *pdev, pm_message_t state)

set_bit(__I40E_SUSPENDED, &pf->state);
set_bit(__I40E_DOWN, &pf->state);
del_timer_sync(&pf->service_timer);
cancel_work_sync(&pf->service_task);
i40e_fdir_teardown(pf);

rtnl_lock();
i40e_prep_for_reset(pf);
Expand Down
7 changes: 7 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_register.h
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,13 @@
#define I40E_PFINT_CEQCTL_CAUSE_ENA_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_CAUSE_ENA_SHIFT)
#define I40E_PFINT_CEQCTL_INTEVENT_SHIFT 31
#define I40E_PFINT_CEQCTL_INTEVENT_MASK I40E_MASK(0x1, I40E_PFINT_CEQCTL_INTEVENT_SHIFT)
#define I40E_GLINT_CTL 0x0003F800 /* Reset: CORER */
#define I40E_GLINT_CTL_DIS_AUTOMASK_PF0_SHIFT 0
#define I40E_GLINT_CTL_DIS_AUTOMASK_PF0_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_PF0_SHIFT)
#define I40E_GLINT_CTL_DIS_AUTOMASK_VF0_SHIFT 1
#define I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_VF0_SHIFT)
#define I40E_GLINT_CTL_DIS_AUTOMASK_N_SHIFT 2
#define I40E_GLINT_CTL_DIS_AUTOMASK_N_MASK I40E_MASK(0x1, I40E_GLINT_CTL_DIS_AUTOMASK_N_SHIFT)
#define I40E_PFINT_DYN_CTL0 0x00038480 /* Reset: PFR */
#define I40E_PFINT_DYN_CTL0_INTENA_SHIFT 0
#define I40E_PFINT_DYN_CTL0_INTENA_MASK I40E_MASK(0x1, I40E_PFINT_DYN_CTL0_INTENA_SHIFT)
Expand Down
9 changes: 9 additions & 0 deletions drivers/net/ethernet/intel/i40e/i40e_type.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,7 @@ struct i40e_dcbx_config {
#define I40E_DCBX_MODE_CEE 0x1
#define I40E_DCBX_MODE_IEEE 0x2
u32 numapps;
u32 tlv_status; /* CEE mode TLV status */
struct i40e_dcb_ets_config etscfg;
struct i40e_dcb_ets_config etsrec;
struct i40e_dcb_pfc_config pfc;
Expand Down Expand Up @@ -1105,6 +1106,14 @@ struct i40e_eth_stats {
u64 tx_errors; /* tepc */
};

/* Statistics collected per VEB per TC */
struct i40e_veb_tc_stats {
u64 tc_rx_packets[I40E_MAX_TRAFFIC_CLASS];
u64 tc_rx_bytes[I40E_MAX_TRAFFIC_CLASS];
u64 tc_tx_packets[I40E_MAX_TRAFFIC_CLASS];
u64 tc_tx_bytes[I40E_MAX_TRAFFIC_CLASS];
};

#ifdef I40E_FCOE
/* Statistics collected per function for FCoE */
struct i40e_fcoe_stats {
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 @@ -152,6 +152,7 @@ struct i40e_virtchnl_vsi_resource {
#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_AQ 0x00000008
#define I40E_VIRTCHNL_VF_OFFLOAD_RSS_REG 0x00000010
#define I40E_VIRTCHNL_VF_OFFLOAD_VLAN 0x00010000
#define I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING 0x00020000

struct i40e_virtchnl_vf_resource {
u16 num_vsis;
Expand Down
19 changes: 15 additions & 4 deletions drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
Original file line number Diff line number Diff line change
Expand Up @@ -335,6 +335,18 @@ static void i40e_config_irq_link_list(struct i40e_vf *vf, u16 vsi_id,
wr32(hw, reg_idx, reg);
}

/* if the vf is running in polling mode and using interrupt zero,
* need to disable auto-mask on enabling zero interrupt for VFs.
*/
if ((vf->driver_caps & I40E_VIRTCHNL_VF_OFFLOAD_RX_POLLING) &&
(vector_id == 0)) {
reg = rd32(hw, I40E_GLINT_CTL);
if (!(reg & I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK)) {
reg |= I40E_GLINT_CTL_DIS_AUTOMASK_VF0_MASK;
wr32(hw, I40E_GLINT_CTL, reg);
}
}

irq_list_done:
i40e_flush(hw);
}
Expand Down Expand Up @@ -921,8 +933,6 @@ 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) {
dev_err(&pf->pdev->dev,
"Failed to enable SR-IOV, error %d.\n", ret);
pf->num_alloc_vfs = 0;
goto err_iov;
}
Expand Down Expand Up @@ -2106,11 +2116,12 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
goto error_pvid;
}

if (vsi->info.pvid == (vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT)))
if (le16_to_cpu(vsi->info.pvid) ==
(vlan_id | (qos << I40E_VLAN_PRIORITY_SHIFT)))
/* duplicate request, so just return success */
goto error_pvid;

if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi)) {
if (le16_to_cpu(vsi->info.pvid) == 0 && i40e_is_vsi_in_vlan(vsi)) {
dev_err(&pf->pdev->dev,
"VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
vf_id);
Expand Down
Loading

0 comments on commit fe21882

Please sign in to comment.