* [PATCH v3 02/10] net/fec: remove the use of "index" which is legacy
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
The "index" becomes legacy since fep->pdev->id starts working
to identify the instance.
Moreover, the call of fec_enet_init(ndev, 0) always passes 0
to fep->index. This makes the following code in fec_get_mac buggy.
/* Adjust MAC if using default MAC address */
if (iap == fec_mac_default)
dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
It may be the time to remove "index" and use fep->pdev->id instead.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
drivers/net/fec.c | 9 +++------
1 files changed, 3 insertions(+), 6 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 52e9ca8..47f6b3b 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -186,7 +186,6 @@ struct fec_enet_private {
int mii_timeout;
uint phy_speed;
phy_interface_t phy_interface;
- int index;
int link;
int full_duplex;
struct completion mdio_done;
@@ -566,7 +565,7 @@ static void __inline__ fec_get_mac(struct net_device *dev)
/* Adjust MAC if using default MAC address */
if (iap == fec_mac_default)
- dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+ dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->pdev->id;
}
#endif
@@ -1067,9 +1066,8 @@ static const struct net_device_ops fec_netdev_ops = {
/*
* XXX: We need to clean up on failure exits here.
*
- * index is only used in legacy code
*/
-static int fec_enet_init(struct net_device *dev, int index)
+static int fec_enet_init(struct net_device *dev)
{
struct fec_enet_private *fep = netdev_priv(dev);
struct bufdesc *cbd_base;
@@ -1086,7 +1084,6 @@ static int fec_enet_init(struct net_device *dev, int index)
spin_lock_init(&fep->hw_lock);
- fep->index = index;
fep->hwp = (void __iomem *)dev->base_addr;
fep->netdev = dev;
@@ -1316,7 +1313,7 @@ fec_probe(struct platform_device *pdev)
}
clk_enable(fep->clk);
- ret = fec_enet_init(ndev, 0);
+ ret = fec_enet_init(ndev);
if (ret)
goto failed_init;
--
1.7.1
^ permalink raw reply related
* [PATCH v3 04/10] net/fec: improve pm for better suspend/resume
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
The following commit made a fix to use fec_enet_open/fec_enet_close
over fec_enet_init/fec_stop for suspend/resume, because fec_enet_init
does not allow to have a working network interface at resume.
e3fe8558c7fc182972c3d947d88744482111f304
net/fec: fix pm to survive to suspend/resume
This fix works for i.mx/mxc fec controller, but fails on mx28 fec
which gets a different interrupt logic design. On i.mx fec, interrupt
can be triggered even bit ETHER_EN of ECR register is not set. But
on mx28 fec, ETHER_EN must be set to get interrupt work. Meanwhile,
MII interrupt is mandatory to resume the driver, because MDIO
read/write changed to interrupt mode by commit below.
97b72e4320a9aaa4a7f1592ee7d2da7e2c9bd349
fec: use interrupt for MDIO completion indication
fec_restart/fec_stop comes out as the solution working for both
cases.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
drivers/net/fec.c | 12 ++++++++----
1 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 47a3c7b..8a1c51f 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -1372,8 +1372,10 @@ fec_suspend(struct device *dev)
if (ndev) {
fep = netdev_priv(ndev);
- if (netif_running(ndev))
- fec_enet_close(ndev);
+ if (netif_running(ndev)) {
+ fec_stop(ndev);
+ netif_device_detach(ndev);
+ }
clk_disable(fep->clk);
}
return 0;
@@ -1388,8 +1390,10 @@ fec_resume(struct device *dev)
if (ndev) {
fep = netdev_priv(ndev);
clk_enable(fep->clk);
- if (netif_running(ndev))
- fec_enet_open(ndev);
+ if (netif_running(ndev)) {
+ fec_restart(ndev, fep->full_duplex);
+ netif_device_attach(ndev);
+ }
}
return 0;
}
--
1.7.1
^ permalink raw reply related
* [PATCH v3 05/10] net/fec: add dual fec support for mx28
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
This patch is to add mx28 dual fec support. Here are some key notes
for mx28 fec controller.
- The mx28 fec controller naming ENET-MAC is a different IP from FEC
used on other i.mx variants. But they are basically compatible
on software interface, so it's possible to share the same driver.
- ENET-MAC design made an improper assumption that it runs on a
big-endian system. As the result, driver has to swap every frame
going to and coming from the controller.
- The external phys can only be configured by fec0, which means fec1
can not work independently and both phys need to be configured by
mii_bus attached on fec0.
- ENET-MAC reset will get mac address registers reset too.
- ENET-MAC MII/RMII mode and 10M/100M speed are configured
differently FEC.
- ETHER_EN bit must be set to get ENET-MAC interrupt work.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Move v2 changes into patch #3
- Use device name to check if it's running on ENET-MAC
drivers/net/Kconfig | 7 ++-
drivers/net/fec.c | 140 +++++++++++++++++++++++++++++++++++++++++++++------
drivers/net/fec.h | 5 +-
3 files changed, 131 insertions(+), 21 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 4f1755b..f34629b 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1944,18 +1944,19 @@ config 68360_ENET
config FEC
bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
- MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
+ MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
select PHYLIB
help
Say Y here if you want to use the built-in 10/100 Fast ethernet
controller on some Motorola ColdFire and Freescale i.MX processors.
config FEC2
- bool "Second FEC ethernet controller (on some ColdFire CPUs)"
+ bool "Second FEC ethernet controller"
depends on FEC
help
Say Y here if you want to use the second built-in 10/100 Fast
- ethernet controller on some Motorola ColdFire processors.
+ ethernet controller on some Motorola ColdFire and Freescale
+ i.MX processors.
config FEC_MPC52xx
tristate "MPC52xx FEC driver"
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 8a1c51f..67ba263 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -17,6 +17,8 @@
*
* Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
* Copyright (c) 2004-2006 Macq Electronique SA.
+ *
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
*/
#include <linux/module.h>
@@ -45,20 +47,33 @@
#include <asm/cacheflush.h>
-#ifndef CONFIG_ARCH_MXC
+#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_SOC_IMX28)
#include <asm/coldfire.h>
#include <asm/mcfsim.h>
#endif
#include "fec.h"
-#ifdef CONFIG_ARCH_MXC
-#include <mach/hardware.h>
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
#define FEC_ALIGNMENT 0xf
#else
#define FEC_ALIGNMENT 0x3
#endif
+#define DRIVER_NAME "fec"
+#define ENET_MAC_NAME "enet-mac"
+
+static struct platform_device_id fec_devtype[] = {
+ {
+ .name = DRIVER_NAME,
+ }, {
+ .name = ENET_MAC_NAME,
+ }
+};
+
+static unsigned fec_is_enetmac;
+static struct mii_bus *fec_mii_bus;
+
static unsigned char macaddr[ETH_ALEN];
module_param_array(macaddr, byte, NULL, 0);
MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
@@ -129,7 +144,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
* account when setting it.
*/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+ defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
#define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
#else
#define OPT_FRAME_SIZE 0
@@ -208,6 +224,17 @@ static void fec_stop(struct net_device *dev);
/* Transmitter timeout */
#define TX_TIMEOUT (2 * HZ)
+static void *swap_buffer(void *bufaddr, int len)
+{
+ int i;
+ unsigned int *buf = bufaddr;
+
+ for (i = 0; i < (len + 3) / 4; i++, buf++)
+ *buf = __swab32(*buf);
+
+ return bufaddr;
+}
+
static netdev_tx_t
fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
@@ -256,6 +283,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
bufaddr = fep->tx_bounce[index];
}
+ /*
+ * enet-mac design made an improper assumption that it's running
+ * on a big endian system. As the result, driver has to swap
+ * every frame going to and coming from the controller.
+ */
+ if (fec_is_enetmac)
+ swap_buffer(bufaddr, skb->len);
+
/* Save skb pointer */
fep->tx_skbuff[fep->skb_cur] = skb;
@@ -487,6 +522,9 @@ fec_enet_rx(struct net_device *dev)
dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
DMA_FROM_DEVICE);
+ if (fec_is_enetmac)
+ swap_buffer(data, pkt_len);
+
/* This does 16 byte alignment, exactly what we need.
* The packet length includes FCS, but we don't want to
* include that when passing upstream as it messes up
@@ -689,6 +727,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
char mdio_bus_id[MII_BUS_ID_SIZE];
char phy_name[MII_BUS_ID_SIZE + 3];
int phy_id;
+ int dev_id = fep->pdev->id;
fep->phy_dev = NULL;
@@ -700,6 +739,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
continue;
if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
continue;
+ if (fec_is_enetmac && dev_id--)
+ continue;
strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
break;
}
@@ -741,6 +782,28 @@ static int fec_enet_mii_init(struct platform_device *pdev)
struct fec_enet_private *fep = netdev_priv(dev);
int err = -ENXIO, i;
+ /*
+ * The dual fec interfaces are not equivalent with enet-mac.
+ * Here are the differences:
+ *
+ * - fec0 supports MII & RMII modes while fec1 only supports RMII
+ * - fec0 acts as the 1588 time master while fec1 is slave
+ * - external phys can only be configured by fec0
+ *
+ * That is to say fec1 can not work independently. It only works
+ * when fec0 is working. The reason behind this design is that the
+ * second interface is added primarily for Switch mode.
+ *
+ * Because of the last point above, both phys are attached on fec0
+ * mdio interface in board design, and need to be configured by
+ * fec0 mii_bus.
+ */
+ if (fec_is_enetmac && pdev->id) {
+ /* fec1 uses fec0 mii_bus */
+ fep->mii_bus = fec_mii_bus;
+ return 0;
+ }
+
fep->mii_timeout = 0;
/*
@@ -777,6 +840,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
if (mdiobus_register(fep->mii_bus))
goto err_out_free_mdio_irq;
+ /* save fec0 mii_bus */
+ if (fec_is_enetmac)
+ fec_mii_bus = fep->mii_bus;
+
return 0;
err_out_free_mdio_irq:
@@ -1149,11 +1216,22 @@ fec_restart(struct net_device *dev, int duplex)
{
struct fec_enet_private *fep = netdev_priv(dev);
int i;
+ u32 val, temp_mac[2];
/* Whack a reset. We should wait for this. */
writel(1, fep->hwp + FEC_ECNTRL);
udelay(10);
+ /*
+ * enet-mac reset will reset mac address registers too,
+ * so need to reconfigure it.
+ */
+ if (fec_is_enetmac) {
+ memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
+ writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
+ writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
+ }
+
/* Clear any outstanding interrupt. */
writel(0xffc00000, fep->hwp + FEC_IEVENT);
@@ -1200,20 +1278,45 @@ fec_restart(struct net_device *dev, int duplex)
/* Set MII speed */
writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
-#ifdef FEC_MIIGSK_ENR
- if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
- /* disable the gasket and wait */
- writel(0, fep->hwp + FEC_MIIGSK_ENR);
- while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
- udelay(1);
+ /*
+ * The phy interface and speed need to get configured
+ * differently on enet-mac.
+ */
+ if (fec_is_enetmac) {
+ val = readl(fep->hwp + FEC_R_CNTRL);
- /* configure the gasket: RMII, 50 MHz, no loopback, no echo */
- writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+ /* MII or RMII */
+ if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
+ val |= (1 << 8);
+ else
+ val &= ~(1 << 8);
- /* re-enable the gasket */
- writel(2, fep->hwp + FEC_MIIGSK_ENR);
- }
+ /* 10M or 100M */
+ if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
+ val &= ~(1 << 9);
+ else
+ val |= (1 << 9);
+
+ writel(val, fep->hwp + FEC_R_CNTRL);
+ } else {
+#ifdef FEC_MIIGSK_ENR
+ if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
+ /* disable the gasket and wait */
+ writel(0, fep->hwp + FEC_MIIGSK_ENR);
+ while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
+ udelay(1);
+
+ /*
+ * configure the gasket:
+ * RMII, 50 MHz, no loopback, no echo
+ */
+ writel(1, fep->hwp + FEC_MIIGSK_CFGR);
+
+ /* re-enable the gasket */
+ writel(2, fep->hwp + FEC_MIIGSK_ENR);
+ }
#endif
+ }
/* And last, enable the transmit and receive processing */
writel(2, fep->hwp + FEC_ECNTRL);
@@ -1301,6 +1404,10 @@ fec_probe(struct platform_device *pdev)
}
}
+ /* check if it's ENET-MAC controller via device name */
+ if (!strcmp(pdev->name, ENET_MAC_NAME))
+ fec_is_enetmac = 1;
+
fep->clk = clk_get(&pdev->dev, "fec_clk");
if (IS_ERR(fep->clk)) {
ret = PTR_ERR(fep->clk);
@@ -1410,12 +1517,13 @@ static const struct dev_pm_ops fec_pm_ops = {
static struct platform_driver fec_driver = {
.driver = {
- .name = "fec",
+ .name = DRIVER_NAME,
.owner = THIS_MODULE,
#ifdef CONFIG_PM
.pm = &fec_pm_ops,
#endif
},
+ .id_table = fec_devtype,
.probe = fec_probe,
.remove = __devexit_p(fec_drv_remove),
};
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 2c48b25..ace318d 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -14,7 +14,8 @@
/****************************************************************************/
#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
- defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
+ defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
+ defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
/*
* Just figures, Motorola would have to change the offsets for
* registers in the same peripheral device on different models
@@ -78,7 +79,7 @@
/*
* Define the buffer descriptor structure.
*/
-#ifdef CONFIG_ARCH_MXC
+#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
struct bufdesc {
unsigned short cbd_datlen; /* Data length */
unsigned short cbd_sc; /* Control and status info */
--
1.7.1
^ permalink raw reply related
* [PATCH v3 06/10] ARM: mx28: update clock and device name for dual fec support
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
Change device name from "fec" to "enet-mac", so that fec driver
can distinguish ENET-MAC controller from FEC.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v3:
- Change device name to "enet-mac"
arch/arm/mach-mxs/clock-mx28.c | 3 ++-
arch/arm/mach-mxs/devices/platform-fec.c | 2 +-
2 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-mxs/clock-mx28.c b/arch/arm/mach-mxs/clock-mx28.c
index f20b254..933d3e6 100644
--- a/arch/arm/mach-mxs/clock-mx28.c
+++ b/arch/arm/mach-mxs/clock-mx28.c
@@ -606,7 +606,8 @@ static struct clk_lookup lookups[] = {
_REGISTER_CLOCK("duart", "apb_pclk", xbus_clk)
/* for amba-pl011 driver */
_REGISTER_CLOCK("duart", NULL, uart_clk)
- _REGISTER_CLOCK("fec.0", NULL, fec_clk)
+ _REGISTER_CLOCK("enet-mac.0", NULL, fec_clk)
+ _REGISTER_CLOCK("enet-mac.1", NULL, fec_clk)
_REGISTER_CLOCK("rtc", NULL, rtc_clk)
_REGISTER_CLOCK("pll2", NULL, pll2_clk)
_REGISTER_CLOCK(NULL, "hclk", hbus_clk)
diff --git a/arch/arm/mach-mxs/devices/platform-fec.c b/arch/arm/mach-mxs/devices/platform-fec.c
index c08168c..754bd83 100644
--- a/arch/arm/mach-mxs/devices/platform-fec.c
+++ b/arch/arm/mach-mxs/devices/platform-fec.c
@@ -45,6 +45,6 @@ struct platform_device *__init mxs_add_fec(
},
};
- return mxs_add_platform_device("fec", data->id,
+ return mxs_add_platform_device("enet-mac", data->id,
res, ARRAY_SIZE(res), pdata, sizeof(*pdata));
}
--
1.7.1
^ permalink raw reply related
* [PATCH v3 08/10] ARM: mxs: add ocotp read function
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Add mutex locking for mxs_read_ocotp()
- Use type size_t for count and i
- Add comment for clk_enable/disable skipping
- Add ERROR bit clearing and polling step
arch/arm/mach-mxs/Makefile | 2 +-
arch/arm/mach-mxs/include/mach/common.h | 1 +
arch/arm/mach-mxs/ocotp.c | 79 +++++++++++++++++++++++++++++++
3 files changed, 81 insertions(+), 1 deletions(-)
create mode 100644 arch/arm/mach-mxs/ocotp.c
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index 39d3f9c..f23ebbd 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,5 +1,5 @@
# Common support
-obj-y := clock.o devices.o gpio.o icoll.o iomux.o system.o timer.o
+obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/include/mach/common.h b/arch/arm/mach-mxs/include/mach/common.h
index 59133eb..cf02552 100644
--- a/arch/arm/mach-mxs/include/mach/common.h
+++ b/arch/arm/mach-mxs/include/mach/common.h
@@ -13,6 +13,7 @@
struct clk;
+extern int mxs_read_ocotp(int offset, int count, u32 *values);
extern int mxs_reset_block(void __iomem *);
extern void mxs_timer_init(struct clk *, int);
diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
new file mode 100644
index 0000000..902ef59
--- /dev/null
+++ b/arch/arm/mach-mxs/ocotp.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+
+#include <mach/mxs.h>
+
+#define BM_OCOTP_CTRL_BUSY (1 << 8)
+#define BM_OCOTP_CTRL_ERROR (1 << 9)
+#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
+
+static DEFINE_MUTEX(ocotp_mutex);
+
+int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
+{
+ void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
+ int timeout = 0x400;
+ size_t i;
+
+ mutex_lock(&ocotp_mutex);
+
+ /*
+ * clk_enable(hbus_clk) for ocotp can be skipped
+ * as it must be on when system is running.
+ */
+
+ /* try to clear ERROR bit */
+ __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
+
+ /* check both BUSY and ERROR cleared */
+ while ((__raw_readl(ocotp_base) &
+ (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
+ /* nothing */;
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ /* open OCOTP banks for read */
+ __mxs_setl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ /* approximately wait 32 hclk cycles */
+ udelay(1);
+
+ /* poll BUSY bit becoming cleared */
+ timeout = 0x400;
+ while ((__raw_readl(ocotp_base) & BM_OCOTP_CTRL_BUSY) && --timeout)
+ /* nothing */;
+
+ if (unlikely(!timeout))
+ goto error_unlock;
+
+ for (i = 0; i < count; i++, offset += 4)
+ *values++ = __raw_readl(ocotp_base + offset);
+
+ /* close banks for power saving */
+ __mxs_clrl(BM_OCOTP_CTRL_RD_BANK_OPEN, ocotp_base);
+
+ mutex_unlock(&ocotp_mutex);
+
+ return 0;
+
+error_unlock:
+ mutex_unlock(&ocotp_mutex);
+ pr_err("%s: timeout in reading OCOTP\n", __func__);
+ return -ETIMEDOUT;
+}
--
1.7.1
^ permalink raw reply related
* [PATCH v3 07/10] ARM: mx28: add the second fec device registration
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
arch/arm/mach-mxs/mach-mx28evk.c | 28 +++++++++++++++++++++++++---
1 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index d162e95..def6519 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -57,6 +57,19 @@ static const iomux_cfg_t mx28evk_pads[] __initconst = {
(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
MX28_PAD_ENET_CLK__CLKCTRL_ENET |
(MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ /* fec1 */
+ MX28_PAD_ENET0_CRS__ENET1_RX_EN |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RXD2__ENET1_RXD0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_RXD3__ENET1_RXD1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_COL__ENET1_TX_EN |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TXD2__ENET1_TXD0 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
+ MX28_PAD_ENET0_TXD3__ENET1_TXD1 |
+ (MXS_PAD_8MA | MXS_PAD_3V3 | MXS_PAD_PULLUP),
/* phy power line */
MX28_PAD_SSP1_DATA3__GPIO_2_15 |
(MXS_PAD_4MA | MXS_PAD_3V3 | MXS_PAD_NOPULL),
@@ -106,8 +119,14 @@ static void __init mx28evk_fec_reset(void)
gpio_set_value(MX28EVK_FEC_PHY_RESET, 1);
}
-static const struct fec_platform_data mx28_fec_pdata __initconst = {
- .phy = PHY_INTERFACE_MODE_RMII,
+static struct fec_platform_data mx28_fec_pdata[] = {
+ {
+ /* fec0 */
+ .phy = PHY_INTERFACE_MODE_RMII,
+ }, {
+ /* fec1 */
+ .phy = PHY_INTERFACE_MODE_RMII,
+ },
};
static void __init mx28evk_init(void)
@@ -117,7 +136,10 @@ static void __init mx28evk_init(void)
mx28_add_duart();
mx28evk_fec_reset();
- mx28_add_fec(0, &mx28_fec_pdata);
+ mx28_add_fec(0, &mx28_fec_pdata[0]);
+#ifdef CONFIG_FEC2
+ mx28_add_fec(1, &mx28_fec_pdata[1]);
+#endif
}
static void __init mx28evk_timer_init(void)
--
1.7.1
^ permalink raw reply related
* [PATCH v3 10/10] ARM: mxs: add initial pm support
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
This is a very initial pm support and basically does nothing.
With this pm support entry, drivers can start testing their own
pm functions.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- Let build of pm.c depend on CONFIG_PM
- Remove the blank line above device_initcall in pm.c
arch/arm/mach-mxs/Makefile | 2 ++
arch/arm/mach-mxs/pm.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 45 insertions(+), 0 deletions(-)
create mode 100644 arch/arm/mach-mxs/pm.c
diff --git a/arch/arm/mach-mxs/Makefile b/arch/arm/mach-mxs/Makefile
index f23ebbd..45a2925 100644
--- a/arch/arm/mach-mxs/Makefile
+++ b/arch/arm/mach-mxs/Makefile
@@ -1,6 +1,8 @@
# Common support
obj-y := clock.o devices.o gpio.o icoll.o iomux.o ocotp.o system.o timer.o
+obj-$(CONFIG_PM) += pm.o
+
obj-$(CONFIG_SOC_IMX23) += clock-mx23.o mm-mx23.o
obj-$(CONFIG_SOC_IMX28) += clock-mx28.o mm-mx28.o
diff --git a/arch/arm/mach-mxs/pm.c b/arch/arm/mach-mxs/pm.c
new file mode 100644
index 0000000..fb042da
--- /dev/null
+++ b/arch/arm/mach-mxs/pm.c
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2010 Freescale Semiconductor, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/suspend.h>
+#include <linux/io.h>
+#include <mach/system.h>
+
+static int mxs_suspend_enter(suspend_state_t state)
+{
+ switch (state) {
+ case PM_SUSPEND_MEM:
+ arch_idle();
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static struct platform_suspend_ops mxs_suspend_ops = {
+ .enter = mxs_suspend_enter,
+ .valid = suspend_valid_only_mem,
+};
+
+static int __init mxs_pm_init(void)
+{
+ suspend_set_ops(&mxs_suspend_ops);
+ return 0;
+}
+device_initcall(mxs_pm_init);
--
1.7.1
^ permalink raw reply related
* [PATCH v3 09/10] ARM: mx28: read fec mac address from ocotp
From: Shawn Guo @ 2011-01-05 14:07 UTC (permalink / raw)
To: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig
Cc: Shawn Guo
In-Reply-To: <1294236457-17476-1-git-send-email-shawn.guo@freescale.com>
Read fec mac address from ocotp and save it into fec_platform_data
mac field for fec driver to use.
Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
---
Changes for v2:
- It's not necessary to remove "const" for fec_platform_data from
platform-fec.c and devices-common.h, so add it back.
- Hard-coding Freescale OUI (00:04:9f) instead of just the first
two two octets.
- Correct the return of mx28evk_fec_get_mac() and check it
with caller
arch/arm/mach-mxs/mach-mx28evk.c | 32 ++++++++++++++++++++++++++++++++
1 files changed, 32 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-mxs/mach-mx28evk.c b/arch/arm/mach-mxs/mach-mx28evk.c
index def6519..54fa512 100644
--- a/arch/arm/mach-mxs/mach-mx28evk.c
+++ b/arch/arm/mach-mxs/mach-mx28evk.c
@@ -129,12 +129,44 @@ static struct fec_platform_data mx28_fec_pdata[] = {
},
};
+static int __init mx28evk_fec_get_mac(void)
+{
+ int i, ret;
+ u32 val;
+
+ /*
+ * OCOTP only stores the last 4 octets for each mac address,
+ * so hard-code Freescale OUI (00:04:9f) here.
+ */
+ for (i = 0; i < 2; i++) {
+ ret = mxs_read_ocotp(0x20 + i * 0x10, 1, &val);
+ if (ret)
+ goto error;
+
+ mx28_fec_pdata[i].mac[0] = 0x00;
+ mx28_fec_pdata[i].mac[1] = 0x04;
+ mx28_fec_pdata[i].mac[2] = 0x9f;
+ mx28_fec_pdata[i].mac[3] = (val >> 16) & 0xff;
+ mx28_fec_pdata[i].mac[4] = (val >> 8) & 0xff;
+ mx28_fec_pdata[i].mac[5] = (val >> 0) & 0xff;
+ }
+
+ return 0;
+
+error:
+ pr_err("%s: timeout when reading fec mac from OCOTP\n", __func__);
+ return ret;
+}
+
static void __init mx28evk_init(void)
{
mxs_iomux_setup_multiple_pads(mx28evk_pads, ARRAY_SIZE(mx28evk_pads));
mx28_add_duart();
+ if (mx28evk_fec_get_mac())
+ pr_warn("%s: failed on fec mac setup\n", __func__);
+
mx28evk_fec_reset();
mx28_add_fec(0, &mx28_fec_pdata[0]);
#ifdef CONFIG_FEC2
--
1.7.1
^ permalink raw reply related
* [PATCH v2] netfilter: fix the race when initializing nf_ct_expect_hash_rnd
From: Changli Gao @ 2011-01-05 14:23 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, David S. Miller, netdev, Changli Gao
Since nf_ct_expect_dst_hash() may be called without nf_conntrack_lock
locked, nf_ct_expect_hash_rnd should be initialized in the atomic way.
In this patch, we use nf_conntrack_hash_rnd instead of
nf_ct_expect_hash_rnd.
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
v2: use nf_conntrack_hash_rnd.
include/net/netfilter/nf_conntrack.h | 2 ++
net/netfilter/nf_conntrack_core.c | 30 +++++++++++++++++-------------
net/netfilter/nf_conntrack_expect.c | 10 +++-------
3 files changed, 22 insertions(+), 20 deletions(-)
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index caf17db..d85cff1 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -298,6 +298,8 @@ static inline int nf_ct_is_untracked(const struct nf_conn *ct)
extern int nf_conntrack_set_hashsize(const char *val, struct kernel_param *kp);
extern unsigned int nf_conntrack_htable_size;
extern unsigned int nf_conntrack_max;
+extern unsigned int nf_conntrack_hash_rnd;
+void init_nf_conntrack_hash_rnd(void);
#define NF_CT_STAT_INC(net, count) \
__this_cpu_inc((net)->ct.stat->count)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 27a5ea6..e615119 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -65,7 +65,7 @@ EXPORT_SYMBOL_GPL(nf_conntrack_max);
DEFINE_PER_CPU(struct nf_conn, nf_conntrack_untracked);
EXPORT_PER_CPU_SYMBOL(nf_conntrack_untracked);
-static unsigned int nf_conntrack_hash_rnd __read_mostly;
+unsigned int nf_conntrack_hash_rnd __read_mostly;
static u32 hash_conntrack_raw(const struct nf_conntrack_tuple *tuple, u16 zone)
{
@@ -596,6 +596,21 @@ static noinline int early_drop(struct net *net, unsigned int hash)
return dropped;
}
+void init_nf_conntrack_hash_rnd(void)
+{
+ unsigned int rand;
+
+ /*
+ * Why not initialize nf_conntrack_rnd in a "init()" function ?
+ * Because there isn't enough entropy when system initializing,
+ * and we initialize it as late as possible.
+ */
+ do {
+ get_random_bytes(&rand, sizeof(rand));
+ } while (!rand);
+ cmpxchg(&nf_conntrack_hash_rnd, 0, rand);
+}
+
static struct nf_conn *
__nf_conntrack_alloc(struct net *net, u16 zone,
const struct nf_conntrack_tuple *orig,
@@ -605,18 +620,7 @@ __nf_conntrack_alloc(struct net *net, u16 zone,
struct nf_conn *ct;
if (unlikely(!nf_conntrack_hash_rnd)) {
- unsigned int rand;
-
- /*
- * Why not initialize nf_conntrack_rnd in a "init()" function ?
- * Because there isn't enough entropy when system initializing,
- * and we initialize it as late as possible.
- */
- do {
- get_random_bytes(&rand, sizeof(rand));
- } while (!rand);
- cmpxchg(&nf_conntrack_hash_rnd, 0, rand);
-
+ init_nf_conntrack_hash_rnd();
/* recompute the hash as nf_conntrack_hash_rnd is initialized */
hash = hash_conntrack_raw(orig, zone);
}
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index 46e8966..a20fb0b 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -32,9 +32,7 @@
unsigned int nf_ct_expect_hsize __read_mostly;
EXPORT_SYMBOL_GPL(nf_ct_expect_hsize);
-static unsigned int nf_ct_expect_hash_rnd __read_mostly;
unsigned int nf_ct_expect_max __read_mostly;
-static int nf_ct_expect_hash_rnd_initted __read_mostly;
static struct kmem_cache *nf_ct_expect_cachep __read_mostly;
@@ -77,15 +75,13 @@ static unsigned int nf_ct_expect_dst_hash(const struct nf_conntrack_tuple *tuple
{
unsigned int hash;
- if (unlikely(!nf_ct_expect_hash_rnd_initted)) {
- get_random_bytes(&nf_ct_expect_hash_rnd,
- sizeof(nf_ct_expect_hash_rnd));
- nf_ct_expect_hash_rnd_initted = 1;
+ if (unlikely(!nf_conntrack_hash_rnd)) {
+ init_nf_conntrack_hash_rnd();
}
hash = jhash2(tuple->dst.u3.all, ARRAY_SIZE(tuple->dst.u3.all),
(((tuple->dst.protonum ^ tuple->src.l3num) << 16) |
- (__force __u16)tuple->dst.u.all) ^ nf_ct_expect_hash_rnd);
+ (__force __u16)tuple->dst.u.all) ^ nf_conntrack_hash_rnd);
return ((u64)hash * nf_ct_expect_hsize) >> 32;
}
^ permalink raw reply related
* Re: linux-next: manual merge of the trivial tree with the net tree
From: Jiri Kosina @ 2011-01-05 14:51 UTC (permalink / raw)
To: Stephen Rothwell
Cc: linux-next, linux-kernel, Justin P. Mattock, Wey-Yi Guy,
John W. Linville, David Miller, netdev
In-Reply-To: <20110104142229.7aa6b99f.sfr@canb.auug.org.au>
On Tue, 4 Jan 2011, Stephen Rothwell wrote:
> Today's linux-next merge of the trivial tree got a conflict in
> drivers/net/wireless/iwlwifi/iwl-core.c between commit
> 81baf6ec9c190ae128748cf2a026bff5cb811b70 ("iwlwifi: Legacy isr only used
> by legacy devices") from the net tree and commit
> 62e45c14fb9a978dca6c7a5dc8372cc8ea2f42c8 ("wireless: comment typo fix
> diable -> disable") from the trivial tree.
>
> The former moves the code modified by the latter to
> drivers/net/wireless/iwlwifi/iwl-legacy.c. I didn't bother refixing the
> typo there.
I will definitely be merging to Linus trivial queue later than davem will,
so I'll be resolving this. Thanks,
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: linux-next: manual merge of the trivial tree with the net tree
From: Justin P. Mattock @ 2011-01-05 15:22 UTC (permalink / raw)
To: Jiri Kosina
Cc: Stephen Rothwell, linux-next, linux-kernel, Wey-Yi Guy,
John W. Linville, David Miller, netdev
In-Reply-To: <alpine.LNX.2.00.1101051550240.26685@pobox.suse.cz>
On 01/05/2011 06:51 AM, Jiri Kosina wrote:
> On Tue, 4 Jan 2011, Stephen Rothwell wrote:
>
>> Today's linux-next merge of the trivial tree got a conflict in
>> drivers/net/wireless/iwlwifi/iwl-core.c between commit
>> 81baf6ec9c190ae128748cf2a026bff5cb811b70 ("iwlwifi: Legacy isr only used
>> by legacy devices") from the net tree and commit
>> 62e45c14fb9a978dca6c7a5dc8372cc8ea2f42c8 ("wireless: comment typo fix
>> diable -> disable") from the trivial tree.
>>
>> The former moves the code modified by the latter to
>> drivers/net/wireless/iwlwifi/iwl-legacy.c. I didn't bother refixing the
>> typo there.
>
> I will definitely be merging to Linus trivial queue later than davem will,
> so I'll be resolving this. Thanks,
>
yeah, I saw this, but was not sure how to reply due to not really
knowing what happened(looking at the patch these are just in comments,
as opposed to the other patch(7) that actually changes code. keep in
mind im not sure if it was moved forward due to me having to send out
another version due to changes(haven't gotten around due to external
things that need to be taken care of))..
Justin P. Mattock
^ permalink raw reply
* Re: [net-next-2.6 PATCH] ethtool: update get_rx_ntuple to correctly interpret string count
From: Ben Hutchings @ 2011-01-05 15:26 UTC (permalink / raw)
To: Alexander Duyck; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <4D23C423.3050609@intel.com>
On Tue, 2011-01-04 at 17:06 -0800, Alexander Duyck wrote:
> On 1/4/2011 4:01 PM, Ben Hutchings wrote:
> > On Tue, 2011-01-04 at 15:29 -0800, Alexander Duyck wrote:
> >> Currently any strings returned via the get_rx_ntuple call will just be
> >> dropped because the num_strings will be zero. In order to correct this I
> >> am updating things so that the return value of get_rx_ntuple is the number
> >> of strings that were written, or a negative value if there was an error.
> > [...]
> >
> > Nothing implements ethtool_ops::get_rx_ntuple, anyway.
> >
> > The fallback implementation is totally bogus, too. Maximum of 1024
> > filters? Erm, sfc can handle more than that. And doing complex string
> > formatting in the kernel, even though all the parsing is in ethtool?
> >
> > Please, let's write off ETHTOOL_GRXNTUPLE as a failed experiment and
> > replace it with a command that behaves more like ETHTOOL_GRXCLSRLALL.
> >
> > Ben.
>
> In order to address several different issues in the perfect filters
> provided by 82599 I found it necessary to implement get_rx_ntuple so
> that the driver could maintain the filter list inside of the driver
> instead of having it maintained by the stack. In doing so though I
> found the bug.
>
> I agree the fallback implementation has a limitation on the number and
> format of filters it supports. However declaring the function a "failed
> experiment" and just dropping it isn't exactly constructive since we
> have customers that are making use of the feature.
[...]
We can at least drop that fallback implementation since it apparently
doesn't work properly for either of the drivers that currently use it.
In the medium term, I do want to replace it with a binary interface and
move that formatting to ethtool. ETHTOOL_GRXNTUPLE could be kept around
for a while for ixgbe only, while your customers have a chance to get
the updated ethtool.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] atl1: fix oops when changing tx/rx ring params
From: Luca Tettamanti @ 2011-01-05 15:42 UTC (permalink / raw)
To: J. K. Cliburn
Cc: David Miller, netdev, stable, jussuf, chris.snook, Xiong.Huang
In-Reply-To: <20110101090212.7149010d@osprey.hogchain.net>
On Sat, Jan 1, 2011 at 4:02 PM, J. K. Cliburn <jcliburn@gmail.com> wrote:
> Commit 3f5a2a713aad28480d86b0add00c68484b54febc zeroes out the statistics
> message block (SMB) and coalescing message block (CMB) when adapter ring
> resources are freed. This is desirable behavior, but, as a side effect,
> the commit leads to an oops when atl1_set_ringparam() attempts to alter
> the number of rx or tx elements in the ring buffer (by using ethtool
> -G, for example). We don't want SMB or CMB to change during this
> operation.
>
> Modify atl1_set_ringparam() to preserve SMB and CMB when changing ring
> parameters.
>
> Cc: stable@kernel.org
> Signed-off-by: Jay Cliburn <jcliburn@gmail.com>
> Reported-by: Tõnu Raitviir <jussuf@linux.ee>
> ---
> drivers/net/atlx/atl1.c | 10 ++++++++++
> 1 files changed, 10 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/net/atlx/atl1.c b/drivers/net/atlx/atl1.c
> index 5336310..3acf512 100644
> --- a/drivers/net/atlx/atl1.c
> +++ b/drivers/net/atlx/atl1.c
> @@ -3504,6 +3504,8 @@ static int atl1_set_ringparam(struct net_device *netdev,
> struct atl1_rfd_ring rfd_old, rfd_new;
> struct atl1_rrd_ring rrd_old, rrd_new;
> struct atl1_ring_header rhdr_old, rhdr_new;
> + struct atl1_smb smb;
> + struct atl1_cmb cmb;
> int err;
>
> tpd_old = adapter->tpd_ring;
> @@ -3544,11 +3546,19 @@ static int atl1_set_ringparam(struct net_device *netdev,
> adapter->rrd_ring = rrd_old;
> adapter->tpd_ring = tpd_old;
> adapter->ring_header = rhdr_old;
> + /*
> + * Save SMB and CMB, since atl1_free_ring_resources
> + * will clear them.
> + */
> + smb = adapter->smb;
> + cmb = adapter->cmb;
> atl1_free_ring_resources(adapter);
Hum, unless I'm missing something atl1_free_ring_resources frees the
whole ring_header->dma block which contains both SMB and CMB.
> adapter->rfd_ring = rfd_new;
> adapter->rrd_ring = rrd_new;
> adapter->tpd_ring = tpd_new;
> adapter->ring_header = rhdr_new;
> + adapter->smb = smb;
> + adapter->cmb = cmb;
So here you're using pointers to freed memory.
In order to preserve the stats you'd have to copy the structure.
Luca
^ permalink raw reply
* Re: [PATCH] atl1: fix oops when changing tx/rx ring params
From: Luca Tettamanti @ 2011-01-05 15:45 UTC (permalink / raw)
To: J. K. Cliburn
Cc: David Miller, netdev, stable, jussuf, chris.snook, Xiong.Huang
In-Reply-To: <AANLkTinizyGFhzTgTMQ=ojL4v+htqvRM9c62dgHUss3f@mail.gmail.com>
On Wed, Jan 5, 2011 at 4:42 PM, Luca Tettamanti <kronos.it@gmail.com> wrote:
> So here you're using pointers to freed memory.
> In order to preserve the stats you'd have to copy the structure.
Doh. I still haven't recovered from all the partying ;-)
Sorry for the noise...
L
^ permalink raw reply
* Re: [PATCH v2] net: Allow ethtool to set interface in loopback mode.
From: Jeff Garzik @ 2011-01-05 16:22 UTC (permalink / raw)
To: Ben Hutchings
Cc: Stephen Hemminger, Mahesh Bandewar, David Miller, Laurent Chavey,
Tom Herbert, netdev
In-Reply-To: <1294190504.2992.3.camel@localhost>
On 01/04/2011 08:21 PM, Ben Hutchings wrote:
> On Tue, 2011-01-04 at 16:36 -0800, Stephen Hemminger wrote:
>> On Tue, 4 Jan 2011 16:30:01 -0800
>> Mahesh Bandewar<maheshb@google.com> wrote:
>>
>>> This patch enables ethtool to set the loopback mode on a given interface.
>>> By configuring the interface in loopback mode in conjunction with a policy
>>> route / rule, a userland application can stress the egress / ingress path
>>> exposing the flows of the change in progress and potentially help developer(s)
>>> understand the impact of those changes without even sending a packet out
>>> on the network.
>>>
>>> Following set of commands illustrates one such example -
>>> a) ip -4 addr add 192.168.1.1/24 dev eth1
>>> b) ip -4 rule add from all iif eth1 lookup 250
>>> c) ip -4 route add local 0/0 dev lo proto kernel scope host table 250
>>> d) arp -Ds 192.168.1.100 eth1
>>> e) arp -Ds 192.168.1.200 eth1
>>> f) sysctl -w net.ipv4.ip_nonlocal_bind=1
>>> g) sysctl -w net.ipv4.conf.all.accept_local=1
>>> # Assuming that the machine has 8 cores
>>> h) taskset 000f netserver -L 192.168.1.200
>>> i) taskset 00f0 netperf -t TCP_CRR -L 192.168.1.100 -H 192.168.1.200 -l 30
>>>
>>> Signed-off-by: Mahesh Bandewar<maheshb@google.com>
>>> Reviewed-by: Ben Hutchings<bhutchings@solarflare.com>
>>
>> Since this is a boolean it SHOULD go into ethtool_flags rather than
>> being a high level operation.
>
> It could do, but I though ETHTOOL_{G,S}FLAGS were intended for
> controlling offload features.
It doesn't have to be. As Stephen guessed, [GS]FLAGS are basically
common flags -- as differentiated from private,
driver-specific/hardware-specific flags.
Jeff
^ permalink raw reply
* Re: [PATCH v3 08/10] ARM: mxs: add ocotp read function
From: Jamie Iles @ 2011-01-05 16:16 UTC (permalink / raw)
To: Shawn Guo
Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542,
u.kleine-koenig, lw, w.sang, s.hauer, netdev, linux-arm-kernel
In-Reply-To: <1294236457-17476-9-git-send-email-shawn.guo@freescale.com>
Hi Shawn,
On Wed, Jan 05, 2011 at 10:07:35PM +0800, Shawn Guo wrote:
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v2:
> - Add mutex locking for mxs_read_ocotp()
> - Use type size_t for count and i
> - Add comment for clk_enable/disable skipping
> - Add ERROR bit clearing and polling step
>
> arch/arm/mach-mxs/Makefile | 2 +-
> arch/arm/mach-mxs/include/mach/common.h | 1 +
> arch/arm/mach-mxs/ocotp.c | 79 +++++++++++++++++++++++++++++++
> 3 files changed, 81 insertions(+), 1 deletions(-)
> create mode 100644 arch/arm/mach-mxs/ocotp.c
>
[...]
> diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> new file mode 100644
> index 0000000..902ef59
> --- /dev/null
> +++ b/arch/arm/mach-mxs/ocotp.c
> @@ -0,0 +1,79 @@
> +/*
> + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License as published by
> + * the Free Software Foundation; either version 2 of the License, or
> + * (at your option) any later version.
> + *
> + * This program is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/err.h>
> +#include <linux/mutex.h>
> +
> +#include <mach/mxs.h>
> +
> +#define BM_OCOTP_CTRL_BUSY (1 << 8)
> +#define BM_OCOTP_CTRL_ERROR (1 << 9)
> +#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
> +
> +static DEFINE_MUTEX(ocotp_mutex);
> +
> +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> +{
> + void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> + int timeout = 0x400;
> + size_t i;
> +
> + mutex_lock(&ocotp_mutex);
> +
> + /*
> + * clk_enable(hbus_clk) for ocotp can be skipped
> + * as it must be on when system is running.
> + */
> +
> + /* try to clear ERROR bit */
> + __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> +
> + /* check both BUSY and ERROR cleared */
> + while ((__raw_readl(ocotp_base) &
> + (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> + /* nothing */;
Is it worth using cpu_relax() in these polling loops?
Jamie
^ permalink raw reply
* Gaah: selinux_socket_unix_stream_connect oops
From: Linus Torvalds @ 2011-01-05 16:27 UTC (permalink / raw)
To: David Miller, Network Development, Jeremy Fitzhardinge,
James Morris
[-- Attachment #1: Type: text/plain, Size: 2441 bytes --]
This was actually a regression entry, but only ever reported once by
Jeremy, I think. So it was basically ignored as not being very common
and there not being any hints about what causes it.
But after doing the 2.6.37 release, and intending to put it on all the
machines I have access to, guess what I find on the kids computer?
Right.
It must be a reasonably rare race condition, because that computer had
been up for three weeks or so (since middle of December), but
yesterday evening it crashed due to that thing.
The code disassembly is
13: 55 push %ebp
14: 89 e5 mov %esp,%ebp
16: 57 push %edi
17: 8d 7d 90 lea -0x70(%ebp),%edi
1a: 56 push %esi
1b: 53 push %ebx
1c: 83 ec 6c sub $0x6c,%esp
1f: 8b 40 14 mov 0x14(%eax),%eax
22: 8b 52 14 mov 0x14(%edx),%edx
25: 8b 98 58 01 00 00 mov 0x158(%eax),%ebx
2b:* 8b 82 58 01 00 00 mov 0x158(%edx),%eax <-- trapping
instruction
31: 89 45 8c mov %eax,-0x74(%ebp)
34: 31 c0 xor %eax,%eax
36: 8b b1 58 01 00 00 mov 0x158(%ecx),%esi
3c: 89 7d 88 mov %edi,-0x78(%ebp)
which means that it's "other->sk" that is NULL, which I think matches
Jeremy's case exactly.
The logs have a hint: this seems to have coincided with the
console-kit-daemon giving a warning like:
WARNING: Couldn't read /proc/13585/environ: Failed to open file
'/proc/13585/environ': No such file or directory
and then NetworkManager having a bunch of authentication warnings that
end up about being
Could not get UID of name ':1.3871': no such name
(full text in the attachment).
So I wonder if there is some subtle race that happens when one end of
a unix domain socket attaches just as another end disconnects?
Especially as "security_unix_stream_connect()" is called before the
whole connect sequence is really final. It's generally
"unix_release()" that sets 'sock->sk' to NULL.
Btw, why do we pass in "sock" and "other->sk_socket" ("struct
socket"), when it appears that what the security code really wants to
get "struct sock" (which would be "sk" and "other" in the caller)? The
calling convention seems to result in (a) this NULL pointer thing and
(b) all these extra dereferences.
Comments? Ideas?
Linus
[-- Attachment #2: kids.txt --]
[-- Type: text/plain, Size: 5215 bytes --]
Happened with
Linux version 2.6.37-rc5-00333-gdaefc3d
after perhaps three weeks of uptime. That kernel isn't in git, it has
an extra patch (to force-enable AHCI on the mac mini), so it's really
v2.6.37-rc5-332-g0fcdcfbbc98f in baseline.
---
Jan 4 17:02:50 kids console-kit-daemon[2884]: WARNING: Couldn't read /proc/13585/environ: Failed to open file '/proc/13585/environ': No such file or directory
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.network-control: (6) Remote Exception invoking org.freedesktop.PolicyKit1.Authority.CheckAuthorization() on /org/freede...
...NameHasNoOwner: Could not get UID of name ':1.3871': no such name
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> User connections unavailable: (6) Remote Exception invoking org.freedesktop.PolicyKit1.Authority.CheckAuthorization() ...
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.enable-disable-network: (6) Remote Exception invoking org.fre...
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.sleep-wake: (6) Remote Exception invoking org.freedesktop.Pol...
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.enable-disable-wifi: (6) Remote Exception invoking org.freede...
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.enable-disable-wwan: (6) Remote Exception invoking org.freede...
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.use-user-connections: (6) Remote Exception invoking org.freed...
Jan 4 17:02:50 kids NetworkManager[2438]: <warn> error requesting auth for org.freedesktop.NetworkManager.network-control: (6) Remote Exception invoking org.freedeskto...
Jan 4 17:02:50 kids bonobo-activation-server (celeste-15075): could not associate with desktop session: Failed to connect to socket /tmp/dbus-8AXjzuuw2I: Connection re...
...NameHasNoOwner: Could not get UID of name ':1.3871': no such name
Jan 4 17:02:50 kids kernel: [1755465.955480] BUG: unable to handle kernel NULL pointer dereference at 00000158
Jan 4 17:02:50 kids kernel: [1755465.956226] IP: [<c111297e>] selinux_socket_unix_stream_connect+0x18/0x84
Jan 4 17:02:50 kids kernel: [1755465.956226] *pde = 00000000
Jan 4 17:02:50 kids kernel: [1755465.956226] Oops: 0000 [#1] SMP
Jan 4 17:02:50 kids kernel: [1755465.956226] last sysfs file: /sys/devices/virtual/sound/timer/uevent
Jan 4 17:02:50 kids kernel: [1755465.956226] Modules linked in: [last unloaded: scsi_wait_scan]
Jan 4 17:02:50 kids kernel: [1755465.956226]
Jan 4 17:02:50 kids kernel: [1755465.956226] Pid: 15075, comm: bonobo-activati Not tainted 2.6.37-rc5-00333-gdaefc3d #13 Mac-F4208EC8/Macmini1,1
Jan 4 17:02:50 kids kernel: [1755465.956226] EIP: 0060:[<c111297e>] EFLAGS: 00210296 CPU: 1
Jan 4 17:02:50 kids kernel: [1755465.956226] EIP is at selinux_socket_unix_stream_connect+0x18/0x84
Jan 4 17:02:50 kids kernel: [1755465.956226] EAX: ee48b200 EBX: f1f983c0 ECX: ee48be00 EDX: 00000000
Jan 4 17:02:50 kids kernel: [1755465.956226] ESI: ee48b200 EDI: f59c5e1c EBP: f59c5e8c ESP: f59c5e14
Jan 4 17:02:50 kids kernel: [1755465.956226] DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Jan 4 17:02:50 kids kernel: [1755465.956226] Process bonobo-activati (pid: 15075, ti=f59c4000 task=ee45eb50 task.ti=f59c4000)
Jan 4 17:02:50 kids kernel: [1755465.956226] Stack:
Jan 4 17:02:50 kids kernel: [1755465.956226] 00000000 00000000 00000000 00000000 00000000 00200046 00200046 00000059
Jan 4 17:02:50 kids kernel: [1755465.956226] 00000013 00000000 f59c5e44 c103070e f59c5e5c c1003cc5 f59c5e64 ee432a00
Jan 4 17:02:50 kids kernel: [1755465.956226] ee48b200 ee48be00 f59c5ed4 c1002ce9 ee432a00 f59c5ec0 e1b02900 ee48b200
Jan 4 17:02:50 kids kernel: [1755465.956226] Call Trace:
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c103070e>] ? irq_exit+0x39/0x5d
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c1003cc5>] ? do_IRQ+0x83/0x97
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c1002ce9>] ? common_interrupt+0x29/0x30
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c111072c>] ? security_unix_stream_connect+0x10/0x13
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c1390029>] ? unix_stream_connect+0x1e3/0x35e
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c1316047>] ? sys_connect+0x60/0x7d
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c1316b29>] ? sys_socketcall+0x8f/0x1a5
Jan 4 17:02:50 kids kernel: [1755465.956226] [<c100278c>] ? sysenter_do_call+0x12/0x22
Jan 4 17:02:50 kids kernel: [1755465.956226] Code: 56 68 00 00 04 00 e8 ba f2 ff ff 8d 65 f4 5b 5e 5f c9 c3 55 89 e5 57 8d 7d 90 56 53 83 ec 6c 8b 40 14 8b 52 14 8b 98 58 01 00 00 <8b> 82 58 01 00 00 89 45 8c 31 c0 8b b1 58 01 00 00 89 7d 88 b9
Jan 4 17:02:50 kids kernel: [1755465.956226] EIP: [<c111297e>] selinux_socket_unix_stream_connect+0x18/0x84 SS:ESP 0068:f59c5e14
Jan 4 17:02:50 kids kernel: [1755465.956226] CR2: 0000000000000158
Jan 4 17:02:50 kids kernel: [1755466.037178] ---[ end trace 9fd0d9b8feb78e69 ]---
^ permalink raw reply
* Re: [PATCH v3 05/10] net/fec: add dual fec support for mx28
From: Uwe Kleine-König @ 2011-01-05 16:34 UTC (permalink / raw)
To: Shawn Guo
Cc: davem, gerg, baruch, eric, bryan.wu, r64343, B32542, lw, w.sang,
s.hauer, netdev, linux-arm-kernel
In-Reply-To: <1294236457-17476-6-git-send-email-shawn.guo@freescale.com>
Hello,
On Wed, Jan 05, 2011 at 10:07:32PM +0800, Shawn Guo wrote:
> This patch is to add mx28 dual fec support. Here are some key notes
> for mx28 fec controller.
>
> - The mx28 fec controller naming ENET-MAC is a different IP from FEC
> used on other i.mx variants. But they are basically compatible
> on software interface, so it's possible to share the same driver.
> - ENET-MAC design made an improper assumption that it runs on a
> big-endian system. As the result, driver has to swap every frame
> going to and coming from the controller.
> - The external phys can only be configured by fec0, which means fec1
> can not work independently and both phys need to be configured by
> mii_bus attached on fec0.
> - ENET-MAC reset will get mac address registers reset too.
> - ENET-MAC MII/RMII mode and 10M/100M speed are configured
> differently FEC.
> - ETHER_EN bit must be set to get ENET-MAC interrupt work.
>
> Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> ---
> Changes for v3:
> - Move v2 changes into patch #3
> - Use device name to check if it's running on ENET-MAC
>
> drivers/net/Kconfig | 7 ++-
> drivers/net/fec.c | 140 +++++++++++++++++++++++++++++++++++++++++++++------
> drivers/net/fec.h | 5 +-
> 3 files changed, 131 insertions(+), 21 deletions(-)
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index 4f1755b..f34629b 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -1944,18 +1944,19 @@ config 68360_ENET
> config FEC
> bool "FEC ethernet controller (of ColdFire and some i.MX CPUs)"
> depends on M523x || M527x || M5272 || M528x || M520x || M532x || \
> - MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5
> + MACH_MX27 || ARCH_MX35 || ARCH_MX25 || ARCH_MX5 || SOC_IMX28
> select PHYLIB
> help
> Say Y here if you want to use the built-in 10/100 Fast ethernet
> controller on some Motorola ColdFire and Freescale i.MX processors.
>
> config FEC2
> - bool "Second FEC ethernet controller (on some ColdFire CPUs)"
> + bool "Second FEC ethernet controller"
> depends on FEC
> help
> Say Y here if you want to use the second built-in 10/100 Fast
> - ethernet controller on some Motorola ColdFire processors.
> + ethernet controller on some Motorola ColdFire and Freescale
> + i.MX processors.
>
> config FEC_MPC52xx
> tristate "MPC52xx FEC driver"
> diff --git a/drivers/net/fec.c b/drivers/net/fec.c
> index 8a1c51f..67ba263 100644
> --- a/drivers/net/fec.c
> +++ b/drivers/net/fec.c
> @@ -17,6 +17,8 @@
> *
> * Bug fixes and cleanup by Philippe De Muyter (phdm@macqel.be)
> * Copyright (c) 2004-2006 Macq Electronique SA.
> + *
> + * Copyright (C) 2010 Freescale Semiconductor, Inc.
> */
>
> #include <linux/module.h>
> @@ -45,20 +47,33 @@
>
> #include <asm/cacheflush.h>
>
> -#ifndef CONFIG_ARCH_MXC
> +#if !defined(CONFIG_ARCH_MXC) && !defined(CONFIG_SOC_IMX28)
maybe !defined(CONFIG_ARM)?
> #include <asm/coldfire.h>
> #include <asm/mcfsim.h>
> #endif
>
> #include "fec.h"
>
> -#ifdef CONFIG_ARCH_MXC
> -#include <mach/hardware.h>
> +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
> #define FEC_ALIGNMENT 0xf
> #else
> #define FEC_ALIGNMENT 0x3
> #endif
>
> +#define DRIVER_NAME "fec"
> +#define ENET_MAC_NAME "enet-mac"
> +
> +static struct platform_device_id fec_devtype[] = {
> + {
> + .name = DRIVER_NAME,
> + }, {
> + .name = ENET_MAC_NAME,
> + }
I'd done it differently:
{
.name = "fec",
.driver_data = 0,
}, {
.name = "imx28-fec",
.driver_data = HAS_ENET_MAC | ...,
}
and then test the bits in driver_data (which you get using
platform_get_device_id() when you need to distinguish.
Comparing names doesn't scale, assume there are three further features
to distinguish, then you need to use strtok or index and get device
names like enet-mac-with-feature1-but-without-feature2-and-feature3.
> +};
> +
> +static unsigned fec_is_enetmac;
> +static struct mii_bus *fec_mii_bus;
In practice this might work, but actually these are per-device
properties, not driver-global. So it should go into the private data
struct.
> +
> static unsigned char macaddr[ETH_ALEN];
> module_param_array(macaddr, byte, NULL, 0);
> MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
> @@ -129,7 +144,8 @@ MODULE_PARM_DESC(macaddr, "FEC Ethernet MAC address");
> * account when setting it.
> */
> #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> - defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> + defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> + defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
> #define OPT_FRAME_SIZE (PKT_MAXBUF_SIZE << 16)
> #else
> #define OPT_FRAME_SIZE 0
> @@ -208,6 +224,17 @@ static void fec_stop(struct net_device *dev);
> /* Transmitter timeout */
> #define TX_TIMEOUT (2 * HZ)
>
> +static void *swap_buffer(void *bufaddr, int len)
> +{
> + int i;
> + unsigned int *buf = bufaddr;
> +
> + for (i = 0; i < (len + 3) / 4; i++, buf++)
> + *buf = __swab32(*buf);
Would it better to use cpu_to_be32 here? Then the compiler might
be smart enough to optimize it away on BE. (Currently the code
generated for a BE build would be wrong with your patch, wouldn't it?)
> +
> + return bufaddr;
> +}
> +
> static netdev_tx_t
> fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
> {
> @@ -256,6 +283,14 @@ fec_enet_start_xmit(struct sk_buff *skb, struct net_device *dev)
> bufaddr = fep->tx_bounce[index];
> }
>
> + /*
> + * enet-mac design made an improper assumption that it's running
> + * on a big endian system. As the result, driver has to swap
if he was really aware that he limits the performant use of the fec to
big endian systems, can you please make him stop designing hardware!?
> + * every frame going to and coming from the controller.
> + */
> + if (fec_is_enetmac)
> + swap_buffer(bufaddr, skb->len);
> +
> /* Save skb pointer */
> fep->tx_skbuff[fep->skb_cur] = skb;
>
> @@ -487,6 +522,9 @@ fec_enet_rx(struct net_device *dev)
> dma_unmap_single(NULL, bdp->cbd_bufaddr, bdp->cbd_datlen,
> DMA_FROM_DEVICE);
>
> + if (fec_is_enetmac)
> + swap_buffer(data, pkt_len);
> +
> /* This does 16 byte alignment, exactly what we need.
> * The packet length includes FCS, but we don't want to
> * include that when passing upstream as it messes up
> @@ -689,6 +727,7 @@ static int fec_enet_mii_probe(struct net_device *dev)
> char mdio_bus_id[MII_BUS_ID_SIZE];
> char phy_name[MII_BUS_ID_SIZE + 3];
> int phy_id;
> + int dev_id = fep->pdev->id;
>
> fep->phy_dev = NULL;
>
> @@ -700,6 +739,8 @@ static int fec_enet_mii_probe(struct net_device *dev)
> continue;
> if (fep->mii_bus->phy_map[phy_id]->phy_id == 0)
> continue;
> + if (fec_is_enetmac && dev_id--)
> + continue;
> strncpy(mdio_bus_id, fep->mii_bus->id, MII_BUS_ID_SIZE);
> break;
> }
> @@ -741,6 +782,28 @@ static int fec_enet_mii_init(struct platform_device *pdev)
> struct fec_enet_private *fep = netdev_priv(dev);
> int err = -ENXIO, i;
>
> + /*
> + * The dual fec interfaces are not equivalent with enet-mac.
> + * Here are the differences:
> + *
> + * - fec0 supports MII & RMII modes while fec1 only supports RMII
> + * - fec0 acts as the 1588 time master while fec1 is slave
> + * - external phys can only be configured by fec0
> + *
> + * That is to say fec1 can not work independently. It only works
> + * when fec0 is working. The reason behind this design is that the
> + * second interface is added primarily for Switch mode.
> + *
> + * Because of the last point above, both phys are attached on fec0
> + * mdio interface in board design, and need to be configured by
> + * fec0 mii_bus.
> + */
> + if (fec_is_enetmac && pdev->id) {
> + /* fec1 uses fec0 mii_bus */
> + fep->mii_bus = fec_mii_bus;
> + return 0;
> + }
> +
> fep->mii_timeout = 0;
>
> /*
> @@ -777,6 +840,10 @@ static int fec_enet_mii_init(struct platform_device *pdev)
> if (mdiobus_register(fep->mii_bus))
> goto err_out_free_mdio_irq;
>
> + /* save fec0 mii_bus */
> + if (fec_is_enetmac)
> + fec_mii_bus = fep->mii_bus;
> +
> return 0;
>
> err_out_free_mdio_irq:
> @@ -1149,11 +1216,22 @@ fec_restart(struct net_device *dev, int duplex)
> {
> struct fec_enet_private *fep = netdev_priv(dev);
> int i;
> + u32 val, temp_mac[2];
>
> /* Whack a reset. We should wait for this. */
> writel(1, fep->hwp + FEC_ECNTRL);
> udelay(10);
>
> + /*
> + * enet-mac reset will reset mac address registers too,
> + * so need to reconfigure it.
> + */
> + if (fec_is_enetmac) {
> + memcpy(&temp_mac, dev->dev_addr, ETH_ALEN);
> + writel(cpu_to_be32(temp_mac[0]), fep->hwp + FEC_ADDR_LOW);
> + writel(cpu_to_be32(temp_mac[1]), fep->hwp + FEC_ADDR_HIGH);
where is the value saved to temp_mac[]? For me it looks you write
uninitialized data into the mac registers.
> + }
> +
> /* Clear any outstanding interrupt. */
> writel(0xffc00000, fep->hwp + FEC_IEVENT);
>
> @@ -1200,20 +1278,45 @@ fec_restart(struct net_device *dev, int duplex)
> /* Set MII speed */
> writel(fep->phy_speed, fep->hwp + FEC_MII_SPEED);
>
> -#ifdef FEC_MIIGSK_ENR
> - if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
> - /* disable the gasket and wait */
> - writel(0, fep->hwp + FEC_MIIGSK_ENR);
> - while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
> - udelay(1);
> + /*
> + * The phy interface and speed need to get configured
> + * differently on enet-mac.
> + */
> + if (fec_is_enetmac) {
> + val = readl(fep->hwp + FEC_R_CNTRL);
>
> - /* configure the gasket: RMII, 50 MHz, no loopback, no echo */
> - writel(1, fep->hwp + FEC_MIIGSK_CFGR);
> + /* MII or RMII */
> + if (fep->phy_interface == PHY_INTERFACE_MODE_RMII)
> + val |= (1 << 8);
> + else
> + val &= ~(1 << 8);
>
> - /* re-enable the gasket */
> - writel(2, fep->hwp + FEC_MIIGSK_ENR);
> - }
> + /* 10M or 100M */
> + if (fep->phy_dev && fep->phy_dev->speed == SPEED_100)
> + val &= ~(1 << 9);
> + else
> + val |= (1 << 9);
> +
> + writel(val, fep->hwp + FEC_R_CNTRL);
> + } else {
> +#ifdef FEC_MIIGSK_ENR
> + if (fep->phy_interface == PHY_INTERFACE_MODE_RMII) {
> + /* disable the gasket and wait */
> + writel(0, fep->hwp + FEC_MIIGSK_ENR);
> + while (readl(fep->hwp + FEC_MIIGSK_ENR) & 4)
> + udelay(1);
> +
> + /*
> + * configure the gasket:
> + * RMII, 50 MHz, no loopback, no echo
> + */
> + writel(1, fep->hwp + FEC_MIIGSK_CFGR);
> +
> + /* re-enable the gasket */
> + writel(2, fep->hwp + FEC_MIIGSK_ENR);
> + }
> #endif
> + }
>
> /* And last, enable the transmit and receive processing */
> writel(2, fep->hwp + FEC_ECNTRL);
> @@ -1301,6 +1404,10 @@ fec_probe(struct platform_device *pdev)
> }
> }
>
> + /* check if it's ENET-MAC controller via device name */
> + if (!strcmp(pdev->name, ENET_MAC_NAME))
> + fec_is_enetmac = 1;
> +
> fep->clk = clk_get(&pdev->dev, "fec_clk");
> if (IS_ERR(fep->clk)) {
> ret = PTR_ERR(fep->clk);
> @@ -1410,12 +1517,13 @@ static const struct dev_pm_ops fec_pm_ops = {
>
> static struct platform_driver fec_driver = {
> .driver = {
> - .name = "fec",
> + .name = DRIVER_NAME,
> .owner = THIS_MODULE,
> #ifdef CONFIG_PM
> .pm = &fec_pm_ops,
> #endif
> },
> + .id_table = fec_devtype,
> .probe = fec_probe,
> .remove = __devexit_p(fec_drv_remove),
> };
> diff --git a/drivers/net/fec.h b/drivers/net/fec.h
> index 2c48b25..ace318d 100644
> --- a/drivers/net/fec.h
> +++ b/drivers/net/fec.h
> @@ -14,7 +14,8 @@
> /****************************************************************************/
>
> #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
> - defined(CONFIG_M520x) || defined(CONFIG_M532x) || defined(CONFIG_ARCH_MXC)
> + defined(CONFIG_M520x) || defined(CONFIG_M532x) || \
> + defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
> /*
> * Just figures, Motorola would have to change the offsets for
> * registers in the same peripheral device on different models
> @@ -78,7 +79,7 @@
> /*
> * Define the buffer descriptor structure.
> */
> -#ifdef CONFIG_ARCH_MXC
> +#if defined(CONFIG_ARCH_MXC) || defined(CONFIG_SOC_IMX28)
> struct bufdesc {
> unsigned short cbd_datlen; /* Data length */
> unsigned short cbd_sc; /* Control and status info */
> --
> 1.7.1
>
>
>
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* Re: [PATCH v3 08/10] ARM: mxs: add ocotp read function
From: Uwe Kleine-König @ 2011-01-05 16:44 UTC (permalink / raw)
To: Jamie Iles
Cc: Shawn Guo, gerg, B32542, netdev, s.hauer, baruch, w.sang, r64343,
eric, bryan.wu, davem, linux-arm-kernel, lw
In-Reply-To: <20110105161235.GA2112@gallagher>
Hello Jamie,
On Wed, Jan 05, 2011 at 04:16:46PM +0000, Jamie Iles wrote:
> On Wed, Jan 05, 2011 at 10:07:35PM +0800, Shawn Guo wrote:
> > Signed-off-by: Shawn Guo <shawn.guo@freescale.com>
> > ---
> > Changes for v2:
> > - Add mutex locking for mxs_read_ocotp()
> > - Use type size_t for count and i
> > - Add comment for clk_enable/disable skipping
> > - Add ERROR bit clearing and polling step
> >
> > arch/arm/mach-mxs/Makefile | 2 +-
> > arch/arm/mach-mxs/include/mach/common.h | 1 +
> > arch/arm/mach-mxs/ocotp.c | 79 +++++++++++++++++++++++++++++++
> > 3 files changed, 81 insertions(+), 1 deletions(-)
> > create mode 100644 arch/arm/mach-mxs/ocotp.c
> >
> [...]
> > diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c
> > new file mode 100644
> > index 0000000..902ef59
> > --- /dev/null
> > +++ b/arch/arm/mach-mxs/ocotp.c
> > @@ -0,0 +1,79 @@
> > +/*
> > + * Copyright 2010 Freescale Semiconductor, Inc. All Rights Reserved.
> > + *
> > + * This program is free software; you can redistribute it and/or modify
> > + * it under the terms of the GNU General Public License as published by
> > + * the Free Software Foundation; either version 2 of the License, or
> > + * (at your option) any later version.
> > + *
> > + * This program is distributed in the hope that it will be useful,
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> > + * GNU General Public License for more details.
> > + */
> > +
> > +#include <linux/delay.h>
> > +#include <linux/err.h>
> > +#include <linux/mutex.h>
> > +
> > +#include <mach/mxs.h>
> > +
> > +#define BM_OCOTP_CTRL_BUSY (1 << 8)
> > +#define BM_OCOTP_CTRL_ERROR (1 << 9)
> > +#define BM_OCOTP_CTRL_RD_BANK_OPEN (1 << 12)
> > +
> > +static DEFINE_MUTEX(ocotp_mutex);
> > +
> > +int mxs_read_ocotp(unsigned offset, size_t count, u32 *values)
> > +{
> > + void __iomem *ocotp_base = MXS_IO_ADDRESS(MXS_OCOTP_BASE_ADDR);
> > + int timeout = 0x400;
> > + size_t i;
> > +
> > + mutex_lock(&ocotp_mutex);
> > +
> > + /*
> > + * clk_enable(hbus_clk) for ocotp can be skipped
> > + * as it must be on when system is running.
> > + */
> > +
> > + /* try to clear ERROR bit */
> > + __mxs_clrl(BM_OCOTP_CTRL_ERROR, ocotp_base);
> > +
> > + /* check both BUSY and ERROR cleared */
> > + while ((__raw_readl(ocotp_base) &
> > + (BM_OCOTP_CTRL_BUSY | BM_OCOTP_CTRL_ERROR)) && --timeout)
> > + /* nothing */;
>
> Is it worth using cpu_relax() in these polling loops?
I don't know what cpu_relax does for other platforms, but on ARM it's
just a memory barrier which AFAICT doesn't help here at all (which
doesn't need to be correct). Why do you think it would be better?
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [RFC PATCH] m68knommu: added dm9000 support
From: Angelo Dureghello @ 2011-01-05 16:48 UTC (permalink / raw)
To: linux-kernel, netdev
This patch allows to use the dm9000 network chip with a m68knommu
big-endian cpu. From the HW point of view, the cpu data bus connected to
the dm9000 chip should be hardware-byte-swapped, crossing the bytes
wires (D0:7 to D24:31, etc.). In anyway, has been also added an option
to swap the bytes in the driver, if some cpu has been wired straight
D0:D31 to dm9000.
Signed-off-by: Angelo Dureghello <angelo70@gmail.com>
---
--- drivers/net/Kconfig.orig 2011-01-05 17:11:37.992376124 +0100
+++ drivers/net/Kconfig 2011-01-04 22:33:14.132301872 +0100
@@ -960,7 +960,7 @@ config TI_DAVINCI_EMAC
config DM9000
tristate "DM9000 support"
- depends on ARM || BLACKFIN || MIPS
+ depends on COLDFIRE || ARM || BLACKFIN || MIPS
select CRC32
select MII
---help---
@@ -986,6 +986,14 @@ config DM9000_FORCE_SIMPLE_PHY_POLL
costly MII PHY reads. Note, this will not work if the chip is
operating with an external PHY.
+config DM9000_32BIT_SW_SWAP
+ bool "Software byte swap for 32 bit data bus"
+ depends on DM9000 && COLDFIRE
+ ---help---
+ This configuration allows to swap data bytes from the dm9000
+ driver itself, when the big endian cpu is wired straight to
+ the dm9000 32 bit data bus.
+
config ENC28J60
tristate "ENC28J60 support"
depends on EXPERIMENTAL && SPI && NET_ETHERNET
@@ -3347,4 +3355,3 @@ config VMXNET3
module will be called vmxnet3.
endif # NETDEVICES
-
--- drivers/net/dm9000.c.orig 2010-12-30 23:19:39.747836070 +0100
+++ drivers/net/dm9000.c 2011-01-05 16:30:48.636116500 +0100
@@ -158,9 +158,17 @@ dm9000_reset(board_info_t * db)
dev_dbg(db->dev, "resetting device\n");
/* RESET device */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(DM9000_NCR, db->io_addr);
+#else
writeb(DM9000_NCR, db->io_addr);
+#endif
udelay(200);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(NCR_RST, db->io_data);
+#else
writeb(NCR_RST, db->io_data);
+#endif
udelay(200);
}
@@ -170,8 +178,13 @@ dm9000_reset(board_info_t * db)
static u8
ior(board_info_t * db, int reg)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg, db->io_addr);
+ return (u8)readl(db->io_data);
+#else
writeb(reg, db->io_addr);
return readb(db->io_data);
+#endif
}
/*
@@ -181,43 +194,72 @@ ior(board_info_t * db, int reg)
static void
iow(board_info_t * db, int reg, int value)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg, db->io_addr);
+ writel(value, db->io_data);
+#else
writeb(reg, db->io_addr);
writeb(value, db->io_data);
+#endif
}
/* routines for sending block to chip */
static void dm9000_outblk_8bit(void __iomem *reg, void *data, int count)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writesbsw(reg, data, count);
+#else
writesb(reg, data, count);
+#endif
}
static void dm9000_outblk_16bit(void __iomem *reg, void *data, int count)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writeswsw(reg, data, (count+1) >> 1);
+#else
writesw(reg, data, (count+1) >> 1);
+#endif
}
static void dm9000_outblk_32bit(void __iomem *reg, void *data, int count)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writeslsw(reg, data, (count+3) >> 2);
+#else
writesl(reg, data, (count+3) >> 2);
+#endif
}
/* input block from chip to memory */
static void dm9000_inblk_8bit(void __iomem *reg, void *data, int count)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ readsbsw(reg, data, count);
+#else
readsb(reg, data, count);
+#endif
}
static void dm9000_inblk_16bit(void __iomem *reg, void *data, int count)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ readswsw(reg, data, (count+1) >> 1);
+#else
readsw(reg, data, (count+1) >> 1);
+#endif
}
static void dm9000_inblk_32bit(void __iomem *reg, void *data, int count)
{
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ readslsw(reg, data, (count+3) >> 2);
+#else
readsl(reg, data, (count+3) >> 2);
+#endif
}
/* dump block from chip to null */
@@ -863,8 +905,13 @@ static void dm9000_timeout(struct net_de
netif_wake_queue(dev);
/* Restore previous register address */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg_save, db->io_addr);
+#else
writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock, flags);
+#endif
+
+ spin_unlock_irqrestore(&db->lock,flags);
}
static void dm9000_send_packet(struct net_device *dev,
@@ -908,7 +955,11 @@ dm9000_start_xmit(struct sk_buff *skb, s
spin_lock_irqsave(&db->lock, flags);
/* Move data to DM9000 TX RAM */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(DM9000_MWCMD, db->io_addr);
+#else
writeb(DM9000_MWCMD, db->io_addr);
+#endif
(db->outblk)(db->io_data, skb->data, skb->len);
dev->stats.tx_bytes += skb->len;
@@ -981,7 +1032,11 @@ dm9000_rx(struct net_device *dev)
ior(db, DM9000_MRCMDX); /* Dummy read */
/* Get most updated data */
- rxbyte = readb(db->io_data);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ rxbyte = (u8)readl(db->io_data);
+#else
+ rxbyte = readb(db->io_data);
+#endif
/* Status check: this byte must be 0 or 1 */
if (rxbyte & DM9000_PKT_ERR) {
@@ -996,8 +1051,13 @@ dm9000_rx(struct net_device *dev)
/* A packet ready now & Get status/length */
GoodPacket = true;
- writeb(DM9000_MRCMD, db->io_addr);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(DM9000_MRCMD, db->io_addr);
+#else
+ writeb(DM9000_MRCMD, db->io_addr);
+#endif
+
(db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr));
RxLen = le16_to_cpu(rxhdr.RxLen);
@@ -1077,7 +1137,7 @@ static irqreturn_t dm9000_interrupt(int
unsigned long flags;
u8 reg_save;
- dm9000_dbg(db, 3, "entering %s\n", __func__);
+ //dm9000_dbg(db, 3, "entering %s\n", __func__);
/* A real interrupt coming */
@@ -1085,7 +1145,11 @@ static irqreturn_t dm9000_interrupt(int
spin_lock_irqsave(&db->lock, flags);
/* Save previous register address */
- reg_save = readb(db->io_addr);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ reg_save = (u8)readl(db->io_addr);
+#else
+ reg_save = readb(db->io_addr);
+#endif
/* Disable all interrupts */
iow(db, DM9000_IMR, IMR_PAR);
@@ -1100,7 +1164,7 @@ static irqreturn_t dm9000_interrupt(int
/* Received the coming packet */
if (int_status & ISR_PRS)
dm9000_rx(dev);
-
+
/* Trnasmit Interrupt check */
if (int_status & ISR_PTS)
dm9000_tx_done(dev, db);
@@ -1116,8 +1180,12 @@ static irqreturn_t dm9000_interrupt(int
iow(db, DM9000_IMR, db->imr_all);
/* Restore previous register address */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg_save, db->io_addr);
+#else
writeb(reg_save, db->io_addr);
-
+#endif
+
spin_unlock_irqrestore(&db->lock, flags);
return IRQ_HANDLED;
@@ -1233,11 +1301,15 @@ dm9000_phy_read(struct net_device *dev,
int ret;
mutex_lock(&db->addr_lock);
-
+
spin_lock_irqsave(&db->lock,flags);
/* Save previous register address */
- reg_save = readb(db->io_addr);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ reg_save = (u8)readl(db->io_addr);
+#else
+ reg_save = readb(db->io_addr);
+#endif
/* Fill the phyxcer register into REG_0C */
iow(db, DM9000_EPAR, DM9000_PHY | reg);
@@ -1250,7 +1322,11 @@ dm9000_phy_read(struct net_device *dev,
dm9000_msleep(db, 1); /* Wait read complete */
spin_lock_irqsave(&db->lock,flags);
- reg_save = readb(db->io_addr);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ reg_save = (u8)readl(db->io_addr);
+#else
+ reg_save = readb(db->io_addr);
+#endif
iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer read command */
@@ -1258,9 +1334,14 @@ dm9000_phy_read(struct net_device *dev,
ret = (ior(db, DM9000_EPDRH) << 8) | ior(db, DM9000_EPDRL);
/* restore the previous address */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg_save, db->io_addr);
+#else
writeb(reg_save, db->io_addr);
- spin_unlock_irqrestore(&db->lock,flags);
+#endif
+ spin_unlock_irqrestore(&db->lock,flags);
+
mutex_unlock(&db->addr_lock);
dm9000_dbg(db, 5, "phy_read[%02x] -> %04x\n", reg, ret);
@@ -1284,7 +1365,11 @@ dm9000_phy_write(struct net_device *dev,
spin_lock_irqsave(&db->lock,flags);
/* Save previous register address */
- reg_save = readb(db->io_addr);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ reg_save = (u8)readl(db->io_addr);
+#else
+ reg_save = readb(db->io_addr);
+#endif
/* Fill the phyxcer register into REG_0C */
iow(db, DM9000_EPAR, DM9000_PHY | reg);
@@ -1295,18 +1380,31 @@ dm9000_phy_write(struct net_device *dev,
iow(db, DM9000_EPCR, EPCR_EPOS | EPCR_ERPRW); /* Issue phyxcer
write command */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg_save, db->io_addr);
+#else
writeb(reg_save, db->io_addr);
+#endif
+
spin_unlock_irqrestore(&db->lock, flags);
dm9000_msleep(db, 1); /* Wait write complete */
spin_lock_irqsave(&db->lock,flags);
- reg_save = readb(db->io_addr);
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ reg_save = (u8)readl(db->io_addr);
+#else
+ reg_save = readb(db->io_addr);
+#endif
iow(db, DM9000_EPCR, 0x0); /* Clear phyxcer write command */
/* restore the previous address */
+#ifdef CONFIG_DM9000_32BIT_SW_SWAP
+ writel(reg_save, db->io_addr);
+#else
writeb(reg_save, db->io_addr);
+#endif
spin_unlock_irqrestore(&db->lock, flags);
mutex_unlock(&db->addr_lock);
@@ -1713,4 +1811,3 @@ MODULE_AUTHOR("Sascha Hauer, Ben Dooks")
MODULE_DESCRIPTION("Davicom DM9000 network driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:dm9000");
-
--- arch/m68k/include/asm/io_no.h.orig 2011-01-05 16:53:55.904905038
+0100
+++ arch/m68k/include/asm/io_no.h 2011-01-04 23:45:08.893049554 +0100
@@ -47,6 +47,91 @@ static inline unsigned int _swapl(volati
#define writew(b,addr) (void)((*(volatile unsigned short *) (addr)) = (b))
#define writel(b,addr) (void)((*(volatile unsigned int *) (addr)) = (b))
+static inline void writesb (void __iomem *reg, void *data, int count)
+{
+ unsigned char *p = (unsigned char*) data;
+
+ while (count--) writeb(*p++, reg);
+}
+
+static inline void writesbsw (void __iomem *reg, void *data, int count)
+{
+ unsigned char *p = (unsigned char *) data;
+
+ while (count--) writel((int)(*p++), reg);
+}
+
+static inline void writesw (void __iomem *reg, void *data, int count)
+{
+ unsigned short *p = (unsigned short*) data;
+
+ while (count--) writew(*p++, reg);
+}
+
+static inline void writeswsw (void __iomem *reg, void *data, int count)
+{
+ unsigned short *p = (unsigned short *) data;
+
+ while (count--) writel((int)(_swapw(*p++)), reg);
+}
+
+static inline void writesl (void __iomem *reg, void *data, int count)
+{
+ unsigned long *p = (unsigned long*) data;
+
+ while (count--) writel(*p++, reg);
+}
+
+static inline void writeslsw (void __iomem *reg, void *data, int count)
+{
+ unsigned long *p = (unsigned long *) data;
+
+ while (count--) writel((int)(_swapl(*p++)), reg);
+}
+
+static inline void readsb (void __iomem *reg, void *data, int count)
+{
+ unsigned char *p = (unsigned char *) data;
+
+ while (count--) *p++ = readb(reg);
+}
+
+static inline void readsbsw (void __iomem *reg, void *data, int count)
+{
+ unsigned char *p = (unsigned char *) data;
+
+ while (count--) *p++ = (unsigned char)readl(reg);
+}
+
+static inline void readsw (void __iomem *reg, void *data, int count)
+{
+ unsigned short *p = (unsigned short *) data;
+
+ while (count--) *p++ = readb(reg);
+}
+
+static inline void readswsw (void __iomem *reg, void *data, int count)
+{
+ unsigned short *p = (unsigned short *) data;
+
+ while (count--) *p++ = _swapw((unsigned short)readw(reg));
+}
+
+static inline void readsl (void __iomem *reg, void *data, int count)
+{
+ unsigned long *p = (unsigned long *) data;
+
+ while (count--) *p++ = readb(reg);
+}
+
+static inline void readslsw (void __iomem *reg, void *data, int count)
+{
+ unsigned long *p = (unsigned long *) data;
+
+ while (count--) *p++ = _swapl(readl(reg));
+}
+
+
#define __raw_readb readb
#define __raw_readw readw
#define __raw_readl readl
@@ -180,4 +265,3 @@ extern void iounmap(void *addr);
#endif /* __KERNEL__ */
#endif /* _M68KNOMMU_IO_H */
-
^ permalink raw reply
* Re: [net-next-2.6 PATCH] ethtool: update get_rx_ntuple to correctly interpret string count
From: Alexander Duyck @ 2011-01-05 16:57 UTC (permalink / raw)
To: Ben Hutchings; +Cc: davem@davemloft.net, netdev@vger.kernel.org
In-Reply-To: <1294241216.15866.14.camel@bwh-desktop>
On 1/5/2011 7:26 AM, Ben Hutchings wrote:
> On Tue, 2011-01-04 at 17:06 -0800, Alexander Duyck wrote:
>> On 1/4/2011 4:01 PM, Ben Hutchings wrote:
>>> On Tue, 2011-01-04 at 15:29 -0800, Alexander Duyck wrote:
>>>> Currently any strings returned via the get_rx_ntuple call will just be
>>>> dropped because the num_strings will be zero. In order to correct this I
>>>> am updating things so that the return value of get_rx_ntuple is the number
>>>> of strings that were written, or a negative value if there was an error.
>>> [...]
>>>
>>> Nothing implements ethtool_ops::get_rx_ntuple, anyway.
>>>
>>> The fallback implementation is totally bogus, too. Maximum of 1024
>>> filters? Erm, sfc can handle more than that. And doing complex string
>>> formatting in the kernel, even though all the parsing is in ethtool?
>>>
>>> Please, let's write off ETHTOOL_GRXNTUPLE as a failed experiment and
>>> replace it with a command that behaves more like ETHTOOL_GRXCLSRLALL.
>>>
>>> Ben.
>>
>> In order to address several different issues in the perfect filters
>> provided by 82599 I found it necessary to implement get_rx_ntuple so
>> that the driver could maintain the filter list inside of the driver
>> instead of having it maintained by the stack. In doing so though I
>> found the bug.
>>
>> I agree the fallback implementation has a limitation on the number and
>> format of filters it supports. However declaring the function a "failed
>> experiment" and just dropping it isn't exactly constructive since we
>> have customers that are making use of the feature.
> [...]
>
> We can at least drop that fallback implementation since it apparently
> doesn't work properly for either of the drivers that currently use it.
>
> In the medium term, I do want to replace it with a binary interface and
> move that formatting to ethtool. ETHTOOL_GRXNTUPLE could be kept around
> for a while for ixgbe only, while your customers have a chance to get
> the updated ethtool.
>
> Ben.
>
I'm fine with us replacing the ETHTOOL_GRXNTUPLE interface, but I would
prefer to do it after the merge windows for 2.6.39 has opened. For now
I would like to get this patch accepted as my main concern is getting a
minor fix in versus rewriting the entire interface.
While we're at it how would you feel about us inverting the masks for
setting up an ntuple by making them an inclusion mask instead of an
exclusion one? The reason why I ask is because I have to perform an and
operation over all the input anyway before I can use it to compute the
hashes and as such I am having to invert almost all of the mask bits,
and it appears you are having to do this as well for many of the masks
in sfc.
Thanks,
Alex
^ permalink raw reply
* Re: [RFC PATCH] m68knommu: added dm9000 support
From: Randy Dunlap @ 2011-01-05 16:59 UTC (permalink / raw)
To: Angelo Dureghello; +Cc: linux-kernel, netdev
In-Reply-To: <4D24A0E4.1070805@gmail.com>
On Wed, 05 Jan 2011 17:48:36 +0100 Angelo Dureghello wrote:
> This patch allows to use the dm9000 network chip with a m68knommu
> big-endian cpu. From the HW point of view, the cpu data bus connected to
> the dm9000 chip should be hardware-byte-swapped, crossing the bytes
> wires (D0:7 to D24:31, etc.). In anyway, has been also added an option
> to swap the bytes in the driver, if some cpu has been wired straight
> D0:D31 to dm9000.
>
> Signed-off-by: Angelo Dureghello <angelo70@gmail.com>
> ---
>
> --- drivers/net/Kconfig.orig 2011-01-05 17:11:37.992376124 +0100
> +++ drivers/net/Kconfig 2011-01-04 22:33:14.132301872 +0100
File names should begin at top level of linux kernel source tree, like this e.g.:
> --- linux/drivers/net/Kconfig.orig 2011-01-05 17:11:37.992376124 +0100
> +++ linux/drivers/net/Kconfig 2011-01-04 22:33:14.132301872 +0100
> @@ -960,7 +960,7 @@ config TI_DAVINCI_EMAC
>
> config DM9000
> tristate "DM9000 support"
> - depends on ARM || BLACKFIN || MIPS
> + depends on COLDFIRE || ARM || BLACKFIN || MIPS
> select CRC32
> select MII
> ---help---
Something has modified tab(s) to spaces in this patch, so the patch won't
apply cleanly. See if Documentation/email-clients.txt can help you.
Oh, are you using the gmail web-based email client? That won't work
for kernel patches. You could use gmail via SMTP.
> @@ -986,6 +986,14 @@ config DM9000_FORCE_SIMPLE_PHY_POLL
> costly MII PHY reads. Note, this will not work if the chip is
> operating with an external PHY.
>
> +config DM9000_32BIT_SW_SWAP
> + bool "Software byte swap for 32 bit data bus"
> + depends on DM9000 && COLDFIRE
> + ---help---
> + This configuration allows to swap data bytes from the dm9000
> + driver itself, when the big endian cpu is wired straight to
> + the dm9000 32 bit data bus.
> +
> config ENC28J60
> tristate "ENC28J60 support"
> depends on EXPERIMENTAL && SPI && NET_ETHERNET
---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***
desserts: http://www.xenotime.net/linux/recipes/
^ permalink raw reply
* Re: [PATCH] ipv4: IP defragmentation must be ECN aware
From: Stephen Hemminger @ 2011-01-05 17:13 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1294235942.2775.191.camel@edumazet-laptop>
On Wed, 05 Jan 2011 14:59:02 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> +
> +static inline int ip4_frag_ecn(int tos)
Since tos is only a byte, this should be:
static inline u8 ip4_frag_ecn(u8 tos)
--
^ permalink raw reply
* [BUG] net_sched: pfifo_head_drop problem
From: Eric Dumazet @ 2011-01-05 17:00 UTC (permalink / raw)
To: David Miller
Cc: netdev, Florian Westphal, Patrick McHardy, Hagen Paul Pfeifer,
Stephen Hemminger, Jarek Poplawski
While reviewing CHOKe stuff, I found following problem :
commit 57dbb2d83d100ea (sched: add head drop fifo queue)
introduced pfifo_head_drop, and broke the invariant that
sch->bstats.bytes and sch->bstats.packets are COUNTER (increasing
counters only)
This can break estimators because est_timer() handle unsigned deltas
only. A decreasing counter can then give a huge unsigned delta.
My suggestion would be to change things so that sch->bstats.bytes and
sch->bstats.packets are incremented in dequeue() only, not at enqueue()
time.
It would be more sensible anyway for very low speeds, and big bursts.
Right now, if we drop packets, they still are accounted in estimators.
Or maybe my understanding of estimators is wrong, and only apply to
enqueue rate, not dequeue rate ?
If so, we should remove the
sch->bstats.bytes -= qdisc_pkt_len(skb_head);
sch->bstats.packets--;
done in pfifo_tail_enqueue() in case we drop the head skb.
My preference would be to add dropped pack/byte rates to estimators...
It might be good for tuning.
^ permalink raw reply
* Re: [BUG] net_sched: pfifo_head_drop problem
From: Stephen Hemminger @ 2011-01-05 17:15 UTC (permalink / raw)
To: Eric Dumazet
Cc: David Miller, netdev, Florian Westphal, Patrick McHardy,
Hagen Paul Pfeifer, Jarek Poplawski
In-Reply-To: <1294246850.2775.244.camel@edumazet-laptop>
On Wed, 05 Jan 2011 18:00:50 +0100
Eric Dumazet <eric.dumazet@gmail.com> wrote:
> While reviewing CHOKe stuff, I found following problem :
>
> commit 57dbb2d83d100ea (sched: add head drop fifo queue)
> introduced pfifo_head_drop, and broke the invariant that
> sch->bstats.bytes and sch->bstats.packets are COUNTER (increasing
> counters only)
>
> This can break estimators because est_timer() handle unsigned deltas
> only. A decreasing counter can then give a huge unsigned delta.
>
> My suggestion would be to change things so that sch->bstats.bytes and
> sch->bstats.packets are incremented in dequeue() only, not at enqueue()
> time.
>
> It would be more sensible anyway for very low speeds, and big bursts.
> Right now, if we drop packets, they still are accounted in estimators.
>
> Or maybe my understanding of estimators is wrong, and only apply to
> enqueue rate, not dequeue rate ?
>
> If so, we should remove the
>
> sch->bstats.bytes -= qdisc_pkt_len(skb_head);
> sch->bstats.packets--;
>
> done in pfifo_tail_enqueue() in case we drop the head skb.
>
>
> My preference would be to add dropped pack/byte rates to estimators...
> It might be good for tuning.
Agreed counters should reflect dequeued packets not enqueued packets.
--
^ 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