Netdev List
 help / color / mirror / Atom feed
* (unknown), 
From: MONEY GRAM TRANSFER SERVICES @ 2011-03-08  5:38 UTC (permalink / raw)



MONEY GRAM CUSTOMER CARE
21st Floor, Jalan Kampar, Plaza Permata,
50400, Kuala Lumpur, Wilayah Persekutuan
Malayasia

My working partner in relationship with HSBC London has concluded that our working
partner has helped us to send you first payment of US$5,000 to you asinstructed by 
Malaysia government and willkeep sending you $5000 twice a week untilthe payment of 
(US$820,000 ) is completed within six months and here is the information

Your are to contact RONALD FINSON for the fundS clearance certificate from the {IMF}

below is the information.

MONEY TRANSFER REFERENCE:2340-3297
SENDER'S NAME:Esther Lee
AMOUNT: US$5000

To track your funds forward money gram
Transfer agent Mr RONALD FINSON

Your Name.__________________________
Phone .__________________________

Contact Allan Davis for the funds clearance
certificate necessary for the realise of your funds

E-mail:moneygramservices@gncn.net


Please direct all enquiring to:
money gram Mr RONALD FINSON


Please direct all enquiring to:
moneygramservice@gncn.net


Best Regards,
RONALD FINSON

^ permalink raw reply

* [PATCH] tcp_cubic: enable TCP timestamps
From: Lucas Nussbaum @ 2011-03-08  8:09 UTC (permalink / raw)
  To: netdev; +Cc: Sangtae Ha

The Hystart slow start algorithm requires precise RTT delay measurements
to decide when to leave slow start. However, currently, CUBIC doesn't
enable TCP timestamps. This can cause Hystart to mis-estimate the RTT,
and to leave slow start too early, generating bad performance since
convergence to the optimal cwnd is slower.

Timestamps are already used by TCP Illinois, LP, Vegas, Veno and Yeah.

Signed-off-by: Lucas Nussbaum <lucas.nussbaum@loria.fr>

-- 
| Lucas Nussbaum             MCF Université Nancy 2 |
| lucas.nussbaum@loria.fr         LORIA / AlGorille |
| http://www.loria.fr/~lnussbau/  +33 3 54 95 86 19 |

diff --git a/net/ipv4/tcp_cubic.c b/net/ipv4/tcp_cubic.c
index 71d5f2f..3a73509 100644
--- a/net/ipv4/tcp_cubic.c
+++ b/net/ipv4/tcp_cubic.c
@@ -406,6 +406,7 @@ static void bictcp_acked(struct sock *sk, u32 cnt, s32 rtt_us)
 }
 
 static struct tcp_congestion_ops cubictcp = {
+       .flags          = TCP_CONG_RTT_STAMP,
        .init           = bictcp_init,
        .ssthresh       = bictcp_recalc_ssthresh,
        .cong_avoid     = bictcp_cong_avoid,

^ permalink raw reply related

* [PATCH 6/6] net: sh_eth: add set_mdio_gate in bb_info
From: Yoshihiro Shimoda @ 2011-03-08  7:59 UTC (permalink / raw)
  To: netdev; +Cc: SH-Linux

The SH7757's ETHER and GETHER use common MDIO pin. The MDIO pin is
selected by specific register. So this patch adds new interface in
bb_info, and when the sh_eth driver use the mdio, the register can
be changed by the function.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 This patch are based on net-next-2.6.git.

 arch/sh/include/asm/sh_eth.h |    1 +
 drivers/net/sh_eth.c         |   21 +++++++++++++++++++--
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index e86c880..0f325da 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -15,6 +15,7 @@ struct sh_eth_plat_data {
 	int edmac_endian;
 	int register_type;
 	phy_interface_t phy_interface;
+	void (*set_mdio_gate)(unsigned long addr);

 	unsigned char mac_addr[6];
 	unsigned no_ether_link:1;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index dcf9f87..e9e7a53 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -512,6 +512,7 @@ static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
 }

 struct bb_info {
+	void (*set_gate)(unsigned long addr);
 	struct mdiobb_ctrl ctrl;
 	u32 addr;
 	u32 mmd_msk;/* MMD */
@@ -542,6 +543,10 @@ static int bb_read(u32 addr, u32 msk)
 static void sh_mmd_ctrl(struct mdiobb_ctrl *ctrl, int bit)
 {
 	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+	if (bitbang->set_gate)
+		bitbang->set_gate(bitbang->addr);
+
 	if (bit)
 		bb_set(bitbang->addr, bitbang->mmd_msk);
 	else
@@ -553,6 +558,9 @@ static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
 {
 	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);

+	if (bitbang->set_gate)
+		bitbang->set_gate(bitbang->addr);
+
 	if (bit)
 		bb_set(bitbang->addr, bitbang->mdo_msk);
 	else
@@ -563,6 +571,10 @@ static void sh_set_mdio(struct mdiobb_ctrl *ctrl, int bit)
 static int sh_get_mdio(struct mdiobb_ctrl *ctrl)
 {
 	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);
+
+	if (bitbang->set_gate)
+		bitbang->set_gate(bitbang->addr);
+
 	return bb_read(bitbang->addr, bitbang->mdi_msk);
 }

@@ -571,6 +583,9 @@ static void sh_mdc_ctrl(struct mdiobb_ctrl *ctrl, int bit)
 {
 	struct bb_info *bitbang = container_of(ctrl, struct bb_info, ctrl);

+	if (bitbang->set_gate)
+		bitbang->set_gate(bitbang->addr);
+
 	if (bit)
 		bb_set(bitbang->addr, bitbang->mdc_msk);
 	else
@@ -1646,7 +1661,8 @@ static int sh_mdio_release(struct net_device *ndev)
 }

 /* MDIO bus init function */
-static int sh_mdio_init(struct net_device *ndev, int id)
+static int sh_mdio_init(struct net_device *ndev, int id,
+			struct sh_eth_plat_data *pd)
 {
 	int ret, i;
 	struct bb_info *bitbang;
@@ -1661,6 +1677,7 @@ static int sh_mdio_init(struct net_device *ndev, int id)

 	/* bitbang init */
 	bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR];
+	bitbang->set_gate = pd->set_mdio_gate;
 	bitbang->mdi_msk = 0x08;
 	bitbang->mdo_msk = 0x04;
 	bitbang->mmd_msk = 0x02;/* MMD */
@@ -1854,7 +1871,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 		goto out_release;

 	/* mdio bus init */
-	ret = sh_mdio_init(ndev, pdev->id);
+	ret = sh_mdio_init(ndev, pdev->id, pd);
 	if (ret)
 		goto out_unregister;

-- 
1.7.1

^ permalink raw reply related

* [PATCH v2 5/6] net: sh_eth: add support for SH7757's GETHER
From: Yoshihiro Shimoda @ 2011-03-08  7:59 UTC (permalink / raw)
  To: netdev; +Cc: SH-Linux

The SH7757 have GETHER and ETHER both. This patch supports them.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 This patch are based on net-next-2.6.git.

 about v2:
  - modify line number only

 drivers/net/sh_eth.c |  136 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 135 insertions(+), 1 deletions(-)

diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 5d28ce6..dcf9f87 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -94,7 +94,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.rpadir_value	= 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
 };
 #elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-#define SH_ETH_RESET_DEFAULT	1
+#define SH_ETH_HAS_BOTH_MODULES	1
+#define SH_ETH_HAS_TSU	1
 static void sh_eth_set_duplex(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -141,6 +142,135 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.no_ade		= 1,
 };

+#define SH_GIGA_ETH_BASE	0xfee00000
+#define GIGA_MALR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
+#define GIGA_MAHR(port)		(SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
+static void sh_eth_chip_reset_giga(struct net_device *ndev)
+{
+	int i;
+	unsigned long mahr[2], malr[2];
+
+	/* save MAHR and MALR */
+	for (i = 0; i < 2; i++) {
+		malr[i] = readl(GIGA_MALR(i));
+		mahr[i] = readl(GIGA_MAHR(i));
+	}
+
+	/* reset device */
+	writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800);
+	mdelay(1);
+
+	/* restore MAHR and MALR */
+	for (i = 0; i < 2; i++) {
+		writel(malr[i], GIGA_MALR(i));
+		writel(mahr[i], GIGA_MAHR(i));
+	}
+}
+
+static int sh_eth_is_gether(struct sh_eth_private *mdp);
+static void sh_eth_reset(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int cnt = 100;
+
+	if (sh_eth_is_gether(mdp)) {
+		sh_eth_write(ndev, 0x03, EDSR);
+		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
+				EDMR);
+		while (cnt > 0) {
+			if (!(sh_eth_read(ndev, EDMR) & 0x3))
+				break;
+			mdelay(1);
+			cnt--;
+		}
+		if (cnt < 0)
+			printk(KERN_ERR "Device reset fail\n");
+
+		/* Table Init */
+		sh_eth_write(ndev, 0x0, TDLAR);
+		sh_eth_write(ndev, 0x0, TDFAR);
+		sh_eth_write(ndev, 0x0, TDFXR);
+		sh_eth_write(ndev, 0x0, TDFFR);
+		sh_eth_write(ndev, 0x0, RDLAR);
+		sh_eth_write(ndev, 0x0, RDFAR);
+		sh_eth_write(ndev, 0x0, RDFXR);
+		sh_eth_write(ndev, 0x0, RDFFR);
+	} else {
+		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
+				EDMR);
+		mdelay(3);
+		sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
+				EDMR);
+	}
+}
+
+static void sh_eth_set_duplex_giga(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+
+	if (mdp->duplex) /* Full */
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
+	else		/* Half */
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
+}
+
+static void sh_eth_set_rate_giga(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+
+	switch (mdp->speed) {
+	case 10: /* 10BASE */
+		sh_eth_write(ndev, 0x00000000, GECMR);
+		break;
+	case 100:/* 100BASE */
+		sh_eth_write(ndev, 0x00000010, GECMR);
+		break;
+	case 1000: /* 1000BASE */
+		sh_eth_write(ndev, 0x00000020, GECMR);
+		break;
+	default:
+		break;
+	}
+}
+
+/* SH7757(GETHERC) */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
+	.chip_reset	= sh_eth_chip_reset_giga,
+	.set_duplex	= sh_eth_set_duplex_giga,
+	.set_rate	= sh_eth_set_rate_giga,
+
+	.ecsr_value	= ECSR_ICD | ECSR_MPD,
+	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+	.tx_check	= EESR_TC1 | EESR_FTC,
+	.eesr_err_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
+			  EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
+			  EESR_ECI,
+	.tx_error_check	= EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
+			  EESR_TFE,
+	.fdr_value	= 0x0000072f,
+	.rmcr_value	= 0x00000001,
+
+	.apr		= 1,
+	.mpr		= 1,
+	.tpauser	= 1,
+	.bculr		= 1,
+	.hw_swap	= 1,
+	.rpadir		= 1,
+	.rpadir_value   = 2 << 16,
+	.no_trimd	= 1,
+	.no_ade		= 1,
+};
+
+static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
+{
+	if (sh_eth_is_gether(mdp))
+		return &sh_eth_my_cpu_data_giga;
+	else
+		return &sh_eth_my_cpu_data;
+}
+
 #elif defined(CONFIG_CPU_SUBTYPE_SH7763)
 #define SH_ETH_HAS_TSU	1
 static void sh_eth_chip_reset(struct net_device *ndev)
@@ -1677,7 +1807,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);

 	/* set cpu data */
+#if defined(SH_ETH_HAS_BOTH_MODULES)
+	mdp->cd = sh_eth_get_cpu_data(mdp);
+#else
 	mdp->cd = &sh_eth_my_cpu_data;
+#endif
 	sh_eth_set_default_cpu_data(mdp->cd);

 	/* set function */
-- 
1.7.1

^ permalink raw reply related

* [PATCH 4/6] net: sh_eth: modify the PHY_INTERFACE_MODE
From: Yoshihiro Shimoda @ 2011-03-08  7:59 UTC (permalink / raw)
  To: netdev; +Cc: SH-Linux

The previous code had hardcoded the PHY_INTERFACE_MODE_MII of phy_connect.
So some Gigabit PHYs will not behave correctly.
The patch adds the phy_interface in sh_eth_plat_data, so we can select
the phy interface.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 This patch are based on net-next-2.6.git.

 arch/sh/include/asm/sh_eth.h |    3 +++
 drivers/net/sh_eth.c         |    3 ++-
 drivers/net/sh_eth.h         |    1 +
 3 files changed, 6 insertions(+), 1 deletions(-)

diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index 1557696..e86c880 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -1,6 +1,8 @@
 #ifndef __ASM_SH_ETH_H__
 #define __ASM_SH_ETH_H__

+#include <linux/phy.h>
+
 enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
 enum {
 	SH_ETH_REG_GIGABIT,
@@ -12,6 +14,7 @@ struct sh_eth_plat_data {
 	int phy;
 	int edmac_endian;
 	int register_type;
+	phy_interface_t phy_interface;

 	unsigned char mac_addr[6];
 	unsigned no_ether_link:1;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 6734311..5d28ce6 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1071,7 +1071,7 @@ static int sh_eth_phy_init(struct net_device *ndev)

 	/* Try connect to PHY */
 	phydev = phy_connect(ndev, phy_id, sh_eth_adjust_link,
-				0, PHY_INTERFACE_MODE_MII);
+				0, mdp->phy_interface);
 	if (IS_ERR(phydev)) {
 		dev_err(&ndev->dev, "phy_connect failed\n");
 		return PTR_ERR(phydev);
@@ -1669,6 +1669,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	pd = (struct sh_eth_plat_data *)(pdev->dev.platform_data);
 	/* get PHY ID */
 	mdp->phy_id = pd->phy;
+	mdp->phy_interface = pd->phy_interface;
 	/* EDMAC endian */
 	mdp->edmac_endian = pd->edmac_endian;
 	mdp->no_ether_link = pd->no_ether_link;
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index b349c5e..c3048a6 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -781,6 +781,7 @@ struct sh_eth_private {
 	struct mii_bus *mii_bus;	/* MDIO bus control */
 	struct phy_device *phydev;	/* PHY device control */
 	enum phy_state link;
+	phy_interface_t phy_interface;
 	int msg_enable;
 	int speed;
 	int duplex;
-- 
1.7.1

^ permalink raw reply related

* [PATCH v2 3/6] net: sh_eth: remove almost #ifdef of SH7763
From: Yoshihiro Shimoda @ 2011-03-08  7:59 UTC (permalink / raw)
  To: netdev; +Cc: SH-Linux

The SH7763 has GETHER. So the specification of some registers differs than
other CPUs. This patch removes almost #ifdef of CONFIG_CPU_SUBTYPE_SH7763.
Then we are able to add other CPU's GETHER easily.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 This patch are based on net-next-2.6.git.

 drivers/net/sh_eth.c |   72 +++++++++++++++++++++++++++++--------------------
 drivers/net/sh_eth.h |   14 +++-------
 2 files changed, 47 insertions(+), 39 deletions(-)

diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index c7abcc5..6734311 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -157,7 +157,7 @@ static void sh_eth_reset(struct net_device *ndev)
 	int cnt = 100;

 	sh_eth_write(ndev, EDSR_ENALL, EDSR);
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
 	while (cnt > 0) {
 		if (!(sh_eth_read(ndev, EDMR) & 0x3))
 			break;
@@ -285,9 +285,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
 /* Chip Reset */
 static void sh_eth_reset(struct net_device *ndev)
 {
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
 	mdelay(3);
-	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR);
 }
 #endif

@@ -365,6 +365,22 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac)
 	}
 }

+static int sh_eth_is_gether(struct sh_eth_private *mdp)
+{
+	if (mdp->reg_offset == sh_eth_offset_gigabit)
+		return 1;
+	else
+		return 0;
+}
+
+static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
+{
+	if (sh_eth_is_gether(mdp))
+		return EDTRR_TRNS_GETHER;
+	else
+		return EDTRR_TRNS_ETHER;
+}
+
 struct bb_info {
 	struct mdiobb_ctrl ctrl;
 	u32 addr;
@@ -504,9 +520,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		/* Rx descriptor address set */
 		if (i == 0) {
 			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-			sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
-#endif
+			if (sh_eth_is_gether(mdp))
+				sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
 		}
 	}

@@ -526,9 +541,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		if (i == 0) {
 			/* Tx descriptor address set */
 			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-			sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
-#endif
+			if (sh_eth_is_gether(mdp))
+				sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
 		}
 	}

@@ -940,9 +954,9 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		sh_eth_txfree(ndev);

 		/* SH7712 BUG */
-		if (edtrr ^ EDTRR_TRNS) {
+		if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
 			/* tx dma start */
-			sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
+			sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
 		}
 		/* wakeup */
 		netif_wake_queue(ndev);
@@ -1347,8 +1361,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)

 	mdp->cur_tx++;

-	if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS))
-		sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
+	if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
+		sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);

 	return NETDEV_TX_OK;
 }
@@ -1406,15 +1420,15 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
 	sh_eth_write(ndev, 0, CDCR);	/* (write clear) */
 	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
 	sh_eth_write(ndev, 0, LCCR);	/* (write clear) */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */
-	sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
-	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */
-	sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
-#else
-	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
-	sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
-#endif
+	if (sh_eth_is_gether(mdp)) {
+		mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
+		sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
+		mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
+		sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
+	} else {
+		mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
+		sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
+	}
 	pm_runtime_put_sync(&mdp->pdev->dev);

 	return &mdp->stats;
@@ -1465,13 +1479,13 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
 	sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
 	sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
 	sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-	sh_eth_tsu_write(mdp, 0, TSU_QTAG0);	/* Disable QTAG(0->1) */
-	sh_eth_tsu_write(mdp, 0, TSU_QTAG1);	/* Disable QTAG(1->0) */
-#else
-	sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);	/* Disable QTAG(0->1) */
-	sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);	/* Disable QTAG(1->0) */
-#endif
+	if (sh_eth_is_gether(mdp)) {
+		sh_eth_tsu_write(mdp, 0, TSU_QTAG0);	/* Disable QTAG(0->1) */
+		sh_eth_tsu_write(mdp, 0, TSU_QTAG1);	/* Disable QTAG(1->0) */
+	} else {
+		sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);	/* Disable QTAG(0->1) */
+		sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);	/* Disable QTAG(1->0) */
+	}
 	sh_eth_tsu_write(mdp, 0, TSU_FWSR);	/* all interrupt status clear */
 	sh_eth_tsu_write(mdp, 0, TSU_FWINMK);	/* Disable all interrupt */
 	sh_eth_tsu_write(mdp, 0, TSU_TEN);	/* Disable all CAM entry */
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 35a3adb..b349c5e 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -400,20 +400,14 @@ enum GECMR_BIT {
 enum DMAC_M_BIT {
 	EDMR_EL = 0x40, /* Litte endian */
 	EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-	EDMR_SRST = 0x03,
-#else /* CONFIG_CPU_SUBTYPE_SH7763 */
-	EDMR_SRST = 0x01,
-#endif
+	EDMR_SRST_GETHER = 0x03,
+	EDMR_SRST_ETHER = 0x01,
 };

 /* EDTRR */
 enum DMAC_T_BIT {
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
-	EDTRR_TRNS = 0x03,
-#else
-	EDTRR_TRNS = 0x01,
-#endif
+	EDTRR_TRNS_GETHER = 0x03,
+	EDTRR_TRNS_ETHER = 0x01,
 };

 /* EDRRR*/
-- 
1.7.1

^ permalink raw reply related

* [PATCH v2 2/6] net: sh_eth: remove the SH_TSU_ADDR
From: Yoshihiro Shimoda @ 2011-03-08  7:59 UTC (permalink / raw)
  To: netdev; +Cc: SH-Linux

The defination is hardcoded in this driver for some CPUs. This patch
modifies to get resource of TSU address from platform_device.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 This patch are based on net-next-2.6.git.

 about v2:
  - fix the ARSTR for SH7763

 drivers/net/sh_eth.c |   31 ++++++++++++++++++++++++-------
 drivers/net/sh_eth.h |   18 +++---------------
 2 files changed, 27 insertions(+), 22 deletions(-)

diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 51268f5..c7abcc5 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -145,8 +145,10 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 #define SH_ETH_HAS_TSU	1
 static void sh_eth_chip_reset(struct net_device *ndev)
 {
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+
 	/* reset device */
-	writel(ARSTR_ARSTR, ARSTR);
+	sh_eth_tsu_write(mdp, ARSTR_ARSTR, ARSTR);
 	mdelay(1);
 }

@@ -229,6 +231,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.hw_swap	= 1,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.tsu		= 1,
 };

 #elif defined(CONFIG_CPU_SUBTYPE_SH7619)
@@ -246,6 +249,7 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 #define SH_ETH_HAS_TSU	1
 static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 	.eesipr_value	= DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+	.tsu		= 1,
 };
 #endif

@@ -1446,6 +1450,7 @@ static void sh_eth_set_multicast_list(struct net_device *ndev)
 				ECMR_MCT, ECMR);
 	}
 }
+#endif /* SH_ETH_HAS_TSU */

 /* SuperH's TSU register init function */
 static void sh_eth_tsu_init(struct sh_eth_private *mdp)
@@ -1475,7 +1480,6 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
 	sh_eth_tsu_write(mdp, 0, TSU_POST3);	/* Disable CAM entry [16-23] */
 	sh_eth_tsu_write(mdp, 0, TSU_POST4);	/* Disable CAM entry [24-31] */
 }
-#endif /* SH_ETH_HAS_TSU */

 /* MDIO bus release function */
 static int sh_mdio_release(struct net_device *ndev)
@@ -1676,14 +1680,23 @@ static int sh_eth_drv_probe(struct platform_device *pdev)

 	/* First device only init */
 	if (!devno) {
+		if (mdp->cd->tsu) {
+			struct resource *rtsu;
+			rtsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+			if (!rtsu) {
+				dev_err(&pdev->dev, "Not found TSU resource\n");
+				goto out_release;
+			}
+			mdp->tsu_addr = ioremap(rtsu->start,
+						resource_size(rtsu));
+		}
 		if (mdp->cd->chip_reset)
 			mdp->cd->chip_reset(ndev);

-#if defined(SH_ETH_HAS_TSU)
-		/* TSU init (Init only)*/
-		mdp->tsu_addr = SH_TSU_ADDR;
-		sh_eth_tsu_init(mdp);
-#endif
+		if (mdp->cd->tsu) {
+			/* TSU init (Init only)*/
+			sh_eth_tsu_init(mdp);
+		}
 	}

 	/* network device register */
@@ -1709,6 +1722,8 @@ out_unregister:

 out_release:
 	/* net_dev free */
+	if (mdp->tsu_addr)
+		iounmap(mdp->tsu_addr);
 	if (ndev)
 		free_netdev(ndev);

@@ -1719,7 +1734,9 @@ out:
 static int sh_eth_drv_remove(struct platform_device *pdev)
 {
 	struct net_device *ndev = platform_get_drvdata(pdev);
+	struct sh_eth_private *mdp = netdev_priv(ndev);

+	iounmap(mdp->tsu_addr);
 	sh_mdio_release(ndev);
 	unregister_netdev(ndev);
 	pm_runtime_disable(&pdev->dev);
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 1510a7c..35a3adb 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -207,6 +207,7 @@ static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
 	[CEECR]	= 0x0770,
 	[MAFCR]	= 0x0778,

+	[ARSTR]	= 0x0000,
 	[TSU_CTRST]	= 0x0004,
 	[TSU_FWEN0]	= 0x0010,
 	[TSU_FWEN1]	= 0x0014,
@@ -328,6 +329,7 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
 	[TPAUSER]	= 0x01c4,
 	[BCFR]	= 0x01cc,

+	[ARSTR]	= 0x0000,
 	[TSU_CTRST]	= 0x0004,
 	[TSU_FWEN0]	= 0x0010,
 	[TSU_FWEN1]	= 0x0014,
@@ -371,21 +373,6 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {

 };

-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-/* This CPU register maps is very difference by other SH4 CPU */
-/* Chip Base Address */
-# define SH_TSU_ADDR	0xFEE01800
-# define ARSTR		SH_TSU_ADDR
-#elif defined(CONFIG_CPU_SH4)	/* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */
-#else /* #elif defined(CONFIG_CPU_SH4) */
-/* This section is SH3 or SH2 */
-#ifndef CONFIG_CPU_SUBTYPE_SH7619
-/* Chip base address */
-# define SH_TSU_ADDR  0xA7000804
-# define ARSTR		  0xA7000800
-#endif
-#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
-
 /* Driver's parameters */
 #if defined(CONFIG_CPU_SH4)
 #define SH4_SKB_RX_ALIGN	32
@@ -770,6 +757,7 @@ struct sh_eth_cpu_data {
 	unsigned mpr:1;			/* EtherC have MPR */
 	unsigned tpauser:1;		/* EtherC have TPAUSER */
 	unsigned bculr:1;		/* EtherC have BCULR */
+	unsigned tsu:1;			/* EtherC have TSU */
 	unsigned hw_swap:1;		/* E-DMAC have DE bit in EDMR */
 	unsigned rpadir:1;		/* E-DMAC have RPADIR */
 	unsigned no_trimd:1;		/* E-DMAC DO NOT have TRIMD */
-- 
1.7.1

^ permalink raw reply related

* [PATCH v2 1/6] net: sh_eth: modify the definitions of register
From: Yoshihiro Shimoda @ 2011-03-08  7:59 UTC (permalink / raw)
  To: netdev; +Cc: SH-Linux

The previous code cannot handle the ETHER and GETHER both as same time
because the definitions of register was hardcoded.

Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
 This patch are based on net-next-2.6.git.

 about v2:
  - remove SH_ETH_REG_DEFAULT

 arch/sh/include/asm/sh_eth.h |    6 +
 drivers/net/sh_eth.c         |  326 +++++++++++-----------
 drivers/net/sh_eth.h         |  623 ++++++++++++++++++++++++------------------
 3 files changed, 533 insertions(+), 422 deletions(-)

diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index f739061..1557696 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -2,10 +2,16 @@
 #define __ASM_SH_ETH_H__

 enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
+enum {
+	SH_ETH_REG_GIGABIT,
+	SH_ETH_REG_FAST_SH4,
+	SH_ETH_REG_FAST_SH3_SH2
+};

 struct sh_eth_plat_data {
 	int phy;
 	int edmac_endian;
+	int register_type;

 	unsigned char mac_addr[6];
 	unsigned no_ether_link:1;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 095e525..51268f5 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -49,25 +49,23 @@
 static void sh_eth_set_duplex(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	if (mdp->duplex) /* Full */
-		writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
 	else		/* Half */
-		writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
 }

 static void sh_eth_set_rate(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	switch (mdp->speed) {
 	case 10: /* 10BASE */
-		writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
 		break;
 	case 100:/* 100BASE */
-		writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
 		break;
 	default:
 		break;
@@ -100,25 +98,23 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
 static void sh_eth_set_duplex(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	if (mdp->duplex) /* Full */
-		writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
 	else		/* Half */
-		writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
 }

 static void sh_eth_set_rate(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	switch (mdp->speed) {
 	case 10: /* 10BASE */
-		writel(0, ioaddr + RTRATE);
+		sh_eth_write(ndev, 0, RTRATE);
 		break;
 	case 100:/* 100BASE */
-		writel(1, ioaddr + RTRATE);
+		sh_eth_write(ndev, 1, RTRATE);
 		break;
 	default:
 		break;
@@ -156,13 +152,12 @@ static void sh_eth_chip_reset(struct net_device *ndev)

 static void sh_eth_reset(struct net_device *ndev)
 {
-	u32 ioaddr = ndev->base_addr;
 	int cnt = 100;

-	writel(EDSR_ENALL, ioaddr + EDSR);
-	writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+	sh_eth_write(ndev, EDSR_ENALL, EDSR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
 	while (cnt > 0) {
-		if (!(readl(ioaddr + EDMR) & 0x3))
+		if (!(sh_eth_read(ndev, EDMR) & 0x3))
 			break;
 		mdelay(1);
 		cnt--;
@@ -171,41 +166,39 @@ static void sh_eth_reset(struct net_device *ndev)
 		printk(KERN_ERR "Device reset fail\n");

 	/* Table Init */
-	writel(0x0, ioaddr + TDLAR);
-	writel(0x0, ioaddr + TDFAR);
-	writel(0x0, ioaddr + TDFXR);
-	writel(0x0, ioaddr + TDFFR);
-	writel(0x0, ioaddr + RDLAR);
-	writel(0x0, ioaddr + RDFAR);
-	writel(0x0, ioaddr + RDFXR);
-	writel(0x0, ioaddr + RDFFR);
+	sh_eth_write(ndev, 0x0, TDLAR);
+	sh_eth_write(ndev, 0x0, TDFAR);
+	sh_eth_write(ndev, 0x0, TDFXR);
+	sh_eth_write(ndev, 0x0, TDFFR);
+	sh_eth_write(ndev, 0x0, RDLAR);
+	sh_eth_write(ndev, 0x0, RDFAR);
+	sh_eth_write(ndev, 0x0, RDFXR);
+	sh_eth_write(ndev, 0x0, RDFFR);
 }

 static void sh_eth_set_duplex(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	if (mdp->duplex) /* Full */
-		writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
 	else		/* Half */
-		writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+		sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
 }

 static void sh_eth_set_rate(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	switch (mdp->speed) {
 	case 10: /* 10BASE */
-		writel(GECMR_10, ioaddr + GECMR);
+		sh_eth_write(ndev, GECMR_10, GECMR);
 		break;
 	case 100:/* 100BASE */
-		writel(GECMR_100, ioaddr + GECMR);
+		sh_eth_write(ndev, GECMR_100, GECMR);
 		break;
 	case 1000: /* 1000BASE */
-		writel(GECMR_1000, ioaddr + GECMR);
+		sh_eth_write(ndev, GECMR_1000, GECMR);
 		break;
 	default:
 		break;
@@ -288,11 +281,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
 /* Chip Reset */
 static void sh_eth_reset(struct net_device *ndev)
 {
-	u32 ioaddr = ndev->base_addr;
-
-	writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
 	mdelay(3);
-	writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR);
 }
 #endif

@@ -341,13 +332,11 @@ static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
  */
 static void update_mac_address(struct net_device *ndev)
 {
-	u32 ioaddr = ndev->base_addr;
-
-	writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
-		  (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]),
-		  ioaddr + MAHR);
-	writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]),
-		  ioaddr + MALR);
+	sh_eth_write(ndev,
+		(ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
+		(ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR);
+	sh_eth_write(ndev,
+		(ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR);
 }

 /*
@@ -360,17 +349,15 @@ static void update_mac_address(struct net_device *ndev)
  */
 static void read_mac_address(struct net_device *ndev, unsigned char *mac)
 {
-	u32 ioaddr = ndev->base_addr;
-
 	if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
 		memcpy(ndev->dev_addr, mac, 6);
 	} else {
-		ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24);
-		ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF;
-		ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF;
-		ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF);
-		ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF;
-		ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF);
+		ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24);
+		ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF;
+		ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF;
+		ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF);
+		ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF;
+		ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF);
 	}
 }

@@ -477,7 +464,6 @@ static void sh_eth_ring_free(struct net_device *ndev)
 /* format skb and descriptor buffer */
 static void sh_eth_ring_format(struct net_device *ndev)
 {
-	u32 ioaddr = ndev->base_addr;
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	int i;
 	struct sk_buff *skb;
@@ -513,9 +499,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
 		/* Rx descriptor address set */
 		if (i == 0) {
-			writel(mdp->rx_desc_dma, ioaddr + RDLAR);
+			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
-			writel(mdp->rx_desc_dma, ioaddr + RDFAR);
+			sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
 #endif
 		}
 	}
@@ -535,9 +521,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
 		txdesc->buffer_length = 0;
 		if (i == 0) {
 			/* Tx descriptor address set */
-			writel(mdp->tx_desc_dma, ioaddr + TDLAR);
+			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
-			writel(mdp->tx_desc_dma, ioaddr + TDFAR);
+			sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
 #endif
 		}
 	}
@@ -620,7 +606,6 @@ static int sh_eth_dev_init(struct net_device *ndev)
 {
 	int ret = 0;
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;
 	u_int32_t rx_int_var, tx_int_var;
 	u32 val;

@@ -630,71 +615,71 @@ static int sh_eth_dev_init(struct net_device *ndev)
 	/* Descriptor format */
 	sh_eth_ring_format(ndev);
 	if (mdp->cd->rpadir)
-		writel(mdp->cd->rpadir_value, ioaddr + RPADIR);
+		sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);

 	/* all sh_eth int mask */
-	writel(0, ioaddr + EESIPR);
+	sh_eth_write(ndev, 0, EESIPR);

 #if defined(__LITTLE_ENDIAN__)
 	if (mdp->cd->hw_swap)
-		writel(EDMR_EL, ioaddr + EDMR);
+		sh_eth_write(ndev, EDMR_EL, EDMR);
 	else
 #endif
-		writel(0, ioaddr + EDMR);
+		sh_eth_write(ndev, 0, EDMR);

 	/* FIFO size set */
-	writel(mdp->cd->fdr_value, ioaddr + FDR);
-	writel(0, ioaddr + TFTR);
+	sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
+	sh_eth_write(ndev, 0, TFTR);

 	/* Frame recv control */
-	writel(mdp->cd->rmcr_value, ioaddr + RMCR);
+	sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);

 	rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
 	tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
-	writel(rx_int_var | tx_int_var, ioaddr + TRSCER);
+	sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);

 	if (mdp->cd->bculr)
-		writel(0x800, ioaddr + BCULR);	/* Burst sycle set */
+		sh_eth_write(ndev, 0x800, BCULR);	/* Burst sycle set */

-	writel(mdp->cd->fcftr_value, ioaddr + FCFTR);
+	sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);

 	if (!mdp->cd->no_trimd)
-		writel(0, ioaddr + TRIMD);
+		sh_eth_write(ndev, 0, TRIMD);

 	/* Recv frame limit set register */
-	writel(RFLR_VALUE, ioaddr + RFLR);
+	sh_eth_write(ndev, RFLR_VALUE, RFLR);

-	writel(readl(ioaddr + EESR), ioaddr + EESR);
-	writel(mdp->cd->eesipr_value, ioaddr + EESIPR);
+	sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
+	sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);

 	/* PAUSE Prohibition */
-	val = (readl(ioaddr + ECMR) & ECMR_DM) |
+	val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
 		ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;

-	writel(val, ioaddr + ECMR);
+	sh_eth_write(ndev, val, ECMR);

 	if (mdp->cd->set_rate)
 		mdp->cd->set_rate(ndev);

 	/* E-MAC Status Register clear */
-	writel(mdp->cd->ecsr_value, ioaddr + ECSR);
+	sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);

 	/* E-MAC Interrupt Enable register */
-	writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
+	sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);

 	/* Set MAC address */
 	update_mac_address(ndev);

 	/* mask reset */
 	if (mdp->cd->apr)
-		writel(APR_AP, ioaddr + APR);
+		sh_eth_write(ndev, APR_AP, APR);
 	if (mdp->cd->mpr)
-		writel(MPR_MP, ioaddr + MPR);
+		sh_eth_write(ndev, MPR_MP, MPR);
 	if (mdp->cd->tpauser)
-		writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
+		sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);

 	/* Setting the Rx mode will start the Rx process. */
-	writel(EDRRR_R, ioaddr + EDRRR);
+	sh_eth_write(ndev, EDRRR_R, EDRRR);

 	netif_start_queue(ndev);

@@ -818,38 +803,37 @@ static int sh_eth_rx(struct net_device *ndev)

 	/* Restart Rx engine if stopped. */
 	/* If we don't need to check status, don't. -KDU */
-	if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R))
-		writel(EDRRR_R, ndev->base_addr + EDRRR);
+	if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
+		sh_eth_write(ndev, EDRRR_R, EDRRR);

 	return 0;
 }

-static void sh_eth_rcv_snd_disable(u32 ioaddr)
+static void sh_eth_rcv_snd_disable(struct net_device *ndev)
 {
 	/* disable tx and rx */
-	writel(readl(ioaddr + ECMR) &
-		~(ECMR_RE | ECMR_TE), ioaddr + ECMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
+		~(ECMR_RE | ECMR_TE), ECMR);
 }

-static void sh_eth_rcv_snd_enable(u32 ioaddr)
+static void sh_eth_rcv_snd_enable(struct net_device *ndev)
 {
 	/* enable tx and rx */
-	writel(readl(ioaddr + ECMR) |
-		(ECMR_RE | ECMR_TE), ioaddr + ECMR);
+	sh_eth_write(ndev, sh_eth_read(ndev, ECMR) |
+		(ECMR_RE | ECMR_TE), ECMR);
 }

 /* error control function */
 static void sh_eth_error(struct net_device *ndev, int intr_status)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;
 	u32 felic_stat;
 	u32 link_stat;
 	u32 mask;

 	if (intr_status & EESR_ECI) {
-		felic_stat = readl(ioaddr + ECSR);
-		writel(felic_stat, ioaddr + ECSR);	/* clear int */
+		felic_stat = sh_eth_read(ndev, ECSR);
+		sh_eth_write(ndev, felic_stat, ECSR);	/* clear int */
 		if (felic_stat & ECSR_ICD)
 			mdp->stats.tx_carrier_errors++;
 		if (felic_stat & ECSR_LCHNG) {
@@ -860,23 +844,23 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 				else
 					link_stat = PHY_ST_LINK;
 			} else {
-				link_stat = (readl(ioaddr + PSR));
+				link_stat = (sh_eth_read(ndev, PSR));
 				if (mdp->ether_link_active_low)
 					link_stat = ~link_stat;
 			}
 			if (!(link_stat & PHY_ST_LINK))
-				sh_eth_rcv_snd_disable(ioaddr);
+				sh_eth_rcv_snd_disable(ndev);
 			else {
 				/* Link Up */
-				writel(readl(ioaddr + EESIPR) &
-					  ~DMAC_M_ECI, ioaddr + EESIPR);
+				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
+					  ~DMAC_M_ECI, EESIPR);
 				/*clear int */
-				writel(readl(ioaddr + ECSR),
-					  ioaddr + ECSR);
-				writel(readl(ioaddr + EESIPR) |
-					  DMAC_M_ECI, ioaddr + EESIPR);
+				sh_eth_write(ndev, sh_eth_read(ndev, ECSR),
+					  ECSR);
+				sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) |
+					  DMAC_M_ECI, EESIPR);
 				/* enable tx and rx */
-				sh_eth_rcv_snd_enable(ioaddr);
+				sh_eth_rcv_snd_enable(ndev);
 			}
 		}
 	}
@@ -917,8 +901,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		/* Receive Descriptor Empty int */
 		mdp->stats.rx_over_errors++;

-		if (readl(ioaddr + EDRRR) ^ EDRRR_R)
-			writel(EDRRR_R, ioaddr + EDRRR);
+		if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R)
+			sh_eth_write(ndev, EDRRR_R, EDRRR);
 		if (netif_msg_rx_err(mdp))
 			dev_err(&ndev->dev, "Receive Descriptor Empty\n");
 	}
@@ -942,7 +926,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		mask &= ~EESR_ADE;
 	if (intr_status & mask) {
 		/* Tx error */
-		u32 edtrr = readl(ndev->base_addr + EDTRR);
+		u32 edtrr = sh_eth_read(ndev, EDTRR);
 		/* dmesg */
 		dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
 				intr_status, mdp->cur_tx);
@@ -954,7 +938,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
 		/* SH7712 BUG */
 		if (edtrr ^ EDTRR_TRNS) {
 			/* tx dma start */
-			writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
+			sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
 		}
 		/* wakeup */
 		netif_wake_queue(ndev);
@@ -967,18 +951,17 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	struct sh_eth_cpu_data *cd = mdp->cd;
 	irqreturn_t ret = IRQ_NONE;
-	u32 ioaddr, intr_status = 0;
+	u32 intr_status = 0;

-	ioaddr = ndev->base_addr;
 	spin_lock(&mdp->lock);

 	/* Get interrpt stat */
-	intr_status = readl(ioaddr + EESR);
+	intr_status = sh_eth_read(ndev, EESR);
 	/* Clear interrupt */
 	if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
 			EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
 			cd->tx_check | cd->eesr_err_check)) {
-		writel(intr_status, ioaddr + EESR);
+		sh_eth_write(ndev, intr_status, EESR);
 		ret = IRQ_HANDLED;
 	} else
 		goto other_irq;
@@ -1021,7 +1004,6 @@ static void sh_eth_adjust_link(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	struct phy_device *phydev = mdp->phydev;
-	u32 ioaddr = ndev->base_addr;
 	int new_state = 0;

 	if (phydev->link != PHY_DOWN) {
@@ -1039,8 +1021,8 @@ static void sh_eth_adjust_link(struct net_device *ndev)
 				mdp->cd->set_rate(ndev);
 		}
 		if (mdp->link == PHY_DOWN) {
-			writel((readl(ioaddr + ECMR) & ~ECMR_TXF)
-					| ECMR_DM, ioaddr + ECMR);
+			sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF)
+					| ECMR_DM, ECMR);
 			new_state = 1;
 			mdp->link = phydev->link;
 		}
@@ -1122,12 +1104,11 @@ static int sh_eth_set_settings(struct net_device *ndev,
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 	unsigned long flags;
 	int ret;
-	u32 ioaddr = ndev->base_addr;

 	spin_lock_irqsave(&mdp->lock, flags);

 	/* disable tx and rx */
-	sh_eth_rcv_snd_disable(ioaddr);
+	sh_eth_rcv_snd_disable(ndev);

 	ret = phy_ethtool_sset(mdp->phydev, ecmd);
 	if (ret)
@@ -1145,7 +1126,7 @@ error_exit:
 	mdelay(1);

 	/* enable tx and rx */
-	sh_eth_rcv_snd_enable(ioaddr);
+	sh_eth_rcv_snd_enable(ndev);

 	spin_unlock_irqrestore(&mdp->lock, flags);

@@ -1282,7 +1263,6 @@ out_free_irq:
 static void sh_eth_tx_timeout(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;
 	struct sh_eth_rxdesc *rxdesc;
 	int i;

@@ -1290,7 +1270,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)

 	if (netif_msg_timer(mdp))
 		dev_err(&ndev->dev, "%s: transmit timed out, status %8.8x,"
-	       " resetting...\n", ndev->name, (int)readl(ioaddr + EESR));
+	       " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));

 	/* tx_errors count up */
 	mdp->stats.tx_errors++;
@@ -1363,8 +1343,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)

 	mdp->cur_tx++;

-	if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
-		writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
+	if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS))
+		sh_eth_write(ndev, EDTRR_TRNS, EDTRR);

 	return NETDEV_TX_OK;
 }
@@ -1373,17 +1353,16 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
 static int sh_eth_close(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;
 	int ringsize;

 	netif_stop_queue(ndev);

 	/* Disable interrupts by clearing the interrupt mask. */
-	writel(0x0000, ioaddr + EESIPR);
+	sh_eth_write(ndev, 0x0000, EESIPR);

 	/* Stop the chip's Tx and Rx processes. */
-	writel(0, ioaddr + EDTRR);
-	writel(0, ioaddr + EDRRR);
+	sh_eth_write(ndev, 0, EDTRR);
+	sh_eth_write(ndev, 0, EDRRR);

 	/* PHY Disconnect */
 	if (mdp->phydev) {
@@ -1414,24 +1393,23 @@ static int sh_eth_close(struct net_device *ndev)
 static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
-	u32 ioaddr = ndev->base_addr;

 	pm_runtime_get_sync(&mdp->pdev->dev);

-	mdp->stats.tx_dropped += readl(ioaddr + TROCR);
-	writel(0, ioaddr + TROCR);	/* (write clear) */
-	mdp->stats.collisions += readl(ioaddr + CDCR);
-	writel(0, ioaddr + CDCR);	/* (write clear) */
-	mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR);
-	writel(0, ioaddr + LCCR);	/* (write clear) */
+	mdp->stats.tx_dropped += sh_eth_read(ndev, TROCR);
+	sh_eth_write(ndev, 0, TROCR);	/* (write clear) */
+	mdp->stats.collisions += sh_eth_read(ndev, CDCR);
+	sh_eth_write(ndev, 0, CDCR);	/* (write clear) */
+	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
+	sh_eth_write(ndev, 0, LCCR);	/* (write clear) */
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
-	mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */
-	writel(0, ioaddr + CERCR);	/* (write clear) */
-	mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */
-	writel(0, ioaddr + CEECR);	/* (write clear) */
+	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */
+	sh_eth_write(ndev, 0, CERCR);	/* (write clear) */
+	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */
+	sh_eth_write(ndev, 0, CEECR);	/* (write clear) */
 #else
-	mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR);
-	writel(0, ioaddr + CNDCR);	/* (write clear) */
+	mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
+	sh_eth_write(ndev, 0, CNDCR);	/* (write clear) */
 #endif
 	pm_runtime_put_sync(&mdp->pdev->dev);

@@ -1458,46 +1436,44 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
 /* Multicast reception directions set */
 static void sh_eth_set_multicast_list(struct net_device *ndev)
 {
-	u32 ioaddr = ndev->base_addr;
-
 	if (ndev->flags & IFF_PROMISC) {
 		/* Set promiscuous. */
-		writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM,
-			  ioaddr + ECMR);
+		sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) |
+				ECMR_PRM, ECMR);
 	} else {
 		/* Normal, unicast/broadcast-only mode. */
-		writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT,
-			  ioaddr + ECMR);
+		sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) |
+				ECMR_MCT, ECMR);
 	}
 }

 /* SuperH's TSU register init function */
-static void sh_eth_tsu_init(u32 ioaddr)
+static void sh_eth_tsu_init(struct sh_eth_private *mdp)
 {
-	writel(0, ioaddr + TSU_FWEN0);	/* Disable forward(0->1) */
-	writel(0, ioaddr + TSU_FWEN1);	/* Disable forward(1->0) */
-	writel(0, ioaddr + TSU_FCM);	/* forward fifo 3k-3k */
-	writel(0xc, ioaddr + TSU_BSYSL0);
-	writel(0xc, ioaddr + TSU_BSYSL1);
-	writel(0, ioaddr + TSU_PRISL0);
-	writel(0, ioaddr + TSU_PRISL1);
-	writel(0, ioaddr + TSU_FWSL0);
-	writel(0, ioaddr + TSU_FWSL1);
-	writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
+	sh_eth_tsu_write(mdp, 0, TSU_FWEN0);	/* Disable forward(0->1) */
+	sh_eth_tsu_write(mdp, 0, TSU_FWEN1);	/* Disable forward(1->0) */
+	sh_eth_tsu_write(mdp, 0, TSU_FCM);	/* forward fifo 3k-3k */
+	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0);
+	sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1);
+	sh_eth_tsu_write(mdp, 0, TSU_PRISL0);
+	sh_eth_tsu_write(mdp, 0, TSU_PRISL1);
+	sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
+	sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
+	sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
-	writel(0, ioaddr + TSU_QTAG0);	/* Disable QTAG(0->1) */
-	writel(0, ioaddr + TSU_QTAG1);	/* Disable QTAG(1->0) */
+	sh_eth_tsu_write(mdp, 0, TSU_QTAG0);	/* Disable QTAG(0->1) */
+	sh_eth_tsu_write(mdp, 0, TSU_QTAG1);	/* Disable QTAG(1->0) */
 #else
-	writel(0, ioaddr + TSU_QTAGM0);	/* Disable QTAG(0->1) */
-	writel(0, ioaddr + TSU_QTAGM1);	/* Disable QTAG(1->0) */
+	sh_eth_tsu_write(mdp, 0, TSU_QTAGM0);	/* Disable QTAG(0->1) */
+	sh_eth_tsu_write(mdp, 0, TSU_QTAGM1);	/* Disable QTAG(1->0) */
 #endif
-	writel(0, ioaddr + TSU_FWSR);	/* all interrupt status clear */
-	writel(0, ioaddr + TSU_FWINMK);	/* Disable all interrupt */
-	writel(0, ioaddr + TSU_TEN);	/* Disable all CAM entry */
-	writel(0, ioaddr + TSU_POST1);	/* Disable CAM entry [ 0- 7] */
-	writel(0, ioaddr + TSU_POST2);	/* Disable CAM entry [ 8-15] */
-	writel(0, ioaddr + TSU_POST3);	/* Disable CAM entry [16-23] */
-	writel(0, ioaddr + TSU_POST4);	/* Disable CAM entry [24-31] */
+	sh_eth_tsu_write(mdp, 0, TSU_FWSR);	/* all interrupt status clear */
+	sh_eth_tsu_write(mdp, 0, TSU_FWINMK);	/* Disable all interrupt */
+	sh_eth_tsu_write(mdp, 0, TSU_TEN);	/* Disable all CAM entry */
+	sh_eth_tsu_write(mdp, 0, TSU_POST1);	/* Disable CAM entry [ 0- 7] */
+	sh_eth_tsu_write(mdp, 0, TSU_POST2);	/* Disable CAM entry [ 8-15] */
+	sh_eth_tsu_write(mdp, 0, TSU_POST3);	/* Disable CAM entry [16-23] */
+	sh_eth_tsu_write(mdp, 0, TSU_POST4);	/* Disable CAM entry [24-31] */
 }
 #endif /* SH_ETH_HAS_TSU */

@@ -1536,7 +1512,7 @@ static int sh_mdio_init(struct net_device *ndev, int id)
 	}

 	/* bitbang init */
-	bitbang->addr = ndev->base_addr + PIR;
+	bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR];
 	bitbang->mdi_msk = 0x08;
 	bitbang->mdo_msk = 0x04;
 	bitbang->mmd_msk = 0x02;/* MMD */
@@ -1587,6 +1563,28 @@ out:
 	return ret;
 }

+static const u16 *sh_eth_get_register_offset(int register_type)
+{
+	const u16 *reg_offset = NULL;
+
+	switch (register_type) {
+	case SH_ETH_REG_GIGABIT:
+		reg_offset = sh_eth_offset_gigabit;
+		break;
+	case SH_ETH_REG_FAST_SH4:
+		reg_offset = sh_eth_offset_fast_sh4;
+		break;
+	case SH_ETH_REG_FAST_SH3_SH2:
+		reg_offset = sh_eth_offset_fast_sh3_sh2;
+		break;
+	default:
+		printk(KERN_ERR "Unknown register type (%d)\n", register_type);
+		break;
+	}
+
+	return reg_offset;
+}
+
 static const struct net_device_ops sh_eth_netdev_ops = {
 	.ndo_open		= sh_eth_open,
 	.ndo_stop		= sh_eth_close,
@@ -1657,6 +1655,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
 	mdp->edmac_endian = pd->edmac_endian;
 	mdp->no_ether_link = pd->no_ether_link;
 	mdp->ether_link_active_low = pd->ether_link_active_low;
+	mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);

 	/* set cpu data */
 	mdp->cd = &sh_eth_my_cpu_data;
@@ -1682,7 +1681,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)

 #if defined(SH_ETH_HAS_TSU)
 		/* TSU init (Init only)*/
-		sh_eth_tsu_init(SH_TSU_ADDR);
+		mdp->tsu_addr = SH_TSU_ADDR;
+		sh_eth_tsu_init(mdp);
 #endif
 	}

diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index efa6422..1510a7c 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -2,7 +2,7 @@
  *  SuperH Ethernet device driver
  *
  *  Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- *  Copyright (C) 2008-2009 Renesas Solutions Corp.
+ *  Copyright (C) 2008-2011 Renesas Solutions Corp.
  *
  *  This program is free software; you can redistribute it and/or modify it
  *  under the terms and conditions of the GNU General Public License,
@@ -38,162 +38,345 @@
 #define ETHERSMALL		60
 #define PKT_BUF_SZ		1538

+enum {
+	/* E-DMAC registers */
+	EDSR = 0,
+	EDMR,
+	EDTRR,
+	EDRRR,
+	EESR,
+	EESIPR,
+	TDLAR,
+	TDFAR,
+	TDFXR,
+	TDFFR,
+	RDLAR,
+	RDFAR,
+	RDFXR,
+	RDFFR,
+	TRSCER,
+	RMFCR,
+	TFTR,
+	FDR,
+	RMCR,
+	EDOCR,
+	TFUCR,
+	RFOCR,
+	FCFTR,
+	RPADIR,
+	TRIMD,
+	RBWAR,
+	TBRAR,
+
+	/* Ether registers */
+	ECMR,
+	ECSR,
+	ECSIPR,
+	PIR,
+	PSR,
+	RDMLR,
+	PIPR,
+	RFLR,
+	IPGR,
+	APR,
+	MPR,
+	PFTCR,
+	PFRCR,
+	RFCR,
+	RFCF,
+	TPAUSER,
+	TPAUSECR,
+	BCFR,
+	BCFRR,
+	GECMR,
+	BCULR,
+	MAHR,
+	MALR,
+	TROCR,
+	CDCR,
+	LCCR,
+	CNDCR,
+	CEFCR,
+	FRECR,
+	TSFRCR,
+	TLFRCR,
+	CERCR,
+	CEECR,
+	MAFCR,
+	RTRATE,
+
+	/* TSU Absolute address */
+	ARSTR,
+	TSU_CTRST,
+	TSU_FWEN0,
+	TSU_FWEN1,
+	TSU_FCM,
+	TSU_BSYSL0,
+	TSU_BSYSL1,
+	TSU_PRISL0,
+	TSU_PRISL1,
+	TSU_FWSL0,
+	TSU_FWSL1,
+	TSU_FWSLC,
+	TSU_QTAG0,
+	TSU_QTAG1,
+	TSU_QTAGM0,
+	TSU_QTAGM1,
+	TSU_FWSR,
+	TSU_FWINMK,
+	TSU_ADQT0,
+	TSU_ADQT1,
+	TSU_VTAG0,
+	TSU_VTAG1,
+	TSU_ADSBSY,
+	TSU_TEN,
+	TSU_POST1,
+	TSU_POST2,
+	TSU_POST3,
+	TSU_POST4,
+	TSU_ADRH0,
+	TSU_ADRL0,
+	TSU_ADRH31,
+	TSU_ADRL31,
+
+	TXNLCR0,
+	TXALCR0,
+	RXNLCR0,
+	RXALCR0,
+	FWNLCR0,
+	FWALCR0,
+	TXNLCR1,
+	TXALCR1,
+	RXNLCR1,
+	RXALCR1,
+	FWNLCR1,
+	FWALCR1,
+
+	/* This value must be written at last. */
+	SH_ETH_MAX_REGISTER_OFFSET,
+};
+
+static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
+	[EDSR]	= 0x0000,
+	[EDMR]	= 0x0400,
+	[EDTRR]	= 0x0408,
+	[EDRRR]	= 0x0410,
+	[EESR]	= 0x0428,
+	[EESIPR]	= 0x0430,
+	[TDLAR]	= 0x0010,
+	[TDFAR]	= 0x0014,
+	[TDFXR]	= 0x0018,
+	[TDFFR]	= 0x001c,
+	[RDLAR]	= 0x0030,
+	[RDFAR]	= 0x0034,
+	[RDFXR]	= 0x0038,
+	[RDFFR]	= 0x003c,
+	[TRSCER]	= 0x0438,
+	[RMFCR]	= 0x0440,
+	[TFTR]	= 0x0448,
+	[FDR]	= 0x0450,
+	[RMCR]	= 0x0458,
+	[RPADIR]	= 0x0460,
+	[FCFTR]	= 0x0468,
+
+	[ECMR]	= 0x0500,
+	[ECSR]	= 0x0510,
+	[ECSIPR]	= 0x0518,
+	[PIR]	= 0x0520,
+	[PSR]	= 0x0528,
+	[PIPR]	= 0x052c,
+	[RFLR]	= 0x0508,
+	[APR]	= 0x0554,
+	[MPR]	= 0x0558,
+	[PFTCR]	= 0x055c,
+	[PFRCR]	= 0x0560,
+	[TPAUSER]	= 0x0564,
+	[GECMR]	= 0x05b0,
+	[BCULR]	= 0x05b4,
+	[MAHR]	= 0x05c0,
+	[MALR]	= 0x05c8,
+	[TROCR]	= 0x0700,
+	[CDCR]	= 0x0708,
+	[LCCR]	= 0x0710,
+	[CEFCR]	= 0x0740,
+	[FRECR]	= 0x0748,
+	[TSFRCR]	= 0x0750,
+	[TLFRCR]	= 0x0758,
+	[RFCR]	= 0x0760,
+	[CERCR]	= 0x0768,
+	[CEECR]	= 0x0770,
+	[MAFCR]	= 0x0778,
+
+	[TSU_CTRST]	= 0x0004,
+	[TSU_FWEN0]	= 0x0010,
+	[TSU_FWEN1]	= 0x0014,
+	[TSU_FCM]	= 0x0018,
+	[TSU_BSYSL0]	= 0x0020,
+	[TSU_BSYSL1]	= 0x0024,
+	[TSU_PRISL0]	= 0x0028,
+	[TSU_PRISL1]	= 0x002c,
+	[TSU_FWSL0]	= 0x0030,
+	[TSU_FWSL1]	= 0x0034,
+	[TSU_FWSLC]	= 0x0038,
+	[TSU_QTAG0]	= 0x0040,
+	[TSU_QTAG1]	= 0x0044,
+	[TSU_FWSR]	= 0x0050,
+	[TSU_FWINMK]	= 0x0054,
+	[TSU_ADQT0]	= 0x0048,
+	[TSU_ADQT1]	= 0x004c,
+	[TSU_VTAG0]	= 0x0058,
+	[TSU_VTAG1]	= 0x005c,
+	[TSU_ADSBSY]	= 0x0060,
+	[TSU_TEN]	= 0x0064,
+	[TSU_POST1]	= 0x0070,
+	[TSU_POST2]	= 0x0074,
+	[TSU_POST3]	= 0x0078,
+	[TSU_POST4]	= 0x007c,
+	[TSU_ADRH0]	= 0x0100,
+	[TSU_ADRL0]	= 0x0104,
+	[TSU_ADRH31]	= 0x01f8,
+	[TSU_ADRL31]	= 0x01fc,
+
+	[TXNLCR0]	= 0x0080,
+	[TXALCR0]	= 0x0084,
+	[RXNLCR0]	= 0x0088,
+	[RXALCR0]	= 0x008c,
+	[FWNLCR0]	= 0x0090,
+	[FWALCR0]	= 0x0094,
+	[TXNLCR1]	= 0x00a0,
+	[TXALCR1]	= 0x00a0,
+	[RXNLCR1]	= 0x00a8,
+	[RXALCR1]	= 0x00ac,
+	[FWNLCR1]	= 0x00b0,
+	[FWALCR1]	= 0x00b4,
+};
+
+static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
+	[ECMR]	= 0x0100,
+	[RFLR]	= 0x0108,
+	[ECSR]	= 0x0110,
+	[ECSIPR]	= 0x0118,
+	[PIR]	= 0x0120,
+	[PSR]	= 0x0128,
+	[RDMLR]	= 0x0140,
+	[IPGR]	= 0x0150,
+	[APR]	= 0x0154,
+	[MPR]	= 0x0158,
+	[TPAUSER]	= 0x0164,
+	[RFCF]	= 0x0160,
+	[TPAUSECR]	= 0x0168,
+	[BCFRR]	= 0x016c,
+	[MAHR]	= 0x01c0,
+	[MALR]	= 0x01c8,
+	[TROCR]	= 0x01d0,
+	[CDCR]	= 0x01d4,
+	[LCCR]	= 0x01d8,
+	[CNDCR]	= 0x01dc,
+	[CEFCR]	= 0x01e4,
+	[FRECR]	= 0x01e8,
+	[TSFRCR]	= 0x01ec,
+	[TLFRCR]	= 0x01f0,
+	[RFCR]	= 0x01f4,
+	[MAFCR]	= 0x01f8,
+	[RTRATE]	= 0x01fc,
+
+	[EDMR]	= 0x0000,
+	[EDTRR]	= 0x0008,
+	[EDRRR]	= 0x0010,
+	[TDLAR]	= 0x0018,
+	[RDLAR]	= 0x0020,
+	[EESR]	= 0x0028,
+	[EESIPR]	= 0x0030,
+	[TRSCER]	= 0x0038,
+	[RMFCR]	= 0x0040,
+	[TFTR]	= 0x0048,
+	[FDR]	= 0x0050,
+	[RMCR]	= 0x0058,
+	[TFUCR]	= 0x0064,
+	[RFOCR]	= 0x0068,
+	[FCFTR]	= 0x0070,
+	[RPADIR]	= 0x0078,
+	[TRIMD]	= 0x007c,
+	[RBWAR]	= 0x00c8,
+	[RDFAR]	= 0x00cc,
+	[TBRAR]	= 0x00d4,
+	[TDFAR]	= 0x00d8,
+};
+
+static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
+	[ECMR]	= 0x0160,
+	[ECSR]	= 0x0164,
+	[ECSIPR]	= 0x0168,
+	[PIR]	= 0x016c,
+	[MAHR]	= 0x0170,
+	[MALR]	= 0x0174,
+	[RFLR]	= 0x0178,
+	[PSR]	= 0x017c,
+	[TROCR]	= 0x0180,
+	[CDCR]	= 0x0184,
+	[LCCR]	= 0x0188,
+	[CNDCR]	= 0x018c,
+	[CEFCR]	= 0x0194,
+	[FRECR]	= 0x0198,
+	[TSFRCR]	= 0x019c,
+	[TLFRCR]	= 0x01a0,
+	[RFCR]	= 0x01a4,
+	[MAFCR]	= 0x01a8,
+	[IPGR]	= 0x01b4,
+	[APR]	= 0x01b8,
+	[MPR]	= 0x01bc,
+	[TPAUSER]	= 0x01c4,
+	[BCFR]	= 0x01cc,
+
+	[TSU_CTRST]	= 0x0004,
+	[TSU_FWEN0]	= 0x0010,
+	[TSU_FWEN1]	= 0x0014,
+	[TSU_FCM]	= 0x0018,
+	[TSU_BSYSL0]	= 0x0020,
+	[TSU_BSYSL1]	= 0x0024,
+	[TSU_PRISL0]	= 0x0028,
+	[TSU_PRISL1]	= 0x002c,
+	[TSU_FWSL0]	= 0x0030,
+	[TSU_FWSL1]	= 0x0034,
+	[TSU_FWSLC]	= 0x0038,
+	[TSU_QTAGM0]	= 0x0040,
+	[TSU_QTAGM1]	= 0x0044,
+	[TSU_ADQT0]	= 0x0048,
+	[TSU_ADQT1]	= 0x004c,
+	[TSU_FWSR]	= 0x0050,
+	[TSU_FWINMK]	= 0x0054,
+	[TSU_ADSBSY]	= 0x0060,
+	[TSU_TEN]	= 0x0064,
+	[TSU_POST1]	= 0x0070,
+	[TSU_POST2]	= 0x0074,
+	[TSU_POST3]	= 0x0078,
+	[TSU_POST4]	= 0x007c,
+
+	[TXNLCR0]	= 0x0080,
+	[TXALCR0]	= 0x0084,
+	[RXNLCR0]	= 0x0088,
+	[RXALCR0]	= 0x008c,
+	[FWNLCR0]	= 0x0090,
+	[FWALCR0]	= 0x0094,
+	[TXNLCR1]	= 0x00a0,
+	[TXALCR1]	= 0x00a0,
+	[RXNLCR1]	= 0x00a8,
+	[RXALCR1]	= 0x00ac,
+	[FWNLCR1]	= 0x00b0,
+	[FWALCR1]	= 0x00b4,
+
+	[TSU_ADRH0]	= 0x0100,
+	[TSU_ADRL0]	= 0x0104,
+	[TSU_ADRL31]	= 0x01fc,
+
+};
+
 #if defined(CONFIG_CPU_SUBTYPE_SH7763)
 /* This CPU register maps is very difference by other SH4 CPU */
-
 /* Chip Base Address */
 # define SH_TSU_ADDR	0xFEE01800
 # define ARSTR		SH_TSU_ADDR
-
-/* Chip Registers */
-/* E-DMAC */
-# define EDSR    0x000
-# define EDMR    0x400
-# define EDTRR   0x408
-# define EDRRR   0x410
-# define EESR    0x428
-# define EESIPR  0x430
-# define TDLAR   0x010
-# define TDFAR   0x014
-# define TDFXR   0x018
-# define TDFFR   0x01C
-# define RDLAR   0x030
-# define RDFAR   0x034
-# define RDFXR   0x038
-# define RDFFR   0x03C
-# define TRSCER  0x438
-# define RMFCR   0x440
-# define TFTR    0x448
-# define FDR     0x450
-# define RMCR    0x458
-# define RPADIR  0x460
-# define FCFTR   0x468
-
-/* Ether Register */
-# define ECMR    0x500
-# define ECSR    0x510
-# define ECSIPR  0x518
-# define PIR     0x520
-# define PSR     0x528
-# define PIPR    0x52C
-# define RFLR    0x508
-# define APR     0x554
-# define MPR     0x558
-# define PFTCR	 0x55C
-# define PFRCR	 0x560
-# define TPAUSER 0x564
-# define GECMR   0x5B0
-# define BCULR   0x5B4
-# define MAHR    0x5C0
-# define MALR    0x5C8
-# define TROCR   0x700
-# define CDCR    0x708
-# define LCCR    0x710
-# define CEFCR   0x740
-# define FRECR   0x748
-# define TSFRCR  0x750
-# define TLFRCR  0x758
-# define RFCR    0x760
-# define CERCR   0x768
-# define CEECR   0x770
-# define MAFCR   0x778
-
-/* TSU Absolute Address */
-# define TSU_CTRST       0x004
-# define TSU_FWEN0       0x010
-# define TSU_FWEN1       0x014
-# define TSU_FCM         0x18
-# define TSU_BSYSL0      0x20
-# define TSU_BSYSL1      0x24
-# define TSU_PRISL0      0x28
-# define TSU_PRISL1      0x2C
-# define TSU_FWSL0       0x30
-# define TSU_FWSL1       0x34
-# define TSU_FWSLC       0x38
-# define TSU_QTAG0       0x40
-# define TSU_QTAG1       0x44
-# define TSU_FWSR        0x50
-# define TSU_FWINMK      0x54
-# define TSU_ADQT0       0x48
-# define TSU_ADQT1       0x4C
-# define TSU_VTAG0       0x58
-# define TSU_VTAG1       0x5C
-# define TSU_ADSBSY      0x60
-# define TSU_TEN         0x64
-# define TSU_POST1       0x70
-# define TSU_POST2       0x74
-# define TSU_POST3       0x78
-# define TSU_POST4       0x7C
-# define TSU_ADRH0       0x100
-# define TSU_ADRL0       0x104
-# define TSU_ADRH31      0x1F8
-# define TSU_ADRL31      0x1FC
-
-# define TXNLCR0         0x80
-# define TXALCR0         0x84
-# define RXNLCR0         0x88
-# define RXALCR0         0x8C
-# define FWNLCR0         0x90
-# define FWALCR0         0x94
-# define TXNLCR1         0xA0
-# define TXALCR1         0xA4
-# define RXNLCR1         0xA8
-# define RXALCR1         0xAC
-# define FWNLCR1         0xB0
-# define FWALCR1         0x40
-
 #elif defined(CONFIG_CPU_SH4)	/* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */
-/* EtherC */
-#define ECMR		0x100
-#define RFLR		0x108
-#define ECSR		0x110
-#define ECSIPR		0x118
-#define PIR		0x120
-#define PSR		0x128
-#define RDMLR		0x140
-#define IPGR		0x150
-#define APR		0x154
-#define MPR		0x158
-#define TPAUSER		0x164
-#define RFCF		0x160
-#define TPAUSECR	0x168
-#define BCFRR		0x16c
-#define MAHR		0x1c0
-#define MALR		0x1c8
-#define TROCR		0x1d0
-#define CDCR		0x1d4
-#define LCCR		0x1d8
-#define CNDCR		0x1dc
-#define CEFCR		0x1e4
-#define FRECR		0x1e8
-#define TSFRCR		0x1ec
-#define TLFRCR		0x1f0
-#define RFCR		0x1f4
-#define MAFCR		0x1f8
-#define RTRATE		0x1fc
-
-/* E-DMAC */
-#define EDMR		0x000
-#define EDTRR		0x008
-#define EDRRR		0x010
-#define TDLAR		0x018
-#define RDLAR		0x020
-#define EESR		0x028
-#define EESIPR		0x030
-#define TRSCER		0x038
-#define RMFCR		0x040
-#define TFTR		0x048
-#define FDR		0x050
-#define RMCR		0x058
-#define TFUCR		0x064
-#define RFOCR		0x068
-#define FCFTR		0x070
-#define RPADIR		0x078
-#define TRIMD		0x07c
-#define RBWAR		0x0c8
-#define RDFAR		0x0cc
-#define TBRAR		0x0d4
-#define TDFAR		0x0d8
 #else /* #elif defined(CONFIG_CPU_SH4) */
 /* This section is SH3 or SH2 */
 #ifndef CONFIG_CPU_SUBTYPE_SH7619
@@ -201,116 +384,8 @@
 # define SH_TSU_ADDR  0xA7000804
 # define ARSTR		  0xA7000800
 #endif
-/* Chip Registers */
-/* E-DMAC */
-# define EDMR	0x0000
-# define EDTRR	0x0004
-# define EDRRR	0x0008
-# define TDLAR	0x000C
-# define RDLAR	0x0010
-# define EESR	0x0014
-# define EESIPR	0x0018
-# define TRSCER	0x001C
-# define RMFCR	0x0020
-# define TFTR	0x0024
-# define FDR	0x0028
-# define RMCR	0x002C
-# define EDOCR	0x0030
-# define FCFTR	0x0034
-# define RPADIR	0x0038
-# define TRIMD	0x003C
-# define RBWAR	0x0040
-# define RDFAR	0x0044
-# define TBRAR	0x004C
-# define TDFAR	0x0050
-
-/* Ether Register */
-# define ECMR	0x0160
-# define ECSR	0x0164
-# define ECSIPR	0x0168
-# define PIR	0x016C
-# define MAHR	0x0170
-# define MALR	0x0174
-# define RFLR	0x0178
-# define PSR	0x017C
-# define TROCR	0x0180
-# define CDCR	0x0184
-# define LCCR	0x0188
-# define CNDCR	0x018C
-# define CEFCR	0x0194
-# define FRECR	0x0198
-# define TSFRCR	0x019C
-# define TLFRCR	0x01A0
-# define RFCR	0x01A4
-# define MAFCR	0x01A8
-# define IPGR	0x01B4
-# if defined(CONFIG_CPU_SUBTYPE_SH7710)
-# define APR	0x01B8
-# define MPR 	0x01BC
-# define TPAUSER 0x1C4
-# define BCFR	0x1CC
-# endif /* CONFIG_CPU_SH7710 */
-
-/* TSU */
-# define TSU_CTRST	0x004
-# define TSU_FWEN0	0x010
-# define TSU_FWEN1	0x014
-# define TSU_FCM	0x018
-# define TSU_BSYSL0	0x020
-# define TSU_BSYSL1	0x024
-# define TSU_PRISL0	0x028
-# define TSU_PRISL1	0x02C
-# define TSU_FWSL0	0x030
-# define TSU_FWSL1	0x034
-# define TSU_FWSLC	0x038
-# define TSU_QTAGM0	0x040
-# define TSU_QTAGM1	0x044
-# define TSU_ADQT0 	0x048
-# define TSU_ADQT1	0x04C
-# define TSU_FWSR	0x050
-# define TSU_FWINMK	0x054
-# define TSU_ADSBSY	0x060
-# define TSU_TEN	0x064
-# define TSU_POST1	0x070
-# define TSU_POST2	0x074
-# define TSU_POST3	0x078
-# define TSU_POST4	0x07C
-# define TXNLCR0	0x080
-# define TXALCR0	0x084
-# define RXNLCR0	0x088
-# define RXALCR0	0x08C
-# define FWNLCR0	0x090
-# define FWALCR0	0x094
-# define TXNLCR1	0x0A0
-# define TXALCR1	0x0A4
-# define RXNLCR1	0x0A8
-# define RXALCR1	0x0AC
-# define FWNLCR1	0x0B0
-# define FWALCR1	0x0B4
-
-#define TSU_ADRH0	0x0100
-#define TSU_ADRL0	0x0104
-#define TSU_ADRL31	0x01FC
-
 #endif /* CONFIG_CPU_SUBTYPE_SH7763 */

-/* There are avoid compile error... */
-#if !defined(BCULR)
-#define BCULR	0x0fc
-#endif
-#if !defined(TRIMD)
-#define TRIMD	0x0fc
-#endif
-#if !defined(APR)
-#define APR	0x0fc
-#endif
-#if !defined(MPR)
-#define MPR	0x0fc
-#endif
-#if !defined(TPAUSER)
-#define TPAUSER	0x0fc
-#endif
-
 /* Driver's parameters */
 #if defined(CONFIG_CPU_SH4)
 #define SH4_SKB_RX_ALIGN	32
@@ -704,6 +779,8 @@ struct sh_eth_cpu_data {
 struct sh_eth_private {
 	struct platform_device *pdev;
 	struct sh_eth_cpu_data *cd;
+	const u16 *reg_offset;
+	void __iomem *tsu_addr;
 	dma_addr_t rx_desc_dma;
 	dma_addr_t tx_desc_dma;
 	struct sh_eth_rxdesc *rx_ring;
@@ -746,4 +823,32 @@ static inline void sh_eth_soft_swap(char *src, int len)
 #endif
 }

+static inline void sh_eth_write(struct net_device *ndev, unsigned long data,
+				int enum_index)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+
+	writel(data, ndev->base_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline unsigned long sh_eth_read(struct net_device *ndev,
+					int enum_index)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+
+	return readl(ndev->base_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline void sh_eth_tsu_write(struct sh_eth_private *mdp,
+				unsigned long data, int enum_index)
+{
+	writel(data, mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline unsigned long sh_eth_tsu_read(struct sh_eth_private *mdp,
+					int enum_index)
+{
+	return readl(mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
 #endif	/* #ifndef __SH_ETH_H__ */
-- 
1.7.1

^ permalink raw reply related

* Re: [patch net-next-2.6 4/8] bonding: wrap slave state work
From: Jiri Pirko @ 2011-03-08  7:18 UTC (permalink / raw)
  To: Nicolas de Pesloüan
  Cc: netdev, davem, shemminger, kaber, fubar, eric.dumazet, andy
In-Reply-To: <4D753820.2070608@gmail.com>

Mon, Mar 07, 2011 at 08:55:12PM CET, nicolas.2p.debian@gmail.com wrote:
>Le 07/03/2011 10:58, Jiri Pirko a écrit :
>>>>
>>>>+static inline void bond_set_active_slave(struct slave *slave)
>>>>+{
>>>>+	slave->backup = 0;
>>>
>>>In the comment above, you said that the possible value for backup
>>>corresponds with BOND_STATE_ACTIVE and BOND_STATE_BACKUP.
>>>
>>>So, should be:
>>>
>>>slave->backup = BOND_STATE_ACTIVE;
>>>
>>>>+}
>>>>+
>>>>+static inline void bond_set_backup_slave(struct slave *slave)
>>>>+{
>>>>+	slave->backup = 1;
>>>
>>>slave->backup = BOND_STATE_BACKUP;
>>>
>>
>>Well, I think it's weird and misleading to assign some define to :1
>>bitfield. Should be 0 or 1, nothing else.
>
>Agreed, but the comment appears missleading... May be you should fix the comment, not the code.

Hmm. I thought that the comment is accurate. BOND_STATE_ACTIVE
corresponds with 0, BOND_STATE_BACKUP corresponds with 1. Anyway, let me
know how would you like to formulate this and I can repost (or do a
little comment-changing followup)

Thanks Nicolas

>
>	Nicolas.
>

^ permalink raw reply

* Re: [patch net-next-2.6] net: reinject arps into bonding slave instead of master
From: Jiri Pirko @ 2011-03-08  7:13 UTC (permalink / raw)
  To: Andy Gospodarek
  Cc: Nicolas de Pesloüan, netdev, davem, shemminger, kaber, fubar,
	eric.dumazet
In-Reply-To: <20110307224338.GU11864@gospo.rdu.redhat.com>

Mon, Mar 07, 2011 at 11:43:38PM CET, andy@greyhouse.net wrote:
>On Mon, Mar 07, 2011 at 01:51:00PM +0100, Jiri Pirko wrote:
>> Recent patch "bonding: move processing of recv handlers into
>> handle_frame()" caused a regression on following net scheme:
>> 
>> eth0 - bond0 - bond0.5
>> 
>> where arp monitoring is happening over vlan. This patch fixes it by
>> reinjecting the arp packet into bonding slave device so the bonding
>> rx_handler can pickup and process it.
>> 
>> Signed-off-by: Jiri Pirko <jpirko@redhat.com>
>> ---
>>  net/core/dev.c |    8 ++++----
>>  1 files changed, 4 insertions(+), 4 deletions(-)
>> 
>> diff --git a/net/core/dev.c b/net/core/dev.c
>> index c71bd18..3d88458 100644
>> --- a/net/core/dev.c
>> +++ b/net/core/dev.c
>> @@ -3094,12 +3094,12 @@ void netdev_rx_handler_unregister(struct net_device *dev)
>>  }
>>  EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
>>  
>> -static void vlan_on_bond_hook(struct sk_buff *skb)
>> +static void vlan_on_bond_hook(struct sk_buff *skb, struct net_device *orig_dev)
>>  {
>>  	/*
>>  	 * Make sure ARP frames received on VLAN interfaces stacked on
>>  	 * bonding interfaces still make their way to any base bonding
>> -	 * device that may have registered for a specific ptype.
>> +	 * device by reinjecting the frame into bonding slave (orig_dev)
>>  	 */
>>  	if (skb->dev->priv_flags & IFF_802_1Q_VLAN &&
>>  	    vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING &&
>> @@ -3108,7 +3108,7 @@ static void vlan_on_bond_hook(struct sk_buff *skb)
>>  
>>  		if (!skb2)
>>  			return;
>> -		skb2->dev = vlan_dev_real_dev(skb->dev);
>> +		skb2->dev = orig_dev;
>>  		netif_rx(skb2);
>>  	}
>>  }
>> @@ -3202,7 +3202,7 @@ ncls:
>>  			goto out;
>>  	}
>>  
>> -	vlan_on_bond_hook(skb);
>> +	vlan_on_bond_hook(skb, orig_dev);
>>  
>>  	/* deliver only exact match when indicated */
>>  	null_or_dev = deliver_exact ? skb->dev : NULL;
>
>This patch doesn't work.
>
>My setup has bond0.100 -> bond0 -> eth2 and eth3.  ARP monitoring is
>enabled as is arp_valiate.
>
>The initial problem was just that just before vlan_on_bond_hook is
>called, skb->dev = bond0.100 and orig_dev = eth2.   (This is after
>running goto another_route and having been called back through
>__netif_receive_skb since vlan_hwaccel_do_receive it true.)
>
>Now vlan_on_bond_hook is called and we have 2 skbs.
>
>The original skb still have skb->dev = bond0.100 and orig_dev = eth2.
>Since bond_arp_rcv is registered for traffic only to bond0, the handler
>is not hit and the frame is dropped (or processed by another handler).
>
>The cloned skb has skb->dev = bond0 and is put back on the receive queue
>and comes back through __netif_receive_skb.  This frame will match the
>ptype entry for bond_arp_rcv, but since orig_dev = bond0 in this case,
>the code in bond_arp_rcv will not handle the frame.  
>
>If we truly want to track the original interface that received the
>frame, the following is a better option.  With the recursive nature of
>__netif_receive_skb at this point, we should really consider setting
>orig_dev from skb_iif rather than just from skb->dev.
>
>diff --git a/net/core/dev.c b/net/core/dev.c
>index 30440e7..500fdbc 100644
>--- a/net/core/dev.c
>+++ b/net/core/dev.c
>@@ -3135,7 +3135,6 @@ static int __netif_receive_skb(struct sk_buff *skb)
> 
> 	if (!skb->skb_iif)
> 		skb->skb_iif = skb->dev->ifindex;
>-	orig_dev = skb->dev;
> 
> 	skb_reset_network_header(skb);
> 	skb_reset_transport_header(skb);
>@@ -3145,6 +3144,7 @@ static int __netif_receive_skb(struct sk_buff *skb)
> 
> 	rcu_read_lock();
> 
>+	orig_dev = dev_get_by_index_rcu(dev_net(skb->dev),skb->skb_iif);
> another_round:
> 
> 	__this_cpu_inc(softnet_data.processed);
>

This was proposed earlier. people did not like this very much :(

I forgot to include crucial part of "goto another_round for vlan".
Following patch should work (will test it once I get to work):

Subject: [patch net-next 2.6] net: reinject arps into bonding slave instead of master

Recent patch "bonding: move processing of recv handlers into
handle_frame()" caused a regression on following net scheme:

eth0 - bond0 - bond0.5

where arp monitoring is happening over vlan. This patch fixes it by
reinjecting the arp packet into bonding slave device so the bonding
rx_handler can pickup and process it.

also instead of calling __netif_receive_skb recursively, "goto another
round" does this recursion. The point is the orig_dev variable remains
intact.

Signed-off-by: Jiri Pirko <jpirko@redhat.com>
---
 net/core/dev.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

diff --git a/net/core/dev.c b/net/core/dev.c
index c71bd18..ec330e1 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -3094,12 +3094,12 @@ void netdev_rx_handler_unregister(struct net_device *dev)
 }
 EXPORT_SYMBOL_GPL(netdev_rx_handler_unregister);
 
-static void vlan_on_bond_hook(struct sk_buff *skb)
+static void vlan_on_bond_hook(struct sk_buff *skb, struct net_device *orig_dev)
 {
 	/*
 	 * Make sure ARP frames received on VLAN interfaces stacked on
 	 * bonding interfaces still make their way to any base bonding
-	 * device that may have registered for a specific ptype.
+	 * device by reinjecting the frame into bonding slave (orig_dev)
 	 */
 	if (skb->dev->priv_flags & IFF_802_1Q_VLAN &&
 	    vlan_dev_real_dev(skb->dev)->priv_flags & IFF_BONDING &&
@@ -3108,7 +3108,7 @@ static void vlan_on_bond_hook(struct sk_buff *skb)
 
 		if (!skb2)
 			return;
-		skb2->dev = vlan_dev_real_dev(skb->dev);
+		skb2->dev = orig_dev;
 		netif_rx(skb2);
 	}
 }
@@ -3196,13 +3196,12 @@ ncls:
 			pt_prev = NULL;
 		}
 		if (vlan_hwaccel_do_receive(&skb)) {
-			ret = __netif_receive_skb(skb);
-			goto out;
+			goto another_round;
 		} else if (unlikely(!skb))
 			goto out;
 	}
 
-	vlan_on_bond_hook(skb);
+	vlan_on_bond_hook(skb, orig_dev);
 
 	/* deliver only exact match when indicated */
 	null_or_dev = deliver_exact ? skb->dev : NULL;
-- 
1.7.4


^ permalink raw reply related

* Re: [RFC] [PATCH 06/11] esp4: Add support for IPsec extended sequence numbers
From: Steffen Klassert @ 2011-03-08  7:04 UTC (permalink / raw)
  To: Herbert Xu
  Cc: David Miller, Andreas Gruenbacher, Alex Badea, netdev,
	linux-crypto
In-Reply-To: <20101202072947.GA22998@gondor.apana.org.au>

Sorry for the huge delay...

On Thu, Dec 02, 2010 at 03:29:47PM +0800, Herbert Xu wrote:
> On Mon, Nov 22, 2010 at 11:30:14AM +0100, Steffen Klassert wrote:
> >
> > @@ -205,11 +228,18 @@ static int esp_output(struct xfrm_state *x, struct sk_buff *skb)
> >  	skb_to_sgvec(skb, sg,
> >  		     esph->enc_data + crypto_aead_ivsize(aead) - skb->data,
> >  		     clen + alen);
> > -	sg_init_one(asg, esph, sizeof(*esph));
> > +
> > +	if ((x->props.flags & XFRM_STATE_ESN)) {
> > +		sg_init_table(asg, 2);
> > +		sg_set_buf(asg, esph, sizeof(*esph));
> > +		*seqhi = htonl(XFRM_SKB_CB(skb)->seq.output.hi);
> > +		sg_set_buf(asg + 1, seqhi, seqhilen);
> > +	} else
> > +		sg_init_one(asg, esph, sizeof(*esph));
> 
> I think this is wrong for AEAD algorithms.  You want the sequence
> number in network byte order for them so the high bits need to be
> inserted into the middle of the ESP header.
> 

Yes, indeed.

> The other problem is that you're currently requiring the authencesn
> user to provide two SG entries which is fine for now.  However,
> since this might be exported to user-space in future, authenecesn
> shouldn't really rely on that, or at least it shouldn't BUG.
> 
> So one solution is to do it based on bytes in authencesn.  That is,
> your associated input should always be 12 bytes long, and then you
> simply construct a new SG list for your actual processing with the
> middle 4 bytes taken out.
> 
> For IPsec it could just provide an SG list with three entries,
> of 4 bytes each.

Ok, I've updated the patchset in this regard.

> 
> Of course for simplicity, you could require this to be the case in
> authencesn and return -EINVAL (not BUG :) if it's not the case.
> 

Doing BUG was a leftover from debugging the thing. On debugging it is 
sometimes better to pull the emergency brake as soon as something
unexpected happens. I replaced BUG with return -EINVAL now.

I'll resend the patchset for a second round of review.

^ permalink raw reply

* Re: ANNOUNCE: debloat-testing kernel git tree
From: Pavel Machek @ 2011-03-08  6:58 UTC (permalink / raw)
  To: Tianji Li
  Cc: rick.jones2, Dave T?ht, sedat.dilek, netdev, linux-wireless,
	bloat-devel, linux-kernel
In-Reply-To: <4D6FEFD4.9010608@nuim.ie>

On Thu 2011-03-03 13:45:24, Tianji Li wrote:
> 
> 
> On 03/03/2011 12:16 PM, Rick Jones wrote:
> >>For wireless routers and cable home gateways especially, this research
> >>shows that the total un-managed buffers in your system should be less
> >>than 32.
> >
> >Would it be a good thing to start describing these queues not so much in
> >terms of packets but in terms of delay (or bandwidth X delay)?
> >
> 
> The unit of bandwidth is something like Mbps, that of delay can be
> second, so bandwidth X delay --> Mb, which is the unit of packet
> size. So both packets and delay should have the same effect for
> sizing buffers.

Bandwidth varies greatly with time. On cellphone, you can go from
5KB/sec GPRS to 300KB/sec HSDPA and back...
								Pavel
-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: bonding can't change to another slave if you ifdown the active slave
From: Weiping Pan @ 2011-03-08  6:52 UTC (permalink / raw)
  To: netdev


On 03/08/2011 05:15 AM, Nicolas de Pesloüan wrote:
> Le 07/03/2011 04:13, Weiping Pan a écrit :
>> On 03/05/2011 09:49 PM, Nicolas de Pesloüan wrote:
>>> Le 05/03/2011 03:53, Andy Gospodarek a écrit :
>>>> On Fri, Mar 04, 2011 at 10:15:17AM +0800, Weiping Pan wrote:
>>>>> Hi,
>>>>>
>>>>> I'm doing some Linux bonding driver test, and I find a problem in
>>>>> balance-rr mode.
>>>>> That's it can't change to another slave if you ifdown the active 
>>>>> slave.
>>>>> Any comments are warmly welcomed!
>>>>>
>>>>> regards
>>>>> Weiping Pan
>>>>>
>>>>> My host is Fedora 14, and I install VirtualBox (4.0.2), and enable 4
>>>>> nics for the guest system.
>>>>
>>>> Does this mean you are passing 4 NICs from your host to your guest
>>>> (maybe via direct pci-device assignment to the guest) or are you
>>>> creating 4 virtual devices on the host that are in a bridge group 
>>>> on the
>>>> host?
>>>
>>> VirtualBox does not allow assignment of pci-device to the guest. The
>>> network interfaces on the guest are pure virtual one, with several
>>> modes available. In order to help you trouble shooting this problem,
>>> we need to know the mode form each of the virtual interfaces. Possible
>>> modes are NAT, bridged, internal-network, and host-only-network.
>>>
>>> Please provide the output of the following command:
>>>
>>> VBoxManage showvminfo <your-vm-uuid> | grep ^NIC
>>>
>>> To display your vm uuid, use the following command:
>>>
>>> VBoxManage list vms
>> [root@localhost ~]# VBoxManage showvminfo
>> 67b83c47-0ee2-46bc-b0ff-e0eb43edc1c2 |grep ^NIC
>> NIC 1: MAC: 0800270481A8, Attachment: Bridged Interface 'eth0', Cable
>> connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0
>> Mbps, Boot priority: 0
>> NIC 2: MAC: 08002778F641, Attachment: Bridged Interface 'eth0', Cable
>> connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0
>> Mbps, Boot priority: 0
>> NIC 3: MAC: 080027C408BA, Attachment: Bridged Interface 'eth0', Cable
>> connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0
>> Mbps, Boot priority: 0
>> NIC 4: MAC: 080027DB339A, Attachment: Bridged Interface 'eth0', Cable
>> connected: on, Trace: off (file: none), Type: 82540EM, Reported speed: 0
>> Mbps, Boot priority: 0
>> NIC 5: disabled
>> NIC 6: disabled
>> NIC 7: disabled
>> NIC 8: disabled
>>
>> And when guest starts, i find that:
>> NIC 1: eth7
>> NIC 2: eth6
>> NIC 3: eth9
>> NIC 4: eth8
>
> Would you mind testing with "Host-only Interface 'vboxnet0'", instead 
> of "Bridged Interface 'eth0'"?
>
> All the bonding tests I do use this setup and the link failure 
> detection work well.
>
>     Nicolas.
ok, I use "Host-only mode" and get



an conclusion, that if the first enslaved nic is pulled out, bonding 
can't handle well.

First test.
I first enslave eth6, then pull it out, bonding doesn't work.
on host,
[root@localhost ~]# VBoxManage -v
4.0.2r69518

[root@localhost ~]# VBoxManage showvminfo 
67b83c47-0ee2-46bc-b0ff-e0eb43edc1c2|grep ^NIC
NIC 1:           MAC: 0800270481A8, Attachment: Host-only Interface 
'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, 
Reported speed: 0 Mbps, Boot priority: 0
NIC 2:           MAC: 08002778F641, Attachment: Host-only Interface 
'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, 
Reported speed: 0 Mbps, Boot priority: 0
NIC 3:           MAC: 080027C408BA, Attachment: Host-only Interface 
'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, 
Reported speed: 0 Mbps, Boot priority: 0
NIC 4:           MAC: 080027DB339A, Attachment: Host-only Interface 
'vboxnet0', Cable connected: on, Trace: off (file: none), Type: 82540EM, 
Reported speed: 0 Mbps, Boot priority: 0
NIC 5:           disabled
NIC 6:           disabled
NIC 7:           disabled
NIC 8:           disabled

[root@localhost ~]# ifconfig vboxnet0
vboxnet0  Link encap:Ethernet  HWaddr 0A:00:27:00:00:00
           inet addr:192.168.56.1  Bcast:192.168.56.255  Mask:255.255.255.0
           inet6 addr: fe80::800:27ff:fe00:0/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:0 errors:0 dropped:0 overruns:0 frame:0
           TX packets:268 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:0 (0.0 b)  TX bytes:52456 (51.2 KiB)

restart guest,
[root@localhost ~]# uname -a
Linux localhost.localdomain 2.6.35.11-83.fc14.i686 #1 SMP Mon Feb 7 
07:04:18 UTC 2011 i686 i686 i386 GNU/Linux

[root@localhost ~]# ifconfig
eth6      Link encap:Ethernet  HWaddr 08:00:27:78:F6:41
           inet addr:192.168.56.101  Bcast:192.168.56.255  
Mask:255.255.255.0
           inet6 addr: fe80::a00:27ff:fe78:f641/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:14 errors:0 dropped:0 overruns:0 frame:0
           TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:6772 (6.6 KiB)  TX bytes:1152 (1.1 KiB)

eth7      Link encap:Ethernet  HWaddr 08:00:27:04:81:A8
           inet addr:192.168.56.102  Bcast:192.168.56.255  
Mask:255.255.255.0
           inet6 addr: fe80::a00:27ff:fe04:81a8/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:14 errors:0 dropped:0 overruns:0 frame:0
           TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:6772 (6.6 KiB)  TX bytes:1152 (1.1 KiB)

eth8      Link encap:Ethernet  HWaddr 08:00:27:DB:33:9A
           inet addr:192.168.56.104  Bcast:192.168.56.255  
Mask:255.255.255.0
           inet6 addr: fe80::a00:27ff:fedb:339a/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:63 errors:0 dropped:0 overruns:0 frame:0
           TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:19456 (19.0 KiB)  TX bytes:1152 (1.1 KiB)

eth9      Link encap:Ethernet  HWaddr 08:00:27:C4:08:BA
           inet addr:192.168.56.103  Bcast:192.168.56.255  
Mask:255.255.255.0
           inet6 addr: fe80::a00:27ff:fec4:8ba/64 Scope:Link
           UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
           RX packets:63 errors:0 dropped:0 overruns:0 frame:0
           TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:1000
           RX bytes:19456 (19.0 KiB)  TX bytes:1152 (1.1 KiB)

lo        Link encap:Local Loopback
           inet addr:127.0.0.1  Mask:255.0.0.0
           inet6 addr: ::1/128 Scope:Host
           UP LOOPBACK RUNNING  MTU:16436  Metric:1
           RX packets:16 errors:0 dropped:0 overruns:0 frame:0
           TX packets:16 errors:0 dropped:0 overruns:0 carrier:0
           collisions:0 txqueuelen:0
           RX bytes:880 (880.0 b)  TX bytes:880 (880.0 b)

so
NIC 1:           eth7
NIC 2:           eth6
NIC 3:           eth9
NIC 4:           eth8

on guest,
[root@localhost ~]# for i in eth{6..9}; do ifconfig $i down; done
[root@localhost ~]# modprobe bonding mode=0 miimon=100
[root@localhost ~]# ifconfig bond0 192.168.56.2 netmask 255.255.255.0 up
[root@localhost ~]# ifenslave bond0 eth6
[root@localhost ~]# ifenslave bond0 eth7
[root@localhost ~]# ping 192.168.56.1 -c 5
PING 192.168.56.1 (192.168.56.1) 56(84) bytes of data.
64 bytes from 192.168.56.1: icmp_req=1 ttl=64 time=1.83 ms
64 bytes from 192.168.56.1: icmp_req=2 ttl=64 time=0.149 ms
64 bytes from 192.168.56.1: icmp_req=3 ttl=64 time=0.204 ms
64 bytes from 192.168.56.1: icmp_req=4 ttl=64 time=0.294 ms
64 bytes from 192.168.56.1: icmp_req=5 ttl=64 time=0.412 ms

--- 192.168.56.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4003ms
rtt min/avg/max/mdev = 0.149/0.578/1.832/0.633 ms
[root@localhost ~]# arp
Address                  HWtype  HWaddress           Flags 
Mask            Iface
192.168.56.1             ether   0a:00:27:00:00:00   
C                     bond0

on host,
[root@localhost ~]# arp
Address                  HWtype  HWaddress           Flags 
Mask            Iface
192.168.56.2             ether   08:00:27:78:f6:41   
C                     vboxnet0
corerouter.nay.redhat.c  ether   00:1d:45:20:d5:ff   
C                     eth0
[root@localhost ~]# VBoxManage controlvm 
67b83c47-0ee2-46bc-b0ff-e0eb43edc1c2 setlinkstate2 off

[root@localhost ~]# ping 192.168.56.1 -c 5
PING 192.168.56.1 (192.168.56.1) 56(84) bytes of data.
 From 192.168.56.2 icmp_seq=2 Destination Host Unreachable
 From 192.168.56.2 icmp_seq=3 Destination Host Unreachable
 From 192.168.56.2 icmp_seq=4 Destination Host Unreachable
 From 192.168.56.2 icmp_seq=5 Destination Host Unreachable

--- 192.168.56.1 ping statistics ---
5 packets transmitted, 0 received, +4 errors, 100% packet loss, time 4001ms
pipe 3
[root@localhost ~]# dmesg
[  513.093249] e1000: eth6 NIC Link is Down
[  513.129123] bonding: bond0: link status definitely down for interface 
eth6, disabling it
[root@localhost ~]# ip route show
192.168.56.0/24 dev bond0  proto kernel  scope link  src 192.168.56.2
192.168.56.0/24 dev eth7  proto kernel  scope link  src 192.168.56.101  
metric 1
[root@localhost ~]# ip neigh show
192.168.56.1 dev bond0  FAILED

on host,
[root@localhost ~]# ip route show
192.168.1.0/24 dev eth0  proto kernel  scope link  src 192.168.1.100
192.168.56.0/24 dev vboxnet0  proto kernel  scope link  src 192.168.56.1
10.66.64.0/23 dev eth0  proto kernel  scope link  src 10.66.65.228  
metric 1
default via 10.66.65.254 dev eth0  proto static
[root@localhost ~]# ip neigh show
192.168.56.2 dev vboxnet0 lladdr 08:00:27:78:f6:41 STALE
10.66.65.254 dev eth0 lladdr 00:1d:45:20:d5:ff REACHABLE


Second test
I first enslave eth6, then pull eth7 out, bonding works well.
on guest,
[root@localhost ~]# modprobe bonding mode=0 miimon=100
[root@localhost ~]# ifconfig bond0 192.168.56.2 netmask 255.255.255.0 up
[root@localhost ~]# ifenslave bond0 eth6
[root@localhost ~]# ifenslave bond0 eth7
[root@localhost ~]# ping 192.168.56.1 -c 5
PING 192.168.56.1 (192.168.56.1) 56(84) bytes of data.
64 bytes from 192.168.56.1: icmp_req=1 ttl=64 time=0.902 ms
64 bytes from 192.168.56.1: icmp_req=2 ttl=64 time=0.260 ms
64 bytes from 192.168.56.1: icmp_req=3 ttl=64 time=0.237 ms
64 bytes from 192.168.56.1: icmp_req=4 ttl=64 time=0.335 ms
64 bytes from 192.168.56.1: icmp_req=5 ttl=64 time=0.170 ms

--- 192.168.56.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4001ms
rtt min/avg/max/mdev = 0.170/0.380/0.902/0.267 ms

[root@localhost ~]# dmesg
[ 1162.524825] bonding: MII link monitoring set to 100 ms
[ 1165.845586] ADDRCONF(NETDEV_UP): bond0: link is not ready
[ 1174.505912] e1000: eth6 NIC Link is Up 1000 Mbps Full Duplex, Flow 
Control: RX
[ 1174.512372] bonding: bond0: enslaving eth6 as an active interface 
with an up link.
[ 1174.512897] ADDRCONF(NETDEV_CHANGE): bond0: link becomes ready
[ 1178.857322] ICMPv6 NA: someone advertises our address 
fe80:0000:0000:0000:0a00:27ff:fe78:f641 on bond0!
[ 1178.858649] e1000: eth7 NIC Link is Up 1000 Mbps Full Duplex, Flow 
Control: RX
[ 1178.861391] bonding: bond0: enslaving eth7 as an active interface 
with an up link.
[ 1184.682110] bond0: no IPv6 routers present

on host,
[root@localhost ~]# VBoxManage controlvm 
67b83c47-0ee2-46bc-b0ff-e0eb43edc1c2 setlinkstate1 off

on guest,
[root@localhost ~]# ping 192.168.56.1 -c 5
PING 192.168.56.1 (192.168.56.1) 56(84) bytes of data.
64 bytes from 192.168.56.1: icmp_req=1 ttl=64 time=0.599 ms
64 bytes from 192.168.56.1: icmp_req=2 ttl=64 time=0.150 ms
64 bytes from 192.168.56.1: icmp_req=3 ttl=64 time=0.224 ms
64 bytes from 192.168.56.1: icmp_req=4 ttl=64 time=0.154 ms
64 bytes from 192.168.56.1: icmp_req=5 ttl=64 time=0.189 ms

--- 192.168.56.1 ping statistics ---
5 packets transmitted, 5 received, 0% packet loss, time 4000ms
rtt min/avg/max/mdev = 0.150/0.263/0.599/0.170 ms
[root@localhost ~]# dmesg
[ 1281.421231] e1000: eth7 NIC Link is Down
[ 1281.492178] bonding: bond0: link status definitely down for interface 
eth7, disabling it


many thanks
Weiping Pan






^ permalink raw reply

* [PATCH] ipv4: Cache source address in nexthop entries.
From: David Miller @ 2011-03-08  4:58 UTC (permalink / raw)
  To: netdev


When doing output route lookups, we have to select the source address
if the user has not specified an explicit one.

First, if the route has an explicit preferred source address
specified, then we use that.

Otherwise we search the route's outgoing interface for a suitable
address.

This search can be precomputed and cached at route insertion time.

The only missing part is that we have to refresh this precomputed
value any time addresses are added or removed from the interface, and
this is accomplished by fib_update_nh_saddrs().

Signed-off-by: David S. Miller <davem@davemloft.net>
---
 include/net/ip_fib.h     |    7 +++++--
 net/ipv4/fib_frontend.c  |    2 ++
 net/ipv4/fib_semantics.c |   31 ++++++++++++++++++++++++-------
 3 files changed, 31 insertions(+), 9 deletions(-)

diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 523a170..0e14083 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -60,6 +60,7 @@ struct fib_nh {
 #endif
 	int			nh_oif;
 	__be32			nh_gw;
+	__be32			nh_saddr;
 };
 
 /*
@@ -139,11 +140,13 @@ struct fib_result_nl {
 
 #endif /* CONFIG_IP_ROUTE_MULTIPATH */
 
-#define FIB_RES_PREFSRC(res)		((res).fi->fib_prefsrc ? : __fib_res_prefsrc(&res))
+#define FIB_RES_SADDR(res)		(FIB_RES_NH(res).nh_saddr)
 #define FIB_RES_GW(res)			(FIB_RES_NH(res).nh_gw)
 #define FIB_RES_DEV(res)		(FIB_RES_NH(res).nh_dev)
 #define FIB_RES_OIF(res)		(FIB_RES_NH(res).nh_oif)
 
+#define FIB_RES_PREFSRC(res)		((res).fi->fib_prefsrc ? : FIB_RES_SADDR(res))
+
 struct fib_table {
 	struct hlist_node tb_hlist;
 	u32		tb_id;
@@ -224,8 +227,8 @@ extern void fib_select_default(struct fib_result *res);
 extern int ip_fib_check_default(__be32 gw, struct net_device *dev);
 extern int fib_sync_down_dev(struct net_device *dev, int force);
 extern int fib_sync_down_addr(struct net *net, __be32 local);
+extern void fib_update_nh_saddrs(struct net_device *dev);
 extern int fib_sync_up(struct net_device *dev);
-extern __be32  __fib_res_prefsrc(struct fib_result *res);
 extern void fib_select_multipath(const struct flowi *flp, struct fib_result *res);
 
 /* Exported by fib_trie.c */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index ad0778a..1d2233c 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -890,10 +890,12 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 		fib_sync_up(dev);
 #endif
+		fib_update_nh_saddrs(dev);
 		rt_cache_flush(dev_net(dev), -1);
 		break;
 	case NETDEV_DOWN:
 		fib_del_ifaddr(ifa);
+		fib_update_nh_saddrs(dev);
 		if (ifa->ifa_dev->ifa_list == NULL) {
 			/* Last address was deleted from this interface.
 			 * Disable IP.
diff --git a/net/ipv4/fib_semantics.c b/net/ipv4/fib_semantics.c
index 6349a21..952c737 100644
--- a/net/ipv4/fib_semantics.c
+++ b/net/ipv4/fib_semantics.c
@@ -853,6 +853,12 @@ struct fib_info *fib_create_info(struct fib_config *cfg)
 				goto err_inval;
 	}
 
+	change_nexthops(fi) {
+		nexthop_nh->nh_saddr = inet_select_addr(nexthop_nh->nh_dev,
+							nexthop_nh->nh_gw,
+							nexthop_nh->nh_scope);
+	} endfor_nexthops(fi)
+
 link_it:
 	ofi = fib_find_info(fi);
 	if (ofi) {
@@ -898,13 +904,6 @@ failure:
 	return ERR_PTR(err);
 }
 
-/* Find appropriate source address to this destination */
-
-__be32 __fib_res_prefsrc(struct fib_result *res)
-{
-	return inet_select_addr(FIB_RES_DEV(*res), FIB_RES_GW(*res), res->scope);
-}
-
 int fib_dump_info(struct sk_buff *skb, u32 pid, u32 seq, int event,
 		  u32 tb_id, u8 type, u8 scope, __be32 dst, int dst_len, u8 tos,
 		  struct fib_info *fi, unsigned int flags)
@@ -1128,6 +1127,24 @@ out:
 	return;
 }
 
+void fib_update_nh_saddrs(struct net_device *dev)
+{
+	struct hlist_head *head;
+	struct hlist_node *node;
+	struct fib_nh *nh;
+	unsigned int hash;
+
+	hash = fib_devindex_hashfn(dev->ifindex);
+	head = &fib_info_devhash[hash];
+	hlist_for_each_entry(nh, node, head, nh_hash) {
+		if (nh->nh_dev != dev)
+			continue;
+		nh->nh_saddr = inet_select_addr(nh->nh_dev,
+						nh->nh_gw,
+						nh->nh_scope);
+	}
+}
+
 #ifdef CONFIG_IP_ROUTE_MULTIPATH
 
 /*
-- 
1.7.4.1


^ permalink raw reply related

* Re: dccp test-tree [RFC] [Patch 1/1] dccp: Only activate NN values after receiving the Confirm option
From: Samuel Jero @ 2011-03-08  4:50 UTC (permalink / raw)
  To: Gerrit Renker; +Cc: dccp, netdev
In-Reply-To: <20110228112511.GE3620@gerrit.erg.abdn.ac.uk>

[-- Attachment #1: Type: text/plain, Size: 8053 bytes --]

> I am sending this as RFC since I have not yet deeply tested this. It makes
> the exchange of NN options in established state conform to RFC 4340, 6.6.1
> and thus actually is a bug fix.

I now had a chance to put this patch through extensive tests. I had to
modify two things about the patch to get good performance:
1)CCID2 now checks the congestion window against the currently
negotiating ack ratio value to determine whether to change the ack ratio
after an RTO, an idle period, or a loss. This prevents a problem where
an RTO or loss or idle period occurs and the ack ratio is less than the
congestion window but is in the process of being negotiated larger. That
negotiation will reach the sender on the first packet sent and RTOs will
result.
The primary change is adding a function called
dccp_feat_get_nn_next_val() to feat.c. This function returns the value
of the NN feature indicated that is is the process of being negotiated.
If the feature is not being negotiated, then the current value is
returned.
2)In a situation where the ack ratio has to be reduced because of an
RTO, idle period, or loss, CCID2 now sets the ack ratio to half of the
congestion window (or 1 if that's zero) instead of to the congestion
window. This should reduce the problems if one ack is lost (we have to
lose two acks to not acknowledge an entire congestion window and trigger
RTO)

Below is an improved patch. What are your thoughts on these changes?

Samuel Jero
Internetworking Research Group
Ohio University


>>>>>>>>>>>>>>>>>>>>>>>>>Patch<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
dccp: Only activate NN values after receiving the Confirm option

This defers changing local values using exchange of NN options in
established connection state by only activating the value after
receiving the Confirm option, as mandated by RFC 4340, 6.6.1.

Signed-off-by: Samuel Jero
diff --git a/net/dccp/ccids/ccid2.c b/net/dccp/ccids/ccid2.c
--- a/net/dccp/ccids/ccid2.c
+++ b/net/dccp/ccids/ccid2.c
@@ -83,9 +82,13 @@ static int ccid2_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
 	return CCID_PACKET_SEND_AT_ONCE;
 }
 
+static __u64 ccid2_ack_ratio_next(struct sock *sk)
+{
+	return dccp_feat_get_nn_next_val(sk, DCCPF_ACK_RATIO);
+}
+
 static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
 {
-	struct dccp_sock *dp = dccp_sk(sk);
 	u32 max_ratio = DIV_ROUND_UP(ccid2_hc_tx_sk(sk)->tx_cwnd, 2);
 
 	/*
@@ -101,11 +104,10 @@ static void ccid2_change_l_ack_ratio(struct sock *sk, u32 val)
 	if (val > DCCPF_ACK_RATIO_MAX)
 		val = DCCPF_ACK_RATIO_MAX;
 
-	if (val == dp->dccps_l_ack_ratio)
+	if (val == ccid2_ack_ratio_next(sk))
 		return;
 
 	ccid2_pr_debug("changing local ack ratio to %u\n", val);
-	dp->dccps_l_ack_ratio = val;
 	dccp_feat_signal_nn_change(sk, DCCPF_ACK_RATIO, val);
 }
 
@@ -117,11 +119,9 @@ static void ccid2_change_l_seq_window(struct sock *sk, u64 val)
 		val = DCCPF_SEQ_WMIN;
 	if (val > DCCPF_SEQ_WMAX)
 		val = DCCPF_SEQ_WMAX;
-	if (val == dp->dccps_l_seq_win)
-		return;
 
-	dp->dccps_l_seq_win = val;
-	dccp_feat_signal_nn_change(sk, DCCPF_SEQUENCE_WINDOW, val);
+	if (val != dp->dccps_l_seq_win)
+		dccp_feat_signal_nn_change(sk, DCCPF_SEQUENCE_WINDOW, val);
 }
 
 static void ccid2_hc_tx_rto_expire(unsigned long data)
@@ -203,6 +203,10 @@ static void ccid2_cwnd_application_limited(struct sock *sk, const u32 now)
 	}
 	hc->tx_cwnd_used  = 0;
 	hc->tx_cwnd_stamp = now;
+
+	/* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
+	if (ccid2_ack_ratio_next(sk) > hc->tx_cwnd)
+		ccid2_change_l_ack_ratio(sk, hc->tx_cwnd/2 ? : 1U);
 }
 
 /* This borrows the code of tcp_cwnd_restart() */
@@ -221,6 +225,10 @@ static void ccid2_cwnd_restart(struct sock *sk, const u32 now)
 
 	hc->tx_cwnd_stamp = now;
 	hc->tx_cwnd_used  = 0;
+
+	/* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
+	if (ccid2_ack_ratio_next(sk) > hc->tx_cwnd)
+		ccid2_change_l_ack_ratio(sk, hc->tx_cwnd/2 ? : 1U);
 }
 
 static void ccid2_hc_tx_packet_sent(struct sock *sk, unsigned int len)
@@ -491,8 +531,8 @@ static void ccid2_congestion_event(struct sock *sk, struct ccid2_seq *seqp)
 	hc->tx_ssthresh  = max(hc->tx_cwnd, 2U);
 
 	/* Avoid spurious timeouts resulting from Ack Ratio > cwnd */
-	if (dccp_sk(sk)->dccps_l_ack_ratio > hc->tx_cwnd)
-		ccid2_change_l_ack_ratio(sk, hc->tx_cwnd);
+	if (ccid2_ack_ratio_next(sk) > hc->tx_cwnd)
+		ccid2_change_l_ack_ratio(sk, hc->tx_cwnd/2 ? : 1U);
 }
 
 static int ccid2_hc_tx_parse_options(struct sock *sk, u8 packet_type,
diff --git a/net/dccp/dccp.h b/net/dccp/dccp.h
index 26cba68..e8cf5a7 100644
--- a/net/dccp/dccp.h
+++ b/net/dccp/dccp.h
@@ -491,6 +491,7 @@ static inline int dccp_ack_pending(const struct sock *sk)
 }
 
 extern int  dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val);
+extern __u64 dccp_feat_get_nn_next_val(struct sock *sk, u8 feat);
 extern int  dccp_feat_finalise_settings(struct dccp_sock *dp);
 extern int  dccp_feat_server_ccid_dependencies(struct dccp_request_sock *dreq);
 extern int  dccp_feat_insert_opts(struct dccp_sock*, struct dccp_request_sock*,
diff --git a/net/dccp/feat.c b/net/dccp/feat.c
index 9a8c2ba..bc26f33 100644
--- a/net/dccp/feat.c
+++ b/net/dccp/feat.c
@@ -775,12 +775,7 @@ int dccp_feat_register_sp(struct sock *sk, u8 feat, u8 is_local,
  * @sk: DCCP socket of an established connection
  * @feat: NN feature number from %dccp_feature_numbers
  * @nn_val: the new value to use
- * This function is used to communicate NN updates out-of-band. The difference
- * to feature negotiation during connection setup is that values are activated
- * immediately after validation, i.e. we don't wait for the Confirm: either the
- * value is accepted by the peer (and then the waiting is futile), or it is not
- * (Reset or empty Confirm). We don't accept empty Confirms - transmitted values
- * are validated, and the peer "MUST accept any valid value" (RFC 4340, 6.3.2).
+ * This function is used to communicate NN updates out-of-band.
  */
 int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val)
 {
@@ -805,9 +800,6 @@ int dccp_feat_signal_nn_change(struct sock *sk, u8 feat, u64 nn_val)
 		dccp_feat_list_pop(entry);
 	}
 
-	if (dccp_feat_activate(sk, feat, 1, &fval))
-		return -EADV;
-
 	inet_csk_schedule_ack(sk);
 	return dccp_feat_push_change(fn, feat, 1, 0, &fval);
 }
@@ -1356,6 +1348,9 @@ static u8 dccp_feat_handle_nn_established(struct sock *sk, u8 mandatory, u8 opt,
 		if (fval.nn != entry->val.nn)
 			return 0;
 
+		/* Only activate after receiving the Confirm option (6.6.1). */
+		dccp_feat_activate(sk, feat, local, &fval);
+
 		/* It has been confirmed - so remove the entry */
 		dccp_feat_list_pop(entry);
 
@@ -1374,6 +1369,39 @@ fast_path_failed:
 			 : DCCP_RESET_CODE_OPTION_ERROR;
 }
 
+/*
+* dccp_feat_get_nn_next_val  -  Get the currently negotiating value of an NN
+*				feature. If the feature isn't being currently
+*				negotiated, return it's current value.
+* @sk: DCCP socket of an established connection
+* @feat: NN feature number from %dccp_feature_numbers
+*/
+__u64 dccp_feat_get_nn_next_val(struct sock *sk, u8 feat)
+{
+	struct list_head *fn = &dccp_sk(sk)->dccps_featneg;
+	struct dccp_feat_entry *entry;
+	u8 type = dccp_feat_type(feat);
+
+	if (type == FEAT_UNKNOWN || type != FEAT_NN)
+		return 0;
+
+	entry = dccp_feat_list_lookup(fn, feat, 1);
+	if (entry != NULL)
+		return entry->val.nn;
+
+	switch (feat) {
+	case DCCPF_ACK_RATIO:
+		return dccp_sk(sk)->dccps_l_ack_ratio;
+	case DCCPF_SEQUENCE_WINDOW:
+		return dccp_sk(sk)->dccps_l_seq_win;
+	default:
+		dccp_pr_debug("Attempting to get value \
+						for unknown NN feature");
+	}
+return 0;
+}
+EXPORT_SYMBOL_GPL(dccp_feat_get_nn_next_val);
+
 /**
  * dccp_feat_parse_options  -  Process Feature-Negotiation Options
  * @sk: for general use and used by the client during connection setup

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 198 bytes --]

^ permalink raw reply related

* Re: [Patch] bonding: fix netpoll in active-backup mode
From: Cong Wang @ 2011-03-08  4:15 UTC (permalink / raw)
  To: Neil Horman
  Cc: linux-kernel, Jay Vosburgh, David S. Miller, Herbert Xu,
	Paul E. McKenney, John W. Linville, Eric Dumazet, netdev
In-Reply-To: <20110307185038.GA31788@hmsreliant.think-freely.org>

于 2011年03月08日 02:50, Neil Horman 写道:
> On Mon, Mar 07, 2011 at 10:11:50PM +0800, Amerigo Wang wrote:
>> netconsole doesn't work in active-backup mode, because we don't do anything
>> for nic failover in active-backup mode. This patch fixes the problem by:
>>
>> 1) make slave_enable_netpoll() and slave_disable_netpoll() callable in softirq
>>     context, that is, moving code after synchronize_rcu_bh() into call_rcu_bh()
>>     callback function, teaching kzalloc() to use GFP_ATOMIC.
>>
>> 2) disable netpoll on old slave and enable netpoll on the new slave.
>>
>> Tested by ifdown the current active slave and ifup it again for several times,
>> netconsole works well.
>>
>> Signed-off-by: WANG Cong<amwang@redhat.com>
>>
> I may be missing soething but this seems way over-complicated to me.  I presume
> the problem is that in active backup mode a failover results in the new active
> slave not having netpoll setup on it?  If thats the case, why not just setup
> netpoll on all slaves when ndo_netpoll_setup is called on the bonding interface?
> I don't see anything immeidately catastrophic that would happen as a result.


But we still need to clean up the netpoll on the failing slave, which still
needs to call slave_disable_netpoll() in monitor code, I see no big differences
with the solution I take.


> And then you wouldn't have to worry about disabling/enabling anything on a
> failover (or during a panic for that matter).  As for the rcu bits?  Why are
> they needed?  One would presume that wouldn't (or at least shouldn't) be able to
> teardown our netpoll setup until such time as all the pending frames for that
> netpoll client have been transmitted.  If we're not blocknig on that RCU isn't
> really going to help.  Seems like the proper fix is take a reference to the
> appropriate npinfo struct in netpoll_send_skb, and drop it from the skbs
> destructor or some such.

I saw a "scheduling while in atomic" warning without touching the rcu bits.

Thanks!

^ permalink raw reply

* linux-next: manual merge of the net tree with the net-current tree
From: Stephen Rothwell @ 2011-03-08  3:09 UTC (permalink / raw)
  To: David Miller, netdev
  Cc: linux-next, linux-kernel, Dmitry Kravkov, Eilon Greenstein,
	Vladislav Zolotarov

Hi all,

Today's linux-next merge of the net tree got a conflict in
drivers/net/bnx2x/bnx2x_cmn.c between commit
e3835b99333eb3ac7222f6fc0af5cae46074ac49 ("bnx2x: (NPAR) prevent HW
access in D3 state") from the net-current tree and commit
6e30dd4e3935ddb4e7dd27d5be7a6e5504e64a27 (bnx2x: Proper
netdev->ndo_set_rx_mode() implementation"") from the net tree.

Just overlapping additions (I think).  I have fixed it up (see below) and
can carry the fix as necessary.
-- 
Cheers,
Stephen Rothwell                    sfr@canb.auug.org.au

diff --cc drivers/net/bnx2x/bnx2x_cmn.c
index a71b329,b01b622..0000000
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@@ -1481,11 -1489,15 +1506,20 @@@ int bnx2x_nic_load(struct bnx2x *bp, in
  
  	bnx2x_set_eth_mac(bp, 1);
  
 +	if (bp->pending_max) {
 +		bnx2x_update_max_mf_config(bp, bp->pending_max);
 +		bp->pending_max = 0;
 +	}
 +
+ 	/* Clear MC configuration */
+ 	if (CHIP_IS_E1(bp))
+ 		bnx2x_invalidate_e1_mc_list(bp);
+ 	else
+ 		bnx2x_invalidate_e1h_mc_list(bp);
+ 
+ 	/* Clear UC lists configuration */
+ 	bnx2x_invalidate_uc_list(bp);
+ 
  	if (bp->port.pmf)
  		bnx2x_initial_phy_init(bp, load_mode);
  

^ permalink raw reply

* RE: [net-next-2.6 05/14] vlan: add support to ndo_fcoe_ddp_target()
From: Zou, Yi @ 2011-03-08  2:51 UTC (permalink / raw)
  To: Ben Hutchings, Kirsher, Jeffrey T
  Cc: davem@davemloft.net, netdev@vger.kernel.org, gospo@redhat.com,
	bphilips@novell.com, Patil, Kiran
In-Reply-To: <1299552267.3967.3.camel@localhost>

> On Mon, 2011-03-07 at 18:24 -0800, Jeff Kirsher wrote:
> > From: Yi Zou <yi.zou@intel.com>
> >
> > Add the new target ddp offload support ndo_fcoe_ddp_target().
> >
> > Signed-off-by: Yi Zou <yi.zou@intel.com>
> > Signed-off-by: Kiran Patil <kiran.patil@intel.com>
> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > ---
> >  net/8021q/vlan_dev.c |   14 ++++++++++++++
> >  1 files changed, 14 insertions(+), 0 deletions(-)
> >
> > diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
> > index be73753..ae610f0 100644
> > --- a/net/8021q/vlan_dev.c
> > +++ b/net/8021q/vlan_dev.c
> > @@ -625,6 +625,19 @@ static int vlan_dev_fcoe_get_wwn(struct net_device
> *dev, u64 *wwn, int type)
> >  		rc = ops->ndo_fcoe_get_wwn(real_dev, wwn, type);
> >  	return rc;
> >  }
> > +
> > +static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid,
> > +				    struct scatterlist *sgl, unsigned int sgc)
> > +{
> > +	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
> > +	const struct net_device_ops *ops = real_dev->netdev_ops;
> > +	int rc = 0;
> > +
> > +	if (ops->ndo_fcoe_ddp_target)
> > +		rc = ops->ndo_fcoe_ddp_target(real_dev, xid, sgl, sgc);
> > +
> > +	return rc;
> > +}
> 
> I can't see a caller or any documentation for this operation, so I don't
> know what the semantics are supposed to be.  But shouldn't the return
> value be -EOPNOTSUPP if real_dev does not implement the operation?
> 
> Ben.
This is similar to existing ndo_fcoe_ddp_setup(), but is for target mode,
the two are the same on semantics, but the LLD implementation will/may
be different depending on the driver as e.g. ,target works on RX_ID where
initiator works on OX_ID. The returning of rc being 0 indicates no DDP
was setup for this fc exchange, not necessarily EOPNOTSUPP.

Thanks,
yi

> 
> >  #endif
> >
> >  static void vlan_dev_change_rx_flags(struct net_device *dev, int
> change)
> > @@ -858,6 +871,7 @@ static const struct net_device_ops vlan_netdev_ops
> = {
> >  	.ndo_fcoe_enable	= vlan_dev_fcoe_enable,
> >  	.ndo_fcoe_disable	= vlan_dev_fcoe_disable,
> >  	.ndo_fcoe_get_wwn	= vlan_dev_fcoe_get_wwn,
> > +	.ndo_fcoe_ddp_target	= vlan_dev_fcoe_ddp_target,
> >  #endif
> >  };
> >
> 
> --
> 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: [net-next-2.6 04/14] net: add ndo_fcoe_ddp_target() to support FCoE DDP in target mode
From: Zou, Yi @ 2011-03-08  2:54 UTC (permalink / raw)
  To: Ben Hutchings, Kirsher, Jeffrey T
  Cc: davem@davemloft.net, netdev@vger.kernel.org, gospo@redhat.com,
	bphilips@novell.com, Patil, Kiran
In-Reply-To: <1299552202.3967.2.camel@localhost>

> On Mon, 2011-03-07 at 18:24 -0800, Jeff Kirsher wrote:
> > From: Yi Zou <yi.zou@intel.com>
> >
> > The Fiber Channel over Ethernet (FCoE) Direct Data Placement (DDP) can
> also be
> > used for FCoE target, where the DDP used for read I/O on an initiator
> can be
> > used on an FCoE target to speed up the write I/O to the target from the
> initiator.
> > The added ndo_fcoe_ddp_target() works in the similar way as the
> existing
> > ndo_fcoe_ddp_setup() to allow the underlying hardware set up the DDP
> context
> > accordingly when it gets called from the FCoE target implementation on
> top
> > the existing Open-FCoE fcoe/libfc protocol stack so without losing the
> ability
> > to provide DDP for read I/O as an initiator, it can also provide DDP
> offload
> > to the write I/O coming from the initiator as a target.
> >
> > Signed-off-by: Yi Zou <yi.zou@intel.com>
> > Signed-off-by: Kiran Patil <kiran.patil@intel.com>
> > Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
> > Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> > ---
> >  include/linux/netdevice.h |    4 ++++
> >  1 files changed, 4 insertions(+), 0 deletions(-)
> >
> > diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> > index 71563e7..6bd5d46 100644
> > --- a/include/linux/netdevice.h
> > +++ b/include/linux/netdevice.h
> > @@ -871,6 +871,10 @@ struct net_device_ops {
> >  						      unsigned int sgc);
> >  	int			(*ndo_fcoe_ddp_done)(struct net_device *dev,
> >  						     u16 xid);
> > +	int			(*ndo_fcoe_ddp_target)(struct net_device *dev,
> > +						       u16 xid,
> > +						       struct scatterlist *sgl,
> > +						       unsigned int sgc);
> 
> This should be described in the comment heading net_device_ops.
> (Really, all the existing FCoE operations ought to have been described
> as well.)
> 
> Ben.
Yes, you are right, it should be. Will it be ok if I send a separate 
patch as follow-up to properly add all comments?

yi

> 
> >  #define NETDEV_FCOE_WWNN 0
> >  #define NETDEV_FCOE_WWPN 1
> >  	int			(*ndo_fcoe_get_wwn)(struct net_device *dev,
> 
> --
> 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: [net-next-2.6 05/14] vlan: add support to ndo_fcoe_ddp_target()
From: Ben Hutchings @ 2011-03-08  2:44 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: davem, Yi Zou, netdev, gospo, bphilips, Kiran Patil
In-Reply-To: <1299551108-23663-6-git-send-email-jeffrey.t.kirsher@intel.com>

On Mon, 2011-03-07 at 18:24 -0800, Jeff Kirsher wrote:
> From: Yi Zou <yi.zou@intel.com>
> 
> Add the new target ddp offload support ndo_fcoe_ddp_target().
> 
> Signed-off-by: Yi Zou <yi.zou@intel.com>
> Signed-off-by: Kiran Patil <kiran.patil@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
>  net/8021q/vlan_dev.c |   14 ++++++++++++++
>  1 files changed, 14 insertions(+), 0 deletions(-)
> 
> diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
> index be73753..ae610f0 100644
> --- a/net/8021q/vlan_dev.c
> +++ b/net/8021q/vlan_dev.c
> @@ -625,6 +625,19 @@ static int vlan_dev_fcoe_get_wwn(struct net_device *dev, u64 *wwn, int type)
>  		rc = ops->ndo_fcoe_get_wwn(real_dev, wwn, type);
>  	return rc;
>  }
> +
> +static int vlan_dev_fcoe_ddp_target(struct net_device *dev, u16 xid,
> +				    struct scatterlist *sgl, unsigned int sgc)
> +{
> +	struct net_device *real_dev = vlan_dev_info(dev)->real_dev;
> +	const struct net_device_ops *ops = real_dev->netdev_ops;
> +	int rc = 0;
> +
> +	if (ops->ndo_fcoe_ddp_target)
> +		rc = ops->ndo_fcoe_ddp_target(real_dev, xid, sgl, sgc);
> +
> +	return rc;
> +}

I can't see a caller or any documentation for this operation, so I don't
know what the semantics are supposed to be.  But shouldn't the return
value be -EOPNOTSUPP if real_dev does not implement the operation?

Ben.

>  #endif
>  
>  static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
> @@ -858,6 +871,7 @@ static const struct net_device_ops vlan_netdev_ops = {
>  	.ndo_fcoe_enable	= vlan_dev_fcoe_enable,
>  	.ndo_fcoe_disable	= vlan_dev_fcoe_disable,
>  	.ndo_fcoe_get_wwn	= vlan_dev_fcoe_get_wwn,
> +	.ndo_fcoe_ddp_target	= vlan_dev_fcoe_ddp_target,
>  #endif
>  };
>  

-- 
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 net-next-2.6] net: reinject arps into bonding slave instead of master
From: Andy Gospodarek @ 2011-03-08  2:43 UTC (permalink / raw)
  To: Nicolas de Pesloüan
  Cc: Andy Gospodarek, Jiri Pirko, netdev, davem, shemminger, kaber,
	fubar, eric.dumazet
In-Reply-To: <4D7565BC.4050201@gmail.com>

On Tue, Mar 08, 2011 at 12:09:48AM +0100, Nicolas de Pesloüan wrote:
>
> After Jiri's last patch series, bond_arp_rcv() is not registered anymore 
> as a protocol handler on bond0, but directly called from inside 
> bond_handle_frame(), through bond->recv_probe.
>
> Because bond_handler_frame() is a rx_handler for the slave interfaces, 
> bond_arp_rcv() is now called at the slave level and not a the master 
> level anymore.
>
> Hence this patch and the reason I thought it should work.
>
> Did you tested this patch with Jiri's previous patches applied before?
>

No, I have not tested them yet.  I looked at this problem first as
Jiri's patch did not fix a regression in code that is actually in
net-next right now.

I don't have a problem with the work you and Jiri are doing on this
latest patch series, but the frequency of patch revisions and now
regressions concerns me.


^ permalink raw reply

* Re: [net-next-2.6 04/14] net: add ndo_fcoe_ddp_target() to support FCoE DDP in target mode
From: Ben Hutchings @ 2011-03-08  2:43 UTC (permalink / raw)
  To: Jeff Kirsher; +Cc: davem, Yi Zou, netdev, gospo, bphilips, Kiran Patil
In-Reply-To: <1299551108-23663-5-git-send-email-jeffrey.t.kirsher@intel.com>

On Mon, 2011-03-07 at 18:24 -0800, Jeff Kirsher wrote:
> From: Yi Zou <yi.zou@intel.com>
> 
> The Fiber Channel over Ethernet (FCoE) Direct Data Placement (DDP) can also be
> used for FCoE target, where the DDP used for read I/O on an initiator can be
> used on an FCoE target to speed up the write I/O to the target from the initiator.
> The added ndo_fcoe_ddp_target() works in the similar way as the existing
> ndo_fcoe_ddp_setup() to allow the underlying hardware set up the DDP context
> accordingly when it gets called from the FCoE target implementation on top
> the existing Open-FCoE fcoe/libfc protocol stack so without losing the ability
> to provide DDP for read I/O as an initiator, it can also provide DDP offload
> to the write I/O coming from the initiator as a target.
> 
> Signed-off-by: Yi Zou <yi.zou@intel.com>
> Signed-off-by: Kiran Patil <kiran.patil@intel.com>
> Tested-by: Kavindya Deegala <kavindya.s.deegala@intel.com>
> Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
>  include/linux/netdevice.h |    4 ++++
>  1 files changed, 4 insertions(+), 0 deletions(-)
> 
> diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
> index 71563e7..6bd5d46 100644
> --- a/include/linux/netdevice.h
> +++ b/include/linux/netdevice.h
> @@ -871,6 +871,10 @@ struct net_device_ops {
>  						      unsigned int sgc);
>  	int			(*ndo_fcoe_ddp_done)(struct net_device *dev,
>  						     u16 xid);
> +	int			(*ndo_fcoe_ddp_target)(struct net_device *dev,
> +						       u16 xid,
> +						       struct scatterlist *sgl,
> +						       unsigned int sgc);

This should be described in the comment heading net_device_ops.
(Really, all the existing FCoE operations ought to have been described
as well.)

Ben.

>  #define NETDEV_FCOE_WWNN 0
>  #define NETDEV_FCOE_WWPN 1
>  	int			(*ndo_fcoe_get_wwn)(struct net_device *dev,

-- 
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: [net-next 08/12] ixgb: convert to new VLAN model
From: Jeff Kirsher @ 2011-03-08  2:30 UTC (permalink / raw)
  To: Jesse Gross
  Cc: Tantilov, Emil S, davem@davemloft.net, netdev@vger.kernel.org,
	bphilips@novell.com, Pieper, Jeffrey E, Ben Hutchings
In-Reply-To: <AANLkTikkMTv4uCbpOFfdgHzt2jMa5u5ipCOQ3OOh3KLs@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 3131 bytes --]

On Mon, 2011-03-07 at 17:31 -0800, Jesse Gross wrote:
> On Tue, Jan 25, 2011 at 10:20 AM, Tantilov, Emil S
> <emil.s.tantilov@intel.com> wrote:
> >>-----Original Message-----
> >>From: Jesse Gross [mailto:jesse@nicira.com]
> >>Sent: Tuesday, January 25, 2011 9:23 AM
> >>To: Tantilov, Emil S
> >>Cc: Kirsher, Jeffrey T; davem@davemloft.net; netdev@vger.kernel.org;
> >>bphilips@novell.com; Pieper, Jeffrey E
> >>Subject: Re: [net-next 08/12] ixgb: convert to new VLAN model
> >>
> >>On Sun, Jan 23, 2011 at 4:25 PM, Tantilov, Emil S
> >><emil.s.tantilov@intel.com> wrote:
> >>> Jesse Gross wrote:
> >>>> On Thu, Jan 6, 2011 at 7:29 PM,  <jeffrey.t.kirsher@intel.com> wrote:
> >>>>> +static int ixgb_set_flags(struct net_device *netdev, u32 data) +{
> >>>>> +       struct ixgb_adapter *adapter = netdev_priv(netdev); +
> >>>>> bool need_reset; +       int rc;
> >>>>> +
> >>>>> +       /*
> >>>>> +        * TX vlan insertion does not work per HW design when Rx
> >>>>> stripping is +        * disabled.  Disable txvlan when rxvlan is
> >>>>> off. +        */ +       if ((data & ETH_FLAG_RXVLAN) !=
> >>>>> (netdev->features & NETIF_F_HW_VLAN_RX)) +               data ^=
> >>>>> ETH_FLAG_TXVLAN;
> >>>>
> >>>> Does this really do the right thing?  If the RX vlan setting is
> >>>> changed, it will do the opposite of what the user requested for TX
> >>>> vlan?
> >>>>
> >>>> So if I start with both on (the default) and turn them both off in one
> >>>> command (a valid setting), I will get RX off and TX on (an invalid
> >>>> setting).
> >>>>
> >>>> Why not:
> >>>>
> >>>> if (!(data & ETH_FLAG_RXVLAN))
> >>>>         data &= ~ETH_FLAG_TXVLAN;
> >>>
> >>> Yeah that works for disabling rxvlan, but what if rxvlan is disabled, and
> >>the user attempts to enable txvlan? At least our validation argued that we
> >>should make it work both ways. Perhaps something like the following?
> >>>
> >>>        if (!(data & ETH_FLAG_RXVLAN) &&
> >>>           (netdev->features & NETIF_F_HW_VLAN_TX))
> >>>                data &= ~ETH_FLAG_TXVLAN;
> >>>        else if (data & ETH_FLAG_TXVLAN)
> >>>                data |= ETH_FLAG_RXVLAN;
> >>
> >>I think the logic above does what you describe and will always result
> >>in a consistent state.  Turning dependent features on when needed is a
> >>little bit inconsistent with the rest of Ethtool (for example, turning
> >>on TSO when checksum offloading is off will not enable checksum
> >>offloading, it will produce an error).  However, I know that drivers
> >
> > That is the reason I asked, as I don't want to keep bouncing the patch back and forth. Personally I like the idea of helping the user and adjusting the flags to something that works rather than a generic error message.
> 
> Were you able to take a look at this?  I think that we have something
> that is pretty close, so it would be nice to wrap it up.

I have a patch which has passed testing from Emil, I just need to check
with Emil that the current patch I have ready to push is the "latest"
version and does not need any more tweaks.

Cheers,
Jeff

[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

^ permalink raw reply

* [net-next-2.6 07/14] ixgbe: cleanup PHY init
From: Jeff Kirsher @ 2011-03-08  2:25 UTC (permalink / raw)
  To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299551108-23663-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Emil Tantilov <emil.s.tantilov@intel.com>

This change cleans up several situations in which we were either stepping
over possible errors, or calling initialization routines multiple times.
Also includes whitespace fixes where applicable.

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe_82598.c |   31 ++++++++--
 drivers/net/ixgbe/ixgbe_82599.c |  121 +++++++++++++++++++++++----------------
 drivers/net/ixgbe/ixgbe_phy.c   |   21 ++++++-
 3 files changed, 114 insertions(+), 59 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_82598.c b/drivers/net/ixgbe/ixgbe_82598.c
index fc41329..dc977b1 100644
--- a/drivers/net/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ixgbe/ixgbe_82598.c
@@ -280,10 +280,22 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
 {
 	enum ixgbe_media_type media_type;
 
+	/* Detect if there is a copper PHY attached. */
+	switch (hw->phy.type) {
+	case ixgbe_phy_cu_unknown:
+	case ixgbe_phy_tn:
+	case ixgbe_phy_aq:
+		media_type = ixgbe_media_type_copper;
+		goto out;
+	default:
+		break;
+	}
+
 	/* Media type for I82598 is based on device ID */
 	switch (hw->device_id) {
 	case IXGBE_DEV_ID_82598:
 	case IXGBE_DEV_ID_82598_BX:
+		/* Default device ID is mezzanine card KX/KX4 */
 		media_type = ixgbe_media_type_backplane;
 		break;
 	case IXGBE_DEV_ID_82598AF_DUAL_PORT:
@@ -306,7 +318,7 @@ static enum ixgbe_media_type ixgbe_get_media_type_82598(struct ixgbe_hw *hw)
 		media_type = ixgbe_media_type_unknown;
 		break;
 	}
-
+out:
 	return media_type;
 }
 
@@ -632,7 +644,7 @@ out:
  *  @hw: pointer to hardware structure
  *  @speed: new link speed
  *  @autoneg: true if auto-negotiation enabled
- *  @autoneg_wait_to_complete: true if waiting is needed to complete
+ *  @autoneg_wait_to_complete: true when waiting for completion is needed
  *
  *  Set the link speed in the AUTOC register and restarts link.
  **/
@@ -671,7 +683,8 @@ static s32 ixgbe_setup_mac_link_82598(struct ixgbe_hw *hw,
 		 * ixgbe_hw This will write the AUTOC register based on the new
 		 * stored values
 		 */
-		status = ixgbe_start_mac_link_82598(hw, autoneg_wait_to_complete);
+		status = ixgbe_start_mac_link_82598(hw,
+						    autoneg_wait_to_complete);
 	}
 
 	return status;
@@ -1090,10 +1103,12 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
 
 	/* Copper PHY must be checked before AUTOC LMS to determine correct
 	 * physical layer because 10GBase-T PHYs use LMS = KX4/KX */
-	if (hw->phy.type == ixgbe_phy_tn ||
-	    hw->phy.type == ixgbe_phy_cu_unknown) {
-		hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE, MDIO_MMD_PMAPMD,
-				     &ext_ability);
+	switch (hw->phy.type) {
+	case ixgbe_phy_tn:
+	case ixgbe_phy_aq:
+	case ixgbe_phy_cu_unknown:
+		hw->phy.ops.read_reg(hw, MDIO_PMA_EXTABLE,
+		MDIO_MMD_PMAPMD, &ext_ability);
 		if (ext_ability & MDIO_PMA_EXTABLE_10GBT)
 			physical_layer |= IXGBE_PHYSICAL_LAYER_10GBASE_T;
 		if (ext_ability & MDIO_PMA_EXTABLE_1000BT)
@@ -1101,6 +1116,8 @@ static u32 ixgbe_get_supported_physical_layer_82598(struct ixgbe_hw *hw)
 		if (ext_ability & MDIO_PMA_EXTABLE_100BTX)
 			physical_layer |= IXGBE_PHYSICAL_LAYER_100BASE_TX;
 		goto out;
+	default:
+		break;
 	}
 
 	switch (autoc & IXGBE_AUTOC_LMS_MASK) {
diff --git a/drivers/net/ixgbe/ixgbe_82599.c b/drivers/net/ixgbe/ixgbe_82599.c
index 5ef968a..2f8b9f4 100644
--- a/drivers/net/ixgbe/ixgbe_82599.c
+++ b/drivers/net/ixgbe/ixgbe_82599.c
@@ -470,8 +470,6 @@ static void ixgbe_enable_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
  **/
 static void ixgbe_flap_tx_laser_multispeed_fiber(struct ixgbe_hw *hw)
 {
-	hw_dbg(hw, "ixgbe_flap_tx_laser_multispeed_fiber\n");
-
 	if (hw->mac.autotry_restart) {
 		ixgbe_disable_tx_laser_multispeed_fiber(hw);
 		ixgbe_enable_tx_laser_multispeed_fiber(hw);
@@ -494,17 +492,21 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
                                           bool autoneg_wait_to_complete)
 {
 	s32 status = 0;
-	ixgbe_link_speed phy_link_speed;
+	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
 	ixgbe_link_speed highest_link_speed = IXGBE_LINK_SPEED_UNKNOWN;
 	u32 speedcnt = 0;
 	u32 esdp_reg = IXGBE_READ_REG(hw, IXGBE_ESDP);
+	u32 i = 0;
 	bool link_up = false;
 	bool negotiation;
-	int i;
 
 	/* Mask off requested but non-supported speeds */
-	hw->mac.ops.get_link_capabilities(hw, &phy_link_speed, &negotiation);
-	speed &= phy_link_speed;
+	status = hw->mac.ops.get_link_capabilities(hw, &link_speed,
+						   &negotiation);
+	if (status != 0)
+		return status;
+
+	speed &= link_speed;
 
 	/*
 	 * Try each speed one by one, highest priority first.  We do this in
@@ -515,9 +517,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 		highest_link_speed = IXGBE_LINK_SPEED_10GB_FULL;
 
 		/* If we already have link at this speed, just jump out */
-		hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+		status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
+						false);
+		if (status != 0)
+			return status;
 
-		if ((phy_link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
+		if ((link_speed == IXGBE_LINK_SPEED_10GB_FULL) && link_up)
 			goto out;
 
 		/* Set the module link speed */
@@ -529,9 +534,9 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 		msleep(40);
 
 		status = ixgbe_setup_mac_link_82599(hw,
-		                               IXGBE_LINK_SPEED_10GB_FULL,
-		                               autoneg,
-		                               autoneg_wait_to_complete);
+						    IXGBE_LINK_SPEED_10GB_FULL,
+						    autoneg,
+						    autoneg_wait_to_complete);
 		if (status != 0)
 			return status;
 
@@ -548,8 +553,11 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 			msleep(100);
 
 			/* If we have link, just jump out */
-			hw->mac.ops.check_link(hw, &phy_link_speed,
-			                       &link_up, false);
+			status = hw->mac.ops.check_link(hw, &link_speed,
+							&link_up, false);
+			if (status != 0)
+				return status;
+
 			if (link_up)
 				goto out;
 		}
@@ -561,9 +569,12 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 			highest_link_speed = IXGBE_LINK_SPEED_1GB_FULL;
 
 		/* If we already have link at this speed, just jump out */
-		hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+		status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
+						false);
+		if (status != 0)
+			return status;
 
-		if ((phy_link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
+		if ((link_speed == IXGBE_LINK_SPEED_1GB_FULL) && link_up)
 			goto out;
 
 		/* Set the module link speed */
@@ -576,9 +587,9 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 		msleep(40);
 
 		status = ixgbe_setup_mac_link_82599(hw,
-		                                      IXGBE_LINK_SPEED_1GB_FULL,
-		                                      autoneg,
-		                                      autoneg_wait_to_complete);
+						    IXGBE_LINK_SPEED_1GB_FULL,
+						    autoneg,
+						    autoneg_wait_to_complete);
 		if (status != 0)
 			return status;
 
@@ -589,7 +600,11 @@ s32 ixgbe_setup_mac_link_multispeed_fiber(struct ixgbe_hw *hw,
 		msleep(100);
 
 		/* If we have link, just jump out */
-		hw->mac.ops.check_link(hw, &phy_link_speed, &link_up, false);
+		status = hw->mac.ops.check_link(hw, &link_speed, &link_up,
+						false);
+		if (status != 0)
+			return status;
+
 		if (link_up)
 			goto out;
 	}
@@ -632,13 +647,10 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 				     bool autoneg_wait_to_complete)
 {
 	s32 status = 0;
-	ixgbe_link_speed link_speed;
+	ixgbe_link_speed link_speed = IXGBE_LINK_SPEED_UNKNOWN;
 	s32 i, j;
 	bool link_up = false;
 	u32 autoc_reg = IXGBE_READ_REG(hw, IXGBE_AUTOC);
-	struct ixgbe_adapter *adapter = hw->back;
-
-	hw_dbg(hw, "ixgbe_setup_mac_link_smartspeed.\n");
 
 	 /* Set autoneg_advertised value based on input link speed */
 	hw->phy.autoneg_advertised = 0;
@@ -664,7 +676,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 	for (j = 0; j < IXGBE_SMARTSPEED_MAX_RETRIES; j++) {
 		status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
 						    autoneg_wait_to_complete);
-		if (status)
+		if (status != 0)
 			goto out;
 
 		/*
@@ -677,8 +689,11 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 			mdelay(100);
 
 			/* If we have link, just jump out */
-			hw->mac.ops.check_link(hw, &link_speed,
-			                       &link_up, false);
+			status = hw->mac.ops.check_link(hw, &link_speed,
+							&link_up, false);
+			if (status != 0)
+				goto out;
+
 			if (link_up)
 				goto out;
 		}
@@ -696,7 +711,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 	hw->phy.smart_speed_active = true;
 	status = ixgbe_setup_mac_link_82599(hw, speed, autoneg,
 					    autoneg_wait_to_complete);
-	if (status)
+	if (status != 0)
 		goto out;
 
 	/*
@@ -709,8 +724,11 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 		mdelay(100);
 
 		/* If we have link, just jump out */
-		hw->mac.ops.check_link(hw, &link_speed,
-		                       &link_up, false);
+		status = hw->mac.ops.check_link(hw, &link_speed,
+						&link_up, false);
+		if (status != 0)
+			goto out;
+
 		if (link_up)
 			goto out;
 	}
@@ -722,7 +740,7 @@ static s32 ixgbe_setup_mac_link_smartspeed(struct ixgbe_hw *hw,
 
 out:
 	if (link_up && (link_speed == IXGBE_LINK_SPEED_1GB_FULL))
-		e_info(hw, "Smartspeed has downgraded the link speed from "
+		hw_dbg(hw, "Smartspeed has downgraded the link speed from "
 		       "the maximum advertised\n");
 	return status;
 }
@@ -883,7 +901,7 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
 
 	/* PHY ops must be identified and initialized prior to reset */
 
-	/* Init PHY and function pointers, perform SFP setup */
+	/* Identify PHY and related function pointers */
 	status = hw->phy.ops.init(hw);
 
 	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
@@ -895,6 +913,9 @@ static s32 ixgbe_reset_hw_82599(struct ixgbe_hw *hw)
 		hw->phy.sfp_setup_needed = false;
 	}
 
+	if (status == IXGBE_ERR_SFP_NOT_SUPPORTED)
+		goto reset_hw_out;
+
 	/* Reset PHY */
 	if (hw->phy.reset_disable == false && hw->phy.ops.reset != NULL)
 		hw->phy.ops.reset(hw);
@@ -2051,28 +2072,28 @@ static struct ixgbe_mac_operations mac_ops_82599 = {
 };
 
 static struct ixgbe_eeprom_operations eeprom_ops_82599 = {
-	.init_params            = &ixgbe_init_eeprom_params_generic,
-	.read                   = &ixgbe_read_eerd_generic,
-	.write                  = &ixgbe_write_eeprom_generic,
-	.calc_checksum          = &ixgbe_calc_eeprom_checksum_generic,
-	.validate_checksum      = &ixgbe_validate_eeprom_checksum_generic,
-	.update_checksum        = &ixgbe_update_eeprom_checksum_generic,
+	.init_params		= &ixgbe_init_eeprom_params_generic,
+	.read			= &ixgbe_read_eerd_generic,
+	.write			= &ixgbe_write_eeprom_generic,
+	.calc_checksum		= &ixgbe_calc_eeprom_checksum_generic,
+	.validate_checksum	= &ixgbe_validate_eeprom_checksum_generic,
+	.update_checksum	= &ixgbe_update_eeprom_checksum_generic,
 };
 
 static struct ixgbe_phy_operations phy_ops_82599 = {
-	.identify               = &ixgbe_identify_phy_82599,
-	.identify_sfp           = &ixgbe_identify_sfp_module_generic,
-	.init			            = &ixgbe_init_phy_ops_82599,
-	.reset                  = &ixgbe_reset_phy_generic,
-	.read_reg               = &ixgbe_read_phy_reg_generic,
-	.write_reg              = &ixgbe_write_phy_reg_generic,
-	.setup_link             = &ixgbe_setup_phy_link_generic,
-	.setup_link_speed       = &ixgbe_setup_phy_link_speed_generic,
-	.read_i2c_byte          = &ixgbe_read_i2c_byte_generic,
-	.write_i2c_byte         = &ixgbe_write_i2c_byte_generic,
-	.read_i2c_eeprom        = &ixgbe_read_i2c_eeprom_generic,
-	.write_i2c_eeprom       = &ixgbe_write_i2c_eeprom_generic,
-	.check_overtemp         = &ixgbe_tn_check_overtemp,
+	.identify		= &ixgbe_identify_phy_82599,
+	.identify_sfp		= &ixgbe_identify_sfp_module_generic,
+	.init			= &ixgbe_init_phy_ops_82599,
+	.reset			= &ixgbe_reset_phy_generic,
+	.read_reg		= &ixgbe_read_phy_reg_generic,
+	.write_reg		= &ixgbe_write_phy_reg_generic,
+	.setup_link		= &ixgbe_setup_phy_link_generic,
+	.setup_link_speed	= &ixgbe_setup_phy_link_speed_generic,
+	.read_i2c_byte		= &ixgbe_read_i2c_byte_generic,
+	.write_i2c_byte		= &ixgbe_write_i2c_byte_generic,
+	.read_i2c_eeprom	= &ixgbe_read_i2c_eeprom_generic,
+	.write_i2c_eeprom	= &ixgbe_write_i2c_eeprom_generic,
+	.check_overtemp		= &ixgbe_tn_check_overtemp,
 };
 
 struct ixgbe_info ixgbe_82599_info = {
diff --git a/drivers/net/ixgbe/ixgbe_phy.c b/drivers/net/ixgbe/ixgbe_phy.c
index 197230b..9190a8f 100644
--- a/drivers/net/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ixgbe/ixgbe_phy.c
@@ -57,6 +57,7 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
 {
 	s32 status = IXGBE_ERR_PHY_ADDR_INVALID;
 	u32 phy_addr;
+	u16 ext_ability = 0;
 
 	if (hw->phy.type == ixgbe_phy_unknown) {
 		for (phy_addr = 0; phy_addr < IXGBE_MAX_PHY_ADDR; phy_addr++) {
@@ -65,12 +66,29 @@ s32 ixgbe_identify_phy_generic(struct ixgbe_hw *hw)
 				ixgbe_get_phy_id(hw);
 				hw->phy.type =
 				        ixgbe_get_phy_type_from_id(hw->phy.id);
+
+				if (hw->phy.type == ixgbe_phy_unknown) {
+					hw->phy.ops.read_reg(hw,
+							     MDIO_PMA_EXTABLE,
+							     MDIO_MMD_PMAPMD,
+							     &ext_ability);
+					if (ext_ability &
+					    (MDIO_PMA_EXTABLE_10GBT |
+					     MDIO_PMA_EXTABLE_1000BT))
+						hw->phy.type =
+							 ixgbe_phy_cu_unknown;
+					else
+						hw->phy.type =
+							 ixgbe_phy_generic;
+				}
+
 				status = 0;
 				break;
 			}
 		}
 		/* clear value if nothing found */
-		hw->phy.mdio.prtad = 0;
+		if (status != 0)
+			hw->phy.mdio.prtad = 0;
 	} else {
 		status = 0;
 	}
@@ -823,7 +841,6 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
 			goto out;
 		}
 
-		/* This is guaranteed to be 82599, no need to check for NULL */
 		hw->mac.ops.get_device_caps(hw, &enforce_sfp);
 		if (!(enforce_sfp & IXGBE_DEVICE_CAPS_ALLOW_ANY_SFP) &&
 		    !((hw->phy.sfp_type == ixgbe_sfp_type_1g_cu_core0) ||
-- 
1.7.4


^ permalink raw reply related

* [net-next-2.6 14/14] ixgbe: fix setting and reporting of advertised speeds
From: Jeff Kirsher @ 2011-03-08  2:25 UTC (permalink / raw)
  To: davem; +Cc: Emil Tantilov, netdev, gospo, bphilips, Jeff Kirsher
In-Reply-To: <1299551108-23663-1-git-send-email-jeffrey.t.kirsher@intel.com>

From: Emil Tantilov <emil.s.tantilov@intel.com>

Add the ability to set 100/F on x540.
Fix reporting of advertised modes by adding check for phy.autoneg_advertised

Signed-off-by: Emil Tantilov <emil.s.tantilov@intel.com>
Tested-by: Stephen Ko <stephen.s.ko@intel.com>
Signed-off-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
---
 drivers/net/ixgbe/ixgbe_ethtool.c |   41 ++++++++++++++++++-------------------
 1 files changed, 20 insertions(+), 21 deletions(-)

diff --git a/drivers/net/ixgbe/ixgbe_ethtool.c b/drivers/net/ixgbe/ixgbe_ethtool.c
index 83511c0..76380a2 100644
--- a/drivers/net/ixgbe/ixgbe_ethtool.c
+++ b/drivers/net/ixgbe/ixgbe_ethtool.c
@@ -161,29 +161,25 @@ static int ixgbe_get_settings(struct net_device *netdev,
 		}
 
 		ecmd->advertising = ADVERTISED_Autoneg;
-		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_100_FULL)
-			ecmd->advertising |= ADVERTISED_100baseT_Full;
-		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_10GB_FULL)
-			ecmd->advertising |= ADVERTISED_10000baseT_Full;
-		if (hw->phy.autoneg_advertised & IXGBE_LINK_SPEED_1GB_FULL)
-			ecmd->advertising |= ADVERTISED_1000baseT_Full;
-		/*
-		 * It's possible that phy.autoneg_advertised may not be
-		 * set yet.  If so display what the default would be -
-		 * both 1G and 10G supported.
-		 */
-		if (!(ecmd->advertising & (ADVERTISED_1000baseT_Full |
-					   ADVERTISED_10000baseT_Full)))
+		if (hw->phy.autoneg_advertised) {
+			if (hw->phy.autoneg_advertised &
+			    IXGBE_LINK_SPEED_100_FULL)
+				ecmd->advertising |= ADVERTISED_100baseT_Full;
+			if (hw->phy.autoneg_advertised &
+			    IXGBE_LINK_SPEED_10GB_FULL)
+				ecmd->advertising |= ADVERTISED_10000baseT_Full;
+			if (hw->phy.autoneg_advertised &
+			    IXGBE_LINK_SPEED_1GB_FULL)
+				ecmd->advertising |= ADVERTISED_1000baseT_Full;
+		} else {
+			/*
+			 * Default advertised modes in case
+			 * phy.autoneg_advertised isn't set.
+			 */
 			ecmd->advertising |= (ADVERTISED_10000baseT_Full |
 					      ADVERTISED_1000baseT_Full);
-
-		switch (hw->mac.type) {
-		case ixgbe_mac_X540:
-			if (!(ecmd->advertising & ADVERTISED_100baseT_Full))
-				ecmd->advertising |= (ADVERTISED_100baseT_Full);
-			break;
-		default:
-			break;
+			if (hw->mac.type == ixgbe_mac_X540)
+				ecmd->advertising |= ADVERTISED_100baseT_Full;
 		}
 
 		if (hw->phy.media_type == ixgbe_media_type_copper) {
@@ -336,6 +332,9 @@ static int ixgbe_set_settings(struct net_device *netdev,
 		if (ecmd->advertising & ADVERTISED_1000baseT_Full)
 			advertised |= IXGBE_LINK_SPEED_1GB_FULL;
 
+		if (ecmd->advertising & ADVERTISED_100baseT_Full)
+			advertised |= IXGBE_LINK_SPEED_100_FULL;
+
 		if (old == advertised)
 			return err;
 		/* this sets the link speed and restarts auto-neg */
-- 
1.7.4


^ permalink raw reply related


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