Netdev List
 help / color / mirror / Atom feed
* Rx checksum offload for fragments
From: Dimitris Michailidis @ 2010-07-27 22:56 UTC (permalink / raw)
  To: David Miller, netdev

I am looking at a problem with the cxgb4 driver related to Rx checksum 
offload and IPv6 fragments.  For IP/IPv6 fragments the device provides the 
L4 checksum without the pseudo-header, which the driver passes in skb->csum 
and sets CHECKSUM_COMPLETE.  This works for IP fragments but triggers errors 
  from netdev_rx_csum_fault for IPv6.  The errors are because of this code 
in ip6_frag_queue:

	if (skb->ip_summed == CHECKSUM_COMPLETE) {
		const unsigned char *nh = skb_network_header(skb);
		skb->csum = csum_sub(skb->csum,
			             csum_partial(nh, (u8 *)(fhdr + 1) - nh,
                                                   0));
	}

which subtracts the checksum for the L3 headers (that HW does not include in 
the first place).  AFAICS IPv4 does not make a similar adjustment to 
skb->csum for its header.  Am I missing something here or do IP and IPv6 
interpret CHECKSUM_COMPLETE differently?  And what should the driver do?

^ permalink raw reply

* [PATCH v2] ks8842: Support DMA when accessed via timberdale
From: Richard Röjfors @ 2010-07-27 22:57 UTC (permalink / raw)
  To: netdev; +Cc: davem

This patch adds support for RX and TX DMA via the DMA API,
this is only supported when the KS8842 is accessed via timberdale.

There is no support for DMA on the generic bus interface it self,
a state machine inside the FPGA is handling RX and TX transfers to/from
buffers in the FPGA. The host CPU can do DMA to and from these buffers.

The FPGA has to handle the RX interrupts, so these must be enabled in
the ks8842 but not in the FPGA. The driver must not disable the RX interrupt
that would mean that the data transfers into the FPGA buffers would stop.

The host shall not enable TX interrupts since TX is handled by the FPGA,
the host is notified by DMA callbacks when transfers are finished.

Which DMA channels to use are added as parameters in the platform data struct.

Signed-off-by: Richard Röjfors <richard.rojfors@pelagicore.com>
---
diff --git a/drivers/net/ks8842.c b/drivers/net/ks8842.c
index 289b0be..3fe38c7 100644
--- a/drivers/net/ks8842.c
+++ b/drivers/net/ks8842.c
@@ -30,6 +30,9 @@
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/ks8842.h>
+#include <linux/dmaengine.h>
+#include <linux/dma-mapping.h>
+#include <linux/scatterlist.h>
 
 #define DRV_NAME "ks8842"
 
@@ -82,6 +85,15 @@
 #define IRQ_RX_ERROR	0x0080
 #define ENABLED_IRQS	(IRQ_LINK_CHANGE | IRQ_TX | IRQ_RX | IRQ_RX_STOPPED | \
 		IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
+/* When running via timberdale in DMA mode, the RX interrupt should be
+   enabled in the KS8842, but not in the FPGA IP, since the IP handles
+   RX DMA internally.
+   TX interrupts are not needed it is handled by the FPGA the driver is
+   notified via DMA callbacks.
+*/
+#define ENABLED_IRQS_DMA_IP	(IRQ_LINK_CHANGE | IRQ_RX_STOPPED | \
+	IRQ_TX_STOPPED | IRQ_RX_OVERRUN | IRQ_RX_ERROR)
+#define ENABLED_IRQS_DMA	(ENABLED_IRQS_DMA_IP | IRQ_RX)
 #define REG_ISR		0x02
 #define REG_RXSR	0x04
 #define RXSR_VALID	0x8000
@@ -124,6 +136,28 @@
 #define	MICREL_KS884X		0x01	/* 0=Timeberdale(FPGA), 1=Micrel */
 #define	KS884X_16BIT		0x02	/*  1=16bit, 0=32bit */
 
+#define DMA_BUFFER_SIZE		2048
+
+struct ks8842_tx_dma_ctl {
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *adesc;
+	void *buf;
+	struct scatterlist sg;
+	int channel;
+};
+
+struct ks8842_rx_dma_ctl {
+	struct dma_chan *chan;
+	struct dma_async_tx_descriptor *adesc;
+	struct sk_buff  *skb;
+	struct scatterlist sg;
+	struct tasklet_struct tasklet;
+	int channel;
+};
+
+#define KS8842_USE_DMA(adapter) (((adapter)->dma_tx.channel != -1) && \
+	 ((adapter)->dma_rx.channel != -1))
+
 struct ks8842_adapter {
 	void __iomem	*hw_addr;
 	int		irq;
@@ -132,8 +166,19 @@ struct ks8842_adapter {
 	spinlock_t	lock; /* spinlock to be interrupt safe */
 	struct work_struct timeout_work;
 	struct net_device *netdev;
+	struct device *dev;
+	struct ks8842_tx_dma_ctl	dma_tx;
+	struct ks8842_rx_dma_ctl	dma_rx;
 };
 
+static void ks8842_dma_rx_cb(void *data);
+static void ks8842_dma_tx_cb(void *data);
+
+static inline void ks8842_resume_dma(struct ks8842_adapter *adapter)
+{
+	iowrite32(1, adapter->hw_addr + REQ_TIMB_DMA_RESUME);
+}
+
 static inline void ks8842_select_bank(struct ks8842_adapter *adapter, u16 bank)
 {
 	iowrite16(bank, adapter->hw_addr + REG_SELECT_BANK);
@@ -297,8 +342,19 @@ static void ks8842_reset_hw(struct ks8842_adapter *adapter)
 	ks8842_write16(adapter, 18, 0xffff, REG_ISR);
 
 	/* enable interrupts */
-	ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
-
+	if (KS8842_USE_DMA(adapter)) {
+		/* When running in DMA Mode the RX interrupt is not enabled in
+		   timberdale because RX data is received by DMA callbacks
+		   it must still be enabled in the KS8842 because it indicates
+		   to timberdale when there is RX data for it's DMA FIFOs */
+		iowrite16(ENABLED_IRQS_DMA_IP, adapter->hw_addr + REG_TIMB_IER);
+		ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER);
+	} else {
+		if (!(adapter->conf_flags & MICREL_KS884X))
+			iowrite16(ENABLED_IRQS,
+				adapter->hw_addr + REG_TIMB_IER);
+		ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
+	}
 	/* enable the switch */
 	ks8842_write16(adapter, 32, 0x1, REG_SW_ID_AND_ENABLE);
 }
@@ -371,6 +427,53 @@ static inline u16 ks8842_tx_fifo_space(struct ks8842_adapter *adapter)
 	return ks8842_read16(adapter, 16, REG_TXMIR) & 0x1fff;
 }
 
+static int ks8842_tx_frame_dma(struct sk_buff *skb, struct net_device *netdev)
+{
+	struct ks8842_adapter *adapter = netdev_priv(netdev);
+	struct ks8842_tx_dma_ctl *ctl = &adapter->dma_tx;
+	u8 *buf = ctl->buf;
+
+	if (ctl->adesc) {
+		netdev_dbg(netdev, "%s: TX ongoing\n", __func__);
+		/* transfer ongoing */
+		return NETDEV_TX_BUSY;
+	}
+
+	sg_dma_len(&ctl->sg) = skb->len + sizeof(u32);
+
+	/* copy data to the TX buffer */
+	/* the control word, enable IRQ, port 1 and the length */
+	*buf++ = 0x00;
+	*buf++ = 0x01; /* Port 1 */
+	*buf++ = skb->len & 0xff;
+	*buf++ = (skb->len >> 8) & 0xff;
+	skb_copy_from_linear_data(skb, buf, skb->len);
+
+	dma_sync_single_range_for_device(adapter->dev,
+		sg_dma_address(&ctl->sg), 0, sg_dma_len(&ctl->sg),
+		DMA_TO_DEVICE);
+
+	/* make sure the length is a multiple of 4 */
+	if (sg_dma_len(&ctl->sg) % 4)
+		sg_dma_len(&ctl->sg) += 4 - sg_dma_len(&ctl->sg) % 4;
+
+	ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan,
+		&ctl->sg, 1, DMA_TO_DEVICE,
+		DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
+	if (!ctl->adesc)
+		return NETDEV_TX_BUSY;
+
+	ctl->adesc->callback_param = netdev;
+	ctl->adesc->callback = ks8842_dma_tx_cb;
+	ctl->adesc->tx_submit(ctl->adesc);
+
+	netdev->stats.tx_bytes += skb->len;
+
+	dev_kfree_skb(skb);
+
+	return NETDEV_TX_OK;
+}
+
 static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct ks8842_adapter *adapter = netdev_priv(netdev);
@@ -422,6 +525,121 @@ static int ks8842_tx_frame(struct sk_buff *skb, struct net_device *netdev)
 	return NETDEV_TX_OK;
 }
 
+static void ks8842_update_rx_err_counters(struct net_device *netdev, u32 status)
+{
+	netdev_dbg(netdev, "RX error, status: %x\n", status);
+
+	netdev->stats.rx_errors++;
+	if (status & RXSR_TOO_LONG)
+		netdev->stats.rx_length_errors++;
+	if (status & RXSR_CRC_ERROR)
+		netdev->stats.rx_crc_errors++;
+	if (status & RXSR_RUNT)
+		netdev->stats.rx_frame_errors++;
+}
+
+static void ks8842_update_rx_counters(struct net_device *netdev, u32 status,
+	int len)
+{
+	netdev_dbg(netdev, "RX packet, len: %d\n", len);
+
+	netdev->stats.rx_packets++;
+	netdev->stats.rx_bytes += len;
+	if (status & RXSR_MULTICAST)
+		netdev->stats.multicast++;
+}
+
+static int __ks8842_start_new_rx_dma(struct net_device *netdev)
+{
+	struct ks8842_adapter *adapter = netdev_priv(netdev);
+	struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx;
+	struct scatterlist *sg = &ctl->sg;
+	int err;
+
+	ctl->skb = netdev_alloc_skb(netdev, DMA_BUFFER_SIZE);
+	if (ctl->skb) {
+		sg_init_table(sg, 1);
+		sg_dma_address(sg) = dma_map_single(adapter->dev,
+			ctl->skb->data, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+		err = dma_mapping_error(adapter->dev, sg_dma_address(sg));
+		if (unlikely(err)) {
+			sg_dma_address(sg) = 0;
+			goto out;
+		}
+
+		sg_dma_len(sg) = DMA_BUFFER_SIZE;
+
+		ctl->adesc = ctl->chan->device->device_prep_slave_sg(ctl->chan,
+			sg, 1, DMA_FROM_DEVICE,
+			DMA_PREP_INTERRUPT | DMA_COMPL_SKIP_SRC_UNMAP);
+
+		if (!ctl->adesc)
+			goto out;
+
+		ctl->adesc->callback_param = netdev;
+		ctl->adesc->callback = ks8842_dma_rx_cb;
+		ctl->adesc->tx_submit(ctl->adesc);
+	} else {
+		err = -ENOMEM;
+		sg_dma_address(sg) = 0;
+		goto out;
+	}
+
+	return err;
+out:
+	if (sg_dma_address(sg))
+		dma_unmap_single(adapter->dev, sg_dma_address(sg),
+			DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+	sg_dma_address(sg) = 0;
+	if (ctl->skb)
+		dev_kfree_skb(ctl->skb);
+
+	ctl->skb = NULL;
+
+	printk(KERN_ERR DRV_NAME": Failed to start RX DMA: %d\n", err);
+	return err;
+}
+
+static void ks8842_rx_frame_dma_tasklet(unsigned long arg)
+{
+	struct net_device *netdev = (struct net_device *)arg;
+	struct ks8842_adapter *adapter = netdev_priv(netdev);
+	struct ks8842_rx_dma_ctl *ctl = &adapter->dma_rx;
+	struct sk_buff *skb = ctl->skb;
+	dma_addr_t addr = sg_dma_address(&ctl->sg);
+	u32 status;
+
+	ctl->adesc = NULL;
+
+	/* kick next transfer going */
+	__ks8842_start_new_rx_dma(netdev);
+
+	/* now handle the data we got */
+	dma_unmap_single(adapter->dev, addr, DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+
+	status = *((u32 *)skb->data);
+
+	netdev_dbg(netdev, "%s - rx_data: status: %x\n",
+		__func__, status & 0xffff);
+
+	/* check the status */
+	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
+		int len = (status >> 16) & 0x7ff;
+
+		ks8842_update_rx_counters(netdev, status, len);
+
+		/* reserve 4 bytes which is the status word */
+		skb_reserve(skb, 4);
+		skb_put(skb, len);
+
+		skb->protocol = eth_type_trans(skb, netdev);
+		netif_rx(skb);
+	} else {
+		ks8842_update_rx_err_counters(netdev, status);
+		dev_kfree_skb(skb);
+	}
+}
+
 static void ks8842_rx_frame(struct net_device *netdev,
 	struct ks8842_adapter *adapter)
 {
@@ -445,13 +663,9 @@ static void ks8842_rx_frame(struct net_device *netdev,
 	if ((status & RXSR_VALID) && !(status & RXSR_ERROR)) {
 		struct sk_buff *skb = netdev_alloc_skb_ip_align(netdev, len);
 
-		netdev_dbg(netdev, "%s, got package, len: %d\n", __func__, len);
 		if (skb) {
 
-			netdev->stats.rx_packets++;
-			netdev->stats.rx_bytes += len;
-			if (status & RXSR_MULTICAST)
-				netdev->stats.multicast++;
+			ks8842_update_rx_counters(netdev, status, len);
 
 			if (adapter->conf_flags & KS884X_16BIT) {
 				u16 *data16 = (u16 *)skb_put(skb, len);
@@ -477,16 +691,8 @@ static void ks8842_rx_frame(struct net_device *netdev,
 			netif_rx(skb);
 		} else
 			netdev->stats.rx_dropped++;
-	} else {
-		netdev_dbg(netdev, "RX error, status: %x\n", status);
-		netdev->stats.rx_errors++;
-		if (status & RXSR_TOO_LONG)
-			netdev->stats.rx_length_errors++;
-		if (status & RXSR_CRC_ERROR)
-			netdev->stats.rx_crc_errors++;
-		if (status & RXSR_RUNT)
-			netdev->stats.rx_frame_errors++;
-	}
+	} else
+		ks8842_update_rx_err_counters(netdev, status);
 
 	/* set high watermark to 3K */
 	ks8842_clear_bits(adapter, 0, 1 << 12, REG_QRFCR);
@@ -541,6 +747,12 @@ void ks8842_tasklet(unsigned long arg)
 	isr = ks8842_read16(adapter, 18, REG_ISR);
 	netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr);
 
+	/* when running in DMA mode, do not ack RX interrupts, it is handled
+	   internally by timberdale, otherwise it's DMA FIFO:s would stop
+	*/
+	if (KS8842_USE_DMA(adapter))
+		isr &= ~IRQ_RX;
+
 	/* Ack */
 	ks8842_write16(adapter, 18, isr, REG_ISR);
 
@@ -554,9 +766,11 @@ void ks8842_tasklet(unsigned long arg)
 	if (isr & IRQ_LINK_CHANGE)
 		ks8842_update_link_status(netdev, adapter);
 
-	if (isr & (IRQ_RX | IRQ_RX_ERROR))
+	/* should not get IRQ_RX when running DMA mode */
+	if (isr & (IRQ_RX | IRQ_RX_ERROR) && !KS8842_USE_DMA(adapter))
 		ks8842_handle_rx(netdev, adapter);
 
+	/* should only happen when in PIO mode */
 	if (isr & IRQ_TX)
 		ks8842_handle_tx(netdev, adapter);
 
@@ -575,8 +789,17 @@ void ks8842_tasklet(unsigned long arg)
 
 	/* re-enable interrupts, put back the bank selection register */
 	spin_lock_irqsave(&adapter->lock, flags);
-	ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
+	if (KS8842_USE_DMA(adapter))
+		ks8842_write16(adapter, 18, ENABLED_IRQS_DMA, REG_IER);
+	else
+		ks8842_write16(adapter, 18, ENABLED_IRQS, REG_IER);
 	iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
+
+	/* Make sure timberdale continues DMA operations, they are stopped while
+	   we are handling the ks8842 because we might change bank */
+	if (KS8842_USE_DMA(adapter))
+		ks8842_resume_dma(adapter);
+
 	spin_unlock_irqrestore(&adapter->lock, flags);
 }
 
@@ -592,8 +815,12 @@ static irqreturn_t ks8842_irq(int irq, void *devid)
 	netdev_dbg(netdev, "%s - ISR: 0x%x\n", __func__, isr);
 
 	if (isr) {
-		/* disable IRQ */
-		ks8842_write16(adapter, 18, 0x00, REG_IER);
+		if (KS8842_USE_DMA(adapter))
+			/* disable all but RX IRQ, since the FPGA relies on it*/
+			ks8842_write16(adapter, 18, IRQ_RX, REG_IER);
+		else
+			/* disable IRQ */
+			ks8842_write16(adapter, 18, 0x00, REG_IER);
 
 		/* schedule tasklet */
 		tasklet_schedule(&adapter->tasklet);
@@ -603,9 +830,151 @@ static irqreturn_t ks8842_irq(int irq, void *devid)
 
 	iowrite16(entry_bank, adapter->hw_addr + REG_SELECT_BANK);
 
+	/* After an interrupt, tell timberdale to continue DMA operations.
+	   DMA is disabled while we are handling the ks8842 because we might
+	   change bank */
+	ks8842_resume_dma(adapter);
+
 	return ret;
 }
 
+static void ks8842_dma_rx_cb(void *data)
+{
+	struct net_device	*netdev = data;
+	struct ks8842_adapter	*adapter = netdev_priv(netdev);
+
+	netdev_dbg(netdev, "RX DMA finished\n");
+	/* schedule tasklet */
+	if (adapter->dma_rx.adesc)
+		tasklet_schedule(&adapter->dma_rx.tasklet);
+}
+
+static void ks8842_dma_tx_cb(void *data)
+{
+	struct net_device		*netdev = data;
+	struct ks8842_adapter		*adapter = netdev_priv(netdev);
+	struct ks8842_tx_dma_ctl	*ctl = &adapter->dma_tx;
+
+	netdev_dbg(netdev, "TX DMA finished\n");
+
+	if (!ctl->adesc)
+		return;
+
+	netdev->stats.tx_packets++;
+	ctl->adesc = NULL;
+
+	if (netif_queue_stopped(netdev))
+		netif_wake_queue(netdev);
+}
+
+static void ks8842_stop_dma(struct ks8842_adapter *adapter)
+{
+	struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx;
+	struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
+
+	tx_ctl->adesc = NULL;
+	if (tx_ctl->chan)
+		tx_ctl->chan->device->device_control(tx_ctl->chan,
+			DMA_TERMINATE_ALL, 0);
+
+	rx_ctl->adesc = NULL;
+	if (rx_ctl->chan)
+		rx_ctl->chan->device->device_control(rx_ctl->chan,
+			DMA_TERMINATE_ALL, 0);
+
+	if (sg_dma_address(&rx_ctl->sg))
+		dma_unmap_single(adapter->dev, sg_dma_address(&rx_ctl->sg),
+			DMA_BUFFER_SIZE, DMA_FROM_DEVICE);
+	sg_dma_address(&rx_ctl->sg) = 0;
+
+	dev_kfree_skb(rx_ctl->skb);
+	rx_ctl->skb = NULL;
+}
+
+static void ks8842_dealloc_dma_bufs(struct ks8842_adapter *adapter)
+{
+	struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx;
+	struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
+
+	ks8842_stop_dma(adapter);
+
+	if (tx_ctl->chan)
+		dma_release_channel(tx_ctl->chan);
+	tx_ctl->chan = NULL;
+
+	if (rx_ctl->chan)
+		dma_release_channel(rx_ctl->chan);
+	rx_ctl->chan = NULL;
+
+	tasklet_kill(&rx_ctl->tasklet);
+
+	if (sg_dma_address(&tx_ctl->sg))
+		dma_unmap_single(adapter->dev, sg_dma_address(&tx_ctl->sg),
+			DMA_BUFFER_SIZE, DMA_TO_DEVICE);
+	sg_dma_address(&tx_ctl->sg) = 0;
+
+	kfree(tx_ctl->buf);
+	tx_ctl->buf = NULL;
+}
+
+static bool ks8842_dma_filter_fn(struct dma_chan *chan, void *filter_param)
+{
+	return chan->chan_id == (int)filter_param;
+}
+
+static int ks8842_alloc_dma_bufs(struct net_device *netdev)
+{
+	struct ks8842_adapter *adapter = netdev_priv(netdev);
+	struct ks8842_tx_dma_ctl *tx_ctl = &adapter->dma_tx;
+	struct ks8842_rx_dma_ctl *rx_ctl = &adapter->dma_rx;
+	int err;
+
+	dma_cap_mask_t mask;
+
+	dma_cap_zero(mask);
+	dma_cap_set(DMA_SLAVE, mask);
+	dma_cap_set(DMA_PRIVATE, mask);
+
+	sg_init_table(&tx_ctl->sg, 1);
+
+	tx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn,
+		(void *)tx_ctl->channel);
+	if (!tx_ctl->chan) {
+		err = -ENODEV;
+		goto err;
+	}
+
+	/* allocate DMA buffer */
+	tx_ctl->buf = kmalloc(DMA_BUFFER_SIZE, GFP_KERNEL);
+	if (!tx_ctl->buf) {
+		err = -ENOMEM;
+		goto err;
+	}
+
+	sg_dma_address(&tx_ctl->sg) = dma_map_single(adapter->dev,
+		tx_ctl->buf, DMA_BUFFER_SIZE, DMA_TO_DEVICE);
+	err = dma_mapping_error(adapter->dev,
+		sg_dma_address(&tx_ctl->sg));
+	if (err) {
+		sg_dma_address(&tx_ctl->sg) = 0;
+		goto err;
+	}
+
+	rx_ctl->chan = dma_request_channel(mask, ks8842_dma_filter_fn,
+		(void *)rx_ctl->channel);
+	if (!rx_ctl->chan) {
+		err = -ENODEV;
+		goto err;
+	}
+
+	tasklet_init(&rx_ctl->tasklet, ks8842_rx_frame_dma_tasklet,
+		(unsigned long)netdev);
+
+	return 0;
+err:
+	ks8842_dealloc_dma_bufs(adapter);
+	return err;
+}
 
 /* Netdevice operations */
 
@@ -616,6 +985,25 @@ static int ks8842_open(struct net_device *netdev)
 
 	netdev_dbg(netdev, "%s - entry\n", __func__);
 
+	if (KS8842_USE_DMA(adapter)) {
+		err = ks8842_alloc_dma_bufs(netdev);
+
+		if (!err) {
+			/* start RX dma */
+			err = __ks8842_start_new_rx_dma(netdev);
+			if (err)
+				ks8842_dealloc_dma_bufs(adapter);
+		}
+
+		if (err) {
+			printk(KERN_WARNING DRV_NAME
+				": Failed to initiate DMA, running PIO\n");
+			ks8842_dealloc_dma_bufs(adapter);
+			adapter->dma_rx.channel = -1;
+			adapter->dma_tx.channel = -1;
+		}
+	}
+
 	/* reset the HW */
 	ks8842_reset_hw(adapter);
 
@@ -641,6 +1029,9 @@ static int ks8842_close(struct net_device *netdev)
 
 	cancel_work_sync(&adapter->timeout_work);
 
+	if (KS8842_USE_DMA(adapter))
+		ks8842_dealloc_dma_bufs(adapter);
+
 	/* free the irq */
 	free_irq(adapter->irq, netdev);
 
@@ -658,6 +1049,17 @@ static netdev_tx_t ks8842_xmit_frame(struct sk_buff *skb,
 
 	netdev_dbg(netdev, "%s: entry\n", __func__);
 
+	if (KS8842_USE_DMA(adapter)) {
+		unsigned long flags;
+		ret = ks8842_tx_frame_dma(skb, netdev);
+		/* for now only allow one transfer at the time */
+		spin_lock_irqsave(&adapter->lock, flags);
+		if (adapter->dma_tx.adesc)
+			netif_stop_queue(netdev);
+		spin_unlock_irqrestore(&adapter->lock, flags);
+		return ret;
+	}
+
 	ret = ks8842_tx_frame(skb, netdev);
 
 	if (ks8842_tx_fifo_space(adapter) <  netdev->mtu + 8)
@@ -693,6 +1095,10 @@ static void ks8842_tx_timeout_work(struct work_struct *work)
 	netdev_dbg(netdev, "%s: entry\n", __func__);
 
 	spin_lock_irqsave(&adapter->lock, flags);
+
+	if (KS8842_USE_DMA(adapter))
+		ks8842_stop_dma(adapter);
+
 	/* disable interrupts */
 	ks8842_write16(adapter, 18, 0, REG_IER);
 	ks8842_write16(adapter, 18, 0xFFFF, REG_ISR);
@@ -706,6 +1112,9 @@ static void ks8842_tx_timeout_work(struct work_struct *work)
 	ks8842_write_mac_addr(adapter, netdev->dev_addr);
 
 	ks8842_update_link_status(netdev, adapter);
+
+	if (KS8842_USE_DMA(adapter))
+		__ks8842_start_new_rx_dma(netdev);
 }
 
 static void ks8842_tx_timeout(struct net_device *netdev)
@@ -765,6 +1174,19 @@ static int __devinit ks8842_probe(struct platform_device *pdev)
 		goto err_get_irq;
 	}
 
+	adapter->dev = (pdev->dev.parent) ? pdev->dev.parent : &pdev->dev;
+
+	/* DMA is only supported when accessed via timberdale */
+	if (!(adapter->conf_flags & MICREL_KS884X) && pdata &&
+		(pdata->tx_dma_channel != -1) &&
+		(pdata->rx_dma_channel != -1)) {
+		adapter->dma_rx.channel = pdata->rx_dma_channel;
+		adapter->dma_tx.channel = pdata->tx_dma_channel;
+	} else {
+		adapter->dma_rx.channel = -1;
+		adapter->dma_tx.channel = -1;
+	}
+
 	tasklet_init(&adapter->tasklet, ks8842_tasklet, (unsigned long)netdev);
 	spin_lock_init(&adapter->lock);
 
diff --git a/include/linux/ks8842.h b/include/linux/ks8842.h
index da0341b..14ba445 100644
--- a/include/linux/ks8842.h
+++ b/include/linux/ks8842.h
@@ -25,10 +25,14 @@
  * struct ks8842_platform_data - Platform data of the KS8842 network driver
  * @macaddr:	The MAC address of the device, set to all 0:s to use the on in
  *		the chip.
+ * @rx_dma_channel:	The DMA channel to use for RX, -1 for none.
+ * @tx_dma_channel:	The DMA channel to use for TX, -1 for none.
  *
  */
 struct ks8842_platform_data {
 	u8 macaddr[ETH_ALEN];
+	int rx_dma_channel;
+	int tx_dma_channel;
 };
 
 #endif


^ permalink raw reply related

* [PATCHv3] Add missing memory barriers to clean_rx_irq functions in Intel Drivers
From: Sonny Rao @ 2010-07-27 23:05 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: netdev, e1000-devel
In-Reply-To: <AANLkTikMNFSyPxRCXc=cPWHkOfsx9iH0mEu-TH7bHL_h@mail.gmail.com>

On Tue, Jul 27, 2010 at 03:45:42PM -0700, Jeff Kirsher wrote:
> 
> You also seem to be missing igb.

This patch is similar to what was fixed in ixgbe in this patch:

http://marc.info/?l=e1000-devel&m=126593062701537&w=3

We should add read memory barriers to all the similar cases across the
Intel ethernet driver family.  In the case of ixgbevf, igb, and igbvf
I've also added a missing barrier to the clean_tx_irq path because I
missed it in my last patch.

Without the barrier a processor can speculate a load ahead of the load
which looks at the status bit and get stale information causing a
number of different issues including invalid packet length, NULL
pointers, or bad data since checksumming was assumed to be done
in hardware.

v2: I missed the e100 the first time
v3: I missed igb and igbvf, third time's the charm?

Signed-off-by: Milton Miller <miltonm@bga.com>
Signed-off-by: Sonny Rao <sonnyrao@us.ibm.com>
cc: stable <stable@kernel.org>

Index: linux-2.6.35-rc5/drivers/net/e1000/e1000_main.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/e1000/e1000_main.c	2010-07-27 16:15:18.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/e1000/e1000_main.c	2010-07-27 16:22:21.000000000 -0500
@@ -3638,6 +3638,7 @@ static bool e1000_clean_jumbo_rx_irq(str
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
@@ -3844,6 +3845,7 @@ static bool e1000_clean_rx_irq(struct e1
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
Index: linux-2.6.35-rc5/drivers/net/e1000e/netdev.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/e1000e/netdev.c	2010-07-27 16:22:38.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/e1000e/netdev.c	2010-07-27 16:25:23.000000000 -0500
@@ -774,6 +774,7 @@ static bool e1000_clean_rx_irq(struct e1
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
@@ -1081,6 +1082,7 @@ static bool e1000_clean_rx_irq_ps(struct
 			break;
 		(*work_done)++;
 		skb = buffer_info->skb;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		/* in the packet split case this is header only */
 		prefetch(skb->data - NET_IP_ALIGN);
@@ -1280,6 +1282,7 @@ static bool e1000_clean_jumbo_rx_irq(str
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 
 		status = rx_desc->status;
 		skb = buffer_info->skb;
Index: linux-2.6.35-rc5/drivers/net/ixgb/ixgb_main.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/ixgb/ixgb_main.c	2010-07-27 16:27:23.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/ixgb/ixgb_main.c	2010-07-27 16:41:57.000000000 -0500
@@ -1977,6 +1977,7 @@ ixgb_clean_rx_irq(struct ixgb_adapter *a
 			break;
 
 		(*work_done)++;
+		rmb();	/* read descriptor and rx_buffer_info after status DD */
 		status = rx_desc->status;
 		skb = buffer_info->skb;
 		buffer_info->skb = NULL;
Index: linux-2.6.35-rc5/drivers/net/ixgbevf/ixgbevf_main.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/ixgbevf/ixgbevf_main.c	2010-07-27 16:30:51.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/ixgbevf/ixgbevf_main.c	2010-07-27 16:40:19.000000000 -0500
@@ -231,6 +231,7 @@ static bool ixgbevf_clean_tx_irq(struct 
 	while ((eop_desc->wb.status & cpu_to_le32(IXGBE_TXD_STAT_DD)) &&
 	       (count < tx_ring->work_limit)) {
 		bool cleaned = false;
+		rmb(); /* read buffer_info after eop_desc */
 		for ( ; !cleaned; count++) {
 			struct sk_buff *skb;
 			tx_desc = IXGBE_TX_DESC_ADV(*tx_ring, i);
@@ -518,6 +519,7 @@ static bool ixgbevf_clean_rx_irq(struct 
 			break;
 		(*work_done)++;
 
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 		if (adapter->flags & IXGBE_FLAG_RX_PS_ENABLED) {
 			hdr_info = le16_to_cpu(ixgbevf_get_hdr_info(rx_desc));
 			len = (hdr_info & IXGBE_RXDADV_HDRBUFLEN_MASK) >>
Index: linux-2.6.35-rc5/drivers/net/e100.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/e100.c	2010-07-27 17:36:44.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/e100.c	2010-07-27 17:41:38.000000000 -0500
@@ -1928,6 +1928,7 @@ static int e100_rx_indicate(struct nic *
 
 	netif_printk(nic, rx_status, KERN_DEBUG, nic->netdev,
 		     "status=0x%04X\n", rfd_status);
+	rmb(); /* read size after status bit */
 
 	/* If data isn't ready, nothing to indicate */
 	if (unlikely(!(rfd_status & cb_complete))) {
Index: linux-2.6.35-rc5/drivers/net/igb/igb_main.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/igb/igb_main.c	2010-07-27 17:50:47.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/igb/igb_main.c	2010-07-27 17:57:11.000000000 -0500
@@ -5335,6 +5335,7 @@ static bool igb_clean_tx_irq(struct igb_
 
 	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
+		rmb();	/* read buffer_info after eop_desc status */
 		for (cleaned = false; !cleaned; count++) {
 			tx_desc = E1000_TX_DESC_ADV(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];
@@ -5540,6 +5541,7 @@ static bool igb_clean_rx_irq_adv(struct 
 		if (*work_done >= budget)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		skb = buffer_info->skb;
 		prefetch(skb->data - NET_IP_ALIGN);
Index: linux-2.6.35-rc5/drivers/net/igbvf/netdev.c
===================================================================
--- linux-2.6.35-rc5.orig/drivers/net/igbvf/netdev.c	2010-07-27 17:51:00.000000000 -0500
+++ linux-2.6.35-rc5/drivers/net/igbvf/netdev.c	2010-07-27 17:59:15.000000000 -0500
@@ -248,6 +248,7 @@ static bool igbvf_clean_rx_irq(struct ig
 		if (*work_done >= work_to_do)
 			break;
 		(*work_done)++;
+		rmb(); /* read descriptor and rx_buffer_info after status DD */
 
 		buffer_info = &rx_ring->buffer_info[i];
 
@@ -780,6 +781,7 @@ static bool igbvf_clean_tx_irq(struct ig
 
 	while ((eop_desc->wb.status & cpu_to_le32(E1000_TXD_STAT_DD)) &&
 	       (count < tx_ring->count)) {
+		rmb();	/* read buffer_info after eop_desc status */
 		for (cleaned = false; !cleaned; count++) {
 			tx_desc = IGBVF_TX_DESC_ADV(*tx_ring, i);
 			buffer_info = &tx_ring->buffer_info[i];

^ permalink raw reply

* Re: [PATCHv3] Add missing memory barriers to clean_rx_irq functions in Intel Drivers
From: Jeff Kirsher @ 2010-07-27 23:08 UTC (permalink / raw)
  To: Sonny Rao; +Cc: netdev, e1000-devel
In-Reply-To: <20100727230540.GQ17248@us.ibm.com>

On Tue, Jul 27, 2010 at 16:05, Sonny Rao <sonnyrao@us.ibm.com> wrote:
> On Tue, Jul 27, 2010 at 03:45:42PM -0700, Jeff Kirsher wrote:
>>
>> You also seem to be missing igb.
>
> This patch is similar to what was fixed in ixgbe in this patch:
>
> http://marc.info/?l=e1000-devel&m=126593062701537&w=3
>
> We should add read memory barriers to all the similar cases across the
> Intel ethernet driver family.  In the case of ixgbevf, igb, and igbvf
> I've also added a missing barrier to the clean_tx_irq path because I
> missed it in my last patch.
>
> Without the barrier a processor can speculate a load ahead of the load
> which looks at the status bit and get stale information causing a
> number of different issues including invalid packet length, NULL
> pointers, or bad data since checksumming was assumed to be done
> in hardware.
>
> v2: I missed the e100 the first time
> v3: I missed igb and igbvf, third time's the charm?
>
> Signed-off-by: Milton Miller <miltonm@bga.com>
> Signed-off-by: Sonny Rao <sonnyrao@us.ibm.com>
> cc: stable <stable@kernel.org>
>

Thanks, I have added the patch to my queue.

-- 
Cheers,
Jeff

^ permalink raw reply

* Re: RX/close vcc race with solos/atmtcp/usbatm/he
From: Nathan Williams @ 2010-07-27 23:12 UTC (permalink / raw)
  To: David Woodhouse; +Cc: linux-atm-general, netdev
In-Reply-To: <1275904970.17903.4658.camel@macbook.infradead.org>

On 7/06/2010 8:02 PM, David Woodhouse wrote:
> On Wed, 2010-05-26 at 12:16 +0100, David Woodhouse wrote:
>> I've had this crash reported to me...
>>
>> [18842.727906] EIP: [<e082f490>] br2684_push+0x19/0x234 [br2684]
>> SS:ESP 0068:dfb89d14 
> 
> Nathan, did you manage to get your customer to confirm that this fixes
> the problem? It'd be useful to get this into 2.6.35 and -stable.
> 

I've had confirmation from the customer.  The patch fixed his problem.

^ permalink raw reply

* [PATCH] tun: keep link (carrier) state up to date
From: Nolan Leake @ 2010-07-27 23:53 UTC (permalink / raw)
  To: netdev

Currently, only ethtool can get accurate link state of a tap device.
With this patch, IFF_RUNNING and IF_OPER_UP/DOWN are kept up to date as
well.

Signed-off-by: Nolan Leake <nolan@cumulusnetworks.com>
---
 drivers/net/tun.c |   10 +++-------
 1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/net/tun.c b/drivers/net/tun.c
index 4fdfa2a..393273c 100644
--- a/drivers/net/tun.c
+++ b/drivers/net/tun.c
@@ -144,6 +144,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file)
 	err = 0;
 	tfile->tun = tun;
 	tun->tfile = tfile;
+	netif_carrier_on(tun->dev);
 	dev_hold(tun->dev);
 	sock_hold(tun->socket.sk);
 	atomic_inc(&tfile->count);
@@ -157,6 +158,7 @@ static void __tun_detach(struct tun_struct *tun)
 {
 	/* Detach from net device */
 	netif_tx_lock_bh(tun->dev);
+	netif_carrier_off(tun->dev);
 	tun->tfile = NULL;
 	netif_tx_unlock_bh(tun->dev);
 
@@ -1425,12 +1427,6 @@ static void tun_set_msglevel(struct net_device *dev, u32 value)
 #endif
 }
 
-static u32 tun_get_link(struct net_device *dev)
-{
-	struct tun_struct *tun = netdev_priv(dev);
-	return !!tun->tfile;
-}
-
 static u32 tun_get_rx_csum(struct net_device *dev)
 {
 	struct tun_struct *tun = netdev_priv(dev);
@@ -1452,7 +1448,7 @@ static const struct ethtool_ops tun_ethtool_ops = {
 	.get_drvinfo	= tun_get_drvinfo,
 	.get_msglevel	= tun_get_msglevel,
 	.set_msglevel	= tun_set_msglevel,
-	.get_link	= tun_get_link,
+	.get_link	= ethtool_op_get_link,
 	.get_rx_csum	= tun_get_rx_csum,
 	.set_rx_csum	= tun_set_rx_csum
 };


^ permalink raw reply related

* Re: [patch -next] ixgbe: potential null dereference
From: Jeff Kirsher @ 2010-07-28  0:10 UTC (permalink / raw)
  To: Dan Carpenter
  Cc: kernel-janitors, Mallikarjuna R Chilakala, e1000-devel,
	Bruce Allan, Jesse Brandeburg, John Ronciak, netdev,
	David S. Miller
In-Reply-To: <20100727100556.GM26313@bicker>

On Tue, Jul 27, 2010 at 03:05, Dan Carpenter <error27@gmail.com> wrote:
> The e_dev_err() macro dereferences "adapter" which is NULL here.
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>

Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

------------------------------------------------------------------------------
The Palm PDK Hot Apps Program offers developers who use the
Plug-In Development Kit to bring their C/C++ apps to Palm for a share 
of $1 Million in cash or HP Products. Visit us here for more details:
http://ad.doubleclick.net/clk;226879339;13503038;l?
http://clk.atdmt.com/CRS/go/247765532/direct/01/
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel&#174; Ethernet, visit http://communities.intel.com/community/wired

^ permalink raw reply

* Re: [PATCH v2] macvlan: Fix rx counters update in macvlan_handle_frame()
From: Herbert Xu @ 2010-07-28  0:14 UTC (permalink / raw)
  To: Sridhar Samudrala; +Cc: David Miller, netdev
In-Reply-To: <1280257807.27059.4.camel@w-sridhar.beaverton.ibm.com>

On Tue, Jul 27, 2010 at 12:10:07PM -0700, Sridhar Samudrala wrote:
> Fix macvlan_handle_frame() to update the rx counters based
> on the return value of the vlan->receive call.
> 
> Updated the patch to not do any packet count drops when the interface
> is down based on Herber'ts comments.
> 
> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>

Acked-by: Herbert Xu <herbert@gondor.apana.org.au>

Thanks,
-- 
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt

^ permalink raw reply

* Patch "IPv6: keep route for tentative address" has been added to the 2.6.34-stable tree
From: gregkh @ 2010-07-28  0:24 UTC (permalink / raw)
  To: shemminger, davem, emils.tantilov, emil.s.tantilov, gregkh, greg,
	netdev
  Cc: stable, stable-commits
In-Reply-To: <20100524113118.47cc9852@nehalam>


This is a note to let you know that I've just added the patch titled

    IPv6: keep route for tentative address

to the 2.6.34-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
    ipv6-keep-route-for-tentative-address.patch
and it can be found in the queue-2.6.34 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@kernel.org> know about it.


>From shemminger@vyatta.com  Tue Jul 27 16:56:59 2010
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Mon, 24 May 2010 11:31:18 -0700
Subject: IPv6: keep route for tentative address
To: Emil S Tantilov <emils.tantilov@gmail.com>
Cc: NetDev <netdev@vger.kernel.org>, stable@kernel.org, Greg KH <greg@kroah.com>, "David S. Miller" <davem@davemloft.net>, "Tantilov, Emil S" <emil.s.tantilov@intel.com>
Message-ID: <20100524113118.47cc9852@nehalam>

From: Stephen Hemminger <shemminger@vyatta.com>

(cherry picked from commit 93fa159abe50d3c55c7f83622d3f5c09b6e06f4b)

Recent changes preserve IPv6 address when link goes down (good).
But would cause address to point to dead dst entry (bad).
The simplest fix is to just not delete route if address is
being held for later use.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 net/ipv6/addrconf.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -4047,7 +4047,8 @@ static void __ipv6_ifa_notify(int event,
 			addrconf_leave_anycast(ifp);
 		addrconf_leave_solict(ifp->idev, &ifp->addr);
 		dst_hold(&ifp->rt->u.dst);
-		if (ip6_del_rt(ifp->rt))
+
+		if (ifp->dead && ip6_del_rt(ifp->rt))
 			dst_free(&ifp->rt->u.dst);
 		break;
 	}


Patches currently in stable-queue which might be from shemminger@vyatta.com are

queue-2.6.34/sky2-restore-multicast-after-restart.patch
queue-2.6.34/ipv6-keep-route-for-tentative-address.patch
queue-2.6.34/ipv6-only-notify-protocols-if-address-is-completely-gone.patch
queue-2.6.34/ipv6-fix-null-reference-in-proxy-neighbor-discovery.patch
queue-2.6.34/bridge-fdb-cleanup-runs-too-often.patch

^ permalink raw reply

* RE: e1000e crashes with 2.6.34.x and ThinkPad T60
From: Tantilov, Emil S @ 2010-07-28  0:33 UTC (permalink / raw)
  To: Marc Haber, Linux Kernel Developers,
	Linux Kernel Network Developers
In-Reply-To: <20100724092644.GA13353@torres.zugschlus.de>

Marc Haber wrote:
> Hi,
> 
> I have a new notebook, a Thinkpad T60, which is freezing in random
> intervals (like 30 minutes to two days) as long as I am using the
> on-board wired ethernet interface, which is an e1000e, [8086:109a]. As
> long as I keep using the WLAN, the system runs for weeks despite
> frequent suspend/resume cycles etc. The crashes seem really to be tied
> to using the wired ethernet. This is a hard freeze, with nothing
> happening on the system, only a long push on the power button helps.

When the crashes occur - is there a trace on the screen?

Do you know of a way to reproduce the issue? For example were
you downloading files, browsing internet, or using the ethernet device
in any way when the system crashed?

> Additionally, sometimes, probably after suspend/resume, the wired
> ethernet does not come up properly again, ip addr claims "NO CARRIER"
> even if the LEDs on the interface and on the switch claim that there
> was a link. No packets are received by the interface when it's at this
> stage.
> 
> Both issues appear with 2.6.34 and 2.6.34.1. I didn't try any of these
> issues with an older kernel, 2.6.34 was already out when I started
> using the T60.

I got a T60 notebook running on 2.6.34.1 and will try to reproduce in house.

> 
> To rule out defective hardware, I have tried with a second T60, with
> the same results.
> 
> Full dmesg and lspci-nn attached, please say if you need more.

Doesn't seem that there were any attachments to this email. 
Could you also provide the kernel config?

> Greetings
> Marc

Thanks,
Emil

^ permalink raw reply

* Patch "IPv6: only notify protocols if address is completely gone" has been added to the 2.6.34-stable tree
From: gregkh @ 2010-07-28  0:25 UTC (permalink / raw)
  To: shemminger, davem, emils.tantilov, emil.s.tantilov, gregkh, greg,
	netdev
  Cc: stable, stable-commits
In-Reply-To: <20100524113300.2ef38e12@nehalam>


This is a note to let you know that I've just added the patch titled

    IPv6: only notify protocols if address is completely gone

to the 2.6.34-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
    ipv6-only-notify-protocols-if-address-is-completely-gone.patch
and it can be found in the queue-2.6.34 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@kernel.org> know about it.


>From shemminger@vyatta.com  Tue Jul 27 16:57:29 2010
From: Stephen Hemminger <shemminger@vyatta.com>
Date: Mon, 24 May 2010 11:33:00 -0700
Subject: IPv6: only notify protocols if address is completely gone
To: Emil S Tantilov <emils.tantilov@gmail.com>, "David S. Miller" <davem@davemloft.net>, Greg KH <greg@kroah.com>
Cc: NetDev <netdev@vger.kernel.org>, "Tantilov, Emil S" <emil.s.tantilov@intel.com>, stable@kernel.org
Message-ID: <20100524113300.2ef38e12@nehalam>

From: Stephen Hemminger <shemminger@vyatta.com>

(cherry picked from commit 8595805aafc8b077e01804c9a3668e9aa3510e89)

The notifier for address down should only be called if address is completely
gone, not just being marked as tentative on link transition. The code
in net-next would case bonding/sctp/s390 to see address disappear on link
down, but they would never see it reappear on link up.

Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>

---
 net/ipv6/addrconf.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2729,7 +2729,9 @@ static int addrconf_ifdown(struct net_de
 		write_unlock_bh(&idev->lock);
 
 		__ipv6_ifa_notify(RTM_DELADDR, ifa);
-		atomic_notifier_call_chain(&inet6addr_chain, NETDEV_DOWN, ifa);
+		if (ifa->dead)
+			atomic_notifier_call_chain(&inet6addr_chain,
+						   NETDEV_DOWN, ifa);
 		in6_ifa_put(ifa);
 
 		write_lock_bh(&idev->lock);


Patches currently in stable-queue which might be from shemminger@vyatta.com are

queue-2.6.34/sky2-restore-multicast-after-restart.patch
queue-2.6.34/ipv6-keep-route-for-tentative-address.patch
queue-2.6.34/ipv6-only-notify-protocols-if-address-is-completely-gone.patch
queue-2.6.34/ipv6-fix-null-reference-in-proxy-neighbor-discovery.patch
queue-2.6.34/bridge-fdb-cleanup-runs-too-often.patch

^ permalink raw reply

* Re: Make vhost multi-threaded and associate each thread to its guest's cgroup
From: Sridhar Samudrala @ 2010-07-28  0:41 UTC (permalink / raw)
  To: Michael S. Tsirkin; +Cc: netdev, lkml, kvm@vger.kernel.org, Tejun Heo, Li Zefan
In-Reply-To: <20100727204254.GA17947@redhat.com>

On Tue, 2010-07-27 at 23:42 +0300, Michael S. Tsirkin wrote:
> Sridhar,
> I pushed a patchset with all known issues fixed,
> on my vhost-net-next branch.
> 
> For now this ignores the cpu mask issue, addressing
> only the cgroups issue.
> 
> Would appreciate testing and reports.

I had to apply the following patch to get it build.
With this patch, i am seeing similar results as i saw earlier.

Thanks
Sridhar

diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 996e751..8543898 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -23,6 +23,7 @@
 #include <linux/highmem.h>
 #include <linux/slab.h>
 #include <linux/kthread.h>
+#include <linux/cgroup.h>
 
 #include <linux/net.h>
 #include <linux/if_packet.h>
@@ -252,7 +253,7 @@ static long vhost_dev_set_owner(struct vhost_dev *dev)
 	}
 
 	dev->worker = worker;
-	err = cgroup_attach_task_current_cg(poller);
+	err = cgroup_attach_task_current_cg(worker);
 	if (err)
 		goto err_cgroup;
 	wake_up_process(worker);	/* avoid contributing to loadavg */

^ permalink raw reply related

* Re: Make vhost multi-threaded and associate each thread to its guest's cgroup
From: Michael S. Tsirkin @ 2010-07-28  1:12 UTC (permalink / raw)
  To: Sridhar Samudrala; +Cc: netdev, lkml, kvm@vger.kernel.org, Tejun Heo, Li Zefan
In-Reply-To: <1280277701.27059.11.camel@w-sridhar.beaverton.ibm.com>

On Tue, Jul 27, 2010 at 05:41:41PM -0700, Sridhar Samudrala wrote:
> On Tue, 2010-07-27 at 23:42 +0300, Michael S. Tsirkin wrote:
> > Sridhar,
> > I pushed a patchset with all known issues fixed,
> > on my vhost-net-next branch.
> > 
> > For now this ignores the cpu mask issue, addressing
> > only the cgroups issue.
> > 
> > Would appreciate testing and reports.
> 
> I had to apply the following patch to get it build.
> With this patch, i am seeing similar results as i saw earlier.
> 
> Thanks
> Sridhar


Excellent, thanks for the testing.


> diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
> index 996e751..8543898 100644
> --- a/drivers/vhost/vhost.c
> +++ b/drivers/vhost/vhost.c
> @@ -23,6 +23,7 @@
>  #include <linux/highmem.h>
>  #include <linux/slab.h>
>  #include <linux/kthread.h>
> +#include <linux/cgroup.h>
>  
>  #include <linux/net.h>
>  #include <linux/if_packet.h>
> @@ -252,7 +253,7 @@ static long vhost_dev_set_owner(struct vhost_dev *dev)
>  	}
>  
>  	dev->worker = worker;
> -	err = cgroup_attach_task_current_cg(poller);
> +	err = cgroup_attach_task_current_cg(worker);
>  	if (err)
>  		goto err_cgroup;
>  	wake_up_process(worker);	/* avoid contributing to loadavg */
> 

^ permalink raw reply

* vhost mergeable buffers guest's cgroup
From: Michael S. Tsirkin @ 2010-07-28  1:27 UTC (permalink / raw)
  To: Sridhar Samudrala
  Cc: netdev, lkml, kvm@vger.kernel.org, Tejun Heo, Li Zefan, dlstevens

Sridhar, David,
I pushed a mergeable buffers patchset on my vhost-net-next branch,
on top of the threading changes.
 
This is a minimal patch, which in my testing has zero impact on
non-mergeable path.

Please give this a spin and let me know.

Thanks!

-- 
MST

^ permalink raw reply

* Re: vhost mergeable buffers guest's cgroup
From: Michael S. Tsirkin @ 2010-07-28  1:31 UTC (permalink / raw)
  To: Sridhar Samudrala
  Cc: netdev, lkml, kvm@vger.kernel.org, Tejun Heo, Li Zefan, dlstevens
In-Reply-To: <20100728012735.GA23243@redhat.com>

On Wed, Jul 28, 2010 at 04:27:35AM +0300, Michael S. Tsirkin wrote:
> Sridhar, David,
> I pushed a mergeable buffers patchset on my vhost-net-next branch,
> on top of the threading changes.
>  
> This is a minimal patch, which in my testing has zero impact on
> non-mergeable path.
> 
> Please give this a spin and let me know.
> 
> Thanks!

The userspace bits can be found on my qemu-kvm tree at kernel.org,
branch vhost_mergeable.
Please use these for testing.

> -- 
> MST

^ permalink raw reply

* Re: [PATCH net-next] drivers/net/vxge/vxge-main.c: Use pr_<level> and netdev_<level>
From: Jon Mason @ 2010-07-28  3:21 UTC (permalink / raw)
  To: Joe Perches
  Cc: Ramkrishna Vepa, Sreenivasa Honnur, David S. Miller, netdev, LKML
In-Reply-To: <1280267223.24054.44.camel@Joe-Laptop.home>

On Tue, Jul 27, 2010 at 02:47:03PM -0700, Joe Perches wrote:
> Use pr_fmt, pr_<level> and netdev_<level> where appropriate.
> 
> Signed-off-by: Joe Perches <joe@perches.com>

Acked-by: Jon Mason <jon.mason@exar.com>

> ---
>  drivers/net/vxge/vxge-main.c |   27 +++++++++++----------------
>  1 files changed, 11 insertions(+), 16 deletions(-)
> 
> diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
> index 94d87e8..c7c5605 100644
> --- a/drivers/net/vxge/vxge-main.c
> +++ b/drivers/net/vxge/vxge-main.c
> @@ -41,6 +41,8 @@
>  *
>  ******************************************************************************/
>  
> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
> +
>  #include <linux/if_vlan.h>
>  #include <linux/pci.h>
>  #include <linux/slab.h>
> @@ -144,7 +146,7 @@ vxge_callback_link_up(struct __vxge_hw_device *hldev)
>  
>  	vxge_debug_entryexit(VXGE_TRACE, "%s: %s:%d",
>  		vdev->ndev->name, __func__, __LINE__);
> -	printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name);
> +	netdev_notice(vdev->ndev, "Link Up\n");
>  	vdev->stats.link_up++;
>  
>  	netif_carrier_on(vdev->ndev);
> @@ -168,7 +170,7 @@ vxge_callback_link_down(struct __vxge_hw_device *hldev)
>  
>  	vxge_debug_entryexit(VXGE_TRACE,
>  		"%s: %s:%d", vdev->ndev->name, __func__, __LINE__);
> -	printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
> +	netdev_notice(vdev->ndev, "Link Down\n");
>  
>  	vdev->stats.link_down++;
>  	netif_carrier_off(vdev->ndev);
> @@ -2679,7 +2681,7 @@ vxge_open(struct net_device *dev)
>  
>  	if (vxge_hw_device_link_state_get(vdev->devh) == VXGE_HW_LINK_UP) {
>  		netif_carrier_on(vdev->ndev);
> -		printk(KERN_NOTICE "%s: Link Up\n", vdev->ndev->name);
> +		netdev_notice(vdev->ndev, "Link Up\n");
>  		vdev->stats.link_up++;
>  	}
>  
> @@ -2817,7 +2819,7 @@ int do_vxge_close(struct net_device *dev, int do_io)
>  	}
>  
>  	netif_carrier_off(vdev->ndev);
> -	printk(KERN_NOTICE "%s: Link Down\n", vdev->ndev->name);
> +	netdev_notice(vdev->ndev, "Link Down\n");
>  	netif_tx_stop_all_queues(vdev->ndev);
>  
>  	/* Note that at this point xmit() is stopped by upper layer */
> @@ -3844,9 +3846,7 @@ static pci_ers_result_t vxge_io_slot_reset(struct pci_dev *pdev)
>  	struct vxgedev *vdev = netdev_priv(netdev);
>  
>  	if (pci_enable_device(pdev)) {
> -		printk(KERN_ERR "%s: "
> -			"Cannot re-enable device after reset\n",
> -			VXGE_DRIVER_NAME);
> +		netdev_err(netdev, "Cannot re-enable device after reset\n");
>  		return PCI_ERS_RESULT_DISCONNECT;
>  	}
>  
> @@ -3871,9 +3871,8 @@ static void vxge_io_resume(struct pci_dev *pdev)
>  
>  	if (netif_running(netdev)) {
>  		if (vxge_open(netdev)) {
> -			printk(KERN_ERR "%s: "
> -				"Can't bring device back up after reset\n",
> -				VXGE_DRIVER_NAME);
> +			netdev_err(netdev,
> +				   "Can't bring device back up after reset\n");
>  			return;
>  		}
>  	}
> @@ -4430,13 +4429,9 @@ static int __init
>  vxge_starter(void)
>  {
>  	int ret = 0;
> -	char version[32];
> -	snprintf(version, 32, "%s", DRV_VERSION);
>  
> -	printk(KERN_INFO "%s: Copyright(c) 2002-2010 Exar Corp.\n",
> -		VXGE_DRIVER_NAME);
> -	printk(KERN_INFO "%s: Driver version: %s\n",
> -			VXGE_DRIVER_NAME, version);
> +	pr_info("Copyright(c) 2002-2010 Exar Corp.\n");
> +	pr_info("Driver version: %s\n", DRV_VERSION);
>  
>  	verify_bandwidth();
>  
> 
> 

^ permalink raw reply

* Re: [PATCH net-next 0/8] bnx2x: move bnx2x to separate folder and divide to files
From: David Miller @ 2010-07-28  3:36 UTC (permalink / raw)
  To: dmitry; +Cc: netdev, eilong
In-Reply-To: <1280270447.11551.119.camel@lb-tlvb-dmitry>

From: "Dmitry Kravkov" <dmitry@broadcom.com>
Date: Wed, 28 Jul 2010 01:40:47 +0300

> resubmit the series with fixes for git-apply. Thanks

All applied, thanks.

^ permalink raw reply

* Re: [net-next 2/3] stmmac: fix timer setup when use dual mac Kconfig
From: David Miller @ 2010-07-28  3:45 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <1280225387-26240-2-git-send-email-peppe.cavallaro@st.com>

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Tue, 27 Jul 2010 12:09:46 +0200

> The driver erroneously sets the tmrate to zero when the
> TMU initialisation fails. This actually generates problems
> while using the dual GMAC configuration.
> 
> With this patch, enabling both the dual gmac and the timer
> optimisation, the first interface opened will use the tmu
> channel 2, the second one won't be able to use the timer but
> will continue to work without mitigating the interrupts by
> using the external timer (i.e. TMU channel 2).
> 
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>

This is not how we do things.

All of the options that influence the driver should be right next
to the main driver option.

What the platform SOC Kconfig's can do is 'select' those option.

But even better is to get rid of all of these feature Kconfig options,
and communicate the capability in the platform_device probe
information or similar.

^ permalink raw reply

* Re: [net-next 2/3] stmmac: fix timer setup when use dual mac Kconfig
From: David Miller @ 2010-07-28  3:45 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <1280225387-26240-2-git-send-email-peppe.cavallaro@st.com>

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Tue, 27 Jul 2010 12:09:46 +0200

> The driver erroneously sets the tmrate to zero when the
> TMU initialisation fails. This actually generates problems
> while using the dual GMAC configuration.
> 
> With this patch, enabling both the dual gmac and the timer
> optimisation, the first interface opened will use the tmu
> channel 2, the second one won't be able to use the timer but
> will continue to work without mitigating the interrupts by
> using the external timer (i.e. TMU channel 2).
> 
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>

Applied.

^ permalink raw reply

* Re: [net-next 3/3] stmmac: fix automatic PAD/FCS stripping
From: David Miller @ 2010-07-28  3:45 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <1280225387-26240-3-git-send-email-peppe.cavallaro@st.com>

From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Tue, 27 Jul 2010 12:09:47 +0200

> For Simple Ethernet frames (802.2 and 802.3) the GMAC Core
> never strips pad and fcs. This means the ACS has no effect
> on IPv4/6 frames.
> The FL bits, in the RDES0, include the FCS so the driver
> has to remove it in SW.
> For 802.3 frame format with LLC or LLC-SNAP, when set the ACS
> bit, the HW strips both PAD and FCS.
> The FL bits, in the RDES0, actually represents the frame length
> already stripped.
> This patch fixes this logic within the device driver that
> erroneously removed 4byte from 802.3 frames already stripped
> corrupting the payload.
> 
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>

Applied.

^ permalink raw reply

* Re: [net-next 2/3] stmmac: fix timer setup when use dual mac Kconfig
From: David Miller @ 2010-07-28  3:46 UTC (permalink / raw)
  To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <20100727.204528.149852941.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Tue, 27 Jul 2010 20:45:28 -0700 (PDT)

Sorry, I meant to say this in reply to patch #1 not #2 :)

> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Tue, 27 Jul 2010 12:09:46 +0200
> 
>> The driver erroneously sets the tmrate to zero when the
>> TMU initialisation fails. This actually generates problems
>> while using the dual GMAC configuration.
>> 
>> With this patch, enabling both the dual gmac and the timer
>> optimisation, the first interface opened will use the tmu
>> channel 2, the second one won't be able to use the timer but
>> will continue to work without mitigating the interrupts by
>> using the external timer (i.e. TMU channel 2).
>> 
>> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
> 
> This is not how we do things.
> 
> All of the options that influence the driver should be right next
> to the main driver option.
> 
> What the platform SOC Kconfig's can do is 'select' those option.
> 
> But even better is to get rid of all of these feature Kconfig options,
> and communicate the capability in the platform_device probe
> information or similar.
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH v2] ks8842: Support DMA when accessed via timberdale
From: David Miller @ 2010-07-28  3:48 UTC (permalink / raw)
  To: richard.rojfors; +Cc: netdev
In-Reply-To: <1280271421.11916.2.camel@debian>

From: Richard Röjfors <richard.rojfors@pelagicore.com>
Date: Wed, 28 Jul 2010 00:57:01 +0200

> This patch adds support for RX and TX DMA via the DMA API,
> this is only supported when the KS8842 is accessed via timberdale.
> 
> There is no support for DMA on the generic bus interface it self,
> a state machine inside the FPGA is handling RX and TX transfers to/from
> buffers in the FPGA. The host CPU can do DMA to and from these buffers.
> 
> The FPGA has to handle the RX interrupts, so these must be enabled in
> the ks8842 but not in the FPGA. The driver must not disable the RX interrupt
> that would mean that the data transfers into the FPGA buffers would stop.
> 
> The host shall not enable TX interrupts since TX is handled by the FPGA,
> the host is notified by DMA callbacks when transfers are finished.
> 
> Which DMA channels to use are added as parameters in the platform data struct.
> 
> Signed-off-by: Richard Röjfors <richard.rojfors@pelagicore.com>

Applied.

^ permalink raw reply

* Re: [patch -next] ixgbe: potential null dereference
From: David Miller @ 2010-07-28  3:48 UTC (permalink / raw)
  To: jeffrey.t.kirsher
  Cc: error27, jesse.brandeburg, bruce.w.allan, alexander.h.duyck,
	peter.p.waskiewicz.jr, john.ronciak, donald.c.skidmore,
	mallikarjuna.chilakala, e1000-devel, netdev, kernel-janitors
In-Reply-To: <AANLkTim5LGj0KGs-0fGGAka7Fde3=NVVXWYBLbb_kVMs@mail.gmail.com>

From: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Date: Tue, 27 Jul 2010 17:10:02 -0700

> On Tue, Jul 27, 2010 at 03:05, Dan Carpenter <error27@gmail.com> wrote:
>> The e_dev_err() macro dereferences "adapter" which is NULL here.
>>
>> Signed-off-by: Dan Carpenter <error27@gmail.com>
> 
> Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>

Applied.

^ permalink raw reply

* Re: [PATCH net-next 0/8] bnx2x: move bnx2x to separate folder and divide to files
From: David Miller @ 2010-07-28  3:56 UTC (permalink / raw)
  To: dmitry; +Cc: netdev, eilong
In-Reply-To: <20100727.203640.173839576.davem@davemloft.net>

From: David Miller <davem@davemloft.net>
Date: Tue, 27 Jul 2010 20:36:40 -0700 (PDT)

> From: "Dmitry Kravkov" <dmitry@broadcom.com>
> Date: Wed, 28 Jul 2010 01:40:47 +0300
> 
>> resubmit the series with fixes for git-apply. Thanks
> 
> All applied, thanks.

Ummm, so what in the world did you think was going to happen
the next time I try to merge net-2.6 into net-next-2.6?

Any clue what might happen?

Any idea?

Since you not only moved the driver into a new directory,
but also moved functions all over the damn place into new
files too, the bnx2x bug fixes in net-2.6 have to be applied
by hand by me during the merge, bit by bit.

This is one of the millions of reasons I absolutely detest multi-file
drivers, people move crap around, patches from one tree can't easily
be munged into another, etc.

If it's too big to fit in one file, your driver is too damn bloated.
End of story.  Put the thing into one file under drivers/net and
simplify _everyones_ life.

I'm fixing this merge mess up, but I'm very not happy about how
you guys staged this sequence of events.

^ permalink raw reply

* Re: [PATCH v2] macvlan: Fix rx counters update in macvlan_handle_frame()
From: David Miller @ 2010-07-28  4:03 UTC (permalink / raw)
  To: herbert; +Cc: sri, netdev
In-Reply-To: <20100728001404.GA14038@gondor.apana.org.au>

From: Herbert Xu <herbert@gondor.apana.org.au>
Date: Wed, 28 Jul 2010 08:14:04 +0800

> On Tue, Jul 27, 2010 at 12:10:07PM -0700, Sridhar Samudrala wrote:
>> Fix macvlan_handle_frame() to update the rx counters based
>> on the return value of the vlan->receive call.
>> 
>> Updated the patch to not do any packet count drops when the interface
>> is down based on Herber'ts comments.
>> 
>> Signed-off-by: Sridhar Samudrala <sri@us.ibm.com>
> 
> Acked-by: Herbert Xu <herbert@gondor.apana.org.au>

Applied to net-next-2.6, thanks.

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox