* [PATCH ethtool 06/21] ethtool.8: Allow line-break in description of parameters after -N
From: Ben Hutchings @ 2011-11-01 23:15 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
These lines are currently unbreakable and result in ugly wrapping
in an 80-column window.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 65392d6..3304fe5 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -256,7 +256,7 @@ ethtool \- query or control network driver and hardware settings
.HP
.B ethtool \-N
.I devname
-.RB [ rx\-flow\-hash \ \*(FL \ \*(HO]
+.RB [ rx\-flow\-hash \ \*(FL \: \*(HO]
.HP
.B ethtool \-w|\-\-get\-dump
.I devname
@@ -605,7 +605,7 @@ sctp6 SCTP over IPv6
.B \-N \-\-config\-nfc
Configures the receive network flow classification.
.TP
-.BR rx\-flow\-hash \ \*(FL \ \*(HO
+.BR rx\-flow\-hash \ \*(FL \: \*(HO
Configures the hash options for the specified network traffic type.
.TS
nokeep;
--
1.7.4.4
--
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 related
* [PATCH ethtool 05/21] ethtool.8: Change device name metavariable from 'ethX' to 'devname'
From: Ben Hutchings @ 2011-11-01 23:15 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
The name 'ethX' is a poor choice because:
- Many ethtool options are applicable to non-Ethernet devices
- Ethernet device names don't have to begin with 'eth', and the
new convention is to use the prefix 'lan' for LAN-on-motherboard
or 'pci' for PCI plug-in cards
The online help text already uses 'DEVNAME' instead, so change the
manual page to be consistent.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 62 +++++++++++++++++++++++++++++-----------------------------
1 files changed, 31 insertions(+), 31 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index 286d089..65392d6 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -123,26 +123,26 @@ ethtool \- query or control network driver and hardware settings
.nh
.HP
.B ethtool
-.I ethX
+.I devname
.HP
.B ethtool \-h|\-\-help
.HP
.B ethtool \-\-version
.HP
.B ethtool \-a|\-\-show\-pause
-.I ethX
+.I devname
.HP
.B ethtool \-A|\-\-pause
-.I ethX
+.I devname
.B2 autoneg on off
.B2 rx on off
.B2 tx on off
.HP
.B ethtool \-c|\-\-show\-coalesce
-.I ethX
+.I devname
.HP
.B ethtool \-C|\-\-coalesce
-.I ethX
+.I devname
.B2 adaptive\-rx on off
.B2 adaptive\-tx on off
.BN rx\-usecs
@@ -167,43 +167,43 @@ ethtool \- query or control network driver and hardware settings
.BN sample\-interval
.HP
.B ethtool \-g|\-\-show\-ring
-.I ethX
+.I devname
.HP
.B ethtool \-G|\-\-set\-ring
-.I ethX
+.I devname
.BN rx
.BN rx\-mini
.BN rx\-jumbo
.BN tx
.HP
.B ethtool \-i|\-\-driver
-.I ethX
+.I devname
.HP
.B ethtool \-d|\-\-register\-dump
-.I ethX
+.I devname
.B2 raw on off
.B2 hex on off
.RB [ file
.IR name ]
.HP
.B ethtool \-e|\-\-eeprom\-dump
-.I ethX
+.I devname
.B2 raw on off
.BN offset
.BN length
.HP
.B ethtool \-E|\-\-change\-eeprom
-.I ethX
+.I devname
.BN magic
.BN offset
.BN length
.BN value
.HP
.B ethtool \-k|\-\-show\-offload
-.I ethX
+.I devname
.HP
.B ethtool \-K|\-\-offload
-.I ethX
+.I devname
.B2 rx on off
.B2 tx on off
.B2 sg on off
@@ -217,24 +217,24 @@ ethtool \- query or control network driver and hardware settings
.B2 rxhash on off
.HP
.B ethtool \-p|\-\-identify
-.I ethX
+.I devname
.RI [ N ]
.HP
.B ethtool \-P|\-\-show\-permaddr
-.I ethX
+.I devname
.HP
.B ethtool \-r|\-\-negotiate
-.I ethX
+.I devname
.HP
.B ethtool \-S|\-\-statistics
-.I ethX
+.I devname
.HP
.B ethtool \-t|\-\-test
-.I ethX
+.I devname
.RI [\*(SD]
.HP
.B ethtool \-s
-.I ethX
+.I devname
.BI speed \ N
.B2 duplex half full
.B4 port tp aui bnc mii fibre
@@ -251,27 +251,27 @@ ethtool \- query or control network driver and hardware settings
.RB ...]
.HP
.B ethtool \-n
-.I ethX
+.I devname
.RB [ rx\-flow\-hash \ \*(FL]
.HP
.B ethtool \-N
-.I ethX
+.I devname
.RB [ rx\-flow\-hash \ \*(FL \ \*(HO]
.HP
.B ethtool \-w|\-\-get\-dump
-.I ethX
+.I devname
.RB [ data
.IR filename ]
.HP
.B ethtool\ \-W|\-\-set\-dump
-.I ethX
+.I devname
.BI \ N
.HP
.B ethtool \-x|\-\-show\-rxfh\-indir
-.I ethX
+.I devname
.HP
.B ethtool \-X|\-\-set\-rxfh\-indir
-.I ethX
+.I devname
.RB [\ equal
.IR N \ |
.BI weight\ W0
@@ -279,15 +279,15 @@ ethtool \- query or control network driver and hardware settings
.RB ...\ ]
.HP
.B ethtool \-f|\-\-flash
-.I ethX
+.I devname
.RI FILE
.RI [ N ]
.HP
.B ethtool \-u|\-\-show\-ntuple
-.I ethX
+.I devname
.BN rule
.HP
-.BI ethtool\ \-U|\-\-config\-ntuple \ ethX
+.BI ethtool\ \-U|\-\-config\-ntuple \ devname
.BN delete
.RB [\ flow\-type \ \*(NC
.RB [ src \ \*(MA\ [ m \ \*(MA]]
@@ -309,10 +309,10 @@ ethtool \- query or control network driver and hardware settings
.RB ]
.HP
.B ethtool \-l|\-\-show\-channels
-.I ethX
+.I devname
.HP
.B ethtool \-L|\-\-set\-channels
-.I ethX
+.I devname
.BN rx
.BN tx
.BN other
@@ -327,7 +327,7 @@ ethtool \- query or control network driver and hardware settings
is used to query and control network device driver and hardware
settings, particularly for wired Ethernet devices.
-.I ethX
+.I devname
is the name of the network device on which ethtool should operate.
.SH OPTIONS
--
1.7.4.4
--
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 related
* [PATCH ethtool 04/21] Fix type of bit-number parameter to set_bit() and clear_bit()
From: Ben Hutchings @ 2011-11-01 23:14 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Alexander Duyck
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
The index must not be negative, so the parameter does not need to be
signed. Division and modulus on signed operands generally cannot be
optimised to right-shift and bitwise-and.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
internal.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/internal.h b/internal.h
index 693b091..2b6a54a 100644
--- a/internal.h
+++ b/internal.h
@@ -62,12 +62,12 @@ static inline u64 cpu_to_be64(u64 value)
#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
-static inline void set_bit(int nr, unsigned long *addr)
+static inline void set_bit(unsigned int nr, unsigned long *addr)
{
addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
}
-static inline void clear_bit(int nr, unsigned long *addr)
+static inline void clear_bit(unsigned int nr, unsigned long *addr)
{
addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
}
--
1.7.4.4
--
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 related
* [PATCH ethtool 03/21] Combine ethtool-{bitops,util}.h into internal.h
From: Ben Hutchings @ 2011-11-01 23:14 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
ethtool-util.h contains all kinds of declarations, not just utility
functions or macros.
ethtool-bitops.h contains just a few extra definitions, and its only
user also includes ethtool-util.h.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
Makefile.am | 2 +-
amd8111e.c | 2 +-
at76c50x-usb.c | 2 +-
de2104x.c | 2 +-
e100.c | 2 +-
e1000.c | 2 +-
ethtool-bitops.h | 25 -------------------------
ethtool.c | 2 +-
fec_8xx.c | 2 +-
ibm_emac.c | 2 +-
igb.c | 2 +-
ethtool-util.h => internal.h | 27 ++++++++++++++++++++++++---
ixgb.c | 2 +-
ixgbe.c | 2 +-
marvell.c | 2 +-
natsemi.c | 2 +-
pcnet32.c | 2 +-
realtek.c | 2 +-
rxclass.c | 3 +--
sfc.c | 2 +-
smsc911x.c | 2 +-
stmmac.c | 2 +-
tg3.c | 2 +-
vioc.c | 2 +-
24 files changed, 46 insertions(+), 51 deletions(-)
delete mode 100644 ethtool-bitops.h
rename ethtool-util.h => internal.h (86%)
diff --git a/Makefile.am b/Makefile.am
index c87fb39..1e05640 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,7 +4,7 @@ man_MANS = ethtool.8
EXTRA_DIST = LICENSE ethtool.8 ethtool.spec.in aclocal.m4 ChangeLog autogen.sh
sbin_PROGRAMS = ethtool
-ethtool_SOURCES = ethtool.c ethtool-bitops.h ethtool-copy.h ethtool-util.h \
+ethtool_SOURCES = ethtool.c ethtool-copy.h internal.h \
amd8111e.c de2104x.c e100.c e1000.c igb.c \
fec_8xx.c ibm_emac.c ixgb.c ixgbe.c natsemi.c \
pcnet32.c realtek.c tg3.c marvell.c vioc.c \
diff --git a/amd8111e.c b/amd8111e.c
index b4cd65d..23478f0 100644
--- a/amd8111e.c
+++ b/amd8111e.c
@@ -1,7 +1,7 @@
/* Copyright (C) 2003 Advanced Micro Devices Inc. */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
typedef enum {
/* VAL2 */
diff --git a/at76c50x-usb.c b/at76c50x-usb.c
index 4c2a1a8..39e24a4 100644
--- a/at76c50x-usb.c
+++ b/at76c50x-usb.c
@@ -1,5 +1,5 @@
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
static char *hw_versions[] = {
"503_ISL3861",
diff --git a/de2104x.c b/de2104x.c
index f64e1b2..856e0c0 100644
--- a/de2104x.c
+++ b/de2104x.c
@@ -1,6 +1,6 @@
/* Copyright 2001 Sun Microsystems (thockin@sun.com) */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
static const char * const csr0_tap[4] = {
"No transmit automatic polling",
diff --git a/e100.c b/e100.c
index 4d1cef3..65627ab 100644
--- a/e100.c
+++ b/e100.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2002 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define D102_REV_ID 12
diff --git a/e1000.c b/e1000.c
index 2eb3ac6..d1d3c73 100644
--- a/e1000.c
+++ b/e1000.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2002 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Register Bit Masks */
/* Device Control */
diff --git a/ethtool-bitops.h b/ethtool-bitops.h
deleted file mode 100644
index b1eb426..0000000
--- a/ethtool-bitops.h
+++ /dev/null
@@ -1,25 +0,0 @@
-#ifndef ETHTOOL_BITOPS_H__
-#define ETHTOOL_BITOPS_H__
-
-#define BITS_PER_BYTE 8
-#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
-#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
-#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
-
-static inline void set_bit(int nr, unsigned long *addr)
-{
- addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
-}
-
-static inline void clear_bit(int nr, unsigned long *addr)
-{
- addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
-}
-
-static inline int test_bit(unsigned int nr, const unsigned long *addr)
-{
- return !!((1UL << (nr % BITS_PER_LONG)) &
- (((unsigned long *)addr)[nr / BITS_PER_LONG]));
-}
-
-#endif
diff --git a/ethtool.c b/ethtool.c
index ad2d583..f772f61 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -23,7 +23,7 @@
* * show settings for all devices
*/
-#include "ethtool-util.h"
+#include "internal.h"
#include <string.h>
#include <stdlib.h>
#include <sys/stat.h>
diff --git a/fec_8xx.c b/fec_8xx.c
index 06a25d9..69db8c8 100644
--- a/fec_8xx.c
+++ b/fec_8xx.c
@@ -7,7 +7,7 @@
#include <stdint.h>
#include <stddef.h>
-#include "ethtool-util.h"
+#include "internal.h"
struct fec {
uint32_t addr_low; /* lower 32 bits of station address */
diff --git a/ibm_emac.c b/ibm_emac.c
index 7974836..e128e48 100644
--- a/ibm_emac.c
+++ b/ibm_emac.c
@@ -6,7 +6,7 @@
#include <stdint.h>
#include <stddef.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Ethtool get_regs complex data.
* we want to get not just EMAC registers, but also MAL, ZMII, RGMII, TAH
diff --git a/igb.c b/igb.c
index 4b836d9..ec35d36 100644
--- a/igb.c
+++ b/igb.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2007 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Register Bit Masks */
/* Device Control */
diff --git a/ethtool-util.h b/internal.h
similarity index 86%
rename from ethtool-util.h
rename to internal.h
index 79be7f2..693b091 100644
--- a/ethtool-util.h
+++ b/internal.h
@@ -1,7 +1,7 @@
/* Portions Copyright 2001 Sun Microsystems (thockin@sun.com) */
/* Portions Copyright 2002 Intel (scott.feldman@intel.com) */
-#ifndef ETHTOOL_UTIL_H__
-#define ETHTOOL_UTIL_H__
+#ifndef ETHTOOL_INTERNAL_H__
+#define ETHTOOL_INTERNAL_H__
#ifdef HAVE_CONFIG_H
#include "ethtool-config.h"
@@ -57,6 +57,27 @@ static inline u64 cpu_to_be64(u64 value)
#define ntohll cpu_to_be64
#define htonll cpu_to_be64
+#define BITS_PER_BYTE 8
+#define BITS_PER_LONG (BITS_PER_BYTE * sizeof(long))
+#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+#define BITS_TO_LONGS(nr) DIV_ROUND_UP(nr, BITS_PER_LONG)
+
+static inline void set_bit(int nr, unsigned long *addr)
+{
+ addr[nr / BITS_PER_LONG] |= 1UL << (nr % BITS_PER_LONG);
+}
+
+static inline void clear_bit(int nr, unsigned long *addr)
+{
+ addr[nr / BITS_PER_LONG] &= ~(1UL << (nr % BITS_PER_LONG));
+}
+
+static inline int test_bit(unsigned int nr, const unsigned long *addr)
+{
+ return !!((1UL << (nr % BITS_PER_LONG)) &
+ (((unsigned long *)addr)[nr / BITS_PER_LONG]));
+}
+
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#endif
@@ -140,4 +161,4 @@ int rxclass_rule_ins(int fd, struct ifreq *ifr,
struct ethtool_rx_flow_spec *fsp);
int rxclass_rule_del(int fd, struct ifreq *ifr, __u32 loc);
-#endif /* ETHTOOL_UTIL_H__ */
+#endif /* ETHTOOL_INTERNAL_H__ */
diff --git a/ixgb.c b/ixgb.c
index 00c90d3..8687c21 100644
--- a/ixgb.c
+++ b/ixgb.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2006 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* CTRL0 Bit Masks */
#define IXGB_CTRL0_LRST 0x00000008
diff --git a/ixgbe.c b/ixgbe.c
index e64d34a..dae11d4 100644
--- a/ixgbe.c
+++ b/ixgbe.c
@@ -1,6 +1,6 @@
/* Copyright (c) 2007 Intel Corporation */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
/* Register Bit Masks */
#define IXGBE_FCTRL_SBP 0x00000002
diff --git a/marvell.c b/marvell.c
index af38c21..e583c82 100644
--- a/marvell.c
+++ b/marvell.c
@@ -7,7 +7,7 @@
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
static void dump_addr(int n, const u8 *a)
{
diff --git a/natsemi.c b/natsemi.c
index 24a7cb3..eaf83e2 100644
--- a/natsemi.c
+++ b/natsemi.c
@@ -1,6 +1,6 @@
/* Copyright 2001 Sun Microsystems (thockin@sun.com) */
#include <stdio.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define PCI_VENDOR_NATSEMI 0x100b
#define PCI_DEVICE_DP83815 0x0020
diff --git a/pcnet32.c b/pcnet32.c
index 1dac02d..b87cee7 100644
--- a/pcnet32.c
+++ b/pcnet32.c
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define BIT0 0x0001
#define BIT1 0x0002
diff --git a/realtek.c b/realtek.c
index 11ed835..c3d7ae5 100644
--- a/realtek.c
+++ b/realtek.c
@@ -1,7 +1,7 @@
/* Copyright 2001 Sun Microsystems (thockin@sun.com) */
#include <stdio.h>
#include <stdlib.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/rxclass.c b/rxclass.c
index b227901..809b073 100644
--- a/rxclass.c
+++ b/rxclass.c
@@ -10,8 +10,7 @@
#include <linux/sockios.h>
#include <arpa/inet.h>
-#include "ethtool-util.h"
-#include "ethtool-bitops.h"
+#include "internal.h"
static void invert_flow_mask(struct ethtool_rx_flow_spec *fsp)
{
diff --git a/sfc.c b/sfc.c
index c8ca74a..46a617b 100644
--- a/sfc.c
+++ b/sfc.c
@@ -9,7 +9,7 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
diff --git a/smsc911x.c b/smsc911x.c
index 1aa39a1..c55b97b 100644
--- a/smsc911x.c
+++ b/smsc911x.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
int smsc911x_dump_regs(struct ethtool_drvinfo *info, struct ethtool_regs *regs)
{
diff --git a/stmmac.c b/stmmac.c
index ad4311c..fb69bfe 100644
--- a/stmmac.c
+++ b/stmmac.c
@@ -12,7 +12,7 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
int st_mac100_dump_regs(struct ethtool_drvinfo *info,
struct ethtool_regs *regs)
diff --git a/tg3.c b/tg3.c
index 4868504..3232339 100644
--- a/tg3.c
+++ b/tg3.c
@@ -1,6 +1,6 @@
#include <stdio.h>
#include <string.h>
-#include "ethtool-util.h"
+#include "internal.h"
#define TG3_MAGIC 0x669955aa
diff --git a/vioc.c b/vioc.c
index c771737..eff533d 100644
--- a/vioc.c
+++ b/vioc.c
@@ -2,7 +2,7 @@
#include <stdio.h>
#include <stdlib.h>
-#include "ethtool-util.h"
+#include "internal.h"
struct regs_line {
u32 addr;
--
1.7.4.4
--
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 related
* [PATCH ethtool 02/21] ethtool.8: Fix initial blank line/page
From: Ben Hutchings @ 2011-11-01 23:13 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
Commit 8d63f72ccdcb1b19358d753a8f48f08dcd2136f0 included a regression
of the problem fixed in commit 97b5471fc446d60f8772631b9c4e6d824404336d.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.8.in | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/ethtool.8.in b/ethtool.8.in
index f9d3633..286d089 100644
--- a/ethtool.8.in
+++ b/ethtool.8.in
@@ -75,7 +75,7 @@
.\" \(*NC - Network Classifier type values
.\"
.ds NC \fBether\fP|\fBip4\fP|\fBtcp4\fP|\fBudp4\fP|\fBsctp4\fP|\fBah4\fP|\fBesp4\fP
-
+..
.\"
.\" Start URL.
.de UR
--
1.7.4.4
--
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 related
* [PATCH ethtool 01/21] Report pause frame autonegotiation result
From: Ben Hutchings @ 2011-11-01 23:13 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers, Matt Carlson
In-Reply-To: <1320186901.2758.30.camel@bwh-desktop>
If pause frame autonegotiation is enabled and the driver reports the
link partner's advertising flags, report the result of autonegotiation.
Signed-off-by: Ben Hutchings <bhutchings@solarflare.com>
---
ethtool.c | 46 ++++++++++++++++++++++++++++++++++++++++------
1 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/ethtool.c b/ethtool.c
index a4e8b58..ad2d583 100644
--- a/ethtool.c
+++ b/ethtool.c
@@ -1745,7 +1745,7 @@ static int dump_test(struct ethtool_drvinfo *info, struct ethtool_test *test,
return rc;
}
-static int dump_pause(void)
+static int dump_pause(u32 advertising, u32 lp_advertising)
{
fprintf(stdout,
"Autonegotiate: %s\n"
@@ -1755,6 +1755,30 @@ static int dump_pause(void)
epause.rx_pause ? "on" : "off",
epause.tx_pause ? "on" : "off");
+ if (lp_advertising) {
+ int an_rx = 0, an_tx = 0;
+
+ /* Work out negotiated pause frame usage per
+ * IEEE 802.3-2005 table 28B-3.
+ */
+ if (advertising & lp_advertising & ADVERTISED_Pause) {
+ an_tx = 1;
+ an_rx = 1;
+ } else if (advertising & lp_advertising &
+ ADVERTISED_Asym_Pause) {
+ if (advertising & ADVERTISED_Pause)
+ an_rx = 1;
+ else if (lp_advertising & ADVERTISED_Pause)
+ an_tx = 1;
+ }
+
+ fprintf(stdout,
+ "RX negotiated: %s\n"
+ "TX negotiated: %s\n",
+ an_rx ? "on" : "off",
+ an_tx ? "on" : "off");
+ }
+
fprintf(stdout, "\n");
return 0;
}
@@ -2051,6 +2075,7 @@ static int do_gdrv(int fd, struct ifreq *ifr)
static int do_gpause(int fd, struct ifreq *ifr)
{
+ struct ethtool_cmd ecmd;
int err;
fprintf(stdout, "Pause parameters for %s:\n", devname);
@@ -2058,15 +2083,24 @@ static int do_gpause(int fd, struct ifreq *ifr)
epause.cmd = ETHTOOL_GPAUSEPARAM;
ifr->ifr_data = (caddr_t)&epause;
err = send_ioctl(fd, ifr);
- if (err == 0) {
- err = dump_pause();
- if (err)
- return err;
- } else {
+ if (err) {
perror("Cannot get device pause settings");
return 76;
}
+ if (epause.autoneg) {
+ ecmd.cmd = ETHTOOL_GSET;
+ ifr->ifr_data = (caddr_t)&ecmd;
+ err = send_ioctl(fd, ifr);
+ if (err) {
+ perror("Cannot get device settings");
+ return 1;
+ }
+ dump_pause(ecmd.advertising, ecmd.lp_advertising);
+ } else {
+ dump_pause(0, 0);
+ }
+
return 0;
}
--
1.7.4.4
--
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 related
* [PATCH] udp: fix a race in encap_rcv handling
From: Eric Dumazet @ 2011-11-01 22:56 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <CAKpUy7Z5KOfHbKfBp-qg+77cED=OxUAkm2P4pQacHaHKmKBQpw@mail.gmail.com>
udp_queue_rcv_skb() has a possible race in encap_rcv handling, since
this pointer can be changed anytime.
We should use ACCESS_ONCE() to close the race.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
net/ipv4/udp.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index ebaa96b..15b50df 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -1397,6 +1397,8 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
nf_reset(skb);
if (up->encap_type) {
+ int (*encap_rcv)(struct sock *sk, struct sk_buff *skb);
+
/*
* This is an encapsulation socket so pass the skb to
* the socket's udp_encap_rcv() hook. Otherwise, just
@@ -1409,11 +1411,11 @@ int udp_queue_rcv_skb(struct sock *sk, struct sk_buff *skb)
*/
/* if we're overly short, let UDP handle it */
- if (skb->len > sizeof(struct udphdr) &&
- up->encap_rcv != NULL) {
+ encap_rcv = ACCESS_ONCE(up->encap_rcv);
+ if (skb->len > sizeof(struct udphdr) && encap_rcv != NULL) {
int ret;
- ret = (*up->encap_rcv)(sk, skb);
+ ret = encap_rcv(sk, skb);
if (ret <= 0) {
UDP_INC_STATS_BH(sock_net(sk),
UDP_MIB_INDATAGRAMS,
^ permalink raw reply related
* Re: PROBLEM: pppol2tp over pppoe NULL pointer dereference
From: Eric Dumazet @ 2011-11-01 22:35 UTC (permalink / raw)
To: Misha Labjuk; +Cc: netdev
In-Reply-To: <CAKpUy7Z5KOfHbKfBp-qg+77cED=OxUAkm2P4pQacHaHKmKBQpw@mail.gmail.com>
Le mercredi 02 novembre 2011 à 01:00 +0300, Misha Labjuk a écrit :
> pppol2tp over pppoe NULL pointer dereference
>
> Kernel panic after establishing pppol2tp tunnel over pppoe connection.
> Get panic in 5-15 min with 10 mbit/s data transfer speed.
> pppoe and pppol2tp connections stable separately.
>
> Linux version 3.1.0 (user@host) (gcc version 4.6.1 (Gentoo 4.6.1-r1
> p1.0, pie-0.4.5) ) #1 SMP Mon Oct 31 18:48:18 MSK 2011
>
> [ 151.913193] L2TP core driver, V2.0
> [ 151.974584] L2TP netlink interface
> [ 151.993803] PPPoL2TP kernel driver, V2.0
> [ 437.496670] BUG: unable to handle kernel NULL pointer dereference
> at 0000000000000008
> [ 437.496683] IP: [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621 [l2tp_core]
> [ 437.496691] PGD d7840067 PUD cd4e7067 PMD 0
> [ 437.496697] Oops: 0002 [#1] SMP
> [ 437.496702] CPU 0
> [ 437.496704] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core
> firewire_sbp2 sit tunnel4 netconsole it87 hwmon_vid coretemp pppoe
> pppox ppp_generic slhc ipt_MASQUERADE iptable_nat nf_nat
> nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 xt_TCPMSS iptable_mangle
> ip_tables snd_seq_midi snd_emu10k1_synth snd_emux_synth
> snd_seq_virmidi snd_seq_midi_emul snd_seq_dummy snd_seq_oss
> snd_seq_midi_event snd_seq snd_pcm_oss snd_mixer_oss nfsd lockd
> nfs_acl auth_rpcgss sunrpc usb_storage usb_libusual uas usbhid ipv6
> snd_emu10k1 8250_pnp snd_rawmidi snd_hda_codec_realtek snd_ac97_codec
> snd_hda_intel snd_hda_codec uhci_hcd ac97_bus snd_pcm ehci_hcd usbcore
> snd_seq_device snd_timer 8250 snd_util_mem snd_hwdep psmouse snd
> firewire_ohci firewire_core serial_core intel_agp intel_gtt pcspkr
> soundcore r8169 crc_itu_t mii snd_page_alloc processor button
> [ 437.497005]
> [ 437.497005] Pid: 3274, comm: qbittorrent Not tainted 3.1.0 #1
> Gigabyte Technology Co., Ltd. EP45-EXTREME/EP45-EXTREME
> [ 437.497005] RIP: 0010:[<ffffffffa03679dc>] [<ffffffffa03679dc>]
> l2tp_recv_common+0x4d3/0x621 [l2tp_core]
> [ 437.497005] RSP: 0000:ffff88011fc03b90 EFLAGS: 00010296
> [ 437.497005] RAX: 0000000000000000 RBX: ffff8800d79e8200 RCX: ffff88011fc10bd0
> [ 437.497005] RDX: 0000000000000000 RSI: 0000000000004002 RDI: ffff8800d79e8254
> [ 437.497005] RBP: ffff88011fc03be0 R08: 0000000000004002 R09: 0000000000004002
> [ 437.497005] R10: ffff8801091ec87a R11: ffff88011b300000 R12: ffff880118922300
> [ 437.497005] R13: 0000000000000000 R14: ffff8800d79e8254 R15: ffff8800d79e826c
> [ 437.497005] FS: 00007f0ced3e8700(0000) GS:ffff88011fc00000(0000)
> knlGS:0000000000000000
> [ 437.497005] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
> [ 437.497005] CR2: 0000000000000008 CR3: 00000000c8811000 CR4: 00000000000406f0
> [ 437.497005] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
> [ 437.497005] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
> [ 437.497005] Process qbittorrent (pid: 3274, threadinfo
> ffff8800c9906000, task ffff8800db999200)
> [ 437.497005] Stack:
> [ 437.497005] ffff88011fc03bb0 ffff8801091ec872 ffff8800d79e8240
> 0000052000000520
> [ 437.497005] ffff88011fc03be0 ffff8800d7844e00 ffff880119099200
> ffff8801091ec872
> [ 437.497005] ffff8800db8b6400 00000000000050cd ffff88011fc03c60
> ffffffffa0367e65
> [ 437.497005] Call Trace:
> [ 437.497005] <IRQ>
> [ 437.497005] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
> [ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.497005] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
> [nf_conntrack_ipv4]
> [ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.497005] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
> [ 437.497005] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
> [ 437.497005] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
> [ 437.497005] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
> [ 437.497005] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
> [ 437.497005] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
> [ 437.497005] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
> [ 437.497005] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
> [ 437.497005] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
> [ 437.497005] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
> [ 437.497005] [<ffffffff8102342f>] ? update_curr+0x53/0x89
> [ 437.497005] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
> [ 437.497005] [<ffffffff812a3e6a>] net_rx_action+0x9e/0x171
> [ 437.497005] [<ffffffff810344b0>] __do_softirq+0x93/0x129
> [ 437.497005] [<ffffffff8133034c>] call_softirq+0x1c/0x30
> [ 437.497005] [<ffffffff8100351c>] do_softirq+0x33/0x6b
> [ 437.497005] [<ffffffff8103470b>] irq_exit+0x52/0xac
> [ 437.497005] [<ffffffff81003251>] do_IRQ+0x98/0xaf
> [ 437.497005] [<ffffffff8132eb6b>] common_interrupt+0x6b/0x6b
> [ 437.497005] <EOI>
> [ 437.497005] [<ffffffff8132f17b>] ? system_call_fastpath+0x16/0x1b
> [ 437.497005] Code: 6c e8 57 03 fc e0 e9 22 01 00 00 ff 4b 50 4c 89
> f7 49 8b 14 24 49 c7 04 24 00 00 00 00 49 8b 44 24 08 49 c7 44 24 08
> 00 00 00 00
> [ 437.497005] 89 42 08 48 89 10 e8 1d 6f fc e0 41 0f b7 54 24 3e 48 8b 43
> [ 437.497005] RIP [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621
> [l2tp_core]
> [ 437.497005] RSP <ffff88011fc03b90>
> [ 437.497005] CR2: 0000000000000008
> [ 437.498126] ---[ end trace 053df4c7c6743d26 ]---
> [ 437.498184] Kernel panic - not syncing: Fatal exception in interrupt
> [ 437.498187] Pid: 3274, comm: qbittorrent Tainted: G D 3.1.0 #1
> [ 437.498189] Call Trace:
> [ 437.498190] <IRQ> [<ffffffff81327c11>] panic+0x8c/0x189
> [ 437.498197] [<ffffffff8100471d>] oops_end+0x81/0x8e
> [ 437.498200] [<ffffffff8132765b>] no_context+0x1fe/0x20d
> [ 437.498203] [<ffffffff81327829>] __bad_area_nosemaphore+0x1bf/0x1e0
> [ 437.498206] [<ffffffff812a5308>] ? dev_hard_start_xmit+0x412/0x51b
> [ 437.498210] [<ffffffff81327858>] bad_area_nosemaphore+0xe/0x10
> [ 437.498213] [<ffffffff8101c858>] do_page_fault+0x175/0x371
> [ 437.498217] [<ffffffff812a1eba>] ? netif_rx+0xc5/0xd0
> [ 437.498281] [<ffffffffa031ee7d>] ?
> ppp_receive_nonmp_frame+0x58f/0x5cf [ppp_generic]
> [ 437.498286] [<ffffffffa0320625>] ? ppp_receive_frame+0x5c1/0x5e2
> [ppp_generic]
> [ 437.498290] [<ffffffff8132ed6f>] page_fault+0x1f/0x30
> [ 437.498293] [<ffffffffa03679dc>] ? l2tp_recv_common+0x4d3/0x621 [l2tp_core]
> [ 437.498298] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
> [ 437.498302] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.498306] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
> [nf_conntrack_ipv4]
> [ 437.498310] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
> [l2tp_ppp]
> [ 437.498314] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
> [ 437.498317] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
> [ 437.498321] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
> [ 437.498324] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
> [ 437.498328] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
> [ 437.498332] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
> [ 437.498391] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
> [ 437.498394] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
> [ 437.498398] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
> [ 437.498401] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
> [ 437.498404] [<ffffffff8102342f>] ? update_curr+0x53/0x89
> [ 437.498408] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
>
>
> Software:
> Gnu C 4.6.1
> Gnu make 3.82
> binutils 2.21.1
> openl2tp 1.8-r3
>
> l2tp_recv_common+0x4d3/0x621 is match to
> net/l2tp/l2tp_core.c:429:__skb_unlink(skb, &session->reorder_q);
> skb->next is NULL.
Hi Misha
On what kind of NIC this is happening ?
^ permalink raw reply
* [PATCH ethtool 00/21] ethtool refactoring and misc changes
From: Ben Hutchings @ 2011-11-01 22:35 UTC (permalink / raw)
To: netdev; +Cc: linux-net-drivers
As I looked into supporting features cleanly within the existing -k/-K
options, it became clear that ethtool was overdue for refactoring. And
in order to be confident about doing that, I needed to add some tests.
So I intend to push the following changes:
1. Reporting of pause frame autonegotiation. I don't believe this
requires a new command in the kernel interface; it just needs drivers
to fill out the AN flags.
2. Minor fixes to manual page and online help.
3. Cleanup of ethtool-bitops.h and ethtool-util.h.
4. Encapsulate shared command state into a structure passed into each
sub-command function (and several others).
5. Test argument parsing. Currently this just checks that each command
line is accepted or rejected as expected.
6. For each sub-command (option), move all argument parsing into the
function that implements it. Move the associated static variables
likewise. Declare static constants as const, so that there are no
static variables left (outside of the test wrapper).
7. Run the main ethtool code in the same process as the test code.
This will allow for test cases that cover the ioctl requests and
responses.
Ben.
Ben Hutchings (21):
Report pause frame autonegotiation result
ethtool.8: Fix initial blank line/page
Combine ethtool-{bitops,util}.h into internal.h
Fix type of bit-number parameter to set_bit() and clear_bit()
ethtool.8: Change device name metavariable from 'ethX' to 'devname'
ethtool.8: Allow line-break in description of parameters after -N
Fix format of help text for -f option
Use standard indentation for definition of struct option args
Encapsulate command context in a structure
Add test cases for command-line parsing
Add more test cases for command-line parsing
Move argument parsing to sub-command functions
Support arbitrary numbers of option names for each mode
Fix reference to cmdline_ring in do_schannels()
Convert cmdline_msglvl into array of named flags; convert back at
run-time
Replace global devname variable with a field in struct cmd_context
Change most static global variables into automatic variables
rxclass: Replace global rmgr with automatic variable/parameter
Declare static variables const as appropriate
Run tests in-process
Rearrange definitions and remove unnecessary forward declarations
Makefile.am | 7 +-
amd8111e.c | 2 +-
at76c50x-usb.c | 2 +-
configure.ac | 1 +
de2104x.c | 2 +-
e100.c | 2 +-
e1000.c | 2 +-
ethtool-bitops.h | 25 -
ethtool.8.in | 70 +-
ethtool.c | 2352 +++++++++++++++++++-----------------------
fec_8xx.c | 2 +-
ibm_emac.c | 2 +-
igb.c | 2 +-
ethtool-util.h => internal.h | 57 +-
ixgb.c | 2 +-
ixgbe.c | 2 +-
marvell.c | 2 +-
natsemi.c | 2 +-
pcnet32.c | 2 +-
realtek.c | 2 +-
rxclass.c | 129 +--
sfc.c | 2 +-
smsc911x.c | 2 +-
stmmac.c | 2 +-
test-cmdline.c | 240 +++++
test-common.c | 101 ++
tg3.c | 2 +-
vioc.c | 2 +-
28 files changed, 1565 insertions(+), 1455 deletions(-)
delete mode 100644 ethtool-bitops.h
rename ethtool-util.h => internal.h (71%)
create mode 100644 test-cmdline.c
create mode 100644 test-common.c
--
1.7.4.4
--
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
* ethtool back on git.kernel.org
From: Ben Hutchings @ 2011-11-01 22:18 UTC (permalink / raw)
To: netdev
As of this afternoon, ethtool is again available from:
git://git.kernel.org/pub/scm/network/ethtool/ethtool.git
There are no tarballs available at the moment, as the new upload service
on kernel.org is in limited beta.
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] neigh: print nud_state in neigh timer handler.
From: Daniel Baluta @ 2011-11-01 22:05 UTC (permalink / raw)
To: David Miller; +Cc: eric.dumazet, gregory.v.rose, jeffrey.t.kirsher, netdev
In-Reply-To: <20111101.174411.1200019350687608200.davem@davemloft.net>
On Tue, Nov 1, 2011 at 11:44 PM, David Miller <davem@davemloft.net> wrote:
> From: Daniel Baluta <dbaluta@ixiacom.com>
> Date: Mon, 31 Oct 2011 23:10:48 +0200
>
>> From: Daniel Baluta <daniel.baluta@gmail.com>
>>
>> For debugging purposes it is useful to know the exact state of a
>> non NUD_IN_TIMER neighbour entry whose timer handler just expired.
>>
>> Signed-off-by: Daniel Baluta <dbaluta@ixiacom.com>
>
> This debugging log message is dubious.
>
> Also, it is protected by !SMP and I can almost guarentee you that whatever
> condition makes it happen leigitmately on SMP also can be triggered with
> preemption enabled on !SMP.
>
> So I'm going to simply remove this debug message entirely instead.
Agree. If you can figure out when this condition is true, it is nice
to have a comment.
Daniel.
^ permalink raw reply
* PROBLEM: pppol2tp over pppoe NULL pointer dereference
From: Misha Labjuk @ 2011-11-01 22:00 UTC (permalink / raw)
To: netdev
pppol2tp over pppoe NULL pointer dereference
Kernel panic after establishing pppol2tp tunnel over pppoe connection.
Get panic in 5-15 min with 10 mbit/s data transfer speed.
pppoe and pppol2tp connections stable separately.
Linux version 3.1.0 (user@host) (gcc version 4.6.1 (Gentoo 4.6.1-r1
p1.0, pie-0.4.5) ) #1 SMP Mon Oct 31 18:48:18 MSK 2011
[ 151.913193] L2TP core driver, V2.0
[ 151.974584] L2TP netlink interface
[ 151.993803] PPPoL2TP kernel driver, V2.0
[ 437.496670] BUG: unable to handle kernel NULL pointer dereference
at 0000000000000008
[ 437.496683] IP: [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621 [l2tp_core]
[ 437.496691] PGD d7840067 PUD cd4e7067 PMD 0
[ 437.496697] Oops: 0002 [#1] SMP
[ 437.496702] CPU 0
[ 437.496704] Modules linked in: l2tp_ppp l2tp_netlink l2tp_core
firewire_sbp2 sit tunnel4 netconsole it87 hwmon_vid coretemp pppoe
pppox ppp_generic slhc ipt_MASQUERADE iptable_nat nf_nat
nf_conntrack_ipv4 nf_conntrack nf_defrag_ipv4 xt_TCPMSS iptable_mangle
ip_tables snd_seq_midi snd_emu10k1_synth snd_emux_synth
snd_seq_virmidi snd_seq_midi_emul snd_seq_dummy snd_seq_oss
snd_seq_midi_event snd_seq snd_pcm_oss snd_mixer_oss nfsd lockd
nfs_acl auth_rpcgss sunrpc usb_storage usb_libusual uas usbhid ipv6
snd_emu10k1 8250_pnp snd_rawmidi snd_hda_codec_realtek snd_ac97_codec
snd_hda_intel snd_hda_codec uhci_hcd ac97_bus snd_pcm ehci_hcd usbcore
snd_seq_device snd_timer 8250 snd_util_mem snd_hwdep psmouse snd
firewire_ohci firewire_core serial_core intel_agp intel_gtt pcspkr
soundcore r8169 crc_itu_t mii snd_page_alloc processor button
[ 437.497005]
[ 437.497005] Pid: 3274, comm: qbittorrent Not tainted 3.1.0 #1
Gigabyte Technology Co., Ltd. EP45-EXTREME/EP45-EXTREME
[ 437.497005] RIP: 0010:[<ffffffffa03679dc>] [<ffffffffa03679dc>]
l2tp_recv_common+0x4d3/0x621 [l2tp_core]
[ 437.497005] RSP: 0000:ffff88011fc03b90 EFLAGS: 00010296
[ 437.497005] RAX: 0000000000000000 RBX: ffff8800d79e8200 RCX: ffff88011fc10bd0
[ 437.497005] RDX: 0000000000000000 RSI: 0000000000004002 RDI: ffff8800d79e8254
[ 437.497005] RBP: ffff88011fc03be0 R08: 0000000000004002 R09: 0000000000004002
[ 437.497005] R10: ffff8801091ec87a R11: ffff88011b300000 R12: ffff880118922300
[ 437.497005] R13: 0000000000000000 R14: ffff8800d79e8254 R15: ffff8800d79e826c
[ 437.497005] FS: 00007f0ced3e8700(0000) GS:ffff88011fc00000(0000)
knlGS:0000000000000000
[ 437.497005] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 437.497005] CR2: 0000000000000008 CR3: 00000000c8811000 CR4: 00000000000406f0
[ 437.497005] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
[ 437.497005] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
[ 437.497005] Process qbittorrent (pid: 3274, threadinfo
ffff8800c9906000, task ffff8800db999200)
[ 437.497005] Stack:
[ 437.497005] ffff88011fc03bb0 ffff8801091ec872 ffff8800d79e8240
0000052000000520
[ 437.497005] ffff88011fc03be0 ffff8800d7844e00 ffff880119099200
ffff8801091ec872
[ 437.497005] ffff8800db8b6400 00000000000050cd ffff88011fc03c60
ffffffffa0367e65
[ 437.497005] Call Trace:
[ 437.497005] <IRQ>
[ 437.497005] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
[ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.497005] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
[nf_conntrack_ipv4]
[ 437.497005] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.497005] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
[ 437.497005] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
[ 437.497005] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
[ 437.497005] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
[ 437.497005] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
[ 437.497005] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
[ 437.497005] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
[ 437.497005] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
[ 437.497005] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
[ 437.497005] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
[ 437.497005] [<ffffffff8102342f>] ? update_curr+0x53/0x89
[ 437.497005] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
[ 437.497005] [<ffffffff812a3e6a>] net_rx_action+0x9e/0x171
[ 437.497005] [<ffffffff810344b0>] __do_softirq+0x93/0x129
[ 437.497005] [<ffffffff8133034c>] call_softirq+0x1c/0x30
[ 437.497005] [<ffffffff8100351c>] do_softirq+0x33/0x6b
[ 437.497005] [<ffffffff8103470b>] irq_exit+0x52/0xac
[ 437.497005] [<ffffffff81003251>] do_IRQ+0x98/0xaf
[ 437.497005] [<ffffffff8132eb6b>] common_interrupt+0x6b/0x6b
[ 437.497005] <EOI>
[ 437.497005] [<ffffffff8132f17b>] ? system_call_fastpath+0x16/0x1b
[ 437.497005] Code: 6c e8 57 03 fc e0 e9 22 01 00 00 ff 4b 50 4c 89
f7 49 8b 14 24 49 c7 04 24 00 00 00 00 49 8b 44 24 08 49 c7 44 24 08
00 00 00 00
[ 437.497005] 89 42 08 48 89 10 e8 1d 6f fc e0 41 0f b7 54 24 3e 48 8b 43
[ 437.497005] RIP [<ffffffffa03679dc>] l2tp_recv_common+0x4d3/0x621
[l2tp_core]
[ 437.497005] RSP <ffff88011fc03b90>
[ 437.497005] CR2: 0000000000000008
[ 437.498126] ---[ end trace 053df4c7c6743d26 ]---
[ 437.498184] Kernel panic - not syncing: Fatal exception in interrupt
[ 437.498187] Pid: 3274, comm: qbittorrent Tainted: G D 3.1.0 #1
[ 437.498189] Call Trace:
[ 437.498190] <IRQ> [<ffffffff81327c11>] panic+0x8c/0x189
[ 437.498197] [<ffffffff8100471d>] oops_end+0x81/0x8e
[ 437.498200] [<ffffffff8132765b>] no_context+0x1fe/0x20d
[ 437.498203] [<ffffffff81327829>] __bad_area_nosemaphore+0x1bf/0x1e0
[ 437.498206] [<ffffffff812a5308>] ? dev_hard_start_xmit+0x412/0x51b
[ 437.498210] [<ffffffff81327858>] bad_area_nosemaphore+0xe/0x10
[ 437.498213] [<ffffffff8101c858>] do_page_fault+0x175/0x371
[ 437.498217] [<ffffffff812a1eba>] ? netif_rx+0xc5/0xd0
[ 437.498281] [<ffffffffa031ee7d>] ?
ppp_receive_nonmp_frame+0x58f/0x5cf [ppp_generic]
[ 437.498286] [<ffffffffa0320625>] ? ppp_receive_frame+0x5c1/0x5e2
[ppp_generic]
[ 437.498290] [<ffffffff8132ed6f>] page_fault+0x1f/0x30
[ 437.498293] [<ffffffffa03679dc>] ? l2tp_recv_common+0x4d3/0x621 [l2tp_core]
[ 437.498298] [<ffffffffa0367e65>] l2tp_udp_encap_recv+0x33b/0x3e6 [l2tp_core]
[ 437.498302] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.498306] [<ffffffffa030640c>] ? ipv4_confirm+0x17e/0x198
[nf_conntrack_ipv4]
[ 437.498310] [<ffffffffa0377d96>] ? pppol2tp_setsockopt+0x2e0/0x2e0
[l2tp_ppp]
[ 437.498314] [<ffffffff812eb32b>] udp_queue_rcv_skb+0xee/0x2ce
[ 437.498317] [<ffffffff812ebba3>] __udp4_lib_rcv+0x2d2/0x536
[ 437.498321] [<ffffffff812cb046>] ? ip_rcv_finish+0x29a/0x29a
[ 437.498324] [<ffffffff812ebe1c>] udp_rcv+0x15/0x17
[ 437.498328] [<ffffffff812cb165>] ip_local_deliver_finish+0x11f/0x1c7
[ 437.498332] [<ffffffff812cb361>] ip_local_deliver+0x75/0x7c
[ 437.498391] [<ffffffff812cb023>] ip_rcv_finish+0x277/0x29a
[ 437.498394] [<ffffffff812cb5a1>] ip_rcv+0x239/0x260
[ 437.498398] [<ffffffff812a46cd>] ? napi_skb_finish+0x21/0x38
[ 437.498401] [<ffffffff812a3adb>] __netif_receive_skb+0x430/0x462
[ 437.498404] [<ffffffff8102342f>] ? update_curr+0x53/0x89
[ 437.498408] [<ffffffff812a3b9d>] process_backlog+0x90/0x151
Software:
Gnu C 4.6.1
Gnu make 3.82
binutils 2.21.1
openl2tp 1.8-r3
l2tp_recv_common+0x4d3/0x621 is match to
net/l2tp/l2tp_core.c:429:__skb_unlink(skb, &session->reorder_q);
skb->next is NULL.
^ permalink raw reply
* Re: [PATCH] [RESEND] [TRIVIAL] isdn: hisax: Fix typo 'HISAX_DE_AOC'
From: David Miller @ 2011-11-01 21:59 UTC (permalink / raw)
To: pebolle; +Cc: trivial, linux-kernel, isdn, netdev
In-Reply-To: <1319976044.14409.14.camel@x61.thuisdomein>
From: Paul Bolle <pebolle@tiscali.nl>
Date: Sun, 30 Oct 2011 13:00:44 +0100
> That should probably be 'CONFIG_DE_AOC'.
>
> Signed-off-by: Paul Bolle <pebolle@tiscali.nl>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] net: make the tcp and udp file_operations for the /proc stuff const
From: David Miller @ 2011-11-01 21:56 UTC (permalink / raw)
To: arjan; +Cc: netdev
In-Reply-To: <20111030094630.47e247ae@infradead.org>
From: Arjan van de Ven <arjan@infradead.org>
Date: Sun, 30 Oct 2011 09:46:30 -0700
> the tcp and udp code creates a set of struct file_operations at runtime
> while it can also be done at compile time, with the added benefit of then
> having these file operations be const.
>
> the trickiest part was to get the "THIS_MODULE" reference right; the naive
> method of declaring a struct in the place of registration would not work
> for this reason.
>
> Signed-off-by: Arjan van de Ven <arjan@linux.intel.com>
I have no problem with this, applied, thanks.
^ permalink raw reply
* Re: [PATCH] bonding:update speed/duplex for NETDEV_CHANGE
From: David Miller @ 2011-11-01 21:53 UTC (permalink / raw)
To: wpan; +Cc: netdev, fubar, andy, linux-kernel
In-Reply-To: <9765cb601d0b4330cf7775ec3cd6b9e1ea13c71e.1320117071.git.wpan@redhat.com>
From: Weiping Pan <wpan@redhat.com>
Date: Tue, 1 Nov 2011 11:20:48 +0800
> Zheng Liang(lzheng@redhat.com) found a bug that if we config bonding with
> arp monitor, sometimes bonding driver cannot get the speed and duplex from
> its slaves, it will assume them to be 100Mb/sec and Full, please see
> /proc/net/bonding/bond0.
> But there is no such problem when uses miimon.
>
> (Take igb for example)
> I find that the reason is that after dev_open() in bond_enslave(),
> bond_update_speed_duplex() will call igb_get_settings()
> , but in that function,
> it runs ethtool_cmd_speed_set(ecmd, -1); ecmd->duplex = -1;
> because igb get an error value of status.
> So even dev_open() is called, but the device is not really ready to get its
> settings.
>
> Maybe it is safe for us to call igb_get_settings() only after
> this message shows up, that is "igb: p4p1 NIC Link is Up 1000 Mbps Full Duplex,
> Flow Control: RX".
>
> So I prefer to update the speed and duplex for a slave when reseices
> NETDEV_CHANGE/NETDEV_UP event.
>
> Changelog
> V2:
> 1 remove the "fake 100/Full" logic in bond_update_speed_duplex(),
> set speed and duplex to -1 when it gets error value of speed and duplex.
> 2 delete the warning in bond_enslave() if bond_update_speed_duplex() returns
> error.
> 3 make bond_info_show_slave() handle bad values of speed and duplex.
>
> Signed-off-by: Weiping Pan <wpan@redhat.com>
Looks good, applied, thanks!
^ permalink raw reply
* Re: [PATCH] vlan: Don't propagate flag changes on down interfaces.
From: David Miller @ 2011-11-01 21:51 UTC (permalink / raw)
To: matthijs; +Cc: netdev
In-Reply-To: <1320072793-16490-1-git-send-email-matthijs@stdin.nl>
From: Matthijs Kooijman <matthijs@stdin.nl>
Date: Mon, 31 Oct 2011 15:53:13 +0100
> When (de)configuring a vlan interface, the IFF_ALLMULTI ans IFF_PROMISC
> flags are cleared or set on the underlying interface. So, if these flags
> are changed on a vlan interface that is not up, the flags underlying
> interface might be set or cleared twice.
>
> Only propagating flag changes when a device is up makes sure this does
> not happen. It also makes sure that an underlying device is not set to
> promiscuous or allmulti mode for a vlan device that is down.
>
> Signed-off-by: Matthijs Kooijman <matthijs@stdin.nl>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH] neigh: print nud_state in neigh timer handler.
From: David Miller @ 2011-11-01 21:44 UTC (permalink / raw)
To: dbaluta
Cc: eric.dumazet, gregory.v.rose, jeffrey.t.kirsher, netdev,
daniel.baluta
In-Reply-To: <1320095448-5228-1-git-send-email-dbaluta@ixiacom.com>
From: Daniel Baluta <dbaluta@ixiacom.com>
Date: Mon, 31 Oct 2011 23:10:48 +0200
> From: Daniel Baluta <daniel.baluta@gmail.com>
>
> For debugging purposes it is useful to know the exact state of a
> non NUD_IN_TIMER neighbour entry whose timer handler just expired.
>
> Signed-off-by: Daniel Baluta <dbaluta@ixiacom.com>
This debugging log message is dubious.
Also, it is protected by !SMP and I can almost guarentee you that whatever
condition makes it happen leigitmately on SMP also can be triggered with
preemption enabled on !SMP.
So I'm going to simply remove this debug message entirely instead.
^ permalink raw reply
* Re: [PATCH] IPv6 - support for NLM_F_* flags at IPv6 routing requests
From: Stephen Hemminger @ 2011-11-01 21:43 UTC (permalink / raw)
To: Matti Vaittinen; +Cc: davem, netdev
In-Reply-To: <1320157347.11816.3.camel@lakki>
On Tue, 01 Nov 2011 16:22:27 +0200
Matti Vaittinen <matti.vaittinen@nsn.com> wrote:
>
> +#define RT6_CANT_CREATE ((int)-1)
> #define RT6_DEBUG 2
Rather than introduce a new error flag, why not convert the code
to use the kernel standard PTR_ERR() macros?
^ permalink raw reply
* Re: [PATCH] sysfs: Make sysfs_rename safe with sysfs_dirents in rbtrees.
From: Greg KH @ 2011-11-01 21:19 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linus Torvalds, Jiri Slaby, David Miller, Mikulas Patocka, akpm,
netdev, linux-kernel, Jiri Slaby
In-Reply-To: <m1mxcgrl7q.fsf_-_@fess.ebiederm.org>
On Tue, Nov 01, 2011 at 07:06:17AM -0700, Eric W. Biederman wrote:
>
> In sysfs_rename remove the optimization of not calling sysfs_unlink_sibling
> and sysfs_link_sibling if the renamed parent directory is not changing.
> This optimization is no longer valid now that sysfs dirents are stored in an
> rbtree sorted by name.
>
> Move the assignment of s_ns before the call of sysfs_link_sibling. With no
> sysfs_dirent fields changing after the call of sysfs_link_sibling this allows
> sysfs_link_sibling to take any of the directory entries into account when
> it builds the rbtrees, and s_ns looks like a prime canidate to be used
> in the rbtree in the future.
>
> Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
Looks good, Linus, thanks for taking this in your tree already.
greg k-h
^ permalink raw reply
* [PATCH 16/18] net/irda: convert au1k_ir to platform driver.
From: Manuel Lauss @ 2011-11-01 19:03 UTC (permalink / raw)
To: Linux-MIPS, Ralf Baechle; +Cc: Manuel Lauss, Samuel Ortiz, netdev
In-Reply-To: <1320174224-27305-1-git-send-email-manuel.lauss@googlemail.com>
Moderate driver cleanup:
convert to platform driver, get rid of board-specific code.
Driver loads and runs on a DB1100 board. But since I have no other
IrDA hardware to exchange data with I can't say whether it really sends
and receives.
Cc: Samuel Ortiz <samuel@sortiz.org>
Cc: netdev@vger.kernel.org
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
---
I'd like for this to go in via the MIPS tree since other mips patches depend
on it.
arch/mips/include/asm/mach-au1x00/au1000.h | 52 +-
drivers/net/irda/Kconfig | 6 +-
drivers/net/irda/au1000_ircc.h | 125 ---
drivers/net/irda/au1k_ir.c | 1226 +++++++++++++++------------
4 files changed, 700 insertions(+), 709 deletions(-)
delete mode 100644 drivers/net/irda/au1000_ircc.h
diff --git a/arch/mips/include/asm/mach-au1x00/au1000.h b/arch/mips/include/asm/mach-au1x00/au1000.h
index 65f1262..569828d 100644
--- a/arch/mips/include/asm/mach-au1x00/au1000.h
+++ b/arch/mips/include/asm/mach-au1x00/au1000.h
@@ -1265,44 +1265,20 @@ enum soc_au1200_ints {
#define SSI_ENABLE_CD (1 << 1)
#define SSI_ENABLE_E (1 << 0)
-/* IrDA Controller */
-#define IRDA_BASE 0xB0300000
-#define IR_RING_PTR_STATUS (IRDA_BASE + 0x00)
-#define IR_RING_BASE_ADDR_H (IRDA_BASE + 0x04)
-#define IR_RING_BASE_ADDR_L (IRDA_BASE + 0x08)
-#define IR_RING_SIZE (IRDA_BASE + 0x0C)
-#define IR_RING_PROMPT (IRDA_BASE + 0x10)
-#define IR_RING_ADDR_CMPR (IRDA_BASE + 0x14)
-#define IR_INT_CLEAR (IRDA_BASE + 0x18)
-#define IR_CONFIG_1 (IRDA_BASE + 0x20)
-# define IR_RX_INVERT_LED (1 << 0)
-# define IR_TX_INVERT_LED (1 << 1)
-# define IR_ST (1 << 2)
-# define IR_SF (1 << 3)
-# define IR_SIR (1 << 4)
-# define IR_MIR (1 << 5)
-# define IR_FIR (1 << 6)
-# define IR_16CRC (1 << 7)
-# define IR_TD (1 << 8)
-# define IR_RX_ALL (1 << 9)
-# define IR_DMA_ENABLE (1 << 10)
-# define IR_RX_ENABLE (1 << 11)
-# define IR_TX_ENABLE (1 << 12)
-# define IR_LOOPBACK (1 << 14)
-# define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
- IR_RX_ALL | IR_RX_ENABLE | IR_SF | IR_16CRC)
-#define IR_SIR_FLAGS (IRDA_BASE + 0x24)
-#define IR_ENABLE (IRDA_BASE + 0x28)
-# define IR_RX_STATUS (1 << 9)
-# define IR_TX_STATUS (1 << 10)
-#define IR_READ_PHY_CONFIG (IRDA_BASE + 0x2C)
-#define IR_WRITE_PHY_CONFIG (IRDA_BASE + 0x30)
-#define IR_MAX_PKT_LEN (IRDA_BASE + 0x34)
-#define IR_RX_BYTE_CNT (IRDA_BASE + 0x38)
-#define IR_CONFIG_2 (IRDA_BASE + 0x3C)
-# define IR_MODE_INV (1 << 0)
-# define IR_ONE_PIN (1 << 1)
-#define IR_INTERFACE_CONFIG (IRDA_BASE + 0x40)
+
+/*
+ * The IrDA peripheral has an IRFIRSEL pin, but on the DB/PB boards it's not
+ * used to select FIR/SIR mode on the transceiver but as a GPIO. Instead a
+ * CPLD has to be told about the mode.
+ */
+#define AU1000_IRDA_PHY_MODE_OFF 0
+#define AU1000_IRDA_PHY_MODE_SIR 1
+#define AU1000_IRDA_PHY_MODE_FIR 2
+
+struct au1k_irda_platform_data {
+ void(*set_phy_mode)(int mode);
+};
+
/* GPIO */
#define SYS_PINFUNC 0xB190002C
diff --git a/drivers/net/irda/Kconfig b/drivers/net/irda/Kconfig
index d423d18..e535137 100644
--- a/drivers/net/irda/Kconfig
+++ b/drivers/net/irda/Kconfig
@@ -313,8 +313,12 @@ config TOSHIBA_FIR
donauboe.
config AU1000_FIR
- tristate "Alchemy Au1000 SIR/FIR"
+ tristate "Alchemy IrDA SIR/FIR"
depends on IRDA && MIPS_ALCHEMY
+ help
+ Say Y/M here to build suppor the the IrDA peripheral on the
+ Alchemy Au1000 and Au1100 SoCs.
+ Say M to build a module; it will be called au1k_ir.ko
config SMC_IRCC_FIR
tristate "SMSC IrCC (EXPERIMENTAL)"
diff --git a/drivers/net/irda/au1000_ircc.h b/drivers/net/irda/au1000_ircc.h
deleted file mode 100644
index c072c09..0000000
--- a/drivers/net/irda/au1000_ircc.h
+++ /dev/null
@@ -1,125 +0,0 @@
-/*
- *
- * BRIEF MODULE DESCRIPTION
- * Au1000 IrDA driver.
- *
- * Copyright 2001 MontaVista Software Inc.
- * Author: MontaVista Software, Inc.
- * ppopov@mvista.com or source@mvista.com
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2 of the License, or (at your
- * option) any later version.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
- * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-#ifndef AU1000_IRCC_H
-#define AU1000_IRCC_H
-
-#include <linux/time.h>
-
-#include <linux/spinlock.h>
-#include <linux/pm.h>
-#include <asm/io.h>
-
-#define NUM_IR_IFF 1
-#define NUM_IR_DESC 64
-#define RING_SIZE_4 0x0
-#define RING_SIZE_16 0x3
-#define RING_SIZE_64 0xF
-#define MAX_NUM_IR_DESC 64
-#define MAX_BUF_SIZE 2048
-
-#define BPS_115200 0
-#define BPS_57600 1
-#define BPS_38400 2
-#define BPS_19200 5
-#define BPS_9600 11
-#define BPS_2400 47
-
-/* Ring descriptor flags */
-#define AU_OWN (1<<7) /* tx,rx */
-
-#define IR_DIS_CRC (1<<6) /* tx */
-#define IR_BAD_CRC (1<<5) /* tx */
-#define IR_NEED_PULSE (1<<4) /* tx */
-#define IR_FORCE_UNDER (1<<3) /* tx */
-#define IR_DISABLE_TX (1<<2) /* tx */
-#define IR_HW_UNDER (1<<0) /* tx */
-#define IR_TX_ERROR (IR_DIS_CRC|IR_BAD_CRC|IR_HW_UNDER)
-
-#define IR_PHY_ERROR (1<<6) /* rx */
-#define IR_CRC_ERROR (1<<5) /* rx */
-#define IR_MAX_LEN (1<<4) /* rx */
-#define IR_FIFO_OVER (1<<3) /* rx */
-#define IR_SIR_ERROR (1<<2) /* rx */
-#define IR_RX_ERROR (IR_PHY_ERROR|IR_CRC_ERROR| \
- IR_MAX_LEN|IR_FIFO_OVER|IR_SIR_ERROR)
-
-typedef struct db_dest {
- struct db_dest *pnext;
- volatile u32 *vaddr;
- dma_addr_t dma_addr;
-} db_dest_t;
-
-
-typedef struct ring_desc {
- u8 count_0; /* 7:0 */
- u8 count_1; /* 12:8 */
- u8 reserved;
- u8 flags;
- u8 addr_0; /* 7:0 */
- u8 addr_1; /* 15:8 */
- u8 addr_2; /* 23:16 */
- u8 addr_3; /* 31:24 */
-} ring_dest_t;
-
-
-/* Private data for each instance */
-struct au1k_private {
-
- db_dest_t *pDBfree;
- db_dest_t db[2*NUM_IR_DESC];
- volatile ring_dest_t *rx_ring[NUM_IR_DESC];
- volatile ring_dest_t *tx_ring[NUM_IR_DESC];
- db_dest_t *rx_db_inuse[NUM_IR_DESC];
- db_dest_t *tx_db_inuse[NUM_IR_DESC];
- u32 rx_head;
- u32 tx_head;
- u32 tx_tail;
- u32 tx_full;
-
- iobuff_t rx_buff;
-
- struct net_device *netdev;
-
- struct timeval stamp;
- struct timeval now;
- struct qos_info qos;
- struct irlap_cb *irlap;
-
- u8 open;
- u32 speed;
- u32 newspeed;
-
- u32 intr_work_done; /* number of Rx and Tx pkts processed in the isr */
- struct timer_list timer;
-
- spinlock_t lock; /* For serializing operations */
-};
-#endif /* AU1000_IRCC_H */
diff --git a/drivers/net/irda/au1k_ir.c b/drivers/net/irda/au1k_ir.c
index 670bb05..fc503aa 100644
--- a/drivers/net/irda/au1k_ir.c
+++ b/drivers/net/irda/au1k_ir.c
@@ -18,101 +18,220 @@
* with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
*/
-#include <linux/module.h>
-#include <linux/types.h>
+
#include <linux/init.h>
-#include <linux/errno.h>
+#include <linux/module.h>
#include <linux/netdevice.h>
-#include <linux/slab.h>
-#include <linux/rtnetlink.h>
#include <linux/interrupt.h>
-#include <linux/pm.h>
-#include <linux/bitops.h>
-
-#include <asm/irq.h>
-#include <asm/io.h>
-#include <asm/au1000.h>
-#if defined(CONFIG_MIPS_DB1000)
-#include <asm/mach-db1x00/bcsr.h>
-#else
-#error au1k_ir: unsupported board
-#endif
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include <linux/time.h>
+#include <linux/types.h>
#include <net/irda/irda.h>
#include <net/irda/irmod.h>
#include <net/irda/wrapper.h>
#include <net/irda/irda_device.h>
-#include "au1000_ircc.h"
+#include <asm/mach-au1x00/au1000.h>
+
+/* registers */
+#define IR_RING_PTR_STATUS 0x00
+#define IR_RING_BASE_ADDR_H 0x04
+#define IR_RING_BASE_ADDR_L 0x08
+#define IR_RING_SIZE 0x0C
+#define IR_RING_PROMPT 0x10
+#define IR_RING_ADDR_CMPR 0x14
+#define IR_INT_CLEAR 0x18
+#define IR_CONFIG_1 0x20
+#define IR_SIR_FLAGS 0x24
+#define IR_STATUS 0x28
+#define IR_READ_PHY_CONFIG 0x2C
+#define IR_WRITE_PHY_CONFIG 0x30
+#define IR_MAX_PKT_LEN 0x34
+#define IR_RX_BYTE_CNT 0x38
+#define IR_CONFIG_2 0x3C
+#define IR_ENABLE 0x40
+
+/* Config1 */
+#define IR_RX_INVERT_LED (1 << 0)
+#define IR_TX_INVERT_LED (1 << 1)
+#define IR_ST (1 << 2)
+#define IR_SF (1 << 3)
+#define IR_SIR (1 << 4)
+#define IR_MIR (1 << 5)
+#define IR_FIR (1 << 6)
+#define IR_16CRC (1 << 7)
+#define IR_TD (1 << 8)
+#define IR_RX_ALL (1 << 9)
+#define IR_DMA_ENABLE (1 << 10)
+#define IR_RX_ENABLE (1 << 11)
+#define IR_TX_ENABLE (1 << 12)
+#define IR_LOOPBACK (1 << 14)
+#define IR_SIR_MODE (IR_SIR | IR_DMA_ENABLE | \
+ IR_RX_ALL | IR_RX_ENABLE | IR_SF | \
+ IR_16CRC)
+
+/* ir_status */
+#define IR_RX_STATUS (1 << 9)
+#define IR_TX_STATUS (1 << 10)
+#define IR_PHYEN (1 << 15)
+
+/* ir_write_phy_config */
+#define IR_BR(x) (((x) & 0x3f) << 10) /* baud rate */
+#define IR_PW(x) (((x) & 0x1f) << 5) /* pulse width */
+#define IR_P(x) ((x) & 0x1f) /* preamble bits */
+
+/* Config2 */
+#define IR_MODE_INV (1 << 0)
+#define IR_ONE_PIN (1 << 1)
+#define IR_PHYCLK_40MHZ (0 << 2)
+#define IR_PHYCLK_48MHZ (1 << 2)
+#define IR_PHYCLK_56MHZ (2 << 2)
+#define IR_PHYCLK_64MHZ (3 << 2)
+#define IR_DP (1 << 4)
+#define IR_DA (1 << 5)
+#define IR_FLT_HIGH (0 << 6)
+#define IR_FLT_MEDHI (1 << 6)
+#define IR_FLT_MEDLO (2 << 6)
+#define IR_FLT_LO (3 << 6)
+#define IR_IEN (1 << 8)
+
+/* ir_enable */
+#define IR_HC (1 << 3) /* divide SBUS clock by 2 */
+#define IR_CE (1 << 2) /* clock enable */
+#define IR_C (1 << 1) /* coherency bit */
+#define IR_BE (1 << 0) /* set in big endian mode */
+
+#define NUM_IR_DESC 64
+#define RING_SIZE_4 0x0
+#define RING_SIZE_16 0x3
+#define RING_SIZE_64 0xF
+#define MAX_NUM_IR_DESC 64
+#define MAX_BUF_SIZE 2048
+
+/* Ring descriptor flags */
+#define AU_OWN (1 << 7) /* tx,rx */
+#define IR_DIS_CRC (1 << 6) /* tx */
+#define IR_BAD_CRC (1 << 5) /* tx */
+#define IR_NEED_PULSE (1 << 4) /* tx */
+#define IR_FORCE_UNDER (1 << 3) /* tx */
+#define IR_DISABLE_TX (1 << 2) /* tx */
+#define IR_HW_UNDER (1 << 0) /* tx */
+#define IR_TX_ERROR (IR_DIS_CRC | IR_BAD_CRC | IR_HW_UNDER)
+
+#define IR_PHY_ERROR (1 << 6) /* rx */
+#define IR_CRC_ERROR (1 << 5) /* rx */
+#define IR_MAX_LEN (1 << 4) /* rx */
+#define IR_FIFO_OVER (1 << 3) /* rx */
+#define IR_SIR_ERROR (1 << 2) /* rx */
+#define IR_RX_ERROR (IR_PHY_ERROR | IR_CRC_ERROR | \
+ IR_MAX_LEN | IR_FIFO_OVER | IR_SIR_ERROR)
+
+struct db_dest {
+ struct db_dest *pnext;
+ volatile u32 *vaddr;
+ dma_addr_t dma_addr;
+};
+
+struct ring_dest {
+ u8 count_0; /* 7:0 */
+ u8 count_1; /* 12:8 */
+ u8 reserved;
+ u8 flags;
+ u8 addr_0; /* 7:0 */
+ u8 addr_1; /* 15:8 */
+ u8 addr_2; /* 23:16 */
+ u8 addr_3; /* 31:24 */
+};
+
+/* Private data for each instance */
+struct au1k_private {
+ void __iomem *iobase;
+ int irq_rx, irq_tx;
+
+ struct db_dest *pDBfree;
+ struct db_dest db[2 * NUM_IR_DESC];
+ volatile struct ring_dest *rx_ring[NUM_IR_DESC];
+ volatile struct ring_dest *tx_ring[NUM_IR_DESC];
+ struct db_dest *rx_db_inuse[NUM_IR_DESC];
+ struct db_dest *tx_db_inuse[NUM_IR_DESC];
+ u32 rx_head;
+ u32 tx_head;
+ u32 tx_tail;
+ u32 tx_full;
+
+ iobuff_t rx_buff;
+
+ struct net_device *netdev;
+ struct timeval stamp;
+ struct timeval now;
+ struct qos_info qos;
+ struct irlap_cb *irlap;
+
+ u8 open;
+ u32 speed;
+ u32 newspeed;
-static int au1k_irda_net_init(struct net_device *);
-static int au1k_irda_start(struct net_device *);
-static int au1k_irda_stop(struct net_device *dev);
-static int au1k_irda_hard_xmit(struct sk_buff *, struct net_device *);
-static int au1k_irda_rx(struct net_device *);
-static void au1k_irda_interrupt(int, void *);
-static void au1k_tx_timeout(struct net_device *);
-static int au1k_irda_ioctl(struct net_device *, struct ifreq *, int);
-static int au1k_irda_set_speed(struct net_device *dev, int speed);
+ struct timer_list timer;
-static void *dma_alloc(size_t, dma_addr_t *);
-static void dma_free(void *, size_t);
+ struct resource *ioarea;
+ struct au1k_irda_platform_data *platdata;
+};
static int qos_mtt_bits = 0x07; /* 1 ms or more */
-static struct net_device *ir_devs[NUM_IR_IFF];
-static char version[] __devinitdata =
- "au1k_ircc:1.2 ppopov@mvista.com\n";
#define RUN_AT(x) (jiffies + (x))
-static DEFINE_SPINLOCK(ir_lock);
+static void au1k_irda_plat_set_phy_mode(struct au1k_private *p, int mode)
+{
+ if (p->platdata && p->platdata->set_phy_mode)
+ p->platdata->set_phy_mode(mode);
+}
-/*
- * IrDA peripheral bug. You have to read the register
- * twice to get the right value.
- */
-u32 read_ir_reg(u32 addr)
-{
- readl(addr);
- return readl(addr);
+static inline unsigned long irda_read(struct au1k_private *p,
+ unsigned long ofs)
+{
+ /*
+ * IrDA peripheral bug. You have to read the register
+ * twice to get the right value.
+ */
+ (void)__raw_readl(p->iobase + ofs);
+ return __raw_readl(p->iobase + ofs);
}
+static inline void irda_write(struct au1k_private *p, unsigned long ofs,
+ unsigned long val)
+{
+ __raw_writel(val, p->iobase + ofs);
+ wmb();
+}
/*
* Buffer allocation/deallocation routines. The buffer descriptor returned
- * has the virtual and dma address of a buffer suitable for
+ * has the virtual and dma address of a buffer suitable for
* both, receive and transmit operations.
*/
-static db_dest_t *GetFreeDB(struct au1k_private *aup)
+static struct db_dest *GetFreeDB(struct au1k_private *aup)
{
- db_dest_t *pDB;
- pDB = aup->pDBfree;
-
- if (pDB) {
- aup->pDBfree = pDB->pnext;
- }
- return pDB;
-}
+ struct db_dest *db;
+ db = aup->pDBfree;
-static void ReleaseDB(struct au1k_private *aup, db_dest_t *pDB)
-{
- db_dest_t *pDBfree = aup->pDBfree;
- if (pDBfree)
- pDBfree->pnext = pDB;
- aup->pDBfree = pDB;
+ if (db)
+ aup->pDBfree = db->pnext;
+ return db;
}
-
/*
DMA memory allocation, derived from pci_alloc_consistent.
However, the Au1000 data cache is coherent (when programmed
so), therefore we return KSEG0 address, not KSEG1.
*/
-static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
+static void *dma_alloc(size_t size, dma_addr_t *dma_handle)
{
void *ret;
int gfp = GFP_ATOMIC | GFP_DMA;
- ret = (void *) __get_free_pages(gfp, get_order(size));
+ ret = (void *)__get_free_pages(gfp, get_order(size));
if (ret != NULL) {
memset(ret, 0, size);
@@ -122,7 +241,6 @@ static void *dma_alloc(size_t size, dma_addr_t * dma_handle)
return ret;
}
-
static void dma_free(void *vaddr, size_t size)
{
vaddr = (void *)KSEG0ADDR(vaddr);
@@ -130,206 +248,306 @@ static void dma_free(void *vaddr, size_t size)
}
-static void
-setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
+static void setup_hw_rings(struct au1k_private *aup, u32 rx_base, u32 tx_base)
{
int i;
- for (i=0; i<NUM_IR_DESC; i++) {
- aup->rx_ring[i] = (volatile ring_dest_t *)
- (rx_base + sizeof(ring_dest_t)*i);
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ aup->rx_ring[i] = (volatile struct ring_dest *)
+ (rx_base + sizeof(struct ring_dest) * i);
}
- for (i=0; i<NUM_IR_DESC; i++) {
- aup->tx_ring[i] = (volatile ring_dest_t *)
- (tx_base + sizeof(ring_dest_t)*i);
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ aup->tx_ring[i] = (volatile struct ring_dest *)
+ (tx_base + sizeof(struct ring_dest) * i);
}
}
-static int au1k_irda_init(void)
-{
- static unsigned version_printed = 0;
- struct au1k_private *aup;
- struct net_device *dev;
- int err;
-
- if (version_printed++ == 0) printk(version);
-
- dev = alloc_irdadev(sizeof(struct au1k_private));
- if (!dev)
- return -ENOMEM;
-
- dev->irq = AU1000_IRDA_RX_INT; /* TX has its own interrupt */
- err = au1k_irda_net_init(dev);
- if (err)
- goto out;
- err = register_netdev(dev);
- if (err)
- goto out1;
- ir_devs[0] = dev;
- printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
- return 0;
-
-out1:
- aup = netdev_priv(dev);
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- kfree(aup->rx_buff.head);
-out:
- free_netdev(dev);
- return err;
-}
-
static int au1k_irda_init_iobuf(iobuff_t *io, int size)
{
io->head = kmalloc(size, GFP_KERNEL);
if (io->head != NULL) {
- io->truesize = size;
- io->in_frame = FALSE;
- io->state = OUTSIDE_FRAME;
- io->data = io->head;
+ io->truesize = size;
+ io->in_frame = FALSE;
+ io->state = OUTSIDE_FRAME;
+ io->data = io->head;
}
return io->head ? 0 : -ENOMEM;
}
-static const struct net_device_ops au1k_irda_netdev_ops = {
- .ndo_open = au1k_irda_start,
- .ndo_stop = au1k_irda_stop,
- .ndo_start_xmit = au1k_irda_hard_xmit,
- .ndo_tx_timeout = au1k_tx_timeout,
- .ndo_do_ioctl = au1k_irda_ioctl,
-};
-
-static int au1k_irda_net_init(struct net_device *dev)
+/*
+ * Set the IrDA communications speed.
+ */
+static int au1k_irda_set_speed(struct net_device *dev, int speed)
{
struct au1k_private *aup = netdev_priv(dev);
- int i, retval = 0, err;
- db_dest_t *pDB, *pDBfree;
- dma_addr_t temp;
+ volatile struct ring_dest *ptxd;
+ unsigned long control;
+ int ret = 0, timeout = 10, i;
- err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
- if (err)
- goto out1;
+ if (speed == aup->speed)
+ return ret;
- dev->netdev_ops = &au1k_irda_netdev_ops;
+ /* disable PHY first */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
- irda_init_max_qos_capabilies(&aup->qos);
+ /* disable RX/TX */
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~(IR_RX_ENABLE | IR_TX_ENABLE));
+ msleep(20);
+ while (irda_read(aup, IR_STATUS) & (IR_RX_STATUS | IR_TX_STATUS)) {
+ msleep(20);
+ if (!timeout--) {
+ printk(KERN_ERR "%s: rx/tx disable timeout\n",
+ dev->name);
+ break;
+ }
+ }
- /* The only value we must override it the baudrate */
- aup->qos.baud_rate.bits = IR_9600|IR_19200|IR_38400|IR_57600|
- IR_115200|IR_576000 |(IR_4000000 << 8);
-
- aup->qos.min_turn_time.bits = qos_mtt_bits;
- irda_qos_bits_to_value(&aup->qos);
+ /* disable DMA */
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~IR_DMA_ENABLE);
+ msleep(20);
- retval = -ENOMEM;
+ /* After we disable tx/rx. the index pointers go back to zero. */
+ aup->tx_head = aup->tx_tail = aup->rx_head = 0;
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ ptxd = aup->tx_ring[i];
+ ptxd->flags = 0;
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ }
- /* Tx ring follows rx ring + 512 bytes */
- /* we need a 1k aligned buffer */
- aup->rx_ring[0] = (ring_dest_t *)
- dma_alloc(2*MAX_NUM_IR_DESC*(sizeof(ring_dest_t)), &temp);
- if (!aup->rx_ring[0])
- goto out2;
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ ptxd = aup->rx_ring[i];
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ ptxd->flags = AU_OWN;
+ }
- /* allocate the data buffers */
- aup->db[0].vaddr =
- (void *)dma_alloc(MAX_BUF_SIZE * 2*NUM_IR_DESC, &temp);
- if (!aup->db[0].vaddr)
- goto out3;
+ if (speed == 4000000)
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_FIR);
+ else
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
- setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+ switch (speed) {
+ case 9600:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(11) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 19200:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(5) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 38400:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(2) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 57600:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_BR(1) | IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 115200:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_PW(12));
+ irda_write(aup, IR_CONFIG_1, IR_SIR_MODE);
+ break;
+ case 4000000:
+ irda_write(aup, IR_WRITE_PHY_CONFIG, IR_P(15));
+ irda_write(aup, IR_CONFIG_1, IR_FIR | IR_DMA_ENABLE |
+ IR_RX_ENABLE);
+ break;
+ default:
+ printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
+ ret = -EINVAL;
+ break;
+ }
- pDBfree = NULL;
- pDB = aup->db;
- for (i=0; i<(2*NUM_IR_DESC); i++) {
- pDB->pnext = pDBfree;
- pDBfree = pDB;
- pDB->vaddr =
- (u32 *)((unsigned)aup->db[0].vaddr + MAX_BUF_SIZE*i);
- pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
- pDB++;
+ aup->speed = speed;
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) | IR_PHYEN);
+
+ control = irda_read(aup, IR_STATUS);
+ irda_write(aup, IR_RING_PROMPT, 0);
+
+ if (control & (1 << 14)) {
+ printk(KERN_ERR "%s: configuration error\n", dev->name);
+ } else {
+ if (control & (1 << 11))
+ printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
+ if (control & (1 << 12))
+ printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
+ if (control & (1 << 13))
+ printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
+ if (control & (1 << 10))
+ printk(KERN_DEBUG "%s TX enabled\n", dev->name);
+ if (control & (1 << 9))
+ printk(KERN_DEBUG "%s RX enabled\n", dev->name);
}
- aup->pDBfree = pDBfree;
- /* attach a data buffer to each descriptor */
- for (i=0; i<NUM_IR_DESC; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) goto out;
- aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
- aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
- aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
- aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
- aup->rx_db_inuse[i] = pDB;
+ return ret;
+}
+
+static void update_rx_stats(struct net_device *dev, u32 status, u32 count)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->rx_packets++;
+
+ if (status & IR_RX_ERROR) {
+ ps->rx_errors++;
+ if (status & (IR_PHY_ERROR | IR_FIFO_OVER))
+ ps->rx_missed_errors++;
+ if (status & IR_MAX_LEN)
+ ps->rx_length_errors++;
+ if (status & IR_CRC_ERROR)
+ ps->rx_crc_errors++;
+ } else
+ ps->rx_bytes += count;
+}
+
+static void update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
+{
+ struct net_device_stats *ps = &dev->stats;
+
+ ps->tx_packets++;
+ ps->tx_bytes += pkt_len;
+
+ if (status & IR_TX_ERROR) {
+ ps->tx_errors++;
+ ps->tx_aborted_errors++;
}
- for (i=0; i<NUM_IR_DESC; i++) {
- pDB = GetFreeDB(aup);
- if (!pDB) goto out;
- aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
- aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr>>8) & 0xff);
- aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr>>16) & 0xff);
- aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr>>24) & 0xff);
- aup->tx_ring[i]->count_0 = 0;
- aup->tx_ring[i]->count_1 = 0;
- aup->tx_ring[i]->flags = 0;
- aup->tx_db_inuse[i] = pDB;
+}
+
+static void au1k_tx_ack(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ volatile struct ring_dest *ptxd;
+
+ ptxd = aup->tx_ring[aup->tx_tail];
+ while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
+ update_tx_stats(dev, ptxd->flags,
+ (ptxd->count_1 << 8) | ptxd->count_0);
+ ptxd->count_0 = 0;
+ ptxd->count_1 = 0;
+ wmb();
+ aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
+ ptxd = aup->tx_ring[aup->tx_tail];
+
+ if (aup->tx_full) {
+ aup->tx_full = 0;
+ netif_wake_queue(dev);
+ }
}
-#if defined(CONFIG_MIPS_DB1000)
- /* power on */
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_IRDA_MODE_MASK,
- BCSR_RESETS_IRDA_MODE_FULL);
-#endif
+ if (aup->tx_tail == aup->tx_head) {
+ if (aup->newspeed) {
+ au1k_irda_set_speed(dev, aup->newspeed);
+ aup->newspeed = 0;
+ } else {
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) & ~IR_TX_ENABLE);
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) | IR_RX_ENABLE);
+ irda_write(aup, IR_RING_PROMPT, 0);
+ }
+ }
+}
- return 0;
+static int au1k_irda_rx(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ volatile struct ring_dest *prxd;
+ struct sk_buff *skb;
+ struct db_dest *pDB;
+ u32 flags, count;
-out3:
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
-out2:
- kfree(aup->rx_buff.head);
-out1:
- printk(KERN_ERR "au1k_init_module failed. Returns %d\n", retval);
- return retval;
+ prxd = aup->rx_ring[aup->rx_head];
+ flags = prxd->flags;
+
+ while (!(flags & AU_OWN)) {
+ pDB = aup->rx_db_inuse[aup->rx_head];
+ count = (prxd->count_1 << 8) | prxd->count_0;
+ if (!(flags & IR_RX_ERROR)) {
+ /* good frame */
+ update_rx_stats(dev, flags, count);
+ skb = alloc_skb(count + 1, GFP_ATOMIC);
+ if (skb == NULL) {
+ dev->stats.rx_dropped++;
+ continue;
+ }
+ skb_reserve(skb, 1);
+ if (aup->speed == 4000000)
+ skb_put(skb, count);
+ else
+ skb_put(skb, count - 2);
+ skb_copy_to_linear_data(skb, (void *)pDB->vaddr,
+ count - 2);
+ skb->dev = dev;
+ skb_reset_mac_header(skb);
+ skb->protocol = htons(ETH_P_IRDA);
+ netif_rx(skb);
+ prxd->count_0 = 0;
+ prxd->count_1 = 0;
+ }
+ prxd->flags |= AU_OWN;
+ aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
+ irda_write(aup, IR_RING_PROMPT, 0);
+
+ /* next descriptor */
+ prxd = aup->rx_ring[aup->rx_head];
+ flags = prxd->flags;
+
+ }
+ return 0;
}
+static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct au1k_private *aup = netdev_priv(dev);
+
+ irda_write(aup, IR_INT_CLEAR, 0); /* ack irda interrupts */
+
+ au1k_irda_rx(dev);
+ au1k_tx_ack(dev);
+
+ return IRQ_HANDLED;
+}
static int au1k_init(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
+ u32 enable, ring_address;
int i;
- u32 control;
- u32 ring_address;
- /* bring the device out of reset */
- control = 0xe; /* coherent, clock enable, one half system clock */
-
+ enable = IR_HC | IR_CE | IR_C;
#ifndef CONFIG_CPU_LITTLE_ENDIAN
- control |= 1;
+ enable |= IR_BE;
#endif
aup->tx_head = 0;
aup->tx_tail = 0;
aup->rx_head = 0;
- for (i=0; i<NUM_IR_DESC; i++) {
+ for (i = 0; i < NUM_IR_DESC; i++)
aup->rx_ring[i]->flags = AU_OWN;
- }
- writel(control, IR_INTERFACE_CONFIG);
- au_sync_delay(10);
+ irda_write(aup, IR_ENABLE, enable);
+ msleep(20);
- writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE); /* disable PHY */
- au_sync_delay(1);
+ /* disable PHY */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+ irda_write(aup, IR_STATUS, irda_read(aup, IR_STATUS) & ~IR_PHYEN);
+ msleep(20);
- writel(MAX_BUF_SIZE, IR_MAX_PKT_LEN);
+ irda_write(aup, IR_MAX_PKT_LEN, MAX_BUF_SIZE);
ring_address = (u32)virt_to_phys((void *)aup->rx_ring[0]);
- writel(ring_address >> 26, IR_RING_BASE_ADDR_H);
- writel((ring_address >> 10) & 0xffff, IR_RING_BASE_ADDR_L);
+ irda_write(aup, IR_RING_BASE_ADDR_H, ring_address >> 26);
+ irda_write(aup, IR_RING_BASE_ADDR_L, (ring_address >> 10) & 0xffff);
- writel(RING_SIZE_64<<8 | RING_SIZE_64<<12, IR_RING_SIZE);
+ irda_write(aup, IR_RING_SIZE,
+ (RING_SIZE_64 << 8) | (RING_SIZE_64 << 12));
- writel(1<<2 | IR_ONE_PIN, IR_CONFIG_2); /* 48MHz */
- writel(0, IR_RING_ADDR_CMPR);
+ irda_write(aup, IR_CONFIG_2, IR_PHYCLK_48MHZ | IR_ONE_PIN);
+ irda_write(aup, IR_RING_ADDR_CMPR, 0);
au1k_irda_set_speed(dev, 9600);
return 0;
@@ -337,25 +555,28 @@ static int au1k_init(struct net_device *dev)
static int au1k_irda_start(struct net_device *dev)
{
- int retval;
- char hwname[32];
struct au1k_private *aup = netdev_priv(dev);
+ char hwname[32];
+ int retval;
- if ((retval = au1k_init(dev))) {
+ retval = au1k_init(dev);
+ if (retval) {
printk(KERN_ERR "%s: error in au1k_init\n", dev->name);
return retval;
}
- if ((retval = request_irq(AU1000_IRDA_TX_INT, au1k_irda_interrupt,
- 0, dev->name, dev))) {
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
+ retval = request_irq(aup->irq_tx, &au1k_irda_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ printk(KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
return retval;
}
- if ((retval = request_irq(AU1000_IRDA_RX_INT, au1k_irda_interrupt,
- 0, dev->name, dev))) {
- free_irq(AU1000_IRDA_TX_INT, dev);
- printk(KERN_ERR "%s: unable to get IRQ %d\n",
+ retval = request_irq(aup->irq_rx, &au1k_irda_interrupt, 0,
+ dev->name, dev);
+ if (retval) {
+ free_irq(aup->irq_tx, dev);
+ printk(KERN_ERR "%s: unable to get IRQ %d\n",
dev->name, dev->irq);
return retval;
}
@@ -365,9 +586,13 @@ static int au1k_irda_start(struct net_device *dev)
aup->irlap = irlap_open(dev, &aup->qos, hwname);
netif_start_queue(dev);
- writel(read_ir_reg(IR_CONFIG_2) | 1<<8, IR_CONFIG_2); /* int enable */
+ /* int enable */
+ irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) | IR_IEN);
- aup->timer.expires = RUN_AT((3*HZ));
+ /* power up */
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_SIR);
+
+ aup->timer.expires = RUN_AT((3 * HZ));
aup->timer.data = (unsigned long)dev;
return 0;
}
@@ -376,11 +601,12 @@ static int au1k_irda_stop(struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
+ au1k_irda_plat_set_phy_mode(aup, AU1000_IRDA_PHY_MODE_OFF);
+
/* disable interrupts */
- writel(read_ir_reg(IR_CONFIG_2) & ~(1<<8), IR_CONFIG_2);
- writel(0, IR_CONFIG_1);
- writel(0, IR_INTERFACE_CONFIG); /* disable clock */
- au_sync();
+ irda_write(aup, IR_CONFIG_2, irda_read(aup, IR_CONFIG_2) & ~IR_IEN);
+ irda_write(aup, IR_CONFIG_1, 0);
+ irda_write(aup, IR_ENABLE, 0); /* disable clock */
if (aup->irlap) {
irlap_close(aup->irlap);
@@ -391,83 +617,12 @@ static int au1k_irda_stop(struct net_device *dev)
del_timer(&aup->timer);
/* disable the interrupt */
- free_irq(AU1000_IRDA_TX_INT, dev);
- free_irq(AU1000_IRDA_RX_INT, dev);
- return 0;
-}
-
-static void __exit au1k_irda_exit(void)
-{
- struct net_device *dev = ir_devs[0];
- struct au1k_private *aup = netdev_priv(dev);
-
- unregister_netdev(dev);
-
- dma_free((void *)aup->db[0].vaddr,
- MAX_BUF_SIZE * 2*NUM_IR_DESC);
- dma_free((void *)aup->rx_ring[0],
- 2 * MAX_NUM_IR_DESC*(sizeof(ring_dest_t)));
- kfree(aup->rx_buff.head);
- free_netdev(dev);
-}
-
-
-static inline void
-update_tx_stats(struct net_device *dev, u32 status, u32 pkt_len)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &aup->stats;
-
- ps->tx_packets++;
- ps->tx_bytes += pkt_len;
-
- if (status & IR_TX_ERROR) {
- ps->tx_errors++;
- ps->tx_aborted_errors++;
- }
-}
-
-
-static void au1k_tx_ack(struct net_device *dev)
-{
- struct au1k_private *aup = netdev_priv(dev);
- volatile ring_dest_t *ptxd;
-
- ptxd = aup->tx_ring[aup->tx_tail];
- while (!(ptxd->flags & AU_OWN) && (aup->tx_tail != aup->tx_head)) {
- update_tx_stats(dev, ptxd->flags,
- ptxd->count_1<<8 | ptxd->count_0);
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- au_sync();
-
- aup->tx_tail = (aup->tx_tail + 1) & (NUM_IR_DESC - 1);
- ptxd = aup->tx_ring[aup->tx_tail];
-
- if (aup->tx_full) {
- aup->tx_full = 0;
- netif_wake_queue(dev);
- }
- }
+ free_irq(aup->irq_tx, dev);
+ free_irq(aup->irq_rx, dev);
- if (aup->tx_tail == aup->tx_head) {
- if (aup->newspeed) {
- au1k_irda_set_speed(dev, aup->newspeed);
- aup->newspeed = 0;
- }
- else {
- writel(read_ir_reg(IR_CONFIG_1) & ~IR_TX_ENABLE,
- IR_CONFIG_1);
- au_sync();
- writel(read_ir_reg(IR_CONFIG_1) | IR_RX_ENABLE,
- IR_CONFIG_1);
- writel(0, IR_RING_PROMPT);
- au_sync();
- }
- }
+ return 0;
}
-
/*
* Au1000 transmit routine.
*/
@@ -475,15 +630,12 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct au1k_private *aup = netdev_priv(dev);
int speed = irda_get_next_speed(skb);
- volatile ring_dest_t *ptxd;
- u32 len;
-
- u32 flags;
- db_dest_t *pDB;
+ volatile struct ring_dest *ptxd;
+ struct db_dest *pDB;
+ u32 len, flags;
- if (speed != aup->speed && speed != -1) {
+ if (speed != aup->speed && speed != -1)
aup->newspeed = speed;
- }
if ((skb->len == 0) && (aup->newspeed)) {
if (aup->tx_tail == aup->tx_head) {
@@ -501,138 +653,47 @@ static int au1k_irda_hard_xmit(struct sk_buff *skb, struct net_device *dev)
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return NETDEV_TX_BUSY;
- }
- else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
+ return 1;
+ } else if (((aup->tx_head + 1) & (NUM_IR_DESC - 1)) == aup->tx_tail) {
printk(KERN_DEBUG "%s: tx_full\n", dev->name);
netif_stop_queue(dev);
aup->tx_full = 1;
- return NETDEV_TX_BUSY;
+ return 1;
}
pDB = aup->tx_db_inuse[aup->tx_head];
#if 0
- if (read_ir_reg(IR_RX_BYTE_CNT) != 0) {
- printk("tx warning: rx byte cnt %x\n",
- read_ir_reg(IR_RX_BYTE_CNT));
+ if (irda_read(aup, IR_RX_BYTE_CNT) != 0) {
+ printk(KERN_DEBUG "tx warning: rx byte cnt %x\n",
+ irda_read(aup, IR_RX_BYTE_CNT));
}
#endif
-
+
if (aup->speed == 4000000) {
/* FIR */
- skb_copy_from_linear_data(skb, pDB->vaddr, skb->len);
+ skb_copy_from_linear_data(skb, (void *)pDB->vaddr, skb->len);
ptxd->count_0 = skb->len & 0xff;
ptxd->count_1 = (skb->len >> 8) & 0xff;
-
- }
- else {
+ } else {
/* SIR */
len = async_wrap_skb(skb, (u8 *)pDB->vaddr, MAX_BUF_SIZE);
ptxd->count_0 = len & 0xff;
ptxd->count_1 = (len >> 8) & 0xff;
ptxd->flags |= IR_DIS_CRC;
- au_writel(au_readl(0xae00000c) & ~(1<<13), 0xae00000c);
}
ptxd->flags |= AU_OWN;
- au_sync();
+ wmb();
- writel(read_ir_reg(IR_CONFIG_1) | IR_TX_ENABLE, IR_CONFIG_1);
- writel(0, IR_RING_PROMPT);
- au_sync();
+ irda_write(aup, IR_CONFIG_1,
+ irda_read(aup, IR_CONFIG_1) | IR_TX_ENABLE);
+ irda_write(aup, IR_RING_PROMPT, 0);
dev_kfree_skb(skb);
aup->tx_head = (aup->tx_head + 1) & (NUM_IR_DESC - 1);
return NETDEV_TX_OK;
}
-
-static inline void
-update_rx_stats(struct net_device *dev, u32 status, u32 count)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct net_device_stats *ps = &aup->stats;
-
- ps->rx_packets++;
-
- if (status & IR_RX_ERROR) {
- ps->rx_errors++;
- if (status & (IR_PHY_ERROR|IR_FIFO_OVER))
- ps->rx_missed_errors++;
- if (status & IR_MAX_LEN)
- ps->rx_length_errors++;
- if (status & IR_CRC_ERROR)
- ps->rx_crc_errors++;
- }
- else
- ps->rx_bytes += count;
-}
-
-/*
- * Au1000 receive routine.
- */
-static int au1k_irda_rx(struct net_device *dev)
-{
- struct au1k_private *aup = netdev_priv(dev);
- struct sk_buff *skb;
- volatile ring_dest_t *prxd;
- u32 flags, count;
- db_dest_t *pDB;
-
- prxd = aup->rx_ring[aup->rx_head];
- flags = prxd->flags;
-
- while (!(flags & AU_OWN)) {
- pDB = aup->rx_db_inuse[aup->rx_head];
- count = prxd->count_1<<8 | prxd->count_0;
- if (!(flags & IR_RX_ERROR)) {
- /* good frame */
- update_rx_stats(dev, flags, count);
- skb=alloc_skb(count+1,GFP_ATOMIC);
- if (skb == NULL) {
- aup->netdev->stats.rx_dropped++;
- continue;
- }
- skb_reserve(skb, 1);
- if (aup->speed == 4000000)
- skb_put(skb, count);
- else
- skb_put(skb, count-2);
- skb_copy_to_linear_data(skb, pDB->vaddr, count - 2);
- skb->dev = dev;
- skb_reset_mac_header(skb);
- skb->protocol = htons(ETH_P_IRDA);
- netif_rx(skb);
- prxd->count_0 = 0;
- prxd->count_1 = 0;
- }
- prxd->flags |= AU_OWN;
- aup->rx_head = (aup->rx_head + 1) & (NUM_IR_DESC - 1);
- writel(0, IR_RING_PROMPT);
- au_sync();
-
- /* next descriptor */
- prxd = aup->rx_ring[aup->rx_head];
- flags = prxd->flags;
-
- }
- return 0;
-}
-
-
-static irqreturn_t au1k_irda_interrupt(int dummy, void *dev_id)
-{
- struct net_device *dev = dev_id;
-
- writel(0, IR_INT_CLEAR); /* ack irda interrupts */
-
- au1k_irda_rx(dev);
- au1k_tx_ack(dev);
-
- return IRQ_HANDLED;
-}
-
-
/*
* The Tx ring has been full longer than the watchdog timeout
* value. The transmitter must be hung?
@@ -650,142 +711,7 @@ static void au1k_tx_timeout(struct net_device *dev)
netif_wake_queue(dev);
}
-
-/*
- * Set the IrDA communications speed.
- */
-static int
-au1k_irda_set_speed(struct net_device *dev, int speed)
-{
- unsigned long flags;
- struct au1k_private *aup = netdev_priv(dev);
- u32 control;
- int ret = 0, timeout = 10, i;
- volatile ring_dest_t *ptxd;
-#if defined(CONFIG_MIPS_DB1000)
- unsigned long irda_resets;
-#endif
-
- if (speed == aup->speed)
- return ret;
-
- spin_lock_irqsave(&ir_lock, flags);
-
- /* disable PHY first */
- writel(read_ir_reg(IR_ENABLE) & ~0x8000, IR_ENABLE);
-
- /* disable RX/TX */
- writel(read_ir_reg(IR_CONFIG_1) & ~(IR_RX_ENABLE|IR_TX_ENABLE),
- IR_CONFIG_1);
- au_sync_delay(1);
- while (read_ir_reg(IR_ENABLE) & (IR_RX_STATUS | IR_TX_STATUS)) {
- mdelay(1);
- if (!timeout--) {
- printk(KERN_ERR "%s: rx/tx disable timeout\n",
- dev->name);
- break;
- }
- }
-
- /* disable DMA */
- writel(read_ir_reg(IR_CONFIG_1) & ~IR_DMA_ENABLE, IR_CONFIG_1);
- au_sync_delay(1);
-
- /*
- * After we disable tx/rx. the index pointers
- * go back to zero.
- */
- aup->tx_head = aup->tx_tail = aup->rx_head = 0;
- for (i=0; i<NUM_IR_DESC; i++) {
- ptxd = aup->tx_ring[i];
- ptxd->flags = 0;
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- }
-
- for (i=0; i<NUM_IR_DESC; i++) {
- ptxd = aup->rx_ring[i];
- ptxd->count_0 = 0;
- ptxd->count_1 = 0;
- ptxd->flags = AU_OWN;
- }
-
- if (speed == 4000000) {
-#if defined(CONFIG_MIPS_DB1000)
- bcsr_mod(BCSR_RESETS, 0, BCSR_RESETS_FIR_SEL);
-#else /* Pb1000 and Pb1100 */
- writel(1<<13, CPLD_AUX1);
-#endif
- }
- else {
-#if defined(CONFIG_MIPS_DB1000)
- bcsr_mod(BCSR_RESETS, BCSR_RESETS_FIR_SEL, 0);
-#else /* Pb1000 and Pb1100 */
- writel(readl(CPLD_AUX1) & ~(1<<13), CPLD_AUX1);
-#endif
- }
-
- switch (speed) {
- case 9600:
- writel(11<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 19200:
- writel(5<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 38400:
- writel(2<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 57600:
- writel(1<<10 | 12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 115200:
- writel(12<<5, IR_WRITE_PHY_CONFIG);
- writel(IR_SIR_MODE, IR_CONFIG_1);
- break;
- case 4000000:
- writel(0xF, IR_WRITE_PHY_CONFIG);
- writel(IR_FIR|IR_DMA_ENABLE|IR_RX_ENABLE, IR_CONFIG_1);
- break;
- default:
- printk(KERN_ERR "%s unsupported speed %x\n", dev->name, speed);
- ret = -EINVAL;
- break;
- }
-
- aup->speed = speed;
- writel(read_ir_reg(IR_ENABLE) | 0x8000, IR_ENABLE);
- au_sync();
-
- control = read_ir_reg(IR_ENABLE);
- writel(0, IR_RING_PROMPT);
- au_sync();
-
- if (control & (1<<14)) {
- printk(KERN_ERR "%s: configuration error\n", dev->name);
- }
- else {
- if (control & (1<<11))
- printk(KERN_DEBUG "%s Valid SIR config\n", dev->name);
- if (control & (1<<12))
- printk(KERN_DEBUG "%s Valid MIR config\n", dev->name);
- if (control & (1<<13))
- printk(KERN_DEBUG "%s Valid FIR config\n", dev->name);
- if (control & (1<<10))
- printk(KERN_DEBUG "%s TX enabled\n", dev->name);
- if (control & (1<<9))
- printk(KERN_DEBUG "%s RX enabled\n", dev->name);
- }
-
- spin_unlock_irqrestore(&ir_lock, flags);
- return ret;
-}
-
-static int
-au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
+static int au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
{
struct if_irda_req *rq = (struct if_irda_req *)ifreq;
struct au1k_private *aup = netdev_priv(dev);
@@ -826,8 +752,218 @@ au1k_irda_ioctl(struct net_device *dev, struct ifreq *ifreq, int cmd)
return ret;
}
+static const struct net_device_ops au1k_irda_netdev_ops = {
+ .ndo_open = au1k_irda_start,
+ .ndo_stop = au1k_irda_stop,
+ .ndo_start_xmit = au1k_irda_hard_xmit,
+ .ndo_tx_timeout = au1k_tx_timeout,
+ .ndo_do_ioctl = au1k_irda_ioctl,
+};
+
+static int __devinit au1k_irda_net_init(struct net_device *dev)
+{
+ struct au1k_private *aup = netdev_priv(dev);
+ struct db_dest *pDB, *pDBfree;
+ int i, err, retval = 0;
+ dma_addr_t temp;
+
+ err = au1k_irda_init_iobuf(&aup->rx_buff, 14384);
+ if (err)
+ goto out1;
+
+ dev->netdev_ops = &au1k_irda_netdev_ops;
+
+ irda_init_max_qos_capabilies(&aup->qos);
+
+ /* The only value we must override it the baudrate */
+ aup->qos.baud_rate.bits = IR_9600 | IR_19200 | IR_38400 |
+ IR_57600 | IR_115200 | IR_576000 | (IR_4000000 << 8);
+
+ aup->qos.min_turn_time.bits = qos_mtt_bits;
+ irda_qos_bits_to_value(&aup->qos);
+
+ retval = -ENOMEM;
+
+ /* Tx ring follows rx ring + 512 bytes */
+ /* we need a 1k aligned buffer */
+ aup->rx_ring[0] = (struct ring_dest *)
+ dma_alloc(2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)),
+ &temp);
+ if (!aup->rx_ring[0])
+ goto out2;
+
+ /* allocate the data buffers */
+ aup->db[0].vaddr =
+ (void *)dma_alloc(MAX_BUF_SIZE * 2 * NUM_IR_DESC, &temp);
+ if (!aup->db[0].vaddr)
+ goto out3;
+
+ setup_hw_rings(aup, (u32)aup->rx_ring[0], (u32)aup->rx_ring[0] + 512);
+
+ pDBfree = NULL;
+ pDB = aup->db;
+ for (i = 0; i < (2 * NUM_IR_DESC); i++) {
+ pDB->pnext = pDBfree;
+ pDBfree = pDB;
+ pDB->vaddr =
+ (u32 *)((unsigned)aup->db[0].vaddr + (MAX_BUF_SIZE * i));
+ pDB->dma_addr = (dma_addr_t)virt_to_bus(pDB->vaddr);
+ pDB++;
+ }
+ aup->pDBfree = pDBfree;
+
+ /* attach a data buffer to each descriptor */
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB)
+ goto out3;
+ aup->rx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+ aup->rx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff);
+ aup->rx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff);
+ aup->rx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff);
+ aup->rx_db_inuse[i] = pDB;
+ }
+ for (i = 0; i < NUM_IR_DESC; i++) {
+ pDB = GetFreeDB(aup);
+ if (!pDB)
+ goto out3;
+ aup->tx_ring[i]->addr_0 = (u8)(pDB->dma_addr & 0xff);
+ aup->tx_ring[i]->addr_1 = (u8)((pDB->dma_addr >> 8) & 0xff);
+ aup->tx_ring[i]->addr_2 = (u8)((pDB->dma_addr >> 16) & 0xff);
+ aup->tx_ring[i]->addr_3 = (u8)((pDB->dma_addr >> 24) & 0xff);
+ aup->tx_ring[i]->count_0 = 0;
+ aup->tx_ring[i]->count_1 = 0;
+ aup->tx_ring[i]->flags = 0;
+ aup->tx_db_inuse[i] = pDB;
+ }
+
+ return 0;
+
+out3:
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+out2:
+ kfree(aup->rx_buff.head);
+out1:
+ printk(KERN_ERR "au1k_irda_net_init() failed. Returns %d\n", retval);
+ return retval;
+}
+
+static int __devinit au1k_irda_probe(struct platform_device *pdev)
+{
+ struct au1k_private *aup;
+ struct net_device *dev;
+ struct resource *r;
+ int err;
+
+ dev = alloc_irdadev(sizeof(struct au1k_private));
+ if (!dev)
+ return -ENOMEM;
+
+ aup = netdev_priv(dev);
+
+ aup->platdata = pdev->dev.platform_data;
+
+ err = -EINVAL;
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ if (!r)
+ goto out;
+
+ aup->irq_tx = r->start;
+
+ r = platform_get_resource(pdev, IORESOURCE_IRQ, 1);
+ if (!r)
+ goto out;
+
+ aup->irq_rx = r->start;
+
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!r)
+ goto out;
+
+ err = -EBUSY;
+ aup->ioarea = request_mem_region(r->start, r->end - r->start + 1,
+ pdev->name);
+ if (!aup->ioarea)
+ goto out;
+
+ aup->iobase = ioremap_nocache(r->start, r->end - r->start + 1);
+ if (!aup->iobase)
+ goto out2;
+
+ dev->irq = aup->irq_rx;
+
+ err = au1k_irda_net_init(dev);
+ if (err)
+ goto out3;
+ err = register_netdev(dev);
+ if (err)
+ goto out4;
+
+ platform_set_drvdata(pdev, dev);
+
+ printk(KERN_INFO "IrDA: Registered device %s\n", dev->name);
+ return 0;
+
+out4:
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2 * NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+ kfree(aup->rx_buff.head);
+out3:
+ iounmap(aup->iobase);
+out2:
+ release_resource(aup->ioarea);
+ kfree(aup->ioarea);
+out:
+ free_netdev(dev);
+ return err;
+}
+
+static int __devexit au1k_irda_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct au1k_private *aup = netdev_priv(dev);
+
+ unregister_netdev(dev);
+
+ dma_free((void *)aup->db[0].vaddr,
+ MAX_BUF_SIZE * 2 * NUM_IR_DESC);
+ dma_free((void *)aup->rx_ring[0],
+ 2 * MAX_NUM_IR_DESC * (sizeof(struct ring_dest)));
+ kfree(aup->rx_buff.head);
+
+ iounmap(aup->iobase);
+ release_resource(aup->ioarea);
+ kfree(aup->ioarea);
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+static struct platform_driver au1k_irda_driver = {
+ .driver = {
+ .name = "au1000-irda",
+ .owner = THIS_MODULE,
+ },
+ .probe = au1k_irda_probe,
+ .remove = __devexit_p(au1k_irda_remove),
+};
+
+static int __init au1k_irda_load(void)
+{
+ return platform_driver_register(&au1k_irda_driver);
+}
+
+static void __exit au1k_irda_unload(void)
+{
+ return platform_driver_unregister(&au1k_irda_driver);
+}
+
MODULE_AUTHOR("Pete Popov <ppopov@mvista.com>");
MODULE_DESCRIPTION("Au1000 IrDA Device Driver");
-module_init(au1k_irda_init);
-module_exit(au1k_irda_exit);
+module_init(au1k_irda_load);
+module_exit(au1k_irda_unload);
--
1.7.7.1
^ permalink raw reply related
* Re: spamm of cfg80211: Calling CRDA to update world regulatory domain
From: Thomas Backlund @ 2011-11-01 18:44 UTC (permalink / raw)
To: Justin P. Mattock; +Cc: linux-kernel, netdev, linux-wireless
In-Reply-To: <4EB00DD3.7090701@gmail.com>
Justin P. Mattock skrev 1.11.2011 17:18:
> is there a way to get rid of this annoying spamming of the regulatory?
>
>
> [ 338.519037] cfg80211: Calling CRDA to update world regulatory domain
> [ 338.523266] cfg80211: World regulatory domain updated:
> [ 338.523269] cfg80211: (start_freq - end_freq @ bandwidth),
> (max_antenna_gain, max_eirp)
> [ 338.523272] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523276] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523279] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523281] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 338.523284] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz), (300
> mBi, 2000 mBm)
> [ 340.948738] wlan1: authenticate with 00:1d:a2:d8:7e:70 (try 1)
> [ 340.950479] wlan1: authenticated
> [ 340.950707] wlan1: associate with 00:1d:a2:d8:7e:70 (try 1)
> [ 340.953611] wlan1: RX ReassocResp from 00:1d:a2:d8:7e:70 (capab=0x401
> status=0 aid=79)
> [ 340.953614] wlan1: associated
> [ 458.646604] wlan1: deauthenticated from 00:1d:a2:d8:7e:70 (Reason: 2)
>
>
> my entire syslog is filled with the above.
>
Are you using networkmanager or systemd or even both ?
Atleast at some point networkmanager have had problems when trying to
activate wireless faster than the hw like, so you get into
auth/deauth loop, and for every time interface restart gets detected,
setting crda gets triggered.
For me systemd also has had the same problems for me from time to time,
and the only way to get wireless up then is to disable it for a
~5+ seconds with the hw killswitch, and when I re-enable it, network
comes up as intended.
This happends for me with atleast 3.0 and 3.1 kernels and Intel 4965AGN
wireless connecting to a 11N 5GHz AP.
--
Thomas
^ permalink raw reply
* Re: [PATCH] r8169: Fix WOL in power down case
From: Stefan Becker @ 2011-11-01 17:28 UTC (permalink / raw)
To: netdev
In-Reply-To: <20111009191331.cbfca0b6b724921f35fd8c41@gmx.de>
Marc Ballarin <ballarin.marc <at> gmx.de> writes:
>
> On Sun, 9 Oct 2011 13:54:38 +0200
> Francois Romieu <romieu <at> fr.zoreil.com> wrote:
>
> > ...
> > Moreover, the patch duplicates a chunk of conditional code:
> > 1) it bloats the driver (ok, we have seen worse...).
> > 2) you can bet that both instances won't be updated if / when
> > RTL_GIGA_MAC_VER_xy appears.
>
> I thought so
>
> >
> > The patch below should fix it.
>
> Yes, it works fine here. Thanks a lot.
>
I just upgraded to Fedora 16 with Kernel 3.1.0 and WoL stopped working in the
power down case on my R8168 :-(
[ 8.557372] r8169 0000:02:00.0: eth0: RTL8168c/8111c at 0xf809a000,
00:1f:d0:5a:22:77, XID 1c4000c0 IRQ 43
02:00.0 Ethernet controller [0200]: Realtek Semiconductor Co., Ltd.
RTL8111/8168B PCI Express Gigabit Ethernet controller [10ec:8168] (rev 02)
I've checked the SRPM and git commit 649b3b8c4e868 with the fix discussed here
is included. It obviously doesn't work for my HW.
According to the code the combination "RTL8168c/8111c" means RTL_GIGA_MAC_VER_19
to _22, so the code changes in the fix commit don't apply to them. Could it be
that the fix doesn't cover all the necessary HW?
Regards,
Stefan
PS: Please CC me in your reply, as I don't read the mailing list.
^ permalink raw reply
* [PATCH net-next] bnx2x: stop using on-stack napi struct
From: Ariel Elior @ 2011-11-01 16:04 UTC (permalink / raw)
To: davem, netdev; +Cc: eilong
Napi structure was allocated on stack to hold temporary value of copied
fastpath. This can be avoided by using the source fastpath as a
scratchpad thus saving stack space and code.
Signed-off-by: Ariel Elior <ariele@broadcom.com>
Signed-off-by: Eilon Greenstein <eilong@broadcom.com>
---
drivers/net/bnx2x/bnx2x_cmn.c | 12 +++++++-----
1 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x_cmn.c
b/drivers/net/bnx2x/bnx2x_cmn.c
index 2890443..ff67d9b 100644
--- a/drivers/net/bnx2x/bnx2x_cmn.c
+++ b/drivers/net/bnx2x/bnx2x_cmn.c
@@ -56,19 +56,21 @@ static inline void bnx2x_bz_fp(struct bnx2x *bp, int
index)
* @to: destination FP index
*
* Makes sure the contents of the bp->fp[to].napi is kept
- * intact.
+ * intact. This is done by first copying the napi struct from
+ * the target to the source, and then mem copying the entire
+ * source onto the target
*/
static inline void bnx2x_move_fp(struct bnx2x *bp, int from, int to)
{
struct bnx2x_fastpath *from_fp = &bp->fp[from];
struct bnx2x_fastpath *to_fp = &bp->fp[to];
- struct napi_struct orig_napi = to_fp->napi;
+
+ /* Copy the NAPI object as it has been already initialized */
+ from_fp->napi = to_fp->napi;
+
/* Move bnx2x_fastpath contents */
memcpy(to_fp, from_fp, sizeof(*to_fp));
to_fp->index = to;
-
- /* Restore the NAPI object as it has been already initialized */
- to_fp->napi = orig_napi;
}
/* free skb in the packet ring at pos idx
--
1.7.4.1
^ permalink raw reply related
* spamm of cfg80211: Calling CRDA to update world regulatory domain
From: Justin P. Mattock @ 2011-11-01 15:18 UTC (permalink / raw)
To: linux-kernel, netdev, linux-wireless
is there a way to get rid of this annoying spamming of the regulatory?
[ 338.519037] cfg80211: Calling CRDA to update world regulatory domain
[ 338.523266] cfg80211: World regulatory domain updated:
[ 338.523269] cfg80211: (start_freq - end_freq @ bandwidth),
(max_antenna_gain, max_eirp)
[ 338.523272] cfg80211: (2402000 KHz - 2472000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[ 338.523276] cfg80211: (2457000 KHz - 2482000 KHz @ 20000 KHz),
(300 mBi, 2000 mBm)
[ 338.523279] cfg80211: (2474000 KHz - 2494000 KHz @ 20000 KHz),
(300 mBi, 2000 mBm)
[ 338.523281] cfg80211: (5170000 KHz - 5250000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[ 338.523284] cfg80211: (5735000 KHz - 5835000 KHz @ 40000 KHz),
(300 mBi, 2000 mBm)
[ 340.948738] wlan1: authenticate with 00:1d:a2:d8:7e:70 (try 1)
[ 340.950479] wlan1: authenticated
[ 340.950707] wlan1: associate with 00:1d:a2:d8:7e:70 (try 1)
[ 340.953611] wlan1: RX ReassocResp from 00:1d:a2:d8:7e:70 (capab=0x401
status=0 aid=79)
[ 340.953614] wlan1: associated
[ 458.646604] wlan1: deauthenticated from 00:1d:a2:d8:7e:70 (Reason: 2)
my entire syslog is filled with the above.
Note: I am not on the list so Cc me!
Justin P. Mattock
^ permalink raw reply
* [PATCH] IPv6 - support for NLM_F_* flags at IPv6 routing requests
From: Matti Vaittinen @ 2011-11-01 14:22 UTC (permalink / raw)
To: davem; +Cc: netdev
Hi dee Ho again.
Here's the support for NLM_F_* flags at IPv6 routing requests once again.
This time if no NLM_F_CREATE flag is not defined for RTM_NEWROUTE request,
warning is printed, but no error is returned. Instead new route is added.
Exception is when NLM_F_REPLACE flag is given without NLM_F_CREATE, and
no matching route is found. In this case it should be safe to assume
that the request issuer is familiar with NLM_F_* flags, and does really
not want route to be created.
Specifying NLM_F_REPLACE flag will now make the kernel to search for
matching route, and replace it with new one. If no route is found and
NLM_F_CREATE is specified as well, then new route is created.
Also, specifying NLM_F_EXCL will yield returning of error if matching route
is found.
Patch is created against linux-3.1-rc4
Best Regards
Matti Vaittinen
Signed-off-by: Matti Vaittinen <Mazziesaccount@gmail.com>
---
diff -uNr linux-3.1-rc4.orig/net/ipv6/ip6_fib.c linux-3.1-rc4.new/net/ipv6/ip6_fib.c
--- linux-3.1-rc4.orig/net/ipv6/ip6_fib.c 2011-11-01 14:01:55.000000000 +0200
+++ linux-3.1-rc4.new/net/ipv6/ip6_fib.c 2011-11-01 14:12:28.000000000 +0200
@@ -39,6 +39,7 @@
#include <net/ip6_fib.h>
#include <net/ip6_route.h>
+#define RT6_CANT_CREATE ((int)-1)
#define RT6_DEBUG 2
#if RT6_DEBUG >= 3
@@ -429,17 +430,34 @@
static struct fib6_node * fib6_add_1(struct fib6_node *root, void *addr,
int addrlen, int plen,
- int offset)
+ int offset, struct nl_info *info)
{
struct fib6_node *fn, *in, *ln;
struct fib6_node *pn = NULL;
struct rt6key *key;
int bit;
+
+
+ int allow_create = 1;
+ int replace_required = 0;
+
+
__be32 dir = 0;
__u32 sernum = fib6_new_sernum();
RT6_TRACE("fib6_add_1\n");
+ if (NULL != info &&
+ NULL != info->nlh &&
+ (info->nlh->nlmsg_flags&NLM_F_REPLACE)) {
+ replace_required = 1;
+ }
+ if (NULL != info &&
+ NULL != info->nlh &&
+ !(info->nlh->nlmsg_flags&NLM_F_CREATE)) {
+ allow_create = 0;
+ }
+
/* insert node in tree */
fn = root;
@@ -451,8 +469,12 @@
* Prefix match
*/
if (plen < fn->fn_bit ||
- !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit))
+ !ipv6_prefix_equal(&key->addr, addr, fn->fn_bit)) {
+ if (!allow_create)
+ printk(KERN_WARNING
+ "NLM_F_CREATE should be specified when creating new rt\n");
goto insert_above;
+ }
/*
* Exact match ?
@@ -481,10 +503,27 @@
fn = dir ? fn->right: fn->left;
} while (fn);
+
+ if (replace_required && !allow_create) {
+ /* We should not create new node because
+ * NLM_F_REPLACE was specified without NLM_F_CREATE
+ * I assume it is safe to require NLM_F_CREATE when
+ * REPLACE flag is used! Later we may want to remove the
+ * check for replace_required, because according
+ * to netlink specification, NLM_F_CREATE
+ * MUST be specified if new route is created.
+ * That would keep IPv6 consistent with IPv4
+ */
+ printk(KERN_WARNING
+ "NLM_F_CREATE should be specified when creating new rt - ignoring request\n");
+ return (struct fib6_node *)RT6_CANT_CREATE;
+ }
/*
* We walked to the bottom of tree.
* Create new leaf node without children.
*/
+ if (!allow_create)
+ printk(KERN_WARNING "NLM_F_CREATE should be specified when creating new rt\n");
ln = node_alloc();
@@ -567,7 +606,6 @@
fn->parent = in;
ln->fn_sernum = sernum;
-
if (addr_bit_set(addr, bit)) {
in->right = ln;
in->left = fn;
@@ -585,6 +623,7 @@
ln = node_alloc();
+
if (ln == NULL)
return NULL;
@@ -618,6 +657,12 @@
{
struct rt6_info *iter = NULL;
struct rt6_info **ins;
+ int replace = (NULL != info &&
+ NULL != info->nlh &&
+ (info->nlh->nlmsg_flags&NLM_F_REPLACE));
+ int add = ((NULL == info || NULL == info->nlh) ||
+ (info->nlh->nlmsg_flags&NLM_F_CREATE));
+ int found = 0;
ins = &fn->leaf;
@@ -630,6 +675,13 @@
/*
* Same priority level
*/
+ if (NULL != info->nlh &&
+ (info->nlh->nlmsg_flags&NLM_F_EXCL))
+ return -EEXIST;
+ if (replace) {
+ found++;
+ break;
+ }
if (iter->rt6i_dev == rt->rt6i_dev &&
iter->rt6i_idev == rt->rt6i_idev &&
@@ -659,19 +711,41 @@
/*
* insert node
*/
+ if (!replace) {
+ if (!add)
+ printk(KERN_WARNING "NLM_F_CREATE should be specified when creating new rt\n");
+
+add:
+ rt->dst.rt6_next = iter;
+ *ins = rt;
+ rt->rt6i_node = fn;
+ atomic_inc(&rt->rt6i_ref);
+ inet6_rt_notify(RTM_NEWROUTE, rt, info);
+ info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
+
+ if ((fn->fn_flags & RTN_RTINFO) == 0) {
+ info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
+ fn->fn_flags |= RTN_RTINFO;
+ }
- rt->dst.rt6_next = iter;
- *ins = rt;
- rt->rt6i_node = fn;
- atomic_inc(&rt->rt6i_ref);
- inet6_rt_notify(RTM_NEWROUTE, rt, info);
- info->nl_net->ipv6.rt6_stats->fib_rt_entries++;
-
- if ((fn->fn_flags & RTN_RTINFO) == 0) {
- info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
- fn->fn_flags |= RTN_RTINFO;
+ } else {
+ if (!found) {
+ if (add)
+ goto add;
+ printk(KERN_WARNING "add rtinfo to node - NLM_F_REPLACE specified, but no existing node found! bailing out\n");
+ return -ENOENT;
+ }
+ *ins = rt;
+ rt->rt6i_node = fn;
+ rt->dst.rt6_next = iter->dst.rt6_next;
+ atomic_inc(&rt->rt6i_ref);
+ inet6_rt_notify(RTM_NEWROUTE, rt, info);
+ rt6_release(iter);
+ if ((fn->fn_flags & RTN_RTINFO) == 0) {
+ info->nl_net->ipv6.rt6_stats->fib_route_nodes++;
+ fn->fn_flags |= RTN_RTINFO;
+ }
}
-
return 0;
}
@@ -700,10 +774,29 @@
{
struct fib6_node *fn, *pn = NULL;
int err = -ENOMEM;
+ int allow_create = 1;
+ int allow_replace = 1;
+ if (NULL != info &&
+ NULL != info->nlh &&
+ !(info->nlh->nlmsg_flags&NLM_F_REPLACE)) {
+ allow_replace = 0;
+ }
+ if (NULL != info &&
+ NULL != info->nlh &&
+ !(info->nlh->nlmsg_flags&NLM_F_CREATE)) {
+ allow_create = 0;
+ }
+ if (!allow_create && !allow_replace)
+ printk(KERN_WARNING "RTM_NEWROUTE with no NLM_F_CREATE or NLM_F_REPLACE\n");
fn = fib6_add_1(root, &rt->rt6i_dst.addr, sizeof(struct in6_addr),
- rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst));
+ rt->rt6i_dst.plen, offsetof(struct rt6_info, rt6i_dst),
+ info);
+ if (RT6_CANT_CREATE == (int)fn) {
+ err = -EINVAL;
+ fn = NULL;
+ }
if (fn == NULL)
goto out;
@@ -716,6 +809,8 @@
if (fn->subtree == NULL) {
struct fib6_node *sfn;
+ if (!allow_create)
+ printk(KERN_WARNING "NLM_F_CREATE should be specified when creating new rt\n");
/*
* Create subtree.
*
@@ -740,7 +835,8 @@
sn = fib6_add_1(sfn, &rt->rt6i_src.addr,
sizeof(struct in6_addr), rt->rt6i_src.plen,
- offsetof(struct rt6_info, rt6i_src));
+ offsetof(struct rt6_info, rt6i_src),
+ info);
if (sn == NULL) {
/* If it is failed, discard just allocated
@@ -757,8 +853,13 @@
} else {
sn = fib6_add_1(fn->subtree, &rt->rt6i_src.addr,
sizeof(struct in6_addr), rt->rt6i_src.plen,
- offsetof(struct rt6_info, rt6i_src));
+ offsetof(struct rt6_info, rt6i_src),
+ info);
+ if (RT6_CANT_CREATE == (int)sn) {
+ err = -EINVAL;
+ sn = NULL;
+ }
if (sn == NULL)
goto st_failure;
}
diff -uNr linux-3.1-rc4.orig/net/ipv6/route.c linux-3.1-rc4.new/net/ipv6/route.c
--- linux-3.1-rc4.orig/net/ipv6/route.c 2011-11-01 14:01:55.000000000 +0200
+++ linux-3.1-rc4.new/net/ipv6/route.c 2011-10-27 10:45:05.000000000 +0300
@@ -1223,9 +1223,18 @@
if (cfg->fc_metric == 0)
cfg->fc_metric = IP6_RT_PRIO_USER;
- table = fib6_new_table(net, cfg->fc_table);
+ err = -ENOBUFS;
+ if (NULL != cfg->fc_nlinfo.nlh &&
+ !(cfg->fc_nlinfo.nlh->nlmsg_flags&NLM_F_CREATE)) {
+ table = fib6_get_table(net, cfg->fc_table);
+ if (table == NULL) {
+ printk(KERN_WARNING "NLM_F_CREATE should be specified when creating new rt\n");
+ table = fib6_new_table(net, cfg->fc_table);
+ }
+ } else {
+ table = fib6_new_table(net, cfg->fc_table);
+ }
if (table == NULL) {
- err = -ENOBUFS;
goto out;
}
^ 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