* Re: [PATCH 8/8] bridge: Fix netpoll support
From: Herbert Xu @ 2010-06-17 10:55 UTC (permalink / raw)
To: Cong Wang
Cc: Michael S. Tsirkin, Qianfeng Zhang, David S. Miller, netdev,
Stephen Hemminger, Matt Mackall, Paul E. McKenney
In-Reply-To: <4C19FF98.5080105@redhat.com>
On Thu, Jun 17, 2010 at 06:57:28PM +0800, Cong Wang wrote:
>
> Hmm, I get it now. So this helps to fix problem 3)?
Yes, by allocating real netpoll structures for each device that
we're polling, instead of sharing a single one amongst all of
them.
This is also the basis of the solution of the use-after-free bug.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <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
* Re: [PATCH 8/8] bridge: Fix netpoll support
From: Cong Wang @ 2010-06-17 10:57 UTC (permalink / raw)
To: Herbert Xu
Cc: Michael S. Tsirkin, Qianfeng Zhang, David S. Miller, netdev,
Stephen Hemminger, Matt Mackall, Paul E. McKenney
In-Reply-To: <20100617103819.GA1252@gondor.apana.org.au>
On 06/17/10 18:38, Herbert Xu wrote:
> On Tue, Jun 15, 2010 at 06:28:17PM +0800, Cong Wang wrote:
>>
>>> This allows us to do away with the npinfo juggling that caused
>>> problem number 1.
>>>
>>> Incidentally this patch fixes number 2 by bypassing unsafe code
>>> such as multicast snooping and netfilter.
>>
>> Not sure if I understand problem 2) and 3), this patch is not easy
>> to review. So, what's the point of adding ->np to struct net_bridge_port?
>> since we already have p->dev->npinfo->netpoll?
>
> A netpoll_info structure always maps to one and only one net_device
> structure. While each net_device may have multiple netpoll
> structures attached.
>
> You must not share netpoll or netpoll_info structures between
> devices since that breaks other users (netconsole or anything
> else) from attaching to those devices.
>
Thanks for explanation.
Hmm, I get it now. So this helps to fix problem 3)?
^ permalink raw reply
* [PATCH] socketcan: add a driver for FlexCAN controllers.
From: Hans J. Koch @ 2010-06-17 10:52 UTC (permalink / raw)
To: netdev; +Cc: socketcan-core, Sascha Hauer
This adds a driver for FlexCAN based CAN controllers,
e.g. found in Freescale i.MX35 SoCs.
The original version of this driver was posted by Sascha Hauer in July 2009:
http://kerneltrap.org/mailarchive/linux-netdev/2009/7/29/6251621
I took this version, added NAPI support, and fixed some problems found
during testing. Well, here is the result. Please review.
Thanks,
Hans
Signed-off-by: Hans J. Koch <hjk@linutronix.de>
---
drivers/net/can/Kconfig | 6 +
drivers/net/can/Makefile | 1 +
drivers/net/can/flexcan.c | 828 +++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 835 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/can/flexcan.c
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 2c5227c..4250c99 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -73,6 +73,12 @@ config CAN_JANZ_ICAN3
This driver can also be built as a module. If so, the module will be
called janz-ican3.ko.
+config CAN_FLEXCAN
+ tristate "Support for Freescale FLEXCAN based chips"
+ depends on CAN_DEV
+ ---help---
+ Driver for Freescale FlexCAN.
+
source "drivers/net/can/mscan/Kconfig"
source "drivers/net/can/sja1000/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index 9047cd0..0057537 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -16,5 +16,6 @@ obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
obj-$(CONFIG_CAN_BFIN) += bfin_can.o
obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
+obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/flexcan.c b/drivers/net/can/flexcan.c
new file mode 100644
index 0000000..ab00873
--- /dev/null
+++ b/drivers/net/can/flexcan.c
@@ -0,0 +1,828 @@
+/*
+ * FLEXCAN CAN controller driver
+ *
+ * Copyright (C) 2005-2006 Varma Electronics Oy
+ * Copyright (C) 2009 Sascha Hauer, Pengutronix
+ * Copyright (C) 2010 Hans J. Koch <hjk@linutronix.de>
+ *
+ * Based on code originally by Andrey Volkov
+ *
+ * Licensed under the terms of the GPL v2.
+ *
+ */
+
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/if_arp.h>
+#include <linux/if_ether.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
+#include <linux/kernel.h>
+#include <linux/list.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/platform_device.h>
+
+#include <linux/can/dev.h>
+#include <linux/can/error.h>
+#include <linux/can/netlink.h>
+
+#define DRIVER_NAME "flexcan"
+
+#define TX_ECHO_SKB_MAX 1
+#define FLEXCAN_DEF_NAPI_WEIGHT 6
+
+/* FLEXCAN module configuration register (CANMCR) bits */
+#define CANMCR_MDIS (1 << 31)
+#define CANMCR_FRZ (1 << 30)
+#define CANMCR_FEN (1 << 29)
+#define CANMCR_HALT (1 << 28)
+#define CANMCR_NOT_RDY (1 << 27)
+#define CANMCR_SOFTRST (1 << 25)
+#define CANMCR_FRZACK (1 << 24)
+#define CANMCR_SUPV (1 << 23)
+#define CANMCR_SRX_DIS (1 << 17)
+#define CANMCR_MAXMB(x) ((x) & 0x0f)
+#define CANMCR_IDAM_A (0 << 8)
+#define CANMCR_IDAM_B (1 << 8)
+#define CANMCR_IDAM_C (2 << 8)
+
+/* FLEXCAN control register (CANCTRL) bits */
+#define CANCTRL_PRESDIV(x) (((x) & 0xff) << 24)
+#define CANCTRL_RJW(x) (((x) & 0x03) << 22)
+#define CANCTRL_PSEG1(x) (((x) & 0x07) << 19)
+#define CANCTRL_PSEG2(x) (((x) & 0x07) << 16)
+#define CANCTRL_BOFFMSK (1 << 15)
+#define CANCTRL_ERRMSK (1 << 14)
+#define CANCTRL_CLKSRC (1 << 13)
+#define CANCTRL_LPB (1 << 12)
+#define CANCTRL_TWRN_MSK (1 << 11)
+#define CANCTRL_RWRN_MSK (1 << 10)
+#define CANCTRL_SAMP (1 << 7)
+#define CANCTRL_BOFFREC (1 << 6)
+#define CANCTRL_TSYNC (1 << 5)
+#define CANCTRL_LBUF (1 << 4)
+#define CANCTRL_LOM (1 << 3)
+#define CANCTRL_PROPSEG(x) ((x) & 0x07)
+
+/* FLEXCAN error counter register (ERRCNT) bits */
+#define ERRCNT_REXECTR(x) (((x) & 0xff) << 8)
+#define ERRCNT_TXECTR(x) ((x) & 0xff)
+
+/* FLEXCAN error and status register (ERRSTAT) bits */
+#define ERRSTAT_TWRNINT (1 << 17)
+#define ERRSTAT_RWRNINT (1 << 16)
+#define ERRSTAT_BIT1ERR (1 << 15)
+#define ERRSTAT_BIT0ERR (1 << 14)
+#define ERRSTAT_ACKERR (1 << 13)
+#define ERRSTAT_CRCERR (1 << 12)
+#define ERRSTAT_FRMERR (1 << 11)
+#define ERRSTAT_STFERR (1 << 10)
+#define ERRSTAT_TXWRN (1 << 9)
+#define ERRSTAT_RXWRN (1 << 8)
+#define ERRSTAT_IDLE (1 << 7)
+#define ERRSTAT_TXRX (1 << 6)
+#define ERRSTAT_FLTCONF_MASK (3 << 4)
+#define ERRSTAT_FLTCONF_ERROR_ACTIVE (0 << 4)
+#define ERRSTAT_FLTCONF_ERROR_PASSIVE (1 << 4)
+#define ERRSTAT_FLTCONF_ERROR_BUS_OFF (2 << 4)
+#define ERRSTAT_BOFFINT (1 << 2)
+#define ERRSTAT_ERRINT (1 << 1)
+#define ERRSTAT_WAKINT (1 << 0)
+#define ERRSTAT_INT (ERRSTAT_BOFFINT | ERRSTAT_ERRINT | ERRSTAT_TWRNINT | \
+ ERRSTAT_RWRNINT)
+
+/* FLEXCAN interrupt flag register (IFLAG) bits */
+#define IFLAG_BUF(x) (1 << (x))
+#define IFLAG_RX_FIFO_OVERFLOW (1 << 7)
+#define IFLAG_RX_FIFO_WARN (1 << 6)
+#define IFLAG_RX_FIFO_AVAILABLE (1 << 5)
+
+/* FLEXCAN message buffers */
+#define MB_CNT_CODE(x) (((x) & 0xf) << 24)
+#define MB_CNT_SRR (1 << 22)
+#define MB_CNT_IDE (1 << 21)
+#define MB_CNT_RTR (1 << 20)
+#define MB_CNT_LENGTH(x) (((x) & 0xf) << 16)
+#define MB_CNT_TIMESTAMP(x) ((x) & 0xffff)
+
+#define MB_ID_STD (0x7ff << 18)
+#define MB_ID_EXT 0x1fffffff
+#define MB_CODE_MASK 0xf0ffffff
+
+#define TX_ECHO_SKB_MAX 1
+
+/* Structure of the message buffer */
+struct flexcan_mb {
+ u32 can_ctrl;
+ u32 can_id;
+ u32 data[2];
+};
+
+/* Structure of the hardware registers */
+struct flexcan_regs {
+ u32 canmcr; /* 0x00 */
+ u32 canctrl; /* 0x04 */
+ u32 timer; /* 0x08 */
+ u32 reserved1; /* 0x0c */
+ u32 rxgmask; /* 0x10 */
+ u32 rx14mask; /* 0x14 */
+ u32 rx15mask; /* 0x18 */
+ u32 errcnt; /* 0x1c */
+ u32 errstat; /* 0x20 */
+ u32 imask2; /* 0x24 */
+ u32 imask1; /* 0x28 */
+ u32 iflag2; /* 0x2c */
+ u32 iflag1; /* 0x30 */
+ u32 reserved4[19];
+ struct flexcan_mb cantxfg[64];
+};
+
+struct flexcan_priv {
+ struct can_priv can;
+ void __iomem *base;
+
+ struct net_device *dev;
+ struct napi_struct napi;
+ struct clk *clk;
+};
+
+static struct can_bittiming_const flexcan_bittiming_const = {
+ .name = DRIVER_NAME,
+ .tseg1_min = 1,
+ .tseg1_max = 16,
+ .tseg2_min = 2,
+ .tseg2_max = 8,
+ .sjw_max = 4,
+ .brp_min = 1,
+ .brp_max = 256,
+ .brp_inc = 1,
+};
+
+/* Mailboxes 0..7 are for RX FIFO, 8 for TX */
+#define TX_BUF_ID 8
+
+static void disable_mode_on(struct flexcan_regs __iomem *regs)
+{
+ u32 reg = readl(®s->canmcr);
+
+ writel(reg | CANMCR_MDIS, ®s->canmcr);
+ udelay(100);
+}
+
+static void disable_mode_off(struct flexcan_regs __iomem *regs)
+{
+ u32 reg = readl(®s->canmcr);
+
+ writel(reg & ~CANMCR_MDIS, ®s->canmcr);
+ udelay(100);
+}
+
+static int freeze_mode_on(struct flexcan_regs __iomem *regs)
+{
+ u32 reg = readl(®s->canmcr);
+ int timeout = 10000;
+
+ if (reg & CANMCR_FRZACK)
+ return 0;
+
+ writel(reg | CANMCR_FRZ, ®s->canmcr);
+ writel(reg | CANMCR_HALT, ®s->canmcr);
+ while (!(reg & CANMCR_FRZACK)) {
+ if (--timeout < 0)
+ return -EIO;
+ udelay(10);
+ reg = readl(®s->canmcr);
+ }
+ return 0;
+}
+
+static int freeze_mode_off(struct flexcan_regs __iomem *regs)
+{
+ u32 reg = readl(®s->canmcr);
+ int timeout = 10000;
+
+ if (!(reg & CANMCR_FRZACK))
+ return 0;
+
+ writel(reg & ~(CANMCR_FRZ | CANMCR_HALT), ®s->canmcr);
+ while (reg & CANMCR_FRZACK) {
+ if (--timeout < 0)
+ return -EIO;
+ udelay(10);
+ reg = readl(®s->canmcr);
+ }
+ return 0;
+}
+
+static int flexcan_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct can_frame *frame = (struct can_frame *)skb->data;
+ struct flexcan_priv *priv = netdev_priv(dev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 can_id;
+ u32 ctrl = MB_CNT_CODE(0xc) | (frame->can_dlc << 16);
+ u32 reg = readl(®s->canctrl);
+
+ reg = readl(®s->cantxfg[TX_BUF_ID].can_ctrl);
+
+ if (reg != MB_CNT_CODE(0x8))
+ writel(MB_CNT_CODE(0x08), ®s->cantxfg[TX_BUF_ID].can_ctrl);
+
+ netif_stop_queue(dev);
+
+ if (frame->can_id & CAN_EFF_FLAG) {
+ can_id = frame->can_id & CAN_EFF_MASK;
+ ctrl |= MB_CNT_IDE | MB_CNT_SRR;
+ } else {
+ can_id = (frame->can_id & CAN_SFF_MASK) << 18;
+ }
+
+ if (frame->can_id & CAN_RTR_FLAG)
+ ctrl |= MB_CNT_RTR;
+
+ if (frame->can_dlc > 0) {
+ u32 data;
+ data = frame->data[0] << 24;
+ data |= frame->data[1] << 16;
+ data |= frame->data[2] << 8;
+ data |= frame->data[3];
+ writel(data, ®s->cantxfg[TX_BUF_ID].data[0]);
+ }
+ if (frame->can_dlc > 3) {
+ u32 data;
+ data = frame->data[4] << 24;
+ data |= frame->data[5] << 16;
+ data |= frame->data[6] << 8;
+ data |= frame->data[7];
+ writel(data, ®s->cantxfg[TX_BUF_ID].data[1]);
+ }
+
+ writel(can_id, ®s->cantxfg[TX_BUF_ID].can_id);
+ writel(ctrl, ®s->cantxfg[TX_BUF_ID].can_ctrl);
+
+ kfree_skb(skb);
+
+ return NETDEV_TX_OK;
+}
+
+static void flexcan_rx_frame(struct net_device *ndev,
+ struct flexcan_mb __iomem *mb)
+{
+ struct net_device_stats *stats = &ndev->stats;
+ struct sk_buff *skb;
+ struct can_frame *frame;
+ int ctrl, length;
+ u32 id;
+
+ ctrl = readl(&mb->can_ctrl);
+ length = (ctrl >> 16) & 0x0f;
+ if (length > 8) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (!skb) {
+ stats->rx_dropped++;
+ return;
+ }
+
+ frame = (struct can_frame *)skb_put(skb,
+ sizeof(struct can_frame));
+
+ frame->can_dlc = length;
+ id = readl(&mb->can_id);
+
+ if (ctrl & MB_CNT_IDE) {
+ frame->can_id = id & CAN_EFF_MASK;
+ frame->can_id |= CAN_EFF_FLAG;
+ } else {
+ frame->can_id = (id >> 18) & CAN_SFF_MASK;
+ }
+
+ if (ctrl & MB_CNT_RTR)
+ frame->can_id |= CAN_RTR_FLAG;
+
+ if (length > 0) {
+ u32 data = readl(&mb->data[0]);
+ frame->data[0] = (data >> 24) & 0xff;
+ frame->data[1] = (data >> 16) & 0xff;
+ frame->data[2] = (data >> 8) & 0xff;
+ frame->data[3] = data & 0xff;
+ }
+ if (length > 3) {
+ u32 data = readl(&mb->data[1]);
+ frame->data[4] = (data >> 24) & 0xff;
+ frame->data[5] = (data >> 16) & 0xff;
+ frame->data[6] = (data >> 8) & 0xff;
+ frame->data[7] = data & 0xff;
+ }
+
+ stats->rx_packets++;
+ stats->rx_bytes += frame->can_dlc;
+ skb->dev = ndev;
+ skb->protocol = __constant_htons(ETH_P_CAN);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ netif_rx(skb);
+}
+
+static int flexcan_rx_poll(struct napi_struct *napi, int quota)
+{
+ struct net_device *ndev = napi->dev;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 iflags, imask;
+ int num_pkts = 0;
+
+ if (!netif_running(ndev))
+ return 0;
+
+ iflags = readl(®s->iflag1);
+
+ while ((iflags & IFLAG_RX_FIFO_AVAILABLE) && (num_pkts < quota)) {
+ struct flexcan_mb __iomem *mb = ®s->cantxfg[0];
+
+ flexcan_rx_frame(ndev, mb);
+ writel(IFLAG_RX_FIFO_AVAILABLE, ®s->iflag1);
+ readl(®s->timer);
+ num_pkts++;
+ iflags = readl(®s->iflag1);
+ }
+
+ if (num_pkts < quota) {
+ napi_complete(napi);
+ /* Re-enable RX mailbox interrupts */
+ imask = readl(®s->imask1);
+ writel(imask | IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
+ }
+
+ return num_pkts;
+}
+
+static void flexcan_error(struct net_device *ndev, u32 stat)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct net_device_stats *stats = &ndev->stats;
+ enum can_state state = priv->can.state;
+ int error_warning = 0, rx_errors = 0, tx_errors = 0;
+
+ skb = dev_alloc_skb(sizeof(struct can_frame));
+ if (!skb)
+ return;
+
+ skb->dev = ndev;
+ skb->protocol = __constant_htons(ETH_P_CAN);
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ cf = (struct can_frame *)skb_put(skb, sizeof(*cf));
+ memset(cf, 0, sizeof(*cf));
+
+ cf->can_id = CAN_ERR_FLAG;
+ cf->can_dlc = CAN_ERR_DLC;
+
+ if (stat & ERRSTAT_RWRNINT) {
+ error_warning = 1;
+ cf->data[1] |= CAN_ERR_CRTL_RX_WARNING;
+ }
+
+ if (stat & ERRSTAT_TWRNINT) {
+ error_warning = 1;
+ cf->data[1] |= CAN_ERR_CRTL_TX_WARNING;
+ }
+
+ switch ((stat >> 4) & 0x3) {
+ case 0:
+ state = CAN_STATE_ERROR_ACTIVE;
+ break;
+ case 1:
+ state = CAN_STATE_ERROR_PASSIVE;
+ break;
+ default:
+ state = CAN_STATE_BUS_OFF;
+ break;
+ }
+
+ if (stat & ERRSTAT_BOFFINT) {
+ cf->can_id |= CAN_ERR_BUSOFF;
+ state = CAN_STATE_BUS_OFF;
+ }
+
+ if (stat & ERRSTAT_BIT1ERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ }
+
+ if (stat & ERRSTAT_BIT0ERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ }
+
+ if (stat & ERRSTAT_FRMERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ }
+
+ if (stat & ERRSTAT_STFERR) {
+ rx_errors = 1;
+ cf->can_id |= CAN_ERR_PROT | CAN_ERR_BUSERROR;
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ }
+
+
+ if (stat & ERRSTAT_ACKERR) {
+ tx_errors = 1;
+ cf->can_id |= CAN_ERR_ACK;
+ }
+
+ if (state == CAN_STATE_BUS_OFF)
+ can_bus_off(ndev);
+ if (error_warning)
+ priv->can.can_stats.error_warning++;
+ if (rx_errors)
+ stats->rx_errors++;
+ if (tx_errors)
+ stats->tx_errors++;
+
+ priv->can.state = state;
+
+ netif_rx(skb);
+
+ ndev->last_rx = jiffies;
+ stats->rx_packets++;
+ stats->rx_bytes += cf->can_dlc;
+}
+
+static irqreturn_t flexcan_isr(int irq, void *dev_id)
+{
+ struct net_device *ndev = dev_id;
+ struct net_device_stats *stats = &ndev->stats;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 iflags, imask, errstat;
+
+ errstat = readl(®s->errstat);
+ if (errstat & ERRSTAT_INT) {
+ flexcan_error(ndev, errstat);
+ writel(errstat & ERRSTAT_INT, ®s->errstat);
+ }
+
+ iflags = readl(®s->iflag1);
+
+ if (iflags & IFLAG_RX_FIFO_OVERFLOW) {
+ writel(IFLAG_RX_FIFO_OVERFLOW, ®s->iflag1);
+ stats->rx_over_errors++;
+ stats->rx_errors++;
+ }
+
+ if (iflags & (1 << TX_BUF_ID)) {
+ stats->tx_packets++;
+ writel((1 << TX_BUF_ID), ®s->iflag1);
+ netif_wake_queue(ndev);
+ }
+
+ if (iflags & IFLAG_RX_FIFO_AVAILABLE) {
+ /* disable RX interrupts */
+ imask = readl(®s->imask1);
+ writel(imask & ~IFLAG_RX_FIFO_AVAILABLE, ®s->imask1);
+ /* Let NAPI poll received packets */
+ napi_schedule(&priv->napi);
+ }
+
+ return IRQ_HANDLED;
+}
+
+static void init_regs(struct flexcan_regs __iomem *regs)
+{
+ u32 reg;
+ int i;
+
+ freeze_mode_on(regs);
+
+ /* Enable error and bus off interrupt */
+ reg = readl(®s->canctrl);
+ reg |= CANCTRL_CLKSRC | CANCTRL_ERRMSK | CANCTRL_BOFFMSK |
+ CANCTRL_BOFFREC | CANCTRL_TWRN_MSK | CANCTRL_TWRN_MSK;
+ writel(reg, ®s->canctrl);
+
+ /* Set lowest buffer transmitted first */
+ reg |= CANCTRL_LBUF;
+ writel(reg, ®s->canctrl);
+
+ for (i = 0; i < 64; i++) {
+ writel(0, ®s->cantxfg[i].can_ctrl);
+ writel(0, ®s->cantxfg[i].can_id);
+ writel(0, ®s->cantxfg[i].data[0]);
+ writel(0, ®s->cantxfg[i].data[1]);
+
+ /* Put MB into rx queue */
+ writel(MB_CNT_CODE(0x04), ®s->cantxfg[i].can_ctrl);
+ }
+ writel(MB_CNT_CODE(0x08), ®s->cantxfg[TX_BUF_ID].can_ctrl);
+
+ /* acceptance mask/acceptance code (accept everything) */
+ writel(0x0, ®s->rxgmask);
+ writel(0x0, ®s->rx14mask);
+ writel(0x0, ®s->rx15mask);
+
+ reg = readl(®s->canmcr) & ~0x0f;
+ reg |= CANMCR_IDAM_C | CANMCR_FEN | CANMCR_MAXMB(TX_BUF_ID);
+ writel(reg, ®s->canmcr);
+}
+
+static int flexcan_set_bittiming(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct can_bittiming *bt = &priv->can.bittiming;
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ clk_enable(priv->clk);
+
+ disable_mode_on(regs);
+
+ reg = readl(®s->canctrl);
+ reg &= ~(CANCTRL_SAMP | CANCTRL_PRESDIV(0xff) |
+ CANCTRL_PSEG1(7) | CANCTRL_PSEG2(7) |
+ CANCTRL_PROPSEG(7));
+ reg |= CANCTRL_PRESDIV(bt->brp - 1) |
+ CANCTRL_PSEG1(bt->phase_seg1 - 1) |
+ CANCTRL_PSEG2(bt->phase_seg2 - 1) |
+ CANCTRL_RJW(3) |
+ CANCTRL_PROPSEG(bt->prop_seg - 1);
+ if (priv->can.ctrlmode & CAN_CTRLMODE_3_SAMPLES)
+ reg |= CANCTRL_SAMP;
+ writel(reg, ®s->canctrl);
+
+ dev_dbg(&ndev->dev, "flexcan_set_bittiming: canctrl=0x%08x\n", reg);
+
+ clk_disable(priv->clk);
+
+ return 0;
+}
+
+static int flexcan_open(struct net_device *ndev)
+{
+ int ret;
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+
+ clk_enable(priv->clk);
+
+ ret = open_candev(ndev);
+ if (ret)
+ return ret;
+
+ disable_mode_off(regs);
+ init_regs(regs);
+
+ /* Enable flexcan module */
+ freeze_mode_off(regs);
+
+ /* Enable interrupts */
+ writel(IFLAG_RX_FIFO_OVERFLOW | IFLAG_RX_FIFO_AVAILABLE |
+ IFLAG_BUF(TX_BUF_ID),
+ ®s->imask1);
+
+ napi_enable(&priv->napi);
+ netif_start_queue(ndev);
+
+ ret = request_irq(ndev->irq, flexcan_isr, 0, DRIVER_NAME, ndev);
+ if (!ret)
+ return 0;
+
+ close_candev(ndev);
+ return ret;
+}
+
+static int flexcan_close(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+
+ netif_stop_queue(ndev);
+ napi_disable(&priv->napi);
+
+ /* Disable all interrupts */
+ writel(0, ®s->imask1);
+ free_irq(ndev->irq, ndev);
+
+ close_candev(ndev);
+
+ /* Disable module */
+ disable_mode_on(regs);
+ clk_disable(priv->clk);
+ return 0;
+}
+
+static int flexcan_set_mode(struct net_device *ndev, enum can_mode mode)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ switch (mode) {
+ case CAN_MODE_START:
+ reg = readl(®s->canctrl);
+ reg &= ~CANCTRL_BOFFREC;
+ writel(reg, ®s->canctrl);
+ reg |= CANCTRL_BOFFREC;
+ writel(reg, ®s->canctrl);
+ priv->can.state = CAN_STATE_ERROR_ACTIVE;
+
+ if (netif_queue_stopped(ndev))
+ netif_wake_queue(ndev);
+ break;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+
+ return 0;
+}
+
+static const struct net_device_ops flexcan_netdev_ops = {
+ .ndo_open = flexcan_open,
+ .ndo_stop = flexcan_close,
+ .ndo_start_xmit = flexcan_start_xmit,
+};
+
+static int register_flexcandev(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ /* Ensure clock is enabled so we can access registers */
+ clk_enable(priv->clk);
+ reg = readl(®s->canmcr);
+ reg &= ~CANMCR_MDIS;
+ reg |= CANMCR_FEN;
+ writel(reg, ®s->canmcr);
+ init_regs(regs);
+ udelay(100);
+
+ reg = readl(®s->canmcr);
+ clk_disable(priv->clk);
+
+ /* Currently we only support newer versions of this core featuring
+ * a RX FIFO. Older cores found on some Coldfire derivates are not
+ * yet supported.
+ */
+ if (!(reg & CANMCR_FEN)) {
+ dev_err(&ndev->dev, "Could not enable RX FIFO, unsupported "
+ "core");
+ return -ENODEV;
+ }
+
+ ndev->flags |= IFF_ECHO; /* we support local echo in hardware */
+ ndev->netdev_ops = &flexcan_netdev_ops;
+
+ return register_candev(ndev);
+}
+
+static void unregister_flexcandev(struct net_device *ndev)
+{
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct flexcan_regs __iomem *regs = priv->base;
+ u32 reg;
+
+ clk_enable(priv->clk);
+ reg = readl(®s->canmcr);
+ reg |= CANMCR_FRZ | CANMCR_HALT | CANMCR_MDIS;
+ writel(reg, ®s->canmcr);
+ clk_disable(priv->clk);
+
+ unregister_candev(ndev);
+}
+
+static int __devinit flexcan_probe(struct platform_device *pdev)
+{
+ struct resource *mem;
+ struct net_device *ndev;
+ struct flexcan_priv *priv;
+ u32 mem_size;
+ int ret;
+
+ ndev = alloc_candev(sizeof(struct flexcan_priv), TX_ECHO_SKB_MAX);
+ if (!ndev) {
+ dev_err(&pdev->dev, "flexcan: alloc_candev failed.\n");
+ return -ENOMEM;
+ }
+
+ priv = netdev_priv(ndev);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ ndev->irq = platform_get_irq(pdev, 0);
+ if (!mem || !ndev->irq) {
+ dev_err(&pdev->dev, "flexcan: mem || irq failed.\n");
+ ret = -ENODEV;
+ goto failed_req;
+ }
+
+ mem_size = resource_size(mem);
+
+ if (!request_mem_region(mem->start, mem_size, DRIVER_NAME)) {
+ dev_err(&pdev->dev, "flexcan: request_mem_region failed.\n");
+ ret = -EBUSY;
+ goto failed_req;
+ }
+
+ SET_NETDEV_DEV(ndev, &pdev->dev);
+
+ priv->base = ioremap(mem->start, mem_size);
+ if (!priv->base) {
+ dev_err(&pdev->dev, "flexcan: ioremap failed.\n");
+ ret = -ENOMEM;
+ goto failed_map;
+ }
+
+ priv->clk = clk_get(&pdev->dev, NULL);
+ if (IS_ERR(priv->clk)) {
+ dev_err(&pdev->dev, "flexcan: clk_get failed.\n");
+ ret = PTR_ERR(priv->clk);
+ goto failed_clock;
+ }
+ priv->can.clock.freq = clk_get_rate(priv->clk);
+
+ platform_set_drvdata(pdev, ndev);
+
+ priv->can.do_set_bittiming = flexcan_set_bittiming;
+ priv->can.bittiming_const = &flexcan_bittiming_const;
+ priv->can.do_set_mode = flexcan_set_mode;
+ priv->can.restart_ms = 500;
+
+ netif_napi_add(ndev, &priv->napi, flexcan_rx_poll,
+ FLEXCAN_DEF_NAPI_WEIGHT);
+
+ ret = register_flexcandev(ndev);
+ if (ret) {
+ dev_err(&pdev->dev, "flexcan: register_flexcandev failed.\n");
+ goto failed_register;
+ }
+
+ dev_info(&pdev->dev, "flexcan: probe() succeeded...\n");
+ return 0;
+
+failed_register:
+ clk_put(priv->clk);
+failed_clock:
+ iounmap(priv->base);
+failed_map:
+ release_mem_region(mem->start, mem_size);
+failed_req:
+ free_candev(ndev);
+
+ return ret;
+}
+
+static int __devexit flexcan_remove(struct platform_device *pdev)
+{
+ struct net_device *ndev = platform_get_drvdata(pdev);
+ struct flexcan_priv *priv = netdev_priv(ndev);
+ struct resource *mem;
+
+ unregister_flexcandev(ndev);
+ netif_napi_del(&priv->napi);
+ platform_set_drvdata(pdev, NULL);
+ iounmap(priv->base);
+ clk_put(priv->clk);
+
+ mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ release_mem_region(mem->start, resource_size(mem));
+ free_candev(ndev);
+
+ return 0;
+}
+
+static struct platform_driver flexcan_driver = {
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+ .probe = flexcan_probe,
+ .remove = __devexit_p(flexcan_remove),
+};
+
+static int __init flexcan_init(void)
+{
+ return platform_driver_register(&flexcan_driver);
+}
+
+static void __exit flexcan_exit(void)
+{
+ platform_driver_unregister(&flexcan_driver);
+}
+
+module_init(flexcan_init);
+module_exit(flexcan_exit);
+
+MODULE_AUTHOR("Hans J. Koch <hjk@linutronix.de>");
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("SocketCAN driver for FlexCAN based chips");
--
1.6.3.3
^ permalink raw reply related
* Re: [Patch 2/2] mlx4: add dynamic LRO disable support
From: Cong Wang @ 2010-06-17 10:54 UTC (permalink / raw)
To: Stanislaw Gruszka; +Cc: Ben Hutchings, netdev, herbert.xu, nhorman, davem
In-Reply-To: <20100615113926.30d0cd01@dhcp-lab-109.englab.brq.redhat.com>
On 06/15/10 17:39, Stanislaw Gruszka wrote:
> On Tue, 15 Jun 2010 16:53:27 +0800
> Cong Wang<amwang@redhat.com> wrote:
>
>>> If so, it's better to stop device before modify LRO settings. I suggest
>>> something like that in mlx4_ethtool_op_set_flags:
>>>
>>> if (!!(data& ETH_FLAG_LRO) != !!(dev->features& NETIF_F_LRO)) {
>>
>> What does this line mean? This is to ignore all other flags, right?
>
> Yes, plus check if we are really changing current settings.
>
>>> /* Need to toggle LRO */
>>>
>>> if (netdev_running(dev)) {
>>> mutex_lock(&mdev->state_lock);
>>> mlx4_en_stop_port(dev);
>>> rc = mlx4_en_start_port(dev);
>>> if (rc)
>>> en_err(priv, "Failed to restart port\n");
>>> }
>>>
>>> dev->features ^= NETIF_F_LRO;
>>>
>>> if (netdev_running(dev))
>>> mutex_unlock(&mdev->state_lock);
>>> }
>>>
>>
>> I don't think mdev->state_lock is used to protect dev->feature.
>> rtnl_lock is. I think switching to mlx4_ethtool_op_set_flags()
>> from the default one has already solved this.
>
> Ahh, you have right, may intention was use it to stop and start
> port. Code rather should look like below:
>
> if (netdev_running(dev)) {
> mutex_lock(&mdev->state_lock);
> mlx4_en_stop_port(dev);
> }
>
> dev->features ^= NETIF_F_LRO;
>
> if (netdev_running(dev)) {
> rc = mlx4_en_start_port(dev);
> mutex_unlock(&mdev->state_lock);
> if (rc)
> en_err(priv, "Failed to restart port\n");
> }
>
Hmm, you mean ->features should be changed after port is stopped?
Why?
^ permalink raw reply
* Re: [v2 Patch 2/2] mlx4: add dynamic LRO disable support
From: Cong Wang @ 2010-06-17 10:48 UTC (permalink / raw)
To: Stanislaw Gruszka
Cc: David Miller, netdev, nhorman, herbert.xu, bhutchings,
Ramkrishna.Vepa
In-Reply-To: <20100615121414.26056d15@dhcp-lab-109.englab.brq.redhat.com>
On 06/15/10 18:14, Stanislaw Gruszka wrote:
> On Tue, 15 Jun 2010 16:35:35 +0800
> Cong Wang<amwang@redhat.com> wrote:
>>> BTW: seems default ethtool_op_set_flags introduce a bug on many
>>> devices regarding ETH_FLAG_RXHASH. I think default should
>>> be EOPNOTSUPP, and these few devices that actually support RXHASH
>>> should have custom ethtool_ops->set_flags
>>
>> Hmm, you mean this?
>>
>> if (data& ETH_FLAG_RXHASH)
>> + if (!ops->set_flags)
>> + return -EOPNOTSUPP;
>> ....
>
> Not really, but I do not have good idea how patch with fix should
> looks.
>
> I dislike fact that we setup ->feature that are not in real supported by
> particular device instead of returning EOPNOTSUPP. This actually include
> both flags NETIF_F_LRO and NETIF_F_RXHASH.
>
> Perhaps ethtool_op_set_flags should be removed and drivers should use
> only custom version. In particular seems e1000e and sfc use this
> function improperly and should have NULL as .set_flags.
This depends on if what ethtool_op_set_flags() does is common for
net drivers.
>
> I will think more about that and maybe cook some patches.
>
Yes, please. Cc me when you post patches.
Thanks.
^ permalink raw reply
* Re: [PATCH 8/8] bridge: Fix netpoll support
From: Herbert Xu @ 2010-06-17 10:38 UTC (permalink / raw)
To: Cong Wang
Cc: Michael S. Tsirkin, Qianfeng Zhang, David S. Miller, netdev,
Stephen Hemminger, Matt Mackall, Paul E. McKenney
In-Reply-To: <4C1755C1.3060804@redhat.com>
On Tue, Jun 15, 2010 at 06:28:17PM +0800, Cong Wang wrote:
>
>> This allows us to do away with the npinfo juggling that caused
>> problem number 1.
>>
>> Incidentally this patch fixes number 2 by bypassing unsafe code
>> such as multicast snooping and netfilter.
>
> Not sure if I understand problem 2) and 3), this patch is not easy
> to review. So, what's the point of adding ->np to struct net_bridge_port?
> since we already have p->dev->npinfo->netpoll?
A netpoll_info structure always maps to one and only one net_device
structure. While each net_device may have multiple netpoll
structures attached.
You must not share netpoll or netpoll_info structures between
devices since that breaks other users (netconsole or anything
else) from attaching to those devices.
Cheers,
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <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
* RE: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)
From: Eric Dumazet @ 2010-06-17 10:28 UTC (permalink / raw)
To: Vladislav Zolotarov
Cc: Arnd Bergmann, Patrick McHardy, Pedro Garcia,
netdev@vger.kernel.org, Ben Hutchings
In-Reply-To: <8628FE4E7912BF47A96AE7DD7BAC0AADDDC69DDE7E@SJEXCHCCR02.corp.ad.broadcom.com>
Le jeudi 17 juin 2010 à 01:56 -0700, Vladislav Zolotarov a écrit :
>
> > -----Original Message-----
> > From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
> > Behalf Of Eric Dumazet
> > Sent: Wednesday, June 16, 2010 9:58 PM
> > To: Arnd Bergmann
> > Cc: Patrick McHardy; Pedro Garcia; netdev@vger.kernel.org; Ben Hutchings
> > Subject: Re: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag"
> > (802.1p packet)
> >
> > Le mercredi 16 juin 2010 à 20:26 +0200, Arnd Bergmann a écrit :
> > > On Wednesday 16 June 2010 17:28:23 Patrick McHardy wrote:
> > >
> > > > Since we don't have any special VLAN handling in the bridging code, I
> > > > guess it comes down to optionally using a different ethertype value
> > > > (0x88a8) in the VLAN code. We probably also need some indication from
> > > > device drivers whether they are able to add these headers to avoid
> > > > trying to offload tagging in case they're not.
> > >
> > > It's probably a little more than just supporting the new ethertype, but not
> > > much. The outer tag can be handled like our current VLAN module does,
> > > but the standard does not allow a regular frame to be encapsulated
> > directly,
> > > but rather requires one of
> > >
> > > 1. In 802.1ad: an 802.1Q VLAN tag (ethertype 0x8100) followed by the frame
> > > 2. In 802.1ah: A service tag (ethertype 0x88e7) followed by the 802.1Q VLAN
> > tag
> > > and then the frame.
> > >
> > > Maybe what we can do is extend the vlan code to understand all three frame
> > > formats (q, ad and ah) or at least the first two so we configure both the
> > > provider VID and the Customer VID for the interface in case of 802.1ad but
> > > only the regular VID in 802.1Q.
> > >
> > > Device drivers can then flag whether they support both formats or just
> > > the regular Q tag.
> > >
> > > Arnd
> >
> > Speaking of device drivers, I see bnx2 (hardware accelerated) is able to
> > insert a 8021q tag in case no vlgrp is defined (the 8201q tag that was
> > removed by NIC)... interesting ping pong games, since our 8021q stack
> > will remove it again, eventually.
> >
> > So VLAN 0 'problem' on bnx2 could be solved with following patch
> > (avoiding this insert if vtag==0)
> >
> >
> >
> > diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> > index 522de9f..b5d4d05 100644
> > --- a/drivers/net/bnx2.c
> > +++ b/drivers/net/bnx2.c
> > @@ -3192,7 +3192,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi,
> > int budget)
> > hw_vlan = 1;
> > else
> > #endif
> > - {
> > + if (vtag) {
> > struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
> > __skb_push(skb, 4);
> >
> >
> >
> > --
>
> This way u will loose all the priority information that was on the VLAN header.
16bits vtag = 0 : there is no priority information.
^ permalink raw reply
* Re: [0/8] netpoll/bridge fixes
From: Michael S. Tsirkin @ 2010-06-17 10:18 UTC (permalink / raw)
To: Paul E. McKenney
Cc: David Miller, herbert, eric.dumazet, shemminger, frzhang, netdev,
amwang, mpm
In-Reply-To: <20100616230249.GJ2457@linux.vnet.ibm.com>
On Wed, Jun 16, 2010 at 04:02:49PM -0700, Paul E. McKenney wrote:
> On Tue, Jun 15, 2010 at 09:47:02PM -0700, David Miller wrote:
> > From: Herbert Xu <herbert@gondor.apana.org.au>
> > Date: Wed, 16 Jun 2010 13:33:36 +1000
> >
> > > On Wed, Jun 16, 2010 at 05:03:20AM +0200, Eric Dumazet wrote:
> > >>
> > >> I wonder how these patches were tested, Herbert ?
> > >
> > > You know, not everyone enables RCU debugging...
> >
> > Even though I'm as guilty as you, I have to agree with Eric that
> > especially us core folks should be running with the various lock
> > debugging options on all the time.
> >
> > Maybe someone should add the RCU debugging config option to
> > Documentation/SubmitChecklist :-)
>
> How about the following added to Documentation/RCU/checklist.txt?
>
> The first is in mainline, the second partly there, and the third
> is still languishing in my tree. I did manage to remove a dependency
> on other maintainers, so things will hopefully move a bit faster.
>
> Thanx, Paul
>
> diff --git a/Documentation/RCU/checklist.txt b/Documentation/RCU/checklist.txt
> index 790d1a8..c7c6788 100644
> --- a/Documentation/RCU/checklist.txt
> +++ b/Documentation/RCU/checklist.txt
> @@ -365,3 +365,26 @@ over a rather long period of time, but improvements are always welcome!
> and the compiler to freely reorder code into and out of RCU
> read-side critical sections. It is the responsibility of the
> RCU update-side primitives to deal with this.
> +
> +17. Use CONFIG_PROVE_RCU, CONFIG_DEBUG_OBJECTS_RCU_HEAD, and
> + the __rcu sparse checks to validate your RCU code. These
> + can help find problems as follows:
> +
> + CONFIG_PROVE_RCU: check that accesses to RCU-protected data
> + structures are carried out under the proper RCU
> + read-side critical section, while holding the right
> + combination of locks, or whatever other conditions
> + are appropriate.
> +
> + CONFIG_DEBUG_OBJECTS_RCU_HEAD: check that you don't pass the
> + same object to call_rcu() (or friends) before an RCU
> + grace period has elapsed since the last time that you
> + passed that same object to call_rcu() (or friends).
> +
Cool, will this also work with synchronize etc?
> + __rcu sparse checks: tag the pointer to the RCU-protected data
> + structure with __rcu, and sparse will warn you if you
> + access that pointer without the services of one of the
> + variants of rcu_dereference().
> +
> + These debugging aids can help you find problems that are
> + otherwise extremely difficult to spot.
^ permalink raw reply
* Re: [net-next-2.6 PATCH] net: consolidate netif_needs_gso() checks
From: Herbert Xu @ 2010-06-17 10:18 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: davem, netdev, gospo, bphilips, John Fastabend
In-Reply-To: <20100617001804.5155.30862.stgit@localhost.localdomain>
On Wed, Jun 16, 2010 at 05:18:12PM -0700, Jeff Kirsher wrote:
> From: John Fastabend <john.r.fastabend@intel.com>
>
> netif_needs_gso() is checked twice in the TX path once,
> before submitting the skb to the qdisc and once after
> it is dequeued from the qdisc just before calling
> ndo_hard_start(). This opens a window for a user to
> change the gso/tso or tx checksum settings that can
> cause netif_needs_gso to be true in one check and false
> in the other.
>
> Specifically, changing TX checksum setting may cause
> the warning in skb_gso_segment() to be triggered if
> the checksum is calculated earlier.
>
> This consolidates the netif_needs_gso() calls so that
> the stack only checks if gso is needed in
> dev_hard_start_xmit().
>
> Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
> Cc: Herbert Xu <herbert@gondor.apana.org.au>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Acked-by: Herbert Xu <herbert@gondor.apana.org.au>
Thanks!
--
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <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
* Re: IPv6 stops working after ethtool diagnostic
From: Shan Wei @ 2010-06-17 9:51 UTC (permalink / raw)
To: Tantilov, Emil S
Cc: netdev@vger.kernel.org, Stephen Hemminger, davem@davemloft.net,
Pieper, Jeffrey E, Kirsher, Jeffrey T
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A1365FF43AAD0F@rrsmsx501.amr.corp.intel.com>
Tantilov, Emil S wrote, at 06/16/2010 02:05 AM:
> We ran into a problem on net-next where IPv6 traffic fails after running ethtool -t:
When you execute "ethtool -t" or "ifdown", the router entry to fec0::1314 will be
deleted.
Try to add the router using the following command:
#ip -6 route add fec0::1314 dev eth1
--
Best Regards
-----
Shan Wei
^ permalink raw reply
* [RFC][BUG-FIX] the problem of checksum checking in UDP protocol
From: Shan Wei @ 2010-06-17 9:09 UTC (permalink / raw)
To: David Miller, Ronciak, John, netdev@vger.kernel.org
Cc: Eric Dumazet, Shan Wei
*Description of Problem*
When received an UDP packet, if the length parameter in UDP header is less than
the actual length of payload(including 8 bytes UDP header), and checksum parameter
is calculated including all payload, some NIC devices that supports hardware checksum
success to check checksum, and set ip_summed with CHECKSUM_UNNECESSARY flag.
But If we turn off rx-checksumming offload, UDP protocol failed to check the checksum.
*Step to Reproduce*
We need to download netwib&netwox tools and then install them only on M1 node.
On M1 node, execute the below steps.
M1 M2
+---------------------------+ +---------------------------+
| eth1 |<---------------> |eth0 |
|fe80::225:86ff:fe9d:3efa | |fe80::215:17ff:fe71:51f4 |
+---------------------------+ +---------------------------+
1. netwox 149 -i fe80::215:17ff:fe71:51f4 -d eth1 -E 0:0:0:0:1:0 -e 0:15:17:71:51:f4 -I fe80::200:ff:fe00:100 -c 1
This step is to create neighbor cache for spurious source address of fe80::200:ff:fe00:100.
2. netwox 141 -d eth1 -a 0:0:0:0:1:0 -b 0:15:17:71:51:f4 -f 17 -g 64 -h fe80::200:ff:fe00:100 -i fe80::215:17ff:fe71:51f4 \
-o 3333 -p 7 -q 000000000000000000000000000000000000000000000000 -r 34525 -e 32 -s 16 -t 35126
This step is to construct an UDPv6 packet that length field(16 bytes) less than total payload length(32 bytes).
The readable format of this packet that netwox shows.
Ethernet________________________________________________________.
| 00:00:00:00:01:00->00:15:17:71:51:F4 type:0x86DD |
|_______________________________________________________________|
IP______________________________________________________________.
|version| traffic class | flow label |
|___6___|_______0_______|___________________0___________________|
| payload length | next header | hop limit |
|___________0x0020=32___________|____0x11=17____|______64_______|
| source |
|_____________________fe80::200:ff:fe00:100_____________________|
| destination |
|___________________fe80::215:17ff:fe71:51f4____________________|
UDP_____________________________________________________________.
| source port | destination port |
|__________0x0D05=3333__________|___________0x0007=7____________|
| length | checksum |
|___________0x0010=16___________|_________0x8936=35126__________|
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # ................
00 00 00 00 00 00 00 00 # ........
*Actual Results*
On M2 note, using ethtool to see the counter about rx_csum_offload.
#ethtool -S eth0 | grep csum
rx_csum_offload_good: 1
rx_csum_offload_errors: 0
#cat /proc/net/snmp6 | grep Udp6
Udp6InDatagrams 1
Udp6InErrors 0
*Expected Results*
#ethtool -S eth0 | grep csum
rx_csum_offload_good: 0
rx_csum_offload_errors: 1
#cat /proc/net/snmp6 | grep Udp6
Udp6InDatagrams 0
Udp6InErrors 1
*The Reason*
UDPv6 handles a received packet like this:
1. Confirm length of data
If length parameter in UDPv6 header is greater than skb->len(actual data length added UDP header),
the packet will be dropped. If length parameter in UDPv6 header is lower than skb->len, the data
will be trimmed to be equal to length parameter.
2. Then UDPv6 calculates checksum with 40 bytes IPv6 pseudo-header,8 bytes UDPv6 header, 8 bytes
Payload Data. Note that checksum(35126) in UDPv6 header includes 16 bytes redundant data.
NIC checks checksum with total data includes redundant data, So the checksum that hardware calculated
is different from that UDP did.
*The Solution*
We have reported the problem to Intel E1000e developer, the reply from Ronciak John is that
the driver code of e1000e is ok.
About the discuss, see http://comments.gmane.org/gmane.linux.drivers.e1000.devel/7077
For this case, UDP protocol should not trust the CHECKSUM_UNNECESSARY flag set by driver.
When UDP protocol received this kind of packet, if NIC hardware checked successfully,
we reset ip_summed with CHECKSUM_NONE, and UDP protocol checked checksum again.
(This patch is not complete, it's just for my idea.)
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 1dd1aff..47f7e86 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -723,6 +723,10 @@ int __udp6_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,
if (ulen < skb->len) {
if (pskb_trim_rcsum(skb, ulen))
goto short_packet;
+
+ if (skb_csum_unnecessary(skb))
+ skb->ip_summed = CHECKSUM_NONE;
+
saddr = &ipv6_hdr(skb)->saddr;
daddr = &ipv6_hdr(skb)->daddr;
uh = udp_hdr(skb);
^ permalink raw reply related
* Re: [PATCH] hso: remove setting of low_latency flag
From: Filip Aben @ 2010-06-17 9:03 UTC (permalink / raw)
To: davem, gregkh; +Cc: linux-usb, netdev
In-Reply-To: <alpine.DEB.2.00.1006111100250.6812@filip-linux>
Hi all,
Did the patch below get accepted or is there a problem with it ?
Haven't seen it appearing in any git trees so far.
Thanks,
Filip-
On Fri, 2010-06-11 at 11:17 +0200, f.aben@option.com wrote:
> This patch removes the setting of the low_latency flag.
> tty_flip_buffer_push() is occasionally being called in irq context, which
> causes a hang if the low_latency flag is set.
> Removing the low_latency flag only seems to impact the flush to ldisc,
> which will now be put on a workqueue.
>
> Signed-off-by: Filip Aben <f.aben@option.com>
>
> ---
>
> diff --git a/drivers/net/usb/hso.c b/drivers/net/usb/hso.c
> index 0a3c41f..4dd2351 100644
> --- a/drivers/net/usb/hso.c
> +++ b/drivers/net/usb/hso.c
> @@ -1334,7 +1334,6 @@ static int hso_serial_open(struct tty_struct *tty, struct file *filp)
> /* check for port already opened, if not set the termios */
> serial->open_count++;
> if (serial->open_count == 1) {
> - tty->low_latency = 1;
> serial->rx_state = RX_IDLE;
> /* Force default termio settings */
> _hso_serial_set_termios(tty, NULL);
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" 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
* [PATCH v2 2/2] broadcom: Add 5241 support
From: Dmitry Eremin-Solenikov @ 2010-06-17 9:02 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Matt Carlson, Michael Chan
In-Reply-To: <1276765344-12675-1-git-send-email-dbaryshkov@gmail.com>
This patch adds the 5241 PHY ID to the broadcom module.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/net/phy/broadcom.c | 22 ++++++++++++++++++++++
include/linux/brcmphy.h | 1 +
2 files changed, 23 insertions(+), 0 deletions(-)
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index b743d37..4accd83 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -834,6 +834,21 @@ static struct phy_driver bcmac131_driver = {
.driver = { .owner = THIS_MODULE },
};
+static struct phy_driver bcm5241_driver = {
+ .phy_id = PHY_ID_BCM5241,
+ .phy_id_mask = 0xfffffff0,
+ .name = "Broadcom BCM5241",
+ .features = PHY_BASIC_FEATURES |
+ SUPPORTED_Pause | SUPPORTED_Asym_Pause,
+ .flags = PHY_HAS_MAGICANEG | PHY_HAS_INTERRUPT,
+ .config_init = brcm_fet_config_init,
+ .config_aneg = genphy_config_aneg,
+ .read_status = genphy_read_status,
+ .ack_interrupt = brcm_fet_ack_interrupt,
+ .config_intr = brcm_fet_config_intr,
+ .driver = { .owner = THIS_MODULE },
+};
+
static int __init broadcom_init(void)
{
int ret;
@@ -868,8 +883,13 @@ static int __init broadcom_init(void)
ret = phy_driver_register(&bcmac131_driver);
if (ret)
goto out_ac131;
+ ret = phy_driver_register(&bcm5241_driver);
+ if (ret)
+ goto out_5241;
return ret;
+out_5241:
+ phy_driver_unregister(&bcmac131_driver);
out_ac131:
phy_driver_unregister(&bcm57780_driver);
out_57780:
@@ -894,6 +914,7 @@ out_5411:
static void __exit broadcom_exit(void)
{
+ phy_driver_unregister(&bcm5241_driver);
phy_driver_unregister(&bcmac131_driver);
phy_driver_unregister(&bcm57780_driver);
phy_driver_unregister(&bcm50610m_driver);
@@ -920,6 +941,7 @@ static struct mdio_device_id broadcom_tbl[] = {
{ PHY_ID_BCM50610M, 0xfffffff0 },
{ PHY_ID_BCM57780, 0xfffffff0 },
{ PHY_ID_BCMAC131, 0xfffffff0 },
+ { PHY_ID_BCM5241, 0xfffffff0 },
{ }
};
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index c14c3a1..b840a49 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -1,5 +1,6 @@
#define PHY_ID_BCM50610 0x0143bd60
#define PHY_ID_BCM50610M 0x0143bd70
+#define PHY_ID_BCM5241 0x0143bc30
#define PHY_ID_BCMAC131 0x0143bc70
#define PHY_ID_BCM5481 0x0143bca0
#define PHY_ID_BCM5482 0x0143bcb0
--
1.7.1
^ permalink raw reply related
* [PATCH v2 1/2] broadcom: move all PHY_ID's to header
From: Dmitry Eremin-Solenikov @ 2010-06-17 9:02 UTC (permalink / raw)
To: netdev; +Cc: David S. Miller, Matt Carlson, Michael Chan
Move all PHY IDs to brcmphy.h header for completeness and unification of code.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
drivers/net/phy/broadcom.c | 24 ++++++++++++------------
include/linux/brcmphy.h | 6 ++++++
2 files changed, 18 insertions(+), 12 deletions(-)
diff --git a/drivers/net/phy/broadcom.c b/drivers/net/phy/broadcom.c
index cecdbbd..b743d37 100644
--- a/drivers/net/phy/broadcom.c
+++ b/drivers/net/phy/broadcom.c
@@ -685,7 +685,7 @@ static int brcm_fet_config_intr(struct phy_device *phydev)
}
static struct phy_driver bcm5411_driver = {
- .phy_id = 0x00206070,
+ .phy_id = PHY_ID_BCM5411,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5411",
.features = PHY_GBIT_FEATURES |
@@ -700,7 +700,7 @@ static struct phy_driver bcm5411_driver = {
};
static struct phy_driver bcm5421_driver = {
- .phy_id = 0x002060e0,
+ .phy_id = PHY_ID_BCM5421,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5421",
.features = PHY_GBIT_FEATURES |
@@ -715,7 +715,7 @@ static struct phy_driver bcm5421_driver = {
};
static struct phy_driver bcm5461_driver = {
- .phy_id = 0x002060c0,
+ .phy_id = PHY_ID_BCM5461,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5461",
.features = PHY_GBIT_FEATURES |
@@ -730,7 +730,7 @@ static struct phy_driver bcm5461_driver = {
};
static struct phy_driver bcm5464_driver = {
- .phy_id = 0x002060b0,
+ .phy_id = PHY_ID_BCM5464,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5464",
.features = PHY_GBIT_FEATURES |
@@ -745,7 +745,7 @@ static struct phy_driver bcm5464_driver = {
};
static struct phy_driver bcm5481_driver = {
- .phy_id = 0x0143bca0,
+ .phy_id = PHY_ID_BCM5481,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5481",
.features = PHY_GBIT_FEATURES |
@@ -760,7 +760,7 @@ static struct phy_driver bcm5481_driver = {
};
static struct phy_driver bcm5482_driver = {
- .phy_id = 0x0143bcb0,
+ .phy_id = PHY_ID_BCM5482,
.phy_id_mask = 0xfffffff0,
.name = "Broadcom BCM5482",
.features = PHY_GBIT_FEATURES |
@@ -910,12 +910,12 @@ module_init(broadcom_init);
module_exit(broadcom_exit);
static struct mdio_device_id broadcom_tbl[] = {
- { 0x00206070, 0xfffffff0 },
- { 0x002060e0, 0xfffffff0 },
- { 0x002060c0, 0xfffffff0 },
- { 0x002060b0, 0xfffffff0 },
- { 0x0143bca0, 0xfffffff0 },
- { 0x0143bcb0, 0xfffffff0 },
+ { PHY_ID_BCM5411, 0xfffffff0 },
+ { PHY_ID_BCM5421, 0xfffffff0 },
+ { PHY_ID_BCM5461, 0xfffffff0 },
+ { PHY_ID_BCM5464, 0xfffffff0 },
+ { PHY_ID_BCM5482, 0xfffffff0 },
+ { PHY_ID_BCM5482, 0xfffffff0 },
{ PHY_ID_BCM50610, 0xfffffff0 },
{ PHY_ID_BCM50610M, 0xfffffff0 },
{ PHY_ID_BCM57780, 0xfffffff0 },
diff --git a/include/linux/brcmphy.h b/include/linux/brcmphy.h
index 7f437ca..c14c3a1 100644
--- a/include/linux/brcmphy.h
+++ b/include/linux/brcmphy.h
@@ -1,6 +1,12 @@
#define PHY_ID_BCM50610 0x0143bd60
#define PHY_ID_BCM50610M 0x0143bd70
#define PHY_ID_BCMAC131 0x0143bc70
+#define PHY_ID_BCM5481 0x0143bca0
+#define PHY_ID_BCM5482 0x0143bcb0
+#define PHY_ID_BCM5411 0x00206070
+#define PHY_ID_BCM5421 0x002060e0
+#define PHY_ID_BCM5464 0x002060b0
+#define PHY_ID_BCM5461 0x002060c0
#define PHY_ID_BCM57780 0x03625d90
#define PHY_BCM_OUI_MASK 0xfffffc00
--
1.7.1
^ permalink raw reply related
* RE: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)
From: Vladislav Zolotarov @ 2010-06-17 8:56 UTC (permalink / raw)
To: Eric Dumazet, Arnd Bergmann
Cc: Patrick McHardy, Pedro Garcia, netdev@vger.kernel.org,
Ben Hutchings
In-Reply-To: <1276714691.2970.9.camel@edumazet-laptop>
> -----Original Message-----
> From: netdev-owner@vger.kernel.org [mailto:netdev-owner@vger.kernel.org] On
> Behalf Of Eric Dumazet
> Sent: Wednesday, June 16, 2010 9:58 PM
> To: Arnd Bergmann
> Cc: Patrick McHardy; Pedro Garcia; netdev@vger.kernel.org; Ben Hutchings
> Subject: Re: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag"
> (802.1p packet)
>
> Le mercredi 16 juin 2010 à 20:26 +0200, Arnd Bergmann a écrit :
> > On Wednesday 16 June 2010 17:28:23 Patrick McHardy wrote:
> >
> > > Since we don't have any special VLAN handling in the bridging code, I
> > > guess it comes down to optionally using a different ethertype value
> > > (0x88a8) in the VLAN code. We probably also need some indication from
> > > device drivers whether they are able to add these headers to avoid
> > > trying to offload tagging in case they're not.
> >
> > It's probably a little more than just supporting the new ethertype, but not
> > much. The outer tag can be handled like our current VLAN module does,
> > but the standard does not allow a regular frame to be encapsulated
> directly,
> > but rather requires one of
> >
> > 1. In 802.1ad: an 802.1Q VLAN tag (ethertype 0x8100) followed by the frame
> > 2. In 802.1ah: A service tag (ethertype 0x88e7) followed by the 802.1Q VLAN
> tag
> > and then the frame.
> >
> > Maybe what we can do is extend the vlan code to understand all three frame
> > formats (q, ad and ah) or at least the first two so we configure both the
> > provider VID and the Customer VID for the interface in case of 802.1ad but
> > only the regular VID in 802.1Q.
> >
> > Device drivers can then flag whether they support both formats or just
> > the regular Q tag.
> >
> > Arnd
>
> Speaking of device drivers, I see bnx2 (hardware accelerated) is able to
> insert a 8021q tag in case no vlgrp is defined (the 8201q tag that was
> removed by NIC)... interesting ping pong games, since our 8021q stack
> will remove it again, eventually.
>
> So VLAN 0 'problem' on bnx2 could be solved with following patch
> (avoiding this insert if vtag==0)
>
>
>
> diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
> index 522de9f..b5d4d05 100644
> --- a/drivers/net/bnx2.c
> +++ b/drivers/net/bnx2.c
> @@ -3192,7 +3192,7 @@ bnx2_rx_int(struct bnx2 *bp, struct bnx2_napi *bnapi,
> int budget)
> hw_vlan = 1;
> else
> #endif
> - {
> + if (vtag) {
> struct vlan_ethhdr *ve = (struct vlan_ethhdr *)
> __skb_push(skb, 4);
>
>
>
> --
This way u will loose all the priority information that was on the VLAN header.
> 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: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: Michael Chan @ 2010-06-17 6:24 UTC (permalink / raw)
To: 'davem@davemloft.net', 'Paul Mundt'
Cc: 'Mike Frysinger', James Bottomley, netdev@vger.kernel.org,
linux-parisc@vger.kernel.org, linux-kernel@vger.kernel.org,
FUJITA Tomonori
In-Reply-To: <C27F8246C663564A84BB7AB3439772421B79CBCA1D@IRVEXCHCCR01.corp.ad.broadcom.com>
Michael Chan wrote:
>
> Paul Mundt wrote:
>
> > If you want to have a micro-optimization for the consistent DMA
> > case, you can check dma_is_consistent(), which is part of the API and
> > will be variable on certain platform configurations (ie, some may be
> > consistent with PCI but not on other busses, etc.)
> >
> >
>
> Thanks for the tip. I didn't know about the dma_is_consistent() API.
> I'll use this to fix it then.
>
David, why is dma_is_consistent() always returning 1 on sparc? The
streaming DMA is not consistent.
^ permalink raw reply
* RE: mpd client timeouts (bisected) 2.6.35-rc3
From: Shi, Alex @ 2010-06-17 5:16 UTC (permalink / raw)
To: Fastabend, John R, David Miller, markus@trippelsdorf.de
Cc: linux-kernel@vger.kernel.org, netdev@vger.kernel.org,
yanmin_zhang@linux.intel.com, Chen, Tim C
In-Reply-To: <4C15414E.5090201@intel.com>
It fixed the aim7/specjbb2005 issues!
Tested-by: Alex Shi <alex.shi@intel.com>
Regards!
Alex
>
>Needed to set the wcard bit in copy_skb_header otherwise it will not be cleared
>when called from skb_clone. Which then hits the loopback device gets pushed
>into the rx path and is eventually dropped. The following patch fixes this.
>Hopefully, this is easy and fast enough for you Dave.
>
>
>[PATCH] net: fix deliver_no_wcard regression on loopback device
>
>deliver_no_wcard is not being set in skb_copy_header.
>In the skb_cloned case it is not being cleared and
>may cause the skb to be dropped when the loopback device
>pushes it back up the stack.
>
>Signed-off-by: John Fastabend <john.r.fastabend@intel.com>
>---
>
> net/core/skbuff.c | 1 +
> 1 files changed, 1 insertions(+), 0 deletions(-)
>
>diff --git a/net/core/skbuff.c b/net/core/skbuff.c
>index 9f07e74..bcf2fa3 100644
>--- a/net/core/skbuff.c
>+++ b/net/core/skbuff.c
>@@ -532,6 +532,7 @@ static void __copy_skb_header(struct sk_buff *new, const
>struct sk_buff *old)
> new->ip_summed = old->ip_summed;
> skb_copy_queue_mapping(new, old);
> new->priority = old->priority;
>+ new->deliver_no_wcard = old->deliver_no_wcard;
> #if defined(CONFIG_IP_VS) || defined(CONFIG_IP_VS_MODULE)
> new->ipvs_property = old->ipvs_property;
> #endif
^ permalink raw reply
* Re: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: James Bottomley @ 2010-06-17 4:20 UTC (permalink / raw)
To: Michael Chan
Cc: 'Mike Frysinger', netdev@vger.kernel.org,
linux-parisc@vger.kernel.org, linux-kernel@vger.kernel.org,
FUJITA Tomonori
In-Reply-To: <C27F8246C663564A84BB7AB3439772421B79CBCA1C@IRVEXCHCCR01.corp.ad.broadcom.com>
On Wed, 2010-06-16 at 20:53 -0700, Michael Chan wrote:
> Mike Frysinger wrote:
>
> > On Wed, Jun 16, 2010 at 9:13 PM, James Bottomley wrote:
> > > I'm not quite sure whose fault this one is.
> > >
> > > However, this code in bnx2.c:
> > >
> > > if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) {
> > > next_rx_buf =
> > > &rxr->rx_buf_ring[
> > > RX_RING_IDX(NEXT_RX_BD(sw_cons))];
> > > prefetch(next_rx_buf->desc);
> > > }
> > >
> > > Looks remarkably fragile: what exactly is it trying to do?
>
> If sync_single is not defined, that means the CPU has a consistent
> view of next_rx_buf and so it makes sense to prefetch it.
That's not entirely a correct statement. Many architectures make a DMA
area coherent by turning off the CPU cache over it. In that case,
prefetching makes absolutely no sense (although it usually works but is
a nop).
> > > The commit that causes the problem:
> > >
> > > commit a33fa66bcf365ffe5b79d1ae1d3582cc261ae56e
> > > Author: Michael Chan <mchan@broadcom.com>
> > > Date: Thu May 6 08:58:13 2010 +0000
> > >
> > > bnx2: Add prefetches to rx path.
> > >
> > > Looks fairly innocuous by the description.
> > >
> > > Should parisc have a get_dma_ops()? We don't need one
> > because our dma
> > > ops are per platform not per bus.
> >
> > looks like it'll be broken on more than just parisc:
> > $ grep get_dma_ops arch/*/include/asm/ -rl | cut -d/ -f 2
> > alpha
> > ia64
> > microblaze
> > powerpc
> > sh
> > sparc
> > x86
>
> Most of these archs use the dma functions in:
>
> <asm-genric/dma-mapping-common.h>
>
> so it's not a problem.
Parisc begs to differ.
Plus you're making assumptions about the contents of the ops structure
which is an internal architecture object ... that's bound to run into
portability problems even if we make it compile on all platform.
> I think I'll send in a patch to remove that part of the code
> from bnx2.c for now.
I think that's the best solution.
James
^ permalink raw reply
* Re: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: Michael Chan @ 2010-06-17 4:10 UTC (permalink / raw)
To: 'Paul Mundt'
Cc: 'Mike Frysinger', James Bottomley, netdev@vger.kernel.org,
linux-parisc@vger.kernel.org, linux-kernel@vger.kernel.org,
FUJITA Tomonori
In-Reply-To: <20100617040356.GA8105@linux-sh.org>
Paul Mundt wrote:
> On Wed, Jun 16, 2010 at 08:53:57PM -0700, Michael Chan wrote:
> > If sync_single is not defined, that means the CPU has a consistent
> > view of next_rx_buf and so it makes sense to prefetch it.
> >
> Except that's not a valid assertion, there are platforms that
> implement
> it for sanity checks yet still have consistent DMA. You are making
> inherently non-portable assumptions for a PCI driver, which is a good
> example of why drivers should never be side-stepping the API
> in the first
> place. If you want to have a micro-optimization for the consistent DMA
> case, you can check dma_is_consistent(), which is part of the API and
> will be variable on certain platform configurations (ie, some may be
> consistent with PCI but not on other busses, etc.)
>
>
Thanks for the tip. I didn't know about the dma_is_consistent() API.
I'll use this to fix it then.
^ permalink raw reply
* Re: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: Paul Mundt @ 2010-06-17 4:03 UTC (permalink / raw)
To: Michael Chan
Cc: 'Mike Frysinger', James Bottomley, netdev@vger.kernel.org,
linux-parisc@vger.kernel.org, linux-kernel@vger.kernel.org,
FUJITA Tomonori
In-Reply-To: <C27F8246C663564A84BB7AB3439772421B79CBCA1C@IRVEXCHCCR01.corp.ad.broadcom.com>
On Wed, Jun 16, 2010 at 08:53:57PM -0700, Michael Chan wrote:
> Mike Frysinger wrote:
>
> > On Wed, Jun 16, 2010 at 9:13 PM, James Bottomley wrote:
> > > I'm not quite sure whose fault this one is.
> > >
> > > However, this code in bnx2.c:
> > >
> > > if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) {
> > > next_rx_buf =
> > > &rxr->rx_buf_ring[
> > > RX_RING_IDX(NEXT_RX_BD(sw_cons))];
> > > prefetch(next_rx_buf->desc);
> > > }
> > >
> > > Looks remarkably fragile: what exactly is it trying to do?
>
> If sync_single is not defined, that means the CPU has a consistent
> view of next_rx_buf and so it makes sense to prefetch it.
>
Except that's not a valid assertion, there are platforms that implement
it for sanity checks yet still have consistent DMA. You are making
inherently non-portable assumptions for a PCI driver, which is a good
example of why drivers should never be side-stepping the API in the first
place. If you want to have a micro-optimization for the consistent DMA
case, you can check dma_is_consistent(), which is part of the API and
will be variable on certain platform configurations (ie, some may be
consistent with PCI but not on other busses, etc.)
^ permalink raw reply
* Re: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: Mike Frysinger @ 2010-06-17 4:00 UTC (permalink / raw)
To: Michael Chan
Cc: James Bottomley, netdev@vger.kernel.org,
linux-parisc@vger.kernel.org, linux-kernel@vger.kernel.org,
FUJITA Tomonori
In-Reply-To: <C27F8246C663564A84BB7AB3439772421B79CBCA1C@IRVEXCHCCR01.corp.ad.broadcom.com>
On Wed, Jun 16, 2010 at 11:53 PM, Michael Chan wrote:
> Mike Frysinger wrote:
>> > The commit that causes the problem:
>> >
>> > commit a33fa66bcf365ffe5b79d1ae1d3582cc261ae56e
>> > Author: Michael Chan <mchan@broadcom.com>
>> > Date: Thu May 6 08:58:13 2010 +0000
>> >
>> > bnx2: Add prefetches to rx path.
>> >
>> > Looks fairly innocuous by the description.
>> >
>> > Should parisc have a get_dma_ops()? We don't need one
>> because our dma
>> > ops are per platform not per bus.
>>
>> looks like it'll be broken on more than just parisc:
>> $ grep get_dma_ops arch/*/include/asm/ -rl | cut -d/ -f 2
>> alpha
>> ia64
>> microblaze
>> powerpc
>> sh
>> sparc
>> x86
>
> Most of these archs use the dma functions in:
>
> <asm-genric/dma-mapping-common.h>
>
> so it's not a problem.
the grep is showing only the arches that define get_dma_ops (and so
the new code works). you'd have to invert the list to see the ones
which do not define get_dma_ops(), and the inverted list is larger.
that was merely my point.
-mike
^ permalink raw reply
* Re: bnx2 fails to compile on parisc because of missing get_dma_ops()
From: Michael Chan @ 2010-06-17 3:53 UTC (permalink / raw)
To: 'Mike Frysinger', James Bottomley
Cc: netdev@vger.kernel.org, linux-parisc@vger.kernel.org,
linux-kernel@vger.kernel.org, FUJITA Tomonori
In-Reply-To: <AANLkTilSfOwwT87mgDcWBogL4gPnM7VBTOALKpZv_upN@mail.gmail.com>
Mike Frysinger wrote:
> On Wed, Jun 16, 2010 at 9:13 PM, James Bottomley wrote:
> > I'm not quite sure whose fault this one is.
> >
> > However, this code in bnx2.c:
> >
> > if (!get_dma_ops(&pdev->dev)->sync_single_for_cpu) {
> > next_rx_buf =
> > &rxr->rx_buf_ring[
> > RX_RING_IDX(NEXT_RX_BD(sw_cons))];
> > prefetch(next_rx_buf->desc);
> > }
> >
> > Looks remarkably fragile: what exactly is it trying to do?
If sync_single is not defined, that means the CPU has a consistent
view of next_rx_buf and so it makes sense to prefetch it.
> >
> > The commit that causes the problem:
> >
> > commit a33fa66bcf365ffe5b79d1ae1d3582cc261ae56e
> > Author: Michael Chan <mchan@broadcom.com>
> > Date: Thu May 6 08:58:13 2010 +0000
> >
> > bnx2: Add prefetches to rx path.
> >
> > Looks fairly innocuous by the description.
> >
> > Should parisc have a get_dma_ops()? We don't need one
> because our dma
> > ops are per platform not per bus.
>
> looks like it'll be broken on more than just parisc:
> $ grep get_dma_ops arch/*/include/asm/ -rl | cut -d/ -f 2
> alpha
> ia64
> microblaze
> powerpc
> sh
> sparc
> x86
Most of these archs use the dma functions in:
<asm-genric/dma-mapping-common.h>
so it's not a problem.
I think I'll send in a patch to remove that part of the code
from bnx2.c for now.
Thanks.
^ permalink raw reply
* Re: ftp on udp and tcp .
From: Narendra Choyal @ 2010-06-17 2:31 UTC (permalink / raw)
To: Ben Hutchings; +Cc: ratheesh k, netdev, linux-net
In-Reply-To: <1276602615.14011.464.camel@localhost>
TCP handles segmentation and bandwidth/congestion management. It
recovers from packet loss and reordering. Recent implementations are
also quite resilient to address spoofing. The downsides are higher
latency (potentially very high when recovering from packet loss), higher
setup cost (3-way handshake), and lack of multicast support.
UDP does none of that. It gives you flexibility and control, but the
downside is you have to handle all of those problems yourself.
Its nice but.
Initial checking of availability for both active port & passive port.
^ permalink raw reply
* [PATCH] sky2: enable rx/tx in sky2_phy_reinit()
From: Brandon Philips @ 2010-06-17 2:21 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev, davem
sky2_phy_reinit is called by the ethtool helpers sky2_set_settings,
sky2_nway_reset and sky2_set_pauseparam when netif_running.
However, at the end of sky2_phy_init GM_GP_CTRL has GM_GPCR_RX_ENA and
GM_GPCR_TX_ENA cleared. So, doing these commands causes the device to
stop working:
$ ethtool -r eth0
$ ethtool -A eth0 autoneg off
Fix this issue by enabling Rx/Tx after running sky2_phy_init in
sky2_phy_reinit.
Signed-off-by: Brandon Philips <bphilips@suse.de>
Tested-by: Brandon Philips <bphilips@suse.de>
Cc: stable@kernel.org
---
drivers/net/sky2.c | 19 ++++++++++++++-----
1 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c
index 2111c7b..7985165 100644
--- a/drivers/net/sky2.c
+++ b/drivers/net/sky2.c
@@ -717,11 +717,24 @@ static void sky2_phy_power_down(struct sky2_hw *hw, unsigned port)
sky2_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
}
+/* Enable Rx/Tx */
+static void sky2_enable_rx_tx(struct sky2_port *sky2)
+{
+ struct sky2_hw *hw = sky2->hw;
+ unsigned port = sky2->port;
+ u16 reg;
+
+ reg = gma_read16(hw, port, GM_GP_CTRL);
+ reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
+ gma_write16(hw, port, GM_GP_CTRL, reg);
+}
+
/* Force a renegotiation */
static void sky2_phy_reinit(struct sky2_port *sky2)
{
spin_lock_bh(&sky2->phy_lock);
sky2_phy_init(sky2->hw, sky2->port);
+ sky2_enable_rx_tx(sky2);
spin_unlock_bh(&sky2->phy_lock);
}
@@ -2040,7 +2053,6 @@ static void sky2_link_up(struct sky2_port *sky2)
{
struct sky2_hw *hw = sky2->hw;
unsigned port = sky2->port;
- u16 reg;
static const char *fc_name[] = {
[FC_NONE] = "none",
[FC_TX] = "tx",
@@ -2048,10 +2060,7 @@ static void sky2_link_up(struct sky2_port *sky2)
[FC_BOTH] = "both",
};
- /* enable Rx/Tx */
- reg = gma_read16(hw, port, GM_GP_CTRL);
- reg |= GM_GPCR_RX_ENA | GM_GPCR_TX_ENA;
- gma_write16(hw, port, GM_GP_CTRL, reg);
+ sky2_enable_rx_tx(sky2);
gm_phy_write(hw, port, PHY_MARV_INT_MASK, PHY_M_DEF_MSK);
--
1.7.1
^ permalink raw reply related
* Re: iputils flowlabel
From: YOSHIFUJI Hideaki @ 2010-06-17 2:20 UTC (permalink / raw)
To: Jiri Skala; +Cc: netdev
In-Reply-To: <1272444708.3035.39.camel@localhost.localdomain>
Jiri Skala wrote:
> I'd like to ask about current state of FLOWLABEL functionality. This is
> currently wrapped into define and disabled by default.
>
> Trying to enable it means to define (somehow = in proprietary header)
> in6_flowlabel_req structure because usage of linux/in6.h conflicts with
> glibc's headers.
>
> Is flowlabel fnc inside ifdef due to described 'header' issue? Any other
> comment to this topic?
Yes, that's right.
--yoshfuji
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox