* [PATCH 1/2] net/r8169: adjust rtl8169_set_speed_xmii function
From: Hayes Wang @ 2011-02-22 9:26 UTC (permalink / raw)
To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
Adjust code of rtl8169_set_speed_xmii function and remove part
codes which have done in rtl_pll_power_up function.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/r8169.c | 16 ++--------------
1 files changed, 2 insertions(+), 14 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 469ab0b..de94489 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1124,6 +1124,8 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
struct rtl8169_private *tp = netdev_priv(dev);
int giga_ctrl, bmcr;
+ rtl_writephy(tp, 0x1f, 0x0000);
+
if (autoneg == AUTONEG_ENABLE) {
int auto_nego;
@@ -1152,18 +1154,6 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
bmcr = BMCR_ANENABLE | BMCR_ANRESTART;
- if ((tp->mac_version == RTL_GIGA_MAC_VER_11) ||
- (tp->mac_version == RTL_GIGA_MAC_VER_12) ||
- (tp->mac_version >= RTL_GIGA_MAC_VER_17)) {
- /*
- * Wake up the PHY.
- * Vendor specific (0x1f) and reserved (0x0e) MII
- * registers.
- */
- rtl_writephy(tp, 0x1f, 0x0000);
- rtl_writephy(tp, 0x0e, 0x0000);
- }
-
rtl_writephy(tp, MII_ADVERTISE, auto_nego);
rtl_writephy(tp, MII_CTRL1000, giga_ctrl);
} else {
@@ -1178,8 +1168,6 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
if (duplex == DUPLEX_FULL)
bmcr |= BMCR_FULLDPLX;
-
- rtl_writephy(tp, 0x1f, 0x0000);
}
tp->phy_1000_ctrl_reg = giga_ctrl;
--
1.7.3.2
^ permalink raw reply related
* [PATCH 1/3] net/r8169: Correct settings of rtl8102e
From: Hayes Wang @ 2011-02-22 9:26 UTC (permalink / raw)
To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1298366782-1508-1-git-send-email-hayeswang@realtek.com>
Adjust and remove certain settings of RTL8102E which are for previous chips.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/r8169.c | 20 ++++++--------------
1 files changed, 6 insertions(+), 14 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 469ab0b..3630dd7 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3042,7 +3042,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_mwi_2;
}
- tp->cp_cmd = PCIMulRW | RxChkSum;
+ tp->cp_cmd = RxChkSum;
if ((sizeof(dma_addr_t) > 4) &&
!pci_set_dma_mask(pdev, DMA_BIT_MASK(64)) && use_dac) {
@@ -3847,8 +3847,7 @@ static void rtl_hw_start_8168(struct net_device *dev)
Cxpl_dbg_sel | \
ASF | \
PktCntrDisable | \
- PCIDAC | \
- PCIMulRW)
+ Mac_dbgo_sel)
static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
{
@@ -3878,8 +3877,6 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
if ((cfg1 & LEDS0) && (cfg1 & LEDS1))
RTL_W8(Config1, cfg1 & ~LEDS0);
- RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
-
rtl_ephy_init(ioaddr, e_info_8102e_1, ARRAY_SIZE(e_info_8102e_1));
}
@@ -3891,8 +3888,6 @@ static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
RTL_W8(Config1, MEMMAP | IOMAP | VPD | PMEnable);
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
-
- RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R810X_CPCMD_QUIRK_MASK);
}
static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
@@ -3918,6 +3913,8 @@ static void rtl_hw_start_8101(struct net_device *dev)
}
}
+ RTL_W8(Cfg9346, Cfg9346_Unlock);
+
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_07:
rtl_hw_start_8102e_1(ioaddr, pdev);
@@ -3932,14 +3929,13 @@ static void rtl_hw_start_8101(struct net_device *dev)
break;
}
- RTL_W8(Cfg9346, Cfg9346_Unlock);
+ RTL_W8(Cfg9346, Cfg9346_Lock);
RTL_W8(MaxTxPacketSize, TxPacketMax);
rtl_set_rx_max_size(ioaddr, rx_buf_sz);
- tp->cp_cmd |= rtl_rw_cpluscmd(ioaddr) | PCIMulRW;
-
+ tp->cp_cmd &= ~R810X_CPCMD_QUIRK_MASK;
RTL_W16(CPlusCmd, tp->cp_cmd);
RTL_W16(IntrMitigate, 0x0000);
@@ -3949,14 +3945,10 @@ static void rtl_hw_start_8101(struct net_device *dev)
RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
rtl_set_rx_tx_config_registers(tp);
- RTL_W8(Cfg9346, Cfg9346_Lock);
-
RTL_R8(IntrMask);
rtl_set_rx_mode(dev);
- RTL_W8(ChipCmd, CmdTxEnb | CmdRxEnb);
-
RTL_W16(MultiIntr, RTL_R16(MultiIntr) & 0xf000);
RTL_W16(IntrMask, tp->intr_event);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 2/2] net/r8169: Support RTL8105E
From: Hayes Wang @ 2011-02-22 9:26 UTC (permalink / raw)
To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1298366782-1508-1-git-send-email-hayeswang@realtek.com>
Support the new chips for RTL8105E
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/r8169.c | 92 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 90 insertions(+), 2 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index de94489..2543edd 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -36,6 +36,7 @@
#define FIRMWARE_8168D_1 "rtl_nic/rtl8168d-1.fw"
#define FIRMWARE_8168D_2 "rtl_nic/rtl8168d-2.fw"
+#define FIRMWARE_8105E_1 "rtl_nic/rtl8105e-1.fw"
#ifdef RTL8169_DEBUG
#define assert(expr) \
@@ -123,6 +124,8 @@ enum mac_version {
RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP
RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP
+ RTL_GIGA_MAC_VER_29 = 0x1d, // 8105E
+ RTL_GIGA_MAC_VER_30 = 0x1e, // 8105E
};
#define _R(NAME,MAC,MASK) \
@@ -160,7 +163,9 @@ static const struct {
_R("RTL8168d/8111d", RTL_GIGA_MAC_VER_25, 0xff7e1880), // PCI-E
_R("RTL8168d/8111d", RTL_GIGA_MAC_VER_26, 0xff7e1880), // PCI-E
_R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_27, 0xff7e1880), // PCI-E
- _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880) // PCI-E
+ _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880), // PCI-E
+ _R("RTL8105e", RTL_GIGA_MAC_VER_29, 0xff7e1880), // PCI-E
+ _R("RTL8105e", RTL_GIGA_MAC_VER_30, 0xff7e1880) // PCI-E
};
#undef _R
@@ -267,9 +272,15 @@ enum rtl8168_8101_registers {
#define EPHYAR_REG_MASK 0x1f
#define EPHYAR_REG_SHIFT 16
#define EPHYAR_DATA_MASK 0xffff
+ DLLPR = 0xd0,
+#define PM_SWITCH (1 << 6)
DBG_REG = 0xd1,
#define FIX_NAK_1 (1 << 4)
#define FIX_NAK_2 (1 << 3)
+ TWSI = 0xd2,
+ MCU = 0xd3,
+#define EN_NDP (1 << 3)
+#define EN_OOB_RESET (1 << 2)
EFUSEAR = 0xdc,
#define EFUSEAR_FLAG 0x80000000
#define EFUSEAR_WRITE_CMD 0x80000000
@@ -568,6 +579,7 @@ MODULE_LICENSE("GPL");
MODULE_VERSION(RTL8169_VERSION);
MODULE_FIRMWARE(FIRMWARE_8168D_1);
MODULE_FIRMWARE(FIRMWARE_8168D_2);
+MODULE_FIRMWARE(FIRMWARE_8105E_1);
static int rtl8169_open(struct net_device *dev);
static netdev_tx_t rtl8169_start_xmit(struct sk_buff *skb,
@@ -1145,7 +1157,9 @@ static int rtl8169_set_speed_xmii(struct net_device *dev,
(tp->mac_version != RTL_GIGA_MAC_VER_13) &&
(tp->mac_version != RTL_GIGA_MAC_VER_14) &&
(tp->mac_version != RTL_GIGA_MAC_VER_15) &&
- (tp->mac_version != RTL_GIGA_MAC_VER_16)) {
+ (tp->mac_version != RTL_GIGA_MAC_VER_16) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_29) &&
+ (tp->mac_version != RTL_GIGA_MAC_VER_30)) {
giga_ctrl |= ADVERTISE_1000FULL | ADVERTISE_1000HALF;
} else {
netif_info(tp, link, dev,
@@ -1547,6 +1561,9 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
{ 0x7c800000, 0x30000000, RTL_GIGA_MAC_VER_11 },
/* 8101 family. */
+ { 0x7cf00000, 0x40a00000, RTL_GIGA_MAC_VER_30 },
+ { 0x7cf00000, 0x40900000, RTL_GIGA_MAC_VER_29 },
+ { 0x7c800000, 0x40800000, RTL_GIGA_MAC_VER_30 },
{ 0x7cf00000, 0x34a00000, RTL_GIGA_MAC_VER_09 },
{ 0x7cf00000, 0x24a00000, RTL_GIGA_MAC_VER_09 },
{ 0x7cf00000, 0x34900000, RTL_GIGA_MAC_VER_08 },
@@ -2423,6 +2440,33 @@ static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
+static void rtl8105e_hw_phy_config(struct rtl8169_private *tp)
+{
+ static const struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0005 },
+ { 0x1a, 0x0000 },
+ { 0x1f, 0x0000 },
+
+ { 0x1f, 0x0004 },
+ { 0x1c, 0x0000 },
+ { 0x1f, 0x0000 },
+
+ { 0x1f, 0x0001 },
+ { 0x15, 0x7701 },
+ { 0x1f, 0x0000 }
+ };
+
+ /* Disable ALDPS before ram code */
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x18, 0x0310);
+ msleep(100);
+
+ if (rtl_apply_firmware(tp, FIRMWARE_8105E_1) < 0)
+ netif_warn(tp, probe, tp->dev, "unable to apply firmware patch\n");
+
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+}
+
static void rtl_hw_phy_config(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -2490,6 +2534,10 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_28:
rtl8168d_4_hw_phy_config(tp);
break;
+ case RTL_GIGA_MAC_VER_29:
+ case RTL_GIGA_MAC_VER_30:
+ rtl8105e_hw_phy_config(tp);
+ break;
default:
break;
@@ -2928,6 +2976,8 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_09:
case RTL_GIGA_MAC_VER_10:
case RTL_GIGA_MAC_VER_16:
+ case RTL_GIGA_MAC_VER_29:
+ case RTL_GIGA_MAC_VER_30:
ops->down = r810x_pll_power_down;
ops->up = r810x_pll_power_up;
break;
@@ -3890,6 +3940,37 @@ static void rtl_hw_start_8102e_3(void __iomem *ioaddr, struct pci_dev *pdev)
rtl_ephy_write(ioaddr, 0x03, 0xc2f9);
}
+static void rtl_hw_start_8105e_1(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ static const struct ephy_info e_info_8105e_1[] = {
+ { 0x07, 0, 0x4000 },
+ { 0x19, 0, 0x0200 },
+ { 0x19, 0, 0x0020 },
+ { 0x1e, 0, 0x2000 },
+ { 0x03, 0, 0x0001 },
+ { 0x19, 0, 0x0100 },
+ { 0x19, 0, 0x0004 },
+ { 0x0a, 0, 0x0020 }
+ };
+
+ /* Force LAN exit from ASPM if Rx/Tx are not idel */
+ RTL_W32(FuncEvent, RTL_R32(FuncEvent) | 0x002800);
+
+ /* disable Early Tally Counter */
+ RTL_W32(FuncEvent, RTL_R32(FuncEvent) & ~0x010000);
+
+ RTL_W8(MCU, RTL_R8(MCU) | EN_NDP | EN_OOB_RESET);
+ RTL_W8(DLLPR, RTL_R8(DLLPR) | PM_SWITCH);
+
+ rtl_ephy_init(ioaddr, e_info_8105e_1, ARRAY_SIZE(e_info_8105e_1));
+}
+
+static void rtl_hw_start_8105e_2(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ rtl_hw_start_8105e_1(ioaddr, pdev);
+ rtl_ephy_write(ioaddr, 0x1e, rtl_ephy_read(ioaddr, 0x1e) | 0x8000);
+}
+
static void rtl_hw_start_8101(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -3918,6 +3999,13 @@ static void rtl_hw_start_8101(struct net_device *dev)
case RTL_GIGA_MAC_VER_09:
rtl_hw_start_8102e_2(ioaddr, pdev);
break;
+
+ case RTL_GIGA_MAC_VER_29:
+ rtl_hw_start_8105e_1(ioaddr, pdev);
+ break;
+ case RTL_GIGA_MAC_VER_30:
+ rtl_hw_start_8105e_2(ioaddr, pdev);
+ break;
}
RTL_W8(Cfg9346, Cfg9346_Unlock);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 3/3] net/r8169: fix RTL8168DP issue
From: Hayes Wang @ 2011-02-22 9:26 UTC (permalink / raw)
To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1298366782-1508-1-git-send-email-hayeswang@realtek.com>
Fix the RTL8111DP turn off the power when DASH is enabled.
Fix RTL_GIGA_MAC_VER_27 don't wait tx finish before reset.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/r8169.c | 17 ++++++++++++++---
1 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 336ba94..ef2133b 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -2869,8 +2869,11 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
- if (tp->mac_version == RTL_GIGA_MAC_VER_27)
+ if (((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_28)) &&
+ (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {
return;
+ }
if (((tp->mac_version == RTL_GIGA_MAC_VER_23) ||
(tp->mac_version == RTL_GIGA_MAC_VER_24)) &&
@@ -2892,6 +2895,8 @@ static void r8168_pll_power_down(struct rtl8169_private *tp)
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_25:
case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
break;
}
@@ -2901,12 +2906,17 @@ static void r8168_pll_power_up(struct rtl8169_private *tp)
{
void __iomem *ioaddr = tp->mmio_addr;
- if (tp->mac_version == RTL_GIGA_MAC_VER_27)
+ if (((tp->mac_version == RTL_GIGA_MAC_VER_27) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_28)) &&
+ (ocp_read(tp, 0x0f, 0x0010) & 0x00008000)) {
return;
+ }
switch (tp->mac_version) {
case RTL_GIGA_MAC_VER_25:
case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
break;
}
@@ -3319,7 +3329,8 @@ static void rtl8169_hw_reset(struct rtl8169_private *tp)
/* Disable interrupts */
rtl8169_irq_mask_and_ack(ioaddr);
- if (tp->mac_version == RTL_GIGA_MAC_VER_28) {
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27 ||
+ tp->mac_version == RTL_GIGA_MAC_VER_28) {
while (RTL_R8(TxPoll) & NPQ)
udelay(20);
--
1.7.3.2
^ permalink raw reply related
* [PATCH 2/3] net/r8169: fix the wrong parameter of point address
From: Hayes Wang @ 2011-02-22 9:26 UTC (permalink / raw)
To: romieu; +Cc: netdev, linux-kernel, Hayes Wang
In-Reply-To: <1298366782-1508-1-git-send-email-hayeswang@realtek.com>
Correct the parameter of rtl8168_oob_notify. It results in the
wrong point address and influences RTL8168DP.
Signed-off-by: Hayes Wang <hayeswang@realtek.com>
---
drivers/net/r8169.c | 5 +++--
1 files changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 3630dd7..336ba94 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -617,8 +617,9 @@ static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
}
}
-static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd)
+static void rtl8168_oob_notify(struct rtl8169_private *tp, u8 cmd)
{
+ void __iomem *ioaddr = tp->mmio_addr;
int i;
RTL_W8(ERIDR, cmd);
@@ -630,7 +631,7 @@ static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd)
break;
}
- ocp_write(ioaddr, 0x1, 0x30, 0x00000001);
+ ocp_write(tp, 0x1, 0x30, 0x00000001);
}
#define OOB_CMD_RESET 0x00
--
1.7.3.2
^ permalink raw reply related
* [PATCH 0/4] simple generic timer infrastructure and stmmac example
From: Peppe CAVALLARO @ 2011-02-22 10:17 UTC (permalink / raw)
To: linux-sh@vger.kernel.org, netdev@vger.kernel.org
Cc: Stuart MENEFY, Peppe CAVALLARO
Many devices targeted at the embedded market provide a number of
generic timers which are capable of generating interrupts at a
requested rate. These can then be used in the implementation of drivers
for other peripherals which require a timer interrupt, without having
to provide an additional timer as part of that peripheral.
A code provides a simple abstraction layer which allows a timer to be
registered, and for a driver to request a timer.
Currently this doesn't provide any of the additional information, such
as precision or position in clock framework which might be required
for a fully featured driver.
This patches also updates the stmmac Network device driver to use
the generic timer infrastructure The timer is used for mitigating
the number of the interrupts. This helps many people to save the
CPU on STM platforms with MAC10/100 and GMAC device without an
embedded timer.
Welcome comments and review.
Giuseppe Cavallaro (3):
sh_timer: add the support to use the generic timer
stmmac: switch to use the new generic timer interface
stmmac: rework and improvement the stmmac timer
Stuart Menefy (1):
clksource: Generic timer infrastructure
drivers/clocksource/Makefile | 1 +
drivers/clocksource/generictimer.c | 60 +++++++++++++++++++++
drivers/clocksource/sh_tmu.c | 72 +++++++++++++++++++++++++
drivers/net/stmmac/Kconfig | 19 ++++---
drivers/net/stmmac/Makefile | 2 +-
drivers/net/stmmac/common.h | 6 ++
drivers/net/stmmac/stmmac.h | 5 +-
drivers/net/stmmac/stmmac_main.c | 66 ++++++++++++-----------
drivers/net/stmmac/stmmac_timer.c | 103 +++++++++++++++++++++---------------
drivers/net/stmmac/stmmac_timer.h | 12 ++---
include/linux/generictimer.h | 41 ++++++++++++++
11 files changed, 295 insertions(+), 92 deletions(-)
create mode 100644 drivers/clocksource/generictimer.c
create mode 100644 include/linux/generictimer.h
--
1.7.4
^ permalink raw reply
* [PATCH (sh-2.6) 1/4] clksource: Generic timer infrastructure
From: Peppe CAVALLARO @ 2011-02-22 10:17 UTC (permalink / raw)
To: linux-sh@vger.kernel.org, netdev@vger.kernel.org; +Cc: Stuart MENEFY
In-Reply-To: <1298369864-24429-1-git-send-email-peppe.cavallaro@st.com>
From: Stuart Menefy <stuart.menefy@st.com>
Many devices targeted at the embedded market provide a number of
generic timers which are capable of generating interrupts at a
requested rate. These can then be used in the implementation of drivers
for other peripherals which require a timer interrupt, without having
to provide an additional timer as part of that peripheral.
A code provides a simple abstraction layer which allows a timer to be
registered, and for a driver to request a timer.
Currently this doesn't provide any of the additional information, such
as precision or position in clock framework which might be required
for a fully featured driver.
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Hacked-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/clocksource/Makefile | 1 +
drivers/clocksource/generictimer.c | 60 ++++++++++++++++++++++++++++++++++++
include/linux/generictimer.h | 41 ++++++++++++++++++++++++
3 files changed, 102 insertions(+), 0 deletions(-)
create mode 100644 drivers/clocksource/generictimer.c
create mode 100644 include/linux/generictimer.h
diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile
index be61ece..b0be293 100644
--- a/drivers/clocksource/Makefile
+++ b/drivers/clocksource/Makefile
@@ -6,3 +6,4 @@ obj-$(CONFIG_CS5535_CLOCK_EVENT_SRC) += cs5535-clockevt.o
obj-$(CONFIG_SH_TIMER_CMT) += sh_cmt.o
obj-$(CONFIG_SH_TIMER_MTU2) += sh_mtu2.o
obj-$(CONFIG_SH_TIMER_TMU) += sh_tmu.o
+obj-y += generictimer.o
diff --git a/drivers/clocksource/generictimer.c b/drivers/clocksource/generictimer.c
new file mode 100644
index 0000000..a74a87a
--- /dev/null
+++ b/drivers/clocksource/generictimer.c
@@ -0,0 +1,60 @@
+/*
+ * Simple generic hardware timer interface
+ *
+ * Copyright (C) 2010 STMicroelectronics Limited
+ * Authors: Giuseppe Cavallaro <peppe.cavallaro@st.com>
+ * Stuart Menefy <stuart.menefy@st.com>
+ *
+ * May be copied or modified under the terms of the GNU General Public
+ * License. See linux/COPYING for more information.
+ */
+
+#include <linux/kernel.h>
+#include <linux/mutex.h>
+#include <linux/list.h>
+#include <linux/generictimer.h>
+
+static DEFINE_MUTEX(gt_mutex);
+static LIST_HEAD(gt_list);
+
+void generic_timer_register_device(struct generic_timer *gt)
+{
+ mutex_lock(>_mutex);
+ list_add(>->list, >_list);
+ mutex_unlock(>_mutex);
+}
+
+struct generic_timer *generic_timer_claim(void (*handler) (void *), void *data)
+{
+ struct generic_timer *gt = NULL;
+
+ if (!handler) {
+ pr_err("%s: invalid handler\n", __func__);
+ return NULL;
+ }
+
+ mutex_lock(>_mutex);
+ if (!list_empty(>_list)) {
+ struct list_head *list = gt_list.next;
+ list_del(list);
+ gt = container_of(list, struct generic_timer, list);
+ }
+ mutex_unlock(>_mutex);
+
+ if (!gt)
+ return NULL;
+
+ /* Prepare the new handler */
+ gt->priv_handler = handler;
+ gt->data = data;
+
+ return gt;
+}
+
+void generic_timer_release(struct generic_timer *gt)
+{
+ /* Just in case... */
+ generic_timer_stop(gt);
+
+ generic_timer_register_device(gt);
+}
diff --git a/include/linux/generictimer.h b/include/linux/generictimer.h
new file mode 100644
index 0000000..87fb656
--- /dev/null
+++ b/include/linux/generictimer.h
@@ -0,0 +1,41 @@
+#ifndef __STM_GENERIC_TIMER_H
+#define __STM_GENERIC_TIMER_H
+
+#include <linux/list.h>
+
+/* Generic timer device intrface */
+
+struct generic_timer {
+ char *name;
+ struct list_head list;
+ void (*priv_handler)(void *data);
+ void *data;
+ void (*timer_start)(struct generic_timer *gt);
+ void (*timer_stop)(struct generic_timer *gt);
+ void (*set_rate)(struct generic_timer *gt, unsigned long rate);
+};
+
+void generic_timer_register_device(struct generic_timer *gt);
+
+/* Driver interface */
+
+struct generic_timer *generic_timer_claim(void (*handler)(void *), void *data);
+void generic_timer_release(struct generic_timer *gt);
+
+static inline void generic_timer_start(struct generic_timer *gt)
+{
+ gt->timer_start(gt);
+}
+
+static inline void generic_timer_stop(struct generic_timer *gt)
+{
+ gt->timer_stop(gt);
+}
+
+static inline void generic_timer_set_rate(struct generic_timer *gt,
+ unsigned long rate)
+{
+ gt->set_rate(gt, rate);
+}
+
+#endif /* __STM_GENERIC_TIMER_H */
--
1.7.4
^ permalink raw reply related
* [PATCH (sh-2.6) 2/4] sh_timer: add the support to use the generic timer
From: Peppe CAVALLARO @ 2011-02-22 10:17 UTC (permalink / raw)
To: linux-sh@vger.kernel.org, netdev@vger.kernel.org
Cc: Stuart MENEFY, Peppe CAVALLARO
In-Reply-To: <1298369864-24429-1-git-send-email-peppe.cavallaro@st.com>
Add the support to register and use a TMU channel as
generic timer. For example the stmmac network device
driver, on STM platforms, uses the TMU channel 2 for
mitigating the number of interrupts.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
---
drivers/clocksource/sh_tmu.c | 72 ++++++++++++++++++++++++++++++++++++++++++
1 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/drivers/clocksource/sh_tmu.c b/drivers/clocksource/sh_tmu.c
index 36aba99..8199556 100644
--- a/drivers/clocksource/sh_tmu.c
+++ b/drivers/clocksource/sh_tmu.c
@@ -29,6 +29,7 @@
#include <linux/err.h>
#include <linux/clocksource.h>
#include <linux/clockchips.h>
+#include <linux/generictimer.h>
#include <linux/sh_timer.h>
#include <linux/slab.h>
@@ -41,6 +42,7 @@ struct sh_tmu_priv {
unsigned long periodic;
struct clock_event_device ced;
struct clocksource cs;
+ struct generic_timer gt;
};
static DEFINE_SPINLOCK(sh_tmu_lock);
@@ -184,6 +186,74 @@ static irqreturn_t sh_tmu_interrupt(int irq, void *dev_id)
return IRQ_HANDLED;
}
+static struct sh_tmu_priv *gt_to_sh_tmu(struct generic_timer *gt)
+{
+ return container_of(gt, struct sh_tmu_priv, gt);
+}
+
+static void sh_tmu_generic_timer_start(struct generic_timer *gt)
+{
+ struct sh_tmu_priv *p = gt_to_sh_tmu(gt);
+
+ sh_tmu_write(p, TCR, 0x0020);
+ sh_tmu_start_stop_ch(p, 1);
+}
+
+static void sh_tmu_generic_timer_stop(struct generic_timer *gt)
+{
+ struct sh_tmu_priv *p = gt_to_sh_tmu(gt);
+
+ sh_tmu_start_stop_ch(p, 0);
+ sh_tmu_write(p, TCR, 0x0000);
+}
+
+static void sh_tmu_generic_timer_set_rate(struct generic_timer *gt,
+ unsigned long rate)
+{
+ struct sh_tmu_priv *p = gt_to_sh_tmu(gt);
+
+ sh_tmu_enable(p);
+ p->periodic = p->rate / rate;
+ sh_tmu_set_next(p, p->periodic, 1);
+}
+
+static irqreturn_t sh_tmu_generic_timer_interrupt(int irq, void *dev_id)
+{
+ struct sh_tmu_priv *p = dev_id;
+
+ sh_tmu_write(p, TCR, 0x0020);
+
+ p->gt.priv_handler(p->gt.data);
+ return IRQ_HANDLED;
+}
+
+static void sh_tmu_register_generic_timer(struct sh_tmu_priv *p, char *name)
+{
+ struct generic_timer *gt = &p->gt;
+ int ret;
+
+ gt->name = name;
+ gt->timer_start = sh_tmu_generic_timer_start;
+ gt->timer_stop = sh_tmu_generic_timer_stop;
+ gt->set_rate = sh_tmu_generic_timer_set_rate;
+
+ p->irqaction.handler = sh_tmu_generic_timer_interrupt;
+
+ ret = setup_irq(p->irqaction.irq, &p->irqaction);
+ if (unlikely(ret)) {
+ dev_err(&p->pdev->dev, "failed to request irq %d\n",
+ p->irqaction.irq);
+ return;
+ }
+
+ sh_tmu_generic_timer_stop(gt);
+ sh_tmu_write(p, TCOR, 0xffffffff);
+ sh_tmu_write(p, TCNT, 0xffffffff);
+
+ dev_info(&p->pdev->dev, "used for generic timer\n");
+ generic_timer_register_device(gt);
+}
+
static struct sh_tmu_priv *cs_to_sh_tmu(struct clocksource *cs)
{
return container_of(cs, struct sh_tmu_priv, cs);
@@ -342,6 +412,8 @@ static int sh_tmu_register(struct sh_tmu_priv *p, char *name,
sh_tmu_register_clockevent(p, name, clockevent_rating);
else if (clocksource_rating)
sh_tmu_register_clocksource(p, name, clocksource_rating);
+ else
+ sh_tmu_register_generic_timer(p, name);
return 0;
}
--
1.7.4
^ permalink raw reply related
* [PATCH (net-2.6) 3/4] stmmac: switch to use the new generic timer interface
From: Peppe CAVALLARO @ 2011-02-22 10:17 UTC (permalink / raw)
To: linux-sh@vger.kernel.org, netdev@vger.kernel.org
Cc: Stuart MENEFY, Peppe CAVALLARO
In-Reply-To: <1298369864-24429-1-git-send-email-peppe.cavallaro@st.com>
The stmmac can use an external timer for mitigating
the number of interrupts.
On SH4 platforms based this can be done by using the
TMU channel 2 interrupt.
This actually helps many people to save the CPU usage
on platforms with MAC10/100 and GMAC devices without
an embedded timer.
This patch removes the old code (obsoleted and only
valid for old STM Kernels) and uses the new generic
timer interface.
Signed-off-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/stmmac/Kconfig | 1 -
drivers/net/stmmac/stmmac_main.c | 21 ++++----
drivers/net/stmmac/stmmac_timer.c | 101 +++++++++++++++++++++---------------
drivers/net/stmmac/stmmac_timer.h | 11 ++---
4 files changed, 74 insertions(+), 60 deletions(-)
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index 7df7df4..b74e79b 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -32,7 +32,6 @@ config STMMAC_DUAL_MAC
config STMMAC_TIMER
bool "STMMAC Timer optimisation"
default n
- depends on RTC_HCTOSYS_DEVICE
help
Use an external timer for mitigating the number of network
interrupts. Currently, for SH architectures, it is possible
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 34a0af3..26714b4 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -652,7 +652,7 @@ static inline void stmmac_enable_irq(struct stmmac_priv *priv)
{
#ifdef CONFIG_STMMAC_TIMER
if (likely(priv->tm->enable))
- priv->tm->timer_start(tmrate);
+ priv->tm->timer_start(priv->tm->timer_callb, tmrate);
else
#endif
priv->hw->dma->enable_dma_irq(priv->ioaddr);
@@ -662,7 +662,7 @@ static inline void stmmac_disable_irq(struct stmmac_priv *priv)
{
#ifdef CONFIG_STMMAC_TIMER
if (likely(priv->tm->enable))
- priv->tm->timer_stop();
+ priv->tm->timer_stop(priv->tm->timer_callb);
else
#endif
priv->hw->dma->disable_dma_irq(priv->ioaddr);
@@ -703,11 +703,11 @@ void stmmac_schedule(struct net_device *dev)
_stmmac_schedule(priv);
}
-static void stmmac_no_timer_started(unsigned int x)
+static void stmmac_no_timer_started(void *t, unsigned int x)
{;
};
-static void stmmac_no_timer_stopped(void)
+static void stmmac_no_timer_stopped(void *t)
{;
};
#endif
@@ -720,7 +720,6 @@ static void stmmac_no_timer_stopped(void)
*/
static void stmmac_tx_err(struct stmmac_priv *priv)
{
-
netif_stop_queue(priv->dev);
priv->hw->dma->stop_tx(priv->ioaddr);
@@ -807,7 +806,8 @@ static int stmmac_open(struct net_device *dev)
/* Test if the external timer can be actually used.
* In case of failure continue without timer. */
if (unlikely((stmmac_open_ext_timer(dev, priv->tm)) < 0)) {
- pr_warning("stmmaceth: cannot attach the external timer.\n");
+ pr_warning("stmmac (%s): cannot attach the external timer.\n",
+ dev->name);
priv->tm->freq = 0;
priv->tm->timer_start = stmmac_no_timer_started;
priv->tm->timer_stop = stmmac_no_timer_stopped;
@@ -864,7 +864,8 @@ static int stmmac_open(struct net_device *dev)
priv->hw->dma->start_rx(priv->ioaddr);
#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_start(tmrate);
+ if (likely(priv->tm->enable))
+ priv->tm->timer_start(priv->tm->timer_callb, tmrate);
#endif
/* Dump DMA/MAC registers */
if (netif_msg_hw(priv)) {
@@ -902,7 +903,7 @@ static int stmmac_release(struct net_device *dev)
#ifdef CONFIG_STMMAC_TIMER
/* Stop and release the timer */
- stmmac_close_ext_timer();
+ stmmac_close_ext_timer(priv->tm->timer_callb);
if (priv->tm != NULL)
kfree(priv->tm);
#endif
@@ -1815,7 +1816,7 @@ static int stmmac_suspend(struct device *dev)
phy_stop(priv->phydev);
#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_stop();
+ priv->tm->timer_stop(priv->tm->timer_callb);
if (likely(priv->tm->enable))
dis_ic = 1;
#endif
@@ -1866,7 +1867,7 @@ static int stmmac_resume(struct device *dev)
#ifdef CONFIG_STMMAC_TIMER
if (likely(priv->tm->enable))
- priv->tm->timer_start(tmrate);
+ priv->tm->timer_start(priv->tm->timer_callb, tmrate);
#endif
napi_enable(&priv->napi);
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
index 2a0e1ab..2481daa 100644
--- a/drivers/net/stmmac/stmmac_timer.c
+++ b/drivers/net/stmmac/stmmac_timer.c
@@ -33,102 +33,119 @@ static void stmmac_timer_handler(void *data)
stmmac_schedule(dev);
}
-#define STMMAC_TIMER_MSG(timer, freq) \
-printk(KERN_INFO "stmmac_timer: %s Timer ON (freq %dHz)\n", timer, freq);
+#define STMMAC_TIMER_MSG(dev_name, timer, freq) \
+printk(KERN_INFO "stmmac_timer: (%s) %s Timer (freq %dHz)\n", \
+ dev_name, timer, freq);
#if defined(CONFIG_STMMAC_RTC_TIMER)
#include <linux/rtc.h>
-static struct rtc_device *stmmac_rtc;
-static rtc_task_t stmmac_task;
-static void stmmac_rtc_start(unsigned int new_freq)
+static void stmmac_rtc_start(void *timer, unsigned int new_freq)
{
- rtc_irq_set_freq(stmmac_rtc, &stmmac_task, new_freq);
- rtc_irq_set_state(stmmac_rtc, &stmmac_task, 1);
+ struct rtc_device *rtc = timer;
+
+ rtc_irq_set_freq(rtc, rtc->irq_task, new_freq);
+ rtc_irq_set_state(rtc, rtc->irq_task, 1);
+ return;
}
-static void stmmac_rtc_stop(void)
+static void stmmac_rtc_stop(void *timer)
{
- rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
+ struct rtc_device *rtc = timer;
+
+ rtc_irq_set_state(rtc, rtc->irq_task, 0);
+ return;
}
int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
{
- stmmac_task.private_data = dev;
- stmmac_task.func = stmmac_timer_handler;
+ struct rtc_device *rtc;
+ rtc_task_t rtc_task;
+
+ rtc_task.private_data = dev;
+ rtc_task.func = stmmac_timer_handler;
- stmmac_rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
- if (stmmac_rtc == NULL) {
+ rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);
+ if (rtc == NULL) {
pr_err("open rtc device failed\n");
return -ENODEV;
}
- rtc_irq_register(stmmac_rtc, &stmmac_task);
+ rtc_irq_register(rtc, &rtc_task);
/* Periodic mode is not supported */
- if ((rtc_irq_set_freq(stmmac_rtc, &stmmac_task, tm->freq) < 0)) {
+ if ((rtc_irq_set_freq(rtc, &rtc_task, tm->freq) < 0)) {
pr_err("set periodic failed\n");
- rtc_irq_unregister(stmmac_rtc, &stmmac_task);
- rtc_class_close(stmmac_rtc);
+ rtc_irq_unregister(rtc, &rtc_task);
+ rtc_class_close(rtc);
return -1;
}
- STMMAC_TIMER_MSG(CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
+ STMMAC_TIMER_MSG(dev->name, CONFIG_RTC_HCTOSYS_DEVICE, tm->freq);
+ rtc->irq_task = &rtc_task;
+ tm->timer_callb = rtc;
tm->timer_start = stmmac_rtc_start;
tm->timer_stop = stmmac_rtc_stop;
return 0;
}
-int stmmac_close_ext_timer(void)
+int stmmac_close_ext_timer(void *timer)
{
- rtc_irq_set_state(stmmac_rtc, &stmmac_task, 0);
- rtc_irq_unregister(stmmac_rtc, &stmmac_task);
- rtc_class_close(stmmac_rtc);
+ struct rtc_device *rtc = timer;
+
+ rtc_irq_set_state(rtc, rtc->irq_task, 0);
+ rtc_irq_unregister(rtc, rtc->irq_task);
+ rtc_class_close(rtc);
+
return 0;
}
#elif defined(CONFIG_STMMAC_TMU_TIMER)
-#include <linux/clk.h>
-#define TMU_CHANNEL "tmu2_clk"
-static struct clk *timer_clock;
+#include <linux/generictimer.h>
-static void stmmac_tmu_start(unsigned int new_freq)
+/* Set rate and start the timer */
+static void stmmac_tmu_set_rate(void *timer_callb, unsigned int new_freq)
{
- clk_set_rate(timer_clock, new_freq);
- clk_enable(timer_clock);
+ struct generic_timer *timer = timer_callb;
+
+ generic_timer_start(timer);
+ generic_timer_set_rate(timer, new_freq);
+ return;
}
-static void stmmac_tmu_stop(void)
+static void stmmac_tmu_stop(void *timer_callb)
{
- clk_disable(timer_clock);
+ struct generic_timer *timer = timer_callb;
+
+ generic_timer_stop(timer);
+ return;
}
int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
{
- timer_clock = clk_get(NULL, TMU_CHANNEL);
+ struct generic_timer *timer;
+ timer = generic_timer_claim(stmmac_timer_handler, dev);
- if (timer_clock == NULL)
+ if (timer == NULL)
return -1;
- if (tmu2_register_user(stmmac_timer_handler, (void *)dev) < 0) {
- timer_clock = NULL;
- return -1;
- }
+ STMMAC_TIMER_MSG(dev->name, "sh_tmu", tm->freq);
- STMMAC_TIMER_MSG("TMU2", tm->freq);
- tm->timer_start = stmmac_tmu_start;
+ tm->timer_callb = timer;
+ tm->timer_start = stmmac_tmu_set_rate;
tm->timer_stop = stmmac_tmu_stop;
return 0;
}
-int stmmac_close_ext_timer(void)
+int stmmac_close_ext_timer(void *timer_callb)
{
- clk_disable(timer_clock);
- tmu2_unregister_user();
- clk_put(timer_clock);
+ struct generic_timer *timer = timer_callb;
+
+ stmmac_tmu_stop(timer_callb);
+ generic_timer_release(timer);
return 0;
}
#endif
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h
index 6863590..250f5cb 100644
--- a/drivers/net/stmmac/stmmac_timer.h
+++ b/drivers/net/stmmac/stmmac_timer.h
@@ -23,20 +23,17 @@
*******************************************************************************/
struct stmmac_timer {
- void (*timer_start) (unsigned int new_freq);
- void (*timer_stop) (void);
+ void (*timer_start) (void *timer, unsigned int new_freq);
+ void (*timer_stop) (void *timer);
unsigned int freq;
unsigned int enable;
+ void *timer_callb;
};
/* Open the HW timer device and return 0 in case of success */
int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm);
/* Stop the timer and release it */
-int stmmac_close_ext_timer(void);
+int stmmac_close_ext_timer(void *priv);
/* Function used for scheduling task within the stmmac */
void stmmac_schedule(struct net_device *dev);
-#if defined(CONFIG_STMMAC_TMU_TIMER)
-extern int tmu2_register_user(void *fnt, void *data);
-extern void tmu2_unregister_user(void);
-#endif
--
1.7.4
^ permalink raw reply related
* Re: sysctls below net.ipv[46].conf.all not working as expected
From: Uwe Kleine-König @ 2011-02-22 9:34 UTC (permalink / raw)
To: David Miller; +Cc: netdev, Marco d'Itri
In-Reply-To: <20101230204319.GE14221@pengutronix.de>
Hello David,
On Thu, Dec 30, 2010 at 09:43:19PM +0100, Uwe Kleine-König wrote:
> On Thu, Dec 30, 2010 at 12:30:23PM -0800, David Miller wrote:
> > From: Uwe Kleine-König <u.kleine-koenig@pengutronix.de>
> > Date: Wed, 29 Dec 2010 17:06:07 +0100
> >
> > > I did the following:
> > >
> > > cassiopeia:~# sysctl net.ipv6.conf.all.use_tempaddr
> > > net.ipv6.conf.all.use_tempaddr = 0
> > >
> > > cassiopeia:~# sysctl net.ipv6.conf.eth0.use_tempaddr
> > > net.ipv6.conf.eth0.use_tempaddr = 0
> > >
> > > cassiopeia:~# sysctl -w net.ipv6.conf.all.use_tempaddr=1
> > > net.ipv6.conf.all.use_tempaddr = 1
> > >
> > > cassiopeia:~# sysctl net.ipv6.conf.all.use_tempaddr
> > > net.ipv6.conf.all.use_tempaddr = 1
> > >
> > > cassiopeia:~# sysctl net.ipv6.conf.eth0.use_tempaddr
> > > net.ipv6.conf.eth0.use_tempaddr = 0
> > >
> > > Here I would have expected that eth0's use_tempaddr is 1, too. The
> > > problem is not that this entry isn't writeable:
> >
> > The "all" value is propagated at the first moment that the ipv6 device
> > private is created, usually that is when the device is first brought up
> > which means it can happen as early as the exact moment the device is
> > registered.
> >
> > Therefore, if you want "all" to apply to "eth0", you must make sure
> > the sysctl is set properly before the device is registered.
> I thought this is what "default" was used for?!
I took the time now to dig into the source for ipv4/{all,default}.
Unless I'm mistaken I found:
- inetdev_init copies dev_net(dev)->ipv4.devconf_dflt to &in_dev->cnf
That's called from inetdev_event if there is no in_dev.
- devinet_copy_dflt_conf copies to all devices that have !test_bit(i,
in_dev->cnf.state)
devinet_copy_dflt_conf is called when /proc/sys/net/ipv4/conf/default
is written to. I didn't found where the in_dev->cnf.state bits are
set.
- net->ipv4.devconf_all is never propagated to the devices.
- The data behind /proc/sys/net/ipv4/conf/all is used in registering
net->ipv4.forw_hdr and seems only have to do with ip_forward
So I think that it's really "default" that propagates to a new device as
I expected and the documentation suggests.
So IMHO a better name for "all" would be "global" ...
> If you are really right, the documentation is (IMHO) misleading. e.g.
> Documentation/networking/ip-sysctl.txt tells:
>
> conf/default/*:
> Change the interface-specific default settings.
>
> conf/all/*:
> Change all the interface-specific settings.
... and this is misleading. I wonder if it would be considered OK, to
create a new config directory called "global" that acts like "all" now
and let "all" propagate all changes to all devices, "default" and
"global". If not the documentation needs clearification.
I guess for ipv6 it's similar, though I didn't check that.
Best regards
Uwe
--
Pengutronix e.K. | Uwe Kleine-König |
Industrial Linux Solutions | http://www.pengutronix.de/ |
^ permalink raw reply
* [PATCH (net-2.6) 4/4] stmmac: rework and improvement the stmmac timer
From: Peppe CAVALLARO @ 2011-02-22 10:17 UTC (permalink / raw)
To: linux-sh@vger.kernel.org, netdev@vger.kernel.org
Cc: Stuart MENEFY, Peppe CAVALLARO
In-Reply-To: <1298369864-24429-1-git-send-email-peppe.cavallaro@st.com>
This patch prepares the stmmac to use the
embedded watchdog timer included in the new
mac generations. The STMMAC_TIMER option becomes
STMMAC_EXT_TIMER. The patch also tidies-up the code
and improvements the Kconfig information.
The driver can use the external timer and in case
of problems, i.e. while registering the timer,
it'll continue to work with NAPI and interrupts.
Currently, the STMMAC_EXT_TIMER can be turned on
SUPERH only and it depends on SH_TIMER_TMU: I mean
on platforms where I performed all my tests.
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/stmmac/Kconfig | 18 ++++++++----
drivers/net/stmmac/Makefile | 2 +-
drivers/net/stmmac/common.h | 6 ++++
drivers/net/stmmac/stmmac.h | 5 ++-
drivers/net/stmmac/stmmac_main.c | 51 +++++++++++++++++++-----------------
drivers/net/stmmac/stmmac_timer.c | 4 +-
drivers/net/stmmac/stmmac_timer.h | 1 -
7 files changed, 51 insertions(+), 36 deletions(-)
diff --git a/drivers/net/stmmac/Kconfig b/drivers/net/stmmac/Kconfig
index b74e79b..cdbe5a8 100644
--- a/drivers/net/stmmac/Kconfig
+++ b/drivers/net/stmmac/Kconfig
@@ -29,22 +29,28 @@ config STMMAC_DUAL_MAC
Ethernet Controllers. This option turns on the second Ethernet
device on this kind of platforms.
-config STMMAC_TIMER
+config STMMAC_EXT_TIMER
bool "STMMAC Timer optimisation"
default n
help
Use an external timer for mitigating the number of network
interrupts. Currently, for SH architectures, it is possible
- to use the TMU channel 2 and the SH-RTC device.
+ to use the TMU channel 2 (via Generic Timer) and the SH-RTC
+ device. If the timer registration fails during the interface
+ initialisation then the driver will work without any
+ mitigation schema.
choice
prompt "Select Timer device"
- depends on STMMAC_TIMER
+ depends on STMMAC_EXT_TIMER
-config STMMAC_TMU_TIMER
- bool "TMU channel 2"
- depends on CPU_SH4
+config STMMAC_GEN_TIMER
+ bool "Generic External Timer"
+ depends on SH_TIMER_TMU
help
+ Use the Generic timer for mitigating the interrupts.
+ For example, in case of SUPERH the TMU channel 2
+ is used for that.
config STMMAC_RTC_TIMER
bool "Real time clock"
diff --git a/drivers/net/stmmac/Makefile b/drivers/net/stmmac/Makefile
index 9691733..05d84b2 100644
--- a/drivers/net/stmmac/Makefile
+++ b/drivers/net/stmmac/Makefile
@@ -1,5 +1,5 @@
obj-$(CONFIG_STMMAC_ETH) += stmmac.o
-stmmac-$(CONFIG_STMMAC_TIMER) += stmmac_timer.o
+stmmac-$(CONFIG_STMMAC_EXT_TIMER) += stmmac_timer.o
stmmac-objs:= stmmac_main.o stmmac_ethtool.o stmmac_mdio.o \
dwmac_lib.o dwmac1000_core.o dwmac1000_dma.o \
dwmac100_core.o dwmac100_dma.o enh_desc.o norm_desc.o $(stmmac-y)
diff --git a/drivers/net/stmmac/common.h b/drivers/net/stmmac/common.h
index 375ea19..4bd9d01 100644
--- a/drivers/net/stmmac/common.h
+++ b/drivers/net/stmmac/common.h
@@ -43,6 +43,12 @@
#undef FRAME_FILTER_DEBUG
/* #define FRAME_FILTER_DEBUG */
+enum mitigation_timer {
+ no_timer = 0,
+ external = 1,
+ embedded = 2,
+};
+
struct stmmac_extra_stats {
/* Transmit errors */
unsigned long tx_underflow ____cacheline_aligned;
diff --git a/drivers/net/stmmac/stmmac.h b/drivers/net/stmmac/stmmac.h
index 5f06c47..1b76977 100644
--- a/drivers/net/stmmac/stmmac.h
+++ b/drivers/net/stmmac/stmmac.h
@@ -25,7 +25,7 @@
#include <linux/stmmac.h>
#include "common.h"
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
#include "stmmac_timer.h"
#endif
@@ -77,9 +77,10 @@ struct stmmac_priv {
spinlock_t lock;
int wolopts;
int wolenabled;
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
struct stmmac_timer *tm;
#endif
+ unsigned int timer;
#ifdef STMMAC_VLAN_TAG_USED
struct vlan_group *vlgrp;
#endif
diff --git a/drivers/net/stmmac/stmmac_main.c b/drivers/net/stmmac/stmmac_main.c
index 26714b4..53a7086 100644
--- a/drivers/net/stmmac/stmmac_main.c
+++ b/drivers/net/stmmac/stmmac_main.c
@@ -122,7 +122,7 @@ MODULE_PARM_DESC(tc, "DMA threshold control value");
/* Pay attention to tune this parameter; take care of both
* hardware capability and network stabitily/performance impact.
* Many tests showed that ~4ms latency seems to be good enough. */
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
#define DEFAULT_PERIODIC_RATE 256
static int tmrate = DEFAULT_PERIODIC_RATE;
module_param(tmrate, int, S_IRUGO | S_IWUSR);
@@ -415,9 +415,9 @@ static void init_dma_desc_rings(struct net_device *dev)
else
bfsize = DMA_BUFFER_SIZE;
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
/* Disable interrupts on completion for the reception if timer is on */
- if (likely(priv->tm->enable))
+ if (likely(priv->timer == external))
dis_ic = 1;
#endif
/* If the MTU exceeds 8k so use the second buffer in the chain */
@@ -650,8 +650,8 @@ static void stmmac_tx(struct stmmac_priv *priv)
static inline void stmmac_enable_irq(struct stmmac_priv *priv)
{
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
+#ifdef CONFIG_STMMAC_EXT_TIMER
+ if (likely(priv->timer == external))
priv->tm->timer_start(priv->tm->timer_callb, tmrate);
else
#endif
@@ -660,8 +660,8 @@ static inline void stmmac_enable_irq(struct stmmac_priv *priv)
static inline void stmmac_disable_irq(struct stmmac_priv *priv)
{
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
+#ifdef CONFIG_STMMAC_EXT_TIMER
+ if (likely(priv->timer == external))
priv->tm->timer_stop(priv->tm->timer_callb);
else
#endif
@@ -693,7 +693,7 @@ static inline void _stmmac_schedule(struct stmmac_priv *priv)
}
}
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
void stmmac_schedule(struct net_device *dev)
{
struct stmmac_priv *priv = netdev_priv(dev);
@@ -795,7 +795,7 @@ static int stmmac_open(struct net_device *dev)
return ret;
}
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
priv->tm = kzalloc(sizeof(struct stmmac_timer *), GFP_KERNEL);
if (unlikely(priv->tm == NULL)) {
pr_err("%s: ERROR: timer memory alloc failed\n", __func__);
@@ -812,7 +812,7 @@ static int stmmac_open(struct net_device *dev)
priv->tm->timer_start = stmmac_no_timer_started;
priv->tm->timer_stop = stmmac_no_timer_stopped;
} else
- priv->tm->enable = 1;
+ priv->timer = external;
#endif
/* Create and initialize the TX/RX descriptors chains. */
@@ -863,8 +863,8 @@ static int stmmac_open(struct net_device *dev)
priv->hw->dma->start_tx(priv->ioaddr);
priv->hw->dma->start_rx(priv->ioaddr);
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
+#ifdef CONFIG_STMMAC_EXT_TIMER
+ if (likely(priv->timer == external))
priv->tm->timer_start(priv->tm->timer_callb, tmrate);
#endif
/* Dump DMA/MAC registers */
@@ -901,11 +901,13 @@ static int stmmac_release(struct net_device *dev)
netif_stop_queue(dev);
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
/* Stop and release the timer */
- stmmac_close_ext_timer(priv->tm->timer_callb);
- if (priv->tm != NULL)
+ if (priv->tm != NULL) {
+ if (likely(priv->timer == external))
+ stmmac_close_ext_timer(priv->tm->timer_callb);
kfree(priv->tm);
+ }
#endif
napi_disable(&priv->napi);
skb_queue_purge(&priv->rx_recycle);
@@ -1096,9 +1098,9 @@ static netdev_tx_t stmmac_xmit(struct sk_buff *skb, struct net_device *dev)
/* Interrupt on completition only for the latest segment */
priv->hw->desc->close_tx_desc(desc);
-#ifdef CONFIG_STMMAC_TIMER
- /* Clean IC while using timer */
- if (likely(priv->tm->enable))
+#ifdef CONFIG_STMMAC_EXT_TIMER
+ /* Clean IC while using ext timer */
+ if (likely(priv->timer == external))
priv->hw->desc->clear_tx_ic(desc);
#endif
/* To avoid raise condition */
@@ -1815,10 +1817,11 @@ static int stmmac_suspend(struct device *dev)
if (priv->phydev)
phy_stop(priv->phydev);
-#ifdef CONFIG_STMMAC_TIMER
- priv->tm->timer_stop(priv->tm->timer_callb);
- if (likely(priv->tm->enable))
+#ifdef CONFIG_STMMAC_EXT_TIMER
+ if (likely(priv->timer == external)) {
+ priv->tm->timer_stop(priv->tm->timer_callb);
dis_ic = 1;
+ }
#endif
napi_disable(&priv->napi);
@@ -1865,8 +1868,8 @@ static int stmmac_resume(struct device *dev)
priv->hw->dma->start_tx(priv->ioaddr);
priv->hw->dma->start_rx(priv->ioaddr);
-#ifdef CONFIG_STMMAC_TIMER
- if (likely(priv->tm->enable))
+#ifdef CONFIG_STMMAC_EXT_TIMER
+ if (likely(priv->timer == external))
priv->tm->timer_start(priv->tm->timer_callb, tmrate);
#endif
napi_enable(&priv->napi);
@@ -1977,7 +1980,7 @@ static int __init stmmac_cmdline_opt(char *str)
(unsigned long *)&flow_ctrl);
else if (!strncmp(opt, "pause:", 6))
strict_strtoul(opt + 6, 0, (unsigned long *)&pause);
-#ifdef CONFIG_STMMAC_TIMER
+#ifdef CONFIG_STMMAC_EXT_TIMER
else if (!strncmp(opt, "tmrate:", 7))
strict_strtoul(opt + 7, 0, (unsigned long *)&tmrate);
#endif
diff --git a/drivers/net/stmmac/stmmac_timer.c b/drivers/net/stmmac/stmmac_timer.c
index 2481daa..e64db59 100644
--- a/drivers/net/stmmac/stmmac_timer.c
+++ b/drivers/net/stmmac/stmmac_timer.c
@@ -102,7 +102,7 @@ int stmmac_close_ext_timer(void *timer)
return 0;
}
-#elif defined(CONFIG_STMMAC_TMU_TIMER)
+#elif defined(CONFIG_STMMAC_GEN_TIMER)
#include <linux/generictimer.h>
/* Set rate and start the timer */
@@ -131,7 +131,7 @@ int stmmac_open_ext_timer(struct net_device *dev, struct stmmac_timer *tm)
if (timer == NULL)
return -1;
- STMMAC_TIMER_MSG(dev->name, "sh_tmu", tm->freq);
+ STMMAC_TIMER_MSG(dev->name, "Generic", tm->freq);
tm->timer_callb = timer;
tm->timer_start = stmmac_tmu_set_rate;
diff --git a/drivers/net/stmmac/stmmac_timer.h b/drivers/net/stmmac/stmmac_timer.h
index 250f5cb..d719bd5 100644
--- a/drivers/net/stmmac/stmmac_timer.h
+++ b/drivers/net/stmmac/stmmac_timer.h
@@ -26,7 +26,6 @@ struct stmmac_timer {
void (*timer_start) (void *timer, unsigned int new_freq);
void (*timer_stop) (void *timer);
unsigned int freq;
- unsigned int enable;
void *timer_callb;
};
--
1.7.4
^ permalink raw reply related
* [PATCH] llc: avoid skb_clone() if there is only one handler
From: Changli Gao @ 2011-02-22 11:55 UTC (permalink / raw)
To: Arnaldo Carvalho de Melo; +Cc: David S. Miller, netdev, Changli Gao
Signed-off-by: Changli Gao <xiaosuo@gmail.com>
---
net/llc/llc_input.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index f996874..058f1e9 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -181,25 +181,26 @@ int llc_rcv(struct sk_buff *skb, struct net_device *dev,
* LLC functionality
*/
rcv = rcu_dereference(sap->rcv_func);
- if (rcv) {
- struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC);
- if (cskb)
- rcv(cskb, dev, pt, orig_dev);
- }
dest = llc_pdu_type(skb);
- if (unlikely(!dest || !llc_type_handlers[dest - 1]))
- goto drop_put;
- llc_type_handlers[dest - 1](sap, skb);
-out_put:
+ if (unlikely(!dest || !llc_type_handlers[dest - 1])) {
+ if (rcv)
+ rcv(skb, dev, pt, orig_dev);
+ else
+ kfree_skb(skb);
+ } else {
+ if (rcv) {
+ struct sk_buff *cskb = skb_clone(skb, GFP_ATOMIC);
+ if (cskb)
+ rcv(cskb, dev, pt, orig_dev);
+ }
+ llc_type_handlers[dest - 1](sap, skb);
+ }
llc_sap_put(sap);
out:
return 0;
drop:
kfree_skb(skb);
goto out;
-drop_put:
- kfree_skb(skb);
- goto out_put;
handle_station:
if (!llc_station_handler)
goto drop;
^ permalink raw reply related
* [PATCH] r8169: disable ASPM
From: Stanislaw Gruszka @ 2011-02-22 12:00 UTC (permalink / raw)
To: netdev; +Cc: Francois Romieu, stable
r8169: disable ASPM
For some time is known that ASPM is causing troubles on r8169, i.e. make
device randomly stop working without any errors in dmesg.
Currently Tomi Leppikangas reports that system with r8169 device hangs
with MCE errors when ASPM is enabled:
https://bugzilla.redhat.com/show_bug.cgi?id=642861#c4
Lets disable ASPM for r8169 devices at all, to avoid problems with
r8169 PCIe devices at least for some users.
Reported-by: Tomi Leppikangas <tomi.leppikangas@gmail.com>
Cc: stable@kernel.org
Signed-off-by: Stanislaw Gruszka <sgruszka@redhat.com>
---
I have to add (with shame on us) that we selfishly carry this patch
in RHEL6 for some time now.
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 469ab0b..ae40c0e 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -25,6 +25,7 @@
#include <linux/dma-mapping.h>
#include <linux/pm_runtime.h>
#include <linux/firmware.h>
+#include <linux/pci-aspm.h>
#include <asm/system.h>
#include <asm/io.h>
@@ -3009,6 +3010,11 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
mii->reg_num_mask = 0x1f;
mii->supports_gmii = !!(cfg->features & RTL_FEATURE_GMII);
+ /* disable ASPM completely as that cause random device stop working
+ * problems as well as full system hangs for some PCIe devices users */
+ pci_disable_link_state(pdev, PCIE_LINK_STATE_L0S | PCIE_LINK_STATE_L1 |
+ PCIE_LINK_STATE_CLKPM);
+
/* enable device (incl. PCI PM wakeup and hotplug setup) */
rc = pci_enable_device(pdev);
if (rc < 0) {
^ permalink raw reply related
* Re: [PATCH ethtool 5/5] ethtool: Add --version option
From: Ben Hutchings @ 2011-02-22 12:37 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <1561212236.5138.1298355384916.JavaMail.root@tahiti.vyatta.com>
On Mon, 2011-02-21 at 22:16 -0800, Stephen Hemminger wrote:
[...]
> The standard convention is to use -V for short form of version option.
This is not anywhere near standard.
$ cp -V
cp: invalid option -- 'V'
Try `cp --help' for more information.
$ bash -V
bash: -V: invalid option
[...]
$ emacs -V
[opens window]
$ vim -V
chdir(/usr/share/vim)
fchdir() to previous dir
sourcing "$VIM/vimrc"
[...looks like that meant 'verbose'...]
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH 2/2] DM9000B: Fix PHY power for network down/up
From: Sergei Shtylyov @ 2011-02-22 12:36 UTC (permalink / raw)
To: Henry Nestler; +Cc: Sergei Shtylyov, netdev, akpm, linux-arm-kernel, tori
In-Reply-To: <4D62D323.7010403@henry.nestler.mail.gmail.com>
Hello.
On 22-02-2011 0:03, Henry Nestler wrote:
>>> DM9000 revision B needs 1 ms delay after PHY power on (see spec), and PHY
>>> power must on in register
>> Couldn't parse that.
You seem to have missed a word in your patch description.
> This can read in manual DM900B-12-DS-F02 from September 2 2010, Page 14:
> "If this Register 1FH bit 0 is updated from '1' to '0', the all
> Registers can not be accessed within 1ms."
That I've understood.
> The example driver code waits 2 ms.
>>> diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c
>>> index 2d4c4fc..5925569 100644
>>> --- a/drivers/net/dm9000.c
>>> +++ b/drivers/net/dm9000.c
>> [...]
>>> @@ -1194,6 +1191,10 @@ dm9000_open(struct net_device *dev)
>>> if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
>>> return -EAGAIN;
>>>
>>> + /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
>>> + iow(db, DM9000_GPR, 0); /* REG_1F bit0 activate phyxcer */
>>> + udelay(1000); /* delay needs by DM9000B */
>> Why not mdelay(1)?
> Because udelay is the base of mdelay.
> See include/linux/delay.h:31
> #define mdelay(n) ... udelay((n)*1000)
And?
WBR, Sergei
^ permalink raw reply
* Re: why all packets have same queue no when rps enabled?
From: Ben Hutchings @ 2011-02-22 12:45 UTC (permalink / raw)
To: Jon Zhou; +Cc: netdev@vger.kernel.org
In-Reply-To: <4A6A2125329CFD4D8CC40C9E8ABCAB9F24D3DE6D0C@MILEXCH2.ds.jdsu.net>
On Mon, 2011-02-21 at 20:07 -0800, Jon Zhou wrote:
> Hi
>
> I expect each incoming packet will have a different queue no. when I
> enabled RPS on kernel 2.6.36.4
[...]
> Looks almost all packets fall at same queue?
> Will RPS allocate queue no for each packet? and what hash algorithm
> rps used? (is it Toeplitz hash algorithm?)
The queue number identifies a hardware queue. RPS therefore does not
update this number when queueing packets for processing on other CPUs.
If the hardware/driver provides a receive hash (probably Toeplitz) then
this is used for RPS. Otherwise a much cheaper hash is used.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: why all packets have same queue no when rps enabled?
From: Eric Dumazet @ 2011-02-22 13:01 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Jon Zhou, netdev@vger.kernel.org
In-Reply-To: <1298378756.2211.478.camel@localhost>
Le mardi 22 février 2011 à 12:45 +0000, Ben Hutchings a écrit :
> The queue number identifies a hardware queue. RPS therefore does not
> update this number when queueing packets for processing on other CPUs.
>
> If the hardware/driver provides a receive hash (probably Toeplitz) then
> this is used for RPS. Otherwise a much cheaper hash is used.
The default is/should be : rxhash generated in network stack.
ethtool -k eth0 | grep hash
receive-hashing: off
To use the device/harwdare provided rxhash, you need to ask for it.
ethtool -K eth0 rxhash on
BTW, I am not sure what you mean by "much cheaper hash is used"...
I presume hardware provided hash is less expensive (for our cpu) than
computing our rxhash...
^ permalink raw reply
* Re: [PATCH ethtool 5/5] ethtool: Add --version option
From: Eric Dumazet @ 2011-02-22 13:05 UTC (permalink / raw)
To: Ben Hutchings; +Cc: Stephen Hemminger, netdev
In-Reply-To: <1298378228.2211.472.camel@localhost>
Le mardi 22 février 2011 à 12:37 +0000, Ben Hutchings a écrit :
> On Mon, 2011-02-21 at 22:16 -0800, Stephen Hemminger wrote:
> [...]
> > The standard convention is to use -V for short form of version option.
>
> This is not anywhere near standard.
>
> $ cp -V
> cp: invalid option -- 'V'
> Try `cp --help' for more information.
> $ bash -V
> bash: -V: invalid option
> [...]
> $ emacs -V
> [opens window]
> $ vim -V
> chdir(/usr/share/vim)
> fchdir() to previous dir
> sourcing "$VIM/vimrc"
> [...looks like that meant 'verbose'...]
Now try with networking tools, many use -V
(As a matter of fact, ethtool -h already is used to display help)
# ping -V
ping utility, iputils-sss20071127
# tc -V
tc utility, iproute2-ss100823
# ssh -V
OpenSSH_5.1p1 Debian-5, OpenSSL 0.9.8g 19 Oct 2007
^ permalink raw reply
* Re: why all packets have same queue no when rps enabled?
From: Ben Hutchings @ 2011-02-22 13:09 UTC (permalink / raw)
To: Eric Dumazet; +Cc: Jon Zhou, netdev@vger.kernel.org
In-Reply-To: <1298379718.2861.3.camel@edumazet-laptop>
On Tue, 2011-02-22 at 14:01 +0100, Eric Dumazet wrote:
> Le mardi 22 février 2011 à 12:45 +0000, Ben Hutchings a écrit :
>
> > The queue number identifies a hardware queue. RPS therefore does not
> > update this number when queueing packets for processing on other CPUs.
> >
> > If the hardware/driver provides a receive hash (probably Toeplitz) then
> > this is used for RPS. Otherwise a much cheaper hash is used.
>
> The default is/should be : rxhash generated in network stack.
>
> ethtool -k eth0 | grep hash
> receive-hashing: off
>
> To use the device/harwdare provided rxhash, you need to ask for it.
>
> ethtool -K eth0 rxhash on
Whether this is enabled by default depends on the driver.
> BTW, I am not sure what you mean by "much cheaper hash is used"...
>
> I presume hardware provided hash is less expensive (for our cpu) than
> computing our rxhash...
I mean the hash function we use is much cheaper than Toeplitz.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH] rt2x00: Use ops name instead of device name
From: Steven Rostedt @ 2011-02-22 13:12 UTC (permalink / raw)
To: LKML, netdev; +Cc: Felix Fietkau, Ivo van Doorn, John W. Linville, abogani
Recently, someone complained that they see the PCI address of a device
in the interrupts file instead of the device name.
19: 73474106 0 IO-APIC-fasteoi ata_piix, uhci_hcd:usb6, 0000:05:01.0
>From lspci:
05:01.0 Network controller: RaLink RT2561/RT61 rev B 802.11g
Subsystem: D-Link System Inc AirPlus G DWL-G510 Wireless Network Adapter (Rev.C)
Flags: bus master, slow devsel, latency 32,
IRQ 19 Memory at f9100000 (32-bit, non-prefetchable) [size=32K]
Capabilities: <access denied>
Kernel driver in use: rt61pci
Kernel modules: rt61pci
Investigating this, it seems to be the result of the pci_name() used in
rt2x00pci_probe().
Since the struct rt2x00_ops records the module name for the device as
well as the ops, it would make more sense to show that in the interrupt
output instead.
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
index ace0b66..06575dc 100644
--- a/drivers/net/wireless/rt2x00/rt2x00pci.c
+++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
@@ -284,7 +284,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
rt2x00dev->ops = ops;
rt2x00dev->hw = hw;
rt2x00dev->irq = pci_dev->irq;
- rt2x00dev->name = pci_name(pci_dev);
+ rt2x00dev->name = ops->name;
if (pci_is_pcie(pci_dev))
rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
^ permalink raw reply related
* Re: [PATCH] rt2x00: Use ops name instead of device name
From: Ben Hutchings @ 2011-02-22 13:34 UTC (permalink / raw)
To: Steven Rostedt
Cc: LKML, netdev, Felix Fietkau, Ivo van Doorn, John W. Linville,
abogani
In-Reply-To: <1298380368.6140.1193.camel@gandalf.stny.rr.com>
On Tue, 2011-02-22 at 08:12 -0500, Steven Rostedt wrote:
> Recently, someone complained that they see the PCI address of a device
> in the interrupts file instead of the device name.
>
> 19: 73474106 0 IO-APIC-fasteoi ata_piix, uhci_hcd:usb6, 0000:05:01.0
[...]
> diff --git a/drivers/net/wireless/rt2x00/rt2x00pci.c b/drivers/net/wireless/rt2x00/rt2x00pci.c
> index ace0b66..06575dc 100644
> --- a/drivers/net/wireless/rt2x00/rt2x00pci.c
> +++ b/drivers/net/wireless/rt2x00/rt2x00pci.c
> @@ -284,7 +284,7 @@ int rt2x00pci_probe(struct pci_dev *pci_dev, const struct pci_device_id *id)
> rt2x00dev->ops = ops;
> rt2x00dev->hw = hw;
> rt2x00dev->irq = pci_dev->irq;
> - rt2x00dev->name = pci_name(pci_dev);
> + rt2x00dev->name = ops->name;
>
> if (pci_is_pcie(pci_dev))
> rt2x00_set_chip_intf(rt2x00dev, RT2X00_CHIP_INTF_PCIE);
But then how can users distinguish the IRQs for multiple devices handled
by the same driver? (Probably unusual for WLAN devices, but still
possible.)
I assume you can't use a net device name as there may be multiple net
devices per bus device?
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH] rt2x00: Use ops name instead of device name
From: Steven Rostedt @ 2011-02-22 13:44 UTC (permalink / raw)
To: Ben Hutchings
Cc: LKML, netdev, Felix Fietkau, Ivo van Doorn, John W. Linville,
abogani
In-Reply-To: <1298381695.2211.486.camel@localhost>
On Tue, 2011-02-22 at 13:34 +0000, Ben Hutchings wrote:
> > 19: 73474106 0 IO-APIC-fasteoi ata_piix, uhci_hcd:usb6, 0000:05:01.0
> > rt2x00dev->irq = pci_dev->irq;
> > - rt2x00dev->name = pci_name(pci_dev);
> > + rt2x00dev->name = ops->name;
> But then how can users distinguish the IRQs for multiple devices handled
> by the same driver? (Probably unusual for WLAN devices, but still
> possible.)
>
> I assume you can't use a net device name as there may be multiple net
> devices per bus device?
Honestly, I do not know this code well enough, but this patch seemed to
solve the problem at hand. Hence I sent it out to the experts hoping
they either take this patch or come up with a proper solution ;)
In any case, just posting the pci address is not a pretty answer.
-- Steve
^ permalink raw reply
* [PATCH] USB 10/100 RJ45 Ethernet Network Adapter
From: Shahar Havivi @ 2011-02-22 14:07 UTC (permalink / raw)
To: linux-usb, linux-kernel; +Cc: Peter Korsgaard, Greg Kroah-Hartman, netdev
The device is very similar to (0x0fe6, 0x8101),
And works well with dm9601 driver.
---
drivers/net/usb/dm9601.c | 5 +++++
1 files changed, 5 insertions(+), 0 deletions(-)
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 02b622e..2d1c8ae 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -654,6 +654,11 @@ static const struct usb_device_id products[] = {
USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
.driver_info = (unsigned long)&dm9601_info,
},
+ {
+ USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */
+
+ .driver_info = (unsigned long)&dm9601_info,
+ },
{}, // END
};
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH] USB 10/100 RJ45 Ethernet Network Adapter
From: Peter Korsgaard @ 2011-02-22 14:21 UTC (permalink / raw)
To: Shahar Havivi; +Cc: linux-usb, linux-kernel, Greg Kroah-Hartman, netdev
In-Reply-To: <20110222140705.GA6055@redhat.com>
>>>>> "Shahar" == Shahar Havivi <shaharh@redhat.com> writes:
Shahar> The device is very similar to (0x0fe6, 0x8101),
Shahar> And works well with dm9601 driver.
Shahar> ---
Shahar> drivers/net/usb/dm9601.c | 5 +++++
Shahar> 1 files changed, 5 insertions(+), 0 deletions(-)
Shahar> diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
Shahar> index 02b622e..2d1c8ae 100644
Shahar> --- a/drivers/net/usb/dm9601.c
Shahar> +++ b/drivers/net/usb/dm9601.c
Shahar> @@ -654,6 +654,11 @@ static const struct usb_device_id products[] = {
Shahar> USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
Shahar> .driver_info = (unsigned long)&dm9601_info,
Shahar> },
Shahar> + {
Shahar> + USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */
Shahar> +
Shahar> + .driver_info = (unsigned long)&dm9601_info,
Shahar> + },
Shahar> {}, // END
Please put it after the 0x8100 device and get rid of the empty line
before .driver_info - Otherwise it looks good.
Acked-by: Peter Korsgaard <jacmet@sunsite.dk>
--
Bye, Peter Korsgaard
^ permalink raw reply
* [PATCH-v2] Added support for usb ethernet (0x0fe6, 0x9700)
From: Shahar Havivi @ 2011-02-22 14:41 UTC (permalink / raw)
To: Peter Korsgaard; +Cc: linux-usb, linux-kernel, Greg Kroah-Hartman, netdev
The device is very similar to (0x0fe6, 0x8101),
And works well with dm9601 driver.
Signed-off-by: Shahar Havivi <shaharh@redhat.com>
---
v2:
Fix Peter Korsgaard comments:
got rid of empty line,
move after the 0x8101 device
---
drivers/net/usb/dm9601.c | 4 ++++
1 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/usb/dm9601.c b/drivers/net/usb/dm9601.c
index 02b622e..5002f5b 100644
--- a/drivers/net/usb/dm9601.c
+++ b/drivers/net/usb/dm9601.c
@@ -651,6 +651,10 @@ static const struct usb_device_id products[] = {
.driver_info = (unsigned long)&dm9601_info,
},
{
+ USB_DEVICE(0x0fe6, 0x9700), /* DM9601 USB to Fast Ethernet Adapter */
+ .driver_info = (unsigned long)&dm9601_info,
+ },
+ {
USB_DEVICE(0x0a46, 0x9000), /* DM9000E */
.driver_info = (unsigned long)&dm9601_info,
},
--
1.7.4
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox