netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path
@ 2015-05-06 15:07 Claudiu Manoil
  2015-05-06 15:07 ` [PATCH net-next 2/2] gianfar: Enable changing mac addr when if up Claudiu Manoil
  2015-05-09 21:37 ` [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path David Miller
  0 siblings, 2 replies; 4+ messages in thread
From: Claudiu Manoil @ 2015-05-06 15:07 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller

Handle TxFIFO underrun exceptions outside the fast path.
A controller reset is more reliable in this exceptional
case, as opposed to re-enabling on-the-fly the Tx DMA.

As the controller reset is handled outside the fast path
by the reset_gfar() workqueue handler, the locking
scheme on the Tx path is significantly simplified.
Because the Tx processing (xmit queues and tx napi) is
disabled during controller reset, tstat access from xmit
does not require locking.  So the scope of the txlock on
the processing path is now reduced to num_txbdfree, which
is shared only between process context (xmit) and softirq
(clean_tx_ring).  As a result, the txlock must not guard
against interrupt context, and the spin_lock_irqsave()
from xmit can be replaced by spin_lock_bh().  Likewise,
the locking has been downgraded for clean_tx_ring().

Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
 drivers/net/ethernet/freescale/gianfar.c | 40 ++++++++------------------------
 1 file changed, 10 insertions(+), 30 deletions(-)

diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 4ee080d..3c84e5a 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -2254,7 +2254,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	int i, rq = 0;
 	int do_tstamp, do_csum, do_vlan;
 	u32 bufaddr;
-	unsigned long flags;
 	unsigned int nr_frags, nr_txbds, bytes_sent, fcb_len = 0;
 
 	rq = skb->queue_mapping;
@@ -2434,19 +2433,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	netdev_tx_sent_queue(txq, bytes_sent);
 
-	/* We can work in parallel with gfar_clean_tx_ring(), except
-	 * when modifying num_txbdfree. Note that we didn't grab the lock
-	 * when we were reading the num_txbdfree and checking for available
-	 * space, that's because outside of this function it can only grow,
-	 * and once we've got needed space, it cannot suddenly disappear.
-	 *
-	 * The lock also protects us from gfar_error(), which can modify
-	 * regs->tstat and thus retrigger the transfers, which is why we
-	 * also must grab the lock before setting ready bit for the first
-	 * to be transmitted BD.
-	 */
-	spin_lock_irqsave(&tx_queue->txlock, flags);
-
 	gfar_wmb();
 
 	txbdp_start->lstatus = cpu_to_be32(lstatus);
@@ -2463,8 +2449,15 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 
 	tx_queue->cur_tx = next_txbd(txbdp, base, tx_queue->tx_ring_size);
 
+	/* We can work in parallel with gfar_clean_tx_ring(), except
+	 * when modifying num_txbdfree. Note that we didn't grab the lock
+	 * when we were reading the num_txbdfree and checking for available
+	 * space, that's because outside of this function it can only grow.
+	 */
+	spin_lock_bh(&tx_queue->txlock);
 	/* reduce TxBD free count */
 	tx_queue->num_txbdfree -= (nr_txbds);
+	spin_unlock_bh(&tx_queue->txlock);
 
 	/* If the next BD still needs to be cleaned up, then the bds
 	 * are full.  We need to tell the kernel to stop sending us stuff.
@@ -2478,9 +2471,6 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
 	/* Tell the DMA to go go go */
 	gfar_write(&regs->tstat, TSTAT_CLEAR_THALT >> tx_queue->qindex);
 
-	/* Unlock priv */
-	spin_unlock_irqrestore(&tx_queue->txlock, flags);
-
 	return NETDEV_TX_OK;
 
 dma_map_err:
@@ -2622,7 +2612,6 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 	skb_dirtytx = tx_queue->skb_dirtytx;
 
 	while ((skb = tx_queue->tx_skbuff[skb_dirtytx])) {
-		unsigned long flags;
 
 		frags = skb_shinfo(skb)->nr_frags;
 
@@ -2686,9 +2675,9 @@ static void gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
 			      TX_RING_MOD_MASK(tx_ring_size);
 
 		howmany++;
-		spin_lock_irqsave(&tx_queue->txlock, flags);
+		spin_lock(&tx_queue->txlock);
 		tx_queue->num_txbdfree += nr_txbds;
-		spin_unlock_irqrestore(&tx_queue->txlock, flags);
+		spin_unlock(&tx_queue->txlock);
 	}
 
 	/* If we freed a buffer, we can restart transmission, if necessary */
@@ -3411,21 +3400,12 @@ static irqreturn_t gfar_error(int irq, void *grp_id)
 		if (events & IEVENT_CRL)
 			dev->stats.tx_aborted_errors++;
 		if (events & IEVENT_XFUN) {
-			unsigned long flags;
-
 			netif_dbg(priv, tx_err, dev,
 				  "TX FIFO underrun, packet dropped\n");
 			dev->stats.tx_dropped++;
 			atomic64_inc(&priv->extra_stats.tx_underrun);
 
-			local_irq_save(flags);
-			lock_tx_qs(priv);
-
-			/* Reactivate the Tx Queues */
-			gfar_write(&regs->tstat, gfargrp->tstat);
-
-			unlock_tx_qs(priv);
-			local_irq_restore(flags);
+			schedule_work(&priv->reset_task);
 		}
 		netif_dbg(priv, tx_err, dev, "Transmit Error\n");
 	}
-- 
1.7.11.7

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

* [PATCH net-next 2/2] gianfar: Enable changing mac addr when if up
  2015-05-06 15:07 [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path Claudiu Manoil
@ 2015-05-06 15:07 ` Claudiu Manoil
  2015-05-09 21:38   ` David Miller
  2015-05-09 21:37 ` [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path David Miller
  1 sibling, 1 reply; 4+ messages in thread
From: Claudiu Manoil @ 2015-05-06 15:07 UTC (permalink / raw)
  To: netdev; +Cc: David S. Miller

Use device flag IFF_LIVE_ADDR_CHANGE to signal that
the device supports changing the hardware address when
the device is running.
This allows eth_mac_addr() to change the mac address
also when the network device's interface is open.
This capability is required by certain applications,
like bonding mode 6 (Adaptive Load Balancing).

Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>
---
 drivers/net/ethernet/freescale/gianfar.c | 13 ++++++++++++-
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 3c84e5a..ff87502 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -516,6 +516,15 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev)
 	return &dev->stats;
 }
 
+static int gfar_set_mac_addr(struct net_device *dev, void *p)
+{
+	eth_mac_addr(dev, p);
+
+	gfar_set_mac_for_addr(dev, 0, dev->dev_addr);
+
+	return 0;
+}
+
 static const struct net_device_ops gfar_netdev_ops = {
 	.ndo_open = gfar_enet_open,
 	.ndo_start_xmit = gfar_start_xmit,
@@ -526,7 +535,7 @@ static const struct net_device_ops gfar_netdev_ops = {
 	.ndo_tx_timeout = gfar_timeout,
 	.ndo_do_ioctl = gfar_ioctl,
 	.ndo_get_stats = gfar_get_stats,
-	.ndo_set_mac_address = eth_mac_addr,
+	.ndo_set_mac_address = gfar_set_mac_addr,
 	.ndo_validate_addr = eth_validate_addr,
 #ifdef CONFIG_NET_POLL_CONTROLLER
 	.ndo_poll_controller = gfar_netpoll,
@@ -1411,6 +1420,8 @@ static int gfar_probe(struct platform_device *ofdev)
 		dev->features |= NETIF_F_HW_VLAN_CTAG_RX;
 	}
 
+	dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+
 	gfar_init_addr_hash_table(priv);
 
 	/* Insert receive time stamps into padding alignment bytes */
-- 
1.7.11.7

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

* Re: [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path
  2015-05-06 15:07 [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path Claudiu Manoil
  2015-05-06 15:07 ` [PATCH net-next 2/2] gianfar: Enable changing mac addr when if up Claudiu Manoil
@ 2015-05-09 21:37 ` David Miller
  1 sibling, 0 replies; 4+ messages in thread
From: David Miller @ 2015-05-09 21:37 UTC (permalink / raw)
  To: claudiu.manoil; +Cc: netdev

From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Wed, 6 May 2015 18:07:29 +0300

> Handle TxFIFO underrun exceptions outside the fast path.
> A controller reset is more reliable in this exceptional
> case, as opposed to re-enabling on-the-fly the Tx DMA.
> 
> As the controller reset is handled outside the fast path
> by the reset_gfar() workqueue handler, the locking
> scheme on the Tx path is significantly simplified.
> Because the Tx processing (xmit queues and tx napi) is
> disabled during controller reset, tstat access from xmit
> does not require locking.  So the scope of the txlock on
> the processing path is now reduced to num_txbdfree, which
> is shared only between process context (xmit) and softirq
> (clean_tx_ring).  As a result, the txlock must not guard
> against interrupt context, and the spin_lock_irqsave()
> from xmit can be replaced by spin_lock_bh().  Likewise,
> the locking has been downgraded for clean_tx_ring().
> 
> Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>

Applied.

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

* Re: [PATCH net-next 2/2] gianfar: Enable changing mac addr when if up
  2015-05-06 15:07 ` [PATCH net-next 2/2] gianfar: Enable changing mac addr when if up Claudiu Manoil
@ 2015-05-09 21:38   ` David Miller
  0 siblings, 0 replies; 4+ messages in thread
From: David Miller @ 2015-05-09 21:38 UTC (permalink / raw)
  To: claudiu.manoil; +Cc: netdev

From: Claudiu Manoil <claudiu.manoil@freescale.com>
Date: Wed, 6 May 2015 18:07:30 +0300

> Use device flag IFF_LIVE_ADDR_CHANGE to signal that
> the device supports changing the hardware address when
> the device is running.
> This allows eth_mac_addr() to change the mac address
> also when the network device's interface is open.
> This capability is required by certain applications,
> like bonding mode 6 (Adaptive Load Balancing).
> 
> Signed-off-by: Claudiu Manoil <claudiu.manoil@freescale.com>

Applied.

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

end of thread, other threads:[~2015-05-09 21:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-05-06 15:07 [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path Claudiu Manoil
2015-05-06 15:07 ` [PATCH net-next 2/2] gianfar: Enable changing mac addr when if up Claudiu Manoil
2015-05-09 21:38   ` David Miller
2015-05-09 21:37 ` [PATCH net-next 1/2] gianfar: Move TxFIFO underrun handling to reset path David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).