* [net-next-2.6 04/08] r8169: 8168DP specific MII registers access methods.
From: Francois Romieu @ 2011-01-02 23:37 UTC (permalink / raw)
To: davem; +Cc: netdev, Hayes Wang, Ben Hutchings
Adapted from version 8.019.00 of Realtek's r8168 driver.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes <hayeswang@realtek.com>
---
drivers/net/r8169.c | 83 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 81 insertions(+), 2 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f9d8ff0..7f6fd12 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -277,6 +277,20 @@ enum rtl8168_8101_registers {
#define EFUSEAR_DATA_MASK 0xff
};
+enum rtl8168_registers {
+ EPHY_RXER_NUM = 0x7c,
+ OCPDR = 0xb0, /* OCP GPHY access */
+#define OCPDR_WRITE_CMD 0x80000000
+#define OCPDR_READ_CMD 0x00000000
+#define OCPDR_REG_MASK 0xff
+#define OCPDR_GPHY_REG_SHIFT 12
+#define OCPDR_DATA_MASK 0xffff
+ OCPAR = 0xb4,
+#define OCPAR_FLAG 0x80000000
+#define OCPAR_GPHY_WRITE_CMD 0x8000f060
+#define OCPAR_GPHY_READ_CMD 0x0000f060
+};
+
enum rtl_register_content {
/* InterruptStatusBits */
SYSErr = 0x8000,
@@ -500,6 +514,12 @@ struct rtl8169_private {
#ifdef CONFIG_R8169_VLAN
struct vlan_group *vlgrp;
#endif
+
+ struct mdio_ops {
+ void (*write)(void __iomem *, int, int);
+ int (*read)(void __iomem *, int);
+ } mdio_ops;
+
int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
void (*phy_reset_enable)(struct rtl8169_private *tp);
@@ -595,14 +615,55 @@ static int r8169_mdio_read(void __iomem *ioaddr, int reg_addr)
return value;
}
+static void r8168dp_1_mdio_access(void __iomem *ioaddr, int reg_addr, u32 data)
+{
+ int i;
+
+ RTL_W32(OCPDR, data |
+ ((reg_addr & OCPDR_REG_MASK) << OCPDR_GPHY_REG_SHIFT));
+ RTL_W32(OCPAR, OCPAR_GPHY_WRITE_CMD);
+ RTL_W32(EPHY_RXER_NUM, 0);
+
+ for (i = 0; i < 100; i++) {
+ mdelay(1);
+ if (!(RTL_R32(OCPAR) & OCPAR_FLAG))
+ break;
+ }
+}
+
+static void r8168dp_1_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+{
+ r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_WRITE_CMD |
+ (value & OCPDR_DATA_MASK));
+}
+
+static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr)
+{
+ int i;
+
+ r8168dp_1_mdio_access(ioaddr, reg_addr, OCPDR_READ_CMD);
+
+ mdelay(1);
+ RTL_W32(OCPAR, OCPAR_GPHY_READ_CMD);
+ RTL_W32(EPHY_RXER_NUM, 0);
+
+ for (i = 0; i < 100; i++) {
+ mdelay(1);
+ if (RTL_R32(OCPAR) & OCPAR_FLAG)
+ break;
+ }
+
+ return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
+}
+
static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
{
- r8169_mdio_write(tp->mmio_addr, location, val);
+ tp->mdio_ops.write(tp->mmio_addr, location, val);
}
static int rtl_readphy(struct rtl8169_private *tp, int location)
{
- return r8169_mdio_read(tp->mmio_addr, location);
+ return tp->mdio_ops.read(tp->mmio_addr, location);
}
static void rtl_patchphy(struct rtl8169_private *tp, int reg_addr, int value)
@@ -2474,6 +2535,22 @@ static const struct net_device_ops rtl8169_netdev_ops = {
};
+static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
+{
+ struct mdio_ops *ops = &tp->mdio_ops;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_27:
+ ops->write = r8168dp_1_mdio_write;
+ ops->read = r8168dp_1_mdio_read;
+ break;
+ default:
+ ops->write = r8169_mdio_write;
+ ops->read = r8169_mdio_read;
+ break;
+ }
+}
+
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -2592,6 +2669,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* Identify chip attached to board */
rtl8169_get_mac_version(tp, ioaddr);
+ rtl_init_mdio_ops(tp);
+
/* Use appropriate default if unknown */
if (tp->mac_version == RTL_GIGA_MAC_NONE) {
netif_notice(tp, probe, dev,
--
1.7.3.4
^ permalink raw reply related
* [net-next-2.6 05/08] r8169: phy power ops
From: Francois Romieu @ 2011-01-02 23:37 UTC (permalink / raw)
To: davem; +Cc: netdev, Hayes Wang, Ben Hutchings
Bits from :
- version 8.019.00 of Realtek's 8168 driver
- version 1.019.00 of Realtek's 8101 driver
Plain old 8169 (PCI) devices do not seem to need anything akin to it.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes <hayeswang@realtek.com>
---
drivers/net/r8169.c | 167 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 166 insertions(+), 1 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 7f6fd12..fd7e40a 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -258,7 +258,7 @@ enum rtl8168_8101_registers {
#define CSIAR_BYTE_ENABLE 0x0f
#define CSIAR_BYTE_ENABLE_SHIFT 12
#define CSIAR_ADDR_MASK 0x0fff
-
+ PMCH = 0x6f,
EPHYAR = 0x80,
#define EPHYAR_FLAG 0x80000000
#define EPHYAR_WRITE_CMD 0x80000000
@@ -520,6 +520,11 @@ struct rtl8169_private {
int (*read)(void __iomem *, int);
} mdio_ops;
+ struct pll_power_ops {
+ void (*down)(struct rtl8169_private *);
+ void (*up)(struct rtl8169_private *);
+ } pll_power_ops;
+
int (*set_speed)(struct net_device *, u8 autoneg, u16 speed, u8 duplex);
int (*get_settings)(struct net_device *, struct ethtool_cmd *);
void (*phy_reset_enable)(struct rtl8169_private *tp);
@@ -2551,6 +2556,152 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
}
}
+static void r810x_phy_power_down(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+}
+
+static void r810x_phy_power_up(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
+}
+
+static void r810x_pll_power_down(struct rtl8169_private *tp)
+{
+ if (__rtl8169_get_wol(tp) & WAKE_ANY) {
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, 0x0000);
+ return;
+ }
+
+ r810x_phy_power_down(tp);
+}
+
+static void r810x_pll_power_up(struct rtl8169_private *tp)
+{
+ r810x_phy_power_up(tp);
+}
+
+static void r8168_phy_power_up(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x0e, 0x0000);
+ rtl_writephy(tp, MII_BMCR, BMCR_ANENABLE);
+}
+
+static void r8168_phy_power_down(struct rtl8169_private *tp)
+{
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, 0x0e, 0x0200);
+ rtl_writephy(tp, MII_BMCR, BMCR_PDOWN);
+}
+
+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)
+ return;
+
+ if (((tp->mac_version == RTL_GIGA_MAC_VER_23) ||
+ (tp->mac_version == RTL_GIGA_MAC_VER_24)) &&
+ (RTL_R16(CPlusCmd) & ASF)) {
+ return;
+ }
+
+ if (__rtl8169_get_wol(tp) & WAKE_ANY) {
+ rtl_writephy(tp, 0x1f, 0x0000);
+ rtl_writephy(tp, MII_BMCR, 0x0000);
+
+ RTL_W32(RxConfig, RTL_R32(RxConfig) |
+ AcceptBroadcast | AcceptMulticast | AcceptMyPhys);
+ return;
+ }
+
+ r8168_phy_power_down(tp);
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ RTL_W8(PMCH, RTL_R8(PMCH) & ~0x80);
+ break;
+ }
+}
+
+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)
+ return;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ RTL_W8(PMCH, RTL_R8(PMCH) | 0x80);
+ break;
+ }
+
+ r8168_phy_power_up(tp);
+}
+
+static void rtl_pll_power_op(struct rtl8169_private *tp,
+ void (*op)(struct rtl8169_private *))
+{
+ if (op)
+ op(tp);
+}
+
+static void rtl_pll_power_down(struct rtl8169_private *tp)
+{
+ rtl_pll_power_op(tp, tp->pll_power_ops.down);
+}
+
+static void rtl_pll_power_up(struct rtl8169_private *tp)
+{
+ rtl_pll_power_op(tp, tp->pll_power_ops.up);
+}
+
+static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
+{
+ struct pll_power_ops *ops = &tp->pll_power_ops;
+
+ switch (tp->mac_version) {
+ case RTL_GIGA_MAC_VER_07:
+ case RTL_GIGA_MAC_VER_08:
+ case RTL_GIGA_MAC_VER_09:
+ case RTL_GIGA_MAC_VER_10:
+ case RTL_GIGA_MAC_VER_16:
+ ops->down = r810x_pll_power_down;
+ ops->up = r810x_pll_power_up;
+ break;
+
+ case RTL_GIGA_MAC_VER_11:
+ case RTL_GIGA_MAC_VER_12:
+ case RTL_GIGA_MAC_VER_17:
+ case RTL_GIGA_MAC_VER_18:
+ case RTL_GIGA_MAC_VER_19:
+ case RTL_GIGA_MAC_VER_20:
+ case RTL_GIGA_MAC_VER_21:
+ case RTL_GIGA_MAC_VER_22:
+ case RTL_GIGA_MAC_VER_23:
+ case RTL_GIGA_MAC_VER_24:
+ case RTL_GIGA_MAC_VER_25:
+ case RTL_GIGA_MAC_VER_26:
+ case RTL_GIGA_MAC_VER_27:
+ ops->down = r8168_pll_power_down;
+ ops->up = r8168_pll_power_up;
+ break;
+
+ default:
+ ops->down = NULL;
+ ops->up = NULL;
+ break;
+ }
+}
+
static int __devinit
rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
{
@@ -2670,6 +2821,7 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rtl8169_get_mac_version(tp, ioaddr);
rtl_init_mdio_ops(tp);
+ rtl_init_pll_power_ops(tp);
/* Use appropriate default if unknown */
if (tp->mac_version == RTL_GIGA_MAC_NONE) {
@@ -2849,6 +3001,8 @@ static int rtl8169_open(struct net_device *dev)
napi_enable(&tp->napi);
+ rtl_pll_power_up(tp);
+
rtl_hw_start(dev);
rtl8169_request_timer(dev);
@@ -4257,6 +4411,8 @@ static void rtl8169_down(struct net_device *dev)
rtl8169_tx_clear(tp);
rtl8169_rx_clear(tp);
+
+ rtl_pll_power_down(tp);
}
static int rtl8169_close(struct net_device *dev)
@@ -4361,9 +4517,13 @@ static struct net_device_stats *rtl8169_get_stats(struct net_device *dev)
static void rtl8169_net_suspend(struct net_device *dev)
{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
if (!netif_running(dev))
return;
+ rtl_pll_power_down(tp);
+
netif_device_detach(dev);
netif_stop_queue(dev);
}
@@ -4382,7 +4542,12 @@ static int rtl8169_suspend(struct device *device)
static void __rtl8169_resume(struct net_device *dev)
{
+ struct rtl8169_private *tp = netdev_priv(dev);
+
netif_device_attach(dev);
+
+ rtl_pll_power_up(tp);
+
rtl8169_schedule_work(dev, rtl8169_reset_task);
}
--
1.7.3.4
^ permalink raw reply related
* [net-next-2.6 06/08] r8169: magic.
From: Francois Romieu @ 2011-01-02 23:37 UTC (permalink / raw)
To: davem; +Cc: netdev, Hayes Wang, Ben Hutchings
Adapted from version 8.019.00 of Realtek's r8168 driver.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes <hayeswang@realtek.com>
---
drivers/net/r8169.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 93 insertions(+), 0 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index fd7e40a..ab1741d 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -278,6 +278,18 @@ enum rtl8168_8101_registers {
};
enum rtl8168_registers {
+ ERIDR = 0x70,
+ ERIAR = 0x74,
+#define ERIAR_FLAG 0x80000000
+#define ERIAR_WRITE_CMD 0x80000000
+#define ERIAR_READ_CMD 0x00000000
+#define ERIAR_ADDR_BYTE_ALIGN 4
+#define ERIAR_EXGMAC 0
+#define ERIAR_MSIX 1
+#define ERIAR_ASF 2
+#define ERIAR_TYPE_SHIFT 16
+#define ERIAR_BYTEEN 0x0f
+#define ERIAR_BYTEEN_SHIFT 12
EPHY_RXER_NUM = 0x7c,
OCPDR = 0xb0, /* OCP GPHY access */
#define OCPDR_WRITE_CMD 0x80000000
@@ -572,6 +584,81 @@ static int rtl8169_poll(struct napi_struct *napi, int budget);
static const unsigned int rtl8169_rx_config =
(RX_FIFO_THRESH << RxCfgFIFOShift) | (RX_DMA_BURST << RxCfgDMAShift);
+static u32 ocp_read(struct rtl8169_private *tp, u8 mask, u16 reg)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ int i;
+
+ RTL_W32(OCPAR, ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
+ for (i = 0; i < 20; i++) {
+ udelay(100);
+ if (RTL_R32(OCPAR) & OCPAR_FLAG)
+ break;
+ }
+ return RTL_R32(OCPDR);
+}
+
+static void ocp_write(struct rtl8169_private *tp, u8 mask, u16 reg, u32 data)
+{
+ void __iomem *ioaddr = tp->mmio_addr;
+ int i;
+
+ RTL_W32(OCPDR, data);
+ RTL_W32(OCPAR, OCPAR_FLAG | ((u32)mask & 0x0f) << 12 | (reg & 0x0fff));
+ for (i = 0; i < 20; i++) {
+ udelay(100);
+ if ((RTL_R32(OCPAR) & OCPAR_FLAG) == 0)
+ break;
+ }
+}
+
+static void rtl8168_oob_notify(void __iomem *ioaddr, u8 cmd)
+{
+ int i;
+
+ RTL_W8(ERIDR, cmd);
+ RTL_W32(ERIAR, 0x800010e8);
+ msleep(2);
+ for (i = 0; i < 5; i++) {
+ udelay(100);
+ if (!(RTL_R32(ERIDR) & ERIAR_FLAG))
+ break;
+ }
+
+ ocp_write(ioaddr, 0x1, 0x30, 0x00000001);
+}
+
+#define OOB_CMD_RESET 0x00
+#define OOB_CMD_DRIVER_START 0x05
+#define OOB_CMD_DRIVER_STOP 0x06
+
+static void rtl8168_driver_start(struct rtl8169_private *tp)
+{
+ int i;
+
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_START);
+
+ for (i = 0; i < 10; i++) {
+ msleep(10);
+ if (ocp_read(tp, 0x0f, 0x0010) & 0x00000800)
+ break;
+ }
+}
+
+static void rtl8168_driver_stop(struct rtl8169_private *tp)
+{
+ int i;
+
+ rtl8168_oob_notify(tp, OOB_CMD_DRIVER_STOP);
+
+ for (i = 0; i < 10; i++) {
+ msleep(10);
+ if ((ocp_read(tp, 0x0f, 0x0010) & 0x00000800) == 0)
+ break;
+ }
+}
+
+
static void r8169_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
{
int i;
@@ -2913,6 +3000,9 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->base_addr, dev->dev_addr,
(u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27)
+ rtl8168_driver_start(tp);
+
rtl8169_init_phy(dev, tp);
/*
@@ -2948,6 +3038,9 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
+ if (tp->mac_version == RTL_GIGA_MAC_VER_27)
+ rtl8168_driver_stop(tp);
+
cancel_delayed_work_sync(&tp->task);
unregister_netdev(dev);
--
1.7.3.4
^ permalink raw reply related
* [net-next-2.6 07/08] r8169: rtl_csi_access_enable rename.
From: Francois Romieu @ 2011-01-02 23:37 UTC (permalink / raw)
To: davem; +Cc: netdev, Hayes Wang, Ben Hutchings
Newer 8168 needs a slightly different rtl_csi_access_enable.
This patch separates some noise from the real thing.
No functional change.
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes <hayeswang@realtek.com>
---
drivers/net/r8169.c | 27 ++++++++++++++++-----------
1 files changed, 16 insertions(+), 11 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index ab1741d..a8df458 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3310,12 +3310,17 @@ static void rtl_tx_performance_tweak(struct pci_dev *pdev, u16 force)
}
}
-static void rtl_csi_access_enable(void __iomem *ioaddr)
+static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits)
{
u32 csi;
csi = rtl_csi_read(ioaddr, 0x070c) & 0x00ffffff;
- rtl_csi_write(ioaddr, 0x070c, csi | 0x27000000);
+ rtl_csi_write(ioaddr, 0x070c, csi | bits);
+}
+
+static void rtl_csi_access_enable_2(void __iomem *ioaddr)
+{
+ rtl_csi_access_enable(ioaddr, 0x27000000);
}
struct ephy_info {
@@ -3403,7 +3408,7 @@ static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x07, 0, 0x2000 }
};
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_ephy_init(ioaddr, e_info_8168cp, ARRAY_SIZE(e_info_8168cp));
@@ -3412,7 +3417,7 @@ static void rtl_hw_start_8168cp_1(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
@@ -3423,7 +3428,7 @@ static void rtl_hw_start_8168cp_2(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8168cp_3(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(Config3, RTL_R8(Config3) & ~Beacon_en);
@@ -3445,7 +3450,7 @@ static void rtl_hw_start_8168c_1(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x06, 0x0080, 0x0000 }
};
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(DBG_REG, 0x06 | FIX_NAK_1 | FIX_NAK_2);
@@ -3461,7 +3466,7 @@ static void rtl_hw_start_8168c_2(void __iomem *ioaddr, struct pci_dev *pdev)
{ 0x03, 0x0400, 0x0220 }
};
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_ephy_init(ioaddr, e_info_8168c_2, ARRAY_SIZE(e_info_8168c_2));
@@ -3475,14 +3480,14 @@ static void rtl_hw_start_8168c_3(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8168c_4(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
__rtl_hw_start_8168cp(ioaddr, pdev);
}
static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_disable_clock_request(pdev);
@@ -3611,7 +3616,7 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
};
u8 cfg1;
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
RTL_W8(DBG_REG, FIX_NAK_1);
@@ -3632,7 +3637,7 @@ static void rtl_hw_start_8102e_1(void __iomem *ioaddr, struct pci_dev *pdev)
static void rtl_hw_start_8102e_2(void __iomem *ioaddr, struct pci_dev *pdev)
{
- rtl_csi_access_enable(ioaddr);
+ rtl_csi_access_enable_2(ioaddr);
rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
--
1.7.3.4
^ permalink raw reply related
* [net-next-2.6 08/08] r8169: more 8168dp support.
From: Francois Romieu @ 2011-01-02 23:37 UTC (permalink / raw)
To: davem; +Cc: netdev, Hayes Wang, Ben Hutchings
Adapted from version 8.019.00 of Realtek's r8168 driver
Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
Cc: Hayes <hayeswang@realtek.com>
---
drivers/net/r8169.c | 145 +++++++++++++++++++++++++++++++++++++++++++++++---
1 files changed, 136 insertions(+), 9 deletions(-)
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index a8df458..f13194f 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -121,7 +121,8 @@ enum mac_version {
RTL_GIGA_MAC_VER_24 = 0x18, // 8168CP
RTL_GIGA_MAC_VER_25 = 0x19, // 8168D
RTL_GIGA_MAC_VER_26 = 0x1a, // 8168D
- RTL_GIGA_MAC_VER_27 = 0x1b // 8168DP
+ RTL_GIGA_MAC_VER_27 = 0x1b, // 8168DP
+ RTL_GIGA_MAC_VER_28 = 0x1c, // 8168DP
};
#define _R(NAME,MAC,MASK) \
@@ -158,7 +159,8 @@ static const struct {
_R("RTL8168cp/8111cp", RTL_GIGA_MAC_VER_24, 0xff7e1880), // PCI-E
_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_27, 0xff7e1880), // PCI-E
+ _R("RTL8168dp/8111dp", RTL_GIGA_MAC_VER_28, 0xff7e1880) // PCI-E
};
#undef _R
@@ -301,6 +303,7 @@ enum rtl8168_registers {
#define OCPAR_FLAG 0x80000000
#define OCPAR_GPHY_WRITE_CMD 0x8000f060
#define OCPAR_GPHY_READ_CMD 0x0000f060
+ RDSAR1 = 0xd0 /* 8168c only. Undocumented on 8168dp */
};
enum rtl_register_content {
@@ -748,6 +751,40 @@ static int r8168dp_1_mdio_read(void __iomem *ioaddr, int reg_addr)
return RTL_R32(OCPDR) & OCPDR_DATA_MASK;
}
+#define R8168DP_1_MDIO_ACCESS_BIT 0x00020000
+
+static void r8168dp_2_mdio_start(void __iomem *ioaddr)
+{
+ RTL_W32(0xd0, RTL_R32(0xd0) & ~R8168DP_1_MDIO_ACCESS_BIT);
+}
+
+static void r8168dp_2_mdio_stop(void __iomem *ioaddr)
+{
+ RTL_W32(0xd0, RTL_R32(0xd0) | R8168DP_1_MDIO_ACCESS_BIT);
+}
+
+static void r8168dp_2_mdio_write(void __iomem *ioaddr, int reg_addr, int value)
+{
+ r8168dp_2_mdio_start(ioaddr);
+
+ r8169_mdio_write(ioaddr, reg_addr, value);
+
+ r8168dp_2_mdio_stop(ioaddr);
+}
+
+static int r8168dp_2_mdio_read(void __iomem *ioaddr, int reg_addr)
+{
+ int value;
+
+ r8168dp_2_mdio_start(ioaddr);
+
+ value = r8169_mdio_read(ioaddr, reg_addr);
+
+ r8168dp_2_mdio_stop(ioaddr);
+
+ return value;
+}
+
static void rtl_writephy(struct rtl8169_private *tp, int location, u32 val)
{
tp->mdio_ops.write(tp->mmio_addr, location, val);
@@ -1495,9 +1532,12 @@ static void rtl8169_get_mac_version(struct rtl8169_private *tp,
/* 8168D family. */
{ 0x7cf00000, 0x28300000, RTL_GIGA_MAC_VER_26 },
{ 0x7cf00000, 0x28100000, RTL_GIGA_MAC_VER_25 },
- { 0x7c800000, 0x28800000, RTL_GIGA_MAC_VER_27 },
{ 0x7c800000, 0x28000000, RTL_GIGA_MAC_VER_26 },
+ /* 8168DP family. */
+ { 0x7cf00000, 0x28800000, RTL_GIGA_MAC_VER_27 },
+ { 0x7cf00000, 0x28a00000, RTL_GIGA_MAC_VER_28 },
+
/* 8168C family. */
{ 0x7cf00000, 0x3cb00000, RTL_GIGA_MAC_VER_24 },
{ 0x7cf00000, 0x3c900000, RTL_GIGA_MAC_VER_23 },
@@ -2246,6 +2286,22 @@ static void rtl8168d_3_hw_phy_config(struct rtl8169_private *tp)
rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
}
+static void rtl8168d_4_hw_phy_config(struct rtl8169_private *tp)
+{
+ static const struct phy_reg phy_reg_init[] = {
+ { 0x1f, 0x0001 },
+ { 0x17, 0x0cc0 },
+
+ { 0x1f, 0x0007 },
+ { 0x1e, 0x002d },
+ { 0x18, 0x0040 },
+ { 0x1f, 0x0000 }
+ };
+
+ rtl_writephy_batch(tp, phy_reg_init, ARRAY_SIZE(phy_reg_init));
+ rtl_patchphy(tp, 0x0d, 1 << 5);
+}
+
static void rtl8102e_hw_phy_config(struct rtl8169_private *tp)
{
static const struct phy_reg phy_reg_init[] = {
@@ -2327,6 +2383,9 @@ static void rtl_hw_phy_config(struct net_device *dev)
case RTL_GIGA_MAC_VER_27:
rtl8168d_3_hw_phy_config(tp);
break;
+ case RTL_GIGA_MAC_VER_28:
+ rtl8168d_4_hw_phy_config(tp);
+ break;
default:
break;
@@ -2636,6 +2695,10 @@ static void __devinit rtl_init_mdio_ops(struct rtl8169_private *tp)
ops->write = r8168dp_1_mdio_write;
ops->read = r8168dp_1_mdio_read;
break;
+ case RTL_GIGA_MAC_VER_28:
+ ops->write = r8168dp_2_mdio_write;
+ ops->read = r8168dp_2_mdio_read;
+ break;
default:
ops->write = r8169_mdio_write;
ops->read = r8169_mdio_read;
@@ -2778,6 +2841,7 @@ static void __devinit rtl_init_pll_power_ops(struct rtl8169_private *tp)
case RTL_GIGA_MAC_VER_25:
case RTL_GIGA_MAC_VER_26:
case RTL_GIGA_MAC_VER_27:
+ case RTL_GIGA_MAC_VER_28:
ops->down = r8168_pll_power_down;
ops->up = r8168_pll_power_up;
break;
@@ -3000,8 +3064,10 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
dev->base_addr, dev->dev_addr,
(u32)(RTL_R32(TxConfig) & 0x9cf0f8ff), dev->irq);
- 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)) {
rtl8168_driver_start(tp);
+ }
rtl8169_init_phy(dev, tp);
@@ -3038,8 +3104,10 @@ static void __devexit rtl8169_remove_one(struct pci_dev *pdev)
struct net_device *dev = pci_get_drvdata(pdev);
struct rtl8169_private *tp = netdev_priv(dev);
- 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)) {
rtl8168_driver_stop(tp);
+ }
cancel_delayed_work_sync(&tp->task);
@@ -3122,11 +3190,19 @@ err_pm_runtime_put:
goto out;
}
-static void rtl8169_hw_reset(void __iomem *ioaddr)
+static void rtl8169_hw_reset(struct rtl8169_private *tp)
{
+ void __iomem *ioaddr = tp->mmio_addr;
+
/* Disable interrupts */
rtl8169_irq_mask_and_ack(ioaddr);
+ if (tp->mac_version == RTL_GIGA_MAC_VER_28) {
+ while (RTL_R8(TxPoll) & NPQ)
+ udelay(20);
+
+ }
+
/* Reset the chipset */
RTL_W8(ChipCmd, CmdReset);
@@ -3318,6 +3394,11 @@ static void rtl_csi_access_enable(void __iomem *ioaddr, u32 bits)
rtl_csi_write(ioaddr, 0x070c, csi | bits);
}
+static void rtl_csi_access_enable_1(void __iomem *ioaddr)
+{
+ rtl_csi_access_enable(ioaddr, 0x17000000);
+}
+
static void rtl_csi_access_enable_2(void __iomem *ioaddr)
{
rtl_csi_access_enable(ioaddr, 0x27000000);
@@ -3355,6 +3436,21 @@ static void rtl_disable_clock_request(struct pci_dev *pdev)
}
}
+static void rtl_enable_clock_request(struct pci_dev *pdev)
+{
+ struct net_device *dev = pci_get_drvdata(pdev);
+ struct rtl8169_private *tp = netdev_priv(dev);
+ int cap = tp->pcie_cap;
+
+ if (cap) {
+ u16 ctl;
+
+ pci_read_config_word(pdev, cap + PCI_EXP_LNKCTL, &ctl);
+ ctl |= PCI_EXP_LNKCTL_CLKREQ_EN;
+ pci_write_config_word(pdev, cap + PCI_EXP_LNKCTL, ctl);
+ }
+}
+
#define R8168_CPCMD_QUIRK_MASK (\
EnableBist | \
Mac_dbgo_oe | \
@@ -3498,6 +3594,32 @@ static void rtl_hw_start_8168d(void __iomem *ioaddr, struct pci_dev *pdev)
RTL_W16(CPlusCmd, RTL_R16(CPlusCmd) & ~R8168_CPCMD_QUIRK_MASK);
}
+static void rtl_hw_start_8168d_4(void __iomem *ioaddr, struct pci_dev *pdev)
+{
+ static const struct ephy_info e_info_8168d_4[] = {
+ { 0x0b, ~0, 0x48 },
+ { 0x19, 0x20, 0x50 },
+ { 0x0c, ~0, 0x20 }
+ };
+ int i;
+
+ rtl_csi_access_enable_1(ioaddr);
+
+ rtl_tx_performance_tweak(pdev, 0x5 << MAX_READ_REQUEST_SHIFT);
+
+ RTL_W8(MaxTxPacketSize, TxPacketMax);
+
+ for (i = 0; i < ARRAY_SIZE(e_info_8168d_4); i++) {
+ const struct ephy_info *e = e_info_8168d_4 + i;
+ u16 w;
+
+ w = rtl_ephy_read(ioaddr, e->offset);
+ rtl_ephy_write(ioaddr, 0x03, (w & e->mask) | e->bits);
+ }
+
+ rtl_enable_clock_request(pdev);
+}
+
static void rtl_hw_start_8168(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
@@ -3575,6 +3697,10 @@ static void rtl_hw_start_8168(struct net_device *dev)
rtl_hw_start_8168d(ioaddr, pdev);
break;
+ case RTL_GIGA_MAC_VER_28:
+ rtl_hw_start_8168d_4(ioaddr, pdev);
+ break;
+
default:
printk(KERN_ERR PFX "%s: unknown chipset (mac_version = %d).\n",
dev->name, tp->mac_version);
@@ -3987,7 +4113,7 @@ static void rtl8169_tx_timeout(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
- rtl8169_hw_reset(tp->mmio_addr);
+ rtl8169_hw_reset(tp);
/* Let's wait a bit while any (async) irq lands on */
rtl8169_schedule_work(dev, rtl8169_reset_task);
@@ -4145,7 +4271,6 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
{
struct rtl8169_private *tp = netdev_priv(dev);
struct pci_dev *pdev = tp->pci_dev;
- void __iomem *ioaddr = tp->mmio_addr;
u16 pci_status, pci_cmd;
pci_read_config_word(pdev, PCI_COMMAND, &pci_cmd);
@@ -4176,13 +4301,15 @@ static void rtl8169_pcierr_interrupt(struct net_device *dev)
/* The infamous DAC f*ckup only happens at boot time */
if ((tp->cp_cmd & PCIDAC) && !tp->dirty_rx && !tp->cur_rx) {
+ void __iomem *ioaddr = tp->mmio_addr;
+
netif_info(tp, intr, dev, "disabling PCI DAC\n");
tp->cp_cmd &= ~PCIDAC;
RTL_W16(CPlusCmd, tp->cp_cmd);
dev->features &= ~NETIF_F_HIGHDMA;
}
- rtl8169_hw_reset(ioaddr);
+ rtl8169_hw_reset(tp);
rtl8169_schedule_work(dev, rtl8169_reinit_task);
}
--
1.7.3.4
^ permalink raw reply related
* [PATCH] ksz884x: Fix section mismatch derived from pci_device_driver variable
From: Sedat Dilek @ 2011-01-03 2:01 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: Sedat Dilek
WARNING: drivers/net/ksz884x.o(.data+0x18): Section mismatch in reference from the variable pci_device_driver to the function .init.text:pcidev_init()
The variable pci_device_driver references
the function __init pcidev_init()
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console,
This patch fixes the warning.
Tested with linux-next (next-20101231)
Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
---
drivers/net/ksz884x.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/ksz884x.c b/drivers/net/ksz884x.c
index 49ea870..515b0d7 100644
--- a/drivers/net/ksz884x.c
+++ b/drivers/net/ksz884x.c
@@ -7277,7 +7277,7 @@ static struct pci_device_id pcidev_table[] = {
MODULE_DEVICE_TABLE(pci, pcidev_table);
-static struct pci_driver pci_device_driver = {
+static struct pci_driver pci_device_driver __refdata = {
#ifdef CONFIG_PM
.suspend = pcidev_suspend,
.resume = pcidev_resume,
--
1.7.4.rc0
^ permalink raw reply related
* Re: [net-next-2.6 PATCH v2 0/3] Series short description
From: John Fastabend @ 2011-01-03 2:27 UTC (permalink / raw)
To: David Miller; +Cc: netdev@vger.kernel.org, Liu, Lucy, shmulikr@broadcom.com
In-Reply-To: <20101231.104941.189703153.davem@davemloft.net>
On 12/31/2010 10:49 AM, David Miller wrote:
> From: John Fastabend <john.r.fastabend@intel.com>
> Date: Thu, 30 Dec 2010 11:25:40 -0800
>
>> Version 2 adds the recommended tlv attributes to the ets struct this will
>> be needed for offloaded LLDP engines. Host controlled LLDP agents will most
>> likely not use these fields.
>>
>> Also Shmulik Ravid caught an error with a spin_lock on kmalloc failure.
>
> BTW, even though I replied "applied" to v1 of these patches I made
> sure to actully apply v2 :-)
> --
Thanks David.
^ permalink raw reply
* [PATCH] smsc-ircc2: Fix section mismatch derived from smsc_ircc_pnp_driver variable
From: Sedat Dilek @ 2011-01-03 2:28 UTC (permalink / raw)
To: samuel, netdev, linux-kernel; +Cc: Sedat Dilek
>From my build.log:
drivers/net/irda/smsc-ircc2.o(.data+0x18): Section mismatch in reference from the variable smsc_ircc_pnp_driver to the function .init.text:smsc_ircc_pnp_probe()
The variable smsc_ircc_pnp_driver references
the function __init smsc_ircc_pnp_probe()
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console,
This patch fixes the warning.
Tested with linux-next (next-20101231)
Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
---
drivers/net/irda/smsc-ircc2.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/irda/smsc-ircc2.c b/drivers/net/irda/smsc-ircc2.c
index 8c57bfb..0ebd4a8 100644
--- a/drivers/net/irda/smsc-ircc2.c
+++ b/drivers/net/irda/smsc-ircc2.c
@@ -397,7 +397,7 @@ static int __init smsc_ircc_pnp_probe(struct pnp_dev *dev,
return 0;
}
-static struct pnp_driver smsc_ircc_pnp_driver = {
+static struct pnp_driver smsc_ircc_pnp_driver __refdata = {
.name = "smsc-ircc2",
.id_table = smsc_ircc_pnp_table,
.probe = smsc_ircc_pnp_probe,
--
1.7.4.rc0
^ permalink raw reply related
* [PATCH] depca: Fix section mismatch derived from depca_isa_driver variable
From: Sedat Dilek @ 2011-01-03 2:33 UTC (permalink / raw)
To: netdev, linux-kernel; +Cc: Sedat Dilek
>From my build.log:
WARNING: drivers/net/depca.o(.data+0x0): Section mismatch in reference from the variable depca_isa_driver to the function .init.text:depca_isa_probe()
The variable depca_isa_driver references
the function __init depca_isa_probe()
If the reference is valid then annotate the
variable with __init* or __refdata (see linux/init.h) or name the variable:
*_template, *_timer, *_sht, *_ops, *_probe, *_probe_one, *_console,
This patch fixes the warning.
Tested with linux-next (next-20101231)
Signed-off-by: Sedat Dilek <sedat.dilek@gmail.com>
---
drivers/net/depca.c | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 91b3846..dfaf746 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -405,7 +405,7 @@ static int __devexit depca_isa_remove(struct platform_device *pdev)
return depca_device_remove(&pdev->dev);
}
-static struct platform_driver depca_isa_driver = {
+static struct platform_driver depca_isa_driver __refdata = {
.probe = depca_isa_probe,
.remove = __devexit_p(depca_isa_remove),
.driver = {
--
1.7.4.rc0
^ permalink raw reply related
* Re: [net-next-2.6 PATCH v2 2/4] dcbnl: adding DCBX feature flags get-set
From: John Fastabend @ 2011-01-03 2:38 UTC (permalink / raw)
To: Shmulik Ravid
Cc: davem@davemloft.net, Eilon Greenstein, Liu, Lucy,
netdev@vger.kernel.org
In-Reply-To: <1293984061.29378.101.camel@lb-tlvb-shmulik.il.broadcom.com>
On 1/2/2011 8:01 AM, Shmulik Ravid wrote:
>
>> One more nit ;)
>>
>>> +
>>> + ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
>>> + dcbnl_featcfg_nest);
>>> + if (ret) {
>>> + ret = -EINVAL;
>>> + goto err_out;
>>> + }
>>
>> Why do you set EINVAL here if you use the returned error code from nla_parse_nested you get a more descriptive error. See ./lib/nlattr.c:nla_parse()/validate_nla().
>>
>> [...]
>>
>>> +static int dcbnl_setfeatcfg(struct net_device *netdev, struct nlattr **tb,
>>> + u32 pid, u32 seq, u16 flags)
>>> +{
>>> + struct nlattr *data[DCB_FEATCFG_ATTR_MAX + 1];
>>> + int ret = -EINVAL;
>>> + u8 value;
>>> + int i;
>>> +
>>> + if (!tb[DCB_ATTR_FEATCFG] || !netdev->dcbnl_ops->setfeatcfg)
>>> + return ret;
>>> +
>>> + ret = nla_parse_nested(data, DCB_FEATCFG_ATTR_MAX, tb[DCB_ATTR_FEATCFG],
>>> + dcbnl_featcfg_nest);
>>> +
>>> + if (ret) {
>>> + ret = -EINVAL;
>>> + goto err;
>>> + }
>>
>> Same here.
>>
>
> I'll send a patch with the improved return values for the the new dcbnl
> routines. While I'm at it, is it safe to fix on the same lines the
> older already established dcbnl routines?
This should be safe I would not expect using more accurate error values could hurt any existing applications. Be sure to make it a separate patch though.
John
^ permalink raw reply
* Re: [net-next-2.6 02/08] r8169: identify different registers.
From: Ben Hutchings @ 2011-01-03 2:52 UTC (permalink / raw)
To: Francois Romieu; +Cc: davem, netdev, Hayes Wang, David Woodhouse
In-Reply-To: <20110102233617.GC5780@electric-eye.fr.zoreil.com>
[-- Attachment #1: Type: text/plain, Size: 1003 bytes --]
On Mon, 2011-01-03 at 00:36 +0100, Francois Romieu wrote:
> Documentation (sort of).
>
> The location are the same, the values are the same but it is
> just accidental. Note that the 810x could cope with a smaller
> value as it does not support jumbo frames.
>
> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
> Cc: Hayes <hayeswang@realtek.com>
> ---
> drivers/net/r8169.c | 22 ++++++++++++++--------
> 1 files changed, 14 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
> index 3124462..8aa92ad 100644
> --- a/drivers/net/r8169.c
> +++ b/drivers/net/r8169.c
[...]
> @@ -3036,7 +3042,7 @@ static void rtl_hw_start_8168bef(void __iomem *ioaddr, struct pci_dev *pdev)
> {
> rtl_hw_start_8168bb(ioaddr, pdev);
>
> - RTL_W8(EarlyTxThres, EarlyTxThld);
> + RTL_W8(MaxTxPacketSize, 0x3f);
[...]
Shouldn't the value here be written as TxPacketMax?
Ben.
--
Ben Hutchings, Debian Developer and kernel team member
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 828 bytes --]
^ permalink raw reply
* Re: [net-next-2.6 02/08] r8169: identify different registers.
From: David Miller @ 2011-01-03 2:58 UTC (permalink / raw)
To: benh; +Cc: romieu, netdev, hayeswang, dwmw2
In-Reply-To: <1294023131.3167.138.camel@localhost>
From: Ben Hutchings <benh@debian.org>
Date: Mon, 03 Jan 2011 02:52:11 +0000
> On Mon, 2011-01-03 at 00:36 +0100, Francois Romieu wrote:
>> Documentation (sort of).
>>
>> The location are the same, the values are the same but it is
>> just accidental. Note that the 810x could cope with a smaller
>> value as it does not support jumbo frames.
>>
>> Signed-off-by: Francois Romieu <romieu@fr.zoreil.com>
>> Cc: Hayes <hayeswang@realtek.com>
>> ---
>> drivers/net/r8169.c | 22 ++++++++++++++--------
>> 1 files changed, 14 insertions(+), 8 deletions(-)
>>
>> diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
>> index 3124462..8aa92ad 100644
>> --- a/drivers/net/r8169.c
>> +++ b/drivers/net/r8169.c
> [...]
>> @@ -3036,7 +3042,7 @@ static void rtl_hw_start_8168bef(void __iomem *ioaddr, struct pci_dev *pdev)
>> {
>> rtl_hw_start_8168bb(ioaddr, pdev);
>>
>> - RTL_W8(EarlyTxThres, EarlyTxThld);
>> + RTL_W8(MaxTxPacketSize, 0x3f);
> [...]
>
> Shouldn't the value here be written as TxPacketMax?
Yep, looks that way to me too.
Otherwise why add the new TxPacketMax definition :-)
^ permalink raw reply
* [patch] mac80211: potential null dereference in mesh forwarding
From: Dan Carpenter @ 2011-01-03 5:43 UTC (permalink / raw)
To: John W. Linville
Cc: Johannes Berg, David S. Miller, linux-wireless, netdev,
kernel-janitors
The printk() is supposed to be ratelimited but we should always goto out
when fwd_skb is NULL. Otherwise it gets dereferenced on the next line.
Signed-off-by: Dan Carpenter <error27@gmail.com>
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
index 5e9d3bc..dc8b566 100644
--- a/net/mac80211/rx.c
+++ b/net/mac80211/rx.c
@@ -1831,8 +1831,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
fwd_skb = skb_copy(skb, GFP_ATOMIC);
- if (!fwd_skb && net_ratelimit()) {
- printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
+ if (!fwd_skb) {
+ if (net_ratelimit())
+ printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
sdata->name);
goto out;
}
^ permalink raw reply related
* Re: [net-next-2.6 PATCH v2 3/3] net_sched: implement a root container qdisc sch_mclass
From: John Fastabend @ 2011-01-03 5:43 UTC (permalink / raw)
To: Jarek Poplawski
Cc: davem@davemloft.net, netdev@vger.kernel.org, hadi@cyberus.ca,
shemminger@vyatta.com, tgraf@infradead.org,
eric.dumazet@gmail.com, bhutchings@solarflare.com,
nhorman@tuxdriver.com
In-Reply-To: <4D1D17C9.3040500@gmail.com>
On 12/30/2010 3:37 PM, Jarek Poplawski wrote:
> John Fastabend wrote:
>> This implements a mclass 'multi-class' queueing discipline that by
>> default creates multiple mq qdisc's one for each traffic class. Each
>> mq qdisc then owns a range of queues per the netdev_tc_txq mappings.
>
> Is it really necessary to add one more abstraction layer for this,
> probably not most often used (or even asked by users), functionality?
> Why mclass can't simply do these few things more instead of attaching
> (and changing) mq?
>
The statistics work nicely when the mq qdisc is used.
qdisc mclass 8002: root tc 4 map 0 1 2 3 0 1 2 3 1 1 1 1 1 1 1 1
queues:(0:1) (2:3) (4:5) (6:15)
Sent 140 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc mq 8003: parent 8002:1
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc mq 8004: parent 8002:2
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc mq 8005: parent 8002:3
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc mq 8006: parent 8002:4
Sent 140 bytes 2 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc sfq 8007: parent 8005:1 limit 127p quantum 1514b
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
qdisc sfq 8008: parent 8005:2 limit 127p quantum 1514b
Sent 0 bytes 0 pkt (dropped 0, overlimits 0 requeues 0)
backlog 0b 0p requeues 0
The mclass gives the statistics for the interface and then statistics on the mq qdisc gives statistics for each traffic class. Also, when using the 'mq qdisc' with this abstraction other qdisc can be grafted onto the queue. For example the sch_sfq is used in the above example.
Although I am not too hung up on this use case it does seem to be a good abstraction to me. Is it strictly necessary though no and looking at the class statistics of mclass could be used to get stats per traffic class.
> ...
>> diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
>> index 0af57eb..723ee52 100644
>> --- a/include/net/sch_generic.h
>> +++ b/include/net/sch_generic.h
>> @@ -50,6 +50,7 @@ struct Qdisc {
>> #define TCQ_F_INGRESS 4
>> #define TCQ_F_CAN_BYPASS 8
>> #define TCQ_F_MQROOT 16
>> +#define TCQ_F_MQSAFE 32
>
> If every other qdisc added a flag for qdiscs it likes...
>
then we run out of bits and get unneeded complexity. I think I will drop the MQSAFE bit completely and let user space catch this. The worst that should happen is the noop qdisc is used.
>> @@ -709,7 +709,13 @@ static void attach_default_qdiscs(struct net_device *dev)
>> dev->qdisc = txq->qdisc_sleeping;
>> atomic_inc(&dev->qdisc->refcnt);
>> } else {
>> - qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT);
>> + if (dev->num_tc)
>
> Actually, where this num_tc is expected to be set? I can see it inside
> mclass only, with unsetting on destruction, but probably I miss something.
Either through mclass as you noted or a driver could set the num_tc. One of the RFC's I sent out has ixgbe setting the num_tc when DCB was enabled.
>> + qdisc = qdisc_create_dflt(txq, &mclass_qdisc_ops,
>> + TC_H_ROOT);
>> + else
>> + qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops,
>> + TC_H_ROOT);
>> +
>> +static int mclass_init(struct Qdisc *sch, struct nlattr *opt)
>> +{
>> + struct net_device *dev = qdisc_dev(sch);
>> + struct mclass_sched *priv = qdisc_priv(sch);
>> + struct netdev_queue *dev_queue;
>> + struct Qdisc *qdisc;
>> + int i, err = -EOPNOTSUPP;
>> + struct tc_mclass_qopt *qopt = NULL;
>> +
>> + /* Unwind attributes on failure */
>> + u8 unwnd_tc = dev->num_tc;
>> + u8 unwnd_map[16];
>
> [TC_MAX_QUEUE] ?
Actually TC_BITMASK+1 is probably more accurate. This array maps the skb priority to a traffic class after the priority is masked with TC_BITMASK.
>
>> + struct netdev_tc_txq unwnd_txq[16];
>> +
Although unwnd_txq should be TC_MAX_QUEUE.
>> + if (sch->parent != TC_H_ROOT)
>> + return -EOPNOTSUPP;
>> +
>> + if (!netif_is_multiqueue(dev))
>> + return -EOPNOTSUPP;
>> +
>> + if (nla_len(opt) < sizeof(*qopt))
>> + return -EINVAL;
>> + qopt = nla_data(opt);
>> +
>> + memcpy(unwnd_map, dev->prio_tc_map, sizeof(unwnd_map));
>> + memcpy(unwnd_txq, dev->tc_to_txq, sizeof(unwnd_txq));
>> +
>> + /* If the mclass options indicate that hardware should own
>> + * the queue mapping then run ndo_setup_tc if this can not
>> + * be done fail immediately.
>> + */
>> + if (qopt->hw && dev->netdev_ops->ndo_setup_tc) {
>> + priv->hw_owned = 1;
>> + if (dev->netdev_ops->ndo_setup_tc(dev, qopt->num_tc))
>> + return -EINVAL;
>> + } else if (!qopt->hw) {
>> + if (mclass_parse_opt(dev, qopt))
>> + return -EINVAL;
>> +
>> + if (netdev_set_num_tc(dev, qopt->num_tc))
>> + return -ENOMEM;
>> +
>> + for (i = 0; i < qopt->num_tc; i++)
>> + netdev_set_tc_queue(dev, i,
>> + qopt->count[i], qopt->offset[i]);
>> + } else {
>> + return -EINVAL;
>> + }
>> +
>> + /* Always use supplied priority mappings */
>> + for (i = 0; i < 16; i++) {
>
> i < qopt->num_tc ?
Nope, TC_BITMASK+1 here. If we only have 4 tcs for example we still need to map all 16 priority values to a tc.
>
>> + if (netdev_set_prio_tc_map(dev, i, qopt->prio_tc_map[i])) {
>> + err = -EINVAL;
>> + goto tc_err;
>> + }
>> + }
>> +
>> + /* pre-allocate qdisc, attachment can't fail */
>> + priv->qdiscs = kcalloc(qopt->num_tc,
>> + sizeof(priv->qdiscs[0]), GFP_KERNEL);
>> + if (priv->qdiscs == NULL) {
>> + err = -ENOMEM;
>> + goto tc_err;
>> + }
>> +
>> + for (i = 0; i < dev->num_tc; i++) {
>> + dev_queue = netdev_get_tx_queue(dev, dev->tc_to_txq[i].offset);
>
> Are these offsets etc. validated?
Yes, as your next email noted.
Thanks,
John
^ permalink raw reply
* Re: [net-next-2.6 PATCH v2 3/3] net_sched: implement a root container qdisc sch_mclass
From: John Fastabend @ 2011-01-03 5:46 UTC (permalink / raw)
To: Jarek Poplawski
Cc: davem@davemloft.net, netdev@vger.kernel.org, hadi@cyberus.ca,
shemminger@vyatta.com, tgraf@infradead.org,
eric.dumazet@gmail.com, bhutchings@solarflare.com,
nhorman@tuxdriver.com
In-Reply-To: <20101231092543.GA7809@ff.dom.local>
On 12/31/2010 1:25 AM, Jarek Poplawski wrote:
> On 2010-12-21 20:29, John Fastabend wrote:
>> This implements a mclass 'multi-class' queueing discipline that by
>> default creates multiple mq qdisc's one for each traffic class. Each
>> mq qdisc then owns a range of queues per the netdev_tc_txq mappings.
>
> Btw, you could also consider better name (mqprio?) because there're
> many 'multi-class' queueing disciplines around.
>
OK.
>> +static int mclass_parse_opt(struct net_device *dev, struct tc_mclass_qopt *qopt)
>> +{
>> + int i, j;
>> +
>> + /* Verify TC offset and count are sane */
>
> if (qopt->num_tc > TC_MAX_QUEUE) ?
> return -EINVAL;
This would be caught later when netdev_set_num_tc() fails although probably best to catch all failures in this function as early as possible.
>
>> + for (i = 0; i < qopt->num_tc; i++) {
>> + int last = qopt->offset[i] + qopt->count[i];
>> + if (last > dev->num_tx_queues)
>
> if (last >= dev->num_tx_queues) ?
>
>> + return -EINVAL;
>> + for (j = i + 1; j < qopt->num_tc; j++) {
>> + if (last > qopt->offset[j])
>
> if (last >= qopt->offset[j]) ?
I believe the below works as expected. The offset needs to be verified (this I missed) but offset+count can be equal to num_tx_queue indicating the last queue is in use. With 8 tx queues and num_tc=2 a valid configuration is, tc1 offset of 0 and a count of 7 with tc2 offset of 7 and count of 1.
/* Verify num_tc is in max range */
if (qopt->num_tc > TC_MAX_QUEUE)
return -EINVAL;
for (i = 0; i < qopt->num_tc; i++) {
/* Verify the queue offset is in the num tx range */
if (qopt->offset[i] >= dev->num_tx_queues)
return -EINVAL;
/* Verify the queue count is in tx range being equal to the
* num_tx_queues indicates the last queue is in use.
*/
else if (qopt->offset[i] + qopt->count[i] > dev->num_tx_queues)
return -EINVAL;
/* Verify that the offset and counts do not overlap */
for (j = i + 1; j < qopt->num_tc; j++) {
if (last > qopt->offset[j])
return -EINVAL;
}
}
Thanks for the review!
John.
>
> Jarek P.
^ permalink raw reply
* Re: [patch] mac80211: potential null dereference in mesh forwarding
From: Eric Dumazet @ 2011-01-03 7:45 UTC (permalink / raw)
To: Dan Carpenter
Cc: John W. Linville, Johannes Berg, David S. Miller, linux-wireless,
netdev, kernel-janitors
In-Reply-To: <20110103054355.GP1886@bicker>
Le lundi 03 janvier 2011 à 08:43 +0300, Dan Carpenter a écrit :
> The printk() is supposed to be ratelimited but we should always goto out
> when fwd_skb is NULL. Otherwise it gets dereferenced on the next line.
>
> Signed-off-by: Dan Carpenter <error27@gmail.com>
>
> diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c
> index 5e9d3bc..dc8b566 100644
> --- a/net/mac80211/rx.c
> +++ b/net/mac80211/rx.c
> @@ -1831,8 +1831,9 @@ ieee80211_rx_h_mesh_fwding(struct ieee80211_rx_data *rx)
>
> fwd_skb = skb_copy(skb, GFP_ATOMIC);
>
> - if (!fwd_skb && net_ratelimit()) {
> - printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
> + if (!fwd_skb) {
> + if (net_ratelimit())
> + printk(KERN_DEBUG "%s: failed to clone mesh frame\n",
> sdata->name);
> goto out;
> }
Already discovered/coped by Milton Miller.
^ permalink raw reply
* [PATCHv2 NEXT 2/2] netxen: update driver version 4.0.75
From: Amit Kumar Salecha @ 2011-01-03 7:58 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, anirban.chakraborty
In-Reply-To: <1294041525-15553-1-git-send-email-amit.salecha@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/netxen/netxen_nic.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 4e54587..a113805 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -53,8 +53,8 @@
#define _NETXEN_NIC_LINUX_MAJOR 4
#define _NETXEN_NIC_LINUX_MINOR 0
-#define _NETXEN_NIC_LINUX_SUBVERSION 74
-#define NETXEN_NIC_LINUX_VERSIONID "4.0.74"
+#define _NETXEN_NIC_LINUX_SUBVERSION 75
+#define NETXEN_NIC_LINUX_VERSIONID "4.0.75"
#define NETXEN_VERSION_CODE(a, b, c) (((a) << 24) + ((b) << 16) + (c))
#define _major(v) (((v) >> 24) & 0xff)
--
1.7.3.2
^ permalink raw reply related
* [PATCHv2 NEXT 1/2] netxen: enable LRO based on NETIF_F_LRO
From: Amit Kumar Salecha @ 2011-01-03 7:58 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, anirban.chakraborty, Sucheta Chakraborty
In-Reply-To: <1294041525-15553-1-git-send-email-amit.salecha@qlogic.com>
From: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
o Enable/disable LRO in device based on NETIF_F_LRO flag, instead of using
driver private flag.
o Disable LRO, if rx csum offloading is off.
David Miller,
You should use netdev_info() instead of dev_info().
Signed-off-by: Sucheta Chakraborty <sucheta.chakraborty@qlogic.com>
Signed-off-by: Amit Kumar Salecha <amit.salecha@qlogic.com>
---
drivers/net/netxen/netxen_nic.h | 1 +
drivers/net/netxen/netxen_nic_ethtool.c | 26 ++++++++++++++++++++++++--
drivers/net/netxen/netxen_nic_hw.c | 5 -----
drivers/net/netxen/netxen_nic_main.c | 4 +---
4 files changed, 26 insertions(+), 10 deletions(-)
diff --git a/drivers/net/netxen/netxen_nic.h b/drivers/net/netxen/netxen_nic.h
index 8e8a978..4e54587 100644
--- a/drivers/net/netxen/netxen_nic.h
+++ b/drivers/net/netxen/netxen_nic.h
@@ -1132,6 +1132,7 @@ typedef struct {
#define NETXEN_NIC_MSI_ENABLED 0x02
#define NETXEN_NIC_MSIX_ENABLED 0x04
#define NETXEN_NIC_LRO_ENABLED 0x08
+#define NETXEN_NIC_LRO_DISABLED 0x00
#define NETXEN_NIC_BRIDGE_ENABLED 0X10
#define NETXEN_NIC_DIAG_ENABLED 0x20
#define NETXEN_IS_MSI_FAMILY(adapter) \
diff --git a/drivers/net/netxen/netxen_nic_ethtool.c b/drivers/net/netxen/netxen_nic_ethtool.c
index b30de24..587498e 100644
--- a/drivers/net/netxen/netxen_nic_ethtool.c
+++ b/drivers/net/netxen/netxen_nic_ethtool.c
@@ -720,7 +720,21 @@ static u32 netxen_nic_get_rx_csum(struct net_device *dev)
static int netxen_nic_set_rx_csum(struct net_device *dev, u32 data)
{
struct netxen_adapter *adapter = netdev_priv(dev);
- adapter->rx_csum = !!data;
+
+ if (data) {
+ adapter->rx_csum = data;
+ return 0;
+ }
+
+ if (dev->features & NETIF_F_LRO) {
+ if (netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_DISABLED))
+ return -EIO;
+
+ dev->features &= ~NETIF_F_LRO;
+ netxen_send_lro_cleanup(adapter);
+ netdev_info(dev, "disabling LRO as rx_csum is off\n");
+ }
+ adapter->rx_csum = data;
return 0;
}
@@ -893,11 +907,19 @@ static int netxen_nic_set_flags(struct net_device *netdev, u32 data)
if (!(adapter->capabilities & NX_FW_CAPABILITY_HW_LRO))
return -EINVAL;
+ if (!adapter->rx_csum) {
+ netdev_info(netdev, "rx csum is off, cannot toggle LRO\n");
+ return -EINVAL;
+ }
+
+ if (!!(data & ETH_FLAG_LRO) == !!(netdev->features & NETIF_F_LRO))
+ return 0;
+
if (data & ETH_FLAG_LRO) {
hw_lro = NETXEN_NIC_LRO_ENABLED;
netdev->features |= NETIF_F_LRO;
} else {
- hw_lro = 0;
+ hw_lro = NETXEN_NIC_LRO_DISABLED;
netdev->features &= ~NETIF_F_LRO;
}
diff --git a/drivers/net/netxen/netxen_nic_hw.c b/drivers/net/netxen/netxen_nic_hw.c
index e42d26e..5cef718 100644
--- a/drivers/net/netxen/netxen_nic_hw.c
+++ b/drivers/net/netxen/netxen_nic_hw.c
@@ -809,9 +809,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
u64 word;
int rv = 0;
- if ((adapter->flags & NETXEN_NIC_LRO_ENABLED) == enable)
- return 0;
-
memset(&req, 0, sizeof(nx_nic_req_t));
req.qhdr = cpu_to_le64(NX_HOST_REQUEST << 23);
@@ -827,8 +824,6 @@ int netxen_config_hw_lro(struct netxen_adapter *adapter, int enable)
"configure hw lro request\n");
}
- adapter->flags ^= NETXEN_NIC_LRO_ENABLED;
-
return rv;
}
diff --git a/drivers/net/netxen/netxen_nic_main.c b/drivers/net/netxen/netxen_nic_main.c
index 58a3643..33fac32 100644
--- a/drivers/net/netxen/netxen_nic_main.c
+++ b/drivers/net/netxen/netxen_nic_main.c
@@ -762,8 +762,6 @@ netxen_check_options(struct netxen_adapter *adapter)
if (adapter->fw_version >= NETXEN_VERSION_CODE(4, 0, 222))
adapter->capabilities = NXRD32(adapter, CRB_FW_CAPABILITIES_1);
- adapter->flags &= ~NETXEN_NIC_LRO_ENABLED;
-
if (adapter->ahw.port_type == NETXEN_NIC_XGBE) {
adapter->num_rxd = DEFAULT_RCV_DESCRIPTORS_10G;
adapter->num_jumbo_rxd = MAX_JUMBO_RCV_DESCRIPTORS_10G;
@@ -990,7 +988,7 @@ __netxen_nic_up(struct netxen_adapter *adapter, struct net_device *netdev)
if (NX_IS_REVISION_P3(adapter->ahw.revision_id))
netxen_config_intr_coalesce(adapter);
- if (adapter->capabilities & NX_FW_CAPABILITY_HW_LRO)
+ if (netdev->features & NETIF_F_LRO)
netxen_config_hw_lro(adapter, NETXEN_NIC_LRO_ENABLED);
netxen_napi_enable(adapter);
--
1.7.3.2
^ permalink raw reply related
* [PATCHv2 0/2]netxen: updates
From: Amit Kumar Salecha @ 2011-01-03 7:58 UTC (permalink / raw)
To: davem; +Cc: netdev, ameen.rahman, anirban.chakraborty
Hi,
Series v2 of 2 patches to fix LRO in netxen nic driver. Apply these on
net-next branch.
-Amit
^ permalink raw reply
* [PATCH] trivial: Fix typo fault in netdevice.h
From: Michal Simek @ 2011-01-03 8:54 UTC (permalink / raw)
To: davem; +Cc: linux-kernel, netdev, Michal Simek
Signed-off-by: Michal Simek <monstr@monstr.eu>
---
include/linux/netdevice.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index d8fd2c2..c773bc8 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -683,7 +683,7 @@ struct netdev_rx_queue {
* neither operation.
*
* void (*ndo_vlan_rx_register)(struct net_device *dev, struct vlan_group *grp);
- * If device support VLAN receive accleration
+ * If device support VLAN receive acceleration
* (ie. dev->features & NETIF_F_HW_VLAN_RX), then this function is called
* when vlan groups for the device changes. Note: grp is NULL
* if no vlan's groups are being used.
--
1.5.5.6
^ permalink raw reply related
* Re: [PATCH] new UDPCP Communication Protocol
From: Stefani Seibold @ 2011-01-03 9:08 UTC (permalink / raw)
To: Jesper Juhl
Cc: Eric Dumazet, linux-kernel, akpm, davem, netdev, shemminger,
daniel.baluta, jochen
In-Reply-To: <alpine.LNX.2.00.1101022356550.11481@swampdragon.chaosbits.net>
Am Montag, den 03.01.2011, 00:04 +0100 schrieb Jesper Juhl:
> On Sun, 2 Jan 2011, Stefani Seibold wrote:
>
> > Am Sonntag, den 02.01.2011, 23:49 +0100 schrieb Eric Dumazet:
> > > Le dimanche 02 janvier 2011 à 23:39 +0100, stefani@seibold.net a écrit :
> > > > +
> > > > +/*
> > > > + * Create a new destination descriptor for the given IPV4 address and port
> > > > + */
> > > > +static struct udpcp_dest *new_dest(struct sock *sk, __be32 addr, __be16 port)
> > > > +{
> > > > + struct udpcp_dest *dest;
> > > > + struct udpcp_sock *usk = udpcp_sk(sk);
> > > > +
> > > > + if (usk->connections >= udpcp_max_connections)
> > > > + return NULL;
> > > > +
> > > > + dest = kzalloc(sizeof(*dest), sk->sk_allocation);
> > > > +
> > > > + if (dest) {
> > > > + usk->connections++;
> > > > + skb_queue_head_init(&dest->xmit);
> > > > + dest->addr = addr;
> > > > + dest->port = port;
> > > > + dest->ackmode = UDPCP_ACK;
> > > > + list_add_tail(&dest->list, &usk->destlist);
> > > > + }
> > > > +
> > > > + return dest;
> > > > +}
> > > > +
> > >
> > > Hmm, so 'connections' is increased, never decreased.
> > >
> > > This seems a fatal flaw in this protocol, since a malicious user can
> > > easily fill the list with garbage, and block regular communications.
> >
> > You are right, there is now way to detect which connection is no longer
> > needed. I have not designed this protocol, so i cannot fix it.
> >
> > But in our environment this will be used together with an firewall
> > and/or ipsec. In this case it it safe.
> >
>
> Hmm, the first thing that springs into my head as a possible band-aid
> (which is probbaly wrong for many reasons I've not considered, so feel
> free to shoot it down) is; couldn't we use a timer (set to some outrageous
> high value by default and admin tunable) that would decrement
> 'connections' (discount dead connections) when there has not been any
> acctivity for a huge period of time? Kill off connections that have been
> idle for ages.
>
This will not work for two reasons:
- First there is no way to detect a dead connection. A connection can
stay for a very long time without data transfer.
- Second it will not save against a attack where all communication slots
will be eaten by an attacker and then new valid connections will be not
handled.
The only thing what is possible to make an ioctl call which allows the
user land client to cancel connections.
But this will be in my opinion dead code, because white lists of trusted
address must be fostered and this will make the upgrading of a
infrastructure to complicate.
^ permalink raw reply
* Re: [*v3 PATCH 02/22] IPVS: netns to services part 1
From: Hans Schillstrom @ 2011-01-03 9:14 UTC (permalink / raw)
To: Jan Engelhardt
Cc: hans@schillstrom.com, horms@verge.net.au, ja@ssi.bg,
daniel.lezcano@free.fr, wensong@linux-vs.org,
lvs-devel@vger.kernel.org, netdev@vger.kernel.org,
netfilter-devel@vger.kernel.org
In-Reply-To: <alpine.LNX.2.01.1101011547040.9065@obet.zrqbmnf.qr>
On Sat, 2011-01-01 at 15:57 +0100, Jan Engelhardt wrote:
> On Thursday 2010-12-30 11:50, hans@schillstrom.com wrote:
> >+/*
> >+ * Get net ptr from skb in traffic cases
> >+ * use skb_sknet when call is from userland (ioctl or netlink)
> >+ */
> >+static inline struct net *skb_net(struct sk_buff *skb) {
> >+#ifdef CONFIG_NET_NS
> >+#ifdef CONFIG_IP_VS_DEBUG
> >+ /*
> >+ * This is used for debug only.
> >+ * Start with the most likely hit
> >+ * End with BUG
> >+ */
> >+ if (likely(skb->dev && skb->dev->nd_net))
> >+ return dev_net(skb->dev);
> >+ if (skb_dst(skb)->dev)
> >+ return dev_net(skb_dst(skb)->dev);
> >+ WARN(skb->sk,"Maybe skb_sknet should be used instead in %s() line:%d\n",
> >+ __func__, __LINE__);
> >+ if (likely(skb->sk && skb->sk->sk_net))
> >+ return sock_net(skb->sk);
> >+ pr_err("There is no net ptr to find in the skb in %s() line:%d\n",
> >+ __func__, __LINE__);
> >+ BUG();
> >+#else
> >+ return dev_net(skb->dev ? : skb_dst(skb)->dev);
> >+#endif
> >+#else
> >+ return &init_net;
> >+#endif
> >+}
>
> Whether NETNS is disabled or not, dev_net(skb->dev) can be used in either case,
> so the extra return &init_net case is not really required AFAICS.
OK, but the debug part will not compile without the ifdef since there is
some symbols that is #ifdef CONFIG_NET_NS.
"&init_net" is faster than the " ? : "
And the rest I guess is obvious.
>
> >@@ -3446,43 +3471,48 @@ static struct pernet_operations ipvs_control_ops = {
> >- smp_wmb();
> >+
> >+ smp_wmb(); /* Do wee really need it now ? */
>
> not "whee" :)
^ permalink raw reply
* Re: [PATCH] new UDPCP Communication Protocol
From: Eric Dumazet @ 2011-01-03 9:27 UTC (permalink / raw)
To: Stefani Seibold
Cc: Jesper Juhl, linux-kernel, akpm, davem, netdev, shemminger,
daniel.baluta, jochen
In-Reply-To: <1294045732.19666.6.camel@wall-e>
Le lundi 03 janvier 2011 à 10:08 +0100, Stefani Seibold a écrit :
> This will not work for two reasons:
>
> - First there is no way to detect a dead connection. A connection can
> stay for a very long time without data transfer.
>
> - Second it will not save against a attack where all communication slots
> will be eaten by an attacker and then new valid connections will be not
> handled.
>
> The only thing what is possible to make an ioctl call which allows the
> user land client to cancel connections.
>
> But this will be in my opinion dead code, because white lists of trusted
> address must be fostered and this will make the upgrading of a
> infrastructure to complicate.
>
>
Yep, and as UDP messages can easily spoofed, this means you need more
than a list of trusted addresses. You also need to encapsulate the thing
in an secured layer.
Stefani, your implementation has very litle chance being added in
standard kernel, because it is not correctly layered, or documented.
Copying hundred (thousand ?) of lines from existing code only shows
there is a design error in your proposal. It means every time we have to
make a change in this code, we'll have to do it twice.
SUNRPC uses UDP/TCP sockets, and use callbacks to existing UDP/TCP code,
maybe you should take a look to implement an UDPCP stack in kernel.
For instance, a pure socket API seems not the correct choice for UDPCP,
since a transmit should give a report to user, of frame being
delivered/aknowledged or not to/by the remote side ?
With send(), this means you have only one message in transit, no
asynchronous handling.
At least you forgot to document the API, and restrictions.
^ permalink raw reply
* Re: [PATCH V8 08/13] posix clocks: cleanup the CLOCK_DISPTACH macro
From: Peter Zijlstra @ 2011-01-03 9:29 UTC (permalink / raw)
To: Richard Cochran
Cc: linux-kernel, linux-api, netdev, Alan Cox, Arnd Bergmann,
Christoph Lameter, David Miller, John Stultz, Krzysztof Halasa,
Rodolfo Giometti, Thomas Gleixner
In-Reply-To: <503cd1fa268867573001cfc9bb5681ee3b5b32fa.1293820862.git.richard.cochran@omicron.at>
On Fri, 2010-12-31 at 20:15 +0100, Richard Cochran wrote:
> +#define CLOCK_DISPATCH(clock, call, arglist) dispatch_##call arglist
How about you run something like:
:% s/CLOCK_DISPATCH([^,]*, \([^,]*\), \([^)]*)\))/dispatch_\1\2/g
and remove that cruft all together?
^ permalink raw reply
* Re: [PATCH 1/1 V3] bridge: fix br_multicast_ipv6_rcv for paged skbs
From: Johannes Berg @ 2011-01-03 9:34 UTC (permalink / raw)
To: Tomas Winkler; +Cc: davem, netdev, Stephen Hemminger
In-Reply-To: <1293999538-9298-1-git-send-email-tomas.winkler@intel.com>
On Sun, 2011-01-02 at 22:18 +0200, Tomas Winkler wrote:
> icmp6h = icmp6_hdr(skb2);
>
> switch (icmp6h->icmp6_type) {
> @@ -1516,7 +1517,12 @@ static int br_multicast_ipv6_rcv(struct net_bridge *br,
> switch (icmp6h->icmp6_type) {
> case ICMPV6_MGM_REPORT:
> {
> - struct mld_msg *mld = (struct mld_msg *)icmp6h;
> + struct mld_msg *mld;
> + if (!pskb_may_pull(skb2, sizeof(*mld))) {
> + err = -EINVAL;
> + goto out;
> + }
> + mld = (struct mld_msg *)icmp6h;
This (and the second instance) is incorrect afaict -- the pointer
"icmp6h" should be reloaded after the pskb_may_pull(), no?
Also, the "out_nopush" thing is pointless since the push is completely
unnecessary as "skb2 != skb" is always true.
johannes
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox