All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop
@ 2017-10-11 13:29 Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 2/9] staging: fsl-dpaa2/eth: Account for Rx FD buffers on error path Ioana Radulescu
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

We incorrectly assumed that dpaa2_io_release() can only
return -EBUSY as an error code, when in fact it can also
fail in case some of its arguments don't have valid values.

Make sure we only retry the operation while the portal is
busy and abort for all other error cases, otherwise we risk
entering an endless loop.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 58 ++++++++++++++++----------
 1 file changed, 35 insertions(+), 23 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index 26017fe..801ba07 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -718,6 +718,23 @@ static int set_tx_csum(struct dpaa2_eth_priv *priv, bool enable)
 	return 0;
 }
 
+/* Free buffers acquired from the buffer pool or which were meant to
+ * be released in the pool
+ */
+static void free_bufs(struct dpaa2_eth_priv *priv, u64 *buf_array, int count)
+{
+	struct device *dev = priv->net_dev->dev.parent;
+	void *vaddr;
+	int i;
+
+	for (i = 0; i < count; i++) {
+		vaddr = dpaa2_iova_to_virt(priv->iommu_domain, buf_array[i]);
+		dma_unmap_single(dev, buf_array[i], DPAA2_ETH_RX_BUF_SIZE,
+				 DMA_BIDIRECTIONAL);
+		skb_free_frag(vaddr);
+	}
+}
+
 /* Perform a single release command to add buffers
  * to the specified buffer pool
  */
@@ -727,7 +744,7 @@ static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid)
 	u64 buf_array[DPAA2_ETH_BUFS_PER_CMD];
 	void *buf;
 	dma_addr_t addr;
-	int i;
+	int i, err;
 
 	for (i = 0; i < DPAA2_ETH_BUFS_PER_CMD; i++) {
 		/* Allocate buffer visible to WRIOP + skb shared info +
@@ -754,22 +771,27 @@ static int add_bufs(struct dpaa2_eth_priv *priv, u16 bpid)
 	}
 
 release_bufs:
-	/* In case the portal is busy, retry until successful.
-	 * The buffer release function would only fail if the QBMan portal
-	 * was busy, which implies portal contention (i.e. more CPUs than
-	 * portals, i.e. GPPs w/o affine DPIOs). For all practical purposes,
-	 * there is little we can realistically do, short of giving up -
-	 * in which case we'd risk depleting the buffer pool and never again
-	 * receiving the Rx interrupt which would kick-start the refill logic.
-	 * So just keep retrying, at the risk of being moved to ksoftirqd.
-	 */
-	while (dpaa2_io_service_release(NULL, bpid, buf_array, i))
+	/* In case the portal is busy, retry until successful */
+	while ((err = dpaa2_io_service_release(NULL, bpid,
+					       buf_array, i)) == -EBUSY)
 		cpu_relax();
+
+	/* If release command failed, clean up and bail out;
+	 * not much else we can do about it
+	 */
+	if (err) {
+		free_bufs(priv, buf_array, i);
+		return 0;
+	}
+
 	return i;
 
 err_map:
 	skb_free_frag(buf);
 err_alloc:
+	/* If we managed to allocate at least some buffers,
+	 * release them to hardware
+	 */
 	if (i)
 		goto release_bufs;
 
@@ -811,10 +833,8 @@ static int seed_pool(struct dpaa2_eth_priv *priv, u16 bpid)
  */
 static void drain_bufs(struct dpaa2_eth_priv *priv, int count)
 {
-	struct device *dev = priv->net_dev->dev.parent;
 	u64 buf_array[DPAA2_ETH_BUFS_PER_CMD];
-	void *vaddr;
-	int ret, i;
+	int ret;
 
 	do {
 		ret = dpaa2_io_service_acquire(NULL, priv->bpid,
@@ -823,15 +843,7 @@ static void drain_bufs(struct dpaa2_eth_priv *priv, int count)
 			netdev_err(priv->net_dev, "dpaa2_io_service_acquire() failed\n");
 			return;
 		}
-		for (i = 0; i < ret; i++) {
-			/* Same logic as on regular Rx path */
-			vaddr = dpaa2_iova_to_virt(priv->iommu_domain,
-						   buf_array[i]);
-			dma_unmap_single(dev, buf_array[i],
-					 DPAA2_ETH_RX_BUF_SIZE,
-					 DMA_FROM_DEVICE);
-			skb_free_frag(vaddr);
-		}
+		free_bufs(priv, buf_array, ret);
 	} while (ret);
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/9] staging: fsl-dpaa2/eth: Account for Rx FD buffers on error path
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 3/9] staging: fsl-dpaa2/eth: Check SGT final bit is present Ioana Radulescu
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

On Rx path, if we fail to build an skb from the incoming FD,
we still need to update the channel buffer count accordingly,
otherwise we risk depleting the pool while the software counter
still sees available buffers.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 15 +++++++++++----
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index 801ba07..e9fe1c9 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -131,6 +131,8 @@ static struct sk_buff *build_linear_skb(struct dpaa2_eth_priv *priv,
 	u16 fd_offset = dpaa2_fd_get_offset(fd);
 	u32 fd_length = dpaa2_fd_get_len(fd);
 
+	ch->buf_count--;
+
 	skb = build_skb(fd_vaddr, DPAA2_ETH_RX_BUF_SIZE +
 			SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
 	if (unlikely(!skb))
@@ -139,8 +141,6 @@ static struct sk_buff *build_linear_skb(struct dpaa2_eth_priv *priv,
 	skb_reserve(skb, fd_offset);
 	skb_put(skb, fd_length);
 
-	ch->buf_count--;
-
 	return skb;
 }
 
@@ -178,8 +178,15 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
 			/* We build the skb around the first data buffer */
 			skb = build_skb(sg_vaddr, DPAA2_ETH_RX_BUF_SIZE +
 				SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
-			if (unlikely(!skb))
-				return NULL;
+			if (unlikely(!skb)) {
+				/* We still need to subtract the buffers used
+				 * by this FD from our software counter
+				 */
+				while (!dpaa2_sg_is_final(&sgt[i]) &&
+				       i < DPAA2_ETH_MAX_SG_ENTRIES)
+					i++;
+				break;
+			}
 
 			sg_offset = dpaa2_sg_get_offset(sge);
 			skb_reserve(skb, sg_offset);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/9] staging: fsl-dpaa2/eth: Check SGT final bit is present
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 2/9] staging: fsl-dpaa2/eth: Account for Rx FD buffers on error path Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 4/9] staging: fsl-dpaa2/eth: Check if notification rearm is successful Ioana Radulescu
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

For scatter-gather ingress frames, we expect to receive
a list of fragments from the hardware, last of which is
marked with a "final" bit.

Add a check to make sure the Rx frame has this bit set
correctly; there's not much we can do in case of a
malformed frame, but at least issue a warning.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index e9fe1c9..6f009d1 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -213,6 +213,8 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
 			break;
 	}
 
+	WARN_ONCE(i == DPAA2_ETH_MAX_SG_ENTRIES, "Final bit not set in SGT");
+
 	/* Count all data buffers + SG table buffer */
 	ch->buf_count -= i + 2;
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/9] staging: fsl-dpaa2/eth: Check if notification rearm is successful
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 2/9] staging: fsl-dpaa2/eth: Account for Rx FD buffers on error path Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 3/9] staging: fsl-dpaa2/eth: Check SGT final bit is present Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 5/9] staging: fsl-dpaa2/eth: Refactor interrupt arming in NAPI poll Ioana Radulescu
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

In case dpaa2_io_service_rearm() fails with an error other then
EBUSY, it will do so silently; add a check for this and a warning
message, as a failure here means we're unable to receive any
more traffic on the current cpu.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index 6f009d1..f390de6 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -955,6 +955,8 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
 			err = dpaa2_io_service_rearm(NULL, &ch->nctx);
 			cpu_relax();
 		} while (err == -EBUSY);
+		WARN_ONCE(err, "CDAN notifications rearm failed on core %d",
+			  ch->nctx.desired_cpu);
 	}
 
 	ch->stats.frames += cleaned;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/9] staging: fsl-dpaa2/eth: Refactor interrupt arming in NAPI poll
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
                   ` (2 preceding siblings ...)
  2017-10-11 13:29 ` [PATCH 4/9] staging: fsl-dpaa2/eth: Check if notification rearm is successful Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 6/9] staging: fsl-dpaa2/eth: Fix double DMA unmap Ioana Radulescu
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

Take into consideration the return value of napi_complete_done(),
since there might be an indication that it's not suitable to
enable driver interrupts yet.

Signed-off-by: Bogdan Purcareata <bogdan.purcareata@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index f390de6..a0be9ab 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -948,8 +948,7 @@ static int dpaa2_eth_poll(struct napi_struct *napi, int budget)
 			break;
 	}
 
-	if (cleaned < budget) {
-		napi_complete_done(napi, cleaned);
+	if (cleaned < budget && napi_complete_done(napi, cleaned)) {
 		/* Re-enable data available notifications */
 		do {
 			err = dpaa2_io_service_rearm(NULL, &ch->nctx);
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/9] staging: fsl-dpaa2/eth: Fix double DMA unmap
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
                   ` (3 preceding siblings ...)
  2017-10-11 13:29 ` [PATCH 5/9] staging: fsl-dpaa2/eth: Refactor interrupt arming in NAPI poll Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 7/9] staging: fsl-dpaa2/eth: Use implicit clear of link interrupt Ioana Radulescu
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

In case we fail to allocate a skb for a fragmented ingress
frame, the cleanup function will attempt to unmap again the
first frame fragment, which had already been unmapped during
early Rx processing.

Avoid this by freeing the first buffer immediately in case
we hit an error, leaving the cleanup function to free only
the subsequent buffers.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 11 +++++++++--
 1 file changed, 9 insertions(+), 2 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index a0be9ab..6540ab0 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -104,9 +104,11 @@ static void free_rx_fd(struct dpaa2_eth_priv *priv,
 		/* We don't support any other format */
 		return;
 
-	/* For S/G frames, we first need to free all SG entries */
+	/* For S/G frames, we first need to free all SG entries
+	 * except the first one, which was taken care of already
+	 */
 	sgt = vaddr + dpaa2_fd_get_offset(fd);
-	for (i = 0; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
+	for (i = 1; i < DPAA2_ETH_MAX_SG_ENTRIES; i++) {
 		addr = dpaa2_sg_get_addr(&sgt[i]);
 		sg_vaddr = dpaa2_iova_to_virt(priv->iommu_domain, addr);
 		dma_unmap_single(dev, addr, DPAA2_ETH_RX_BUF_SIZE,
@@ -179,6 +181,11 @@ static struct sk_buff *build_frag_skb(struct dpaa2_eth_priv *priv,
 			skb = build_skb(sg_vaddr, DPAA2_ETH_RX_BUF_SIZE +
 				SKB_DATA_ALIGN(sizeof(struct skb_shared_info)));
 			if (unlikely(!skb)) {
+				/* Free the first SG entry now, since we already
+				 * unmapped it and obtained the virtual address
+				 */
+				skb_free_frag(sg_vaddr);
+
 				/* We still need to subtract the buffers used
 				 * by this FD from our software counter
 				 */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 7/9] staging: fsl-dpaa2/eth: Use implicit clear of link interrupt
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
                   ` (4 preceding siblings ...)
  2017-10-11 13:29 ` [PATCH 6/9] staging: fsl-dpaa2/eth: Fix double DMA unmap Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 8/9] staging: fsl-dpaa2/eth: Don't use netdev_err too early Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 9/9] staging: fsl-dpaa2/eth: Add firmware version Ioana Radulescu
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

dpni_get_irq_status() also looks at the input value of its
status parameter, and if not null it automatically clears
from pending state the bits that are set there.

Use this feature to avoid a separate MC command for clearing
the interrupt event bits after reading the status.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 12 +++---------
 1 file changed, 3 insertions(+), 9 deletions(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index 6540ab0..3a8bad1 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -2332,7 +2332,7 @@ static irqreturn_t dpni_irq0_handler(int irq_num, void *arg)
 
 static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
 {
-	u32 status = 0, clear = 0;
+	u32 status = ~0;
 	struct device *dev = (struct device *)arg;
 	struct fsl_mc_device *dpni_dev = to_fsl_mc_device(dev);
 	struct net_device *net_dev = dev_get_drvdata(dev);
@@ -2342,18 +2342,12 @@ static irqreturn_t dpni_irq0_handler_thread(int irq_num, void *arg)
 				  DPNI_IRQ_INDEX, &status);
 	if (unlikely(err)) {
 		netdev_err(net_dev, "Can't get irq status (err %d)\n", err);
-		clear = 0xffffffff;
-		goto out;
+		return IRQ_HANDLED;
 	}
 
-	if (status & DPNI_IRQ_EVENT_LINK_CHANGED) {
-		clear |= DPNI_IRQ_EVENT_LINK_CHANGED;
+	if (status & DPNI_IRQ_EVENT_LINK_CHANGED)
 		link_state_update(netdev_priv(net_dev));
-	}
 
-out:
-	dpni_clear_irq_status(dpni_dev->mc_io, 0, dpni_dev->mc_handle,
-			      DPNI_IRQ_INDEX, clear);
 	return IRQ_HANDLED;
 }
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 8/9] staging: fsl-dpaa2/eth: Don't use netdev_err too early
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
                   ` (5 preceding siblings ...)
  2017-10-11 13:29 ` [PATCH 7/9] staging: fsl-dpaa2/eth: Use implicit clear of link interrupt Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  2017-10-11 13:29 ` [PATCH 9/9] staging: fsl-dpaa2/eth: Add firmware version Ioana Radulescu
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

Early during probe the netdevice name is not initialized yet,
so use dev_err instead of netdev_err when printing error
messages.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
index 3a8bad1..9fbc0ee 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-eth.c
@@ -2114,7 +2114,7 @@ static int bind_dpni(struct dpaa2_eth_priv *priv)
 	 */
 	err = dpaa2_eth_set_hash(net_dev, DPAA2_RXH_SUPPORTED);
 	if (err)
-		netdev_err(net_dev, "Failed to configure hashing\n");
+		dev_err(dev, "Failed to configure hashing\n");
 
 	/* Configure handling of error frames */
 	err_cfg.errors = DPAA2_FAS_RX_ERR_MASK;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 9/9] staging: fsl-dpaa2/eth: Add firmware version
  2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
                   ` (6 preceding siblings ...)
  2017-10-11 13:29 ` [PATCH 8/9] staging: fsl-dpaa2/eth: Don't use netdev_err too early Ioana Radulescu
@ 2017-10-11 13:29 ` Ioana Radulescu
  7 siblings, 0 replies; 9+ messages in thread
From: Ioana Radulescu @ 2017-10-11 13:29 UTC (permalink / raw)
  To: gregkh
  Cc: devel, linux-kernel, agraf, arnd, bogdan.purcareata, stuyoder,
	laurentiu.tudor

Include firmware version in the driver information exported
through ethtool.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
 drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c | 14 +++++++++-
 drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h      |  5 ++++
 drivers/staging/fsl-dpaa2/ethernet/dpni.c          | 32 ++++++++++++++++++++++
 drivers/staging/fsl-dpaa2/ethernet/dpni.h          |  5 ++++
 4 files changed, 55 insertions(+), 1 deletion(-)

diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
index 031179a..ebe8fd6 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpaa2-ethtool.c
@@ -76,10 +76,22 @@ static char dpaa2_ethtool_extras[][ETH_GSTRING_LEN] = {
 static void dpaa2_eth_get_drvinfo(struct net_device *net_dev,
 				  struct ethtool_drvinfo *drvinfo)
 {
+	struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+	u16 fw_major, fw_minor;
+	int err;
+
 	strlcpy(drvinfo->driver, KBUILD_MODNAME, sizeof(drvinfo->driver));
 	strlcpy(drvinfo->version, dpaa2_eth_drv_version,
 		sizeof(drvinfo->version));
-	strlcpy(drvinfo->fw_version, "N/A", sizeof(drvinfo->fw_version));
+
+	err =  dpni_get_api_version(priv->mc_io, 0, &fw_major, &fw_minor);
+	if (!err)
+		snprintf(drvinfo->fw_version, sizeof(drvinfo->fw_version),
+			 "%u.%u", fw_major, fw_minor);
+	else
+		strlcpy(drvinfo->fw_version, "N/A",
+			sizeof(drvinfo->fw_version));
+
 	strlcpy(drvinfo->bus_info, dev_name(net_dev->dev.parent->parent),
 		sizeof(drvinfo->bus_info));
 }
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h b/drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h
index 57df222..3120e22 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni-cmd.h
@@ -538,4 +538,9 @@ struct dpni_rsp_get_taildrop {
 	__le32 threshold;
 };
 
+struct dpni_rsp_get_api_version {
+	u16 major;
+	u16 minor;
+};
+
 #endif /* _FSL_DPNI_CMD_H */
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpni.c b/drivers/staging/fsl-dpaa2/ethernet/dpni.c
index 04a5b14..e8be761 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni.c
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni.c
@@ -1594,3 +1594,35 @@ int dpni_get_taildrop(struct fsl_mc_io *mc_io,
 
 	return 0;
 }
+
+/**
+ * dpni_get_api_version() - Get Data Path Network Interface API version
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
+ * @major_ver:	Major version of data path network interface API
+ * @minor_ver:	Minor version of data path network interface API
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+			 u32 cmd_flags,
+			 u16 *major_ver,
+			 u16 *minor_ver)
+{
+	struct dpni_rsp_get_api_version *rsp_params;
+	struct mc_command cmd = { 0 };
+	int err;
+
+	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_API_VERSION,
+					  cmd_flags, 0);
+
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	rsp_params = (struct dpni_rsp_get_api_version *)cmd.params;
+	*major_ver = le16_to_cpu(rsp_params->major);
+	*minor_ver = le16_to_cpu(rsp_params->minor);
+
+	return 0;
+}
diff --git a/drivers/staging/fsl-dpaa2/ethernet/dpni.h b/drivers/staging/fsl-dpaa2/ethernet/dpni.h
index 282e5e8..ce86a81 100644
--- a/drivers/staging/fsl-dpaa2/ethernet/dpni.h
+++ b/drivers/staging/fsl-dpaa2/ethernet/dpni.h
@@ -829,4 +829,9 @@ struct dpni_rule_cfg {
 	u8	key_size;
 };
 
+int dpni_get_api_version(struct fsl_mc_io *mc_io,
+			 u32 cmd_flags,
+			 u16 *major_ver,
+			 u16 *minor_ver);
+
 #endif /* __FSL_DPNI_H */
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2017-10-11 13:32 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-10-11 13:29 [PATCH 1/9] staging: fsl-dpaa2/eth: Fix potential endless loop Ioana Radulescu
2017-10-11 13:29 ` [PATCH 2/9] staging: fsl-dpaa2/eth: Account for Rx FD buffers on error path Ioana Radulescu
2017-10-11 13:29 ` [PATCH 3/9] staging: fsl-dpaa2/eth: Check SGT final bit is present Ioana Radulescu
2017-10-11 13:29 ` [PATCH 4/9] staging: fsl-dpaa2/eth: Check if notification rearm is successful Ioana Radulescu
2017-10-11 13:29 ` [PATCH 5/9] staging: fsl-dpaa2/eth: Refactor interrupt arming in NAPI poll Ioana Radulescu
2017-10-11 13:29 ` [PATCH 6/9] staging: fsl-dpaa2/eth: Fix double DMA unmap Ioana Radulescu
2017-10-11 13:29 ` [PATCH 7/9] staging: fsl-dpaa2/eth: Use implicit clear of link interrupt Ioana Radulescu
2017-10-11 13:29 ` [PATCH 8/9] staging: fsl-dpaa2/eth: Don't use netdev_err too early Ioana Radulescu
2017-10-11 13:29 ` [PATCH 9/9] staging: fsl-dpaa2/eth: Add firmware version Ioana Radulescu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.