* [Intel-wired-lan] [PATCH v2] e1000e: Don't return uninitialized stats
From: Jeff Kirsher @ 2017-05-19 8:16 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170518.104614.1739169308591707817.davem@davemloft.net>
On Thu, 2017-05-18 at 10:46 -0400, David Miller wrote:
> From: Benjamin Poirier <bpoirier@suse.com>
> Date: Wed, 17 May 2017 16:24:13 -0400
>
> > Some statistics passed to ethtool are garbage because
> > e1000e_get_stats64()
> > doesn't write them, for example: tx_heartbeat_errors. This leaks kernel
> > memory to userspace and confuses users.
> >
> > Do like ixgbe and use dev_get_stats() which first zeroes out
> > rtnl_link_stats64.
> >
> > Fixes: 5944701df90d ("net: remove useless memset's in drivers
> > get_stats64")
> > Reported-by: Stefan Priebe <s.priebe@profihost.ag>
> > Signed-off-by: Benjamin Poirier <bpoirier@suse.com>
>
> Jeff, please be sure to pick this up, thanks.
Yep, I have it in my tree, thanks.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 819 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20170519/af01001c/attachment.asc>
^ permalink raw reply
* [Intel-wired-lan] [PATCH] e1000e: use disable_hardirq() also for MSIX vectors in e1000_netpoll()
From: Konstantin Khlebnikov @ 2017-05-19 7:18 UTC (permalink / raw)
To: intel-wired-lan
Replace disable_irq() which waits for threaded irq handlers with
disable_hardirq() which waits only for hardirq part.
Signed-off-by: Konstantin Khlebnikov <khlebnikov@yandex-team.ru>
Fixes: 311191297125 ("e1000: use disable_hardirq() for e1000_netpoll()")
---
drivers/net/ethernet/intel/e1000e/netdev.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index b3679728caac..7f185f481b12 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -6733,20 +6733,20 @@ static irqreturn_t e1000_intr_msix(int __always_unused irq, void *data)
vector = 0;
msix_irq = adapter->msix_entries[vector].vector;
- disable_irq(msix_irq);
- e1000_intr_msix_rx(msix_irq, netdev);
+ if (disable_hardirq(msix_irq))
+ e1000_intr_msix_rx(msix_irq, netdev);
enable_irq(msix_irq);
vector++;
msix_irq = adapter->msix_entries[vector].vector;
- disable_irq(msix_irq);
- e1000_intr_msix_tx(msix_irq, netdev);
+ if (disable_hardirq(msix_irq))
+ e1000_intr_msix_tx(msix_irq, netdev);
enable_irq(msix_irq);
vector++;
msix_irq = adapter->msix_entries[vector].vector;
- disable_irq(msix_irq);
- e1000_msix_other(msix_irq, netdev);
+ if (disable_hardirq(msix_irq))
+ e1000_msix_other(msix_irq, netdev);
enable_irq(msix_irq);
}
^ permalink raw reply related
* [Intel-wired-lan] [PATCH v5 2/2] i40e: add support for XDP_TX action
From: =?unknown-8bit?q?Bj=C3=B6rn_T=C3=B6pel?= @ 2017-05-19 7:08 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170519070856.13900-1-bjorn.topel@gmail.com>
From: Bj?rn T?pel <bjorn.topel@intel.com>
This patch adds proper XDP_TX action support. For each Tx ring, an
additional XDP Tx ring is allocated and setup. This version does the
DMA mapping in the fast-path, which will penalize performance for
IOMMU enabled systems. Further, debugfs support is not wired up for
the XDP Tx rings.
Signed-off-by: Bj?rn T?pel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e.h | 1 +
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 57 +++++++-
drivers/net/ethernet/intel/i40e/i40e_main.c | 195 +++++++++++++++++++++----
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 119 ++++++++++++++-
drivers/net/ethernet/intel/i40e/i40e_txrx.h | 11 ++
5 files changed, 350 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index d3195b29d53c..4250ab55a9f1 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -629,6 +629,7 @@ struct i40e_vsi {
/* These are containers of ring pointers, allocated at run-time */
struct i40e_ring **rx_rings;
struct i40e_ring **tx_rings;
+ struct i40e_ring **xdp_rings; /* XDP Tx rings */
u32 active_filters;
u32 promisc_threshold;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
index 3d58762efbc0..518788e42887 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -1302,7 +1302,7 @@ static void i40e_get_ringparam(struct net_device *netdev,
static int i40e_set_ringparam(struct net_device *netdev,
struct ethtool_ringparam *ring)
{
- struct i40e_ring *tx_rings = NULL, *rx_rings = NULL;
+ struct i40e_ring *tx_rings = NULL, *rx_rings = NULL, *xdp_rings = NULL;
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_hw *hw = &np->vsi->back->hw;
struct i40e_vsi *vsi = np->vsi;
@@ -1310,6 +1310,7 @@ static int i40e_set_ringparam(struct net_device *netdev,
u32 new_rx_count, new_tx_count;
int timeout = 50;
int i, err = 0;
+ bool xdp = i40e_enabled_xdp_vsi(vsi);
if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
return -EINVAL;
@@ -1345,6 +1346,8 @@ static int i40e_set_ringparam(struct net_device *netdev,
for (i = 0; i < vsi->num_queue_pairs; i++) {
vsi->tx_rings[i]->count = new_tx_count;
vsi->rx_rings[i]->count = new_rx_count;
+ if (xdp)
+ vsi->xdp_rings[i]->count = new_tx_count;
}
goto done;
}
@@ -1440,6 +1443,41 @@ static int i40e_set_ringparam(struct net_device *netdev,
}
}
+ /* alloc updated XDP Tx resources */
+ if (xdp && new_tx_count != vsi->xdp_rings[0]->count) {
+ netdev_info(netdev,
+ "Changing XDP Tx descriptor count from %d to %d.\n",
+ vsi->xdp_rings[0]->count, new_tx_count);
+ xdp_rings = kcalloc(vsi->alloc_queue_pairs,
+ sizeof(struct i40e_ring), GFP_KERNEL);
+ if (!xdp_rings) {
+ err = -ENOMEM;
+ goto free_rx;
+ }
+
+ for (i = 0; i < vsi->num_queue_pairs; i++) {
+ /* clone ring and setup updated count */
+ xdp_rings[i] = *vsi->xdp_rings[i];
+ xdp_rings[i].count = new_tx_count;
+ /* the desc and bi pointers will be reallocated in the
+ * setup call
+ */
+ xdp_rings[i].desc = NULL;
+ xdp_rings[i].rx_bi = NULL;
+ err = i40e_setup_tx_descriptors(&xdp_rings[i]);
+ if (err) {
+ while (i) {
+ i--;
+ i40e_free_tx_resources(&xdp_rings[i]);
+ }
+ kfree(xdp_rings);
+ xdp_rings = NULL;
+
+ goto free_rx;
+ }
+ }
+ }
+
/* Bring interface down, copy in the new ring info,
* then restore the interface
*/
@@ -1474,8 +1512,25 @@ static int i40e_set_ringparam(struct net_device *netdev,
rx_rings = NULL;
}
+ if (xdp_rings) {
+ for (i = 0; i < vsi->num_queue_pairs; i++) {
+ i40e_free_tx_resources(vsi->xdp_rings[i]);
+ *vsi->xdp_rings[i] = xdp_rings[i];
+ }
+ kfree(xdp_rings);
+ xdp_rings = NULL;
+ }
+
i40e_up(vsi);
+free_rx:
+ /* error cleanup if the XDP Tx allocations failed after getting Rx */
+ if (rx_rings) {
+ for (i = 0; i < vsi->num_queue_pairs; i++)
+ i40e_free_rx_resources(&rx_rings[i]);
+ kfree(rx_rings);
+ rx_rings = NULL;
+ }
free_tx:
/* error cleanup if the Rx allocations failed after getting Tx */
if (tx_rings) {
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 27a29904611a..f1dbcead79ba 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -408,6 +408,27 @@ struct rtnl_link_stats64 *i40e_get_vsi_stats_struct(struct i40e_vsi *vsi)
}
/**
+ * i40e_get_netdev_stats_struct_tx - populate stats from a Tx ring
+ * @ring: Tx ring to get statistics from
+ * @stats: statistics entry to be updated
+ **/
+static void i40e_get_netdev_stats_struct_tx(struct i40e_ring *ring,
+ struct rtnl_link_stats64 *stats)
+{
+ u64 bytes, packets;
+ unsigned int start;
+
+ do {
+ start = u64_stats_fetch_begin_irq(&ring->syncp);
+ packets = ring->stats.packets;
+ bytes = ring->stats.bytes;
+ } while (u64_stats_fetch_retry_irq(&ring->syncp, start));
+
+ stats->tx_packets += packets;
+ stats->tx_bytes += bytes;
+}
+
+/**
* i40e_get_netdev_stats_struct - Get statistics for netdev interface
* @netdev: network interface device structure
*
@@ -437,15 +458,8 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev,
tx_ring = ACCESS_ONCE(vsi->tx_rings[i]);
if (!tx_ring)
continue;
+ i40e_get_netdev_stats_struct_tx(tx_ring, stats);
- do {
- start = u64_stats_fetch_begin_irq(&tx_ring->syncp);
- packets = tx_ring->stats.packets;
- bytes = tx_ring->stats.bytes;
- } while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
-
- stats->tx_packets += packets;
- stats->tx_bytes += bytes;
rx_ring = &tx_ring[1];
do {
@@ -456,6 +470,9 @@ static void i40e_get_netdev_stats_struct(struct net_device *netdev,
stats->rx_packets += packets;
stats->rx_bytes += bytes;
+
+ if (i40e_enabled_xdp_vsi(vsi))
+ i40e_get_netdev_stats_struct_tx(&rx_ring[1], stats);
}
rcu_read_unlock();
@@ -2802,6 +2819,12 @@ static int i40e_vsi_setup_tx_resources(struct i40e_vsi *vsi)
for (i = 0; i < vsi->num_queue_pairs && !err; i++)
err = i40e_setup_tx_descriptors(vsi->tx_rings[i]);
+ if (!i40e_enabled_xdp_vsi(vsi))
+ return err;
+
+ for (i = 0; i < vsi->num_queue_pairs && !err; i++)
+ err = i40e_setup_tx_descriptors(vsi->xdp_rings[i]);
+
return err;
}
@@ -2815,12 +2838,17 @@ static void i40e_vsi_free_tx_resources(struct i40e_vsi *vsi)
{
int i;
- if (!vsi->tx_rings)
- return;
+ if (vsi->tx_rings) {
+ for (i = 0; i < vsi->num_queue_pairs; i++)
+ if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc)
+ i40e_free_tx_resources(vsi->tx_rings[i]);
+ }
- for (i = 0; i < vsi->num_queue_pairs; i++)
- if (vsi->tx_rings[i] && vsi->tx_rings[i]->desc)
- i40e_free_tx_resources(vsi->tx_rings[i]);
+ if (vsi->xdp_rings) {
+ for (i = 0; i < vsi->num_queue_pairs; i++)
+ if (vsi->xdp_rings[i] && vsi->xdp_rings[i]->desc)
+ i40e_free_tx_resources(vsi->xdp_rings[i]);
+ }
}
/**
@@ -3081,6 +3109,12 @@ static int i40e_vsi_configure_tx(struct i40e_vsi *vsi)
for (i = 0; (i < vsi->num_queue_pairs) && !err; i++)
err = i40e_configure_tx_ring(vsi->tx_rings[i]);
+ if (!i40e_enabled_xdp_vsi(vsi))
+ return err;
+
+ for (i = 0; (i < vsi->num_queue_pairs) && !err; i++)
+ err = i40e_configure_tx_ring(vsi->xdp_rings[i]);
+
return err;
}
@@ -3230,6 +3264,7 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
u16 vector;
int i, q;
u32 qp;
+ bool has_xdp = i40e_enabled_xdp_vsi(vsi);
/* The interrupt indexing is offset by 1 in the PFINT_ITRn
* and PFINT_LNKLSTn registers, e.g.:
@@ -3256,16 +3291,28 @@ static void i40e_vsi_configure_msix(struct i40e_vsi *vsi)
wr32(hw, I40E_PFINT_LNKLSTN(vector - 1), qp);
for (q = 0; q < q_vector->num_ringpairs; q++) {
u32 val;
+ u32 nextqp = has_xdp ? qp + vsi->alloc_queue_pairs : qp;
val = I40E_QINT_RQCTL_CAUSE_ENA_MASK |
(I40E_RX_ITR << I40E_QINT_RQCTL_ITR_INDX_SHIFT) |
(vector << I40E_QINT_RQCTL_MSIX_INDX_SHIFT) |
- (qp << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)|
+ (nextqp << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)|
(I40E_QUEUE_TYPE_TX
<< I40E_QINT_RQCTL_NEXTQ_TYPE_SHIFT);
wr32(hw, I40E_QINT_RQCTL(qp), val);
+ if (has_xdp) {
+ val = I40E_QINT_TQCTL_CAUSE_ENA_MASK |
+ (I40E_TX_ITR << I40E_QINT_TQCTL_ITR_INDX_SHIFT) |
+ (vector << I40E_QINT_TQCTL_MSIX_INDX_SHIFT) |
+ (qp << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT)|
+ (I40E_QUEUE_TYPE_TX
+ << I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT);
+
+ wr32(hw, I40E_QINT_TQCTL(nextqp), val);
+ }
+
val = I40E_QINT_TQCTL_CAUSE_ENA_MASK |
(I40E_TX_ITR << I40E_QINT_TQCTL_ITR_INDX_SHIFT) |
(vector << I40E_QINT_TQCTL_MSIX_INDX_SHIFT) |
@@ -3334,6 +3381,7 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
struct i40e_pf *pf = vsi->back;
struct i40e_hw *hw = &pf->hw;
u32 val;
+ u32 nextqp = i40e_enabled_xdp_vsi(vsi) ? vsi->alloc_queue_pairs : 0;
/* set the ITR configuration */
q_vector->itr_countdown = ITR_COUNTDOWN_START;
@@ -3350,12 +3398,22 @@ static void i40e_configure_msi_and_legacy(struct i40e_vsi *vsi)
wr32(hw, I40E_PFINT_LNKLST0, 0);
/* Associate the queue pair to the vector and enable the queue int */
- val = I40E_QINT_RQCTL_CAUSE_ENA_MASK |
- (I40E_RX_ITR << I40E_QINT_RQCTL_ITR_INDX_SHIFT) |
+ val = I40E_QINT_RQCTL_CAUSE_ENA_MASK |
+ (I40E_RX_ITR << I40E_QINT_RQCTL_ITR_INDX_SHIFT) |
+ (nextqp << I40E_QINT_RQCTL_NEXTQ_INDX_SHIFT)|
(I40E_QUEUE_TYPE_TX << I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT);
wr32(hw, I40E_QINT_RQCTL(0), val);
+ if (i40e_enabled_xdp_vsi(vsi)) {
+ val = I40E_QINT_TQCTL_CAUSE_ENA_MASK |
+ (I40E_TX_ITR << I40E_QINT_TQCTL_ITR_INDX_SHIFT)|
+ (I40E_QUEUE_TYPE_TX
+ << I40E_QINT_TQCTL_NEXTQ_TYPE_SHIFT);
+
+ wr32(hw, I40E_QINT_TQCTL(nextqp), val);
+ }
+
val = I40E_QINT_TQCTL_CAUSE_ENA_MASK |
(I40E_TX_ITR << I40E_QINT_TQCTL_ITR_INDX_SHIFT) |
(I40E_QUEUE_END_OF_LIST << I40E_QINT_TQCTL_NEXTQ_INDX_SHIFT);
@@ -3522,6 +3580,9 @@ static void i40e_vsi_disable_irq(struct i40e_vsi *vsi)
for (i = 0; i < vsi->num_queue_pairs; i++) {
wr32(hw, I40E_QINT_TQCTL(vsi->tx_rings[i]->reg_idx), 0);
wr32(hw, I40E_QINT_RQCTL(vsi->rx_rings[i]->reg_idx), 0);
+ if (!i40e_enabled_xdp_vsi(vsi))
+ continue;
+ wr32(hw, I40E_QINT_TQCTL(vsi->xdp_rings[i]->reg_idx), 0);
}
if (pf->flags & I40E_FLAG_MSIX_ENABLED) {
@@ -3818,12 +3879,22 @@ 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];
struct i40e_ring *rx_ring = vsi->rx_rings[qp_idx];
+ struct i40e_ring *xdp_ring = i40e_enabled_xdp_vsi(vsi) ?
+ vsi->xdp_rings[qp_idx] : NULL;
tx_ring->q_vector = q_vector;
tx_ring->next = q_vector->tx.ring;
q_vector->tx.ring = tx_ring;
q_vector->tx.count++;
+ /* Place XDP Tx ring in the same q_vector ring list as regular Tx */
+ if (xdp_ring) {
+ xdp_ring->q_vector = q_vector;
+ xdp_ring->next = q_vector->tx.ring;
+ q_vector->tx.ring = xdp_ring;
+ q_vector->tx.count++;
+ }
+
rx_ring->q_vector = q_vector;
rx_ring->next = q_vector->rx.ring;
q_vector->rx.ring = rx_ring;
@@ -4026,6 +4097,23 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
}
}
+ if (ret || !i40e_enabled_xdp_vsi(vsi))
+ return ret;
+
+ pf_q = vsi->base_queue + vsi->alloc_queue_pairs;
+ for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
+ i40e_control_tx_q(pf, pf_q, enable);
+
+ /* wait for the change to finish */
+ ret = i40e_pf_txq_wait(pf, pf_q, enable);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+ "VSI seid %d XDP Tx ring %d %sable timeout\n",
+ vsi->seid, pf_q, (enable ? "en" : "dis"));
+ break;
+ }
+ }
+
return ret;
}
@@ -4535,7 +4623,7 @@ int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi)
vsi->seid, pf_q);
return ret;
}
- /* Check and wait for the Tx queue */
+ /* Check and wait for the Rx queue */
ret = i40e_pf_rxq_wait(pf, pf_q, false);
if (ret) {
dev_info(&pf->pdev->dev,
@@ -4545,6 +4633,21 @@ int i40e_vsi_wait_queues_disabled(struct i40e_vsi *vsi)
}
}
+ if (!i40e_enabled_xdp_vsi(vsi))
+ return 0;
+
+ pf_q = vsi->base_queue + vsi->alloc_queue_pairs;
+ for (i = 0; i < vsi->num_queue_pairs; i++, pf_q++) {
+ /* Check and wait for the XDP Tx queue */
+ ret = i40e_pf_txq_wait(pf, pf_q, false);
+ if (ret) {
+ dev_info(&pf->pdev->dev,
+ "VSI seid %d XDP Tx ring %d disable timeout\n",
+ vsi->seid, pf_q);
+ return ret;
+ }
+ }
+
return 0;
}
@@ -5454,6 +5557,8 @@ void i40e_down(struct i40e_vsi *vsi)
for (i = 0; i < vsi->num_queue_pairs; i++) {
i40e_clean_tx_ring(vsi->tx_rings[i]);
+ if (i40e_enabled_xdp_vsi(vsi))
+ i40e_clean_tx_ring(vsi->xdp_rings[i]);
i40e_clean_rx_ring(vsi->rx_rings[i]);
}
@@ -7475,6 +7580,7 @@ static int i40e_set_num_rings_in_vsi(struct i40e_vsi *vsi)
switch (vsi->type) {
case I40E_VSI_MAIN:
vsi->alloc_queue_pairs = pf->num_lan_qps;
+
vsi->num_desc = ALIGN(I40E_DEFAULT_NUM_DESCRIPTORS,
I40E_REQ_DESCRIPTOR_MULTIPLE);
if (pf->flags & I40E_FLAG_MSIX_ENABLED)
@@ -7524,13 +7630,17 @@ static int i40e_vsi_alloc_arrays(struct i40e_vsi *vsi, bool alloc_qvectors)
{
int size;
int ret = 0;
+ int nrings;
- /* allocate memory for both Tx and Rx ring pointers */
- size = sizeof(struct i40e_ring *) * vsi->alloc_queue_pairs * 2;
+ /* allocate memory for both Tx, Rx and XDP Tx ring pointers */
+ nrings = i40e_enabled_xdp_vsi(vsi) ? 3 : 2;
+ size = sizeof(struct i40e_ring *) * vsi->alloc_queue_pairs * nrings;
vsi->tx_rings = kzalloc(size, GFP_KERNEL);
if (!vsi->tx_rings)
return -ENOMEM;
vsi->rx_rings = &vsi->tx_rings[vsi->alloc_queue_pairs];
+ if (i40e_enabled_xdp_vsi(vsi))
+ vsi->xdp_rings = &vsi->rx_rings[vsi->alloc_queue_pairs];
if (alloc_qvectors) {
/* allocate memory for q_vector pointers */
@@ -7650,6 +7760,7 @@ static void i40e_vsi_free_arrays(struct i40e_vsi *vsi, bool free_qvectors)
kfree(vsi->tx_rings);
vsi->tx_rings = NULL;
vsi->rx_rings = NULL;
+ vsi->xdp_rings = NULL;
}
/**
@@ -7733,6 +7844,8 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi)
kfree_rcu(vsi->tx_rings[i], rcu);
vsi->tx_rings[i] = NULL;
vsi->rx_rings[i] = NULL;
+ if (vsi->xdp_rings)
+ vsi->xdp_rings[i] = NULL;
}
}
}
@@ -7743,14 +7856,15 @@ static void i40e_vsi_clear_rings(struct i40e_vsi *vsi)
**/
static int i40e_alloc_rings(struct i40e_vsi *vsi)
{
- struct i40e_ring *tx_ring, *rx_ring;
+ struct i40e_ring *tx_ring, *rx_ring, *xdp_ring;
struct i40e_pf *pf = vsi->back;
- int i;
+ int i, nr;
+ nr = i40e_enabled_xdp_vsi(vsi) ? 3 : 2;
/* Set basic values in the rings to be used later during open() */
for (i = 0; i < vsi->alloc_queue_pairs; i++) {
/* allocate space for both Tx and Rx in one shot */
- tx_ring = kzalloc(sizeof(struct i40e_ring) * 2, GFP_KERNEL);
+ tx_ring = kcalloc(nr, sizeof(*tx_ring), GFP_KERNEL);
if (!tx_ring)
goto err_out;
@@ -7780,6 +7894,26 @@ static int i40e_alloc_rings(struct i40e_vsi *vsi)
rx_ring->dcb_tc = 0;
rx_ring->rx_itr_setting = pf->rx_itr_default;
vsi->rx_rings[i] = rx_ring;
+
+ if (!i40e_enabled_xdp_vsi(vsi))
+ continue;
+
+ xdp_ring = &rx_ring[1];
+ xdp_ring->queue_index = vsi->alloc_queue_pairs + i;
+ xdp_ring->reg_idx = vsi->base_queue +
+ vsi->alloc_queue_pairs + i;
+ xdp_ring->ring_active = false;
+ xdp_ring->vsi = vsi;
+ xdp_ring->netdev = NULL;
+ xdp_ring->dev = &pf->pdev->dev;
+ xdp_ring->count = vsi->num_desc;
+ xdp_ring->size = 0;
+ xdp_ring->dcb_tc = 0;
+ if (vsi->back->flags & I40E_FLAG_WB_ON_ITR_CAPABLE)
+ xdp_ring->flags = I40E_TXR_FLAGS_WB_ON_ITR;
+ set_ring_xdp(xdp_ring);
+ xdp_ring->tx_itr_setting = pf->tx_itr_default;
+ vsi->xdp_rings[i] = xdp_ring;
}
return 0;
@@ -9988,6 +10122,7 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
struct i40e_pf *pf;
u8 enabled_tc;
int ret;
+ u16 alloc_queue_pairs;
if (!vsi)
return NULL;
@@ -10003,11 +10138,14 @@ static struct i40e_vsi *i40e_vsi_reinit_setup(struct i40e_vsi *vsi)
if (ret)
goto err_vsi;
- ret = i40e_get_lump(pf, pf->qp_pile, vsi->alloc_queue_pairs, vsi->idx);
+ alloc_queue_pairs = vsi->alloc_queue_pairs *
+ (i40e_enabled_xdp_vsi(vsi) ? 2 : 1);
+
+ ret = i40e_get_lump(pf, pf->qp_pile, alloc_queue_pairs, vsi->idx);
if (ret < 0) {
dev_info(&pf->pdev->dev,
"failed to get tracking for %d queues for VSI %d err %d\n",
- vsi->alloc_queue_pairs, vsi->seid, ret);
+ alloc_queue_pairs, vsi->seid, ret);
goto err_vsi;
}
vsi->base_queue = ret;
@@ -10065,6 +10203,7 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
struct i40e_veb *veb = NULL;
int ret, i;
int v_idx;
+ u16 alloc_queue_pairs;
/* The requested uplink_seid must be either
* - the PF's port seid
@@ -10150,12 +10289,14 @@ struct i40e_vsi *i40e_vsi_setup(struct i40e_pf *pf, u8 type,
else if (type == I40E_VSI_SRIOV)
vsi->vf_id = param1;
/* assign it some queues */
- ret = i40e_get_lump(pf, pf->qp_pile, vsi->alloc_queue_pairs,
- vsi->idx);
+ alloc_queue_pairs = vsi->alloc_queue_pairs *
+ (i40e_enabled_xdp_vsi(vsi) ? 2 : 1);
+
+ ret = i40e_get_lump(pf, pf->qp_pile, alloc_queue_pairs, vsi->idx);
if (ret < 0) {
dev_info(&pf->pdev->dev,
"failed to get tracking for %d queues for VSI %d err=%d\n",
- vsi->alloc_queue_pairs, vsi->seid, ret);
+ alloc_queue_pairs, vsi->seid, ret);
goto err_vsi;
}
vsi->base_queue = ret;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 0c2f0230faf4..c025e517f7e5 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -630,6 +630,8 @@ static void i40e_unmap_and_free_tx_resource(struct i40e_ring *ring,
if (tx_buffer->skb) {
if (tx_buffer->tx_flags & I40E_TX_FLAGS_FD_SB)
kfree(tx_buffer->raw_buf);
+ else if (ring_is_xdp(ring))
+ page_frag_free(tx_buffer->raw_buf);
else
dev_kfree_skb_any(tx_buffer->skb);
if (dma_unmap_len(tx_buffer, len))
@@ -771,8 +773,11 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
total_bytes += tx_buf->bytecount;
total_packets += tx_buf->gso_segs;
- /* free the skb */
- napi_consume_skb(tx_buf->skb, napi_budget);
+ /* free the skb/XDP data */
+ if (ring_is_xdp(tx_ring))
+ page_frag_free(tx_buf->raw_buf);
+ else
+ napi_consume_skb(tx_buf->skb, napi_budget);
/* unmap skb header data */
dma_unmap_single(tx_ring->dev,
@@ -848,6 +853,9 @@ static bool i40e_clean_tx_irq(struct i40e_vsi *vsi,
tx_ring->arm_wb = true;
}
+ if (ring_is_xdp(tx_ring))
+ return !!budget;
+
/* notify netdev of completed buffers */
netdev_tx_completed_queue(txring_txq(tx_ring),
total_packets, total_bytes);
@@ -1969,6 +1977,10 @@ static bool i40e_is_non_eop(struct i40e_ring *rx_ring,
#define I40E_XDP_PASS 0
#define I40E_XDP_CONSUMED 1
+#define I40E_XDP_TX 2
+
+static int i40e_xmit_xdp_ring(struct xdp_buff *xdp,
+ struct i40e_ring *xdp_ring);
/**
* i40e_run_xdp - run an XDP program
@@ -1981,6 +1993,7 @@ static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring,
int result = I40E_XDP_PASS;
struct bpf_prog *xdp_prog;
u32 act;
+ struct i40e_ring *xdp_ring;
rcu_read_lock();
xdp_prog = READ_ONCE(rx_ring->xdp_prog);
@@ -1989,12 +2002,16 @@ static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring,
goto xdp_out;
act = bpf_prog_run_xdp(xdp_prog, xdp);
+
switch (act) {
case XDP_PASS:
break;
+ case XDP_TX:
+ xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index];
+ result = i40e_xmit_xdp_ring(xdp, xdp_ring);
+ break;
default:
bpf_warn_invalid_xdp_action(act);
- case XDP_TX:
case XDP_ABORTED:
trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
/* fallthrough -- handle aborts by dropping packet */
@@ -2008,6 +2025,27 @@ static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring,
}
/**
+ * i40e_rx_buffer_flip - adjusted rx_buffer to point to an unused region
+ * @rx_ring: Rx ring
+ * @rx_buffer: Rx buffer to adjust
+ * @size: Size of adjustment
+ **/
+static void i40e_rx_buffer_flip(struct i40e_ring *rx_ring,
+ struct i40e_rx_buffer *rx_buffer,
+ unsigned int size)
+{
+#if (PAGE_SIZE < 8192)
+ unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2;
+
+ rx_buffer->page_offset ^= truesize;
+#else
+ unsigned int truesize = SKB_DATA_ALIGN(i40e_rx_offset(rx_ring) + size);
+
+ rx_buffer->page_offset += truesize;
+#endif
+}
+
+/**
* i40e_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf
* @rx_ring: rx descriptor ring to transact packets on
* @budget: Total limit on number of packets to process
@@ -2024,7 +2062,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
unsigned int total_rx_bytes = 0, total_rx_packets = 0;
struct sk_buff *skb = rx_ring->skb;
u16 cleaned_count = I40E_DESC_UNUSED(rx_ring);
- bool failure = false;
+ bool failure = false, xdp_xmit = false;
while (likely(total_rx_packets < budget)) {
struct i40e_rx_buffer *rx_buffer;
@@ -2081,9 +2119,14 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
}
if (IS_ERR(skb)) {
+ if (PTR_ERR(skb) == -I40E_XDP_TX) {
+ xdp_xmit = true;
+ i40e_rx_buffer_flip(rx_ring, rx_buffer, size);
+ } else {
+ rx_buffer->pagecnt_bias++;
+ }
total_rx_bytes += size;
total_rx_packets++;
- rx_buffer->pagecnt_bias++;
} else if (skb) {
i40e_add_rx_frag(rx_ring, rx_buffer, skb, size);
} else if (ring_uses_build_skb(rx_ring)) {
@@ -2131,6 +2174,19 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
total_rx_packets++;
}
+ if (xdp_xmit) {
+ struct i40e_ring *xdp_ring;
+
+ xdp_ring = rx_ring->vsi->xdp_rings[rx_ring->queue_index];
+
+ /* Force memory writes to complete before letting h/w
+ * know there are new descriptors to fetch.
+ */
+ wmb();
+
+ writel(xdp_ring->next_to_use, xdp_ring->tail);
+ }
+
rx_ring->skb = skb;
u64_stats_update_begin(&rx_ring->syncp);
@@ -3188,6 +3244,59 @@ static inline int i40e_tx_map(struct i40e_ring *tx_ring, struct sk_buff *skb,
}
/**
+ * i40e_xmit_xdp_ring - transmits an XDP buffer to an XDP Tx ring
+ * @xdp: data to transmit
+ * @xdp_ring: XDP Tx ring
+ **/
+static int i40e_xmit_xdp_ring(struct xdp_buff *xdp,
+ struct i40e_ring *xdp_ring)
+{
+ struct i40e_tx_buffer *tx_bi;
+ struct i40e_tx_desc *tx_desc;
+ u16 i = xdp_ring->next_to_use;
+ dma_addr_t dma;
+ u32 size = xdp->data_end - xdp->data;
+
+ if (!unlikely(I40E_DESC_UNUSED(xdp_ring))) {
+ xdp_ring->tx_stats.tx_busy++;
+ return I40E_XDP_CONSUMED;
+ }
+
+ dma = dma_map_single(xdp_ring->dev, xdp->data, size, DMA_TO_DEVICE);
+ if (dma_mapping_error(xdp_ring->dev, dma))
+ return I40E_XDP_CONSUMED;
+
+ tx_bi = &xdp_ring->tx_bi[i];
+ tx_bi->bytecount = size;
+ tx_bi->gso_segs = 1;
+ tx_bi->raw_buf = xdp->data;
+
+ /* record length, and DMA address */
+ dma_unmap_len_set(tx_bi, len, size);
+ dma_unmap_addr_set(tx_bi, dma, dma);
+
+ tx_desc = I40E_TX_DESC(xdp_ring, i);
+ tx_desc->buffer_addr = cpu_to_le64(dma);
+ tx_desc->cmd_type_offset_bsz = build_ctob(I40E_TX_DESC_CMD_ICRC
+ | I40E_TXD_CMD,
+ 0, size, 0);
+
+ /* Make certain all of the status bits have been updated
+ * before next_to_watch is written.
+ */
+ smp_wmb();
+
+ i++;
+ if (i == xdp_ring->count)
+ i = 0;
+
+ tx_bi->next_to_watch = tx_desc;
+ xdp_ring->next_to_use = i;
+
+ return I40E_XDP_TX;
+}
+
+/**
* i40e_xmit_frame_ring - Sends buffer on Tx ring
* @skb: send buffer
* @tx_ring: ring to send buffer on
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
index 31f0b162996f..b288d58313a6 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -396,6 +396,7 @@ struct i40e_ring {
u16 flags;
#define I40E_TXR_FLAGS_WB_ON_ITR BIT(0)
#define I40E_RXR_FLAGS_BUILD_SKB_ENABLED BIT(1)
+#define I40E_TXR_FLAGS_XDP BIT(2)
/* stats structs */
struct i40e_queue_stats stats;
@@ -438,6 +439,16 @@ static inline void clear_ring_build_skb_enabled(struct i40e_ring *ring)
ring->flags &= ~I40E_RXR_FLAGS_BUILD_SKB_ENABLED;
}
+static inline bool ring_is_xdp(struct i40e_ring *ring)
+{
+ return !!(ring->flags & I40E_TXR_FLAGS_XDP);
+}
+
+static inline void set_ring_xdp(struct i40e_ring *ring)
+{
+ ring->flags |= I40E_TXR_FLAGS_XDP;
+}
+
enum i40e_latency_range {
I40E_LOWEST_LATENCY = 0,
I40E_LOW_LATENCY = 1,
--
2.11.0
^ permalink raw reply related
* [Intel-wired-lan] [PATCH v5 1/2] i40e: add XDP support for pass and drop actions
From: =?unknown-8bit?q?Bj=C3=B6rn_T=C3=B6pel?= @ 2017-05-19 7:08 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170519070856.13900-1-bjorn.topel@gmail.com>
From: Bj?rn T?pel <bjorn.topel@intel.com>
This commit adds basic XDP support for i40e derived NICs. All XDP
actions will end up in XDP_DROP.
Signed-off-by: Bj?rn T?pel <bjorn.topel@intel.com>
---
drivers/net/ethernet/intel/i40e/i40e.h | 7 ++
drivers/net/ethernet/intel/i40e/i40e_main.c | 75 ++++++++++++++++
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 130 +++++++++++++++++++++-------
drivers/net/ethernet/intel/i40e/i40e_txrx.h | 1 +
4 files changed, 182 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index 395ca94faf80..d3195b29d53c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -645,6 +645,8 @@ struct i40e_vsi {
u16 max_frame;
u16 rx_buf_len;
+ struct bpf_prog *xdp_prog;
+
/* List of q_vectors allocated to this VSI */
struct i40e_q_vector **q_vectors;
int num_q_vectors;
@@ -972,4 +974,9 @@ i40e_status i40e_get_npar_bw_setting(struct i40e_pf *pf);
i40e_status i40e_set_npar_bw_setting(struct i40e_pf *pf);
i40e_status i40e_commit_npar_bw_setting(struct i40e_pf *pf);
void i40e_print_link_message(struct i40e_vsi *vsi, bool isup);
+
+static inline bool i40e_enabled_xdp_vsi(struct i40e_vsi *vsi)
+{
+ return !!vsi->xdp_prog;
+}
#endif /* _I40E_H_ */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 8d1d3b859af7..27a29904611a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_main.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
@@ -27,6 +27,7 @@
#include <linux/etherdevice.h>
#include <linux/of_net.h>
#include <linux/pci.h>
+#include <linux/bpf.h>
/* Local includes */
#include "i40e.h"
@@ -2408,6 +2409,13 @@ static int i40e_change_mtu(struct net_device *netdev, int new_mtu)
struct i40e_vsi *vsi = np->vsi;
struct i40e_pf *pf = vsi->back;
+ if (i40e_enabled_xdp_vsi(vsi)) {
+ int frame_size = new_mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+
+ if (frame_size > vsi->rx_buf_len)
+ return -EINVAL;
+ }
+
netdev_info(netdev, "changing MTU from %d to %d\n",
netdev->mtu, new_mtu);
netdev->mtu = new_mtu;
@@ -9310,6 +9318,72 @@ static netdev_features_t i40e_features_check(struct sk_buff *skb,
return features & ~(NETIF_F_CSUM_MASK | NETIF_F_GSO_MASK);
}
+/**
+ * i40e_xdp_setup - add/remove an XDP program
+ * @vsi: VSI to changed
+ * @prog: XDP program
+ **/
+static int i40e_xdp_setup(struct i40e_vsi *vsi,
+ struct bpf_prog *prog)
+{
+ struct i40e_pf *pf = vsi->back;
+ int frame_size = vsi->netdev->mtu + ETH_HLEN + ETH_FCS_LEN + VLAN_HLEN;
+ int i;
+ bool need_reset;
+ struct bpf_prog *old_prog;
+
+ /* Don't allow frames that span over multiple buffers */
+ if (frame_size > vsi->rx_buf_len)
+ return -EINVAL;
+
+ if (!i40e_enabled_xdp_vsi(vsi) && !prog)
+ return 0;
+
+ /* When turning XDP on->off/off->on we reset and rebuild the rings. */
+ need_reset = (i40e_enabled_xdp_vsi(vsi) != !!prog);
+
+ if (need_reset)
+ i40e_prep_for_reset(pf, true);
+
+ old_prog = xchg(&vsi->xdp_prog, prog);
+
+ if (need_reset)
+ i40e_reset_and_rebuild(pf, true, true);
+
+ for (i = 0; i < vsi->num_queue_pairs; i++)
+ WRITE_ONCE(vsi->rx_rings[i]->xdp_prog, vsi->xdp_prog);
+
+ if (old_prog)
+ bpf_prog_put(old_prog);
+
+ return 0;
+}
+
+/**
+ * i40e_xdp - implements ndo_xdp for i40e
+ * @dev: netdevice
+ * @xdp: XDP command
+ **/
+static int i40e_xdp(struct net_device *dev,
+ struct netdev_xdp *xdp)
+{
+ struct i40e_netdev_priv *np = netdev_priv(dev);
+ struct i40e_vsi *vsi = np->vsi;
+
+ if (vsi->type != I40E_VSI_MAIN)
+ return -EINVAL;
+
+ switch (xdp->command) {
+ case XDP_SETUP_PROG:
+ return i40e_xdp_setup(vsi, xdp->prog);
+ case XDP_QUERY_PROG:
+ xdp->prog_attached = i40e_enabled_xdp_vsi(vsi);
+ return 0;
+ default:
+ return -EINVAL;
+ }
+}
+
static const struct net_device_ops i40e_netdev_ops = {
.ndo_open = i40e_open,
.ndo_stop = i40e_close,
@@ -9342,6 +9416,7 @@ static const struct net_device_ops i40e_netdev_ops = {
.ndo_features_check = i40e_features_check,
.ndo_bridge_getlink = i40e_ndo_bridge_getlink,
.ndo_bridge_setlink = i40e_ndo_bridge_setlink,
+ .ndo_xdp = i40e_xdp,
};
/**
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index af554f3cda19..0c2f0230faf4 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -26,6 +26,7 @@
#include <linux/prefetch.h>
#include <net/busy_poll.h>
+#include <linux/bpf_trace.h>
#include "i40e.h"
#include "i40e_trace.h"
#include "i40e_prototype.h"
@@ -1195,6 +1196,7 @@ void i40e_clean_rx_ring(struct i40e_ring *rx_ring)
void i40e_free_rx_resources(struct i40e_ring *rx_ring)
{
i40e_clean_rx_ring(rx_ring);
+ rx_ring->xdp_prog = NULL;
kfree(rx_ring->rx_bi);
rx_ring->rx_bi = NULL;
@@ -1241,6 +1243,8 @@ int i40e_setup_rx_descriptors(struct i40e_ring *rx_ring)
rx_ring->next_to_clean = 0;
rx_ring->next_to_use = 0;
+ rx_ring->xdp_prog = rx_ring->vsi->xdp_prog;
+
return 0;
err:
kfree(rx_ring->rx_bi);
@@ -1592,6 +1596,7 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring,
/**
* i40e_cleanup_headers - Correct empty headers
* @rx_ring: rx descriptor ring packet is being transacted on
+ * @rx_desc: pointer to the EOP Rx descriptor
* @skb: pointer to current skb being fixed
*
* Also address the case where we are pulling data in on pages only
@@ -1602,8 +1607,25 @@ void i40e_process_skb_fields(struct i40e_ring *rx_ring,
*
* Returns true if an error was encountered and skb was freed.
**/
-static bool i40e_cleanup_headers(struct i40e_ring *rx_ring, struct sk_buff *skb)
+static bool i40e_cleanup_headers(struct i40e_ring *rx_ring,
+ union i40e_rx_desc *rx_desc,
+ struct sk_buff *skb)
{
+ /* XDP packets use error pointer so abort at this point */
+ if (IS_ERR(skb))
+ return true;
+
+ /* ERR_MASK will only have valid bits if EOP set, and
+ * what we are doing here is actually checking
+ * I40E_RX_DESC_ERROR_RXE_SHIFT, since it is the zeroth bit in
+ * the error field
+ */
+ if (unlikely(i40e_test_staterr(rx_desc,
+ BIT(I40E_RXD_QW1_ERROR_SHIFT)))) {
+ dev_kfree_skb_any(skb);
+ return true;
+ }
+
/* if eth_skb_pad returns an error the skb was freed */
if (eth_skb_pad(skb))
return true;
@@ -1783,10 +1805,10 @@ static struct i40e_rx_buffer *i40e_get_rx_buffer(struct i40e_ring *rx_ring,
* skb correctly.
*/
static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,
- struct i40e_rx_buffer *rx_buffer,
- unsigned int size)
+ struct xdp_buff *xdp,
+ struct i40e_rx_buffer *rx_buffer)
{
- void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
+ unsigned int size = xdp->data_end - xdp->data;
#if (PAGE_SIZE < 8192)
unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2;
#else
@@ -1796,9 +1818,9 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,
struct sk_buff *skb;
/* prefetch first cache line of first page */
- prefetch(va);
+ prefetch(xdp->data);
#if L1_CACHE_BYTES < 128
- prefetch(va + L1_CACHE_BYTES);
+ prefetch(xdp->data + L1_CACHE_BYTES);
#endif
/* allocate a skb to store the frags */
@@ -1811,10 +1833,11 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,
/* Determine available headroom for copy */
headlen = size;
if (headlen > I40E_RX_HDR_SIZE)
- headlen = eth_get_headlen(va, I40E_RX_HDR_SIZE);
+ headlen = eth_get_headlen(xdp->data, I40E_RX_HDR_SIZE);
/* align pull length to size of long to optimize memcpy performance */
- memcpy(__skb_put(skb, headlen), va, ALIGN(headlen, sizeof(long)));
+ memcpy(__skb_put(skb, headlen), xdp->data,
+ ALIGN(headlen, sizeof(long)));
/* update all of the pointers */
size -= headlen;
@@ -1847,10 +1870,10 @@ static struct sk_buff *i40e_construct_skb(struct i40e_ring *rx_ring,
* to set up the skb correctly and avoid any memcpy overhead.
*/
static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
- struct i40e_rx_buffer *rx_buffer,
- unsigned int size)
+ struct xdp_buff *xdp,
+ struct i40e_rx_buffer *rx_buffer)
{
- void *va = page_address(rx_buffer->page) + rx_buffer->page_offset;
+ unsigned int size = xdp->data_end - xdp->data;
#if (PAGE_SIZE < 8192)
unsigned int truesize = i40e_rx_pg_size(rx_ring) / 2;
#else
@@ -1860,12 +1883,12 @@ static struct sk_buff *i40e_build_skb(struct i40e_ring *rx_ring,
struct sk_buff *skb;
/* prefetch first cache line of first page */
- prefetch(va);
+ prefetch(xdp->data);
#if L1_CACHE_BYTES < 128
- prefetch(va + L1_CACHE_BYTES);
+ prefetch(xdp->data + L1_CACHE_BYTES);
#endif
/* build an skb around the page buffer */
- skb = build_skb(va - I40E_SKB_PAD, truesize);
+ skb = build_skb(xdp->data_hard_start, truesize);
if (unlikely(!skb))
return NULL;
@@ -1944,6 +1967,46 @@ static bool i40e_is_non_eop(struct i40e_ring *rx_ring,
return true;
}
+#define I40E_XDP_PASS 0
+#define I40E_XDP_CONSUMED 1
+
+/**
+ * i40e_run_xdp - run an XDP program
+ * @rx_ring: Rx ring being processed
+ * @xdp: XDP buffer containing the frame
+ **/
+static struct sk_buff *i40e_run_xdp(struct i40e_ring *rx_ring,
+ struct xdp_buff *xdp)
+{
+ int result = I40E_XDP_PASS;
+ struct bpf_prog *xdp_prog;
+ u32 act;
+
+ rcu_read_lock();
+ xdp_prog = READ_ONCE(rx_ring->xdp_prog);
+
+ if (!xdp_prog)
+ goto xdp_out;
+
+ act = bpf_prog_run_xdp(xdp_prog, xdp);
+ switch (act) {
+ case XDP_PASS:
+ break;
+ default:
+ bpf_warn_invalid_xdp_action(act);
+ case XDP_TX:
+ case XDP_ABORTED:
+ trace_xdp_exception(rx_ring->netdev, xdp_prog, act);
+ /* fallthrough -- handle aborts by dropping packet */
+ case XDP_DROP:
+ result = I40E_XDP_CONSUMED;
+ break;
+ }
+xdp_out:
+ rcu_read_unlock();
+ return ERR_PTR(-result);
+}
+
/**
* i40e_clean_rx_irq - Clean completed descriptors from Rx ring - bounce buf
* @rx_ring: rx descriptor ring to transact packets on
@@ -1970,6 +2033,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
u16 vlan_tag;
u8 rx_ptype;
u64 qword;
+ struct xdp_buff xdp;
/* return some buffers to hardware, one at a time is too slow */
if (cleaned_count >= I40E_RX_BUFFER_WRITE) {
@@ -2006,12 +2070,27 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
rx_buffer = i40e_get_rx_buffer(rx_ring, size);
/* retrieve a buffer from the ring */
- if (skb)
+ if (!skb) {
+ xdp.data = page_address(rx_buffer->page) +
+ rx_buffer->page_offset;
+ xdp.data_hard_start = xdp.data -
+ i40e_rx_offset(rx_ring);
+ xdp.data_end = xdp.data + size;
+
+ skb = i40e_run_xdp(rx_ring, &xdp);
+ }
+
+ if (IS_ERR(skb)) {
+ total_rx_bytes += size;
+ total_rx_packets++;
+ rx_buffer->pagecnt_bias++;
+ } else if (skb) {
i40e_add_rx_frag(rx_ring, rx_buffer, skb, size);
- else if (ring_uses_build_skb(rx_ring))
- skb = i40e_build_skb(rx_ring, rx_buffer, size);
- else
- skb = i40e_construct_skb(rx_ring, rx_buffer, size);
+ } else if (ring_uses_build_skb(rx_ring)) {
+ skb = i40e_build_skb(rx_ring, &xdp, rx_buffer);
+ } else {
+ skb = i40e_construct_skb(rx_ring, &xdp, rx_buffer);
+ }
/* exit if we failed to retrieve a buffer */
if (!skb) {
@@ -2026,18 +2105,7 @@ static int i40e_clean_rx_irq(struct i40e_ring *rx_ring, int budget)
if (i40e_is_non_eop(rx_ring, rx_desc, skb))
continue;
- /* ERR_MASK will only have valid bits if EOP set, and
- * what we are doing here is actually checking
- * I40E_RX_DESC_ERROR_RXE_SHIFT, since it is the zeroth bit in
- * the error field
- */
- if (unlikely(i40e_test_staterr(rx_desc, BIT(I40E_RXD_QW1_ERROR_SHIFT)))) {
- dev_kfree_skb_any(skb);
- skb = NULL;
- continue;
- }
-
- if (i40e_cleanup_headers(rx_ring, skb)) {
+ if (i40e_cleanup_headers(rx_ring, rx_desc, skb)) {
skb = NULL;
continue;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.h b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
index f5de51124cae..31f0b162996f 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.h
@@ -360,6 +360,7 @@ struct i40e_ring {
void *desc; /* Descriptor ring memory */
struct device *dev; /* Used for DMA mapping */
struct net_device *netdev; /* netdev ring maps to */
+ struct bpf_prog *xdp_prog;
union {
struct i40e_tx_buffer *tx_bi;
struct i40e_rx_buffer *rx_bi;
--
2.11.0
^ permalink raw reply related
* [Intel-wired-lan] [PATCH v5 0/2] i40e: support for XDP
From: =?unknown-8bit?q?Bj=C3=B6rn_T=C3=B6pel?= @ 2017-05-19 7:08 UTC (permalink / raw)
To: intel-wired-lan
From: Bj?rn T?pel <bjorn.topel@intel.com>
This series adds XDP support for i40e-based NICs.
The first patch wires up ndo_xdp and implements XDP_DROP semantics for
all actions. The second patch adds egress support via the XDP_TX
action.
Performance numbers (40GbE port, 64B packets) for xdp1 and xdp2
programs, from samples/bpf/:
IOMMU | xdp1 | xdp2
---------------------------+-----------+-----------
iommu=off | 29.7 Mpps | 17.1 Mpps
iommu=pt intel_iommu=on | 29.7 Mpps | 11.6 Mpps
iommu=on intel_iommu=on | 21.8 Mpps | 3.7 Mpps
Future improvements, not covered by the patches:
* Egress: Create the iova mappings upfront
(DMA_BIDIRECTIONAL/dma_sync_*), instead of creating a new iova
mapping in the transmit fast-path. This will improve performance
for the IOMMU-enabled case.
* Proper debugfs support.
* i40evf support.
Thanks to Alex, Daniel, John and Scott for all feedback!
v5:
* Aligned the implementation to ixgbe's XDP support: naming, favor
xchg instead of RCU semantics
* Support for XDP headroom (piggybacking on Alex' build_skb work)
* Added xdp tracepoints for exception states (as suggested by
Daniel)
v4:
* Removed unused i40e_page_is_reserved function
* Prior running the XDP program, set the struct xdp_buff
data_hard_start member
v3:
* Rebased patch set on Jeff's dev-queue branch
* MSI-X is no longer a prerequisite for XDP
* RCU locking for the XDP program and XDP_RX support is introduced
in the same patch
* Rx bytes is now bumped for XDP
* Removed pointer-to-pointer clunkiness
* Added comments to XDP preconditions in ndo_xdp
* When a non-EOF is received, log once, and drop the frame
v2:
* Fixed kbuild error for PAGE_SIZE >= 8192.
* Renamed i40e_try_flip_rx_page to i40e_can_reuse_rx_page, which is
more in line to the other Intel Ethernet drivers (igb/fm10k).
* Validate xdp_adjust_head support in ndo_xdp/XDP_SETUP_PROG.
Bj?rn T?pel (2):
i40e: add XDP support for pass and drop actions
i40e: add support for XDP_TX action
drivers/net/ethernet/intel/i40e/i40e.h | 8 +
drivers/net/ethernet/intel/i40e/i40e_ethtool.c | 57 +++++-
drivers/net/ethernet/intel/i40e/i40e_main.c | 270 ++++++++++++++++++++++---
drivers/net/ethernet/intel/i40e/i40e_txrx.c | 245 ++++++++++++++++++----
drivers/net/ethernet/intel/i40e/i40e_txrx.h | 12 ++
5 files changed, 530 insertions(+), 62 deletions(-)
--
2.11.0
^ permalink raw reply
* [Intel-wired-lan] [PATCH 2/5] ixgbe: add write flush when configuring CS4223/7
From: Bowers, AndrewX @ 2017-05-18 23:56 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221746.15538.89916.stgit@localhost6.localdomain6>
> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Emil Tantilov
> Sent: Wednesday, May 17, 2017 3:18 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 2/5] ixgbe: add write flush when
> configuring CS4223/7
>
> Make sure the writes are processed immediately. Without the flush it is
> possible for operations on one port to spill over the other as the resource is
> shared.
>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 20
> ++++++++++++++++++--
> 1 file changed, 18 insertions(+), 2 deletions(-)
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
^ permalink raw reply
* [Intel-wired-lan] [PATCH 1/5] ixgbe: correct CS4223/7 PHY identification
From: Bowers, AndrewX @ 2017-05-18 23:55 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221741.15538.227.stgit@localhost6.localdomain6>
> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Emil Tantilov
> Sent: Wednesday, May 17, 2017 3:18 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 1/5] ixgbe: correct CS4223/7 PHY
> identification
>
> Previous method was unreliable. Use a different register to diferentiate
> between the SKUs.
>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_phy.h | 5 +++--
> drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 8 ++++----
> 2 files changed, 7 insertions(+), 6 deletions(-)
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
^ permalink raw reply
* [Intel-wired-lan] [PATCH v2] ixgbe: fix incorrect status check
From: Emil Tantilov @ 2017-05-18 23:45 UTC (permalink / raw)
To: intel-wired-lan
Check for ret_val instead of !ret_val to allow the rest of
the code to execute and configure the speed properly.
v2 - fixed few more cases in ixgbe_setup_mac_link_sfp_n()
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
index cb5d363..c729ef0 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
@@ -1750,14 +1750,14 @@ static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
return 0;
- if (!ret_val)
+ if (ret_val)
return ret_val;
/* Configure internal PHY for native SFI based on module type */
ret_val = hw->mac.ops.read_iosf_sb_reg(hw,
IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
IXGBE_SB_IOSF_TARGET_KR_PHY, ®_phy_int);
- if (!ret_val)
+ if (ret_val)
return ret_val;
reg_phy_int &= IXGBE_KRM_PMD_FLX_MASK_ST20_SFI_10G_DA;
@@ -1767,7 +1767,7 @@ static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
ret_val = hw->mac.ops.write_iosf_sb_reg(hw,
IXGBE_KRM_PMD_FLX_MASK_ST20(hw->bus.lan_id),
IXGBE_SB_IOSF_TARGET_KR_PHY, reg_phy_int);
- if (!ret_val)
+ if (ret_val)
return ret_val;
/* Setup SFI internal link. */
@@ -1798,7 +1798,7 @@ static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
return 0;
- if (!ret_val)
+ if (ret_val)
return ret_val;
/* Configure internal PHY for KR/KX. */
^ permalink raw reply related
* [Intel-wired-lan] [PATCH 5/5] ixgbe: fix incorrect status check
From: Bowers, AndrewX @ 2017-05-18 22:40 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221801.15538.81934.stgit@localhost6.localdomain6>
> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Emil Tantilov
> Sent: Wednesday, May 17, 2017 3:18 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 5/5] ixgbe: fix incorrect status check
>
> Check for ret_val instead of !ret_val to allow the rest of the code to execute
> and configure the speed properly.
>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
^ permalink raw reply
* [Intel-wired-lan] [PATCH 4/5] ixgbe: add missing configuration for rate select 1
From: Bowers, AndrewX @ 2017-05-18 22:39 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221756.15538.27845.stgit@localhost6.localdomain6>
> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Emil Tantilov
> Sent: Wednesday, May 17, 2017 3:18 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 4/5] ixgbe: add missing configuration for
> rate select 1
>
> Add RS1 configuration to ixgbe_set_soft_rate_select_speed()
>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 19
> +++++++++++++++++++
> 1 file changed, 19 insertions(+)
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
^ permalink raw reply
* [Intel-wired-lan] [PATCH 3/5] ixgbe: always call setup_mac_link for multispeed fiber
From: Bowers, AndrewX @ 2017-05-18 22:39 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221751.15538.97694.stgit@localhost6.localdomain6>
> -----Original Message-----
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On
> Behalf Of Emil Tantilov
> Sent: Wednesday, May 17, 2017 3:18 PM
> To: intel-wired-lan at lists.osuosl.org
> Subject: [Intel-wired-lan] [PATCH 3/5] ixgbe: always call setup_mac_link for
> multispeed fiber
>
> Remove the logic which would previously skip the link configuration in the
> case where we are already at the requested speed in
> ixgbe_setup_mac_link_multispeed_fiber().
>
> By exiting early we are skipping the link configuration and as such the driver
> may not always configure the PHY correctly for SFP+.
>
> Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 18 ------------------
> 1 file changed, 18 deletions(-)
Tested-by: Andrew Bowers <andrewx.bowers@intel.com>
^ permalink raw reply
* [Intel-wired-lan] [net-intel-e1000e] question about value overwrite
From: Gustavo A. R. Silva @ 2017-05-18 22:22 UTC (permalink / raw)
To: intel-wired-lan
Hello everybody,
While looking into Coverity ID 1226905 I ran into the following piece
of code at drivers/net/ethernet/intel/e1000e/ich8lan.c:2400
2400/**
2401 * e1000_hv_phy_workarounds_ich8lan - A series of Phy workarounds to be
2402 * done after every PHY reset.
2403 **/
2404static s32 e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
2405{
2406 s32 ret_val = 0;
2407 u16 phy_data;
2408
2409 if (hw->mac.type != e1000_pchlan)
2410 return 0;
2411
2412 /* Set MDIO slow mode before any other MDIO access */
2413 if (hw->phy.type == e1000_phy_82577) {
2414 ret_val = e1000_set_mdio_slow_mode_hv(hw);
2415 if (ret_val)
2416 return ret_val;
2417 }
2418
2419 if (((hw->phy.type == e1000_phy_82577) &&
2420 ((hw->phy.revision == 1) || (hw->phy.revision == 2))) ||
2421 ((hw->phy.type == e1000_phy_82578) &&
(hw->phy.revision == 1))) {
2422 /* Disable generation of early preamble */
2423 ret_val = e1e_wphy(hw, PHY_REG(769, 25), 0x4431);
2424 if (ret_val)
2425 return ret_val;
2426
2427 /* Preamble tuning for SSC */
2428 ret_val = e1e_wphy(hw, HV_KMRN_FIFO_CTRLSTA, 0xA204);
2429 if (ret_val)
2430 return ret_val;
2431 }
2432
2433 if (hw->phy.type == e1000_phy_82578) {
2434 /* Return registers to default by doing a soft reset then
2435 * writing 0x3140 to the control register.
2436 */
2437 if (hw->phy.revision < 2) {
2438 e1000e_phy_sw_reset(hw);
2439 ret_val = e1e_wphy(hw, MII_BMCR, 0x3140);
2440 }
2441 }
2442
2443 /* Select page 0 */
2444 ret_val = hw->phy.ops.acquire(hw);
2445 if (ret_val)
2446 return ret_val;
2447
2448 hw->phy.addr = 1;
2449 ret_val = e1000e_write_phy_reg_mdic(hw,
IGP01E1000_PHY_PAGE_SELECT, 0);
2450 hw->phy.ops.release(hw);
2451 if (ret_val)
2452 return ret_val;
2453
2454 /* Configure the K1 Si workaround during phy reset
assuming there is
2455 * link so that it disables K1 if link is in 1Gbps.
2456 */
2457 ret_val = e1000_k1_gig_workaround_hv(hw, true);
2458 if (ret_val)
2459 return ret_val;
2460
2461 /* Workaround for link disconnects on a busy hub in half duplex */
2462 ret_val = hw->phy.ops.acquire(hw);
2463 if (ret_val)
2464 return ret_val;
2465 ret_val = e1e_rphy_locked(hw, BM_PORT_GEN_CFG, &phy_data);
2466 if (ret_val)
2467 goto release;
2468 ret_val = e1e_wphy_locked(hw, BM_PORT_GEN_CFG, phy_data & 0x00FF);
2469 if (ret_val)
2470 goto release;
2471
2472 /* set MSE higher to enable link to stay up when noise is high */
2473 ret_val = e1000_write_emi_reg_locked(hw,
I82577_MSE_THRESHOLD, 0x0034);
2474release:
2475 hw->phy.ops.release(hw);
2476
2477 return ret_val;
2478}
The issue is that the value stored in variable _ret_val_ at line 2439
is overwritten by the one stored at line 2444, before it can be used.
My question is if the original intention was to return this value
immediately after the assignment at line 2439, something like in the
following patch:
index 68ea8b4..d6d4ed7 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -2437,6 +2437,8 @@ static s32
e1000_hv_phy_workarounds_ich8lan(struct e1000_hw *hw)
if (hw->phy.revision < 2) {
e1000e_phy_sw_reset(hw);
ret_val = e1e_wphy(hw, MII_BMCR, 0x3140);
+ if (ret_val)
+ return ret_val;
}
}
What do you think?
I'd really appreciate any comment on this.
Thank you!
--
Gustavo A. R. Silva
^ permalink raw reply related
* [Intel-wired-lan] [PATCH 2/2] ixgbevf: Bump version number
From: Tony Nguyen @ 2017-05-18 21:55 UTC (permalink / raw)
To: intel-wired-lan
Update ixgbevf version number.
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index aced91c..084c535 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -57,7 +57,7 @@ const char ixgbevf_driver_name[] = "ixgbevf";
static const char ixgbevf_driver_string[] =
"Intel(R) 10 Gigabit PCI Express Virtual Function Network Driver";
-#define DRV_VERSION "3.2.2-k"
+#define DRV_VERSION "4.1.0-k"
const char ixgbevf_driver_version[] = DRV_VERSION;
static char ixgbevf_copyright[] =
"Copyright (c) 2009 - 2015 Intel Corporation.";
--
2.9.3
^ permalink raw reply related
* [Intel-wired-lan] [PATCH 1/2] ixgbe: Bump version number
From: Tony Nguyen @ 2017-05-18 21:55 UTC (permalink / raw)
To: intel-wired-lan
Update ixgbe version number.
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index 8a8535d..3cf8fac 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -76,7 +76,7 @@ char ixgbe_default_device_descr[] =
static char ixgbe_default_device_descr[] =
"Intel(R) 10 Gigabit Network Connection";
#endif
-#define DRV_VERSION "5.0.0-k"
+#define DRV_VERSION "5.1.0-k"
const char ixgbe_driver_version[] = DRV_VERSION;
static const char ixgbe_copyright[] =
"Copyright (c) 1999-2016 Intel Corporation.";
--
2.9.3
^ permalink raw reply related
* [Intel-wired-lan] [PATCH] i40evf: Use le32_to_cpu before evaluating HW desc fields.
From: tndave @ 2017-05-18 18:05 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <1494976037.40313.1.camel@intel.com>
On 05/16/2017 04:07 PM, Jeff Kirsher wrote:
> On Mon, 2017-05-01 at 16:15 -0700, Tushar Dave wrote:
>> i40e hardware descriptor fields are in little-endian format. Driver
>> must use le32_to_cpu while evaluating these fields otherwise on
>> big-endian arch we end up evaluating incorrect values, cause errors
>> like:
>>
>> i40evf 0001:04:02.0: Expected response 0 from PF, received 285212672
>> i40evf 0001:04:02.1: Expected response 0 from PF, received 285212672
>>
>> Signed-off-by: Tushar Dave <tushar.n.dave@oracle.com>
>> ---
>> drivers/net/ethernet/intel/i40evf/i40evf_main.c | 6 ++++--
>> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> Due to recent patches already applied to my tree, this patch does not
> apply cleanly. Feel free to send an updated patch, if the change is
> still needed.
Okay. I will send v2.
Thanks.
-Tushar
>
^ permalink raw reply
* [Intel-wired-lan] [net-intel-i40e] question about assignment overwrite
From: Gustavo A. R. Silva @ 2017-05-18 17:44 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <1495086551.46489.1.camel@intel.com>
Hi Jeff,
Quoting Jeff Kirsher <jeffrey.t.kirsher@intel.com>:
> On Wed, 2017-05-17 at 15:48 -0500, Gustavo A. R. Silva wrote:
>> While looking into Coverity ID 1408956 I ran into the following
>> piece??
>> of code at drivers/net/ethernet/intel/i40e/i40e_main.c:8807:
>>
>> 8807??????? if (pf->hw.mac.type == I40E_MAC_X722) {
>> 8808??????????????? pf->flags |= I40E_FLAG_RSS_AQ_CAPABLE
>> 8809???????????????????????????? | I40E_FLAG_128_QP_RSS_CAPABLE
>> 8810???????????????????????????? | I40E_FLAG_HW_ATR_EVICT_CAPABLE
>> 8811???????????????????????????? | I40E_FLAG_OUTER_UDP_CSUM_CAPABLE
>> 8812???????????????????????????? | I40E_FLAG_WB_ON_ITR_CAPABLE
>> 8813???????????????????????????? |
>> I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE
>> 8814???????????????????????????? | I40E_FLAG_NO_PCI_LINK_CHECK
>> 8815???????????????????????????? | I40E_FLAG_USE_SET_LLDP_MIB
>> 8816???????????????????????????? | I40E_FLAG_GENEVE_OFFLOAD_CAPABLE
>> 8817???????????????????????????? | I40E_FLAG_PTP_L4_CAPABLE
>> 8818???????????????????????????? | I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE;
>> 8819??????? } else if ((pf->hw.aq.api_maj_ver > 1) ||
>> 8820?????????????????? ((pf->hw.aq.api_maj_ver == 1) &&
>> 8821??????????????????? (pf->hw.aq.api_min_ver > 4))) {
>> 8822??????????????? /* Supported in FW API version higher than 1.4 */
>> 8823??????????????? pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
>> 8824??????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
>> 8825??????? } else {
>> 8826??????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
>> 8827??????? }
>>
>> The issue here is that the assignment at line 8823 is overwritten
>> by??
>> the code at line 8824.
>>
>> I'm suspicious that line 8824 should be remove and a patch like the??
>> following can be applied:
>>
>> index d5c9c9e..48ffa73 100644
>> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
>> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
>> @@ -8821,7 +8821,6 @@ static int i40e_sw_init(struct i40e_pf *pf)
>> ???????????????????? (pf->hw.aq.api_min_ver > 4))) {
>> ???????????????? /* Supported in FW API version higher than 1.4 */
>> ???????????????? pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
>> -?????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
>> ???????? } else {
>> ???????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
>> ???????? }
>>
>> What do you think?
>
> This issue is already fixed in my dev-queue branch on my next-queue
> tree.
Great, it's good to know.
Thanks!
--
Gustavo A. R. Silva
^ permalink raw reply
* [Intel-wired-lan] [jkirsher-net-queue:dev-queue] BUILD SUCCESS 561818887441c045d366caa5ba41a99401eb4e4f
From: kbuild test robot @ 2017-05-18 16:27 UTC (permalink / raw)
To: intel-wired-lan
https://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/net-queue.git dev-queue
561818887441c045d366caa5ba41a99401eb4e4f i40e/i40evf: proper update of the page_offset field
elapsed time: 252m
configs tested: 123
The following configs have been built successfully.
More configs may be tested in the coming days.
cris etrax-100lx_v2_defconfig
blackfin TCM-BF537_defconfig
blackfin BF561-EZKIT-SMP_defconfig
blackfin BF533-EZKIT_defconfig
blackfin BF526-EZBRD_defconfig
i386 tinyconfig
sh titan_defconfig
sh rsk7269_defconfig
sh sh7785lcr_32bit_defconfig
sh allnoconfig
x86_64 allmodconfig
parisc c3000_defconfig
parisc b180_defconfig
parisc defconfig
alpha defconfig
parisc allnoconfig
x86_64 randconfig-x019-201720
x86_64 randconfig-x010-201720
x86_64 randconfig-x015-201720
x86_64 randconfig-x014-201720
x86_64 randconfig-x012-201720
x86_64 randconfig-x018-201720
x86_64 randconfig-x017-201720
x86_64 randconfig-x016-201720
x86_64 randconfig-x013-201720
x86_64 randconfig-x011-201720
i386 randconfig-a0-05181312
mn10300 asb2364_defconfig
openrisc or1ksim_defconfig
um x86_64_defconfig
um i386_defconfig
frv defconfig
tile tilegx_defconfig
x86_64 nfsroot+CONFIG_DEBUG_INFO_REDUCED
x86_64 acpi-redef
x86_64 allyesdebian
x86_64 nfsroot
i386 allnoconfig
i386 defconfig
i386 alldefconfig
mips jz4740
mips malta_kvm_defconfig
mips 64r6el_defconfig
mips 32r2_defconfig
mips allnoconfig
mips fuloong2e_defconfig
mips txx9
powerpc defconfig
s390 default_defconfig
powerpc ppc64_defconfig
powerpc allnoconfig
x86_64 randconfig-i0-201720
i386 randconfig-x016-201720
i386 randconfig-x017-201720
i386 randconfig-x012-201720
i386 randconfig-x018-201720
i386 randconfig-x010-201720
i386 randconfig-x019-201720
i386 randconfig-x013-201720
i386 randconfig-x014-201720
i386 randconfig-x015-201720
i386 randconfig-x011-201720
i386 allmodconfig
arm at91_dt_defconfig
arm allnoconfig
arm efm32_defconfig
arm64 defconfig
arm multi_v5_defconfig
arm sunxi_defconfig
arm64 allnoconfig
arm exynos_defconfig
arm shmobile_defconfig
arm multi_v7_defconfig
m68k sun3_defconfig
m68k multi_defconfig
m68k m5475evb_defconfig
sparc defconfig
sparc64 allnoconfig
sparc64 defconfig
c6x evmc6678_defconfig
xtensa common_defconfig
m32r m32104ut_defconfig
xtensa iss_defconfig
m32r opsput_defconfig
m32r usrv_defconfig
m32r mappi3.smp_defconfig
nios2 10m50_defconfig
h8300 h8300h-sim_defconfig
x86_64 randconfig-x008-05181530
x86_64 randconfig-x002-05181530
x86_64 randconfig-x007-05181530
x86_64 randconfig-x004-05181530
x86_64 randconfig-x005-05181530
x86_64 randconfig-x006-05181530
x86_64 randconfig-x009-05181530
x86_64 randconfig-x000-05181530
x86_64 randconfig-x001-05181530
x86_64 randconfig-x003-05181530
x86_64 kexec
x86_64 rhel
i386 randconfig-x074-05150639
i386 randconfig-x076-05150639
i386 randconfig-x070-05150639
i386 randconfig-x077-05150639
i386 randconfig-x078-05150639
i386 randconfig-x075-05150639
i386 randconfig-x072-05150639
i386 randconfig-x071-05150639
i386 randconfig-x079-05150639
i386 randconfig-x073-05150639
ia64 allnoconfig
ia64 defconfig
ia64 alldefconfig
i386 randconfig-x002-201720
i386 randconfig-x006-201720
i386 randconfig-x009-201720
i386 randconfig-x008-201720
i386 randconfig-x001-201720
i386 randconfig-x000-201720
i386 randconfig-x005-201720
i386 randconfig-x007-201720
i386 randconfig-x004-201720
i386 randconfig-x003-201720
Thanks,
Fengguang
^ permalink raw reply
* [Intel-wired-lan] [PATCH v2] e1000e: Don't return uninitialized stats
From: David Miller @ 2017-05-18 14:46 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517202413.18321-1-bpoirier@suse.com>
From: Benjamin Poirier <bpoirier@suse.com>
Date: Wed, 17 May 2017 16:24:13 -0400
> Some statistics passed to ethtool are garbage because e1000e_get_stats64()
> doesn't write them, for example: tx_heartbeat_errors. This leaks kernel
> memory to userspace and confuses users.
>
> Do like ixgbe and use dev_get_stats() which first zeroes out
> rtnl_link_stats64.
>
> Fixes: 5944701df90d ("net: remove useless memset's in drivers get_stats64")
> Reported-by: Stefan Priebe <s.priebe@profihost.ag>
> Signed-off-by: Benjamin Poirier <bpoirier@suse.com>
Jeff, please be sure to pick this up, thanks.
^ permalink raw reply
* [Intel-wired-lan] [jkirsher-next-queue:dev-queue] BUILD SUCCESS 7cc52a4bf18c481e931182884fe8ac9aed983c40
From: kbuild test robot @ 2017-05-18 11:35 UTC (permalink / raw)
To: intel-wired-lan
https://git.kernel.org/pub/scm/linux/kernel/git/jkirsher/next-queue.git dev-queue
7cc52a4bf18c481e931182884fe8ac9aed983c40 ixgbe: fix incorrect status check
elapsed time: 379m
configs tested: 112
The following configs have been built successfully.
More configs may be tested in the coming days.
powerpc defconfig
s390 default_defconfig
powerpc ppc64_defconfig
powerpc allnoconfig
i386 randconfig-a0-05181312
cris etrax-100lx_v2_defconfig
blackfin TCM-BF537_defconfig
blackfin BF561-EZKIT-SMP_defconfig
blackfin BF533-EZKIT_defconfig
blackfin BF526-EZBRD_defconfig
i386 allmodconfig
x86_64 randconfig-x019-201720
x86_64 randconfig-x010-201720
x86_64 randconfig-x015-201720
x86_64 randconfig-x014-201720
x86_64 randconfig-x012-201720
x86_64 randconfig-x018-201720
x86_64 randconfig-x017-201720
x86_64 randconfig-x016-201720
x86_64 randconfig-x013-201720
x86_64 randconfig-x011-201720
i386 tinyconfig
sparc defconfig
sparc64 allnoconfig
sparc64 defconfig
i386 randconfig-x016-201720
i386 randconfig-x017-201720
i386 randconfig-x012-201720
i386 randconfig-x018-201720
i386 randconfig-x010-201720
i386 randconfig-x019-201720
i386 randconfig-x013-201720
i386 randconfig-x014-201720
i386 randconfig-x015-201720
i386 randconfig-x011-201720
arm at91_dt_defconfig
arm allnoconfig
arm efm32_defconfig
arm64 defconfig
arm multi_v5_defconfig
arm sunxi_defconfig
arm64 allnoconfig
arm exynos_defconfig
arm shmobile_defconfig
arm multi_v7_defconfig
m68k sun3_defconfig
m68k multi_defconfig
m68k m5475evb_defconfig
sh titan_defconfig
sh rsk7269_defconfig
sh sh7785lcr_32bit_defconfig
sh allnoconfig
x86_64 allmodconfig
parisc c3000_defconfig
parisc b180_defconfig
parisc defconfig
alpha defconfig
parisc allnoconfig
mn10300 asb2364_defconfig
openrisc or1ksim_defconfig
um x86_64_defconfig
um i386_defconfig
frv defconfig
tile tilegx_defconfig
x86_64 acpi-redef
x86_64 allyesdebian+CONFIG_DEBUG_INFO_REDUCED
x86_64 allyesdebian
x86_64 nfsroot
c6x evmc6678_defconfig
xtensa common_defconfig
m32r m32104ut_defconfig
xtensa iss_defconfig
m32r opsput_defconfig
m32r usrv_defconfig
m32r mappi3.smp_defconfig
nios2 10m50_defconfig
h8300 h8300h-sim_defconfig
i386 randconfig-x074-05150639
i386 randconfig-x076-05150639
i386 randconfig-x070-05150639
i386 randconfig-x077-05150639
i386 randconfig-x078-05150639
i386 randconfig-x075-05150639
i386 randconfig-x072-05150639
i386 randconfig-x071-05150639
i386 randconfig-x079-05150639
i386 randconfig-x073-05150639
i386 allnoconfig
i386 defconfig
i386 alldefconfig
ia64 allnoconfig
ia64 defconfig
ia64 alldefconfig
x86_64 randconfig-x006-201720
x86_64 randconfig-x007-201720
x86_64 randconfig-x001-201720
x86_64 randconfig-x004-201720
x86_64 randconfig-x005-201720
x86_64 randconfig-x000-201720
x86_64 randconfig-x008-201720
x86_64 randconfig-x002-201720
x86_64 randconfig-x003-201720
x86_64 randconfig-x009-201720
x86_64 kexec
x86_64 rhel
mips jz4740
mips malta_kvm_defconfig
mips 64r6el_defconfig
mips 32r2_defconfig
mips allnoconfig
mips fuloong2e_defconfig
mips txx9
Thanks,
Fengguang
^ permalink raw reply
* [Intel-wired-lan] [net-intel-i40e] question about assignment overwrite
From: Jeff Kirsher @ 2017-05-18 5:49 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517154858.Horde.xMvsIEhHNSGu52mfyp7HA3R@gator4166.hostgator.com>
On Wed, 2017-05-17 at 15:48 -0500, Gustavo A. R. Silva wrote:
> While looking into Coverity ID 1408956 I ran into the following
> piece??
> of code at drivers/net/ethernet/intel/i40e/i40e_main.c:8807:
>
> 8807??????? if (pf->hw.mac.type == I40E_MAC_X722) {
> 8808??????????????? pf->flags |= I40E_FLAG_RSS_AQ_CAPABLE
> 8809???????????????????????????? | I40E_FLAG_128_QP_RSS_CAPABLE
> 8810???????????????????????????? | I40E_FLAG_HW_ATR_EVICT_CAPABLE
> 8811???????????????????????????? | I40E_FLAG_OUTER_UDP_CSUM_CAPABLE
> 8812???????????????????????????? | I40E_FLAG_WB_ON_ITR_CAPABLE
> 8813???????????????????????????? |
> I40E_FLAG_MULTIPLE_TCP_UDP_RSS_PCTYPE
> 8814???????????????????????????? | I40E_FLAG_NO_PCI_LINK_CHECK
> 8815???????????????????????????? | I40E_FLAG_USE_SET_LLDP_MIB
> 8816???????????????????????????? | I40E_FLAG_GENEVE_OFFLOAD_CAPABLE
> 8817???????????????????????????? | I40E_FLAG_PTP_L4_CAPABLE
> 8818???????????????????????????? | I40E_FLAG_WOL_MC_MAGIC_PKT_WAKE;
> 8819??????? } else if ((pf->hw.aq.api_maj_ver > 1) ||
> 8820?????????????????? ((pf->hw.aq.api_maj_ver == 1) &&
> 8821??????????????????? (pf->hw.aq.api_min_ver > 4))) {
> 8822??????????????? /* Supported in FW API version higher than 1.4 */
> 8823??????????????? pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
> 8824??????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
> 8825??????? } else {
> 8826??????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
> 8827??????? }
>
> The issue here is that the assignment at line 8823 is overwritten
> by??
> the code at line 8824.
>
> I'm suspicious that line 8824 should be remove and a patch like the??
> following can be applied:
>
> index d5c9c9e..48ffa73 100644
> --- a/drivers/net/ethernet/intel/i40e/i40e_main.c
> +++ b/drivers/net/ethernet/intel/i40e/i40e_main.c
> @@ -8821,7 +8821,6 @@ static int i40e_sw_init(struct i40e_pf *pf)
> ???????????????????? (pf->hw.aq.api_min_ver > 4))) {
> ???????????????? /* Supported in FW API version higher than 1.4 */
> ???????????????? pf->flags |= I40E_FLAG_GENEVE_OFFLOAD_CAPABLE;
> -?????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
> ???????? } else {
> ???????????????? pf->flags = I40E_FLAG_HW_ATR_EVICT_CAPABLE;
> ???????? }
>
> What do you think?
This issue is already fixed in my dev-queue branch on my next-queue
tree.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: This is a digitally signed message part
URL: <http://lists.osuosl.org/pipermail/intel-wired-lan/attachments/20170517/9e80a5f1/attachment.asc>
^ permalink raw reply
* [Intel-wired-lan] [next-queue v2] igb: Remove useless argument
From: Brown, Aaron F @ 2017-05-18 2:33 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170516225516.65557-1-jeffrey.t.kirsher@intel.com>
> From: Intel-wired-lan [mailto:intel-wired-lan-bounces at osuosl.org] On Behalf
> Of Jeff Kirsher
> Sent: Tuesday, May 16, 2017 3:55 PM
> To: intel-wired-lan at lists.osuosl.org
> Cc: Benjamin Poirier <bpoirier@suse.com>
> Subject: [Intel-wired-lan] [next-queue v2] igb: Remove useless argument
>
> From: Benjamin Poirier <bpoirier@suse.com>
>
> Given that all callers of igb_update_stats() pass the same two arguments:
> (adapter, &adapter->stats64), the second argument can be removed.
>
> Signed-off-by: Benjamin Poirier <bpoirier@suse.com>
> ---
> drivers/net/ethernet/intel/igb/igb.h | 2 +-
> drivers/net/ethernet/intel/igb/igb_ethtool.c | 2 +-
> drivers/net/ethernet/intel/igb/igb_main.c | 10 +++++-----
> 3 files changed, 7 insertions(+), 7 deletions(-)
>
I'm getting a warning from checkpatch with this:
------------------------------------------------------------
WARNING: function definition argument 'struct igb_adapter *' should also have an identifier name
#25: FILE: drivers/net/ethernet/intel/igb/igb.h:670:
+void igb_update_stats(struct igb_adapter *);
total: 0 errors, 1 warnings, 0 checks, 51 lines checked
NOTE: For some of the reported defects, checkpatch may be able to
mechanically convert to the typical style using --fix or --fix-inplace.
Your patch has style problems, please review.
NOTE: If any of the errors are false positives, please report
them to the maintainer, see CHECKPATCH in MAINTAINERS.
u1515:[2]/usr/src/kernels/next-queue>
------------------------------------------------------------
But it otherwise seems fine so I'm not inclined to hold it up for that.
Tested-by: Aaron Brown <aaron.f.brown@intel.com>
^ permalink raw reply
* [Intel-wired-lan] [PATCH 5/5] ixgbe: fix incorrect status check
From: Emil Tantilov @ 2017-05-17 22:18 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221424.15538.5968.stgit@localhost6.localdomain6>
Check for ret_val instead of !ret_val to allow the rest of
the code to execute and configure the speed properly.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
index cb5d363..47c8f24 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
@@ -1798,7 +1798,7 @@ static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
if (ret_val == IXGBE_ERR_SFP_NOT_PRESENT)
return 0;
- if (!ret_val)
+ if (ret_val)
return ret_val;
/* Configure internal PHY for KR/KX. */
^ permalink raw reply related
* [Intel-wired-lan] [PATCH 4/5] ixgbe: add missing configuration for rate select 1
From: Emil Tantilov @ 2017-05-17 22:17 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221424.15538.5968.stgit@localhost6.localdomain6>
Add RS1 configuration to ixgbe_set_soft_rate_select_speed()
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 8a2e8bf8..9b8e594 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -4278,4 +4278,23 @@ void ixgbe_set_soft_rate_select_speed(struct ixgbe_hw *hw,
hw_dbg(hw, "Failed to write Rx Rate Select RS0\n");
return;
}
+
+ /* Set RS1 */
+ status = hw->phy.ops.read_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ &eeprom_data);
+ if (status) {
+ hw_dbg(hw, "Failed to read Rx Rate Select RS1\n");
+ return;
+ }
+
+ eeprom_data = (eeprom_data & ~IXGBE_SFF_SOFT_RS_SELECT_MASK) | rs;
+
+ status = hw->phy.ops.write_i2c_byte(hw, IXGBE_SFF_SFF_8472_ESCB,
+ IXGBE_I2C_EEPROM_DEV_ADDR2,
+ eeprom_data);
+ if (status) {
+ hw_dbg(hw, "Failed to write Rx Rate Select RS1\n");
+ return;
+ }
}
^ permalink raw reply related
* [Intel-wired-lan] [PATCH 3/5] ixgbe: always call setup_mac_link for multispeed fiber
From: Emil Tantilov @ 2017-05-17 22:17 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221424.15538.5968.stgit@localhost6.localdomain6>
Remove the logic which would previously skip the link configuration
in the case where we are already at the requested speed in
ixgbe_setup_mac_link_multispeed_fiber().
By exiting early we are skipping the link configuration and as such
the driver may not always configure the PHY correctly for SFP+.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_common.c | 18 ------------------
1 file changed, 18 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 3af6127..8a2e8bf8 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -4121,15 +4121,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
speedcnt++;
highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
- /* If we already have link at this speed, just jump out */
- status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
- false);
- if (status)
- return status;
-
- if (link_speed == IXGBE_LINK_SPEED_10GB_FULL && link_up)
- goto out;
-
/* Set the module link speed */
switch (hw->phy.media_type) {
case ixgbe_media_type_fiber:
@@ -4181,15 +4172,6 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
if (highest_link_speed == IXGBE_LINK_SPEED_UNKNOWN)
highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
- /* If we already have link at this speed, just jump out */
- status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
- false);
- if (status)
- return status;
-
- if (link_speed == IXGBE_LINK_SPEED_1GB_FULL && link_up)
- goto out;
-
/* Set the module link speed */
switch (hw->phy.media_type) {
case ixgbe_media_type_fiber:
^ permalink raw reply related
* [Intel-wired-lan] [PATCH 2/5] ixgbe: add write flush when configuring CS4223/7
From: Emil Tantilov @ 2017-05-17 22:17 UTC (permalink / raw)
To: intel-wired-lan
In-Reply-To: <20170517221424.15538.5968.stgit@localhost6.localdomain6>
Make sure the writes are processed immediately. Without the flush it
is possible for operations on one port to spill over the other as the
resource is shared.
Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
---
drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c | 20 ++++++++++++++++++--
1 file changed, 18 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
index 870f9e1..cb5d363 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_x550.c
@@ -1824,12 +1824,28 @@ static s32 ixgbe_setup_sfi_x550a(struct ixgbe_hw *hw, ixgbe_link_speed *speed)
/* Configure CS4227/CS4223 LINE side to proper mode. */
reg_slice = IXGBE_CS4227_LINE_SPARE24_LSB + slice_offset;
+
+ ret_val = hw->phy.ops.read_reg(hw, reg_slice,
+ IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
+ if (ret_val)
+ return ret_val;
+
+ reg_phy_ext &= ~((IXGBE_CS4227_EDC_MODE_CX1 << 1) |
+ (IXGBE_CS4227_EDC_MODE_SR << 1));
+
if (setup_linear)
reg_phy_ext = (IXGBE_CS4227_EDC_MODE_CX1 << 1) | 1;
else
reg_phy_ext = (IXGBE_CS4227_EDC_MODE_SR << 1) | 1;
- return hw->phy.ops.write_reg(hw, reg_slice, IXGBE_MDIO_ZERO_DEV_TYPE,
- reg_phy_ext);
+
+ ret_val = hw->phy.ops.write_reg(hw, reg_slice,
+ IXGBE_MDIO_ZERO_DEV_TYPE, reg_phy_ext);
+ if (ret_val)
+ return ret_val;
+
+ /* Flush previous write with a read */
+ return hw->phy.ops.read_reg(hw, reg_slice,
+ IXGBE_MDIO_ZERO_DEV_TYPE, ®_phy_ext);
}
/**
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox