* [PATCH RFC 06/15] via-rhine: The Great Renaming.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
- rhine_dmi_table --> rhine_dmi_table_quirk_avoid_d3
- rhine_ethop_*()
(clarify layering by renaming parts)
- rqWOL --> rqHaveWOL
(improves clarity - WOL is not "quirky", we simply have it)
- rhine_cleanup() --> rhine_exit()
These are specific handlers meant to serve the module_init()/module_exit()
interface, thus there's no reason to have them named differently
from the interface that they cover
- until a rename of module_*() happens to come along, that is...
- rhine_shutdown() --> rhine_shutdown_and_keep_wol()
- correct to rhine_update_rx_crc_and_missed_errors()
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 47 ++++++++++++++++++---------------
1 files changed, 26 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 4162649..053375b 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -255,7 +255,7 @@ enum rhine_revs {
};
enum rhine_quirks {
- rqWOL = 0x0001, /* Wake-On-LAN support */
+ rqHaveWOL = 0x0001, /* Wake-On-LAN support */
rqForceReset = 0x0002,
rq6patterns = 0x0040, /* 6 instead of 4 patterns for WOL */
rqStatusWBRace = 0x0080, /* Tx Status Writeback Error possible */
@@ -571,7 +571,7 @@ static void rhine_power_init(struct net_device *dev)
void __iomem *ioaddr = rp->base;
u16 wolstat;
- if (rp->quirks & rqWOL) {
+ if (rp->quirks & rqHaveWOL) {
/* Make sure chip is in power state D0 */
iowrite8(ioread8(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW);
@@ -689,7 +689,7 @@ static void rhine_reload_eeprom(long pioaddr, struct net_device *dev)
#endif
/* Turn off EEPROM-controlled wake-up (magic packet) */
- if (rp->quirks & rqWOL)
+ if (rp->quirks & rqHaveWOL)
iowrite8(ioread8(ioaddr + ConfigA) & 0xFC, ioaddr + ConfigA);
}
@@ -744,7 +744,8 @@ static void rhine_tx_err(struct rhine_private *rp, u32 status)
rhine_restart_tx(dev);
}
-static void rhine_update_rx_crc_and_missed_errord(struct rhine_private *rp)
+static void
+rhine_update_rx_crc_and_missed_errors(struct rhine_private *rp)
{
void __iomem *ioaddr = rp->base;
struct net_device_stats *stats = &rp->dev->stats;
@@ -814,7 +815,7 @@ static int rhine_napipoll(struct napi_struct *napi, int budget)
if (status & IntrStatsMax) {
spin_lock(&rp->lock);
- rhine_update_rx_crc_and_missed_errord(rp);
+ rhine_update_rx_crc_and_missed_errors(rp);
spin_unlock(&rp->lock);
}
@@ -895,7 +896,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
io_size = 128;
}
else if (pdev->revision >= VT6102) {
- quirks = rqWOL | rqForceReset;
+ quirks = rqHaveWOL | rqForceReset;
if (pdev->revision < VT6105) {
name = "Rhine II";
quirks |= rqStatusWBRace; /* Rhine-II exclusive */
@@ -2033,7 +2034,7 @@ static struct net_device_stats *rhine_get_stats(struct net_device *dev)
struct rhine_private *rp = netdev_priv(dev);
spin_lock_bh(&rp->lock);
- rhine_update_rx_crc_and_missed_errord(rp);
+ rhine_update_rx_crc_and_missed_errors(rp);
spin_unlock_bh(&rp->lock);
return &dev->stats;
@@ -2149,11 +2150,12 @@ static void netdev_set_msglevel(struct net_device *dev, u32 value)
rp->msg_enable = value;
}
-static void rhine_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+static void
+rhine_ethop_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rhine_private *rp = netdev_priv(dev);
- if (!(rp->quirks & rqWOL))
+ if (!(rp->quirks & rqHaveWOL))
return;
spin_lock_irq(&rp->lock);
@@ -2163,13 +2165,14 @@ static void rhine_get_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
spin_unlock_irq(&rp->lock);
}
-static int rhine_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
+static int
+rhine_ethop_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
{
struct rhine_private *rp = netdev_priv(dev);
u32 support = WAKE_PHY | WAKE_MAGIC |
WAKE_UCAST | WAKE_MCAST | WAKE_BCAST; /* Untested */
- if (!(rp->quirks & rqWOL))
+ if (!(rp->quirks & rqHaveWOL))
return -EINVAL;
if (wol->wolopts & ~support)
@@ -2190,8 +2193,8 @@ static const struct ethtool_ops netdev_ethtool_ops = {
.get_link = netdev_get_link,
.get_msglevel = netdev_get_msglevel,
.set_msglevel = netdev_set_msglevel,
- .get_wol = rhine_get_wol,
- .set_wol = rhine_set_wol,
+ .get_wol = rhine_ethop_get_wol,
+ .set_wol = rhine_ethop_set_wol,
};
static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -2254,13 +2257,14 @@ static void rhine_remove_one(struct pci_dev *pdev)
pci_set_drvdata(pdev, NULL);
}
-static void rhine_shutdown (struct pci_dev *pdev)
+static void
+rhine_shutdown_and_keep_wol(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rhine_private *rp = netdev_priv(dev);
void __iomem *ioaddr = rp->base;
- if (!(rp->quirks & rqWOL))
+ if (!(rp->quirks & rqHaveWOL))
return; /* Nothing to do for non-WOL adapters */
rhine_power_init(dev);
@@ -2321,7 +2325,7 @@ static int rhine_suspend(struct device *device)
netif_device_detach(dev);
- rhine_shutdown(pdev);
+ rhine_shutdown_and_keep_wol(pdev);
return 0;
}
@@ -2393,11 +2397,11 @@ static struct pci_driver rhine_driver = {
.id_table = rhine_pci_tbl,
.probe = rhine_init_one,
.remove = rhine_remove_one,
- .shutdown = rhine_shutdown,
+ .shutdown = rhine_shutdown_and_keep_wol,
.driver.pm = RHINE_PM_OPS,
};
-static struct dmi_system_id __initdata rhine_dmi_table[] = {
+static struct dmi_system_id __initdata rhine_dmi_table_quirk_avoid_d3[] = {
{
.ident = "EPIA-M",
.matches = {
@@ -2421,7 +2425,7 @@ static int __init rhine_init(void)
#ifdef MODULE
pr_info("%s\n", version);
#endif
- if (dmi_check_system(rhine_dmi_table)) {
+ if (dmi_check_system(rhine_dmi_table_quirk_avoid_d3)) {
/* these BIOSes fail at PXE boot if chip is in D3 */
avoid_D3 = true;
pr_warn("Broken BIOS detected, avoid_D3 enabled\n");
@@ -2433,11 +2437,12 @@ static int __init rhine_init(void)
}
-static void __exit rhine_cleanup(void)
+static void __exit
+rhine_exit(void)
{
pci_unregister_driver(&rhine_driver);
}
module_init(rhine_init);
-module_exit(rhine_cleanup);
+module_exit(rhine_exit);
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 02/15] via-rhine: some suspend/resume cleanup.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Work towards unifying duplicated power setup sections,
add large comment.
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 27 +++++++++++++++++++++++----
1 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 5facb0b..928d96f 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -955,8 +955,10 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
goto err_out_free_res;
}
+ rp->base = ioaddr;
+
#ifdef USE_MMIO
- enable_mmio(pioaddr, quirks);
+ enable_mmio(rp->pioaddr, rp->quirks);
/* Check that selected MMIO registers match the PIO ones */
i = 0;
@@ -974,11 +976,9 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
#endif /* USE_MMIO */
- rp->base = ioaddr;
-
/* Get chip registers into a sane state */
rhine_power_init(dev);
- rhine_hw_init(dev, pioaddr);
+ rhine_hw_init(dev, rp->pioaddr);
for (i = 0; i < 6; i++)
dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
@@ -2324,6 +2324,25 @@ static int rhine_resume(struct device *device)
struct net_device *dev = pci_get_drvdata(pdev);
struct rhine_private *rp = netdev_priv(dev);
+ /*
+ * Resume theory of operation ("state machine" description):
+ * Card state post resume() needs to be sufficiently restored
+ * to be at least as "good" as post-probe()
+ * (plus certain user-side card attribute modifications
+ * ideally being preserved, too!).
+ * In the case of an ifdown iface prior to suspend,
+ * this means equal state.
+ * open()/close() then do a state elevation (working iface)
+ * and reversal (back down to post-probe() card state).
+ * NetworkManager likes to close() ifaces prior to suspend(),
+ * thus they end up "closed" on resume() yet the card
+ * needs to be sufficiently restored to have its basics working...
+ * (open() does NOT and should not carry out such things!!).
+ * FIXME: the card setup parts here are duplicated
+ * with corresponding parts in probe() - they should be moved
+ * into a helper to be commonly called by both places.
+ */
+
#ifdef USE_MMIO
enable_mmio(rp->pioaddr, rp->quirks);
#endif
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 07/15] via-rhine: MMIO: move register verify into helper function.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Add mmio_verify_registers() function.
Gets rid of a useless USE_MMIO define section, too.
Reverse logging of MMIO vs. PIO values since the description suggests
different order.
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 49 +++++++++++++++++++--------------
1 files changed, 28 insertions(+), 21 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 053375b..a16e227 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -338,14 +338,6 @@ enum bcr1_bits {
BCR1_MED1=0x80, /* for VT6102 */
};
-#ifdef USE_MMIO
-/* Registers we check that mmio and reg are the same. */
-static const int mmio_verify_registers[] = {
- RxConfig, TxConfig, IntrEnable, ConfigA, ConfigB, ConfigC, ConfigD,
- 0
-};
-#endif
-
/* Bits in the interrupt status/mask registers. */
enum intr_status_bits {
IntrRxDone = 0x0001,
@@ -659,6 +651,31 @@ static void enable_mmio(long pioaddr, u32 quirks)
outb(n, pioaddr + ConfigD);
}
}
+/* Check that selected MMIO registers match the PIO ones */
+static inline bool
+mmio_verify_registers(struct pci_dev *pdev, long pioaddr, void __iomem *ioaddr)
+{
+ /* Registers we check to verify that mmio and reg are the same. */
+ static const int registers_to_verify[] = {
+ RxConfig, TxConfig, IntrEnable,
+ ConfigA, ConfigB, ConfigC, ConfigD,
+ 0
+ };
+
+ int i = 0;
+ while (registers_to_verify[i]) {
+ int reg = registers_to_verify[i++];
+ unsigned char pio = inb(pioaddr+reg);
+ unsigned char mmio = readb(ioaddr+reg);
+ if (pio != mmio) {
+ dev_err(&pdev->dev,
+ "MMIO do not match PIO [%02x] (%02x != %02x)\n",
+ reg, mmio, pio);
+ return false;
+ }
+ }
+ return true;
+}
#endif
/*
@@ -969,19 +986,9 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
#ifdef USE_MMIO
enable_mmio(rp->pioaddr, rp->quirks);
- /* Check that selected MMIO registers match the PIO ones */
- i = 0;
- while (mmio_verify_registers[i]) {
- int reg = mmio_verify_registers[i++];
- unsigned char a = inb(pioaddr+reg);
- unsigned char b = readb(ioaddr+reg);
- if (a != b) {
- rc = -EIO;
- dev_err(&pdev->dev,
- "MMIO do not match PIO [%02x] (%02x != %02x)\n",
- reg, a, b);
- goto err_out_unmap;
- }
+ if (!mmio_verify_registers(pdev, pioaddr, ioaddr)) {
+ rc = -EIO;
+ goto err_out_unmap;
}
#endif /* USE_MMIO */
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 09/15] via-rhine: mark some variables as __read_mostly.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index a4b8d84..ca788c0 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -49,14 +49,14 @@ static int debug = 0;
#if defined(__alpha__) || defined(__arm__) || defined(__hppa__) || \
defined(CONFIG_SPARC) || defined(__ia64__) || \
defined(__sh__) || defined(__mips__)
-static int rx_copybreak = 1518;
+static int rx_copybreak __read_mostly = 1518;
#else
-static int rx_copybreak;
+static int rx_copybreak __read_mostly;
#endif
/* Work-around for broken BIOSes: they are unable to get the chip back out of
power state D3 so PXE booting fails. bootparam(7): via-rhine.avoid_D3=1 */
-static bool avoid_D3;
+static bool avoid_D3 __read_mostly;
/*
* In case you are looking for 'options[]' or 'full_duplex[]', they
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 04/15] via-rhine: handle compile warnings (use PCI_VDEVICE macro).
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Gets rid of W=2 warnings
drivers/net/ethernet/via/via-rhine.c:274: warning: missing initializer
drivers/net/ethernet/via/via-rhine.c:274: warning: (near initialization for 'rhine_pci_tbl[0].class')
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 8 ++++----
1 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 6be6566..2d410ec 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -271,10 +271,10 @@ enum rhine_quirks {
#define IOSYNC do { ioread8(ioaddr + StationAddr); } while (0)
static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
- { 0x1106, 0x3043, PCI_ANY_ID, PCI_ANY_ID, }, /* VT86C100A */
- { 0x1106, 0x3065, PCI_ANY_ID, PCI_ANY_ID, }, /* VT6102 */
- { 0x1106, 0x3106, PCI_ANY_ID, PCI_ANY_ID, }, /* 6105{,L,LOM} */
- { 0x1106, 0x3053, PCI_ANY_ID, PCI_ANY_ID, }, /* VT6105M */
+ { PCI_VDEVICE(VIA, 0x3043), 0 }, /* VT86C100A */
+ { PCI_VDEVICE(VIA, 0x3065), 0 }, /* VT6102 */
+ { PCI_VDEVICE(VIA, 0x3106), 0 }, /* 6105{,L,LOM} */
+ { PCI_VDEVICE(VIA, 0x3053), 0 }, /* VT6105M */
{ } /* terminate list */
};
MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 03/15] via-rhine: small rhine_wait_bit() improvement.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Precalculate actual I/O address,
make sure to remember value in helper variable,
add a logging helper line.
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 12 ++++++++++--
1 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 928d96f..6be6566 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -505,11 +505,19 @@ static void rhine_restart_tx(struct net_device *dev);
static void rhine_wait_bit(struct rhine_private *rp, u8 reg, u8 mask, bool low)
{
- void __iomem *ioaddr = rp->base;
+ void __iomem *ioaddr_reg = rp->base;
int i;
+ ioaddr_reg += reg;
for (i = 0; i < 1024; i++) {
- bool has_mask_bits = !!(ioread8(ioaddr + reg) & mask);
+ u8 val = ioread8(ioaddr_reg);
+ bool has_mask_bits = !!(val & mask);
+
+ if (i < 20 /* avoid log spew */) {
+ /* netif_err(rp, hw, rp->dev,
+ "wait_bit %02x val %02x mask %02x %s hmb %d\n",
+ reg, val, mask, low ? "low" : "high", has_mask_bits); */
+ }
if (low ^ has_mask_bits)
break;
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 05/15] via-rhine: Spelling/phrases cleanup.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 2d410ec..4162649 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -83,7 +83,7 @@ static const int multicast_filter_limit = 32;
/* Time in jiffies before concluding the transmitter is hung. */
#define TX_TIMEOUT (2*HZ)
-#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer.*/
+#define PKT_BUF_SZ 1536 /* Size of each temporary Rx buffer. */
#include <linux/module.h>
#include <linux/moduleparam.h>
@@ -264,7 +264,7 @@ enum rhine_quirks {
/*
* rqRhineI: VT86C100A (aka Rhine-I) uses different bits to enable
* MMIO as well as for the collision counter and the Tx FIFO underflow
- * indicator. In addition, Tx and Rx buffers need to 4 byte aligned.
+ * indicator. In addition, Tx and Rx buffers need to be 4 byte aligned.
*/
/* Beware of PCI posted writes */
@@ -1266,7 +1266,7 @@ static void rhine_set_carrier(struct mii_if_info *mii)
/* autoneg is off: Link is always assumed to be up */
if (!netif_carrier_ok(dev))
netif_carrier_on(dev);
- } else /* Let MMI library update carrier status */
+ } else /* Let MII library update carrier status */
rhine_check_media(dev, 0);
netif_info(rp, link, dev, "force_media %d, carrier %d\n",
@@ -1649,7 +1649,7 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
void __iomem *ioaddr = rp->base;
unsigned entry;
- /* Caution: the write order is important here, set the field
+ /* Caution: the write order is important here - set the field
with the "ownership" bits last. */
/* Calculate the next Tx descriptor entry. */
@@ -1868,7 +1868,7 @@ static int rhine_rx(struct net_device *dev, int limit)
&rp->rx_ring[entry]);
dev->stats.rx_length_errors++;
} else if (desc_status & RxErr) {
- /* There was a error. */
+ /* There was an error. */
netif_dbg(rp, rx_err, dev,
"%s() Rx error %08x\n", __func__,
desc_status);
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 12/15] via-rhine: implement get_regs() ethtool ops.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Quite useful to pinpoint pre-suspend vs. post-resume register mismatches.
Adds io_size member for use in rhine_ethop_get_regs_len().
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 40 ++++++++++++++++++++++++++++++++++
1 files changed, 40 insertions(+), 0 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 8950eb0..90d109a 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -452,6 +452,7 @@ struct rhine_private {
struct work_struct reset_task;
u32 msg_enable;
+ int io_size;
/* Frequently used values: keep some adjacent for cache effect. */
u32 quirks;
@@ -1001,6 +1002,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rp = netdev_priv(dev);
rp->dev = dev;
+ rp->io_size = io_size;
rp->quirks = quirks;
rp->pioaddr = pioaddr;
rp->pdev = pdev;
@@ -2199,6 +2201,42 @@ static void netdev_set_msglevel(struct net_device *dev, u32 value)
rp->msg_enable = value;
}
+/*
+ * ethtool get_regs() handlers.
+ * Use e.g. to pinpoint pre-suspend vs. post-resume register mismatches
+ * due to yet another all-too-frequent suspend/resume issue.
+ */
+static int
+rhine_ethop_get_regs_len(struct net_device *dev)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+ return rp->io_size;
+}
+
+static void
+rhine_ethop_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *p)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+ unsigned long flags;
+ void __iomem *ioaddr = rp->base;
+ u8 *p8 = (u8 *)p;
+ int len = regs->len;
+ int len_max = rhine_ethop_get_regs_len(dev);
+ int i = 0;
+
+ if (len > len_max)
+ len = len_max;
+
+ regs->version = 1;
+
+ memset(p, 0xFF, len);
+
+ spin_lock_irqsave(&rp->lock, flags);
+ for (i = 0; i < len; ++i)
+ p8[i] = ioread8(ioaddr + i);
+ spin_unlock_irqrestore(&rp->lock, flags);
+}
+
/* Indicates the set of WOL features supported by this card rev. */
static inline u32
rhine_wol_support_bits_get(struct rhine_private *rp)
@@ -2241,6 +2279,8 @@ rhine_ethop_set_wol(struct net_device *dev, struct ethtool_wolinfo *wol)
static const struct ethtool_ops netdev_ethtool_ops = {
.get_drvinfo = netdev_get_drvinfo,
+ .get_regs_len = rhine_ethop_get_regs_len,
+ .get_regs = rhine_ethop_get_regs,
.get_settings = netdev_get_settings,
.set_settings = netdev_set_settings,
.nway_reset = netdev_nway_reset,
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 00/15] via-rhine: fix resume, cleanup, eth ops (regs)
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
From: Andreas Mohr <andim2@users.sf.net>
This patchset fixes suspend/resume of via-rhine in the NetworkManager case
(patch 0001), with subsequent patches being predominantly
about general cleanup/renovation work
(one patch adds get_regs() ethtool support, though).
Currently marked as RFC since it's somewhat larger,
without prior review activity.
checkpatch.pl'd patchset against a slightly oldish master
(current state of via-rhine.c in linux-next is identical).
Note that some parts in this patchset have a dependency on predecessors
(e.g. __read_mostly comes to mind).
I managed to stay at 15 patches, thus right at (below) the
official mailing list patch limit.
Somehow Christmas must have been mighty boring :)
And one of the patches narrows down on non-default
compiler warning levels, too (c.f. my recent LKML tirade).
The first patch (resume fix) possibly is -stable material,
but since layer separation currently is not crystal clear
there might be some risk, thus I'm hesitating.
Thanks!
Andreas Mohr (15):
via-rhine: YARB: fix broken resume of ifdown case (NetworkManager).
via-rhine: some suspend/resume cleanup.
via-rhine: small rhine_wait_bit() improvement.
via-rhine: handle compile warnings (use PCI_VDEVICE macro).
via-rhine: Spelling/phrases cleanup.
via-rhine: The Great Renaming.
via-rhine: MMIO: move register verify into helper function.
via-rhine: MMIO: move support decision (compile-time-only to
runtime).
via-rhine: mark some variables as __read_mostly.
via-rhine: WOL: remove duplication into a helper.
via-rhine: WOL: separate WOL configuration (and its logging).
via-rhine: implement get_regs() ethtool ops.
via-rhine: misc. cleanup.
via-rhine: The Great Deduplication.
via-rhine: add helper (reduce type-unsafe void * assignments).
drivers/net/ethernet/via/via-rhine.c | 572 +++++++++++++++++++++++-----------
1 files changed, 396 insertions(+), 176 deletions(-)
--
1.7.2.5
^ permalink raw reply
* [PATCH RFC 13/15] via-rhine: misc. cleanup.
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Several register values remained open-coded - use their defines instead.
Improve register define grouping.
Improve log messages.
Add comments.
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 92 ++++++++++++++++++++++++++++------
1 files changed, 76 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 90d109a..984f056 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -27,6 +27,34 @@
http://www.scyld.com/network/via-rhine.html
[link no longer provides useful info -jgarzik]
+
+ This driver should get some whack: several handlers
+ seem to have their concerns intermingled. Rather,
+ functions should be grouped into generically usable micro handlers
+ (I/O access concerns, WOL handling, MII, etc. - with card specifics
+ properly dealt with via suitable *internal* abstraction as needed)
+ which are then being invoked by *specifically-purposed*
+ high-level, system-side operational handlers
+ on an as-needed-in-this-scope basis.
+ But that's a very painful issue with too many drivers, unfortunately.
+ Some rather unrelated handling within a function may easily end up
+ becoming an unwanted "side effect" once other use cases appear,
+ with rather unclear grouping of concerns being the root cause :(
+ Or, to put it bluntly: you're in the wild here - an uncontrollable mass
+ of unwashed developers hacking away at things
+ (and breaking things willy-nilly whenever getting confused
+ about intentions of original implementation!!),
+ with the only marginal chance of getting this avoided being
+ to better get your core implementation, layering
+ and especially component naming right (well, DAMN RIGHT).
+
+ TODO: one example would be clean encapsulation of I/O register access -
+ such helper functions would optionally allow keeping a watch on access
+ to extended registers unsupported by earlier revs.
+
+ TODO list:
+ (see TODO annotations at future work sites below
+ [more hunk-friendly])
*/
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -299,18 +327,23 @@ enum register_offsets {
MIIPhyAddr=0x6C, MIIStatus=0x6D, PCIBusConfig=0x6E, PCIBusConfig1=0x6F,
MIICmd=0x70, MIIRegAddr=0x71, MIIData=0x72, MACRegEEcsr=0x74,
ConfigA=0x78, ConfigB=0x79, ConfigC=0x7A, ConfigD=0x7B,
- RxMissed=0x7C, RxCRCErrs=0x7E, MiscCmd=0x81,
+ RxMissed = 0x7C, RxCRCErrs = 0x7E,
+ /*** Extended register range (newer revs only) starts here ***/
+ MiscCmd = 0x81,
StickyHW=0x83, IntrStatus2=0x84,
- CamMask=0x88, CamCon=0x92, CamAddr=0x93,
- WOLcrSet=0xA0, PwcfgSet=0xA1, WOLcgSet=0xA3, WOLcrClr=0xA4,
- WOLcrClr1=0xA6, WOLcgClr=0xA7,
- PwrcsrSet=0xA8, PwrcsrSet1=0xA9, PwrcsrClr=0xAC, PwrcsrClr1=0xAD,
+ CamMask = 0x88, CamCon = 0x92, CamAddr = 0x93,
+ /* various flag set/clear registers */
+ WOLcrSet = 0xA0, PwcfgSet = 0xA1, WOLcgSet = 0xA3,
+ WOLcrClr = 0xA4, WOLcrClr1 = 0xA6, WOLcgClr = 0xA7,
+ PwrcsrSet = 0xA8, PwrcsrSet1 = 0xA9,
+ PwrcsrClr = 0xAC, PwrcsrClr1 = 0xAD,
};
/* Bits in ConfigD */
enum backoff_bits {
- BackOptional=0x01, BackModify=0x02,
- BackCaptureEffect=0x04, BackRandom=0x08
+ BackOptional = 0x01, BackModify = 0x02,
+ BackCaptureEffect = 0x04, BackRandom = 0x08,
+ MMIOEnable = 0x80
};
/* Bits in the TxConfig (TCR) register */
@@ -688,7 +721,7 @@ static void enable_mmio(long pioaddr, u32 quirks)
n = inb(pioaddr + ConfigA) | 0x20;
outb(n, pioaddr + ConfigA);
} else {
- n = inb(pioaddr + ConfigD) | 0x80;
+ n = inb(pioaddr + ConfigD) | MMIOEnable;
outb(n, pioaddr + ConfigD);
}
}
@@ -759,6 +792,18 @@ static void rhine_poll(struct net_device *dev)
struct rhine_private *rp = netdev_priv(dev);
const int irq = rp->pdev->irq;
+ /*
+ * TODO: this "weird" section (passes in a "fake" irq number
+ * param, etc.) here looks like some functionality inversion
+ * is in order (i.e., probably the non-irq related IRQ handler core
+ * should be moved into helper function, which then is the one
+ * to *cleanly* be called from here, too!)
+ * OTOH maybe it's a specific requirement to disable IRQ
+ * and then do call the real handler impl instead -
+ * but then a comment should have been provided,
+ * to explain specifics of why we're manually calling
+ * into the actual interrupt handler...
+ */
disable_irq(irq);
rhine_interrupt(irq, dev);
enable_irq(irq);
@@ -771,7 +816,7 @@ static void rhine_kick_tx_threshold(struct rhine_private *rp)
void __iomem *ioaddr = rp->base;
rp->tx_thresh += 0x20;
- BYTE_REG_BITS_SET(rp->tx_thresh, 0x80, ioaddr + TxConfig);
+ BYTE_REG_BITS_SET(rp->tx_thresh, TCR_RTSF, ioaddr + TxConfig);
}
}
@@ -1044,6 +1089,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
rhine_power_init(dev);
rhine_hw_init(dev, rp->pioaddr);
+ /* Do bootstrap-only init steps (initial dev_addr, phy_id) */
for (i = 0; i < 6; i++)
dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
@@ -1058,7 +1104,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* For Rhine-I/II, phy_id is loaded from EEPROM */
if (!phy_id)
- phy_id = ioread8(ioaddr + 0x6C);
+ phy_id = ioread8(ioaddr + MIIPhyAddr);
spin_lock_init(&rp->lock);
mutex_init(&rp->task_lock);
@@ -1097,6 +1143,10 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
pci_set_drvdata(pdev, dev);
+ /* FIXME!! I really *don't* think that this stuff has any business
+ * being open-coded in probe() rather than being a helper possibly
+ * called from multiple sites (resume, etc.) - netif_carrier_on()!!
+ */
{
u16 mii_cmd;
int mii_status = mdio_read(dev, phy_id, 1);
@@ -1119,8 +1169,10 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
}
}
rp->mii_if.phy_id = phy_id;
+
+ /* Use this occasion to announce avoid_D3 state, too. */
if (avoid_D3)
- netif_info(rp, probe, dev, "No D3 power state at shutdown\n");
+ netif_info(rp, probe, dev, "Will avoid entering D3 power state at shutdown\n");
return 0;
@@ -1499,8 +1551,10 @@ static void init_registers(struct net_device *dev)
/* Initialize other registers. */
iowrite16(0x0006, ioaddr + PCIBusConfig); /* Tune configuration??? */
+ /* Seems that it's DMA Length reg (select "store & forward" option). */
+
/* Configure initial FIFO thresholds. */
- iowrite8(0x20, ioaddr + TxConfig);
+ iowrite8(TCR_RTFT0, ioaddr + TxConfig);
rp->tx_thresh = 0x20;
rp->rx_thresh = 0x60; /* Written in rhine_set_rx_mode(). */
@@ -1543,7 +1597,7 @@ static void rhine_disable_linkmon(struct rhine_private *rp)
iowrite8(0, ioaddr + MIICmd);
if (rp->quirks & rqRhineI) {
- iowrite8(0x01, ioaddr + MIIRegAddr); // MII_BMSR
+ iowrite8(MII_BMSR, ioaddr + MIIRegAddr);
/* Can be called from ISR. Evil. */
mdelay(1);
@@ -2316,11 +2370,11 @@ static int rhine_close(struct net_device *dev)
napi_disable(&rp->napi);
netif_stop_queue(dev);
- netif_dbg(rp, ifdown, dev, "Shutting down ethercard, status was %04x\n",
- ioread16(ioaddr + ChipCmd));
+ netif_dbg(rp, ifdown, dev, "%s() Shutting down ethercard, status was %04x\n",
+ __func__, ioread16(ioaddr + ChipCmd));
/* Switch to loopback mode to avoid hardware races. */
- iowrite8(rp->tx_thresh | 0x02, ioaddr + TxConfig);
+ iowrite8(rp->tx_thresh | TCR_LB0, ioaddr + TxConfig);
rhine_irq_disable(rp);
@@ -2369,6 +2423,11 @@ rhine_shutdown_and_keep_wol(struct pci_dev *pdev)
spin_lock(&rp->lock);
+ /*
+ * We are able to poke single bits in sequence
+ * (due to registers being organised as a set/clear combo).
+ */
+
if (rp->wolopts & WAKE_MAGIC) {
iowrite8(WOLmagic, ioaddr + WOLcrSet);
/*
@@ -2404,6 +2463,7 @@ rhine_shutdown_and_keep_wol(struct pci_dev *pdev)
}
#ifdef CONFIG_PM_SLEEP
+/* TODO: implement full runtime pm, e.g. as done by r8169.c */
static int rhine_suspend(struct device *device)
{
struct pci_dev *pdev = to_pci_dev(device);
--
1.7.2.5
^ permalink raw reply related
* [PATCH RFC 11/15] via-rhine: WOL: separate WOL configuration (and its logging).
From: Andreas Mohr @ 2012-12-31 15:25 UTC (permalink / raw)
To: andim2; +Cc: Roger Luethi, netdev, Francois Romieu
In-Reply-To: <1356967549-5056-1-git-send-email-andi@lisas.de>
From: Andreas Mohr <andim2@users.sf.net>
Add helper rhine_power_state_configure().
Signed-off-by: Andreas Mohr <andim2@users.sf.net>
---
drivers/net/ethernet/via/via-rhine.c | 129 +++++++++++++++++++++-------------
1 files changed, 80 insertions(+), 49 deletions(-)
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index 7e13d50..8950eb0 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -562,6 +562,81 @@ static void rhine_ack_events(struct rhine_private *rp, u32 mask)
mmiowb();
}
+/* Configures ACPI D0..D3 on card side. */
+static void
+rhine_power_state_configure(struct rhine_private *rp, u8 pci_state)
+{
+ void __iomem *ioaddr = rp->base;
+ u8 other_bits;
+ WARN_ON(!((pci_state >= 0) && (pci_state <= 3)));
+
+ other_bits = ioread8(ioaddr + StickyHW) & 0xFC;
+ iowrite8(other_bits | pci_state, ioaddr + StickyHW);
+}
+
+static inline void
+rhine_wol_configure(struct net_device *dev, u16 *wolstat_out)
+{
+ struct rhine_private *rp = netdev_priv(dev);
+ void __iomem *ioaddr = rp->base;
+ u16 wolstat = 0;
+
+ /* Make sure chip is in power state D0 */
+ rhine_power_state_configure(rp, 0);
+
+ /* Disable "force PME-enable" */
+ iowrite8(0x80, ioaddr + WOLcgClr);
+
+ /* Clear power-event config bits (WOL) */
+ iowrite8(0xFF, ioaddr + WOLcrClr);
+ /* More recent cards can manage two additional patterns */
+ if (rp->quirks & rq6patterns)
+ iowrite8(0x03, ioaddr + WOLcrClr1);
+
+ /* Save power-event status bits */
+ wolstat = ioread8(ioaddr + PwrcsrSet);
+ if (rp->quirks & rq6patterns)
+ wolstat |= (ioread8(ioaddr + PwrcsrSet1) & 0x03) << 8;
+
+ /* Clear power-event status bits */
+ iowrite8(0xFF, ioaddr + PwrcsrClr);
+ if (rp->quirks & rq6patterns)
+ iowrite8(0x03, ioaddr + PwrcsrClr1);
+
+ if (wolstat_out)
+ *wolstat_out = wolstat;
+}
+
+static inline void
+rhine_wol_log_wakeup_reason(struct net_device *dev, u16 wolstat)
+{
+ if (wolstat) {
+ const char *reason;
+ switch (wolstat) {
+ case WOLmagic:
+ reason = "Magic packet";
+ break;
+ case WOLlnkon:
+ reason = "Link went up";
+ break;
+ case WOLlnkoff:
+ reason = "Link went down";
+ break;
+ case WOLucast:
+ reason = "Unicast packet";
+ break;
+ case WOLbmcast:
+ reason = "Multicast/broadcast packet";
+ break;
+ default:
+ reason = "Unknown";
+ break;
+ }
+ netdev_info(dev, "Woke system up. Reason: %s\n",
+ reason);
+ }
+}
+
/*
* Get power related registers into sane state.
* Notify user about past WOL event.
@@ -569,56 +644,12 @@ static void rhine_ack_events(struct rhine_private *rp, u32 mask)
static void rhine_power_init(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
- void __iomem *ioaddr = rp->base;
- u16 wolstat;
if (rp->quirks & rqHaveWOL) {
- /* Make sure chip is in power state D0 */
- iowrite8(ioread8(ioaddr + StickyHW) & 0xFC, ioaddr + StickyHW);
-
- /* Disable "force PME-enable" */
- iowrite8(0x80, ioaddr + WOLcgClr);
-
- /* Clear power-event config bits (WOL) */
- iowrite8(0xFF, ioaddr + WOLcrClr);
- /* More recent cards can manage two additional patterns */
- if (rp->quirks & rq6patterns)
- iowrite8(0x03, ioaddr + WOLcrClr1);
-
- /* Save power-event status bits */
- wolstat = ioread8(ioaddr + PwrcsrSet);
- if (rp->quirks & rq6patterns)
- wolstat |= (ioread8(ioaddr + PwrcsrSet1) & 0x03) << 8;
-
- /* Clear power-event status bits */
- iowrite8(0xFF, ioaddr + PwrcsrClr);
- if (rp->quirks & rq6patterns)
- iowrite8(0x03, ioaddr + PwrcsrClr1);
-
- if (wolstat) {
- char *reason;
- switch (wolstat) {
- case WOLmagic:
- reason = "Magic packet";
- break;
- case WOLlnkon:
- reason = "Link went up";
- break;
- case WOLlnkoff:
- reason = "Link went down";
- break;
- case WOLucast:
- reason = "Unicast packet";
- break;
- case WOLbmcast:
- reason = "Multicast/broadcast packet";
- break;
- default:
- reason = "Unknown";
- }
- netdev_info(dev, "Woke system up. Reason: %s\n",
- reason);
- }
+ u16 wolstat;
+ rhine_wol_configure(dev, &wolstat);
+
+ rhine_wol_log_wakeup_reason(dev, wolstat);
}
}
@@ -2325,7 +2356,7 @@ rhine_shutdown_and_keep_wol(struct pci_dev *pdev)
spin_unlock(&rp->lock);
if (system_state == SYSTEM_POWER_OFF && !avoid_D3) {
- iowrite8(ioread8(ioaddr + StickyHW) | 0x03, ioaddr + StickyHW);
+ rhine_power_state_configure(rp, 3);
pci_wake_from_d3(pdev, true);
pci_set_power_state(pdev, PCI_D3hot);
--
1.7.2.5
^ permalink raw reply related
* [PATCH net-next 6/8] x86: bpf_jit_comp: add JMP_NEQ instructions for BPF JIT
From: Daniel Borkmann @ 2012-12-31 17:00 UTC (permalink / raw)
To: davem; +Cc: netdev, Eric Dumazet
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
This patch is a follow-up for patch "net: bpf: add neq jump
operations to bpf machine" that implements BPF x86 JIT parts
for the BPF JMP_NEQ operation.
Cc: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
arch/x86/net/bpf_jit_comp.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/x86/net/bpf_jit_comp.c b/arch/x86/net/bpf_jit_comp.c
index 6d6a4ce..bd10c83 100644
--- a/arch/x86/net/bpf_jit_comp.c
+++ b/arch/x86/net/bpf_jit_comp.c
@@ -587,12 +587,14 @@ common_load_ind: seen |= SEEN_DATAREF | SEEN_XREG;
COND_SEL(BPF_S_JMP_JLT_K, X86_JB, X86_JAE);
COND_SEL(BPF_S_JMP_JLE_K, X86_JBE, X86_JA);
COND_SEL(BPF_S_JMP_JEQ_K, X86_JE, X86_JNE);
+ COND_SEL(BPF_S_JMP_JNEQ_K,X86_JNE, X86_JE);
COND_SEL(BPF_S_JMP_JSET_K,X86_JNE, X86_JE);
COND_SEL(BPF_S_JMP_JGT_X, X86_JA, X86_JBE);
COND_SEL(BPF_S_JMP_JGE_X, X86_JAE, X86_JB);
COND_SEL(BPF_S_JMP_JLT_X, X86_JB, X86_JAE);
COND_SEL(BPF_S_JMP_JLE_X, X86_JBE, X86_JA);
COND_SEL(BPF_S_JMP_JEQ_X, X86_JE, X86_JNE);
+ COND_SEL(BPF_S_JMP_JNEQ_X,X86_JNE, X86_JE);
COND_SEL(BPF_S_JMP_JSET_X,X86_JNE, X86_JE);
cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
@@ -610,6 +612,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
case BPF_S_JMP_JLT_X:
case BPF_S_JMP_JLE_X:
case BPF_S_JMP_JEQ_X:
+ case BPF_S_JMP_JNEQ_X:
seen |= SEEN_XREG;
EMIT2(0x39, 0xd8); /* cmp %ebx,%eax */
break;
@@ -618,6 +621,7 @@ cond_branch: f_offset = addrs[i + filter[i].jf] - addrs[i];
EMIT2(0x85, 0xd8); /* test %ebx,%eax */
break;
case BPF_S_JMP_JEQ_K:
+ case BPF_S_JMP_JNEQ_K:
if (K == 0) {
EMIT2(0x85, 0xc0); /* test %eax,%eax */
break;
--
1.7.11.7
^ permalink raw reply related
* Re: [PATCH] net: fix checking boundary of valid vlan id
From: Benny Amorsen @ 2012-12-31 17:12 UTC (permalink / raw)
To: Glen Turner; +Cc: Florian Westphal, akong, netdev, davem
In-Reply-To: <186CBD58-5106-4FCD-8C73-E4EC84C3A303@gdt.id.au>
Glen Turner <gdt@gdt.id.au> writes:
> It may be a valid VLAN ID, or it may not. The meaning of FFF is
> reserved for vendor use, which doesn't preclude a vendor using it as a
> (non-interoperable) VLAN identifier. Many vendor's products treat 4096
> as they do any other VID.
I may be missing something vital, but 4096 is 0x1000 not 0xFFF? 4095 is
reserved and 0 means "treat as if the packet was untagged". 4096 is
impossible, there are only 12 bit and the encoding is AFAIK bog standard
binary.
/Benny
^ permalink raw reply
* [PATCH] tcp: split tcp_ecn sysctl knob to distinguish between IPv4 and IPv6
From: Hannes Frederic Sowa @ 2012-12-31 17:35 UTC (permalink / raw)
To: netdev
ECN could be more reliable when used with IPv6 (I don't have proofs). For
people who want to try ECN with IPv6 but still have problems connecting
to destinations because of broken IPv4 routers this switch allows one
to enable ECN just for IPv6.
Perhaps ECN could be enabled by default in future.
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
include/net/sock.h | 1 +
include/net/tcp.h | 8 +++++---
net/ipv4/syncookies.c | 6 ++++--
net/ipv4/sysctl_net_ipv4.c | 2 +-
net/ipv4/tcp_input.c | 2 --
net/ipv4/tcp_ipv4.c | 3 ++-
net/ipv4/tcp_output.c | 2 +-
net/ipv6/syncookies.c | 3 ++-
net/ipv6/sysctl_net_ipv6.c | 8 ++++++++
net/ipv6/tcp_ipv6.c | 4 +++-
10 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 182ca99..aa3c30e 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -944,6 +944,7 @@ struct proto {
int *sysctl_rmem;
int max_header;
bool no_autobind;
+ int ecn;
struct kmem_cache *slab;
unsigned int obj_size;
diff --git a/include/net/tcp.h b/include/net/tcp.h
index aed42c7..1202a6d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -266,7 +266,6 @@ extern int sysctl_tcp_abort_on_overflow;
extern int sysctl_tcp_max_orphans;
extern int sysctl_tcp_fack;
extern int sysctl_tcp_reordering;
-extern int sysctl_tcp_ecn;
extern int sysctl_tcp_dsack;
extern int sysctl_tcp_wmem[3];
extern int sysctl_tcp_rmem[3];
@@ -351,6 +350,7 @@ static inline bool tcp_synq_no_recent_overflow(const struct sock *sk)
}
extern struct proto tcp_prot;
+extern struct proto tcpv6_prot;
#define TCP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.tcp_statistics, field)
#define TCP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.tcp_statistics, field)
@@ -504,7 +504,8 @@ static inline __u32 cookie_v4_init_sequence(struct sock *sk,
#endif
extern __u32 cookie_init_timestamp(struct request_sock *req);
-extern bool cookie_check_timestamp(struct tcp_options_received *opt, bool *);
+extern bool cookie_check_timestamp(struct tcp_options_received *opt,
+ int sysctl_tcp_ecn, bool *ecn_ok);
/* From net/ipv6/syncookies.c */
extern struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb);
@@ -728,7 +729,8 @@ struct tcp_skb_cb {
* notifications, we disable TCP ECN negociation.
*/
static inline void
-TCP_ECN_create_request(struct request_sock *req, const struct sk_buff *skb)
+TCP_ECN_create_request(struct request_sock *req,
+ const struct sk_buff *skb, int sysctl_tcp_ecn)
{
const struct tcphdr *th = tcp_hdr(skb);
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index b236ef0..64dbfc5 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -232,7 +232,8 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
*
* return false if we decode an option that should not be.
*/
-bool cookie_check_timestamp(struct tcp_options_received *tcp_opt, bool *ecn_ok)
+bool cookie_check_timestamp(struct tcp_options_received *tcp_opt,
+ int sysctl_tcp_ecn, bool *ecn_ok)
{
/* echoed timestamp, lowest bits contain options */
u32 options = tcp_opt->rcv_tsecr & TSMASK;
@@ -278,6 +279,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
struct rtable *rt;
__u8 rcv_wscale;
bool ecn_ok = false;
+ int sysctl_tcp_ecn = sk->sk_prot->ecn;
struct flowi4 fl4;
if (!sysctl_tcp_syncookies || !th->ack || th->rst)
@@ -295,7 +297,7 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
memset(&tcp_opt, 0, sizeof(tcp_opt));
tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL);
- if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
+ if (!cookie_check_timestamp(&tcp_opt, sysctl_tcp_ecn, &ecn_ok))
goto out;
ret = NULL;
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index d84400b..f7aac98 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -539,7 +539,7 @@ static struct ctl_table ipv4_table[] = {
},
{
.procname = "tcp_ecn",
- .data = &sysctl_tcp_ecn,
+ .data = &tcp_prot.ecn,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index a28e4db..38e1184 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -81,8 +81,6 @@ int sysctl_tcp_sack __read_mostly = 1;
int sysctl_tcp_fack __read_mostly = 1;
int sysctl_tcp_reordering __read_mostly = TCP_FASTRETRANS_THRESH;
EXPORT_SYMBOL(sysctl_tcp_reordering);
-int sysctl_tcp_ecn __read_mostly = 2;
-EXPORT_SYMBOL(sysctl_tcp_ecn);
int sysctl_tcp_dsack __read_mostly = 1;
int sysctl_tcp_app_win __read_mostly = 31;
int sysctl_tcp_adv_win_scale __read_mostly = 1;
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 54139fa..32e012a 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -1568,7 +1568,7 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
goto drop_and_free;
if (!want_cookie || tmp_opt.tstamp_ok)
- TCP_ECN_create_request(req, skb);
+ TCP_ECN_create_request(req, skb, tcp_prot.ecn);
if (want_cookie) {
isn = cookie_v4_init_sequence(sk, skb, &req->mss);
@@ -2874,6 +2874,7 @@ struct proto tcp_prot = {
.rsk_prot = &tcp_request_sock_ops,
.h.hashinfo = &tcp_hashinfo,
.no_autobind = true,
+ .ecn = 2,
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt,
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 5d45159..0c75961 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -314,7 +314,7 @@ static inline void TCP_ECN_send_syn(struct sock *sk, struct sk_buff *skb)
struct tcp_sock *tp = tcp_sk(sk);
tp->ecn_flags = 0;
- if (sysctl_tcp_ecn == 1) {
+ if (sk->sk_prot->ecn == 1) {
TCP_SKB_CB(skb)->tcp_flags |= TCPHDR_ECE | TCPHDR_CWR;
tp->ecn_flags = TCP_ECN_OK;
}
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c
index 4016197..ce19227 100644
--- a/net/ipv6/syncookies.c
+++ b/net/ipv6/syncookies.c
@@ -163,6 +163,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
struct dst_entry *dst;
__u8 rcv_wscale;
bool ecn_ok = false;
+ int sysctl_tcp_ecn = sk->sk_prot->ecn;
if (!sysctl_tcp_syncookies || !th->ack || th->rst)
goto out;
@@ -179,7 +180,7 @@ struct sock *cookie_v6_check(struct sock *sk, struct sk_buff *skb)
memset(&tcp_opt, 0, sizeof(tcp_opt));
tcp_parse_options(skb, &tcp_opt, &hash_location, 0, NULL);
- if (!cookie_check_timestamp(&tcp_opt, &ecn_ok))
+ if (!cookie_check_timestamp(&tcp_opt, sysctl_tcp_ecn, &ecn_ok))
goto out;
ret = NULL;
diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c
index e85c48b..a2e764f 100644
--- a/net/ipv6/sysctl_net_ipv6.c
+++ b/net/ipv6/sysctl_net_ipv6.c
@@ -15,6 +15,7 @@
#include <net/ipv6.h>
#include <net/addrconf.h>
#include <net/inet_frag.h>
+#include <net/tcp.h>
static ctl_table ipv6_table_template[] = {
{
@@ -24,6 +25,13 @@ static ctl_table ipv6_table_template[] = {
.mode = 0644,
.proc_handler = proc_dointvec
},
+ {
+ .procname = "tcp_ecn",
+ .data = &tcpv6_prot.ecn,
+ .maxlen = sizeof(int),
+ .mode = 0644,
+ .proc_handler = proc_dointvec
+ },
{ }
};
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
index 93825dd..98bd8a3 100644
--- a/net/ipv6/tcp_ipv6.c
+++ b/net/ipv6/tcp_ipv6.c
@@ -1027,7 +1027,7 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb)
treq->rmt_addr = ipv6_hdr(skb)->saddr;
treq->loc_addr = ipv6_hdr(skb)->daddr;
if (!want_cookie || tmp_opt.tstamp_ok)
- TCP_ECN_create_request(req, skb);
+ TCP_ECN_create_request(req, skb, tcpv6_prot.ecn);
treq->iif = sk->sk_bound_dev_if;
@@ -1955,6 +1955,7 @@ struct proto tcpv6_prot = {
.rsk_prot = &tcp6_request_sock_ops,
.h.hashinfo = &tcp_hashinfo,
.no_autobind = true,
+ .ecn = 2,
#ifdef CONFIG_COMPAT
.compat_setsockopt = compat_tcp_setsockopt,
.compat_getsockopt = compat_tcp_getsockopt,
@@ -1963,6 +1964,7 @@ struct proto tcpv6_prot = {
.proto_cgroup = tcp_proto_cgroup,
#endif
};
+EXPORT_SYMBOL(tcpv6_prot);
static const struct inet6_protocol tcpv6_protocol = {
.early_demux = tcp_v6_early_demux,
^ permalink raw reply related
* Re: [patch net-next 01/15] net: introduce upper device lists
From: Stephen Hemminger @ 2012-12-31 19:22 UTC (permalink / raw)
To: Jiri Pirko
Cc: netdev, davem, edumazet, bhutchings, faisal.latif, fbl, roland,
sean.hefty, hal.rosenstock, fubar, andy, divy, jitendra.kalsaria,
sony.chacko, linux-driver, kaber, ursula.braun, blaschka,
schwidefsky, heiko.carstens, ebiederm, joe, amwang, nhorman,
john.r.fastabend, pablo
In-Reply-To: <1356868702-8144-2-git-send-email-jiri@resnulli.us>
On Sun, 30 Dec 2012 12:58:08 +0100
Jiri Pirko <jiri@resnulli.us> wrote:
> This lists are supposed to serve for storing pointers to all upper devices.
> Eventually it will replace dev->master pointer which is used for
> bonding, bridge, team but it cannot be used for vlan, macvlan where
> there might be multiple upper present. In case the upper link is
> replacement for dev->master, it is marked with "master" flag.
>
> New upper device list resolves this limitation. Also, the information
> stored in lists is used for preventing looping setups like
> "bond->somethingelse->samebond"
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
I like the concept of knowing the topology of layered network devices.
The name "upper device lists" is a little confusing to me.
Also, the amount of additional data structures and book keeping
seems more than needed; but not sure how to reduce it down to the
least code.
For simple case of detecting loops, just using existing master
pointer is sufficient.
ethernet --> bonding --> bridge --+
^ |
| |
+-----------------+
This is the simple case of detecting if singularly linked list
is a loop.
The only device where multiple upper devices is possible seems
to be macvlan. Could the special case code be limited to there?
^ permalink raw reply
* [PATCH] vxlan: allow live mac address change
From: Stephen Hemminger @ 2012-12-31 22:00 UTC (permalink / raw)
To: David Miller; +Cc: netdev
The VXLAN pseudo-device doesn't care if the mac address changes
when device is up.
Signed-off-by: Stephen Hemminger <shemminger@vyatta.com>
--- a/drivers/net/vxlan.c 2012-12-27 22:30:53.630796042 -0800
+++ b/drivers/net/vxlan.c 2012-12-31 10:46:25.435321912 -0800
@@ -1191,6 +1191,7 @@ static void vxlan_setup(struct net_devic
dev->hw_features |= NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
+ dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
spin_lock_init(&vxlan->hash_lock);
^ permalink raw reply
* Re: [PATCH] tcp: split tcp_ecn sysctl knob to distinguish between IPv4 and IPv6
From: Stephen Hemminger @ 2012-12-31 22:04 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: netdev
In-Reply-To: <20121231173532.GA11700@order.stressinduktion.org>
On Mon, 31 Dec 2012 18:35:33 +0100
Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
> diff --git a/include/net/sock.h b/include/net/sock.h
> index 182ca99..aa3c30e 100644
> --- a/include/net/sock.h
> +++ b/include/net/sock.h
> @@ -944,6 +944,7 @@ struct proto {
> int *sysctl_rmem;
> int max_header;
> bool no_autobind;
> + int ecn;
>
Why isn't this a bool?
^ permalink raw reply
* Re: [PATCH] tcp: split tcp_ecn sysctl knob to distinguish between IPv4 and IPv6
From: Stephen Hemminger @ 2012-12-31 22:05 UTC (permalink / raw)
To: Hannes Frederic Sowa; +Cc: netdev
In-Reply-To: <20121231173532.GA11700@order.stressinduktion.org>
On Mon, 31 Dec 2012 18:35:33 +0100
Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
> ECN could be more reliable when used with IPv6 (I don't have proofs). For
> people who want to try ECN with IPv6 but still have problems connecting
> to destinations because of broken IPv4 routers this switch allows one
> to enable ECN just for IPv6.
>
> Perhaps ECN could be enabled by default in future.
>
> Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
Any new or modified sysctl should be documented in:
Documentation/networking/ip-sysctl.txt
^ permalink raw reply
* Re: [PATCH v2 net-next] team: add ethtool support
From: Ben Hutchings @ 2012-12-31 22:16 UTC (permalink / raw)
To: Flavio Leitner; +Cc: netdev, Jiri Pirko
In-Reply-To: <1356835053-25602-1-git-send-email-fbl@redhat.com>
On Sun, 2012-12-30 at 00:37 -0200, Flavio Leitner wrote:
> This patch adds few ethtool operations to team driver.
>
> Signed-off-by: Flavio Leitner <fbl@redhat.com>
> ---
> v2 - removed generic statistics from ethtool
>
> drivers/net/team/team.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/drivers/net/team/team.c b/drivers/net/team/team.c
> index ad86660..7665a088 100644
> --- a/drivers/net/team/team.c
> +++ b/drivers/net/team/team.c
[...]
> +static void team_ethtool_get_drvinfo(struct net_device *dev,
> + struct ethtool_drvinfo *drvinfo)
> +{
> + strncpy(drvinfo->driver, DRV_NAME, 32);
> + strncpy(drvinfo->version, UTS_RELEASE, 32);
> +}
[...]
These must be null-terminated, so use strlcpy() not strncpy().
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
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 RFC 15/15] via-rhine: add helper (reduce type-unsafe void * assignments).
From: David Miller @ 2012-12-31 22:21 UTC (permalink / raw)
To: andi; +Cc: andim2, rl, netdev, romieu
In-Reply-To: <1356967549-5056-16-git-send-email-andi@lisas.de>
From: Andreas Mohr <andi@lisas.de>
Date: Mon, 31 Dec 2012 16:25:49 +0100
> From: Andreas Mohr <andim2@users.sf.net>
>
> Signed-off-by: Andreas Mohr <andim2@users.sf.net>
This is of zero value.
It is just as likely one would forget to use the helper as it would be
to assign pci_get_drvdata() to a pointer of the wrong type.
^ permalink raw reply
* Re: [PATCH] net: fix checking boundary of valid vlan id
From: Glen Turner @ 2012-12-31 22:30 UTC (permalink / raw)
To: Benny Amorsen; +Cc: Florian Westphal, akong, netdev, davem
In-Reply-To: <m3fw2mp2lh.fsf@ursa.amorsen.dk>
On 01/01/2013, at 3:42 AM, Benny Amorsen wrote:
> Glen Turner <gdt@gdt.id.au> writes:
>
>> It may be a valid VLAN ID, or it may not. The meaning of FFF is
>> reserved for vendor use, which doesn't preclude a vendor using it as a
>> (non-interoperable) VLAN identifier. Many vendor's products treat 4096
>> as they do any other VID.
>
> I may be missing something vital, but 4096 is 0x1000 not 0xFFF? 4095 is
> reserved and 0 means "treat as if the packet was untagged". 4096 is
> impossible, there are only 12 bit and the encoding is AFAIK bog standard
> binary.
Yep, I've failed at hex math. 0xfff = 4095 is the maximal VID value, and is the one reserved for vendor use.
Which means that the patch checking values 1 to 4095 is correct.
My apologies,
glen
^ permalink raw reply
* Re: [PATCH net-next 0/8] Add complementary BPF conditional jump instructions
From: David Miller @ 2012-12-31 22:37 UTC (permalink / raw)
To: dborkman; +Cc: netdev
In-Reply-To: <cover.1356960070.git.dborkman@redhat.com>
From: Daniel Borkmann <dborkman@redhat.com>
Date: Mon, 31 Dec 2012 14:59:40 +0100
> This set adds adds jump operations for lt (<), le (<=), ne (!=) that
> compare A with K resp. X in order to facilitate filter programming
> with conditional jumps, as also available in McCanne et. al's BPF+
> paper (``BPF+: Exploiting Global Data-flow Optimization in a Generalized
> Packet Filter Architecture'').
>
> Also, follow-up BPF JIT implementations for x86, Sparc and PowerPC
> are added in this set.
Whilst I agree that adding NE jumps adds great value and closes a
serious gap, the rest can be synthesized by simply swapping the
arguments and using a comparison that does already exist.
Why isn't that sufficient?
^ permalink raw reply
* Re: [PATCH] poll: prevent missed events if _qproc is NULL
From: Eric Wong @ 2012-12-31 23:24 UTC (permalink / raw)
To: linux-kernel
Cc: Hans Verkuil, Jiri Olsa, Jonathan Corbet, Al Viro, Davide Libenzi,
Hans de Goede, Mauro Carvalho Chehab, David Miller, Eric Dumazet,
Andrew Morton, Linus Torvalds, Andreas Voellmy,
Junchang(Jason) Wang, netdev, linux-fsdevel
In-Reply-To: <1356960060-1263-1-git-send-email-normalperson@yhbt.net>
Eric Wong <normalperson@yhbt.net> wrote:
> This patch seems to fix my issue with ppoll() being stuck on my
> SMP machine: http://article.gmane.org/gmane.linux.file-systems/70414
OK, it doesn't fix my issue, but it seems to make it harder-to-hit...
> The change to sock_poll_wait() in
> commit 626cf236608505d376e4799adb4f7eb00a8594af
> (poll: add poll_requested_events() and poll_does_not_wait() functions)
> seems to have allowed additional cases where the SMP memory barrier
> is not issued before checking for readiness.
>
> In my case, this affects the select()-family of functions
> which register descriptors once and set _qproc to NULL before
> checking events again (after poll_schedule_timeout() returns).
> The set_mb() barrier in poll_schedule_timeout() appears to be
> insufficient on my SMP x86-64 machine (as it's only an xchg()).
>
> This may also be related to the epoll issue described by
> Andreas Voellmy in http://thread.gmane.org/gmane.linux.kernel/1408782/
However, I believe my patch will still fix Andreas' issue with epoll
due to how ep_modify() uses a NULL qproc when calling ->poll().
(I've never been able to reproduce Andreas' issue on my 4-core system,
but he's been hitting it since 3.4 (at least))
^ permalink raw reply
* Re: [PATCH] tcp: split tcp_ecn sysctl knob to distinguish between IPv4 and IPv6
From: Hannes Frederic Sowa @ 2012-12-31 23:48 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20121231140412.7dee9821@nehalam.linuxnetplumber.net>
On Mon, Dec 31, 2012 at 02:04:12PM -0800, Stephen Hemminger wrote:
> On Mon, 31 Dec 2012 18:35:33 +0100
> Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
>
> > diff --git a/include/net/sock.h b/include/net/sock.h
> > index 182ca99..aa3c30e 100644
> > --- a/include/net/sock.h
> > +++ b/include/net/sock.h
> > @@ -944,6 +944,7 @@ struct proto {
> > int *sysctl_rmem;
> > int max_header;
> > bool no_autobind;
> > + int ecn;
> >
> Why isn't this a bool?
It is a tristate: disable ecn(0), request ecn(1) and accept ecn(2).
^ permalink raw reply
* Re: [PATCH] tcp: split tcp_ecn sysctl knob to distinguish between IPv4 and IPv6
From: Hannes Frederic Sowa @ 2012-12-31 23:58 UTC (permalink / raw)
To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20121231140538.6e55c82d@nehalam.linuxnetplumber.net>
On Mon, Dec 31, 2012 at 02:05:38PM -0800, Stephen Hemminger wrote:
> On Mon, 31 Dec 2012 18:35:33 +0100
> Hannes Frederic Sowa <hannes@stressinduktion.org> wrote:
>
> > ECN could be more reliable when used with IPv6 (I don't have proofs). For
> > people who want to try ECN with IPv6 but still have problems connecting
> > to destinations because of broken IPv4 routers this switch allows one
> > to enable ECN just for IPv6.
> >
> > Perhaps ECN could be enabled by default in future.
> >
> > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
>
> Any new or modified sysctl should be documented in:
> Documentation/networking/ip-sysctl.txt
Ack. I'll wait a bit for further feedback and will submit a -v2 with updated
documentation.
^ 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