* Re: [PATCH 2/6] unicore32: add pkunity-v3 mac/net driver (umal)
From: Arnd Bergmann @ 2011-05-26 12:43 UTC (permalink / raw)
To: GuanXuetao; +Cc: linux-kernel, linux-arch, greg, netdev
In-Reply-To: <556924396ee34f4af94a2f03767973f1cec35e22.1306408804.git.gxt@mprc.pku.edu.cn>
On Thursday 26 May 2011, GuanXuetao wrote:
> From: Guan Xuetao <gxt@mprc.pku.edu.cn>
>
> Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
No objections to this driver, just remember that network drivers should
go through the netdev tree, and if it wasn't in there before the merge
window, you missed your chance for this time.
^ permalink raw reply
* [patch] net/core/filter.c: Fix build error
From: Ingo Molnar @ 2011-05-26 12:31 UTC (permalink / raw)
To: Joe Perches
Cc: Ben Greear, linux-kernel, linux-arch, David S. Miller,
Arnd Bergmann, netdev
In-Reply-To: <efa062542c692c3f7743bf2d97b5987ab989e27e.1305999731.git.joe@perches.com>
* Joe Perches <joe@perches.com> wrote:
> A mis-configured filter can spam the logs with lots of stack traces.
>
> Rate-limit the warnings and add printout of the bogus filter information.
>
> Original-patch-by: Ben Greear <greearb@candelatech.com>
> Signed-off-by: Joe Perches <joe@perches.com>
> ---
> net/core/filter.c | 4 +++-
> 1 files changed, 3 insertions(+), 1 deletions(-)
>
> diff --git a/net/core/filter.c b/net/core/filter.c
> index 0eb8c44..0e3622f 100644
> --- a/net/core/filter.c
> +++ b/net/core/filter.c
> @@ -350,7 +350,9 @@ load_b:
> continue;
> }
> default:
> - WARN_ON(1);
> + WARN_RATELIMIT(1, "Unknown code:%u jt:%u tf:%u k:%u\n",
> + fentry->code, fentry->jt,
> + fentry->jf, fentry->k);
> return 0;
> }
This change (now upstream) fails to build in about 20% of all
randconfigs. Fix is below.
Thanks,
Ingo
--------------------->
From b658026bc4915d16ff3e0f59b0edda11dbd6b991 Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Thu, 26 May 2011 14:11:14 +0200
Subject: [PATCH] net/core/filter.c: Fix build error
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Fix:
net/core/filter.c:353:4: error: invalid storage class for function ‘DEFINE_RATELIMIT_STATE’
Signed-off-by: Ingo Molnar <mingo@elte.hu>
---
net/core/filter.c | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)
diff --git a/net/core/filter.c b/net/core/filter.c
index 0e3622f..36f975f 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -38,6 +38,7 @@
#include <asm/unaligned.h>
#include <linux/filter.h>
#include <linux/reciprocal_div.h>
+#include <linux/ratelimit.h>
/* No hurry in this branch */
static void *__load_pointer(const struct sk_buff *skb, int k, unsigned int size)
^ permalink raw reply related
* [PATCH 2/6] unicore32: add pkunity-v3 mac/net driver (umal)
From: GuanXuetao @ 2011-05-26 11:36 UTC (permalink / raw)
To: arnd; +Cc: Guan Xuetao, linux-kernel, linux-arch, greg, netdev
In-Reply-To: <cover.1306408804.git.gxt@mprc.pku.edu.cn>
From: Guan Xuetao <gxt@mprc.pku.edu.cn>
Signed-off-by: Guan Xuetao <gxt@mprc.pku.edu.cn>
---
MAINTAINERS | 1 +
arch/unicore32/configs/debug_defconfig | 2 +-
drivers/net/Kconfig | 5 +
drivers/net/Makefile | 1 +
drivers/net/mac-puv3.c | 1942 ++++++++++++++++++++++++++++++++
5 files changed, 1950 insertions(+), 1 deletions(-)
create mode 100644 drivers/net/mac-puv3.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 6ff33ec..4e0b495 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -4930,6 +4930,7 @@ F: drivers/input/serio/i8042-unicore32io.h
F: drivers/i2c/busses/i2c-puv3.c
F: drivers/video/fb-puv3.c
F: drivers/rtc/rtc-puv3.c
+F: drivers/net/mac-puv3.c
PMC SIERRA MaxRAID DRIVER
M: Anil Ravindranath <anil_ravindranath@pmc-sierra.com>
diff --git a/arch/unicore32/configs/debug_defconfig b/arch/unicore32/configs/debug_defconfig
index 9b9c251..69b002c 100644
--- a/arch/unicore32/configs/debug_defconfig
+++ b/arch/unicore32/configs/debug_defconfig
@@ -64,7 +64,6 @@ CONFIG_I2C_BATTERY_BQ27200=n
CONFIG_I2C_EEPROM_AT24=n
CONFIG_LCD_BACKLIGHT=n
-CONFIG_PUV3_UMAL=y
CONFIG_PUV3_MUSB=n
CONFIG_PUV3_AC97=n
CONFIG_PUV3_NAND=n
@@ -101,6 +100,7 @@ CONFIG_SATA_VIA=y
# Network device support
CONFIG_NETDEVICES=y
CONFIG_NET_ETHERNET=y
+CONFIG_MAC_PUV3=y
CONFIG_NETDEV_1000=y
# Wireless LAN
CONFIG_WLAN_80211=n
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 19f04a3..8f8e82d 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2023,6 +2023,11 @@ config LANTIQ_ETOP
help
Support for the MII0 inside the Lantiq SoC
+config MAC_PUV3
+ tristate "PKUnity v3 UMAL Gigabit Network Adapter support"
+ depends on UNICORE32 && ARCH_PUV3
+ select MII
+ select PHYLIB
source "drivers/net/fs_enet/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 209fbb7..4c96359 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -148,6 +148,7 @@ obj-$(CONFIG_NE_H8300) += ne-h8300.o
obj-$(CONFIG_AX88796) += ax88796.o
obj-$(CONFIG_BCM63XX_ENET) += bcm63xx_enet.o
obj-$(CONFIG_FTMAC100) += ftmac100.o
+obj-$(CONFIG_MAC_PUV3) += mac-puv3.o
obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o
obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o
diff --git a/drivers/net/mac-puv3.c b/drivers/net/mac-puv3.c
new file mode 100644
index 0000000..d5163a5
--- /dev/null
+++ b/drivers/net/mac-puv3.c
@@ -0,0 +1,1942 @@
+/*
+ * Code specific to PKUnity SoC and UniCore ISA
+ *
+ * Maintained by GUAN Xue-tao <gxt@mprc.pku.edu.cn>
+ * Copyright (C) 2001-2010 Guan Xuetao
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/bug.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/timer.h>
+#include <linux/errno.h>
+#include <linux/ioport.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/init.h>
+#include <linux/bitops.h>
+#include <linux/err.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/phy.h>
+#include <linux/platform_device.h>
+#include <linux/cache.h>
+#include <linux/io.h>
+
+#include <mach/hardware.h>
+
+MODULE_DESCRIPTION("PKUNITY-3 SoC Ethernet driver");
+MODULE_LICENSE("GPL v2");
+
+/**********************************************************************
+ * Globals
+ ********************************************************************* */
+static const char umal_string[] = "PKUnity-v3-UMAL";
+static const char umal_mdio_string[] = "umal-mdio";
+
+/**********************************************************************
+ * Simple types
+ ********************************************************************* */
+enum umal_speed {
+ umal_speed_none = 0,
+ umal_speed_10 = SPEED_10,
+ umal_speed_100 = SPEED_100,
+ umal_speed_1000 = SPEED_1000,
+};
+
+enum umal_duplex {
+ umal_duplex_none = -1,
+ umal_duplex_half = DUPLEX_HALF,
+ umal_duplex_full = DUPLEX_FULL,
+};
+
+enum umal_fc {
+ umal_fc_none,
+ umal_fc_disabled,
+ umal_fc_frame,
+ umal_fc_collision,
+ umal_fc_carrier,
+};
+
+enum umal_state {
+ umal_state_uninit,
+ umal_state_off,
+ umal_state_on,
+ umal_state_broken,
+};
+
+/**********************************************************************
+ * Macros
+ ********************************************************************* */
+#define UMALDMA_NEXTBUF(d, f) ((((d)->f+1) == (d)->umaldma_dscrtable_end) ? \
+ (d)->umaldma_dscrtable : (d)->f+1)
+
+#define DMA_RX 0
+#define DMA_TX 1
+
+#define UMAL_MAX_TXDESCR 256
+#define UMAL_MAX_RXDESCR 256
+
+#define ETHER_ADDR_LEN 6
+#define ENET_PACKET_SIZE 1518
+
+/* Time in jiffies before concluding the transmitter is hung. */
+#define TX_TIMEOUT (2*HZ)
+
+/**********************************************************************
+ * DMA Descriptor structure
+ ********************************************************************* */
+struct umaldmadscr {
+ dma_addr_t PacketStartAddr;
+ int PacketSize;
+ dma_addr_t NextDescriptor;
+ struct umaldmadscr *NextDescriptor_Virt;
+};
+
+/**********************************************************************
+ * DMA Controller structure
+ ********************************************************************* */
+struct umaldma {
+ /*
+ * This stuff is used to identify the channel and the registers
+ * associated with it.
+ */
+ /* back pointer to associated MAC */
+ struct umal_softc *umaldma_eth;
+ /* direction (1=transmit) */
+ int umaldma_txdir;
+ /* total # of descriptors in ring */
+ int umaldma_maxdescr;
+ /*
+ * This stuff is for maintenance of the ring
+ */
+ /* base of descriptor table */
+ struct umaldmadscr *umaldma_dscrtable;
+ void *umaldma_dscrtable_unaligned;
+ /* and also the phys addr */
+ dma_addr_t umaldma_dscrtable_phys;
+ /* and also the phys addr */
+ dma_addr_t umaldma_dscrtable_phys_unaligned;
+ /* end of descriptor table */
+ struct umaldmadscr *umaldma_dscrtable_end;
+ /* context table, one per descr */
+ struct sk_buff **umaldma_ctxtable;
+ /* next dscr for sw to add */
+ struct umaldmadscr *umaldma_addptr;
+ /* next dscr for sw to remove */
+ struct umaldmadscr *umaldma_remptr;
+};
+
+/**********************************************************************
+ * Ethernet softc structure
+ ********************************************************************* */
+struct umal_softc {
+ /* Linux-specific things */
+ struct net_device *umal_dev; /* pointer to linux device */
+ int umal_idx;
+ struct phy_device *phy_dev; /* the associated PHY device */
+ struct mii_bus *mii_bus; /* the MII bus */
+ int phy_irq[PHY_MAX_ADDR];
+ spinlock_t umal_lock; /* spin lock */
+ int umal_devflags; /* current device flags */
+
+ /* Controller-specific things */
+ enum umal_state umal_state; /* current state */
+ unsigned char umal_hwaddr[ETHER_ADDR_LEN];
+
+ enum umal_speed umal_speed; /* current speed */
+ enum umal_duplex umal_duplex; /* current duplex */
+ enum umal_fc umal_fc; /* cur. flow control setting */
+ int umal_pause; /* current pause setting */
+ int umal_link; /* current link state */
+
+ struct umaldma umal_rxdma; /* rx dma channel */
+ struct umaldma umal_txdma; /* tx dma channel */
+};
+
+/**********************************************************************
+ * Prototypes
+ ********************************************************************* */
+static int umal_mii_reset(struct mii_bus *bus);
+static int umal_mii_read(struct mii_bus *bus, int phyaddr, int regidx);
+static int umal_mii_write(struct mii_bus *bus, int phyaddr, int regidx,
+ u16 val);
+static int umal_mii_probe(struct net_device *dev);
+
+static void umaldma_initctx(struct umaldma *d, struct umal_softc *s,
+ int rxtx, int maxdescr);
+static void umaldma_uninitctx(struct umaldma *d);
+static void umaldma_channel_start(struct umaldma *d, int rxtx);
+static void umaldma_channel_stop(struct umaldma *d);
+static int umaldma_add_rcvbuffer(struct umal_softc *sc, struct umaldma *d,
+ struct sk_buff *m);
+static int umaldma_add_txbuffer(struct umaldma *d, struct sk_buff *m);
+static void umaldma_emptyring(struct umaldma *d);
+static void umaldma_fillring(struct umal_softc *sc, struct umaldma *d);
+static int umaldma_rx_process(struct umal_softc *sc, struct umaldma *d,
+ int work_to_do, int poll);
+static void umaldma_tx_process(struct umal_softc *sc, struct umaldma *d,
+ int poll);
+
+static int umal_initctx(struct umal_softc *s);
+static void umal_uninitctx(struct umal_softc *s);
+static void umal_channel_start(struct umal_softc *s);
+static void umal_channel_stop(struct umal_softc *s);
+static enum umal_state umal_set_channel_state(struct umal_softc *,
+ enum umal_state);
+
+static int umal_init(struct platform_device *pldev, long long base);
+static int umal_open(struct net_device *dev);
+static int umal_close(struct net_device *dev);
+static int umal_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
+static irqreturn_t umal_intr(int irq, void *dev_instance);
+static void umal_clr_intr(struct net_device *dev);
+static int umal_start_tx(struct sk_buff *skb, struct net_device *dev);
+static void umal_tx_timeout(struct net_device *dev);
+static void umal_set_rx_mode(struct net_device *dev);
+static void umal_promiscuous_mode(struct umal_softc *sc, int onoff);
+static void umal_setmulti(struct umal_softc *sc);
+static int umal_set_speed(struct umal_softc *s, enum umal_speed speed);
+static int umal_set_duplex(struct umal_softc *s, enum umal_duplex duplex,
+ enum umal_fc fc);
+static int umal_change_mtu(struct net_device *_dev, int new_mtu);
+static void umal_miipoll(struct net_device *dev);
+
+/**********************************************************************
+ * MII Bus functions for PAL (phy abstraction layer)
+ ********************************************************************* */
+
+/**********************************************************************
+ * UMAL_MII_RESET(bus)
+ *
+ * Reset MII bus.
+ *
+ * Input parameters:
+ * bus - MDIO bus handle
+ *
+ * Return value:
+ * 0 if ok
+ ********************************************************************* */
+static int umal_mii_reset(struct mii_bus *bus)
+{
+ /* reset the MII management */
+ writel(UMAL_MIICFG_RESET, UMAL_MIICFG);
+ /* enable the MII management */
+ writel(0, UMAL_MIICFG);
+ /* source clock division = 28 */
+ writel(readl(UMAL_MIICFG) | 0x7, UMAL_MIICFG);
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL_MII_READ(bus, phyaddr, regidx)
+ * Read a PHY register.
+ *
+ * Input parameters:
+ * bus - MDIO bus handle
+ * phyaddr - PHY's address
+ * regnum - index of register to read
+ *
+ * Return value:
+ * value read, or 0xffff if an error occurred.
+ ********************************************************************* */
+static int umal_mii_read(struct mii_bus *bus, int phyaddr, int regidx)
+{
+ int tmp = 0;
+
+ writel((phyaddr<<8) | regidx, UMAL_MIIADDR);
+ writel(UMAL_MIICMD_READ, UMAL_MIICMD);
+
+ tmp = readl(UMAL_MIIIDCT);
+ while (tmp & UMAL_MIIIDCT_BUSY)
+ tmp = readl(UMAL_MIIIDCT);
+
+ if (tmp & UMAL_MIIIDCT_NOTVALID)
+ return 0xffff;
+
+ writel(0, UMAL_MIICMD);
+
+ tmp = readl(UMAL_MIISTATUS);
+ return tmp;
+}
+
+/**********************************************************************
+ * UMAL_MII_WRITE(bus, phyaddr, regidx, regval)
+ *
+ * Write a value to a PHY register.
+ *
+ * Input parameters:
+ * bus - MDIO bus handle
+ * phyaddr - PHY to use
+ * regidx - register within the PHY
+ * regval - data to write to register
+ *
+ * Return value:
+ * 0 if ok
+ ********************************************************************* */
+static int umal_mii_write(struct mii_bus *bus, int phyaddr, int regidx, u16 val)
+{
+ int tmp = 0;
+
+ writel((phyaddr<<8) | regidx, UMAL_MIIADDR);
+ writel(val, UMAL_MIICTRL);
+
+ tmp = readl(UMAL_MIIIDCT);
+ while (tmp & UMAL_MIIIDCT_BUSY)
+ tmp = readl(UMAL_MIIIDCT);
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL_MII_PROBE(dev)
+ *
+ * Write a value to a PHY register.
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * 0 if ok
+ ********************************************************************* */
+static int umal_mii_probe(struct net_device *dev)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+ struct phy_device *phy_dev;
+ int i;
+
+ for (i = 0; i < PHY_MAX_ADDR; i++) {
+ phy_dev = sc->mii_bus->phy_map[i];
+ if (phy_dev)
+ break;
+ }
+ if (!phy_dev) {
+ printk(KERN_ERR "%s: no PHY found\n", dev->name);
+ return -ENXIO;
+ }
+
+ phy_dev = phy_connect(dev, dev_name(&phy_dev->dev), &umal_miipoll, 0,
+ PHY_INTERFACE_MODE_MII);
+ if (IS_ERR(phy_dev)) {
+ printk(KERN_ERR "%s: could not attach to PHY\n", dev->name);
+ return PTR_ERR(phy_dev);
+ }
+
+ /* Remove any features not supported by the controller */
+ phy_dev->supported &= SUPPORTED_10baseT_Half |
+ SUPPORTED_10baseT_Full |
+ SUPPORTED_100baseT_Half |
+ SUPPORTED_100baseT_Full |
+ SUPPORTED_Autoneg |
+ SUPPORTED_MII;
+ phy_dev->advertising = phy_dev->supported;
+
+ pr_info("%s: attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
+ dev->name, phy_dev->drv->name,
+ dev_name(&phy_dev->dev), phy_dev->irq);
+
+ sc->phy_dev = phy_dev;
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL DMA functions
+ ********************************************************************* */
+
+/**********************************************************************
+ * UMALDMA_INITCTX(d,s,txrx,maxdescr)
+ *
+ * Initialize a DMA channel context. Since there are potentially
+ * eight DMA channels per MAC, it's nice to do this in a standard
+ * way.
+ *
+ * Input parameters:
+ * d - struct umaldma (DMA channel context)
+ * s - struct umal_softc (pointer to a MAC)
+ * txrx - Identifies DMA_TX or DMA_RX for channel direction
+ * maxdescr - number of descriptors
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umaldma_initctx(struct umaldma *d, struct umal_softc *s, int rxtx,
+ int maxdescr)
+{
+ struct umaldmadscr *dscr_item;
+ int idx;
+
+ /*
+ * Save away interesting stuff in the structure
+ */
+ d->umaldma_eth = s;
+ d->umaldma_txdir = rxtx;
+ d->umaldma_maxdescr = maxdescr;
+
+ /*
+ * Allocate memory for the ring
+ */
+ d->umaldma_dscrtable_unaligned = dma_alloc_coherent(NULL,
+ sizeof(*d->umaldma_dscrtable),
+ &d->umaldma_dscrtable_phys_unaligned,
+ GFP_KERNEL | GFP_DMA);
+ dma_cache_sync(NULL, d->umaldma_dscrtable_unaligned,
+ sizeof(*d->umaldma_dscrtable), DMA_BIDIRECTIONAL);
+
+ /*
+ * The descriptor table must be aligned to at least 16 bytes or the
+ * MAC will corrupt it.
+ */
+ d->umaldma_dscrtable = (struct umaldmadscr *)
+ ALIGN((unsigned long)d->umaldma_dscrtable_unaligned,
+ sizeof(*d->umaldma_dscrtable));
+ d->umaldma_dscrtable_end = d->umaldma_dscrtable + d->umaldma_maxdescr;
+ d->umaldma_dscrtable_phys = ALIGN((unsigned long)
+ d->umaldma_dscrtable_phys_unaligned,
+ sizeof(*d->umaldma_dscrtable));
+
+ for (idx = 0; idx < d->umaldma_maxdescr; idx++) {
+ dscr_item = d->umaldma_dscrtable + idx;
+ dscr_item->PacketStartAddr = 0;
+ dscr_item->PacketSize = UMAL_DESC_PACKETSIZE_EMPTY;
+ dscr_item->NextDescriptor = (dma_addr_t)(
+ (struct umaldmadscr *)d->umaldma_dscrtable_phys
+ + (idx+1));
+ dscr_item->NextDescriptor_Virt = d->umaldma_dscrtable + (idx+1);
+ }
+ dscr_item = d->umaldma_dscrtable +
+ (d->umaldma_maxdescr - 1);
+ dscr_item->NextDescriptor = d->umaldma_dscrtable_phys;
+ dscr_item->NextDescriptor_Virt = d->umaldma_dscrtable;
+
+ d->umaldma_addptr = d->umaldma_dscrtable;
+ d->umaldma_remptr = d->umaldma_dscrtable;
+
+ /*
+ * And context table
+ */
+ d->umaldma_ctxtable = kcalloc(d->umaldma_maxdescr,
+ sizeof(*d->umaldma_ctxtable), GFP_KERNEL);
+}
+
+/**********************************************************************
+ * UMALDMA_UNINITCTX(d)
+ *
+ * Uninitialize a DMA channel context.
+ *
+ * Input parameters:
+ * d - struct umaldma (DMA channel context)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umaldma_uninitctx(struct umaldma *d)
+{
+ if (d->umaldma_dscrtable_unaligned) {
+ dma_free_coherent(NULL, sizeof(*d->umaldma_dscrtable),
+ d->umaldma_dscrtable_unaligned,
+ d->umaldma_dscrtable_phys_unaligned);
+ d->umaldma_dscrtable_unaligned = d->umaldma_dscrtable = NULL;
+ d->umaldma_dscrtable_phys_unaligned = 0;
+ d->umaldma_dscrtable_phys = 0;
+ }
+
+ kfree(d->umaldma_ctxtable);
+ d->umaldma_ctxtable = NULL;
+}
+
+/**********************************************************************
+ * UMALDMA_CHANNEL_START(d)
+ *
+ * Open a DMA channel.
+ *
+ * Input parameters:
+ * d - DMA channel to init (context must be previously init'd)
+ * rxtx - DMA_RX or DMA_TX depending on what type of channel
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umaldma_channel_start(struct umaldma *d, int rxtx)
+{
+ /*
+ * Turn on the DMA channel
+ */
+ if (rxtx == DMA_TX) {
+ writel(d->umaldma_dscrtable_phys, UMAL_DMATxDescriptor);
+ writel(UMAL_DMA_Enable, UMAL_DMATxCtrl);
+ } else {
+ writel(d->umaldma_dscrtable_phys, UMAL_DMARxDescriptor);
+ writel(UMAL_DMA_Enable, UMAL_DMARxCtrl);
+ }
+}
+
+/**********************************************************************
+ * UMALDMA_CHANNEL_STOP(d)
+ *
+ * Close DMA channel.
+ *
+ * Input parameters:
+ * d - DMA channel to init (context must be previously init'd
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umaldma_channel_stop(struct umaldma *d)
+{
+ /*
+ * Turn off the DMA channel
+ */
+ if (d->umaldma_txdir == DMA_TX) {
+ writel(0, UMAL_DMATxCtrl);
+ writel(0, UMAL_DMATxDescriptor);
+ } else {
+ writel(0, UMAL_DMARxCtrl);
+ writel(0, UMAL_DMARxDescriptor);
+ }
+
+ /*
+ * Zero ring pointers
+ */
+ d->umaldma_addptr = d->umaldma_dscrtable;
+ d->umaldma_remptr = d->umaldma_dscrtable;
+}
+
+/**********************************************************************
+ * UMALDMA_ADD_RCVBUFFER(d,sb)
+ *
+ * Add a buffer to the specified DMA channel.
+ * For receive channels, this queues a buffer for inbound packets.
+ *
+ * Input parameters:
+ * sc - softc structure
+ * d - DMA channel descriptor
+ * sb - sk_buff to add, or NULL if we should allocate one
+ *
+ * Return value:
+ * 0 if buffer could not be added (ring is full)
+ * 1 if buffer added successfully
+ ********************************************************************* */
+static int umaldma_add_rcvbuffer(struct umal_softc *sc, struct umaldma *d,
+ struct sk_buff *sb)
+{
+ struct net_device *dev = sc->umal_dev;
+ struct umaldmadscr *dsc;
+ struct umaldmadscr *nextdsc;
+ struct sk_buff *sb_new = NULL;
+
+ /* get pointer to our current place in the ring */
+ dsc = d->umaldma_addptr;
+ nextdsc = UMALDMA_NEXTBUF(d, umaldma_addptr);
+
+ /*
+ * figure out if the ring is full - if the next descriptor
+ * is the same as the one that we're going to remove from
+ * the ring, the ring is full
+ */
+ if (nextdsc == d->umaldma_remptr)
+ return -ENOSPC;
+
+ /*
+ * Allocate a sk_buff if we don't already have one.
+ * If we do have an sk_buff, reset it so that it's empty.
+ *
+ * Note: sk_buffs don't seem to be guaranteed to have any sort
+ * of alignment when they are allocated. Therefore, allocate enough
+ * extra space to make sure that:
+ *
+ * 1. the data does not start in the middle of a cache line.
+ * 2. The data does not end in the middle of a cache line
+ * 3. The buffer can be aligned such that the IP addresses are
+ * naturally aligned.
+ *
+ * Remember, the SOCs MAC writes whole cache lines at a time,
+ * without reading the old contents first. So, if the sk_buff's
+ * data portion starts in the middle of a cache line, the SOC
+ * DMA will trash the beginning (and ending) portions.
+ */
+ if (sb == NULL) {
+ sb_new = netdev_alloc_skb(dev, ENET_PACKET_SIZE +
+ SMP_CACHE_BYTES * 2 + NET_IP_ALIGN);
+ if (sb_new == NULL) {
+ pr_info("%s: sk_buff allocation failed\n",
+ d->umaldma_eth->umal_dev->name);
+ return -ENOBUFS;
+ }
+ skb_reserve(sb_new, 2);
+ } else {
+ sb_new = sb;
+ /*
+ * nothing special to reinit buffer, it's already aligned
+ * and sb->data already points to a good place.
+ */
+ }
+
+ /* fill in the descriptor */
+ dsc->PacketStartAddr = virt_to_phys(sb_new->data);
+ dsc->PacketSize = UMAL_DESC_PACKETSIZE_EMPTY;
+
+ /* fill in the context */
+ d->umaldma_ctxtable[dsc-d->umaldma_dscrtable] = sb_new;
+
+ /* point at next packet */
+ d->umaldma_addptr = nextdsc;
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMALDMA_ADD_TXBUFFER(d,sb)
+ *
+ * Add a transmit buffer to the specified DMA channel, causing a
+ * transmit to start.
+ *
+ * Input parameters:
+ * d - DMA channel descriptor
+ * sb - sk_buff to add
+ *
+ * Return value:
+ * 0 transmit queued successfully
+ * otherwise error code
+ ********************************************************************* */
+static int umaldma_add_txbuffer(struct umaldma *d, struct sk_buff *sb)
+{
+ struct umaldmadscr *dsc;
+ struct umaldmadscr *nextdsc;
+
+ /* get pointer to our current place in the ring */
+ dsc = d->umaldma_addptr;
+ nextdsc = UMALDMA_NEXTBUF(d, umaldma_addptr);
+
+ /*
+ * figure out if the ring is full - if the next descriptor
+ * is the same as the one that we're going to remove from
+ * the ring, the ring is full
+ */
+ if (nextdsc == d->umaldma_remptr)
+ return -ENOSPC;
+
+ /*
+ * fill in the descriptor. Note that the number of cache
+ * blocks in the descriptor is the number of blocks
+ * *spanned*, so we need to add in the offset (if any)
+ * while doing the calculation.
+ */
+ dsc->PacketStartAddr = virt_to_phys(sb->data);
+ dsc->PacketSize = sb->len | UMAL_DESC_PACKETSIZE_NONEMPTY;
+
+ dma_map_single(NULL, sb->data, sb->len, DMA_BIDIRECTIONAL);
+ dma_cache_sync(NULL, sb->data, sb->len, DMA_BIDIRECTIONAL);
+
+ /* fill in the context */
+ d->umaldma_ctxtable[dsc-d->umaldma_dscrtable] = sb;
+
+ /* point at next packet */
+ d->umaldma_addptr = nextdsc;
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMALDMA_EMPTYRING(d)
+ *
+ * Free all allocated sk_buffs on the specified DMA channel;
+ *
+ * Input parameters:
+ * d - DMA channel
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umaldma_emptyring(struct umaldma *d)
+{
+ int idx;
+ struct sk_buff *sb;
+
+ for (idx = 0; idx < d->umaldma_maxdescr; idx++) {
+ sb = d->umaldma_ctxtable[idx];
+ if (sb) {
+ dev_kfree_skb(sb);
+ d->umaldma_ctxtable[idx] = NULL;
+ }
+ }
+}
+
+/**********************************************************************
+ * UMALDMA_FILLRING(sc,d)
+ *
+ * Fill the specified DMA channel (must be receive channel) with sk_buffs
+ *
+ * Input parameters:
+ * sc - softc structure
+ * d - DMA channel
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umaldma_fillring(struct umal_softc *sc, struct umaldma *d)
+{
+ int idx;
+ for (idx = 0; idx < UMAL_MAX_RXDESCR - 1; idx++) {
+ if (umaldma_add_rcvbuffer(sc, d, NULL) != 0)
+ break;
+ }
+}
+
+/**********************************************************************
+ * UMALDMA_RX_PROCESS(sc,d,work_to_do,poll)
+ *
+ * Process "completed" receive buffers on the specified DMA channel.
+ *
+ * Input parameters:
+ * sc - softc structure
+ * d - DMA channel context
+ * work_to_do - no. of packets to process before enabling interrupt
+ * again (for NAPI)
+ * poll - 1: using polling (for NAPI)
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static int umaldma_rx_process(struct umal_softc *sc, struct umaldma *d,
+ int work_to_do, int poll)
+{
+ struct net_device *dev = sc->umal_dev;
+ int curidx;
+ int hwidx;
+ struct umaldmadscr *dsc;
+ struct sk_buff *sb;
+ int len;
+ int work_done = 0;
+ int dropped = 0;
+ unsigned int int_status;
+
+ if (!netif_device_present(dev))
+ return 0;
+
+ int_status = readl(UMAL_DMAInterrupt);
+
+ if (int_status & INT_RX_BUS_ERR) {
+ writel(CLR_RX_BUS_ERR, UMAL_DMARxStatus);
+ writel(readl(UMAL_DMARxCtrl) | UMAL_DMA_Enable, UMAL_DMARxCtrl);
+ }
+
+ if (int_status & INT_RX_OVERFLOW) {
+ writel(CLR_RX_OVERFLOW, UMAL_DMARxStatus);
+ writel(readl(UMAL_DMARxCtrl) | UMAL_DMA_Enable, UMAL_DMARxCtrl);
+ }
+
+ if (!(int_status & INT_RX_PKT))
+ return 0;
+
+ while (work_to_do-- > 0) {
+ /*
+ * figure out where we are (as an index) and where
+ * the hardware is (also as an index)
+ *
+ * This could be done faster if (for example) the
+ * descriptor table was page-aligned and contiguous in
+ * both virtual and physical memory -- you could then
+ * just compare the low-order bits of the virtual
+ * address (sbdma_remptr) and the physical address
+ * (sbdma_curdscr CSR)
+ */
+ dsc = d->umaldma_remptr;
+ curidx = dsc - d->umaldma_dscrtable;
+
+ hwidx = (struct umaldmadscr *) readl(UMAL_DMARxDescriptor) -
+ (struct umaldmadscr *)d->umaldma_dscrtable_phys;
+
+ writel(CLR_RX_PKT, UMAL_DMARxStatus);
+
+ /*
+ * If they're the same, that means we've processed all
+ * of the descriptors up to (but not including) the one
+ * that the hardware is working on right now.
+ */
+ if (curidx == hwidx)
+ goto done;
+
+ /*
+ * Otherwise, get the packet's sk_buff ptr back
+ */
+ sb = d->umaldma_ctxtable[curidx];
+ len = dsc->PacketSize & 0xfff;
+ d->umaldma_ctxtable[curidx] = NULL;
+
+ /* .. and advance to the next buffer. */
+ d->umaldma_remptr = UMALDMA_NEXTBUF(d, umaldma_remptr);
+
+ /*
+ * Check packet status. If good, process it.
+ * If not, silently drop it and put it back on the
+ * receive ring.
+ */
+ if (likely(!(dsc->PacketSize & UMAL_DESC_PACKETSIZE_EMPTY))) {
+ /*
+ * Add a new buffer to replace the old one.
+ * If we fail to allocate a buffer, we're going
+ * to drop this packet and put it right back on
+ * the receive ring.
+ */
+ if (unlikely(umaldma_add_rcvbuffer(sc, d, NULL)
+ == -ENOBUFS)) {
+ dev->stats.rx_dropped++;
+ /* Re-add old buffer */
+ umaldma_add_rcvbuffer(sc, d, sb);
+ /* No point in continuing */
+ printk(KERN_ERR "dropped packet (1)\n");
+ d->umaldma_remptr = UMALDMA_NEXTBUF(d,
+ umaldma_remptr);
+ goto done;
+ } else {
+ /* Set length into the packet */
+ skb_put(sb, len + 4);
+
+ /*
+ * Buffer has been replaced on the
+ * receive ring. Pass the buffer to
+ * the kernel
+ */
+ sb->protocol = eth_type_trans(sb,
+ d->umaldma_eth->umal_dev);
+ /*
+ * Check hw IPv4/TCP checksum
+ * if supported
+ */
+ skb_checksum_none_assert(sb);
+
+ if (poll)
+ dropped = netif_receive_skb(sb);
+ else
+ dropped = netif_rx(sb);
+
+ if (dropped == NET_RX_DROP) {
+ dev->stats.rx_dropped++;
+ d->umaldma_remptr = UMALDMA_NEXTBUF(d,
+ umaldma_remptr);
+ goto done;
+ } else {
+ dev->stats.rx_bytes += len;
+ dev->stats.rx_packets++;
+ }
+ }
+ } else {
+ /*
+ * Packet was mangled somehow. Just drop it and
+ * put it back on the receive ring.
+ */
+ dev->stats.rx_errors++;
+ umaldma_add_rcvbuffer(sc, d, sb);
+ }
+ work_done++;
+ }
+done:
+ return work_done;
+}
+
+/**********************************************************************
+ * UMALDMA_TX_PROCESS(sc,d,poll)
+ *
+ * Process "completed" transmit buffers on the specified DMA channel.
+ * This is normally called within the interrupt service routine.
+ * Note that this isn't really ideal for priority channels, since
+ * it processes all of the packets on a given channel before
+ * returning.
+ *
+ * Input parameters:
+ * sc - softc structure
+ * d - DMA channel context
+ * poll - 1: using polling (for NAPI)
+ *
+ * Return value:
+ * nothing
+ **********************************************************************/
+static void umaldma_tx_process(struct umal_softc *sc, struct umaldma *d,
+ int poll)
+{
+ struct net_device *dev = sc->umal_dev;
+ int curidx;
+ int hwidx;
+ struct umaldmadscr *dsc;
+ struct sk_buff *sb;
+ unsigned long flags;
+ int packets_handled = 0;
+ unsigned int int_status;
+
+ spin_lock_irqsave(&(sc->umal_lock), flags);
+
+ if (!netif_device_present(dev))
+ return;
+
+ int_status = readl(UMAL_DMAInterrupt);
+
+ if (int_status & INT_TX_BUS_ERR)
+ writel(CLR_TX_BUS_ERR, UMAL_DMATxStatus);
+
+ if (int_status & INT_TX_UNDERRUN)
+ writel(CLR_TX_UNDERRUN, UMAL_DMATxStatus);
+
+ if (int_status & INT_TX_PKT) {
+ hwidx = (struct umaldmadscr *)readl(UMAL_DMATxDescriptor) -
+ (struct umaldmadscr *)d->umaldma_dscrtable_phys;
+
+ if (d->umaldma_remptr == d->umaldma_addptr)
+ goto end_unlock;
+
+ for (;;) {
+ /*
+ * figure out where we are (as an index) and where
+ * the hardware is (also as an index)
+ *
+ * This could be done faster if (for example) the
+ * descriptor table was page-aligned and contiguous in
+ * both virtual and physical memory -- you could then
+ * just compare the low-order bits of the virtual
+ * address (sbdma_remptr) and the physical address
+ * (sbdma_curdscr CSR)
+ */
+ curidx = d->umaldma_remptr - d->umaldma_dscrtable;
+
+ /*
+ * If they're the same, that means we've processed all
+ * of the descriptors up to (but not including) the one
+ * that the hardware is working on right now.
+ */
+ if (curidx == hwidx)
+ break;
+
+ /* Otherwise, get the packet's sk_buff ptr back */
+ dsc = &(d->umaldma_dscrtable[curidx]);
+ sb = d->umaldma_ctxtable[curidx];
+
+ /* Stats */
+ dev->stats.tx_bytes += sb->len;
+ dev->stats.tx_packets++;
+
+ /* for transmits, we just free buffers. */
+ dev_kfree_skb_irq(sb);
+ d->umaldma_ctxtable[curidx] = NULL;
+ writel(CLR_TX_PKT, UMAL_DMATxStatus);
+
+ /* .. and advance to the next buffer. */
+ d->umaldma_remptr = UMALDMA_NEXTBUF(d, umaldma_remptr);
+ packets_handled++;
+ }
+
+ /*
+ * Decide if we should wake up the protocol or not.
+ * Other drivers seem to do this when we reach a low
+ * watermark on the transmit queue.
+ */
+ if (packets_handled)
+ netif_wake_queue(d->umaldma_eth->umal_dev);
+ }
+
+end_unlock:
+ spin_unlock_irqrestore(&(sc->umal_lock), flags);
+}
+
+/**********************************************************************
+ * UMAL Channel functions
+ ********************************************************************* */
+
+/**********************************************************************
+ * UMAL_INITCTX(s)
+ *
+ * Initialize an Ethernet context structure - this is called
+ * once per MAC. Memory is allocated here, so don't
+ * call it again from inside the ioctl routines that bring the
+ * interface up/down
+ *
+ * Input parameters:
+ * s - umal context structure
+ *
+ * Return value:
+ * 0
+ ********************************************************************* */
+static int umal_initctx(struct umal_softc *s)
+{
+ /*
+ * Initialize the DMA channels.
+ * Note: Only do this _once_, as it allocates memory from the kernel!
+ */
+ umaldma_initctx(&(s->umal_txdma), s, DMA_TX, UMAL_MAX_TXDESCR);
+ umaldma_initctx(&(s->umal_rxdma), s, DMA_RX, UMAL_MAX_RXDESCR);
+
+ /* initial state is OFF */
+ s->umal_state = umal_state_off;
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL_UNINITCTX(s)
+ *
+ * Initialize an Ethernet context structure.
+ * Memory is allocated here, so don't call it again from inside the
+ * ioctl routines that bring the interface up/down
+ *
+ * Input parameters:
+ * s - umal context structure
+ *
+ * Return value:
+ * Nothing
+ ********************************************************************* */
+static void umal_uninitctx(struct umal_softc *s)
+{
+ umaldma_uninitctx(&(s->umal_txdma));
+ umaldma_uninitctx(&(s->umal_rxdma));
+}
+
+/**********************************************************************
+ * UMAL_CHANNEL_START(s)
+ *
+ * Start packet processing on this MAC.
+ *
+ * Input parameters:
+ * s - umal context structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_channel_start(struct umal_softc *s)
+{
+ /*
+ * Don't do this if running
+ */
+ if (s->umal_state == umal_state_on)
+ return;
+
+ /* don't accept any packets, disable all interrupts */
+ umaldma_channel_stop(&(s->umal_rxdma));
+ umaldma_channel_stop(&(s->umal_txdma));
+
+ writel(0, UMAL_DMAIntrMask);
+ umal_clr_intr(s->umal_dev);
+
+ /*
+ * Program the hardware address. It goes into the hardware-address
+ * register as well as the first filter register.
+ */
+ writel(s->umal_hwaddr[0]<<24 | s->umal_hwaddr[1]<<16 |
+ s->umal_hwaddr[2]<<8 | s->umal_hwaddr[3], UMAL_STADDR1);
+ writel(s->umal_hwaddr[4]<<24 | s->umal_hwaddr[5]<<16, UMAL_STADDR2);
+
+ /* Configure the speed, duplex, and flow control */
+ umal_set_speed(s, s->umal_speed);
+ umal_set_duplex(s, s->umal_duplex, s->umal_fc);
+
+ /* Program multicast addresses */
+ umal_setmulti(s);
+
+ /* If channel was in promiscuous mode before, turn that on */
+ if (s->umal_devflags & IFF_PROMISC)
+ umal_promiscuous_mode(s, 1);
+
+ /* Fill the receive ring */
+ umaldma_fillring(s, &(s->umal_rxdma));
+
+ umaldma_channel_start(&(s->umal_rxdma), DMA_RX);
+ umaldma_channel_start(&(s->umal_txdma), DMA_TX);
+
+ s->umal_state = umal_state_on;
+
+ /* Initialize DMA channels (rings should be ok now) */
+ writel(INT_RX_BUS_ERR | INT_RX_OVERFLOW |
+ INT_RX_PKT | INT_TX_BUS_ERR |
+ INT_TX_UNDERRUN | INT_TX_PKT |
+ UMAL_DMAIntrMask_ENABLEHALFWORD, UMAL_DMAIntrMask);
+
+ /* we're running now. */
+ writel(readl(UMAL_CFG1) | UMAL_CFG1_RXENABLE | UMAL_CFG1_TXENABLE,
+ UMAL_CFG1);
+}
+
+/**********************************************************************
+ * UMAL_CHANNEL_STOP(s)
+ *
+ * Stop packet processing on this MAC.
+ *
+ * Input parameters:
+ * s - umal context structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_channel_stop(struct umal_softc *s)
+{
+ /* don't do this if already stopped */
+ if (s->umal_state == umal_state_off)
+ return;
+
+ /* don't accept any packets, disable all interrupts */
+ writel(0, UMAL_DMAIntrMask);
+ umal_clr_intr(s->umal_dev);
+
+ /* turn off receiver and transmitter */
+ writel(UMAL_CFG1_RESET, UMAL_CFG1); /* reset MAC */
+ writel(0, UMAL_CFG1);
+
+ /* We're stopped now. */
+ s->umal_state = umal_state_off;
+
+ /* Stop DMA channels (rings should be ok now) */
+ umaldma_channel_stop(&(s->umal_rxdma));
+ umaldma_channel_stop(&(s->umal_txdma));
+
+ /* Empty the receive and transmit rings */
+ umaldma_emptyring(&(s->umal_rxdma));
+ umaldma_emptyring(&(s->umal_txdma));
+}
+
+/**********************************************************************
+ * UMAL_SET_CHANNEL_STATE(s,state)
+ *
+ * Set the channel's state ON or OFF
+ *
+ * Input parameters:
+ * s - umal context structure
+ * state - new state
+ *
+ * Return value:
+ * old state
+ ********************************************************************* */
+static enum umal_state umal_set_channel_state(struct umal_softc *s,
+ enum umal_state state)
+{
+ enum umal_state oldstate = s->umal_state;
+
+ /* If same as previous state, return */
+ if (state == oldstate)
+ return oldstate;
+
+ /* If new state is ON, turn channel on */
+ if (state == umal_state_on)
+ umal_channel_start(s);
+ else
+ umal_channel_stop(s);
+
+ /* Return previous state */
+ return oldstate;
+}
+
+/**********************************************************************
+ * UMAL functions
+ ********************************************************************* */
+static const struct net_device_ops umal_netdev_ops = {
+ .ndo_open = umal_open,
+ .ndo_stop = umal_close,
+ .ndo_start_xmit = umal_start_tx,
+ .ndo_set_multicast_list = umal_set_rx_mode,
+ .ndo_tx_timeout = umal_tx_timeout,
+ .ndo_do_ioctl = umal_mii_ioctl,
+ .ndo_change_mtu = umal_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_set_mac_address = eth_mac_addr,
+};
+
+/**********************************************************************
+ * UMAL_INIT(dev)
+ *
+ * Attach routine - init hardware and hook ourselves into linux
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * 0 if ok
+ ********************************************************************* */
+static int umal_init(struct platform_device *pldev, long long base)
+{
+ struct net_device *dev = dev_get_drvdata(&pldev->dev);
+ int idx = pldev->id;
+ struct umal_softc *sc = netdev_priv(dev);
+ unsigned char *eaddr;
+ int i;
+ int err;
+
+ sc->umal_dev = dev;
+ sc->umal_idx = idx;
+
+ eaddr = sc->umal_hwaddr;
+
+#ifdef CONFIG_CMDLINE_FORCE
+ eaddr[0] = 0x00;
+ eaddr[1] = 0x25;
+ eaddr[2] = 0x9b;
+ eaddr[3] = 0xff;
+ eaddr[4] = 0x00;
+ eaddr[5] = 0x00;
+#endif
+
+ for (i = 0; i < 6; i++)
+ dev->dev_addr[i] = eaddr[i];
+
+ /* Set up Linux device callins */
+ spin_lock_init(&(sc->umal_lock));
+
+ dev->netdev_ops = &umal_netdev_ops;
+ dev->watchdog_timeo = TX_TIMEOUT;
+ dev->irq = IRQ_UMAL;
+
+ sc->mii_bus = mdiobus_alloc();
+ if (sc->mii_bus == NULL) {
+ err = -ENOMEM;
+ goto uninit_ctx;
+ }
+
+ sc->mii_bus->name = umal_mdio_string;
+ snprintf(sc->mii_bus->id, MII_BUS_ID_SIZE, "%x", idx);
+ sc->mii_bus->priv = sc;
+ sc->mii_bus->read = umal_mii_read;
+ sc->mii_bus->write = umal_mii_write;
+ sc->mii_bus->reset = umal_mii_reset;
+ sc->mii_bus->irq = sc->phy_irq;
+ for (i = 0; i < PHY_MAX_ADDR; ++i)
+ sc->mii_bus->irq[i] = PHY_POLL;
+
+ sc->mii_bus->parent = &pldev->dev;
+
+ /* Probe PHY address */
+ err = mdiobus_register(sc->mii_bus);
+ if (err) {
+ printk(KERN_ERR "%s: unable to register MDIO bus\n",
+ dev->name);
+ goto free_mdio;
+ }
+ dev_set_drvdata(&pldev->dev, sc->mii_bus);
+
+ err = register_netdev(dev);
+ if (err) {
+ printk(KERN_ERR "%s.%d: unable to register netdev\n",
+ umal_string, idx);
+ goto unreg_mdio;
+ }
+
+ pr_info("%s.%d: registered as %s\n", umal_string, idx, dev->name);
+
+ /*
+ * Initialize context (get pointers to registers and stuff), then
+ * allocate the memory for the descriptor tables.
+ */
+ dev->dev.coherent_dma_mask = 0xFFFFFFFF;
+ umal_initctx(sc);
+
+ /*
+ * Display Ethernet address (this is called during the config
+ * process so we need to finish off the config message that
+ * was being displayed)
+ */
+ pr_info("%s: UMAL Ethernet at 0x%08Lx, address: %pM\n",
+ dev->name, base, eaddr);
+
+ return 0;
+unreg_mdio:
+ mdiobus_unregister(sc->mii_bus);
+ dev_set_drvdata(&pldev->dev, NULL);
+free_mdio:
+ mdiobus_free(sc->mii_bus);
+uninit_ctx:
+ umal_uninitctx(sc);
+ return err;
+}
+
+/**********************************************************************
+ * UMAL_OPEN(dev)
+ *
+ * Open umal device
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * 0 if ok
+ * otherwise error
+ ********************************************************************* */
+static int umal_open(struct net_device *dev)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+ int err;
+
+ sc->umal_speed = umal_speed_none;
+ sc->umal_duplex = umal_duplex_none;
+ sc->umal_fc = umal_fc_none;
+ sc->umal_pause = -1;
+ sc->umal_link = 0;
+
+ /* reset mac and interface */
+ writel(UMAL_CFG1_RESET, UMAL_CFG1); /* reset MAC */
+ writel(0, UMAL_CFG1); /* clear the reset bit of MAC */
+ writel(UMAL_IFCTRL_RESET, UMAL_IFCTRL); /* reset the MAC Interface */
+ writel(0, UMAL_DMAIntrMask);
+
+ /* Attach to the PHY */
+ err = umal_mii_probe(dev);
+ if (err)
+ goto out_unregister;
+
+ /* Turn on the channel */
+ phy_start(sc->phy_dev);
+
+ /* config fifo */
+ writel(0x000000ff, UMAL_FIFOCFG0); /* reset FIFO */
+ writel(0x0fff0fff, UMAL_FIFOCFG1);
+ writel(0x0aaa0555, UMAL_FIFOCFG2);
+ writel(0x02800fff, UMAL_FIFOCFG3);
+ writel(0x00000070, UMAL_FIFOCFG4);
+ writel(0x0007ff8f, UMAL_FIFOCFG5);
+ writel(0x0000ff00, UMAL_FIFOCFG0);
+
+ writel(0x7016, UMAL_CFG2);
+
+ /*
+ * map/route interrupt (clear status first, in case something
+ * weird is pending; we haven't initialized the mac registers
+ * yet)
+ */
+ umal_clr_intr(dev);
+
+ err = request_irq(dev->irq, umal_intr, IRQF_SHARED, dev->name, dev);
+ if (err) {
+ printk(KERN_ERR "%s: unable to get IRQ %d\n", dev->name,
+ dev->irq);
+ goto out_err;
+ }
+
+ umal_set_channel_state(sc, umal_state_on);
+
+ netif_start_queue(dev);
+
+ umal_set_rx_mode(dev);
+
+ return 0;
+
+out_unregister:
+ free_irq(dev->irq, dev);
+out_err:
+ return err;
+}
+
+/**********************************************************************
+ * UMAL_CLSOE(dev)
+ *
+ * Close umal device
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * 0 if ok
+ ********************************************************************* */
+static int umal_close(struct net_device *dev)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+
+ phy_stop(sc->phy_dev);
+
+ umal_set_channel_state(sc, umal_state_off);
+
+ netif_stop_queue(dev);
+
+ phy_disconnect(sc->phy_dev);
+ sc->phy_dev = NULL;
+
+ free_irq(dev->irq, dev);
+
+ umaldma_emptyring(&(sc->umal_rxdma));
+ umaldma_emptyring(&(sc->umal_txdma));
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL_MII_IOCTL(dev,rq,cmd)
+ *
+ * Umal device ioctrl routine
+ *
+ * Input parameters:
+ * dev - net_device structure
+ * rq - interface request structure
+ * cmd - ioctrl command
+ *
+ * Return value:
+ * ioctrl command result
+ ********************************************************************* */
+static int umal_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+
+ if (!netif_running(dev) || !sc->phy_dev)
+ return -EINVAL;
+
+ return phy_mii_ioctl(sc->phy_dev, rq, cmd);
+}
+
+/**********************************************************************
+ * UMAL_INTR(irq,dev_instance)
+ *
+ * Interrupt handler for MAC interrupts
+ *
+ * Input parameters:
+ * irq - irq number
+ * dev_instance - net_device structure
+ *
+ * Return value:
+ * irq handling result
+ ********************************************************************* */
+static irqreturn_t umal_intr(int irq, void *dev_instance)
+{
+ struct net_device *dev = (struct net_device *) dev_instance;
+ struct umal_softc *sc = netdev_priv(dev);
+ uint64_t isr;
+ int handled = 0;
+
+ /*
+ * Read the ISR (this clears the bits in the real
+ * register, except for counter addr)
+ */
+ isr = readl(UMAL_DMAInterrupt);
+ if (isr == 0)
+ return IRQ_RETVAL(0);
+
+ if (sc->umal_state != umal_state_on) {
+ umal_clr_intr(dev);
+ return IRQ_RETVAL(0);
+ }
+ handled = 1;
+
+ /* Transmits on channel 0 */
+ if (isr & INT_TX_MASK)
+ umaldma_tx_process(sc, &(sc->umal_txdma), 0);
+ if (isr & INT_RX_MASK)
+ umaldma_rx_process(sc, &(sc->umal_rxdma),
+ UMAL_MAX_RXDESCR * 2, 0);
+
+ return IRQ_RETVAL(handled);
+}
+
+/**********************************************************************
+ * UMAL_CLR_INTR(dev)
+ *
+ * Clear all interrupt of umal
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_clr_intr(struct net_device *dev)
+{
+ unsigned int int_status;
+
+ if (!netif_device_present(dev))
+ return;
+ int_status = readl(UMAL_DMAInterrupt);
+ if (int_status & INT_RX_PKT)
+ writel(CLR_RX_PKT, UMAL_DMARxStatus);
+
+ if (int_status & INT_RX_BUS_ERR)
+ writel(CLR_RX_BUS_ERR, UMAL_DMARxStatus);
+
+ if (int_status & INT_RX_OVERFLOW)
+ writel(CLR_RX_OVERFLOW, UMAL_DMARxStatus);
+
+ if (int_status & INT_TX_PKT)
+ writel(CLR_TX_PKT, UMAL_DMATxStatus);
+
+ if (int_status & INT_TX_BUS_ERR)
+ writel(CLR_TX_BUS_ERR, UMAL_DMATxStatus);
+
+ if (int_status & INT_TX_UNDERRUN)
+ writel(CLR_TX_UNDERRUN, UMAL_DMATxStatus);
+}
+
+/**********************************************************************
+ * UMAL_START_TX(skb,dev)
+ *
+ * Start output on the specified interface. Basically, we
+ * queue as many buffers as we can until the ring fills up, or
+ * we run off the end of the queue, whichever comes first.
+ *
+ * Input parameters:
+ * skb - sk_buff structure
+ * dev - net_device structure
+ *
+ * Return value:
+ * 0 if ok
+ * otherwise error
+ ********************************************************************* */
+static int umal_start_tx(struct sk_buff *skb, struct net_device *dev)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+ unsigned long flags;
+
+ /* lock eth irq */
+ spin_lock_irqsave(&sc->umal_lock, flags);
+
+ /*
+ * Put the buffer on the transmit ring. If we
+ * don't have room, stop the queue.
+ */
+ if (umaldma_add_txbuffer(&(sc->umal_txdma), skb)) {
+ /* XXX: save skb that we could not send */
+ netif_stop_queue(dev);
+ spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+ return NETDEV_TX_BUSY;
+ }
+
+ writel(readl(UMAL_CFG1) | UMAL_CFG1_TXENABLE, UMAL_CFG1);
+ writel(readl(UMAL_DMATxCtrl) | UMAL_DMA_Enable, UMAL_DMATxCtrl);
+
+ spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL_TX_TIMEOUT(dev)
+ *
+ * Tx timeout, update statistic structure
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_tx_timeout(struct net_device *dev)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+ unsigned long flags;
+
+ spin_lock_irqsave(&sc->umal_lock, flags);
+
+ dev->trans_start = jiffies; /* prevent tx timeout */
+ dev->stats.tx_errors++;
+
+ spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+ printk(KERN_WARNING "%s: Transmit timed out\n", dev->name);
+}
+
+/**********************************************************************
+ * UMAL_SET_RX_MODE(dev)
+ *
+ * Set promiscuous mode and multicast list
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_set_rx_mode(struct net_device *dev)
+{
+ unsigned long flags;
+ struct umal_softc *sc = netdev_priv(dev);
+
+ spin_lock_irqsave(&sc->umal_lock, flags);
+ if ((dev->flags ^ sc->umal_devflags) & IFF_PROMISC) {
+ /* Promiscuous changed. */
+ if (dev->flags & IFF_PROMISC)
+ umal_promiscuous_mode(sc, 1);
+ else
+ umal_promiscuous_mode(sc, 0);
+ }
+ spin_unlock_irqrestore(&sc->umal_lock, flags);
+
+ /* Program the multicasts. Do this every time. */
+ umal_setmulti(sc);
+}
+
+/**********************************************************************
+ * UMAL_PROMISCUOUS_MODE(sc,onoff)
+ *
+ * Turn on or off promiscuous mode
+ *
+ * Input parameters:
+ * sc - softc
+ * onoff - 1 to turn on, 0 to turn off
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_promiscuous_mode(struct umal_softc *sc, int onoff)
+{
+ if (onoff) {
+ writel(readl(UMAL_FIFOCFG4) & ~0x40000, UMAL_FIFOCFG4);
+ writel(readl(UMAL_FIFOCFG5) | 0x40000, UMAL_FIFOCFG5);
+ } else {
+ writel(readl(UMAL_FIFOCFG4) | 0x40000, UMAL_FIFOCFG4);
+ writel(readl(UMAL_FIFOCFG5) & ~0x40000, UMAL_FIFOCFG5);
+ }
+}
+
+/**********************************************************************
+ * UMAL_SETMULTI(sc)
+ *
+ * Reprogram the multicast table into the hardware, given
+ * the list of multicasts associated with the interface
+ * structure.
+ *
+ * Input parameters:
+ * sc - softc
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_setmulti(struct umal_softc *sc)
+{
+}
+
+/**********************************************************************
+ * UMAL_SET_SPEED(s,speed)
+ *
+ * Configure LAN speed for the specified MAC.
+ * Warning: must be called when MAC is off!
+ *
+ * Input parameters:
+ * s - sbmac structure
+ * speed - speed to set MAC to (see enum sbmac_speed)
+ *
+ * Return value:
+ * 1 if successful
+ * 0 indicates invalid parameters
+ ********************************************************************* */
+static int umal_set_speed(struct umal_softc *s, enum umal_speed speed)
+{
+ unsigned int cfg;
+
+ /* Save new current values */
+ s->umal_speed = speed;
+
+ if (s->umal_state == umal_state_on)
+ return 0; /* save for next restart */
+
+ /* Read current register values */
+ cfg = readl(UMAL_CFG2);
+
+ /* Mask out the stuff we want to change */
+ cfg &= ~(UMAL_CFG2_MODEMASK);
+
+ /* Now add in the new bits */
+ switch (speed) {
+ case umal_speed_10:
+ case umal_speed_100:
+ cfg |= UMAL_CFG2_NIBBLEMODE;
+ break;
+
+ default:
+ return 0;
+ }
+
+ /* Send the bits back to the hardware */
+ writel(cfg, UMAL_CFG2);
+
+ return 1;
+}
+
+/**********************************************************************
+ * UMAL_SET_DUPLEX(s,duplex,fc)
+ *
+ * Set Ethernet duplex and flow control options for this MAC
+ * Warning: must be called when MAC is off!
+ *
+ * Input parameters:
+ * s - umal structure
+ * duplex - duplex setting (see enum sbmac_duplex)
+ * fc - flow control setting (see enum sbmac_fc)
+ *
+ * Return value:
+ * 1 if ok
+ * 0 if an invalid parameter combination was specified
+ ********************************************************************* */
+static int umal_set_duplex(struct umal_softc *s, enum umal_duplex duplex,
+ enum umal_fc fc)
+{
+ unsigned int cfg1, cfg2;
+ int err = 0;
+
+ /* Save new current values */
+ s->umal_duplex = duplex;
+ s->umal_fc = fc;
+
+ if (s->umal_state == umal_state_on)
+ return 0; /* save for next restart */
+
+ /* Read current register values */
+ cfg1 = readl(UMAL_CFG1);
+ cfg2 = readl(UMAL_CFG2);
+
+ /* Mask off the stuff we're about to change */
+ cfg1 &= ~(UMAL_CFG1_TXFLOWCTL | UMAL_CFG1_RXFLOWCTL);
+ cfg2 &= ~(UMAL_CFG2_FULLDUPLEX);
+
+ err = 0;
+ switch (duplex) {
+ case umal_duplex_half:
+ break;
+
+ case umal_duplex_full:
+ cfg2 |= UMAL_CFG2_FULLDUPLEX;
+ break;
+
+ default:
+ err = 1;
+ }
+ if (!err)
+ writel(cfg2, UMAL_CFG2);
+
+ err = 0;
+ switch (fc) {
+ case umal_fc_disabled:
+ break;
+
+ case umal_fc_collision:
+ break;
+
+ case umal_fc_carrier:
+ break;
+
+ case umal_fc_frame:
+ cfg1 |= UMAL_CFG1_TXFLOWCTL | UMAL_CFG1_RXFLOWCTL;
+ break;
+
+ default:
+ err = 1;
+ }
+
+ if (!err)
+ writel(cfg1, UMAL_CFG1);
+
+ /* Send the bits back to the hardware */
+ return 1;
+}
+
+/**********************************************************************
+ * UMAL_CHANGE_MTU(dev,new_mtu)
+ *
+ * Change MTU value
+ *
+ * Input parameters:
+ * dev - net_device structure
+ * new_mtu - new mtu value
+ *
+ * Return value:
+ * 1 if ok
+ ********************************************************************* */
+static int umal_change_mtu(struct net_device *dev, int new_mtu)
+{
+ if (new_mtu > ENET_PACKET_SIZE)
+ return -EINVAL;
+
+ dev->mtu = new_mtu;
+
+ pr_info("changing the mtu to %d\n", new_mtu);
+
+ return 0;
+}
+
+/**********************************************************************
+ * UMAL_MIIPOLL(dev)
+ *
+ * Phy statemachine call back routine for link change
+ *
+ * Input parameters:
+ * dev - net_device structure
+ *
+ * Return value:
+ * nothing
+ ********************************************************************* */
+static void umal_miipoll(struct net_device *dev)
+{
+ struct umal_softc *sc = netdev_priv(dev);
+ struct phy_device *phy_dev = sc->phy_dev;
+ unsigned long flags;
+ enum umal_fc fc;
+ int link_chg, speed_chg, duplex_chg, pause_chg, fc_chg;
+
+ link_chg = (sc->umal_link != phy_dev->link);
+ speed_chg = (sc->umal_speed != phy_dev->speed);
+ duplex_chg = (sc->umal_duplex != phy_dev->duplex);
+ pause_chg = (sc->umal_pause != phy_dev->pause);
+
+ if (!link_chg && !speed_chg && !duplex_chg && !pause_chg)
+ return;
+
+ if (!phy_dev->link) {
+ if (link_chg) {
+ sc->umal_link = phy_dev->link;
+ sc->umal_speed = umal_speed_none;
+ sc->umal_duplex = umal_duplex_none;
+ sc->umal_fc = umal_fc_disabled;
+ sc->umal_pause = -1;
+ pr_info("%s: link unavailable\n", dev->name);
+ }
+ return;
+ }
+
+ if (phy_dev->duplex == DUPLEX_FULL) {
+ if (phy_dev->pause)
+ fc = umal_fc_frame;
+ else
+ fc = umal_fc_disabled;
+ } else
+ fc = umal_fc_collision;
+ fc_chg = (sc->umal_fc != fc);
+
+ pr_info("%s: link available: %dbase-%cD\n", dev->name, phy_dev->speed,
+ phy_dev->duplex == DUPLEX_FULL ? 'F' : 'H');
+
+ spin_lock_irqsave(&sc->umal_lock, flags);
+
+ sc->umal_speed = phy_dev->speed;
+ sc->umal_duplex = phy_dev->duplex;
+ sc->umal_fc = fc;
+ sc->umal_pause = phy_dev->pause;
+ sc->umal_link = phy_dev->link;
+
+ if ((speed_chg || duplex_chg || fc_chg) &&
+ sc->umal_state != umal_state_off) {
+ /* something changed, restart the channel */
+ umal_channel_stop(sc);
+ umal_channel_start(sc);
+ }
+
+ spin_unlock_irqrestore(&sc->umal_lock, flags);
+}
+
+static int umal_probe(struct platform_device *pldev)
+{
+ struct net_device *dev;
+ struct umal_softc *sc;
+ struct resource *res;
+ int err;
+
+ res = platform_get_resource(pldev, IORESOURCE_MEM, 0);
+ BUG_ON(!res);
+
+ /* Okay. Initialize this MAC. */
+ dev = alloc_etherdev(sizeof(struct umal_softc));
+ if (!dev) {
+ printk(KERN_ERR "%s: unable to allocate etherdev\n",
+ dev_name(&pldev->dev));
+ err = -ENOMEM;
+ goto out_out;
+ }
+
+ dev_set_drvdata(&pldev->dev, dev);
+ SET_NETDEV_DEV(dev, &pldev->dev);
+
+ sc = netdev_priv(dev);
+
+ err = umal_init(pldev, res->start);
+ if (err)
+ goto out_kfree;
+
+ return 0;
+
+out_kfree:
+ free_netdev(dev);
+
+out_out:
+ return err;
+}
+
+static int __exit umal_remove(struct platform_device *pldev)
+{
+ struct net_device *dev = dev_get_drvdata(&pldev->dev);
+ struct umal_softc *sc = netdev_priv(dev);
+
+ unregister_netdev(dev);
+ umal_uninitctx(sc);
+ mdiobus_unregister(sc->mii_bus);
+ free_netdev(dev);
+
+ return 0;
+}
+
+#if CONFIG_PM
+static void umal_reset(struct net_device *ndev)
+{
+ writel(UMAL_CFG1_RESET, UMAL_CFG1); /* reset MAC */
+ writel(0, UMAL_CFG1); /* clear the reset bit of MAC */
+ writel(UMAL_IFCTRL_RESET, UMAL_IFCTRL); /* reset the MAC Interface */
+ writel(1, UMAL_DMAIntrMask);
+
+ writel(0x000000ff, UMAL_FIFOCFG0); /* reset FIFO */
+ writel(0x0fff0fff, UMAL_FIFOCFG1);
+ writel(0x0aaa0555, UMAL_FIFOCFG2);
+ writel(0x02800fff, UMAL_FIFOCFG3);
+ writel(0x00000070, UMAL_FIFOCFG4);
+ writel(0x0007ff8f, UMAL_FIFOCFG5);
+ writel(0x0000ff00, UMAL_FIFOCFG0);
+
+ writel(0x7016, UMAL_CFG2);
+}
+
+static void umal_shutdown(struct net_device *ndev)
+{
+ /* XXX: something should be cleared */
+ return;
+}
+
+static int umal_suspend(struct platform_device *pldev, pm_message_t state)
+{
+ struct net_device *ndev = platform_get_drvdata(pldev);
+
+ if (netif_running(ndev)) {
+ netif_device_detach(ndev);
+ umal_shutdown(ndev);
+ }
+ return 0;
+}
+
+static int umal_resume(struct platform_device *pldev)
+{
+ struct net_device *dev = platform_get_drvdata(pldev);
+
+ if (netif_running(dev)) {
+ umal_reset(dev);
+ netif_device_attach(dev);
+ }
+ return 0;
+}
+#else
+static int umal_suspend(struct platform_device *pldev, pm_message_t state) { }
+static int umal_resume(struct platform_device *pldev) { }
+#endif
+static struct platform_driver umal_driver = {
+ .probe = umal_probe,
+ .remove = __exit_p(umal_remove),
+ .driver = {
+ .name = umal_string,
+ .owner = THIS_MODULE,
+ },
+ .suspend = umal_suspend,
+ .resume = umal_resume,
+};
+
+static int __init umal_init_module(void)
+{
+ return platform_driver_register(&umal_driver);
+}
+
+static void __exit umal_cleanup_module(void)
+{
+ platform_driver_unregister(&umal_driver);
+}
+
+module_init(umal_init_module);
+module_exit(umal_cleanup_module);
--
1.7.5.2
^ permalink raw reply related
* [RESEND PATCH net] net: fix ETHTOOL_SFEATURES compatibility with old ethtool_ops.set_flags
From: Michał Mirosław @ 2011-05-26 10:42 UTC (permalink / raw)
To: netdev; +Cc: David Miller, Ben Hutchings
In-Reply-To: <20110524215923.GA20138@rere.qmqm.pl>
Current code squashes flags to bool - this makes set_flags fail whenever
some ETH_FLAG_* equivalent features are set. Fix this.
Signed-off-by: Michał Mirosław <mirq-linux@rere.qmqm.pl>
---
net/core/ethtool.c | 25 ++++++++++++++++++++++++-
1 files changed, 24 insertions(+), 1 deletions(-)
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 84e7304..fd14116 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -233,6 +233,29 @@ static int ethtool_set_feature_compat(struct net_device *dev,
return 1;
}
+static int ethtool_set_flags_compat(struct net_device *dev,
+ int (*legacy_set)(struct net_device *, u32),
+ struct ethtool_set_features_block *features, u32 mask)
+{
+ u32 value;
+
+ if (!legacy_set)
+ return 0;
+
+ if (!(features[0].valid & mask))
+ return 0;
+
+ value = dev->features & ~features[0].valid;
+ value |= features[0].requested;
+
+ features[0].valid &= ~mask;
+
+ if (legacy_set(dev, value & mask) < 0)
+ netdev_info(dev, "Legacy flags change failed\n");
+
+ return 1;
+}
+
static int ethtool_set_features_compat(struct net_device *dev,
struct ethtool_set_features_block *features)
{
@@ -249,7 +272,7 @@ static int ethtool_set_features_compat(struct net_device *dev,
features, NETIF_F_ALL_TSO);
compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_rx_csum,
features, NETIF_F_RXCSUM);
- compat |= ethtool_set_feature_compat(dev, dev->ethtool_ops->set_flags,
+ compat |= ethtool_set_flags_compat(dev, dev->ethtool_ops->set_flags,
features, flags_dup_features);
return compat;
--
1.7.2.5
^ permalink raw reply related
* Re: [PATCHv3] net: Define enum for the bits used in features.
From: Michał Mirosław @ 2011-05-26 10:40 UTC (permalink / raw)
To: Mahesh Bandewar; +Cc: David Miller, netdev, Tom Herbert, Stephen Hemminger
In-Reply-To: <1306363336-13614-1-git-send-email-maheshb@google.com>
2011/5/26 Mahesh Bandewar <maheshb@google.com>:
> Little bit cleanup by defining enum for all bits used. Also use those enum
> values to redefine flags.
[...]
This BIT2FLAG macro just obfuscates the code (and gives you more
characters to read).
I'd also prefer this patch included the GSO/TSO bits and they are
logically part of this cleanup. But if you think it's easier to review
split, then that's fine by me.
Best Regards,
Michał Mirosław
^ permalink raw reply
* Re: [BUG] netconsole broken by scheduler updates
From: Laurent Riffard @ 2011-05-26 10:35 UTC (permalink / raw)
To: Peter Zijlstra; +Cc: Laurent Riffard, netdev
In-Reply-To: <1306403308.1200.44.camel@twins>
On Thu, 26 May 2011, Peter Zijlstra wrote:
> On Thu, 2011-05-26 at 11:21 +0200, Laurent Riffard wrote:
>> Hi,
>>
>> Recently, netconsole was broken by some scheduler updates. Kernel hangs
>> on boot near the network card initialization. I noticed that it does
>> hang just where a "inconsistent lock state" message normally appears.
>>
>> I did a bisection : e4a52bcb9a18142d79e231b6733cabdbf2e67c1f is the
>> first bad commit.
>> commit e4a52bcb9a18142d79e231b6733cabdbf2e67c1f
>> Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
>> Date: Tue Apr 5 17:23:54 2011 +0200
>>
>> sched: Remove rq->lock from the first half of ttwu()
>>
>>
>> Before this commit, kernel was booting succesfully despite the
>> "inconsistent lock state" message. After this commit, the kernel does
>> hang on boot, I have to push the reset button.
>
> Do you have CONFIG_HARDLOCKUP_DETECTOR=y, and do you get an NMI splat
> after some 10 seconds? It would be interesting to see where its stuck.
CONFIG_HARDLOCKUP_DETECTOR is not set for now. I'll give it a try.
> Also, are you very _very_ sure that lockdep message is a false positive?
I can't answer this question. I just know that before commit e4a52bcb9,
the kernel was able to boot with netconsole despite this message.
Maybe some netconsole developper knows.
~~
laurent
^ permalink raw reply
* Re: [BUG] netconsole broken by scheduler updates
From: Peter Zijlstra @ 2011-05-26 9:48 UTC (permalink / raw)
To: Laurent Riffard; +Cc: netdev
In-Reply-To: <4DDE1B7D.7080707@free.fr>
On Thu, 2011-05-26 at 11:21 +0200, Laurent Riffard wrote:
> Hi,
>
> Recently, netconsole was broken by some scheduler updates. Kernel hangs
> on boot near the network card initialization. I noticed that it does
> hang just where a "inconsistent lock state" message normally appears.
>
> I did a bisection : e4a52bcb9a18142d79e231b6733cabdbf2e67c1f is the
> first bad commit.
> commit e4a52bcb9a18142d79e231b6733cabdbf2e67c1f
> Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
> Date: Tue Apr 5 17:23:54 2011 +0200
>
> sched: Remove rq->lock from the first half of ttwu()
>
>
> Before this commit, kernel was booting succesfully despite the
> "inconsistent lock state" message. After this commit, the kernel does
> hang on boot, I have to push the reset button.
Do you have CONFIG_HARDLOCKUP_DETECTOR=y, and do you get an NMI splat
after some 10 seconds? It would be interesting to see where its stuck.
Also, are you very _very_ sure that lockdep message is a false positive?
^ permalink raw reply
* Re: [RFC Patch] bonding: move to net/ directory
From: Américo Wang @ 2011-05-26 9:32 UTC (permalink / raw)
To: Neil Horman
Cc: Andy Gospodarek, Linux Kernel Network Developers, David Miller,
Jay Vosburgh
In-Reply-To: <20110525152023.GC11867@hmsreliant.think-freely.org>
On Wed, May 25, 2011 at 11:20 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> On Wed, May 25, 2011 at 08:43:21PM +0800, Américo Wang wrote:
>> On Wed, May 25, 2011 at 12:33 AM, Neil Horman <nhorman@tuxdriver.com> wrote:
>> > This all sounds like change for the sake of change to me. I don't see any
>> > compelling argument for moving bonding (or bridging or vlans, etc) around at
>> > all. All of these software drivers have feet in multple subsystems, but that
>> > just means that theres not going to be a compelling argument to move them any
>> > place, at least not without an immediate subsequent argument that it really
>> > belonged back where it was. Unless you can show a solid benefit to moving the
>> > code, I don't see why any reorganization is needed.
>>
>> Well, as a people who worked on bonding code, I have no problem to know
>> bonding code is under drivers/net/, but for people who don't know this, probably
>> net/ is the first place they want to search.
>>
> you've asked them?
>
> cd git/net-next-2.6
> find . -name '*bond*'
No, somone asked me why bonding is not in net/ and after some thinking,
I see no reasons myself (thus sent this patch).
>> The other similar thing is that pktgen is in net/core/ while netconsole is in
>> drivers/net/, which seems a little strange too.
>>
> Its is, and loopback is in /drivers/net, as is tun-tap and xen-netfront (none of
> which touch actual hardware), as is slip and ppp, which are net drivers, but
> only operate on non net hardware. ppoe is another example which operates on
> ethernet, but sits on top of a secondary physical device (and so has no real
> hardware itself). These could all arguably be moved to /net, because they have
> no real hardware, but are in drivers because they implement instances of the net
> driver interface.
>
>> vlan vs macvlan is the third example.
>>
> yes, it is, macvlan, like you assert could be moved, but you could just as
> easily move vlan to /drivers because it implements an instance of the net device
> driver interface.
Then I agree here.
>
> The bottom line is, sometimes things aren't black and white, they're gray. And
> we put code where it makes the most sense at the time. We move it when it
> makes sense to, but I don't hear any compelling argument to make that move.
> Yes, we're not always consistent with where we put hardwareless drivers, but to
> make a policy and shove everything to one place or another doesn't any more
> sense. If we do that we either wind up with things that we think of as drivers
> in the /net directory, or we wind up with stuff thats really protocol oriented
> in the /drivers directory. And if the major problem we solve by doing so is
> making life easier for someone who otherwise wouldn't be able to find said code
> with a quick grep or find operation, it really doesn't seem like its worthwhile
> to me
>
Well, the problem is our code organisation, if we could organize the code
in a better way that would help grepping the code.
>> In short, there are three callers of netdev_rx_handler_register(), macvlan,
>> bonding and bridge, only bridge code stays in net/ directory.
> Why is calling netdev_rx_handler_register a gating factor here?
>
I don't think other drivers are supposed to use this function to register
a packet handler, which is an important difference from my view.
^ permalink raw reply
* [BUG] netconsole broken by scheduler updates
From: Laurent Riffard @ 2011-05-26 9:21 UTC (permalink / raw)
To: netdev, Peter Zijlstra
Hi,
Recently, netconsole was broken by some scheduler updates. Kernel hangs
on boot near the network card initialization. I noticed that it does
hang just where a "inconsistent lock state" message normally appears.
I did a bisection : e4a52bcb9a18142d79e231b6733cabdbf2e67c1f is the
first bad commit.
commit e4a52bcb9a18142d79e231b6733cabdbf2e67c1f
Author: Peter Zijlstra <a.p.zijlstra@chello.nl>
Date: Tue Apr 5 17:23:54 2011 +0200
sched: Remove rq->lock from the first half of ttwu()
Before this commit, kernel was booting succesfully despite the
"inconsistent lock state" message. After this commit, the kernel does
hang on boot, I have to push the reset button.
Here are some lines from dmesg :
Initializing cgroup subsys cpu
Linux version 2.6.39-rc3-00102-g8f42ced (laurent@calimero) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ) #137 SMP PREEMPT Wed May 25 10:09:13 CEST 2011
Command line: BOOT_IMAGE=/vmlinuz-2.6.39-rc3-00102-g8f42ced root=/dev/mapper/vglinux1-lv_ubuntu_64bits ro debug netconsole=4444@192.168.0.9/eth0,6666@192.168.
0.10/6C:62:6D:48:4B:C7 splash vt.handoff=7
[....]
Linux agpgart interface v0.103
forcedeth: Reverse Engineered nForce ethernet driver. Version 0.64.
ACPI: PCI Interrupt Link [APCH] enabled at IRQ 23
forcedeth 0000:00:0a.0: PCI INT A -> Link[APCH] -> GSI 23 (level, low) -> IRQ 23
forcedeth 0000:00:0a.0: setting latency timer to 64
forcedeth 0000:00:0a.0: ifname eth0, PHY OUI 0x732 @ 1, addr 00:1f:d0:53:49:ae
forcedeth 0000:00:0a.0: highdma pwrctl mgmt gbit lnktim msi desc-v3
netconsole: local port 4444
netconsole: local IP 192.168.0.9
netconsole: interface 'eth0'
netconsole: remote port 6666
netconsole: remote IP 192.168.0.10
netconsole: remote ethernet address 6c:62:6d:48:4b:c7
netconsole: device eth0 not up yet, forcing it
forcedeth 0000:00:0a.0: irq 40 for MSI/MSI-X
forcedeth 0000:00:0a.0: eth0: no link during initialization
forcedeth 0000:00:0a.0: eth0: link up
<============== kernel does hang here
=================================
[ INFO: inconsistent lock state ]
2.6.39-rc3-00102-g8f42ced #137
---------------------------------
inconsistent {IN-SOFTIRQ-W} -> {SOFTIRQ-ON-W} usage.
swapper/1 [HC0[0]:SC0[0]:HE1:SE1] takes:
(&(&napi->poll_lock)->rlock){+.?...}, at: [<ffffffff812385a5>] netpoll_poll_dev+0x9e/0x4f1
{IN-SOFTIRQ-W} state was registered at:
[<ffffffff81066607>] __lock_acquire+0x319/0xd62
[<ffffffff8106750e>] lock_acquire+0xd7/0x102
[<ffffffff81295a81>] _raw_spin_lock+0x36/0x45
[<ffffffff81227a13>] net_rx_action+0x8d/0x1e6
[<ffffffff810409b9>] __do_softirq+0xe0/0x1be
[<ffffffff81297e1c>] call_softirq+0x1c/0x30
[<ffffffff810042de>] do_softirq+0x46/0x9c
[<ffffffff81040d0a>] irq_exit+0x4d/0xa2
[<ffffffff81003f92>] do_IRQ+0x88/0x9f
[<ffffffff81296613>] ret_from_intr+0x0/0x1a
[<ffffffff810094b2>] default_idle+0x40/0x74
[<ffffffff810095ca>] c1e_idle+0xe4/0xe6
[<ffffffff81001270>] cpu_idle+0x5e/0x94
[<ffffffff8129018d>] start_secondary+0x18a/0x18f
irq event stamp: 1010077
hardirqs last enabled at (1010077): [<ffffffff81296086>] _raw_spin_unlock_irqrestore+0x40/0x75
hardirqs last disabled at (1010076): [<ffffffff81295b54>] _raw_spin_lock_irqsave+0x1a/0x57
softirqs last enabled at (1008710): [<ffffffff8122cf91>] __dev_mc_add+0x5d/0x6b
softirqs last disabled at (1008704): [<ffffffff81295bdf>] _raw_spin_lock_bh+0x11/0x4a
other info that might help us debug this:
1 lock held by swapper/1:
#0: (target_list_lock){+.+...}, at: [<ffffffff811e258a>] write_msg+0x34/0xd2
stack backtrace:
Pid: 1, comm: swapper Not tainted 2.6.39-rc3-00102-g8f42ced #137
Call Trace:
[<ffffffff81066104>] valid_state+0x17e/0x190
[<ffffffff81065a4c>] ? check_usage_forwards+0x85/0x85
[<ffffffff810661f8>] mark_lock+0xe2/0x1d8
[<ffffffff81066685>] __lock_acquire+0x397/0xd62
[<ffffffff8115e0b5>] ? pci_bus_write_config_dword+0x5e/0x6a
[<ffffffff81296086>] ? _raw_spin_unlock_irqrestore+0x40/0x75
[<ffffffff8106792a>] ? trace_hardirqs_on_caller+0x10b/0x12f
[<ffffffff812385a5>] ? netpoll_poll_dev+0x9e/0x4f1
[<ffffffff8106750e>] lock_acquire+0xd7/0x102
[<ffffffff812385a5>] ? netpoll_poll_dev+0x9e/0x4f1
[<ffffffff81295fbf>] _raw_spin_trylock+0x4a/0x7f
[<ffffffff812385a5>] ? netpoll_poll_dev+0x9e/0x4f1
[<ffffffff812385a5>] netpoll_poll_dev+0x9e/0x4f1
[<ffffffff81238b95>] netpoll_send_skb_on_dev+0x112/0x216
[<ffffffff81238e84>] netpoll_send_udp+0x1eb/0x1fa
[<ffffffff811e258a>] ? write_msg+0x34/0xd2
[<ffffffff811e25e2>] write_msg+0x8c/0xd2
[<ffffffff8103b215>] __call_console_drivers+0x72/0x84
[<ffffffff8103b280>] _call_console_drivers+0x59/0x5e
[<ffffffff8103babb>] console_unlock+0xf3/0x1ac
[<ffffffff8103c30f>] register_console+0x228/0x2b3
[<ffffffff816a71ec>] init_netconsole+0x15d/0x1e4
[<ffffffff8116379b>] ? __pci_register_driver+0x9b/0xcd
[<ffffffff816a708f>] ? option_setup+0x1f/0x1f
[<ffffffff8100030f>] do_one_initcall+0x7a/0x137
[<ffffffff81685be1>] kernel_init+0xb0/0x130
[<ffffffff811553ce>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff81297d24>] kernel_thread_helper+0x4/0x10
[<ffffffff812966d8>] ? retint_restore_args+0x13/0x13
[<ffffffff81685b31>] ? start_kernel+0x379/0x379
[<ffffffff81297d20>] ? gs_change+0x13/0x13
------------[ cut here ]------------
WARNING: at net/core/netpoll.c:346 netpoll_send_skb_on_dev+0x15f/0x216()
Hardware name: M68SM-S2L
netpoll_send_skb(): eth0 enabled interrupts in poll (nv_start_xmit_optimized+0x0/0x487)
Modules linked in:
Pid: 1, comm: swapper Not tainted 2.6.39-rc3-00102-g8f42ced #137
Call Trace:
[<ffffffff8103ae08>] warn_slowpath_common+0x80/0x98
[<ffffffff8103aeb4>] warn_slowpath_fmt+0x41/0x43
[<ffffffff811e1fa9>] ? nv_start_xmit+0x3df/0x3df
[<ffffffff81238be2>] netpoll_send_skb_on_dev+0x15f/0x216
[<ffffffff81238e84>] netpoll_send_udp+0x1eb/0x1fa
[<ffffffff811e258a>] ? write_msg+0x34/0xd2
[<ffffffff811e25e2>] write_msg+0x8c/0xd2
[<ffffffff8103b215>] __call_console_drivers+0x72/0x84
[<ffffffff8103b280>] _call_console_drivers+0x59/0x5e
[<ffffffff8103babb>] console_unlock+0xf3/0x1ac
[<ffffffff8103c30f>] register_console+0x228/0x2b3
[<ffffffff816a71ec>] init_netconsole+0x15d/0x1e4
[<ffffffff8116379b>] ? __pci_register_driver+0x9b/0xcd
[<ffffffff816a708f>] ? option_setup+0x1f/0x1f
[<ffffffff8100030f>] do_one_initcall+0x7a/0x137
[<ffffffff81685be1>] kernel_init+0xb0/0x130
[<ffffffff811553ce>] ? trace_hardirqs_on_thunk+0x3a/0x3f
[<ffffffff81297d24>] kernel_thread_helper+0x4/0x10
[<ffffffff812966d8>] ? retint_restore_args+0x13/0x13
[<ffffffff81685b31>] ? start_kernel+0x379/0x379
[<ffffffff81297d20>] ? gs_change+0x13/0x13
---[ end trace 2b8ff4190d73b338 ]---
console [netcon0] enabled
netconsole: network logging started
~~
laurent
^ permalink raw reply
* hi
From: genesambo @ 2011-05-26 9:26 UTC (permalink / raw)
Hi,i am miss gene,i see your profile now,and i am so interested on you,please write to me back with this email, (genesambo@yahoo.co.uk)i will tell you about me with my picture,
^ permalink raw reply
* Re: [RFC Patch] bonding: move to net/ directory
From: Américo Wang @ 2011-05-26 9:11 UTC (permalink / raw)
To: Neil Horman
Cc: Andy Gospodarek, Linux Kernel Network Developers, David Miller,
Jay Vosburgh
In-Reply-To: <20110525150144.GB11867@hmsreliant.think-freely.org>
On Wed, May 25, 2011 at 11:01 PM, Neil Horman <nhorman@tuxdriver.com> wrote:
> While thats a fine rule to draw a distinction on, it also creates other
> organizational oddities. By this reasoning, the loopback/tun-tap and xen
> netfront drivers should also be moved to /net. While this might be an ok move
> to make, I think we can all agree, that while they don't touch specific
> hardware, they implement instances of the driver model, and as such are
> reasonably placed in /drivers.
>
Hmm, after reading Andy's comments again, I think his point is
probably bridge has STP management code which makes a difference
with bonding, but you know, we have 802.3ad in bonding too.
> This is really a false assertion. Theres nothing more or less hard about
> finding bonding code in /drivers than there is in /net. grep and find let you
> locate the code in either place equally well, and cscope really makes it all
> moot anyway.
>
Sometimes cscope sucks, especially when you meet function pointers
which are pretty common in net code. When I grep netpoll code, I have to
do `grep ndo_netpoll_setup -nr net/ drivers/net`, if bonding were in net/
`grep -nr net/` is enough. 'netdev_rx_handler_register' too.
^ permalink raw reply
* Re: [PATCH][Trivial] mac80211: Remove duplicate linux/slab.h include from net/mac80211/scan.c
From: Luciano Coelho @ 2011-05-26 9:06 UTC (permalink / raw)
To: Jesper Juhl
Cc: linux-kernel, John W. Linville, Johannes Berg, David S. Miller,
netdev, linux-wireless, trivial
In-Reply-To: <alpine.LNX.2.00.1105261048570.17400@swampdragon.chaosbits.net>
On Thu, 2011-05-26 at 10:53 +0200, Jesper Juhl wrote:
> Commit 79f460ca49d8d5700756ab7071c951311c7f29cc add a duplicate
> linux/slab.h include to net/mac80211/scan.c - remove it.
>
> Signed-off-by: Jesper Juhl <jj@chaosbits.net>
> ---
Hmmm... indeed! Must have been a rebase mistake I made. Thanks for
fixing it.
Acked-by: Luciano Coelho <coelho@ti.com>
--
Cheers,
Luca.
^ permalink raw reply
* [PATCH][Trivial] mac80211: Remove duplicate linux/slab.h include from net/mac80211/scan.c
From: Jesper Juhl @ 2011-05-26 8:53 UTC (permalink / raw)
To: linux-kernel
Cc: Luciano Coelho, John W. Linville, Johannes Berg, David S. Miller,
netdev, linux-wireless, trivial
Commit 79f460ca49d8d5700756ab7071c951311c7f29cc add a duplicate
linux/slab.h include to net/mac80211/scan.c - remove it.
Signed-off-by: Jesper Juhl <jj@chaosbits.net>
---
scan.c | 1 -
1 file changed, 1 deletion(-)
patch against current Linus' tree
diff --git a/net/mac80211/scan.c b/net/mac80211/scan.c
index 27af672..58ffa7d 100644
--- a/net/mac80211/scan.c
+++ b/net/mac80211/scan.c
@@ -15,7 +15,6 @@
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/pm_qos_params.h>
-#include <linux/slab.h>
#include <net/sch_generic.h>
#include <linux/slab.h>
#include <net/mac80211.h>
--
Jesper Juhl <jj@chaosbits.net> http://www.chaosbits.net/
Don't top-post http://www.catb.org/jargon/html/T/top-post.html
Plain text mails only, please.
^ permalink raw reply related
* Re: [PATCH V5 2/6 net-next] netdevice.h: Add zero-copy flag in netdevice
From: Michael S. Tsirkin @ 2011-05-26 8:49 UTC (permalink / raw)
To: Shirley Ma
Cc: Michał Mirosław, Ben Hutchings, David Miller,
Eric Dumazet, Avi Kivity, Arnd Bergmann, netdev, kvm,
linux-kernel
In-Reply-To: <1306363780.26270.44.camel@localhost.localdomain>
On Wed, May 25, 2011 at 03:49:40PM -0700, Shirley Ma wrote:
> On Fri, 2011-05-20 at 02:41 +0300, Michael S. Tsirkin wrote:
> > So the requirements are
> > - data must be released in a timely fashion (e.g. unlike virtio-net
> > tun or bridge)
> The current patch doesn't enable tun zero-copy. tun will copy data It's
> not an issue now.
> We can disallow macvtap attach to bridge when
> zero-copy is enabled.
Attach macvtap to a tun device though. Or e.g. veth device ...
So there should be so generic way to disable zerocopy.
It can either be a whitelist or a blacklist.
>
> > - SG support
> > - HIGHDMA support (on arches where this makes sense)
>
> This can be checked by device flags.
OK, but pls note that SG can get turned off dynamically.
> > - no filtering based on data (data is mapped in guest)
>
> > - on fast path no calls to skb_copy, skb_clone, pskb_copy,
> > pskb_expand_head as these are slow
>
> Any calls to skb_copy, skb_clone, pskb_copy, pskb_expand_head will do a
> copy. The performance should be the same as none zero-copy case before.
I'm guessing a copy is cheaper than get_user_pages+copy+put_page.
But maybe not by much. Care checking that?
> I have done/tested the patch V6, will send it out for review tomorrow.
>
> I am looking at where there are some cases, skb remains the same for
> filtering.
To reliably filter on data I think we'll need to copy it first, otherwise
guest can change it. Most filters only look at the header though.
> > First 2 requirements are a must, all other requirements
> > are just dependencies to make sure zero copy will be faster
> > than non zero copy.
> > Using a new feature bit is probably the simplest approach to
> > this. macvtap on top of most physical NICs most likely works
> > correctly so it seems a bit more work than it needs to be,
> > but it's also the safest one I think ...
>
> For "macvtap/vhost zero-copy" we can use SG & HIGHDMA to enable it, it
> looks safe to me once patching skb_copy, skb_clone, pskb_copy,
> pskb_expand_head.
>
> To extend zero-copy in other usages, we can have a new feature bit
> later.
>
> Is that reasonable?
>
> Thanks
> Shirley
Is the problem is extra work needed to extend feature bits?
--
MST
^ permalink raw reply
* Re: [PATCH 12/34] isdn/diva: Drop __TIME__ usage
From: Michal Marek @ 2011-05-26 8:29 UTC (permalink / raw)
To: Armin Schindler; +Cc: linux-kbuild, linux-kernel, netdev
In-Reply-To: <alpine.DEB.2.00.1105261012360.20696@justus.melware.de>
On 26.5.2011 10:15, Armin Schindler wrote:
> On Wed, 25 May 2011, Michal Marek wrote:
>> Dne 5.4.2011 17:10, Armin Schindler napsal(a):
>>> On Tue, 5 Apr 2011, Michal Marek wrote:
>>>> The kernel already prints its build timestamp during boot, no need to
>>>> repeat it in random drivers and produce different object files each
>>>> time.
>>>
>>> The module can be build separately from the kernel, therefore it can have
>>> an own build timestamp.
>>
>> So the module timestamp and kernel timestamp vary by a couple of
>> minutes. But is it really a problem?
>
> It could be a lot more than minutes. But it isn't a problem.
> I just tried to keep the sources in sync with out-of-tree version.
>
>> I don't think so. So is there an
>> objection against applying this patch?
>
> No objection. Please go ahead with the patch.
OK, thanks. Applied to kbuild-2.6.git#trivial.
Michal
^ permalink raw reply
* Re: [PATCH 12/34] isdn/diva: Drop __TIME__ usage
From: Armin Schindler @ 2011-05-26 8:15 UTC (permalink / raw)
To: Michal Marek; +Cc: linux-kbuild, linux-kernel, netdev
In-Reply-To: <4DDD68C3.7000004@suse.cz>
On Wed, 25 May 2011, Michal Marek wrote:
> Dne 5.4.2011 17:10, Armin Schindler napsal(a):
>> On Tue, 5 Apr 2011, Michal Marek wrote:
>>> The kernel already prints its build timestamp during boot, no need to
>>> repeat it in random drivers and produce different object files each
>>> time.
>>
>> The module can be build separately from the kernel, therefore it can have
>> an own build timestamp.
>
> So the module timestamp and kernel timestamp vary by a couple of
> minutes. But is it really a problem?
It could be a lot more than minutes. But it isn't a problem.
I just tried to keep the sources in sync with out-of-tree version.
> I don't think so. So is there an
> objection against applying this patch?
No objection. Please go ahead with the patch.
Thanks
Armin
^ permalink raw reply
* Re: [PATCH 1/1] IPVS : bug in ip_vs_ftp, same list heaad used in all netns.
From: Julian Anastasov @ 2011-05-26 8:07 UTC (permalink / raw)
To: Hans Schillstrom; +Cc: horms, wensong, lvs-devel, netdev, netfilter-devel, hans
In-Reply-To: <1306239065-17271-1-git-send-email-hans.schillstrom@ericsson.com>
Hello,
On Tue, 24 May 2011, Hans Schillstrom wrote:
> When ip_vs was adapted to netns the ftp application was not adapted
> in a correct way.
> However this is a fix to avoid kernel errors. In the long term another solution
> might be chosen. I.e the ports that the ftp appl, uses should be per netns.
>
> Signed-off-by: Hans Schillstrom <hans.schillstrom@ericsson.com>
Looks good
Acked-by: Julian Anastasov <ja@ssi.bg>
> ---
> include/net/ip_vs.h | 3 ++-
> net/netfilter/ipvs/ip_vs_ftp.c | 27 +++++++++++++++++++--------
> 2 files changed, 21 insertions(+), 9 deletions(-)
>
> diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h
> index 4fff432..481f856 100644
> --- a/include/net/ip_vs.h
> +++ b/include/net/ip_vs.h
> @@ -797,7 +797,8 @@ struct netns_ipvs {
> struct list_head rs_table[IP_VS_RTAB_SIZE];
> /* ip_vs_app */
> struct list_head app_list;
> -
> + /* ip_vs_ftp */
> + struct ip_vs_app *ftp_app;
> /* ip_vs_proto */
> #define IP_VS_PROTO_TAB_SIZE 32 /* must be power of 2 */
> struct ip_vs_proto_data *proto_data_table[IP_VS_PROTO_TAB_SIZE];
> diff --git a/net/netfilter/ipvs/ip_vs_ftp.c b/net/netfilter/ipvs/ip_vs_ftp.c
> index 6b5dd6d..af63553 100644
> --- a/net/netfilter/ipvs/ip_vs_ftp.c
> +++ b/net/netfilter/ipvs/ip_vs_ftp.c
> @@ -411,25 +411,35 @@ static struct ip_vs_app ip_vs_ftp = {
> static int __net_init __ip_vs_ftp_init(struct net *net)
> {
> int i, ret;
> - struct ip_vs_app *app = &ip_vs_ftp;
> + struct ip_vs_app *app;
> + struct netns_ipvs *ipvs = net_ipvs(net);
> +
> + app = kmemdup(&ip_vs_ftp, sizeof(struct ip_vs_app), GFP_KERNEL);
> + if (!app)
> + return -ENOMEM;
> + INIT_LIST_HEAD(&app->a_list);
> + INIT_LIST_HEAD(&app->incs_list);
> + ipvs->ftp_app = app;
>
> ret = register_ip_vs_app(net, app);
> if (ret)
> - return ret;
> + goto err_exit;
>
> for (i=0; i<IP_VS_APP_MAX_PORTS; i++) {
> if (!ports[i])
> continue;
> ret = register_ip_vs_app_inc(net, app, app->protocol, ports[i]);
> if (ret)
> - break;
> + goto err_unreg;
> pr_info("%s: loaded support on port[%d] = %d\n",
> app->name, i, ports[i]);
> }
> + return 0;
>
> - if (ret)
> - unregister_ip_vs_app(net, app);
> -
> +err_unreg:
> + unregister_ip_vs_app(net, app);
> +err_exit:
> + kfree(ipvs->ftp_app);
> return ret;
> }
> /*
> @@ -437,9 +447,10 @@ static int __net_init __ip_vs_ftp_init(struct net *net)
> */
> static void __ip_vs_ftp_exit(struct net *net)
> {
> - struct ip_vs_app *app = &ip_vs_ftp;
> + struct netns_ipvs *ipvs = net_ipvs(net);
>
> - unregister_ip_vs_app(net, app);
> + unregister_ip_vs_app(net, ipvs->ftp_app);
> + kfree(ipvs->ftp_app);
> }
>
> static struct pernet_operations ip_vs_ftp_ops = {
> --
> 1.7.2.3
Regards
--
Julian Anastasov <ja@ssi.bg>
^ permalink raw reply
* (no subject)
From: ©2011.Coca-Cola Great Britain @ 2011-05-25 18:36 UTC (permalink / raw)
--
25-05-2011
Your Mail-ID has been awarded £750,000.00 GBP as one of our online winners
in our web bonanza sweepstakes From The Coca-Cola Online Promo 2011 . For
claims send;
Name:
Address:
Phone No:
Age: Sex:
Occupation:
Country:
Contact: Mr. Jim Gardner
Claims department : jim-gardner.c@live.com
TEL: +44 755 284 8328
^ permalink raw reply
* Re: [PATCH] timers: consider slack value in mod_timer()
From: Yong Zhang @ 2011-05-26 6:19 UTC (permalink / raw)
To: Thomas Gleixner
Cc: Sebastian Andrzej Siewior, LKML, Arjan van de Ven,
Trond Myklebust, David Miller, netdev
In-Reply-To: <alpine.LFD.2.02.1105251126590.3078@ionos>
On Wed, May 25, 2011 at 6:17 PM, Thomas Gleixner <tglx@linutronix.de> wrote:
>> Hmmm, so the reason is for a timer whose timer->slack is not set
>> explicitly. when we recalculate expires, we will get different value
>> sometimes.
>
> No, that's not the problem.
>
>> Could you please try the attached patch(webmail will mangle it)
>
> Grrr. gmail allows usage of real mail clients, doesn't it ?
Yeah, but sometimes I can only access webmail due to some reason
>
>> diff --git a/kernel/timer.c b/kernel/timer.c
>> index fd61986..73af53c 100644
>> --- a/kernel/timer.c
>> +++ b/kernel/timer.c
>> @@ -749,6 +749,10 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
>> unsigned long expires_limit, mask;
>> int bit;
>>
>> + /* no need to account slack again for a same-expire pending timer */
>> + if (timer_pending(timer) && time_after_eq(timer->expires, expires))
>> + return timer->expires;
>
> That's total crap. Assume some code sets the timer with 5 seconds for
> some purpose and after a second it wants it to fire in 50ms from now
> because some state change happened. The above will keep the original 5
> seconds timeout no matter what, so the requested 50ms timeout will
> fire about 4 seconds late.
Indeed. I forgot that case
.
>
>> expires_limit = expires;
>>
>> if (timer->slack >= 0) {
>> @@ -795,6 +799,8 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
>> */
>> int mod_timer(struct timer_list *timer, unsigned long expires)
>> {
>> + expires = apply_slack(timer, expires);
>> +
>
> We need to analyse the problem thoroughly and not slap random changes
> into the code without knowing about the consequences. And the problem
> is mostly in the call sites because they are not aware of the slack
> effect.
>
> The sunrpc code is one of those which are affected by the slack magic
> simply because it makes the mod_timer() call basically unconditional
> even if the jiffies value is unchanged.
>
> diff --git a/net/sunrpc/xprt.c b/net/sunrpc/xprt.c
> index ce5eb68..cb0574f 100644
> --- a/net/sunrpc/xprt.c
> +++ b/net/sunrpc/xprt.c
> @@ -1053,10 +1053,12 @@ void xprt_release(struct rpc_task *task)
> xprt->ops->release_request(task);
> if (!list_empty(&req->rq_list))
> list_del(&req->rq_list);
> - xprt->last_used = jiffies;
> - if (list_empty(&xprt->recv) && xprt_has_timer(xprt))
> - mod_timer(&xprt->timer,
> - xprt->last_used + xprt->idle_timeout);
> + if (xprt->last_used = jiffies) {
Typo? s/=/!=/?
> + xprt->last_used = jiffies;
> + if (list_empty(&xprt->recv) && xprt_has_timer(xprt))
> + mod_timer(&xprt->timer,
> + xprt->last_used + xprt->idle_timeout);
> + }
> spin_unlock_bh(&xprt->transport_lock);
> if (req->rq_buffer)
> xprt->ops->buf_free(req->rq_buffer);
>
> The above patch does not solve the problem when the resulting new
> timeout is rounded up to the same expiry value after the slack is
> applied, which is not unlikely when jiffies only advanced by a small
> amount.
>
> So we must check after apply_slack() and the reason why the first
> check before apply_slack triggers very often is that auto slack only
> changes the expiry value for timeouts >= 256 jiffies.
>
> And the main caller is the networking code via
> tcp_send_delayed_ack(). The standard delay we see from there is 40ms
> (10 jiffies for HZ=250) and that falls below the 256 jiffies treshold.
>
> The patch below is a reasonable compromise between overhead and
> correctness.
Yup, I think it could smooth Sebastian's issue.
Thanks,
Yong
>
> Thanks,
>
> tglx
>
> diff --git a/kernel/timer.c b/kernel/timer.c
> index fd61986..458fd81 100644
> --- a/kernel/timer.c
> +++ b/kernel/timer.c
> @@ -749,16 +749,15 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
> unsigned long expires_limit, mask;
> int bit;
>
> - expires_limit = expires;
> -
> if (timer->slack >= 0) {
> expires_limit = expires + timer->slack;
> } else {
> - unsigned long now = jiffies;
> + long delta = expires - jiffies;
> +
> + if (delta < 256)
> + return expires;
>
> - /* No slack, if already expired else auto slack 0.4% */
> - if (time_after(expires, now))
> - expires_limit = expires + (expires - now)/256;
> + expires_limit = expires + (expires - now)/256;
> }
> mask = expires ^ expires_limit;
> if (mask == 0)
> @@ -795,6 +794,8 @@ unsigned long apply_slack(struct timer_list *timer, unsigned long expires)
> */
> int mod_timer(struct timer_list *timer, unsigned long expires)
> {
> + expires = apply_slack(timer, expires);
> +
> /*
> * This is a common optimization triggered by the
> * networking code - if the timer is re-modified
> @@ -803,8 +804,6 @@ int mod_timer(struct timer_list *timer, unsigned long expires)
> if (timer_pending(timer) && timer->expires == expires)
> return 1;
>
> - expires = apply_slack(timer, expires);
> -
> return __mod_timer(timer, expires, false, TIMER_NOT_PINNED);
> }
> EXPORT_SYMBOL(mod_timer);
>
--
Only stand for myself
^ permalink raw reply
* Re: [PATCH net-next-2.6] bonding: cleanup module option descriptions
From: WeipingPan @ 2011-05-26 3:35 UTC (permalink / raw)
To: Andy Gospodarek; +Cc: netdev
In-Reply-To: <1306334519-20243-1-git-send-email-andy@greyhouse.net>
On 05/25/2011 10:41 PM, Andy Gospodarek wrote:
> Weiping Pan noticed that the module option description for
> xmit_hash_policy was incorrect and was nice enough to post a patch to
> fix it. The text was correct, but created a line over 80 characters and
> I would rather not add those. I realized I could take a few minutes and
> clean up all the descriptions and things would look much better. This
> is the result.
>
> Based on patch from Weiping Pan<panweiping3@gmail.com>.
>
> Signed-off-by: Andy Gospodarek<andy@greyhouse.net>
> CC: Weiping Pan<panweiping3@gmail.com>
>
> ---
> drivers/net/bonding/bond_main.c | 34 ++++++++++++++++++++++------------
> 1 files changed, 22 insertions(+), 12 deletions(-)
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 088fd84..31a61d3 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -113,9 +113,11 @@ MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
> module_param(tx_queues, int, 0);
> MODULE_PARM_DESC(tx_queues, "Max number of transmit queues (default = 16)");
> module_param_named(num_grat_arp, num_peer_notif, int, 0644);
> -MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on failover event (alias of num_unsol_na)");
> +MODULE_PARM_DESC(num_grat_arp, "Number of peer notifications to send on "
> + "failover event (alias of num_unsol_na)");
> module_param_named(num_unsol_na, num_peer_notif, int, 0644);
> -MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on failover event (alias of num_grat_arp)");
> +MODULE_PARM_DESC(num_unsol_na, "Number of peer notifications to send on "
> + "failover event (alias of num_grat_arp)");
> module_param(miimon, int, 0);
> MODULE_PARM_DESC(miimon, "Link check interval in milliseconds");
> module_param(updelay, int, 0);
> @@ -127,7 +129,7 @@ module_param(use_carrier, int, 0);
> MODULE_PARM_DESC(use_carrier, "Use netif_carrier_ok (vs MII ioctls) in miimon; "
> "0 for off, 1 for on (default)");
> module_param(mode, charp, 0);
> -MODULE_PARM_DESC(mode, "Mode of operation : 0 for balance-rr, "
> +MODULE_PARM_DESC(mode, "Mode of operation; 0 for balance-rr, "
> "1 for active-backup, 2 for balance-xor, "
> "3 for broadcast, 4 for 802.3ad, 5 for balance-tlb, "
> "6 for balance-alb");
> @@ -142,27 +144,35 @@ MODULE_PARM_DESC(primary_reselect, "Reselect primary slave "
> "2 for only on active slave "
> "failure");
> module_param(lacp_rate, charp, 0);
> -MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner "
> - "(slow/fast)");
> +MODULE_PARM_DESC(lacp_rate, "LACPDU tx rate to request from 802.3ad partner; "
> + "0 for slow, 1 for fast");
> module_param(ad_select, charp, 0);
> -MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic: stable (0, default), bandwidth (1), count (2)");
> +MODULE_PARM_DESC(ad_select, "803.ad aggregation selection logic; "
> + "0 for stable (default), 1 for bandwidth, "
> + "2 for count");
> module_param(xmit_hash_policy, charp, 0);
> -MODULE_PARM_DESC(xmit_hash_policy, "XOR hashing method: 0 for layer 2 (default)"
> - ", 1 for layer 3+4");
> +MODULE_PARM_DESC(xmit_hash_policy, "balance-xor and 802.3ad hashing method; "
> + "0 for layer 2 (default), 1 for layer 3+4, "
> + "2 for layer 2+3");
> module_param(arp_interval, int, 0);
> MODULE_PARM_DESC(arp_interval, "arp interval in milliseconds");
> module_param_array(arp_ip_target, charp, NULL, 0);
> MODULE_PARM_DESC(arp_ip_target, "arp targets in n.n.n.n form");
> module_param(arp_validate, charp, 0);
> -MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes: none (default), active, backup or all");
> +MODULE_PARM_DESC(arp_validate, "validate src/dst of ARP probes; "
> + "0 for none (default), 1 for active, "
> + "2 for backup, 3 for all");
> module_param(fail_over_mac, charp, 0);
> -MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to the same MAC. none (default), active or follow");
> +MODULE_PARM_DESC(fail_over_mac, "For active-backup, do not set all slaves to "
> + "the same MAC; 0 for none (default), "
> + "1 for active, 2 for follow");
> module_param(all_slaves_active, int, 0);
> MODULE_PARM_DESC(all_slaves_active, "Keep all frames received on an interface"
> - "by setting active flag for all slaves. "
> + "by setting active flag for all slaves; "
> "0 for never (default), 1 for always.");
> module_param(resend_igmp, int, 0);
> -MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on link failure");
> +MODULE_PARM_DESC(resend_igmp, "Number of IGMP membership reports to send on "
> + "link failure");
>
> /*----------------------------- Global variables ----------------------------*/
>
That look much clearer.
Reviewed-by: Weiping Pan <panweiping3@gmail.com>
^ permalink raw reply
* Re: [PATCHv2 10/14] virtio_net: limit xmit polling
From: Rusty Russell @ 2011-05-26 3:28 UTC (permalink / raw)
To: Michael S. Tsirkin
Cc: Krishna Kumar, Carsten Otte, lguest-uLR06cmDAlY/bJ5BZ2RsiQ,
Shirley Ma, kvm-u79uwXL29TY76Z2rM5mHXA,
linux-s390-u79uwXL29TY76Z2rM5mHXA, netdev-u79uwXL29TY76Z2rM5mHXA,
habanero-23VcF4HTsmIX0ybBhKVfKdBPR1lH4CV8, Heiko Carstens,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
virtualization-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA,
steved-r/Jw6+rmf7HQT0dZR+AlfA, Christian Borntraeger,
Tom Lendacky, Martin Schwidefsky, linux390-tA70FqPdS9bQT0dZR+AlfA
In-Reply-To: <20110525060759.GC26352-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
On Wed, 25 May 2011 09:07:59 +0300, "Michael S. Tsirkin" <mst-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
> On Wed, May 25, 2011 at 11:05:04AM +0930, Rusty Russell wrote:
> Hmm I'm not sure I got it, need to think about this.
> I'd like to go back and document how my design was supposed to work.
> This really should have been in commit log or even a comment.
> I thought we need a min, not a max.
> We start with this:
>
> while ((c = (virtqueue_get_capacity(vq) < 2 + MAX_SKB_FRAGS) &&
> (skb = get_buf)))
> kfree_skb(skb);
> return !c;
>
> This is clean and simple, right? And it's exactly asking for what we need.
No, I started from the other direction:
for (i = 0; i < 2; i++) {
skb = get_buf();
if (!skb)
break;
kfree_skb(skb);
}
ie. free two packets for every one we're about to add. For steady state
that would work really well. Then we hit the case where the ring seems
full after we do the add: at that point, screw latency, and just try to
free all the buffers we can.
> on the normal path min == 2 so we're low latency but we keep ahead on
> average. min == 0 for the "we're out of capacity, we may have to stop
> the queue".
>
> Does the above make sense at all?
It makes sense, but I think it's a classic case where incremental
improvements aren't as good as starting from scratch.
Cheers,
Rusty.
^ permalink raw reply
* Re: CPU instruction to calculate tcp checksum and udp integrity?
From: Peter Teoh @ 2011-05-26 2:57 UTC (permalink / raw)
To: Jon Zhou; +Cc: netdev@vger.kernel.org, kernelnewbies@kernelnewbies.org
In-Reply-To: <4A6A2125329CFD4D8CC40C9E8ABCAB9F250D8894E6@MILEXCH2.ds.jdsu.net>
In net/ipv4/tcp_ipv4.c:
/* This routine computes an IPv4 TCP checksum. */
void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb)
{
struct inet_sock *inet = inet_sk(sk);
__tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr);
}
EXPORT_SYMBOL(tcp_v4_send_check);
On Mon, May 23, 2011 at 11:26 PM, Jon Zhou <Jon.Zhou@jdsu.com> wrote:
> hi
> now I am using sw to calculate the tcp checksum, is there CPU(nehalem)
> instruction or NIC /kernel API to do such thing?
>
> thanks a lot
> jon
>
>
> _______________________________________________
> Kernelnewbies mailing list
> Kernelnewbies@kernelnewbies.org
> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>
>
--
Regards,
Peter Teoh
^ permalink raw reply
* Re: [Bugme-new] [Bug 35862] New: arp requests from wrong src IP
From: Victor Mataré @ 2011-05-26 2:00 UTC (permalink / raw)
To: David Miller; +Cc: akpm, netdev, bugzilla-daemon, bugme-daemon
In-Reply-To: <20110525.215222.22117057747103565.davem@davemloft.net>
On Thursday, 26.05.2011 03:52:22 David Miller wrote:
> From: Andrew Morton <akpm@linux-foundation.org>
> Date: Wed, 25 May 2011 16:31:37 -0700
>
> >> I switched a host's ip address from 137.226.164.13 to 137.226.164.2. The .13 IP
> >> now belongs to the host that had .2 before (I swapped them). Now both hosts
> >> still arp from their old IPs although ifconfig as well as ip clearly tell
> >> otherwise. Examining the host which now has 137.226.164.13:
> >>
> >> # ip addr show dev eth0
> >> 4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
> >> link/ether 00:e0:81:41:1f:e4 brd ff:ff:ff:ff:ff:ff
> >> inet 137.226.164.2/24 brd 137.226.164.255 scope global eth0
> >> inet 192.168.23.2/24 brd 137.226.164.255 scope global eth0:0
>
> If you keep the old IP address around it remains as the "primary"
> IP address.
>
> You have to explicitly remove the original IP address from the
> interface first, then add the new one, in order for the new
> one to become the "primary"
>
> Not a bug, please close this.
>
Sorry, there's a typo. It's supposed to read:
[...]
Examining the host which now has 137.226.164.2 (used to have 137.226.164.13):
# ip addr show dev eth0
4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
link/ether 00:e0:81:41:1f:e4 brd ff:ff:ff:ff:ff:ff
inet 137.226.164.2/24 brd 137.226.164.255 scope global eth0
inet 192.168.23.2/24 brd 137.226.164.255 scope global eth0:0
[...]
Sorry, got confused with all the swapping. I'm *not* keeping the old address around, it's completely *gone*, from both ifconfig and ip. But still it's being used as arp src address. That's what this bug is about. Sorry for the confusion.
^ permalink raw reply
* LOAN
From: STF @ 2011-05-25 16:30 UTC (permalink / raw)
--
Good Day,
We are private Loan lending Firm who give out loans to reliable individuals
and companies globally at 2% interest rate per annum. Do you need finance
to establish your business or for personal purpose? Our interest rate is
very affordable and our loan process is very fast as well. If you are
really ready to get your financial problems solved, then search no further
and apply for a loan today.If interested, Please reply with the following
information.
Amount Needed:
Duration of the loan:
Phone Number:
Country:
Regards,
Mrs Linda More
Secretary.
^ permalink raw reply
* Re: [Bugme-new] [Bug 35862] New: arp requests from wrong src IP
From: David Miller @ 2011-05-26 1:52 UTC (permalink / raw)
To: akpm; +Cc: netdev, bugzilla-daemon, bugme-daemon, matare
In-Reply-To: <20110525163137.6f04f26e.akpm@linux-foundation.org>
From: Andrew Morton <akpm@linux-foundation.org>
Date: Wed, 25 May 2011 16:31:37 -0700
>> I switched a host's ip address from 137.226.164.13 to 137.226.164.2. The .13 IP
>> now belongs to the host that had .2 before (I swapped them). Now both hosts
>> still arp from their old IPs although ifconfig as well as ip clearly tell
>> otherwise. Examining the host which now has 137.226.164.13:
>>
>> # ip addr show dev eth0
>> 4: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP qlen 1000
>> link/ether 00:e0:81:41:1f:e4 brd ff:ff:ff:ff:ff:ff
>> inet 137.226.164.2/24 brd 137.226.164.255 scope global eth0
>> inet 192.168.23.2/24 brd 137.226.164.255 scope global eth0:0
If you keep the old IP address around it remains as the "primary"
IP address.
You have to explicitly remove the original IP address from the
interface first, then add the new one, in order for the new
one to become the "primary"
Not a bug, please close this.
^ 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